openssl-1.0.0 upgrade

external/openssl

    Updated version to 1.0.0
	openssl.version

    Updated small records patch for 1.0.0. This is probably the most significant change.
	patches/small_records.patch

    Removed bad_version.patch since fix is included in 0.9.8n and beyond
	patches/README
	patches/bad_version.patch
	openssl.config

    Changed import_openssl.sh to generate armv4 asm with the 1.0.0
    scripts, not our backported 0.9.9-dev backported version in
    patches/arm-asm.patch.
	import_openssl.sh
	openssl.config
	patches/README
	patches/arm-asm.patch

    Added -DOPENSSL_NO_STORE to match ./Configure output
    Added -DOPENSSL_NO_WHIRLPOOL (no-whrlpool) to skip new optional cipher
	android-config.mk
	openssl.config

    Fixed import to remove include directory during import like other
    imported directories (apps, ssl, crypto)
	import_openssl.sh

    Updated UNNEEDED_SOURCES. Pruned Makefiles which we don't use.
	openssl.config

    Updated to build newly required files
	patches/apps_Android.mk
	patches/crypto_Android.mk

    Disable some new openssl tools
	patches/progs.patch

    Updated upgrade testing notes to include running BigInteger tests
	README.android

    Automatically imported
	android.testssl/
	apps/
	crypto/
	e_os.h
	e_os2.h
	include/
	ssl/

dalvik

   Change makeCipherList to skip SSLv2 ciphers that 1.0.0 now returns
   so there are not duplicate ciphersuite names in getEnabledCipherSuites.
	libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp

   Updated OpenSSLSocketImpl_cipherauthenticationmethod for new
   SSL_CIPHER algorithms -> algorithm_auth (and const-ness)
	libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp

   Update to const SSL_CIPHER in OpenSSLSessionImpl_getCipherSuite (and cipherauthenticationmethod)
	libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp

   test_EnabledCipherSuites on both SSLSocketTest and
   SSLServerSocketTest caught the makeCipherList problem. However the
   asserts where a bit out of sync and didn't give good messages
   because they didn't actually show what was going on. As part of
   debugging the issue they found, I tried to make align the asserts
   and improve their output for the future.

	libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLServerSocketTest.java
	libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLSocketTest.java

vendor/google

    Add const to X509V3_EXT_METHOD* for 1.0.0 compatibility
	libraries/libjingle/talk/base/openssladapter.cc

Change-Id: I608dbb2ecf4b7a15e13b3f3dcea7c0443ff01e32
diff --git a/README.android b/README.android
index 7110d3d..1036838 100644
--- a/README.android
+++ b/README.android
@@ -51,6 +51,8 @@
 
      (cd android.testssl/ && ./testssl.sh)
      adb shell run-core-tests tests.xnet.AllTests
+     adb shell run-core-tests org.apache.harmony.math.tests.java.math.AllTests
+     adb shell run-core-tests tests.api.java.math.BigIntegerTest
 
 8) Do a full build before checking in:
 
diff --git a/android-config.mk b/android-config.mk
index 3670593..a28e35d 100644
--- a/android-config.mk
+++ b/android-config.mk
@@ -1,17 +1,14 @@
 #
-# These flags represent the build-time configuration of openssl for
-# android
+# These flags represent the build-time configuration of openssl for android
 #
-# They were pruned from the "Makefile" generated by running
-# "./Configure linux-generic32 no-idea no-bf no-cast no-seed no-md2 -DL_ENDIAN zlib"
-# in the openssl distribution directory
+# They were pruned from the "Makefile" generated by running ./Configure from import_openssl.sh
 #
 
 # From CLFAG=	
 LOCAL_CFLAGS += -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN #-DTERMIO
 
 # From DEPFLAG=
-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_MD2 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SEED 
+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_MD2 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SEED -DOPENSSL_NO_STORE -DOPENSSL_NO_WHIRLPOOL
 
 # Extra
 LOCAL_CFLAGS += -DOPENSSL_NO_HW -DOPENSSL_NO_ENGINE -DOPENSSL_NO_EC -DOPENSSL_NO_ECDH -DOPENSSL_NO_ECDSA -DZLIB
diff --git a/android.testssl/CAss.cnf b/android.testssl/CAss.cnf
index a7959c0..1173c08 100644
--- a/android.testssl/CAss.cnf
+++ b/android.testssl/CAss.cnf
@@ -7,7 +7,7 @@
 
 ####################################################################
 [ req ]
-default_bits		= 1024
+default_bits		= 512
 default_keyfile 	= keySS.pem
 distinguished_name	= req_distinguished_name
 encrypt_rsa_key		= no
diff --git a/android.testssl/Uss.cnf b/android.testssl/Uss.cnf
index 1244a57..56dcdd5 100644
--- a/android.testssl/Uss.cnf
+++ b/android.testssl/Uss.cnf
@@ -7,7 +7,7 @@
 
 ####################################################################
 [ req ]
-default_bits		= 1024
+default_bits		= 512
 default_keyfile 	= keySS.pem
 distinguished_name	= req_distinguished_name
 encrypt_rsa_key		= no
diff --git a/android.testssl/testssl b/android.testssl/testssl
index 049fe2f..46f4576 100755
--- a/android.testssl/testssl
+++ b/android.testssl/testssl
@@ -152,4 +152,10 @@
   fi
 fi
 
+echo test tls1 with PSK
+$ssltest -tls1 -cipher PSK -psk abc123 $extra || exit 1
+
+echo test tls1 with PSK via BIO pair
+$ssltest -bio_pair -tls1 -cipher PSK -psk abc123 $extra || exit 1
+
 exit 0
diff --git a/apps/Android.mk b/apps/Android.mk
index e9a4981..a908806 100644
--- a/apps/Android.mk
+++ b/apps/Android.mk
@@ -4,13 +4,49 @@
 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
+	app_rand.c \
+	apps.c \
+	asn1pars.c \
+	ca.c \
+	ciphers.c \
+	crl.c \
+	crl2p7.c \
+	dgst.c \
+	dh.c \
+	dhparam.c \
+	dsa.c \
+	dsaparam.c \
+	ecparam.c \
+	enc.c \
+	engine.c \
+	errstr.c \
+	gendh.c \
+	gendsa.c \
+	genpkey.c \
+	genrsa.c \
+	nseq.c \
+	ocsp.c \
+	openssl.c \
+	passwd.c \
+	pkcs12.c \
+	pkcs7.c \
+	pkcs8.c \
+	prime.c \
+	rand.c \
+	req.c \
+	rsa.c \
+	rsautl.c \
+	s_cb.c \
+	s_client.c \
+	s_socket.c \
+	s_time.c \
+	sess_id.c \
+	smime.c \
+	speed.c \
+	spkac.c \
+	verify.c \
+	version.c \
+	x509.c
 
 #   cms.c ec.c s_server.c
 
diff --git a/apps/Makefile b/apps/Makefile
deleted file mode 100644
index a548815..0000000
--- a/apps/Makefile
+++ /dev/null
@@ -1,985 +0,0 @@
-#
-#  apps/Makefile
-#
-
-DIR=		apps
-TOP=		..
-CC=		cc
-INCLUDES=	-I$(TOP) -I../include $(KRB5_INCLUDES)
-CFLAG=		-g -static
-MAKEFILE=	Makefile
-PERL=		perl
-RM=		rm -f
-# KRB5 stuff
-KRB5_INCLUDES=
-LIBKRB5=
-
-PEX_LIBS=
-EX_LIBS= 
-EXE_EXT= 
-
-SHLIB_TARGET=
-
-CFLAGS= -DMONOLITH $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile makeapps.com install.com
-
-DLIBCRYPTO=../libcrypto.a
-DLIBSSL=../libssl.a
-LIBCRYPTO=-L.. -lcrypto
-LIBSSL=-L.. -lssl
-
-PROGRAM= openssl
-
-SCRIPTS=CA.sh CA.pl
-
-EXE= $(PROGRAM)$(EXE_EXT)
-
-E_EXE=	verify asn1pars req dgst dh dhparam enc passwd gendh errstr \
-	ca crl rsa rsautl dsa dsaparam ec ecparam \
-	x509 genrsa gendsa s_server s_client speed \
-	s_time version pkcs7 cms crl2pkcs7 sess_id ciphers nseq pkcs12 \
-	pkcs8 spkac smime rand engine ocsp prime
-
-PROGS= $(PROGRAM).c
-
-A_OBJ=apps.o
-A_SRC=apps.c
-S_OBJ=	s_cb.o s_socket.o
-S_SRC=	s_cb.c s_socket.c
-RAND_OBJ=app_rand.o
-RAND_SRC=app_rand.c
-
-E_OBJ=	verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o errstr.o \
-	ca.o pkcs7.o crl2p7.o crl.o \
-	rsa.o rsautl.o dsa.o dsaparam.o ec.o ecparam.o \
-	x509.o genrsa.o gendsa.o s_server.o s_client.o speed.o \
-	s_time.o $(A_OBJ) $(S_OBJ) $(RAND_OBJ) version.o sess_id.o \
-	ciphers.o nseq.o pkcs12.o pkcs8.o spkac.o smime.o rand.o engine.o \
-	ocsp.o prime.o cms.o
-
-E_SRC=	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 ec.c ecparam.c \
-	x509.c genrsa.c gendsa.c s_server.c s_client.c speed.c \
-	s_time.c $(A_SRC) $(S_SRC) $(RAND_SRC) 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 cms.c
-
-SRC=$(E_SRC)
-
-EXHEADER=
-HEADER=	apps.h progs.h s_apps.h \
-	testdsa.h testrsa.h \
-	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	@(cd ..; $(MAKE) DIRS=$(DIR) all)
-
-all:	exe
-
-exe:	$(EXE)
-
-req: sreq.o $(A_OBJ) $(DLIBCRYPTO)
-	shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \
-		shlib_target="$(SHLIB_TARGET)"; \
-	fi; \
-	$(MAKE) -f $(TOP)/Makefile.shared -e \
-		APPNAME=req OBJECTS="sreq.o $(A_OBJ) $(RAND_OBJ)" \
-		LIBDEPS="$(PEX_LIBS) $(LIBCRYPTO) $(EX_LIBS)" \
-		link_app.$${shlib_target}
-
-sreq.o: req.c 
-	$(CC) -c $(INCLUDES) $(CFLAG) -o sreq.o req.c
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-install:
-	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
-	@set -e; for i in $(EXE); \
-	do  \
-	(echo installing $$i; \
-	 cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
-	 chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
-	 mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i ); \
-	 done;
-	@set -e; for i in $(SCRIPTS); \
-	do  \
-	(echo installing $$i; \
-	 cp $$i $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new; \
-	 chmod 755 $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new; \
-	 mv -f $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i ); \
-	 done
-	@cp openssl.cnf $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf.new; \
-	chmod 644 $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf.new; \
-	mv -f  $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf.new $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-links:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-depend:
-	@if [ -z "$(THIS)" ]; then \
-	    $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
-	else \
-	    $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(SRC); \
-	fi
-
-dclean:
-	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
-	mv -f Makefile.new $(MAKEFILE)
-
-clean:
-	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff $(EXE)
-	rm -f req
-
-$(DLIBSSL):
-	(cd ..; $(MAKE) DIRS=ssl all)
-
-$(DLIBCRYPTO):
-	(cd ..; $(MAKE) DIRS=crypto all)
-
-$(EXE): progs.h $(E_OBJ) $(PROGRAM).o $(DLIBCRYPTO) $(DLIBSSL)
-	$(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 \
-		CC="$${CC}" APPNAME=$(EXE) OBJECTS="$(PROGRAM).o $(E_OBJ)" \
-		LIBDEPS="$(PEX_LIBS) $$LIBRARIES $(EX_LIBS)" \
-		link_app.$${shlib_target}
-	@if [ -z "$(CROSS_COMPILE)" ]; then \
-		(cd ..; \
-	  	OPENSSL="`pwd`/util/opensslwrap.sh"; export OPENSSL; \
-	  	$(PERL) tools/c_rehash certs) \
-	fi
-
-progs.h: progs.pl
-	$(PERL) progs.pl $(E_EXE) >progs.h
-	$(RM) $(PROGRAM).o
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-app_rand.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-app_rand.o: ../include/openssl/buffer.h ../include/openssl/conf.h
-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/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/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/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/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
-ciphers.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
-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/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
-ciphers.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-ciphers.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-ciphers.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-ciphers.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-ciphers.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-ciphers.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-ciphers.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-ciphers.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
-ciphers.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-ciphers.o: ../include/openssl/x509v3.h apps.h ciphers.c
-cms.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-cms.o: ../include/openssl/buffer.h ../include/openssl/conf.h
-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/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/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/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/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
-dh.o: ../include/openssl/dh.h ../include/openssl/e_os2.h
-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/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
-dsa.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
-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/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
-dsaparam.o: ../include/openssl/dh.h ../include/openssl/dsa.h
-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/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/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/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/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
-engine.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
-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/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
-engine.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-engine.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-engine.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-engine.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-engine.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-engine.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-engine.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-engine.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
-engine.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-engine.o: ../include/openssl/x509v3.h apps.h engine.c
-errstr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-errstr.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-errstr.o: ../include/openssl/comp.h ../include/openssl/conf.h
-errstr.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
-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/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
-errstr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-errstr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-errstr.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-errstr.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-errstr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-errstr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-errstr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-errstr.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
-errstr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-errstr.o: ../include/openssl/x509v3.h apps.h errstr.c
-gendh.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-gendh.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-gendh.o: ../include/openssl/conf.h ../include/openssl/crypto.h
-gendh.o: ../include/openssl/dh.h ../include/openssl/dsa.h
-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/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
-gendsa.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
-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/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
-genrsa.o: ../include/openssl/dh.h ../include/openssl/dsa.h
-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/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/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
-ocsp.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
-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/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
-ocsp.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-ocsp.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-ocsp.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-ocsp.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-ocsp.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-ocsp.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-ocsp.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-ocsp.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
-ocsp.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-ocsp.o: ../include/openssl/x509v3.h apps.h ocsp.c
-openssl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-openssl.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-openssl.o: ../include/openssl/comp.h ../include/openssl/conf.h
-openssl.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
-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/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
-openssl.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-openssl.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-openssl.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-openssl.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-openssl.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-openssl.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-openssl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-openssl.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
-openssl.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-openssl.o: ../include/openssl/x509v3.h apps.h openssl.c progs.h s_apps.h
-passwd.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-passwd.o: ../include/openssl/buffer.h ../include/openssl/conf.h
-passwd.o: ../include/openssl/crypto.h ../include/openssl/des.h
-passwd.o: ../include/openssl/des_old.h ../include/openssl/e_os2.h
-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/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/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/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/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/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/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
-req.o: ../include/openssl/dh.h ../include/openssl/dsa.h
-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/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/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/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
-s_cb.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
-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/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
-s_cb.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-s_cb.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s_cb.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s_cb.o: ../include/openssl/rand.h ../include/openssl/safestack.h
-s_cb.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s_cb.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s_cb.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s_cb.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s_cb.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-s_cb.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-s_cb.o: s_apps.h s_cb.c
-s_client.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s_client.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s_client.o: ../include/openssl/comp.h ../include/openssl/conf.h
-s_client.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
-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/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
-s_client.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-s_client.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s_client.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s_client.o: ../include/openssl/rand.h ../include/openssl/safestack.h
-s_client.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s_client.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s_client.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s_client.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s_client.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-s_client.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-s_client.o: s_apps.h s_client.c timeouts.h
-s_server.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s_server.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s_server.o: ../include/openssl/comp.h ../include/openssl/conf.h
-s_server.o: ../include/openssl/crypto.h ../include/openssl/dh.h
-s_server.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/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
-s_server.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-s_server.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s_server.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s_server.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-s_server.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s_server.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s_server.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s_server.o: ../include/openssl/stack.h ../include/openssl/store.h
-s_server.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s_server.o: ../include/openssl/txt_db.h ../include/openssl/ui.h
-s_server.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-s_server.o: ../include/openssl/x509v3.h apps.h s_apps.h s_server.c timeouts.h
-s_socket.o: ../e_os.h ../e_os2.h ../include/openssl/asn1.h
-s_socket.o: ../include/openssl/bio.h ../include/openssl/bn.h
-s_socket.o: ../include/openssl/buffer.h ../include/openssl/comp.h
-s_socket.o: ../include/openssl/conf.h ../include/openssl/crypto.h
-s_socket.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
-s_socket.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
-s_socket.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
-s_socket.o: ../include/openssl/evp.h ../include/openssl/fips.h
-s_socket.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
-s_socket.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-s_socket.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-s_socket.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-s_socket.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-s_socket.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s_socket.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s_socket.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s_socket.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s_socket.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s_socket.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s_socket.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
-s_socket.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-s_socket.o: ../include/openssl/x509v3.h apps.h s_apps.h s_socket.c
-s_time.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s_time.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s_time.o: ../include/openssl/comp.h ../include/openssl/conf.h
-s_time.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
-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/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
-s_time.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-s_time.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s_time.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s_time.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s_time.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s_time.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s_time.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s_time.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
-s_time.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-s_time.o: ../include/openssl/x509v3.h apps.h s_apps.h s_time.c
-sess_id.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-sess_id.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-sess_id.o: ../include/openssl/comp.h ../include/openssl/conf.h
-sess_id.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
-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/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
-sess_id.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-sess_id.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-sess_id.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-sess_id.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-sess_id.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-sess_id.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-sess_id.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-sess_id.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
-sess_id.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-sess_id.o: ../include/openssl/x509v3.h apps.h sess_id.c
-smime.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-smime.o: ../include/openssl/buffer.h ../include/openssl/conf.h
-smime.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-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/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
-speed.o: ../include/openssl/cast.h ../include/openssl/conf.h
-speed.o: ../include/openssl/crypto.h ../include/openssl/des.h
-speed.o: ../include/openssl/des_old.h ../include/openssl/dsa.h
-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/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/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/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
-version.o: ../include/openssl/crypto.h ../include/openssl/des.h
-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/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
-x509.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
-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/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 35b62b8..5dccea7 100644
--- a/apps/apps.c
+++ b/apps/apps.c
@@ -109,12 +109,21 @@
  *
  */
 
+#ifndef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 2	/* On VMS, you need to define this to get
+				   the declaration of fileno().  The value
+				   2 is to make sure no function defined
+				   in POSIX-2 is left undefined. */
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#if !defined(OPENSSL_SYSNAME_WIN32) && !defined(NETWARE_CLIB)
+#include <strings.h>
+#endif
 #include <sys/types.h>
-#include <sys/stat.h>
 #include <ctype.h>
+#include <errno.h>
 #include <assert.h>
 #include <openssl/err.h>
 #include <openssl/x509.h>
@@ -138,6 +147,11 @@
 #include "apps.h"
 #undef NON_MAIN
 
+#ifdef _WIN32
+static int WIN32_rename(const char *from, const char *to);
+#define rename(from,to) WIN32_rename((from),(to))
+#endif
+
 typedef struct {
 	const char *name;
 	unsigned long flag;
@@ -166,18 +180,23 @@
 	static char *buf=NULL;
 	static char **arg=NULL;
 	char *p;
-	struct stat stbuf;
-
-	if (stat(file,&stbuf) < 0) return(0);
 
 	fp=fopen(file,"r");
 	if (fp == NULL)
 		return(0);
 
+	if (fseek(fp,0,SEEK_END)==0)
+		len=ftell(fp), rewind(fp);
+	else	len=-1;
+	if (len<=0)
+		{
+		fclose(fp);
+		return(0);
+		}
+
 	*argc=0;
 	*argv=NULL;
 
-	len=(unsigned int)stbuf.st_size;
 	if (buf != NULL) OPENSSL_free(buf);
 	buf=(char *)OPENSSL_malloc(len+1);
 	if (buf == NULL) return(0);
@@ -242,18 +261,25 @@
 		return(FORMAT_ASN1);
 	else if ((*s == 'T') || (*s == 't'))
 		return(FORMAT_TEXT);
-	else if ((*s == 'P') || (*s == 'p'))
-		return(FORMAT_PEM);
-	else if ((*s == 'N') || (*s == 'n'))
-		return(FORMAT_NETSCAPE);
-	else if ((*s == 'S') || (*s == 's'))
-		return(FORMAT_SMIME);
+  	else if ((*s == 'N') || (*s == 'n'))
+  		return(FORMAT_NETSCAPE);
+  	else if ((*s == 'S') || (*s == 's'))
+  		return(FORMAT_SMIME);
+ 	else if ((*s == 'M') || (*s == 'm'))
+ 		return(FORMAT_MSBLOB);
 	else if ((*s == '1')
 		|| (strcmp(s,"PKCS12") == 0) || (strcmp(s,"pkcs12") == 0)
 		|| (strcmp(s,"P12") == 0) || (strcmp(s,"p12") == 0))
 		return(FORMAT_PKCS12);
 	else if ((*s == 'E') || (*s == 'e'))
 		return(FORMAT_ENGINE);
+	else if ((*s == 'P') || (*s == 'p'))
+ 		{
+ 		if (s[1] == 'V' || s[1] == 'v')
+ 			return FORMAT_PVK;
+ 		else
+  			return(FORMAT_PEM);
+ 		}
 	else
 		return(FORMAT_UNDEF);
 	}
@@ -639,6 +665,15 @@
 				BIO_printf(err, "Can't open file %s\n", arg + 5);
 				return NULL;
 			}
+#if !defined(_WIN32)
+		/*
+		 * Under _WIN32, which covers even Win64 and CE, file
+		 * descriptors referenced by BIO_s_fd are not inherited
+		 * by child process and therefore below is not an option.
+		 * It could have been an option if bss_fd.c was operating
+		 * on real Windows descriptors, such as those obtained
+		 * with CreateFile.
+		 */
 		} else if(!strncmp(arg, "fd:", 3)) {
 			BIO *btmp;
 			i = atoi(arg + 3);
@@ -650,6 +685,7 @@
 			/* Can't do BIO_gets on an fd BIO so add a buffering BIO */
 			btmp = BIO_new(BIO_f_buffer());
 			pwdbio = BIO_push(btmp, pwdbio);
+#endif
 		} else if(!strcmp(arg, "stdin")) {
 			pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE);
 			if(!pwdbio) {
@@ -749,8 +785,6 @@
 X509 *load_cert(BIO *err, const char *file, int format,
 	const char *pass, ENGINE *e, const char *cert_descrip)
 	{
-	ASN1_HEADER *ah=NULL;
-	BUF_MEM *buf=NULL;
 	X509 *x=NULL;
 	BIO *cert;
 
@@ -762,7 +796,9 @@
 
 	if (file == NULL)
 		{
+#ifdef _IONBF
 		setvbuf(stdin, NULL, _IONBF, 0);
+#endif
 		BIO_set_fp(cert,stdin,BIO_NOCLOSE);
 		}
 	else
@@ -780,46 +816,21 @@
 		x=d2i_X509_bio(cert,NULL);
 	else if (format == FORMAT_NETSCAPE)
 		{
-		const unsigned char *p,*op;
-		int size=0,i;
-
-		/* We sort of have to do it this way because it is sort of nice
-		 * to read the header first and check it, then
-		 * try to read the certificate */
-		buf=BUF_MEM_new();
-		for (;;)
-			{
-			if ((buf == NULL) || (!BUF_MEM_grow(buf,size+1024*10)))
+		NETSCAPE_X509 *nx;
+		nx=ASN1_item_d2i_bio(ASN1_ITEM_rptr(NETSCAPE_X509),cert,NULL);
+		if (nx == NULL)
 				goto end;
-			i=BIO_read(cert,&(buf->data[size]),1024*10);
-			size+=i;
-			if (i == 0) break;
-			if (i < 0)
-				{
-				perror("reading certificate");
-				goto end;
-				}
-			}
-		p=(unsigned char *)buf->data;
-		op=p;
 
-		/* First load the header */
-		if ((ah=d2i_ASN1_HEADER(NULL,&p,(long)size)) == NULL)
-			goto end;
-		if ((ah->header == NULL) || (ah->header->data == NULL) ||
-			(strncmp(NETSCAPE_CERT_HDR,(char *)ah->header->data,
-			ah->header->length) != 0))
+		if ((strncmp(NETSCAPE_CERT_HDR,(char *)nx->header->data,
+			nx->header->length) != 0))
 			{
+			NETSCAPE_X509_free(nx);
 			BIO_printf(err,"Error reading header on certificate\n");
 			goto end;
 			}
-		/* header is ok, so now read the object */
-		p=op;
-		ah->meth=X509_asn1_meth();
-		if ((ah=d2i_ASN1_HEADER(&ah,&p,(long)size)) == NULL)
-			goto end;
-		x=(X509 *)ah->data;
-		ah->data=NULL;
+		x=nx->cert;
+		nx->cert = NULL;
+		NETSCAPE_X509_free(nx);
 		}
 	else if (format == FORMAT_PEM)
 		x=PEM_read_bio_X509_AUX(cert,NULL,
@@ -841,9 +852,7 @@
 		BIO_printf(err,"unable to load certificate\n");
 		ERR_print_errors(err);
 		}
-	if (ah != NULL) ASN1_HEADER_free(ah);
 	if (cert != NULL) BIO_free(cert);
-	if (buf != NULL) BUF_MEM_free(buf);
 	return(x);
 	}
 
@@ -881,7 +890,9 @@
 		}
 	if (file == NULL && maybe_stdin)
 		{
+#ifdef _IONBF
 		setvbuf(stdin, NULL, _IONBF, 0);
+#endif
 		BIO_set_fp(key,stdin,BIO_NOCLOSE);
 		}
 	else
@@ -912,6 +923,13 @@
 				&pkey, NULL, NULL))
 			goto end;
 		}
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
+	else if (format == FORMAT_MSBLOB)
+		pkey = b2i_PrivateKey_bio(key);
+	else if (format == FORMAT_PVK)
+		pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback,
+								&cb_data);
+#endif
 	else
 		{
 		BIO_printf(err,"bad input format specified for key file\n");
@@ -958,7 +976,9 @@
 		}
 	if (file == NULL && maybe_stdin)
 		{
+#ifdef _IONBF
 		setvbuf(stdin, NULL, _IONBF, 0);
+#endif
 		BIO_set_fp(key,stdin,BIO_NOCLOSE);
 		}
 	else
@@ -973,6 +993,37 @@
 		{
 		pkey=d2i_PUBKEY_bio(key, NULL);
 		}
+#ifndef OPENSSL_NO_RSA
+	else if (format == FORMAT_ASN1RSA)
+		{
+		RSA *rsa;
+		rsa = d2i_RSAPublicKey_bio(key, NULL);
+		if (rsa)
+			{
+			pkey = EVP_PKEY_new();
+			if (pkey)
+				EVP_PKEY_set1_RSA(pkey, rsa);
+			RSA_free(rsa);
+			}
+		else
+			pkey = NULL;
+		}
+	else if (format == FORMAT_PEMRSA)
+		{
+		RSA *rsa;
+		rsa = PEM_read_bio_RSAPublicKey(key, NULL, 
+			(pem_password_cb *)password_callback, &cb_data);
+		if (rsa)
+			{
+			pkey = EVP_PKEY_new();
+			if (pkey)
+				EVP_PKEY_set1_RSA(pkey, rsa);
+			RSA_free(rsa);
+			}
+		else
+			pkey = NULL;
+		}
+#endif
 	else if (format == FORMAT_PEM)
 		{
 		pkey=PEM_read_bio_PUBKEY(key,NULL,
@@ -982,6 +1033,10 @@
 	else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
 		pkey = load_netscape_key(err, key, file, key_descrip, format);
 #endif
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
+	else if (format == FORMAT_MSBLOB)
+		pkey = b2i_PublicKey_bio(key);
+#endif
 	else
 		{
 		BIO_printf(err,"bad input format specified for key file\n");
@@ -1040,76 +1095,120 @@
 	}
 #endif /* ndef OPENSSL_NO_RC4 */
 
-STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
-	const char *pass, ENGINE *e, const char *cert_descrip)
+static int load_certs_crls(BIO *err, const char *file, int format,
+	const char *pass, ENGINE *e, const char *desc,
+	STACK_OF(X509) **pcerts, STACK_OF(X509_CRL) **pcrls)
 	{
-	BIO *certs;
 	int i;
-	STACK_OF(X509) *othercerts = NULL;
-	STACK_OF(X509_INFO) *allcerts = NULL;
+	BIO *bio;
+	STACK_OF(X509_INFO) *xis = NULL;
 	X509_INFO *xi;
 	PW_CB_DATA cb_data;
+	int rv = 0;
 
 	cb_data.password = pass;
 	cb_data.prompt_info = file;
 
-	if((certs = BIO_new(BIO_s_file())) == NULL)
+	if (format != FORMAT_PEM)
 		{
-		ERR_print_errors(err);
-		goto end;
+		BIO_printf(err,"bad input format specified for %s\n", desc);
+		return 0;
 		}
 
 	if (file == NULL)
-		BIO_set_fp(certs,stdin,BIO_NOCLOSE);
+		bio = BIO_new_fp(stdin,BIO_NOCLOSE);
 	else
+		bio = BIO_new_file(file, "r");
+
+	if (bio == NULL)
 		{
-		if (BIO_read_filename(certs,file) <= 0)
-			{
-			BIO_printf(err, "Error opening %s %s\n",
-				cert_descrip, file);
-			ERR_print_errors(err);
+		BIO_printf(err, "Error opening %s %s\n",
+				desc, file ? file : "stdin");
+		ERR_print_errors(err);
+		return 0;
+		}
+
+	xis = PEM_X509_INFO_read_bio(bio, NULL,
+				(pem_password_cb *)password_callback, &cb_data);
+
+	BIO_free(bio);
+
+	if (pcerts)
+		{
+		*pcerts = sk_X509_new_null();
+		if (!*pcerts)
 			goto end;
+		}
+
+	if (pcrls)
+		{
+		*pcrls = sk_X509_CRL_new_null();
+		if (!*pcrls)
+			goto end;
+		}
+
+	for(i = 0; i < sk_X509_INFO_num(xis); i++)
+		{
+		xi = sk_X509_INFO_value (xis, i);
+		if (xi->x509 && pcerts)
+			{
+			if (!sk_X509_push(*pcerts, xi->x509))
+				goto end;
+			xi->x509 = NULL;
+			}
+		if (xi->crl && pcrls)
+			{
+			if (!sk_X509_CRL_push(*pcrls, xi->crl))
+				goto end;
+			xi->crl = NULL;
 			}
 		}
 
-	if      (format == FORMAT_PEM)
+	if (pcerts && sk_X509_num(*pcerts) > 0)
+		rv = 1;
+
+	if (pcrls && sk_X509_CRL_num(*pcrls) > 0)
+		rv = 1;
+
+	end:
+
+	if (xis)
+		sk_X509_INFO_pop_free(xis, X509_INFO_free);
+
+	if (rv == 0)
 		{
-		othercerts = sk_X509_new_null();
-		if(!othercerts)
+		if (pcerts)
 			{
-			sk_X509_free(othercerts);
-			othercerts = NULL;
-			goto end;
+			sk_X509_pop_free(*pcerts, X509_free);
+			*pcerts = NULL;
 			}
-		allcerts = PEM_X509_INFO_read_bio(certs, NULL,
-				(pem_password_cb *)password_callback, &cb_data);
-		for(i = 0; i < sk_X509_INFO_num(allcerts); i++)
+		if (pcrls)
 			{
-			xi = sk_X509_INFO_value (allcerts, i);
-			if (xi->x509)
-				{
-				sk_X509_push(othercerts, xi->x509);
-				xi->x509 = NULL;
-				}
+			sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
+			*pcrls = NULL;
 			}
-		goto end;
-		}
-	else	{
-		BIO_printf(err,"bad input format specified for %s\n",
-			cert_descrip);
-		goto end;
-		}
-end:
-	if (othercerts == NULL)
-		{
-		BIO_printf(err,"unable to load certificates\n");
+		BIO_printf(err,"unable to load %s\n",
+				pcerts ? "certificates" : "CRLs");
 		ERR_print_errors(err);
 		}
-	if (allcerts) sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
-	if (certs != NULL) BIO_free(certs);
-	return(othercerts);
+	return rv;
 	}
 
+STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
+	const char *pass, ENGINE *e, const char *desc)
+	{
+	STACK_OF(X509) *certs;
+	load_certs_crls(err, file, format, pass, e, desc, &certs, NULL);
+	return certs;
+	}	
+
+STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
+	const char *pass, ENGINE *e, const char *desc)
+	{
+	STACK_OF(X509_CRL) *crls;
+	load_certs_crls(err, file, format, pass, e, desc, NULL, &crls);
+	return crls;
+	}	
 
 #define X509V3_EXT_UNKNOWN_MASK		(0xfL << 16)
 /* Return error for unknown extensions */
@@ -1396,6 +1495,10 @@
 
 int load_config(BIO *err, CONF *cnf)
 	{
+	static int load_config_called = 0;
+	if (load_config_called)
+		return 1;
+	load_config_called = 1;
 	if (!cnf)
 		cnf = config;
 	if (!cnf)
@@ -1429,7 +1532,7 @@
 	return p;
 	}
 
-static unsigned long index_serial_hash(const char **a)
+static unsigned long index_serial_hash(const OPENSSL_CSTRING *a)
 	{
 	const char *n;
 
@@ -1438,7 +1541,7 @@
 	return(lh_strhash(n));
 	}
 
-static int index_serial_cmp(const char **a, const char **b)
+static int index_serial_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
 	{
 	const char *aa,*bb;
 
@@ -1450,17 +1553,16 @@
 static int index_name_qual(char **a)
 	{ return(a[0][0] == 'V'); }
 
-static unsigned long index_name_hash(const char **a)
+static unsigned long index_name_hash(const OPENSSL_CSTRING *a)
 	{ return(lh_strhash(a[DB_name])); }
 
-int index_name_cmp(const char **a, const char **b)
-	{ return(strcmp(a[DB_name],
-	     b[DB_name])); }
+int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
+	{ return(strcmp(a[DB_name], b[DB_name])); }
 
-static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **)
-static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **)
-static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **)
-static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **)
+static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
+static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING)
+static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING)
+static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING)
 
 #undef BSIZE
 #define BSIZE 256
@@ -1588,7 +1690,6 @@
 	{
 	char buf[5][BSIZE];
 	int i,j;
-	struct stat sb;
 
 	i = strlen(serialfile) + strlen(old_suffix);
 	j = strlen(serialfile) + strlen(new_suffix);
@@ -1613,30 +1714,21 @@
 	j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s",
 		serialfile, old_suffix);
 #endif
-	if (stat(serialfile,&sb) < 0)
-		{
-		if (errno != ENOENT 
+#ifdef RL_DEBUG
+	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+		serialfile, buf[1]);
+#endif
+	if (rename(serialfile,buf[1]) < 0 && errno != ENOENT
 #ifdef ENOTDIR
 			&& errno != ENOTDIR
 #endif
-		   )
-			goto err;
-		}
-	else
-		{
-#ifdef RL_DEBUG
-		BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
-			serialfile, buf[1]);
-#endif
-		if (rename(serialfile,buf[1]) < 0)
-			{
+	   )		{
 			BIO_printf(bio_err,
 				"unable to rename %s to %s\n",
 				serialfile, buf[1]);
 			perror("reason");
 			goto err;
 			}
-		}
 #ifdef RL_DEBUG
 	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
 		buf[0],serialfile);
@@ -1703,10 +1795,7 @@
 		goto err;
 		}
 	if ((tmpdb = TXT_DB_read(in,DB_NUMBER)) == NULL)
-		{
-		if (tmpdb != NULL) TXT_DB_free(tmpdb);
 		goto err;
-		}
 
 #ifndef OPENSSL_SYS_VMS
 	BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile);
@@ -1767,8 +1856,8 @@
 int index_index(CA_DB *db)
 	{
 	if (!TXT_DB_create_index(db->db, DB_serial, NULL,
-				LHASH_HASH_FN(index_serial_hash),
-				LHASH_COMP_FN(index_serial_cmp)))
+				LHASH_HASH_FN(index_serial),
+				LHASH_COMP_FN(index_serial)))
 		{
 		BIO_printf(bio_err,
 		  "error creating serial number index:(%ld,%ld,%ld)\n",
@@ -1778,8 +1867,8 @@
 
 	if (db->attributes.unique_subject
 		&& !TXT_DB_create_index(db->db, DB_name, index_name_qual,
-			LHASH_HASH_FN(index_name_hash),
-			LHASH_COMP_FN(index_name_cmp)))
+			LHASH_HASH_FN(index_name),
+			LHASH_COMP_FN(index_name)))
 		{
 		BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
 			db->db->error,db->db->arg1,db->db->arg2);
@@ -1859,7 +1948,6 @@
 	{
 	char buf[5][BSIZE];
 	int i,j;
-	struct stat sb;
 
 	i = strlen(dbfile) + strlen(old_suffix);
 	j = strlen(dbfile) + strlen(new_suffix);
@@ -1903,30 +1991,21 @@
 	j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s",
 		dbfile, old_suffix);
 #endif
-	if (stat(dbfile,&sb) < 0)
-		{
-		if (errno != ENOENT 
-#ifdef ENOTDIR
-			&& errno != ENOTDIR
-#endif
-		   )
-			goto err;
-		}
-	else
-		{
 #ifdef RL_DEBUG
-		BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
-			dbfile, buf[1]);
+	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+		dbfile, buf[1]);
 #endif
-		if (rename(dbfile,buf[1]) < 0)
-			{
+	if (rename(dbfile,buf[1]) < 0 && errno != ENOENT
+#ifdef ENOTDIR
+		&& errno != ENOTDIR
+#endif
+	   )		{
 			BIO_printf(bio_err,
 				"unable to rename %s to %s\n",
 				dbfile, buf[1]);
 			perror("reason");
 			goto err;
 			}
-		}
 #ifdef RL_DEBUG
 	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
 		buf[0],dbfile);
@@ -1940,23 +2019,15 @@
 		rename(buf[1],dbfile);
 		goto err;
 		}
-	if (stat(buf[4],&sb) < 0)
-		{
-		if (errno != ENOENT 
-#ifdef ENOTDIR
-			&& errno != ENOTDIR
-#endif
-		   )
-			goto err;
-		}
-	else
-		{
 #ifdef RL_DEBUG
-		BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
-			buf[4],buf[3]);
+	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
+		buf[4],buf[3]);
 #endif
-		if (rename(buf[4],buf[3]) < 0)
-			{
+	if (rename(buf[4],buf[3]) < 0 && errno != ENOENT
+#ifdef ENOTDIR
+		&& errno != ENOTDIR
+#endif
+	   )		{
 			BIO_printf(bio_err,
 				"unable to rename %s to %s\n",
 				buf[4], buf[3]);
@@ -1965,7 +2036,6 @@
 			rename(buf[1],dbfile);
 			goto err;
 			}
-		}
 #ifdef RL_DEBUG
 	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
 		buf[2],buf[4]);
@@ -2160,52 +2230,13 @@
 	return NULL;
 }
 
-/* This code MUST COME AFTER anything that uses rename() */
-#ifdef OPENSSL_SYS_WIN32
-int WIN32_rename(const char *from, const char *to)
-	{
-#ifndef OPENSSL_SYS_WINCE
-	/* Windows rename gives an error if 'to' exists, so delete it
-	 * first and ignore file not found errror
-	 */
-	if((remove(to) != 0) && (errno != ENOENT))
-		return -1;
-#undef rename
-	return rename(from, to);
-#else
-	/* convert strings to UNICODE */
-	{
-	BOOL result = FALSE;
-	WCHAR* wfrom;
-	WCHAR* wto;
-	int i;
-	wfrom = malloc((strlen(from)+1)*2);
-	wto = malloc((strlen(to)+1)*2);
-	if (wfrom != NULL && wto != NULL)
-		{
-		for (i=0; i<(int)strlen(from)+1; i++)
-			wfrom[i] = (short)from[i];
-		for (i=0; i<(int)strlen(to)+1; i++)
-			wto[i] = (short)to[i];
-		result = MoveFile(wfrom, wto);
-		}
-	if (wfrom != NULL)
-		free(wfrom);
-	if (wto != NULL)
-		free(wto);
-	return result;
-	}
-#endif
-	}
-#endif
-
 int args_verify(char ***pargs, int *pargc,
 			int *badarg, BIO *err, X509_VERIFY_PARAM **pm)
 	{
 	ASN1_OBJECT *otmp = NULL;
 	unsigned long flags = 0;
 	int i;
-	int purpose = 0;
+	int purpose = 0, depth = -1;
 	char **oldargs = *pargs;
 	char *arg = **pargs, *argn = (*pargs)[1];
 	if (!strcmp(arg, "-policy"))
@@ -2245,6 +2276,21 @@
 			}
 		(*pargs)++;
 		}
+	else if (strcmp(arg,"-verify_depth") == 0)
+		{
+		if (!argn)
+			*badarg = 1;
+		else
+			{
+			depth = atoi(argn);
+			if(depth < 0)
+				{
+				BIO_printf(err, "invalid depth\n");
+				*badarg = 1;
+				}
+			}
+		(*pargs)++;
+		}
 	else if (!strcmp(arg, "-ignore_critical"))
 		flags |= X509_V_FLAG_IGNORE_CRITICAL;
 	else if (!strcmp(arg, "-issuer_checks"))
@@ -2257,8 +2303,16 @@
 		flags |= X509_V_FLAG_POLICY_CHECK;
 	else if (!strcmp(arg, "-explicit_policy"))
 		flags |= X509_V_FLAG_EXPLICIT_POLICY;
+	else if (!strcmp(arg, "-inhibit_any"))
+		flags |= X509_V_FLAG_INHIBIT_ANY;
+	else if (!strcmp(arg, "-inhibit_map"))
+		flags |= X509_V_FLAG_INHIBIT_MAP;
 	else if (!strcmp(arg, "-x509_strict"))
 		flags |= X509_V_FLAG_X509_STRICT;
+	else if (!strcmp(arg, "-extended_crl"))
+		flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT;
+	else if (!strcmp(arg, "-use_deltas"))
+		flags |= X509_V_FLAG_USE_DELTAS;
 	else if (!strcmp(arg, "-policy_print"))
 		flags |= X509_V_FLAG_NOTIFY_POLICY;
 	else if (!strcmp(arg, "-check_ss_sig"))
@@ -2288,6 +2342,9 @@
 	if (purpose)
 		X509_VERIFY_PARAM_set_purpose(*pm, purpose);
 
+	if (depth >= 0)
+		X509_VERIFY_PARAM_set_depth(*pm, depth);
+
 	end:
 
 	(*pargs)++;
@@ -2299,6 +2356,61 @@
 
 	}
 
+/* Read whole contents of a BIO into an allocated memory buffer and
+ * return it.
+ */
+
+int bio_to_mem(unsigned char **out, int maxlen, BIO *in)
+	{
+	BIO *mem;
+	int len, ret;
+	unsigned char tbuf[1024];
+	mem = BIO_new(BIO_s_mem());
+	if (!mem)
+		return -1;
+	for(;;)
+		{
+		if ((maxlen != -1) && maxlen < 1024)
+			len = maxlen;
+		else
+			len = 1024;
+		len = BIO_read(in, tbuf, len);
+		if (len <= 0)
+			break;
+		if (BIO_write(mem, tbuf, len) != len)
+			{
+			BIO_free(mem);
+			return -1;
+			}
+		maxlen -= len;
+
+		if (maxlen == 0)
+			break;
+		}
+	ret = BIO_get_mem_data(mem, (char **)out);
+	BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY);
+	BIO_free(mem);
+	return ret;
+	}
+
+int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value)
+	{
+	int rv;
+	char *stmp, *vtmp = NULL;
+	stmp = BUF_strdup(value);
+	if (!stmp)
+		return -1;
+	vtmp = strchr(stmp, ':');
+	if (vtmp)
+		{
+		*vtmp = 0;
+		vtmp++;
+		}
+	rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp);
+	OPENSSL_free(stmp);
+	return rv;
+	}
+
 static void nodes_print(BIO *out, const char *name,
 	STACK_OF(X509_POLICY_NODE) *nodes)
 	{
@@ -2340,7 +2452,7 @@
 		BIO_free(out);
 	}
 
-#ifndef OPENSSL_NO_JPAKE
+#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
 
 static JPAKE_CTX *jpake_init(const char *us, const char *them,
 							 const char *secret)
@@ -2523,17 +2635,14 @@
 	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_puts(out, "JPAKE authentication succeeded, setting PSK\n");
+
+	psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx));
 
 	BIO_pop(bconn);
 	BIO_free(bconn);
+
+	JPAKE_CTX_free(ctx);
 	}
 
 void jpake_server_auth(BIO *out, BIO *conn, const char *secret)
@@ -2555,17 +2664,340 @@
 	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_puts(out, "JPAKE authentication succeeded, setting PSK\n");
+
+	psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx));
 
 	BIO_pop(bconn);
 	BIO_free(bconn);
+
+	JPAKE_CTX_free(ctx);
 	}
 
 #endif
+
+/*
+ * Platform-specific sections
+ */
+#if defined(_WIN32)
+# ifdef fileno
+#  undef fileno
+#  define fileno(a) (int)_fileno(a)
+# endif
+
+# include <windows.h>
+# include <tchar.h>
+
+static int WIN32_rename(const char *from, const char *to)
+	{
+	TCHAR  *tfrom=NULL,*tto;
+	DWORD	err;
+	int	ret=0;
+
+	if (sizeof(TCHAR) == 1)
+		{
+		tfrom = (TCHAR *)from;
+		tto   = (TCHAR *)to;
+		}
+	else	/* UNICODE path */
+		{
+		size_t i,flen=strlen(from)+1,tlen=strlen(to)+1;
+		tfrom = (TCHAR *)malloc(sizeof(TCHAR)*(flen+tlen));
+		if (tfrom==NULL) goto err;
+		tto=tfrom+flen;
+#if !defined(_WIN32_WCE) || _WIN32_WCE>=101
+		if (!MultiByteToWideChar(CP_ACP,0,from,flen,(WCHAR *)tfrom,flen))
+#endif
+			for (i=0;i<flen;i++)	tfrom[i]=(TCHAR)from[i];
+#if !defined(_WIN32_WCE) || _WIN32_WCE>=101
+		if (!MultiByteToWideChar(CP_ACP,0,to,  tlen,(WCHAR *)tto,  tlen))
+#endif
+			for (i=0;i<tlen;i++)	tto[i]  =(TCHAR)to[i];
+		}
+
+	if (MoveFile(tfrom,tto))	goto ok;
+	err=GetLastError();
+	if (err==ERROR_ALREADY_EXISTS || err==ERROR_FILE_EXISTS)
+		{
+		if (DeleteFile(tto) && MoveFile(tfrom,tto))
+			goto ok;
+		err=GetLastError();
+		}
+	if (err==ERROR_FILE_NOT_FOUND || err==ERROR_PATH_NOT_FOUND)
+		errno = ENOENT;
+	else if (err==ERROR_ACCESS_DENIED)
+		errno = EACCES;
+	else
+		errno = EINVAL;	/* we could map more codes... */
+err:
+	ret=-1;
+ok:
+	if (tfrom!=NULL && tfrom!=(TCHAR *)from)	free(tfrom);
+	return ret;
+	}
+#endif
+
+/* app_tminterval section */
+#if defined(_WIN32)
+double app_tminterval(int stop,int usertime)
+	{
+	FILETIME		now;
+	double			ret=0;
+	static ULARGE_INTEGER	tmstart;
+	static int		warning=1;
+#ifdef _WIN32_WINNT
+	static HANDLE		proc=NULL;
+
+	if (proc==NULL)
+		{
+		if (GetVersion() < 0x80000000)
+			proc = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,
+						GetCurrentProcessId());
+		if (proc==NULL) proc = (HANDLE)-1;
+		}
+
+	if (usertime && proc!=(HANDLE)-1)
+		{
+		FILETIME junk;
+		GetProcessTimes(proc,&junk,&junk,&junk,&now);
+		}
+	else
+#endif
+		{
+		SYSTEMTIME systime;
+
+		if (usertime && warning)
+			{
+			BIO_printf(bio_err,"To get meaningful results, run "
+					   "this program on idle system.\n");
+			warning=0;
+			}
+		GetSystemTime(&systime);
+		SystemTimeToFileTime(&systime,&now);
+		}
+
+	if (stop==TM_START)
+		{
+		tmstart.u.LowPart  = now.dwLowDateTime;
+		tmstart.u.HighPart = now.dwHighDateTime;
+		}
+	else	{
+		ULARGE_INTEGER tmstop;
+
+		tmstop.u.LowPart   = now.dwLowDateTime;
+		tmstop.u.HighPart  = now.dwHighDateTime;
+
+		ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart)*1e-7;
+		}
+
+	return (ret);
+	}
+
+#elif defined(OPENSSL_SYS_NETWARE)
+#include <time.h>
+
+double app_tminterval(int stop,int usertime)
+	{
+	double		ret=0;
+	static clock_t	tmstart;
+	static int	warning=1;
+
+	if (usertime && warning)
+		{
+		BIO_printf(bio_err,"To get meaningful results, run "
+				   "this program on idle system.\n");
+		warning=0;
+		}
+
+	if (stop==TM_START)	tmstart = clock();
+	else			ret     = (clock()-tmstart)/(double)CLOCKS_PER_SEC;
+
+	return (ret);
+	}
+
+#elif defined(OPENSSL_SYSTEM_VXWORKS)
+#include <time.h>
+
+double app_tminterval(int stop,int usertime)
+	{
+	double ret=0;
+#ifdef CLOCK_REALTIME
+	static struct timespec	tmstart;
+	struct timespec		now;
+#else
+	static unsigned long	tmstart;
+	unsigned long		now;
+#endif
+	static int warning=1;
+
+	if (usertime && warning)
+		{
+		BIO_printf(bio_err,"To get meaningful results, run "
+				   "this program on idle system.\n");
+		warning=0;
+		}
+
+#ifdef CLOCK_REALTIME
+	clock_gettime(CLOCK_REALTIME,&now);
+	if (stop==TM_START)	tmstart = now;
+	else	ret = ( (now.tv_sec+now.tv_nsec*1e-9)
+			- (tmstart.tv_sec+tmstart.tv_nsec*1e-9) );
+#else
+	now = tickGet();
+	if (stop==TM_START)	tmstart = now;
+	else			ret = (now - tmstart)/(double)sysClkRateGet();
+#endif
+	return (ret);
+	}
+
+#elif defined(OPENSSL_SYSTEM_VMS)
+#include <time.h>
+#include <times.h>
+
+double app_tminterval(int stop,int usertime)
+	{
+	static clock_t	tmstart;
+	double		ret = 0;
+	clock_t		now;
+#ifdef __TMS
+	struct tms	rus;
+
+	now = times(&rus);
+	if (usertime)	now = rus.tms_utime;
+#else
+	if (usertime)
+		now = clock(); /* sum of user and kernel times */
+	else	{
+		struct timeval tv;
+		gettimeofday(&tv,NULL);
+		now = (clock_t)(
+			(unsigned long long)tv.tv_sec*CLK_TCK +
+			(unsigned long long)tv.tv_usec*(1000000/CLK_TCK)
+			);
+		}
+#endif
+	if (stop==TM_START)	tmstart = now;
+	else			ret = (now - tmstart)/(double)(CLK_TCK);
+
+	return (ret);
+	}
+
+#elif defined(_SC_CLK_TCK)	/* by means of unistd.h */
+#include <sys/times.h>
+
+double app_tminterval(int stop,int usertime)
+	{
+	double		ret = 0;
+	struct tms	rus;
+	clock_t		now = times(&rus);
+	static clock_t	tmstart;
+
+	if (usertime)		now = rus.tms_utime;
+
+	if (stop==TM_START)	tmstart = now;
+	else
+		{
+		long int tck = sysconf(_SC_CLK_TCK);
+		ret = (now - tmstart)/(double)tck;
+		}
+
+	return (ret);
+	}
+
+#else
+#include <sys/time.h>
+#include <sys/resource.h>
+
+double app_tminterval(int stop,int usertime)
+	{
+	double		ret = 0;
+	struct rusage	rus;
+	struct timeval	now;
+	static struct timeval tmstart;
+
+	if (usertime)		getrusage(RUSAGE_SELF,&rus), now = rus.ru_utime;
+	else			gettimeofday(&now,NULL);
+
+	if (stop==TM_START)	tmstart = now;
+	else			ret = ( (now.tv_sec+now.tv_usec*1e-6)
+					- (tmstart.tv_sec+tmstart.tv_usec*1e-6) );
+
+	return ret;
+	}
+#endif
+
+/* app_isdir section */
+#ifdef _WIN32
+int app_isdir(const char *name)
+	{
+	HANDLE		hList;
+	WIN32_FIND_DATA	FileData;
+#if defined(UNICODE) || defined(_UNICODE)
+	size_t i, len_0 = strlen(name)+1;
+
+	if (len_0 > sizeof(FileData.cFileName)/sizeof(FileData.cFileName[0]))
+		return -1;
+
+#if !defined(_WIN32_WCE) || _WIN32_WCE>=101
+	if (!MultiByteToWideChar(CP_ACP,0,name,len_0,FileData.cFileName,len_0))
+#endif
+		for (i=0;i<len_0;i++)
+			FileData.cFileName[i] = (WCHAR)name[i];
+
+	hList = FindFirstFile(FileData.cFileName,&FileData);
+#else
+	hList = FindFirstFile(name,&FileData);
+#endif
+	if (hList == INVALID_HANDLE_VALUE)	return -1;
+	FindClose(hList);
+	return ((FileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0);
+	}
+#else
+#include <sys/stat.h>
+#ifndef S_ISDIR
+# if defined(_S_IFMT) && defined(_S_IFDIR)
+#  define S_ISDIR(a)   (((a) & _S_IFMT) == _S_IFDIR)
+# else 
+#  define S_ISDIR(a)   (((a) & S_IFMT) == S_IFDIR)
+# endif 
+#endif 
+
+int app_isdir(const char *name)
+	{
+#if defined(S_ISDIR)
+	struct stat st;
+
+	if (stat(name,&st)==0)	return S_ISDIR(st.st_mode);
+	else			return -1;
+#else
+	return -1;
+#endif
+	}
+#endif
+
+/* raw_read|write section */
+#if defined(_WIN32) && defined(STD_INPUT_HANDLE)
+int raw_read_stdin(void *buf,int siz)
+	{
+	DWORD n;
+	if (ReadFile(GetStdHandle(STD_INPUT_HANDLE),buf,siz,&n,NULL))
+		return (n);
+	else	return (-1);
+	}
+#else
+int raw_read_stdin(void *buf,int siz)
+	{	return read(fileno(stdin),buf,siz);	}
+#endif
+
+#if defined(_WIN32) && defined(STD_OUTPUT_HANDLE)
+int raw_write_stdout(const void *buf,int siz)
+	{
+	DWORD n;
+	if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),buf,siz,&n,NULL))
+		return (n);
+	else	return (-1);
+	}
+#else
+int raw_write_stdout(const void *buf,int siz)
+	{	return write(fileno(stdout),buf,siz);	}
+#endif
diff --git a/apps/apps.h b/apps/apps.h
index 8857909..596a39a 100644
--- a/apps/apps.h
+++ b/apps/apps.h
@@ -137,11 +137,6 @@
                                        * (see e_os.h).  The string is
                                        * destroyed! */
 
-#ifdef OPENSSL_SYS_WIN32
-#define rename(from,to) WIN32_rename((from),(to))
-int WIN32_rename(const char *oldname,const char *newname);
-#endif
-
 #ifndef MONOLITH
 
 #define MAIN(a,v)	main(a,v)
@@ -149,11 +144,9 @@
 #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
@@ -162,7 +155,6 @@
 extern CONF *config;
 extern char *default_config_file;
 extern BIO *bio_err;
-extern int in_FIPS_mode;
 
 #endif
 
@@ -176,61 +168,37 @@
 #define do_pipe_sig()
 #endif
 
+#ifdef OPENSSL_NO_COMP
+#define zlib_cleanup() 
+#else
+#define zlib_cleanup() COMP_zlib_cleanup()
+#endif
+
 #if defined(MONOLITH) && !defined(OPENSSL_C)
 #  define apps_startup() \
 		do_pipe_sig()
 #  define apps_shutdown()
 #else
 #  ifndef OPENSSL_NO_ENGINE
-#    if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WIN16) || \
-     defined(OPENSSL_SYS_WIN32)
-#      ifdef _O_BINARY
-#        define apps_startup() \
-			do { _fmode=_O_BINARY; do_pipe_sig(); CRYPTO_malloc_init(); \
+#    define apps_startup() \
+			do { do_pipe_sig(); CRYPTO_malloc_init(); \
 			ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); \
 			ENGINE_load_builtin_engines(); setup_ui_method(); } while(0)
-#      else
-#        define apps_startup() \
-			do { _fmode=O_BINARY; do_pipe_sig(); CRYPTO_malloc_init(); \
-			ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); \
-			ENGINE_load_builtin_engines(); setup_ui_method(); } while(0)
-#      endif
-#    else
-#      define apps_startup() \
-			do { do_pipe_sig(); OpenSSL_add_all_algorithms(); \
-			ERR_load_crypto_strings(); ENGINE_load_builtin_engines(); \
-			setup_ui_method(); } while(0)
-#    endif
 #    define apps_shutdown() \
 			do { CONF_modules_unload(1); destroy_ui_method(); \
-			EVP_cleanup(); ENGINE_cleanup(); \
-			CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); \
-			ERR_free_strings(); } while(0)
+			OBJ_cleanup(); EVP_cleanup(); ENGINE_cleanup(); \
+			CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); \
+			ERR_free_strings(); zlib_cleanup();} while(0)
 #  else
-#    if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WIN16) || \
-     defined(OPENSSL_SYS_WIN32)
-#      ifdef _O_BINARY
-#        define apps_startup() \
-			do { _fmode=_O_BINARY; do_pipe_sig(); CRYPTO_malloc_init(); \
+#    define apps_startup() \
+			do { do_pipe_sig(); CRYPTO_malloc_init(); \
 			ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); \
 			setup_ui_method(); } while(0)
-#      else
-#        define apps_startup() \
-			do { _fmode=O_BINARY; do_pipe_sig(); CRYPTO_malloc_init(); \
-			ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); \
-			setup_ui_method(); } while(0)
-#      endif
-#    else
-#      define apps_startup() \
-			do { do_pipe_sig(); OpenSSL_add_all_algorithms(); \
-			ERR_load_crypto_strings(); \
-			setup_ui_method(); } while(0)
-#    endif
 #    define apps_shutdown() \
 			do { CONF_modules_unload(1); destroy_ui_method(); \
-			EVP_cleanup(); \
-			CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); \
-			ERR_free_strings(); } while(0)
+			OBJ_cleanup(); EVP_cleanup(); \
+			CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); \
+			ERR_free_strings(); zlib_cleanup(); } while(0)
 #  endif
 #endif
 
@@ -240,6 +208,7 @@
 #  define openssl_fdset(a,b) FD_SET(a, b)
 #endif
 
+
 typedef struct args_st
 	{
 	char **data;
@@ -282,6 +251,8 @@
 	const char *pass, ENGINE *e, const char *key_descrip);
 STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
 	const char *pass, ENGINE *e, const char *cert_descrip);
+STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
+	const char *pass, ENGINE *e, const char *cert_descrip);
 X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath);
 #ifndef OPENSSL_NO_ENGINE
 ENGINE *setup_engine(BIO *err, const char *engine, int debug);
@@ -290,6 +261,7 @@
 #ifndef OPENSSL_NO_OCSP
 OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
 			char *host, char *path, char *port, int use_ssl,
+			STACK_OF(CONF_VALUE) *headers,
 			int req_timeout);
 #endif
 
@@ -331,13 +303,23 @@
 int save_index(const char *dbfile, const char *suffix, CA_DB *db);
 int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix);
 void free_index(CA_DB *db);
-int index_name_cmp(const char **a, const char **b);
+#define index_name_cmp_noconst(a, b) \
+	index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \
+	(const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b))
+int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b);
 int parse_yesno(const char *str, int def);
 
 X509_NAME *parse_name(char *str, long chtype, int multirdn);
 int args_verify(char ***pargs, int *pargc,
 			int *badarg, BIO *err, X509_VERIFY_PARAM **pm);
 void policies_print(BIO *out, X509_STORE_CTX *ctx);
+int bio_to_mem(unsigned char **out, int maxlen, BIO *in);
+int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value);
+int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
+			const char *algname, ENGINE *e, int do_param);
+#ifndef OPENSSL_NO_PSK
+extern char *psk_key;
+#endif
 #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);
@@ -353,6 +335,10 @@
 #define FORMAT_ENGINE   7
 #define FORMAT_IISSGC	8	/* XXX this stupid macro helps us to avoid
 				 * adding yet another param to load_*key() */
+#define FORMAT_PEMRSA	9	/* PEM RSAPubicKey format */
+#define FORMAT_ASN1RSA	10	/* DER RSAPubicKey format */
+#define FORMAT_MSBLOB	11	/* MS Key blob format */
+#define FORMAT_PVK	12	/* MS PVK file format */
 
 #define EXT_COPY_NONE	0
 #define EXT_COPY_ADD	1
@@ -364,4 +350,11 @@
 
 #define SERIAL_RAND_BITS	64
 
+int app_isdir(const char *);
+int raw_read_stdin(void *,int);
+int raw_write_stdout(const void *,int);
+
+#define TM_START	0
+#define TM_STOP		1
+double app_tminterval (int stop,int usertime);
 #endif
diff --git a/apps/asn1pars.c b/apps/asn1pars.c
index bde61d0..b5d65e7 100644
--- a/apps/asn1pars.c
+++ b/apps/asn1pars.c
@@ -96,7 +96,7 @@
 	unsigned char *tmpbuf;
 	const unsigned char *ctmpbuf;
 	BUF_MEM *buf=NULL;
-	STACK *osk=NULL;
+	STACK_OF(OPENSSL_STRING) *osk=NULL;
 	ASN1_TYPE *at=NULL;
 
 	informat=FORMAT_PEM;
@@ -113,7 +113,7 @@
 	prog=argv[0];
 	argc--;
 	argv++;
-	if ((osk=sk_new_null()) == NULL)
+	if ((osk=sk_OPENSSL_STRING_new_null()) == NULL)
 		{
 		BIO_printf(bio_err,"Memory allocation failure\n");
 		goto end;
@@ -169,7 +169,7 @@
 		else if (strcmp(*argv,"-strparse") == 0)
 			{
 			if (--argc < 1) goto bad;
-			sk_push(osk,*(++argv));
+			sk_OPENSSL_STRING_push(osk,*(++argv));
 			}
 		else if (strcmp(*argv,"-genstr") == 0)
 			{
@@ -302,18 +302,18 @@
 
 	/* If any structs to parse go through in sequence */
 
-	if (sk_num(osk))
+	if (sk_OPENSSL_STRING_num(osk))
 		{
 		tmpbuf=(unsigned char *)str;
 		tmplen=num;
-		for (i=0; i<sk_num(osk); i++)
+		for (i=0; i<sk_OPENSSL_STRING_num(osk); i++)
 			{
 			ASN1_TYPE *atmp;
 			int typ;
-			j=atoi(sk_value(osk,i));
+			j=atoi(sk_OPENSSL_STRING_value(osk,i));
 			if (j == 0)
 				{
-				BIO_printf(bio_err,"'%s' is an invalid number\n",sk_value(osk,i));
+				BIO_printf(bio_err,"'%s' is an invalid number\n",sk_OPENSSL_STRING_value(osk,i));
 				continue;
 				}
 			tmpbuf+=j;
@@ -378,7 +378,7 @@
 		ERR_print_errors(bio_err);
 	if (buf != NULL) BUF_MEM_free(buf);
 	if (at != NULL) ASN1_TYPE_free(at);
-	if (osk != NULL) sk_free(osk);
+	if (osk != NULL) sk_OPENSSL_STRING_free(osk);
 	OBJ_cleanup();
 	apps_shutdown();
 	OPENSSL_EXIT(ret);
diff --git a/apps/ca.c b/apps/ca.c
index 651c5a6..6b8b0ef 100644
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -63,7 +63,6 @@
 #include <string.h>
 #include <ctype.h>
 #include <sys/types.h>
-#include <sys/stat.h>
 #include <openssl/conf.h>
 #include <openssl/bio.h>
 #include <openssl/err.h>
@@ -83,7 +82,7 @@
 #    else
 #      include <unixlib.h>
 #    endif
-#  elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_NETWARE) && !defined(__TANDEM)
+#  elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_NETWARE)
 #    include <sys/file.h>
 #  endif
 #endif
@@ -258,6 +257,7 @@
 	int doupdatedb=0;
 	long crldays=0;
 	long crlhours=0;
+	long crlsec=0;
 	long errorline= -1;
 	char *configfile=NULL;
 	char *md=NULL;
@@ -305,7 +305,8 @@
 	ASN1_TIME *tmptm;
 	ASN1_INTEGER *tmpser;
 	char *f;
-	const char *p, **pp;
+	const char *p;
+	char * const *pp;
 	int i,j;
 	const EVP_MD *dgst=NULL;
 	STACK_OF(CONF_VALUE) *attribs=NULL;
@@ -456,6 +457,11 @@
 			if (--argc < 1) goto bad;
 			crlhours= atol(*(++argv));
 			}
+		else if (strcmp(*argv,"-crlsec") == 0)
+			{
+			if (--argc < 1) goto bad;
+			crlsec = atol(*(++argv));
+			}
 		else if (strcmp(*argv,"-infiles") == 0)
 			{
 			argc--;
@@ -549,8 +555,10 @@
 
 	if (badops)
 		{
-		for (pp=ca_usage; (*pp != NULL); pp++)
-			BIO_printf(bio_err,"%s",*pp);
+		const char **pp2;
+
+		for (pp2=ca_usage; (*pp2 != NULL); pp2++)
+			BIO_printf(bio_err,"%s",*pp2);
 		goto err;
 		}
 
@@ -825,7 +833,6 @@
 	/* lookup where to write new certificates */
 	if ((outdir == NULL) && (req))
 		{
-		struct stat sb;
 
 		if ((outdir=NCONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
 			== NULL)
@@ -844,28 +851,24 @@
 	       that to access().  However, time's too short to do that just
 	       now.
 	    */
+#ifndef _WIN32
 		if (access(outdir,R_OK|W_OK|X_OK) != 0)
+#else
+		if (_access(outdir,R_OK|W_OK|X_OK) != 0)
+#endif
 			{
 			BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir);
 			perror(outdir);
 			goto err;
 			}
 
-		if (stat(outdir,&sb) != 0)
-			{
-			BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
-			perror(outdir);
-			goto err;
-			}
-#ifdef S_ISDIR
-		if (!S_ISDIR(sb.st_mode))
+		if (app_isdir(outdir)<=0)
 			{
 			BIO_printf(bio_err,"%s need to be a directory\n",outdir);
 			perror(outdir);
 			goto err;
 			}
 #endif
-#endif
 		}
 
 	/*****************************************************************/
@@ -879,9 +882,9 @@
 	if (db == NULL) goto err;
 
 	/* Lets check some fields */
-	for (i=0; i<sk_num(db->db->data); i++)
+	for (i=0; i<sk_OPENSSL_PSTRING_num(db->db->data); i++)
 		{
-		pp=(const char **)sk_value(db->db->data,i);
+		pp=sk_OPENSSL_PSTRING_value(db->db->data,i);
 		if ((pp[DB_type][0] != DB_TYPE_REV) &&
 			(pp[DB_rev_date][0] != '\0'))
 			{
@@ -894,7 +897,7 @@
 			BIO_printf(bio_err," in entry %d\n", i+1);
 			goto err;
 			}
-		if (!check_time_format(pp[DB_exp_date]))
+		if (!check_time_format((char *)pp[DB_exp_date]))
 			{
 			BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
 			goto err;
@@ -934,7 +937,7 @@
 #endif
 		TXT_DB_write(out,db->db);
 		BIO_printf(bio_err,"%d entries loaded from the database\n",
-			db->db->data->num);
+			   sk_OPENSSL_PSTRING_num(db->db->data));
 		BIO_printf(bio_err,"generating index\n");
 		}
 	
@@ -1025,6 +1028,17 @@
 		goto err;
 		}
 
+	if (!strcmp(md, "default"))
+		{
+		int def_nid;
+		if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
+			{
+			BIO_puts(bio_err,"no default digest\n");
+			goto err;
+			}
+		md = (char *)OBJ_nid2sn(def_nid);
+		}
+
 	if ((dgst=EVP_get_digestbyname(md)) == NULL)
 		{
 		BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
@@ -1094,9 +1108,9 @@
 			if (startdate == NULL)
 				ERR_clear_error();
 			}
-		if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
+		if (startdate && !ASN1_TIME_set_string(NULL, startdate))
 			{
-			BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n");
+			BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
 			goto err;
 			}
 		if (startdate == NULL) startdate="today";
@@ -1108,9 +1122,9 @@
 			if (enddate == NULL)
 				ERR_clear_error();
 			}
-		if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
+		if (enddate && !ASN1_TIME_set_string(NULL, enddate))
 			{
-			BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
+			BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
 			goto err;
 			}
 
@@ -1370,7 +1384,7 @@
 				goto err;
 				}
 
-		if (!crldays && !crlhours)
+		if (!crldays && !crlhours && !crlsec)
 			{
 			if (!NCONF_get_number(conf,section,
 				ENV_DEFAULT_CRL_DAYS, &crldays))
@@ -1379,7 +1393,7 @@
 				ENV_DEFAULT_CRL_HOURS, &crlhours))
 				crlhours = 0;
 			}
-		if ((crldays == 0) && (crlhours == 0))
+		if ((crldays == 0) && (crlhours == 0) && (crlsec == 0))
 			{
 			BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n");
 			goto err;
@@ -1393,14 +1407,19 @@
 		if (!tmptm) goto err;
 		X509_gmtime_adj(tmptm,0);
 		X509_CRL_set_lastUpdate(crl, tmptm);	
-		X509_gmtime_adj(tmptm,(crldays*24+crlhours)*60*60);
+		if (!X509_time_adj_ex(tmptm, crldays, crlhours*60*60 + crlsec,
+			NULL))
+			{
+			BIO_puts(bio_err, "error setting CRL nextUpdate\n");
+			goto err;
+			}
 		X509_CRL_set_nextUpdate(crl, tmptm);	
 
 		ASN1_TIME_free(tmptm);
 
-		for (i=0; i<sk_num(db->db->data); i++)
+		for (i=0; i<sk_OPENSSL_PSTRING_num(db->db->data); i++)
 			{
-			pp=(const char **)sk_value(db->db->data,i);
+			pp=sk_OPENSSL_PSTRING_value(db->db->data,i);
 			if (pp[DB_type][0] == DB_TYPE_REV)
 				{
 				if ((r=X509_REVOKED_new()) == NULL) goto err;
@@ -1426,15 +1445,6 @@
 
 		/* we now have a CRL */
 		if (verbose) BIO_printf(bio_err,"signing CRL\n");
-#ifndef OPENSSL_NO_DSA
-		if (pkey->type == EVP_PKEY_DSA) 
-			dgst=EVP_dss1();
-		else
-#endif
-#ifndef OPENSSL_NO_ECDSA
-		if (pkey->type == EVP_PKEY_EC)
-			dgst=EVP_ecdsa();
-#endif
 
 		/* Add any extensions asked for */
 
@@ -1467,6 +1477,12 @@
 		if (crlnumberfile != NULL)	/* we have a CRL number that need updating */
 			if (!save_serial(crlnumberfile,"new",crlnumber,NULL)) goto err;
 
+		if (crlnumber)
+			{
+			BN_free(crlnumber);
+			crlnumber = NULL;
+			}
+
 		if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
 
 		PEM_write_bio_X509_CRL(Sout,crl);
@@ -1519,6 +1535,7 @@
 	if (free_key && key)
 		OPENSSL_free(key);
 	BN_free(serial);
+	BN_free(crlnumber);
 	free_index(db);
 	EVP_PKEY_free(pkey);
 	if (x509) X509_free(x509);
@@ -1677,7 +1694,9 @@
 	int ok= -1,i,j,last,nid;
 	const char *p;
 	CONF_VALUE *cv;
-	char *row[DB_NUMBER],**rrow=NULL,**irow=NULL;
+	OPENSSL_STRING row[DB_NUMBER];
+	OPENSSL_STRING *irow=NULL;
+	OPENSSL_STRING *rrow=NULL;
 	char buf[25];
 
 	tmptm=ASN1_UTCTIME_new();
@@ -1919,7 +1938,9 @@
 
 	if (db->attributes.unique_subject)
 		{
-		rrow=TXT_DB_get_by_index(db->db,DB_name,row);
+		OPENSSL_STRING *crow=row;
+
+		rrow=TXT_DB_get_by_index(db->db,DB_name,crow);
 		if (rrow != NULL)
 			{
 			BIO_printf(bio_err,
@@ -1995,11 +2016,11 @@
 
 	if (strcmp(startdate,"today") == 0)
 		X509_gmtime_adj(X509_get_notBefore(ret),0);
-	else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
+	else ASN1_TIME_set_string(X509_get_notBefore(ret),startdate);
 
 	if (enddate == NULL)
-		X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
-	else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
+		X509_time_adj_ex(X509_get_notAfter(ret),days, 0, NULL);
+	else ASN1_TIME_set_string(X509_get_notAfter(ret),enddate);
 
 	if (!X509_set_subject_name(ret,subject)) goto err;
 
@@ -2119,25 +2140,11 @@
 			}
 		}
 
-
-#ifndef OPENSSL_NO_DSA
-	if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1();
 	pktmp=X509_get_pubkey(ret);
 	if (EVP_PKEY_missing_parameters(pktmp) &&
 		!EVP_PKEY_missing_parameters(pkey))
 		EVP_PKEY_copy_parameters(pktmp,pkey);
 	EVP_PKEY_free(pktmp);
-#endif
-#ifndef OPENSSL_NO_ECDSA
-	if (pkey->type == EVP_PKEY_EC)
-		dgst = EVP_ecdsa();
-	pktmp = X509_get_pubkey(ret);
-	if (EVP_PKEY_missing_parameters(pktmp) &&
-		!EVP_PKEY_missing_parameters(pkey))
-		EVP_PKEY_copy_parameters(pktmp, pkey);
-	EVP_PKEY_free(pktmp);
-#endif
-
 
 	if (!X509_sign(ret,pkey,dgst))
 		goto err;
@@ -2239,7 +2246,7 @@
 	     unsigned long nameopt, int default_op, int ext_copy)
 	{
 	STACK_OF(CONF_VALUE) *sk=NULL;
-	LHASH *parms=NULL;
+	LHASH_OF(CONF_VALUE) *parms=NULL;
 	X509_REQ *req=NULL;
 	CONF_VALUE *cv=NULL;
 	NETSCAPE_SPKI *spki = NULL;
@@ -2373,15 +2380,7 @@
 
 static int check_time_format(const char *str)
 	{
-	ASN1_TIME tm;
-
-	tm.data=(unsigned char *)str;
-	tm.length=strlen(str);
-	tm.type=V_ASN1_UTCTIME;
-	if (ASN1_TIME_check(&tm))
-		return 1;
-	tm.type=V_ASN1_GENERALIZEDTIME;
-	return ASN1_TIME_check(&tm);
+	return ASN1_TIME_set_string(NULL, str);
 	}
 
 static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
@@ -2396,6 +2395,8 @@
 		row[i]=NULL;
 	row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
 	bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
+	if (!bn)
+		goto err;
 	if (BN_is_zero(bn))
 		row[DB_serial]=BUF_strdup("00");
 	else
@@ -2465,7 +2466,7 @@
 		goto err;
 
 		}
-	else if (index_name_cmp((const char **)row,(const char **)rrow))
+	else if (index_name_cmp_noconst(row, rrow))
 		{
 		BIO_printf(bio_err,"ERROR:name does not match %s\n",
 			   row[DB_name]);
@@ -2614,9 +2615,9 @@
 	else
 		a_y2k = 0;
 
-	for (i = 0; i < sk_num(db->db->data); i++)
+	for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
 		{
-		rrow = (char **) sk_value(db->db->data, i);
+		rrow = sk_OPENSSL_PSTRING_value(db->db->data, i);
 
 		if (rrow[DB_type][0] == 'V')
 		 	{
@@ -2863,22 +2864,13 @@
 	p=(char *)str->data;
 	for (j=str->length; j>0; j--)
 		{
-#ifdef CHARSET_EBCDIC
-		if ((*p >= 0x20) && (*p <= 0x7e))
-			BIO_printf(bp,"%c",os_toebcdic[*p]);
-#else
 		if ((*p >= ' ') && (*p <= '~'))
 			BIO_printf(bp,"%c",*p);
-#endif
 		else if (*p & 0x80)
 			BIO_printf(bp,"\\0x%02X",*p);
 		else if ((unsigned char)*p == 0xf7)
 			BIO_printf(bp,"^?");
-#ifdef CHARSET_EBCDIC
-		else	BIO_printf(bp,"^%c",os_toebcdic[*p+0x40]);
-#else
 		else	BIO_printf(bp,"^%c",*p+'@');
-#endif
 		p++;
 		}
 	BIO_printf(bp,"'\n");
diff --git a/apps/ciphers.c b/apps/ciphers.c
index 43f0ac5..3d4c60d 100644
--- a/apps/ciphers.c
+++ b/apps/ciphers.c
@@ -71,7 +71,8 @@
 
 static const char *ciphers_usage[]={
 "usage: ciphers args\n",
-" -v          - verbose mode, a textual listing of the ciphers in SSLeay\n",
+" -v          - verbose mode, a textual listing of the SSL/TLS ciphers in OpenSSL\n",
+" -V          - even more verbose\n",
 " -ssl2       - SSL2 mode\n",
 " -ssl3       - SSL3 mode\n",
 " -tls1       - TLS1 mode\n",
@@ -83,14 +84,14 @@
 int MAIN(int argc, char **argv)
 	{
 	int ret=1,i;
-	int verbose=0;
+	int verbose=0,Verbose=0;
 	const char **pp;
 	const char *p;
 	int badops=0;
 	SSL_CTX *ctx=NULL;
 	SSL *ssl=NULL;
 	char *ciphers=NULL;
-	SSL_METHOD *meth=NULL;
+	const SSL_METHOD *meth=NULL;
 	STACK_OF(SSL_CIPHER) *sk;
 	char buf[512];
 	BIO *STDout=NULL;
@@ -114,6 +115,8 @@
 	STDout = BIO_push(tmpbio, STDout);
 	}
 #endif
+	if (!load_config(bio_err, NULL))
+		goto end;
 
 	argc--;
 	argv++;
@@ -121,6 +124,8 @@
 		{
 		if (strcmp(*argv,"-v") == 0)
 			verbose=1;
+		else if (strcmp(*argv,"-V") == 0)
+			verbose=Verbose=1;
 #ifndef OPENSSL_NO_SSL2
 		else if (strcmp(*argv,"-ssl2") == 0)
 			meth=SSLv2_client_method();
@@ -179,15 +184,33 @@
 			}
 		BIO_printf(STDout,"\n");
 		}
-	else
+	else /* verbose */
 		{
 		sk=SSL_get_ciphers(ssl);
 
 		for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
 			{
-			BIO_puts(STDout,SSL_CIPHER_description(
-				sk_SSL_CIPHER_value(sk,i),
-				buf,sizeof buf));
+			SSL_CIPHER *c;
+
+			c = sk_SSL_CIPHER_value(sk,i);
+			
+			if (Verbose)
+				{
+				unsigned long id = c->id;
+				int id0 = (int)(id >> 24);
+				int id1 = (int)((id >> 16) & 0xffL);
+				int id2 = (int)((id >> 8) & 0xffL);
+				int id3 = (int)(id & 0xffL);
+				
+				if ((id & 0xff000000L) == 0x02000000L)
+					BIO_printf(STDout, "     0x%02X,0x%02X,0x%02X - ", id1, id2, id3); /* SSL2 cipher */
+				else if ((id & 0xff000000L) == 0x03000000L)
+					BIO_printf(STDout, "          0x%02X,0x%02X - ", id2, id3); /* SSL3 cipher */
+				else
+					BIO_printf(STDout, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); /* whatever */
+				}
+
+			BIO_puts(STDout,SSL_CIPHER_description(c,buf,sizeof buf));
 			}
 		}
 
diff --git a/apps/cms.c b/apps/cms.c
index 6d227ac..d29a884 100644
--- a/apps/cms.c
+++ b/apps/cms.c
@@ -71,8 +71,9 @@
 static int save_certs(char *signerfile, STACK_OF(X509) *signers);
 static int cms_cb(int ok, X509_STORE_CTX *ctx);
 static void receipt_request_print(BIO *out, CMS_ContentInfo *cms);
-static CMS_ReceiptRequest *make_receipt_request(STACK *rr_to, int rr_allorfirst,
-								STACK *rr_from);
+static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to,
+						int rr_allorfirst,
+					STACK_OF(OPENSSL_STRING) *rr_from);
 
 #define SMIME_OP	0x10
 #define SMIME_IP	0x20
@@ -94,6 +95,8 @@
 #define SMIME_SIGN_RECEIPT	(15 | SMIME_IP | SMIME_OP)
 #define SMIME_VERIFY_RECEIPT	(16 | SMIME_IP)
 
+int verify_err = 0;
+
 int MAIN(int, char **);
 
 int MAIN(int argc, char **argv)
@@ -105,7 +108,7 @@
 	const char *inmode = "r", *outmode = "w";
 	char *infile = NULL, *outfile = NULL, *rctfile = NULL;
 	char *signerfile = NULL, *recipfile = NULL;
-	STACK *sksigners = NULL, *skkeys = NULL;
+	STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL;
 	char *certfile = NULL, *keyfile = NULL, *contfile=NULL;
 	char *certsoutfile = NULL;
 	const EVP_CIPHER *cipher = NULL;
@@ -116,9 +119,10 @@
 	STACK_OF(X509) *encerts = NULL, *other = NULL;
 	BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
 	int badarg = 0;
-	int flags = CMS_DETACHED;
+	int flags = CMS_DETACHED, noout = 0, print = 0;
+	int verify_retcode = 0;
 	int rr_print = 0, rr_allorfirst = -1;
-	STACK *rr_to = NULL, *rr_from = NULL;
+	STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL;
 	CMS_ReceiptRequest *rr = NULL;
 	char *to = NULL, *from = NULL, *subject = NULL;
 	char *CAfile = NULL, *CApath = NULL;
@@ -166,6 +170,8 @@
 			operation = SMIME_RESIGN;
 		else if (!strcmp (*args, "-verify"))
 			operation = SMIME_VERIFY;
+		else if (!strcmp (*args, "-verify_retcode"))
+			verify_retcode = 1;
 		else if (!strcmp(*args,"-verify_receipt"))
 			{
 			operation = SMIME_VERIFY_RECEIPT;
@@ -252,21 +258,17 @@
 		else if (!strcmp (*args, "-no_attr_verify"))
 				flags |= CMS_NO_ATTR_VERIFY;
 		else if (!strcmp (*args, "-stream"))
-				{
-				args++;
-				continue;
-				}
+				flags |= CMS_STREAM;
 		else if (!strcmp (*args, "-indef"))
-				{
-				args++;
-				continue;
-				}
+				flags |= CMS_STREAM;
 		else if (!strcmp (*args, "-noindef"))
 				flags &= ~CMS_STREAM;
 		else if (!strcmp (*args, "-nooldmime"))
 				flags |= CMS_NOOLDMIMETYPE;
 		else if (!strcmp (*args, "-crlfeol"))
 				flags |= CMS_CRLFEOL;
+		else if (!strcmp (*args, "-noout"))
+				noout = 1;
 		else if (!strcmp (*args, "-receipt_request_print"))
 				rr_print = 1;
 		else if (!strcmp (*args, "-receipt_request_all"))
@@ -279,8 +281,8 @@
 				goto argerr;
 			args++;
 			if (!rr_from)
-				rr_from = sk_new_null();
-			sk_push(rr_from, *args);
+				rr_from = sk_OPENSSL_STRING_new_null();
+			sk_OPENSSL_STRING_push(rr_from, *args);
 			}
 		else if (!strcmp(*args,"-receipt_request_to"))
 			{
@@ -288,9 +290,14 @@
 				goto argerr;
 			args++;
 			if (!rr_to)
-				rr_to = sk_new_null();
-			sk_push(rr_to, *args);
+				rr_to = sk_OPENSSL_STRING_new_null();
+			sk_OPENSSL_STRING_push(rr_to, *args);
 			}
+		else if (!strcmp (*args, "-print"))
+				{
+				noout = 1;
+				print = 1;
+				}
 		else if (!strcmp(*args,"-secretkey"))
 			{
 			long ltmp;
@@ -380,13 +387,13 @@
 			if (signerfile)
 				{
 				if (!sksigners)
-					sksigners = sk_new_null();
-				sk_push(sksigners, signerfile);
+					sksigners = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(sksigners, signerfile);
 				if (!keyfile)
 					keyfile = signerfile;
 				if (!skkeys)
-					skkeys = sk_new_null();
-				sk_push(skkeys, keyfile);
+					skkeys = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(skkeys, keyfile);
 				keyfile = NULL;
 				}
 			signerfile = *++args;
@@ -428,12 +435,12 @@
 					goto argerr;
 					}
 				if (!sksigners)
-					sksigners = sk_new_null();
-				sk_push(sksigners, signerfile);
+					sksigners = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(sksigners, signerfile);
 				signerfile = NULL;
 				if (!skkeys)
-					skkeys = sk_new_null();
-				sk_push(skkeys, keyfile);
+					skkeys = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(skkeys, keyfile);
 				}
 			keyfile = *++args;
 			}
@@ -532,13 +539,13 @@
 		if (signerfile)
 			{
 			if (!sksigners)
-				sksigners = sk_new_null();
-			sk_push(sksigners, signerfile);
+				sksigners = sk_OPENSSL_STRING_new_null();
+			sk_OPENSSL_STRING_push(sksigners, signerfile);
 			if (!skkeys)
-				skkeys = sk_new_null();
+				skkeys = sk_OPENSSL_STRING_new_null();
 			if (!keyfile)
 				keyfile = signerfile;
-			sk_push(skkeys, keyfile);
+			sk_OPENSSL_STRING_push(skkeys, keyfile);
 			}
 		if (!sksigners)
 			{
@@ -697,7 +704,7 @@
 
 		if (secret_key && !secret_keyid)
 			{
-			BIO_printf(bio_err, "No sectre key id\n");
+			BIO_printf(bio_err, "No secret key id\n");
 			goto end;
 			}
 
@@ -873,7 +880,7 @@
 		{
 		if (!(store = setup_verify(bio_err, CAfile, CApath)))
 			goto end;
-		X509_STORE_set_verify_cb_func(store, cms_cb);
+		X509_STORE_set_verify_cb(store, cms_cb);
 		if (vpm)
 			X509_STORE_set1_param(store, vpm);
 		}
@@ -973,11 +980,11 @@
 			}
 		else
 			flags |= CMS_REUSE_DIGEST;
-		for (i = 0; i < sk_num(sksigners); i++)
+		for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++)
 			{
 			CMS_SignerInfo *si;
-			signerfile = sk_value(sksigners, i);
-			keyfile = sk_value(skkeys, i);
+			signerfile = sk_OPENSSL_STRING_value(sksigners, i);
+			keyfile = sk_OPENSSL_STRING_value(skkeys, i);
 			signer = load_cert(bio_err, signerfile,FORMAT_PEM, NULL,
 					e, "signer certificate");
 			if (!signer)
@@ -1075,6 +1082,8 @@
 		else
 			{
 			BIO_printf(bio_err, "Verification failure\n");
+			if (verify_retcode)
+				ret = verify_err + 32;
 			goto end;
 			}
 		if (signerfile)
@@ -1107,7 +1116,12 @@
 		}
 	else
 		{
-		if (outformat == FORMAT_SMIME)
+		if (noout)
+			{
+			if (print)
+				CMS_ContentInfo_print_ctx(out, cms, 0, NULL);
+			}
+		else if (outformat == FORMAT_SMIME)
 			{
 			if (to)
 				BIO_printf(out, "To: %s\n", to);
@@ -1121,9 +1135,9 @@
 				ret = SMIME_write_CMS(out, cms, in, flags);
 			}
 		else if (outformat == FORMAT_PEM) 
-			ret = PEM_write_bio_CMS(out, cms);
+			ret = PEM_write_bio_CMS_stream(out, cms, in, flags);
 		else if (outformat == FORMAT_ASN1) 
-			ret = i2d_CMS_bio(out,cms);
+			ret = i2d_CMS_bio_stream(out,cms, in, flags);
 		else
 			{
 			BIO_printf(bio_err, "Bad output format for CMS file\n");
@@ -1146,9 +1160,9 @@
 	if (vpm)
 		X509_VERIFY_PARAM_free(vpm);
 	if (sksigners)
-		sk_free(sksigners);
+		sk_OPENSSL_STRING_free(sksigners);
 	if (skkeys)
-		sk_free(skkeys);
+		sk_OPENSSL_STRING_free(skkeys);
 	if (secret_key)
 		OPENSSL_free(secret_key);
 	if (secret_keyid)
@@ -1158,9 +1172,9 @@
 	if (rr)
 		CMS_ReceiptRequest_free(rr);
 	if (rr_to)
-		sk_free(rr_to);
+		sk_OPENSSL_STRING_free(rr_to);
 	if (rr_from)
-		sk_free(rr_from);
+		sk_OPENSSL_STRING_free(rr_from);
 	X509_STORE_free(store);
 	X509_free(cert);
 	X509_free(recip);
@@ -1199,6 +1213,8 @@
 
 	error = X509_STORE_CTX_get_error(ctx);
 
+	verify_err = error;
+
 	if ((error != X509_V_ERR_NO_EXPLICIT_POLICY)
 		&& ((error != X509_V_OK) || (ok != 2)))
 		return ok;
@@ -1280,7 +1296,7 @@
 		}
 	}
 
-static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK *ns)
+static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK_OF(OPENSSL_STRING) *ns)
 	{
 	int i;
 	STACK_OF(GENERAL_NAMES) *ret;
@@ -1289,12 +1305,10 @@
 	ret = sk_GENERAL_NAMES_new_null();
 	if (!ret)
 		goto err;
-	for (i = 0; i < sk_num(ns); i++)
+	for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++)
 		{
-		CONF_VALUE cnf;
-		cnf.name = "email";
-		cnf.value = sk_value(ns, i);
-		gen = v2i_GENERAL_NAME(NULL, NULL, &cnf);
+		char *str = sk_OPENSSL_STRING_value(ns, i);
+		gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0);
 		if (!gen)
 			goto err;
 		gens = GENERAL_NAMES_new();
@@ -1321,8 +1335,9 @@
 	}
 
 
-static CMS_ReceiptRequest *make_receipt_request(STACK *rr_to, int rr_allorfirst,
-								STACK *rr_from)
+static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to,
+						int rr_allorfirst,
+						STACK_OF(OPENSSL_STRING) *rr_from)
 	{
 	STACK_OF(GENERAL_NAMES) *rct_to, *rct_from;
 	CMS_ReceiptRequest *rr;
diff --git a/apps/crl2p7.c b/apps/crl2p7.c
index b2f2d12..bbc8377 100644
--- a/apps/crl2p7.c
+++ b/apps/crl2p7.c
@@ -63,7 +63,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <sys/types.h>
-#include <sys/stat.h>
 #include "apps.h"
 #include <openssl/err.h>
 #include <openssl/evp.h>
@@ -93,7 +92,7 @@
 	PKCS7 *p7 = NULL;
 	PKCS7_SIGNED *p7s = NULL;
 	X509_CRL *crl=NULL;
-	STACK *certflst=NULL;
+	STACK_OF(OPENSSL_STRING) *certflst=NULL;
 	STACK_OF(X509_CRL) *crl_stack=NULL;
 	STACK_OF(X509) *cert_stack=NULL;
 	int ret=1,nocrl=0;
@@ -141,8 +140,8 @@
 		else if (strcmp(*argv,"-certfile") == 0)
 			{
 			if (--argc < 1) goto bad;
-			if(!certflst) certflst = sk_new_null();
-			sk_push(certflst,*(++argv));
+			if(!certflst) certflst = sk_OPENSSL_STRING_new_null();
+			sk_OPENSSL_STRING_push(certflst,*(++argv));
 			}
 		else
 			{
@@ -227,8 +226,8 @@
 	if ((cert_stack=sk_X509_new_null()) == NULL) goto end;
 	p7s->cert=cert_stack;
 
-	if(certflst) for(i = 0; i < sk_num(certflst); i++) {
-		certfile = sk_value(certflst, i);
+	if(certflst) for(i = 0; i < sk_OPENSSL_STRING_num(certflst); i++) {
+		certfile = sk_OPENSSL_STRING_value(certflst, i);
 		if (add_certs_from_file(cert_stack,certfile) < 0)
 			{
 			BIO_printf(bio_err, "error loading certificates\n");
@@ -237,7 +236,7 @@
 			}
 	}
 
-	sk_free(certflst);
+	sk_OPENSSL_STRING_free(certflst);
 
 	if (outfile == NULL)
 		{
@@ -295,19 +294,12 @@
  */
 static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile)
 	{
-	struct stat st;
 	BIO *in=NULL;
 	int count=0;
 	int ret= -1;
 	STACK_OF(X509_INFO) *sk=NULL;
 	X509_INFO *xi;
 
-	if ((stat(certfile,&st) != 0))
-		{
-		BIO_printf(bio_err,"unable to load the file, %s\n",certfile);
-		goto end;
-		}
-
 	in=BIO_new(BIO_s_file());
 	if ((in == NULL) || (BIO_read_filename(in,certfile) <= 0))
 		{
diff --git a/apps/dgst.c b/apps/dgst.c
index 9ebfc22..9bf38ce 100644
--- a/apps/dgst.c
+++ b/apps/dgst.c
@@ -75,8 +75,29 @@
 #define PROG	dgst_main
 
 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, int non_fips_allow);
+	  EVP_PKEY *key, unsigned char *sigin, int siglen,
+	  const char *sig_name, const char *md_name,
+	  const char *file,BIO *bmd);
+
+static void list_md_fn(const EVP_MD *m,
+			const char *from, const char *to, void *arg)
+	{
+	const char *mname;
+	/* Skip aliases */
+	if (!m)
+		return;
+	mname = OBJ_nid2ln(EVP_MD_type(m));
+	/* Skip shortnames */
+	if (strcmp(from, mname))
+		return;
+	/* Skip clones */
+	if (EVP_MD_flags(m) & EVP_MD_FLAG_PKEY_DIGEST)
+		return;
+	if (strchr(mname, ' '))
+		mname= EVP_MD_name(m);
+	BIO_printf(arg, "-%-14s to use the %s message digest algorithm\n",
+			mname, mname);
+	}
 
 int MAIN(int, char **);
 
@@ -89,7 +110,6 @@
 	BIO *in=NULL,*inp;
 	BIO *bmd=NULL;
 	BIO *out = NULL;
-	const char *name;
 #define PROG_NAME_SIZE  39
 	char pname[PROG_NAME_SIZE+1];
 	int separator=0;
@@ -101,16 +121,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;
+	char *mac_name=NULL;
+	STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL;
 
 	apps_startup();
-ERR_load_crypto_strings();
+
 	if ((buf=(unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL)
 		{
 		BIO_printf(bio_err,"out of memory\n");
@@ -135,6 +155,8 @@
 		if ((*argv)[0] != '-') break;
 		if (strcmp(*argv,"-c") == 0)
 			separator=1;
+		else if (strcmp(*argv,"-r") == 0)
+			separator=2;
 		else if (strcmp(*argv,"-rand") == 0)
 			{
 			if (--argc < 1) break;
@@ -169,27 +191,6 @@
 			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;
@@ -205,6 +206,7 @@
 			{
 			if (--argc < 1) break;
 			engine= *(++argv);
+        		e = setup_engine(bio_err, engine, 0);
 			}
 #endif
 		else if (strcmp(*argv,"-hex") == 0)
@@ -213,16 +215,36 @@
 			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"))
 			{
 			if (--argc < 1)
 				break;
 			hmac_key=*++argv;
 			}
+		else if (!strcmp(*argv,"-mac"))
+			{
+			if (--argc < 1)
+				break;
+			mac_name=*++argv;
+			}
+		else if (strcmp(*argv,"-sigopt") == 0)
+			{
+			if (--argc < 1)
+				break;
+			if (!sigopts)
+				sigopts = sk_OPENSSL_STRING_new_null();
+			if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
+				break;
+			}
+		else if (strcmp(*argv,"-macopt") == 0)
+			{
+			if (--argc < 1)
+				break;
+			if (!macopts)
+				macopts = sk_OPENSSL_STRING_new_null();
+			if (!macopts || !sk_OPENSSL_STRING_push(macopts, *(++argv)))
+				break;
+			}
 		else if ((m=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
 			md=m;
 		else
@@ -231,12 +253,9 @@
 		argv++;
 		}
 
-	if (md == NULL)
-		md=EVP_md5();
 
 	if(do_verify && !sigfile) {
 		BIO_printf(bio_err, "No signature to verify: use the -signature option\n");
-		err = 1; 
 		goto end;
 	}
 
@@ -245,6 +264,7 @@
 		BIO_printf(bio_err,"unknown option '%s'\n",*argv);
 		BIO_printf(bio_err,"options are\n");
 		BIO_printf(bio_err,"-c              to output the digest with separating colons\n");
+		BIO_printf(bio_err,"-r              to output the digest in coreutils format\n");
 		BIO_printf(bio_err,"-d              to output debug info\n");
 		BIO_printf(bio_err,"-hex            output as hex dump\n");
 		BIO_printf(bio_err,"-binary         output in binary form\n");
@@ -252,49 +272,20 @@
 		BIO_printf(bio_err,"-verify file    verify a signature using public key in file\n");
 		BIO_printf(bio_err,"-prverify file  verify a signature using private key in file\n");
 		BIO_printf(bio_err,"-keyform arg    key file format (PEM or ENGINE)\n");
+		BIO_printf(bio_err,"-out filename   output to filename rather than stdout\n");
 		BIO_printf(bio_err,"-signature file signature to verify\n");
-		BIO_printf(bio_err,"-binary         output in binary form\n");
+		BIO_printf(bio_err,"-sigopt nm:v    signature parameter\n");
 		BIO_printf(bio_err,"-hmac key       create hashed MAC with key\n");
+		BIO_printf(bio_err,"-mac algorithm  create MAC (not neccessarily HMAC)\n"); 
+		BIO_printf(bio_err,"-macopt nm:v    MAC algorithm parameters or 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,"-%-14s to use the %s message digest algorithm (default)\n",
-			LN_md5,LN_md5);
-		BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
-			LN_md4,LN_md4);
-		BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
-			LN_md2,LN_md2);
-#ifndef OPENSSL_NO_SHA
-		BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
-			LN_sha1,LN_sha1);
-		BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
-			LN_sha,LN_sha);
-#ifndef OPENSSL_NO_SHA256
-		BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
-			LN_sha224,LN_sha224);
-		BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
-			LN_sha256,LN_sha256);
-#endif
-#ifndef OPENSSL_NO_SHA512
-		BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
-			LN_sha384,LN_sha384);
-		BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
-			LN_sha512,LN_sha512);
-#endif
-#endif
-		BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
-			LN_mdc2,LN_mdc2);
-		BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n",
-			LN_ripemd160,LN_ripemd160);
-		err=1;
+		EVP_MD_do_all_sorted(list_md_fn, bio_err);
 		goto end;
 		}
 
-#ifndef OPENSSL_NO_ENGINE
-        e = setup_engine(bio_err, engine, 0);
-#endif
-
 	in=BIO_new(BIO_s_file());
 	bmd=BIO_new(BIO_f_md());
 	if (debug)
@@ -317,8 +308,10 @@
 		}
 
 	if(out_bin == -1) {
-		if(keyfile) out_bin = 1;
-		else out_bin = 0;
+		if(keyfile)
+			out_bin = 1;
+		else
+			out_bin = 0;
 	}
 
 	if(randfile)
@@ -344,6 +337,11 @@
 		ERR_print_errors(bio_err);
 		goto end;
 	}
+	if ((!!mac_name + !!keyfile + !!hmac_key) > 1)
+		{
+		BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n");
+		goto end;
+		}
 
 	if(keyfile)
 		{
@@ -361,6 +359,101 @@
 			}
 		}
 
+	if (mac_name)
+		{
+		EVP_PKEY_CTX *mac_ctx = NULL;
+		int r = 0;
+		if (!init_gen_str(bio_err, &mac_ctx, mac_name,e, 0))
+			goto mac_end;
+		if (macopts)
+			{
+			char *macopt;
+			for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++)
+				{
+				macopt = sk_OPENSSL_STRING_value(macopts, i);
+				if (pkey_ctrl_string(mac_ctx, macopt) <= 0)
+					{
+					BIO_printf(bio_err,
+						"MAC parameter error \"%s\"\n",
+						macopt);
+					ERR_print_errors(bio_err);
+					goto mac_end;
+					}
+				}
+			}
+		if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0)
+			{
+			BIO_puts(bio_err, "Error generating key\n");
+			ERR_print_errors(bio_err);
+			goto mac_end;
+			}
+		r = 1;
+		mac_end:
+		if (mac_ctx)
+			EVP_PKEY_CTX_free(mac_ctx);
+		if (r == 0)
+			goto end;
+		}
+
+	if (hmac_key)
+		{
+		sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, e,
+					(unsigned char *)hmac_key, -1);
+		if (!sigkey)
+			goto end;
+		}
+
+	if (sigkey)
+		{
+		EVP_MD_CTX *mctx = NULL;
+		EVP_PKEY_CTX *pctx = NULL;
+		int r;
+		if (!BIO_get_md_ctx(bmd, &mctx))
+			{
+			BIO_printf(bio_err, "Error getting context\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		if (do_verify)
+			r = EVP_DigestVerifyInit(mctx, &pctx, md, e, sigkey);
+		else
+			r = EVP_DigestSignInit(mctx, &pctx, md, e, sigkey);
+		if (!r)
+			{
+			BIO_printf(bio_err, "Error setting context\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		if (sigopts)
+			{
+			char *sigopt;
+			for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++)
+				{
+				sigopt = sk_OPENSSL_STRING_value(sigopts, i);
+				if (pkey_ctrl_string(pctx, sigopt) <= 0)
+					{
+					BIO_printf(bio_err,
+						"parameter error \"%s\"\n",
+						sigopt);
+					ERR_print_errors(bio_err);
+					goto end;
+					}
+				}
+			}
+		}
+	/* we use md as a filter, reading from 'in' */
+	else
+		{
+		if (md == NULL)
+			md = EVP_md5(); 
+		if (!BIO_set_md(bmd,md))
+			{
+			BIO_printf(bio_err, "Error setting digest %s\n", pname);
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+
 	if(sigfile && sigkey) {
 		BIO *sigbio;
 		sigbio = BIO_new_file(sigfile, "rb");
@@ -381,67 +474,51 @@
 			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))
-		{
-		BIO_printf(bio_err, "Error setting digest %s\n", pname);
-		ERR_print_errors(bio_err);
-		goto end;
-		}
-		
 	inp=BIO_push(bmd,in);
 
+	if (md == NULL)
+		{
+		EVP_MD_CTX *tctx;
+		BIO_get_md_ctx(bmd, &tctx);
+		md = EVP_MD_CTX_md(tctx);
+		}
+
 	if (argc == 0)
 		{
 		BIO_set_fp(in,stdin,BIO_NOCLOSE);
 		err=do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf,
-			  siglen,"","(stdin)",bmd,hmac_key,non_fips_allow);
+			  siglen,NULL,NULL,"stdin",bmd);
 		}
 	else
 		{
-		name=OBJ_nid2sn(md->type);
+		const char *md_name = NULL, *sig_name = NULL;
+		if(!out_bin)
+			{
+			if (sigkey)
+				{
+				const EVP_PKEY_ASN1_METHOD *ameth;
+				ameth = EVP_PKEY_get0_asn1(sigkey);
+				if (ameth)
+					EVP_PKEY_asn1_get0_info(NULL, NULL,
+						NULL, NULL, &sig_name, ameth);
+				}
+			md_name = EVP_MD_name(md);
+			}
 		err = 0;
 		for (i=0; i<argc; i++)
 			{
-			char *tmp,*tofree=NULL;
 			int r;
-
 			if (BIO_read_filename(in,argv[i]) <= 0)
 				{
 				perror(argv[i]);
 				err++;
 				continue;
 				}
-			if(!out_bin)
-				{
-				size_t len = strlen(name)+strlen(argv[i])+(hmac_key ? 5 : 0)+5;
-				tmp=tofree=OPENSSL_malloc(len);
-				BIO_snprintf(tmp,len,"%s%s(%s)= ",
-							 hmac_key ? "HMAC-" : "",name,argv[i]);
-				}
 			else
-				tmp="";
 			r=do_fp(out,buf,inp,separator,out_bin,sigkey,sigbuf,
-				siglen,tmp,argv[i],bmd,hmac_key,non_fips_allow);
+				siglen,sig_name,md_name, argv[i],bmd);
 			if(r)
 			    err=r;
-			if(tofree)
-				OPENSSL_free(tofree);
 			(void)BIO_reset(bmd);
 			}
 		}
@@ -456,6 +533,10 @@
 		OPENSSL_free(passin);
 	BIO_free_all(out);
 	EVP_PKEY_free(sigkey);
+	if (sigopts)
+		sk_OPENSSL_STRING_free(sigopts);
+	if (macopts)
+		sk_OPENSSL_STRING_free(macopts);
 	if(sigbuf) OPENSSL_free(sigbuf);
 	if (bmd != NULL) BIO_free(bmd);
 	apps_shutdown();
@@ -463,24 +544,13 @@
 	}
 
 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,int non_fips_allow)
+	  EVP_PKEY *key, unsigned char *sigin, int siglen,
+	  const char *sig_name, const char *md_name,
+	  const char *file,BIO *bmd)
 	{
-	unsigned int len;
+	size_t len;
 	int i;
-	EVP_MD_CTX *md_ctx;
-	HMAC_CTX hmac_ctx;
 
-	if (hmac_key)
-		{
-		EVP_MD *md;
-
-		BIO_get_md(bmd,&md);
-		HMAC_CTX_init(&hmac_ctx);
-		HMAC_Init_ex(&hmac_ctx,hmac_key,strlen(hmac_key),md, NULL);
-		BIO_get_md_ctx(bmd,&md_ctx);
-		BIO_set_md_ctx(bmd,&hmac_ctx.md_ctx);
-		}
 	for (;;)
 		{
 		i=BIO_read(bp,(char *)buf,BUFSIZE);
@@ -496,7 +566,7 @@
 		{
 		EVP_MD_CTX *ctx;
 		BIO_get_md_ctx(bp, &ctx);
-		i = EVP_VerifyFinal(ctx, sigin, (unsigned int)siglen, key); 
+		i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int)siglen); 
 		if(i > 0)
 			BIO_printf(out, "Verified OK\n");
 		else if(i == 0)
@@ -516,25 +586,39 @@
 		{
 		EVP_MD_CTX *ctx;
 		BIO_get_md_ctx(bp, &ctx);
-		if(!EVP_SignFinal(ctx, buf, (unsigned int *)&len, key)) 
+		len = BUFSIZE;
+		if(!EVP_DigestSignFinal(ctx, buf, &len)) 
 			{
 			BIO_printf(bio_err, "Error Signing Data\n");
 			ERR_print_errors(bio_err);
 			return 1;
 			}
 		}
-	else if(hmac_key)
-		{
-		HMAC_Final(&hmac_ctx,buf,&len);
-		HMAC_CTX_cleanup(&hmac_ctx);
-		}
 	else
+		{
 		len=BIO_gets(bp,(char *)buf,BUFSIZE);
+		if ((int)len <0)
+			{
+			ERR_print_errors(bio_err);
+			return 1;
+			}
+		}
 
 	if(binout) BIO_write(out, buf, len);
+	else if (sep == 2)
+		{
+		for (i=0; i<(int)len; i++)
+			BIO_printf(out, "%02x",buf[i]);
+		BIO_printf(out, " *%s\n", file);
+		}
 	else 
 		{
-		BIO_write(out,title,strlen(title));
+		if (sig_name)
+			BIO_printf(out, "%s-%s(%s)= ", sig_name, md_name, file);
+		else if (md_name)
+			BIO_printf(out, "%s(%s)= ", md_name, file);
+		else
+			BIO_printf(out, "(%s)= ", file);
 		for (i=0; i<(int)len; i++)
 			{
 			if (sep && (i != 0))
@@ -543,10 +627,6 @@
 			}
 		BIO_printf(out, "\n");
 		}
-	if (hmac_key)
-		{
-		BIO_set_md_ctx(bmd,md_ctx);
-		}
 	return 0;
 	}
 
diff --git a/apps/dh.c b/apps/dh.c
index c4d891e..e9609d6 100644
--- a/apps/dh.c
+++ b/apps/dh.c
@@ -349,4 +349,10 @@
 	apps_shutdown();
 	OPENSSL_EXIT(ret);
 	}
+#else /* !OPENSSL_NO_DH */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
 #endif
diff --git a/apps/dhparam.c b/apps/dhparam.c
index 04bd57c..5fab29e 100644
--- a/apps/dhparam.c
+++ b/apps/dhparam.c
@@ -554,4 +554,10 @@
 	return 1;
 	}
 
+#else /* !OPENSSL_NO_DH */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
 #endif
diff --git a/apps/dsa.c b/apps/dsa.c
index 5e68a56..1109346 100644
--- a/apps/dsa.c
+++ b/apps/dsa.c
@@ -65,11 +65,11 @@
 #include "apps.h"
 #include <openssl/bio.h>
 #include <openssl/err.h>
+#include <openssl/dsa.h>
 #include <openssl/evp.h>
 #include <openssl/x509.h>
 #include <openssl/pem.h>
 #include <openssl/bn.h>
-#include <openssl/dsa.h>
 
 #undef PROG
 #define PROG	dsa_main
@@ -112,6 +112,8 @@
 	char *passin = NULL, *passout = NULL;
 	int modulus=0;
 
+	int pvk_encr = 2;
+
 	apps_startup();
 
 	if (bio_err == NULL)
@@ -171,6 +173,12 @@
 			engine= *(++argv);
 			}
 #endif
+		else if (strcmp(*argv,"-pvk-strong") == 0)
+			pvk_encr=2;
+		else if (strcmp(*argv,"-pvk-weak") == 0)
+			pvk_encr=1;
+		else if (strcmp(*argv,"-pvk-none") == 0)
+			pvk_encr=0;
 		else if (strcmp(*argv,"-noout") == 0)
 			noout=1;
 		else if (strcmp(*argv,"-text") == 0)
@@ -238,16 +246,30 @@
 		goto end;
 	}
 
+	in=BIO_new(BIO_s_file());
 	out=BIO_new(BIO_s_file());
-	if (out == NULL)
+	if ((in == NULL) || (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");
-	{
+
+		{
 		EVP_PKEY	*pkey;
+
 		if (pubin)
 			pkey = load_pubkey(bio_err, infile, informat, 1,
 				passin, e, "Public Key");
@@ -255,10 +277,12 @@
 			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 (pkey)
+			{
+			dsa = EVP_PKEY_get1_DSA(pkey);
+			EVP_PKEY_free(pkey);
+			}
+		}
 	if (dsa == NULL)
 		{
 		BIO_printf(bio_err,"unable to load Key\n");
@@ -310,11 +334,24 @@
 			i=PEM_write_bio_DSA_PUBKEY(out,dsa);
 		else i=PEM_write_bio_DSAPrivateKey(out,dsa,enc,
 							NULL,0,NULL, passout);
+#ifndef OPENSSL_NO_RSA
+	} else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) {
+		EVP_PKEY *pk;
+		pk = EVP_PKEY_new();
+		EVP_PKEY_set1_DSA(pk, dsa);
+		if (outformat == FORMAT_PVK)
+			i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout);
+		else if (pubin || pubout)
+			i = i2b_PublicKey_bio(out, pk);
+		else
+			i = i2b_PrivateKey_bio(out, pk);
+		EVP_PKEY_free(pk);
+#endif
 	} else {
 		BIO_printf(bio_err,"bad output format specified for outfile\n");
 		goto end;
 		}
-	if (!i)
+	if (i <= 0)
 		{
 		BIO_printf(bio_err,"unable to write private key\n");
 		ERR_print_errors(bio_err);
@@ -330,4 +367,10 @@
 	apps_shutdown();
 	OPENSSL_EXIT(ret);
 	}
+#else /* !OPENSSL_NO_DSA */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
 #endif
diff --git a/apps/ec.c b/apps/ec.c
index 771e15f..31194b4 100644
--- a/apps/ec.c
+++ b/apps/ec.c
@@ -400,4 +400,10 @@
 	apps_shutdown();
 	OPENSSL_EXIT(ret);
 }
+#else /* !OPENSSL_NO_EC */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
 #endif
diff --git a/apps/ecparam.c b/apps/ecparam.c
index 4e1fc83..e9aa0a1 100644
--- a/apps/ecparam.c
+++ b/apps/ecparam.c
@@ -725,4 +725,10 @@
 	BIO_printf(out, "\n\t};\n\n");
 	return 1;
 	}
+#else /* !OPENSSL_NO_EC */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
 #endif
diff --git a/apps/enc.c b/apps/enc.c
index 8f5e5b8..3c2c91e 100644
--- a/apps/enc.c
+++ b/apps/enc.c
@@ -67,6 +67,7 @@
 #include <openssl/x509.h>
 #include <openssl/rand.h>
 #include <openssl/pem.h>
+#include <openssl/comp.h>
 #include <ctype.h>
 
 int set_hex(char *in,unsigned char *out,int size);
@@ -116,6 +117,10 @@
 	char *hkey=NULL,*hiv=NULL,*hsalt = NULL;
 	char *md=NULL;
 	int enc=1,printkey=0,i,base64=0;
+#ifdef ZLIB
+	int do_zlib=0;
+	BIO *bzl = NULL;
+#endif
 	int debug=0,olb64=0,nosalt=0;
 	const EVP_CIPHER *cipher=NULL,*c;
 	EVP_CIPHER_CTX *ctx = NULL;
@@ -127,7 +132,6 @@
 	char *engine = NULL;
 #endif
 	const EVP_MD *dgst=NULL;
-	int non_fips_allow = 0;
 
 	apps_startup();
 
@@ -142,9 +146,18 @@
 	program_name(argv[0],pname,sizeof pname);
 	if (strcmp(pname,"base64") == 0)
 		base64=1;
+#ifdef ZLIB
+	if (strcmp(pname,"zlib") == 0)
+		do_zlib=1;
+#endif
 
 	cipher=EVP_get_cipherbyname(pname);
+#ifdef ZLIB
+	if (!do_zlib && !base64 && (cipher == NULL)
+				&& (strcmp(pname,"enc") != 0))
+#else
 	if (!base64 && (cipher == NULL) && (strcmp(pname,"enc") != 0))
+#endif
 		{
 		BIO_printf(bio_err,"%s is an unknown cipher\n",pname);
 		goto bad;
@@ -200,6 +213,10 @@
 			base64=1;
 		else if	(strcmp(*argv,"-base64") == 0)
 			base64=1;
+#ifdef ZLIB
+		else if	(strcmp(*argv,"-z") == 0)
+			do_zlib=1;
+#endif
 		else if (strcmp(*argv,"-bufsize") == 0)
 			{
 			if (--argc < 1) goto bad;
@@ -267,8 +284,6 @@
 			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))
 			{
@@ -291,9 +306,11 @@
 			BIO_printf(bio_err,"%-14s passphrase is the first line of the file argument\n","-kfile");
 			BIO_printf(bio_err,"%-14s the next argument is the md to use to create a key\n","-md");
 			BIO_printf(bio_err,"%-14s   from a passphrase.  One of md2, md5, sha or sha1\n","");
+			BIO_printf(bio_err,"%-14s salt in hex is the next argument\n","-S");
 			BIO_printf(bio_err,"%-14s key/iv in hex is the next argument\n","-K/-iv");
 			BIO_printf(bio_err,"%-14s print the iv/key (then exit if -P)\n","-[pP]");
 			BIO_printf(bio_err,"%-14s buffer size\n","-bufsize <n>");
+			BIO_printf(bio_err,"%-14s disable standard block padding\n","-nopad");
 #ifndef OPENSSL_NO_ENGINE
 			BIO_printf(bio_err,"%-14s use engine e, possibly a hardware device.\n","-engine e");
 #endif
@@ -322,10 +339,7 @@
 
 	if (dgst == NULL)
 		{
-		if (in_FIPS_mode)
-			dgst = EVP_sha1();
-		else
-			dgst = EVP_md5();
+		dgst = EVP_md5();
 		}
 
 	if (bufsize != NULL)
@@ -457,6 +471,19 @@
 	rbio=in;
 	wbio=out;
 
+#ifdef ZLIB
+
+	if (do_zlib)
+		{
+		if ((bzl=BIO_new(BIO_f_zlib())) == NULL)
+			goto end;
+		if (enc)
+			wbio=BIO_push(bzl,wbio);
+		else
+			rbio=BIO_push(bzl,rbio);
+		}
+#endif
+
 	if (base64)
 		{
 		if ((b64=BIO_new(BIO_f_base64())) == NULL)
@@ -561,11 +588,6 @@
 		 */
 
 		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",
@@ -656,6 +678,9 @@
 	if (out != NULL) BIO_free_all(out);
 	if (benc != NULL) BIO_free(benc);
 	if (b64 != NULL) BIO_free(b64);
+#ifdef ZLIB
+	if (bzl != NULL) BIO_free(bzl);
+#endif
 	if(pass) OPENSSL_free(pass);
 	apps_shutdown();
 	OPENSSL_EXIT(ret);
diff --git a/apps/engine.c b/apps/engine.c
index 17bd81f..9a02943 100644
--- a/apps/engine.c
+++ b/apps/engine.c
@@ -92,7 +92,7 @@
 NULL
 };
 
-static void identity(void *ptr)
+static void identity(char *ptr)
 	{
 	return;
 	}
@@ -148,11 +148,6 @@
 
 	if(flags & ENGINE_CMD_FLAG_NUMERIC)
 		{
-		if(started)
-			{
-			BIO_printf(bio_out, "|");
-			err = 1;
-			}
 		BIO_printf(bio_out, "NUMERIC");
 		started = 1;
 		}
@@ -205,7 +200,7 @@
 	char *desc = NULL;
 	int flags;
 	int xpos = 0;
-	STACK *cmds = NULL;
+	STACK_OF(OPENSSL_STRING) *cmds = NULL;
 	if(!ENGINE_ctrl(e, ENGINE_CTRL_HAS_CTRL_FUNCTION, 0, NULL, NULL) ||
 			((num = ENGINE_ctrl(e, ENGINE_CTRL_GET_FIRST_CMD_TYPE,
 					0, NULL, NULL)) <= 0))
@@ -216,7 +211,7 @@
 		return 1;
 		}
 
-	cmds = sk_new_null();
+	cmds = sk_OPENSSL_STRING_new_null();
 
 	if(!cmds)
 		goto err;
@@ -289,15 +284,17 @@
 		BIO_printf(bio_out, "\n");
 	ret = 1;
 err:
-	if(cmds) sk_pop_free(cmds, identity);
+	if(cmds) sk_OPENSSL_STRING_pop_free(cmds, identity);
 	if(name) OPENSSL_free(name);
 	if(desc) OPENSSL_free(desc);
 	return ret;
 	}
 
-static void util_do_cmds(ENGINE *e, STACK *cmds, BIO *bio_out, const char *indent)
+static void util_do_cmds(ENGINE *e, STACK_OF(OPENSSL_STRING) *cmds,
+			BIO *bio_out, const char *indent)
 	{
-	int loop, res, num = sk_num(cmds);
+	int loop, res, num = sk_OPENSSL_STRING_num(cmds);
+
 	if(num < 0)
 		{
 		BIO_printf(bio_out, "[Error]: internal stack error\n");
@@ -307,7 +304,7 @@
 		{
 		char buf[256];
 		const char *cmd, *arg;
-		cmd = sk_value(cmds, loop);
+		cmd = sk_OPENSSL_STRING_value(cmds, loop);
 		res = 1; /* assume success */
 		/* Check if this command has no ":arg" */
 		if((arg = strstr(cmd, ":")) == NULL)
@@ -347,9 +344,9 @@
 	const char **pp;
 	int verbose=0, list_cap=0, test_avail=0, test_avail_noise = 0;
 	ENGINE *e;
-	STACK *engines = sk_new_null();
-	STACK *pre_cmds = sk_new_null();
-	STACK *post_cmds = sk_new_null();
+	STACK_OF(OPENSSL_STRING) *engines = sk_OPENSSL_STRING_new_null();
+	STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null();
+	STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null();
 	int badops=1;
 	BIO *bio_out=NULL;
 	const char *indent = "     ";
@@ -396,20 +393,20 @@
 			argc--; argv++;
 			if (argc == 0)
 				goto skip_arg_loop;
-			sk_push(pre_cmds,*argv);
+			sk_OPENSSL_STRING_push(pre_cmds,*argv);
 			}
 		else if (strcmp(*argv,"-post") == 0)
 			{
 			argc--; argv++;
 			if (argc == 0)
 				goto skip_arg_loop;
-			sk_push(post_cmds,*argv);
+			sk_OPENSSL_STRING_push(post_cmds,*argv);
 			}
 		else if ((strncmp(*argv,"-h",2) == 0) ||
 				(strcmp(*argv,"-?") == 0))
 			goto skip_arg_loop;
 		else
-			sk_push(engines,*argv);
+			sk_OPENSSL_STRING_push(engines,*argv);
 		argc--;
 		argv++;
 		}
@@ -424,17 +421,17 @@
 		goto end;
 		}
 
-	if (sk_num(engines) == 0)
+	if (sk_OPENSSL_STRING_num(engines) == 0)
 		{
 		for(e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e))
 			{
-			sk_push(engines,(char *)ENGINE_get_id(e));
+			sk_OPENSSL_STRING_push(engines,(char *)ENGINE_get_id(e));
 			}
 		}
 
-	for (i=0; i<sk_num(engines); i++)
+	for (i=0; i<sk_OPENSSL_STRING_num(engines); i++)
 		{
-		const char *id = sk_value(engines,i);
+		const char *id = sk_OPENSSL_STRING_value(engines,i);
 		if ((e = ENGINE_by_id(id)) != NULL)
 			{
 			const char *name = ENGINE_get_name(e);
@@ -454,6 +451,7 @@
 				const int *nids;
 				ENGINE_CIPHERS_PTR fn_c;
 				ENGINE_DIGESTS_PTR fn_d;
+				ENGINE_PKEY_METHS_PTR fn_pk;
 
 				if (ENGINE_get_RSA(e) != NULL
 					&& !append_buf(&cap_buf, "RSA",
@@ -492,6 +490,15 @@
 						goto end;
 
 skip_digests:
+				fn_pk = ENGINE_get_pkey_meths(e);
+				if(!fn_pk) goto skip_pmeths;
+				n = fn_pk(e, NULL, &nids, 0);
+				for(k=0 ; k < n ; ++k)
+					if(!append_buf(&cap_buf,
+						       OBJ_nid2sn(nids[k]),
+						       &cap_size, 256))
+						goto end;
+skip_pmeths:
 				if (cap_buf && (*cap_buf != '\0'))
 					BIO_printf(bio_out, " [%s]\n", cap_buf);
 
@@ -526,9 +533,9 @@
 end:
 
 	ERR_print_errors(bio_err);
-	sk_pop_free(engines, identity);
-	sk_pop_free(pre_cmds, identity);
-	sk_pop_free(post_cmds, identity);
+	sk_OPENSSL_STRING_pop_free(engines, identity);
+	sk_OPENSSL_STRING_pop_free(pre_cmds, identity);
+	sk_OPENSSL_STRING_pop_free(post_cmds, identity);
 	if (bio_out != NULL) BIO_free_all(bio_out);
 	apps_shutdown();
 	OPENSSL_EXIT(ret);
diff --git a/apps/errstr.c b/apps/errstr.c
index 19489b0..fe3b980 100644
--- a/apps/errstr.c
+++ b/apps/errstr.c
@@ -97,10 +97,12 @@
 			out = BIO_push(tmpbio, out);
 			}
 #endif
-			lh_node_stats_bio((LHASH *)ERR_get_string_table(),out);
-			lh_stats_bio((LHASH *)ERR_get_string_table(),out);
-			lh_node_usage_stats_bio((LHASH *)
-				ERR_get_string_table(),out);
+			lh_ERR_STRING_DATA_node_stats_bio(
+						  ERR_get_string_table(), out);
+			lh_ERR_STRING_DATA_stats_bio(ERR_get_string_table(),
+						     out);
+			lh_ERR_STRING_DATA_node_usage_stats_bio(
+						    ERR_get_string_table(),out);
 			}
 		if (out != NULL) BIO_free_all(out);
 		argc--;
diff --git a/apps/gendh.c b/apps/gendh.c
index 4749786..caa7327 100644
--- a/apps/gendh.c
+++ b/apps/gendh.c
@@ -235,4 +235,10 @@
 #endif
 	return 1;
 	}
+#else /* !OPENSSL_NO_DH */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
 #endif
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 (steve@openssl.org) for the OpenSSL
+ * project 2006
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include <stdio.h>
+#include <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 5759acb..37e9310 100644
--- a/apps/genrsa.c
+++ b/apps/genrsa.c
@@ -95,7 +95,6 @@
 	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;
@@ -139,8 +138,6 @@
 			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)
 			{
@@ -268,22 +265,15 @@
 
 	BIO_printf(bio_err,"Generating RSA private key, %d bit long modulus\n",
 		num);
-
+#ifdef OPENSSL_NO_ENGINE
 	rsa = RSA_new();
+#else
+	rsa = RSA_new_method(e);
+#endif
 	if (!rsa)
 		goto err;
 
-	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))
+	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 cb749bf..b96c4a1 100644
--- a/apps/makeapps.com
+++ b/apps/makeapps.com
@@ -139,12 +139,12 @@
 $! making it fairly easy to verify that the lists are the same.
 $!
 $ LIB_OPENSSL = "VERIFY,ASN1PARS,REQ,DGST,DH,DHPARAM,ENC,PASSWD,GENDH,ERRSTR,"+-
-		"CA,PKCS7,CRL2P7,CRL,"+-
-		"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,RAND,ENGINE,"+-
-		"OCSP,PRIME,CMS"
+	     	"CA,PKCS7,CRL2P7,CRL,"+-
+	      	"RSA,RSAUTL,DSA,DSAPARAM,EC,ECPARAM,"+-
+	      	"X509,GENRSA,GENDSA,GENPKEY,S_SERVER,S_CLIENT,SPEED,"+-
+	      	"S_TIME,APPS,S_CB,S_SOCKET,APP_RAND,VERSION,SESS_ID,"+-
+	      	"CIPHERS,NSEQ,PKCS12,PKCS8,PKEY,PKEYPARAM,PKEYUTL,"+ -
+	      	"SPKAC,SMIME,CMS,RAND,ENGINE,OCSP,PRIME,TS"
 $ TCPIP_PROGRAMS = ",,"
 $ IF COMPILER .EQS. "VAXC" THEN -
      TCPIP_PROGRAMS = ",OPENSSL,"
diff --git a/apps/ocsp.c b/apps/ocsp.c
index 251044d..01847df 100644
--- a/apps/ocsp.c
+++ b/apps/ocsp.c
@@ -56,25 +56,53 @@
  *
  */
 #ifndef OPENSSL_NO_OCSP
+
+#ifdef OPENSSL_SYS_VMS
+#define _XOPEN_SOURCE_EXTENDED	/* So fd_set and friends get properly defined
+				   on OpenVMS */
+#endif
+
 #define USE_SOCKETS
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 #include "apps.h" /* needs to be included before the openssl headers! */
 #include <openssl/e_os2.h>
-#include <openssl/ssl.h>
+#include <openssl/crypto.h>
 #include <openssl/err.h>
+#include <openssl/ssl.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/x509v3.h>
 
+#if defined(NETWARE_CLIB)
+#  ifdef NETWARE_BSDSOCK
+#    include <sys/socket.h>
+#    include <sys/bsdskt.h>
+#  else
+#    include <novsock2.h>
+#  endif
+#elif defined(NETWARE_LIBC)
+#  ifdef NETWARE_BSDSOCK
+#    include <sys/select.h>
+#  else
+#    include <novsock2.h>
+#  endif
+#endif
+  
 /* Maximum leeway in validity period: default 5 minutes */
 #define MAX_VALIDITY_PERIOD	(5 * 60)
 
-static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
+static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md, X509 *issuer,
 				STACK_OF(OCSP_CERTID) *ids);
-static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer,
+static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, const EVP_MD * cert_id_md, X509 *issuer,
 				STACK_OF(OCSP_CERTID) *ids);
 static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
-				STACK *names, STACK_OF(OCSP_CERTID) *ids,
-				long nsec, long maxage);
+			      STACK_OF(OPENSSL_STRING) *names,
+			      STACK_OF(OCSP_CERTID) *ids, long nsec,
+			      long maxage);
 
 static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
 			X509 *ca, X509 *rcert, EVP_PKEY *rkey,
@@ -86,6 +114,7 @@
 static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port);
 static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp);
 static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
+				STACK_OF(CONF_VALUE) *headers,
 				OCSP_REQUEST *req, int req_timeout);
 
 #undef PROG
@@ -104,6 +133,7 @@
 	char *rsignfile = NULL, *rkeyfile = NULL;
 	char *outfile = NULL;
 	int add_nonce = 1, noverify = 0, use_ssl = -1;
+	STACK_OF(CONF_VALUE) *headers = NULL;
 	OCSP_REQUEST *req = NULL;
 	OCSP_RESPONSE *resp = NULL;
 	OCSP_BASICRESP *bs = NULL;
@@ -126,7 +156,7 @@
 	int badarg = 0;
 	int i;
 	int ignore_err = 0;
-	STACK *reqnames = NULL;
+	STACK_OF(OPENSSL_STRING) *reqnames = NULL;
 	STACK_OF(OCSP_CERTID) *ids = NULL;
 
 	X509 *rca_cert = NULL;
@@ -134,6 +164,7 @@
 	char *rca_filename = NULL;
 	CA_DB *rdb = NULL;
 	int nmin = 0, ndays = -1;
+	const EVP_MD *cert_id_md = NULL;
 
 	if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
 
@@ -142,7 +173,7 @@
 	SSL_load_error_strings();
 	OpenSSL_add_ssl_algorithms();
 	args = argv + 1;
-	reqnames = sk_new_null();
+	reqnames = sk_OPENSSL_STRING_new_null();
 	ids = sk_OCSP_CERTID_new_null();
 	while (!badarg && *args && *args[0] == '-')
 		{
@@ -202,6 +233,16 @@
 				}
 			else badarg = 1;
 			}
+		else if (!strcmp(*args, "-header"))
+			{
+			if (args[1] && args[2])
+				{
+				if (!X509V3_add_value(args[1], args[2], &headers))
+					goto end;
+				args += 2;
+				}
+			else badarg = 1;
+			}
 		else if (!strcmp(*args, "-ignore_err"))
 			ignore_err = 1;
 		else if (!strcmp(*args, "-noverify"))
@@ -401,9 +442,10 @@
 				cert = load_cert(bio_err, *args, FORMAT_PEM,
 					NULL, e, "certificate");
 				if(!cert) goto end;
-				if(!add_ocsp_cert(&req, cert, issuer, ids))
+				if (!cert_id_md) cert_id_md = EVP_sha1();
+				if(!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids))
 					goto end;
-				if(!sk_push(reqnames, *args))
+				if(!sk_OPENSSL_STRING_push(reqnames, *args))
 					goto end;
 				}
 			else badarg = 1;
@@ -413,9 +455,10 @@
 			if (args[1])
 				{
 				args++;
-				if(!add_ocsp_serial(&req, *args, issuer, ids))
+				if (!cert_id_md) cert_id_md = EVP_sha1();
+				if(!add_ocsp_serial(&req, *args, cert_id_md, issuer, ids))
 					goto end;
-				if(!sk_push(reqnames, *args))
+				if(!sk_OPENSSL_STRING_push(reqnames, *args))
 					goto end;
 				}
 			else badarg = 1;
@@ -515,7 +558,10 @@
 				}
 			else badarg = 1;
 			}
-		else badarg = 1;
+		else if ((cert_id_md = EVP_get_digestbyname((*args)+1))==NULL)
+			{
+			badarg = 1;
+			}
 		args++;
 		}
 
@@ -571,6 +617,7 @@
 		BIO_printf (bio_err, "-ndays n	 	 number of days before next update\n");
 		BIO_printf (bio_err, "-resp_key_id       identify reponse by signing certificate key ID\n");
 		BIO_printf (bio_err, "-nrequest n        number of requests to accept (default unlimited)\n");
+		BIO_printf (bio_err, "-<dgst alg>     use specified digest in the request");
 		goto end;
 		}
 
@@ -677,7 +724,8 @@
 			"signer private key");
 		if (!key)
 			goto end;
-		if (!OCSP_request_sign(req, signer, key, EVP_sha1(), sign_other, sign_flags))
+
+		if (!OCSP_request_sign(req, signer, key, NULL, sign_other, sign_flags))
 			{
 			BIO_printf(bio_err, "Error signing OCSP request\n");
 			goto end;
@@ -721,7 +769,7 @@
 		{
 #ifndef OPENSSL_NO_SOCK
 		resp = process_responder(bio_err, req, host, path,
-						port, use_ssl, req_timeout);
+					port, use_ssl, headers, req_timeout);
 		if (!resp)
 			goto end;
 #else
@@ -866,10 +914,11 @@
 	OCSP_REQUEST_free(req);
 	OCSP_RESPONSE_free(resp);
 	OCSP_BASICRESP_free(bs);
-	sk_free(reqnames);
+	sk_OPENSSL_STRING_free(reqnames);
 	sk_OCSP_CERTID_free(ids);
 	sk_X509_pop_free(sign_other, X509_free);
 	sk_X509_pop_free(verify_other, X509_free);
+	sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);
 
 	if (use_ssl != -1)
 		{
@@ -881,7 +930,7 @@
 	OPENSSL_EXIT(ret);
 }
 
-static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
+static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md,X509 *issuer,
 				STACK_OF(OCSP_CERTID) *ids)
 	{
 	OCSP_CERTID *id;
@@ -892,7 +941,7 @@
 		}
 	if(!*req) *req = OCSP_REQUEST_new();
 	if(!*req) goto err;
-	id = OCSP_cert_to_id(NULL, cert, issuer);
+	id = OCSP_cert_to_id(cert_id_md, cert, issuer);
 	if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
 	if(!OCSP_request_add0_id(*req, id)) goto err;
 	return 1;
@@ -902,7 +951,7 @@
 	return 0;
 	}
 
-static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer,
+static int add_ocsp_serial(OCSP_REQUEST **req, char *serial,const EVP_MD *cert_id_md, X509 *issuer,
 				STACK_OF(OCSP_CERTID) *ids)
 	{
 	OCSP_CERTID *id;
@@ -924,7 +973,7 @@
 		BIO_printf(bio_err, "Error converting serial number %s\n", serial);
 		return 0;
 		}
-	id = OCSP_cert_id_new(EVP_sha1(), iname, ikey, sno);
+	id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno);
 	ASN1_INTEGER_free(sno);
 	if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
 	if(!OCSP_request_add0_id(*req, id)) goto err;
@@ -936,8 +985,9 @@
 	}
 
 static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
-					STACK *names, STACK_OF(OCSP_CERTID) *ids,
-					long nsec, long maxage)
+			      STACK_OF(OPENSSL_STRING) *names,
+			      STACK_OF(OCSP_CERTID) *ids, long nsec,
+			      long maxage)
 	{
 	OCSP_CERTID *id;
 	char *name;
@@ -947,13 +997,13 @@
 
 	ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
 
-	if (!bs || !req || !sk_num(names) || !sk_OCSP_CERTID_num(ids))
+	if (!bs || !req || !sk_OPENSSL_STRING_num(names) || !sk_OCSP_CERTID_num(ids))
 		return 1;
 
 	for (i = 0; i < sk_OCSP_CERTID_num(ids); i++)
 		{
 		id = sk_OCSP_CERTID_value(ids, i);
-		name = sk_value(names, i);
+		name = sk_OPENSSL_STRING_value(names, i);
 		BIO_printf(out, "%s: ", name);
 
 		if(!OCSP_resp_find_status(bs, id, &status, &reason,
@@ -1010,7 +1060,6 @@
 	OCSP_BASICRESP *bs = NULL;
 	int i, id_count, ret = 1;
 
-
 	id_count = OCSP_request_onereq_count(req);
 
 	if (id_count <= 0)
@@ -1019,7 +1068,6 @@
 		goto end;
 		}
 
-	ca_id = OCSP_cert_to_id(EVP_sha1(), NULL, ca);
 
 	bs = OCSP_BASICRESP_new();
 	thisupd = X509_gmtime_adj(NULL, 0);
@@ -1032,8 +1080,23 @@
 		OCSP_ONEREQ *one;
 		ASN1_INTEGER *serial;
 		char **inf;
+		ASN1_OBJECT *cert_id_md_oid;
+		const EVP_MD *cert_id_md;
 		one = OCSP_request_onereq_get0(req, i);
 		cid = OCSP_onereq_get0_id(one);
+
+		OCSP_id_get0_info(NULL,&cert_id_md_oid, NULL,NULL, cid);
+
+		cert_id_md = EVP_get_digestbyobj(cert_id_md_oid);	
+		if (! cert_id_md) 
+			{
+			*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR,
+				NULL);
+				goto end;
+			}	
+		if (ca_id) OCSP_CERTID_free(ca_id);
+		ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca);
+
 		/* Is this request about our CA? */
 		if (OCSP_id_issuer_cmp(ca_id, cid))
 			{
@@ -1078,8 +1141,8 @@
 		}
 
 	OCSP_copy_nonce(bs, req);
-		
-	OCSP_basic_sign(bs, rcert, rkey, EVP_sha1(), rother, flags);
+	
+	OCSP_basic_sign(bs, rcert, rkey, NULL, rother, flags);
 
 	*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
 
@@ -1211,10 +1274,12 @@
 	}
 
 static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
+				STACK_OF(CONF_VALUE) *headers,
 				OCSP_REQUEST *req, int req_timeout)
 	{
 	int fd;
 	int rv;
+	int i;
 	OCSP_REQ_CTX *ctx = NULL;
 	OCSP_RESPONSE *rsp = NULL;
 	fd_set confds;
@@ -1231,16 +1296,13 @@
 		return NULL;
 		}
 
-	if (req_timeout == -1)
-		return OCSP_sendreq_bio(cbio, path, req);
-
 	if (BIO_get_fd(cbio, &fd) <= 0)
 		{
 		BIO_puts(err, "Can't get connection fd\n");
 		goto err;
 		}
 
-	if (rv <= 0)
+	if (req_timeout != -1 && rv <= 0)
 		{
 		FD_ZERO(&confds);
 		openssl_fdset(fd, &confds);
@@ -1255,15 +1317,27 @@
 		}
 
 
-	ctx = OCSP_sendreq_new(cbio, path, req, -1);
+	ctx = OCSP_sendreq_new(cbio, path, NULL, -1);
 	if (!ctx)
 		return NULL;
+
+	for (i = 0; i < sk_CONF_VALUE_num(headers); i++)
+		{
+		CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i);
+		if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value))
+			goto err;
+		}
+
+	if (!OCSP_REQ_CTX_set1_req(ctx, req))
+		goto err;
 	
 	for (;;)
 		{
 		rv = OCSP_sendreq_nbio(&rsp, ctx);
 		if (rv != -1)
 			break;
+		if (req_timeout == -1)
+			continue;
 		FD_ZERO(&confds);
 		openssl_fdset(fd, &confds);
 		tv.tv_usec = 0;
@@ -1287,7 +1361,7 @@
 			BIO_puts(err, "Select error\n");
 			break;
 			}
-			
+
 		}
 	err:
 	if (ctx)
@@ -1298,6 +1372,7 @@
 
 OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
 			char *host, char *path, char *port, int use_ssl,
+			STACK_OF(CONF_VALUE) *headers,
 			int req_timeout)
 	{
 	BIO *cbio = NULL;
@@ -1332,14 +1407,14 @@
 		sbio = BIO_new_ssl(ctx, 1);
 		cbio = BIO_push(sbio, cbio);
 		}
-	resp = query_responder(err, cbio, path, req, req_timeout);
+	resp = query_responder(err, cbio, path, headers, req, req_timeout);
 	if (!resp)
 		BIO_printf(bio_err, "Error querying OCSP responsder\n");
 	end:
-	if (ctx)
-		SSL_CTX_free(ctx);
 	if (cbio)
 		BIO_free_all(cbio);
+	if (ctx)
+		SSL_CTX_free(ctx);
 	return resp;
 	}
 
diff --git a/apps/openssl-vms.cnf b/apps/openssl-vms.cnf
index fae82b0..20ed61b 100644
--- a/apps/openssl-vms.cnf
+++ b/apps/openssl-vms.cnf
@@ -21,12 +21,17 @@
 
 [ new_oids ]
 
-# We can add new OIDs in here for use by 'ca' and 'req'.
+# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
 # Add a simple OID like this:
 # testoid1=1.2.3.4
 # Or use config file substitution like this:
 # testoid2=${testoid1}.5.6
 
+# Policies used by the TSA examples.
+tsa_policy1 = 1.2.3.4.1
+tsa_policy2 = 1.2.3.4.5.6
+tsa_policy3 = 1.2.3.4.5.7
+
 ####################################################################
 [ ca ]
 default_ca	= CA_default		# The default ca section
@@ -67,7 +72,7 @@
 
 default_days	= 365			# how long to certify for
 default_crl_days= 30			# how long before next CRL
-default_md	= sha1			# which md to use.
+default_md	= default		# use public key default MD
 preserve	= no			# keep passed DN ordering
 
 # A few difference way of specifying how similar the request should look
@@ -110,13 +115,12 @@
 
 # This sets a mask for permitted string types. There are several options. 
 # default: PrintableString, T61String, BMPString.
-# pkix	 : PrintableString, BMPString.
-# utf8only: only UTF8Strings.
+# pkix	 : PrintableString, BMPString (PKIX recommendation before 2004)
+# utf8only: only UTF8Strings (PKIX recommendation after 2004).
 # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
 # MASK:XXXX a literal mask value.
-# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
-# so use this option with caution!
-string_mask = nombstr
+# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
+string_mask = utf8only
 
 # req_extensions = v3_req # The extensions to add to a certificate request
 
@@ -207,6 +211,9 @@
 #nsCaPolicyUrl
 #nsSslServerName
 
+# This is required for TSA certificates.
+# extendedKeyUsage = critical,timeStamping
+
 [ v3_req ]
 
 # Extensions to add to a certificate request
@@ -224,7 +231,7 @@
 
 subjectKeyIdentifier=hash
 
-authorityKeyIdentifier=keyid:always,issuer:always
+authorityKeyIdentifier=keyid:always,issuer
 
 # This is what PKIX recommends but some broken software chokes on critical
 # extensions.
@@ -257,7 +264,7 @@
 # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
 
 # issuerAltName=issuer:copy
-authorityKeyIdentifier=keyid:always,issuer:always
+authorityKeyIdentifier=keyid:always
 
 [ proxy_cert_ext ]
 # These extensions should be added when creating a proxy certificate
@@ -290,7 +297,7 @@
 
 # PKIX recommendations harmless if included in all certificates.
 subjectKeyIdentifier=hash
-authorityKeyIdentifier=keyid,issuer:always
+authorityKeyIdentifier=keyid,issuer
 
 # This stuff is for subjectAltName and issuerAltname.
 # Import the email address.
@@ -311,3 +318,33 @@
 
 # This really needs to be in place for it to be a proxy certificate.
 proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
+
+####################################################################
+[ tsa ]
+
+default_tsa = tsa_config1	# the default TSA section
+
+[ tsa_config1 ]
+
+# These are used by the TSA reply generation only.
+dir		= sys\$disk:[.demoCA		# TSA root directory
+serial		= $dir]tsaserial.	# The current serial number (mandatory)
+crypto_device	= builtin		# OpenSSL engine to use for signing
+signer_cert	= $dir/tsacert.pem 	# The TSA signing certificate
+					# (optional)
+certs		= $dir.cacert.pem]	# Certificate chain to include in reply
+					# (optional)
+signer_key	= $dir/private/tsakey.pem # The TSA private key (optional)
+
+default_policy	= tsa_policy1		# Policy if request did not specify it
+					# (optional)
+other_policies	= tsa_policy2, tsa_policy3	# acceptable policies (optional)
+digests		= md5, sha1		# Acceptable message digests (mandatory)
+accuracy	= secs:1, millisecs:500, microsecs:100	# (optional)
+clock_precision_digits  = 0	# number of digits after dot. (optional)
+ordering		= yes	# Is ordering defined for timestamps?
+				# (optional, default: no)
+tsa_name		= yes	# Must the TSA name be included in the reply?
+				# (optional, default: no)
+ess_cert_id_chain	= no	# Must the ESS cert id chain be included?
+				# (optional, default: no)
diff --git a/apps/openssl.c b/apps/openssl.c
index 480fef9..851e639 100644
--- a/apps/openssl.c
+++ b/apps/openssl.c
@@ -135,19 +135,17 @@
  * type of "FUNCTION*"). This removes the necessity for macro-generated wrapper
  * functions. */
 
-/* static unsigned long MS_CALLBACK hash(FUNCTION *a); */
-static unsigned long MS_CALLBACK hash(const void *a_void);
-/* static int MS_CALLBACK cmp(FUNCTION *a,FUNCTION *b); */
-static int MS_CALLBACK cmp(const void *a_void,const void *b_void);
-static LHASH *prog_init(void );
-static int do_cmd(LHASH *prog,int argc,char *argv[]);
+static LHASH_OF(FUNCTION) *prog_init(void );
+static int do_cmd(LHASH_OF(FUNCTION) *prog,int argc,char *argv[]);
+static void list_pkey(BIO *out);
+static void list_cipher(BIO *out);
+static void list_md(BIO *out);
 char *default_config_file=NULL;
 
 /* Make sure there is only one when MONOLITH is defined */
 #ifdef MONOLITH
 CONF *config=NULL;
 BIO *bio_err=NULL;
-int in_FIPS_mode=0;
 #endif
 
 
@@ -227,28 +225,12 @@
 	int n,i,ret=0;
 	int argc;
 	char **argv,*p;
-	LHASH *prog=NULL;
+	LHASH_OF(FUNCTION) *prog=NULL;
 	long errline;
  
 	arg.data=NULL;
 	arg.count=0;
 
-	in_FIPS_mode = 0;
-
-	if(getenv("OPENSSL_FIPS")) {
-#ifdef 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;
-#else
-		fprintf(stderr, "FIPS mode not supported.\n");
-		EXIT(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);
@@ -290,9 +272,21 @@
 	i=NCONF_load(config,p,&errline);
 	if (i == 0)
 		{
-		NCONF_free(config);
-		config = NULL;
-		ERR_clear_error();
+		if (ERR_GET_REASON(ERR_peek_last_error())
+		    == CONF_R_NO_SUCH_FILE)
+			{
+			BIO_printf(bio_err,
+				   "WARNING: can't open config file: %s\n",p);
+			ERR_clear_error();
+			NCONF_free(config);
+			config = NULL;
+			}
+		else
+			{
+			ERR_print_errors(bio_err);
+			NCONF_free(config);
+			exit(1);
+			}
 		}
 
 	prog=prog_init();
@@ -301,7 +295,7 @@
 	program_name(Argv[0],pname,sizeof pname);
 
 	f.name=pname;
-	fp=(FUNCTION *)lh_retrieve(prog,&f);
+	fp=lh_FUNCTION_retrieve(prog,&f);
 	if (fp != NULL)
 		{
 		Argv[0]=pname;
@@ -368,7 +362,7 @@
 		NCONF_free(config);
 		config=NULL;
 		}
-	if (prog != NULL) lh_free(prog);
+	if (prog != NULL) lh_FUNCTION_free(prog);
 	if (arg.data != NULL) OPENSSL_free(arg.data);
 
 	apps_shutdown();
@@ -384,9 +378,13 @@
 
 #define LIST_STANDARD_COMMANDS "list-standard-commands"
 #define LIST_MESSAGE_DIGEST_COMMANDS "list-message-digest-commands"
+#define LIST_MESSAGE_DIGEST_ALGORITHMS "list-message-digest-algorithms"
 #define LIST_CIPHER_COMMANDS "list-cipher-commands"
+#define LIST_CIPHER_ALGORITHMS "list-cipher-algorithms"
+#define LIST_PUBLIC_KEY_ALGORITHMS "list-public-key-algorithms"
 
-static int do_cmd(LHASH *prog, int argc, char *argv[])
+
+static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[])
 	{
 	FUNCTION f,*fp;
 	int i,ret=1,tp,nl;
@@ -394,7 +392,22 @@
 	if ((argc <= 0) || (argv[0] == NULL))
 		{ ret=0; goto end; }
 	f.name=argv[0];
-	fp=(FUNCTION *)lh_retrieve(prog,&f);
+	fp=lh_FUNCTION_retrieve(prog,&f);
+	if (fp == NULL)
+		{
+		if (EVP_get_digestbyname(argv[0]))
+			{
+			f.type = FUNC_TYPE_MD;
+			f.func = dgst_main;
+			fp = &f;
+			}
+		else if (EVP_get_cipherbyname(argv[0]))
+			{
+			f.type = FUNC_TYPE_CIPHER;
+			f.func = enc_main;
+			fp = &f;
+			}
+		}
 	if (fp != NULL)
 		{
 		ret=fp->func(argc,argv);
@@ -409,7 +422,7 @@
 		}
 #endif
 		f.name=argv[0]+3;
-		ret = (lh_retrieve(prog,&f) != NULL);
+		ret = (lh_FUNCTION_retrieve(prog,&f) != NULL);
 		if (!ret)
 			BIO_printf(bio_stdout, "%s\n", argv[0]);
 		else
@@ -427,7 +440,10 @@
 		}
 	else if ((strcmp(argv[0],LIST_STANDARD_COMMANDS) == 0) ||
 		(strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0) ||
-		(strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0))
+		(strcmp(argv[0],LIST_MESSAGE_DIGEST_ALGORITHMS) == 0) ||
+		(strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0) ||
+		(strcmp(argv[0],LIST_CIPHER_ALGORITHMS) == 0) ||
+		(strcmp(argv[0],LIST_PUBLIC_KEY_ALGORITHMS) == 0))
 		{
 		int list_type;
 		BIO *bio_stdout;
@@ -436,6 +452,12 @@
 			list_type = FUNC_TYPE_GENERAL;
 		else if (strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0)
 			list_type = FUNC_TYPE_MD;
+		else if (strcmp(argv[0],LIST_MESSAGE_DIGEST_ALGORITHMS) == 0)
+			list_type = FUNC_TYPE_MD_ALG;
+		else if (strcmp(argv[0],LIST_PUBLIC_KEY_ALGORITHMS) == 0)
+			list_type = FUNC_TYPE_PKEY;
+		else if (strcmp(argv[0],LIST_CIPHER_ALGORITHMS) == 0)
+			list_type = FUNC_TYPE_CIPHER_ALG;
 		else /* strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0 */
 			list_type = FUNC_TYPE_CIPHER;
 		bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE);
@@ -445,10 +467,23 @@
 		bio_stdout = BIO_push(tmpbio, bio_stdout);
 		}
 #endif
-		
-		for (fp=functions; fp->name != NULL; fp++)
-			if (fp->type == list_type)
-				BIO_printf(bio_stdout, "%s\n", fp->name);
+
+		if (!load_config(bio_err, NULL))
+			goto end;
+
+		if (list_type == FUNC_TYPE_PKEY)
+			list_pkey(bio_stdout);	
+		if (list_type == FUNC_TYPE_MD_ALG)
+			list_md(bio_stdout);	
+		if (list_type == FUNC_TYPE_CIPHER_ALG)
+			list_cipher(bio_stdout);	
+		else
+			{
+			for (fp=functions; fp->name != NULL; fp++)
+				if (fp->type == list_type)
+					BIO_printf(bio_stdout, "%s\n",
+								fp->name);
+			}
 		BIO_free_all(bio_stdout);
 		ret=0;
 		goto end;
@@ -511,9 +546,94 @@
     return strcmp(f1->name,f2->name);
     }
 
-static LHASH *prog_init(void)
+static void list_pkey(BIO *out)
 	{
-	LHASH *ret;
+	int i;
+	for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
+		{
+		const EVP_PKEY_ASN1_METHOD *ameth;
+		int pkey_id, pkey_base_id, pkey_flags;
+		const char *pinfo, *pem_str;
+		ameth = EVP_PKEY_asn1_get0(i);
+		EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags,
+						&pinfo, &pem_str, ameth);
+		if (pkey_flags & ASN1_PKEY_ALIAS)
+			{
+			BIO_printf(out, "Name: %s\n", 
+					OBJ_nid2ln(pkey_id));
+			BIO_printf(out, "\tType: Alias to %s\n",
+					OBJ_nid2ln(pkey_base_id));
+			}
+		else
+			{
+			BIO_printf(out, "Name: %s\n", pinfo);
+			BIO_printf(out, "\tType: %s Algorithm\n", 
+				pkey_flags & ASN1_PKEY_DYNAMIC ?
+					"External" : "Builtin");
+			BIO_printf(out, "\tOID: %s\n", OBJ_nid2ln(pkey_id));
+			if (pem_str == NULL)
+				pem_str = "(none)";
+			BIO_printf(out, "\tPEM string: %s\n", pem_str);
+			}
+					
+		}
+	}
+
+static void list_cipher_fn(const EVP_CIPHER *c,
+			const char *from, const char *to, void *arg)
+	{
+	if (c)
+		BIO_printf(arg, "%s\n", EVP_CIPHER_name(c));
+	else
+		{
+		if (!from)
+			from = "<undefined>";
+		if (!to)
+			to = "<undefined>";
+		BIO_printf(arg, "%s => %s\n", from, to);
+		}
+	}
+
+static void list_cipher(BIO *out)
+	{
+	EVP_CIPHER_do_all_sorted(list_cipher_fn, out);
+	}
+
+static void list_md_fn(const EVP_MD *m,
+			const char *from, const char *to, void *arg)
+	{
+	if (m)
+		BIO_printf(arg, "%s\n", EVP_MD_name(m));
+	else
+		{
+		if (!from)
+			from = "<undefined>";
+		if (!to)
+			to = "<undefined>";
+		BIO_printf(arg, "%s => %s\n", from, to);
+		}
+	}
+
+static void list_md(BIO *out)
+	{
+	EVP_MD_do_all_sorted(list_md_fn, out);
+	}
+
+static int MS_CALLBACK function_cmp(const FUNCTION *a, const FUNCTION *b)
+	{
+	return strncmp(a->name,b->name,8);
+	}
+static IMPLEMENT_LHASH_COMP_FN(function, FUNCTION)
+
+static unsigned long MS_CALLBACK function_hash(const FUNCTION *a)
+	{
+	return lh_strhash(a->name);
+	}	
+static IMPLEMENT_LHASH_HASH_FN(function, FUNCTION)
+
+static LHASH_OF(FUNCTION) *prog_init(void)
+	{
+	LHASH_OF(FUNCTION) *ret;
 	FUNCTION *f;
 	size_t i;
 
@@ -522,23 +642,11 @@
 	    ;
 	qsort(functions,i,sizeof *functions,SortFnByName);
 
-	if ((ret=lh_new(hash, cmp)) == NULL)
+	if ((ret=lh_FUNCTION_new()) == NULL)
 		return(NULL);
 
 	for (f=functions; f->name != NULL; f++)
-		lh_insert(ret,f);
+		(void)lh_FUNCTION_insert(ret,f);
 	return(ret);
 	}
 
-/* static int MS_CALLBACK cmp(FUNCTION *a, FUNCTION *b) */
-static int MS_CALLBACK cmp(const void *a_void, const void *b_void)
-	{
-	return(strncmp(((const FUNCTION *)a_void)->name,
-			((const FUNCTION *)b_void)->name,8));
-	}
-
-/* static unsigned long MS_CALLBACK hash(FUNCTION *a) */
-static unsigned long MS_CALLBACK hash(const void *a_void)
-	{
-	return(lh_strhash(((const FUNCTION *)a_void)->name));
-	}
diff --git a/apps/openssl.cnf b/apps/openssl.cnf
index 9e59020..9d2cd5b 100644
--- a/apps/openssl.cnf
+++ b/apps/openssl.cnf
@@ -21,12 +21,17 @@
 
 [ new_oids ]
 
-# We can add new OIDs in here for use by 'ca' and 'req'.
+# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
 # Add a simple OID like this:
 # testoid1=1.2.3.4
 # Or use config file substitution like this:
 # testoid2=${testoid1}.5.6
 
+# Policies used by the TSA examples.
+tsa_policy1 = 1.2.3.4.1
+tsa_policy2 = 1.2.3.4.5.6
+tsa_policy3 = 1.2.3.4.5.7
+
 ####################################################################
 [ ca ]
 default_ca	= CA_default		# The default ca section
@@ -67,7 +72,7 @@
 
 default_days	= 365			# how long to certify for
 default_crl_days= 30			# how long before next CRL
-default_md	= sha1			# which md to use.
+default_md	= default		# use public key default MD
 preserve	= no			# keep passed DN ordering
 
 # A few difference way of specifying how similar the request should look
@@ -110,13 +115,12 @@
 
 # This sets a mask for permitted string types. There are several options. 
 # default: PrintableString, T61String, BMPString.
-# pkix	 : PrintableString, BMPString.
-# utf8only: only UTF8Strings.
+# pkix	 : PrintableString, BMPString (PKIX recommendation before 2004)
+# utf8only: only UTF8Strings (PKIX recommendation after 2004).
 # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
 # MASK:XXXX a literal mask value.
-# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
-# so use this option with caution!
-string_mask = nombstr
+# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
+string_mask = utf8only
 
 # req_extensions = v3_req # The extensions to add to a certificate request
 
@@ -207,6 +211,9 @@
 #nsCaPolicyUrl
 #nsSslServerName
 
+# This is required for TSA certificates.
+# extendedKeyUsage = critical,timeStamping
+
 [ v3_req ]
 
 # Extensions to add to a certificate request
@@ -224,7 +231,7 @@
 
 subjectKeyIdentifier=hash
 
-authorityKeyIdentifier=keyid:always,issuer:always
+authorityKeyIdentifier=keyid:always,issuer
 
 # This is what PKIX recommends but some broken software chokes on critical
 # extensions.
@@ -257,7 +264,7 @@
 # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
 
 # issuerAltName=issuer:copy
-authorityKeyIdentifier=keyid:always,issuer:always
+authorityKeyIdentifier=keyid:always
 
 [ proxy_cert_ext ]
 # These extensions should be added when creating a proxy certificate
@@ -290,7 +297,7 @@
 
 # PKIX recommendations harmless if included in all certificates.
 subjectKeyIdentifier=hash
-authorityKeyIdentifier=keyid,issuer:always
+authorityKeyIdentifier=keyid,issuer
 
 # This stuff is for subjectAltName and issuerAltname.
 # Import the email address.
@@ -311,3 +318,33 @@
 
 # This really needs to be in place for it to be a proxy certificate.
 proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
+
+####################################################################
+[ tsa ]
+
+default_tsa = tsa_config1	# the default TSA section
+
+[ tsa_config1 ]
+
+# These are used by the TSA reply generation only.
+dir		= ./demoCA		# TSA root directory
+serial		= $dir/tsaserial	# The current serial number (mandatory)
+crypto_device	= builtin		# OpenSSL engine to use for signing
+signer_cert	= $dir/tsacert.pem 	# The TSA signing certificate
+					# (optional)
+certs		= $dir/cacert.pem	# Certificate chain to include in reply
+					# (optional)
+signer_key	= $dir/private/tsakey.pem # The TSA private key (optional)
+
+default_policy	= tsa_policy1		# Policy if request did not specify it
+					# (optional)
+other_policies	= tsa_policy2, tsa_policy3	# acceptable policies (optional)
+digests		= md5, sha1		# Acceptable message digests (mandatory)
+accuracy	= secs:1, millisecs:500, microsecs:100	# (optional)
+clock_precision_digits  = 0	# number of digits after dot. (optional)
+ordering		= yes	# Is ordering defined for timestamps?
+				# (optional, default: no)
+tsa_name		= yes	# Must the TSA name be included in the reply?
+				# (optional, default: no)
+ess_cert_id_chain	= no	# Must the ESS cert id chain be included?
+				# (optional, default: no)
diff --git a/apps/pkcs12.c b/apps/pkcs12.c
index 0db0b79..514a02e 100644
--- a/apps/pkcs12.c
+++ b/apps/pkcs12.c
@@ -68,12 +68,6 @@
 #include <openssl/pem.h>
 #include <openssl/pkcs12.h>
 
-#ifdef OPENSSL_SYS_NETWARE
-/* Rename these functions to avoid name clashes on NetWare OS */
-#define uni2asc OPENSSL_uni2asc
-#define asc2uni OPENSSL_asc2uni
-#endif
-
 #define PROG pkcs12_main
 
 const EVP_CIPHER *enc;
@@ -94,6 +88,7 @@
 void hex_prin(BIO *out, unsigned char *buf, int len);
 int alg_print(BIO *x, X509_ALGOR *alg);
 int cert_load(BIO *in, STACK_OF(X509) *sk);
+static int set_pbe(BIO *err, int *ppbe, const char *str);
 
 int MAIN(int, char **);
 
@@ -117,16 +112,17 @@
     int maciter = PKCS12_DEFAULT_ITER;
     int twopass = 0;
     int keytype = 0;
-    int cert_pbe;
+    int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
     int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
     int ret = 1;
     int macver = 1;
     int noprompt = 0;
-    STACK *canames = NULL;
+    STACK_OF(OPENSSL_STRING) *canames = NULL;
     char *cpass = NULL, *mpass = NULL;
     char *passargin = NULL, *passargout = NULL, *passarg = NULL;
     char *passin = NULL, *passout = NULL;
     char *inrand = NULL;
+    char *macalg = NULL;
     char *CApath = NULL, *CAfile = NULL;
 #ifndef OPENSSL_NO_ENGINE
     char *engine=NULL;
@@ -134,13 +130,6 @@
 
     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);
 
@@ -191,33 +180,18 @@
 					 maciter = 1;
 		else if (!strcmp (*args, "-nomac"))
 					 maciter = -1;
+		else if (!strcmp (*args, "-macalg"))
+		    if (args[1]) {
+			args++;	
+			macalg = *args;
+		    } else badarg = 1;
 		else if (!strcmp (*args, "-nodes")) enc=NULL;
 		else if (!strcmp (*args, "-certpbe")) {
-			if (args[1]) {
-				args++;
-				if (!strcmp(*args, "NONE"))
-					cert_pbe = -1;
-				else
-					cert_pbe=OBJ_txt2nid(*args);
-				if(cert_pbe == NID_undef) {
-					BIO_printf(bio_err,
-						 "Unknown PBE algorithm %s\n", *args);
-					badarg = 1;
-				}
-			} else badarg = 1;
+			if (!set_pbe(bio_err, &cert_pbe, *++args))
+				badarg = 1;
 		} else if (!strcmp (*args, "-keypbe")) {
-			if (args[1]) {
-				args++;
-				if (!strcmp(*args, "NONE"))
-					key_pbe = -1;
-				else
-					key_pbe=OBJ_txt2nid(*args);
-				if(key_pbe == NID_undef) {
-					BIO_printf(bio_err,
-						 "Unknown PBE algorithm %s\n", *args);
-					badarg = 1;
-				}
-			} else badarg = 1;
+			if (!set_pbe(bio_err, &key_pbe, *++args))
+				badarg = 1;
 		} else if (!strcmp (*args, "-rand")) {
 		    if (args[1]) {
 			args++;	
@@ -248,8 +222,8 @@
 		} else if (!strcmp (*args, "-caname")) {
 		    if (args[1]) {
 			args++;	
-			if (!canames) canames = sk_new_null();
-			sk_push(canames, *args);
+			if (!canames) canames = sk_OPENSSL_STRING_new_null();
+			sk_OPENSSL_STRING_push(canames, *args);
 		    } else badarg = 1;
 		} else if (!strcmp (*args, "-in")) {
 		    if (args[1]) {
@@ -338,11 +312,14 @@
 #endif
 	BIO_printf (bio_err, "-nodes        don't encrypt private keys\n");
 	BIO_printf (bio_err, "-noiter       don't use encryption iteration\n");
+	BIO_printf (bio_err, "-nomaciter    don't use MAC iteration\n");
 	BIO_printf (bio_err, "-maciter      use MAC iteration\n");
+	BIO_printf (bio_err, "-nomac        don't generate MAC\n");
 	BIO_printf (bio_err, "-twopass      separate MAC, encryption passwords\n");
 	BIO_printf (bio_err, "-descert      encrypt PKCS#12 certificates with triple DES (default RC2-40)\n");
 	BIO_printf (bio_err, "-certpbe alg  specify certificate PBE algorithm (default RC2-40)\n");
 	BIO_printf (bio_err, "-keypbe alg   specify private key PBE algorithm (default 3DES)\n");
+	BIO_printf (bio_err, "-macalg alg   digest algorithm used in MAC (default SHA1)\n");
 	BIO_printf (bio_err, "-keyex        set MS key exchange type\n");
 	BIO_printf (bio_err, "-keysig       set MS key signature type\n");
 	BIO_printf (bio_err, "-password p   set import/export password source\n");
@@ -354,8 +331,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");
+	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;
     }
 
@@ -445,6 +422,7 @@
 	EVP_PKEY *key = NULL;
 	X509 *ucert = NULL, *x = NULL;
 	STACK_OF(X509) *certs=NULL;
+	const EVP_MD *macmd = NULL;
 	unsigned char *catmp = NULL;
 	int i;
 
@@ -571,9 +549,9 @@
 
 	/* Add any CA names */
 
-	for (i = 0; i < sk_num(canames); i++)
+	for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++)
 		{
-		catmp = (unsigned char *)sk_value(canames, i);
+		catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i);
 		X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
 		}
 
@@ -611,8 +589,18 @@
 		goto export_end;
 		}
 
+	if (macalg)
+		{
+		macmd = EVP_get_digestbyname(macalg);
+		if (!macmd)
+			{
+			BIO_printf(bio_err, "Unknown digest algorithm %s\n", 
+						macalg);
+			}
+		}
+
 	if (maciter != -1)
-		PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, NULL);
+		PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd);
 
 #ifdef CRYPTO_MDEBUG
 	CRYPTO_pop_info();
@@ -699,7 +687,7 @@
 #endif
     BIO_free(in);
     BIO_free_all(out);
-    if (canames) sk_free(canames);
+    if (canames) sk_OPENSSL_STRING_free(canames);
     if(passin) OPENSSL_free(passin);
     if(passout) OPENSSL_free(passout);
     apps_shutdown();
@@ -935,7 +923,7 @@
 			av = sk_ASN1_TYPE_value(attr->value.set, 0);
 			switch(av->type) {
 				case V_ASN1_BMPSTRING:
-        			value = uni2asc(av->value.bmpstring->data,
+        			value = OPENSSL_uni2asc(av->value.bmpstring->data,
                                 	       av->value.bmpstring->length);
 				BIO_printf(out, "%s\n", value);
 				OPENSSL_free(value);
@@ -968,4 +956,22 @@
 	for (i = 0; i < len; i++) BIO_printf (out, "%02X ", buf[i]);
 }
 
+static int set_pbe(BIO *err, int *ppbe, const char *str)
+	{
+	if (!str)
+		return 0;
+	if (!strcmp(str, "NONE"))
+		{
+		*ppbe = -1;
+		return 1;
+		}
+	*ppbe=OBJ_txt2nid(str);
+	if (*ppbe == NID_undef)
+		{
+		BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str);
+		return 0;
+		}
+	return 1;
+	}
+			
 #endif
diff --git a/apps/pkcs7.c b/apps/pkcs7.c
index da4dbe7..86d31b9 100644
--- a/apps/pkcs7.c
+++ b/apps/pkcs7.c
@@ -90,7 +90,7 @@
 	BIO *in=NULL,*out=NULL;
 	int informat,outformat;
 	char *infile,*outfile,*prog;
-	int print_certs=0,text=0,noout=0;
+	int print_certs=0,text=0,noout=0,p7_print=0;
 	int ret=1;
 #ifndef OPENSSL_NO_ENGINE
 	char *engine=NULL;
@@ -139,6 +139,8 @@
 			noout=1;
 		else if (strcmp(*argv,"-text") == 0)
 			text=1;
+		else if (strcmp(*argv,"-print") == 0)
+			p7_print=1;
 		else if (strcmp(*argv,"-print_certs") == 0)
 			print_certs=1;
 #ifndef OPENSSL_NO_ENGINE
@@ -238,6 +240,9 @@
 			}
 		}
 
+	if (p7_print)
+		PKCS7_print_ctx(out, p7, 0, NULL);
+
 	if (print_certs)
 		{
 		STACK_OF(X509) *certs=NULL;
diff --git a/apps/pkcs8.c b/apps/pkcs8.c
index 9633a14..7edeb17 100644
--- a/apps/pkcs8.c
+++ b/apps/pkcs8.c
@@ -80,11 +80,12 @@
 	int informat, outformat;
 	int p8_broken = PKCS8_OK;
 	int nocrypt = 0;
-	X509_SIG *p8;
-	PKCS8_PRIV_KEY_INFO *p8inf;
+	X509_SIG *p8 = NULL;
+	PKCS8_PRIV_KEY_INFO *p8inf = NULL;
 	EVP_PKEY *pkey=NULL;
 	char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL;
 	int badarg = 0;
+	int ret = 1;
 #ifndef OPENSSL_NO_ENGINE
 	char *engine=NULL;
 #endif
@@ -225,7 +226,7 @@
 #ifndef OPENSSL_NO_ENGINE
 		BIO_printf(bio_err," -engine e       use engine e, possibly a hardware device.\n");
 #endif
-		return 1;
+		goto end;
 		}
 
 #ifndef OPENSSL_NO_ENGINE
@@ -235,7 +236,7 @@
 	if (!app_passwd(bio_err, passargin, passargout, &passin, &passout))
 		{
 		BIO_printf(bio_err, "Error getting passwords\n");
-		return 1;
+		goto end;
 		}
 
 	if ((pbe_nid == -1) && !cipher)
@@ -247,7 +248,7 @@
 			{
 			BIO_printf(bio_err,
 				 "Can't open input file %s\n", infile);
-			return (1);
+			goto end;
 			}
 		}
 	else
@@ -259,7 +260,7 @@
 			{
 			BIO_printf(bio_err,
 				 "Can't open output file %s\n", outfile);
-			return (1);
+			goto end;
 			}
 		}
 	else
@@ -274,21 +275,15 @@
 		}
 	if (topk8)
 		{
-		BIO_free(in); /* Not needed in this section */
 		pkey = load_key(bio_err, infile, informat, 1,
 			passin, e, "key");
 		if (!pkey)
-			{
-			BIO_free_all(out);
-			return 1;
-			}
+			goto end;
 		if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken)))
 			{
 			BIO_printf(bio_err, "Error converting key\n");
 			ERR_print_errors(bio_err);
-			EVP_PKEY_free(pkey);
-			BIO_free_all(out);
-			return 1;
+			goto end;
 			}
 		if (nocrypt)
 			{
@@ -299,10 +294,7 @@
 			else
 				{
 				BIO_printf(bio_err, "Bad format specified for key\n");
-				PKCS8_PRIV_KEY_INFO_free(p8inf);
-				EVP_PKEY_free(pkey);
-				BIO_free_all(out);
-				return (1);
+				goto end;
 				}
 			}
 		else
@@ -313,12 +305,7 @@
 				{
 				p8pass = pass;
 				if (EVP_read_pw_string(pass, sizeof pass, "Enter Encryption Password:", 1))
-					{
-					PKCS8_PRIV_KEY_INFO_free(p8inf);
-					EVP_PKEY_free(pkey);
-					BIO_free_all(out);
-					return (1);
-					}
+					goto end;
 				}
 			app_RAND_load_file(NULL, bio_err, 0);
 			if (!(p8 = PKCS8_encrypt(pbe_nid, cipher,
@@ -327,10 +314,7 @@
 				{
 				BIO_printf(bio_err, "Error encrypting key\n");
 				ERR_print_errors(bio_err);
-				PKCS8_PRIV_KEY_INFO_free(p8inf);
-				EVP_PKEY_free(pkey);
-				BIO_free_all(out);
-				return (1);
+				goto end;
 				}
 			app_RAND_write_file(NULL, bio_err);
 			if (outformat == FORMAT_PEM) 
@@ -340,22 +324,12 @@
 			else
 				{
 				BIO_printf(bio_err, "Bad format specified for key\n");
-				PKCS8_PRIV_KEY_INFO_free(p8inf);
-				EVP_PKEY_free(pkey);
-				BIO_free_all(out);
-				return (1);
+				goto end;
 				}
-			X509_SIG_free(p8);
 			}
 
-		PKCS8_PRIV_KEY_INFO_free (p8inf);
-		EVP_PKEY_free(pkey);
-		BIO_free_all(out);
-		if (passin)
-			OPENSSL_free(passin);
-		if (passout)
-			OPENSSL_free(passout);
-		return (0);
+		ret = 0;
+		goto end;
 		}
 
 	if (nocrypt)
@@ -367,7 +341,7 @@
 		else
 			{
 			BIO_printf(bio_err, "Bad format specified for key\n");
-			return (1);
+			goto end;
 			}
 		}
 	else
@@ -379,14 +353,14 @@
 		else
 			{
 			BIO_printf(bio_err, "Bad format specified for key\n");
-			return (1);
+			goto end;
 			}
 
 		if (!p8)
 			{
 			BIO_printf (bio_err, "Error reading key\n");
 			ERR_print_errors(bio_err);
-			return (1);
+			goto end;
 			}
 		if (passin)
 			p8pass = passin;
@@ -396,21 +370,20 @@
 			EVP_read_pw_string(pass, sizeof pass, "Enter Password:", 0);
 			}
 		p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass));
-		X509_SIG_free(p8);
 		}
 
 	if (!p8inf)
 		{
 		BIO_printf(bio_err, "Error decrypting key\n");
 		ERR_print_errors(bio_err);
-		return (1);
+		goto end;
 		}
 
 	if (!(pkey = EVP_PKCS82PKEY(p8inf)))
 		{
 		BIO_printf(bio_err, "Error converting key\n");
 		ERR_print_errors(bio_err);
-		return (1);
+		goto end;
 		}
 	
 	if (p8inf->broken)
@@ -430,13 +403,16 @@
 			BIO_printf(bio_err, "DSA public key include in PrivateKey\n");
 			break;
 
+			case PKCS8_NEG_PRIVKEY:
+			BIO_printf(bio_err, "DSA private key value is negative\n");
+			break;
+
 			default:
 			BIO_printf(bio_err, "Unknown broken type\n");
 			break;
 		}
 	}
 	
-	PKCS8_PRIV_KEY_INFO_free(p8inf);
 	if (outformat == FORMAT_PEM) 
 		PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout);
 	else if (outformat == FORMAT_ASN1)
@@ -444,10 +420,13 @@
 	else
 		{
 		BIO_printf(bio_err, "Bad format specified for key\n");
-			return (1);
+			goto end;
 		}
+	ret = 0;
 
 	end:
+	X509_SIG_free(p8);
+	PKCS8_PRIV_KEY_INFO_free(p8inf);
 	EVP_PKEY_free(pkey);
 	BIO_free_all(out);
 	BIO_free(in);
@@ -456,5 +435,5 @@
 	if (passout)
 		OPENSSL_free(passout);
 
-	return (0);
+	return ret;
 	}
diff --git a/apps/prime.c b/apps/prime.c
index af2fed1..f1aaef8 100644
--- a/apps/prime.c
+++ b/apps/prime.c
@@ -62,6 +62,9 @@
     {
     int hex=0;
     int checks=20;
+    int generate=0;
+    int bits=0;
+    int safe=0;
     BIGNUM *bn=NULL;
     BIO *bio_out;
 
@@ -77,6 +80,15 @@
 	{
 	if(!strcmp(*argv,"-hex"))
 	    hex=1;
+	else if(!strcmp(*argv,"-generate"))
+	    generate=1;
+	else if(!strcmp(*argv,"-bits"))
+	    if(--argc < 1)
+		goto bad;
+	    else
+		bits=atoi(*++argv);
+	else if(!strcmp(*argv,"-safe"))
+	    safe=1;
 	else if(!strcmp(*argv,"-checks"))
 	    if(--argc < 1)
 		goto bad;
@@ -91,13 +103,13 @@
 	++argv;
 	}
 
-    if (argv[0] == NULL)
+    if (argv[0] == NULL && !generate)
 	{
 	BIO_printf(bio_err,"No prime specified\n");
 	goto bad;
 	}
 
-   if ((bio_out=BIO_new(BIO_s_file())) != NULL)
+    if ((bio_out=BIO_new(BIO_s_file())) != NULL)
 	{
 	BIO_set_fp(bio_out,stdout,BIO_NOCLOSE);
 #ifdef OPENSSL_SYS_VMS
@@ -108,14 +120,32 @@
 #endif
 	}
 
-    if(hex)
-	BN_hex2bn(&bn,argv[0]);
-    else
-	BN_dec2bn(&bn,argv[0]);
+    if(generate)
+	{
+	char *s;
 
-    BN_print(bio_out,bn);
-    BIO_printf(bio_out," is %sprime\n",
-	       BN_is_prime_ex(bn,checks,NULL,NULL) ? "" : "not ");
+	if(!bits)
+	    {
+	    BIO_printf(bio_err,"Specifiy the number of bits.\n");
+	    return 1;
+	    }
+	bn=BN_new();
+	BN_generate_prime_ex(bn,bits,safe,NULL,NULL,NULL);
+	s=hex ? BN_bn2hex(bn) : BN_bn2dec(bn);
+	BIO_printf(bio_out,"%s\n",s);
+	OPENSSL_free(s);
+	}
+    else
+	{
+	if(hex)
+	    BN_hex2bn(&bn,argv[0]);
+	else
+	    BN_dec2bn(&bn,argv[0]);
+
+	BN_print(bio_out,bn);
+	BIO_printf(bio_out," is %sprime\n",
+		   BN_is_prime_ex(bn,checks,NULL,NULL) ? "" : "not ");
+	}
 
     BN_free(bn);
     BIO_free_all(bio_out);
diff --git a/apps/progs.h b/apps/progs.h
index 4e7d32a..40bfcb5 100644
--- a/apps/progs.h
+++ b/apps/progs.h
@@ -22,9 +22,8 @@
 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 genpkey_main(int argc,char *argv[]);
 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[]);
@@ -37,6 +36,9 @@
 extern int nseq_main(int argc,char *argv[]);
 extern int pkcs12_main(int argc,char *argv[]);
 extern int pkcs8_main(int argc,char *argv[]);
+extern int pkey_main(int argc,char *argv[]);
+extern int pkeyparam_main(int argc,char *argv[]);
+extern int pkeyutl_main(int argc,char *argv[]);
 extern int spkac_main(int argc,char *argv[]);
 extern int smime_main(int argc,char *argv[]);
 extern int rand_main(int argc,char *argv[]);
@@ -45,16 +47,21 @@
 extern int ocsp_main(int argc,char *argv[]);
 #endif
 extern int prime_main(int argc,char *argv[]);
+extern int ts_main(int argc,char *argv[]);
 
 #define FUNC_TYPE_GENERAL	1
 #define FUNC_TYPE_MD		2
 #define FUNC_TYPE_CIPHER	3
+#define FUNC_TYPE_PKEY		4
+#define FUNC_TYPE_MD_ALG	5
+#define FUNC_TYPE_CIPHER_ALG	6
 
 typedef struct {
 	int type;
 	const char *name;
 	int (*func)(int argc,char *argv[]);
 	} FUNCTION;
+DECLARE_LHASH_OF(FUNCTION);
 
 FUNCTION functions[] = {
 	{FUNC_TYPE_GENERAL,"verify",verify_main},
@@ -100,6 +107,7 @@
 #ifndef OPENSSL_NO_DSA
 	{FUNC_TYPE_GENERAL,"gendsa",gendsa_main},
 #endif
+	{FUNC_TYPE_GENERAL,"genpkey",genpkey_main},
 #if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
 #if 0 /* ANDROID */
         {FUNC_TYPE_GENERAL,"s_server",s_server_main},
@@ -129,6 +137,11 @@
 	{FUNC_TYPE_GENERAL,"pkcs12",pkcs12_main},
 #endif
 	{FUNC_TYPE_GENERAL,"pkcs8",pkcs8_main},
+#if 0 /* ANDROID */
+	{FUNC_TYPE_GENERAL,"pkey",pkey_main},
+	{FUNC_TYPE_GENERAL,"pkeyparam",pkeyparam_main},
+	{FUNC_TYPE_GENERAL,"pkeyutl",pkeyutl_main},
+#endif
 	{FUNC_TYPE_GENERAL,"spkac",spkac_main},
 	{FUNC_TYPE_GENERAL,"smime",smime_main},
 	{FUNC_TYPE_GENERAL,"rand",rand_main},
@@ -139,6 +152,9 @@
 	{FUNC_TYPE_GENERAL,"ocsp",ocsp_main},
 #endif
 	{FUNC_TYPE_GENERAL,"prime",prime_main},
+#if 0 /* ANDROID */
+	{FUNC_TYPE_GENERAL,"ts",ts_main},
+#endif
 #ifndef OPENSSL_NO_MD2
 	{FUNC_TYPE_MD,"md2",dgst_main},
 #endif
@@ -197,6 +213,9 @@
 	{FUNC_TYPE_CIPHER,"camellia-256-ecb",enc_main},
 #endif
 	{FUNC_TYPE_CIPHER,"base64",enc_main},
+#ifdef ZLIB
+	{FUNC_TYPE_CIPHER,"zlib",enc_main},
+#endif
 #ifndef OPENSSL_NO_DES
 	{FUNC_TYPE_CIPHER,"des",enc_main},
 #endif
diff --git a/apps/progs.pl b/apps/progs.pl
index 645432c..de6fdea 100644
--- a/apps/progs.pl
+++ b/apps/progs.pl
@@ -13,12 +13,16 @@
 #define FUNC_TYPE_GENERAL	1
 #define FUNC_TYPE_MD		2
 #define FUNC_TYPE_CIPHER	3
+#define FUNC_TYPE_PKEY		4
+#define FUNC_TYPE_MD_ALG	5
+#define FUNC_TYPE_CIPHER_ALG	6
 
 typedef struct {
 	int type;
 	const char *name;
 	int (*func)(int argc,char *argv[]);
 	} FUNCTION;
+DECLARE_LHASH_OF(FUNCTION);
 
 FUNCTION functions[] = {
 EOF
@@ -45,6 +49,8 @@
 		{ print "#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)\n${str}#endif\n"; }
 	elsif ( ($_ =~ /^cms$/))
 		{ print "#ifndef OPENSSL_NO_CMS\n${str}#endif\n"; }
+	elsif ( ($_ =~ /^ocsp$/))
+		{ print "#ifndef OPENSSL_NO_OCSP\n${str}#endif\n"; }
 	else
 		{ print $str; }
 	}
@@ -62,7 +68,7 @@
 	"camellia-128-cbc", "camellia-128-ecb",
 	"camellia-192-cbc", "camellia-192-ecb",
 	"camellia-256-cbc", "camellia-256-ecb",
-	"base64",
+	"base64", "zlib",
 	"des", "des3", "desx", "idea", "seed", "rc4", "rc4-40",
 	"rc2", "bf", "cast", "rc5",
 	"des-ecb", "des-ede",    "des-ede3",
@@ -89,6 +95,7 @@
 	elsif ($_ =~ /bf/)   { $t="#ifndef OPENSSL_NO_BF\n${t}#endif\n"; }
 	elsif ($_ =~ /cast/) { $t="#ifndef OPENSSL_NO_CAST\n${t}#endif\n"; }
 	elsif ($_ =~ /rc5/)  { $t="#ifndef OPENSSL_NO_RC5\n${t}#endif\n"; }
+	elsif ($_ =~ /zlib/)  { $t="#ifdef ZLIB\n${t}#endif\n"; }
 	print $t;
 	}
 
diff --git a/apps/req.c b/apps/req.c
index 314197d..820cd18 100644
--- a/apps/req.c
+++ b/apps/req.c
@@ -141,39 +141,33 @@
 				int n_max, unsigned long chtype);
 static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value,
 	int nid,int n_min,int n_max, unsigned long chtype, int mval);
-#ifndef OPENSSL_NO_RSA
-static int MS_CALLBACK req_cb(int p, int n, BN_GENCB *cb);
-#endif
+static int genpkey_cb(EVP_PKEY_CTX *ctx);
 static int req_check_len(int len,int n_min,int n_max);
 static int check_end(const char *str, const char *end);
+static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, int *pkey_type,
+					long *pkeylen, char **palgnam,
+					ENGINE *keygen_engine);
 #ifndef MONOLITH
 static char *default_config_file=NULL;
 #endif
 static CONF *req_conf=NULL;
 static int batch=0;
 
-#define TYPE_RSA	1
-#define TYPE_DSA	2
-#define TYPE_DH		3
-#define TYPE_EC		4
-
 int MAIN(int, char **);
 
 int MAIN(int argc, char **argv)
 	{
-	ENGINE *e = NULL;
-#ifndef OPENSSL_NO_DSA
-	DSA *dsa_params=NULL;
-#endif
-#ifndef OPENSSL_NO_ECDSA
-	EC_KEY *ec_params = NULL;
-#endif
+	ENGINE *e = NULL, *gen_eng = NULL;
 	unsigned long nmflag = 0, reqflag = 0;
 	int ex=1,x509=0,days=30;
 	X509 *x509ss=NULL;
 	X509_REQ *req=NULL;
+	EVP_PKEY_CTX *genctx = NULL;
+	const char *keyalg = NULL;
+	char *keyalgstr = NULL;
+	STACK_OF(OPENSSL_STRING) *pkeyopts = NULL;
 	EVP_PKEY *pkey=NULL;
-	int i=0,badops=0,newreq=0,verbose=0,pkey_type=TYPE_RSA;
+	int i=0,badops=0,newreq=0,verbose=0,pkey_type=-1;
 	long newkey = -1;
 	BIO *in=NULL,*out=NULL;
 	int informat,outformat,verify=0,noout=0,text=0,keyform=FORMAT_PEM;
@@ -193,7 +187,7 @@
 	char *p;
 	char *subj = NULL;
 	int multirdn = 0;
-	const EVP_MD *md_alg=NULL,*digest=EVP_sha1();
+	const EVP_MD *md_alg=NULL,*digest=NULL;
 	unsigned long chtype = MBSTRING_ASC;
 #ifndef MONOLITH
 	char *to_free;
@@ -236,6 +230,16 @@
 			if (--argc < 1) goto bad;
 			engine= *(++argv);
 			}
+		else if (strcmp(*argv,"-keygen_engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			gen_eng = ENGINE_by_id(*(++argv));
+			if (gen_eng == NULL)
+				{
+				BIO_printf(bio_err, "Can't find keygen engine %s\n", *argv);
+				goto end;
+				}
+			}
 #endif
 		else if (strcmp(*argv,"-key") == 0)
 			{
@@ -292,126 +296,20 @@
 			}
 		else if (strcmp(*argv,"-newkey") == 0)
 			{
-			int is_numeric;
-
-			if (--argc < 1) goto bad;
-			p= *(++argv);
-			is_numeric = p[0] >= '0' && p[0] <= '9';
-			if (strncmp("rsa:",p,4) == 0 || is_numeric)
-				{
-				pkey_type=TYPE_RSA;
-				if(!is_numeric)
-				    p+=4;
-				newkey= atoi(p);
-				}
-			else
-#ifndef OPENSSL_NO_DSA
-				if (strncmp("dsa:",p,4) == 0)
-				{
-				X509 *xtmp=NULL;
-				EVP_PKEY *dtmp;
-
-				pkey_type=TYPE_DSA;
-				p+=4;
-				if ((in=BIO_new_file(p,"r")) == NULL)
-					{
-					perror(p);
-					goto end;
-					}
-				if ((dsa_params=PEM_read_bio_DSAparams(in,NULL,NULL,NULL)) == NULL)
-					{
-					ERR_clear_error();
-					(void)BIO_reset(in);
-					if ((xtmp=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
-						{
-						BIO_printf(bio_err,"unable to load DSA parameters from file\n");
-						goto end;
-						}
-
-					if ((dtmp=X509_get_pubkey(xtmp)) == NULL) goto end;
-					if (dtmp->type == EVP_PKEY_DSA)
-						dsa_params=DSAparams_dup(dtmp->pkey.dsa);
-					EVP_PKEY_free(dtmp);
-					X509_free(xtmp);
-					if (dsa_params == NULL)
-						{
-						BIO_printf(bio_err,"Certificate does not contain DSA parameters\n");
-						goto end;
-						}
-					}
-				BIO_free(in);
-				in=NULL;
-				newkey=BN_num_bits(dsa_params->p);
-				}
-			else 
-#endif
-#ifndef OPENSSL_NO_ECDSA
-				if (strncmp("ec:",p,3) == 0)
-				{
-				X509 *xtmp=NULL;
-				EVP_PKEY *dtmp;
-				EC_GROUP *group;
-
-				pkey_type=TYPE_EC;
-				p+=3;
-				if ((in=BIO_new_file(p,"r")) == NULL)
-					{
-					perror(p);
-					goto end;
-					}
-				if ((ec_params = EC_KEY_new()) == NULL)
-					goto end;
-				group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
-				if (group == NULL)
-					{
-					EC_KEY_free(ec_params);
-					ERR_clear_error();
-					(void)BIO_reset(in);
-					if ((xtmp=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
-						{	
-						BIO_printf(bio_err,"unable to load EC parameters from file\n");
-						goto end;
-						}
-
-					if ((dtmp=X509_get_pubkey(xtmp))==NULL)
-						goto end;
-					if (dtmp->type == EVP_PKEY_EC)
-						ec_params = EC_KEY_dup(dtmp->pkey.ec);
-					EVP_PKEY_free(dtmp);
-					X509_free(xtmp);
-					if (ec_params == NULL)
-						{
-						BIO_printf(bio_err,"Certificate does not contain EC parameters\n");
-						goto end;
-						}
-					}
-				else
-					{
-					if (EC_KEY_set_group(ec_params, group) == 0)
-						goto end;
-					EC_GROUP_free(group);
-					}
-
-				BIO_free(in);
-				in=NULL;
-				newkey = EC_GROUP_get_degree(EC_KEY_get0_group(ec_params));
-				}
-			else
-#endif
-#ifndef OPENSSL_NO_DH
-				if (strncmp("dh:",p,4) == 0)
-				{
-				pkey_type=TYPE_DH;
-				p+=3;
-				}
-			else
-#endif
-				{
+			if (--argc < 1)
 				goto bad;
-				}
-
+			keyalg = *(++argv);
 			newreq=1;
 			}
+		else if (strcmp(*argv,"-pkeyopt") == 0)
+			{
+			if (--argc < 1)
+				goto bad;
+			if (!pkeyopts)
+				pkeyopts = sk_OPENSSL_STRING_new_null();
+			if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, *(++argv)))
+				goto bad;
+			}
 		else if (strcmp(*argv,"-batch") == 0)
 			batch=1;
 		else if (strcmp(*argv,"-newhdr") == 0)
@@ -467,11 +365,6 @@
 			serial = s2i_ASN1_INTEGER(NULL, *(++argv));
 			if (!serial) goto bad;
 			}
-		else if ((md_alg=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
-			{
-			/* ok */
-			digest=md_alg;
-			}
 		else if (strcmp(*argv,"-extensions") == 0)
 			{
 			if (--argc < 1) goto bad;
@@ -482,6 +375,11 @@
 			if (--argc < 1) goto bad;
 			req_exts = *(++argv);
 			}
+		else if ((md_alg=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
+			{
+			/* ok */
+			digest=md_alg;
+			}
 		else
 			{
 			BIO_printf(bio_err,"unknown option %s\n",*argv);
@@ -730,15 +628,20 @@
 
 	if (newreq && (pkey == NULL))
 		{
-#ifndef OPENSSL_NO_RSA
-		BN_GENCB cb;
-#endif
 		char *randfile = NCONF_get_string(req_conf,SECTION,"RANDFILE");
 		if (randfile == NULL)
 			ERR_clear_error();
 		app_RAND_load_file(randfile, bio_err, 0);
 		if (inrand)
 			app_RAND_load_files(inrand);
+
+		if (keyalg)
+			{
+			genctx = set_keygen_ctx(bio_err, keyalg, &pkey_type, &newkey,
+							&keyalgstr, gen_eng);
+			if (!genctx)
+				goto end;
+			}
 	
 		if (newkey <= 0)
 			{
@@ -746,58 +649,55 @@
 				newkey=DEFAULT_KEY_LENGTH;
 			}
 
-		if (newkey < MIN_KEY_LENGTH && (pkey_type == TYPE_RSA || pkey_type == TYPE_DSA))
+		if (newkey < MIN_KEY_LENGTH && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA))
 			{
 			BIO_printf(bio_err,"private key length is too short,\n");
 			BIO_printf(bio_err,"it needs to be at least %d bits, not %ld\n",MIN_KEY_LENGTH,newkey);
 			goto end;
 			}
-		BIO_printf(bio_err,"Generating a %ld bit %s private key\n",
-			newkey,(pkey_type == TYPE_RSA)?"RSA":
-			(pkey_type == TYPE_DSA)?"DSA":"EC");
 
-		if ((pkey=EVP_PKEY_new()) == NULL) goto end;
-
-#ifndef OPENSSL_NO_RSA
-		BN_GENCB_set(&cb, req_cb, bio_err);
-		if (pkey_type == TYPE_RSA)
+		if (!genctx)
 			{
-			RSA *rsa = RSA_new();
-			BIGNUM *bn = BN_new();
-			if(!bn || !rsa || !BN_set_word(bn, 0x10001) ||
-					!RSA_generate_key_ex(rsa, newkey, bn, &cb) ||
-					!EVP_PKEY_assign_RSA(pkey, rsa))
+			genctx = set_keygen_ctx(bio_err, NULL, &pkey_type, &newkey,
+							&keyalgstr, gen_eng);
+			if (!genctx)
+				goto end;
+			}
+
+		if (pkeyopts)
+			{
+			char *genopt;
+			for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++)
 				{
-				if(bn) BN_free(bn);
-				if(rsa) RSA_free(rsa);
-				goto end;
+				genopt = sk_OPENSSL_STRING_value(pkeyopts, i);
+				if (pkey_ctrl_string(genctx, genopt) <= 0)
+					{
+					BIO_printf(bio_err,
+						"parameter error \"%s\"\n",
+						genopt);
+					ERR_print_errors(bio_err);
+					goto end;
+					}
 				}
-			BN_free(bn);
 			}
-		else
-#endif
-#ifndef OPENSSL_NO_DSA
-			if (pkey_type == TYPE_DSA)
+
+		BIO_printf(bio_err,"Generating a %ld bit %s private key\n",
+				newkey, keyalgstr);
+
+		EVP_PKEY_CTX_set_cb(genctx, genpkey_cb);
+		EVP_PKEY_CTX_set_app_data(genctx, bio_err);
+
+		if (EVP_PKEY_keygen(genctx, &pkey) <= 0)
 			{
-			if (!DSA_generate_key(dsa_params)) goto end;
-			if (!EVP_PKEY_assign_DSA(pkey,dsa_params)) goto end;
-			dsa_params=NULL;
+			BIO_puts(bio_err, "Error Generating Key\n");
+			goto end;
 			}
-#endif
-#ifndef OPENSSL_NO_ECDSA
-			if (pkey_type == TYPE_EC)
-			{
-			if (!EC_KEY_generate_key(ec_params)) goto end;
-			if (!EVP_PKEY_assign_EC_KEY(pkey, ec_params)) 
-				goto end;
-			ec_params = NULL;
-			}
-#endif
+
+		EVP_PKEY_CTX_free(genctx);
+		genctx = NULL;
 
 		app_RAND_write_file(randfile, bio_err);
 
-		if (pkey == NULL) goto end;
-
 		if (keyout == NULL)
 			{
 			keyout=NCONF_get_string(req_conf,SECTION,KEYFILE);
@@ -895,14 +795,7 @@
 			BIO_printf(bio_err,"you need to specify a private key\n");
 			goto end;
 			}
-#ifndef OPENSSL_NO_DSA
-		if (pkey->type == EVP_PKEY_DSA)
-			digest=EVP_dss1();
-#endif
-#ifndef OPENSSL_NO_ECDSA
-		if (pkey->type == EVP_PKEY_EC)
-			digest=EVP_ecdsa();
-#endif
+
 		if (req == NULL)
 			{
 			req=X509_REQ_new();
@@ -945,7 +838,7 @@
 
 			if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req))) goto end;
 			if (!X509_gmtime_adj(X509_get_notBefore(x509ss),0)) goto end;
-			if (!X509_gmtime_adj(X509_get_notAfter(x509ss), (long)60*60*24*days)) goto end;
+			if (!X509_time_adj_ex(X509_get_notAfter(x509ss), days, 0, NULL)) goto end;
 			if (!X509_set_subject_name(x509ss, X509_REQ_get_subject_name(req))) goto end;
 			tmppkey = X509_REQ_get_pubkey(req);
 			if (!tmppkey || !X509_set_pubkey(x509ss,tmppkey)) goto end;
@@ -967,7 +860,10 @@
 				}
 			
 			if (!(i=X509_sign(x509ss,pkey,digest)))
+				{
+				ERR_print_errors(bio_err);
 				goto end;
+				}
 			}
 		else
 			{
@@ -988,7 +884,10 @@
 				goto end;
 				}
 			if (!(i=X509_REQ_sign(req,pkey,digest)))
+				{
+				ERR_print_errors(bio_err);
 				goto end;
+				}
 			}
 		}
 
@@ -1125,7 +1024,7 @@
 			}
 		fprintf(stdout,"Modulus=");
 #ifndef OPENSSL_NO_RSA
-		if (tpubkey->type == EVP_PKEY_RSA)
+		if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA)
 			BN_print(out,tpubkey->pkey.rsa->n);
 		else
 #endif
@@ -1181,18 +1080,22 @@
 	BIO_free(in);
 	BIO_free_all(out);
 	EVP_PKEY_free(pkey);
+	if (genctx)
+		EVP_PKEY_CTX_free(genctx);
+	if (pkeyopts)
+		sk_OPENSSL_STRING_free(pkeyopts);
+#ifndef OPENSSL_NO_ENGINE
+	if (gen_eng)
+		ENGINE_free(gen_eng);
+#endif
+	if (keyalgstr)
+		OPENSSL_free(keyalgstr);
 	X509_REQ_free(req);
 	X509_free(x509ss);
 	ASN1_INTEGER_free(serial);
 	if(passargin && passin) OPENSSL_free(passin);
 	if(passargout && passout) OPENSSL_free(passout);
 	OBJ_cleanup();
-#ifndef OPENSSL_NO_DSA
-	if (dsa_params != NULL) DSA_free(dsa_params);
-#endif
-#ifndef OPENSSL_NO_ECDSA
-	if (ec_params != NULL) EC_KEY_free(ec_params);
-#endif
 	apps_shutdown();
 	OPENSSL_EXIT(ex);
 	}
@@ -1433,11 +1336,17 @@
 
 				BIO_snprintf(buf,sizeof buf,"%s_min",type);
 				if (!NCONF_get_number(req_conf,attr_sect,buf, &n_min))
+					{
+					ERR_clear_error();
 					n_min = -1;
+					}
 
 				BIO_snprintf(buf,sizeof buf,"%s_max",type);
 				if (!NCONF_get_number(req_conf,attr_sect,buf, &n_max))
+					{
+					ERR_clear_error();
 					n_max = -1;
+					}
 
 				if (!add_attribute_object(req,
 					v->value,def,value,nid,n_min,n_max, chtype))
@@ -1641,24 +1550,6 @@
 	return(0);
 	}
 
-#ifndef OPENSSL_NO_RSA
-static int MS_CALLBACK req_cb(int p, int n, BN_GENCB *cb)
-	{
-	char c='*';
-
-	if (p == 0) c='.';
-	if (p == 1) c='+';
-	if (p == 2) c='*';
-	if (p == 3) c='\n';
-	BIO_write(cb->arg,&c,1);
-	(void)BIO_flush(cb->arg);
-#ifdef LINT
-	p=n;
-#endif
-	return 1;
-	}
-#endif
-
 static int req_check_len(int len, int n_min, int n_max)
 	{
 	if ((n_min > 0) && (len < n_min))
@@ -1685,3 +1576,183 @@
 	tmp = str + slen - elen;
 	return strcmp(tmp, end);
 }
+
+static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, int *pkey_type,
+					long *pkeylen, char **palgnam,
+					ENGINE *keygen_engine)
+	{
+	EVP_PKEY_CTX *gctx = NULL;
+	EVP_PKEY *param = NULL;
+	long keylen = -1;
+	BIO *pbio = NULL;
+	const char *paramfile = NULL;
+
+	if (gstr == NULL)
+		{
+		*pkey_type = EVP_PKEY_RSA;
+		keylen = *pkeylen;
+		}
+	else if (gstr[0] >= '0' && gstr[0] <= '9')
+		{
+		*pkey_type = EVP_PKEY_RSA;
+		keylen = atol(gstr);
+		*pkeylen = keylen;
+		}
+	else if (!strncmp(gstr, "param:", 6))
+		paramfile = gstr + 6;
+	else
+		{
+		const char *p = strchr(gstr, ':');
+		int len;
+		ENGINE *tmpeng;
+		const EVP_PKEY_ASN1_METHOD *ameth;
+
+		if (p)
+			len = p - gstr;
+		else
+			len = strlen(gstr);
+		/* The lookup of a the string will cover all engines so
+		 * keep a note of the implementation.
+		 */
+
+		ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len);
+
+		if (!ameth)
+			{
+			BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr);
+			return NULL;
+			}
+
+		EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL,
+									ameth);
+#ifndef OPENSSL_NO_ENGINE
+		if (tmpeng)
+			ENGINE_finish(tmpeng);
+#endif
+		if (*pkey_type == EVP_PKEY_RSA)
+			{
+			if (p)
+				{
+				keylen = atol(p + 1);
+				*pkeylen = keylen;
+				}
+			}
+		else if (p)
+			paramfile = p + 1;
+		}
+
+	if (paramfile)
+		{
+		pbio = BIO_new_file(paramfile, "r");
+		if (!pbio)
+			{
+			BIO_printf(err, "Can't open parameter file %s\n",
+					paramfile);
+			return NULL;
+			}
+		param = PEM_read_bio_Parameters(pbio, NULL);
+
+		if (!param)
+			{
+			X509 *x;
+			(void)BIO_reset(pbio);
+			x = PEM_read_bio_X509(pbio, NULL, NULL, NULL);
+			if (x)
+				{
+				param = X509_get_pubkey(x);
+				X509_free(x);
+				}
+			}
+
+		BIO_free(pbio);
+
+		if (!param)
+			{
+			BIO_printf(err, "Error reading parameter file %s\n",
+					paramfile);
+			return NULL;
+			}
+		if (*pkey_type == -1)
+			*pkey_type = EVP_PKEY_id(param);
+		else if (*pkey_type != EVP_PKEY_base_id(param))
+			{
+			BIO_printf(err, "Key Type does not match parameters\n");
+			EVP_PKEY_free(param);
+			return NULL;
+			}
+		}
+
+	if (palgnam)
+		{
+		const EVP_PKEY_ASN1_METHOD *ameth;
+		ENGINE *tmpeng;
+		const char *anam;
+		ameth = EVP_PKEY_asn1_find(&tmpeng, *pkey_type);
+		if (!ameth)
+			{
+			BIO_puts(err, "Internal error: can't find key algorithm\n");
+			return NULL;
+			}
+		EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth);
+		*palgnam = BUF_strdup(anam);
+#ifndef OPENSSL_NO_ENGINE
+		if (tmpeng)
+			ENGINE_finish(tmpeng);
+#endif
+		}
+
+	if (param)
+		{
+		gctx = EVP_PKEY_CTX_new(param, keygen_engine);
+		*pkeylen = EVP_PKEY_bits(param);
+		EVP_PKEY_free(param);
+		}
+	else
+		gctx = EVP_PKEY_CTX_new_id(*pkey_type, keygen_engine);
+
+	if (!gctx)
+		{
+		BIO_puts(err, "Error allocating keygen context\n");
+		ERR_print_errors(err);
+		return NULL;
+		}
+
+	if (EVP_PKEY_keygen_init(gctx) <= 0)
+		{
+		BIO_puts(err, "Error initializing keygen context\n");
+		ERR_print_errors(err);
+		return NULL;
+		}
+#ifndef OPENSSL_NO_RSA
+	if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1))
+		{
+		if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0)
+			{
+			BIO_puts(err, "Error setting RSA keysize\n");
+			ERR_print_errors(err);
+			EVP_PKEY_CTX_free(gctx);
+			return NULL;
+			}
+		}
+#endif
+
+	return gctx;
+	}
+
+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/rsa.c b/apps/rsa.c
index 930f1f0..b3c8aff 100644
--- a/apps/rsa.c
+++ b/apps/rsa.c
@@ -115,6 +115,8 @@
 #endif
 	int modulus=0;
 
+	int pvk_encr = 2;
+
 	apps_startup();
 
 	if (bio_err == NULL)
@@ -177,6 +179,16 @@
 			pubin=1;
 		else if (strcmp(*argv,"-pubout") == 0)
 			pubout=1;
+		else if (strcmp(*argv,"-RSAPublicKey_in") == 0)
+			pubin = 2;
+		else if (strcmp(*argv,"-RSAPublicKey_out") == 0)
+			pubout = 2;
+		else if (strcmp(*argv,"-pvk-strong") == 0)
+			pvk_encr=2;
+		else if (strcmp(*argv,"-pvk-weak") == 0)
+			pvk_encr=1;
+		else if (strcmp(*argv,"-pvk-none") == 0)
+			pvk_encr=0;
 		else if (strcmp(*argv,"-noout") == 0)
 			noout=1;
 		else if (strcmp(*argv,"-text") == 0)
@@ -257,10 +269,23 @@
 		EVP_PKEY	*pkey;
 
 		if (pubin)
-			pkey = load_pubkey(bio_err, infile,
-				(informat == FORMAT_NETSCAPE && sgckey ?
-					FORMAT_IISSGC : informat), 1,
+			{
+			int tmpformat=-1;
+			if (pubin == 2)
+				{
+				if (informat == FORMAT_PEM)
+					tmpformat = FORMAT_PEMRSA;
+				else if (informat == FORMAT_ASN1)
+					tmpformat = FORMAT_ASN1RSA;
+				}
+			else if (informat == FORMAT_NETSCAPE && sgckey)
+				tmpformat = FORMAT_IISSGC;
+			else
+				tmpformat = informat;
+					
+			pkey = load_pubkey(bio_err, infile, tmpformat, 1,
 				passin, e, "Public Key");
+			}
 		else
 			pkey = load_key(bio_err, infile,
 				(informat == FORMAT_NETSCAPE && sgckey ?
@@ -268,7 +293,7 @@
 				passin, e, "Private Key");
 
 		if (pkey != NULL)
-		rsa = pkey == NULL ? NULL : EVP_PKEY_get1_RSA(pkey);
+			rsa = EVP_PKEY_get1_RSA(pkey);
 		EVP_PKEY_free(pkey);
 	}
 
@@ -346,7 +371,13 @@
 		}
 	BIO_printf(bio_err,"writing RSA key\n");
 	if 	(outformat == FORMAT_ASN1) {
-		if(pubout || pubin) i=i2d_RSA_PUBKEY_bio(out,rsa);
+		if(pubout || pubin) 
+			{
+			if (pubout == 2)
+				i=i2d_RSAPublicKey_bio(out,rsa);
+			else
+				i=i2d_RSA_PUBKEY_bio(out,rsa);
+			}
 		else i=i2d_RSAPrivateKey_bio(out,rsa);
 	}
 #ifndef OPENSSL_NO_RC4
@@ -370,14 +401,32 @@
 #endif
 	else if (outformat == FORMAT_PEM) {
 		if(pubout || pubin)
-		    i=PEM_write_bio_RSA_PUBKEY(out,rsa);
+			{
+			if (pubout == 2)
+		    		i=PEM_write_bio_RSAPublicKey(out,rsa);
+			else
+		    		i=PEM_write_bio_RSA_PUBKEY(out,rsa);
+			}
 		else i=PEM_write_bio_RSAPrivateKey(out,rsa,
 						enc,NULL,0,NULL,passout);
+#ifndef OPENSSL_NO_DSA
+	} else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) {
+		EVP_PKEY *pk;
+		pk = EVP_PKEY_new();
+		EVP_PKEY_set1_RSA(pk, rsa);
+		if (outformat == FORMAT_PVK)
+			i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout);
+		else if (pubin || pubout)
+			i = i2b_PublicKey_bio(out, pk);
+		else
+			i = i2b_PrivateKey_bio(out, pk);
+		EVP_PKEY_free(pk);
+#endif
 	} else	{
 		BIO_printf(bio_err,"bad output format specified for outfile\n");
 		goto end;
 		}
-	if (!i)
+	if (i <= 0)
 		{
 		BIO_printf(bio_err,"unable to write key\n");
 		ERR_print_errors(bio_err);
diff --git a/apps/rsautl.c b/apps/rsautl.c
index 923e2b6..b01f004 100644
--- a/apps/rsautl.c
+++ b/apps/rsautl.c
@@ -342,4 +342,10 @@
 
 }
 
+#else /* !OPENSSL_NO_RSA */
+
+# if PEDANTIC
+static void *dummy=&dummy;
+# endif
+
 #endif
diff --git a/apps/s_apps.h b/apps/s_apps.h
index f5a39ba..820e5c5 100644
--- a/apps/s_apps.h
+++ b/apps/s_apps.h
@@ -117,7 +117,7 @@
 #include <conio.h>
 #endif
 
-#ifdef OPENSSL_SYS_MSDOS
+#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32)
 #define _kbhit kbhit
 #endif
 
@@ -162,7 +162,7 @@
 int extract_host_port(char *str,char **host_ptr,unsigned char *ip,short *p);
 
 long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp,
-	int argi, long argl, long ret);
+				   int argi, long argl, long ret);
 
 #ifdef HEADER_SSL_H
 void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret);
diff --git a/apps/s_cb.c b/apps/s_cb.c
index 97caffc..c4f5512 100644
--- a/apps/s_cb.c
+++ b/apps/s_cb.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -126,12 +126,12 @@
 
 int verify_depth=0;
 int verify_error=X509_V_OK;
+int verify_return_error=0;
 unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
 int cookie_initialized=0;
 
 int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
 	{
-	char buf[256];
 	X509 *err_cert;
 	int err,depth;
 
@@ -139,15 +139,23 @@
 	err=	X509_STORE_CTX_get_error(ctx);
 	depth=	X509_STORE_CTX_get_error_depth(ctx);
 
-	X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof buf);
-	BIO_printf(bio_err,"depth=%d %s\n",depth,buf);
+	BIO_printf(bio_err,"depth=%d ",depth);
+	if (err_cert)
+		{
+		X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert),
+					0, XN_FLAG_ONELINE);
+		BIO_puts(bio_err, "\n");
+		}
+	else
+		BIO_puts(bio_err, "<no cert>\n");
 	if (!ok)
 		{
 		BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
 			X509_verify_cert_error_string(err));
 		if (verify_depth >= depth)
 			{
-			ok=1;
+			if (!verify_return_error)
+				ok=1;
 			verify_error=X509_V_OK;
 			}
 		else
@@ -156,25 +164,33 @@
 			verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
 			}
 		}
-	switch (ctx->error)
+	switch (err)
 		{
 	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
-		X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,sizeof buf);
-		BIO_printf(bio_err,"issuer= %s\n",buf);
+		BIO_puts(bio_err,"issuer= ");
+		X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert),
+					0, XN_FLAG_ONELINE);
+		BIO_puts(bio_err, "\n");
 		break;
 	case X509_V_ERR_CERT_NOT_YET_VALID:
 	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
 		BIO_printf(bio_err,"notBefore=");
-		ASN1_TIME_print(bio_err,X509_get_notBefore(ctx->current_cert));
+		ASN1_TIME_print(bio_err,X509_get_notBefore(err_cert));
 		BIO_printf(bio_err,"\n");
 		break;
 	case X509_V_ERR_CERT_HAS_EXPIRED:
 	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
 		BIO_printf(bio_err,"notAfter=");
-		ASN1_TIME_print(bio_err,X509_get_notAfter(ctx->current_cert));
+		ASN1_TIME_print(bio_err,X509_get_notAfter(err_cert));
 		BIO_printf(bio_err,"\n");
 		break;
+	case X509_V_ERR_NO_EXPLICIT_POLICY:
+		policies_print(bio_err, ctx);
+		break;
 		}
+	if (err == X509_V_OK && ok == 2)
+		policies_print(bio_err, ctx);
+
 	BIO_printf(bio_err,"verify return:%d\n",ok);
 	return(ok);
 	}
@@ -263,7 +279,7 @@
 	}
 
 long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp,
-	int argi, long argl, long ret)
+				   int argi, long argl, long ret)
 	{
 	BIO *out;
 
@@ -272,15 +288,15 @@
 
 	if (cmd == (BIO_CB_READ|BIO_CB_RETURN))
 		{
-		BIO_printf(out,"read from %p [%p] (%d bytes => %ld (0x%lX))\n",
- 			(void *)bio,argp,argi,ret,ret);
+		BIO_printf(out,"read from %p [%p] (%lu bytes => %ld (0x%lX))\n",
+ 			(void *)bio,argp,(unsigned long)argi,ret,ret);
 		BIO_dump(out,argp,(int)ret);
 		return(ret);
 		}
 	else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN))
 		{
-		BIO_printf(out,"write to %p [%p] (%d bytes => %ld (0x%lX))\n",
-			(void *)bio,argp,argi,ret,ret);
+		BIO_printf(out,"write to %p [%p] (%lu bytes => %ld (0x%lX))\n",
+			(void *)bio,argp,(unsigned long)argi,ret,ret);
 		BIO_dump(out,argp,(int)ret);
 		}
 	return(ret);
@@ -341,14 +357,14 @@
 	case TLS1_VERSION:
 		str_version = "TLS 1.0 ";
 		break;
-	default:
-		str_version = "???";
 	case DTLS1_VERSION:
 		str_version = "DTLS 1.0 ";
 		break;
 	case DTLS1_BAD_VER:
 		str_version = "DTLS 1.0 (bad) ";
 		break;
+	default:
+		str_version = "???";
 		}
 
 	if (version == SSL2_VERSION)
@@ -518,6 +534,21 @@
 				case 100:
 					str_details2 = " no_renegotiation";
 					break;
+				case 110:
+					str_details2 = " unsupported_extension";
+					break;
+				case 111:
+					str_details2 = " certificate_unobtainable";
+					break;
+				case 112:
+					str_details2 = " unrecognized_name";
+					break;
+				case 113:
+					str_details2 = " bad_certificate_status_response";
+					break;
+				case 114:
+					str_details2 = " bad_certificate_hash_value";
+					break;
 					}
 				}
 			}
@@ -539,6 +570,9 @@
 				case 2:
 					str_details1 = ", ServerHello";
 					break;
+				case 3:
+					str_details1 = ", HelloVerifyRequest";
+					break;
 				case 11:
 					str_details1 = ", Certificate";
 					break;
@@ -554,9 +588,6 @@
 				case 15:
 					str_details1 = ", CertificateVerify";
 					break;
-				case 3:
-					str_details1 = ", HelloVerifyRequest";
-					break;
 				case 16:
 					str_details1 = ", ClientKeyExchange";
 					break;
@@ -642,6 +673,12 @@
 		extname = "renegotiate";
 		break;
 
+#ifdef TLSEXT_TYPE_opaque_prf_input
+		case TLSEXT_TYPE_opaque_prf_input:
+		extname = "opaque PRF input";
+		break;
+#endif
+
 		default:
 		extname = "unknown";
 		break;
@@ -659,8 +696,14 @@
 	{
 	unsigned char *buffer, result[EVP_MAX_MD_SIZE];
 	unsigned int length, resultlength;
-	struct sockaddr_in peer;
-	
+	union {
+		struct sockaddr sa;
+		struct sockaddr_in s4;
+#if OPENSSL_USE_IPV6
+		struct sockaddr_in6 s6;
+#endif
+	} peer;
+
 	/* Initialize a random secret */
 	if (!cookie_initialized)
 		{
@@ -676,8 +719,23 @@
 	(void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
 
 	/* Create buffer with peer's address and port */
-	length = sizeof(peer.sin_addr);
-	length += sizeof(peer.sin_port);
+	length = 0;
+	switch (peer.sa.sa_family)
+		{
+	case AF_INET:
+		length += sizeof(struct in_addr);
+		length += sizeof(peer.s4.sin_port);
+		break;
+#if OPENSSL_USE_IPV6
+	case AF_INET6:
+		length += sizeof(struct in6_addr);
+		length += sizeof(peer.s6.sin6_port);
+		break;
+#endif
+	default:
+		OPENSSL_assert(0);
+		break;
+		}
 	buffer = OPENSSL_malloc(length);
 
 	if (buffer == NULL)
@@ -685,9 +743,31 @@
 		BIO_printf(bio_err,"out of memory\n");
 		return 0;
 		}
-	
-	memcpy(buffer, &peer.sin_addr, sizeof(peer.sin_addr));
-	memcpy(buffer + sizeof(peer.sin_addr), &peer.sin_port, sizeof(peer.sin_port));
+
+	switch (peer.sa.sa_family)
+		{
+	case AF_INET:
+		memcpy(buffer,
+		       &peer.s4.sin_port,
+		       sizeof(peer.s4.sin_port));
+		memcpy(buffer + sizeof(peer.s4.sin_port),
+		       &peer.s4.sin_addr,
+		       sizeof(struct in_addr));
+		break;
+#if OPENSSL_USE_IPV6
+	case AF_INET6:
+		memcpy(buffer,
+		       &peer.s6.sin6_port,
+		       sizeof(peer.s6.sin6_port));
+		memcpy(buffer + sizeof(peer.s6.sin6_port),
+		       &peer.s6.sin6_addr,
+		       sizeof(struct in6_addr));
+		break;
+#endif
+	default:
+		OPENSSL_assert(0);
+		break;
+		}
 
 	/* Calculate HMAC of buffer using the secret */
 	HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
@@ -704,8 +784,14 @@
 	{
 	unsigned char *buffer, result[EVP_MAX_MD_SIZE];
 	unsigned int length, resultlength;
-	struct sockaddr_in peer;
-	
+	union {
+		struct sockaddr sa;
+		struct sockaddr_in s4;
+#if OPENSSL_USE_IPV6
+		struct sockaddr_in6 s6;
+#endif
+	} peer;
+
 	/* If secret isn't initialized yet, the cookie can't be valid */
 	if (!cookie_initialized)
 		return 0;
@@ -714,24 +800,61 @@
 	(void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
 
 	/* Create buffer with peer's address and port */
-	length = sizeof(peer.sin_addr);
-	length += sizeof(peer.sin_port);
-	buffer = (unsigned char*) OPENSSL_malloc(length);
+	length = 0;
+	switch (peer.sa.sa_family)
+		{
+	case AF_INET:
+		length += sizeof(struct in_addr);
+		length += sizeof(peer.s4.sin_port);
+		break;
+#if OPENSSL_USE_IPV6
+	case AF_INET6:
+		length += sizeof(struct in6_addr);
+		length += sizeof(peer.s6.sin6_port);
+		break;
+#endif
+	default:
+		OPENSSL_assert(0);
+		break;
+		}
+	buffer = OPENSSL_malloc(length);
 	
 	if (buffer == NULL)
 		{
 		BIO_printf(bio_err,"out of memory\n");
 		return 0;
 		}
-	
-	memcpy(buffer, &peer.sin_addr, sizeof(peer.sin_addr));
-	memcpy(buffer + sizeof(peer.sin_addr), &peer.sin_port, sizeof(peer.sin_port));
+
+	switch (peer.sa.sa_family)
+		{
+	case AF_INET:
+		memcpy(buffer,
+		       &peer.s4.sin_port,
+		       sizeof(peer.s4.sin_port));
+		memcpy(buffer + sizeof(peer.s4.sin_port),
+		       &peer.s4.sin_addr,
+		       sizeof(struct in_addr));
+		break;
+#if OPENSSL_USE_IPV6
+	case AF_INET6:
+		memcpy(buffer,
+		       &peer.s6.sin6_port,
+		       sizeof(peer.s6.sin6_port));
+		memcpy(buffer + sizeof(peer.s6.sin6_port),
+		       &peer.s6.sin6_addr,
+		       sizeof(struct in6_addr));
+		break;
+#endif
+	default:
+		OPENSSL_assert(0);
+		break;
+		}
 
 	/* Calculate HMAC of buffer using the secret */
 	HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
 	     buffer, length, result, &resultlength);
 	OPENSSL_free(buffer);
-	
+
 	if (cookie_len == resultlength && memcmp(result, cookie, resultlength) == 0)
 		return 1;
 
diff --git a/apps/s_client.c b/apps/s_client.c
index 2f743f0..fd5f35e 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -108,8 +108,35 @@
  * Hudson (tjh@cryptsoft.com).
  *
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 #include <assert.h>
+#include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -135,23 +162,19 @@
 #include <openssl/pem.h>
 #include <openssl/rand.h>
 #include <openssl/ocsp.h>
+#include <openssl/bn.h>
 #include "s_apps.h"
 #include "timeouts.h"
 
-#ifdef OPENSSL_SYS_WINCE
-/* Windows CE incorrectly defines fileno as returning void*, so to avoid problems below... */
-#ifdef fileno
-#undef fileno
-#endif
-#define fileno(a) (int)_fileno(a)
-#endif
-
-
 #if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
 /* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
 #undef FIONBIO
 #endif
 
+#if defined(OPENSSL_SYS_BEOS_R5)
+#include <fcntl.h>
+#endif
+
 #undef PROG
 #define PROG	s_client_main
 
@@ -166,6 +189,7 @@
 
 extern int verify_depth;
 extern int verify_error;
+extern int verify_return_error;
 
 #ifdef FIONBIO
 static int c_nbio=0;
@@ -188,6 +212,72 @@
 static int c_quiet=0;
 static int c_ign_eof=0;
 
+#ifndef OPENSSL_NO_PSK
+/* Default PSK identity and key */
+static char *psk_identity="Client_identity";
+/*char *psk_key=NULL;  by default PSK is not used */
+#if 1 /* ANDROID */
+char *psk_key=NULL;
+#endif
+
+static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity,
+	unsigned int max_identity_len, unsigned char *psk,
+	unsigned int max_psk_len)
+	{
+	unsigned int psk_len = 0;
+	int ret;
+        BIGNUM *bn=NULL;
+
+	if (c_debug)
+		BIO_printf(bio_c_out, "psk_client_cb\n");
+	if (!hint)
+                {
+                /* no ServerKeyExchange message*/
+		if (c_debug)
+			BIO_printf(bio_c_out,"NULL received PSK identity hint, continuing anyway\n");
+                }
+        else if (c_debug)
+		BIO_printf(bio_c_out, "Received PSK identity hint '%s'\n", hint);
+
+	/* lookup PSK identity and PSK key based on the given identity hint here */
+	ret = BIO_snprintf(identity, max_identity_len, "%s", psk_identity);
+	if (ret < 0 || (unsigned int)ret > max_identity_len)
+		goto out_err;
+	if (c_debug)
+		BIO_printf(bio_c_out, "created identity '%s' len=%d\n", identity, ret);
+        ret=BN_hex2bn(&bn, psk_key);
+        if (!ret)
+                {
+                BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", psk_key);
+                if (bn)
+                        BN_free(bn);
+                return 0;
+                }
+
+        if ((unsigned int)BN_num_bytes(bn) > max_psk_len)
+                {
+                BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n",
+                        max_psk_len, BN_num_bytes(bn));
+                BN_free(bn);
+                return 0;
+                }
+
+        psk_len=BN_bn2bin(bn, psk);
+        BN_free(bn);
+        if (psk_len == 0)
+                goto out_err;
+
+	if (c_debug)
+		BIO_printf(bio_c_out, "created PSK len=%d\n", psk_len);
+
+        return psk_len;
+ out_err:
+	if (c_debug)
+		BIO_printf(bio_err, "Error in PSK client callback\n");
+        return 0;
+	}
+#endif
+
 static void sc_usage(void)
 	{
 	BIO_printf(bio_err,"usage: s_client args\n");
@@ -196,7 +286,7 @@
 	BIO_printf(bio_err," -port port     - use -connect instead\n");
 	BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR);
 
-	BIO_printf(bio_err," -verify depth - turn on peer certificate verification\n");
+	BIO_printf(bio_err," -verify arg   - turn on peer certificate verification\n");
 	BIO_printf(bio_err," -cert arg     - certificate file to use, PEM format assumed\n");
 	BIO_printf(bio_err," -certform arg - certificate format (PEM or DER) PEM default\n");
 	BIO_printf(bio_err," -key arg      - Private key file to use, in cert file if\n");
@@ -222,6 +312,13 @@
 	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");
+#ifndef OPENSSL_NO_PSK
+	BIO_printf(bio_err," -psk_identity arg - PSK identity\n");
+	BIO_printf(bio_err," -psk arg      - PSK in hex (without 0x)\n");
+# ifndef OPENSSL_NO_JPAKE
+	BIO_printf(bio_err," -jpake arg    - JPAKE secret to use\n");
+# endif
+#endif
 	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");
@@ -273,6 +370,7 @@
 	return SSL_TLSEXT_ERR_OK;
 	}
 #endif
+
 enum
 {
 	PROTO_OFF	= 0,
@@ -287,9 +385,8 @@
 
 int MAIN(int argc, char **argv)
 	{
-	int off=0, clr = 0;
-	SSL *con=NULL,*con2=NULL;
-	X509_STORE *store = NULL;
+	unsigned int off=0, clr=0;
+	SSL *con=NULL;
 	int s,k,width,state=0;
 	char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL;
 	int cbuf_len,cbuf_off;
@@ -310,12 +407,11 @@
 	SSL_CTX *ctx=NULL;
 	int ret=1,in_init=1,i,nbio_test=0;
 	int starttls_proto = PROTO_OFF;
-	int prexit = 0, vflags = 0;
-	SSL_METHOD *meth=NULL;
-#ifdef sock_type
-#undef sock_type
-#endif
-	int sock_type=SOCK_STREAM;
+	int prexit = 0;
+	X509_VERIFY_PARAM *vpm = NULL;
+	int badarg = 0;
+	const SSL_METHOD *meth=NULL;
+	int socket_type=SOCK_STREAM;
 	BIO *sbio;
 	char *inrand=NULL;
 	int mbuf_len=0;
@@ -326,10 +422,12 @@
 	ENGINE *ssl_client_engine=NULL;
 #endif
 	ENGINE *e=NULL;
-#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
 	struct timeval tv;
+#if defined(OPENSSL_SYS_BEOS_R5)
+	int stdin_set = 0;
 #endif
-
+#endif
 #ifndef OPENSSL_NO_TLSEXT
 	char *servername = NULL; 
         tlsextctx tlsextcbp = 
@@ -429,10 +527,14 @@
 			if (--argc < 1) goto bad;
 			cert_format = str2fmt(*(++argv));
 			}
-		else if	(strcmp(*argv,"-crl_check") == 0)
-			vflags |= X509_V_FLAG_CRL_CHECK;
-		else if	(strcmp(*argv,"-crl_check_all") == 0)
-			vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
+		else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm))
+			{
+			if (badarg)
+				goto bad;
+			continue;
+			}
+		else if (strcmp(*argv,"-verify_return_error") == 0)
+			verify_return_error = 1;
 		else if	(strcmp(*argv,"-prexit") == 0)
 			prexit=1;
 		else if	(strcmp(*argv,"-crlf") == 0)
@@ -468,6 +570,27 @@
 			nbio_test=1;
 		else if	(strcmp(*argv,"-state") == 0)
 			state=1;
+#ifndef OPENSSL_NO_PSK
+                else if (strcmp(*argv,"-psk_identity") == 0)
+			{
+			if (--argc < 1) goto bad;
+			psk_identity=*(++argv);
+			}
+                else if (strcmp(*argv,"-psk") == 0)
+			{
+                        size_t j;
+
+			if (--argc < 1) goto bad;
+			psk_key=*(++argv);
+			for (j = 0; j < strlen(psk_key); j++)
+                                {
+                                if (isxdigit((int)psk_key[j]))
+                                        continue;
+                                BIO_printf(bio_err,"Not a hex number '%s'\n",*argv);
+                                goto bad;
+                                }
+			}
+#endif
 #ifndef OPENSSL_NO_SSL2
 		else if	(strcmp(*argv,"-ssl2") == 0)
 			meth=SSLv2_client_method();
@@ -484,7 +607,7 @@
 		else if	(strcmp(*argv,"-dtls1") == 0)
 			{
 			meth=DTLSv1_client_method();
-			sock_type=SOCK_DGRAM;
+			socket_type=SOCK_DGRAM;
 			}
 		else if (strcmp(*argv,"-timeout") == 0)
 			enable_timeouts=1;
@@ -531,6 +654,8 @@
 			off|=SSL_OP_NO_SSLv3;
 		else if (strcmp(*argv,"-no_ssl2") == 0)
 			off|=SSL_OP_NO_SSLv2;
+		else if	(strcmp(*argv,"-no_comp") == 0)
+			{ off|=SSL_OP_NO_COMPRESSION; }
 #ifndef OPENSSL_NO_TLSEXT
 		else if	(strcmp(*argv,"-no_ticket") == 0)
 			{ off|=SSL_OP_NO_TICKET; }
@@ -617,6 +742,26 @@
 		goto end;
 		}
 
+#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
+	if (jpake_secret)
+		{
+		if (psk_key)
+			{
+			BIO_printf(bio_err,
+				   "Can't use JPAKE and PSK together\n");
+			goto end;
+			}
+		psk_identity = "JPAKE";
+		}
+
+	if (cipher)
+		{
+		BIO_printf(bio_err, "JPAKE sets cipher to PSK\n");
+		goto end;
+		}
+	cipher = "PSK";
+#endif
+
 	OpenSSL_add_ssl_algorithms();
 	SSL_load_error_strings();
 
@@ -632,6 +777,7 @@
 			goto end;
 			}
 		}
+
 #endif
 	if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
 		{
@@ -699,6 +845,9 @@
 		goto end;
 		}
 
+	if (vpm)
+		SSL_CTX_set1_param(ctx, vpm);
+
 #ifndef OPENSSL_NO_ENGINE
 	if (ssl_client_engine)
 		{
@@ -713,6 +862,18 @@
 		}
 #endif
 
+#ifndef OPENSSL_NO_PSK
+#ifdef OPENSSL_NO_JPAKE
+	if (psk_key != NULL)
+#else
+	if (psk_key != NULL || jpake_secret)
+#endif
+		{
+		if (c_debug)
+			BIO_printf(bio_c_out, "PSK key given or JPAKE in use, setting client callback\n");
+		SSL_CTX_set_psk_client_callback(ctx, psk_client_cb);
+		}
+#endif
 	if (bugs)
 		SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
 	else
@@ -723,7 +884,7 @@
 	/* DTLS: partial reads end up discarding unread UDP bytes :-( 
 	 * Setting read ahead solves this problem.
 	 */
-	if (sock_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
+	if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
 
 	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
 	if (cipher != NULL)
@@ -749,8 +910,6 @@
 		/* goto end; */
 		}
 
-	store = SSL_CTX_get_cert_store(ctx);
-	X509_STORE_set_flags(store, vflags);
 #ifndef OPENSSL_NO_TLSEXT
 	if (servername != NULL)
 		{
@@ -795,7 +954,6 @@
 			}
 		}
 #endif
-
 #ifndef OPENSSL_NO_KRB5
 	if (con  &&  (con->kssl_ctx = kssl_ctx_new()) != NULL)
                 {
@@ -803,10 +961,15 @@
 		}
 #endif	/* OPENSSL_NO_KRB5  */
 /*	SSL_set_cipher_list(con,"RC4-MD5"); */
+#if 0
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	SSL_set_tlsext_opaque_prf_input(con, "Test client", 11);
+#endif
+#endif
 
 re_start:
 
-	if (init_client(&s,host,port,sock_type) == 0)
+	if (init_client(&s,host,port,socket_type) == 0)
 		{
 		BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
 		SHUTDOWN(s);
@@ -842,7 +1005,7 @@
 
 		(void)BIO_ctrl_set_connected(sbio, 1, &peer);
 
-		if ( enable_timeouts)
+		if (enable_timeouts)
 			{
 			timeout.tv_sec = 0;
 			timeout.tv_usec = DGRAM_RCV_TIMEOUT;
@@ -1063,6 +1226,14 @@
 			if (in_init)
 				{
 				in_init=0;
+#if 0 /* This test doesn't really work as intended (needs to be fixed) */
+#ifndef OPENSSL_NO_TLSEXT
+				if (servername != NULL && !SSL_session_reused(con))
+					{
+					BIO_printf(bio_c_out,"Server did %sacknowledge servername extension.\n",tlsextcbp.ack?"":"not ");
+					}
+#endif
+#endif
 				if (sess_out)
 					{
 					BIO *stmp = BIO_new_file(sess_out, "w");
@@ -1100,22 +1271,22 @@
 
 		if (!ssl_pending)
 			{
-#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE)
+#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined (OPENSSL_SYS_BEOS_R5)
 			if (tty_on)
 				{
-				if (read_tty)  FD_SET(fileno(stdin),&readfds);
-				if (write_tty) FD_SET(fileno(stdout),&writefds);
+				if (read_tty)  openssl_fdset(fileno(stdin),&readfds);
+				if (write_tty) openssl_fdset(fileno(stdout),&writefds);
 				}
 			if (read_ssl)
-				FD_SET(SSL_get_fd(con),&readfds);
+				openssl_fdset(SSL_get_fd(con),&readfds);
 			if (write_ssl)
-				FD_SET(SSL_get_fd(con),&writefds);
+				openssl_fdset(SSL_get_fd(con),&writefds);
 #else
 			if(!tty_on || !write_tty) {
 				if (read_ssl)
-					FD_SET(SSL_get_fd(con),&readfds);
+					openssl_fdset(SSL_get_fd(con),&readfds);
 				if (write_ssl)
-					FD_SET(SSL_get_fd(con),&writefds);
+					openssl_fdset(SSL_get_fd(con),&writefds);
 			}
 #endif
 /*			printf("mode tty(%d %d%d) ssl(%d%d)\n",
@@ -1160,6 +1331,25 @@
 				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
 					NULL,timeoutp);
 			}
+#elif defined(OPENSSL_SYS_BEOS_R5)
+			/* Under BeOS-R5 the situation is similar to DOS */
+			i=0;
+			stdin_set = 0;
+			(void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
+			if(!write_tty) {
+				if(read_tty) {
+					tv.tv_sec = 1;
+					tv.tv_usec = 0;
+					i=select(width,(void *)&readfds,(void *)&writefds,
+						 NULL,&tv);
+					if (read(fileno(stdin), sbuf, 0) >= 0)
+						stdin_set = 1;
+					if (!i && (stdin_set != 1 || !read_tty))
+						continue;
+				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
+					 NULL,timeoutp);
+			}
+			(void)fcntl(fileno(stdin), F_SETFL, 0);
 #else
 			i=select(width,(void *)&readfds,(void *)&writefds,
 				 NULL,timeoutp);
@@ -1218,6 +1408,7 @@
 				if (cbuf_len != 0)
 					{
 					BIO_printf(bio_c_out,"shutdown\n");
+					ret = 0;
 					goto shut;
 					}
 				else
@@ -1245,8 +1436,8 @@
 				goto shut;
 				}
 			}
-#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
-		/* Assume Windows/DOS can always write */
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
+		/* Assume Windows/DOS/BeOS can always write */
 		else if (!ssl_pending && write_tty)
 #else
 		else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds))
@@ -1255,11 +1446,12 @@
 #ifdef CHARSET_EBCDIC
 			ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len);
 #endif
-			i=write(fileno(stdout),&(sbuf[sbuf_off]),sbuf_len);
+			i=raw_write_stdout(&(sbuf[sbuf_off]),sbuf_len);
 
 			if (i <= 0)
 				{
 				BIO_printf(bio_c_out,"DONE\n");
+				ret = 0;
 				goto shut;
 				/* goto end; */
 				}
@@ -1314,10 +1506,12 @@
 				BIO_printf(bio_c_out,"read X BLOCK\n");
 				break;
 			case SSL_ERROR_SYSCALL:
-				BIO_printf(bio_err,"read:errno=%d\n",get_last_socket_error());
+				ret=get_last_socket_error();
+				BIO_printf(bio_err,"read:errno=%d\n",ret);
 				goto shut;
 			case SSL_ERROR_ZERO_RETURN:
 				BIO_printf(bio_c_out,"closed\n");
+				ret=0;
 				goto shut;
 			case SSL_ERROR_SSL:
 				ERR_print_errors(bio_err);
@@ -1333,7 +1527,9 @@
 		else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
 #endif
 #elif defined (OPENSSL_SYS_NETWARE)
-        else if (_kbhit())
+		else if (_kbhit())
+#elif defined(OPENSSL_SYS_BEOS_R5)
+		else if (stdin_set)
 #else
 		else if (FD_ISSET(fileno(stdin),&readfds))
 #endif
@@ -1342,7 +1538,7 @@
 				{
 				int j, lf_num;
 
-				i=read(fileno(stdin),cbuf,BUFSIZZ/2);
+				i=raw_read_stdin(cbuf,BUFSIZZ/2);
 				lf_num = 0;
 				/* both loops are skipped when i <= 0 */
 				for (j = 0; j < i; j++)
@@ -1361,11 +1557,12 @@
 				assert(lf_num == 0);
 				}
 			else
-				i=read(fileno(stdin),cbuf,BUFSIZZ);
+				i=raw_read_stdin(cbuf,BUFSIZZ);
 
 			if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q')))
 				{
 				BIO_printf(bio_err,"DONE\n");
+				ret=0;
 				goto shut;
 				}
 
@@ -1388,14 +1585,20 @@
 			read_tty=0;
 			}
 		}
+
+	ret=0;
 shut:
+	if (in_init)
+		print_stuff(bio_c_out,con,full_log);
 	SSL_shutdown(con);
 	SHUTDOWN(SSL_get_fd(con));
-	ret=0;
 end:
-	if(prexit) print_stuff(bio_c_out,con,1);
-	if (con != NULL) SSL_free(con);
-	if (con2 != NULL) SSL_free(con2);
+	if (con != NULL)
+		{
+		if (prexit != 0)
+			print_stuff(bio_c_out,con,1);
+		SSL_free(con);
+		}
 	if (ctx != NULL) SSL_CTX_free(ctx);
 	if (cert)
 		X509_free(cert);
@@ -1424,7 +1627,7 @@
 	char buf[BUFSIZ];
 	STACK_OF(X509) *sk;
 	STACK_OF(X509_NAME) *sk2;
-	SSL_CIPHER *c;
+	const SSL_CIPHER *c;
 	X509_NAME *xn;
 	int j,i;
 #ifndef OPENSSL_NO_COMP
@@ -1577,4 +1780,5 @@
 	OCSP_RESPONSE_free(rsp);
 	return 1;
 	}
-#endif  /* ndef OPENSSL_NO_TLSEXT */
+
+#endif
diff --git a/apps/s_server.c b/apps/s_server.c
index 88b308c..1a06d19 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -113,6 +113,32 @@
  * ECC cipher suite support in OpenSSL originally developed by 
  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 /* Until the key-gen callbacks are modified to use newer prototypes, we allow
  * deprecated functions for openssl-internal code */
@@ -121,11 +147,11 @@
 #endif
 
 #include <assert.h>
+#include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-#include <sys/stat.h>
 #include <openssl/e_os2.h>
 #ifdef OPENSSL_NO_STDIO
 #define APPS_WIN16
@@ -163,19 +189,15 @@
 #include "s_apps.h"
 #include "timeouts.h"
 
-#ifdef OPENSSL_SYS_WINCE
-/* Windows CE incorrectly defines fileno as returning void*, so to avoid problems below... */
-#ifdef fileno
-#undef fileno
-#endif
-#define fileno(a) (int)_fileno(a)
-#endif
-
 #if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
 /* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
 #undef FIONBIO
 #endif
 
+#if defined(OPENSSL_SYS_BEOS_R5)
+#include <fcntl.h>
+#endif
+
 #ifndef OPENSSL_NO_RSA
 static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength);
 #endif
@@ -196,14 +218,6 @@
 static void s_server_init(void);
 #endif
 
-#ifndef S_ISDIR
-# if defined(_S_IFMT) && defined(_S_IFDIR)
-#  define S_ISDIR(a)	(((a) & _S_IFMT) == _S_IFDIR)
-# else
-#  define S_ISDIR(a)	(((a) & S_IFMT) == S_IFDIR)
-# endif
-#endif
-
 #ifndef OPENSSL_NO_DH
 static unsigned char dh512_p[]={
 	0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
@@ -245,7 +259,7 @@
 #undef PROG
 #define PROG		s_server_main
 
-extern int verify_depth;
+extern int verify_depth, verify_return_error;
 
 static char *cipher=NULL;
 static int s_server_verify=SSL_VERIFY_NONE;
@@ -288,6 +302,72 @@
 static int cert_chain = 0;
 #endif
 
+#ifndef OPENSSL_NO_PSK
+static char *psk_identity="Client_identity";
+char *psk_key=NULL; /* by default PSK is not used */
+
+static unsigned int psk_server_cb(SSL *ssl, const char *identity,
+	unsigned char *psk, unsigned int max_psk_len)
+	{
+	unsigned int psk_len = 0;
+	int ret;
+	BIGNUM *bn = NULL;
+
+	if (s_debug)
+		BIO_printf(bio_s_out,"psk_server_cb\n");
+	if (!identity)
+		{
+		BIO_printf(bio_err,"Error: client did not send PSK identity\n");
+		goto out_err;
+		}
+	if (s_debug)
+		BIO_printf(bio_s_out,"identity_len=%d identity=%s\n",
+			identity ? (int)strlen(identity) : 0, identity);
+
+	/* here we could lookup the given identity e.g. from a database */
+  	if (strcmp(identity, psk_identity) != 0)
+		{
+                BIO_printf(bio_s_out, "PSK error: client identity not found"
+			   " (got '%s' expected '%s')\n", identity,
+			   psk_identity);
+		goto out_err;
+                }
+	if (s_debug)
+		BIO_printf(bio_s_out, "PSK client identity found\n");
+
+	/* convert the PSK key to binary */
+	ret = BN_hex2bn(&bn, psk_key);
+	if (!ret)
+		{
+		BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", psk_key);
+		if (bn)
+			BN_free(bn);
+		return 0;
+		}
+	if (BN_num_bytes(bn) > (int)max_psk_len)
+		{
+		BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n",
+			max_psk_len, BN_num_bytes(bn));
+		BN_free(bn);
+		return 0;
+		}
+
+	ret = BN_bn2bin(bn, psk);
+	BN_free(bn);
+
+	if (ret < 0)
+		goto out_err;
+	psk_len = (unsigned int)ret;
+
+	if (s_debug)
+		BIO_printf(bio_s_out, "fetched PSK len=%d\n", psk_len);
+        return psk_len;
+ out_err:
+	if (s_debug)
+		BIO_printf(bio_err, "Error in PSK server callback\n");
+	return 0;
+        }
+#endif
 
 #ifdef MONOLITH
 static void s_server_init(void)
@@ -352,7 +432,7 @@
 #ifndef OPENSSL_NO_ECDH
 	BIO_printf(bio_err," -named_curve arg  - Elliptic curve name to use for ephemeral ECDH keys.\n" \
 	                   "                 Use \"openssl ecparam -list_curves\" for all names\n" \
-	                   "                 (default is sect163r2).\n");
+	                   "                 (default is nistp256).\n");
 #endif
 #ifdef FIONBIO
 	BIO_printf(bio_err," -nbio         - Run with non-blocking IO\n");
@@ -369,6 +449,13 @@
 	BIO_printf(bio_err," -serverpref   - Use server's cipher preferences\n");
 	BIO_printf(bio_err," -quiet        - No server output\n");
 	BIO_printf(bio_err," -no_tmp_rsa   - Do not generate a tmp RSA key\n");
+#ifndef OPENSSL_NO_PSK
+	BIO_printf(bio_err," -psk_hint arg - PSK identity hint to use\n");
+	BIO_printf(bio_err," -psk arg      - PSK in hex (without 0x)\n");
+# ifndef OPENSSL_NO_JPAKE
+	BIO_printf(bio_err," -jpake arg    - JPAKE secret to use\n");
+# endif
+#endif
 	BIO_printf(bio_err," -ssl2         - Just talk SSLv2\n");
 	BIO_printf(bio_err," -ssl3         - Just talk SSLv3\n");
 	BIO_printf(bio_err," -tls1         - Just talk TLSv1\n");
@@ -587,7 +674,7 @@
 			return p->extension_error;
 		if (ctx2)
 			{
-			BIO_printf(p->biodebug,"Swiching server context.\n");
+			BIO_printf(p->biodebug,"Switching server context.\n");
 			SSL_set_SSL_CTX(s,ctx2);
 			}     
 		}
@@ -626,7 +713,7 @@
 	int use_ssl;
 	unsigned char *rspder = NULL;
 	int rspderlen;
-	STACK *aia = NULL;
+	STACK_OF(OPENSSL_STRING) *aia = NULL;
 	X509 *x = NULL;
 	X509_STORE_CTX inctx;
 	X509_OBJECT obj;
@@ -648,7 +735,7 @@
 	aia = X509_get1_ocsp(x);
 	if (aia)
 		{
-		if (!OCSP_parse_url(sk_value(aia, 0),
+		if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0),
 			&host, &port, &path, &use_ssl))
 			{
 			BIO_puts(err, "cert_status: can't parse AIA URL\n");
@@ -656,7 +743,7 @@
 			}
 		if (srctx->verbose)
 			BIO_printf(err, "cert_status: AIA URL: %s\n",
-					sk_value(aia, 0));
+					sk_OPENSSL_STRING_value(aia, 0));
 		}
 	else
 		{
@@ -701,7 +788,7 @@
 		if (!OCSP_REQUEST_add_ext(req, ext, -1))
 			goto err;
 		}
-	resp = process_responder(err, req, host, path, port, use_ssl,
+	resp = process_responder(err, req, host, path, port, use_ssl, NULL,
 					srctx->timeout);
 	if (!resp)
 		{
@@ -740,6 +827,7 @@
 	goto done;
 	}
 #endif
+
 int MAIN(int, char **);
 
 #ifndef OPENSSL_NO_JPAKE
@@ -748,8 +836,8 @@
 
 int MAIN(int argc, char *argv[])
 	{
-	X509_STORE *store = NULL;
-	int vflags = 0;
+	X509_VERIFY_PARAM *vpm = NULL;
+	int badarg = 0;
 	short port=PORT;
 	char *CApath=NULL,*CAfile=NULL;
 	unsigned char *context = NULL;
@@ -762,8 +850,8 @@
 	int off=0;
 	int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0;
 	int state=0;
-	SSL_METHOD *meth=NULL;
-        int socket_type=SOCK_STREAM;
+	const SSL_METHOD *meth=NULL;
+	int socket_type=SOCK_STREAM;
 	ENGINE *e=NULL;
 	char *inrand=NULL;
 	int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
@@ -780,7 +868,10 @@
 #ifndef OPENSSL_NO_TLSEXT
         tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING};
 #endif
-
+#ifndef OPENSSL_NO_PSK
+	/* by default do not send a PSK identity hint */
+	static char *psk_identity_hint=NULL;
+#endif
 #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
 	meth=SSLv23_server_method();
 #elif !defined(OPENSSL_NO_SSL3)
@@ -914,14 +1005,14 @@
 			}
 		else if (strcmp(*argv,"-no_cache") == 0)
 			no_cache = 1;
-		else if (strcmp(*argv,"-crl_check") == 0)
+		else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm))
 			{
-			vflags |= X509_V_FLAG_CRL_CHECK;
+			if (badarg)
+				goto bad;
+			continue;
 			}
-		else if (strcmp(*argv,"-crl_check_all") == 0)
-			{
-			vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
-			}
+		else if (strcmp(*argv,"-verify_return_error") == 0)
+			verify_return_error = 1;
 		else if	(strcmp(*argv,"-serverpref") == 0)
 			{ off|=SSL_OP_CIPHER_SERVER_PREFERENCE; }
 		else if (strcmp(*argv,"-legacy_renegotiation") == 0)
@@ -998,6 +1089,27 @@
 			{ no_dhe=1; }
 		else if	(strcmp(*argv,"-no_ecdhe") == 0)
 			{ no_ecdhe=1; }
+#ifndef OPENSSL_NO_PSK
+                else if (strcmp(*argv,"-psk_hint") == 0)
+			{
+                        if (--argc < 1) goto bad;
+                        psk_identity_hint= *(++argv);
+                        }
+                else if (strcmp(*argv,"-psk") == 0)
+			{
+			size_t i;
+
+			if (--argc < 1) goto bad;
+			psk_key=*(++argv);
+			for (i=0; i<strlen(psk_key); i++)
+				{
+				if (isxdigit((int)psk_key[i]))
+					continue;
+				BIO_printf(bio_err,"Not a hex number '%s'\n",*argv);
+				goto bad;
+				}
+			}
+#endif
 		else if	(strcmp(*argv,"-www") == 0)
 			{ www=1; }
 		else if	(strcmp(*argv,"-WWW") == 0)
@@ -1010,6 +1122,8 @@
 			{ off|=SSL_OP_NO_SSLv3; }
 		else if	(strcmp(*argv,"-no_tls1") == 0)
 			{ off|=SSL_OP_NO_TLSv1; }
+		else if	(strcmp(*argv,"-no_comp") == 0)
+			{ off|=SSL_OP_NO_COMPRESSION; }
 #ifndef OPENSSL_NO_TLSEXT
 		else if	(strcmp(*argv,"-no_ticket") == 0)
 			{ off|=SSL_OP_NO_TICKET; }
@@ -1079,7 +1193,7 @@
 			}
 			
 #endif
-#ifndef OPENSSL_NO_JPAKE
+#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
 		else if (strcmp(*argv,"-jpake") == 0)
 			{
 			if (--argc < 1) goto bad;
@@ -1102,6 +1216,26 @@
 		goto end;
 		}
 
+#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
+	if (jpake_secret)
+		{
+		if (psk_key)
+			{
+			BIO_printf(bio_err,
+				   "Can't use JPAKE and PSK together\n");
+			goto end;
+			}
+		psk_identity = "JPAKE";
+		if (cipher)
+			{
+			BIO_printf(bio_err, "JPAKE sets cipher to PSK\n");
+			goto end;
+			}
+		cipher = "PSK";
+		}
+
+#endif
+
 	SSL_load_error_strings();
 	OpenSSL_add_ssl_algorithms();
 
@@ -1164,6 +1298,8 @@
 			}
 #endif
 		}
+
+
 	if (s_dcert_file)
 		{
 
@@ -1282,8 +1418,9 @@
 		ERR_print_errors(bio_err);
 		/* goto end; */
 		}
-	store = SSL_CTX_get_cert_store(ctx);
-	X509_STORE_set_flags(store, vflags);
+	if (vpm)
+		SSL_CTX_set1_param(ctx, vpm);
+
 #ifndef OPENSSL_NO_TLSEXT
 	if (s_cert2)
 		{
@@ -1319,13 +1456,11 @@
 		if (bugs) SSL_CTX_set_options(ctx2,SSL_OP_ALL);
 		if (hack) SSL_CTX_set_options(ctx2,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
 		SSL_CTX_set_options(ctx2,off);
-
 		/* DTLS: partial reads end up discarding unread UDP bytes :-( 
 		 * Setting read ahead solves this problem.
 		 */
 		if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx2, 1);
 
-
 		if (state) SSL_CTX_set_info_callback(ctx2,apps_ssl_info_callback);
 
 		if (no_cache)
@@ -1338,12 +1473,11 @@
 			{
 			ERR_print_errors(bio_err);
 			}
-		store = SSL_CTX_get_cert_store(ctx2);
-		X509_STORE_set_flags(store, vflags);
+		if (vpm)
+			SSL_CTX_set1_param(ctx2, vpm);
 		}
 #endif 
 
-
 #ifndef OPENSSL_NO_DH
 	if (!no_dhe)
 		{
@@ -1419,10 +1553,10 @@
 		else
 			{
 			BIO_printf(bio_s_out,"Using default temp ECDH parameters\n");
-			ecdh = EC_KEY_new_by_curve_name(NID_sect163r2);
+			ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
 			if (ecdh == NULL) 
 				{
-				BIO_printf(bio_err, "unable to create curve (sect163r2)\n");
+				BIO_printf(bio_err, "unable to create curve (nistp256)\n");
 				goto end;
 				}
 			}
@@ -1457,7 +1591,7 @@
 #ifndef OPENSSL_NO_TLSEXT
 		if (ctx2) 
 			SSL_CTX_set_tmp_rsa_callback(ctx2,tmp_rsa_cb);
-#endif	
+#endif		
 		}
 #else
 	if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx))
@@ -1490,11 +1624,34 @@
 #endif
 #endif
 
-	if (cipher != NULL)
-		if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
-		BIO_printf(bio_err,"error setting cipher list\n");
+#ifndef OPENSSL_NO_PSK
+#ifdef OPENSSL_NO_JPAKE
+	if (psk_key != NULL)
+#else
+	if (psk_key != NULL || jpake_secret)
+#endif
+		{
+		if (s_debug)
+			BIO_printf(bio_s_out, "PSK key given or JPAKE in use, setting server callback\n");
+		SSL_CTX_set_psk_server_callback(ctx, psk_server_cb);
+		}
+
+	if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint))
+		{
+		BIO_printf(bio_err,"error setting PSK identity hint to context\n");
 		ERR_print_errors(bio_err);
 		goto end;
+		}
+#endif
+
+	if (cipher != NULL)
+		{
+		if(!SSL_CTX_set_cipher_list(ctx,cipher))
+			{
+			BIO_printf(bio_err,"error setting cipher list\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
 #ifndef OPENSSL_NO_TLSEXT
 		if (ctx2 && !SSL_CTX_set_cipher_list(ctx2,cipher))
 			{
@@ -1503,7 +1660,7 @@
 			goto end;
 			}
 #endif
-	}
+		}
 	SSL_CTX_set_verify(ctx,s_server_verify,verify_callback);
 	SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context,
 		sizeof s_server_session_id_context);
@@ -1526,6 +1683,7 @@
 		SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
 		}
 #endif
+
 	if (CAfile != NULL)
 		{
 		SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
@@ -1534,7 +1692,9 @@
 			SSL_CTX_set_client_CA_list(ctx2,SSL_load_client_CA_file(CAfile));
 #endif
 		}
+
 	BIO_printf(bio_s_out,"ACCEPT\n");
+	(void)BIO_flush(bio_s_out);
 	if (www)
 		do_server(port,socket_type,&accept_socket,www_body, context);
 	else
@@ -1606,7 +1766,7 @@
 	SSL *con=NULL;
 	BIO *sbio;
 	struct timeval timeout;
-#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
 	struct timeval tv;
 #else
 	struct timeval *timeoutp;
@@ -1658,13 +1818,18 @@
 						 strlen((char *)context));
 	}
 	SSL_clear(con);
+#if 0
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	SSL_set_tlsext_opaque_prf_input(con, "Test server", 11);
+#endif
+#endif
 
 	if (SSL_version(con) == DTLS1_VERSION)
 		{
 
 		sbio=BIO_new_dgram(s,BIO_NOCLOSE);
 
-		if ( enable_timeouts)
+		if (enable_timeouts)
 			{
 			timeout.tv_sec = 0;
 			timeout.tv_usec = DGRAM_RCV_TIMEOUT;
@@ -1675,7 +1840,6 @@
 			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
 			}
 
-		
 		if (socket_mtu > 28)
 			{
 			SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
@@ -1738,10 +1902,10 @@
 		if (!read_from_sslcon)
 			{
 			FD_ZERO(&readfds);
-#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE)
-			FD_SET(fileno(stdin),&readfds);
+#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined(OPENSSL_SYS_BEOS_R5)
+			openssl_fdset(fileno(stdin),&readfds);
 #endif
-			FD_SET(s,&readfds);
+			openssl_fdset(s,&readfds);
 			/* Note: under VMS with SOCKETSHR the second parameter is
 			 * currently of type (int *) whereas under other systems
 			 * it is (void *) if you don't have a cast it will choke
@@ -1760,6 +1924,17 @@
 			if((i < 0) || (!i && !_kbhit() ) )continue;
 			if(_kbhit())
 				read_from_terminal = 1;
+#elif defined(OPENSSL_SYS_BEOS_R5)
+			/* Under BeOS-R5 the situation is similar to DOS */
+			tv.tv_sec = 1;
+			tv.tv_usec = 0;
+			(void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
+			i=select(width,(void *)&readfds,NULL,NULL,&tv);
+			if ((i < 0) || (!i && read(fileno(stdin), buf, 0) < 0))
+				continue;
+			if (read(fileno(stdin), buf, 0) >= 0)
+				read_from_terminal = 1;
+			(void)fcntl(fileno(stdin), F_SETFL, 0);
 #else
 			if ((SSL_version(con) == DTLS1_VERSION) &&
 				DTLSv1_get_timeout(con, &timeout))
@@ -1787,7 +1962,7 @@
 				{
 				int j, lf_num;
 
-				i=read(fileno(stdin), buf, bufsize/2);
+				i=raw_read_stdin(buf, bufsize/2);
 				lf_num = 0;
 				/* both loops are skipped when i <= 0 */
 				for (j = 0; j < i; j++)
@@ -1806,7 +1981,7 @@
 				assert(lf_num == 0);
 				}
 			else
-				i=read(fileno(stdin),buf,bufsize);
+				i=raw_read_stdin(buf,bufsize);
 			if (!s_quiet)
 				{
 				if ((i <= 0) || (buf[0] == 'Q'))
@@ -1826,6 +2001,7 @@
 					ret= -11;*/
 					goto err;
 					}
+
 				if ((buf[0] == 'r') && 
 					((buf[1] == '\n') || (buf[1] == '\r')))
 					{
@@ -1922,7 +2098,7 @@
 #ifdef CHARSET_EBCDIC
 					ascii2ebcdic(buf,buf,i);
 #endif
-					write(fileno(stdout),buf,
+					raw_write_stdout(buf,
 						(unsigned int)i);
 					if (SSL_pending(con)) goto again;
 					break;
@@ -1946,13 +2122,16 @@
 			}
 		}
 err:
-	BIO_printf(bio_s_out,"shutting down SSL\n");
+	if (con != NULL)
+		{
+		BIO_printf(bio_s_out,"shutting down SSL\n");
 #if 1
-	SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+		SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
 #else
-	SSL_shutdown(con);
+		SSL_shutdown(con);
 #endif
-	if (con != NULL) SSL_free(con);
+		SSL_free(con);
+		}
 	BIO_printf(bio_s_out,"CONNECTION CLOSED\n");
 	if (buf != NULL)
 		{
@@ -2076,9 +2255,8 @@
 	char *buf=NULL;
 	int ret=1;
 	int i,j,k,blank,dot;
-	struct stat st_buf;
 	SSL *con;
-	SSL_CIPHER *c;
+	const SSL_CIPHER *c;
 	BIO *io,*ssl_bio,*sbio;
 	long total_bytes;
 
@@ -2348,14 +2526,7 @@
 #endif
 
 			/* if a directory, do the index thang */
-			if (stat(p,&st_buf) < 0)
-				{
-				BIO_puts(io,text);
-				BIO_printf(io,"Error accessing '%s'\r\n",p);
-				ERR_print_errors(io);
-				break;
-				}
-			if (S_ISDIR(st_buf.st_mode))
+			if (app_isdir(p)>0)
 				{
 #if 0 /* must check buffer size */
 				strcat(p,"/index.html");
diff --git a/apps/s_socket.c b/apps/s_socket.c
index cf82358..6b8713d 100644
--- a/apps/s_socket.c
+++ b/apps/s_socket.c
@@ -237,13 +237,11 @@
 int init_client(int *sock, char *host, int port, int type)
 	{
 	unsigned char ip[4];
-	short p=0;
 
 	if (!host_ip(host,&(ip[0])))
 		{
 		return(0);
 		}
-	if (p != 0) port=p;
 	return(init_client_ip(sock,ip,port,type));
 	}
 
@@ -272,7 +270,7 @@
 			
 	if (s == INVALID_SOCKET) { perror("socket"); return(0); }
 
-#ifndef OPENSSL_SYS_MPE
+#if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE)
 	if (type == SOCK_STREAM)
 		{
 		i=0;
@@ -282,7 +280,7 @@
 #endif
 
 	if (connect(s,(struct sockaddr *)&them,sizeof(them)) == -1)
-		{ close(s); perror("connect"); return(0); }
+		{ closesocket(s); perror("connect"); return(0); }
 	*sock=s;
 	return(1);
 	}
@@ -291,7 +289,7 @@
 	{
 	int sock;
 	char *name = NULL;
-	int accept_socket;
+	int accept_socket = 0;
 	int i;
 
 	if (!init_server(&accept_socket,port,type)) return(0);
diff --git a/apps/s_time.c b/apps/s_time.c
index 904945e..b823c33 100644
--- a/apps/s_time.c
+++ b/apps/s_time.c
@@ -85,54 +85,6 @@
 #include OPENSSL_UNISTD
 #endif
 
-#if !defined(OPENSSL_SYS_NETWARE) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VXWORKS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC))
-#define TIMES
-#endif
-
-#ifndef _IRIX
-#include <time.h>
-#endif
-#ifdef TIMES
-#include <sys/types.h>
-#include <sys/times.h>
-#endif
-
-/* Depending on the VMS version, the tms structure is perhaps defined.
-   The __TMS macro will show if it was.  If it wasn't defined, we should
-   undefine TIMES, since that tells the rest of the program how things
-   should be handled.				-- Richard Levitte */
-#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
-#undef TIMES
-#endif
-
-#if !defined(TIMES) && !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_NETWARE)
-#include <sys/timeb.h>
-#endif
-
-#if defined(sun) || defined(__ultrix)
-#define _POSIX_SOURCE
-#include <limits.h>
-#include <sys/param.h>
-#endif
-
-/* The following if from times(3) man page.  It may need to be changed
-*/
-#ifndef HZ
-# ifdef _SC_CLK_TCK
-#  define HZ ((double)sysconf(_SC_CLK_TCK))
-# else
-#  ifndef CLK_TCK
-#   ifndef _BSD_CLK_TCK_ /* FreeBSD hack */
-#    define HZ	100.0
-#   else /* _BSD_CLK_TCK_ */
-#    define HZ ((double)_BSD_CLK_TCK_)
-#   endif
-#  else /* CLK_TCK */
-#   define HZ ((double)CLK_TCK)
-#  endif
-# endif
-#endif
-
 #undef PROG
 #define PROG s_time_main
 
@@ -177,7 +129,7 @@
 static int tm_verify = SSL_VERIFY_NONE;
 static int maxTime = SECONDS;
 static SSL_CTX *tm_ctx=NULL;
-static SSL_METHOD *s_time_meth=NULL;
+static const SSL_METHOD *s_time_meth=NULL;
 static char *s_www_path=NULL;
 static long bytes_read=0; 
 static int st_bugs=0;
@@ -372,63 +324,8 @@
 
 static double tm_Time_F(int s)
 	{
-	static double ret;
-#ifdef TIMES
-	static struct tms tstart,tend;
-
-	if(s == START) {
-		times(&tstart);
-		return(0);
-	} else {
-		times(&tend);
-		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
-		return((ret == 0.0)?1e-6:ret);
+	return app_tminterval(s,1);
 	}
-#elif defined(OPENSSL_SYS_NETWARE)
-    static clock_t tstart,tend;
-
-    if (s == START)
-    {
-        tstart=clock();
-        return(0);
-    }
-    else
-    {
-        tend=clock();
-        ret=(double)((double)(tend)-(double)(tstart));
-        return((ret < 0.001)?0.001:ret);
-    }
-#elif defined(OPENSSL_SYS_VXWORKS)
-        {
-	static unsigned long tick_start, tick_end;
-
-	if( s == START )
-		{
-		tick_start = tickGet();
-		return 0;
-		}
-	else
-		{
-		tick_end = tickGet();
-		ret = (double)(tick_end - tick_start) / (double)sysClkRateGet();
-		return((ret == 0.0)?1e-6:ret);
-		}
-        }
-#else /* !times() */
-	static struct timeb tstart,tend;
-	long i;
-
-	if(s == START) {
-		ftime(&tstart);
-		return(0);
-	} else {
-		ftime(&tend);
-		i=(long)tend.millitm-(long)tstart.millitm;
-		ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
-		return((ret == 0.0)?1e-6:ret);
-	}
-#endif
-}
 
 /***********************************************************************
  * MAIN - main processing area for client
@@ -704,7 +601,7 @@
 			i=SSL_get_fd(serverCon);
 			width=i+1;
 			FD_ZERO(&readfds);
-			FD_SET(i,&readfds);
+			openssl_fdset(i,&readfds);
 			/* Note: under VMS with SOCKETSHR the 2nd parameter
 			 * is currently of type (int *) whereas under other
 			 * systems it is (void *) if you don't have a cast it
diff --git a/apps/smime.c b/apps/smime.c
index 75804b8..c583f8a0 100644
--- a/apps/smime.c
+++ b/apps/smime.c
@@ -73,11 +73,14 @@
 static int smime_cb(int ok, X509_STORE_CTX *ctx);
 
 #define SMIME_OP	0x10
+#define SMIME_IP	0x20
+#define SMIME_SIGNERS	0x40
 #define SMIME_ENCRYPT	(1 | SMIME_OP)
-#define SMIME_DECRYPT	2
-#define SMIME_SIGN	(3 | SMIME_OP)
-#define SMIME_VERIFY	4
-#define SMIME_PK7OUT	5
+#define SMIME_DECRYPT	(2 | SMIME_IP)
+#define SMIME_SIGN	(3 | SMIME_OP | SMIME_SIGNERS)
+#define SMIME_VERIFY	(4 | SMIME_IP)
+#define SMIME_PK7OUT	(5 | SMIME_IP | SMIME_OP)
+#define SMIME_RESIGN	(6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
 
 int MAIN(int, char **);
 
@@ -90,6 +93,7 @@
 	const char *inmode = "r", *outmode = "w";
 	char *infile = NULL, *outfile = NULL;
 	char *signerfile = NULL, *recipfile = NULL;
+	STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL;
 	char *certfile = NULL, *keyfile = NULL, *contfile=NULL;
 	const EVP_CIPHER *cipher = NULL;
 	PKCS7 *p7 = NULL;
@@ -105,6 +109,8 @@
 	char *passargin = NULL, *passin = NULL;
 	char *inrand = NULL;
 	int need_rand = 0;
+	int indef = 0;
+	const EVP_MD *sign_md = NULL;
 	int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
         int keyform = FORMAT_PEM;
 #ifndef OPENSSL_NO_ENGINE
@@ -135,6 +141,8 @@
 			operation = SMIME_DECRYPT;
 		else if (!strcmp (*args, "-sign"))
 			operation = SMIME_SIGN;
+		else if (!strcmp (*args, "-resign"))
+			operation = SMIME_RESIGN;
 		else if (!strcmp (*args, "-verify"))
 			operation = SMIME_VERIFY;
 		else if (!strcmp (*args, "-pk7out"))
@@ -193,205 +201,209 @@
 				flags |= PKCS7_BINARY;
 		else if (!strcmp (*args, "-nosigs"))
 				flags |= PKCS7_NOSIGS;
+		else if (!strcmp (*args, "-stream"))
+				indef = 1;
+		else if (!strcmp (*args, "-indef"))
+				indef = 1;
+		else if (!strcmp (*args, "-noindef"))
+				indef = 0;
 		else if (!strcmp (*args, "-nooldmime"))
 				flags |= PKCS7_NOOLDMIMETYPE;
 		else if (!strcmp (*args, "-crlfeol"))
 				flags |= PKCS7_CRLFEOL;
 		else if (!strcmp(*args,"-rand"))
 			{
-			if (args[1])
-				{
-				args++;
-				inrand = *args;
-				}
-			else
-				badarg = 1;
+			if (!args[1])
+				goto argerr;
+			args++;
+			inrand = *args;
 			need_rand = 1;
 			}
 #ifndef OPENSSL_NO_ENGINE
 		else if (!strcmp(*args,"-engine"))
 			{
-			if (args[1])
-				{
-				args++;
-				engine = *args;
-				}
-			else badarg = 1;
+			if (!args[1])
+				goto argerr;
+			engine = *++args;
 			}
 #endif
 		else if (!strcmp(*args,"-passin"))
 			{
-			if (args[1])
-				{
-				args++;
-				passargin = *args;
-				}
-			else
-				badarg = 1;
+			if (!args[1])
+				goto argerr;
+			passargin = *++args;
 			}
 		else if (!strcmp (*args, "-to"))
 			{
-			if (args[1])
-				{
-				args++;
-				to = *args;
-				}
-			else
-				badarg = 1;
+			if (!args[1])
+				goto argerr;
+			to = *++args;
 			}
 		else if (!strcmp (*args, "-from"))
 			{
-			if (args[1])
-				{
-				args++;
-				from = *args;
-				}
-			else badarg = 1;
+			if (!args[1])
+				goto argerr;
+			from = *++args;
 			}
 		else if (!strcmp (*args, "-subject"))
 			{
-			if (args[1])
-				{
-				args++;
-				subject = *args;
-				}
-			else
-				badarg = 1;
+			if (!args[1])
+				goto argerr;
+			subject = *++args;
 			}
 		else if (!strcmp (*args, "-signer"))
 			{
-			if (args[1])
+			if (!args[1])
+				goto argerr;
+			/* If previous -signer argument add signer to list */
+
+			if (signerfile)
 				{
-				args++;
-				signerfile = *args;
+				if (!sksigners)
+					sksigners = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(sksigners, signerfile);
+				if (!keyfile)
+					keyfile = signerfile;
+				if (!skkeys)
+					skkeys = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(skkeys, keyfile);
+				keyfile = NULL;
 				}
-			else
-				badarg = 1;
+			signerfile = *++args;
 			}
 		else if (!strcmp (*args, "-recip"))
 			{
-			if (args[1])
+			if (!args[1])
+				goto argerr;
+			recipfile = *++args;
+			}
+		else if (!strcmp (*args, "-md"))
+			{
+			if (!args[1])
+				goto argerr;
+			sign_md = EVP_get_digestbyname(*++args);
+			if (sign_md == NULL)
 				{
-				args++;
-				recipfile = *args;
+				BIO_printf(bio_err, "Unknown digest %s\n",
+							*args);
+				goto argerr;
 				}
-			else badarg = 1;
 			}
 		else if (!strcmp (*args, "-inkey"))
 			{
-			if (args[1])
+			if (!args[1])	
+				goto argerr;
+			/* If previous -inkey arument add signer to list */
+			if (keyfile)
 				{
-				args++;
-				keyfile = *args;
+				if (!signerfile)
+					{
+					BIO_puts(bio_err, "Illegal -inkey without -signer\n");
+					goto argerr;
+					}
+				if (!sksigners)
+					sksigners = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(sksigners, signerfile);
+				signerfile = NULL;
+				if (!skkeys)
+					skkeys = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(skkeys, keyfile);
 				}
-			else
-				badarg = 1;
-		}
+			keyfile = *++args;
+			}
 		else if (!strcmp (*args, "-keyform"))
 			{
-			if (args[1])
-				{
-				args++;
-				keyform = str2fmt(*args);
-				}
-			else
-				badarg = 1;
+			if (!args[1])
+				goto argerr;
+			keyform = str2fmt(*++args);
 			}
 		else if (!strcmp (*args, "-certfile"))
 			{
-			if (args[1])
-				{
-				args++;
-				certfile = *args;
-				}
-			else
-				badarg = 1;
+			if (!args[1])
+				goto argerr;
+			certfile = *++args;
 			}
 		else if (!strcmp (*args, "-CAfile"))
 			{
-			if (args[1])
-				{
-				args++;
-				CAfile = *args;
-				}
-			else
-				badarg = 1;
+			if (!args[1])
+				goto argerr;
+			CAfile = *++args;
 			}
 		else if (!strcmp (*args, "-CApath"))
 			{
-			if (args[1])
-				{
-				args++;
-				CApath = *args;
-				}
-			else
-				badarg = 1;
+			if (!args[1])
+				goto argerr;
+			CApath = *++args;
 			}
 		else if (!strcmp (*args, "-in"))
 			{
-			if (args[1])
-				{
-				args++;
-				infile = *args;
-				}
-			else
-				badarg = 1;
+			if (!args[1])
+				goto argerr;
+			infile = *++args;
 			}
 		else if (!strcmp (*args, "-inform"))
 			{
-			if (args[1])
-				{
-				args++;
-				informat = str2fmt(*args);
-				}
-			else
-				badarg = 1;
+			if (!args[1])
+				goto argerr;
+			informat = str2fmt(*++args);
 			}
 		else if (!strcmp (*args, "-outform"))
 			{
-			if (args[1])
-				{
-				args++;
-				outformat = str2fmt(*args);
-				}
-			else
-				badarg = 1;
+			if (!args[1])
+				goto argerr;
+			outformat = str2fmt(*++args);
 			}
 		else if (!strcmp (*args, "-out"))
 			{
-			if (args[1])
-				{
-				args++;
-				outfile = *args;
-				}
-			else
-				badarg = 1;
+			if (!args[1])
+				goto argerr;
+			outfile = *++args;
 			}
 		else if (!strcmp (*args, "-content"))
 			{
-			if (args[1])
-				{
-				args++;
-				contfile = *args;
-				}
-			else
-				badarg = 1;
+			if (!args[1])
+				goto argerr;
+			contfile = *++args;
 			}
 		else if (args_verify(&args, NULL, &badarg, bio_err, &vpm))
 			continue;
-		else
+		else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL)
 			badarg = 1;
 		args++;
 		}
 
-
-	if (operation == SMIME_SIGN)
+	if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners))
 		{
-		if (!signerfile)
+		BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
+		goto argerr;
+		}
+
+	if (operation & SMIME_SIGNERS)
+		{
+		/* Check to see if any final signer needs to be appended */
+		if (keyfile && !signerfile)
+			{
+			BIO_puts(bio_err, "Illegal -inkey without -signer\n");
+			goto argerr;
+			}
+		if (signerfile)
+			{
+			if (!sksigners)
+				sksigners = sk_OPENSSL_STRING_new_null();
+			sk_OPENSSL_STRING_push(sksigners, signerfile);
+			if (!skkeys)
+				skkeys = sk_OPENSSL_STRING_new_null();
+			if (!keyfile)
+				keyfile = signerfile;
+			sk_OPENSSL_STRING_push(skkeys, keyfile);
+			}
+		if (!sksigners)
 			{
 			BIO_printf(bio_err, "No signer certificate specified\n");
 			badarg = 1;
 			}
+		signerfile = NULL;
+		keyfile = NULL;
 		need_rand = 1;
 		}
 	else if (operation == SMIME_DECRYPT)
@@ -416,6 +428,7 @@
 
 	if (badarg)
 		{
+		argerr:
 		BIO_printf (bio_err, "Usage smime [options] cert.pem ...\n");
 		BIO_printf (bio_err, "where options are\n");
 		BIO_printf (bio_err, "-encrypt       encrypt message\n");
@@ -499,13 +512,11 @@
 
 	ret = 2;
 
-	if (operation != SMIME_SIGN)
+	if (!(operation & SMIME_SIGNERS))
 		flags &= ~PKCS7_DETACHED;
 
 	if (operation & SMIME_OP)
 		{
-		if (flags & PKCS7_BINARY)
-			inmode = "rb";
 		if (outformat == FORMAT_ASN1)
 			outmode = "wb";
 		}
@@ -513,9 +524,18 @@
 		{
 		if (flags & PKCS7_BINARY)
 			outmode = "wb";
+		}
+
+	if (operation & SMIME_IP)
+		{
 		if (informat == FORMAT_ASN1)
 			inmode = "rb";
 		}
+	else
+		{
+		if (flags & PKCS7_BINARY)
+			inmode = "rb";
+		}
 
 	if (operation == SMIME_ENCRYPT)
 		{
@@ -545,26 +565,11 @@
 			}
 		}
 
-	if (signerfile && (operation == SMIME_SIGN))
-		{
-		if (!(signer = load_cert(bio_err,signerfile,FORMAT_PEM, NULL,
-			e, "signer certificate")))
-			{
-#if 0			/* An appropri message has already been printed */
-			BIO_printf(bio_err, "Can't read signer certificate file %s\n", signerfile);
-#endif
-			goto end;
-			}
-		}
-
 	if (certfile)
 		{
 		if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL,
 			e, "certificate file")))
 			{
-#if 0			/* An appropriate message has already been printed */
-			BIO_printf(bio_err, "Can't read certificate file %s\n", certfile);
-#endif
 			ERR_print_errors(bio_err);
 			goto end;
 			}
@@ -575,9 +580,6 @@
 		if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL,
 			e, "recipient certificate file")))
 			{
-#if 0			/* An appropriate message has alrady been printed */
-			BIO_printf(bio_err, "Can't read recipient certificate file %s\n", recipfile);
-#endif
 			ERR_print_errors(bio_err);
 			goto end;
 			}
@@ -615,50 +617,7 @@
 	else
 		in = BIO_new_fp(stdin, BIO_NOCLOSE);
 
-	if (outfile)
-		{
-		if (!(out = BIO_new_file(outfile, outmode)))
-			{
-			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 (operation == SMIME_VERIFY)
-		{
-		if (!(store = setup_verify(bio_err, CAfile, CApath)))
-			goto end;
-		X509_STORE_set_verify_cb_func(store, smime_cb);
-		if (vpm)
-			X509_STORE_set1_param(store, vpm);
-		}
-
-
-	ret = 3;
-
-	if (operation == SMIME_ENCRYPT)
-		p7 = PKCS7_encrypt(encerts, in, cipher, flags);
-	else if (operation == SMIME_SIGN)
-		{
-		/* If detached data and SMIME output enable partial
-		 * signing.
-		 */
-		if ((flags & PKCS7_DETACHED) && (outformat == FORMAT_SMIME))
-			flags |= PKCS7_STREAM;
-		p7 = PKCS7_sign(signer, key, other, in, flags);
-		}
-	else
+	if (operation & SMIME_IP)
 		{
 		if (informat == FORMAT_SMIME) 
 			p7 = SMIME_read_PKCS7(in, &indata);
@@ -688,6 +647,94 @@
 			}
 		}
 
+	if (outfile)
+		{
+		if (!(out = BIO_new_file(outfile, outmode)))
+			{
+			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 (operation == SMIME_VERIFY)
+		{
+		if (!(store = setup_verify(bio_err, CAfile, CApath)))
+			goto end;
+		X509_STORE_set_verify_cb(store, smime_cb);
+		if (vpm)
+			X509_STORE_set1_param(store, vpm);
+		}
+
+
+	ret = 3;
+
+	if (operation == SMIME_ENCRYPT)
+		{
+		if (indef)
+			flags |= PKCS7_STREAM;
+		p7 = PKCS7_encrypt(encerts, in, cipher, flags);
+		}
+	else if (operation & SMIME_SIGNERS)
+		{
+		int i;
+		/* If detached data content we only enable streaming if
+		 * S/MIME output format.
+		 */
+		if (operation == SMIME_SIGN)
+			{
+			if (flags & PKCS7_DETACHED)
+				{
+				if (outformat == FORMAT_SMIME)
+					flags |= PKCS7_STREAM;
+				}
+			else if (indef)
+				flags |= PKCS7_STREAM;
+			flags |= PKCS7_PARTIAL;
+			p7 = PKCS7_sign(NULL, NULL, other, in, flags);
+			if (!p7)
+				goto end;
+			}
+		else
+			flags |= PKCS7_REUSE_DIGEST;
+		for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++)
+			{
+			signerfile = sk_OPENSSL_STRING_value(sksigners, i);
+			keyfile = sk_OPENSSL_STRING_value(skkeys, i);
+			signer = load_cert(bio_err, signerfile,FORMAT_PEM, NULL,
+					e, "signer certificate");
+			if (!signer)
+				goto end;
+			key = load_key(bio_err, keyfile, keyform, 0, passin, e,
+			       "signing key file");
+			if (!key)
+				goto end;
+			if (!PKCS7_sign_add_signer(p7, signer, key,
+						sign_md, flags))
+				goto end;
+			X509_free(signer);
+			signer = NULL;
+			EVP_PKEY_free(key);
+			key = NULL;
+			}
+		/* If not streaming or resigning finalize structure */
+		if ((operation == SMIME_SIGN) && !(flags & PKCS7_STREAM))
+			{
+			if (!PKCS7_final(p7, in, flags))
+				goto end;
+			}
+		}
+
 	if (!p7)
 		{
 		BIO_printf(bio_err, "Error creating PKCS#7 structure\n");
@@ -734,11 +781,16 @@
 		if (subject)
 			BIO_printf(out, "Subject: %s\n", subject);
 		if (outformat == FORMAT_SMIME) 
-			SMIME_write_PKCS7(out, p7, in, flags);
+			{
+			if (operation == SMIME_RESIGN)
+				SMIME_write_PKCS7(out, p7, indata, flags);
+			else
+				SMIME_write_PKCS7(out, p7, in, flags);
+			}
 		else if (outformat == FORMAT_PEM) 
-			PEM_write_bio_PKCS7(out,p7);
+			PEM_write_bio_PKCS7_stream(out, p7, in, flags);
 		else if (outformat == FORMAT_ASN1) 
-			i2d_PKCS7_bio(out,p7);
+			i2d_PKCS7_bio_stream(out,p7, in, flags);
 		else
 			{
 			BIO_printf(bio_err, "Bad output format for PKCS#7 file\n");
@@ -754,6 +806,10 @@
 	sk_X509_pop_free(other, X509_free);
 	if (vpm)
 		X509_VERIFY_PARAM_free(vpm);
+	if (sksigners)
+		sk_OPENSSL_STRING_free(sksigners);
+	if (skkeys)
+		sk_OPENSSL_STRING_free(skkeys);
 	X509_STORE_free(store);
 	X509_free(cert);
 	X509_free(recip);
diff --git a/apps/speed.c b/apps/speed.c
index a0be93f..b903864 100644
--- a/apps/speed.c
+++ b/apps/speed.c
@@ -108,53 +108,8 @@
 #include <signal.h>
 #endif
 
-#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) && !defined(HAVE_ANDROID_OS) /* FIXME */
-# define TIMEB
-#endif
-
-#if defined(OPENSSL_SYS_NETWARE)
-#undef TIMES
-#undef TIMEB
-#include <time.h>
-#endif
-
-#ifndef _IRIX
-# include <time.h>
-#endif
-#ifdef TIMES
-# include <sys/types.h>
-# include <sys/times.h>
-#endif
-#ifdef USE_TOD
-# include <sys/time.h>
-# include <sys/resource.h>
-#endif
-
-/* Depending on the VMS version, the tms structure is perhaps defined.
-   The __TMS macro will show if it was.  If it wasn't defined, we should
-   undefine TIMES, since that tells the rest of the program how things
-   should be handled.				-- Richard Levitte */
-#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
-#undef TIMES
-#endif
-
-#ifdef TIMEB
-#include <sys/timeb.h>
-#endif
-
-#if !defined(TIMES) && !defined(TIMEB) && !defined(USE_TOD) && !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_NETWARE)
-#error "It seems neither struct tms nor struct timeb is supported in this platform!"
-#endif
-
-#if defined(sun) || defined(__ultrix)
-#define _POSIX_SOURCE
-#include <limits.h>
-#include <sys/param.h>
+#ifdef _WIN32
+#include <windows.h>
 #endif
 
 #include <openssl/bn.h>
@@ -189,6 +144,9 @@
 #ifndef OPENSSL_NO_RIPEMD
 #include <openssl/ripemd.h>
 #endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+#include <openssl/whrlpool.h>
+#endif
 #ifndef OPENSSL_NO_RC4
 #include <openssl/rc4.h>
 #endif
@@ -226,47 +184,24 @@
 #include <openssl/ecdh.h>
 #endif
 
-/*
- * The following "HZ" timing stuff should be sync'd up with the code in
- * crypto/tmdiff.[ch]. That appears to try to do the same job, though I think
- * this code is more up to date than libcrypto's so there may be features to
- * migrate over first. This is used in two places further down AFAICS. 
- * The point is that nothing in openssl actually *uses* that tmdiff stuff, so
- * either speed.c should be using it or it should go because it's obviously not
- * useful enough. Anyone want to do a janitorial job on this?
- */
-
-/* The following if from times(3) man page.  It may need to be changed */
-#ifndef HZ
-# if defined(_SC_CLK_TCK) \
-     && (!defined(OPENSSL_SYS_VMS) || __CTRL_VER >= 70000000)
-#  define HZ sysconf(_SC_CLK_TCK)
+#ifndef HAVE_FORK
+# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_NETWARE)
+#  define HAVE_FORK 0
 # else
-#  ifndef CLK_TCK
-#   ifndef _BSD_CLK_TCK_ /* FreeBSD hack */
-#    define HZ	100.0
-#   else /* _BSD_CLK_TCK_ */
-#    define HZ ((double)_BSD_CLK_TCK_)
-#   endif
-#  else /* CLK_TCK */
-#   define HZ ((double)CLK_TCK)
-#  endif
+#  define HAVE_FORK 1
 # endif
 #endif
 
-#if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_NETWARE)
-# define NO_FORK 1
-#elif HAVE_FORK
-# undef NO_FORK
+#if HAVE_FORK
+#undef NO_FORK
 #else
-# define NO_FORK 1
+#define NO_FORK
 #endif
 
 #undef BUFSIZE
 #define BUFSIZE	((long)1024*8+1)
 int run=0;
 
-static char ftime_used = 0, times_used = 0, gettimeofday_used = 0, getrusage_used = 0;
 static int mr=0;
 static int usertime=1;
 
@@ -279,7 +214,7 @@
 static int do_multi(int multi);
 #endif
 
-#define ALGOR_NUM	28
+#define ALGOR_NUM	29
 #define SIZE_NUM	5
 #define RSA_NUM		4
 #define DSA_NUM		3
@@ -293,7 +228,7 @@
   "rc2 cbc","rc5-32/12 cbc","blowfish cbc","cast cbc",
   "aes-128 cbc","aes-192 cbc","aes-256 cbc",
   "camellia-128 cbc","camellia-192 cbc","camellia-256 cbc",
-  "evp","sha256","sha512",
+  "evp","sha256","sha512","whirlpool",
   "aes-128 ige","aes-192 ige","aes-256 ige"};
 static double results[ALGOR_NUM][SIZE_NUM];
 static int lengths[SIZE_NUM]={16,64,256,1024,8*1024};
@@ -336,141 +271,46 @@
 #define START	0
 #define STOP	1
 
-#if defined(OPENSSL_SYS_NETWARE)
+#if defined(_WIN32)
 
-   /* for NetWare the best we can do is use clock() which returns the
-    * time, in hundredths of a second, since the NLM began executing
-   */
+#define SIGALRM
+static unsigned int lapse,schlock;
+static void alarm(unsigned int secs) { lapse = secs*1000; }
+
+static DWORD WINAPI sleepy(VOID *arg)
+	{
+	schlock = 1;
+	Sleep(lapse);
+	run = 0;
+	return 0;
+	}
+
 static double Time_F(int s)
 	{
-	double ret;
+	if (s == START)
+		{
+		HANDLE	thr;
+		schlock = 0;
+		thr = CreateThread(NULL,4096,sleepy,NULL,0,NULL);
+		if (thr==NULL)
+			{
+			DWORD ret=GetLastError();
+			BIO_printf(bio_err,"unable to CreateThread (%d)",ret);
+			ExitProcess(ret);
+			}
+		CloseHandle(thr);		/* detach the thread	*/
+		while (!schlock) Sleep(0);	/* scheduler spinlock	*/
+		}
 
-   static clock_t tstart,tend;
-
-   if (s == START)
-   {
-      tstart=clock();
-      return(0);
-   }
-   else
-   {
-      tend=clock();
-      ret=(double)((double)(tend)-(double)(tstart));
-      return((ret < 0.001)?0.001:ret);
-   }
-   }
-
+	return app_tminterval(s,usertime);
+	}
 #else
 
 static double Time_F(int s)
 	{
-	double ret;
-
-#ifdef USE_TOD
-	if(usertime)
-		{
-		static struct rusage tstart,tend;
-
-		getrusage_used = 1;
-		if (s == START)
-			{
-			getrusage(RUSAGE_SELF,&tstart);
-			return(0);
-			}
-		else
-			{
-			long i;
-
-			getrusage(RUSAGE_SELF,&tend);
-			i=(long)tend.ru_utime.tv_usec-(long)tstart.ru_utime.tv_usec;
-			ret=((double)(tend.ru_utime.tv_sec-tstart.ru_utime.tv_sec))
-			  +((double)i)/1000000.0;
-			return((ret < 0.001)?0.001:ret);
-			}
-		}
-	else
-		{
-		static struct timeval tstart,tend;
-		long i;
-
-		gettimeofday_used = 1;
-		if (s == START)
-			{
-			gettimeofday(&tstart,NULL);
-			return(0);
-			}
-		else
-			{
-			gettimeofday(&tend,NULL);
-			i=(long)tend.tv_usec-(long)tstart.tv_usec;
-			ret=((double)(tend.tv_sec-tstart.tv_sec))+((double)i)/1000000.0;
-			return((ret < 0.001)?0.001:ret);
-			}
-		}
-#else  /* ndef USE_TOD */
-		
-# ifdef TIMES
-	if (usertime)
-		{
-		static struct tms tstart,tend;
-
-		times_used = 1;
-		if (s == START)
-			{
-			times(&tstart);
-			return(0);
-			}
-		else
-			{
-			times(&tend);
-			ret = HZ;
-			ret=(double)(tend.tms_utime-tstart.tms_utime) / ret;
-			return((ret < 1e-3)?1e-3:ret);
-			}
-		}
-# endif /* times() */
-# if defined(TIMES) && defined(TIMEB)
-	else
-# endif
-# ifdef OPENSSL_SYS_VXWORKS
-                {
-		static unsigned long tick_start, tick_end;
-
-		if( s == START )
-			{
-			tick_start = tickGet();
-			return 0;
-			}
-		else
-			{
-			tick_end = tickGet();
-			ret = (double)(tick_end - tick_start) / (double)sysClkRateGet();
-			return((ret < 0.001)?0.001:ret);
-			}
-                }
-# elif defined(TIMEB)
-		{
-		static struct timeb tstart,tend;
-		long i;
-
-		ftime_used = 1;
-		if (s == START)
-			{
-			ftime(&tstart);
-			return(0);
-			}
-		else
-			{
-			ftime(&tend);
-			i=(long)tend.millitm-(long)tstart.millitm;
-			ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
-			return((ret < 0.001)?0.001:ret);
-			}
-		}
-# endif
-#endif
+	return app_tminterval(s,usertime);
 	}
-#endif /* if defined(OPENSSL_SYS_NETWARE) */
+#endif
 
 
 #ifndef OPENSSL_NO_ECDH
@@ -530,6 +370,9 @@
 	unsigned char sha512[SHA512_DIGEST_LENGTH];
 #endif
 #endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+	unsigned char whirlpool[WHIRLPOOL_DIGEST_LENGTH];
+#endif
 #ifndef OPENSSL_NO_RIPEMD
 	unsigned char rmd160[RIPEMD160_DIGEST_LENGTH];
 #endif
@@ -626,9 +469,10 @@
 #define D_EVP		22
 #define D_SHA256	23	
 #define D_SHA512	24
-#define D_IGE_128_AES   25
-#define D_IGE_192_AES   26
-#define D_IGE_256_AES   27
+#define D_WHIRLPOOL	25
+#define D_IGE_128_AES   26
+#define D_IGE_192_AES   27
+#define D_IGE_256_AES   28
 	double d=0.0;
 	long c[ALGOR_NUM][SIZE_NUM];
 #define	R_DSA_512	0
@@ -948,6 +792,10 @@
 		else
 #endif
 #endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+			if (strcmp(*argv,"whirlpool") == 0) doit[D_WHIRLPOOL]=1;
+		else
+#endif
 #ifndef OPENSSL_NO_RIPEMD
 			if (strcmp(*argv,"ripemd") == 0) doit[D_RMD160]=1;
 		else
@@ -1159,12 +1007,16 @@
 #ifndef OPENSSL_NO_SHA512
 			BIO_printf(bio_err,"sha512   ");
 #endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+			BIO_printf(bio_err,"whirlpool");
+#endif
 #ifndef OPENSSL_NO_RIPEMD160
 			BIO_printf(bio_err,"rmd160");
 #endif
 #if !defined(OPENSSL_NO_MD2) || !defined(OPENSSL_NO_MDC2) || \
     !defined(OPENSSL_NO_MD4) || !defined(OPENSSL_NO_MD5) || \
-    !defined(OPENSSL_NO_SHA1) || !defined(OPENSSL_NO_RIPEMD160)
+    !defined(OPENSSL_NO_SHA1) || !defined(OPENSSL_NO_RIPEMD160) || \
+    !defined(OPENSSL_NO_WHIRLPOOL)
 			BIO_printf(bio_err,"\n");
 #endif
 
@@ -1291,17 +1143,20 @@
 			rsa_doit[i]=1;
 		for (i=0; i<DSA_NUM; i++)
 			dsa_doit[i]=1;
+#ifndef OPENSSL_NO_ECDSA
+		for (i=0; i<EC_NUM; i++)
+			ecdsa_doit[i]=1;
+#endif
+#ifndef OPENSSL_NO_ECDH
+		for (i=0; i<EC_NUM; i++)
+			ecdh_doit[i]=1;
+#endif
 		}
 	for (i=0; i<ALGOR_NUM; i++)
 		if (doit[i]) pr_header++;
 
 	if (usertime == 0 && !mr)
 		BIO_printf(bio_err,"You have chosen to measure elapsed time instead of user CPU time.\n");
-	if (usertime <= 0 && !mr)
-		{
-		BIO_printf(bio_err,"To get the most accurate results, try to run this\n");
-		BIO_printf(bio_err,"program when this computer is idle.\n");
-		}
 
 #ifndef OPENSSL_NO_RSA
 	for (i=0; i<RSA_NUM; i++)
@@ -1411,6 +1266,7 @@
 	c[D_CBC_256_CML][0]=count;
 	c[D_SHA256][0]=count;
 	c[D_SHA512][0]=count;
+	c[D_WHIRLPOOL][0]=count;
 	c[D_IGE_128_AES][0]=count;
 	c[D_IGE_192_AES][0]=count;
 	c[D_IGE_256_AES][0]=count;
@@ -1426,6 +1282,7 @@
 		c[D_RMD160][i]=c[D_RMD160][0]*4*lengths[0]/lengths[i];
 		c[D_SHA256][i]=c[D_SHA256][0]*4*lengths[0]/lengths[i];
 		c[D_SHA512][i]=c[D_SHA512][0]*4*lengths[0]/lengths[i];
+		c[D_WHIRLPOOL][i]=c[D_WHIRLPOOL][0]*4*lengths[0]/lengths[i];
 		}
 	for (i=1; i<SIZE_NUM; i++)
 		{
@@ -1609,7 +1466,9 @@
 #else
 #define COND(c)	(run)
 #define COUNT(d) (count)
+#ifndef _WIN32
 	signal(SIGALRM,sig_done);
+#endif
 #endif /* SIGALRM */
 
 #ifndef OPENSSL_NO_MD2
@@ -1739,8 +1598,23 @@
 			}
 		}
 #endif
-
 #endif
+
+#ifndef OPENSSL_NO_WHIRLPOOL
+	if (doit[D_WHIRLPOOL])
+		{
+		for (j=0; j<SIZE_NUM; j++)
+			{
+			print_message(names[D_WHIRLPOOL],c[D_WHIRLPOOL][j],lengths[j]);
+			Time_F(START);
+			for (count=0,run=1; COND(c[D_WHIRLPOOL][j]); count++)
+				WHIRLPOOL(buf,lengths[j],whirlpool);
+			d=Time_F(STOP);
+			print_result(D_WHIRLPOOL,j,count,d);
+			}
+		}
+#endif
+
 #ifndef OPENSSL_NO_RIPEMD
 	if (doit[D_RMD160])
 		{
@@ -1887,6 +1761,8 @@
 			print_result(D_IGE_256_AES,j,count,d);
 			}
 		}
+
+
 #endif
 #endif
 #ifndef OPENSSL_NO_CAMELLIA
@@ -2500,35 +2376,6 @@
 		printf("%s ",BF_options());
 #endif
 		fprintf(stdout,"\n%s\n",SSLeay_version(SSLEAY_CFLAGS));
-		printf("available timing options: ");
-#ifdef TIMES
-		printf("TIMES ");
-#endif
-#ifdef TIMEB
-		printf("TIMEB ");
-#endif
-#ifdef USE_TOD
-		printf("USE_TOD ");
-#endif
-#ifdef HZ
-#define as_string(s) (#s)
-		{
-		double dbl = HZ;
-		printf("HZ=%g", dbl);
-		}
-# ifdef _SC_CLK_TCK
-		printf(" [sysconf value]");
-# endif
-#endif
-		printf("\n");
-		printf("timing function used: %s%s%s%s%s%s%s\n",
-		       (ftime_used ? "ftime" : ""),
-		       (ftime_used + times_used > 1 ? "," : ""),
-		       (times_used ? "times" : ""),
-		       (ftime_used + times_used + gettimeofday_used > 1 ? "," : ""),
-		       (gettimeofday_used ? "gettimeofday" : ""),
-		       (ftime_used + times_used + gettimeofday_used + getrusage_used > 1 ? "," : ""),
-		       (getrusage_used ? "getrusage" : ""));
 		}
 
 	if (pr_header)
@@ -2785,6 +2632,7 @@
 			close(fd[1]);
 			mr=1;
 			usertime=0;
+			free(fds);
 			return 0;
 			}
 		printf("Forked child %d\n",n);
@@ -2933,7 +2781,10 @@
 			else
 				fprintf(stderr,"Unknown type '%s' from child %d\n",buf,n);
 			}
+
+		fclose(f);
 		}
+	free(fds);
 	return 1;
 	}
 #endif
diff --git a/apps/verify.c b/apps/verify.c
index 20cc9e3..9163997 100644
--- a/apps/verify.c
+++ b/apps/verify.c
@@ -70,8 +70,9 @@
 #define PROG	verify_main
 
 static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx);
-static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain, STACK_OF(X509) *tchain, int purpose, ENGINE *e);
-static STACK_OF(X509) *load_untrusted(char *file);
+static int check(X509_STORE *ctx, char *file,
+		STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
+		STACK_OF(X509_CRL) *crls, ENGINE *e);
 static int v_verbose=0, vflags = 0;
 
 int MAIN(int, char **);
@@ -80,10 +81,10 @@
 	{
 	ENGINE *e = NULL;
 	int i,ret=1, badarg = 0;
-	int purpose = -1;
 	char *CApath=NULL,*CAfile=NULL;
-	char *untfile = NULL, *trustfile = NULL;
+	char *untfile = NULL, *trustfile = NULL, *crlfile = NULL;
 	STACK_OF(X509) *untrusted = NULL, *trusted = NULL;
+	STACK_OF(X509_CRL) *crls = NULL;
 	X509_STORE *cert_ctx=NULL;
 	X509_LOOKUP *lookup=NULL;
 	X509_VERIFY_PARAM *vpm = NULL;
@@ -93,7 +94,7 @@
 
 	cert_ctx=X509_STORE_new();
 	if (cert_ctx == NULL) goto end;
-	X509_STORE_set_verify_cb_func(cert_ctx,cb);
+	X509_STORE_set_verify_cb(cert_ctx,cb);
 
 	ERR_load_crypto_strings();
 
@@ -139,6 +140,11 @@
 				if (argc-- < 1) goto end;
 				trustfile= *(++argv);
 				}
+			else if (strcmp(*argv,"-CRLfile") == 0)
+				{
+				if (argc-- < 1) goto end;
+				crlfile= *(++argv);
+				}
 #ifndef OPENSSL_NO_ENGINE
 			else if (strcmp(*argv,"-engine") == 0)
 				{
@@ -192,26 +198,34 @@
 
 	ERR_clear_error();
 
-	if(untfile) {
-		if(!(untrusted = load_untrusted(untfile))) {
-			BIO_printf(bio_err, "Error loading untrusted file %s\n", untfile);
-			ERR_print_errors(bio_err);
+	if(untfile)
+		{
+		untrusted = load_certs(bio_err, untfile, FORMAT_PEM,
+					NULL, e, "untrusted certificates");
+		if(!untrusted)
 			goto end;
 		}
-	}
 
-	if(trustfile) {
-		if(!(trusted = load_untrusted(trustfile))) {
-			BIO_printf(bio_err, "Error loading untrusted file %s\n", trustfile);
-			ERR_print_errors(bio_err);
+	if(trustfile)
+		{
+		trusted = load_certs(bio_err, trustfile, FORMAT_PEM,
+					NULL, e, "trusted certificates");
+		if(!trusted)
 			goto end;
 		}
-	}
 
-	if (argc < 1) check(cert_ctx, NULL, untrusted, trusted, purpose, e);
+	if(crlfile)
+		{
+		crls = load_crls(bio_err, crlfile, FORMAT_PEM,
+					NULL, e, "other CRLs");
+		if(!crls)
+			goto end;
+		}
+
+	if (argc < 1) check(cert_ctx, NULL, untrusted, trusted, crls, e);
 	else
 		for (i=0; i<argc; i++)
-			check(cert_ctx,argv[i], untrusted, trusted, purpose, e);
+			check(cert_ctx,argv[i], untrusted, trusted, crls, e);
 	ret=0;
 end:
 	if (ret == 1) {
@@ -232,11 +246,14 @@
 	if (cert_ctx != NULL) X509_STORE_free(cert_ctx);
 	sk_X509_pop_free(untrusted, X509_free);
 	sk_X509_pop_free(trusted, X509_free);
+	sk_X509_CRL_pop_free(crls, X509_CRL_free);
 	apps_shutdown();
 	OPENSSL_EXIT(ret);
 	}
 
-static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain, STACK_OF(X509) *tchain, int purpose, ENGINE *e)
+static int check(X509_STORE *ctx, char *file,
+		STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
+		STACK_OF(X509_CRL) *crls, ENGINE *e)
 	{
 	X509 *x=NULL;
 	int i=0,ret=0;
@@ -260,7 +277,8 @@
 		goto end;
 		}
 	if(tchain) X509_STORE_CTX_trusted_stack(csc, tchain);
-	if(purpose >= 0) X509_STORE_CTX_set_purpose(csc, purpose);
+	if (crls)
+		X509_STORE_CTX_set0_crls(csc, crls);
 	i=X509_verify_cert(csc);
 	X509_STORE_CTX_free(csc);
 
@@ -278,90 +296,53 @@
 	return(ret);
 	}
 
-static STACK_OF(X509) *load_untrusted(char *certfile)
-{
-	STACK_OF(X509_INFO) *sk=NULL;
-	STACK_OF(X509) *stack=NULL, *ret=NULL;
-	BIO *in=NULL;
-	X509_INFO *xi;
-
-	if(!(stack = sk_X509_new_null())) {
-		BIO_printf(bio_err,"memory allocation failure\n");
-		goto end;
-	}
-
-	if(!(in=BIO_new_file(certfile, "r"))) {
-		BIO_printf(bio_err,"error opening the file, %s\n",certfile);
-		goto end;
-	}
-
-	/* This loads from a file, a stack of x509/crl/pkey sets */
-	if(!(sk=PEM_X509_INFO_read_bio(in,NULL,NULL,NULL))) {
-		BIO_printf(bio_err,"error reading the file, %s\n",certfile);
-		goto end;
-	}
-
-	/* scan over it and pull out the certs */
-	while (sk_X509_INFO_num(sk))
-		{
-		xi=sk_X509_INFO_shift(sk);
-		if (xi->x509 != NULL)
-			{
-			sk_X509_push(stack,xi->x509);
-			xi->x509=NULL;
-			}
-		X509_INFO_free(xi);
-		}
-	if(!sk_X509_num(stack)) {
-		BIO_printf(bio_err,"no certificates in file, %s\n",certfile);
-		sk_X509_free(stack);
-		goto end;
-	}
-	ret=stack;
-end:
-	BIO_free(in);
-	sk_X509_INFO_free(sk);
-	return(ret);
-	}
-
 static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx)
 	{
-	char buf[256];
+	int cert_error = X509_STORE_CTX_get_error(ctx);
+	X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
 
 	if (!ok)
 		{
-		if (ctx->current_cert)
+		if (current_cert)
 			{
-			X509_NAME_oneline(
-				X509_get_subject_name(ctx->current_cert),buf,
-				sizeof buf);
-			printf("%s\n",buf);
+			X509_NAME_print_ex_fp(stdout,
+				X509_get_subject_name(current_cert),
+				0, XN_FLAG_ONELINE);
+			printf("\n");
 			}
-		printf("error %d at %d depth lookup:%s\n",ctx->error,
-			ctx->error_depth,
-			X509_verify_cert_error_string(ctx->error));
-		if (ctx->error == X509_V_ERR_CERT_HAS_EXPIRED) ok=1;
-		/* since we are just checking the certificates, it is
-		 * ok if they are self signed. But we should still warn
-		 * the user.
- 		 */
-		if (ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) ok=1;
-		/* Continue after extension errors too */
-		if (ctx->error == X509_V_ERR_INVALID_CA) ok=1;
-		if (ctx->error == X509_V_ERR_INVALID_NON_CA) ok=1;
-		if (ctx->error == X509_V_ERR_PATH_LENGTH_EXCEEDED) ok=1;
-		if (ctx->error == X509_V_ERR_INVALID_PURPOSE) ok=1;
-		if (ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) ok=1;
-		if (ctx->error == X509_V_ERR_CRL_HAS_EXPIRED) ok=1;
-		if (ctx->error == X509_V_ERR_CRL_NOT_YET_VALID) ok=1;
-		if (ctx->error == X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION) ok=1;
+		printf("%serror %d at %d depth lookup:%s\n",
+			X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path]" : "",
+			cert_error,
+			X509_STORE_CTX_get_error_depth(ctx),
+			X509_verify_cert_error_string(cert_error));
+		switch(cert_error)
+			{
+			case X509_V_ERR_NO_EXPLICIT_POLICY:
+				policies_print(NULL, ctx);
+			case X509_V_ERR_CERT_HAS_EXPIRED:
 
-		if (ctx->error == X509_V_ERR_NO_EXPLICIT_POLICY)
-			policies_print(NULL, ctx);
+			/* since we are just checking the certificates, it is
+			 * ok if they are self signed. But we should still warn
+			 * the user.
+			 */
+
+			case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+			/* Continue after extension errors too */
+			case X509_V_ERR_INVALID_CA:
+			case X509_V_ERR_INVALID_NON_CA:
+			case X509_V_ERR_PATH_LENGTH_EXCEEDED:
+			case X509_V_ERR_INVALID_PURPOSE:
+			case X509_V_ERR_CRL_HAS_EXPIRED:
+			case X509_V_ERR_CRL_NOT_YET_VALID:
+			case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
+			ok = 1;
+
+			}
+
 		return ok;
 
 		}
-	if ((ctx->error == X509_V_OK) && (ok == 2))
+	if (cert_error == X509_V_OK && ok == 2)
 		policies_print(NULL, ctx);
 	if (!v_verbose)
 		ERR_clear_error();
diff --git a/apps/x509.c b/apps/x509.c
index b25508a..e7e46d7 100644
--- a/apps/x509.c
+++ b/apps/x509.c
@@ -99,7 +99,13 @@
 " -passin arg     - private key password source\n",
 " -serial         - print serial number value\n",
 " -subject_hash   - print subject hash value\n",
+#ifndef OPENSSL_NO_MD5
+" -subject_hash_old   - print old-style (MD5) subject hash value\n",
+#endif
 " -issuer_hash    - print issuer hash value\n",
+#ifndef OPENSSL_NO_MD5
+" -issuer_hash_old    - print old-style (MD5) issuer hash value\n",
+#endif
 " -hash           - synonym for -subject_hash\n",
 " -subject        - print subject DN\n",
 " -issuer         - print issuer DN\n",
@@ -179,6 +185,9 @@
 	int text=0,serial=0,subject=0,issuer=0,startdate=0,enddate=0;
 	int next_serial=0;
 	int subject_hash=0,issuer_hash=0,ocspid=0;
+#ifndef OPENSSL_NO_MD5
+	int subject_hash_old=0,issuer_hash_old=0;
+#endif
 	int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0;
 	int ocsp_uri=0;
 	int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0;
@@ -190,7 +199,7 @@
 	X509_REQ *rq=NULL;
 	int fingerprint=0;
 	char buf[256];
-	const EVP_MD *md_alg,*digest=EVP_sha1();
+	const EVP_MD *md_alg,*digest=NULL;
 	CONF *extconf = NULL;
 	char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL;
 	int need_rand = 0;
@@ -225,7 +234,7 @@
 
 	ctx=X509_STORE_new();
 	if (ctx == NULL) goto end;
-	X509_STORE_set_verify_cb_func(ctx,callb);
+	X509_STORE_set_verify_cb(ctx,callb);
 
 	argc--;
 	argv++;
@@ -397,8 +406,16 @@
 		else if (strcmp(*argv,"-hash") == 0
 			|| strcmp(*argv,"-subject_hash") == 0)
 			subject_hash= ++num;
+#ifndef OPENSSL_NO_MD5
+		else if (strcmp(*argv,"-subject_hash_old") == 0)
+			subject_hash_old= ++num;
+#endif
 		else if (strcmp(*argv,"-issuer_hash") == 0)
 			issuer_hash= ++num;
+#ifndef OPENSSL_NO_MD5
+		else if (strcmp(*argv,"-issuer_hash_old") == 0)
+			issuer_hash_old= ++num;
+#endif
 		else if (strcmp(*argv,"-subject") == 0)
 			subject= ++num;
 		else if (strcmp(*argv,"-issuer") == 0)
@@ -626,7 +643,7 @@
 		if (!X509_set_subject_name(x,req->req_info->subject)) goto end;
 
 		X509_gmtime_adj(X509_get_notBefore(x),0);
-	        X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);
+	        X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL);
 
 		pkey = X509_REQ_get_pubkey(req);
 		X509_set_pubkey(x,pkey);
@@ -738,13 +755,14 @@
 			else if ((email == i) || (ocsp_uri == i))
 				{
 				int j;
-				STACK *emlst;
+				STACK_OF(OPENSSL_STRING) *emlst;
 				if (email == i)
 					emlst = X509_get1_email(x);
 				else
 					emlst = X509_get1_ocsp(x);
-				for (j = 0; j < sk_num(emlst); j++)
-					BIO_printf(STDout, "%s\n", sk_value(emlst, j));
+				for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
+					BIO_printf(STDout, "%s\n",
+						   sk_OPENSSL_STRING_value(emlst, j));
 				X509_email_free(emlst);
 				}
 			else if (aliasout == i)
@@ -758,10 +776,22 @@
 				{
 				BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x));
 				}
+#ifndef OPENSSL_NO_MD5
+			else if (subject_hash_old == i)
+				{
+				BIO_printf(STDout,"%08lx\n",X509_subject_name_hash_old(x));
+				}
+#endif
 			else if (issuer_hash == i)
 				{
 				BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash(x));
 				}
+#ifndef OPENSSL_NO_MD5
+			else if (issuer_hash_old == i)
+				{
+				BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash_old(x));
+				}
+#endif
 			else if (pprint == i)
 				{
 				X509_PURPOSE *ptmp;
@@ -892,14 +922,18 @@
 				int j;
 				unsigned int n;
 				unsigned char md[EVP_MAX_MD_SIZE];
+				const EVP_MD *fdig = digest;
 
-				if (!X509_digest(x,digest,md,&n))
+				if (!fdig)
+					fdig = EVP_sha1();
+
+				if (!X509_digest(x,fdig,md,&n))
 					{
 					BIO_printf(bio_err,"out of memory\n");
 					goto end;
 					}
 				BIO_printf(STDout,"%s Fingerprint=",
-						OBJ_nid2sn(EVP_MD_type(digest)));
+						OBJ_nid2sn(EVP_MD_type(fdig)));
 				for (j=0; j<(int)n; j++)
 					{
 					BIO_printf(STDout,"%02X%c",md[j],
@@ -919,14 +953,6 @@
 						passin, e, "Private key");
 					if (Upkey == NULL) goto end;
 					}
-#ifndef OPENSSL_NO_DSA
-		                if (Upkey->type == EVP_PKEY_DSA)
-		                        digest=EVP_dss1();
-#endif
-#ifndef OPENSSL_NO_ECDSA
-				if (Upkey->type == EVP_PKEY_EC)
-					digest=EVP_ecdsa();
-#endif
 
 				assert(need_rand);
 				if (!sign(x,Upkey,days,clrext,digest,
@@ -943,14 +969,6 @@
 						"CA Private Key");
 					if (CApkey == NULL) goto end;
 					}
-#ifndef OPENSSL_NO_DSA
-		                if (CApkey->type == EVP_PKEY_DSA)
-		                        digest=EVP_dss1();
-#endif
-#ifndef OPENSSL_NO_ECDSA
-				if (CApkey->type == EVP_PKEY_EC)
-					digest = EVP_ecdsa();
-#endif
 				
 				assert(need_rand);
 				if (!x509_certify(ctx,CAfile,digest,x,xca,
@@ -978,15 +996,6 @@
 
 				BIO_printf(bio_err,"Generating certificate request\n");
 
-#ifndef OPENSSL_NO_DSA
-		                if (pk->type == EVP_PKEY_DSA)
-		                        digest=EVP_dss1();
-#endif
-#ifndef OPENSSL_NO_ECDSA
-				if (pk->type == EVP_PKEY_EC)
-					digest=EVP_ecdsa();
-#endif
-
 				rq=X509_to_X509_REQ(x,pk,digest);
 				EVP_PKEY_free(pk);
 				if (rq == NULL)
@@ -1040,16 +1049,15 @@
 		}
 	else if (outformat == FORMAT_NETSCAPE)
 		{
-		ASN1_HEADER ah;
-		ASN1_OCTET_STRING os;
+		NETSCAPE_X509 nx;
+		ASN1_OCTET_STRING hdr;
 
-		os.data=(unsigned char *)NETSCAPE_CERT_HDR;
-		os.length=strlen(NETSCAPE_CERT_HDR);
-		ah.header= &os;
-		ah.data=(char *)x;
-		ah.meth=X509_asn1_meth();
+		hdr.data=(unsigned char *)NETSCAPE_CERT_HDR;
+		hdr.length=strlen(NETSCAPE_CERT_HDR);
+		nx.header= &hdr;
+		nx.cert=x;
 
-		i=ASN1_i2d_bio_of(ASN1_HEADER,i2d_ASN1_HEADER,out,&ah);
+		i=ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509),out,&nx);
 		}
 	else	{
 		BIO_printf(bio_err,"bad output format specified for outfile\n");
@@ -1168,7 +1176,7 @@
 		goto end;
 
 	/* hardwired expired */
-	if (X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days) == NULL)
+	if (X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL) == NULL)
 		goto end;
 
 	if (clrext)
diff --git a/crypto/0.9.9-dev/README.android b/crypto/0.9.9-dev/README.android
deleted file mode 100644
index b82f6d4..0000000
--- a/crypto/0.9.9-dev/README.android
+++ /dev/null
@@ -1,6 +0,0 @@
-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.
diff --git a/crypto/0.9.9-dev/sha/sha1-armv4-large.s b/crypto/0.9.9-dev/sha/sha1-armv4-large.s
deleted file mode 100644
index 4945754..0000000
--- a/crypto/0.9.9-dev/sha/sha1-armv4-large.s
+++ /dev/null
@@ -1,376 +0,0 @@
-.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 <appro@openssl.org>"
diff --git a/crypto/Android.mk b/crypto/Android.mk
index 23e56b0..14bac8e 100644
--- a/crypto/Android.mk
+++ b/crypto/Android.mk
@@ -3,11 +3,11 @@
 
 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
+	LOCAL_SRC_FILES:= aes/asm/aes-armv4.s \
+	                  bn/asm/armv4-mont.s \
+	                  sha/asm/sha1-armv4-large.s \
+	                  sha/asm/sha256-armv4.s \
+	                  sha/asm/sha512-armv4.s
 else
 	LOCAL_SRC_FILES:= aes/aes_core.c
 endif
@@ -23,255 +23,281 @@
 	mem_clr.c \
 	mem_dbg.c \
 	cversion.c \
-	dyn_lck.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_ecb.c \
+	aes/aes_misc.c \
+	aes/aes_ofb.c \
 	aes/aes_wrap.c \
-	asn1/a_object.c \
 	asn1/a_bitstr.c \
-	asn1/a_utctm.c \
+	asn1/a_bool.c \
+	asn1/a_bytes.c \
+	asn1/a_d2i_fp.c \
+	asn1/a_digest.c \
+	asn1/a_dup.c \
+	asn1/a_enum.c \
 	asn1/a_gentm.c \
-	asn1/a_time.c \
+	asn1/a_i2d_fp.c \
 	asn1/a_int.c \
+	asn1/a_mbstr.c \
+	asn1/a_object.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/a_strnid.c \
+	asn1/a_time.c \
+	asn1/a_type.c \
+	asn1/a_utctm.c \
+	asn1/a_utf8.c \
+	asn1/a_verify.c \
+	asn1/ameth_lib.c \
+	asn1/asn1_err.c \
+	asn1/asn1_gen.c \
+	asn1/asn1_lib.c \
+	asn1/asn1_par.c \
+	asn1/asn_mime.c \
+	asn1/asn_moid.c \
+	asn1/asn_pack.c \
+	asn1/bio_asn1.c \
+	asn1/bio_ndef.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/d2i_pu.c \
+	asn1/evp_asn1.c \
+	asn1/f_enum.c \
 	asn1/f_int.c \
 	asn1/f_string.c \
+	asn1/i2d_pr.c \
+	asn1/i2d_pu.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/nsseq.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 \
+	asn1/t_bitst.c \
+	asn1/t_crl.c \
+	asn1/t_pkey.c \
+	asn1/t_req.c \
+	asn1/t_spki.c \
+	asn1/t_x509.c \
+	asn1/t_x509a.c \
+	asn1/tasn_dec.c \
+	asn1/tasn_enc.c \
+	asn1/tasn_fre.c \
+	asn1/tasn_new.c \
+	asn1/tasn_prn.c \
+	asn1/tasn_typ.c \
+	asn1/tasn_utl.c \
+	asn1/x_algor.c \
+	asn1/x_attrib.c \
+	asn1/x_bignum.c \
+	asn1/x_crl.c \
+	asn1/x_exten.c \
+	asn1/x_info.c \
+	asn1/x_long.c \
+	asn1/x_name.c \
+	asn1/x_nx509.c \
+	asn1/x_pkey.c \
+	asn1/x_pubkey.c \
+	asn1/x_req.c \
+	asn1/x_sig.c \
+	asn1/x_spki.c \
+	asn1/x_val.c \
+	asn1/x_x509.c \
+	asn1/x_x509a.c \
+	bio/b_dump.c \
+	bio/b_print.c \
+	bio/b_sock.c \
+	bio/bf_buff.c \
+	bio/bf_nbio.c \
+	bio/bf_null.c \
 	bio/bio_cb.c \
 	bio/bio_err.c \
-	bio/bss_mem.c \
-	bio/bss_null.c \
+	bio/bio_lib.c \
+	bio/bss_acpt.c \
+	bio/bss_bio.c \
+	bio/bss_conn.c \
+	bio/bss_dgram.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 \
+	bio/bss_mem.c \
+	bio/bss_null.c \
+	bio/bss_sock.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_blind.c \
+	bn/bn_ctx.c \
+	bn/bn_div.c \
+	bn/bn_err.c \
+	bn/bn_exp.c \
+	bn/bn_exp2.c \
+	bn/bn_gcd.c \
+	bn/bn_gf2m.c \
+	bn/bn_kron.c \
+	bn/bn_lib.c \
+	bn/bn_mod.c \
 	bn/bn_mont.c \
 	bn/bn_mpi.c \
-	bn/bn_exp2.c \
+	bn/bn_mul.c \
 	bn/bn_nist.c \
-	bn/bn_gf2m.c \
-	bn/bn_x931p.c \
-	buffer/buffer.c \
+	bn/bn_prime.c \
+	bn/bn_print.c \
+	bn/bn_rand.c \
+	bn/bn_recp.c \
+	bn/bn_shift.c \
+	bn/bn_sqr.c \
+	bn/bn_sqrt.c \
+	bn/bn_word.c \
 	buffer/buf_err.c \
-	buffer/buf_str.c \
-	comp/comp_lib.c \
-	comp/comp_err.c \
+	buffer/buffer.c \
 	comp/c_rle.c \
 	comp/c_zlib.c \
-	conf/conf_err.c \
-	conf/conf_lib.c \
+	comp/comp_err.c \
+	comp/comp_lib.c \
 	conf/conf_api.c \
 	conf/conf_def.c \
-	conf/conf_mod.c \
+	conf/conf_err.c \
+	conf/conf_lib.c \
 	conf/conf_mall.c \
+	conf/conf_mod.c \
 	conf/conf_sap.c \
 	des/cbc_cksm.c \
 	des/cbc_enc.c \
+	des/cfb64ede.c \
 	des/cfb64enc.c \
 	des/cfb_enc.c \
-	des/des_lib.c \
+	des/des_enc.c \
+	des/des_old.c \
+	des/des_old2.c \
 	des/ecb3_enc.c \
 	des/ecb_enc.c \
+	des/ede_cbcm_enc.c \
 	des/enc_read.c \
 	des/enc_writ.c \
 	des/fcrypt.c \
+	des/fcrypt_b.c \
+	des/ofb64ede.c \
 	des/ofb64enc.c \
 	des/ofb_enc.c \
 	des/pcbc_enc.c \
 	des/qud_cksm.c \
 	des/rand_key.c \
+	des/read2pwd.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 \
+	des/xcbc_enc.c \
+	dh/dh_ameth.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 \
+	dh/dh_pmeth.c \
+	dsa/dsa_ameth.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_pmeth.c \
+	dsa/dsa_prn.c \
+	dsa/dsa_sign.c \
+	dsa/dsa_vrf.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 \
+	dso/dso_win32.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/bio_b64.c \
+	evp/bio_enc.c \
+	evp/bio_md.c \
+	evp/bio_ok.c \
+	evp/c_all.c \
+	evp/c_allc.c \
+	evp/c_alld.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_aes.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_null.c \
+	evp/e_old.c \
 	evp/e_rc2.c \
+	evp/e_rc4.c \
 	evp/e_rc5.c \
-	evp/m_null.c \
+	evp/e_xcbc_d.c \
+	evp/encode.c \
+	evp/evp_acnf.c \
+	evp/evp_enc.c \
+	evp/evp_err.c \
+	evp/evp_key.c \
+	evp/evp_lib.c \
+	evp/evp_pbe.c \
+	evp/evp_pkey.c \
+	evp/m_dss.c \
+	evp/m_dss1.c \
 	evp/m_md2.c \
 	evp/m_md4.c \
 	evp/m_md5.c \
+	evp/m_mdc2.c \
+	evp/m_null.c \
+	evp/m_ripemd.c \
 	evp/m_sha.c \
 	evp/m_sha1.c \
-	evp/m_dss.c \
-	evp/m_dss1.c \
-	evp/m_mdc2.c \
+	evp/m_sigver.c \
+	evp/m_wp.c \
+	evp/names.c \
+	evp/p5_crpt.c \
+	evp/p5_crpt2.c \
+	evp/p_dec.c \
+	evp/p_enc.c \
+	evp/p_lib.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 \
+	evp/pmeth_fn.c \
+	evp/pmeth_gn.c \
+	evp/pmeth_lib.c \
+	hmac/hm_ameth.c \
+	hmac/hm_pmeth.c \
 	hmac/hmac.c \
 	krb5/krb5_asn.c \
-	lhash/lhash.c \
 	lhash/lh_stats.c \
+	lhash/lhash.c \
 	md4/md4_dgst.c \
 	md4/md4_one.c \
 	md5/md5_dgst.c \
 	md5/md5_one.c \
+	modes/cbc128.c \
+	modes/cfb128.c \
+	modes/ctr128.c \
+	modes/ofb128.c \
 	objects/o_names.c \
 	objects/obj_dat.c \
-	objects/obj_lib.c \
 	objects/obj_err.c \
+	objects/obj_lib.c \
+	objects/obj_xref.c \
 	ocsp/ocsp_asn.c \
 	ocsp/ocsp_cl.c \
 	ocsp/ocsp_err.c \
@@ -281,17 +307,18 @@
 	ocsp/ocsp_prn.c \
 	ocsp/ocsp_srv.c \
 	ocsp/ocsp_vfy.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_info.c \
+	pem/pem_lib.c \
 	pem/pem_oth.c \
 	pem/pem_pk8.c \
 	pem/pem_pkey.c \
+	pem/pem_seal.c \
+	pem/pem_sign.c \
+	pem/pem_x509.c \
+	pem/pem_xaux.c \
+	pem/pvkfmt.c \
 	pkcs12/p12_add.c \
 	pkcs12/p12_asn.c \
 	pkcs12/p12_attr.c \
@@ -302,139 +329,123 @@
 	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 \
+	pkcs12/p12_utl.c \
+	pkcs12/pk12err.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_doit.c \
+	pkcs7/pk7_lib.c	\
 	pkcs7/pk7_mime.c \
+	pkcs7/pk7_smime.c \
+	pkcs7/pkcs7err.c \
 	rand/md_rand.c \
-	rand/randfile.c \
-	rand/rand_lib.c \
-	rand/rand_err.c \
 	rand/rand_egd.c \
+	rand/rand_err.c \
+	rand/rand_lib.c \
 	rand/rand_unix.c \
+	rand/randfile.c \
+	rc2/rc2_cbc.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 \
+	rc4/rc4_skey.c \
+	ripemd/rmd_dgst.c \
+	ripemd/rmd_one.c \
+	rsa/rsa_ameth.c \
+	rsa/rsa_asn1.c \
+	rsa/rsa_chk.c \
 	rsa/rsa_eay.c \
-	rsa/rsa_eng.c \
+	rsa/rsa_err.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_oaep.c \
+	rsa/rsa_pk1.c \
+	rsa/rsa_pmeth.c \
+	rsa/rsa_prn.c \
 	rsa/rsa_pss.c \
+	rsa/rsa_saos.c \
+	rsa/rsa_sign.c \
+	rsa/rsa_ssl.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/sha1dgst.c \
 	sha/sha256.c \
 	sha/sha512.c \
+	sha/sha_dgst.c \
+	sha/sha_one.c \
 	stack/stack.c \
+	ts/ts_err.c \
 	txt_db/txt_db.c \
+	ui/ui_compat.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 \
+	x509/by_file.c \
+	x509/x509_att.c \
+	x509/x509_cmp.c \
+	x509/x509_d2.c \
+	x509/x509_def.c \
+	x509/x509_err.c \
+	x509/x509_ext.c \
+	x509/x509_lu.c \
+	x509/x509_obj.c \
+	x509/x509_r2x.c \
+	x509/x509_req.c \
+	x509/x509_set.c \
+	x509/x509_trs.c \
+	x509/x509_txt.c \
+	x509/x509_v3.c \
+	x509/x509_vfy.c \
+	x509/x509_vpm.c \
+	x509/x509cset.c \
+	x509/x509name.c \
+	x509/x509rset.c \
+	x509/x509spki.c \
+	x509/x509type.c \
+	x509/x_all.c \
+	x509v3/pcy_cache.c \
+	x509v3/pcy_data.c \
+	x509v3/pcy_lib.c \
+	x509v3/pcy_map.c \
+	x509v3/pcy_node.c \
+	x509v3/pcy_tree.c \
+	x509v3/v3_akey.c \
+	x509v3/v3_akeya.c \
+	x509v3/v3_alt.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_enum.c \
+	x509v3/v3_extku.c \
+	x509v3/v3_genn.c \
+	x509v3/v3_ia5.c \
 	x509v3/v3_info.c \
-	x509v3/v3_akeya.c \
-	x509v3/v3_ocsp.c \
-	x509v3/v3_pcia.c \
-	x509v3/v3_pci.c \
-	x509v3/v3_pmaps.c \
-	x509v3/v3_pcons.c \
+	x509v3/v3_int.c \
+	x509v3/v3_lib.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
+	x509v3/v3_ocsp.c \
+	x509v3/v3_pci.c \
+	x509v3/v3_pcia.c \
+	x509v3/v3_pcons.c \
+	x509v3/v3_pku.c \
+	x509v3/v3_pmaps.c \
+	x509v3/v3_prn.c \
+	x509v3/v3_purp.c \
+	x509v3/v3_skey.c \
+	x509v3/v3_sxnet.c \
+	x509v3/v3_utl.c \
+	x509v3/v3err.c
 
 LOCAL_CFLAGS += -DNO_WINDOWS_BRAINDEATH
 
@@ -442,7 +453,10 @@
 
 LOCAL_C_INCLUDES += \
 	external/openssl \
+	external/openssl/crypto/asn1 \
+	external/openssl/crypto/evp \
 	external/openssl/include \
+	external/openssl/include/openssl \
 	external/zlib
 
 LOCAL_SHARED_LIBRARIES += libz
diff --git a/crypto/LPdir_win.c b/crypto/LPdir_win.c
index 09b475b..702dbc7 100644
--- a/crypto/LPdir_win.c
+++ b/crypto/LPdir_win.c
@@ -54,8 +54,6 @@
 
 const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
 {
-  struct dirent *direntry = NULL;
-
   if (ctx == NULL || directory == NULL)
     {
       errno = EINVAL;
diff --git a/crypto/Makefile b/crypto/Makefile
deleted file mode 100644
index 6557f2b..0000000
--- a/crypto/Makefile
+++ /dev/null
@@ -1,224 +0,0 @@
-#
-# OpenSSL/crypto/Makefile
-#
-
-DIR=		crypto
-TOP=		..
-CC=		cc
-INCLUDE=	-I. -I$(TOP) -I../include
-# INCLUDES targets sudbirs!
-INCLUDES=	-I.. -I../.. -I../../include
-CFLAG=		-g
-MAKEDEPPROG=	makedepend
-MAKEDEPEND=	$(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
-MAKEFILE=       Makefile
-RM=             rm -f
-AR=		ar r
-
-RECURSIVE_MAKE=	[ -n "$(SDIRS)" ] && for i in $(SDIRS) ; do \
-		    (cd $$i && echo "making $$target in $(DIR)/$$i..." && \
-		    $(MAKE) -e TOP=../.. DIR=$$i INCLUDES='${INCLUDES}' $$target ) || exit 1; \
-		done;
-
-PEX_LIBS=
-EX_LIBS=
- 
-CFLAGS= $(INCLUDE) $(CFLAG)
-ASFLAGS= $(INCLUDE) $(ASFLAG)
-AFLAGS=$(ASFLAGS)
-
-LIBS=
-
-GENERAL=Makefile README crypto-lib.com install.com
-
-LIB= $(TOP)/libcrypto.a
-SHARED_LIB= libcrypto$(SHLIB_EXT)
-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)
-
-EXHEADER= crypto.h tmdiff.h opensslv.h opensslconf.h ebcdic.h symhacks.h \
-	ossl_typ.h
-HEADER=	cryptlib.h buildinf.h md32_common.h o_time.h o_str.h o_dir.h $(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	@(cd ..; $(MAKE) DIRS=$(DIR) all)
-
-all: lib
-
-buildinf.h: ../Makefile
-	( echo "#ifndef MK1MF_BUILD"; \
-	echo '  /* auto-generated by crypto/Makefile for crypto/cversion.c */'; \
-	echo '  #define CFLAGS "$(CC) $(CFLAG)"'; \
-	echo '  #define PLATFORM "$(PLATFORM)"'; \
-	echo "  #define DATE \"`LC_ALL=C LC_TIME=C date`\""; \
-	echo '#endif' ) >buildinf.h
-
-x86cpuid-elf.s:	x86cpuid.pl perlasm/x86asm.pl
-	$(PERL) x86cpuid.pl elf $(CFLAGS) $(PROCESSOR) > $@
-x86cpuid-cof.s: x86cpuid.pl perlasm/x86asm.pl
-	$(PERL) x86cpuid.pl coff $(CFLAGS) $(PROCESSOR) > $@
-x86cpuid-out.s: x86cpuid.pl perlasm/x86asm.pl
-	$(PERL) x86cpuid.pl a.out $(CFLAGS) $(PROCESSOR) > $@
-
-uplink.o:	../ms/uplink.c
-	$(CC) $(CFLAGS) -c -o $@ ../ms/uplink.c
-
-uplink-cof.s:	../ms/uplink.pl
-	$(PERL) ../ms/uplink.pl coff > $@
-
-x86_64cpuid.s: x86_64cpuid.pl
-	$(PERL) x86_64cpuid.pl $@
-ia64cpuid.s: ia64cpuid.S
-	$(CC) $(CFLAGS) -E ia64cpuid.S > $@
-
-testapps:
-	[ -z "$(THIS)" ] || (	if echo ${SDIRS} | fgrep ' des '; \
-				then cd des && $(MAKE) -e des; fi )
-	[ -z "$(THIS)" ] || ( cd pkcs7 && $(MAKE) -e testapps );
-	@if [ -z "$(THIS)" ]; then $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; fi
-
-subdirs:
-	@target=all; $(RECURSIVE_MAKE)
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-	@target=files; $(RECURSIVE_MAKE)
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../apps $(APPS)
-	@target=links; $(RECURSIVE_MAKE)
-
-# lib: and $(LIB): are splitted to avoid end-less loop
-lib:	buildinf.h $(LIB) subdirs
-	@touch lib
-$(LIB):	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-
-shared: buildinf.h lib subdirs
-	if [ -n "$(SHARED_LIBS)" ]; then \
-		(cd ..; $(MAKE) $(SHARED_LIB)); \
-	fi
-
-libs:
-	@target=lib; $(RECURSIVE_MAKE)
-
-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;
-	@target=install; $(RECURSIVE_MAKE)
-
-lint:
-	@target=lint; $(RECURSIVE_MAKE)
-
-depend:
-	@[ -z "$(THIS)" -o -f buildinf.h ] || touch buildinf.h # fake buildinf.h if it does not exist
-	@[ -z "$(THIS)" ] || $(MAKEDEPEND) -- $(CFLAG) $(INCLUDE) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
-	@[ -z "$(THIS)" -o -s buildinf.h ] || rm buildinf.h
-	@[ -z "$(THIS)" ] || (set -e; target=depend; $(RECURSIVE_MAKE) )
-	@if [ -z "$(THIS)" ]; then $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; fi
-
-clean:
-	rm -f buildinf.h *.s *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-	@target=clean; $(RECURSIVE_MAKE)
-
-dclean:
-	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
-	mv -f Makefile.new $(MAKEFILE)
-	@target=dclean; $(RECURSIVE_MAKE)
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-cpt_err.o: ../include/openssl/bio.h ../include/openssl/crypto.h
-cpt_err.o: ../include/openssl/e_os2.h ../include/openssl/err.h
-cpt_err.o: ../include/openssl/lhash.h ../include/openssl/opensslconf.h
-cpt_err.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-cpt_err.o: ../include/openssl/safestack.h ../include/openssl/stack.h
-cpt_err.o: ../include/openssl/symhacks.h cpt_err.c
-cryptlib.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
-cryptlib.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-cryptlib.o: ../include/openssl/err.h ../include/openssl/lhash.h
-cryptlib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-cryptlib.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
-cryptlib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.c
-cryptlib.o: cryptlib.h
-cversion.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
-cversion.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-cversion.o: ../include/openssl/err.h ../include/openssl/lhash.h
-cversion.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-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
-ex_data.o: ../include/openssl/err.h ../include/openssl/lhash.h
-ex_data.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-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
-mem.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-mem.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
-mem.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h
-mem.o: mem.c
-mem_clr.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-mem_clr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-mem_clr.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
-mem_clr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h mem_clr.c
-mem_dbg.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
-mem_dbg.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-mem_dbg.o: ../include/openssl/err.h ../include/openssl/lhash.h
-mem_dbg.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-mem_dbg.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
-mem_dbg.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h
-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
-o_time.o: o_time.h
-tmdiff.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
-tmdiff.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-tmdiff.o: ../include/openssl/err.h ../include/openssl/lhash.h
-tmdiff.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-tmdiff.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
-tmdiff.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-tmdiff.o: ../include/openssl/tmdiff.h cryptlib.h tmdiff.c
-uid.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-uid.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-uid.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
-uid.o: ../include/openssl/stack.h ../include/openssl/symhacks.h uid.c
diff --git a/crypto/aes/Makefile b/crypto/aes/Makefile
deleted file mode 100644
index 9d174f4..0000000
--- a/crypto/aes/Makefile
+++ /dev/null
@@ -1,131 +0,0 @@
-#
-# crypto/aes/Makefile
-#
-
-DIR=	aes
-TOP=	../..
-CC=	cc
-CPP=	$(CC) -E
-INCLUDES=
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-AES_ASM_OBJ=aes_core.o aes_cbc.o
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-ASFLAGS= $(INCLUDES) $(ASFLAG)
-AFLAGS= $(ASFLAGS)
-
-GENERAL=Makefile
-#TEST=aestest.c
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=aes_core.c aes_misc.c aes_ecb.c aes_cbc.c aes_cfb.c aes_ofb.c \
-       aes_ctr.c aes_ige.c aes_wrap.c
-LIBOBJ=aes_misc.o aes_ecb.o aes_cfb.o aes_ofb.o aes_ctr.o aes_ige.o aes_wrap.o \
-       $(AES_ASM_OBJ)
-
-SRC= $(LIBSRC)
-
-EXHEADER= aes.h
-HEADER= aes_locl.h $(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-$(LIBOBJ): $(LIBSRC)
-
-aes-ia64.s: asm/aes-ia64.S
-	$(CC) $(CFLAGS) -E asm/aes-ia64.S > $@
-
-ax86-elf.s: asm/aes-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) aes-586.pl elf $(CFLAGS) $(PROCESSOR) > ../$@)
-ax86-cof.s: asm/aes-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) aes-586.pl coff $(CFLAGS) $(PROCESSOR) > ../$@)
-ax86-out.s: asm/aes-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) aes-586.pl a.out $(CFLAGS) $(PROCESSOR) > ../$@)
-
-aes-x86_64.s: asm/aes-x86_64.pl
-	$(PERL) asm/aes-x86_64.pl $@
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-aes_cbc.o: ../../include/openssl/aes.h ../../include/openssl/e_os2.h
-aes_cbc.o: ../../include/openssl/opensslconf.h aes_cbc.c aes_locl.h
-aes_cfb.o: ../../e_os.h ../../include/openssl/aes.h
-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/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
-aes_ecb.o: ../../include/openssl/opensslconf.h aes_ecb.c aes_locl.h
-aes_ige.o: ../../e_os.h ../../include/openssl/aes.h ../../include/openssl/bio.h
-aes_ige.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-aes_ige.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-aes_ige.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-aes_ige.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-aes_ige.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-aes_ige.o: ../../include/openssl/symhacks.h ../cryptlib.h aes_ige.c aes_locl.h
-aes_misc.o: ../../include/openssl/aes.h ../../include/openssl/e_os2.h
-aes_misc.o: ../../include/openssl/opensslconf.h
-aes_misc.o: ../../include/openssl/opensslv.h aes_locl.h aes_misc.c
-aes_ofb.o: ../../include/openssl/aes.h ../../include/openssl/e_os2.h
-aes_ofb.o: ../../include/openssl/opensslconf.h aes_locl.h aes_ofb.c
-aes_wrap.o: ../../e_os.h ../../include/openssl/aes.h
-aes_wrap.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-aes_wrap.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-aes_wrap.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-aes_wrap.o: ../../include/openssl/opensslconf.h
-aes_wrap.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-aes_wrap.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-aes_wrap.o: ../../include/openssl/symhacks.h ../cryptlib.h aes_wrap.c
diff --git a/crypto/aes/aes.h b/crypto/aes/aes.h
index 450f2b4..d2c9973 100644
--- a/crypto/aes/aes.h
+++ b/crypto/aes/aes.h
@@ -58,6 +58,8 @@
 #error AES is disabled.
 #endif
 
+#include <stddef.h>
+
 #define AES_ENCRYPT	1
 #define AES_DECRYPT	0
 
@@ -66,10 +68,6 @@
 #define AES_MAXNR 14
 #define AES_BLOCK_SIZE 16
 
-#ifdef OPENSSL_FIPS
-#define FIPS_AES_SIZE_T	int
-#endif
-
 #ifdef  __cplusplus
 extern "C" {
 #endif
@@ -100,37 +98,32 @@
 void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
 	const AES_KEY *key, const int enc);
 void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const AES_KEY *key,
+	size_t length, const AES_KEY *key,
 	unsigned char *ivec, const int enc);
 void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const AES_KEY *key,
+	size_t length, const AES_KEY *key,
 	unsigned char *ivec, int *num, const int enc);
 void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const AES_KEY *key,
+	size_t length, const AES_KEY *key,
 	unsigned char *ivec, int *num, const int enc);
 void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const AES_KEY *key,
+	size_t length, const AES_KEY *key,
 	unsigned char *ivec, int *num, const int enc);
-void AES_cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
-			    const int nbits,const AES_KEY *key,
-			    unsigned char *ivec,const int enc);
 void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const AES_KEY *key,
+	size_t length, const AES_KEY *key,
 	unsigned char *ivec, int *num);
 void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const AES_KEY *key,
+	size_t length, const AES_KEY *key,
 	unsigned char ivec[AES_BLOCK_SIZE],
 	unsigned char ecount_buf[AES_BLOCK_SIZE],
 	unsigned int *num);
-
-/* For IGE, see also http://www.links.org/files/openssl-ige.pdf */
 /* NB: the IV is _two_ blocks long */
 void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
-		     const unsigned long length, const AES_KEY *key,
+		     size_t length, const AES_KEY *key,
 		     unsigned char *ivec, const int enc);
 /* NB: the IV is _four_ blocks long */
 void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
-			const unsigned long length, const AES_KEY *key,
+			size_t length, const AES_KEY *key,
 			const AES_KEY *key2, const unsigned char *ivec,
 			const int enc);
 
@@ -141,6 +134,7 @@
 		unsigned char *out,
 		const unsigned char *in, unsigned int inlen);
 
+
 #ifdef  __cplusplus
 }
 #endif
diff --git a/crypto/aes/aes_cbc.c b/crypto/aes/aes_cbc.c
index 373864c..227f756 100644
--- a/crypto/aes/aes_cbc.c
+++ b/crypto/aes/aes_cbc.c
@@ -49,85 +49,15 @@
  *
  */
 
-#ifndef AES_DEBUG
-# ifndef NDEBUG
-#  define NDEBUG
-# endif
-#endif
-#include <assert.h>
-
 #include <openssl/aes.h>
-#include "aes_locl.h"
+#include <openssl/modes.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,
+		     size_t len, const AES_KEY *key,
 		     unsigned char *ivec, const int enc) {
 
-	unsigned long n;
-	unsigned long len = length;
-	unsigned char tmp[AES_BLOCK_SIZE];
-	const unsigned char *iv = ivec;
-
-	assert(in && out && key && ivec);
-	assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
-
-	if (AES_ENCRYPT == enc) {
-		while (len >= AES_BLOCK_SIZE) {
-			for(n=0; n < AES_BLOCK_SIZE; ++n)
-				out[n] = in[n] ^ iv[n];
-			AES_encrypt(out, out, key);
-			iv = out;
-			len -= AES_BLOCK_SIZE;
-			in += AES_BLOCK_SIZE;
-			out += AES_BLOCK_SIZE;
-		}
-		if (len) {
-			for(n=0; n < len; ++n)
-				out[n] = in[n] ^ iv[n];
-			for(n=len; n < AES_BLOCK_SIZE; ++n)
-				out[n] = iv[n];
-			AES_encrypt(out, out, key);
-			iv = out;
-		}
-		memcpy(ivec,iv,AES_BLOCK_SIZE);
-	} else if (in != out) {
-		while (len >= AES_BLOCK_SIZE) {
-			AES_decrypt(in, out, key);
-			for(n=0; n < AES_BLOCK_SIZE; ++n)
-				out[n] ^= iv[n];
-			iv = in;
-			len -= AES_BLOCK_SIZE;
-			in  += AES_BLOCK_SIZE;
-			out += AES_BLOCK_SIZE;
-		}
-		if (len) {
-			AES_decrypt(in,tmp,key);
-			for(n=0; n < len; ++n)
-				out[n] = tmp[n] ^ iv[n];
-			iv = in;
-		}
-		memcpy(ivec,iv,AES_BLOCK_SIZE);
-	} else {
-		while (len >= AES_BLOCK_SIZE) {
-			memcpy(tmp, in, AES_BLOCK_SIZE);
-			AES_decrypt(in, out, key);
-			for(n=0; n < AES_BLOCK_SIZE; ++n)
-				out[n] ^= ivec[n];
-			memcpy(ivec, tmp, AES_BLOCK_SIZE);
-			len -= AES_BLOCK_SIZE;
-			in += AES_BLOCK_SIZE;
-			out += AES_BLOCK_SIZE;
-		}
-		if (len) {
-			memcpy(tmp, in, AES_BLOCK_SIZE);
-			AES_decrypt(tmp, out, key);
-			for(n=0; n < len; ++n)
-				out[n] ^= ivec[n];
-			for(n=len; n < AES_BLOCK_SIZE; ++n)
-				out[n] = tmp[n];
-			memcpy(ivec, tmp, AES_BLOCK_SIZE);
-		}
-	}
+	if (enc)
+		CRYPTO_cbc128_encrypt(in,out,len,key,ivec,(block128_f)AES_encrypt);
+	else
+		CRYPTO_cbc128_decrypt(in,out,len,key,ivec,(block128_f)AES_decrypt);
 }
-#endif
diff --git a/crypto/aes/aes_cfb.c b/crypto/aes/aes_cfb.c
index 9384ba6..0c6d058 100644
--- a/crypto/aes/aes_cfb.c
+++ b/crypto/aes/aes_cfb.c
@@ -1,6 +1,6 @@
 /* crypto/aes/aes_cfb.c -*- mode:C; c-file-style: "eay" -*- */
 /* ====================================================================
- * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 2002-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
@@ -48,73 +48,9 @@
  * ====================================================================
  *
  */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#ifndef AES_DEBUG
-# ifndef NDEBUG
-#  define NDEBUG
-# endif
-#endif
-#include <assert.h>
 
 #include <openssl/aes.h>
-#include "aes_locl.h"
-#include "e_os.h"
+#include <openssl/modes.h>
 
 /* The input and output encrypted as though 128bit cfb mode is being
  * used.  The extra state information to record how much of the
@@ -122,103 +58,24 @@
  */
 
 void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const AES_KEY *key,
+	size_t length, const AES_KEY *key,
 	unsigned char *ivec, int *num, const int enc) {
 
-	unsigned int n;
-	unsigned long l = length;
-	unsigned char c;
-
-	assert(in && out && key && ivec && num);
-
-	n = *num;
-
-	if (enc) {
-		while (l--) {
-			if (n == 0) {
-				AES_encrypt(ivec, ivec, key);
-			}
-			ivec[n] = *(out++) = *(in++) ^ ivec[n];
-			n = (n+1) % AES_BLOCK_SIZE;
-		}
-	} else {
-		while (l--) {
-			if (n == 0) {
-				AES_encrypt(ivec, ivec, key);
-			}
-			c = *(in);
-			*(out++) = *(in++) ^ ivec[n];
-			ivec[n] = c;
-			n = (n+1) % AES_BLOCK_SIZE;
-		}
-	}
-
-	*num=n;
+	CRYPTO_cfb128_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);
 }
 
-/* This expects a single block of size nbits for both in and out. Note that
-   it corrupts any extra bits in the last byte of out */
-void AES_cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
-			    const int nbits,const AES_KEY *key,
-			    unsigned char *ivec,const int enc)
-    {
-    int n,rem,num;
-    unsigned char ovec[AES_BLOCK_SIZE*2];
-
-    if (nbits<=0 || nbits>128) return;
-
-	/* fill in the first half of the new IV with the current IV */
-	memcpy(ovec,ivec,AES_BLOCK_SIZE);
-	/* construct the new IV */
-	AES_encrypt(ivec,ivec,key);
-	num = (nbits+7)/8;
-	if (enc)	/* encrypt the input */
-	    for(n=0 ; n < num ; ++n)
-		out[n] = (ovec[AES_BLOCK_SIZE+n] = in[n] ^ ivec[n]);
-	else		/* decrypt the input */
-	    for(n=0 ; n < num ; ++n)
-		out[n] = (ovec[AES_BLOCK_SIZE+n] = in[n]) ^ ivec[n];
-	/* shift ovec left... */
-	rem = nbits%8;
-	num = nbits/8;
-	if(rem==0)
-	    memcpy(ivec,ovec+num,AES_BLOCK_SIZE);
-	else
-	    for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
-		ivec[n] = ovec[n+num]<<rem | ovec[n+num+1]>>(8-rem);
-
-    /* it is not necessary to cleanse ovec, since the IV is not secret */
-    }
-
 /* N.B. This expects the input to be packed, MS bit first */
 void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
-		      const unsigned long length, const AES_KEY *key,
+		      size_t length, const AES_KEY *key,
 		      unsigned char *ivec, int *num, const int enc)
     {
-    unsigned int n;
-    unsigned char c[1],d[1];
-
-    assert(in && out && key && ivec && num);
-    assert(*num == 0);
-
-    for(n=0 ; n < length ; ++n)
-	{
-	c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
-	AES_cfbr_encrypt_block(c,d,1,key,ivec,enc);
-	out[n/8]=(out[n/8]&~(1 << (7-n%8)))|((d[0]&0x80) >> (n%8));
-	}
+    CRYPTO_cfb128_1_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);
     }
 
 void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
-		      const unsigned long length, const AES_KEY *key,
+		      size_t length, const AES_KEY *key,
 		      unsigned char *ivec, int *num, const int enc)
     {
-    unsigned int n;
-
-    assert(in && out && key && ivec && num);
-    assert(*num == 0);
-
-    for(n=0 ; n < length ; ++n)
-	AES_cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc);
+    CRYPTO_cfb128_8_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);
     }
 
diff --git a/crypto/aes/aes_core.c b/crypto/aes/aes_core.c
index cffdd4d..a7ec54f 100644
--- a/crypto/aes/aes_core.c
+++ b/crypto/aes/aes_core.c
@@ -37,12 +37,9 @@
 
 #include <stdlib.h>
 #include <openssl/aes.h>
-#ifdef OPENSSL_FIPS
-#include <openssl/fips.h>
-#endif
-
 #include "aes_locl.h"
 
+#ifndef AES_ASM
 /*
 Te0[x] = S [x].[02, 01, 01, 03];
 Te1[x] = S [x].[03, 02, 01, 01];
@@ -635,10 +632,6 @@
    	int i = 0;
 	u32 temp;
 
-#ifdef OPENSSL_FIPS
-	FIPS_selftest_check();
-#endif
-
 	if (!userKey || !key)
 		return -1;
 	if (bits != 128 && bits != 192 && bits != 256)
@@ -781,7 +774,6 @@
 	return 0;
 }
 
-#ifndef AES_ASM
 /*
  * Encrypt a single block
  * in and out can overlap
@@ -1164,4 +1156,203 @@
 	PUTU32(out + 12, s3);
 }
 
+#else /* AES_ASM */
+
+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 u32 rcon[] = {
+	0x01000000, 0x02000000, 0x04000000, 0x08000000,
+	0x10000000, 0x20000000, 0x40000000, 0x80000000,
+	0x1B000000, 0x36000000, /* 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 >> 16) & 0xff] << 24) ^
+				(Te4[(temp >>  8) & 0xff] << 16) ^
+				(Te4[(temp      ) & 0xff] << 8) ^
+				(Te4[(temp >> 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 >> 16) & 0xff] << 24) ^
+				(Te4[(temp >>  8) & 0xff] << 16) ^
+				(Te4[(temp      ) & 0xff] << 8) ^
+				(Te4[(temp >> 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 >> 16) & 0xff] << 24) ^
+				(Te4[(temp >>  8) & 0xff] << 16) ^
+				(Te4[(temp      ) & 0xff] << 8) ^
+				(Te4[(temp >> 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 >> 24)       ] << 24) ^
+				(Te4[(temp >> 16) & 0xff] << 16) ^
+				(Te4[(temp >>  8) & 0xff] << 8) ^
+				(Te4[(temp      ) & 0xff]);
+			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;
+		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,24) ^ ROTATE(tpb,8);
+#else
+			rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ 
+				(tp9 >> 8) ^ (tp9 << 24) ^
+				(tpb >> 24) ^ (tpb << 8);
+#endif
+		}
+	}
+	return 0;
+}
+
 #endif /* AES_ASM */
diff --git a/crypto/aes/aes_ctr.c b/crypto/aes/aes_ctr.c
index f36982b..7c9d165 100644
--- a/crypto/aes/aes_ctr.c
+++ b/crypto/aes/aes_ctr.c
@@ -49,91 +49,13 @@
  *
  */
 
-#ifndef AES_DEBUG
-# ifndef NDEBUG
-#  define NDEBUG
-# endif
-#endif
-#include <assert.h>
-
 #include <openssl/aes.h>
-#include "aes_locl.h"
+#include <openssl/modes.h>
 
-/* NOTE: the IV/counter CTR mode is big-endian.  The rest of the AES code
- * is endian-neutral. */
-
-/* increment counter (128-bit int) by 1 */
-static void AES_ctr128_inc(unsigned char *counter) {
-	unsigned long c;
-
-	/* Grab bottom dword of counter and increment */
-	c = GETU32(counter + 12);
-	c++;	c &= 0xFFFFFFFF;
-	PUTU32(counter + 12, c);
-
-	/* if no overflow, we're done */
-	if (c)
-		return;
-
-	/* Grab 1st dword of counter and increment */
-	c = GETU32(counter +  8);
-	c++;	c &= 0xFFFFFFFF;
-	PUTU32(counter +  8, c);
-
-	/* if no overflow, we're done */
-	if (c)
-		return;
-
-	/* Grab 2nd dword of counter and increment */
-	c = GETU32(counter +  4);
-	c++;	c &= 0xFFFFFFFF;
-	PUTU32(counter +  4, c);
-
-	/* if no overflow, we're done */
-	if (c)
-		return;
-
-	/* Grab top dword of counter and increment */
-	c = GETU32(counter +  0);
-	c++;	c &= 0xFFFFFFFF;
-	PUTU32(counter +  0, c);
-}
-
-/* The input encrypted as though 128bit counter mode is being
- * used.  The extra state information to record how much of the
- * 128bit block we have used is contained in *num, and the
- * encrypted counter is kept in ecount_buf.  Both *num and
- * ecount_buf must be initialised with zeros before the first
- * call to AES_ctr128_encrypt().
- *
- * This algorithm assumes that the counter is in the x lower bits
- * of the IV (ivec), and that the application has full control over
- * overflow and the rest of the IV.  This implementation takes NO
- * responsability for checking that the counter doesn't overflow
- * into the rest of the IV when incremented.
- */
 void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const AES_KEY *key,
-	unsigned char ivec[AES_BLOCK_SIZE],
-	unsigned char ecount_buf[AES_BLOCK_SIZE],
-	unsigned int *num) {
-
-	unsigned int n;
-	unsigned long l=length;
-
-	assert(in && out && key && counter && num);
-	assert(*num < AES_BLOCK_SIZE);
-
-	n = *num;
-
-	while (l--) {
-		if (n == 0) {
-			AES_encrypt(ivec, ecount_buf, key);
- 			AES_ctr128_inc(ivec);
-		}
-		*(out++) = *(in++) ^ ecount_buf[n];
-		n = (n+1) % AES_BLOCK_SIZE;
-	}
-
-	*num=n;
+			size_t length, const AES_KEY *key,
+			unsigned char ivec[AES_BLOCK_SIZE],
+			unsigned char ecount_buf[AES_BLOCK_SIZE],
+			unsigned int *num) {
+	CRYPTO_ctr128_encrypt(in,out,length,key,ivec,ecount_buf,num,(block128_f)AES_encrypt);
 }
diff --git a/crypto/aes/aes_ige.c b/crypto/aes/aes_ige.c
index 45d7096..c161351 100644
--- a/crypto/aes/aes_ige.c
+++ b/crypto/aes/aes_ige.c
@@ -77,11 +77,11 @@
 /* N.B. The IV for this mode is _twice_ the block size */
 
 void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
-					 const unsigned long length, const AES_KEY *key,
+					 size_t length, const AES_KEY *key,
 					 unsigned char *ivec, const int enc)
 	{
-	unsigned long n;
-	unsigned long len;
+	size_t n;
+	size_t len = length;
 
 	OPENSSL_assert(in && out && key && ivec);
 	OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
@@ -211,12 +211,12 @@
 /* N.B. The IV for this mode is _four times_ the block size */
 
 void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
-						const unsigned long length, const AES_KEY *key,
+						size_t length, const AES_KEY *key,
 						const AES_KEY *key2, const unsigned char *ivec,
 						const int enc)
 	{
-	unsigned long n;
-	unsigned long len = length;
+	size_t n;
+	size_t len = length;
 	unsigned char tmp[AES_BLOCK_SIZE];
 	unsigned char tmp2[AES_BLOCK_SIZE];
 	unsigned char tmp3[AES_BLOCK_SIZE];
diff --git a/crypto/aes/aes_ofb.c b/crypto/aes/aes_ofb.c
index f358bb3..50bf0b8 100644
--- a/crypto/aes/aes_ofb.c
+++ b/crypto/aes/aes_ofb.c
@@ -1,6 +1,6 @@
 /* crypto/aes/aes_ofb.c -*- mode:C; c-file-style: "eay" -*- */
 /* ====================================================================
- * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 2002-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
@@ -48,95 +48,13 @@
  * ====================================================================
  *
  */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#ifndef AES_DEBUG
-# ifndef NDEBUG
-#  define NDEBUG
-# endif
-#endif
-#include <assert.h>
 
 #include <openssl/aes.h>
-#include "aes_locl.h"
+#include <openssl/modes.h>
 
-/* The input and output encrypted as though 128bit ofb mode is being
- * used.  The extra state information to record how much of the
- * 128bit block we have used is contained in *num;
- */
 void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const AES_KEY *key,
-	unsigned char *ivec, int *num) {
-
-	unsigned int n;
-	unsigned long l=length;
-
-	assert(in && out && key && ivec && num);
-
-	n = *num;
-
-	while (l--) {
-		if (n == 0) {
-			AES_encrypt(ivec, ivec, key);
-		}
-		*(out++) = *(in++) ^ ivec[n];
-		n = (n+1) % AES_BLOCK_SIZE;
-	}
-
-	*num=n;
+	size_t length, const AES_KEY *key,
+	unsigned char *ivec, int *num)
+{
+	CRYPTO_ofb128_encrypt(in,out,length,key,ivec,num,(block128_f)AES_encrypt);
 }
diff --git a/crypto/aes/aes_x86core.c b/crypto/aes/aes_x86core.c
new file mode 100644
index 0000000..d323e26
--- /dev/null
+++ b/crypto/aes/aes_x86core.c
@@ -0,0 +1,1063 @@
+/* crypto/aes/aes_core.c -*- mode:C; c-file-style: "eay" -*- */
+/**
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This is experimental x86[_64] derivative. It assumes little-endian
+ * byte order and expects CPU to sustain unaligned memory references.
+ * It is used as playground for cache-time attack mitigations and
+ * serves as reference C implementation for x86[_64] assembler.
+ *
+ *					<appro@fy.chalmers.se>
+ */
+
+
+#ifndef AES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+#include <stdlib.h>
+#include <openssl/aes.h>
+#include "aes_locl.h"
+
+/*
+ * These two parameters control which table, 256-byte or 2KB, is
+ * referenced in outer and respectively inner rounds.
+ */
+#define AES_COMPACT_IN_OUTER_ROUNDS
+#ifdef  AES_COMPACT_IN_OUTER_ROUNDS
+/* AES_COMPACT_IN_OUTER_ROUNDS costs ~30% in performance, while
+ * adding AES_COMPACT_IN_INNER_ROUNDS reduces benchmark *further*
+ * by factor of ~2. */
+# undef  AES_COMPACT_IN_INNER_ROUNDS
+#endif
+
+#if 1
+static void prefetch256(const void *table)
+{
+	volatile unsigned long *t=(void *)table,ret;
+	unsigned long sum;
+	int i;
+
+	/* 32 is common least cache-line size */
+	for (sum=0,i=0;i<256/sizeof(t[0]);i+=32/sizeof(t[0]))	sum ^= t[i];
+
+	ret = sum;
+}
+#else
+# define prefetch256(t)
+#endif
+
+#undef GETU32
+#define GETU32(p) (*((u32*)(p)))
+
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
+typedef unsigned __int64 u64;
+#define U64(C)	C##UI64
+#elif defined(__arch64__)
+typedef unsigned long u64;
+#define U64(C)	C##UL
+#else
+typedef unsigned long long u64;
+#define U64(C)	C##ULL
+#endif
+
+#undef ROTATE
+#if defined(_MSC_VER) || defined(__ICC)
+# define ROTATE(a,n)	_lrotl(a,n)
+#elif defined(__GNUC__) && __GNUC__>=2
+# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+#   define ROTATE(a,n)	({ register unsigned int ret;	\
+				asm (			\
+				"roll %1,%0"		\
+				: "=r"(ret)		\
+				: "I"(n), "0"(a)	\
+				: "cc");		\
+			   ret;				\
+			})
+# endif
+#endif
+/*
+Te [x] = S [x].[02, 01, 01, 03, 02, 01, 01, 03];
+Te0[x] = S [x].[02, 01, 01, 03];
+Te1[x] = S [x].[03, 02, 01, 01];
+Te2[x] = S [x].[01, 03, 02, 01];
+Te3[x] = S [x].[01, 01, 03, 02];
+*/
+#define Te0 (u32)((u64*)((u8*)Te+0))
+#define Te1 (u32)((u64*)((u8*)Te+3))
+#define Te2 (u32)((u64*)((u8*)Te+2))
+#define Te3 (u32)((u64*)((u8*)Te+1))
+/*
+Td [x] = Si[x].[0e, 09, 0d, 0b, 0e, 09, 0d, 0b];
+Td0[x] = Si[x].[0e, 09, 0d, 0b];
+Td1[x] = Si[x].[0b, 0e, 09, 0d];
+Td2[x] = Si[x].[0d, 0b, 0e, 09];
+Td3[x] = Si[x].[09, 0d, 0b, 0e];
+Td4[x] = Si[x].[01];
+*/
+#define Td0 (u32)((u64*)((u8*)Td+0))
+#define Td1 (u32)((u64*)((u8*)Td+3))
+#define Td2 (u32)((u64*)((u8*)Td+2))
+#define Td3 (u32)((u64*)((u8*)Td+1))
+
+static const u64 Te[256] = {
+    U64(0xa56363c6a56363c6), U64(0x847c7cf8847c7cf8),
+    U64(0x997777ee997777ee), U64(0x8d7b7bf68d7b7bf6),
+    U64(0x0df2f2ff0df2f2ff), U64(0xbd6b6bd6bd6b6bd6),
+    U64(0xb16f6fdeb16f6fde), U64(0x54c5c59154c5c591),
+    U64(0x5030306050303060), U64(0x0301010203010102),
+    U64(0xa96767cea96767ce), U64(0x7d2b2b567d2b2b56),
+    U64(0x19fefee719fefee7), U64(0x62d7d7b562d7d7b5),
+    U64(0xe6abab4de6abab4d), U64(0x9a7676ec9a7676ec),
+    U64(0x45caca8f45caca8f), U64(0x9d82821f9d82821f),
+    U64(0x40c9c98940c9c989), U64(0x877d7dfa877d7dfa),
+    U64(0x15fafaef15fafaef), U64(0xeb5959b2eb5959b2),
+    U64(0xc947478ec947478e), U64(0x0bf0f0fb0bf0f0fb),
+    U64(0xecadad41ecadad41), U64(0x67d4d4b367d4d4b3),
+    U64(0xfda2a25ffda2a25f), U64(0xeaafaf45eaafaf45),
+    U64(0xbf9c9c23bf9c9c23), U64(0xf7a4a453f7a4a453),
+    U64(0x967272e4967272e4), U64(0x5bc0c09b5bc0c09b),
+    U64(0xc2b7b775c2b7b775), U64(0x1cfdfde11cfdfde1),
+    U64(0xae93933dae93933d), U64(0x6a26264c6a26264c),
+    U64(0x5a36366c5a36366c), U64(0x413f3f7e413f3f7e),
+    U64(0x02f7f7f502f7f7f5), U64(0x4fcccc834fcccc83),
+    U64(0x5c3434685c343468), U64(0xf4a5a551f4a5a551),
+    U64(0x34e5e5d134e5e5d1), U64(0x08f1f1f908f1f1f9),
+    U64(0x937171e2937171e2), U64(0x73d8d8ab73d8d8ab),
+    U64(0x5331316253313162), U64(0x3f15152a3f15152a),
+    U64(0x0c0404080c040408), U64(0x52c7c79552c7c795),
+    U64(0x6523234665232346), U64(0x5ec3c39d5ec3c39d),
+    U64(0x2818183028181830), U64(0xa1969637a1969637),
+    U64(0x0f05050a0f05050a), U64(0xb59a9a2fb59a9a2f),
+    U64(0x0907070e0907070e), U64(0x3612122436121224),
+    U64(0x9b80801b9b80801b), U64(0x3de2e2df3de2e2df),
+    U64(0x26ebebcd26ebebcd), U64(0x6927274e6927274e),
+    U64(0xcdb2b27fcdb2b27f), U64(0x9f7575ea9f7575ea),
+    U64(0x1b0909121b090912), U64(0x9e83831d9e83831d),
+    U64(0x742c2c58742c2c58), U64(0x2e1a1a342e1a1a34),
+    U64(0x2d1b1b362d1b1b36), U64(0xb26e6edcb26e6edc),
+    U64(0xee5a5ab4ee5a5ab4), U64(0xfba0a05bfba0a05b),
+    U64(0xf65252a4f65252a4), U64(0x4d3b3b764d3b3b76),
+    U64(0x61d6d6b761d6d6b7), U64(0xceb3b37dceb3b37d),
+    U64(0x7b2929527b292952), U64(0x3ee3e3dd3ee3e3dd),
+    U64(0x712f2f5e712f2f5e), U64(0x9784841397848413),
+    U64(0xf55353a6f55353a6), U64(0x68d1d1b968d1d1b9),
+    U64(0x0000000000000000), U64(0x2cededc12cededc1),
+    U64(0x6020204060202040), U64(0x1ffcfce31ffcfce3),
+    U64(0xc8b1b179c8b1b179), U64(0xed5b5bb6ed5b5bb6),
+    U64(0xbe6a6ad4be6a6ad4), U64(0x46cbcb8d46cbcb8d),
+    U64(0xd9bebe67d9bebe67), U64(0x4b3939724b393972),
+    U64(0xde4a4a94de4a4a94), U64(0xd44c4c98d44c4c98),
+    U64(0xe85858b0e85858b0), U64(0x4acfcf854acfcf85),
+    U64(0x6bd0d0bb6bd0d0bb), U64(0x2aefefc52aefefc5),
+    U64(0xe5aaaa4fe5aaaa4f), U64(0x16fbfbed16fbfbed),
+    U64(0xc5434386c5434386), U64(0xd74d4d9ad74d4d9a),
+    U64(0x5533336655333366), U64(0x9485851194858511),
+    U64(0xcf45458acf45458a), U64(0x10f9f9e910f9f9e9),
+    U64(0x0602020406020204), U64(0x817f7ffe817f7ffe),
+    U64(0xf05050a0f05050a0), U64(0x443c3c78443c3c78),
+    U64(0xba9f9f25ba9f9f25), U64(0xe3a8a84be3a8a84b),
+    U64(0xf35151a2f35151a2), U64(0xfea3a35dfea3a35d),
+    U64(0xc0404080c0404080), U64(0x8a8f8f058a8f8f05),
+    U64(0xad92923fad92923f), U64(0xbc9d9d21bc9d9d21),
+    U64(0x4838387048383870), U64(0x04f5f5f104f5f5f1),
+    U64(0xdfbcbc63dfbcbc63), U64(0xc1b6b677c1b6b677),
+    U64(0x75dadaaf75dadaaf), U64(0x6321214263212142),
+    U64(0x3010102030101020), U64(0x1affffe51affffe5),
+    U64(0x0ef3f3fd0ef3f3fd), U64(0x6dd2d2bf6dd2d2bf),
+    U64(0x4ccdcd814ccdcd81), U64(0x140c0c18140c0c18),
+    U64(0x3513132635131326), U64(0x2fececc32fececc3),
+    U64(0xe15f5fbee15f5fbe), U64(0xa2979735a2979735),
+    U64(0xcc444488cc444488), U64(0x3917172e3917172e),
+    U64(0x57c4c49357c4c493), U64(0xf2a7a755f2a7a755),
+    U64(0x827e7efc827e7efc), U64(0x473d3d7a473d3d7a),
+    U64(0xac6464c8ac6464c8), U64(0xe75d5dbae75d5dba),
+    U64(0x2b1919322b191932), U64(0x957373e6957373e6),
+    U64(0xa06060c0a06060c0), U64(0x9881811998818119),
+    U64(0xd14f4f9ed14f4f9e), U64(0x7fdcdca37fdcdca3),
+    U64(0x6622224466222244), U64(0x7e2a2a547e2a2a54),
+    U64(0xab90903bab90903b), U64(0x8388880b8388880b),
+    U64(0xca46468cca46468c), U64(0x29eeeec729eeeec7),
+    U64(0xd3b8b86bd3b8b86b), U64(0x3c1414283c141428),
+    U64(0x79dedea779dedea7), U64(0xe25e5ebce25e5ebc),
+    U64(0x1d0b0b161d0b0b16), U64(0x76dbdbad76dbdbad),
+    U64(0x3be0e0db3be0e0db), U64(0x5632326456323264),
+    U64(0x4e3a3a744e3a3a74), U64(0x1e0a0a141e0a0a14),
+    U64(0xdb494992db494992), U64(0x0a06060c0a06060c),
+    U64(0x6c2424486c242448), U64(0xe45c5cb8e45c5cb8),
+    U64(0x5dc2c29f5dc2c29f), U64(0x6ed3d3bd6ed3d3bd),
+    U64(0xefacac43efacac43), U64(0xa66262c4a66262c4),
+    U64(0xa8919139a8919139), U64(0xa4959531a4959531),
+    U64(0x37e4e4d337e4e4d3), U64(0x8b7979f28b7979f2),
+    U64(0x32e7e7d532e7e7d5), U64(0x43c8c88b43c8c88b),
+    U64(0x5937376e5937376e), U64(0xb76d6ddab76d6dda),
+    U64(0x8c8d8d018c8d8d01), U64(0x64d5d5b164d5d5b1),
+    U64(0xd24e4e9cd24e4e9c), U64(0xe0a9a949e0a9a949),
+    U64(0xb46c6cd8b46c6cd8), U64(0xfa5656acfa5656ac),
+    U64(0x07f4f4f307f4f4f3), U64(0x25eaeacf25eaeacf),
+    U64(0xaf6565caaf6565ca), U64(0x8e7a7af48e7a7af4),
+    U64(0xe9aeae47e9aeae47), U64(0x1808081018080810),
+    U64(0xd5baba6fd5baba6f), U64(0x887878f0887878f0),
+    U64(0x6f25254a6f25254a), U64(0x722e2e5c722e2e5c),
+    U64(0x241c1c38241c1c38), U64(0xf1a6a657f1a6a657),
+    U64(0xc7b4b473c7b4b473), U64(0x51c6c69751c6c697),
+    U64(0x23e8e8cb23e8e8cb), U64(0x7cdddda17cdddda1),
+    U64(0x9c7474e89c7474e8), U64(0x211f1f3e211f1f3e),
+    U64(0xdd4b4b96dd4b4b96), U64(0xdcbdbd61dcbdbd61),
+    U64(0x868b8b0d868b8b0d), U64(0x858a8a0f858a8a0f),
+    U64(0x907070e0907070e0), U64(0x423e3e7c423e3e7c),
+    U64(0xc4b5b571c4b5b571), U64(0xaa6666ccaa6666cc),
+    U64(0xd8484890d8484890), U64(0x0503030605030306),
+    U64(0x01f6f6f701f6f6f7), U64(0x120e0e1c120e0e1c),
+    U64(0xa36161c2a36161c2), U64(0x5f35356a5f35356a),
+    U64(0xf95757aef95757ae), U64(0xd0b9b969d0b9b969),
+    U64(0x9186861791868617), U64(0x58c1c19958c1c199),
+    U64(0x271d1d3a271d1d3a), U64(0xb99e9e27b99e9e27),
+    U64(0x38e1e1d938e1e1d9), U64(0x13f8f8eb13f8f8eb),
+    U64(0xb398982bb398982b), U64(0x3311112233111122),
+    U64(0xbb6969d2bb6969d2), U64(0x70d9d9a970d9d9a9),
+    U64(0x898e8e07898e8e07), U64(0xa7949433a7949433),
+    U64(0xb69b9b2db69b9b2d), U64(0x221e1e3c221e1e3c),
+    U64(0x9287871592878715), U64(0x20e9e9c920e9e9c9),
+    U64(0x49cece8749cece87), U64(0xff5555aaff5555aa),
+    U64(0x7828285078282850), U64(0x7adfdfa57adfdfa5),
+    U64(0x8f8c8c038f8c8c03), U64(0xf8a1a159f8a1a159),
+    U64(0x8089890980898909), U64(0x170d0d1a170d0d1a),
+    U64(0xdabfbf65dabfbf65), U64(0x31e6e6d731e6e6d7),
+    U64(0xc6424284c6424284), U64(0xb86868d0b86868d0),
+    U64(0xc3414182c3414182), U64(0xb0999929b0999929),
+    U64(0x772d2d5a772d2d5a), U64(0x110f0f1e110f0f1e),
+    U64(0xcbb0b07bcbb0b07b), U64(0xfc5454a8fc5454a8),
+    U64(0xd6bbbb6dd6bbbb6d), U64(0x3a16162c3a16162c)
+};
+
+static const u8 Te4[256] = {
+    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
+    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
+    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
+    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
+    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
+    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
+    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
+    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
+    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
+    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
+    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
+    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
+    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
+    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
+    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
+    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
+    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
+    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
+    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
+    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
+    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
+    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
+    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
+    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
+    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
+    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
+    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
+    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
+    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
+    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
+    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
+    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
+};
+
+static const u64 Td[256] = {
+    U64(0x50a7f45150a7f451), U64(0x5365417e5365417e),
+    U64(0xc3a4171ac3a4171a), U64(0x965e273a965e273a),
+    U64(0xcb6bab3bcb6bab3b), U64(0xf1459d1ff1459d1f),
+    U64(0xab58faacab58faac), U64(0x9303e34b9303e34b),
+    U64(0x55fa302055fa3020), U64(0xf66d76adf66d76ad),
+    U64(0x9176cc889176cc88), U64(0x254c02f5254c02f5),
+    U64(0xfcd7e54ffcd7e54f), U64(0xd7cb2ac5d7cb2ac5),
+    U64(0x8044352680443526), U64(0x8fa362b58fa362b5),
+    U64(0x495ab1de495ab1de), U64(0x671bba25671bba25),
+    U64(0x980eea45980eea45), U64(0xe1c0fe5de1c0fe5d),
+    U64(0x02752fc302752fc3), U64(0x12f04c8112f04c81),
+    U64(0xa397468da397468d), U64(0xc6f9d36bc6f9d36b),
+    U64(0xe75f8f03e75f8f03), U64(0x959c9215959c9215),
+    U64(0xeb7a6dbfeb7a6dbf), U64(0xda595295da595295),
+    U64(0x2d83bed42d83bed4), U64(0xd3217458d3217458),
+    U64(0x2969e0492969e049), U64(0x44c8c98e44c8c98e),
+    U64(0x6a89c2756a89c275), U64(0x78798ef478798ef4),
+    U64(0x6b3e58996b3e5899), U64(0xdd71b927dd71b927),
+    U64(0xb64fe1beb64fe1be), U64(0x17ad88f017ad88f0),
+    U64(0x66ac20c966ac20c9), U64(0xb43ace7db43ace7d),
+    U64(0x184adf63184adf63), U64(0x82311ae582311ae5),
+    U64(0x6033519760335197), U64(0x457f5362457f5362),
+    U64(0xe07764b1e07764b1), U64(0x84ae6bbb84ae6bbb),
+    U64(0x1ca081fe1ca081fe), U64(0x942b08f9942b08f9),
+    U64(0x5868487058684870), U64(0x19fd458f19fd458f),
+    U64(0x876cde94876cde94), U64(0xb7f87b52b7f87b52),
+    U64(0x23d373ab23d373ab), U64(0xe2024b72e2024b72),
+    U64(0x578f1fe3578f1fe3), U64(0x2aab55662aab5566),
+    U64(0x0728ebb20728ebb2), U64(0x03c2b52f03c2b52f),
+    U64(0x9a7bc5869a7bc586), U64(0xa50837d3a50837d3),
+    U64(0xf2872830f2872830), U64(0xb2a5bf23b2a5bf23),
+    U64(0xba6a0302ba6a0302), U64(0x5c8216ed5c8216ed),
+    U64(0x2b1ccf8a2b1ccf8a), U64(0x92b479a792b479a7),
+    U64(0xf0f207f3f0f207f3), U64(0xa1e2694ea1e2694e),
+    U64(0xcdf4da65cdf4da65), U64(0xd5be0506d5be0506),
+    U64(0x1f6234d11f6234d1), U64(0x8afea6c48afea6c4),
+    U64(0x9d532e349d532e34), U64(0xa055f3a2a055f3a2),
+    U64(0x32e18a0532e18a05), U64(0x75ebf6a475ebf6a4),
+    U64(0x39ec830b39ec830b), U64(0xaaef6040aaef6040),
+    U64(0x069f715e069f715e), U64(0x51106ebd51106ebd),
+    U64(0xf98a213ef98a213e), U64(0x3d06dd963d06dd96),
+    U64(0xae053eddae053edd), U64(0x46bde64d46bde64d),
+    U64(0xb58d5491b58d5491), U64(0x055dc471055dc471),
+    U64(0x6fd406046fd40604), U64(0xff155060ff155060),
+    U64(0x24fb981924fb9819), U64(0x97e9bdd697e9bdd6),
+    U64(0xcc434089cc434089), U64(0x779ed967779ed967),
+    U64(0xbd42e8b0bd42e8b0), U64(0x888b8907888b8907),
+    U64(0x385b19e7385b19e7), U64(0xdbeec879dbeec879),
+    U64(0x470a7ca1470a7ca1), U64(0xe90f427ce90f427c),
+    U64(0xc91e84f8c91e84f8), U64(0x0000000000000000),
+    U64(0x8386800983868009), U64(0x48ed2b3248ed2b32),
+    U64(0xac70111eac70111e), U64(0x4e725a6c4e725a6c),
+    U64(0xfbff0efdfbff0efd), U64(0x5638850f5638850f),
+    U64(0x1ed5ae3d1ed5ae3d), U64(0x27392d3627392d36),
+    U64(0x64d90f0a64d90f0a), U64(0x21a65c6821a65c68),
+    U64(0xd1545b9bd1545b9b), U64(0x3a2e36243a2e3624),
+    U64(0xb1670a0cb1670a0c), U64(0x0fe757930fe75793),
+    U64(0xd296eeb4d296eeb4), U64(0x9e919b1b9e919b1b),
+    U64(0x4fc5c0804fc5c080), U64(0xa220dc61a220dc61),
+    U64(0x694b775a694b775a), U64(0x161a121c161a121c),
+    U64(0x0aba93e20aba93e2), U64(0xe52aa0c0e52aa0c0),
+    U64(0x43e0223c43e0223c), U64(0x1d171b121d171b12),
+    U64(0x0b0d090e0b0d090e), U64(0xadc78bf2adc78bf2),
+    U64(0xb9a8b62db9a8b62d), U64(0xc8a91e14c8a91e14),
+    U64(0x8519f1578519f157), U64(0x4c0775af4c0775af),
+    U64(0xbbdd99eebbdd99ee), U64(0xfd607fa3fd607fa3),
+    U64(0x9f2601f79f2601f7), U64(0xbcf5725cbcf5725c),
+    U64(0xc53b6644c53b6644), U64(0x347efb5b347efb5b),
+    U64(0x7629438b7629438b), U64(0xdcc623cbdcc623cb),
+    U64(0x68fcedb668fcedb6), U64(0x63f1e4b863f1e4b8),
+    U64(0xcadc31d7cadc31d7), U64(0x1085634210856342),
+    U64(0x4022971340229713), U64(0x2011c6842011c684),
+    U64(0x7d244a857d244a85), U64(0xf83dbbd2f83dbbd2),
+    U64(0x1132f9ae1132f9ae), U64(0x6da129c76da129c7),
+    U64(0x4b2f9e1d4b2f9e1d), U64(0xf330b2dcf330b2dc),
+    U64(0xec52860dec52860d), U64(0xd0e3c177d0e3c177),
+    U64(0x6c16b32b6c16b32b), U64(0x99b970a999b970a9),
+    U64(0xfa489411fa489411), U64(0x2264e9472264e947),
+    U64(0xc48cfca8c48cfca8), U64(0x1a3ff0a01a3ff0a0),
+    U64(0xd82c7d56d82c7d56), U64(0xef903322ef903322),
+    U64(0xc74e4987c74e4987), U64(0xc1d138d9c1d138d9),
+    U64(0xfea2ca8cfea2ca8c), U64(0x360bd498360bd498),
+    U64(0xcf81f5a6cf81f5a6), U64(0x28de7aa528de7aa5),
+    U64(0x268eb7da268eb7da), U64(0xa4bfad3fa4bfad3f),
+    U64(0xe49d3a2ce49d3a2c), U64(0x0d9278500d927850),
+    U64(0x9bcc5f6a9bcc5f6a), U64(0x62467e5462467e54),
+    U64(0xc2138df6c2138df6), U64(0xe8b8d890e8b8d890),
+    U64(0x5ef7392e5ef7392e), U64(0xf5afc382f5afc382),
+    U64(0xbe805d9fbe805d9f), U64(0x7c93d0697c93d069),
+    U64(0xa92dd56fa92dd56f), U64(0xb31225cfb31225cf),
+    U64(0x3b99acc83b99acc8), U64(0xa77d1810a77d1810),
+    U64(0x6e639ce86e639ce8), U64(0x7bbb3bdb7bbb3bdb),
+    U64(0x097826cd097826cd), U64(0xf418596ef418596e),
+    U64(0x01b79aec01b79aec), U64(0xa89a4f83a89a4f83),
+    U64(0x656e95e6656e95e6), U64(0x7ee6ffaa7ee6ffaa),
+    U64(0x08cfbc2108cfbc21), U64(0xe6e815efe6e815ef),
+    U64(0xd99be7bad99be7ba), U64(0xce366f4ace366f4a),
+    U64(0xd4099fead4099fea), U64(0xd67cb029d67cb029),
+    U64(0xafb2a431afb2a431), U64(0x31233f2a31233f2a),
+    U64(0x3094a5c63094a5c6), U64(0xc066a235c066a235),
+    U64(0x37bc4e7437bc4e74), U64(0xa6ca82fca6ca82fc),
+    U64(0xb0d090e0b0d090e0), U64(0x15d8a73315d8a733),
+    U64(0x4a9804f14a9804f1), U64(0xf7daec41f7daec41),
+    U64(0x0e50cd7f0e50cd7f), U64(0x2ff691172ff69117),
+    U64(0x8dd64d768dd64d76), U64(0x4db0ef434db0ef43),
+    U64(0x544daacc544daacc), U64(0xdf0496e4df0496e4),
+    U64(0xe3b5d19ee3b5d19e), U64(0x1b886a4c1b886a4c),
+    U64(0xb81f2cc1b81f2cc1), U64(0x7f5165467f516546),
+    U64(0x04ea5e9d04ea5e9d), U64(0x5d358c015d358c01),
+    U64(0x737487fa737487fa), U64(0x2e410bfb2e410bfb),
+    U64(0x5a1d67b35a1d67b3), U64(0x52d2db9252d2db92),
+    U64(0x335610e9335610e9), U64(0x1347d66d1347d66d),
+    U64(0x8c61d79a8c61d79a), U64(0x7a0ca1377a0ca137),
+    U64(0x8e14f8598e14f859), U64(0x893c13eb893c13eb),
+    U64(0xee27a9ceee27a9ce), U64(0x35c961b735c961b7),
+    U64(0xede51ce1ede51ce1), U64(0x3cb1477a3cb1477a),
+    U64(0x59dfd29c59dfd29c), U64(0x3f73f2553f73f255),
+    U64(0x79ce141879ce1418), U64(0xbf37c773bf37c773),
+    U64(0xeacdf753eacdf753), U64(0x5baafd5f5baafd5f),
+    U64(0x146f3ddf146f3ddf), U64(0x86db447886db4478),
+    U64(0x81f3afca81f3afca), U64(0x3ec468b93ec468b9),
+    U64(0x2c3424382c342438), U64(0x5f40a3c25f40a3c2),
+    U64(0x72c31d1672c31d16), U64(0x0c25e2bc0c25e2bc),
+    U64(0x8b493c288b493c28), U64(0x41950dff41950dff),
+    U64(0x7101a8397101a839), U64(0xdeb30c08deb30c08),
+    U64(0x9ce4b4d89ce4b4d8), U64(0x90c1566490c15664),
+    U64(0x6184cb7b6184cb7b), U64(0x70b632d570b632d5),
+    U64(0x745c6c48745c6c48), U64(0x4257b8d04257b8d0)
+};
+static const u8 Td4[256] = {
+    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
+    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
+    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
+    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
+    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
+    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
+    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
+    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
+    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
+    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
+    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
+    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
+    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
+    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
+    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
+    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
+    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
+    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
+    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
+    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
+    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
+    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
+    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
+    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
+    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
+    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
+    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
+    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
+    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
+    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
+    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
+    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU
+};
+
+static const u32 rcon[] = {
+    0x00000001U, 0x00000002U, 0x00000004U, 0x00000008U,
+    0x00000010U, 0x00000020U, 0x00000040U, 0x00000080U,
+    0x0000001bU, 0x00000036U, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+
+/**
+ * Expand the cipher key into the encryption key schedule.
+ */
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+			AES_KEY *key) {
+
+	u32 *rk;
+   	int i = 0;
+	u32 temp;
+
+	if (!userKey || !key)
+		return -1;
+	if (bits != 128 && bits != 192 && bits != 256)
+		return -2;
+
+	rk = key->rd_key;
+
+	if (bits==128)
+		key->rounds = 10;
+	else if (bits==192)
+		key->rounds = 12;
+	else
+		key->rounds = 14;
+
+	rk[0] = GETU32(userKey     );
+	rk[1] = GETU32(userKey +  4);
+	rk[2] = GETU32(userKey +  8);
+	rk[3] = GETU32(userKey + 12);
+	if (bits == 128) {
+		while (1) {
+			temp  = rk[3];
+			rk[4] = rk[0] ^
+				(Te4[(temp >>  8) & 0xff]      ) ^
+				(Te4[(temp >> 16) & 0xff] <<  8) ^
+				(Te4[(temp >> 24)       ] << 16) ^
+				(Te4[(temp      ) & 0xff] << 24) ^
+				rcon[i];
+			rk[5] = rk[1] ^ rk[4];
+			rk[6] = rk[2] ^ rk[5];
+			rk[7] = rk[3] ^ rk[6];
+			if (++i == 10) {
+				return 0;
+			}
+			rk += 4;
+		}
+	}
+	rk[4] = GETU32(userKey + 16);
+	rk[5] = GETU32(userKey + 20);
+	if (bits == 192) {
+		while (1) {
+			temp = rk[ 5];
+			rk[ 6] = rk[ 0] ^
+				(Te4[(temp >>  8) & 0xff]      ) ^
+				(Te4[(temp >> 16) & 0xff] <<  8) ^
+				(Te4[(temp >> 24)       ] << 16) ^
+				(Te4[(temp      ) & 0xff] << 24) ^
+				rcon[i];
+			rk[ 7] = rk[ 1] ^ rk[ 6];
+			rk[ 8] = rk[ 2] ^ rk[ 7];
+			rk[ 9] = rk[ 3] ^ rk[ 8];
+			if (++i == 8) {
+				return 0;
+			}
+			rk[10] = rk[ 4] ^ rk[ 9];
+			rk[11] = rk[ 5] ^ rk[10];
+			rk += 6;
+		}
+	}
+	rk[6] = GETU32(userKey + 24);
+	rk[7] = GETU32(userKey + 28);
+	if (bits == 256) {
+		while (1) {
+			temp = rk[ 7];
+			rk[ 8] = rk[ 0] ^
+				(Te4[(temp >>  8) & 0xff]      ) ^
+				(Te4[(temp >> 16) & 0xff] <<  8) ^
+				(Te4[(temp >> 24)       ] << 16) ^
+				(Te4[(temp      ) & 0xff] << 24) ^
+				rcon[i];
+			rk[ 9] = rk[ 1] ^ rk[ 8];
+			rk[10] = rk[ 2] ^ rk[ 9];
+			rk[11] = rk[ 3] ^ rk[10];
+			if (++i == 7) {
+				return 0;
+			}
+			temp = rk[11];
+			rk[12] = rk[ 4] ^
+				(Te4[(temp      ) & 0xff]      ) ^
+				(Te4[(temp >>  8) & 0xff] <<  8) ^
+				(Te4[(temp >> 16) & 0xff] << 16) ^
+				(Te4[(temp >> 24)       ] << 24);
+			rk[13] = rk[ 5] ^ rk[12];
+			rk[14] = rk[ 6] ^ rk[13];
+			rk[15] = rk[ 7] ^ rk[14];
+
+			rk += 8;
+        	}
+	}
+	return 0;
+}
+
+/**
+ * Expand the cipher key into the decryption key schedule.
+ */
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+			 AES_KEY *key) {
+
+        u32 *rk;
+	int i, j, status;
+	u32 temp;
+
+	/* first, start with an encryption schedule */
+	status = AES_set_encrypt_key(userKey, bits, key);
+	if (status < 0)
+		return status;
+
+	rk = key->rd_key;
+
+	/* invert the order of the round keys: */
+	for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
+		temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
+		temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+		temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+		temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+	}
+	/* apply the inverse MixColumn transform to all round keys but the first and the last: */
+	for (i = 1; i < (key->rounds); i++) {
+		rk += 4;
+#if 1
+		for (j = 0; j < 4; j++) {
+			u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
+
+			tp1 = rk[j];
+			m = tp1 & 0x80808080;
+			tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp2 & 0x80808080;
+			tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp4 & 0x80808080;
+			tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			tp9 = tp8 ^ tp1;
+			tpb = tp9 ^ tp2;
+			tpd = tp9 ^ tp4;
+			tpe = tp8 ^ tp4 ^ tp2;
+#if defined(ROTATE)
+			rk[j] = tpe ^ ROTATE(tpd,16) ^
+				ROTATE(tp9,8) ^ ROTATE(tpb,24);
+#else
+			rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ 
+				(tp9 >> 24) ^ (tp9 << 8) ^
+				(tpb >> 8) ^ (tpb << 24);
+#endif
+		}
+#else
+		rk[0] =
+			Td0[Te2[(rk[0]      ) & 0xff] & 0xff] ^
+			Td1[Te2[(rk[0] >>  8) & 0xff] & 0xff] ^
+			Td2[Te2[(rk[0] >> 16) & 0xff] & 0xff] ^
+			Td3[Te2[(rk[0] >> 24)       ] & 0xff];
+		rk[1] =
+			Td0[Te2[(rk[1]      ) & 0xff] & 0xff] ^
+			Td1[Te2[(rk[1] >>  8) & 0xff] & 0xff] ^
+			Td2[Te2[(rk[1] >> 16) & 0xff] & 0xff] ^
+			Td3[Te2[(rk[1] >> 24)       ] & 0xff];
+		rk[2] =
+			Td0[Te2[(rk[2]      ) & 0xff] & 0xff] ^
+			Td1[Te2[(rk[2] >>  8) & 0xff] & 0xff] ^
+			Td2[Te2[(rk[2] >> 16) & 0xff] & 0xff] ^
+			Td3[Te2[(rk[2] >> 24)       ] & 0xff];
+		rk[3] =
+			Td0[Te2[(rk[3]      ) & 0xff] & 0xff] ^
+			Td1[Te2[(rk[3] >>  8) & 0xff] & 0xff] ^
+			Td2[Te2[(rk[3] >> 16) & 0xff] & 0xff] ^
+			Td3[Te2[(rk[3] >> 24)       ] & 0xff];
+#endif
+	}
+	return 0;
+}
+
+/*
+ * Encrypt a single block
+ * in and out can overlap
+ */
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+		 const AES_KEY *key) {
+
+	const u32 *rk;
+	u32 s0, s1, s2, s3, t[4];
+	int r;
+
+	assert(in && out && key);
+	rk = key->rd_key;
+
+	/*
+	 * map byte array block to cipher state
+	 * and add initial round key:
+	 */
+	s0 = GETU32(in     ) ^ rk[0];
+	s1 = GETU32(in +  4) ^ rk[1];
+	s2 = GETU32(in +  8) ^ rk[2];
+	s3 = GETU32(in + 12) ^ rk[3];
+
+#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
+	prefetch256(Te4);
+
+	t[0] =	Te4[(s0      ) & 0xff]       ^
+		Te4[(s1 >>  8) & 0xff] <<  8 ^
+		Te4[(s2 >> 16) & 0xff] << 16 ^
+		Te4[(s3 >> 24)       ] << 24;
+	t[1] =	Te4[(s1      ) & 0xff]       ^
+		Te4[(s2 >>  8) & 0xff] <<  8 ^
+		Te4[(s3 >> 16) & 0xff] << 16 ^
+		Te4[(s0 >> 24)       ] << 24;
+	t[2] =	Te4[(s2      ) & 0xff]       ^
+		Te4[(s3 >>  8) & 0xff] <<  8 ^
+		Te4[(s0 >> 16) & 0xff] << 16 ^
+		Te4[(s1 >> 24)       ] << 24;
+	t[3] =	Te4[(s3      ) & 0xff]       ^
+		Te4[(s0 >>  8) & 0xff] <<  8 ^
+		Te4[(s1 >> 16) & 0xff] << 16 ^
+		Te4[(s2 >> 24)       ] << 24;
+
+	/* now do the linear transform using words */
+	{	int i;
+		u32 r0, r1, r2;
+
+		for (i = 0; i < 4; i++) {
+			r0 = t[i];
+			r1 = r0 & 0x80808080;
+			r2 = ((r0 & 0x7f7f7f7f) << 1) ^
+				((r1 - (r1 >> 7)) & 0x1b1b1b1b);
+#if defined(ROTATE)
+			t[i] = r2 ^ ROTATE(r2,24) ^ ROTATE(r0,24) ^
+				ROTATE(r0,16) ^ ROTATE(r0,8);
+#else
+			t[i] = r2 ^ ((r2 ^ r0) << 24) ^ ((r2 ^ r0) >> 8) ^
+				(r0 << 16) ^ (r0 >> 16) ^
+				(r0 << 8) ^ (r0 >> 24);
+#endif
+			t[i] ^= rk[4+i];
+		}
+	}
+#else
+	t[0] =	Te0[(s0      ) & 0xff] ^
+		Te1[(s1 >>  8) & 0xff] ^
+		Te2[(s2 >> 16) & 0xff] ^
+		Te3[(s3 >> 24)       ] ^
+		rk[4];
+	t[1] =	Te0[(s1      ) & 0xff] ^
+		Te1[(s2 >>  8) & 0xff] ^
+		Te2[(s3 >> 16) & 0xff] ^
+		Te3[(s0 >> 24)       ] ^
+		rk[5];
+	t[2] =	Te0[(s2      ) & 0xff] ^
+		Te1[(s3 >>  8) & 0xff] ^
+		Te2[(s0 >> 16) & 0xff] ^
+		Te3[(s1 >> 24)       ] ^
+		rk[6];
+	t[3] =	Te0[(s3      ) & 0xff] ^
+		Te1[(s0 >>  8) & 0xff] ^
+		Te2[(s1 >> 16) & 0xff] ^
+		Te3[(s2 >> 24)       ] ^
+		rk[7];
+#endif
+	s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
+
+    /*
+     * Nr - 2 full rounds:
+     */
+    for (rk+=8,r=key->rounds-2; r>0; rk+=4,r--) {
+#if defined(AES_COMPACT_IN_INNER_ROUNDS)
+	t[0] =	Te4[(s0      ) & 0xff]       ^
+		Te4[(s1 >>  8) & 0xff] <<  8 ^
+		Te4[(s2 >> 16) & 0xff] << 16 ^
+		Te4[(s3 >> 24)       ] << 24;
+	t[1] =	Te4[(s1      ) & 0xff]       ^
+		Te4[(s2 >>  8) & 0xff] <<  8 ^
+		Te4[(s3 >> 16) & 0xff] << 16 ^
+		Te4[(s0 >> 24)       ] << 24;
+	t[2] =	Te4[(s2      ) & 0xff]       ^
+		Te4[(s3 >>  8) & 0xff] <<  8 ^
+		Te4[(s0 >> 16) & 0xff] << 16 ^
+		Te4[(s1 >> 24)       ] << 24;
+	t[3] =	Te4[(s3      ) & 0xff]       ^
+		Te4[(s0 >>  8) & 0xff] <<  8 ^
+		Te4[(s1 >> 16) & 0xff] << 16 ^
+		Te4[(s2 >> 24)       ] << 24;
+
+	/* now do the linear transform using words */
+	{	int i;
+		u32 r0, r1, r2;
+
+		for (i = 0; i < 4; i++) {
+			r0 = t[i];
+			r1 = r0 & 0x80808080;
+			r2 = ((r0 & 0x7f7f7f7f) << 1) ^
+				((r1 - (r1 >> 7)) & 0x1b1b1b1b);
+#if defined(ROTATE)
+			t[i] = r2 ^ ROTATE(r2,24) ^ ROTATE(r0,24) ^
+				ROTATE(r0,16) ^ ROTATE(r0,8);
+#else
+			t[i] = r2 ^ ((r2 ^ r0) << 24) ^ ((r2 ^ r0) >> 8) ^
+				(r0 << 16) ^ (r0 >> 16) ^
+				(r0 << 8) ^ (r0 >> 24);
+#endif
+			t[i] ^= rk[i];
+		}
+	}
+#else
+	t[0] =	Te0[(s0      ) & 0xff] ^
+		Te1[(s1 >>  8) & 0xff] ^
+		Te2[(s2 >> 16) & 0xff] ^
+		Te3[(s3 >> 24)       ] ^
+		rk[0];
+	t[1] =	Te0[(s1      ) & 0xff] ^
+		Te1[(s2 >>  8) & 0xff] ^
+		Te2[(s3 >> 16) & 0xff] ^
+		Te3[(s0 >> 24)       ] ^
+		rk[1];
+	t[2] =	Te0[(s2      ) & 0xff] ^
+		Te1[(s3 >>  8) & 0xff] ^
+		Te2[(s0 >> 16) & 0xff] ^
+		Te3[(s1 >> 24)       ] ^
+		rk[2];
+	t[3] =	Te0[(s3      ) & 0xff] ^
+		Te1[(s0 >>  8) & 0xff] ^
+		Te2[(s1 >> 16) & 0xff] ^
+		Te3[(s2 >> 24)       ] ^
+		rk[3];
+#endif
+	s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
+    }
+    /*
+	 * apply last round and
+	 * map cipher state to byte array block:
+	 */
+#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
+	prefetch256(Te4);
+
+	*(u32*)(out+0) =
+		Te4[(s0      ) & 0xff]       ^
+		Te4[(s1 >>  8) & 0xff] <<  8 ^
+		Te4[(s2 >> 16) & 0xff] << 16 ^
+		Te4[(s3 >> 24)       ] << 24 ^
+		rk[0];
+	*(u32*)(out+4) =
+		Te4[(s1      ) & 0xff]       ^
+		Te4[(s2 >>  8) & 0xff] <<  8 ^
+		Te4[(s3 >> 16) & 0xff] << 16 ^
+		Te4[(s0 >> 24)       ] << 24 ^
+		rk[1];
+	*(u32*)(out+8) =
+		Te4[(s2      ) & 0xff]       ^
+		Te4[(s3 >>  8) & 0xff] <<  8 ^
+		Te4[(s0 >> 16) & 0xff] << 16 ^
+		Te4[(s1 >> 24)       ] << 24 ^
+		rk[2];
+	*(u32*)(out+12) =
+		Te4[(s3      ) & 0xff]       ^
+		Te4[(s0 >>  8) & 0xff] <<  8 ^
+		Te4[(s1 >> 16) & 0xff] << 16 ^
+		Te4[(s2 >> 24)       ] << 24 ^
+		rk[3];
+#else
+	*(u32*)(out+0) =
+		(Te2[(s0      ) & 0xff] & 0x000000ffU) ^
+		(Te3[(s1 >>  8) & 0xff] & 0x0000ff00U) ^
+		(Te0[(s2 >> 16) & 0xff] & 0x00ff0000U) ^
+		(Te1[(s3 >> 24)       ] & 0xff000000U) ^
+		rk[0];
+	*(u32*)(out+4) =
+		(Te2[(s1      ) & 0xff] & 0x000000ffU) ^
+		(Te3[(s2 >>  8) & 0xff] & 0x0000ff00U) ^
+		(Te0[(s3 >> 16) & 0xff] & 0x00ff0000U) ^
+		(Te1[(s0 >> 24)       ] & 0xff000000U) ^
+		rk[1];
+	*(u32*)(out+8) =
+		(Te2[(s2      ) & 0xff] & 0x000000ffU) ^
+		(Te3[(s3 >>  8) & 0xff] & 0x0000ff00U) ^
+		(Te0[(s0 >> 16) & 0xff] & 0x00ff0000U) ^
+		(Te1[(s1 >> 24)       ] & 0xff000000U) ^
+		rk[2];
+	*(u32*)(out+12) =
+		(Te2[(s3      ) & 0xff] & 0x000000ffU) ^
+		(Te3[(s0 >>  8) & 0xff] & 0x0000ff00U) ^
+		(Te0[(s1 >> 16) & 0xff] & 0x00ff0000U) ^
+		(Te1[(s2 >> 24)       ] & 0xff000000U) ^
+		rk[3];
+#endif
+}
+
+/*
+ * Decrypt a single block
+ * in and out can overlap
+ */
+void AES_decrypt(const unsigned char *in, unsigned char *out,
+		 const AES_KEY *key) {
+
+	const u32 *rk;
+	u32 s0, s1, s2, s3, t[4];
+	int r;
+
+	assert(in && out && key);
+	rk = key->rd_key;
+
+	/*
+	 * map byte array block to cipher state
+	 * and add initial round key:
+	 */
+	s0 = GETU32(in     ) ^ rk[0];
+	s1 = GETU32(in +  4) ^ rk[1];
+	s2 = GETU32(in +  8) ^ rk[2];
+	s3 = GETU32(in + 12) ^ rk[3];
+
+#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
+	prefetch256(Td4);
+
+        t[0] =	Td4[(s0      ) & 0xff]       ^
+		Td4[(s3 >>  8) & 0xff] <<  8 ^
+		Td4[(s2 >> 16) & 0xff] << 16 ^
+		Td4[(s1 >> 24)       ] << 24;
+        t[1] =	Td4[(s1      ) & 0xff]       ^
+		Td4[(s0 >>  8) & 0xff] <<  8 ^
+		Td4[(s3 >> 16) & 0xff] << 16 ^
+		Td4[(s2 >> 24)       ] << 24;
+        t[2] =	Td4[(s2      ) & 0xff]       ^
+		Td4[(s1 >>  8) & 0xff] <<  8 ^
+		Td4[(s0 >> 16) & 0xff] << 16 ^
+		Td4[(s3 >> 24)       ] << 24;
+        t[3] =	Td4[(s3      ) & 0xff]       ^
+		Td4[(s2 >>  8) & 0xff] <<  8 ^
+		Td4[(s1 >> 16) & 0xff] << 16 ^
+		Td4[(s0 >> 24)       ] << 24;
+
+	/* now do the linear transform using words */ 
+	{	int i;
+		u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
+
+		for (i = 0; i < 4; i++) {
+			tp1 = t[i];
+			m = tp1 & 0x80808080;
+			tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp2 & 0x80808080;
+			tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp4 & 0x80808080;
+			tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			tp9 = tp8 ^ tp1;
+			tpb = tp9 ^ tp2;
+			tpd = tp9 ^ tp4;
+			tpe = tp8 ^ tp4 ^ tp2;
+#if defined(ROTATE)
+			t[i] = tpe ^ ROTATE(tpd,16) ^
+				ROTATE(tp9,8) ^ ROTATE(tpb,24);
+#else
+			t[i] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ 
+				(tp9 >> 24) ^ (tp9 << 8) ^
+				(tpb >> 8) ^ (tpb << 24);
+#endif
+			t[i] ^= rk[4+i];
+		}
+	}
+#else
+	t[0] =	Td0[(s0      ) & 0xff] ^
+		Td1[(s3 >>  8) & 0xff] ^
+		Td2[(s2 >> 16) & 0xff] ^
+		Td3[(s1 >> 24)       ] ^
+		rk[4];
+	t[1] =	Td0[(s1      ) & 0xff] ^
+		Td1[(s0 >>  8) & 0xff] ^
+		Td2[(s3 >> 16) & 0xff] ^
+		Td3[(s2 >> 24)       ] ^
+		rk[5];
+	t[2] =	Td0[(s2      ) & 0xff] ^
+		Td1[(s1 >>  8) & 0xff] ^
+		Td2[(s0 >> 16) & 0xff] ^
+		Td3[(s3 >> 24)       ] ^
+		rk[6];
+	t[3] =	Td0[(s3      ) & 0xff] ^
+		Td1[(s2 >>  8) & 0xff] ^
+		Td2[(s1 >> 16) & 0xff] ^
+		Td3[(s0 >> 24)       ] ^
+		rk[7];
+#endif
+	s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
+
+    /*
+     * Nr - 2 full rounds:
+     */
+    for (rk+=8,r=key->rounds-2; r>0; rk+=4,r--) {
+#if defined(AES_COMPACT_IN_INNER_ROUNDS)
+        t[0] =	Td4[(s0      ) & 0xff]       ^
+		Td4[(s3 >>  8) & 0xff] <<  8 ^
+		Td4[(s2 >> 16) & 0xff] << 16 ^
+		Td4[(s1 >> 24)       ] << 24;
+        t[1] =	Td4[(s1      ) & 0xff]       ^
+		Td4[(s0 >>  8) & 0xff] <<  8 ^
+		Td4[(s3 >> 16) & 0xff] << 16 ^
+		Td4[(s2 >> 24)       ] << 24;
+        t[2] =	Td4[(s2      ) & 0xff]       ^
+		Td4[(s1 >>  8) & 0xff] <<  8 ^
+		Td4[(s0 >> 16) & 0xff] << 16 ^
+		Td4[(s3 >> 24)       ] << 24;
+        t[3] =	Td4[(s3      ) & 0xff]       ^
+		Td4[(s2 >>  8) & 0xff] <<  8 ^
+		Td4[(s1 >> 16) & 0xff] << 16 ^
+		Td4[(s0 >> 24)       ] << 24;
+
+	/* now do the linear transform using words */ 
+	{	int i;
+		u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
+
+		for (i = 0; i < 4; i++) {
+			tp1 = t[i];
+			m = tp1 & 0x80808080;
+			tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp2 & 0x80808080;
+			tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp4 & 0x80808080;
+			tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			tp9 = tp8 ^ tp1;
+			tpb = tp9 ^ tp2;
+			tpd = tp9 ^ tp4;
+			tpe = tp8 ^ tp4 ^ tp2;
+#if defined(ROTATE)
+			t[i] = tpe ^ ROTATE(tpd,16) ^
+				ROTATE(tp9,8) ^ ROTATE(tpb,24);
+#else
+			t[i] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ 
+				(tp9 >> 24) ^ (tp9 << 8) ^
+				(tpb >> 8) ^ (tpb << 24);
+#endif
+			t[i] ^= rk[i];
+		}
+	}
+#else
+	t[0] =	Td0[(s0      ) & 0xff] ^
+		Td1[(s3 >>  8) & 0xff] ^
+		Td2[(s2 >> 16) & 0xff] ^
+		Td3[(s1 >> 24)       ] ^
+		rk[0];
+	t[1] =	Td0[(s1      ) & 0xff] ^
+		Td1[(s0 >>  8) & 0xff] ^
+		Td2[(s3 >> 16) & 0xff] ^
+		Td3[(s2 >> 24)       ] ^
+		rk[1];
+	t[2] =	Td0[(s2      ) & 0xff] ^
+		Td1[(s1 >>  8) & 0xff] ^
+		Td2[(s0 >> 16) & 0xff] ^
+		Td3[(s3 >> 24)       ] ^
+		rk[2];
+	t[3] =	Td0[(s3      ) & 0xff] ^
+		Td1[(s2 >>  8) & 0xff] ^
+		Td2[(s1 >> 16) & 0xff] ^
+		Td3[(s0 >> 24)       ] ^
+		rk[3];
+#endif
+	s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
+    }
+    /*
+	 * apply last round and
+	 * map cipher state to byte array block:
+	 */
+	prefetch256(Td4);
+
+	*(u32*)(out+0) =
+		(Td4[(s0      ) & 0xff])	^
+		(Td4[(s3 >>  8) & 0xff] <<  8) ^
+		(Td4[(s2 >> 16) & 0xff] << 16) ^
+		(Td4[(s1 >> 24)       ] << 24) ^
+		rk[0];
+	*(u32*)(out+4) =
+		(Td4[(s1      ) & 0xff])	 ^
+		(Td4[(s0 >>  8) & 0xff] <<  8) ^
+		(Td4[(s3 >> 16) & 0xff] << 16) ^
+		(Td4[(s2 >> 24)       ] << 24) ^
+		rk[1];
+	*(u32*)(out+8) =
+		(Td4[(s2      ) & 0xff])	 ^
+		(Td4[(s1 >>  8) & 0xff] <<  8) ^
+		(Td4[(s0 >> 16) & 0xff] << 16) ^
+		(Td4[(s3 >> 24)       ] << 24) ^
+		rk[2];
+	*(u32*)(out+12) =
+		(Td4[(s3      ) & 0xff])	 ^
+		(Td4[(s2 >>  8) & 0xff] <<  8) ^
+		(Td4[(s1 >> 16) & 0xff] << 16) ^
+		(Td4[(s0 >> 24)       ] << 24) ^
+		rk[3];
+}
diff --git a/crypto/aes/asm/aes-586.pl b/crypto/aes/asm/aes-586.pl
index 3bc46a9..aab40e6 100755
--- a/crypto/aes/asm/aes-586.pl
+++ b/crypto/aes/asm/aes-586.pl
@@ -2,11 +2,12 @@
 #
 # ====================================================================
 # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. Rights for redistribution and usage in source and binary
-# forms are granted according to the OpenSSL license.
+# 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/.
 # ====================================================================
 #
-# Version 3.6.
+# Version 4.3.
 #
 # You might fail to appreciate this module performance from the first
 # try. If compared to "vanilla" linux-ia32-icc target, i.e. considered
@@ -81,11 +82,117 @@
 # AMD K8	20			19
 # PIII		25			23
 # Pentium	81			78
+#
+# Version 3.7 reimplements outer rounds as "compact." Meaning that
+# first and last rounds reference compact 256 bytes S-box. This means
+# that first round consumes a lot more CPU cycles and that encrypt
+# and decrypt performance becomes asymmetric. Encrypt performance
+# drops by 10-12%, while decrypt - by 20-25%:-( 256 bytes S-box is
+# aggressively pre-fetched.
+#
+# Version 4.0 effectively rolls back to 3.6 and instead implements
+# additional set of functions, _[x86|sse]_AES_[en|de]crypt_compact,
+# which use exclusively 256 byte S-box. These functions are to be
+# called in modes not concealing plain text, such as ECB, or when
+# we're asked to process smaller amount of data [or unconditionally
+# on hyper-threading CPU]. Currently it's called unconditionally from
+# AES_[en|de]crypt, which affects all modes, but CBC. CBC routine
+# still needs to be modified to switch between slower and faster
+# mode when appropriate... But in either case benchmark landscape
+# changes dramatically and below numbers are CPU cycles per processed
+# byte for 128-bit key.
+#
+#		ECB encrypt	ECB decrypt	CBC large chunk
+# P4		56[60]		84[100]		23
+# AMD K8	48[44]		70[79]		18
+# PIII		41[50]		61[91]		24
+# Core 2	32[38]		45[70]		18.5
+# Pentium	120		160		77
+#
+# Version 4.1 switches to compact S-box even in key schedule setup.
+#
+# Version 4.2 prefetches compact S-box in every SSE round or in other
+# words every cache-line is *guaranteed* to be accessed within ~50
+# cycles window. Why just SSE? Because it's needed on hyper-threading
+# CPU! Which is also why it's prefetched with 64 byte stride. Best
+# part is that it has no negative effect on performance:-)  
+#
+# Version 4.3 implements switch between compact and non-compact block
+# functions in AES_cbc_encrypt depending on how much data was asked
+# to be processed in one stroke.
+#
+######################################################################
+# Timing attacks are classified in two classes: synchronous when
+# attacker consciously initiates cryptographic operation and collects
+# timing data of various character afterwards, and asynchronous when
+# malicious code is executed on same CPU simultaneously with AES,
+# instruments itself and performs statistical analysis of this data.
+#
+# As far as synchronous attacks go the root to the AES timing
+# vulnerability is twofold. Firstly, of 256 S-box elements at most 160
+# are referred to in single 128-bit block operation. Well, in C
+# implementation with 4 distinct tables it's actually as little as 40
+# references per 256 elements table, but anyway... Secondly, even
+# though S-box elements are clustered into smaller amount of cache-
+# lines, smaller than 160 and even 40, it turned out that for certain
+# plain-text pattern[s] or simply put chosen plain-text and given key
+# few cache-lines remain unaccessed during block operation. Now, if
+# attacker can figure out this access pattern, he can deduct the key
+# [or at least part of it]. The natural way to mitigate this kind of
+# attacks is to minimize the amount of cache-lines in S-box and/or
+# prefetch them to ensure that every one is accessed for more uniform
+# timing. But note that *if* plain-text was concealed in such way that
+# input to block function is distributed *uniformly*, then attack
+# wouldn't apply. Now note that some encryption modes, most notably
+# CBC, do mask the plain-text in this exact way [secure cipher output
+# is distributed uniformly]. Yes, one still might find input that
+# would reveal the information about given key, but if amount of
+# candidate inputs to be tried is larger than amount of possible key
+# combinations then attack becomes infeasible. This is why revised
+# AES_cbc_encrypt "dares" to switch to larger S-box when larger chunk
+# of data is to be processed in one stroke. The current size limit of
+# 512 bytes is chosen to provide same [diminishigly low] probability
+# for cache-line to remain untouched in large chunk operation with
+# large S-box as for single block operation with compact S-box and
+# surely needs more careful consideration...
+#
+# As for asynchronous attacks. There are two flavours: attacker code
+# being interleaved with AES on hyper-threading CPU at *instruction*
+# level, and two processes time sharing single core. As for latter.
+# Two vectors. 1. Given that attacker process has higher priority,
+# yield execution to process performing AES just before timer fires
+# off the scheduler, immediately regain control of CPU and analyze the
+# cache state. For this attack to be efficient attacker would have to
+# effectively slow down the operation by several *orders* of magnitute,
+# by ratio of time slice to duration of handful of AES rounds, which
+# unlikely to remain unnoticed. Not to mention that this also means
+# that he would spend correspondigly more time to collect enough
+# statistical data to mount the attack. It's probably appropriate to
+# say that if adeversary reckons that this attack is beneficial and
+# risks to be noticed, you probably have larger problems having him
+# mere opportunity. In other words suggested code design expects you
+# to preclude/mitigate this attack by overall system security design.
+# 2. Attacker manages to make his code interrupt driven. In order for
+# this kind of attack to be feasible, interrupt rate has to be high
+# enough, again comparable to duration of handful of AES rounds. But
+# is there interrupt source of such rate? Hardly, not even 1Gbps NIC
+# generates interrupts at such raging rate...
+#
+# And now back to the former, hyper-threading CPU or more specifically
+# Intel P4. Recall that asynchronous attack implies that malicious
+# code instruments itself. And naturally instrumentation granularity
+# has be noticeably lower than duration of codepath accessing S-box.
+# Given that all cache-lines are accessed during that time that is.
+# Current implementation accesses *all* cache-lines within ~50 cycles
+# window, which is actually *less* than RDTSC latency on Intel P4!
 
-push(@INC,"perlasm","../../perlasm");
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
 require "x86asm.pl";
 
-&asm_init($ARGV[0],"aes-586.pl",$ARGV[$#ARGV] eq "386");
+&asm_init($ARGV[0],"aes-586.pl",$x86only = $ARGV[$#ARGV] eq "386");
+&static_label("AES_Te");
+&static_label("AES_Td");
 
 $s0="eax";
 $s1="ebx";
@@ -93,21 +200,36 @@
 $s3="edx";
 $key="edi";
 $acc="esi";
+$tbl="ebp";
 
-$compromise=0;		# $compromise=128 abstains from copying key
-			# schedule to stack when encrypting inputs
-			# shorter than 128 bytes at the cost of
-			# risksing aliasing with S-boxes. In return
-			# you get way better, up to +70%, small block
-			# performance.
+# stack frame layout in _[x86|sse]_AES_* 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
+$__key=&DWP(20,"esp");	# pointer to key schedule
+$__end=&DWP(24,"esp");	# pointer to end of key schedule
+$__tbl=&DWP(28,"esp");	# %ebp backing store
+
+# stack frame layout in AES_[en|crypt] routines, which differs from
+# above by 4 and overlaps by %ebp backing store
+$_tbl=&DWP(24,"esp");
+$_esp=&DWP(28,"esp");
+
+sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
+
+$speed_limit=512;	# chunks smaller than $speed_limit are
+			# processed with compact routine in CBC mode
 $small_footprint=1;	# $small_footprint=1 code is ~5% slower [on
 			# recent µ-archs], but ~5 times smaller!
 			# I favor compact code to minimize cache
 			# contention and in hope to "collect" 5% back
 			# in real-life applications...
+
 $vertical_spin=0;	# shift "verticaly" defaults to 0, because of
 			# its proof-of-concept status...
-
 # Note that there is no decvert(), as well as last encryption round is
 # performed with "horizontal" shifts. This is because this "vertical"
 # implementation [one which groups shifts on a given $s[i] to form a
@@ -170,17 +292,484 @@
 	&movz	($v0,&HB($v1));
 	&and	($v1,0xFF);
 	&xor	($s[3],&DWP(2,$te,$v1,8));		# s1>>16
-	 &mov	($key,&DWP(12,"esp"));			# reincarnate v1 as key
+	 &mov	($key,$__key);				# reincarnate v1 as key
 	&xor	($s[2],&DWP(1,$te,$v0,8));		# s1>>24
 }
 
+# Another experimental routine, which features "horizontal spin," but
+# eliminates one reference to stack. Strangely enough runs slower...
+sub enchoriz()
+{ my $v0 = $key, $v1 = $acc;
+
+	&movz	($v0,&LB($s0));			#  3, 2, 1, 0*
+	&rotr	($s2,8);			#  8,11,10, 9
+	&mov	($v1,&DWP(0,$te,$v0,8));	#  0
+	&movz	($v0,&HB($s1));			#  7, 6, 5*, 4
+	&rotr	($s3,16);			# 13,12,15,14
+	&xor	($v1,&DWP(3,$te,$v0,8));	#  5
+	&movz	($v0,&HB($s2));			#  8,11,10*, 9
+	&rotr	($s0,16);			#  1, 0, 3, 2
+	&xor	($v1,&DWP(2,$te,$v0,8));	# 10
+	&movz	($v0,&HB($s3));			# 13,12,15*,14
+	&xor	($v1,&DWP(1,$te,$v0,8));	# 15, t[0] collected
+	&mov	($__s0,$v1);			# t[0] saved
+
+	&movz	($v0,&LB($s1));			#  7, 6, 5, 4*
+	&shr	($s1,16);			#  -, -, 7, 6
+	&mov	($v1,&DWP(0,$te,$v0,8));	#  4
+	&movz	($v0,&LB($s3));			# 13,12,15,14*
+	&xor	($v1,&DWP(2,$te,$v0,8));	# 14
+	&movz	($v0,&HB($s0));			#  1, 0, 3*, 2
+	&and	($s3,0xffff0000);		# 13,12, -, -
+	&xor	($v1,&DWP(1,$te,$v0,8));	#  3
+	&movz	($v0,&LB($s2));			#  8,11,10, 9*
+	&or	($s3,$s1);			# 13,12, 7, 6
+	&xor	($v1,&DWP(3,$te,$v0,8));	#  9, t[1] collected
+	&mov	($s1,$v1);			#  s[1]=t[1]
+
+	&movz	($v0,&LB($s0));			#  1, 0, 3, 2*
+	&shr	($s2,16);			#  -, -, 8,11
+	&mov	($v1,&DWP(2,$te,$v0,8));	#  2
+	&movz	($v0,&HB($s3));			# 13,12, 7*, 6
+	&xor	($v1,&DWP(1,$te,$v0,8));	#  7
+	&movz	($v0,&HB($s2));			#  -, -, 8*,11
+	&xor	($v1,&DWP(0,$te,$v0,8));	#  8
+	&mov	($v0,$s3);
+	&shr	($v0,24);			# 13
+	&xor	($v1,&DWP(3,$te,$v0,8));	# 13, t[2] collected
+
+	&movz	($v0,&LB($s2));			#  -, -, 8,11*
+	&shr	($s0,24);			#  1*
+	&mov	($s2,&DWP(1,$te,$v0,8));	# 11
+	&xor	($s2,&DWP(3,$te,$s0,8));	#  1
+	&mov	($s0,$__s0);			# s[0]=t[0]
+	&movz	($v0,&LB($s3));			# 13,12, 7, 6*
+	&shr	($s3,16);			#   ,  ,13,12
+	&xor	($s2,&DWP(2,$te,$v0,8));	#  6
+	&mov	($key,$__key);			# reincarnate v0 as key
+	&and	($s3,0xff);			#   ,  ,13,12*
+	&mov	($s3,&DWP(0,$te,$s3,8));	# 12
+	&xor	($s3,$s2);			# s[2]=t[3] collected
+	&mov	($s2,$v1);			# s[2]=t[2]
+}
+
+# More experimental code... SSE one... Even though this one eliminates
+# *all* references to stack, it's not faster...
+sub sse_encbody()
+{
+	&movz	($acc,&LB("eax"));		#  0
+	&mov	("ecx",&DWP(0,$tbl,$acc,8));	#  0
+	&pshufw	("mm2","mm0",0x0d);		#  7, 6, 3, 2
+	&movz	("edx",&HB("eax"));		#  1
+	&mov	("edx",&DWP(3,$tbl,"edx",8));	#  1
+	&shr	("eax",16);			#  5, 4
+
+	&movz	($acc,&LB("ebx"));		# 10
+	&xor	("ecx",&DWP(2,$tbl,$acc,8));	# 10
+	&pshufw	("mm6","mm4",0x08);		# 13,12, 9, 8
+	&movz	($acc,&HB("ebx"));		# 11
+	&xor	("edx",&DWP(1,$tbl,$acc,8));	# 11
+	&shr	("ebx",16);			# 15,14
+
+	&movz	($acc,&HB("eax"));		#  5
+	&xor	("ecx",&DWP(3,$tbl,$acc,8));	#  5
+	&movq	("mm3",QWP(16,$key));
+	&movz	($acc,&HB("ebx"));		# 15
+	&xor	("ecx",&DWP(1,$tbl,$acc,8));	# 15
+	&movd	("mm0","ecx");			# t[0] collected
+
+	&movz	($acc,&LB("eax"));		#  4
+	&mov	("ecx",&DWP(0,$tbl,$acc,8));	#  4
+	&movd	("eax","mm2");			#  7, 6, 3, 2
+	&movz	($acc,&LB("ebx"));		# 14
+	&xor	("ecx",&DWP(2,$tbl,$acc,8));	# 14
+	&movd	("ebx","mm6");			# 13,12, 9, 8
+
+	&movz	($acc,&HB("eax"));		#  3
+	&xor	("ecx",&DWP(1,$tbl,$acc,8));	#  3
+	&movz	($acc,&HB("ebx"));		#  9
+	&xor	("ecx",&DWP(3,$tbl,$acc,8));	#  9
+	&movd	("mm1","ecx");			# t[1] collected
+
+	&movz	($acc,&LB("eax"));		#  2
+	&mov	("ecx",&DWP(2,$tbl,$acc,8));	#  2
+	&shr	("eax",16);			#  7, 6
+	&punpckldq	("mm0","mm1");		# t[0,1] collected
+	&movz	($acc,&LB("ebx"));		#  8
+	&xor	("ecx",&DWP(0,$tbl,$acc,8));	#  8
+	&shr	("ebx",16);			# 13,12
+
+	&movz	($acc,&HB("eax"));		#  7
+	&xor	("ecx",&DWP(1,$tbl,$acc,8));	#  7
+	&pxor	("mm0","mm3");
+	&movz	("eax",&LB("eax"));		#  6
+	&xor	("edx",&DWP(2,$tbl,"eax",8));	#  6
+	&pshufw	("mm1","mm0",0x08);		#  5, 4, 1, 0
+	&movz	($acc,&HB("ebx"));		# 13
+	&xor	("ecx",&DWP(3,$tbl,$acc,8));	# 13
+	&xor	("ecx",&DWP(24,$key));		# t[2]
+	&movd	("mm4","ecx");			# t[2] collected
+	&movz	("ebx",&LB("ebx"));		# 12
+	&xor	("edx",&DWP(0,$tbl,"ebx",8));	# 12
+	&shr	("ecx",16);
+	&movd	("eax","mm1");			#  5, 4, 1, 0
+	&mov	("ebx",&DWP(28,$key));		# t[3]
+	&xor	("ebx","edx");
+	&movd	("mm5","ebx");			# t[3] collected
+	&and	("ebx",0xffff0000);
+	&or	("ebx","ecx");
+
+	&punpckldq	("mm4","mm5");		# t[2,3] collected
+}
+
+######################################################################
+# "Compact" block function
+######################################################################
+
+sub enccompact()
+{ my $Fn = mov;
+  while ($#_>5) { pop(@_); $Fn=sub{}; }
+  my ($i,$te,@s)=@_;
+  my $tmp = $key;
+  my $out = $i==3?$s[0]:$acc;
+
+	# $Fn is used in first compact round and its purpose is to
+	# void restoration of some values from stack, so that after
+	# 4xenccompact with extra argument $key value is left there...
+	if ($i==3)  {	&$Fn	($key,$__key);			}##%edx
+	else        {	&mov	($out,$s[0]);			}
+			&and	($out,0xFF);
+	if ($i==1)  {	&shr	($s[0],16);			}#%ebx[1]
+	if ($i==2)  {	&shr	($s[0],24);			}#%ecx[2]
+			&movz	($out,&BP(-128,$te,$out,1));
+
+	if ($i==3)  {	$tmp=$s[1];				}##%eax
+			&movz	($tmp,&HB($s[1]));
+			&movz	($tmp,&BP(-128,$te,$tmp,1));
+			&shl	($tmp,8);
+			&xor	($out,$tmp);
+
+	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$__s0);		}##%ebx
+	else        {	&mov	($tmp,$s[2]);
+			&shr	($tmp,16);			}
+	if ($i==2)  {	&and	($s[1],0xFF);			}#%edx[2]
+			&and	($tmp,0xFF);
+			&movz	($tmp,&BP(-128,$te,$tmp,1));
+			&shl	($tmp,16);
+			&xor	($out,$tmp);
+
+	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}##%ecx
+	elsif($i==2){	&movz	($tmp,&HB($s[3]));		}#%ebx[2]
+	else        {	&mov	($tmp,$s[3]);
+			&shr	($tmp,24);			}
+			&movz	($tmp,&BP(-128,$te,$tmp,1));
+			&shl	($tmp,24);
+			&xor	($out,$tmp);
+	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
+	if ($i==3)  {	&mov	($s[3],$acc);			}
+	&comment();
+}
+
+sub enctransform()
+{ my @s = ($s0,$s1,$s2,$s3);
+  my $i = shift;
+  my $tmp = $tbl;
+  my $r2  = $key ;
+
+	&mov	($acc,$s[$i]);
+	&and	($acc,0x80808080);
+	&mov	($tmp,$acc);
+	&shr	($tmp,7);
+	&lea	($r2,&DWP(0,$s[$i],$s[$i]));
+	&sub	($acc,$tmp);
+	&and	($r2,0xfefefefe);
+	&and	($acc,0x1b1b1b1b);
+	&mov	($tmp,$s[$i]);
+	&xor	($acc,$r2);	# r2
+
+	&xor	($s[$i],$acc);	# r0 ^ r2
+	&rotl	($s[$i],24);
+	&xor	($s[$i],$acc)	# ROTATE(r2^r0,24) ^ r2
+	&rotr	($tmp,16);
+	&xor	($s[$i],$tmp);
+	&rotr	($tmp,8);
+	&xor	($s[$i],$tmp);
+}
+
+&function_begin_B("_x86_AES_encrypt_compact");
+	# note that caller is expected to allocate stack frame for me!
+	&mov	($__key,$key);			# save key
+
+	&xor	($s0,&DWP(0,$key));		# xor with key
+	&xor	($s1,&DWP(4,$key));
+	&xor	($s2,&DWP(8,$key));
+	&xor	($s3,&DWP(12,$key));
+
+	&mov	($acc,&DWP(240,$key));		# load key->rounds
+	&lea	($acc,&DWP(-2,$acc,$acc));
+	&lea	($acc,&DWP(0,$key,$acc,8));
+	&mov	($__end,$acc);			# end of key schedule
+
+	# prefetch Te4
+	&mov	($key,&DWP(0-128,$tbl));
+	&mov	($acc,&DWP(32-128,$tbl));
+	&mov	($key,&DWP(64-128,$tbl));
+	&mov	($acc,&DWP(96-128,$tbl));
+	&mov	($key,&DWP(128-128,$tbl));
+	&mov	($acc,&DWP(160-128,$tbl));
+	&mov	($key,&DWP(192-128,$tbl));
+	&mov	($acc,&DWP(224-128,$tbl));
+
+	&set_label("loop",16);
+
+		&enccompact(0,$tbl,$s0,$s1,$s2,$s3,1);
+		&enccompact(1,$tbl,$s1,$s2,$s3,$s0,1);
+		&enccompact(2,$tbl,$s2,$s3,$s0,$s1,1);
+		&enccompact(3,$tbl,$s3,$s0,$s1,$s2,1);
+		&enctransform(2);
+		&enctransform(3);
+		&enctransform(0);
+		&enctransform(1);
+		&mov 	($key,$__key);
+		&mov	($tbl,$__tbl);
+		&add	($key,16);		# advance rd_key
+		&xor	($s0,&DWP(0,$key));
+		&xor	($s1,&DWP(4,$key));
+		&xor	($s2,&DWP(8,$key));
+		&xor	($s3,&DWP(12,$key));
+
+	&cmp	($key,$__end);
+	&mov	($__key,$key);
+	&jb	(&label("loop"));
+
+	&enccompact(0,$tbl,$s0,$s1,$s2,$s3);
+	&enccompact(1,$tbl,$s1,$s2,$s3,$s0);
+	&enccompact(2,$tbl,$s2,$s3,$s0,$s1);
+	&enccompact(3,$tbl,$s3,$s0,$s1,$s2);
+
+	&xor	($s0,&DWP(16,$key));
+	&xor	($s1,&DWP(20,$key));
+	&xor	($s2,&DWP(24,$key));
+	&xor	($s3,&DWP(28,$key));
+
+	&ret	();
+&function_end_B("_x86_AES_encrypt_compact");
+
+######################################################################
+# "Compact" SSE block function.
+######################################################################
+#
+# Performance is not actually extraordinary in comparison to pure
+# x86 code. In particular encrypt performance is virtually the same.
+# Decrypt performance on the other hand is 15-20% better on newer
+# µ-archs [but we're thankful for *any* improvement here], and ~50%
+# better on PIII:-) And additionally on the pros side this code
+# eliminates redundant references to stack and thus relieves/
+# minimizes the pressure on the memory bus.
+#
+# MMX register layout                           lsb
+# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+# |          mm4          |          mm0          |
+# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+# |     s3    |     s2    |     s1    |     s0    |    
+# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+# |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+#
+# Indexes translate as s[N/4]>>(8*(N%4)), e.g. 5 means s1>>8.
+# In this terms encryption and decryption "compact" permutation
+# matrices can be depicted as following:
+#
+# encryption              lsb	# decryption              lsb
+# +----++----+----+----+----+	# +----++----+----+----+----+
+# | t0 || 15 | 10 |  5 |  0 |	# | t0 ||  7 | 10 | 13 |  0 |
+# +----++----+----+----+----+	# +----++----+----+----+----+
+# | t1 ||  3 | 14 |  9 |  4 |	# | t1 || 11 | 14 |  1 |  4 |
+# +----++----+----+----+----+	# +----++----+----+----+----+
+# | t2 ||  7 |  2 | 13 |  8 |	# | t2 || 15 |  2 |  5 |  8 |
+# +----++----+----+----+----+	# +----++----+----+----+----+
+# | t3 || 11 |  6 |  1 | 12 |	# | t3 ||  3 |  6 |  9 | 12 |
+# +----++----+----+----+----+	# +----++----+----+----+----+
+#
+######################################################################
+# Why not xmm registers? Short answer. It was actually tested and
+# was not any faster, but *contrary*, most notably on Intel CPUs.
+# Longer answer. Main advantage of using mm registers is that movd
+# latency is lower, especially on Intel P4. While arithmetic
+# instructions are twice as many, they can be scheduled every cycle
+# and not every second one when they are operating on xmm register,
+# so that "arithmetic throughput" remains virtually the same. And
+# finally the code can be executed even on elder SSE-only CPUs:-)
+
+sub sse_enccompact()
+{
+	&pshufw	("mm1","mm0",0x08);		#  5, 4, 1, 0
+	&pshufw	("mm5","mm4",0x0d);		# 15,14,11,10
+	&movd	("eax","mm1");			#  5, 4, 1, 0
+	&movd	("ebx","mm5");			# 15,14,11,10
+
+	&movz	($acc,&LB("eax"));		#  0
+	&movz	("ecx",&BP(-128,$tbl,$acc,1));	#  0
+	&pshufw	("mm2","mm0",0x0d);		#  7, 6, 3, 2
+	&movz	("edx",&HB("eax"));		#  1
+	&movz	("edx",&BP(-128,$tbl,"edx",1));	#  1
+	&shl	("edx",8);			#  1
+	&shr	("eax",16);			#  5, 4
+
+	&movz	($acc,&LB("ebx"));		# 10
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 10
+	&shl	($acc,16);			# 10
+	&or	("ecx",$acc);			# 10
+	&pshufw	("mm6","mm4",0x08);		# 13,12, 9, 8
+	&movz	($acc,&HB("ebx"));		# 11
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 11
+	&shl	($acc,24);			# 11
+	&or	("edx",$acc);			# 11
+	&shr	("ebx",16);			# 15,14
+
+	&movz	($acc,&HB("eax"));		#  5
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  5
+	&shl	($acc,8);			#  5
+	&or	("ecx",$acc);			#  5
+	&movz	($acc,&HB("ebx"));		# 15
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 15
+	&shl	($acc,24);			# 15
+	&or	("ecx",$acc);			# 15
+	&movd	("mm0","ecx");			# t[0] collected
+
+	&movz	($acc,&LB("eax"));		#  4
+	&movz	("ecx",&BP(-128,$tbl,$acc,1));	#  4
+	&movd	("eax","mm2");			#  7, 6, 3, 2
+	&movz	($acc,&LB("ebx"));		# 14
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 14
+	&shl	($acc,16);			# 14
+	&or	("ecx",$acc);			# 14
+
+	&movd	("ebx","mm6");			# 13,12, 9, 8
+	&movz	($acc,&HB("eax"));		#  3
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  3
+	&shl	($acc,24);			#  3
+	&or	("ecx",$acc);			#  3
+	&movz	($acc,&HB("ebx"));		#  9
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  9
+	&shl	($acc,8);			#  9
+	&or	("ecx",$acc);			#  9
+	&movd	("mm1","ecx");			# t[1] collected
+
+	&movz	($acc,&LB("ebx"));		#  8
+	&movz	("ecx",&BP(-128,$tbl,$acc,1));	#  8
+	&shr	("ebx",16);			# 13,12
+	&movz	($acc,&LB("eax"));		#  2
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  2
+	&shl	($acc,16);			#  2
+	&or	("ecx",$acc);			#  2
+	&shr	("eax",16);			#  7, 6
+
+	&punpckldq	("mm0","mm1");		# t[0,1] collected
+
+	&movz	($acc,&HB("eax"));		#  7
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  7
+	&shl	($acc,24);			#  7
+	&or	("ecx",$acc);			#  7
+	&and	("eax",0xff);			#  6
+	&movz	("eax",&BP(-128,$tbl,"eax",1));	#  6
+	&shl	("eax",16);			#  6
+	&or	("edx","eax");			#  6
+	&movz	($acc,&HB("ebx"));		# 13
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 13
+	&shl	($acc,8);			# 13
+	&or	("ecx",$acc);			# 13
+	&movd	("mm4","ecx");			# t[2] collected
+	&and	("ebx",0xff);			# 12
+	&movz	("ebx",&BP(-128,$tbl,"ebx",1));	# 12
+	&or	("edx","ebx");			# 12
+	&movd	("mm5","edx");			# t[3] collected
+
+	&punpckldq	("mm4","mm5");		# t[2,3] collected
+}
+
+					if (!$x86only) {
+&function_begin_B("_sse_AES_encrypt_compact");
+	&pxor	("mm0",&QWP(0,$key));	#  7, 6, 5, 4, 3, 2, 1, 0
+	&pxor	("mm4",&QWP(8,$key));	# 15,14,13,12,11,10, 9, 8
+
+	# note that caller is expected to allocate stack frame for me!
+	&mov	($acc,&DWP(240,$key));		# load key->rounds
+	&lea	($acc,&DWP(-2,$acc,$acc));
+	&lea	($acc,&DWP(0,$key,$acc,8));
+	&mov	($__end,$acc);			# end of key schedule
+
+	&mov	($s0,0x1b1b1b1b);		# magic constant
+	&mov	(&DWP(8,"esp"),$s0);
+	&mov	(&DWP(12,"esp"),$s0);
+
+	# prefetch Te4
+	&mov	($s0,&DWP(0-128,$tbl));
+	&mov	($s1,&DWP(32-128,$tbl));
+	&mov	($s2,&DWP(64-128,$tbl));
+	&mov	($s3,&DWP(96-128,$tbl));
+	&mov	($s0,&DWP(128-128,$tbl));
+	&mov	($s1,&DWP(160-128,$tbl));
+	&mov	($s2,&DWP(192-128,$tbl));
+	&mov	($s3,&DWP(224-128,$tbl));
+
+	&set_label("loop",16);
+		&sse_enccompact();
+		&add	($key,16);
+		&cmp	($key,$__end);
+		&ja	(&label("out"));
+
+		&movq	("mm2",&QWP(8,"esp"));
+		&pxor	("mm3","mm3");		&pxor	("mm7","mm7");
+		&movq	("mm1","mm0");		&movq	("mm5","mm4");	# r0
+		&pcmpgtb("mm3","mm0");		&pcmpgtb("mm7","mm4");
+		&pand	("mm3","mm2");		&pand	("mm7","mm2");
+		&pshufw	("mm2","mm0",0xb1);	&pshufw	("mm6","mm4",0xb1);# ROTATE(r0,16)
+		&paddb	("mm0","mm0");		&paddb	("mm4","mm4");
+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# = r2
+		&pshufw	("mm3","mm2",0xb1);	&pshufw	("mm7","mm6",0xb1);# r0
+		&pxor	("mm1","mm0");		&pxor	("mm5","mm4");	# r0^r2
+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= ROTATE(r0,16)
+
+		&movq	("mm2","mm3");		&movq	("mm6","mm7");
+		&pslld	("mm3",8);		&pslld	("mm7",8);
+		&psrld	("mm2",24);		&psrld	("mm6",24);
+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= r0<<8
+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= r0>>24
+
+		&movq	("mm3","mm1");		&movq	("mm7","mm5");
+		&movq	("mm2",&QWP(0,$key));	&movq	("mm6",&QWP(8,$key));
+		&psrld	("mm1",8);		&psrld	("mm5",8);
+		&mov	($s0,&DWP(0-128,$tbl));
+		&pslld	("mm3",24);		&pslld	("mm7",24);
+		&mov	($s1,&DWP(64-128,$tbl));
+		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= (r2^r0)<<8
+		&mov	($s2,&DWP(128-128,$tbl));
+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= (r2^r0)>>24
+		&mov	($s3,&DWP(192-128,$tbl));
+
+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");
+	&jmp	(&label("loop"));
+
+	&set_label("out",16);
+	&pxor	("mm0",&QWP(0,$key));
+	&pxor	("mm4",&QWP(8,$key));
+
+	&ret	();
+&function_end_B("_sse_AES_encrypt_compact");
+					}
+
+######################################################################
+# Vanilla block function.
+######################################################################
+
 sub encstep()
 { my ($i,$te,@s) = @_;
   my $tmp = $key;
   my $out = $i==3?$s[0]:$acc;
 
 	# lines marked with #%e?x[i] denote "reordered" instructions...
-	if ($i==3)  {	&mov	($key,&DWP(12,"esp"));		}##%edx
+	if ($i==3)  {	&mov	($key,$__key);			}##%edx
 	else        {	&mov	($out,$s[0]);
 			&and	($out,0xFF);			}
 	if ($i==1)  {	&shr	($s[0],16);			}#%ebx[1]
@@ -191,14 +780,14 @@
 			&movz	($tmp,&HB($s[1]));
 			&xor	($out,&DWP(3,$te,$tmp,8));
 
-	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],&DWP(4,"esp"));	}##%ebx
+	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$__s0);		}##%ebx
 	else        {	&mov	($tmp,$s[2]);
 			&shr	($tmp,16);			}
 	if ($i==2)  {	&and	($s[1],0xFF);			}#%edx[2]
 			&and	($tmp,0xFF);
 			&xor	($out,&DWP(2,$te,$tmp,8));
 
-	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],&DWP(8,"esp"));	}##%ecx
+	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}##%ecx
 	elsif($i==2){	&movz	($tmp,&HB($s[3]));		}#%ebx[2]
 	else        {	&mov	($tmp,$s[3]); 
 			&shr	($tmp,24)			}
@@ -213,7 +802,7 @@
   my $tmp = $key;
   my $out = $i==3?$s[0]:$acc;
 
-	if ($i==3)  {	&mov	($key,&DWP(12,"esp"));		}##%edx
+	if ($i==3)  {	&mov	($key,$__key);			}##%edx
 	else        {	&mov	($out,$s[0]);			}
 			&and	($out,0xFF);
 	if ($i==1)  {	&shr	($s[0],16);			}#%ebx[1]
@@ -227,8 +816,8 @@
 			&and	($tmp,0x0000ff00);
 			&xor	($out,$tmp);
 
-	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],&DWP(4,"esp"));	}##%ebx
-	else        {	mov	($tmp,$s[2]);
+	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$__s0);		}##%ebx
+	else        {	&mov	($tmp,$s[2]);
 			&shr	($tmp,16);			}
 	if ($i==2)  {	&and	($s[1],0xFF);			}#%edx[2]
 			&and	($tmp,0xFF);
@@ -236,7 +825,7 @@
 			&and	($tmp,0x00ff0000);
 			&xor	($out,$tmp);
 
-	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],&DWP(8,"esp"));	}##%ecx
+	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}##%ecx
 	elsif($i==2){	&movz	($tmp,&HB($s[3]));		}#%ebx[2]
 	else        {	&mov	($tmp,$s[3]);
 			&shr	($tmp,24);			}
@@ -247,9 +836,6 @@
 	if ($i==3)  {	&mov	($s[3],$acc);			}
 }
 
-sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
-
-&public_label("AES_Te");
 &function_begin_B("_x86_AES_encrypt");
 	if ($vertical_spin) {
 		# I need high parts of volatile registers to be accessible...
@@ -258,7 +844,7 @@
 	}
 
 	# note that caller is expected to allocate stack frame for me!
-	&mov	(&DWP(12,"esp"),$key);		# save key
+	&mov	($__key,$key);			# save key
 
 	&xor	($s0,&DWP(0,$key));		# xor with key
 	&xor	($s1,&DWP(4,$key));
@@ -270,24 +856,24 @@
 	if ($small_footprint) {
 	    &lea	($acc,&DWP(-2,$acc,$acc));
 	    &lea	($acc,&DWP(0,$key,$acc,8));
-	    &mov	(&DWP(16,"esp"),$acc);	# end of key schedule
-	    &align	(4);
-	    &set_label("loop");
+	    &mov	($__end,$acc);		# end of key schedule
+
+	    &set_label("loop",16);
 		if ($vertical_spin) {
-		    &encvert("ebp",$s0,$s1,$s2,$s3);
+		    &encvert($tbl,$s0,$s1,$s2,$s3);
 		} else {
-		    &encstep(0,"ebp",$s0,$s1,$s2,$s3);
-		    &encstep(1,"ebp",$s1,$s2,$s3,$s0);
-		    &encstep(2,"ebp",$s2,$s3,$s0,$s1);
-		    &encstep(3,"ebp",$s3,$s0,$s1,$s2);
+		    &encstep(0,$tbl,$s0,$s1,$s2,$s3);
+		    &encstep(1,$tbl,$s1,$s2,$s3,$s0);
+		    &encstep(2,$tbl,$s2,$s3,$s0,$s1);
+		    &encstep(3,$tbl,$s3,$s0,$s1,$s2);
 		}
 		&add	($key,16);		# advance rd_key
 		&xor	($s0,&DWP(0,$key));
 		&xor	($s1,&DWP(4,$key));
 		&xor	($s2,&DWP(8,$key));
 		&xor	($s3,&DWP(12,$key));
-	    &cmp	($key,&DWP(16,"esp"));
-	    &mov	(&DWP(12,"esp"),$key);
+	    &cmp	($key,$__end);
+	    &mov	($__key,$key);
 	    &jb		(&label("loop"));
 	}
 	else {
@@ -296,15 +882,15 @@
 	    &cmp	($acc,12);
 	    &jle	(&label("12rounds"));
 
-	&set_label("14rounds");
+	&set_label("14rounds",4);
 	    for ($i=1;$i<3;$i++) {
 		if ($vertical_spin) {
-		    &encvert("ebp",$s0,$s1,$s2,$s3);
+		    &encvert($tbl,$s0,$s1,$s2,$s3);
 		} else {
-		    &encstep(0,"ebp",$s0,$s1,$s2,$s3);
-		    &encstep(1,"ebp",$s1,$s2,$s3,$s0);
-		    &encstep(2,"ebp",$s2,$s3,$s0,$s1);
-		    &encstep(3,"ebp",$s3,$s0,$s1,$s2);
+		    &encstep(0,$tbl,$s0,$s1,$s2,$s3);
+		    &encstep(1,$tbl,$s1,$s2,$s3,$s0);
+		    &encstep(2,$tbl,$s2,$s3,$s0,$s1);
+		    &encstep(3,$tbl,$s3,$s0,$s1,$s2);
 		}
 		&xor	($s0,&DWP(16*$i+0,$key));
 		&xor	($s1,&DWP(16*$i+4,$key));
@@ -312,16 +898,16 @@
 		&xor	($s3,&DWP(16*$i+12,$key));
 	    }
 	    &add	($key,32);
-	    &mov	(&DWP(12,"esp"),$key);	# advance rd_key
-	&set_label("12rounds");
+	    &mov	($__key,$key);		# advance rd_key
+	&set_label("12rounds",4);
 	    for ($i=1;$i<3;$i++) {
 		if ($vertical_spin) {
-		    &encvert("ebp",$s0,$s1,$s2,$s3);
+		    &encvert($tbl,$s0,$s1,$s2,$s3);
 		} else {
-		    &encstep(0,"ebp",$s0,$s1,$s2,$s3);
-		    &encstep(1,"ebp",$s1,$s2,$s3,$s0);
-		    &encstep(2,"ebp",$s2,$s3,$s0,$s1);
-		    &encstep(3,"ebp",$s3,$s0,$s1,$s2);
+		    &encstep(0,$tbl,$s0,$s1,$s2,$s3);
+		    &encstep(1,$tbl,$s1,$s2,$s3,$s0);
+		    &encstep(2,$tbl,$s2,$s3,$s0,$s1);
+		    &encstep(3,$tbl,$s3,$s0,$s1,$s2);
 		}
 		&xor	($s0,&DWP(16*$i+0,$key));
 		&xor	($s1,&DWP(16*$i+4,$key));
@@ -329,16 +915,16 @@
 		&xor	($s3,&DWP(16*$i+12,$key));
 	    }
 	    &add	($key,32);
-	    &mov	(&DWP(12,"esp"),$key);	# advance rd_key
-	&set_label("10rounds");
+	    &mov	($__key,$key);		# advance rd_key
+	&set_label("10rounds",4);
 	    for ($i=1;$i<10;$i++) {
 		if ($vertical_spin) {
-		    &encvert("ebp",$s0,$s1,$s2,$s3);
+		    &encvert($tbl,$s0,$s1,$s2,$s3);
 		} else {
-		    &encstep(0,"ebp",$s0,$s1,$s2,$s3);
-		    &encstep(1,"ebp",$s1,$s2,$s3,$s0);
-		    &encstep(2,"ebp",$s2,$s3,$s0,$s1);
-		    &encstep(3,"ebp",$s3,$s0,$s1,$s2);
+		    &encstep(0,$tbl,$s0,$s1,$s2,$s3);
+		    &encstep(1,$tbl,$s1,$s2,$s3,$s0);
+		    &encstep(2,$tbl,$s2,$s3,$s0,$s1);
+		    &encstep(3,$tbl,$s3,$s0,$s1,$s2);
 		}
 		&xor	($s0,&DWP(16*$i+0,$key));
 		&xor	($s1,&DWP(16*$i+4,$key));
@@ -352,10 +938,10 @@
 	    &mov	($s1="ebx",$key="edi");
 	    &mov	($s2="ecx",$acc="esi");
 	}
-	&enclast(0,"ebp",$s0,$s1,$s2,$s3);
-	&enclast(1,"ebp",$s1,$s2,$s3,$s0);
-	&enclast(2,"ebp",$s2,$s3,$s0,$s1);
-	&enclast(3,"ebp",$s3,$s0,$s1,$s2);
+	&enclast(0,$tbl,$s0,$s1,$s2,$s3);
+	&enclast(1,$tbl,$s1,$s2,$s3,$s0);
+	&enclast(2,$tbl,$s2,$s3,$s0,$s1);
+	&enclast(3,$tbl,$s3,$s0,$s1,$s2);
 
 	&add	($key,$small_footprint?16:160);
 	&xor	($s0,&DWP(0,$key));
@@ -430,38 +1016,198 @@
 	&_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0);
 	&_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e);
 	&_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c);
+
+#Te4	# four copies of Te4 to choose from to avoid L1 aliasing
+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
+
+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
+
+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
+
+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
 #rcon:
 	&data_word(0x00000001, 0x00000002, 0x00000004, 0x00000008);
 	&data_word(0x00000010, 0x00000020, 0x00000040, 0x00000080);
-	&data_word(0x0000001b, 0x00000036, 0, 0, 0, 0, 0, 0);
+	&data_word(0x0000001b, 0x00000036, 0x00000000, 0x00000000);
+	&data_word(0x00000000, 0x00000000, 0x00000000, 0x00000000);
 &function_end_B("_x86_AES_encrypt");
 
 # void AES_encrypt (const void *inp,void *out,const AES_KEY *key);
-&public_label("AES_Te");
 &function_begin("AES_encrypt");
 	&mov	($acc,&wparam(0));		# load inp
 	&mov	($key,&wparam(2));		# load key
 
 	&mov	($s0,"esp");
-	&sub	("esp",24);
-	&and	("esp",-64);
-	&add	("esp",4);
-	&mov	(&DWP(16,"esp"),$s0);
+	&sub	("esp",36);
+	&and	("esp",-64);			# align to cache-line
+
+	# place stack frame just "above" the key schedule
+	&lea	($s1,&DWP(-64-63,$key));
+	&sub	($s1,"esp");
+	&neg	($s1);
+	&and	($s1,0x3C0);	# modulo 1024, but aligned to cache-line
+	&sub	("esp",$s1);
+	&add	("esp",4);	# 4 is reserved for caller's return address
+	&mov	($_esp,$s0);			# save stack pointer
 
 	&call   (&label("pic_point"));          # make it PIC!
 	&set_label("pic_point");
-	&blindpop("ebp");
-	&lea    ("ebp",&DWP(&label("AES_Te")."-".&label("pic_point"),"ebp"));
+	&blindpop($tbl);
+	&picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if (!$x86only);
+	&lea    ($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl));
 
+	# pick Te4 copy which can't "overlap" with stack frame or key schedule
+	&lea	($s1,&DWP(768-4,"esp"));
+	&sub	($s1,$tbl);
+	&and	($s1,0x300);
+	&lea	($tbl,&DWP(2048+128,$tbl,$s1));
+
+					if (!$x86only) {
+	&bt	(&DWP(0,$s0),25);	# check for SSE bit
+	&jnc	(&label("x86"));
+
+	&movq	("mm0",&QWP(0,$acc));
+	&movq	("mm4",&QWP(8,$acc));
+	&call	("_sse_AES_encrypt_compact");
+	&mov	("esp",$_esp);			# restore stack pointer
+	&mov	($acc,&wparam(1));		# load out
+	&movq	(&QWP(0,$acc),"mm0");		# write output data
+	&movq	(&QWP(8,$acc),"mm4");
+	&emms	();
+	&function_end_A();
+					}
+	&set_label("x86",16);
+	&mov	($_tbl,$tbl);
 	&mov	($s0,&DWP(0,$acc));		# load input data
 	&mov	($s1,&DWP(4,$acc));
 	&mov	($s2,&DWP(8,$acc));
 	&mov	($s3,&DWP(12,$acc));
-
-	&call	("_x86_AES_encrypt");
-
-	&mov	("esp",&DWP(16,"esp"));
-
+	&call	("_x86_AES_encrypt_compact");
+	&mov	("esp",$_esp);			# restore stack pointer
 	&mov	($acc,&wparam(1));		# load out
 	&mov	(&DWP(0,$acc),$s0);		# write output data
 	&mov	(&DWP(4,$acc),$s1);
@@ -469,7 +1215,370 @@
 	&mov	(&DWP(12,$acc),$s3);
 &function_end("AES_encrypt");
 
-#------------------------------------------------------------------#
+#--------------------------------------------------------------------#
+
+######################################################################
+# "Compact" block function
+######################################################################
+
+sub deccompact()
+{ my $Fn = mov;
+  while ($#_>5) { pop(@_); $Fn=sub{}; }
+  my ($i,$td,@s)=@_;
+  my $tmp = $key;
+  my $out = $i==3?$s[0]:$acc;
+
+	# $Fn is used in first compact round and its purpose is to
+	# void restoration of some values from stack, so that after
+	# 4xdeccompact with extra argument $key, $s0 and $s1 values
+	# are left there...
+	if($i==3)   {	&$Fn	($key,$__key);			}
+	else        {	&mov	($out,$s[0]);			}
+			&and	($out,0xFF);
+			&movz	($out,&BP(-128,$td,$out,1));
+
+	if ($i==3)  {	$tmp=$s[1];				}
+			&movz	($tmp,&HB($s[1]));
+			&movz	($tmp,&BP(-128,$td,$tmp,1));
+			&shl	($tmp,8);
+			&xor	($out,$tmp);
+
+	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$acc);		}
+	else        {	mov	($tmp,$s[2]);			}
+			&shr	($tmp,16);
+			&and	($tmp,0xFF);
+			&movz	($tmp,&BP(-128,$td,$tmp,1));
+			&shl	($tmp,16);
+			&xor	($out,$tmp);
+
+	if ($i==3)  {	$tmp=$s[3]; &$Fn ($s[2],$__s1);		}
+	else        {	&mov	($tmp,$s[3]);			}
+			&shr	($tmp,24);
+			&movz	($tmp,&BP(-128,$td,$tmp,1));
+			&shl	($tmp,24);
+			&xor	($out,$tmp);
+	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
+	if ($i==3)  {	&$Fn	($s[3],$__s0);			}
+}
+
+# must be called with 2,3,0,1 as argument sequence!!!
+sub dectransform()
+{ my @s = ($s0,$s1,$s2,$s3);
+  my $i = shift;
+  my $tmp = $key;
+  my $tp2 = @s[($i+2)%4]; $tp2 = @s[2] if ($i==1);
+  my $tp4 = @s[($i+3)%4]; $tp4 = @s[3] if ($i==1);
+  my $tp8 = $tbl;
+
+	&mov	($acc,$s[$i]);
+	&and	($acc,0x80808080);
+	&mov	($tmp,$acc);
+	&shr	($tmp,7);
+	&lea	($tp2,&DWP(0,$s[$i],$s[$i]));
+	&sub	($acc,$tmp);
+	&and	($tp2,0xfefefefe);
+	&and	($acc,0x1b1b1b1b);
+	&xor	($acc,$tp2);
+	&mov	($tp2,$acc);
+
+	&and	($acc,0x80808080);
+	&mov	($tmp,$acc);
+	&shr	($tmp,7);
+	&lea	($tp4,&DWP(0,$tp2,$tp2));
+	&sub	($acc,$tmp);
+	&and	($tp4,0xfefefefe);
+	&and	($acc,0x1b1b1b1b);
+	 &xor	($tp2,$s[$i]);	# tp2^tp1
+	&xor	($acc,$tp4);
+	&mov	($tp4,$acc);
+
+	&and	($acc,0x80808080);
+	&mov	($tmp,$acc);
+	&shr	($tmp,7);
+	&lea	($tp8,&DWP(0,$tp4,$tp4));
+	&sub	($acc,$tmp);
+	&and	($tp8,0xfefefefe);
+	&and	($acc,0x1b1b1b1b);
+	 &xor	($tp4,$s[$i]);	# tp4^tp1
+	 &rotl	($s[$i],8);	# = ROTATE(tp1,8)
+	&xor	($tp8,$acc);
+
+	&xor	($s[$i],$tp2);
+	&xor	($tp2,$tp8);
+	&rotl	($tp2,24);
+	&xor	($s[$i],$tp4);
+	&xor	($tp4,$tp8);
+	&rotl	($tp4,16);
+	&xor	($s[$i],$tp8);	# ^= tp8^(tp4^tp1)^(tp2^tp1)
+	&rotl	($tp8,8);
+	&xor	($s[$i],$tp2);	# ^= ROTATE(tp8^tp2^tp1,24)
+	&xor	($s[$i],$tp4);	# ^= ROTATE(tp8^tp4^tp1,16)
+	 &mov	($s[0],$__s0)			if($i==2); #prefetch $s0
+	 &mov	($s[1],$__s1)			if($i==3); #prefetch $s1
+	 &mov	($s[2],$__s2)			if($i==1);
+	&xor	($s[$i],$tp8);	# ^= ROTATE(tp8,8)
+
+	&mov	($s[3],$__s3)			if($i==1);
+	&mov	(&DWP(4+4*$i,"esp"),$s[$i])	if($i>=2);
+}
+
+&function_begin_B("_x86_AES_decrypt_compact");
+	# note that caller is expected to allocate stack frame for me!
+	&mov	($__key,$key);			# save key
+
+	&xor	($s0,&DWP(0,$key));		# xor with key
+	&xor	($s1,&DWP(4,$key));
+	&xor	($s2,&DWP(8,$key));
+	&xor	($s3,&DWP(12,$key));
+
+	&mov	($acc,&DWP(240,$key));		# load key->rounds
+
+	&lea	($acc,&DWP(-2,$acc,$acc));
+	&lea	($acc,&DWP(0,$key,$acc,8));
+	&mov	($__end,$acc);			# end of key schedule
+
+	# prefetch Td4
+	&mov	($key,&DWP(0-128,$tbl));
+	&mov	($acc,&DWP(32-128,$tbl));
+	&mov	($key,&DWP(64-128,$tbl));
+	&mov	($acc,&DWP(96-128,$tbl));
+	&mov	($key,&DWP(128-128,$tbl));
+	&mov	($acc,&DWP(160-128,$tbl));
+	&mov	($key,&DWP(192-128,$tbl));
+	&mov	($acc,&DWP(224-128,$tbl));
+
+	&set_label("loop",16);
+
+		&deccompact(0,$tbl,$s0,$s3,$s2,$s1,1);
+		&deccompact(1,$tbl,$s1,$s0,$s3,$s2,1);
+		&deccompact(2,$tbl,$s2,$s1,$s0,$s3,1);
+		&deccompact(3,$tbl,$s3,$s2,$s1,$s0,1);
+		&dectransform(2);
+		&dectransform(3);
+		&dectransform(0);
+		&dectransform(1);
+		&mov 	($key,$__key);
+		&mov	($tbl,$__tbl);
+		&add	($key,16);		# advance rd_key
+		&xor	($s0,&DWP(0,$key));
+		&xor	($s1,&DWP(4,$key));
+		&xor	($s2,&DWP(8,$key));
+		&xor	($s3,&DWP(12,$key));
+
+	&cmp	($key,$__end);
+	&mov	($__key,$key);
+	&jb	(&label("loop"));
+
+	&deccompact(0,$tbl,$s0,$s3,$s2,$s1);
+	&deccompact(1,$tbl,$s1,$s0,$s3,$s2);
+	&deccompact(2,$tbl,$s2,$s1,$s0,$s3);
+	&deccompact(3,$tbl,$s3,$s2,$s1,$s0);
+
+	&xor	($s0,&DWP(16,$key));
+	&xor	($s1,&DWP(20,$key));
+	&xor	($s2,&DWP(24,$key));
+	&xor	($s3,&DWP(28,$key));
+
+	&ret	();
+&function_end_B("_x86_AES_decrypt_compact");
+
+######################################################################
+# "Compact" SSE block function.
+######################################################################
+
+sub sse_deccompact()
+{
+	&pshufw	("mm1","mm0",0x0c);		#  7, 6, 1, 0
+	&movd	("eax","mm1");			#  7, 6, 1, 0
+
+	&pshufw	("mm5","mm4",0x09);		# 13,12,11,10
+	&movz	($acc,&LB("eax"));		#  0
+	&movz	("ecx",&BP(-128,$tbl,$acc,1));	#  0
+	&movd	("ebx","mm5");			# 13,12,11,10
+	&movz	("edx",&HB("eax"));		#  1
+	&movz	("edx",&BP(-128,$tbl,"edx",1));	#  1
+	&shl	("edx",8);			#  1
+
+	&pshufw	("mm2","mm0",0x06);		#  3, 2, 5, 4
+	&movz	($acc,&LB("ebx"));		# 10
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 10
+	&shl	($acc,16);			# 10
+	&or	("ecx",$acc);			# 10
+	&shr	("eax",16);			#  7, 6
+	&movz	($acc,&HB("ebx"));		# 11
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 11
+	&shl	($acc,24);			# 11
+	&or	("edx",$acc);			# 11
+	&shr	("ebx",16);			# 13,12
+
+	&pshufw	("mm6","mm4",0x03);		# 9, 8,15,14
+	&movz	($acc,&HB("eax"));		#  7
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  7
+	&shl	($acc,24);			#  7
+	&or	("ecx",$acc);			#  7
+	&movz	($acc,&HB("ebx"));		# 13
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 13
+	&shl	($acc,8);			# 13
+	&or	("ecx",$acc);			# 13
+	&movd	("mm0","ecx");			# t[0] collected
+
+	&movz	($acc,&LB("eax"));		#  6
+	&movd	("eax","mm2");			#  3, 2, 5, 4
+	&movz	("ecx",&BP(-128,$tbl,$acc,1));	#  6
+	&shl	("ecx",16);			#  6
+	&movz	($acc,&LB("ebx"));		# 12
+	&movd	("ebx","mm6");			#  9, 8,15,14
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 12
+	&or	("ecx",$acc);			# 12
+
+	&movz	($acc,&LB("eax"));		#  4
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  4
+	&or	("edx",$acc);			#  4
+	&movz	($acc,&LB("ebx"));		# 14
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 14
+	&shl	($acc,16);			# 14
+	&or	("edx",$acc);			# 14
+	&movd	("mm1","edx");			# t[1] collected
+
+	&movz	($acc,&HB("eax"));		#  5
+	&movz	("edx",&BP(-128,$tbl,$acc,1));	#  5
+	&shl	("edx",8);			#  5
+	&movz	($acc,&HB("ebx"));		# 15
+	&shr	("eax",16);			#  3, 2
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	# 15
+	&shl	($acc,24);			# 15
+	&or	("edx",$acc);			# 15
+	&shr	("ebx",16);			#  9, 8
+
+	&punpckldq	("mm0","mm1");		# t[0,1] collected
+
+	&movz	($acc,&HB("ebx"));		#  9
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  9
+	&shl	($acc,8);			#  9
+	&or	("ecx",$acc);			#  9
+	&and	("ebx",0xff);			#  8
+	&movz	("ebx",&BP(-128,$tbl,"ebx",1));	#  8
+	&or	("edx","ebx");			#  8
+	&movz	($acc,&LB("eax"));		#  2
+	&movz	($acc,&BP(-128,$tbl,$acc,1));	#  2
+	&shl	($acc,16);			#  2
+	&or	("edx",$acc);			#  2
+	&movd	("mm4","edx");			# t[2] collected
+	&movz	("eax",&HB("eax"));		#  3
+	&movz	("eax",&BP(-128,$tbl,"eax",1));	#  3
+	&shl	("eax",24);			#  3
+	&or	("ecx","eax");			#  3
+	&movd	("mm5","ecx");			# t[3] collected
+
+	&punpckldq	("mm4","mm5");		# t[2,3] collected
+}
+
+					if (!$x86only) {
+&function_begin_B("_sse_AES_decrypt_compact");
+	&pxor	("mm0",&QWP(0,$key));	#  7, 6, 5, 4, 3, 2, 1, 0
+	&pxor	("mm4",&QWP(8,$key));	# 15,14,13,12,11,10, 9, 8
+
+	# note that caller is expected to allocate stack frame for me!
+	&mov	($acc,&DWP(240,$key));		# load key->rounds
+	&lea	($acc,&DWP(-2,$acc,$acc));
+	&lea	($acc,&DWP(0,$key,$acc,8));
+	&mov	($__end,$acc);			# end of key schedule
+
+	&mov	($s0,0x1b1b1b1b);		# magic constant
+	&mov	(&DWP(8,"esp"),$s0);
+	&mov	(&DWP(12,"esp"),$s0);
+
+	# prefetch Td4
+	&mov	($s0,&DWP(0-128,$tbl));
+	&mov	($s1,&DWP(32-128,$tbl));
+	&mov	($s2,&DWP(64-128,$tbl));
+	&mov	($s3,&DWP(96-128,$tbl));
+	&mov	($s0,&DWP(128-128,$tbl));
+	&mov	($s1,&DWP(160-128,$tbl));
+	&mov	($s2,&DWP(192-128,$tbl));
+	&mov	($s3,&DWP(224-128,$tbl));
+
+	&set_label("loop",16);
+		&sse_deccompact();
+		&add	($key,16);
+		&cmp	($key,$__end);
+		&ja	(&label("out"));
+
+		# ROTATE(x^y,N) == ROTATE(x,N)^ROTATE(y,N)
+		&movq	("mm3","mm0");		&movq	("mm7","mm4");
+		&movq	("mm2","mm0",1);	&movq	("mm6","mm4",1);
+		&movq	("mm1","mm0");		&movq	("mm5","mm4");
+		&pshufw	("mm0","mm0",0xb1);	&pshufw	("mm4","mm4",0xb1);# = ROTATE(tp0,16)
+		&pslld	("mm2",8);		&pslld	("mm6",8);
+		&psrld	("mm3",8);		&psrld	("mm7",8);
+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= tp0<<8
+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp0>>8
+		&pslld	("mm2",16);		&pslld	("mm6",16);
+		&psrld	("mm3",16);		&psrld	("mm7",16);
+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= tp0<<24
+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp0>>24
+
+		&movq	("mm3",&QWP(8,"esp"));
+		&pxor	("mm2","mm2");		&pxor	("mm6","mm6");
+		&pcmpgtb("mm2","mm1");		&pcmpgtb("mm6","mm5");
+		&pand	("mm2","mm3");		&pand	("mm6","mm3");
+		&paddb	("mm1","mm1");		&paddb	("mm5","mm5");
+		&pxor	("mm1","mm2");		&pxor	("mm5","mm6");	# tp2
+		&movq	("mm3","mm1");		&movq	("mm7","mm5");
+		&movq	("mm2","mm1");		&movq	("mm6","mm5");
+		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp2
+		&pslld	("mm3",24);		&pslld	("mm7",24);
+		&psrld	("mm2",8);		&psrld	("mm6",8);
+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp2<<24
+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= tp2>>8
+
+		&movq	("mm2",&QWP(8,"esp"));
+		&pxor	("mm3","mm3");		&pxor	("mm7","mm7");
+		&pcmpgtb("mm3","mm1");		&pcmpgtb("mm7","mm5");
+		&pand	("mm3","mm2");		&pand	("mm7","mm2");
+		&paddb	("mm1","mm1");		&paddb	("mm5","mm5");
+		&pxor	("mm1","mm3");		&pxor	("mm5","mm7");	# tp4
+		&pshufw	("mm3","mm1",0xb1);	&pshufw	("mm7","mm5",0xb1);
+		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp4
+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= ROTATE(tp4,16)	
+
+		&pxor	("mm3","mm3");		&pxor	("mm7","mm7");
+		&pcmpgtb("mm3","mm1");		&pcmpgtb("mm7","mm5");
+		&pand	("mm3","mm2");		&pand	("mm7","mm2");
+		&paddb	("mm1","mm1");		&paddb	("mm5","mm5");
+		&pxor	("mm1","mm3");		&pxor	("mm5","mm7");	# tp8
+		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp8
+		&movq	("mm3","mm1");		&movq	("mm7","mm5");
+		&pshufw	("mm2","mm1",0xb1);	&pshufw	("mm6","mm5",0xb1);
+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= ROTATE(tp8,16)
+		&pslld	("mm1",8);		&pslld	("mm5",8);
+		&psrld	("mm3",8);		&psrld	("mm7",8);
+		&movq	("mm2",&QWP(0,$key));	&movq	("mm6",&QWP(8,$key));
+		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp8<<8
+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp8>>8
+		&mov	($s0,&DWP(0-128,$tbl));
+		&pslld	("mm1",16);		&pslld	("mm5",16);
+		&mov	($s1,&DWP(64-128,$tbl));
+		&psrld	("mm3",16);		&psrld	("mm7",16);
+		&mov	($s2,&DWP(128-128,$tbl));
+		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp8<<24
+		&mov	($s3,&DWP(192-128,$tbl));
+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp8>>24
+
+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");
+	&jmp	(&label("loop"));
+
+	&set_label("out",16);
+	&pxor	("mm0",&QWP(0,$key));
+	&pxor	("mm4",&QWP(8,$key));
+
+	&ret	();
+&function_end_B("_sse_AES_decrypt_compact");
+					}
+
+######################################################################
+# Vanilla block function.
+######################################################################
 
 sub decstep()
 { my ($i,$td,@s) = @_;
@@ -480,7 +1589,7 @@
 	# optimal... or rather that all attempts to reorder didn't
 	# result in better performance [which by the way is not a
 	# bit lower than ecryption].
-	if($i==3)   {	&mov	($key,&DWP(12,"esp"));		}
+	if($i==3)   {	&mov	($key,$__key);			}
 	else        {	&mov	($out,$s[0]);			}
 			&and	($out,0xFF);
 			&mov	($out,&DWP(0,$td,$out,8));
@@ -495,12 +1604,12 @@
 			&and	($tmp,0xFF);
 			&xor	($out,&DWP(2,$td,$tmp,8));
 
-	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],&DWP(8,"esp"));	}
+	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}
 	else        {	&mov	($tmp,$s[3]);			}
 			&shr	($tmp,24);
 			&xor	($out,&DWP(1,$td,$tmp,8));
 	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
-	if ($i==3)  {	&mov	($s[3],&DWP(4,"esp"));		}
+	if ($i==3)  {	&mov	($s[3],$__s0);			}
 			&comment();
 }
 
@@ -509,14 +1618,24 @@
   my $tmp = $key;
   my $out = $i==3?$s[0]:$acc;
 
-	if($i==3)   {	&mov	($key,&DWP(12,"esp"));		}
+	if($i==0)   {	&lea	($td,&DWP(2048+128,$td));
+			&mov	($tmp,&DWP(0-128,$td));
+			&mov	($acc,&DWP(32-128,$td));
+			&mov	($tmp,&DWP(64-128,$td));
+			&mov	($acc,&DWP(96-128,$td));
+			&mov	($tmp,&DWP(128-128,$td));
+			&mov	($acc,&DWP(160-128,$td));
+			&mov	($tmp,&DWP(192-128,$td));
+			&mov	($acc,&DWP(224-128,$td));
+			&lea	($td,&DWP(-128,$td));		}
+	if($i==3)   {	&mov	($key,$__key);			}
 	else        {	&mov	($out,$s[0]);			}
 			&and	($out,0xFF);
-			&movz	($out,&BP(2048,$td,$out,1));
+			&movz	($out,&BP(0,$td,$out,1));
 
 	if ($i==3)  {	$tmp=$s[1];				}
 			&movz	($tmp,&HB($s[1]));
-			&movz	($tmp,&BP(2048,$td,$tmp,1));
+			&movz	($tmp,&BP(0,$td,$tmp,1));
 			&shl	($tmp,8);
 			&xor	($out,$tmp);
 
@@ -524,24 +1643,24 @@
 	else        {	mov	($tmp,$s[2]);			}
 			&shr	($tmp,16);
 			&and	($tmp,0xFF);
-			&movz	($tmp,&BP(2048,$td,$tmp,1));
+			&movz	($tmp,&BP(0,$td,$tmp,1));
 			&shl	($tmp,16);
 			&xor	($out,$tmp);
 
-	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],&DWP(8,"esp"));	}
+	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}
 	else        {	&mov	($tmp,$s[3]);			}
 			&shr	($tmp,24);
-			&movz	($tmp,&BP(2048,$td,$tmp,1));
+			&movz	($tmp,&BP(0,$td,$tmp,1));
 			&shl	($tmp,24);
 			&xor	($out,$tmp);
 	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
-	if ($i==3)  {	&mov	($s[3],&DWP(4,"esp"));		}
+	if ($i==3)  {	&mov	($s[3],$__s0);
+			&lea	($td,&DWP(-2048,$td));		}
 }
 
-&public_label("AES_Td");
 &function_begin_B("_x86_AES_decrypt");
 	# note that caller is expected to allocate stack frame for me!
-	&mov	(&DWP(12,"esp"),$key);		# save key
+	&mov	($__key,$key);			# save key
 
 	&xor	($s0,&DWP(0,$key));		# xor with key
 	&xor	($s1,&DWP(4,$key));
@@ -553,20 +1672,19 @@
 	if ($small_footprint) {
 	    &lea	($acc,&DWP(-2,$acc,$acc));
 	    &lea	($acc,&DWP(0,$key,$acc,8));
-	    &mov	(&DWP(16,"esp"),$acc);	# end of key schedule
-	    &align	(4);
-	    &set_label("loop");
-		&decstep(0,"ebp",$s0,$s3,$s2,$s1);
-		&decstep(1,"ebp",$s1,$s0,$s3,$s2);
-		&decstep(2,"ebp",$s2,$s1,$s0,$s3);
-		&decstep(3,"ebp",$s3,$s2,$s1,$s0);
+	    &mov	($__end,$acc);		# end of key schedule
+	    &set_label("loop",16);
+		&decstep(0,$tbl,$s0,$s3,$s2,$s1);
+		&decstep(1,$tbl,$s1,$s0,$s3,$s2);
+		&decstep(2,$tbl,$s2,$s1,$s0,$s3);
+		&decstep(3,$tbl,$s3,$s2,$s1,$s0);
 		&add	($key,16);		# advance rd_key
 		&xor	($s0,&DWP(0,$key));
 		&xor	($s1,&DWP(4,$key));
 		&xor	($s2,&DWP(8,$key));
 		&xor	($s3,&DWP(12,$key));
-	    &cmp	($key,&DWP(16,"esp"));
-	    &mov	(&DWP(12,"esp"),$key);
+	    &cmp	($key,$__end);
+	    &mov	($__key,$key);
 	    &jb		(&label("loop"));
 	}
 	else {
@@ -575,38 +1693,38 @@
 	    &cmp	($acc,12);
 	    &jle	(&label("12rounds"));
 
-	&set_label("14rounds");
+	&set_label("14rounds",4);
 	    for ($i=1;$i<3;$i++) {
-		&decstep(0,"ebp",$s0,$s3,$s2,$s1);
-		&decstep(1,"ebp",$s1,$s0,$s3,$s2);
-		&decstep(2,"ebp",$s2,$s1,$s0,$s3);
-		&decstep(3,"ebp",$s3,$s2,$s1,$s0);
+		&decstep(0,$tbl,$s0,$s3,$s2,$s1);
+		&decstep(1,$tbl,$s1,$s0,$s3,$s2);
+		&decstep(2,$tbl,$s2,$s1,$s0,$s3);
+		&decstep(3,$tbl,$s3,$s2,$s1,$s0);
 		&xor	($s0,&DWP(16*$i+0,$key));
 		&xor	($s1,&DWP(16*$i+4,$key));
 		&xor	($s2,&DWP(16*$i+8,$key));
 		&xor	($s3,&DWP(16*$i+12,$key));
 	    }
 	    &add	($key,32);
-	    &mov	(&DWP(12,"esp"),$key);	# advance rd_key
-	&set_label("12rounds");
+	    &mov	($__key,$key);		# advance rd_key
+	&set_label("12rounds",4);
 	    for ($i=1;$i<3;$i++) {
-		&decstep(0,"ebp",$s0,$s3,$s2,$s1);
-		&decstep(1,"ebp",$s1,$s0,$s3,$s2);
-		&decstep(2,"ebp",$s2,$s1,$s0,$s3);
-		&decstep(3,"ebp",$s3,$s2,$s1,$s0);
+		&decstep(0,$tbl,$s0,$s3,$s2,$s1);
+		&decstep(1,$tbl,$s1,$s0,$s3,$s2);
+		&decstep(2,$tbl,$s2,$s1,$s0,$s3);
+		&decstep(3,$tbl,$s3,$s2,$s1,$s0);
 		&xor	($s0,&DWP(16*$i+0,$key));
 		&xor	($s1,&DWP(16*$i+4,$key));
 		&xor	($s2,&DWP(16*$i+8,$key));
 		&xor	($s3,&DWP(16*$i+12,$key));
 	    }
 	    &add	($key,32);
-	    &mov	(&DWP(12,"esp"),$key);	# advance rd_key
-	&set_label("10rounds");
+	    &mov	($__key,$key);		# advance rd_key
+	&set_label("10rounds",4);
 	    for ($i=1;$i<10;$i++) {
-		&decstep(0,"ebp",$s0,$s3,$s2,$s1);
-		&decstep(1,"ebp",$s1,$s0,$s3,$s2);
-		&decstep(2,"ebp",$s2,$s1,$s0,$s3);
-		&decstep(3,"ebp",$s3,$s2,$s1,$s0);
+		&decstep(0,$tbl,$s0,$s3,$s2,$s1);
+		&decstep(1,$tbl,$s1,$s0,$s3,$s2);
+		&decstep(2,$tbl,$s2,$s1,$s0,$s3);
+		&decstep(3,$tbl,$s3,$s2,$s1,$s0);
 		&xor	($s0,&DWP(16*$i+0,$key));
 		&xor	($s1,&DWP(16*$i+4,$key));
 		&xor	($s2,&DWP(16*$i+8,$key));
@@ -614,10 +1732,10 @@
 	    }
 	}
 
-	&declast(0,"ebp",$s0,$s3,$s2,$s1);
-	&declast(1,"ebp",$s1,$s0,$s3,$s2);
-	&declast(2,"ebp",$s2,$s1,$s0,$s3);
-	&declast(3,"ebp",$s3,$s2,$s1,$s0);
+	&declast(0,$tbl,$s0,$s3,$s2,$s1);
+	&declast(1,$tbl,$s1,$s0,$s3,$s2);
+	&declast(2,$tbl,$s2,$s1,$s0,$s3);
+	&declast(3,$tbl,$s3,$s2,$s1,$s0);
 
 	&add	($key,$small_footprint?16:160);
 	&xor	($s0,&DWP(0,$key));
@@ -692,7 +1810,107 @@
 	&_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff);
 	&_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664);
 	&_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0);
-#Td4:
+
+#Td4:	# four copies of Td4 to choose from to avoid L1 aliasing
+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
+
+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
+
+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
+
 	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
 	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
 	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
@@ -728,43 +1946,57 @@
 &function_end_B("_x86_AES_decrypt");
 
 # void AES_decrypt (const void *inp,void *out,const AES_KEY *key);
-&public_label("AES_Td");
 &function_begin("AES_decrypt");
 	&mov	($acc,&wparam(0));		# load inp
 	&mov	($key,&wparam(2));		# load key
 
 	&mov	($s0,"esp");
-	&sub	("esp",24);
-	&and	("esp",-64);
-	&add	("esp",4);
-	&mov	(&DWP(16,"esp"),$s0);
+	&sub	("esp",36);
+	&and	("esp",-64);			# align to cache-line
+
+	# place stack frame just "above" the key schedule
+	&lea	($s1,&DWP(-64-63,$key));
+	&sub	($s1,"esp");
+	&neg	($s1);
+	&and	($s1,0x3C0);	# modulo 1024, but aligned to cache-line
+	&sub	("esp",$s1);
+	&add	("esp",4);	# 4 is reserved for caller's return address
+	&mov	($_esp,$s0);	# save stack pointer
 
 	&call   (&label("pic_point"));          # make it PIC!
 	&set_label("pic_point");
-	&blindpop("ebp");
-	&lea    ("ebp",&DWP(&label("AES_Td")."-".&label("pic_point"),"ebp"));
+	&blindpop($tbl);
+	&picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if(!$x86only);
+	&lea    ($tbl,&DWP(&label("AES_Td")."-".&label("pic_point"),$tbl));
 
-	# prefetch Td4
-	&lea	("ebp",&DWP(2048+128,"ebp"));
-	&mov	($s0,&DWP(0-128,"ebp"));
-	&mov	($s1,&DWP(32-128,"ebp"));
-	&mov	($s2,&DWP(64-128,"ebp"));
-	&mov	($s3,&DWP(96-128,"ebp"));
-	&mov	($s0,&DWP(128-128,"ebp"));
-	&mov	($s1,&DWP(160-128,"ebp"));
-	&mov	($s2,&DWP(192-128,"ebp"));
-	&mov	($s3,&DWP(224-128,"ebp"));
-	&lea	("ebp",&DWP(-2048-128,"ebp"));
+	# pick Td4 copy which can't "overlap" with stack frame or key schedule
+	&lea	($s1,&DWP(768-4,"esp"));
+	&sub	($s1,$tbl);
+	&and	($s1,0x300);
+	&lea	($tbl,&DWP(2048+128,$tbl,$s1));
 
+					if (!$x86only) {
+	&bt	(&DWP(0,$s0),25);	# check for SSE bit
+	&jnc	(&label("x86"));
+
+	&movq	("mm0",&QWP(0,$acc));
+	&movq	("mm4",&QWP(8,$acc));
+	&call	("_sse_AES_decrypt_compact");
+	&mov	("esp",$_esp);			# restore stack pointer
+	&mov	($acc,&wparam(1));		# load out
+	&movq	(&QWP(0,$acc),"mm0");		# write output data
+	&movq	(&QWP(8,$acc),"mm4");
+	&emms	();
+	&function_end_A();
+					}
+	&set_label("x86",16);
+	&mov	($_tbl,$tbl);
 	&mov	($s0,&DWP(0,$acc));		# load input data
 	&mov	($s1,&DWP(4,$acc));
 	&mov	($s2,&DWP(8,$acc));
 	&mov	($s3,&DWP(12,$acc));
-
-	&call	("_x86_AES_decrypt");
-
-	&mov	("esp",&DWP(16,"esp"));
-
+	&call	("_x86_AES_decrypt_compact");
+	&mov	("esp",$_esp);			# restore stack pointer
 	&mov	($acc,&wparam(1));		# load out
 	&mov	(&DWP(0,$acc),$s0);		# write output data
 	&mov	(&DWP(4,$acc),$s1);
@@ -777,126 +2009,136 @@
 #			unsigned char *ivp,const int enc);
 {
 # stack frame layout
-# -4(%esp)	0(%esp)		return address
-# 0(%esp)	4(%esp)		tmp1
-# 4(%esp)	8(%esp)		tmp2
-# 8(%esp)	12(%esp)	key
-# 12(%esp)	16(%esp)	end of key schedule
-my $_esp=&DWP(16,"esp");	#saved %esp
-my $_inp=&DWP(20,"esp");	#copy of wparam(0)
-my $_out=&DWP(24,"esp");	#copy of wparam(1)
-my $_len=&DWP(28,"esp");	#copy of wparam(2)
-my $_key=&DWP(32,"esp");	#copy of wparam(3)
-my $_ivp=&DWP(36,"esp");	#copy of wparam(4)
-my $_tmp=&DWP(40,"esp");	#volatile variable
-my $ivec=&DWP(44,"esp");	#ivec[16]
-my $aes_key=&DWP(60,"esp");	#copy of aes_key
-my $mark=&DWP(60+240,"esp");	#copy of aes_key->rounds
+#             -4(%esp)		# return address	 0(%esp)
+#              0(%esp)		# s0 backing store	 4(%esp)	
+#              4(%esp)		# s1 backing store	 8(%esp)
+#              8(%esp)		# s2 backing store	12(%esp)
+#             12(%esp)		# s3 backing store	16(%esp)
+#             16(%esp)		# key backup		20(%esp)
+#             20(%esp)		# end of key schedule	24(%esp)
+#             24(%esp)		# %ebp backup		28(%esp)
+#             28(%esp)		# %esp backup
+my $_inp=&DWP(32,"esp");	# copy of wparam(0)
+my $_out=&DWP(36,"esp");	# copy of wparam(1)
+my $_len=&DWP(40,"esp");	# copy of wparam(2)
+my $_key=&DWP(44,"esp");	# copy of wparam(3)
+my $_ivp=&DWP(48,"esp");	# copy of wparam(4)
+my $_tmp=&DWP(52,"esp");	# volatile variable
+#
+my $ivec=&DWP(60,"esp");	# ivec[16]
+my $aes_key=&DWP(76,"esp");	# copy of aes_key
+my $mark=&DWP(76+240,"esp");	# copy of aes_key->rounds
 
-&public_label("AES_Te");
-&public_label("AES_Td");
 &function_begin("AES_cbc_encrypt");
 	&mov	($s2 eq "ecx"? $s2 : "",&wparam(2));	# load len
 	&cmp	($s2,0);
-	&je	(&label("enc_out"));
+	&je	(&label("drop_out"));
 
 	&call   (&label("pic_point"));		# make it PIC!
 	&set_label("pic_point");
-	&blindpop("ebp");
+	&blindpop($tbl);
+	&picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if(!$x86only);
 
+	&cmp	(&wparam(5),0);
+	&lea    ($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl));
+	&jne	(&label("picked_te"));
+	&lea	($tbl,&DWP(&label("AES_Td")."-".&label("AES_Te"),$tbl));
+	&set_label("picked_te");
+
+	# one can argue if this is required
 	&pushf	();
 	&cld	();
 
-	&cmp	(&wparam(5),0);
-	&je	(&label("DECRYPT"));
+	&cmp	($s2,$speed_limit);
+	&jb	(&label("slow_way"));
+	&test	($s2,15);
+	&jnz	(&label("slow_way"));
+					if (!$x86only) {
+	&bt	(&DWP(0,$s0),28);	# check for hyper-threading bit
+	&jc	(&label("slow_way"));
+					}
+	# pre-allocate aligned stack frame...
+	&lea	($acc,&DWP(-80-244,"esp"));
+	&and	($acc,-64);
 
-	&lea    ("ebp",&DWP(&label("AES_Te")."-".&label("pic_point"),"ebp"));
-
-	# allocate aligned stack frame...
-	&lea	($key,&DWP(-64-244,"esp"));
-	&and	($key,-64);
-
-	# ... and make sure it doesn't alias with AES_Te modulo 4096
-	&mov	($s0,"ebp");
-	&lea	($s1,&DWP(2048,"ebp"));
-	&mov	($s3,$key);
+	# ... and make sure it doesn't alias with $tbl modulo 4096
+	&mov	($s0,$tbl);
+	&lea	($s1,&DWP(2048+256,$tbl));
+	&mov	($s3,$acc);
 	&and	($s0,0xfff);		# s = %ebp&0xfff
-	&and	($s1,0xfff);		# e = (%ebp+2048)&0xfff
+	&and	($s1,0xfff);		# e = (%ebp+2048+256)&0xfff
 	&and	($s3,0xfff);		# p = %esp&0xfff
 
 	&cmp	($s3,$s1);		# if (p>=e) %esp =- (p-e);
-	&jb	(&label("te_break_out"));
+	&jb	(&label("tbl_break_out"));
 	&sub	($s3,$s1);
-	&sub	($key,$s3);
-	&jmp	(&label("te_ok"));
-	&set_label("te_break_out");	# else %esp -= (p-s)&0xfff + framesz;
+	&sub	($acc,$s3);
+	&jmp	(&label("tbl_ok"));
+	&set_label("tbl_break_out",4);	# else %esp -= (p-s)&0xfff + framesz;
 	&sub	($s3,$s0);
 	&and	($s3,0xfff);
-	&add	($s3,64+256);
-	&sub	($key,$s3);
-	&align	(4);
-	&set_label("te_ok");
+	&add	($s3,384);
+	&sub	($acc,$s3);
+	&set_label("tbl_ok",4);
 
-	&mov	($s0,&wparam(0));	# load inp
-	&mov	($s1,&wparam(1));	# load out
-	&mov	($s3,&wparam(3));	# load key
-	&mov	($acc,&wparam(4));	# load ivp
-
-	&exch	("esp",$key);
+	&lea	($s3,&wparam(0));	# obtain pointer to parameter block
+	&exch	("esp",$acc);		# allocate stack frame
 	&add	("esp",4);		# reserve for return address!
-	&mov	($_esp,$key);		# save %esp
+	&mov	($_tbl,$tbl);		# save %ebp
+	&mov	($_esp,$acc);		# save %esp
+
+	&mov	($s0,&DWP(0,$s3));	# load inp
+	&mov	($s1,&DWP(4,$s3));	# load out
+	#&mov	($s2,&DWP(8,$s3));	# load len
+	&mov	($key,&DWP(12,$s3));	# load key
+	&mov	($acc,&DWP(16,$s3));	# load ivp
+	&mov	($s3,&DWP(20,$s3));	# load enc flag
 
 	&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	($_key,$key);		# save copy of key
 	&mov	($_ivp,$acc);		# save copy of ivp
 
 	&mov	($mark,0);		# copy of aes_key->rounds = 0;
-	if ($compromise) {
-		&cmp	($s2,$compromise);
-		&jb	(&label("skip_ecopy"));
-	}
 	# do we copy key schedule to stack?
-	&mov	($s1 eq "ebx" ? $s1 : "",$s3);
+	&mov	($s1 eq "ebx" ? $s1 : "",$key);
 	&mov	($s2 eq "ecx" ? $s2 : "",244/4);
-	&sub	($s1,"ebp");
-	&mov	("esi",$s3);
+	&sub	($s1,$tbl);
+	&mov	("esi",$key);
 	&and	($s1,0xfff);
 	&lea	("edi",$aes_key);
-	&cmp	($s1,2048);
-	&jb	(&label("do_ecopy"));
+	&cmp	($s1,2048+256);
+	&jb	(&label("do_copy"));
 	&cmp	($s1,4096-244);
-	&jb	(&label("skip_ecopy"));
-	&align	(4);
-	&set_label("do_ecopy");
+	&jb	(&label("skip_copy"));
+	&set_label("do_copy",4);
 		&mov	($_key,"edi");
 		&data_word(0xA5F3F689);	# rep movsd
-	&set_label("skip_ecopy");
+	&set_label("skip_copy");
 
-	&mov	($acc,$s0);
 	&mov	($key,16);
-	&align	(4);
-	&set_label("prefetch_te");
-		&mov	($s0,&DWP(0,"ebp"));
-		&mov	($s1,&DWP(32,"ebp"));
-		&mov	($s2,&DWP(64,"ebp"));
-		&mov	($s3,&DWP(96,"ebp"));
-		&lea	("ebp",&DWP(128,"ebp"));
-		&dec	($key);
-	&jnz	(&label("prefetch_te"));
-	&sub	("ebp",2048);
+	&set_label("prefetch_tbl",4);
+		&mov	($s0,&DWP(0,$tbl));
+		&mov	($s1,&DWP(32,$tbl));
+		&mov	($s2,&DWP(64,$tbl));
+		&mov	($acc,&DWP(96,$tbl));
+		&lea	($tbl,&DWP(128,$tbl));
+		&sub	($key,1);
+	&jnz	(&label("prefetch_tbl"));
+	&sub	($tbl,2048);
 
-	&mov	($s2,$_len);
+	&mov	($acc,$_inp);
 	&mov	($key,$_ivp);
-	&test	($s2,0xFFFFFFF0);
-	&jz	(&label("enc_tail"));		# short input...
 
+	&cmp	($s3,0);
+	&je	(&label("fast_decrypt"));
+
+#----------------------------- ENCRYPT -----------------------------#
 	&mov	($s0,&DWP(0,$key));		# load iv
 	&mov	($s1,&DWP(4,$key));
 
-	&align	(4);
-	&set_label("enc_loop");
+	&set_label("fast_enc_loop",16);
 		&mov	($s2,&DWP(8,$key));
 		&mov	($s3,&DWP(12,$key));
 
@@ -916,22 +2158,16 @@
 		&mov	(&DWP(8,$key),$s2);
 		&mov	(&DWP(12,$key),$s3);
 
+		&lea	($acc,&DWP(16,$acc));	# advance inp
 		&mov	($s2,$_len);		# load len
-
-		&lea	($acc,&DWP(16,$acc));
 		&mov	($_inp,$acc);		# save inp
-
-		&lea	($s3,&DWP(16,$key));
+		&lea	($s3,&DWP(16,$key));	# advance out
 		&mov	($_out,$s3);		# save out
-
-		&sub	($s2,16);
-		&test	($s2,0xFFFFFFF0);
+		&sub	($s2,16);		# decrease len
 		&mov	($_len,$s2);		# save len
-	&jnz	(&label("enc_loop"));
-	&test	($s2,15);
-	&jnz	(&label("enc_tail"));
+	&jnz	(&label("fast_enc_loop"));
 	&mov	($acc,$_ivp);		# load ivp
-	&mov	($s2,&DWP(8,$key));	# restore last dwords
+	&mov	($s2,&DWP(8,$key));	# restore last 2 dwords
 	&mov	($s3,&DWP(12,$key));
 	&mov	(&DWP(0,$acc),$s0);	# save ivec
 	&mov	(&DWP(4,$acc),$s1);
@@ -949,125 +2185,20 @@
 	&set_label("skip_ezero")
 	&mov	("esp",$_esp);
 	&popf	();
-    &set_label("enc_out");
+    &set_label("drop_out");
 	&function_end_A();
 	&pushf	();			# kludge, never executed
 
-    &align	(4);
-    &set_label("enc_tail");
-	&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
-	&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	($acc,$_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 -----------------------------#
-&align	(4);
-&set_label("DECRYPT");
-	&lea    ("ebp",&DWP(&label("AES_Td")."-".&label("pic_point"),"ebp"));
-
-	# allocate aligned stack frame...
-	&lea	($key,&DWP(-64-244,"esp"));
-	&and	($key,-64);
-
-	# ... and make sure it doesn't alias with AES_Td modulo 4096
-	&mov	($s0,"ebp");
-	&lea	($s1,&DWP(2048+256,"ebp"));
-	&mov	($s3,$key);
-	&and	($s0,0xfff);		# s = %ebp&0xfff
-	&and	($s1,0xfff);		# e = (%ebp+2048+256)&0xfff
-	&and	($s3,0xfff);		# p = %esp&0xfff
-
-	&cmp	($s3,$s1);		# if (p>=e) %esp =- (p-e);
-	&jb	(&label("td_break_out"));
-	&sub	($s3,$s1);
-	&sub	($key,$s3);
-	&jmp	(&label("td_ok"));
-	&set_label("td_break_out");	# else %esp -= (p-s)&0xfff + framesz;
-	&sub	($s3,$s0);
-	&and	($s3,0xfff);
-	&add	($s3,64+256);
-	&sub	($key,$s3);
-	&align	(4);
-	&set_label("td_ok");
-
-	&mov	($s0,&wparam(0));	# load inp
-	&mov	($s1,&wparam(1));	# load out
-	&mov	($s3,&wparam(3));	# load key
-	&mov	($acc,&wparam(4));	# load ivp
-
-	&exch	("esp",$key);
-	&add	("esp",4);		# reserve for return address!
-	&mov	($_esp,$key);		# 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,$acc);		# save copy of ivp
-
-	&mov	($mark,0);		# copy of aes_key->rounds = 0;
-	if ($compromise) {
-		&cmp	($s2,$compromise);
-		&jb	(&label("skip_dcopy"));
-	}
-	# do we copy key schedule to stack?
-	&mov	($s1 eq "ebx" ? $s1 : "",$s3);
-	&mov	($s2 eq "ecx" ? $s2 : "",244/4);
-	&sub	($s1,"ebp");
-	&mov	("esi",$s3);
-	&and	($s1,0xfff);
-	&lea	("edi",$aes_key);
-	&cmp	($s1,2048+256);
-	&jb	(&label("do_dcopy"));
-	&cmp	($s1,4096-244);
-	&jb	(&label("skip_dcopy"));
-	&align	(4);
-	&set_label("do_dcopy");
-		&mov	($_key,"edi");
-		&data_word(0xA5F3F689);	# rep movsd
-	&set_label("skip_dcopy");
-
-	&mov	($acc,$s0);
-	&mov	($key,18);
-	&align	(4);
-	&set_label("prefetch_td");
-		&mov	($s0,&DWP(0,"ebp"));
-		&mov	($s1,&DWP(32,"ebp"));
-		&mov	($s2,&DWP(64,"ebp"));
-		&mov	($s3,&DWP(96,"ebp"));
-		&lea	("ebp",&DWP(128,"ebp"));
-		&dec	($key);
-	&jnz	(&label("prefetch_td"));
-	&sub	("ebp",2048+256);
+&set_label("fast_decrypt",16);
 
 	&cmp	($acc,$_out);
-	&je	(&label("dec_in_place"));	# in-place processing...
+	&je	(&label("fast_dec_in_place"));	# in-place processing...
 
-	&mov	($key,$_ivp);		# load ivp
 	&mov	($_tmp,$key);
 
 	&align	(4);
-	&set_label("dec_loop");
+	&set_label("fast_dec_loop",16);
 		&mov	($s0,&DWP(0,$acc));	# read input
 		&mov	($s1,&DWP(4,$acc));
 		&mov	($s2,&DWP(8,$acc));
@@ -1083,27 +2214,24 @@
 		&xor	($s2,&DWP(8,$key));
 		&xor	($s3,&DWP(12,$key));
 
-		&sub	($acc,16);
-		&jc	(&label("dec_partial"));
-		&mov	($_len,$acc);		# save len
-		&mov	($acc,$_inp);		# load inp
 		&mov	($key,$_out);		# load out
+		&mov	($acc,$_inp);		# load inp
 
 		&mov	(&DWP(0,$key),$s0);	# write output
 		&mov	(&DWP(4,$key),$s1);
 		&mov	(&DWP(8,$key),$s2);
 		&mov	(&DWP(12,$key),$s3);
 
+		&mov	($s2,$_len);		# load len
 		&mov	($_tmp,$acc);		# save ivp
-		&lea	($acc,&DWP(16,$acc));
+		&lea	($acc,&DWP(16,$acc));	# advance inp
 		&mov	($_inp,$acc);		# save inp
-
-		&lea	($key,&DWP(16,$key));
+		&lea	($key,&DWP(16,$key));	# advance out
 		&mov	($_out,$key);		# save out
-
-	&jnz	(&label("dec_loop"));
+		&sub	($s2,16);		# decrease len
+		&mov	($_len,$s2);		# save len
+	&jnz	(&label("fast_dec_loop"));
 	&mov	($key,$_tmp);		# load temp ivp
-    &set_label("dec_end");
 	&mov	($acc,$_ivp);		# load user ivp
 	&mov	($s0,&DWP(0,$key));	# load iv
 	&mov	($s1,&DWP(4,$key));
@@ -1113,31 +2241,16 @@
 	&mov	(&DWP(4,$acc),$s1);
 	&mov	(&DWP(8,$acc),$s2);
 	&mov	(&DWP(12,$acc),$s3);
-	&jmp	(&label("dec_out"));
+	&jmp	(&label("fast_dec_out"));
 
-    &align	(4);
-    &set_label("dec_partial");
-	&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,$acc));
-	&mov	($acc eq "esi" ? $acc : "",$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"));
-
-    &align	(4);
-    &set_label("dec_in_place");
-	&set_label("dec_in_place_loop");
-		&lea	($key,$ivec);
+    &set_label("fast_dec_in_place",16);
+	&set_label("fast_dec_in_place_loop");
 		&mov	($s0,&DWP(0,$acc));	# read input
 		&mov	($s1,&DWP(4,$acc));
 		&mov	($s2,&DWP(8,$acc));
 		&mov	($s3,&DWP(12,$acc));
 
+		&lea	($key,$ivec);
 		&mov	(&DWP(0,$key),$s0);	# copy to temp
 		&mov	(&DWP(4,$key),$s1);
 		&mov	(&DWP(8,$key),$s2);
@@ -1158,7 +2271,7 @@
 		&mov	(&DWP(8,$acc),$s2);
 		&mov	(&DWP(12,$acc),$s3);
 
-		&lea	($acc,&DWP(16,$acc));
+		&lea	($acc,&DWP(16,$acc));	# advance out
 		&mov	($_out,$acc);		# save out
 
 		&lea	($acc,$ivec);
@@ -1173,40 +2286,340 @@
 		&mov	(&DWP(12,$key),$s3);
 
 		&mov	($acc,$_inp);		# load inp
-
-		&lea	($acc,&DWP(16,$acc));
+		&mov	($s2,$_len);		# load len
+		&lea	($acc,&DWP(16,$acc));	# advance inp
 		&mov	($_inp,$acc);		# save inp
+		&sub	($s2,16);		# decrease len
+		&mov	($_len,$s2);		# save len
+	&jnz	(&label("fast_dec_in_place_loop"));
+
+    &set_label("fast_dec_out",4);
+	&cmp	($mark,0);		# was the key schedule copied?
+	&mov	("edi",$_key);
+	&je	(&label("skip_dzero"));
+	# zero copy of key schedule
+	&mov	("ecx",240/4);
+	&xor	("eax","eax");
+	&align	(4);
+	&data_word(0xABF3F689);	# rep stosd
+	&set_label("skip_dzero")
+	&mov	("esp",$_esp);
+	&popf	();
+	&function_end_A();
+	&pushf	();			# kludge, never executed
+
+#--------------------------- SLOW ROUTINE ---------------------------#
+&set_label("slow_way",16);
+
+	&mov	($s0,&DWP(0,$s0)) if (!$x86only);# load OPENSSL_ia32cap
+	&mov	($key,&wparam(3));	# load key
+
+	# pre-allocate aligned stack frame...
+	&lea	($acc,&DWP(-80,"esp"));
+	&and	($acc,-64);
+
+	# ... and make sure it doesn't alias with $key modulo 1024
+	&lea	($s1,&DWP(-80-63,$key));
+	&sub	($s1,$acc);
+	&neg	($s1);
+	&and	($s1,0x3C0);	# modulo 1024, but aligned to cache-line
+	&sub	($acc,$s1);
+
+	# pick S-box copy which can't overlap with stack frame or $key
+	&lea	($s1,&DWP(768,$acc));
+	&sub	($s1,$tbl);
+	&and	($s1,0x300);
+	&lea	($tbl,&DWP(2048+128,$tbl,$s1));
+
+	&lea	($s3,&wparam(0));	# pointer to parameter block
+
+	&exch	("esp",$acc);
+	&add	("esp",4);		# reserve for return address!
+	&mov	($_tbl,$tbl);		# save %ebp
+	&mov	($_esp,$acc);		# save %esp
+	&mov	($_tmp,$s0);		# save OPENSSL_ia32cap
+
+	&mov	($s0,&DWP(0,$s3));	# load inp
+	&mov	($s1,&DWP(4,$s3));	# load out
+	#&mov	($s2,&DWP(8,$s3));	# load len
+	#&mov	($key,&DWP(12,$s3));	# load key
+	&mov	($acc,&DWP(16,$s3));	# load ivp
+	&mov	($s3,&DWP(20,$s3));	# load enc flag
+
+	&mov	($_inp,$s0);		# save copy of inp
+	&mov	($_out,$s1);		# save copy of out
+	&mov	($_len,$s2);		# save copy of len
+	&mov	($_key,$key);		# save copy of key
+	&mov	($_ivp,$acc);		# save copy of ivp
+
+	&mov	($key,$acc);
+	&mov	($acc,$s0);
+
+	&cmp	($s3,0);
+	&je	(&label("slow_decrypt"));
+
+#--------------------------- SLOW ENCRYPT ---------------------------#
+	&cmp	($s2,16);
+	&mov	($s3,$s1);
+	&jb	(&label("slow_enc_tail"));
+
+					if (!$x86only) {
+	&bt	($_tmp,25);		# check for SSE bit
+	&jnc	(&label("slow_enc_x86"));
+
+	&movq	("mm0",&QWP(0,$key));	# load iv
+	&movq	("mm4",&QWP(8,$key));
+
+	&set_label("slow_enc_loop_sse",16);
+		&pxor	("mm0",&QWP(0,$acc));	# xor input data
+		&pxor	("mm4",&QWP(8,$acc));
+
+		&mov	($key,$_key);
+		&call	("_sse_AES_encrypt_compact");
+
+		&mov	($acc,$_inp);		# load inp
+		&mov	($key,$_out);		# load out
+		&mov	($s2,$_len);		# load len
+
+		&movq	(&QWP(0,$key),"mm0");	# save output data
+		&movq	(&QWP(8,$key),"mm4");
+
+		&lea	($acc,&DWP(16,$acc));	# advance inp
+		&mov	($_inp,$acc);		# save inp
+		&lea	($s3,&DWP(16,$key));	# advance out
+		&mov	($_out,$s3);		# save out
+		&sub	($s2,16);		# decrease len
+		&cmp	($s2,16);
+		&mov	($_len,$s2);		# save len
+	&jae	(&label("slow_enc_loop_sse"));
+	&test	($s2,15);
+	&jnz	(&label("slow_enc_tail"));
+	&mov	($acc,$_ivp);		# load ivp
+	&movq	(&QWP(0,$acc),"mm0");	# save ivec
+	&movq	(&QWP(8,$acc),"mm4");
+	&emms	();
+	&mov	("esp",$_esp);
+	&popf	();
+	&function_end_A();
+	&pushf	();			# kludge, never executed
+					}
+    &set_label("slow_enc_x86",16);
+	&mov	($s0,&DWP(0,$key));	# load iv
+	&mov	($s1,&DWP(4,$key));
+
+	&set_label("slow_enc_loop_x86",4);
+		&mov	($s2,&DWP(8,$key));
+		&mov	($s3,&DWP(12,$key));
+
+		&xor	($s0,&DWP(0,$acc));	# xor input data
+		&xor	($s1,&DWP(4,$acc));
+		&xor	($s2,&DWP(8,$acc));
+		&xor	($s3,&DWP(12,$acc));
+
+		&mov	($key,$_key);		# load key
+		&call	("_x86_AES_encrypt_compact");
+
+		&mov	($acc,$_inp);		# load inp
+		&mov	($key,$_out);		# load out
+
+		&mov	(&DWP(0,$key),$s0);	# save output data
+		&mov	(&DWP(4,$key),$s1);
+		&mov	(&DWP(8,$key),$s2);
+		&mov	(&DWP(12,$key),$s3);
 
 		&mov	($s2,$_len);		# load len
-		&sub	($s2,16);
-		&jc	(&label("dec_in_place_partial"));
+		&lea	($acc,&DWP(16,$acc));	# advance inp
+		&mov	($_inp,$acc);		# save inp
+		&lea	($s3,&DWP(16,$key));	# advance out
+		&mov	($_out,$s3);		# save out
+		&sub	($s2,16);		# decrease len
+		&cmp	($s2,16);
 		&mov	($_len,$s2);		# save len
-	&jnz	(&label("dec_in_place_loop"));
-	&jmp	(&label("dec_out"));
+	&jae	(&label("slow_enc_loop_x86"));
+	&test	($s2,15);
+	&jnz	(&label("slow_enc_tail"));
+	&mov	($acc,$_ivp);		# load ivp
+	&mov	($s2,&DWP(8,$key));	# restore last dwords
+	&mov	($s3,&DWP(12,$key));
+	&mov	(&DWP(0,$acc),$s0);	# save ivec
+	&mov	(&DWP(4,$acc),$s1);
+	&mov	(&DWP(8,$acc),$s2);
+	&mov	(&DWP(12,$acc),$s3);
 
-    &align	(4);
-    &set_label("dec_in_place_partial");
-	# one can argue if this is actually required...
-	&mov	($key eq "edi" ? $key : "",$_out);
-	&lea	($acc eq "esi" ? $acc : "",$ivec);
+	&mov	("esp",$_esp);
+	&popf	();
+	&function_end_A();
+	&pushf	();			# kludge, never executed
+
+    &set_label("slow_enc_tail",16);
+	&emms	()	if (!$x86only);
+	&mov	($key eq "edi"? $key:"",$s3);	# load out to edi
+	&mov	($s1,16);
+	&sub	($s1,$s2);
+	&cmp	($key,$acc eq "esi"? $acc:"");	# 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));
-	&lea	($acc,&DWP(16,$acc,$s2));
-	&neg	($s2 eq "ecx" ? $s2 : "");
-	&data_word(0xA4F3F689);	# rep movsb	# restore tail
+    &set_label("enc_skip_in_place");
+	&mov	($s2,$s1);
+	&xor	($s0,$s0);
+	&align	(4);
+	&data_word(0xAAF3F689);	# rep stosb	# zero tail
 
-    &align	(4);
-    &set_label("dec_out");
-    &cmp	($mark,0);		# was the key schedule copied?
-    &mov	("edi",$_key);
-    &je		(&label("skip_dzero"));
-    # zero copy of key schedule
-    &mov	("ecx",240/4);
-    &xor	("eax","eax");
-    &align	(4);
-    &data_word(0xABF3F689);	# rep stosd
-    &set_label("skip_dzero")
-    &mov	("esp",$_esp);
-    &popf	();
+	&mov	($key,$_ivp);			# restore ivp
+	&mov	($acc,$s3);			# output as input
+	&mov	($s0,&DWP(0,$key));
+	&mov	($s1,&DWP(4,$key));
+	&mov	($_len,16);			# len=16
+	&jmp	(&label("slow_enc_loop_x86"));	# one more spin...
+
+#--------------------------- SLOW DECRYPT ---------------------------#
+&set_label("slow_decrypt",16);
+					if (!$x86only) {
+	&bt	($_tmp,25);		# check for SSE bit
+	&jnc	(&label("slow_dec_loop_x86"));
+
+	&set_label("slow_dec_loop_sse",4);
+		&movq	("mm0",&QWP(0,$acc));	# read input
+		&movq	("mm4",&QWP(8,$acc));
+
+		&mov	($key,$_key);
+		&call	("_sse_AES_decrypt_compact");
+
+		&mov	($acc,$_inp);		# load inp
+		&lea	($s0,$ivec);
+		&mov	($s1,$_out);		# load out
+		&mov	($s2,$_len);		# load len
+		&mov	($key,$_ivp);		# load ivp
+
+		&movq	("mm1",&QWP(0,$acc));	# re-read input
+		&movq	("mm5",&QWP(8,$acc));
+
+		&pxor	("mm0",&QWP(0,$key));	# xor iv
+		&pxor	("mm4",&QWP(8,$key));
+
+		&movq	(&QWP(0,$key),"mm1");	# copy input to iv
+		&movq	(&QWP(8,$key),"mm5");
+
+		&sub	($s2,16);		# decrease len
+		&jc	(&label("slow_dec_partial_sse"));
+
+		&movq	(&QWP(0,$s1),"mm0");	# write output
+		&movq	(&QWP(8,$s1),"mm4");
+
+		&lea	($s1,&DWP(16,$s1));	# advance out
+		&mov	($_out,$s1);		# save out
+		&lea	($acc,&DWP(16,$acc));	# advance inp
+		&mov	($_inp,$acc);		# save inp
+		&mov	($_len,$s2);		# save len
+	&jnz	(&label("slow_dec_loop_sse"));
+	&emms	();
+	&mov	("esp",$_esp);
+	&popf	();
+	&function_end_A();
+	&pushf	();			# kludge, never executed
+
+    &set_label("slow_dec_partial_sse",16);
+	&movq	(&QWP(0,$s0),"mm0");	# save output to temp
+	&movq	(&QWP(8,$s0),"mm4");
+	&emms	();
+
+	&add	($s2 eq "ecx" ? "ecx":"",16);
+	&mov	("edi",$s1);		# out
+	&mov	("esi",$s0);		# temp
+	&align	(4);
+	&data_word(0xA4F3F689);		# rep movsb # copy partial output
+
+	&mov	("esp",$_esp);
+	&popf	();
+	&function_end_A();
+	&pushf	();			# kludge, never executed
+					}
+	&set_label("slow_dec_loop_x86",16);
+		&mov	($s0,&DWP(0,$acc));	# read input
+		&mov	($s1,&DWP(4,$acc));
+		&mov	($s2,&DWP(8,$acc));
+		&mov	($s3,&DWP(12,$acc));
+
+		&lea	($key,$ivec);
+		&mov	(&DWP(0,$key),$s0);	# copy to temp
+		&mov	(&DWP(4,$key),$s1);
+		&mov	(&DWP(8,$key),$s2);
+		&mov	(&DWP(12,$key),$s3);
+
+		&mov	($key,$_key);		# load key
+		&call	("_x86_AES_decrypt_compact");
+
+		&mov	($key,$_ivp);		# load ivp
+		&mov	($acc,$_len);		# load len
+		&xor	($s0,&DWP(0,$key));	# xor iv
+		&xor	($s1,&DWP(4,$key));
+		&xor	($s2,&DWP(8,$key));
+		&xor	($s3,&DWP(12,$key));
+
+		&sub	($acc,16);
+		&jc	(&label("slow_dec_partial_x86"));
+
+		&mov	($_len,$acc);		# save len
+		&mov	($acc,$_out);		# load out
+
+		&mov	(&DWP(0,$acc),$s0);	# write output
+		&mov	(&DWP(4,$acc),$s1);
+		&mov	(&DWP(8,$acc),$s2);
+		&mov	(&DWP(12,$acc),$s3);
+
+		&lea	($acc,&DWP(16,$acc));	# advance out
+		&mov	($_out,$acc);		# save out
+
+		&lea	($acc,$ivec);
+		&mov	($s0,&DWP(0,$acc));	# read temp
+		&mov	($s1,&DWP(4,$acc));
+		&mov	($s2,&DWP(8,$acc));
+		&mov	($s3,&DWP(12,$acc));
+
+		&mov	(&DWP(0,$key),$s0);	# copy it to iv
+		&mov	(&DWP(4,$key),$s1);
+		&mov	(&DWP(8,$key),$s2);
+		&mov	(&DWP(12,$key),$s3);
+
+		&mov	($acc,$_inp);		# load inp
+		&lea	($acc,&DWP(16,$acc));	# advance inp
+		&mov	($_inp,$acc);		# save inp
+	&jnz	(&label("slow_dec_loop_x86"));
+	&mov	("esp",$_esp);
+	&popf	();
+	&function_end_A();
+	&pushf	();			# kludge, never executed
+
+    &set_label("slow_dec_partial_x86",16);
+	&lea	($acc,$ivec);
+	&mov	(&DWP(0,$acc),$s0);	# save output to temp
+	&mov	(&DWP(4,$acc),$s1);
+	&mov	(&DWP(8,$acc),$s2);
+	&mov	(&DWP(12,$acc),$s3);
+
+	&mov	($acc,$_inp);
+	&mov	($s0,&DWP(0,$acc));	# re-read input
+	&mov	($s1,&DWP(4,$acc));
+	&mov	($s2,&DWP(8,$acc));
+	&mov	($s3,&DWP(12,$acc));
+
+	&mov	(&DWP(0,$key),$s0);	# copy it to iv
+	&mov	(&DWP(4,$key),$s1);
+	&mov	(&DWP(8,$key),$s2);
+	&mov	(&DWP(12,$key),$s3);
+
+	&mov	("ecx",$_len);
+	&mov	("edi",$_out);
+	&lea	("esi",$ivec);
+	&align	(4);
+	&data_word(0xA4F3F689);		# rep movsb # copy partial output
+
+	&mov	("esp",$_esp);
+	&popf	();
 &function_end("AES_cbc_encrypt");
 }
 
@@ -1215,35 +2628,31 @@
 sub enckey()
 {
 	&movz	("esi",&LB("edx"));		# rk[i]>>0
-	&mov	("ebx",&DWP(2,"ebp","esi",8));
+	&movz	("ebx",&BP(-128,$tbl,"esi",1));
 	&movz	("esi",&HB("edx"));		# rk[i]>>8
-	&and	("ebx",0xFF000000);
+	&shl	("ebx",24);
 	&xor	("eax","ebx");
 
-	&mov	("ebx",&DWP(2,"ebp","esi",8));
+	&movz	("ebx",&BP(-128,$tbl,"esi",1));
 	&shr	("edx",16);
-	&and	("ebx",0x000000FF);
 	&movz	("esi",&LB("edx"));		# rk[i]>>16
 	&xor	("eax","ebx");
 
-	&mov	("ebx",&DWP(0,"ebp","esi",8));
+	&movz	("ebx",&BP(-128,$tbl,"esi",1));
 	&movz	("esi",&HB("edx"));		# rk[i]>>24
-	&and	("ebx",0x0000FF00);
+	&shl	("ebx",8);
 	&xor	("eax","ebx");
 
-	&mov	("ebx",&DWP(0,"ebp","esi",8));
-	&and	("ebx",0x00FF0000);
+	&movz	("ebx",&BP(-128,$tbl,"esi",1));
+	&shl	("ebx",16);
 	&xor	("eax","ebx");
 
-	&xor	("eax",&DWP(2048,"ebp","ecx",4));	# rcon
+	&xor	("eax",&DWP(1024-128,$tbl,"ecx",4));	# rcon
 }
 
-# int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
-#                        AES_KEY *key)
-&public_label("AES_Te");
-&function_begin("AES_set_encrypt_key");
-	&mov	("esi",&wparam(0));		# user supplied key
-	&mov	("edi",&wparam(2));		# private key schedule
+&function_begin("_x86_AES_set_encrypt_key");
+	&mov	("esi",&wparam(1));		# user supplied key
+	&mov	("edi",&wparam(3));		# private key schedule
 
 	&test	("esi",-1);
 	&jz	(&label("badpointer"));
@@ -1252,10 +2661,21 @@
 
 	&call	(&label("pic_point"));
 	&set_label("pic_point");
-	&blindpop("ebp");
-	&lea	("ebp",&DWP(&label("AES_Te")."-".&label("pic_point"),"ebp"));
+	&blindpop($tbl);
+	&lea	($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl));
+	&lea	($tbl,&DWP(2048+128,$tbl));
 
-	&mov	("ecx",&wparam(1));		# number of bits in key
+	# prefetch Te4
+	&mov	("eax",&DWP(0-128,$tbl));
+	&mov	("ebx",&DWP(32-128,$tbl));
+	&mov	("ecx",&DWP(64-128,$tbl));
+	&mov	("edx",&DWP(96-128,$tbl));
+	&mov	("eax",&DWP(128-128,$tbl));
+	&mov	("ebx",&DWP(160-128,$tbl));
+	&mov	("ecx",&DWP(192-128,$tbl));
+	&mov	("edx",&DWP(224-128,$tbl));
+
+	&mov	("ecx",&wparam(2));		# number of bits in key
 	&cmp	("ecx",128);
 	&je	(&label("10rounds"));
 	&cmp	("ecx",192);
@@ -1394,24 +2814,23 @@
 		&mov	("edx","eax");
 		&mov	("eax",&DWP(16,"edi"));		# rk[4]
 		&movz	("esi",&LB("edx"));		# rk[11]>>0
-		&mov	("ebx",&DWP(2,"ebp","esi",8));
+		&movz	("ebx",&BP(-128,$tbl,"esi",1));
 		&movz	("esi",&HB("edx"));		# rk[11]>>8
-		&and	("ebx",0x000000FF);
 		&xor	("eax","ebx");
 
-		&mov	("ebx",&DWP(0,"ebp","esi",8));
+		&movz	("ebx",&BP(-128,$tbl,"esi",1));
 		&shr	("edx",16);
-		&and	("ebx",0x0000FF00);
+		&shl	("ebx",8);
 		&movz	("esi",&LB("edx"));		# rk[11]>>16
 		&xor	("eax","ebx");
 
-		&mov	("ebx",&DWP(0,"ebp","esi",8));
+		&movz	("ebx",&BP(-128,$tbl,"esi",1));
 		&movz	("esi",&HB("edx"));		# rk[11]>>24
-		&and	("ebx",0x00FF0000);
+		&shl	("ebx",16);
 		&xor	("eax","ebx");
 
-		&mov	("ebx",&DWP(2,"ebp","esi",8));
-		&and	("ebx",0xFF000000);
+		&movz	("ebx",&BP(-128,$tbl,"esi",1));
+		&shl	("ebx",24);
 		&xor	("eax","ebx");
 
 		&mov	(&DWP(48,"edi"),"eax");		# rk[12]
@@ -1433,43 +2852,74 @@
     &set_label("badpointer");
 	&mov	("eax",-1);
     &set_label("exit");
-&function_end("AES_set_encrypt_key");
+&function_end("_x86_AES_set_encrypt_key");
+
+# int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+#                        AES_KEY *key)
+&function_begin_B("AES_set_encrypt_key");
+	&call	("_x86_AES_set_encrypt_key");
+	&ret	();
+&function_end_B("AES_set_encrypt_key");
 
 sub deckey()
-{ my ($i,$ptr,$te,$td) = @_;
+{ my ($i,$key,$tp1,$tp2,$tp4,$tp8) = @_;
+  my $tmp = $tbl;
 
-	&mov	("eax",&DWP($i,$ptr));
-	&mov	("edx","eax");
-	&movz	("ebx",&HB("eax"));
-	&shr	("edx",16);
-	&and	("eax",0xFF);
-	&movz	("eax",&BP(2,$te,"eax",8));
-	&movz	("ebx",&BP(2,$te,"ebx",8));
-	&mov	("eax",&DWP(0,$td,"eax",8));
-	&xor	("eax",&DWP(3,$td,"ebx",8));
-	&movz	("ebx",&HB("edx"));
-	&and	("edx",0xFF);
-	&movz	("edx",&BP(2,$te,"edx",8));
-	&movz	("ebx",&BP(2,$te,"ebx",8));
-	&xor	("eax",&DWP(2,$td,"edx",8));
-	&xor	("eax",&DWP(1,$td,"ebx",8));
-	&mov	(&DWP($i,$ptr),"eax");
+	&mov	($acc,$tp1);
+	&and	($acc,0x80808080);
+	&mov	($tmp,$acc);
+	&shr	($tmp,7);
+	&lea	($tp2,&DWP(0,$tp1,$tp1));
+	&sub	($acc,$tmp);
+	&and	($tp2,0xfefefefe);
+	&and	($acc,0x1b1b1b1b);
+	&xor	($acc,$tp2);
+	&mov	($tp2,$acc);
+
+	&and	($acc,0x80808080);
+	&mov	($tmp,$acc);
+	&shr	($tmp,7);
+	&lea	($tp4,&DWP(0,$tp2,$tp2));
+	&sub	($acc,$tmp);
+	&and	($tp4,0xfefefefe);
+	&and	($acc,0x1b1b1b1b);
+	 &xor	($tp2,$tp1);	# tp2^tp1
+	&xor	($acc,$tp4);
+	&mov	($tp4,$acc);
+
+	&and	($acc,0x80808080);
+	&mov	($tmp,$acc);
+	&shr	($tmp,7);
+	&lea	($tp8,&DWP(0,$tp4,$tp4));
+	 &xor	($tp4,$tp1);	# tp4^tp1
+	&sub	($acc,$tmp);
+	&and	($tp8,0xfefefefe);
+	&and	($acc,0x1b1b1b1b);
+	 &rotl	($tp1,8);	# = ROTATE(tp1,8)
+	&xor	($tp8,$acc);
+
+	&mov	($tmp,&DWP(4*($i+1),$key));	# modulo-scheduled load
+
+	&xor	($tp1,$tp2);
+	&xor	($tp2,$tp8);
+	&xor	($tp1,$tp4);
+	&rotl	($tp2,24);
+	&xor	($tp4,$tp8);
+	&xor	($tp1,$tp8);	# ^= tp8^(tp4^tp1)^(tp2^tp1)
+	&rotl	($tp4,16);
+	&xor	($tp1,$tp2);	# ^= ROTATE(tp8^tp2^tp1,24)
+	&rotl	($tp8,8);
+	&xor	($tp1,$tp4);	# ^= ROTATE(tp8^tp4^tp1,16)
+	&mov	($tp2,$tmp);
+	&xor	($tp1,$tp8);	# ^= ROTATE(tp8,8)
+
+	&mov	(&DWP(4*$i,$key),$tp1);
 }
 
 # int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
 #                        AES_KEY *key)
-&public_label("AES_Td");
-&public_label("AES_Te");
 &function_begin_B("AES_set_decrypt_key");
-	&mov	("eax",&wparam(0));
-	&mov	("ecx",&wparam(1));
-	&mov	("edx",&wparam(2));
-	&sub	("esp",12);
-	&mov	(&DWP(0,"esp"),"eax");
-	&mov	(&DWP(4,"esp"),"ecx");
-	&mov	(&DWP(8,"esp"),"edx");
-	&call	("AES_set_encrypt_key");
-	&add	("esp",12);
+	&call	("_x86_AES_set_encrypt_key");
 	&cmp	("eax",0);
 	&je	(&label("proceed"));
 	&ret	();
@@ -1485,8 +2935,7 @@
 	&lea	("ecx",&DWP(0,"","ecx",4));
 	&lea	("edi",&DWP(0,"esi","ecx",4));	# pointer to last chunk
 
-	&align	(4);
-	&set_label("invert");			# invert order of chunks
+	&set_label("invert",4);			# invert order of chunks
 		&mov	("eax",&DWP(0,"esi"));
 		&mov	("ebx",&DWP(4,"esi"));
 		&mov	("ecx",&DWP(0,"edi"));
@@ -1508,26 +2957,24 @@
 		&cmp	("esi","edi");
 	&jne	(&label("invert"));
 
-	&call	(&label("pic_point"));
-	&set_label("pic_point");
-	blindpop("ebp");
-	&lea	("edi",&DWP(&label("AES_Td")."-".&label("pic_point"),"ebp"));
-	&lea	("ebp",&DWP(&label("AES_Te")."-".&label("pic_point"),"ebp"));
+	&mov	($key,&wparam(2));
+	&mov	($acc,&DWP(240,$key));		# pull number of rounds
+	&lea	($acc,&DWP(-2,$acc,$acc));
+	&lea	($acc,&DWP(0,$key,$acc,8));
+	&mov	(&wparam(2),$acc);
 
-	&mov	("esi",&wparam(2));
-	&mov	("ecx",&DWP(240,"esi"));	# pull number of rounds
-	&dec	("ecx");
-	&align	(4);
-	&set_label("permute");			# permute the key schedule
-		&add	("esi",16);
-		&deckey	(0,"esi","ebp","edi");
-		&deckey	(4,"esi","ebp","edi");
-		&deckey	(8,"esi","ebp","edi");
-		&deckey	(12,"esi","ebp","edi");
-		&dec	("ecx");
-	&jnz	(&label("permute"));
+	&mov	($s0,&DWP(16,$key));		# modulo-scheduled load
+	&set_label("permute",4);		# permute the key schedule
+		&add	($key,16);
+		&deckey	(0,$key,$s0,$s1,$s2,$s3);
+		&deckey	(1,$key,$s1,$s2,$s3,$s0);
+		&deckey	(2,$key,$s2,$s3,$s0,$s1);
+		&deckey	(3,$key,$s3,$s0,$s1,$s2);
+		&cmp	($key,&wparam(2));
+	&jb	(&label("permute"));
 
 	&xor	("eax","eax");			# return success
 &function_end("AES_set_decrypt_key");
+&asciz("AES for x86, CRYPTOGAMS by <appro\@openssl.org>");
 
 &asm_finish();
diff --git a/crypto/0.9.9-dev/aes/aes-armv4.pl b/crypto/aes/asm/aes-armv4.pl
similarity index 99%
rename from crypto/0.9.9-dev/aes/aes-armv4.pl
rename to crypto/aes/asm/aes-armv4.pl
index 15742c1..6902441 100644
--- a/crypto/0.9.9-dev/aes/aes-armv4.pl
+++ b/crypto/aes/asm/aes-armv4.pl
@@ -1024,6 +1024,7 @@
 	mov	pc,lr			@ return
 .size	_armv4_AES_decrypt,.-_armv4_AES_decrypt
 .asciz	"AES for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
+.align	2
 ___
 
 $code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
diff --git a/crypto/0.9.9-dev/aes/aes-armv4.s b/crypto/aes/asm/aes-armv4.s
similarity index 100%
rename from crypto/0.9.9-dev/aes/aes-armv4.s
rename to crypto/aes/asm/aes-armv4.s
diff --git a/crypto/aes/asm/aes-ppc.pl b/crypto/aes/asm/aes-ppc.pl
new file mode 100644
index 0000000..ce42765
--- /dev/null
+++ b/crypto/aes/asm/aes-ppc.pl
@@ -0,0 +1,1176 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# Needs more work: key setup, page boundaries, CBC routine...
+#
+# ppc_AES_[en|de]crypt perform at 18 cycles per byte processed with
+# 128-bit key, which is ~40% better than 64-bit code generated by gcc
+# 4.0. But these are not the ones currently used! Their "compact"
+# counterparts are, for security reason. ppc_AES_encrypt_compact runs
+# at 1/2 of ppc_AES_encrypt speed, while ppc_AES_decrypt_compact -
+# at 1/3 of ppc_AES_decrypt.
+
+$flavour = shift;
+
+if ($flavour =~ /64/) {
+	$SIZE_T	=8;
+	$STU	="stdu";
+	$POP	="ld";
+	$PUSH	="std";
+} elsif ($flavour =~ /32/) {
+	$SIZE_T	=4;
+	$STU	="stwu";
+	$POP	="lwz";
+	$PUSH	="stw";
+} else { die "nonsense $flavour"; }
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
+die "can't locate ppc-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
+
+$FRAME=32*$SIZE_T;
+
+sub _data_word()
+{ my $i;
+    while(defined($i=shift)) { $code.=sprintf"\t.long\t0x%08x,0x%08x\n",$i,$i; }
+}
+
+$sp="r1";
+$toc="r2";
+$inp="r3";
+$out="r4";
+$key="r5";
+
+$Tbl0="r3";
+$Tbl1="r6";
+$Tbl2="r7";
+$Tbl3="r2";
+
+$s0="r8";
+$s1="r9";
+$s2="r10";
+$s3="r11";
+
+$t0="r12";
+$t1="r13";
+$t2="r14";
+$t3="r15";
+
+$acc00="r16";
+$acc01="r17";
+$acc02="r18";
+$acc03="r19";
+
+$acc04="r20";
+$acc05="r21";
+$acc06="r22";
+$acc07="r23";
+
+$acc08="r24";
+$acc09="r25";
+$acc10="r26";
+$acc11="r27";
+
+$acc12="r28";
+$acc13="r29";
+$acc14="r30";
+$acc15="r31";
+
+# stay away from TLS pointer
+if ($SIZE_T==8)	{ die if ($t1 ne "r13");  $t1="r0";		}
+else		{ die if ($Tbl3 ne "r2"); $Tbl3=$t0; $t0="r0";	}
+$mask80=$Tbl2;
+$mask1b=$Tbl3;
+
+$code.=<<___;
+.machine	"any"
+.text
+
+.align	7
+LAES_Te:
+	mflr	r0
+	bcl	20,31,\$+4
+	mflr	$Tbl0	;    vvvvv "distance" between . and 1st data entry
+	addi	$Tbl0,$Tbl0,`128-8`
+	mtlr	r0
+	blr
+	.space	`32-24`
+LAES_Td:
+	mflr	r0
+	bcl	20,31,\$+4
+	mflr	$Tbl0	;    vvvvvvvv "distance" between . and 1st data entry
+	addi	$Tbl0,$Tbl0,`128-8-32+2048+256`
+	mtlr	r0
+	blr
+	.space	`128-32-24`
+___
+&_data_word(
+	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
+	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
+	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
+	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
+	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
+	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
+	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
+	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
+	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
+	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
+	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
+	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
+	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
+	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
+	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
+	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
+	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
+	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
+	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
+	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
+	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
+	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
+	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
+	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
+	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
+	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
+	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
+	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
+	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
+	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
+	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
+	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
+	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
+	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
+	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
+	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
+	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
+	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
+	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
+	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
+	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
+	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
+	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
+	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
+	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
+	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
+	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
+	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
+	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
+	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
+	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
+	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
+	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
+	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
+	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
+	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
+	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
+	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
+	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
+	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
+	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
+	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
+	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
+	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
+$code.=<<___;
+.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
+.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
+.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
+.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
+.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
+.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
+.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
+.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
+.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
+.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
+.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
+.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
+.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
+.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
+.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
+.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
+.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
+.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
+.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
+.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
+.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
+.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
+.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
+.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
+.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
+.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
+.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
+.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
+.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
+.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
+.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
+.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+___
+&_data_word(
+	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
+	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
+	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
+	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
+	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
+	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
+	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
+	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
+	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
+	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
+	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
+	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
+	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
+	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
+	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
+	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
+	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
+	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
+	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
+	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
+	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
+	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
+	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
+	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
+	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
+	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
+	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
+	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
+	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
+	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
+	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
+	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
+	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
+	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
+	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
+	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
+	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
+	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
+	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
+	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
+	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
+	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
+	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
+	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
+	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
+	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
+	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
+	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
+	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
+	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
+	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
+	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
+	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
+	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
+	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
+	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
+	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
+	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
+	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
+	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
+	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
+	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
+	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
+	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
+$code.=<<___;
+.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
+.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
+.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
+.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
+.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
+.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
+.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
+.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
+.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
+.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
+.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
+.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
+.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
+.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
+.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
+.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
+.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+
+
+.globl	.AES_encrypt
+.align	7
+.AES_encrypt:
+	mflr	r0
+	$STU	$sp,-$FRAME($sp)
+
+	$PUSH	r0,`$FRAME-$SIZE_T*21`($sp)
+	$PUSH	$toc,`$FRAME-$SIZE_T*20`($sp)
+	$PUSH	r13,`$FRAME-$SIZE_T*19`($sp)
+	$PUSH	r14,`$FRAME-$SIZE_T*18`($sp)
+	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
+	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
+	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
+	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
+	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
+	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
+	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
+	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
+	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
+	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
+	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
+	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
+	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
+	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
+	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
+	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
+	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
+
+	lwz	$s0,0($inp)
+	lwz	$s1,4($inp)
+	lwz	$s2,8($inp)
+	lwz	$s3,12($inp)
+	bl	LAES_Te
+	bl	Lppc_AES_encrypt_compact
+	stw	$s0,0($out)
+	stw	$s1,4($out)
+	stw	$s2,8($out)
+	stw	$s3,12($out)
+
+	$POP	r0,`$FRAME-$SIZE_T*21`($sp)
+	$POP	$toc,`$FRAME-$SIZE_T*20`($sp)
+	$POP	r13,`$FRAME-$SIZE_T*19`($sp)
+	$POP	r14,`$FRAME-$SIZE_T*18`($sp)
+	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
+	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
+	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
+	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
+	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
+	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
+	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
+	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
+	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
+	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
+	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
+	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
+	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
+	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
+	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
+	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
+	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
+	mtlr	r0
+	addi	$sp,$sp,$FRAME
+	blr
+
+.align	4
+Lppc_AES_encrypt:
+	lwz	$acc00,240($key)
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	addi	$Tbl1,$Tbl0,3
+	addi	$Tbl2,$Tbl0,2
+	addi	$Tbl3,$Tbl0,1
+	addi	$acc00,$acc00,-1
+	addi	$key,$key,16
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	mtctr	$acc00
+.align	4
+Lenc_loop:
+	rlwinm	$acc00,$s0,`32-24+3`,21,28
+	rlwinm	$acc01,$s1,`32-24+3`,21,28
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	rlwinm	$acc02,$s2,`32-24+3`,21,28
+	rlwinm	$acc03,$s3,`32-24+3`,21,28
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	rlwinm	$acc04,$s1,`32-16+3`,21,28
+	rlwinm	$acc05,$s2,`32-16+3`,21,28
+	lwzx	$acc00,$Tbl0,$acc00
+	lwzx	$acc01,$Tbl0,$acc01
+	rlwinm	$acc06,$s3,`32-16+3`,21,28
+	rlwinm	$acc07,$s0,`32-16+3`,21,28
+	lwzx	$acc02,$Tbl0,$acc02
+	lwzx	$acc03,$Tbl0,$acc03
+	rlwinm	$acc08,$s2,`32-8+3`,21,28
+	rlwinm	$acc09,$s3,`32-8+3`,21,28
+	lwzx	$acc04,$Tbl1,$acc04
+	lwzx	$acc05,$Tbl1,$acc05
+	rlwinm	$acc10,$s0,`32-8+3`,21,28
+	rlwinm	$acc11,$s1,`32-8+3`,21,28
+	lwzx	$acc06,$Tbl1,$acc06
+	lwzx	$acc07,$Tbl1,$acc07
+	rlwinm	$acc12,$s3,`0+3`,21,28
+	rlwinm	$acc13,$s0,`0+3`,21,28
+	lwzx	$acc08,$Tbl2,$acc08
+	lwzx	$acc09,$Tbl2,$acc09
+	rlwinm	$acc14,$s1,`0+3`,21,28
+	rlwinm	$acc15,$s2,`0+3`,21,28
+	lwzx	$acc10,$Tbl2,$acc10
+	lwzx	$acc11,$Tbl2,$acc11
+	xor	$t0,$t0,$acc00
+	xor	$t1,$t1,$acc01
+	lwzx	$acc12,$Tbl3,$acc12
+	lwzx	$acc13,$Tbl3,$acc13
+	xor	$t2,$t2,$acc02
+	xor	$t3,$t3,$acc03
+	lwzx	$acc14,$Tbl3,$acc14
+	lwzx	$acc15,$Tbl3,$acc15
+	xor	$t0,$t0,$acc04
+	xor	$t1,$t1,$acc05
+	xor	$t2,$t2,$acc06
+	xor	$t3,$t3,$acc07
+	xor	$t0,$t0,$acc08
+	xor	$t1,$t1,$acc09
+	xor	$t2,$t2,$acc10
+	xor	$t3,$t3,$acc11
+	xor	$s0,$t0,$acc12
+	xor	$s1,$t1,$acc13
+	xor	$s2,$t2,$acc14
+	xor	$s3,$t3,$acc15
+	addi	$key,$key,16
+	bdnz-	Lenc_loop
+
+	addi	$Tbl2,$Tbl0,2048
+	nop
+	lwz	$acc08,`2048+0`($Tbl0)	! prefetch Te4
+	lwz	$acc09,`2048+32`($Tbl0)
+	lwz	$acc10,`2048+64`($Tbl0)
+	lwz	$acc11,`2048+96`($Tbl0)
+	lwz	$acc08,`2048+128`($Tbl0)
+	lwz	$acc09,`2048+160`($Tbl0)
+	lwz	$acc10,`2048+192`($Tbl0)
+	lwz	$acc11,`2048+224`($Tbl0)
+	rlwinm	$acc00,$s0,`32-24`,24,31
+	rlwinm	$acc01,$s1,`32-24`,24,31
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	rlwinm	$acc02,$s2,`32-24`,24,31
+	rlwinm	$acc03,$s3,`32-24`,24,31
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	rlwinm	$acc04,$s1,`32-16`,24,31
+	rlwinm	$acc05,$s2,`32-16`,24,31
+	lbzx	$acc00,$Tbl2,$acc00
+	lbzx	$acc01,$Tbl2,$acc01
+	rlwinm	$acc06,$s3,`32-16`,24,31
+	rlwinm	$acc07,$s0,`32-16`,24,31
+	lbzx	$acc02,$Tbl2,$acc02
+	lbzx	$acc03,$Tbl2,$acc03
+	rlwinm	$acc08,$s2,`32-8`,24,31
+	rlwinm	$acc09,$s3,`32-8`,24,31
+	lbzx	$acc04,$Tbl2,$acc04
+	lbzx	$acc05,$Tbl2,$acc05
+	rlwinm	$acc10,$s0,`32-8`,24,31
+	rlwinm	$acc11,$s1,`32-8`,24,31
+	lbzx	$acc06,$Tbl2,$acc06
+	lbzx	$acc07,$Tbl2,$acc07
+	rlwinm	$acc12,$s3,`0`,24,31
+	rlwinm	$acc13,$s0,`0`,24,31
+	lbzx	$acc08,$Tbl2,$acc08
+	lbzx	$acc09,$Tbl2,$acc09
+	rlwinm	$acc14,$s1,`0`,24,31
+	rlwinm	$acc15,$s2,`0`,24,31
+	lbzx	$acc10,$Tbl2,$acc10
+	lbzx	$acc11,$Tbl2,$acc11
+	rlwinm	$s0,$acc00,24,0,7
+	rlwinm	$s1,$acc01,24,0,7
+	lbzx	$acc12,$Tbl2,$acc12
+	lbzx	$acc13,$Tbl2,$acc13
+	rlwinm	$s2,$acc02,24,0,7
+	rlwinm	$s3,$acc03,24,0,7
+	lbzx	$acc14,$Tbl2,$acc14
+	lbzx	$acc15,$Tbl2,$acc15
+	rlwimi	$s0,$acc04,16,8,15
+	rlwimi	$s1,$acc05,16,8,15
+	rlwimi	$s2,$acc06,16,8,15
+	rlwimi	$s3,$acc07,16,8,15
+	rlwimi	$s0,$acc08,8,16,23
+	rlwimi	$s1,$acc09,8,16,23
+	rlwimi	$s2,$acc10,8,16,23
+	rlwimi	$s3,$acc11,8,16,23
+	or	$s0,$s0,$acc12
+	or	$s1,$s1,$acc13
+	or	$s2,$s2,$acc14
+	or	$s3,$s3,$acc15
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	blr
+
+.align	4
+Lppc_AES_encrypt_compact:
+	lwz	$acc00,240($key)
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	addi	$Tbl1,$Tbl0,2048
+	lis	$mask80,0x8080
+	lis	$mask1b,0x1b1b
+	addi	$key,$key,16
+	ori	$mask80,$mask80,0x8080
+	ori	$mask1b,$mask1b,0x1b1b
+	mtctr	$acc00
+.align	4
+Lenc_compact_loop:
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	rlwinm	$acc00,$s0,`32-24`,24,31
+	rlwinm	$acc01,$s1,`32-24`,24,31
+	rlwinm	$acc02,$s2,`32-24`,24,31
+	rlwinm	$acc03,$s3,`32-24`,24,31
+	lbzx	$acc00,$Tbl1,$acc00
+	lbzx	$acc01,$Tbl1,$acc01
+	rlwinm	$acc04,$s1,`32-16`,24,31
+	rlwinm	$acc05,$s2,`32-16`,24,31
+	lbzx	$acc02,$Tbl1,$acc02
+	lbzx	$acc03,$Tbl1,$acc03
+	rlwinm	$acc06,$s3,`32-16`,24,31
+	rlwinm	$acc07,$s0,`32-16`,24,31
+	lbzx	$acc04,$Tbl1,$acc04
+	lbzx	$acc05,$Tbl1,$acc05
+	rlwinm	$acc08,$s2,`32-8`,24,31
+	rlwinm	$acc09,$s3,`32-8`,24,31
+	lbzx	$acc06,$Tbl1,$acc06
+	lbzx	$acc07,$Tbl1,$acc07
+	rlwinm	$acc10,$s0,`32-8`,24,31
+	rlwinm	$acc11,$s1,`32-8`,24,31
+	lbzx	$acc08,$Tbl1,$acc08
+	lbzx	$acc09,$Tbl1,$acc09
+	rlwinm	$acc12,$s3,`0`,24,31
+	rlwinm	$acc13,$s0,`0`,24,31
+	lbzx	$acc10,$Tbl1,$acc10
+	lbzx	$acc11,$Tbl1,$acc11
+	rlwinm	$acc14,$s1,`0`,24,31
+	rlwinm	$acc15,$s2,`0`,24,31
+	lbzx	$acc12,$Tbl1,$acc12
+	lbzx	$acc13,$Tbl1,$acc13
+	rlwinm	$s0,$acc00,24,0,7
+	rlwinm	$s1,$acc01,24,0,7
+	lbzx	$acc14,$Tbl1,$acc14
+	lbzx	$acc15,$Tbl1,$acc15
+	rlwinm	$s2,$acc02,24,0,7
+	rlwinm	$s3,$acc03,24,0,7
+	rlwimi	$s0,$acc04,16,8,15
+	rlwimi	$s1,$acc05,16,8,15
+	rlwimi	$s2,$acc06,16,8,15
+	rlwimi	$s3,$acc07,16,8,15
+	rlwimi	$s0,$acc08,8,16,23
+	rlwimi	$s1,$acc09,8,16,23
+	rlwimi	$s2,$acc10,8,16,23
+	rlwimi	$s3,$acc11,8,16,23
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	or	$s0,$s0,$acc12
+	or	$s1,$s1,$acc13
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	or	$s2,$s2,$acc14
+	or	$s3,$s3,$acc15
+
+	addi	$key,$key,16
+	bdz	Lenc_compact_done
+
+	and	$acc00,$s0,$mask80	# r1=r0&0x80808080
+	and	$acc01,$s1,$mask80
+	and	$acc02,$s2,$mask80
+	and	$acc03,$s3,$mask80
+	srwi	$acc04,$acc00,7		# r1>>7
+	srwi	$acc05,$acc01,7
+	srwi	$acc06,$acc02,7
+	srwi	$acc07,$acc03,7
+	andc	$acc08,$s0,$mask80	# r0&0x7f7f7f7f
+	andc	$acc09,$s1,$mask80
+	andc	$acc10,$s2,$mask80
+	andc	$acc11,$s3,$mask80
+	sub	$acc00,$acc00,$acc04	# r1-(r1>>7)
+	sub	$acc01,$acc01,$acc05
+	sub	$acc02,$acc02,$acc06
+	sub	$acc03,$acc03,$acc07
+	add	$acc08,$acc08,$acc08	# (r0&0x7f7f7f7f)<<1
+	add	$acc09,$acc09,$acc09
+	add	$acc10,$acc10,$acc10
+	add	$acc11,$acc11,$acc11
+	and	$acc00,$acc00,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc01,$acc01,$mask1b
+	and	$acc02,$acc02,$mask1b
+	and	$acc03,$acc03,$mask1b
+	xor	$acc00,$acc00,$acc08	# r2
+	xor	$acc01,$acc01,$acc09
+	xor	$acc02,$acc02,$acc10
+	xor	$acc03,$acc03,$acc11
+
+	rotlwi	$acc12,$s0,16		# ROTATE(r0,16)
+	rotlwi	$acc13,$s1,16
+	rotlwi	$acc14,$s2,16
+	rotlwi	$acc15,$s3,16
+	xor	$s0,$s0,$acc00		# r0^r2
+	xor	$s1,$s1,$acc01
+	xor	$s2,$s2,$acc02
+	xor	$s3,$s3,$acc03
+	rotrwi	$s0,$s0,24		# ROTATE(r2^r0,24)
+	rotrwi	$s1,$s1,24
+	rotrwi	$s2,$s2,24
+	rotrwi	$s3,$s3,24
+	xor	$s0,$s0,$acc00		# ROTATE(r2^r0,24)^r2
+	xor	$s1,$s1,$acc01
+	xor	$s2,$s2,$acc02
+	xor	$s3,$s3,$acc03
+	rotlwi	$acc08,$acc12,8		# ROTATE(r0,24)
+	rotlwi	$acc09,$acc13,8
+	rotlwi	$acc10,$acc14,8
+	rotlwi	$acc11,$acc15,8
+	xor	$s0,$s0,$acc12		#
+	xor	$s1,$s1,$acc13
+	xor	$s2,$s2,$acc14
+	xor	$s3,$s3,$acc15
+	xor	$s0,$s0,$acc08		#
+	xor	$s1,$s1,$acc09
+	xor	$s2,$s2,$acc10
+	xor	$s3,$s3,$acc11
+
+	b	Lenc_compact_loop
+.align	4
+Lenc_compact_done:
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	blr
+
+.globl	.AES_decrypt
+.align	7
+.AES_decrypt:
+	mflr	r0
+	$STU	$sp,-$FRAME($sp)
+
+	$PUSH	r0,`$FRAME-$SIZE_T*21`($sp)
+	$PUSH	$toc,`$FRAME-$SIZE_T*20`($sp)
+	$PUSH	r13,`$FRAME-$SIZE_T*19`($sp)
+	$PUSH	r14,`$FRAME-$SIZE_T*18`($sp)
+	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
+	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
+	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
+	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
+	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
+	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
+	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
+	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
+	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
+	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
+	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
+	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
+	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
+	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
+	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
+	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
+	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
+
+	lwz	$s0,0($inp)
+	lwz	$s1,4($inp)
+	lwz	$s2,8($inp)
+	lwz	$s3,12($inp)
+	bl	LAES_Td
+	bl	Lppc_AES_decrypt_compact
+	stw	$s0,0($out)
+	stw	$s1,4($out)
+	stw	$s2,8($out)
+	stw	$s3,12($out)
+
+	$POP	r0,`$FRAME-$SIZE_T*21`($sp)
+	$POP	$toc,`$FRAME-$SIZE_T*20`($sp)
+	$POP	r13,`$FRAME-$SIZE_T*19`($sp)
+	$POP	r14,`$FRAME-$SIZE_T*18`($sp)
+	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
+	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
+	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
+	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
+	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
+	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
+	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
+	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
+	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
+	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
+	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
+	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
+	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
+	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
+	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
+	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
+	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
+	mtlr	r0
+	addi	$sp,$sp,$FRAME
+	blr
+
+.align	4
+Lppc_AES_decrypt:
+	lwz	$acc00,240($key)
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	addi	$Tbl1,$Tbl0,3
+	addi	$Tbl2,$Tbl0,2
+	addi	$Tbl3,$Tbl0,1
+	addi	$acc00,$acc00,-1
+	addi	$key,$key,16
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	mtctr	$acc00
+.align	4
+Ldec_loop:
+	rlwinm	$acc00,$s0,`32-24+3`,21,28
+	rlwinm	$acc01,$s1,`32-24+3`,21,28
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	rlwinm	$acc02,$s2,`32-24+3`,21,28
+	rlwinm	$acc03,$s3,`32-24+3`,21,28
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	rlwinm	$acc04,$s3,`32-16+3`,21,28
+	rlwinm	$acc05,$s0,`32-16+3`,21,28
+	lwzx	$acc00,$Tbl0,$acc00
+	lwzx	$acc01,$Tbl0,$acc01
+	rlwinm	$acc06,$s1,`32-16+3`,21,28
+	rlwinm	$acc07,$s2,`32-16+3`,21,28
+	lwzx	$acc02,$Tbl0,$acc02
+	lwzx	$acc03,$Tbl0,$acc03
+	rlwinm	$acc08,$s2,`32-8+3`,21,28
+	rlwinm	$acc09,$s3,`32-8+3`,21,28
+	lwzx	$acc04,$Tbl1,$acc04
+	lwzx	$acc05,$Tbl1,$acc05
+	rlwinm	$acc10,$s0,`32-8+3`,21,28
+	rlwinm	$acc11,$s1,`32-8+3`,21,28
+	lwzx	$acc06,$Tbl1,$acc06
+	lwzx	$acc07,$Tbl1,$acc07
+	rlwinm	$acc12,$s1,`0+3`,21,28
+	rlwinm	$acc13,$s2,`0+3`,21,28
+	lwzx	$acc08,$Tbl2,$acc08
+	lwzx	$acc09,$Tbl2,$acc09
+	rlwinm	$acc14,$s3,`0+3`,21,28
+	rlwinm	$acc15,$s0,`0+3`,21,28
+	lwzx	$acc10,$Tbl2,$acc10
+	lwzx	$acc11,$Tbl2,$acc11
+	xor	$t0,$t0,$acc00
+	xor	$t1,$t1,$acc01
+	lwzx	$acc12,$Tbl3,$acc12
+	lwzx	$acc13,$Tbl3,$acc13
+	xor	$t2,$t2,$acc02
+	xor	$t3,$t3,$acc03
+	lwzx	$acc14,$Tbl3,$acc14
+	lwzx	$acc15,$Tbl3,$acc15
+	xor	$t0,$t0,$acc04
+	xor	$t1,$t1,$acc05
+	xor	$t2,$t2,$acc06
+	xor	$t3,$t3,$acc07
+	xor	$t0,$t0,$acc08
+	xor	$t1,$t1,$acc09
+	xor	$t2,$t2,$acc10
+	xor	$t3,$t3,$acc11
+	xor	$s0,$t0,$acc12
+	xor	$s1,$t1,$acc13
+	xor	$s2,$t2,$acc14
+	xor	$s3,$t3,$acc15
+	addi	$key,$key,16
+	bdnz-	Ldec_loop
+
+	addi	$Tbl2,$Tbl0,2048
+	nop
+	lwz	$acc08,`2048+0`($Tbl0)	! prefetch Td4
+	lwz	$acc09,`2048+32`($Tbl0)
+	lwz	$acc10,`2048+64`($Tbl0)
+	lwz	$acc11,`2048+96`($Tbl0)
+	lwz	$acc08,`2048+128`($Tbl0)
+	lwz	$acc09,`2048+160`($Tbl0)
+	lwz	$acc10,`2048+192`($Tbl0)
+	lwz	$acc11,`2048+224`($Tbl0)
+	rlwinm	$acc00,$s0,`32-24`,24,31
+	rlwinm	$acc01,$s1,`32-24`,24,31
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	rlwinm	$acc02,$s2,`32-24`,24,31
+	rlwinm	$acc03,$s3,`32-24`,24,31
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	rlwinm	$acc04,$s3,`32-16`,24,31
+	rlwinm	$acc05,$s0,`32-16`,24,31
+	lbzx	$acc00,$Tbl2,$acc00
+	lbzx	$acc01,$Tbl2,$acc01
+	rlwinm	$acc06,$s1,`32-16`,24,31
+	rlwinm	$acc07,$s2,`32-16`,24,31
+	lbzx	$acc02,$Tbl2,$acc02
+	lbzx	$acc03,$Tbl2,$acc03
+	rlwinm	$acc08,$s2,`32-8`,24,31
+	rlwinm	$acc09,$s3,`32-8`,24,31
+	lbzx	$acc04,$Tbl2,$acc04
+	lbzx	$acc05,$Tbl2,$acc05
+	rlwinm	$acc10,$s0,`32-8`,24,31
+	rlwinm	$acc11,$s1,`32-8`,24,31
+	lbzx	$acc06,$Tbl2,$acc06
+	lbzx	$acc07,$Tbl2,$acc07
+	rlwinm	$acc12,$s1,`0`,24,31
+	rlwinm	$acc13,$s2,`0`,24,31
+	lbzx	$acc08,$Tbl2,$acc08
+	lbzx	$acc09,$Tbl2,$acc09
+	rlwinm	$acc14,$s3,`0`,24,31
+	rlwinm	$acc15,$s0,`0`,24,31
+	lbzx	$acc10,$Tbl2,$acc10
+	lbzx	$acc11,$Tbl2,$acc11
+	rlwinm	$s0,$acc00,24,0,7
+	rlwinm	$s1,$acc01,24,0,7
+	lbzx	$acc12,$Tbl2,$acc12
+	lbzx	$acc13,$Tbl2,$acc13
+	rlwinm	$s2,$acc02,24,0,7
+	rlwinm	$s3,$acc03,24,0,7
+	lbzx	$acc14,$Tbl2,$acc14
+	lbzx	$acc15,$Tbl2,$acc15
+	rlwimi	$s0,$acc04,16,8,15
+	rlwimi	$s1,$acc05,16,8,15
+	rlwimi	$s2,$acc06,16,8,15
+	rlwimi	$s3,$acc07,16,8,15
+	rlwimi	$s0,$acc08,8,16,23
+	rlwimi	$s1,$acc09,8,16,23
+	rlwimi	$s2,$acc10,8,16,23
+	rlwimi	$s3,$acc11,8,16,23
+	or	$s0,$s0,$acc12
+	or	$s1,$s1,$acc13
+	or	$s2,$s2,$acc14
+	or	$s3,$s3,$acc15
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	blr
+
+.align	4
+Lppc_AES_decrypt_compact:
+	lwz	$acc00,240($key)
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	addi	$Tbl1,$Tbl0,2048
+	lis	$mask80,0x8080
+	lis	$mask1b,0x1b1b
+	addi	$key,$key,16
+	ori	$mask80,$mask80,0x8080
+	ori	$mask1b,$mask1b,0x1b1b
+___
+$code.=<<___ if ($SIZE_T==8);
+	insrdi	$mask80,$mask80,32,0
+	insrdi	$mask1b,$mask1b,32,0
+___
+$code.=<<___;
+	mtctr	$acc00
+.align	4
+Ldec_compact_loop:
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	rlwinm	$acc00,$s0,`32-24`,24,31
+	rlwinm	$acc01,$s1,`32-24`,24,31
+	rlwinm	$acc02,$s2,`32-24`,24,31
+	rlwinm	$acc03,$s3,`32-24`,24,31
+	lbzx	$acc00,$Tbl1,$acc00
+	lbzx	$acc01,$Tbl1,$acc01
+	rlwinm	$acc04,$s3,`32-16`,24,31
+	rlwinm	$acc05,$s0,`32-16`,24,31
+	lbzx	$acc02,$Tbl1,$acc02
+	lbzx	$acc03,$Tbl1,$acc03
+	rlwinm	$acc06,$s1,`32-16`,24,31
+	rlwinm	$acc07,$s2,`32-16`,24,31
+	lbzx	$acc04,$Tbl1,$acc04
+	lbzx	$acc05,$Tbl1,$acc05
+	rlwinm	$acc08,$s2,`32-8`,24,31
+	rlwinm	$acc09,$s3,`32-8`,24,31
+	lbzx	$acc06,$Tbl1,$acc06
+	lbzx	$acc07,$Tbl1,$acc07
+	rlwinm	$acc10,$s0,`32-8`,24,31
+	rlwinm	$acc11,$s1,`32-8`,24,31
+	lbzx	$acc08,$Tbl1,$acc08
+	lbzx	$acc09,$Tbl1,$acc09
+	rlwinm	$acc12,$s1,`0`,24,31
+	rlwinm	$acc13,$s2,`0`,24,31
+	lbzx	$acc10,$Tbl1,$acc10
+	lbzx	$acc11,$Tbl1,$acc11
+	rlwinm	$acc14,$s3,`0`,24,31
+	rlwinm	$acc15,$s0,`0`,24,31
+	lbzx	$acc12,$Tbl1,$acc12
+	lbzx	$acc13,$Tbl1,$acc13
+	rlwinm	$s0,$acc00,24,0,7
+	rlwinm	$s1,$acc01,24,0,7
+	lbzx	$acc14,$Tbl1,$acc14
+	lbzx	$acc15,$Tbl1,$acc15
+	rlwinm	$s2,$acc02,24,0,7
+	rlwinm	$s3,$acc03,24,0,7
+	rlwimi	$s0,$acc04,16,8,15
+	rlwimi	$s1,$acc05,16,8,15
+	rlwimi	$s2,$acc06,16,8,15
+	rlwimi	$s3,$acc07,16,8,15
+	rlwimi	$s0,$acc08,8,16,23
+	rlwimi	$s1,$acc09,8,16,23
+	rlwimi	$s2,$acc10,8,16,23
+	rlwimi	$s3,$acc11,8,16,23
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	or	$s0,$s0,$acc12
+	or	$s1,$s1,$acc13
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	or	$s2,$s2,$acc14
+	or	$s3,$s3,$acc15
+
+	addi	$key,$key,16
+	bdz	Ldec_compact_done
+___
+$code.=<<___ if ($SIZE_T==8);
+	# vectorized permutation improves decrypt performance by 10%
+	insrdi	$s0,$s1,32,0
+	insrdi	$s2,$s3,32,0
+
+	and	$acc00,$s0,$mask80	# r1=r0&0x80808080
+	and	$acc02,$s2,$mask80
+	srdi	$acc04,$acc00,7		# r1>>7
+	srdi	$acc06,$acc02,7
+	andc	$acc08,$s0,$mask80	# r0&0x7f7f7f7f
+	andc	$acc10,$s2,$mask80
+	sub	$acc00,$acc00,$acc04	# r1-(r1>>7)
+	sub	$acc02,$acc02,$acc06
+	add	$acc08,$acc08,$acc08	# (r0&0x7f7f7f7f)<<1
+	add	$acc10,$acc10,$acc10
+	and	$acc00,$acc00,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc02,$acc02,$mask1b
+	xor	$acc00,$acc00,$acc08	# r2
+	xor	$acc02,$acc02,$acc10
+
+	and	$acc04,$acc00,$mask80	# r1=r2&0x80808080
+	and	$acc06,$acc02,$mask80
+	srdi	$acc08,$acc04,7		# r1>>7
+	srdi	$acc10,$acc06,7
+	andc	$acc12,$acc00,$mask80	# r2&0x7f7f7f7f
+	andc	$acc14,$acc02,$mask80
+	sub	$acc04,$acc04,$acc08	# r1-(r1>>7)
+	sub	$acc06,$acc06,$acc10
+	add	$acc12,$acc12,$acc12	# (r2&0x7f7f7f7f)<<1
+	add	$acc14,$acc14,$acc14
+	and	$acc04,$acc04,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc06,$acc06,$mask1b
+	xor	$acc04,$acc04,$acc12	# r4
+	xor	$acc06,$acc06,$acc14
+
+	and	$acc08,$acc04,$mask80	# r1=r4&0x80808080
+	and	$acc10,$acc06,$mask80
+	srdi	$acc12,$acc08,7		# r1>>7
+	srdi	$acc14,$acc10,7
+	sub	$acc08,$acc08,$acc12	# r1-(r1>>7)
+	sub	$acc10,$acc10,$acc14
+	andc	$acc12,$acc04,$mask80	# r4&0x7f7f7f7f
+	andc	$acc14,$acc06,$mask80
+	add	$acc12,$acc12,$acc12	# (r4&0x7f7f7f7f)<<1
+	add	$acc14,$acc14,$acc14
+	and	$acc08,$acc08,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc10,$acc10,$mask1b
+	xor	$acc08,$acc08,$acc12	# r8
+	xor	$acc10,$acc10,$acc14
+
+	xor	$acc00,$acc00,$s0	# r2^r0
+	xor	$acc02,$acc02,$s2
+	xor	$acc04,$acc04,$s0	# r4^r0
+	xor	$acc06,$acc06,$s2
+
+	extrdi	$acc01,$acc00,32,0
+	extrdi	$acc03,$acc02,32,0
+	extrdi	$acc05,$acc04,32,0
+	extrdi	$acc07,$acc06,32,0
+	extrdi	$acc09,$acc08,32,0
+	extrdi	$acc11,$acc10,32,0
+___
+$code.=<<___ if ($SIZE_T==4);
+	and	$acc00,$s0,$mask80	# r1=r0&0x80808080
+	and	$acc01,$s1,$mask80
+	and	$acc02,$s2,$mask80
+	and	$acc03,$s3,$mask80
+	srwi	$acc04,$acc00,7		# r1>>7
+	srwi	$acc05,$acc01,7
+	srwi	$acc06,$acc02,7
+	srwi	$acc07,$acc03,7
+	andc	$acc08,$s0,$mask80	# r0&0x7f7f7f7f
+	andc	$acc09,$s1,$mask80
+	andc	$acc10,$s2,$mask80
+	andc	$acc11,$s3,$mask80
+	sub	$acc00,$acc00,$acc04	# r1-(r1>>7)
+	sub	$acc01,$acc01,$acc05
+	sub	$acc02,$acc02,$acc06
+	sub	$acc03,$acc03,$acc07
+	add	$acc08,$acc08,$acc08	# (r0&0x7f7f7f7f)<<1
+	add	$acc09,$acc09,$acc09
+	add	$acc10,$acc10,$acc10
+	add	$acc11,$acc11,$acc11
+	and	$acc00,$acc00,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc01,$acc01,$mask1b
+	and	$acc02,$acc02,$mask1b
+	and	$acc03,$acc03,$mask1b
+	xor	$acc00,$acc00,$acc08	# r2
+	xor	$acc01,$acc01,$acc09
+	xor	$acc02,$acc02,$acc10
+	xor	$acc03,$acc03,$acc11
+
+	and	$acc04,$acc00,$mask80	# r1=r2&0x80808080
+	and	$acc05,$acc01,$mask80
+	and	$acc06,$acc02,$mask80
+	and	$acc07,$acc03,$mask80
+	srwi	$acc08,$acc04,7		# r1>>7
+	srwi	$acc09,$acc05,7
+	srwi	$acc10,$acc06,7
+	srwi	$acc11,$acc07,7
+	andc	$acc12,$acc00,$mask80	# r2&0x7f7f7f7f
+	andc	$acc13,$acc01,$mask80
+	andc	$acc14,$acc02,$mask80
+	andc	$acc15,$acc03,$mask80
+	sub	$acc04,$acc04,$acc08	# r1-(r1>>7)
+	sub	$acc05,$acc05,$acc09
+	sub	$acc06,$acc06,$acc10
+	sub	$acc07,$acc07,$acc11
+	add	$acc12,$acc12,$acc12	# (r2&0x7f7f7f7f)<<1
+	add	$acc13,$acc13,$acc13
+	add	$acc14,$acc14,$acc14
+	add	$acc15,$acc15,$acc15
+	and	$acc04,$acc04,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc05,$acc05,$mask1b
+	and	$acc06,$acc06,$mask1b
+	and	$acc07,$acc07,$mask1b
+	xor	$acc04,$acc04,$acc12	# r4
+	xor	$acc05,$acc05,$acc13
+	xor	$acc06,$acc06,$acc14
+	xor	$acc07,$acc07,$acc15
+
+	and	$acc08,$acc04,$mask80	# r1=r4&0x80808080
+	and	$acc09,$acc05,$mask80
+	and	$acc10,$acc06,$mask80
+	and	$acc11,$acc07,$mask80
+	srwi	$acc12,$acc08,7		# r1>>7
+	srwi	$acc13,$acc09,7
+	srwi	$acc14,$acc10,7
+	srwi	$acc15,$acc11,7
+	sub	$acc08,$acc08,$acc12	# r1-(r1>>7)
+	sub	$acc09,$acc09,$acc13
+	sub	$acc10,$acc10,$acc14
+	sub	$acc11,$acc11,$acc15
+	andc	$acc12,$acc04,$mask80	# r4&0x7f7f7f7f
+	andc	$acc13,$acc05,$mask80
+	andc	$acc14,$acc06,$mask80
+	andc	$acc15,$acc07,$mask80
+	add	$acc12,$acc12,$acc12	# (r4&0x7f7f7f7f)<<1
+	add	$acc13,$acc13,$acc13
+	add	$acc14,$acc14,$acc14
+	add	$acc15,$acc15,$acc15
+	and	$acc08,$acc08,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc09,$acc09,$mask1b
+	and	$acc10,$acc10,$mask1b
+	and	$acc11,$acc11,$mask1b
+	xor	$acc08,$acc08,$acc12	# r8
+	xor	$acc09,$acc09,$acc13
+	xor	$acc10,$acc10,$acc14
+	xor	$acc11,$acc11,$acc15
+
+	xor	$acc00,$acc00,$s0	# r2^r0
+	xor	$acc01,$acc01,$s1
+	xor	$acc02,$acc02,$s2
+	xor	$acc03,$acc03,$s3
+	xor	$acc04,$acc04,$s0	# r4^r0
+	xor	$acc05,$acc05,$s1
+	xor	$acc06,$acc06,$s2
+	xor	$acc07,$acc07,$s3
+___
+$code.=<<___;
+	rotrwi	$s0,$s0,8		# = ROTATE(r0,8)
+	rotrwi	$s1,$s1,8
+	rotrwi	$s2,$s2,8
+	rotrwi	$s3,$s3,8
+	xor	$s0,$s0,$acc00		# ^= r2^r0
+	xor	$s1,$s1,$acc01
+	xor	$s2,$s2,$acc02
+	xor	$s3,$s3,$acc03
+	xor	$acc00,$acc00,$acc08
+	xor	$acc01,$acc01,$acc09
+	xor	$acc02,$acc02,$acc10
+	xor	$acc03,$acc03,$acc11
+	xor	$s0,$s0,$acc04		# ^= r4^r0
+	xor	$s1,$s1,$acc05
+	xor	$s2,$s2,$acc06
+	xor	$s3,$s3,$acc07
+	rotrwi	$acc00,$acc00,24
+	rotrwi	$acc01,$acc01,24
+	rotrwi	$acc02,$acc02,24
+	rotrwi	$acc03,$acc03,24
+	xor	$acc04,$acc04,$acc08
+	xor	$acc05,$acc05,$acc09
+	xor	$acc06,$acc06,$acc10
+	xor	$acc07,$acc07,$acc11
+	xor	$s0,$s0,$acc08		# ^= r8 [^((r4^r0)^(r2^r0)=r4^r2)]
+	xor	$s1,$s1,$acc09
+	xor	$s2,$s2,$acc10
+	xor	$s3,$s3,$acc11
+	rotrwi	$acc04,$acc04,16
+	rotrwi	$acc05,$acc05,16
+	rotrwi	$acc06,$acc06,16
+	rotrwi	$acc07,$acc07,16
+	xor	$s0,$s0,$acc00		# ^= ROTATE(r8^r2^r0,24)
+	xor	$s1,$s1,$acc01
+	xor	$s2,$s2,$acc02
+	xor	$s3,$s3,$acc03
+	rotrwi	$acc08,$acc08,8
+	rotrwi	$acc09,$acc09,8
+	rotrwi	$acc10,$acc10,8
+	rotrwi	$acc11,$acc11,8
+	xor	$s0,$s0,$acc04		# ^= ROTATE(r8^r4^r0,16)
+	xor	$s1,$s1,$acc05
+	xor	$s2,$s2,$acc06
+	xor	$s3,$s3,$acc07
+	xor	$s0,$s0,$acc08		# ^= ROTATE(r8,8)	
+	xor	$s1,$s1,$acc09	
+	xor	$s2,$s2,$acc10	
+	xor	$s3,$s3,$acc11	
+
+	b	Ldec_compact_loop
+.align	4
+Ldec_compact_done:
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	blr
+.long	0
+.asciz	"AES for PPC, CRYPTOGAMS by <appro\@openssl.org>"
+.align	7
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/crypto/aes/asm/aes-s390x.pl b/crypto/aes/asm/aes-s390x.pl
new file mode 100644
index 0000000..7e01889
--- /dev/null
+++ b/crypto/aes/asm/aes-s390x.pl
@@ -0,0 +1,1339 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# AES for s390x.
+
+# April 2007.
+#
+# Software performance improvement over gcc-generated code is ~70% and
+# in absolute terms is ~73 cycles per byte processed with 128-bit key.
+# You're likely to exclaim "why so slow?" Keep in mind that z-CPUs are
+# *strictly* in-order execution and issued instruction [in this case
+# load value from memory is critical] has to complete before execution
+# flow proceeds. S-boxes are compressed to 2KB[+256B].
+#
+# As for hardware acceleration support. It's basically a "teaser," as
+# it can and should be improved in several ways. Most notably support
+# for CBC is not utilized, nor multiple blocks are ever processed.
+# Then software key schedule can be postponed till hardware support
+# detection... Performance improvement over assembler is reportedly
+# ~2.5x, but can reach >8x [naturally on larger chunks] if proper
+# support is implemented.
+
+# May 2007.
+#
+# Implement AES_set_[en|de]crypt_key. Key schedule setup is avoided
+# for 128-bit keys, if hardware support is detected.
+
+# Januray 2009.
+#
+# Add support for hardware AES192/256 and reschedule instructions to
+# minimize/avoid Address Generation Interlock hazard and to favour
+# dual-issue z10 pipeline. This gave ~25% improvement on z10 and
+# almost 50% on z9. The gain is smaller on z10, because being dual-
+# issue z10 makes it improssible to eliminate the interlock condition:
+# critial path is not long enough. Yet it spends ~24 cycles per byte
+# processed with 128-bit key.
+#
+# Unlike previous version hardware support detection takes place only
+# at the moment of key schedule setup, which is denoted in key->rounds.
+# This is done, because deferred key setup can't be made MT-safe, not
+# for key lengthes longer than 128 bits.
+#
+# Add AES_cbc_encrypt, which gives incredible performance improvement,
+# it was measured to be ~6.6x. It's less than previously mentioned 8x,
+# because software implementation was optimized.
+
+$softonly=0;	# allow hardware support
+
+$t0="%r0";	$mask="%r0";
+$t1="%r1";
+$t2="%r2";	$inp="%r2";
+$t3="%r3";	$out="%r3";	$bits="%r3";
+$key="%r4";
+$i1="%r5";
+$i2="%r6";
+$i3="%r7";
+$s0="%r8";
+$s1="%r9";
+$s2="%r10";
+$s3="%r11";
+$tbl="%r12";
+$rounds="%r13";
+$ra="%r14";
+$sp="%r15";
+
+sub _data_word()
+{ my $i;
+    while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; }
+}
+
+$code=<<___;
+.text
+
+.type	AES_Te,\@object
+.align	256
+AES_Te:
+___
+&_data_word(
+	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
+	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
+	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
+	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
+	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
+	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
+	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
+	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
+	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
+	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
+	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
+	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
+	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
+	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
+	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
+	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
+	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
+	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
+	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
+	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
+	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
+	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
+	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
+	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
+	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
+	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
+	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
+	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
+	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
+	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
+	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
+	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
+	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
+	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
+	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
+	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
+	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
+	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
+	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
+	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
+	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
+	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
+	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
+	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
+	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
+	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
+	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
+	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
+	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
+	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
+	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
+	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
+	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
+	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
+	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
+	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
+	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
+	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
+	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
+	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
+	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
+	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
+	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
+	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
+$code.=<<___;
+# Te4[256]
+.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
+.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
+.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
+.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
+.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
+.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
+.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
+.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
+.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
+.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
+.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
+.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
+.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
+.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
+.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
+.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
+.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
+.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
+.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
+.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
+.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
+.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
+.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
+.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
+.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
+.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
+.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
+.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
+.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
+.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
+.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
+.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+# rcon[]
+.long	0x01000000, 0x02000000, 0x04000000, 0x08000000
+.long	0x10000000, 0x20000000, 0x40000000, 0x80000000
+.long	0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
+.align	256
+.size	AES_Te,.-AES_Te
+
+# void AES_encrypt(const unsigned char *inp, unsigned char *out,
+# 		 const AES_KEY *key) {
+.globl	AES_encrypt
+.type	AES_encrypt,\@function
+AES_encrypt:
+___
+$code.=<<___ if (!$softonly);
+	l	%r0,240($key)
+	lhi	%r1,16
+	clr	%r0,%r1
+	jl	.Lesoft
+
+	la	%r1,0($key)
+	#la	%r2,0($inp)
+	la	%r4,0($out)
+	lghi	%r3,16		# single block length
+	.long	0xb92e0042	# km %r4,%r2
+	brc	1,.-4		# can this happen?
+	br	%r14
+.align	64
+.Lesoft:
+___
+$code.=<<___;
+	stmg	%r3,$ra,24($sp)
+
+	llgf	$s0,0($inp)
+	llgf	$s1,4($inp)
+	llgf	$s2,8($inp)
+	llgf	$s3,12($inp)
+
+	larl	$tbl,AES_Te
+	bras	$ra,_s390x_AES_encrypt
+
+	lg	$out,24($sp)
+	st	$s0,0($out)
+	st	$s1,4($out)
+	st	$s2,8($out)
+	st	$s3,12($out)
+
+	lmg	%r6,$ra,48($sp)
+	br	$ra
+.size	AES_encrypt,.-AES_encrypt
+
+.type   _s390x_AES_encrypt,\@function
+.align	16
+_s390x_AES_encrypt:
+	stg	$ra,152($sp)
+	x	$s0,0($key)
+	x	$s1,4($key)
+	x	$s2,8($key)
+	x	$s3,12($key)
+	l	$rounds,240($key)
+	llill	$mask,`0xff<<3`
+	aghi	$rounds,-1
+	j	.Lenc_loop
+.align	16
+.Lenc_loop:
+	sllg	$t1,$s0,`0+3`
+	srlg	$t2,$s0,`8-3`
+	srlg	$t3,$s0,`16-3`
+	srl	$s0,`24-3`
+	nr	$s0,$mask
+	ngr	$t1,$mask
+	nr	$t2,$mask
+	nr	$t3,$mask
+
+	srlg	$i1,$s1,`16-3`	# i0
+	sllg	$i2,$s1,`0+3`
+	srlg	$i3,$s1,`8-3`
+	srl	$s1,`24-3`
+	nr	$i1,$mask
+	nr	$s1,$mask
+	ngr	$i2,$mask
+	nr	$i3,$mask
+
+	l	$s0,0($s0,$tbl)	# Te0[s0>>24]
+	l	$t1,1($t1,$tbl)	# Te3[s0>>0]
+	l	$t2,2($t2,$tbl) # Te2[s0>>8]
+	l	$t3,3($t3,$tbl)	# Te1[s0>>16]
+
+	x	$s0,3($i1,$tbl)	# Te1[s1>>16]
+	l	$s1,0($s1,$tbl)	# Te0[s1>>24]
+	x	$t2,1($i2,$tbl)	# Te3[s1>>0]
+	x	$t3,2($i3,$tbl)	# Te2[s1>>8]
+
+	srlg	$i1,$s2,`8-3`	# i0
+	srlg	$i2,$s2,`16-3`	# i1
+	nr	$i1,$mask
+	nr	$i2,$mask
+	sllg	$i3,$s2,`0+3`
+	srl	$s2,`24-3`
+	nr	$s2,$mask
+	ngr	$i3,$mask
+
+	xr	$s1,$t1
+	srlg	$ra,$s3,`8-3`	# i1
+	sllg	$t1,$s3,`0+3`	# i0
+	nr	$ra,$mask
+	la	$key,16($key)
+	ngr	$t1,$mask
+
+	x	$s0,2($i1,$tbl)	# Te2[s2>>8]
+	x	$s1,3($i2,$tbl)	# Te1[s2>>16]
+	l	$s2,0($s2,$tbl)	# Te0[s2>>24]
+	x	$t3,1($i3,$tbl)	# Te3[s2>>0]
+
+	srlg	$i3,$s3,`16-3`	# i2
+	xr	$s2,$t2
+	srl	$s3,`24-3`
+	nr	$i3,$mask
+	nr	$s3,$mask
+
+	x	$s0,0($key)
+	x	$s1,4($key)
+	x	$s2,8($key)
+	x	$t3,12($key)
+
+	x	$s0,1($t1,$tbl)	# Te3[s3>>0]
+	x	$s1,2($ra,$tbl)	# Te2[s3>>8]
+	x	$s2,3($i3,$tbl)	# Te1[s3>>16]
+	l	$s3,0($s3,$tbl)	# Te0[s3>>24]
+	xr	$s3,$t3
+
+	brct	$rounds,.Lenc_loop
+	.align	16
+
+	sllg	$t1,$s0,`0+3`
+	srlg	$t2,$s0,`8-3`
+	ngr	$t1,$mask
+	srlg	$t3,$s0,`16-3`
+	srl	$s0,`24-3`
+	nr	$s0,$mask
+	nr	$t2,$mask
+	nr	$t3,$mask
+
+	srlg	$i1,$s1,`16-3`	# i0
+	sllg	$i2,$s1,`0+3`
+	ngr	$i2,$mask
+	srlg	$i3,$s1,`8-3`
+	srl	$s1,`24-3`
+	nr	$i1,$mask
+	nr	$s1,$mask
+	nr	$i3,$mask
+
+	llgc	$s0,2($s0,$tbl)	# Te4[s0>>24]
+	llgc	$t1,2($t1,$tbl)	# Te4[s0>>0]
+	sll	$s0,24
+	llgc	$t2,2($t2,$tbl)	# Te4[s0>>8]
+	llgc	$t3,2($t3,$tbl)	# Te4[s0>>16]
+	sll	$t2,8
+	sll	$t3,16
+
+	llgc	$i1,2($i1,$tbl)	# Te4[s1>>16]
+	llgc	$s1,2($s1,$tbl)	# Te4[s1>>24]
+	llgc	$i2,2($i2,$tbl)	# Te4[s1>>0]
+	llgc	$i3,2($i3,$tbl)	# Te4[s1>>8]
+	sll	$i1,16
+	sll	$s1,24
+	sll	$i3,8
+	or	$s0,$i1
+	or	$s1,$t1
+	or	$t2,$i2
+	or	$t3,$i3
+	
+	srlg	$i1,$s2,`8-3`	# i0
+	srlg	$i2,$s2,`16-3`	# i1
+	nr	$i1,$mask
+	nr	$i2,$mask
+	sllg	$i3,$s2,`0+3`
+	srl	$s2,`24-3`
+	ngr	$i3,$mask
+	nr	$s2,$mask
+
+	sllg	$t1,$s3,`0+3`	# i0
+	srlg	$ra,$s3,`8-3`	# i1
+	ngr	$t1,$mask
+
+	llgc	$i1,2($i1,$tbl)	# Te4[s2>>8]
+	llgc	$i2,2($i2,$tbl)	# Te4[s2>>16]
+	sll	$i1,8
+	llgc	$s2,2($s2,$tbl)	# Te4[s2>>24]
+	llgc	$i3,2($i3,$tbl)	# Te4[s2>>0]
+	sll	$i2,16
+	nr	$ra,$mask
+	sll	$s2,24
+	or	$s0,$i1
+	or	$s1,$i2
+	or	$s2,$t2
+	or	$t3,$i3
+
+	srlg	$i3,$s3,`16-3`	# i2
+	srl	$s3,`24-3`
+	nr	$i3,$mask
+	nr	$s3,$mask
+
+	l	$t0,16($key)
+	l	$t2,20($key)
+
+	llgc	$i1,2($t1,$tbl)	# Te4[s3>>0]
+	llgc	$i2,2($ra,$tbl)	# Te4[s3>>8]
+	llgc	$i3,2($i3,$tbl)	# Te4[s3>>16]
+	llgc	$s3,2($s3,$tbl)	# Te4[s3>>24]
+	sll	$i2,8
+	sll	$i3,16
+	sll	$s3,24
+	or	$s0,$i1
+	or	$s1,$i2
+	or	$s2,$i3
+	or	$s3,$t3
+
+	lg	$ra,152($sp)
+	xr	$s0,$t0
+	xr	$s1,$t2
+	x	$s2,24($key)
+	x	$s3,28($key)
+
+	br	$ra	
+.size	_s390x_AES_encrypt,.-_s390x_AES_encrypt
+___
+
+$code.=<<___;
+.type	AES_Td,\@object
+.align	256
+AES_Td:
+___
+&_data_word(
+	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
+	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
+	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
+	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
+	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
+	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
+	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
+	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
+	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
+	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
+	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
+	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
+	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
+	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
+	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
+	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
+	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
+	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
+	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
+	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
+	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
+	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
+	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
+	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
+	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
+	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
+	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
+	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
+	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
+	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
+	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
+	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
+	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
+	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
+	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
+	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
+	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
+	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
+	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
+	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
+	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
+	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
+	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
+	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
+	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
+	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
+	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
+	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
+	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
+	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
+	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
+	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
+	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
+	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
+	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
+	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
+	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
+	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
+	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
+	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
+	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
+	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
+	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
+	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
+$code.=<<___;
+# Td4[256]
+.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
+.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
+.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
+.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
+.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
+.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
+.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
+.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
+.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
+.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
+.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
+.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
+.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
+.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
+.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
+.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
+.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+.size	AES_Td,.-AES_Td
+
+# void AES_decrypt(const unsigned char *inp, unsigned char *out,
+# 		 const AES_KEY *key) {
+.globl	AES_decrypt
+.type	AES_decrypt,\@function
+AES_decrypt:
+___
+$code.=<<___ if (!$softonly);
+	l	%r0,240($key)
+	lhi	%r1,16
+	clr	%r0,%r1
+	jl	.Ldsoft
+
+	la	%r1,0($key)
+	#la	%r2,0($inp)
+	la	%r4,0($out)
+	lghi	%r3,16		# single block length
+	.long	0xb92e0042	# km %r4,%r2
+	brc	1,.-4		# can this happen?
+	br	%r14
+.align	64
+.Ldsoft:
+___
+$code.=<<___;
+	stmg	%r3,$ra,24($sp)
+
+	llgf	$s0,0($inp)
+	llgf	$s1,4($inp)
+	llgf	$s2,8($inp)
+	llgf	$s3,12($inp)
+
+	larl	$tbl,AES_Td
+	bras	$ra,_s390x_AES_decrypt
+
+	lg	$out,24($sp)
+	st	$s0,0($out)
+	st	$s1,4($out)
+	st	$s2,8($out)
+	st	$s3,12($out)
+
+	lmg	%r6,$ra,48($sp)
+	br	$ra
+.size	AES_decrypt,.-AES_decrypt
+
+.type   _s390x_AES_decrypt,\@function
+.align	16
+_s390x_AES_decrypt:
+	stg	$ra,152($sp)
+	x	$s0,0($key)
+	x	$s1,4($key)
+	x	$s2,8($key)
+	x	$s3,12($key)
+	l	$rounds,240($key)
+	llill	$mask,`0xff<<3`
+	aghi	$rounds,-1
+	j	.Ldec_loop
+.align	16
+.Ldec_loop:
+	srlg	$t1,$s0,`16-3`
+	srlg	$t2,$s0,`8-3`
+	sllg	$t3,$s0,`0+3`
+	srl	$s0,`24-3`
+	nr	$s0,$mask
+	nr	$t1,$mask
+	nr	$t2,$mask
+	ngr	$t3,$mask
+
+	sllg	$i1,$s1,`0+3`	# i0
+	srlg	$i2,$s1,`16-3`
+	srlg	$i3,$s1,`8-3`
+	srl	$s1,`24-3`
+	ngr	$i1,$mask
+	nr	$s1,$mask
+	nr	$i2,$mask
+	nr	$i3,$mask
+
+	l	$s0,0($s0,$tbl)	# Td0[s0>>24]
+	l	$t1,3($t1,$tbl)	# Td1[s0>>16]
+	l	$t2,2($t2,$tbl)	# Td2[s0>>8]
+	l	$t3,1($t3,$tbl)	# Td3[s0>>0]
+
+	x	$s0,1($i1,$tbl)	# Td3[s1>>0]
+	l	$s1,0($s1,$tbl)	# Td0[s1>>24]
+	x	$t2,3($i2,$tbl)	# Td1[s1>>16]
+	x	$t3,2($i3,$tbl)	# Td2[s1>>8]
+
+	srlg	$i1,$s2,`8-3`	# i0
+	sllg	$i2,$s2,`0+3`	# i1
+	srlg	$i3,$s2,`16-3`
+	srl	$s2,`24-3`
+	nr	$i1,$mask
+	ngr	$i2,$mask
+	nr	$s2,$mask
+	nr	$i3,$mask
+
+	xr	$s1,$t1
+	srlg	$ra,$s3,`8-3`	# i1
+	srlg	$t1,$s3,`16-3`	# i0
+	nr	$ra,$mask
+	la	$key,16($key)
+	nr	$t1,$mask
+
+	x	$s0,2($i1,$tbl)	# Td2[s2>>8]
+	x	$s1,1($i2,$tbl)	# Td3[s2>>0]
+	l	$s2,0($s2,$tbl)	# Td0[s2>>24]
+	x	$t3,3($i3,$tbl)	# Td1[s2>>16]
+
+	sllg	$i3,$s3,`0+3`	# i2
+	srl	$s3,`24-3`
+	ngr	$i3,$mask
+	nr	$s3,$mask
+
+	xr	$s2,$t2
+	x	$s0,0($key)
+	x	$s1,4($key)
+	x	$s2,8($key)
+	x	$t3,12($key)
+
+	x	$s0,3($t1,$tbl)	# Td1[s3>>16]
+	x	$s1,2($ra,$tbl)	# Td2[s3>>8]
+	x	$s2,1($i3,$tbl)	# Td3[s3>>0]
+	l	$s3,0($s3,$tbl)	# Td0[s3>>24]
+	xr	$s3,$t3
+
+	brct	$rounds,.Ldec_loop
+	.align	16
+
+	l	$t1,`2048+0`($tbl)	# prefetch Td4
+	l	$t2,`2048+64`($tbl)
+	l	$t3,`2048+128`($tbl)
+	l	$i1,`2048+192`($tbl)
+	llill	$mask,0xff
+
+	srlg	$i3,$s0,24	# i0
+	srlg	$t1,$s0,16
+	srlg	$t2,$s0,8
+	nr	$s0,$mask	# i3
+	nr	$t1,$mask
+
+	srlg	$i1,$s1,24
+	nr	$t2,$mask
+	srlg	$i2,$s1,16
+	srlg	$ra,$s1,8
+	nr	$s1,$mask	# i0
+	nr	$i2,$mask
+	nr	$ra,$mask
+
+	llgc	$i3,2048($i3,$tbl)	# Td4[s0>>24]
+	llgc	$t1,2048($t1,$tbl)	# Td4[s0>>16]
+	llgc	$t2,2048($t2,$tbl)	# Td4[s0>>8]
+	sll	$t1,16
+	llgc	$t3,2048($s0,$tbl)	# Td4[s0>>0]
+	sllg	$s0,$i3,24
+	sll	$t2,8
+
+	llgc	$s1,2048($s1,$tbl)	# Td4[s1>>0]
+	llgc	$i1,2048($i1,$tbl)	# Td4[s1>>24]
+	llgc	$i2,2048($i2,$tbl)	# Td4[s1>>16]
+	sll	$i1,24
+	llgc	$i3,2048($ra,$tbl)	# Td4[s1>>8]
+	sll	$i2,16
+	sll	$i3,8
+	or	$s0,$s1
+	or	$t1,$i1
+	or	$t2,$i2
+	or	$t3,$i3
+
+	srlg	$i1,$s2,8	# i0
+	srlg	$i2,$s2,24
+	srlg	$i3,$s2,16
+	nr	$s2,$mask	# i1
+	nr	$i1,$mask
+	nr	$i3,$mask
+	llgc	$i1,2048($i1,$tbl)	# Td4[s2>>8]
+	llgc	$s1,2048($s2,$tbl)	# Td4[s2>>0]
+	llgc	$i2,2048($i2,$tbl)	# Td4[s2>>24]
+	llgc	$i3,2048($i3,$tbl)	# Td4[s2>>16]
+	sll	$i1,8
+	sll	$i2,24
+	or	$s0,$i1
+	sll	$i3,16
+	or	$t2,$i2
+	or	$t3,$i3
+
+	srlg	$i1,$s3,16	# i0
+	srlg	$i2,$s3,8	# i1
+	srlg	$i3,$s3,24
+	nr	$s3,$mask	# i2
+	nr	$i1,$mask
+	nr	$i2,$mask
+
+	lg	$ra,152($sp)
+	or	$s1,$t1
+	l	$t0,16($key)
+	l	$t1,20($key)
+
+	llgc	$i1,2048($i1,$tbl)	# Td4[s3>>16]
+	llgc	$i2,2048($i2,$tbl)	# Td4[s3>>8]
+	sll	$i1,16
+	llgc	$s2,2048($s3,$tbl)	# Td4[s3>>0]
+	llgc	$s3,2048($i3,$tbl)	# Td4[s3>>24]
+	sll	$i2,8
+	sll	$s3,24
+	or	$s0,$i1
+	or	$s1,$i2
+	or	$s2,$t2
+	or	$s3,$t3
+
+	xr	$s0,$t0
+	xr	$s1,$t1
+	x	$s2,24($key)
+	x	$s3,28($key)
+
+	br	$ra	
+.size	_s390x_AES_decrypt,.-_s390x_AES_decrypt
+___
+
+$code.=<<___;
+# void AES_set_encrypt_key(const unsigned char *in, int bits,
+# 		 AES_KEY *key) {
+.globl	AES_set_encrypt_key
+.type	AES_set_encrypt_key,\@function
+.align	16
+AES_set_encrypt_key:
+	lghi	$t0,0
+	clgr	$inp,$t0
+	je	.Lminus1
+	clgr	$key,$t0
+	je	.Lminus1
+
+	lghi	$t0,128
+	clr	$bits,$t0
+	je	.Lproceed
+	lghi	$t0,192
+	clr	$bits,$t0
+	je	.Lproceed
+	lghi	$t0,256
+	clr	$bits,$t0
+	je	.Lproceed
+	lghi	%r2,-2
+	br	%r14
+
+.align	16
+.Lproceed:
+___
+$code.=<<___ if (!$softonly);
+	# convert bits to km code, [128,192,256]->[18,19,20]
+	lhi	%r5,-128
+	lhi	%r0,18
+	ar	%r5,$bits
+	srl	%r5,6
+	ar	%r5,%r0
+
+	larl	%r1,OPENSSL_s390xcap_P
+	lg	%r0,0(%r1)
+	tmhl	%r0,0x4000	# check for message-security assist
+	jz	.Lekey_internal
+
+	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
+.comm  OPENSSL_s390xcap_P,8,8
+___
+}
+$code.=<<___;
+.string	"AES for s390x, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
diff --git a/crypto/aes/asm/aes-sparcv9.pl b/crypto/aes/asm/aes-sparcv9.pl
new file mode 100755
index 0000000..c57b3a2
--- /dev/null
+++ b/crypto/aes/asm/aes-sparcv9.pl
@@ -0,0 +1,1181 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. Rights for redistribution and usage in source and binary
+# forms are granted according to the OpenSSL license.
+# ====================================================================
+#
+# Version 1.1
+#
+# The major reason for undertaken effort was to mitigate the hazard of
+# cache-timing attack. This is [currently and initially!] addressed in
+# two ways. 1. S-boxes are compressed from 5KB to 2KB+256B size each.
+# 2. References to them are scheduled for L2 cache latency, meaning
+# that the tables don't have to reside in L1 cache. Once again, this
+# is an initial draft and one should expect more countermeasures to
+# be implemented...
+#
+# Version 1.1 prefetches T[ed]4 in order to mitigate attack on last
+# round.
+#
+# Even though performance was not the primary goal [on the contrary,
+# extra shifts "induced" by compressed S-box and longer loop epilogue
+# "induced" by scheduling for L2 have negative effect on performance],
+# the code turned out to run in ~23 cycles per processed byte en-/
+# decrypted with 128-bit key. This is pretty good result for code
+# with mentioned qualities and UltraSPARC core. Compared to Sun C
+# generated code my encrypt procedure runs just few percents faster,
+# while decrypt one - whole 50% faster [yes, Sun C failed to generate
+# optimal decrypt procedure]. Compared to GNU C generated code both
+# procedures are more than 60% faster:-)
+
+$bits=32;
+for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
+if ($bits==64)	{ $bias=2047; $frame=192; }
+else		{ $bias=0;    $frame=112; }
+$locals=16;
+
+$acc0="%l0";
+$acc1="%o0";
+$acc2="%o1";
+$acc3="%o2";
+
+$acc4="%l1";
+$acc5="%o3";
+$acc6="%o4";
+$acc7="%o5";
+
+$acc8="%l2";
+$acc9="%o7";
+$acc10="%g1";
+$acc11="%g2";
+
+$acc12="%l3";
+$acc13="%g3";
+$acc14="%g4";
+$acc15="%g5";
+
+$t0="%l4";
+$t1="%l5";
+$t2="%l6";
+$t3="%l7";
+
+$s0="%i0";
+$s1="%i1";
+$s2="%i2";
+$s3="%i3";
+$tbl="%i4";
+$key="%i5";
+$rounds="%i7";	# aliases with return address, which is off-loaded to stack
+
+sub _data_word()
+{ my $i;
+    while(defined($i=shift)) { $code.=sprintf"\t.long\t0x%08x,0x%08x\n",$i,$i; }
+}
+
+$code.=<<___ if ($bits==64);
+.register	%g2,#scratch
+.register	%g3,#scratch
+___
+$code.=<<___;
+.section	".text",#alloc,#execinstr
+
+.align	256
+AES_Te:
+___
+&_data_word(
+	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
+	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
+	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
+	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
+	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
+	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
+	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
+	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
+	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
+	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
+	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
+	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
+	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
+	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
+	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
+	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
+	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
+	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
+	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
+	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
+	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
+	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
+	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
+	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
+	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
+	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
+	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
+	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
+	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
+	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
+	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
+	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
+	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
+	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
+	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
+	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
+	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
+	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
+	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
+	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
+	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
+	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
+	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
+	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
+	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
+	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
+	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
+	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
+	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
+	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
+	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
+	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
+	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
+	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
+	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
+	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
+	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
+	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
+	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
+	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
+	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
+	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
+	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
+	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
+$code.=<<___;
+	.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
+	.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
+	.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
+	.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
+	.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
+	.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
+	.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
+	.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
+	.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
+	.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
+	.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
+	.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
+	.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
+	.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
+	.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
+	.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
+	.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
+	.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
+	.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
+	.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
+	.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
+	.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
+	.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
+	.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
+	.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
+	.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
+	.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
+	.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
+	.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
+	.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
+	.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
+	.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+.type	AES_Te,#object
+.size	AES_Te,(.-AES_Te)
+
+.align	64
+.skip	16
+_sparcv9_AES_encrypt:
+	save	%sp,-$frame-$locals,%sp
+	stx	%i7,[%sp+$bias+$frame+0]	! off-load return address
+	ld	[$key+240],$rounds
+	ld	[$key+0],$t0
+	ld	[$key+4],$t1			!
+	ld	[$key+8],$t2
+	srl	$rounds,1,$rounds
+	xor	$t0,$s0,$s0
+	ld	[$key+12],$t3
+	srl	$s0,21,$acc0
+	xor	$t1,$s1,$s1
+	ld	[$key+16],$t0
+	srl	$s1,13,$acc1			!
+	xor	$t2,$s2,$s2
+	ld	[$key+20],$t1
+	xor	$t3,$s3,$s3
+	ld	[$key+24],$t2
+	and	$acc0,2040,$acc0
+	ld	[$key+28],$t3
+	nop
+.Lenc_loop:
+	srl	$s2,5,$acc2			!
+	and	$acc1,2040,$acc1
+	ldx	[$tbl+$acc0],$acc0
+	sll	$s3,3,$acc3
+	and	$acc2,2040,$acc2
+	ldx	[$tbl+$acc1],$acc1
+	srl	$s1,21,$acc4
+	and	$acc3,2040,$acc3
+	ldx	[$tbl+$acc2],$acc2		!
+	srl	$s2,13,$acc5
+	and	$acc4,2040,$acc4
+	ldx	[$tbl+$acc3],$acc3
+	srl	$s3,5,$acc6
+	and	$acc5,2040,$acc5
+	ldx	[$tbl+$acc4],$acc4
+	fmovs	%f0,%f0
+	sll	$s0,3,$acc7			!
+	and	$acc6,2040,$acc6
+	ldx	[$tbl+$acc5],$acc5
+	srl	$s2,21,$acc8
+	and	$acc7,2040,$acc7
+	ldx	[$tbl+$acc6],$acc6
+	srl	$s3,13,$acc9
+	and	$acc8,2040,$acc8
+	ldx	[$tbl+$acc7],$acc7		!
+	srl	$s0,5,$acc10
+	and	$acc9,2040,$acc9
+	ldx	[$tbl+$acc8],$acc8
+	sll	$s1,3,$acc11
+	and	$acc10,2040,$acc10
+	ldx	[$tbl+$acc9],$acc9
+	fmovs	%f0,%f0
+	srl	$s3,21,$acc12			!
+	and	$acc11,2040,$acc11
+	ldx	[$tbl+$acc10],$acc10
+	srl	$s0,13,$acc13
+	and	$acc12,2040,$acc12
+	ldx	[$tbl+$acc11],$acc11
+	srl	$s1,5,$acc14
+	and	$acc13,2040,$acc13
+	ldx	[$tbl+$acc12],$acc12		!
+	sll	$s2,3,$acc15
+	and	$acc14,2040,$acc14
+	ldx	[$tbl+$acc13],$acc13
+	and	$acc15,2040,$acc15
+	add	$key,32,$key
+	ldx	[$tbl+$acc14],$acc14
+	fmovs	%f0,%f0
+	subcc	$rounds,1,$rounds		!
+	ldx	[$tbl+$acc15],$acc15
+	bz,a,pn	%icc,.Lenc_last
+	add	$tbl,2048,$rounds
+
+		srlx	$acc1,8,$acc1
+		xor	$acc0,$t0,$t0
+	ld	[$key+0],$s0
+	fmovs	%f0,%f0
+		srlx	$acc2,16,$acc2		!
+		xor	$acc1,$t0,$t0
+	ld	[$key+4],$s1
+		srlx	$acc3,24,$acc3
+		xor	$acc2,$t0,$t0
+	ld	[$key+8],$s2
+		srlx	$acc5,8,$acc5
+		xor	$acc3,$t0,$t0
+	ld	[$key+12],$s3			!
+		srlx	$acc6,16,$acc6
+		xor	$acc4,$t1,$t1
+	fmovs	%f0,%f0
+		srlx	$acc7,24,$acc7
+		xor	$acc5,$t1,$t1
+		srlx	$acc9,8,$acc9
+		xor	$acc6,$t1,$t1
+		srlx	$acc10,16,$acc10	!
+		xor	$acc7,$t1,$t1
+		srlx	$acc11,24,$acc11
+		xor	$acc8,$t2,$t2
+		srlx	$acc13,8,$acc13
+		xor	$acc9,$t2,$t2
+		srlx	$acc14,16,$acc14
+		xor	$acc10,$t2,$t2
+		srlx	$acc15,24,$acc15	!
+		xor	$acc11,$t2,$t2
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$t3,$t3
+	srl	$t0,21,$acc0
+		xor	$acc14,$t3,$t3
+	srl	$t1,13,$acc1
+		xor	$acc15,$t3,$t3
+
+	and	$acc0,2040,$acc0		!
+	srl	$t2,5,$acc2
+	and	$acc1,2040,$acc1
+	ldx	[$tbl+$acc0],$acc0
+	sll	$t3,3,$acc3
+	and	$acc2,2040,$acc2
+	ldx	[$tbl+$acc1],$acc1
+	fmovs	%f0,%f0
+	srl	$t1,21,$acc4			!
+	and	$acc3,2040,$acc3
+	ldx	[$tbl+$acc2],$acc2
+	srl	$t2,13,$acc5
+	and	$acc4,2040,$acc4
+	ldx	[$tbl+$acc3],$acc3
+	srl	$t3,5,$acc6
+	and	$acc5,2040,$acc5
+	ldx	[$tbl+$acc4],$acc4		!
+	sll	$t0,3,$acc7
+	and	$acc6,2040,$acc6
+	ldx	[$tbl+$acc5],$acc5
+	srl	$t2,21,$acc8
+	and	$acc7,2040,$acc7
+	ldx	[$tbl+$acc6],$acc6
+	fmovs	%f0,%f0
+	srl	$t3,13,$acc9			!
+	and	$acc8,2040,$acc8
+	ldx	[$tbl+$acc7],$acc7
+	srl	$t0,5,$acc10
+	and	$acc9,2040,$acc9
+	ldx	[$tbl+$acc8],$acc8
+	sll	$t1,3,$acc11
+	and	$acc10,2040,$acc10
+	ldx	[$tbl+$acc9],$acc9		!
+	srl	$t3,21,$acc12
+	and	$acc11,2040,$acc11
+	ldx	[$tbl+$acc10],$acc10
+	srl	$t0,13,$acc13
+	and	$acc12,2040,$acc12
+	ldx	[$tbl+$acc11],$acc11
+	fmovs	%f0,%f0
+	srl	$t1,5,$acc14			!
+	and	$acc13,2040,$acc13
+	ldx	[$tbl+$acc12],$acc12
+	sll	$t2,3,$acc15
+	and	$acc14,2040,$acc14
+	ldx	[$tbl+$acc13],$acc13
+		srlx	$acc1,8,$acc1
+	and	$acc15,2040,$acc15
+	ldx	[$tbl+$acc14],$acc14		!
+
+		srlx	$acc2,16,$acc2
+		xor	$acc0,$s0,$s0
+	ldx	[$tbl+$acc15],$acc15
+		srlx	$acc3,24,$acc3
+		xor	$acc1,$s0,$s0
+	ld	[$key+16],$t0
+	fmovs	%f0,%f0
+		srlx	$acc5,8,$acc5		!
+		xor	$acc2,$s0,$s0
+	ld	[$key+20],$t1
+		srlx	$acc6,16,$acc6
+		xor	$acc3,$s0,$s0
+	ld	[$key+24],$t2
+		srlx	$acc7,24,$acc7
+		xor	$acc4,$s1,$s1
+	ld	[$key+28],$t3			!
+		srlx	$acc9,8,$acc9
+		xor	$acc5,$s1,$s1
+	ldx	[$tbl+2048+0],%g0		! prefetch te4
+		srlx	$acc10,16,$acc10
+		xor	$acc6,$s1,$s1
+	ldx	[$tbl+2048+32],%g0		! prefetch te4
+		srlx	$acc11,24,$acc11
+		xor	$acc7,$s1,$s1
+	ldx	[$tbl+2048+64],%g0		! prefetch te4
+		srlx	$acc13,8,$acc13
+		xor	$acc8,$s2,$s2
+	ldx	[$tbl+2048+96],%g0		! prefetch te4
+		srlx	$acc14,16,$acc14	!
+		xor	$acc9,$s2,$s2
+	ldx	[$tbl+2048+128],%g0		! prefetch te4
+		srlx	$acc15,24,$acc15
+		xor	$acc10,$s2,$s2
+	ldx	[$tbl+2048+160],%g0		! prefetch te4
+	srl	$s0,21,$acc0
+		xor	$acc11,$s2,$s2
+	ldx	[$tbl+2048+192],%g0		! prefetch te4
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$s3,$s3
+	ldx	[$tbl+2048+224],%g0		! prefetch te4
+	srl	$s1,13,$acc1			!
+		xor	$acc14,$s3,$s3
+		xor	$acc15,$s3,$s3
+	ba	.Lenc_loop
+	and	$acc0,2040,$acc0
+
+.align	32
+.Lenc_last:
+		srlx	$acc1,8,$acc1		!
+		xor	$acc0,$t0,$t0
+	ld	[$key+0],$s0
+		srlx	$acc2,16,$acc2
+		xor	$acc1,$t0,$t0
+	ld	[$key+4],$s1
+		srlx	$acc3,24,$acc3
+		xor	$acc2,$t0,$t0
+	ld	[$key+8],$s2			!
+		srlx	$acc5,8,$acc5
+		xor	$acc3,$t0,$t0
+	ld	[$key+12],$s3
+		srlx	$acc6,16,$acc6
+		xor	$acc4,$t1,$t1
+		srlx	$acc7,24,$acc7
+		xor	$acc5,$t1,$t1
+		srlx	$acc9,8,$acc9		!
+		xor	$acc6,$t1,$t1
+		srlx	$acc10,16,$acc10
+		xor	$acc7,$t1,$t1
+		srlx	$acc11,24,$acc11
+		xor	$acc8,$t2,$t2
+		srlx	$acc13,8,$acc13
+		xor	$acc9,$t2,$t2
+		srlx	$acc14,16,$acc14	!
+		xor	$acc10,$t2,$t2
+		srlx	$acc15,24,$acc15
+		xor	$acc11,$t2,$t2
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$t3,$t3
+	srl	$t0,24,$acc0
+		xor	$acc14,$t3,$t3
+	srl	$t1,16,$acc1			!
+		xor	$acc15,$t3,$t3
+
+	srl	$t2,8,$acc2
+	and	$acc1,255,$acc1
+	ldub	[$rounds+$acc0],$acc0
+	srl	$t1,24,$acc4
+	and	$acc2,255,$acc2
+	ldub	[$rounds+$acc1],$acc1
+	srl	$t2,16,$acc5			!
+	and	$t3,255,$acc3
+	ldub	[$rounds+$acc2],$acc2
+	ldub	[$rounds+$acc3],$acc3
+	srl	$t3,8,$acc6
+	and	$acc5,255,$acc5
+	ldub	[$rounds+$acc4],$acc4
+	fmovs	%f0,%f0
+	srl	$t2,24,$acc8			!
+	and	$acc6,255,$acc6
+	ldub	[$rounds+$acc5],$acc5
+	srl	$t3,16,$acc9
+	and	$t0,255,$acc7
+	ldub	[$rounds+$acc6],$acc6
+	ldub	[$rounds+$acc7],$acc7
+	fmovs	%f0,%f0
+	srl	$t0,8,$acc10			!
+	and	$acc9,255,$acc9
+	ldub	[$rounds+$acc8],$acc8
+	srl	$t3,24,$acc12
+	and	$acc10,255,$acc10
+	ldub	[$rounds+$acc9],$acc9
+	srl	$t0,16,$acc13
+	and	$t1,255,$acc11
+	ldub	[$rounds+$acc10],$acc10		!
+	srl	$t1,8,$acc14
+	and	$acc13,255,$acc13
+	ldub	[$rounds+$acc11],$acc11
+	ldub	[$rounds+$acc12],$acc12
+	and	$acc14,255,$acc14
+	ldub	[$rounds+$acc13],$acc13
+	and	$t2,255,$acc15
+	ldub	[$rounds+$acc14],$acc14		!
+
+		sll	$acc0,24,$acc0
+		xor	$acc3,$s0,$s0
+	ldub	[$rounds+$acc15],$acc15
+		sll	$acc1,16,$acc1
+		xor	$acc0,$s0,$s0
+	ldx	[%sp+$bias+$frame+0],%i7	! restore return address
+	fmovs	%f0,%f0
+		sll	$acc2,8,$acc2		!
+		xor	$acc1,$s0,$s0
+		sll	$acc4,24,$acc4
+		xor	$acc2,$s0,$s0
+		sll	$acc5,16,$acc5
+		xor	$acc7,$s1,$s1
+		sll	$acc6,8,$acc6
+		xor	$acc4,$s1,$s1
+		sll	$acc8,24,$acc8		!
+		xor	$acc5,$s1,$s1
+		sll	$acc9,16,$acc9
+		xor	$acc11,$s2,$s2
+		sll	$acc10,8,$acc10
+		xor	$acc6,$s1,$s1
+		sll	$acc12,24,$acc12
+		xor	$acc8,$s2,$s2
+		sll	$acc13,16,$acc13	!
+		xor	$acc9,$s2,$s2
+		sll	$acc14,8,$acc14
+		xor	$acc10,$s2,$s2
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$s3,$s3
+		xor	$acc14,$s3,$s3
+		xor	$acc15,$s3,$s3
+
+	ret
+	restore
+.type	_sparcv9_AES_encrypt,#function
+.size	_sparcv9_AES_encrypt,(.-_sparcv9_AES_encrypt)
+
+.align	32
+.globl	AES_encrypt
+AES_encrypt:
+	or	%o0,%o1,%g1
+	andcc	%g1,3,%g0
+	bnz,pn	%xcc,.Lunaligned_enc
+	save	%sp,-$frame,%sp
+
+	ld	[%i0+0],%o0
+	ld	[%i0+4],%o1
+	ld	[%i0+8],%o2
+	ld	[%i0+12],%o3
+
+1:	call	.+8
+	add	%o7,AES_Te-1b,%o4
+	call	_sparcv9_AES_encrypt
+	mov	%i2,%o5
+
+	st	%o0,[%i1+0]
+	st	%o1,[%i1+4]
+	st	%o2,[%i1+8]
+	st	%o3,[%i1+12]
+
+	ret
+	restore
+
+.align	32
+.Lunaligned_enc:
+	ldub	[%i0+0],%l0
+	ldub	[%i0+1],%l1
+	ldub	[%i0+2],%l2
+
+	sll	%l0,24,%l0
+	ldub	[%i0+3],%l3
+	sll	%l1,16,%l1
+	ldub	[%i0+4],%l4
+	sll	%l2,8,%l2
+	or	%l1,%l0,%l0
+	ldub	[%i0+5],%l5
+	sll	%l4,24,%l4
+	or	%l3,%l2,%l2
+	ldub	[%i0+6],%l6
+	sll	%l5,16,%l5
+	or	%l0,%l2,%o0
+	ldub	[%i0+7],%l7
+
+	sll	%l6,8,%l6
+	or	%l5,%l4,%l4
+	ldub	[%i0+8],%l0
+	or	%l7,%l6,%l6
+	ldub	[%i0+9],%l1
+	or	%l4,%l6,%o1
+	ldub	[%i0+10],%l2
+
+	sll	%l0,24,%l0
+	ldub	[%i0+11],%l3
+	sll	%l1,16,%l1
+	ldub	[%i0+12],%l4
+	sll	%l2,8,%l2
+	or	%l1,%l0,%l0
+	ldub	[%i0+13],%l5
+	sll	%l4,24,%l4
+	or	%l3,%l2,%l2
+	ldub	[%i0+14],%l6
+	sll	%l5,16,%l5
+	or	%l0,%l2,%o2
+	ldub	[%i0+15],%l7
+
+	sll	%l6,8,%l6
+	or	%l5,%l4,%l4
+	or	%l7,%l6,%l6
+	or	%l4,%l6,%o3
+
+1:	call	.+8
+	add	%o7,AES_Te-1b,%o4
+	call	_sparcv9_AES_encrypt
+	mov	%i2,%o5
+
+	srl	%o0,24,%l0
+	srl	%o0,16,%l1
+	stb	%l0,[%i1+0]
+	srl	%o0,8,%l2
+	stb	%l1,[%i1+1]
+	stb	%l2,[%i1+2]
+	srl	%o1,24,%l4
+	stb	%o0,[%i1+3]
+
+	srl	%o1,16,%l5
+	stb	%l4,[%i1+4]
+	srl	%o1,8,%l6
+	stb	%l5,[%i1+5]
+	stb	%l6,[%i1+6]
+	srl	%o2,24,%l0
+	stb	%o1,[%i1+7]
+
+	srl	%o2,16,%l1
+	stb	%l0,[%i1+8]
+	srl	%o2,8,%l2
+	stb	%l1,[%i1+9]
+	stb	%l2,[%i1+10]
+	srl	%o3,24,%l4
+	stb	%o2,[%i1+11]
+
+	srl	%o3,16,%l5
+	stb	%l4,[%i1+12]
+	srl	%o3,8,%l6
+	stb	%l5,[%i1+13]
+	stb	%l6,[%i1+14]
+	stb	%o3,[%i1+15]
+
+	ret
+	restore
+.type	AES_encrypt,#function
+.size	AES_encrypt,(.-AES_encrypt)
+
+___
+
+$code.=<<___;
+.align	256
+AES_Td:
+___
+&_data_word(
+	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
+	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
+	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
+	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
+	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
+	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
+	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
+	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
+	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
+	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
+	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
+	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
+	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
+	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
+	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
+	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
+	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
+	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
+	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
+	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
+	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
+	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
+	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
+	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
+	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
+	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
+	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
+	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
+	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
+	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
+	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
+	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
+	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
+	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
+	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
+	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
+	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
+	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
+	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
+	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
+	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
+	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
+	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
+	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
+	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
+	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
+	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
+	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
+	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
+	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
+	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
+	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
+	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
+	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
+	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
+	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
+	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
+	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
+	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
+	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
+	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
+	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
+	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
+	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
+$code.=<<___;
+	.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
+	.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+	.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
+	.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+	.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
+	.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+	.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
+	.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+	.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
+	.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+	.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
+	.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+	.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
+	.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+	.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
+	.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+	.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
+	.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+	.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
+	.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+	.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
+	.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+	.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
+	.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+	.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
+	.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+	.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
+	.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+	.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
+	.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+	.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
+	.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+.type	AES_Td,#object
+.size	AES_Td,(.-AES_Td)
+
+.align	64
+.skip	16
+_sparcv9_AES_decrypt:
+	save	%sp,-$frame-$locals,%sp
+	stx	%i7,[%sp+$bias+$frame+0]	! off-load return address
+	ld	[$key+240],$rounds
+	ld	[$key+0],$t0
+	ld	[$key+4],$t1			!
+	ld	[$key+8],$t2
+	ld	[$key+12],$t3
+	srl	$rounds,1,$rounds
+	xor	$t0,$s0,$s0
+	ld	[$key+16],$t0
+	xor	$t1,$s1,$s1
+	ld	[$key+20],$t1
+	srl	$s0,21,$acc0			!
+	xor	$t2,$s2,$s2
+	ld	[$key+24],$t2
+	xor	$t3,$s3,$s3
+	and	$acc0,2040,$acc0
+	ld	[$key+28],$t3
+	srl	$s3,13,$acc1
+	nop
+.Ldec_loop:
+	srl	$s2,5,$acc2			!
+	and	$acc1,2040,$acc1
+	ldx	[$tbl+$acc0],$acc0
+	sll	$s1,3,$acc3
+	and	$acc2,2040,$acc2
+	ldx	[$tbl+$acc1],$acc1
+	srl	$s1,21,$acc4
+	and	$acc3,2040,$acc3
+	ldx	[$tbl+$acc2],$acc2		!
+	srl	$s0,13,$acc5
+	and	$acc4,2040,$acc4
+	ldx	[$tbl+$acc3],$acc3
+	srl	$s3,5,$acc6
+	and	$acc5,2040,$acc5
+	ldx	[$tbl+$acc4],$acc4
+	fmovs	%f0,%f0
+	sll	$s2,3,$acc7			!
+	and	$acc6,2040,$acc6
+	ldx	[$tbl+$acc5],$acc5
+	srl	$s2,21,$acc8
+	and	$acc7,2040,$acc7
+	ldx	[$tbl+$acc6],$acc6
+	srl	$s1,13,$acc9
+	and	$acc8,2040,$acc8
+	ldx	[$tbl+$acc7],$acc7		!
+	srl	$s0,5,$acc10
+	and	$acc9,2040,$acc9
+	ldx	[$tbl+$acc8],$acc8
+	sll	$s3,3,$acc11
+	and	$acc10,2040,$acc10
+	ldx	[$tbl+$acc9],$acc9
+	fmovs	%f0,%f0
+	srl	$s3,21,$acc12			!
+	and	$acc11,2040,$acc11
+	ldx	[$tbl+$acc10],$acc10
+	srl	$s2,13,$acc13
+	and	$acc12,2040,$acc12
+	ldx	[$tbl+$acc11],$acc11
+	srl	$s1,5,$acc14
+	and	$acc13,2040,$acc13
+	ldx	[$tbl+$acc12],$acc12		!
+	sll	$s0,3,$acc15
+	and	$acc14,2040,$acc14
+	ldx	[$tbl+$acc13],$acc13
+	and	$acc15,2040,$acc15
+	add	$key,32,$key
+	ldx	[$tbl+$acc14],$acc14
+	fmovs	%f0,%f0
+	subcc	$rounds,1,$rounds		!
+	ldx	[$tbl+$acc15],$acc15
+	bz,a,pn	%icc,.Ldec_last
+	add	$tbl,2048,$rounds
+
+		srlx	$acc1,8,$acc1
+		xor	$acc0,$t0,$t0
+	ld	[$key+0],$s0
+	fmovs	%f0,%f0
+		srlx	$acc2,16,$acc2		!
+		xor	$acc1,$t0,$t0
+	ld	[$key+4],$s1
+		srlx	$acc3,24,$acc3
+		xor	$acc2,$t0,$t0
+	ld	[$key+8],$s2
+		srlx	$acc5,8,$acc5
+		xor	$acc3,$t0,$t0
+	ld	[$key+12],$s3			!
+		srlx	$acc6,16,$acc6
+		xor	$acc4,$t1,$t1
+	fmovs	%f0,%f0
+		srlx	$acc7,24,$acc7
+		xor	$acc5,$t1,$t1
+		srlx	$acc9,8,$acc9
+		xor	$acc6,$t1,$t1
+		srlx	$acc10,16,$acc10	!
+		xor	$acc7,$t1,$t1
+		srlx	$acc11,24,$acc11
+		xor	$acc8,$t2,$t2
+		srlx	$acc13,8,$acc13
+		xor	$acc9,$t2,$t2
+		srlx	$acc14,16,$acc14
+		xor	$acc10,$t2,$t2
+		srlx	$acc15,24,$acc15	!
+		xor	$acc11,$t2,$t2
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$t3,$t3
+	srl	$t0,21,$acc0
+		xor	$acc14,$t3,$t3
+		xor	$acc15,$t3,$t3
+	srl	$t3,13,$acc1
+
+	and	$acc0,2040,$acc0		!
+	srl	$t2,5,$acc2
+	and	$acc1,2040,$acc1
+	ldx	[$tbl+$acc0],$acc0
+	sll	$t1,3,$acc3
+	and	$acc2,2040,$acc2
+	ldx	[$tbl+$acc1],$acc1
+	fmovs	%f0,%f0
+	srl	$t1,21,$acc4			!
+	and	$acc3,2040,$acc3
+	ldx	[$tbl+$acc2],$acc2
+	srl	$t0,13,$acc5
+	and	$acc4,2040,$acc4
+	ldx	[$tbl+$acc3],$acc3
+	srl	$t3,5,$acc6
+	and	$acc5,2040,$acc5
+	ldx	[$tbl+$acc4],$acc4		!
+	sll	$t2,3,$acc7
+	and	$acc6,2040,$acc6
+	ldx	[$tbl+$acc5],$acc5
+	srl	$t2,21,$acc8
+	and	$acc7,2040,$acc7
+	ldx	[$tbl+$acc6],$acc6
+	fmovs	%f0,%f0
+	srl	$t1,13,$acc9			!
+	and	$acc8,2040,$acc8
+	ldx	[$tbl+$acc7],$acc7
+	srl	$t0,5,$acc10
+	and	$acc9,2040,$acc9
+	ldx	[$tbl+$acc8],$acc8
+	sll	$t3,3,$acc11
+	and	$acc10,2040,$acc10
+	ldx	[$tbl+$acc9],$acc9		!
+	srl	$t3,21,$acc12
+	and	$acc11,2040,$acc11
+	ldx	[$tbl+$acc10],$acc10
+	srl	$t2,13,$acc13
+	and	$acc12,2040,$acc12
+	ldx	[$tbl+$acc11],$acc11
+	fmovs	%f0,%f0
+	srl	$t1,5,$acc14			!
+	and	$acc13,2040,$acc13
+	ldx	[$tbl+$acc12],$acc12
+	sll	$t0,3,$acc15
+	and	$acc14,2040,$acc14
+	ldx	[$tbl+$acc13],$acc13
+		srlx	$acc1,8,$acc1
+	and	$acc15,2040,$acc15
+	ldx	[$tbl+$acc14],$acc14		!
+
+		srlx	$acc2,16,$acc2
+		xor	$acc0,$s0,$s0
+	ldx	[$tbl+$acc15],$acc15
+		srlx	$acc3,24,$acc3
+		xor	$acc1,$s0,$s0
+	ld	[$key+16],$t0
+	fmovs	%f0,%f0
+		srlx	$acc5,8,$acc5		!
+		xor	$acc2,$s0,$s0
+	ld	[$key+20],$t1
+		srlx	$acc6,16,$acc6
+		xor	$acc3,$s0,$s0
+	ld	[$key+24],$t2
+		srlx	$acc7,24,$acc7
+		xor	$acc4,$s1,$s1
+	ld	[$key+28],$t3			!
+		srlx	$acc9,8,$acc9
+		xor	$acc5,$s1,$s1
+	ldx	[$tbl+2048+0],%g0		! prefetch td4
+		srlx	$acc10,16,$acc10
+		xor	$acc6,$s1,$s1
+	ldx	[$tbl+2048+32],%g0		! prefetch td4
+		srlx	$acc11,24,$acc11
+		xor	$acc7,$s1,$s1
+	ldx	[$tbl+2048+64],%g0		! prefetch td4
+		srlx	$acc13,8,$acc13
+		xor	$acc8,$s2,$s2
+	ldx	[$tbl+2048+96],%g0		! prefetch td4
+		srlx	$acc14,16,$acc14	!
+		xor	$acc9,$s2,$s2
+	ldx	[$tbl+2048+128],%g0		! prefetch td4
+		srlx	$acc15,24,$acc15
+		xor	$acc10,$s2,$s2
+	ldx	[$tbl+2048+160],%g0		! prefetch td4
+	srl	$s0,21,$acc0
+		xor	$acc11,$s2,$s2
+	ldx	[$tbl+2048+192],%g0		! prefetch td4
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$s3,$s3
+	ldx	[$tbl+2048+224],%g0		! prefetch td4
+	and	$acc0,2040,$acc0		!
+		xor	$acc14,$s3,$s3
+		xor	$acc15,$s3,$s3
+	ba	.Ldec_loop
+	srl	$s3,13,$acc1
+
+.align	32
+.Ldec_last:
+		srlx	$acc1,8,$acc1		!
+		xor	$acc0,$t0,$t0
+	ld	[$key+0],$s0
+		srlx	$acc2,16,$acc2
+		xor	$acc1,$t0,$t0
+	ld	[$key+4],$s1
+		srlx	$acc3,24,$acc3
+		xor	$acc2,$t0,$t0
+	ld	[$key+8],$s2			!
+		srlx	$acc5,8,$acc5
+		xor	$acc3,$t0,$t0
+	ld	[$key+12],$s3
+		srlx	$acc6,16,$acc6
+		xor	$acc4,$t1,$t1
+		srlx	$acc7,24,$acc7
+		xor	$acc5,$t1,$t1
+		srlx	$acc9,8,$acc9		!
+		xor	$acc6,$t1,$t1
+		srlx	$acc10,16,$acc10
+		xor	$acc7,$t1,$t1
+		srlx	$acc11,24,$acc11
+		xor	$acc8,$t2,$t2
+		srlx	$acc13,8,$acc13
+		xor	$acc9,$t2,$t2
+		srlx	$acc14,16,$acc14	!
+		xor	$acc10,$t2,$t2
+		srlx	$acc15,24,$acc15
+		xor	$acc11,$t2,$t2
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$t3,$t3
+	srl	$t0,24,$acc0
+		xor	$acc14,$t3,$t3
+		xor	$acc15,$t3,$t3		!
+	srl	$t3,16,$acc1
+
+	srl	$t2,8,$acc2
+	and	$acc1,255,$acc1
+	ldub	[$rounds+$acc0],$acc0
+	srl	$t1,24,$acc4
+	and	$acc2,255,$acc2
+	ldub	[$rounds+$acc1],$acc1
+	srl	$t0,16,$acc5			!
+	and	$t1,255,$acc3
+	ldub	[$rounds+$acc2],$acc2
+	ldub	[$rounds+$acc3],$acc3
+	srl	$t3,8,$acc6
+	and	$acc5,255,$acc5
+	ldub	[$rounds+$acc4],$acc4
+	fmovs	%f0,%f0
+	srl	$t2,24,$acc8			!
+	and	$acc6,255,$acc6
+	ldub	[$rounds+$acc5],$acc5
+	srl	$t1,16,$acc9
+	and	$t2,255,$acc7
+	ldub	[$rounds+$acc6],$acc6
+	ldub	[$rounds+$acc7],$acc7
+	fmovs	%f0,%f0
+	srl	$t0,8,$acc10			!
+	and	$acc9,255,$acc9
+	ldub	[$rounds+$acc8],$acc8
+	srl	$t3,24,$acc12
+	and	$acc10,255,$acc10
+	ldub	[$rounds+$acc9],$acc9
+	srl	$t2,16,$acc13
+	and	$t3,255,$acc11
+	ldub	[$rounds+$acc10],$acc10		!
+	srl	$t1,8,$acc14
+	and	$acc13,255,$acc13
+	ldub	[$rounds+$acc11],$acc11
+	ldub	[$rounds+$acc12],$acc12
+	and	$acc14,255,$acc14
+	ldub	[$rounds+$acc13],$acc13
+	and	$t0,255,$acc15
+	ldub	[$rounds+$acc14],$acc14		!
+
+		sll	$acc0,24,$acc0
+		xor	$acc3,$s0,$s0
+	ldub	[$rounds+$acc15],$acc15
+		sll	$acc1,16,$acc1
+		xor	$acc0,$s0,$s0
+	ldx	[%sp+$bias+$frame+0],%i7	! restore return address
+	fmovs	%f0,%f0
+		sll	$acc2,8,$acc2		!
+		xor	$acc1,$s0,$s0
+		sll	$acc4,24,$acc4
+		xor	$acc2,$s0,$s0
+		sll	$acc5,16,$acc5
+		xor	$acc7,$s1,$s1
+		sll	$acc6,8,$acc6
+		xor	$acc4,$s1,$s1
+		sll	$acc8,24,$acc8		!
+		xor	$acc5,$s1,$s1
+		sll	$acc9,16,$acc9
+		xor	$acc11,$s2,$s2
+		sll	$acc10,8,$acc10
+		xor	$acc6,$s1,$s1
+		sll	$acc12,24,$acc12
+		xor	$acc8,$s2,$s2
+		sll	$acc13,16,$acc13	!
+		xor	$acc9,$s2,$s2
+		sll	$acc14,8,$acc14
+		xor	$acc10,$s2,$s2
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$s3,$s3
+		xor	$acc14,$s3,$s3
+		xor	$acc15,$s3,$s3
+
+	ret
+	restore
+.type	_sparcv9_AES_decrypt,#function
+.size	_sparcv9_AES_decrypt,(.-_sparcv9_AES_decrypt)
+
+.align	32
+.globl	AES_decrypt
+AES_decrypt:
+	or	%o0,%o1,%g1
+	andcc	%g1,3,%g0
+	bnz,pn	%xcc,.Lunaligned_dec
+	save	%sp,-$frame,%sp
+
+	ld	[%i0+0],%o0
+	ld	[%i0+4],%o1
+	ld	[%i0+8],%o2
+	ld	[%i0+12],%o3
+
+1:	call	.+8
+	add	%o7,AES_Td-1b,%o4
+	call	_sparcv9_AES_decrypt
+	mov	%i2,%o5
+
+	st	%o0,[%i1+0]
+	st	%o1,[%i1+4]
+	st	%o2,[%i1+8]
+	st	%o3,[%i1+12]
+
+	ret
+	restore
+
+.align	32
+.Lunaligned_dec:
+	ldub	[%i0+0],%l0
+	ldub	[%i0+1],%l1
+	ldub	[%i0+2],%l2
+
+	sll	%l0,24,%l0
+	ldub	[%i0+3],%l3
+	sll	%l1,16,%l1
+	ldub	[%i0+4],%l4
+	sll	%l2,8,%l2
+	or	%l1,%l0,%l0
+	ldub	[%i0+5],%l5
+	sll	%l4,24,%l4
+	or	%l3,%l2,%l2
+	ldub	[%i0+6],%l6
+	sll	%l5,16,%l5
+	or	%l0,%l2,%o0
+	ldub	[%i0+7],%l7
+
+	sll	%l6,8,%l6
+	or	%l5,%l4,%l4
+	ldub	[%i0+8],%l0
+	or	%l7,%l6,%l6
+	ldub	[%i0+9],%l1
+	or	%l4,%l6,%o1
+	ldub	[%i0+10],%l2
+
+	sll	%l0,24,%l0
+	ldub	[%i0+11],%l3
+	sll	%l1,16,%l1
+	ldub	[%i0+12],%l4
+	sll	%l2,8,%l2
+	or	%l1,%l0,%l0
+	ldub	[%i0+13],%l5
+	sll	%l4,24,%l4
+	or	%l3,%l2,%l2
+	ldub	[%i0+14],%l6
+	sll	%l5,16,%l5
+	or	%l0,%l2,%o2
+	ldub	[%i0+15],%l7
+
+	sll	%l6,8,%l6
+	or	%l5,%l4,%l4
+	or	%l7,%l6,%l6
+	or	%l4,%l6,%o3
+
+1:	call	.+8
+	add	%o7,AES_Td-1b,%o4
+	call	_sparcv9_AES_decrypt
+	mov	%i2,%o5
+
+	srl	%o0,24,%l0
+	srl	%o0,16,%l1
+	stb	%l0,[%i1+0]
+	srl	%o0,8,%l2
+	stb	%l1,[%i1+1]
+	stb	%l2,[%i1+2]
+	srl	%o1,24,%l4
+	stb	%o0,[%i1+3]
+
+	srl	%o1,16,%l5
+	stb	%l4,[%i1+4]
+	srl	%o1,8,%l6
+	stb	%l5,[%i1+5]
+	stb	%l6,[%i1+6]
+	srl	%o2,24,%l0
+	stb	%o1,[%i1+7]
+
+	srl	%o2,16,%l1
+	stb	%l0,[%i1+8]
+	srl	%o2,8,%l2
+	stb	%l1,[%i1+9]
+	stb	%l2,[%i1+10]
+	srl	%o3,24,%l4
+	stb	%o2,[%i1+11]
+
+	srl	%o3,16,%l5
+	stb	%l4,[%i1+12]
+	srl	%o3,8,%l6
+	stb	%l5,[%i1+13]
+	stb	%l6,[%i1+14]
+	stb	%o3,[%i1+15]
+
+	ret
+	restore
+.type	AES_decrypt,#function
+.size	AES_decrypt,(.-AES_decrypt)
+___
+
+# fmovs instructions substituting for FP nops were originally added
+# to meet specific instruction alignment requirements to maximize ILP.
+# As UltraSPARC T1, a.k.a. Niagara, has shared FPU, FP nops can have
+# undesired effect, so just omit them and sacrifice some portion of
+# percent in performance...
+$code =~ s/fmovs.*$//gem;
+
+print $code;
diff --git a/crypto/aes/asm/aes-x86_64.pl b/crypto/aes/asm/aes-x86_64.pl
index b008ab5..a545e89 100755
--- a/crypto/aes/asm/aes-x86_64.pl
+++ b/crypto/aes/asm/aes-x86_64.pl
@@ -2,11 +2,12 @@
 #
 # ====================================================================
 # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. Rights for redistribution and usage in source and binary
-# forms are granted according to the OpenSSL license.
+# 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/.
 # ====================================================================
 #
-# Version 1.2.
+# Version 2.1.
 #
 # aes-*-cbc benchmarks are improved by >70% [compared to gcc 3.3.2 on
 # Opteron 240 CPU] plus all the bells-n-whistles from 32-bit version
@@ -17,17 +18,29 @@
 #
 # Performance in number of cycles per processed byte for 128-bit key:
 #
-#		ECB		CBC encrypt
-# AMD64		13.7		13.0(*)
-# EM64T		20.2		18.6(*)
+#		ECB encrypt	ECB decrypt	CBC large chunk
+# AMD64		33		41		13.0
+# EM64T		38		59		18.6(*)
+# Core 2	30		43		14.5(*)
 #
-# (*)	CBC benchmarks are better than ECB thanks to custom ABI used
-#	by the private block encryption function.
+# (*) with hyper-threading off
+
+$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";
 
 $verticalspin=1;	# unlike 32-bit version $verticalspin performs
 			# ~15% better on both AMD and Intel cores
-$output=shift;
-open STDOUT,"| $^X ../perlasm/x86_64-xlate.pl $output";
+$speed_limit=512;	# see aes-586.pl for details
 
 $code=".text\n";
 
@@ -35,9 +48,9 @@
 $s1="%ebx";
 $s2="%ecx";
 $s3="%edx";
-$acc0="%esi";
-$acc1="%edi";
-$acc2="%ebp";
+$acc0="%esi";	$mask80="%rsi";
+$acc1="%edi";	$maskfe="%rdi";
+$acc2="%ebp";	$mask1b="%rbp";
 $inp="%r8";
 $out="%r9";
 $t0="%r10d";
@@ -51,6 +64,8 @@
 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; }
+sub LO() { my $r=shift; $r =~ s/%r([a-z]+)/%e\1/;
+			$r =~ s/%r([0-9]+)/%r\1d/;	$r; }
 sub _data_word()
 { my $i;
     while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; }
@@ -138,22 +153,17 @@
 	movzb	`&lo("$s0")`,$acc0
 	movzb	`&lo("$s1")`,$acc1
 	movzb	`&lo("$s2")`,$acc2
-	mov	2($sbox,$acc0,8),$t0
-	mov	2($sbox,$acc1,8),$t1
-	mov	2($sbox,$acc2,8),$t2
-
-	and	\$0x000000ff,$t0
-	and	\$0x000000ff,$t1
-	and	\$0x000000ff,$t2
+	movzb	2($sbox,$acc0,8),$t0
+	movzb	2($sbox,$acc1,8),$t1
+	movzb	2($sbox,$acc2,8),$t2
 
 	movzb	`&lo("$s3")`,$acc0
 	movzb	`&hi("$s1")`,$acc1
 	movzb	`&hi("$s2")`,$acc2
-	mov	2($sbox,$acc0,8),$t3
+	movzb	2($sbox,$acc0,8),$t3
 	mov	0($sbox,$acc1,8),$acc1	#$t0
 	mov	0($sbox,$acc2,8),$acc2	#$t1
 
-	and	\$0x000000ff,$t3
 	and	\$0x0000ff00,$acc1
 	and	\$0x0000ff00,$acc2
 
@@ -345,6 +355,234 @@
 .size	_x86_64_AES_encrypt,.-_x86_64_AES_encrypt
 ___
 
+# it's possible to implement this by shifting tN by 8, filling least
+# significant byte with byte load and finally bswap-ing at the end,
+# but such partial register load kills Core 2...
+sub enccompactvert()
+{ my ($t3,$t4,$t5)=("%r8d","%r9d","%r13d");
+
+$code.=<<___;
+	movzb	`&lo("$s0")`,$t0
+	movzb	`&lo("$s1")`,$t1
+	movzb	`&lo("$s2")`,$t2
+	movzb	($sbox,$t0,1),$t0
+	movzb	($sbox,$t1,1),$t1
+	movzb	($sbox,$t2,1),$t2
+
+	movzb	`&lo("$s3")`,$t3
+	movzb	`&hi("$s1")`,$acc0
+	movzb	`&hi("$s2")`,$acc1
+	movzb	($sbox,$t3,1),$t3
+	movzb	($sbox,$acc0,1),$t4	#$t0
+	movzb	($sbox,$acc1,1),$t5	#$t1
+
+	movzb	`&hi("$s3")`,$acc2
+	movzb	`&hi("$s0")`,$acc0
+	shr	\$16,$s2
+	movzb	($sbox,$acc2,1),$acc2	#$t2
+	movzb	($sbox,$acc0,1),$acc0	#$t3
+	shr	\$16,$s3
+
+	movzb	`&lo("$s2")`,$acc1
+	shl	\$8,$t4
+	shl	\$8,$t5
+	movzb	($sbox,$acc1,1),$acc1	#$t0
+	xor	$t4,$t0
+	xor	$t5,$t1
+
+	movzb	`&lo("$s3")`,$t4
+	shr	\$16,$s0
+	shr	\$16,$s1
+	movzb	`&lo("$s0")`,$t5
+	shl	\$8,$acc2
+	shl	\$8,$acc0
+	movzb	($sbox,$t4,1),$t4	#$t1
+	movzb	($sbox,$t5,1),$t5	#$t2
+	xor	$acc2,$t2
+	xor	$acc0,$t3
+
+	movzb	`&lo("$s1")`,$acc2
+	movzb	`&hi("$s3")`,$acc0
+	shl	\$16,$acc1
+	movzb	($sbox,$acc2,1),$acc2	#$t3
+	movzb	($sbox,$acc0,1),$acc0	#$t0
+	xor	$acc1,$t0
+
+	movzb	`&hi("$s0")`,$acc1
+	shr	\$8,$s2
+	shr	\$8,$s1
+	movzb	($sbox,$acc1,1),$acc1	#$t1
+	movzb	($sbox,$s2,1),$s3	#$t3
+	movzb	($sbox,$s1,1),$s2	#$t2
+	shl	\$16,$t4
+	shl	\$16,$t5
+	shl	\$16,$acc2
+	xor	$t4,$t1
+	xor	$t5,$t2
+	xor	$acc2,$t3
+
+	shl	\$24,$acc0
+	shl	\$24,$acc1
+	shl	\$24,$s3
+	xor	$acc0,$t0
+	shl	\$24,$s2
+	xor	$acc1,$t1
+	mov	$t0,$s0
+	mov	$t1,$s1
+	xor	$t2,$s2
+	xor	$t3,$s3
+___
+}
+
+sub enctransform_ref()
+{ my $sn = shift;
+  my ($acc,$r2,$tmp)=("%r8d","%r9d","%r13d");
+
+$code.=<<___;
+	mov	$sn,$acc
+	and	\$0x80808080,$acc
+	mov	$acc,$tmp
+	shr	\$7,$tmp
+	lea	($sn,$sn),$r2
+	sub	$tmp,$acc
+	and	\$0xfefefefe,$r2
+	and	\$0x1b1b1b1b,$acc
+	mov	$sn,$tmp
+	xor	$acc,$r2
+
+	xor	$r2,$sn
+	rol	\$24,$sn
+	xor	$r2,$sn
+	ror	\$16,$tmp
+	xor	$tmp,$sn
+	ror	\$8,$tmp
+	xor	$tmp,$sn
+___
+}
+
+# unlike decrypt case it does not pay off to parallelize enctransform
+sub enctransform()
+{ my ($t3,$r20,$r21)=($acc2,"%r8d","%r9d");
+
+$code.=<<___;
+	mov	$s0,$acc0
+	mov	$s1,$acc1
+	and	\$0x80808080,$acc0
+	and	\$0x80808080,$acc1
+	mov	$acc0,$t0
+	mov	$acc1,$t1
+	shr	\$7,$t0
+	lea	($s0,$s0),$r20
+	shr	\$7,$t1
+	lea	($s1,$s1),$r21
+	sub	$t0,$acc0
+	sub	$t1,$acc1
+	and	\$0xfefefefe,$r20
+	and	\$0xfefefefe,$r21
+	and	\$0x1b1b1b1b,$acc0
+	and	\$0x1b1b1b1b,$acc1
+	mov	$s0,$t0
+	mov	$s1,$t1
+	xor	$acc0,$r20
+	xor	$acc1,$r21
+
+	xor	$r20,$s0
+	xor	$r21,$s1
+	 mov	$s2,$acc0
+	 mov	$s3,$acc1
+	rol	\$24,$s0
+	rol	\$24,$s1
+	 and	\$0x80808080,$acc0
+	 and	\$0x80808080,$acc1
+	xor	$r20,$s0
+	xor	$r21,$s1
+	 mov	$acc0,$t2
+	 mov	$acc1,$t3
+	ror	\$16,$t0
+	ror	\$16,$t1
+	 shr	\$7,$t2
+	 lea	($s2,$s2),$r20
+	xor	$t0,$s0
+	xor	$t1,$s1
+	 shr	\$7,$t3
+	 lea	($s3,$s3),$r21
+	ror	\$8,$t0
+	ror	\$8,$t1
+	 sub	$t2,$acc0
+	 sub	$t3,$acc1
+	xor	$t0,$s0
+	xor	$t1,$s1
+
+	and	\$0xfefefefe,$r20
+	and	\$0xfefefefe,$r21
+	and	\$0x1b1b1b1b,$acc0
+	and	\$0x1b1b1b1b,$acc1
+	mov	$s2,$t2
+	mov	$s3,$t3
+	xor	$acc0,$r20
+	xor	$acc1,$r21
+
+	xor	$r20,$s2
+	xor	$r21,$s3
+	rol	\$24,$s2
+	rol	\$24,$s3
+	xor	$r20,$s2
+	xor	$r21,$s3
+	mov	0($sbox),$acc0			# prefetch Te4
+	ror	\$16,$t2
+	ror	\$16,$t3
+	mov	64($sbox),$acc1
+	xor	$t2,$s2
+	xor	$t3,$s3
+	mov	128($sbox),$r20
+	ror	\$8,$t2
+	ror	\$8,$t3
+	mov	192($sbox),$r21
+	xor	$t2,$s2
+	xor	$t3,$s3
+___
+}
+
+$code.=<<___;
+.type	_x86_64_AES_encrypt_compact,\@abi-omnipotent
+.align	16
+_x86_64_AES_encrypt_compact:
+	lea	128($sbox),$inp			# size optimization
+	mov	0-128($inp),$acc1		# prefetch Te4
+	mov	32-128($inp),$acc2
+	mov	64-128($inp),$t0
+	mov	96-128($inp),$t1
+	mov	128-128($inp),$acc1
+	mov	160-128($inp),$acc2
+	mov	192-128($inp),$t0
+	mov	224-128($inp),$t1
+	jmp	.Lenc_loop_compact
+.align	16
+.Lenc_loop_compact:
+		xor	0($key),$s0		# xor with key
+		xor	4($key),$s1
+		xor	8($key),$s2
+		xor	12($key),$s3
+		lea	16($key),$key
+___
+		&enccompactvert();
+$code.=<<___;
+		cmp	16(%rsp),$key
+		je	.Lenc_compact_done
+___
+		&enctransform();
+$code.=<<___;
+	jmp	.Lenc_loop_compact
+.align	16
+.Lenc_compact_done:
+	xor	0($key),$s0
+	xor	4($key),$s1
+	xor	8($key),$s2
+	xor	12($key),$s3
+	.byte	0xf3,0xc3			# rep ret
+.size	_x86_64_AES_encrypt_compact,.-_x86_64_AES_encrypt_compact
+___
+
 # void AES_encrypt (const void *inp,void *out,const AES_KEY *key);
 $code.=<<___;
 .globl	AES_encrypt
@@ -358,31 +596,57 @@
 	push	%r14
 	push	%r15
 
+	# allocate frame "above" key schedule
+	mov	%rsp,%r10
+	lea	-63(%rdx),%rcx	# %rdx is key argument
+	and	\$-64,%rsp
+	sub	%rsp,%rcx
+	neg	%rcx
+	and	\$0x3c0,%rcx
+	sub	%rcx,%rsp
+	sub	\$32,%rsp
+
+	mov	%rsi,16(%rsp)	# save out
+	mov	%r10,24(%rsp)	# save real stack pointer
+.Lenc_prologue:
+
 	mov	%rdx,$key
-	mov	%rdi,$inp
-	mov	%rsi,$out
+	mov	240($key),$rnds	# load rounds
 
-	.picmeup	$sbox
-	lea	AES_Te-.($sbox),$sbox
+	mov	0(%rdi),$s0	# load input vector
+	mov	4(%rdi),$s1
+	mov	8(%rdi),$s2
+	mov	12(%rdi),$s3
 
-	mov	0($inp),$s0
-	mov	4($inp),$s1
-	mov	8($inp),$s2
-	mov	12($inp),$s3
+	shl	\$4,$rnds
+	lea	($key,$rnds),%rbp
+	mov	$key,(%rsp)	# key schedule
+	mov	%rbp,8(%rsp)	# end of key schedule
 
-	call	_x86_64_AES_encrypt
+	# pick Te4 copy which can't "overlap" with stack frame or key schedule
+	lea	.LAES_Te+2048(%rip),$sbox
+	lea	768(%rsp),%rbp
+	sub	$sbox,%rbp
+	and	\$0x300,%rbp
+	lea	($sbox,%rbp),$sbox
 
-	mov	$s0,0($out)
+	call	_x86_64_AES_encrypt_compact
+
+	mov	16(%rsp),$out	# restore out
+	mov	24(%rsp),%rsi	# restore saved stack pointer
+	mov	$s0,0($out)	# write output vector
 	mov	$s1,4($out)
 	mov	$s2,8($out)
 	mov	$s3,12($out)
 
-	pop	%r15
-	pop	%r14
-	pop	%r13
-	pop	%r12
-	pop	%rbp
-	pop	%rbx
+	mov	(%rsi),%r15
+	mov	8(%rsi),%r14
+	mov	16(%rsi),%r13
+	mov	24(%rsi),%r12
+	mov	32(%rsi),%rbp
+	mov	40(%rsi),%rbx
+	lea	48(%rsi),%rsp
+.Lenc_epilogue:
 	ret
 .size	AES_encrypt,.-AES_encrypt
 ___
@@ -453,19 +717,20 @@
 { my $t3="%r8d";	# zaps $inp!
 
 $code.=<<___;
+	lea	2048($sbox),$sbox	# size optimization
 	movzb	`&lo("$s0")`,$acc0
 	movzb	`&lo("$s1")`,$acc1
 	movzb	`&lo("$s2")`,$acc2
-	movzb	2048($sbox,$acc0,1),$t0
-	movzb	2048($sbox,$acc1,1),$t1
-	movzb	2048($sbox,$acc2,1),$t2
+	movzb	($sbox,$acc0,1),$t0
+	movzb	($sbox,$acc1,1),$t1
+	movzb	($sbox,$acc2,1),$t2
 
 	movzb	`&lo("$s3")`,$acc0
 	movzb	`&hi("$s3")`,$acc1
 	movzb	`&hi("$s0")`,$acc2
-	movzb	2048($sbox,$acc0,1),$t3
-	movzb	2048($sbox,$acc1,1),$acc1	#$t0
-	movzb	2048($sbox,$acc2,1),$acc2	#$t1
+	movzb	($sbox,$acc0,1),$t3
+	movzb	($sbox,$acc1,1),$acc1	#$t0
+	movzb	($sbox,$acc2,1),$acc2	#$t1
 
 	shl	\$8,$acc1
 	shl	\$8,$acc2
@@ -477,8 +742,8 @@
 	movzb	`&hi("$s1")`,$acc0
 	movzb	`&hi("$s2")`,$acc1
 	shr	\$16,$s0
-	movzb	2048($sbox,$acc0,1),$acc0	#$t2
-	movzb	2048($sbox,$acc1,1),$acc1	#$t3
+	movzb	($sbox,$acc0,1),$acc0	#$t2
+	movzb	($sbox,$acc1,1),$acc1	#$t3
 
 	shl	\$8,$acc0
 	shl	\$8,$acc1
@@ -490,9 +755,9 @@
 	movzb	`&lo("$s2")`,$acc0
 	movzb	`&lo("$s3")`,$acc1
 	movzb	`&lo("$s0")`,$acc2
-	movzb	2048($sbox,$acc0,1),$acc0	#$t0
-	movzb	2048($sbox,$acc1,1),$acc1	#$t1
-	movzb	2048($sbox,$acc2,1),$acc2	#$t2
+	movzb	($sbox,$acc0,1),$acc0	#$t0
+	movzb	($sbox,$acc1,1),$acc1	#$t1
+	movzb	($sbox,$acc2,1),$acc2	#$t2
 
 	shl	\$16,$acc0
 	shl	\$16,$acc1
@@ -505,9 +770,9 @@
 	movzb	`&lo("$s1")`,$acc0
 	movzb	`&hi("$s1")`,$acc1
 	movzb	`&hi("$s2")`,$acc2
-	movzb	2048($sbox,$acc0,1),$acc0	#$t3
-	movzb	2048($sbox,$acc1,1),$acc1	#$t0
-	movzb	2048($sbox,$acc2,1),$acc2	#$t1
+	movzb	($sbox,$acc0,1),$acc0	#$t3
+	movzb	($sbox,$acc1,1),$acc1	#$t0
+	movzb	($sbox,$acc2,1),$acc2	#$t1
 
 	shl	\$16,$acc0
 	shl	\$24,$acc1
@@ -520,8 +785,8 @@
 	movzb	`&hi("$s3")`,$acc0
 	movzb	`&hi("$s0")`,$acc1
 	mov	16+12($key),$s3
-	movzb	2048($sbox,$acc0,1),$acc0	#$t2
-	movzb	2048($sbox,$acc1,1),$acc1	#$t3
+	movzb	($sbox,$acc0,1),$acc0	#$t2
+	movzb	($sbox,$acc1,1),$acc1	#$t3
 	mov	16+0($key),$s0
 
 	shl	\$24,$acc0
@@ -532,6 +797,7 @@
 
 	mov	16+4($key),$s1
 	mov	16+8($key),$s2
+	lea	-2048($sbox),$sbox
 	xor	$t0,$s0
 	xor	$t1,$s1
 	xor	$t2,$s2
@@ -659,6 +925,260 @@
 .size	_x86_64_AES_decrypt,.-_x86_64_AES_decrypt
 ___
 
+sub deccompactvert()
+{ my ($t3,$t4,$t5)=("%r8d","%r9d","%r13d");
+
+$code.=<<___;
+	movzb	`&lo("$s0")`,$t0
+	movzb	`&lo("$s1")`,$t1
+	movzb	`&lo("$s2")`,$t2
+	movzb	($sbox,$t0,1),$t0
+	movzb	($sbox,$t1,1),$t1
+	movzb	($sbox,$t2,1),$t2
+
+	movzb	`&lo("$s3")`,$t3
+	movzb	`&hi("$s3")`,$acc0
+	movzb	`&hi("$s0")`,$acc1
+	movzb	($sbox,$t3,1),$t3
+	movzb	($sbox,$acc0,1),$t4	#$t0
+	movzb	($sbox,$acc1,1),$t5	#$t1
+
+	movzb	`&hi("$s1")`,$acc2
+	movzb	`&hi("$s2")`,$acc0
+	shr	\$16,$s2
+	movzb	($sbox,$acc2,1),$acc2	#$t2
+	movzb	($sbox,$acc0,1),$acc0	#$t3
+	shr	\$16,$s3
+
+	movzb	`&lo("$s2")`,$acc1
+	shl	\$8,$t4
+	shl	\$8,$t5
+	movzb	($sbox,$acc1,1),$acc1	#$t0
+	xor	$t4,$t0
+	xor	$t5,$t1
+
+	movzb	`&lo("$s3")`,$t4
+	shr	\$16,$s0
+	shr	\$16,$s1
+	movzb	`&lo("$s0")`,$t5
+	shl	\$8,$acc2
+	shl	\$8,$acc0
+	movzb	($sbox,$t4,1),$t4	#$t1
+	movzb	($sbox,$t5,1),$t5	#$t2
+	xor	$acc2,$t2
+	xor	$acc0,$t3
+
+	movzb	`&lo("$s1")`,$acc2
+	movzb	`&hi("$s1")`,$acc0
+	shl	\$16,$acc1
+	movzb	($sbox,$acc2,1),$acc2	#$t3
+	movzb	($sbox,$acc0,1),$acc0	#$t0
+	xor	$acc1,$t0
+
+	movzb	`&hi("$s2")`,$acc1
+	shl	\$16,$t4
+	shl	\$16,$t5
+	movzb	($sbox,$acc1,1),$s1	#$t1
+	xor	$t4,$t1
+	xor	$t5,$t2
+
+	movzb	`&hi("$s3")`,$acc1
+	shr	\$8,$s0
+	shl	\$16,$acc2
+	movzb	($sbox,$acc1,1),$s2	#$t2
+	movzb	($sbox,$s0,1),$s3	#$t3
+	xor	$acc2,$t3
+
+	shl	\$24,$acc0
+	shl	\$24,$s1
+	shl	\$24,$s2
+	xor	$acc0,$t0
+	shl	\$24,$s3
+	xor	$t1,$s1
+	mov	$t0,$s0
+	xor	$t2,$s2
+	xor	$t3,$s3
+___
+}
+
+# parallelized version! input is pair of 64-bit values: %rax=s1.s0
+# and %rcx=s3.s2, output is four 32-bit values in %eax=s0, %ebx=s1,
+# %ecx=s2 and %edx=s3.
+sub dectransform()
+{ my ($tp10,$tp20,$tp40,$tp80,$acc0)=("%rax","%r8", "%r9", "%r10","%rbx");
+  my ($tp18,$tp28,$tp48,$tp88,$acc8)=("%rcx","%r11","%r12","%r13","%rdx");
+  my $prefetch = shift;
+
+$code.=<<___;
+	mov	$tp10,$acc0
+	mov	$tp18,$acc8
+	and	$mask80,$acc0
+	and	$mask80,$acc8
+	mov	$acc0,$tp40
+	mov	$acc8,$tp48
+	shr	\$7,$tp40
+	lea	($tp10,$tp10),$tp20
+	shr	\$7,$tp48
+	lea	($tp18,$tp18),$tp28
+	sub	$tp40,$acc0
+	sub	$tp48,$acc8
+	and	$maskfe,$tp20
+	and	$maskfe,$tp28
+	and	$mask1b,$acc0
+	and	$mask1b,$acc8
+	xor	$tp20,$acc0
+	xor	$tp28,$acc8
+	mov	$acc0,$tp20
+	mov	$acc8,$tp28
+
+	and	$mask80,$acc0
+	and	$mask80,$acc8
+	mov	$acc0,$tp80
+	mov	$acc8,$tp88
+	shr	\$7,$tp80
+	lea	($tp20,$tp20),$tp40
+	shr	\$7,$tp88
+	lea	($tp28,$tp28),$tp48
+	sub	$tp80,$acc0
+	sub	$tp88,$acc8
+	and	$maskfe,$tp40
+	and	$maskfe,$tp48
+	and	$mask1b,$acc0
+	and	$mask1b,$acc8
+	xor	$tp40,$acc0
+	xor	$tp48,$acc8
+	mov	$acc0,$tp40
+	mov	$acc8,$tp48
+
+	and	$mask80,$acc0
+	and	$mask80,$acc8
+	mov	$acc0,$tp80
+	mov	$acc8,$tp88
+	shr	\$7,$tp80
+	 xor	$tp10,$tp20		# tp2^=tp1
+	shr	\$7,$tp88
+	 xor	$tp18,$tp28		# tp2^=tp1
+	sub	$tp80,$acc0
+	sub	$tp88,$acc8
+	lea	($tp40,$tp40),$tp80
+	lea	($tp48,$tp48),$tp88
+	 xor	$tp10,$tp40		# tp4^=tp1
+	 xor	$tp18,$tp48		# tp4^=tp1
+	and	$maskfe,$tp80
+	and	$maskfe,$tp88
+	and	$mask1b,$acc0
+	and	$mask1b,$acc8
+	xor	$acc0,$tp80
+	xor	$acc8,$tp88
+
+	xor	$tp80,$tp10		# tp1^=tp8
+	xor	$tp88,$tp18		# tp1^=tp8
+	xor	$tp80,$tp20		# tp2^tp1^=tp8
+	xor	$tp88,$tp28		# tp2^tp1^=tp8
+	mov	$tp10,$acc0
+	mov	$tp18,$acc8
+	xor	$tp80,$tp40		# tp4^tp1^=tp8
+	xor	$tp88,$tp48		# tp4^tp1^=tp8
+	shr	\$32,$acc0
+	shr	\$32,$acc8
+	xor	$tp20,$tp80		# tp8^=tp8^tp2^tp1=tp2^tp1
+	xor	$tp28,$tp88		# tp8^=tp8^tp2^tp1=tp2^tp1
+	rol	\$8,`&LO("$tp10")`	# ROTATE(tp1^tp8,8)
+	rol	\$8,`&LO("$tp18")`	# ROTATE(tp1^tp8,8)
+	xor	$tp40,$tp80		# tp2^tp1^=tp8^tp4^tp1=tp8^tp4^tp2
+	xor	$tp48,$tp88		# tp2^tp1^=tp8^tp4^tp1=tp8^tp4^tp2
+
+	rol	\$8,`&LO("$acc0")`	# ROTATE(tp1^tp8,8)
+	rol	\$8,`&LO("$acc8")`	# ROTATE(tp1^tp8,8)
+	xor	`&LO("$tp80")`,`&LO("$tp10")`
+	xor	`&LO("$tp88")`,`&LO("$tp18")`
+	shr	\$32,$tp80
+	shr	\$32,$tp88
+	xor	`&LO("$tp80")`,`&LO("$acc0")`
+	xor	`&LO("$tp88")`,`&LO("$acc8")`
+
+	mov	$tp20,$tp80
+	mov	$tp28,$tp88
+	shr	\$32,$tp80
+	shr	\$32,$tp88
+	rol	\$24,`&LO("$tp20")`	# ROTATE(tp2^tp1^tp8,24)
+	rol	\$24,`&LO("$tp28")`	# ROTATE(tp2^tp1^tp8,24)
+	rol	\$24,`&LO("$tp80")`	# ROTATE(tp2^tp1^tp8,24)
+	rol	\$24,`&LO("$tp88")`	# ROTATE(tp2^tp1^tp8,24)
+	xor	`&LO("$tp20")`,`&LO("$tp10")`
+	xor	`&LO("$tp28")`,`&LO("$tp18")`
+	mov	$tp40,$tp20
+	mov	$tp48,$tp28
+	xor	`&LO("$tp80")`,`&LO("$acc0")`
+	xor	`&LO("$tp88")`,`&LO("$acc8")`
+
+	`"mov	0($sbox),$mask80"	if ($prefetch)`
+	shr	\$32,$tp20
+	shr	\$32,$tp28
+	`"mov	64($sbox),$maskfe"	if ($prefetch)`
+	rol	\$16,`&LO("$tp40")`	# ROTATE(tp4^tp1^tp8,16)
+	rol	\$16,`&LO("$tp48")`	# ROTATE(tp4^tp1^tp8,16)
+	`"mov	128($sbox),$mask1b"	if ($prefetch)`
+	rol	\$16,`&LO("$tp20")`	# ROTATE(tp4^tp1^tp8,16)
+	rol	\$16,`&LO("$tp28")`	# ROTATE(tp4^tp1^tp8,16)
+	`"mov	192($sbox),$tp80"	if ($prefetch)`
+	xor	`&LO("$tp40")`,`&LO("$tp10")`
+	xor	`&LO("$tp48")`,`&LO("$tp18")`
+	`"mov	256($sbox),$tp88"	if ($prefetch)`
+	xor	`&LO("$tp20")`,`&LO("$acc0")`
+	xor	`&LO("$tp28")`,`&LO("$acc8")`
+___
+}
+
+$code.=<<___;
+.type	_x86_64_AES_decrypt_compact,\@abi-omnipotent
+.align	16
+_x86_64_AES_decrypt_compact:
+	lea	128($sbox),$inp			# size optimization
+	mov	0-128($inp),$acc1		# prefetch Td4
+	mov	32-128($inp),$acc2
+	mov	64-128($inp),$t0
+	mov	96-128($inp),$t1
+	mov	128-128($inp),$acc1
+	mov	160-128($inp),$acc2
+	mov	192-128($inp),$t0
+	mov	224-128($inp),$t1
+	jmp	.Ldec_loop_compact
+
+.align	16
+.Ldec_loop_compact:
+		xor	0($key),$s0		# xor with key
+		xor	4($key),$s1
+		xor	8($key),$s2
+		xor	12($key),$s3
+		lea	16($key),$key
+___
+		&deccompactvert();
+$code.=<<___;
+		cmp	16(%rsp),$key
+		je	.Ldec_compact_done
+
+		mov	256+0($sbox),$mask80
+		shl	\$32,%rbx
+		shl	\$32,%rdx
+		mov	256+8($sbox),$maskfe
+		or	%rbx,%rax
+		or	%rdx,%rcx
+		mov	256+16($sbox),$mask1b
+___
+		&dectransform(1);
+$code.=<<___;
+	jmp	.Ldec_loop_compact
+.align	16
+.Ldec_compact_done:
+	xor	0($key),$s0
+	xor	4($key),$s1
+	xor	8($key),$s2
+	xor	12($key),$s3
+	.byte	0xf3,0xc3			# rep ret
+.size	_x86_64_AES_decrypt_compact,.-_x86_64_AES_decrypt_compact
+___
+
 # void AES_decrypt (const void *inp,void *out,const AES_KEY *key);
 $code.=<<___;
 .globl	AES_decrypt
@@ -672,43 +1192,59 @@
 	push	%r14
 	push	%r15
 
+	# allocate frame "above" key schedule
+	mov	%rsp,%r10
+	lea	-63(%rdx),%rcx	# %rdx is key argument
+	and	\$-64,%rsp
+	sub	%rsp,%rcx
+	neg	%rcx
+	and	\$0x3c0,%rcx
+	sub	%rcx,%rsp
+	sub	\$32,%rsp
+
+	mov	%rsi,16(%rsp)	# save out
+	mov	%r10,24(%rsp)	# save real stack pointer
+.Ldec_prologue:
+
 	mov	%rdx,$key
-	mov	%rdi,$inp
-	mov	%rsi,$out
+	mov	240($key),$rnds	# load rounds
 
-	.picmeup	$sbox
-	lea	AES_Td-.($sbox),$sbox
+	mov	0(%rdi),$s0	# load input vector
+	mov	4(%rdi),$s1
+	mov	8(%rdi),$s2
+	mov	12(%rdi),$s3
 
-	# prefetch Td4
-	lea	2048+128($sbox),$sbox;
-	mov	0-128($sbox),$s0
-	mov	32-128($sbox),$s1
-	mov	64-128($sbox),$s2
-	mov	96-128($sbox),$s3
-	mov	128-128($sbox),$s0
-	mov	160-128($sbox),$s1
-	mov	192-128($sbox),$s2
-	mov	224-128($sbox),$s3
-	lea	-2048-128($sbox),$sbox;
+	shl	\$4,$rnds
+	lea	($key,$rnds),%rbp
+	mov	$key,(%rsp)	# key schedule
+	mov	%rbp,8(%rsp)	# end of key schedule
 
-	mov	0($inp),$s0
-	mov	4($inp),$s1
-	mov	8($inp),$s2
-	mov	12($inp),$s3
+	# pick Td4 copy which can't "overlap" with stack frame or key schedule
+	lea	.LAES_Td+2048(%rip),$sbox
+	lea	768(%rsp),%rbp
+	sub	$sbox,%rbp
+	and	\$0x300,%rbp
+	lea	($sbox,%rbp),$sbox
+	shr	\$3,%rbp	# recall "magic" constants!
+	add	%rbp,$sbox
 
-	call	_x86_64_AES_decrypt
+	call	_x86_64_AES_decrypt_compact
 
-	mov	$s0,0($out)
+	mov	16(%rsp),$out	# restore out
+	mov	24(%rsp),%rsi	# restore saved stack pointer
+	mov	$s0,0($out)	# write output vector
 	mov	$s1,4($out)
 	mov	$s2,8($out)
 	mov	$s3,12($out)
 
-	pop	%r15
-	pop	%r14
-	pop	%r13
-	pop	%r12
-	pop	%rbp
-	pop	%rbx
+	mov	(%rsi),%r15
+	mov	8(%rsi),%r14
+	mov	16(%rsi),%r13
+	mov	24(%rsi),%r12
+	mov	32(%rsi),%rbp
+	mov	40(%rsi),%rbx
+	lea	48(%rsi),%rsp
+.Ldec_epilogue:
 	ret
 .size	AES_decrypt,.-AES_decrypt
 ___
@@ -718,27 +1254,26 @@
 {
 $code.=<<___;
 	movz	%dl,%esi		# rk[i]>>0
-	mov	2(%rbp,%rsi,8),%ebx
+	movzb	-128(%rbp,%rsi),%ebx
 	movz	%dh,%esi		# rk[i]>>8
-	and	\$0xFF000000,%ebx
+	shl	\$24,%ebx
 	xor	%ebx,%eax
 
-	mov	2(%rbp,%rsi,8),%ebx
+	movzb	-128(%rbp,%rsi),%ebx
 	shr	\$16,%edx
-	and	\$0x000000FF,%ebx
 	movz	%dl,%esi		# rk[i]>>16
 	xor	%ebx,%eax
 
-	mov	0(%rbp,%rsi,8),%ebx
+	movzb	-128(%rbp,%rsi),%ebx
 	movz	%dh,%esi		# rk[i]>>24
-	and	\$0x0000FF00,%ebx
+	shl	\$8,%ebx
 	xor	%ebx,%eax
 
-	mov	0(%rbp,%rsi,8),%ebx
-	and	\$0x00FF0000,%ebx
+	movzb	-128(%rbp,%rsi),%ebx
+	shl	\$16,%ebx
 	xor	%ebx,%eax
 
-	xor	2048(%rbp,%rcx,4),%eax		# rcon
+	xor	1024-128(%rbp,%rcx,4),%eax		# rcon
 ___
 }
 
@@ -751,7 +1286,29 @@
 AES_set_encrypt_key:
 	push	%rbx
 	push	%rbp
+	push	%r12			# redundant, but allows to share 
+	push	%r13			# exception handler...
+	push	%r14
+	push	%r15
+	sub	\$8,%rsp
+.Lenc_key_prologue:
 
+	call	_x86_64_AES_set_encrypt_key
+
+	mov	8(%rsp),%r15
+	mov	16(%rsp),%r14
+	mov	24(%rsp),%r13
+	mov	32(%rsp),%r12
+	mov	40(%rsp),%rbp
+	mov	48(%rsp),%rbx
+	add	\$56,%rsp
+.Lenc_key_epilogue:
+	ret
+.size	AES_set_encrypt_key,.-AES_set_encrypt_key
+
+.type	_x86_64_AES_set_encrypt_key,\@abi-omnipotent
+.align	16
+_x86_64_AES_set_encrypt_key:
 	mov	%esi,%ecx			# %ecx=bits
 	mov	%rdi,%rsi			# %rsi=userKey
 	mov	%rdx,%rdi			# %rdi=key
@@ -761,8 +1318,18 @@
 	test	\$-1,%rdi
 	jz	.Lbadpointer
 
-	.picmeup %rbp
-	lea	AES_Te-.(%rbp),%rbp
+	lea	.LAES_Te(%rip),%rbp
+	lea	2048+128(%rbp),%rbp
+
+	# prefetch Te4
+	mov	0-128(%rbp),%eax
+	mov	32-128(%rbp),%ebx
+	mov	64-128(%rbp),%r8d
+	mov	96-128(%rbp),%edx
+	mov	128-128(%rbp),%eax
+	mov	160-128(%rbp),%ebx
+	mov	192-128(%rbp),%r8d
+	mov	224-128(%rbp),%edx
 
 	cmp	\$128,%ecx
 	je	.L10rounds
@@ -774,15 +1341,12 @@
 	jmp	.Lexit
 
 .L10rounds:
-	mov	0(%rsi),%eax			# copy first 4 dwords
-	mov	4(%rsi),%ebx
-	mov	8(%rsi),%ecx
-	mov	12(%rsi),%edx
-	mov	%eax,0(%rdi)
-	mov	%ebx,4(%rdi)
-	mov	%ecx,8(%rdi)
-	mov	%edx,12(%rdi)
+	mov	0(%rsi),%rax			# copy first 4 dwords
+	mov	8(%rsi),%rdx
+	mov	%rax,0(%rdi)
+	mov	%rdx,8(%rdi)
 
+	shr	\$32,%rdx
 	xor	%ecx,%ecx
 	jmp	.L10shortcut
 .align	4
@@ -810,19 +1374,14 @@
 	jmp	.Lexit
 
 .L12rounds:
-	mov	0(%rsi),%eax			# copy first 6 dwords
-	mov	4(%rsi),%ebx
-	mov	8(%rsi),%ecx
-	mov	12(%rsi),%edx
-	mov	%eax,0(%rdi)
-	mov	%ebx,4(%rdi)
-	mov	%ecx,8(%rdi)
-	mov	%edx,12(%rdi)
-	mov	16(%rsi),%ecx
-	mov	20(%rsi),%edx
-	mov	%ecx,16(%rdi)
-	mov	%edx,20(%rdi)
+	mov	0(%rsi),%rax			# copy first 6 dwords
+	mov	8(%rsi),%rbx
+	mov	16(%rsi),%rdx
+	mov	%rax,0(%rdi)
+	mov	%rbx,8(%rdi)
+	mov	%rdx,16(%rdi)
 
+	shr	\$32,%rdx
 	xor	%ecx,%ecx
 	jmp	.L12shortcut
 .align	4
@@ -858,30 +1417,23 @@
 	jmp	.Lexit
 
 .L14rounds:		
-	mov	0(%rsi),%eax			# copy first 8 dwords
-	mov	4(%rsi),%ebx
-	mov	8(%rsi),%ecx
-	mov	12(%rsi),%edx
-	mov	%eax,0(%rdi)
-	mov	%ebx,4(%rdi)
-	mov	%ecx,8(%rdi)
-	mov	%edx,12(%rdi)
-	mov	16(%rsi),%eax
-	mov	20(%rsi),%ebx
-	mov	24(%rsi),%ecx
-	mov	28(%rsi),%edx
-	mov	%eax,16(%rdi)
-	mov	%ebx,20(%rdi)
-	mov	%ecx,24(%rdi)
-	mov	%edx,28(%rdi)
+	mov	0(%rsi),%rax			# copy first 8 dwords
+	mov	8(%rsi),%rbx
+	mov	16(%rsi),%rcx
+	mov	24(%rsi),%rdx
+	mov	%rax,0(%rdi)
+	mov	%rbx,8(%rdi)
+	mov	%rcx,16(%rdi)
+	mov	%rdx,24(%rdi)
 
+	shr	\$32,%rdx
 	xor	%ecx,%ecx
 	jmp	.L14shortcut
 .align	4
 .L14loop:
+		mov	0(%rdi),%eax			# rk[0]
 		mov	28(%rdi),%edx			# rk[4]
 .L14shortcut:
-		mov	0(%rdi),%eax			# rk[0]
 ___
 		&enckey	();
 $code.=<<___;
@@ -900,24 +1452,23 @@
 		mov	%eax,%edx
 		mov	16(%rdi),%eax			# rk[4]
 		movz	%dl,%esi			# rk[11]>>0
-		mov	2(%rbp,%rsi,8),%ebx
+		movzb	-128(%rbp,%rsi),%ebx
 		movz	%dh,%esi			# rk[11]>>8
-		and	\$0x000000FF,%ebx
 		xor	%ebx,%eax
 
-		mov	0(%rbp,%rsi,8),%ebx
+		movzb	-128(%rbp,%rsi),%ebx
 		shr	\$16,%edx
-		and	\$0x0000FF00,%ebx
+		shl	\$8,%ebx
 		movz	%dl,%esi			# rk[11]>>16
 		xor	%ebx,%eax
 
-		mov	0(%rbp,%rsi,8),%ebx
+		movzb	-128(%rbp,%rsi),%ebx
 		movz	%dh,%esi			# rk[11]>>24
-		and	\$0x00FF0000,%ebx
+		shl	\$16,%ebx
 		xor	%ebx,%eax
 
-		mov	2(%rbp,%rsi,8),%ebx
-		and	\$0xFF000000,%ebx
+		movzb	-128(%rbp,%rsi),%ebx
+		shl	\$24,%ebx
 		xor	%ebx,%eax
 
 		mov	%eax,48(%rdi)			# rk[12]
@@ -938,31 +1489,61 @@
 .Lbadpointer:
 	mov	\$-1,%rax
 .Lexit:
-	pop	%rbp
-	pop	%rbx
-	ret
-.size	AES_set_encrypt_key,.-AES_set_encrypt_key
+	.byte	0xf3,0xc3			# rep ret
+.size	_x86_64_AES_set_encrypt_key,.-_x86_64_AES_set_encrypt_key
 ___
 
-sub deckey()
+sub deckey_ref()
 { my ($i,$ptr,$te,$td) = @_;
+  my ($tp1,$tp2,$tp4,$tp8,$acc)=("%eax","%ebx","%edi","%edx","%r8d");
 $code.=<<___;
-	mov	$i($ptr),%eax
-	mov	%eax,%edx
-	movz	%ah,%ebx
-	shr	\$16,%edx
-	and	\$0xFF,%eax
-	movzb	2($te,%rax,8),%rax
-	movzb	2($te,%rbx,8),%rbx
-	mov	0($td,%rax,8),%eax
-	xor	3($td,%rbx,8),%eax
-	movzb	%dh,%ebx
-	and	\$0xFF,%edx
-	movzb	2($te,%rdx,8),%rdx
-	movzb	2($te,%rbx,8),%rbx
-	xor	2($td,%rdx,8),%eax
-	xor	1($td,%rbx,8),%eax
-	mov	%eax,$i($ptr)
+	mov	$i($ptr),$tp1
+	mov	$tp1,$acc
+	and	\$0x80808080,$acc
+	mov	$acc,$tp4
+	shr	\$7,$tp4
+	lea	0($tp1,$tp1),$tp2
+	sub	$tp4,$acc
+	and	\$0xfefefefe,$tp2
+	and	\$0x1b1b1b1b,$acc
+	xor	$tp2,$acc
+	mov	$acc,$tp2
+
+	and	\$0x80808080,$acc
+	mov	$acc,$tp8
+	shr	\$7,$tp8
+	lea	0($tp2,$tp2),$tp4
+	sub	$tp8,$acc
+	and	\$0xfefefefe,$tp4
+	and	\$0x1b1b1b1b,$acc
+	 xor	$tp1,$tp2		# tp2^tp1
+	xor	$tp4,$acc
+	mov	$acc,$tp4
+
+	and	\$0x80808080,$acc
+	mov	$acc,$tp8
+	shr	\$7,$tp8
+	sub	$tp8,$acc
+	lea	0($tp4,$tp4),$tp8
+	 xor	$tp1,$tp4		# tp4^tp1
+	and	\$0xfefefefe,$tp8
+	and	\$0x1b1b1b1b,$acc
+	xor	$acc,$tp8
+
+	xor	$tp8,$tp1		# tp1^tp8
+	rol	\$8,$tp1		# ROTATE(tp1^tp8,8)
+	xor	$tp8,$tp2		# tp2^tp1^tp8
+	xor	$tp8,$tp4		# tp4^tp1^tp8
+	xor	$tp2,$tp8
+	xor	$tp4,$tp8		# tp8^(tp8^tp4^tp1)^(tp8^tp2^tp1)=tp8^tp4^tp2
+
+	xor	$tp8,$tp1
+	rol	\$24,$tp2		# ROTATE(tp2^tp1^tp8,24)
+	xor	$tp2,$tp1
+	rol	\$16,$tp4		# ROTATE(tp4^tp1^tp8,16)
+	xor	$tp4,$tp1
+
+	mov	$tp1,$i($ptr)
 ___
 }
 
@@ -973,19 +1554,23 @@
 .type	AES_set_decrypt_key,\@function,3
 .align	16
 AES_set_decrypt_key:
-	push	%rdx
-	call	AES_set_encrypt_key
-	cmp	\$0,%eax
-	je	.Lproceed
-	lea	24(%rsp),%rsp
-	ret
-.Lproceed:
-	mov	(%rsp),%r8		# restore key schedule
-	mov	%rbx,(%rsp)
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	push	%rdx			# save key schedule
+.Ldec_key_prologue:
 
-	mov	240(%r8),%ecx		# pull number of rounds
+	call	_x86_64_AES_set_encrypt_key
+	mov	(%rsp),%r8		# restore key schedule
+	cmp	\$0,%eax
+	jne	.Labort
+
+	mov	240(%r8),%r14d		# pull number of rounds
 	xor	%rdi,%rdi
-	lea	(%rdi,%rcx,4),%rcx
+	lea	(%rdi,%r14d,4),%rcx
 	mov	%r8,%rsi
 	lea	(%r8,%rcx,4),%rdi	# pointer to last chunk
 .align	4
@@ -1003,27 +1588,39 @@
 		cmp	%rsi,%rdi
 	jne	.Linvert
 
-	.picmeup %r9
-	lea	AES_Td-.(%r9),%rdi
-	lea	AES_Te-AES_Td(%rdi),%r9
+	lea	.LAES_Te+2048+1024(%rip),%rax	# rcon
 
-	mov	%r8,%rsi
-	mov	240(%r8),%ecx		# pull number of rounds
-	sub	\$1,%ecx
+	mov	40(%rax),$mask80
+	mov	48(%rax),$maskfe
+	mov	56(%rax),$mask1b
+
+	mov	%r8,$key
+	sub	\$1,%r14d
 .align	4
 .Lpermute:
-		lea	16(%rsi),%rsi
+		lea	16($key),$key
+		mov	0($key),%rax
+		mov	8($key),%rcx
 ___
-		&deckey	(0,"%rsi","%r9","%rdi");
-		&deckey	(4,"%rsi","%r9","%rdi");
-		&deckey	(8,"%rsi","%r9","%rdi");
-		&deckey	(12,"%rsi","%r9","%rdi");
+		&dectransform ();
 $code.=<<___;
-		sub	\$1,%ecx
+		mov	%eax,0($key)
+		mov	%ebx,4($key)
+		mov	%ecx,8($key)
+		mov	%edx,12($key)
+		sub	\$1,%r14d
 	jnz	.Lpermute
 
 	xor	%rax,%rax
-	pop	%rbx
+.Labort:
+	mov	8(%rsp),%r15
+	mov	16(%rsp),%r14
+	mov	24(%rsp),%r13
+	mov	32(%rsp),%r12
+	mov	40(%rsp),%rbp
+	mov	48(%rsp),%rbx
+	add	\$56,%rsp
+.Ldec_key_epilogue:
 	ret
 .size	AES_set_decrypt_key,.-AES_set_decrypt_key
 ___
@@ -1034,47 +1631,59 @@
 {
 # stack frame layout
 # -8(%rsp)		return address
-my $_rsp="0(%rsp)";		# saved %rsp
-my $_len="8(%rsp)";		# copy of 3rd parameter, length
-my $_key="16(%rsp)";		# copy of 4th parameter, key
-my $_ivp="24(%rsp)";		# copy of 5th parameter, ivp
-my $keyp="32(%rsp)";		# one to pass as $key
-my $ivec="40(%rsp)";		# ivec[16]
-my $aes_key="56(%rsp)";		# copy of aes_key
-my $mark="56+240(%rsp)";	# copy of aes_key->rounds
+my $keyp="0(%rsp)";		# one to pass as $key
+my $keyend="8(%rsp)";		# &(keyp->rd_key[4*keyp->rounds])
+my $_rsp="16(%rsp)";		# saved %rsp
+my $_inp="24(%rsp)";		# copy of 1st parameter, inp
+my $_out="32(%rsp)";		# copy of 2nd parameter, out
+my $_len="40(%rsp)";		# copy of 3rd parameter, length
+my $_key="48(%rsp)";		# copy of 4th parameter, key
+my $_ivp="56(%rsp)";		# copy of 5th parameter, ivp
+my $ivec="64(%rsp)";		# ivec[16]
+my $aes_key="80(%rsp)";		# copy of aes_key
+my $mark="80+240(%rsp)";	# copy of aes_key->rounds
 
 $code.=<<___;
 .globl	AES_cbc_encrypt
 .type	AES_cbc_encrypt,\@function,6
 .align	16
+.extern	OPENSSL_ia32cap_P
 AES_cbc_encrypt:
 	cmp	\$0,%rdx	# check length
-	je	.Lcbc_just_ret
+	je	.Lcbc_epilogue
+	pushfq
 	push	%rbx
 	push	%rbp
 	push	%r12
 	push	%r13
 	push	%r14
 	push	%r15
-	pushfq
+.Lcbc_prologue:
+
 	cld
 	mov	%r9d,%r9d	# clear upper half of enc
 
-	.picmeup $sbox
-.Lcbc_pic_point:
-
+	lea	.LAES_Te(%rip),$sbox
 	cmp	\$0,%r9
-	je	.LDECRYPT
+	jne	.Lcbc_picked_te
+	lea	.LAES_Td(%rip),$sbox
+.Lcbc_picked_te:
 
-	lea	AES_Te-.Lcbc_pic_point($sbox),$sbox
+	mov	OPENSSL_ia32cap_P(%rip),%r10d
+	cmp	\$$speed_limit,%rdx
+	jb	.Lcbc_slow_prologue
+	test	\$15,%rdx
+	jnz	.Lcbc_slow_prologue
+	bt	\$28,%r10d
+	jc	.Lcbc_slow_prologue
 
 	# allocate aligned stack frame...
-	lea	-64-248(%rsp),$key
+	lea	-88-248(%rsp),$key
 	and	\$-64,$key
 
-	# ... and make it doesn't alias with AES_Te modulo 4096
+	# ... and make sure it doesn't alias with AES_T[ed] modulo 4096
 	mov	$sbox,%r10
-	lea	2048($sbox),%r11
+	lea	2304($sbox),%r11
 	mov	$key,%r12
 	and	\$0xFFF,%r10	# s = $sbox&0xfff
 	and	\$0xFFF,%r11	# e = ($sbox+2048)&0xfff
@@ -1094,22 +1703,27 @@
 .Lcbc_te_ok:
 
 	xchg	%rsp,$key
-	add	\$8,%rsp	# reserve for return address!
+	#add	\$8,%rsp	# reserve for return address!
 	mov	$key,$_rsp	# save %rsp
+.Lcbc_fast_body:
+	mov	%rdi,$_inp	# save copy of inp
+	mov	%rsi,$_out	# save copy of out
 	mov	%rdx,$_len	# save copy of len
 	mov	%rcx,$_key	# save copy of key
 	mov	%r8,$_ivp	# save copy of ivp
 	movl	\$0,$mark	# copy of aes_key->rounds = 0;
 	mov	%r8,%rbp	# rearrange input arguments
+	mov	%r9,%rbx
 	mov	%rsi,$out
 	mov	%rdi,$inp
 	mov	%rcx,$key
 
+	mov	240($key),%eax		# key->rounds
 	# do we copy key schedule to stack?
 	mov	$key,%r10
 	sub	$sbox,%r10
 	and	\$0xfff,%r10
-	cmp	\$2048,%r10
+	cmp	\$2304,%r10
 	jb	.Lcbc_do_ecopy
 	cmp	\$4096-248,%r10
 	jb	.Lcbc_skip_ecopy
@@ -1120,12 +1734,11 @@
 		lea	$aes_key,$key
 		mov	\$240/8,%ecx
 		.long	0x90A548F3	# rep movsq
-		mov	(%rsi),%eax	# copy aes_key->rounds
-		mov	%eax,(%rdi)
+		mov	%eax,(%rdi)	# copy aes_key->rounds
 .Lcbc_skip_ecopy:
 	mov	$key,$keyp	# save key pointer
 
-	mov	\$16,%ecx
+	mov	\$18,%ecx
 .align	4
 .Lcbc_prefetch_te:
 		mov	0($sbox),%r10
@@ -1135,184 +1748,77 @@
 		lea	128($sbox),$sbox
 		sub	\$1,%ecx
 	jnz	.Lcbc_prefetch_te
-	sub	\$2048,$sbox
+	lea	-2304($sbox),$sbox
 
-	test	\$-16,%rdx		# check upon length
-	mov	%rdx,%r10
+	cmp	\$0,%rbx
+	je	.LFAST_DECRYPT
+
+#----------------------------- ENCRYPT -----------------------------#
 	mov	0(%rbp),$s0		# load iv
 	mov	4(%rbp),$s1
 	mov	8(%rbp),$s2
 	mov	12(%rbp),$s3
-	jz	.Lcbc_enc_tail		# short input...
 
 .align	4
-.Lcbc_enc_loop:
+.Lcbc_fast_enc_loop:
 		xor	0($inp),$s0
 		xor	4($inp),$s1
 		xor	8($inp),$s2
 		xor	12($inp),$s3
-		mov	$inp,$ivec	# if ($verticalspin) save inp
-
 		mov	$keyp,$key	# restore key
+		mov	$inp,$_inp	# if ($verticalspin) save inp
+
 		call	_x86_64_AES_encrypt
 
-		mov	$ivec,$inp	# if ($verticalspin) restore inp
+		mov	$_inp,$inp	# if ($verticalspin) restore inp
+		mov	$_len,%r10
 		mov	$s0,0($out)
 		mov	$s1,4($out)
 		mov	$s2,8($out)
 		mov	$s3,12($out)
 
-		mov	$_len,%r10
 		lea	16($inp),$inp
 		lea	16($out),$out
 		sub	\$16,%r10
 		test	\$-16,%r10
 		mov	%r10,$_len
-	jnz	.Lcbc_enc_loop
-	test	\$15,%r10
-	jnz	.Lcbc_enc_tail
+	jnz	.Lcbc_fast_enc_loop
 	mov	$_ivp,%rbp	# restore ivp
 	mov	$s0,0(%rbp)	# save ivec
 	mov	$s1,4(%rbp)
 	mov	$s2,8(%rbp)
 	mov	$s3,12(%rbp)
 
-.align	4
-.Lcbc_cleanup:
-	cmpl	\$0,$mark	# was the key schedule copied?
-	lea	$aes_key,%rdi
-	je	.Lcbc_exit
-		mov	\$240/8,%ecx
-		xor	%rax,%rax
-		.long	0x90AB48F3	# rep stosq
-.Lcbc_exit:
-	mov	$_rsp,%rsp
-	popfq
-	pop	%r15
-	pop	%r14
-	pop	%r13
-	pop	%r12
-	pop	%rbp
-	pop	%rbx
-.Lcbc_just_ret:
-	ret
-.align	4
-.Lcbc_enc_tail:
-	mov	%rax,%r11
-	mov	%rcx,%r12
-	mov	%r10,%rcx
-	mov	$inp,%rsi
-	mov	$out,%rdi
-	.long	0xF689A4F3		# rep movsb
-	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...
+	jmp	.Lcbc_fast_cleanup
+
 #----------------------------- DECRYPT -----------------------------#
 .align	16
-.LDECRYPT:
-	lea	AES_Td-.Lcbc_pic_point($sbox),$sbox
-
-	# allocate aligned stack frame...
-	lea	-64-248(%rsp),$key
-	and	\$-64,$key
-
-	# ... and make it doesn't alias with AES_Td modulo 4096
-	mov	$sbox,%r10
-	lea	2304($sbox),%r11
-	mov	$key,%r12
-	and	\$0xFFF,%r10	# s = $sbox&0xfff
-	and	\$0xFFF,%r11	# e = ($sbox+2048+256)&0xfff
-	and	\$0xFFF,%r12	# p = %rsp&0xfff
-
-	cmp	%r11,%r12	# if (p=>e) %rsp =- (p-e);
-	jb	.Lcbc_td_break_out
-	sub	%r11,%r12
-	sub	%r12,$key
-	jmp	.Lcbc_td_ok
-.Lcbc_td_break_out:		# else %rsp -= (p-s)&0xfff + framesz
-	sub	%r10,%r12
-	and	\$0xFFF,%r12
-	add	\$320,%r12
-	sub	%r12,$key
-.align	4
-.Lcbc_td_ok:
-
-	xchg	%rsp,$key
-	add	\$8,%rsp	# reserve for return address!
-	mov	$key,$_rsp	# save %rsp
-	mov	%rdx,$_len	# save copy of len
-	mov	%rcx,$_key	# save copy of key
-	mov	%r8,$_ivp	# save copy of ivp
-	movl	\$0,$mark	# copy of aes_key->rounds = 0;
-	mov	%r8,%rbp	# rearrange input arguments
-	mov	%rsi,$out
-	mov	%rdi,$inp
-	mov	%rcx,$key
-
-	# do we copy key schedule to stack?
-	mov	$key,%r10
-	sub	$sbox,%r10
-	and	\$0xfff,%r10
-	cmp	\$2304,%r10
-	jb	.Lcbc_do_dcopy
-	cmp	\$4096-248,%r10
-	jb	.Lcbc_skip_dcopy
-.align	4
-.Lcbc_do_dcopy:
-		mov	$key,%rsi
-		lea	$aes_key,%rdi
-		lea	$aes_key,$key
-		mov	\$240/8,%ecx
-		.long	0x90A548F3	# rep movsq
-		mov	(%rsi),%eax	# copy aes_key->rounds
-		mov	%eax,(%rdi)
-.Lcbc_skip_dcopy:
-	mov	$key,$keyp	# save key pointer
-
-	mov	\$18,%ecx
-.align	4
-.Lcbc_prefetch_td:
-		mov	0($sbox),%r10
-		mov	32($sbox),%r11
-		mov	64($sbox),%r12
-		mov	96($sbox),%r13
-		lea	128($sbox),$sbox
-		sub	\$1,%ecx
-	jnz	.Lcbc_prefetch_td
-	sub	\$2304,$sbox
-
+.LFAST_DECRYPT:
 	cmp	$inp,$out
-	je	.Lcbc_dec_in_place
+	je	.Lcbc_fast_dec_in_place
 
 	mov	%rbp,$ivec
 .align	4
-.Lcbc_dec_loop:
-		mov	0($inp),$s0		# read input
+.Lcbc_fast_dec_loop:
+		mov	0($inp),$s0	# read input
 		mov	4($inp),$s1
 		mov	8($inp),$s2
 		mov	12($inp),$s3
-		mov	$inp,8+$ivec	# if ($verticalspin) save inp
-
 		mov	$keyp,$key	# restore key
+		mov	$inp,$_inp	# if ($verticalspin) save inp
+
 		call	_x86_64_AES_decrypt
 
 		mov	$ivec,%rbp	# load ivp
-		mov	8+$ivec,$inp	# if ($verticalspin) restore inp
+		mov	$_inp,$inp	# if ($verticalspin) restore inp
+		mov	$_len,%r10	# load len
 		xor	0(%rbp),$s0	# xor iv
 		xor	4(%rbp),$s1
 		xor	8(%rbp),$s2
 		xor	12(%rbp),$s3
 		mov	$inp,%rbp	# current input, next iv
 
-		mov	$_len,%r10	# load len
 		sub	\$16,%r10
-		jc	.Lcbc_dec_partial
 		mov	%r10,$_len	# update len
 		mov	%rbp,$ivec	# update ivp
 
@@ -1323,81 +1829,281 @@
 
 		lea	16($inp),$inp
 		lea	16($out),$out
-	jnz	.Lcbc_dec_loop
-.Lcbc_dec_end:
+	jnz	.Lcbc_fast_dec_loop
 	mov	$_ivp,%r12		# load user ivp
 	mov	0(%rbp),%r10		# load iv
 	mov	8(%rbp),%r11
 	mov	%r10,0(%r12)		# copy back to user
 	mov	%r11,8(%r12)
-	jmp	.Lcbc_cleanup
-
-.align	4
-.Lcbc_dec_partial:
-	mov	$s0,0+$ivec		# dump output to stack
-	mov	$s1,4+$ivec
-	mov	$s2,8+$ivec
-	mov	$s3,12+$ivec
-	mov	$out,%rdi
-	lea	$ivec,%rsi
-	mov	\$16,%rcx
-	add	%r10,%rcx		# number of bytes to copy
-	.long	0xF689A4F3		# rep movsb
-	jmp	.Lcbc_dec_end
+	jmp	.Lcbc_fast_cleanup
 
 .align	16
-.Lcbc_dec_in_place:
+.Lcbc_fast_dec_in_place:
+	mov	0(%rbp),%r10		# copy iv to stack
+	mov	8(%rbp),%r11
+	mov	%r10,0+$ivec
+	mov	%r11,8+$ivec
+.align	4
+.Lcbc_fast_dec_in_place_loop:
 		mov	0($inp),$s0	# load input
 		mov	4($inp),$s1
 		mov	8($inp),$s2
 		mov	12($inp),$s3
+		mov	$keyp,$key	# restore key
+		mov	$inp,$_inp	# if ($verticalspin) save inp
 
-		mov	$inp,$ivec	# if ($verticalspin) save inp
-		mov	$keyp,$key
 		call	_x86_64_AES_decrypt
 
-		mov	$ivec,$inp	# if ($verticalspin) restore inp
-		mov	$_ivp,%rbp
-		xor	0(%rbp),$s0
-		xor	4(%rbp),$s1
-		xor	8(%rbp),$s2
-		xor	12(%rbp),$s3
+		mov	$_inp,$inp	# if ($verticalspin) restore inp
+		mov	$_len,%r10
+		xor	0+$ivec,$s0
+		xor	4+$ivec,$s1
+		xor	8+$ivec,$s2
+		xor	12+$ivec,$s3
 
-		mov	0($inp),%r10	# copy input to iv
-		mov	8($inp),%r11
-		mov	%r10,0(%rbp)
-		mov	%r11,8(%rbp)
+		mov	0($inp),%r11	# load input
+		mov	8($inp),%r12
+		sub	\$16,%r10
+		jz	.Lcbc_fast_dec_in_place_done
+
+		mov	%r11,0+$ivec	# copy input to iv
+		mov	%r12,8+$ivec
 
 		mov	$s0,0($out)	# save output [zaps input]
 		mov	$s1,4($out)
 		mov	$s2,8($out)
 		mov	$s3,12($out)
 
-		mov	$_len,%rcx
 		lea	16($inp),$inp
 		lea	16($out),$out
-		sub	\$16,%rcx
-		jc	.Lcbc_dec_in_place_partial
-		mov	%rcx,$_len
-	jnz	.Lcbc_dec_in_place
-	jmp	.Lcbc_cleanup
+		mov	%r10,$_len
+	jmp	.Lcbc_fast_dec_in_place_loop
+.Lcbc_fast_dec_in_place_done:
+	mov	$_ivp,%rdi
+	mov	%r11,0(%rdi)	# copy iv back to user
+	mov	%r12,8(%rdi)
+
+	mov	$s0,0($out)	# save output [zaps input]
+	mov	$s1,4($out)
+	mov	$s2,8($out)
+	mov	$s3,12($out)
 
 .align	4
-.Lcbc_dec_in_place_partial:
-	# one can argue if this is actually required
-	lea	($out,%rcx),%rdi
-	lea	(%rbp,%rcx),%rsi
-	neg	%rcx
-	.long	0xF689A4F3	# rep movsb	# restore tail
-	jmp	.Lcbc_cleanup
+.Lcbc_fast_cleanup:
+	cmpl	\$0,$mark	# was the key schedule copied?
+	lea	$aes_key,%rdi
+	je	.Lcbc_exit
+		mov	\$240/8,%ecx
+		xor	%rax,%rax
+		.long	0x90AB48F3	# rep stosq
+
+	jmp	.Lcbc_exit
+
+#--------------------------- SLOW ROUTINE ---------------------------#
+.align	16
+.Lcbc_slow_prologue:
+	# allocate aligned stack frame...
+	lea	-88(%rsp),%rbp
+	and	\$-64,%rbp
+	# ... just "above" key schedule
+	lea	-88-63(%rcx),%r10
+	sub	%rbp,%r10
+	neg	%r10
+	and	\$0x3c0,%r10
+	sub	%r10,%rbp
+
+	xchg	%rsp,%rbp
+	#add	\$8,%rsp	# reserve for return address!
+	mov	%rbp,$_rsp	# save %rsp
+.Lcbc_slow_body:
+	#mov	%rdi,$_inp	# save copy of inp
+	#mov	%rsi,$_out	# save copy of out
+	#mov	%rdx,$_len	# save copy of len
+	#mov	%rcx,$_key	# save copy of key
+	mov	%r8,$_ivp	# save copy of ivp
+	mov	%r8,%rbp	# rearrange input arguments
+	mov	%r9,%rbx
+	mov	%rsi,$out
+	mov	%rdi,$inp
+	mov	%rcx,$key
+	mov	%rdx,%r10
+
+	mov	240($key),%eax
+	mov	$key,$keyp	# save key pointer
+	shl	\$4,%eax
+	lea	($key,%rax),%rax
+	mov	%rax,$keyend
+
+	# pick Te4 copy which can't "overlap" with stack frame or key scdedule
+	lea	2048($sbox),$sbox
+	lea	768-8(%rsp),%rax
+	sub	$sbox,%rax
+	and	\$0x300,%rax
+	lea	($sbox,%rax),$sbox
+
+	cmp	\$0,%rbx
+	je	.LSLOW_DECRYPT
+
+#--------------------------- SLOW ENCRYPT ---------------------------#
+	test	\$-16,%r10		# check upon length
+	mov	0(%rbp),$s0		# load iv
+	mov	4(%rbp),$s1
+	mov	8(%rbp),$s2
+	mov	12(%rbp),$s3
+	jz	.Lcbc_slow_enc_tail	# short input...
+
+.align	4
+.Lcbc_slow_enc_loop:
+		xor	0($inp),$s0
+		xor	4($inp),$s1
+		xor	8($inp),$s2
+		xor	12($inp),$s3
+		mov	$keyp,$key	# restore key
+		mov	$inp,$_inp	# save inp
+		mov	$out,$_out	# save out
+		mov	%r10,$_len	# save len
+
+		call	_x86_64_AES_encrypt_compact
+
+		mov	$_inp,$inp	# restore inp
+		mov	$_out,$out	# restore out
+		mov	$_len,%r10	# restore len
+		mov	$s0,0($out)
+		mov	$s1,4($out)
+		mov	$s2,8($out)
+		mov	$s3,12($out)
+
+		lea	16($inp),$inp
+		lea	16($out),$out
+		sub	\$16,%r10
+		test	\$-16,%r10
+	jnz	.Lcbc_slow_enc_loop
+	test	\$15,%r10
+	jnz	.Lcbc_slow_enc_tail
+	mov	$_ivp,%rbp	# restore ivp
+	mov	$s0,0(%rbp)	# save ivec
+	mov	$s1,4(%rbp)
+	mov	$s2,8(%rbp)
+	mov	$s3,12(%rbp)
+
+	jmp	.Lcbc_exit
+
+.align	4
+.Lcbc_slow_enc_tail:
+	mov	%rax,%r11
+	mov	%rcx,%r12
+	mov	%r10,%rcx
+	mov	$inp,%rsi
+	mov	$out,%rdi
+	.long	0x9066A4F3		# rep movsb
+	mov	\$16,%rcx		# zero tail
+	sub	%r10,%rcx
+	xor	%rax,%rax
+	.long	0x9066AAF3		# rep stosb
+	mov	$out,$inp		# this is not a mistake!
+	mov	\$16,%r10		# len=16
+	mov	%r11,%rax
+	mov	%r12,%rcx
+	jmp	.Lcbc_slow_enc_loop	# one more spin...
+#--------------------------- SLOW DECRYPT ---------------------------#
+.align	16
+.LSLOW_DECRYPT:
+	shr	\$3,%rax
+	add	%rax,$sbox		# recall "magic" constants!
+
+	mov	0(%rbp),%r11		# copy iv to stack
+	mov	8(%rbp),%r12
+	mov	%r11,0+$ivec
+	mov	%r12,8+$ivec
+
+.align	4
+.Lcbc_slow_dec_loop:
+		mov	0($inp),$s0	# load input
+		mov	4($inp),$s1
+		mov	8($inp),$s2
+		mov	12($inp),$s3
+		mov	$keyp,$key	# restore key
+		mov	$inp,$_inp	# save inp
+		mov	$out,$_out	# save out
+		mov	%r10,$_len	# save len
+
+		call	_x86_64_AES_decrypt_compact
+
+		mov	$_inp,$inp	# restore inp
+		mov	$_out,$out	# restore out
+		mov	$_len,%r10
+		xor	0+$ivec,$s0
+		xor	4+$ivec,$s1
+		xor	8+$ivec,$s2
+		xor	12+$ivec,$s3
+
+		mov	0($inp),%r11	# load input
+		mov	8($inp),%r12
+		sub	\$16,%r10
+		jc	.Lcbc_slow_dec_partial
+		jz	.Lcbc_slow_dec_done
+
+		mov	%r11,0+$ivec	# copy input to iv
+		mov	%r12,8+$ivec
+
+		mov	$s0,0($out)	# save output [can zap input]
+		mov	$s1,4($out)
+		mov	$s2,8($out)
+		mov	$s3,12($out)
+
+		lea	16($inp),$inp
+		lea	16($out),$out
+	jmp	.Lcbc_slow_dec_loop
+.Lcbc_slow_dec_done:
+	mov	$_ivp,%rdi
+	mov	%r11,0(%rdi)		# copy iv back to user
+	mov	%r12,8(%rdi)
+
+	mov	$s0,0($out)		# save output [can zap input]
+	mov	$s1,4($out)
+	mov	$s2,8($out)
+	mov	$s3,12($out)
+
+	jmp	.Lcbc_exit
+
+.align	4
+.Lcbc_slow_dec_partial:
+	mov	$_ivp,%rdi
+	mov	%r11,0(%rdi)		# copy iv back to user
+	mov	%r12,8(%rdi)
+
+	mov	$s0,0+$ivec		# save output to stack
+	mov	$s1,4+$ivec
+	mov	$s2,8+$ivec
+	mov	$s3,12+$ivec
+
+	mov	$out,%rdi
+	lea	$ivec,%rsi
+	lea	16(%r10),%rcx
+	.long	0x9066A4F3	# rep movsb
+	jmp	.Lcbc_exit
+
+.align	16
+.Lcbc_exit:
+	mov	$_rsp,%rsi
+	mov	(%rsi),%r15
+	mov	8(%rsi),%r14
+	mov	16(%rsi),%r13
+	mov	24(%rsi),%r12
+	mov	32(%rsi),%rbp
+	mov	40(%rsi),%rbx
+	lea	48(%rsi),%rsp
+.Lcbc_popfq:
+	popfq
+.Lcbc_epilogue:
+	ret
 .size	AES_cbc_encrypt,.-AES_cbc_encrypt
 ___
 }
 
 $code.=<<___;
-.globl	AES_Te
 .align	64
-AES_Te:
+.LAES_Te:
 ___
 	&_data_word(0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6);
 	&_data_word(0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591);
@@ -1463,16 +2169,149 @@
 	&_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0);
 	&_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e);
 	&_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c);
+
+#Te4	# four copies of Te4 to choose from to avoid L1 aliasing
+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
+
+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
+
+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
+
+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
 #rcon:
 $code.=<<___;
 	.long	0x00000001, 0x00000002, 0x00000004, 0x00000008
 	.long	0x00000010, 0x00000020, 0x00000040, 0x00000080
-	.long	0x0000001b, 0x00000036, 0, 0, 0, 0, 0, 0
+	.long	0x0000001b, 0x00000036, 0x80808080, 0x80808080
+	.long	0xfefefefe, 0xfefefefe, 0x1b1b1b1b, 0x1b1b1b1b
 ___
 $code.=<<___;
-.globl	AES_Td
 .align	64
-AES_Td:
+.LAES_Td:
 ___
 	&_data_word(0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a);
 	&_data_word(0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b);
@@ -1538,7 +2377,8 @@
 	&_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff);
 	&_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664);
 	&_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0);
-#Td4:
+
+#Td4:	# four copies of Td4 to choose from to avoid L1 aliasing
 	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
 	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
 	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
@@ -1571,6 +2411,396 @@
 	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
 	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
 	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
+$code.=<<___;
+	.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
+	.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
+___
+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
+$code.=<<___;
+	.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
+	.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
+___
+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
+$code.=<<___;
+	.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
+	.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
+___
+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
+$code.=<<___;
+	.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
+	.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
+.asciz  "AES for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
+.align	64
+___
+
+# 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	block_se_handler,\@abi-omnipotent
+.align	16
+block_se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%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_block_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_block_prologue
+
+	mov	24(%rax),%rax		# pull saved real stack pointer
+	lea	48(%rax),%rax		# adjust...
+
+	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_block_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	block_se_handler,.-block_se_handler
+
+.type	key_se_handler,\@abi-omnipotent
+.align	16
+key_se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%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_key_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_key_prologue
+
+	lea	56(%rax),%rax
+
+	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_key_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	key_se_handler,.-key_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
+	sub	\$64,%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_fast_body(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lcbc_fast_body
+	jb	.Lin_cbc_frame_setup
+
+	lea	.Lcbc_slow_prologue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lcbc_slow_prologue
+	jb	.Lin_cbc_body
+
+	lea	.Lcbc_slow_body(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lcbc_slow_body
+	jb	.Lin_cbc_frame_setup
+
+.Lin_cbc_body:
+	mov	152($context),%rax	# pull context->Rsp
+
+	lea	.Lcbc_epilogue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip>=.Lcbc_epilogue
+	jae	.Lin_cbc_prologue
+
+	lea	8(%rax),%rax
+
+	lea	.Lcbc_popfq(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip>=.Lcbc_popfq
+	jae	.Lin_cbc_prologue
+
+	mov	`16-8`(%rax),%rax	# biased $_rsp
+	lea	56(%rax),%rax
+
+.Lin_cbc_frame_setup:
+	mov	-16(%rax),%rbx
+	mov	-24(%rax),%rbp
+	mov	-32(%rax),%r12
+	mov	-40(%rax),%r13
+	mov	-48(%rax),%r14
+	mov	-56(%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
+
+.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
+	add	\$64,%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_AES_encrypt
+	.rva	.LSEH_end_AES_encrypt
+	.rva	.LSEH_info_AES_encrypt
+
+	.rva	.LSEH_begin_AES_decrypt
+	.rva	.LSEH_end_AES_decrypt
+	.rva	.LSEH_info_AES_decrypt
+
+	.rva	.LSEH_begin_AES_set_encrypt_key
+	.rva	.LSEH_end_AES_set_encrypt_key
+	.rva	.LSEH_info_AES_set_encrypt_key
+
+	.rva	.LSEH_begin_AES_set_decrypt_key
+	.rva	.LSEH_end_AES_set_decrypt_key
+	.rva	.LSEH_info_AES_set_decrypt_key
+
+	.rva	.LSEH_begin_AES_cbc_encrypt
+	.rva	.LSEH_end_AES_cbc_encrypt
+	.rva	.LSEH_info_AES_cbc_encrypt
+
+.section	.xdata
+.align	8
+.LSEH_info_AES_encrypt:
+	.byte	9,0,0,0
+	.rva	block_se_handler
+	.rva	.Lenc_prologue,.Lenc_epilogue	# HandlerData[]
+.LSEH_info_AES_decrypt:
+	.byte	9,0,0,0
+	.rva	block_se_handler
+	.rva	.Ldec_prologue,.Ldec_epilogue	# HandlerData[]
+.LSEH_info_AES_set_encrypt_key:
+	.byte	9,0,0,0
+	.rva	key_se_handler
+	.rva	.Lenc_key_prologue,.Lenc_key_epilogue	# HandlerData[]
+.LSEH_info_AES_set_decrypt_key:
+	.byte	9,0,0,0
+	.rva	key_se_handler
+	.rva	.Ldec_key_prologue,.Ldec_key_epilogue	# HandlerData[]
+.LSEH_info_AES_cbc_encrypt:
+	.byte	9,0,0,0
+	.rva	cbc_se_handler
+___
+}
 
 $code =~ s/\`([^\`]*)\`/eval($1)/gem;
 
diff --git a/crypto/asn1/Makefile b/crypto/asn1/Makefile
deleted file mode 100644
index 94a6885..0000000
--- a/crypto/asn1/Makefile
+++ /dev/null
@@ -1,904 +0,0 @@
-#
-# OpenSSL/crypto/asn1/Makefile
-#
-
-DIR=	asn1
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile README
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=	a_object.c a_bitstr.c a_utctm.c a_gentm.c a_time.c a_int.c a_octet.c \
-	a_print.c a_type.c a_set.c a_dup.c a_d2i_fp.c a_i2d_fp.c \
-	a_enum.c a_utf8.c a_sign.c a_digest.c a_verify.c a_mbstr.c a_strex.c \
-	x_algor.c x_val.c x_pubkey.c x_sig.c x_req.c x_attrib.c x_bignum.c \
-	x_long.c x_name.c x_x509.c x_x509a.c x_crl.c x_info.c x_spki.c nsseq.c \
-	d2i_pu.c d2i_pr.c i2d_pu.c i2d_pr.c\
-	t_req.c t_x509.c t_x509a.c t_crl.c t_pkey.c t_spki.c t_bitst.c \
-	tasn_new.c tasn_fre.c tasn_enc.c tasn_dec.c tasn_utl.c tasn_typ.c \
-	f_int.c f_string.c n_pkey.c \
-	f_enum.c a_hdr.c x_pkey.c a_bool.c x_exten.c asn_mime.c \
-	asn1_gen.c asn1_par.c asn1_lib.c asn1_err.c a_meth.c a_bytes.c a_strnid.c \
-	evp_asn1.c asn_pack.c p5_pbe.c p5_pbev2.c p8_pkey.c asn_moid.c
-LIBOBJ= a_object.o a_bitstr.o a_utctm.o a_gentm.o a_time.o a_int.o a_octet.o \
-	a_print.o a_type.o a_set.o a_dup.o a_d2i_fp.o a_i2d_fp.o \
-	a_enum.o a_utf8.o a_sign.o a_digest.o a_verify.o a_mbstr.o a_strex.o \
-	x_algor.o x_val.o x_pubkey.o x_sig.o x_req.o x_attrib.o x_bignum.o \
-	x_long.o x_name.o x_x509.o x_x509a.o x_crl.o x_info.o x_spki.o nsseq.o \
-	d2i_pu.o d2i_pr.o i2d_pu.o i2d_pr.o \
-	t_req.o t_x509.o t_x509a.o t_crl.o t_pkey.o t_spki.o t_bitst.o \
-	tasn_new.o tasn_fre.o tasn_enc.o tasn_dec.o tasn_utl.o tasn_typ.o \
-	f_int.o f_string.o n_pkey.o \
-	f_enum.o a_hdr.o x_pkey.o a_bool.o x_exten.o asn_mime.o \
-	asn1_gen.o asn1_par.o asn1_lib.o asn1_err.o a_meth.o a_bytes.o a_strnid.o \
-	evp_asn1.o asn_pack.o p5_pbe.o p5_pbev2.o p8_pkey.o asn_moid.o
-
-SRC= $(LIBSRC)
-
-EXHEADER=  asn1.h asn1_mac.h asn1t.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-test:	test.c
-	cc -g -I../../include -c test.c
-	cc -g -I../../include -o test test.o -L../.. -lcrypto
-
-pk:	pk.c
-	cc -g -I../../include -c pk.c
-	cc -g -I../../include -o pk pk.o -L../.. -lcrypto
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-depend:
-	@[ -n "$(MAKEDEPEND)" ] # should be set by top 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 *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-a_bitstr.o: ../../e_os.h ../../include/openssl/asn1.h
-a_bitstr.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-a_bitstr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-a_bitstr.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-a_bitstr.o: ../../include/openssl/opensslconf.h
-a_bitstr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-a_bitstr.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-a_bitstr.o: ../../include/openssl/symhacks.h ../cryptlib.h a_bitstr.c
-a_bool.o: ../../e_os.h ../../include/openssl/asn1.h
-a_bool.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-a_bool.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-a_bool.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-a_bool.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-a_bool.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-a_bool.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-a_bool.o: ../../include/openssl/symhacks.h ../cryptlib.h a_bool.c
-a_bytes.o: ../../e_os.h ../../include/openssl/asn1.h
-a_bytes.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-a_bytes.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-a_bytes.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-a_bytes.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-a_bytes.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-a_bytes.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-a_bytes.o: ../cryptlib.h a_bytes.c
-a_d2i_fp.o: ../../e_os.h ../../include/openssl/asn1.h
-a_d2i_fp.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
-a_d2i_fp.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-a_d2i_fp.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-a_d2i_fp.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-a_d2i_fp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-a_d2i_fp.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-a_d2i_fp.o: ../../include/openssl/symhacks.h ../cryptlib.h a_d2i_fp.c
-a_digest.o: ../../e_os.h ../../include/openssl/asn1.h
-a_digest.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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
-a_digest.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-a_digest.o: ../../include/openssl/x509_vfy.h ../cryptlib.h a_digest.c
-a_dup.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-a_dup.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-a_dup.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-a_dup.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-a_dup.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-a_dup.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-a_dup.o: ../../include/openssl/symhacks.h ../cryptlib.h a_dup.c
-a_enum.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-a_enum.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-a_enum.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-a_enum.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-a_enum.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-a_enum.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-a_enum.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-a_enum.o: ../cryptlib.h a_enum.c
-a_gentm.o: ../../e_os.h ../../include/openssl/asn1.h
-a_gentm.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-a_gentm.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-a_gentm.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-a_gentm.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-a_gentm.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-a_gentm.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-a_gentm.o: ../cryptlib.h ../o_time.h a_gentm.c
-a_hdr.o: ../../e_os.h ../../include/openssl/asn1.h
-a_hdr.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
-a_hdr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-a_hdr.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-a_hdr.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-a_hdr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-a_hdr.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-a_hdr.o: ../../include/openssl/symhacks.h ../cryptlib.h a_hdr.c
-a_i2d_fp.o: ../../e_os.h ../../include/openssl/asn1.h
-a_i2d_fp.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-a_i2d_fp.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-a_i2d_fp.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-a_i2d_fp.o: ../../include/openssl/opensslconf.h
-a_i2d_fp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-a_i2d_fp.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-a_i2d_fp.o: ../../include/openssl/symhacks.h ../cryptlib.h a_i2d_fp.c
-a_int.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-a_int.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-a_int.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-a_int.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-a_int.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-a_int.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-a_int.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-a_int.o: ../cryptlib.h a_int.c
-a_mbstr.o: ../../e_os.h ../../include/openssl/asn1.h
-a_mbstr.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-a_mbstr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-a_mbstr.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-a_mbstr.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-a_mbstr.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-a_mbstr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-a_mbstr.o: ../cryptlib.h a_mbstr.c
-a_meth.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-a_meth.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-a_meth.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-a_meth.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-a_meth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-a_meth.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-a_meth.o: ../../include/openssl/symhacks.h ../cryptlib.h a_meth.c
-a_object.o: ../../e_os.h ../../include/openssl/asn1.h
-a_object.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-a_object.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-a_object.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-a_object.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-a_object.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-a_object.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-a_object.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-a_object.o: ../../include/openssl/symhacks.h ../cryptlib.h a_object.c
-a_octet.o: ../../e_os.h ../../include/openssl/asn1.h
-a_octet.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-a_octet.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-a_octet.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-a_octet.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-a_octet.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-a_octet.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-a_octet.o: ../cryptlib.h a_octet.c
-a_print.o: ../../e_os.h ../../include/openssl/asn1.h
-a_print.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-a_print.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-a_print.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-a_print.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-a_print.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-a_print.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-a_print.o: ../cryptlib.h a_print.c
-a_set.o: ../../e_os.h ../../include/openssl/asn1.h
-a_set.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
-a_set.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-a_set.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-a_set.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-a_set.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-a_set.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-a_set.o: ../../include/openssl/symhacks.h ../cryptlib.h a_set.c
-a_sign.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-a_sign.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-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/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/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
-a_strnid.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-a_strnid.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-a_strnid.o: ../../include/openssl/opensslconf.h
-a_strnid.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-a_strnid.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-a_strnid.o: ../../include/openssl/symhacks.h ../cryptlib.h a_strnid.c
-a_time.o: ../../e_os.h ../../include/openssl/asn1.h
-a_time.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-a_time.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-a_time.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-a_time.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-a_time.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-a_time.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-a_time.o: ../../include/openssl/symhacks.h ../cryptlib.h ../o_time.h a_time.c
-a_type.o: ../../e_os.h ../../include/openssl/asn1.h
-a_type.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-a_type.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-a_type.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-a_type.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-a_type.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-a_type.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-a_type.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-a_type.o: ../../include/openssl/symhacks.h ../cryptlib.h a_type.c
-a_utctm.o: ../../e_os.h ../../include/openssl/asn1.h
-a_utctm.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-a_utctm.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-a_utctm.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-a_utctm.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-a_utctm.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-a_utctm.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-a_utctm.o: ../cryptlib.h ../o_time.h a_utctm.c
-a_utf8.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-a_utf8.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-a_utf8.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-a_utf8.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-a_utf8.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-a_utf8.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-a_utf8.o: ../../include/openssl/symhacks.h ../cryptlib.h a_utf8.c
-a_verify.o: ../../e_os.h ../../include/openssl/asn1.h
-a_verify.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-a_verify.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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
-a_verify.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-a_verify.o: ../../include/openssl/x509_vfy.h ../cryptlib.h a_verify.c
-asn1_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-asn1_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-asn1_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-asn1_err.o: ../../include/openssl/opensslconf.h
-asn1_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-asn1_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-asn1_err.o: ../../include/openssl/symhacks.h asn1_err.c
-asn1_gen.o: ../../e_os.h ../../include/openssl/asn1.h
-asn1_gen.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-asn1_gen.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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
-asn1_gen.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-asn1_gen.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-asn1_gen.o: ../cryptlib.h asn1_gen.c
-asn1_lib.o: ../../e_os.h ../../include/openssl/asn1.h
-asn1_lib.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
-asn1_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-asn1_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-asn1_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-asn1_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-asn1_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-asn1_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h asn1_lib.c
-asn1_par.o: ../../e_os.h ../../include/openssl/asn1.h
-asn1_par.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-asn1_par.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-asn1_par.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-asn1_par.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-asn1_par.o: ../../include/openssl/opensslconf.h
-asn1_par.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-asn1_par.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-asn1_par.o: ../../include/openssl/symhacks.h ../cryptlib.h asn1_par.c
-asn_mime.o: ../../e_os.h ../../include/openssl/asn1.h
-asn_mime.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-asn_mime.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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
-asn_mime.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-asn_mime.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-asn_mime.o: ../cryptlib.h asn_mime.c
-asn_moid.o: ../../e_os.h ../../include/openssl/asn1.h
-asn_moid.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-asn_moid.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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
-asn_moid.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-asn_moid.o: ../../include/openssl/x509_vfy.h ../cryptlib.h asn_moid.c
-asn_pack.o: ../../e_os.h ../../include/openssl/asn1.h
-asn_pack.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-asn_pack.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-asn_pack.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-asn_pack.o: ../../include/openssl/opensslconf.h
-asn_pack.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-asn_pack.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-asn_pack.o: ../../include/openssl/symhacks.h ../cryptlib.h asn_pack.c
-d2i_pr.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-d2i_pr.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-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/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/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
-evp_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-evp_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-evp_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-evp_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-evp_asn1.o: ../../include/openssl/symhacks.h ../cryptlib.h evp_asn1.c
-f_enum.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-f_enum.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-f_enum.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-f_enum.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-f_enum.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-f_enum.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-f_enum.o: ../../include/openssl/symhacks.h ../cryptlib.h f_enum.c
-f_int.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-f_int.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-f_int.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-f_int.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-f_int.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-f_int.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-f_int.o: ../../include/openssl/symhacks.h ../cryptlib.h f_int.c
-f_string.o: ../../e_os.h ../../include/openssl/asn1.h
-f_string.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-f_string.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-f_string.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-f_string.o: ../../include/openssl/opensslconf.h
-f_string.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-f_string.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-f_string.o: ../../include/openssl/symhacks.h ../cryptlib.h f_string.c
-i2d_pr.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-i2d_pr.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-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/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/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/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/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/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/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
-p5_pbev2.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-p5_pbev2.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-p5_pbev2.o: ../cryptlib.h p5_pbev2.c
-p8_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
-p8_pkey.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-p8_pkey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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/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/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
-t_pkey.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
-t_pkey.o: ../../include/openssl/ec.h ../../include/openssl/err.h
-t_pkey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-t_pkey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-t_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-t_pkey.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-t_pkey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-t_pkey.o: ../cryptlib.h t_pkey.c
-t_req.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-t_req.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-t_req.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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/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/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/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
-tasn_dec.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-tasn_dec.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-tasn_dec.o: ../../include/openssl/opensslconf.h
-tasn_dec.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-tasn_dec.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-tasn_dec.o: ../../include/openssl/symhacks.h tasn_dec.c
-tasn_enc.o: ../../e_os.h ../../include/openssl/asn1.h
-tasn_enc.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-tasn_enc.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tasn_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-tasn_enc.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-tasn_enc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-tasn_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-tasn_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-tasn_enc.o: ../../include/openssl/symhacks.h ../cryptlib.h tasn_enc.c
-tasn_fre.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
-tasn_fre.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
-tasn_fre.o: ../../include/openssl/e_os2.h ../../include/openssl/obj_mac.h
-tasn_fre.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-tasn_fre.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-tasn_fre.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-tasn_fre.o: ../../include/openssl/symhacks.h tasn_fre.c
-tasn_new.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
-tasn_new.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
-tasn_new.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-tasn_new.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-tasn_new.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-tasn_new.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-tasn_new.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-tasn_new.o: ../../include/openssl/symhacks.h tasn_new.c
-tasn_typ.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
-tasn_typ.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
-tasn_typ.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-tasn_typ.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-tasn_typ.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-tasn_typ.o: ../../include/openssl/symhacks.h tasn_typ.c
-tasn_utl.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
-tasn_utl.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
-tasn_utl.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-tasn_utl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-tasn_utl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-tasn_utl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-tasn_utl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-tasn_utl.o: ../../include/openssl/symhacks.h tasn_utl.c
-x_algor.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
-x_algor.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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/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
-x_attrib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x_attrib.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_attrib.c
-x_bignum.o: ../../e_os.h ../../include/openssl/asn1.h
-x_bignum.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-x_bignum.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-x_bignum.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-x_bignum.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-x_bignum.o: ../../include/openssl/opensslconf.h
-x_bignum.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-x_bignum.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-x_bignum.o: ../../include/openssl/symhacks.h ../cryptlib.h x_bignum.c
-x_crl.o: ../../e_os.h ../../include/openssl/asn1.h
-x_crl.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-x_crl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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/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/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
-x_long.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-x_long.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-x_long.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-x_long.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-x_long.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-x_long.o: ../cryptlib.h x_long.c
-x_name.o: ../../e_os.h ../../include/openssl/asn1.h
-x_name.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-x_name.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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/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/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
-x_pubkey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-x_pubkey.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-x_pubkey.o: ../cryptlib.h x_pubkey.c
-x_req.o: ../../e_os.h ../../include/openssl/asn1.h
-x_req.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-x_req.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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/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/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/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/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/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_bitstr.c b/crypto/asn1/a_bitstr.c
index 0fb9ce0..3417996 100644
--- a/crypto/asn1/a_bitstr.c
+++ b/crypto/asn1/a_bitstr.c
@@ -223,3 +223,26 @@
 	return((a->data[w]&v) != 0);
 	}
 
+/*
+ * Checks if the given bit string contains only bits specified by 
+ * the flags vector. Returns 0 if there is at least one bit set in 'a'
+ * which is not specified in 'flags', 1 otherwise.
+ * 'len' is the length of 'flags'.
+ */
+int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
+			  unsigned char *flags, int flags_len)
+	{
+	int i, ok;
+	/* Check if there is one bit set at all. */
+	if (!a || !a->data) return 1;
+
+	/* Check each byte of the internal representation of the bit string. */
+	ok = 1;
+	for (i = 0; i < a->length && ok; ++i)
+		{
+		unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
+		/* We are done if there is an unneeded bit set. */
+		ok = (a->data[i] & mask) == 0;
+		}
+	return ok;
+	}
diff --git a/crypto/asn1/a_dup.c b/crypto/asn1/a_dup.c
index 199d50f..d989925 100644
--- a/crypto/asn1/a_dup.c
+++ b/crypto/asn1/a_dup.c
@@ -62,7 +62,7 @@
 
 #ifndef NO_OLD_ASN1
 
-void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x)
+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
 	{
 	unsigned char *b,*p;
 	const unsigned char *p2;
diff --git a/crypto/asn1/a_gentm.c b/crypto/asn1/a_gentm.c
index def7906..c79c6f5 100644
--- a/crypto/asn1/a_gentm.c
+++ b/crypto/asn1/a_gentm.c
@@ -117,8 +117,8 @@
 
 int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
 	{
-	static int min[9]={ 0, 0, 1, 1, 0, 0, 0, 0, 0};
-	static int max[9]={99, 99,12,31,23,59,59,12,59};
+	static const int min[9]={ 0, 0, 1, 1, 0, 0, 0, 0, 0};
+	static const int max[9]={99, 99,12,31,23,59,59,12,59};
 	char *a;
 	int n,i,l,o;
 
@@ -176,6 +176,11 @@
 			o++;
 			}
 		}
+	else
+		{
+		/* Missing time zone information. */
+		goto err;
+		}
 	return(o == l);
 err:
 	return(0);
@@ -206,6 +211,12 @@
 ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
 	     time_t t)
 	{
+		return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
+	}
+
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
+	     time_t t, int offset_day, long offset_sec)
+	{
 	char *p;
 	struct tm *ts;
 	struct tm data;
@@ -220,13 +231,19 @@
 	if (ts == NULL)
 		return(NULL);
 
+	if (offset_day || offset_sec)
+		{ 
+		if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+			return NULL;
+		}
+
 	p=(char *)s->data;
 	if ((p == NULL) || ((size_t)s->length < len))
 		{
 		p=OPENSSL_malloc(len);
 		if (p == NULL)
 			{
-			ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_SET,
+			ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ,
 				ERR_R_MALLOC_FAILURE);
 			return(NULL);
 			}
diff --git a/crypto/asn1/a_hdr.c b/crypto/asn1/a_hdr.c
deleted file mode 100644
index d1c2a7b..0000000
--- a/crypto/asn1/a_hdr.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/* crypto/asn1/a_hdr.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#include <stdio.h>
-#include "cryptlib.h"
-#include <openssl/asn1_mac.h>
-#include <openssl/asn1.h>
-
-int i2d_ASN1_HEADER(ASN1_HEADER *a, unsigned char **pp)
-	{
-	M_ASN1_I2D_vars(a);
-
-	M_ASN1_I2D_len(a->header,	i2d_ASN1_OCTET_STRING);
-	M_ASN1_I2D_len(a->data,		a->meth->i2d);
-
-	M_ASN1_I2D_seq_total();
-
-	M_ASN1_I2D_put(a->header,	i2d_ASN1_OCTET_STRING);
-	M_ASN1_I2D_put(a->data,		a->meth->i2d);
-
-	M_ASN1_I2D_finish();
-	}
-
-ASN1_HEADER *d2i_ASN1_HEADER(ASN1_HEADER **a, const unsigned char **pp,
-	     long length)
-	{
-	M_ASN1_D2I_vars(a,ASN1_HEADER *,ASN1_HEADER_new);
-
-	M_ASN1_D2I_Init();
-        M_ASN1_D2I_start_sequence();
-        M_ASN1_D2I_get_x(ASN1_OCTET_STRING,ret->header,d2i_ASN1_OCTET_STRING);
-	if (ret->meth != NULL)
-		{
-		M_ASN1_D2I_get_x(void,ret->data,ret->meth->d2i);
-		}
-	else
-		{
-		if (a != NULL) (*a)=ret;
-		return(ret);
-		}
-        M_ASN1_D2I_Finish(a,ASN1_HEADER_free,ASN1_F_D2I_ASN1_HEADER);
-	}
-
-ASN1_HEADER *ASN1_HEADER_new(void)
-	{
-	ASN1_HEADER *ret=NULL;
-	ASN1_CTX c;
-
-	M_ASN1_New_Malloc(ret,ASN1_HEADER);
-	M_ASN1_New(ret->header,M_ASN1_OCTET_STRING_new);
-	ret->meth=NULL;
-	ret->data=NULL;
-	return(ret);
-        M_ASN1_New_Error(ASN1_F_ASN1_HEADER_NEW);
-	}
-
-void ASN1_HEADER_free(ASN1_HEADER *a)
-	{
-	if (a == NULL) return;
-	M_ASN1_OCTET_STRING_free(a->header);
-	if (a->meth != NULL)
-		a->meth->destroy(a->data);
-	OPENSSL_free(a);
-	}
diff --git a/crypto/asn1/a_int.c b/crypto/asn1/a_int.c
index f8d198e..c6fd204 100644
--- a/crypto/asn1/a_int.c
+++ b/crypto/asn1/a_int.c
@@ -61,10 +61,10 @@
 #include <openssl/asn1.h>
 #include <openssl/bn.h>
 
-ASN1_INTEGER *ASN1_INTEGER_dup(ASN1_INTEGER *x)
+ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
 { return M_ASN1_INTEGER_dup(x);}
 
-int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y)
+int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
 	{ 
 	int neg, ret;
 	/* Compare signs */
@@ -373,7 +373,7 @@
 	return(1);
 	}
 
-long ASN1_INTEGER_get(ASN1_INTEGER *a)
+long ASN1_INTEGER_get(const ASN1_INTEGER *a)
 	{
 	int neg=0,i;
 	long r=0;
@@ -402,7 +402,7 @@
 	return(r);
 	}
 
-ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai)
+ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
 	{
 	ASN1_INTEGER *ret;
 	int len,j;
@@ -444,7 +444,7 @@
 	return(NULL);
 	}
 
-BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai, BIGNUM *bn)
+BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
 	{
 	BIGNUM *ret;
 
diff --git a/crypto/asn1/a_meth.c b/crypto/asn1/a_meth.c
deleted file mode 100644
index 50bea91..0000000
--- a/crypto/asn1/a_meth.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/* crypto/asn1/a_meth.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#include <stdio.h>
-#include "cryptlib.h"
-#include <openssl/buffer.h>
-#include <openssl/asn1.h>
-
-static  ASN1_METHOD ia5string_meth={
-	(I2D_OF(void))	i2d_ASN1_IA5STRING,
-	(D2I_OF(void))	d2i_ASN1_IA5STRING,
-	(void *(*)(void))ASN1_STRING_new,
-	(void (*)(void *))ASN1_STRING_free};
-
-static  ASN1_METHOD bit_string_meth={
-	(I2D_OF(void))	i2d_ASN1_BIT_STRING,
-	(D2I_OF(void))	d2i_ASN1_BIT_STRING,
-	(void *(*)(void))ASN1_STRING_new,
-	(void (*)(void *))ASN1_STRING_free};
-
-ASN1_METHOD *ASN1_IA5STRING_asn1_meth(void)
-	{
-	return(&ia5string_meth);
-	}
-
-ASN1_METHOD *ASN1_BIT_STRING_asn1_meth(void)
-	{
-	return(&bit_string_meth);
-	}
diff --git a/crypto/asn1/a_object.c b/crypto/asn1/a_object.c
index d169f8c..e5fbe7c 100644
--- a/crypto/asn1/a_object.c
+++ b/crypto/asn1/a_object.c
@@ -281,8 +281,6 @@
 	return ret;
 err:
 	ASN1err(ASN1_F_D2I_ASN1_OBJECT,i);
-	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
-		ASN1_OBJECT_free(ret);
 	return(NULL);
 }
 ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
@@ -290,13 +288,14 @@
 	{
 	ASN1_OBJECT *ret=NULL;
 	const unsigned char *p;
+	unsigned char *data;
 	int i;
-	/* Sanity check OID encoding: can't have 0x80 in subidentifiers, see:
-	 * X.690 8.19.2
+	/* Sanity check OID encoding: can't have leading 0x80 in
+	 * subidentifiers, see: X.690 8.19.2
 	 */
 	for (i = 0, p = *pp + 1; i < len - 1; i++, p++)
 		{
-		if (*p == 0x80)
+		if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
 			{
 			ASN1err(ASN1_F_C2I_ASN1_OBJECT,ASN1_R_INVALID_OBJECT_ENCODING);
 			return NULL;
@@ -313,15 +312,22 @@
 	else	ret=(*a);
 
 	p= *pp;
-	if ((ret->data == NULL) || (ret->length < len))
+	/* detach data from object */
+	data = (unsigned char *)ret->data;
+	ret->data = NULL;
+	/* once detached we can change it */
+	if ((data == NULL) || (ret->length < len))
 		{
-		if (ret->data != NULL) OPENSSL_free(ret->data);
-		ret->data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1);
-		ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
-		if (ret->data == NULL)
+		ret->length=0;
+		if (data != NULL) OPENSSL_free(data);
+		data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1);
+		if (data == NULL)
 			{ i=ERR_R_MALLOC_FAILURE; goto err; }
+		ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
 		}
-	memcpy(ret->data,p,(int)len);
+	memcpy(data,p,(int)len);
+	/* reattach data to object, after which it remains const */
+	ret->data  =data;
 	ret->length=(int)len;
 	ret->sn=NULL;
 	ret->ln=NULL;
@@ -370,7 +376,7 @@
 		}
 	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA)
 		{
-		if (a->data != NULL) OPENSSL_free(a->data);
+		if (a->data != NULL) OPENSSL_free((void *)a->data);
 		a->data=NULL;
 		a->length=0;
 		}
diff --git a/crypto/asn1/a_octet.c b/crypto/asn1/a_octet.c
index 24fd0f8..e8725e4 100644
--- a/crypto/asn1/a_octet.c
+++ b/crypto/asn1/a_octet.c
@@ -60,10 +60,10 @@
 #include "cryptlib.h"
 #include <openssl/asn1.h>
 
-ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(ASN1_OCTET_STRING *x)
+ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
 { return M_ASN1_OCTET_STRING_dup(x); }
 
-int ASN1_OCTET_STRING_cmp(ASN1_OCTET_STRING *a, ASN1_OCTET_STRING *b)
+int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b)
 { return M_ASN1_OCTET_STRING_cmp(a, b); }
 
 int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len)
diff --git a/crypto/asn1/a_set.c b/crypto/asn1/a_set.c
index 958558c..d726c8d 100644
--- a/crypto/asn1/a_set.c
+++ b/crypto/asn1/a_set.c
@@ -85,8 +85,9 @@
     }
 
 /* int is_set:  if TRUE, then sort the contents (i.e. it isn't a SEQUENCE)    */
-int i2d_ASN1_SET(STACK *a, unsigned char **pp, i2d_of_void *i2d, int ex_tag,
-		 int ex_class, int is_set)
+int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
+		 i2d_of_void *i2d, int ex_tag, int ex_class,
+		 int is_set)
 	{
 	int ret=0,r;
 	int i;
@@ -96,8 +97,8 @@
         int totSize;
 
 	if (a == NULL) return(0);
-	for (i=sk_num(a)-1; i>=0; i--)
-		ret+=i2d(sk_value(a,i),NULL);
+	for (i=sk_OPENSSL_BLOCK_num(a)-1; i>=0; i--)
+		ret+=i2d(sk_OPENSSL_BLOCK_value(a,i),NULL);
 	r=ASN1_object_size(1,ret,ex_tag);
 	if (pp == NULL) return(r);
 
@@ -108,10 +109,10 @@
 	/* And then again by Ben */
 	/* And again by Steve */
 
-	if(!is_set || (sk_num(a) < 2))
+	if(!is_set || (sk_OPENSSL_BLOCK_num(a) < 2))
 		{
-		for (i=0; i<sk_num(a); i++)
-                	i2d(sk_value(a,i),&p);
+		for (i=0; i<sk_OPENSSL_BLOCK_num(a); i++)
+                	i2d(sk_OPENSSL_BLOCK_value(a,i),&p);
 
 		*pp=p;
 		return(r);
@@ -119,17 +120,17 @@
 
         pStart  = p; /* Catch the beg of Setblobs*/
 		/* In this array we will store the SET blobs */
-		rgSetBlob = (MYBLOB *)OPENSSL_malloc(sk_num(a) * sizeof(MYBLOB));
+		rgSetBlob = OPENSSL_malloc(sk_OPENSSL_BLOCK_num(a) * sizeof(MYBLOB));
 		if (rgSetBlob == NULL)
 			{
 			ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE);
 			return(0);
 			}
 
-        for (i=0; i<sk_num(a); i++)
+        for (i=0; i<sk_OPENSSL_BLOCK_num(a); i++)
 	        {
                 rgSetBlob[i].pbData = p;  /* catch each set encode blob */
-                i2d(sk_value(a,i),&p);
+                i2d(sk_OPENSSL_BLOCK_value(a,i),&p);
                 rgSetBlob[i].cbData = p - rgSetBlob[i].pbData; /* Length of this
 SetBlob
 */
@@ -139,7 +140,7 @@
 
  /* Now we have to sort the blobs. I am using a simple algo.
     *Sort ptrs *Copy to temp-mem *Copy from temp-mem to user-mem*/
-        qsort( rgSetBlob, sk_num(a), sizeof(MYBLOB), SetBlobCmp);
+        qsort( rgSetBlob, sk_OPENSSL_BLOCK_num(a), sizeof(MYBLOB), SetBlobCmp);
 		if (!(pTempMem = OPENSSL_malloc(totSize)))
 			{
 			ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE);
@@ -148,7 +149,7 @@
 
 /* Copy to temp mem */
         p = pTempMem;
-        for(i=0; i<sk_num(a); ++i)
+        for(i=0; i<sk_OPENSSL_BLOCK_num(a); ++i)
 		{
                 memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData);
                 p += rgSetBlob[i].cbData;
@@ -162,16 +163,18 @@
         return(r);
         }
 
-STACK *d2i_ASN1_SET(STACK **a, const unsigned char **pp, long length,
-		    d2i_of_void *d2i, void (*free_func)(void *), int ex_tag,
-		    int ex_class)
+STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
+			      const unsigned char **pp,
+			      long length, d2i_of_void *d2i,
+			      void (*free_func)(OPENSSL_BLOCK), int ex_tag,
+			      int ex_class)
 	{
 	ASN1_const_CTX c;
-	STACK *ret=NULL;
+	STACK_OF(OPENSSL_BLOCK) *ret=NULL;
 
 	if ((a == NULL) || ((*a) == NULL))
 		{
-		if ((ret=sk_new_null()) == NULL)
+		if ((ret=sk_OPENSSL_BLOCK_new_null()) == NULL)
 			{
 			ASN1err(ASN1_F_D2I_ASN1_SET,ERR_R_MALLOC_FAILURE);
 			goto err;
@@ -216,10 +219,10 @@
 		if ((s=d2i(NULL,&c.p,c.slen)) == NULL)
 			{
 			ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_ERROR_PARSING_SET_ELEMENT);
-			asn1_add_error(*pp,(int)(c.q- *pp));
+			asn1_add_error(*pp,(int)(c.p- *pp));
 			goto err;
 			}
-		if (!sk_push(ret,s)) goto err;
+		if (!sk_OPENSSL_BLOCK_push(ret,s)) goto err;
 		}
 	if (a != NULL) (*a)=ret;
 	*pp=c.p;
@@ -228,9 +231,9 @@
 	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
 		{
 		if (free_func != NULL)
-			sk_pop_free(ret,free_func);
+			sk_OPENSSL_BLOCK_pop_free(ret,free_func);
 		else
-			sk_free(ret);
+			sk_OPENSSL_BLOCK_free(ret);
 		}
 	return(NULL);
 	}
diff --git a/crypto/asn1/a_sign.c b/crypto/asn1/a_sign.c
index 4dee45f..ff63bfc 100644
--- a/crypto/asn1/a_sign.c
+++ b/crypto/asn1/a_sign.c
@@ -123,6 +123,7 @@
 #include <openssl/x509.h>
 #include <openssl/objects.h>
 #include <openssl/buffer.h>
+#include "asn1_locl.h"
 
 #ifndef NO_ASN1_OLD
 
@@ -218,45 +219,47 @@
 	{
 	EVP_MD_CTX ctx;
 	unsigned char *buf_in=NULL,*buf_out=NULL;
-	int i,inl=0,outl=0,outll=0;
-	X509_ALGOR *a;
+	int inl=0,outl=0,outll=0;
+	int signid, paramtype;
 
-	EVP_MD_CTX_init(&ctx);
-	for (i=0; i<2; i++)
+	if (type == NULL)
 		{
-		if (i == 0)
-			a=algor1;
-		else
-			a=algor2;
-		if (a == NULL) continue;
-                if (type->pkey_type == NID_dsaWithSHA1 ||
-			type->pkey_type == NID_ecdsa_with_SHA1)
+		int def_nid;
+		if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
+			type = EVP_get_digestbynid(def_nid);
+		}
+
+	if (type == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_ITEM_SIGN, ASN1_R_NO_DEFAULT_DIGEST);
+		return 0;
+		}
+
+	if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
+		{
+		if (!pkey->ameth ||
+			!OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type),
+						pkey->ameth->pkey_id))
 			{
-			/* special case: RFC 3279 tells us to omit 'parameters'
-			 * with id-dsa-with-sha1 and ecdsa-with-SHA1 */
-			ASN1_TYPE_free(a->parameter);
-			a->parameter = NULL;
-			}
-		else if ((a->parameter == NULL) || 
-			(a->parameter->type != V_ASN1_NULL))
-			{
-			ASN1_TYPE_free(a->parameter);
-			if ((a->parameter=ASN1_TYPE_new()) == NULL) goto err;
-			a->parameter->type=V_ASN1_NULL;
-			}
-		ASN1_OBJECT_free(a->algorithm);
-		a->algorithm=OBJ_nid2obj(type->pkey_type);
-		if (a->algorithm == NULL)
-			{
-			ASN1err(ASN1_F_ASN1_ITEM_SIGN,ASN1_R_UNKNOWN_OBJECT_TYPE);
-			goto err;
-			}
-		if (a->algorithm->length == 0)
-			{
-			ASN1err(ASN1_F_ASN1_ITEM_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
-			goto err;
+			ASN1err(ASN1_F_ASN1_ITEM_SIGN,
+				ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+			return 0;
 			}
 		}
+	else
+		signid = type->pkey_type;
+
+	if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
+		paramtype = V_ASN1_NULL;
+	else
+		paramtype = V_ASN1_UNDEF;
+
+	if (algor1)
+		X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
+	if (algor2)
+		X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
+
+	EVP_MD_CTX_init(&ctx);
 	inl=ASN1_item_i2d(asn,&buf_in, it);
 	outll=outl=EVP_PKEY_size(pkey);
 	buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl);
@@ -267,12 +270,7 @@
 		goto err;
 		}
 
-	if (!EVP_SignInit_ex(&ctx,type, NULL))
-		{
-		outl=0;
-		ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_EVP_LIB);
-		goto err;
-		}
+	EVP_SignInit_ex(&ctx,type, NULL);
 	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_strnid.c b/crypto/asn1/a_strnid.c
index fe515b5..753021a 100644
--- a/crypto/asn1/a_strnid.c
+++ b/crypto/asn1/a_strnid.c
@@ -67,7 +67,6 @@
 static void st_free(ASN1_STRING_TABLE *tbl);
 static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
 			const ASN1_STRING_TABLE * const *b);
-static int table_cmp(const void *a, const void *b);
 
 
 /* This is the global mask for the mbstring functions: this is use to
@@ -158,7 +157,7 @@
 
 /* This table must be kept in NID order */
 
-static ASN1_STRING_TABLE tbl_standard[] = {
+static const ASN1_STRING_TABLE tbl_standard[] = {
 {NID_commonName,		1, ub_common_name, DIRSTRING_TYPE, 0},
 {NID_countryName,		2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
 {NID_localityName,		1, ub_locality_name, DIRSTRING_TYPE, 0},
@@ -186,22 +185,23 @@
 	return (*a)->nid - (*b)->nid;
 }
 
-static int table_cmp(const void *a, const void *b)
+DECLARE_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
+
+static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b)
 {
-	const ASN1_STRING_TABLE *sa = a, *sb = b;
-	return sa->nid - sb->nid;
+	return a->nid - b->nid;
 }
 
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
+
 ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
 {
 	int idx;
 	ASN1_STRING_TABLE *ttmp;
 	ASN1_STRING_TABLE fnd;
 	fnd.nid = nid;
-	ttmp = (ASN1_STRING_TABLE *) OBJ_bsearch((char *)&fnd,
-					(char *)tbl_standard, 
-			sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE),
-			sizeof(ASN1_STRING_TABLE), table_cmp);
+	ttmp = OBJ_bsearch_table(&fnd, tbl_standard, 
+			   sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE));
 	if(ttmp) return ttmp;
 	if(!stable) return NULL;
 	idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
diff --git a/crypto/asn1/a_time.c b/crypto/asn1/a_time.c
index 159681f..e2eb9b2 100644
--- a/crypto/asn1/a_time.c
+++ b/crypto/asn1/a_time.c
@@ -100,18 +100,29 @@
 
 ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t)
 	{
+	return ASN1_TIME_adj(s, t, 0, 0);
+	}
+
+ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
+				int offset_day, long offset_sec)
+	{
 	struct tm *ts;
 	struct tm data;
 
 	ts=OPENSSL_gmtime(&t,&data);
 	if (ts == NULL)
 		{
-		ASN1err(ASN1_F_ASN1_TIME_SET, ASN1_R_ERROR_GETTING_TIME);
+		ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME);
 		return NULL;
 		}
+	if (offset_day || offset_sec)
+		{ 
+		if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+			return NULL;
+		}
 	if((ts->tm_year >= 50) && (ts->tm_year < 150))
-					return ASN1_UTCTIME_set(s, t);
-	return ASN1_GENERALIZEDTIME_set(s,t);
+			return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
+	return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
 	}
 
 int ASN1_TIME_check(ASN1_TIME *t)
@@ -162,3 +173,26 @@
 
 	return ret;
 	}
+
+int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
+	{
+	ASN1_TIME t;
+
+	t.length = strlen(str);
+	t.data = (unsigned char *)str;
+	t.flags = 0;
+	
+	t.type = V_ASN1_UTCTIME;
+
+	if (!ASN1_TIME_check(&t))
+		{
+		t.type = V_ASN1_GENERALIZEDTIME;
+		if (!ASN1_TIME_check(&t))
+			return 0;
+		}
+	
+	if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
+			return 0;
+
+	return 1;
+	}
diff --git a/crypto/asn1/a_type.c b/crypto/asn1/a_type.c
index 36becea..a45d2f9 100644
--- a/crypto/asn1/a_type.c
+++ b/crypto/asn1/a_type.c
@@ -77,7 +77,10 @@
 		ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
 		}
 	a->type=type;
-	a->value.ptr=value;
+	if (type == V_ASN1_BOOLEAN)
+		a->value.boolean = value ? 0xff : 0;
+	else
+		a->value.ptr=value;
 	}
 
 int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
@@ -98,7 +101,7 @@
 	else
 		{
 		ASN1_STRING *sdup;
-		sdup = ASN1_STRING_dup((ASN1_STRING *)value);
+		sdup = ASN1_STRING_dup(value);
 		if (!sdup)
 			return 0;
 		ASN1_TYPE_set(a, type, sdup);
@@ -108,3 +111,49 @@
 
 IMPLEMENT_STACK_OF(ASN1_TYPE)
 IMPLEMENT_ASN1_SET_OF(ASN1_TYPE)
+
+/* Returns 0 if they are equal, != 0 otherwise. */
+int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
+	{
+	int result = -1;
+
+	if (!a || !b || a->type != b->type) return -1;
+
+	switch (a->type)
+		{
+	case V_ASN1_OBJECT:
+		result = OBJ_cmp(a->value.object, b->value.object);
+		break;
+	case V_ASN1_NULL:
+		result = 0;	/* They do not have content. */
+		break;
+	case V_ASN1_INTEGER:
+	case V_ASN1_NEG_INTEGER:
+	case V_ASN1_ENUMERATED:
+	case V_ASN1_NEG_ENUMERATED:
+	case V_ASN1_BIT_STRING:
+	case V_ASN1_OCTET_STRING:
+	case V_ASN1_SEQUENCE:
+	case V_ASN1_SET:
+	case V_ASN1_NUMERICSTRING:
+	case V_ASN1_PRINTABLESTRING:
+	case V_ASN1_T61STRING:
+	case V_ASN1_VIDEOTEXSTRING:
+	case V_ASN1_IA5STRING:
+	case V_ASN1_UTCTIME:
+	case V_ASN1_GENERALIZEDTIME:
+	case V_ASN1_GRAPHICSTRING:
+	case V_ASN1_VISIBLESTRING:
+	case V_ASN1_GENERALSTRING:
+	case V_ASN1_UNIVERSALSTRING:
+	case V_ASN1_BMPSTRING:
+	case V_ASN1_UTF8STRING:
+	case V_ASN1_OTHER:
+	default:
+		result = ASN1_STRING_cmp((ASN1_STRING *) a->value.ptr,
+					 (ASN1_STRING *) b->value.ptr);
+		break;
+		}
+
+	return result;
+	}
diff --git a/crypto/asn1/a_utctm.c b/crypto/asn1/a_utctm.c
index d31c028..072e236 100644
--- a/crypto/asn1/a_utctm.c
+++ b/crypto/asn1/a_utctm.c
@@ -114,8 +114,8 @@
 
 int ASN1_UTCTIME_check(ASN1_UTCTIME *d)
 	{
-	static int min[8]={ 0, 1, 1, 0, 0, 0, 0, 0};
-	static int max[8]={99,12,31,23,59,59,12,59};
+	static const int min[8]={ 0, 1, 1, 0, 0, 0, 0, 0};
+	static const int max[8]={99,12,31,23,59,59,12,59};
 	char *a;
 	int n,i,l,o;
 
@@ -186,6 +186,12 @@
 
 ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
 	{
+	return ASN1_UTCTIME_adj(s, t, 0, 0);
+	}
+
+ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
+				int offset_day, long offset_sec)
+	{
 	char *p;
 	struct tm *ts;
 	struct tm data;
@@ -200,13 +206,22 @@
 	if (ts == NULL)
 		return(NULL);
 
+	if (offset_day || offset_sec)
+		{ 
+		if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+			return NULL;
+		}
+
+	if((ts->tm_year < 50) || (ts->tm_year >= 150))
+		return NULL;
+
 	p=(char *)s->data;
 	if ((p == NULL) || ((size_t)s->length < len))
 		{
 		p=OPENSSL_malloc(len);
 		if (p == NULL)
 			{
-			ASN1err(ASN1_F_ASN1_UTCTIME_SET,ERR_R_MALLOC_FAILURE);
+			ASN1err(ASN1_F_ASN1_UTCTIME_ADJ,ERR_R_MALLOC_FAILURE);
 			return(NULL);
 			}
 		if (s->data != NULL)
diff --git a/crypto/asn1/a_verify.c b/crypto/asn1/a_verify.c
index da3efaa..cecdb13 100644
--- a/crypto/asn1/a_verify.c
+++ b/crypto/asn1/a_verify.c
@@ -60,6 +60,7 @@
 #include <time.h>
 
 #include "cryptlib.h"
+#include "asn1_locl.h"
 
 #ifndef NO_SYS_TYPES_H
 # include <sys/types.h>
@@ -100,12 +101,7 @@
 	p=buf_in;
 
 	i2d(data,&p);
-	if (!EVP_VerifyInit_ex(&ctx,type, NULL))
-		{
-		ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_EVP_LIB);
-		ret=0;
-		goto err;
-		}
+	EVP_VerifyInit_ex(&ctx,type, NULL);
 	EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl);
 
 	OPENSSL_cleanse(buf_in,(unsigned int)inl);
@@ -134,19 +130,34 @@
 	     void *asn, EVP_PKEY *pkey)
 	{
 	EVP_MD_CTX ctx;
-	const EVP_MD *type;
+	const EVP_MD *type = NULL;
 	unsigned char *buf_in=NULL;
-	int ret= -1,i,inl;
+	int ret= -1,inl;
+
+	int mdnid, pknid;
 
 	EVP_MD_CTX_init(&ctx);
-	i=OBJ_obj2nid(a->algorithm);
-	type=EVP_get_digestbyname(OBJ_nid2sn(i));
+
+	/* Convert signature OID into digest and public key OIDs */
+	if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid))
+		{
+		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
+		goto err;
+		}
+	type=EVP_get_digestbynid(mdnid);
 	if (type == NULL)
 		{
 		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
 		goto err;
 		}
 
+	/* Check public key OID matches public key type */
+	if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id)
+		{
+		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_WRONG_PUBLIC_KEY_TYPE);
+		goto err;
+		}
+
 	if (!EVP_VerifyInit_ex(&ctx,type, NULL))
 		{
 		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
diff --git a/crypto/asn1/ameth_lib.c b/crypto/asn1/ameth_lib.c
new file mode 100644
index 0000000..9a8b6cc
--- /dev/null
+++ b/crypto/asn1/ameth_lib.c
@@ -0,0 +1,450 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include "asn1_locl.h"
+
+extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
+extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[];
+extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
+
+/* Keep this sorted in type order !! */
+static const EVP_PKEY_ASN1_METHOD *standard_methods[] = 
+	{
+#ifndef OPENSSL_NO_RSA
+	&rsa_asn1_meths[0],
+	&rsa_asn1_meths[1],
+#endif
+#ifndef OPENSSL_NO_DH
+	&dh_asn1_meth,
+#endif
+#ifndef OPENSSL_NO_DSA
+	&dsa_asn1_meths[0],
+	&dsa_asn1_meths[1],
+	&dsa_asn1_meths[2],
+	&dsa_asn1_meths[3],
+	&dsa_asn1_meths[4],
+#endif
+#ifndef OPENSSL_NO_EC
+	&eckey_asn1_meth,
+#endif
+	&hmac_asn1_meth
+	};
+
+typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
+DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD)
+static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
+
+
+
+#ifdef TEST
+void main()
+	{
+	int i;
+	for (i = 0;
+		i < sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
+		i++)
+		fprintf(stderr, "Number %d id=%d (%s)\n", i,
+			standard_methods[i]->pkey_id,
+			OBJ_nid2sn(standard_methods[i]->pkey_id));
+	}
+#endif
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
+			   const EVP_PKEY_ASN1_METHOD *, ameth);
+
+static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a,
+		     const EVP_PKEY_ASN1_METHOD * const *b)
+	{
+        return ((*a)->pkey_id - (*b)->pkey_id);
+	}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
+			     const EVP_PKEY_ASN1_METHOD *, ameth);
+
+int EVP_PKEY_asn1_get_count(void)
+	{
+	int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
+	if (app_methods)
+		num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
+	return num;
+	}
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
+	{
+	int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
+	if (idx < 0)
+		return NULL; 
+	if (idx < num)
+		return standard_methods[idx];
+	idx -= num;
+	return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
+	}
+
+static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
+	{
+	EVP_PKEY_ASN1_METHOD tmp;
+	const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
+	tmp.pkey_id = type;
+	if (app_methods)
+		{
+		int idx;
+		idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
+		if (idx >= 0)
+			return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
+		}
+	ret = OBJ_bsearch_ameth(&t, standard_methods,
+			  sizeof(standard_methods)
+			  /sizeof(EVP_PKEY_ASN1_METHOD *));
+	if (!ret || !*ret)
+		return NULL;
+	return *ret;
+	}
+
+/* Find an implementation of an ASN1 algorithm. If 'pe' is not NULL
+ * also search through engines and set *pe to a functional reference
+ * to the engine implementing 'type' or NULL if no engine implements 
+ * it.
+ */
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
+	{
+	const EVP_PKEY_ASN1_METHOD *t;
+	ENGINE *e;
+
+	for (;;)
+		{
+		t = pkey_asn1_find(type);
+		if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
+			break;
+		type = t->pkey_base_id;
+		}
+	if (pe)
+		{
+#ifndef OPENSSL_NO_ENGINE
+		/* type will contain the final unaliased type */
+		e = ENGINE_get_pkey_asn1_meth_engine(type);
+		if (e)
+			{
+			*pe = e;
+			return ENGINE_get_pkey_asn1_meth(e, type);
+			}
+#endif
+		*pe = NULL;
+		}
+	return t;
+	}
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
+					const char *str, int len)
+	{
+	int i;
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	if (len == -1)
+		len = strlen(str);
+	if (pe)
+		{
+#ifndef OPENSSL_NO_ENGINE
+		ENGINE *e;
+		ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
+		if (ameth)
+			{
+			/* Convert structural into
+			 * functional reference
+			 */
+			if (!ENGINE_init(e))
+				ameth = NULL;
+			ENGINE_free(e);
+			*pe = e;
+			return ameth;
+			}
+#endif
+		*pe = NULL;
+		}
+	for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
+		{
+		ameth = EVP_PKEY_asn1_get0(i);
+		if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
+			continue;
+		if (((int)strlen(ameth->pem_str) == len) && 
+			!strncasecmp(ameth->pem_str, str, len))
+			return ameth;
+		}
+	return NULL;
+	}
+
+int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
+	{
+	if (app_methods == NULL)
+		{
+		app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
+		if (!app_methods)
+			return 0;
+		}
+	if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
+		return 0;
+	sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
+	return 1;
+	}
+
+int EVP_PKEY_asn1_add_alias(int to, int from)
+	{
+	EVP_PKEY_ASN1_METHOD *ameth;
+	ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
+	if (!ameth)
+		return 0;
+	ameth->pkey_base_id = to;
+	return EVP_PKEY_asn1_add0(ameth);
+	}
+
+int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags,
+				const char **pinfo, const char **ppem_str,
+					const EVP_PKEY_ASN1_METHOD *ameth)
+	{
+	if (!ameth)
+		return 0;
+	if (ppkey_id)
+		*ppkey_id = ameth->pkey_id;
+	if (ppkey_base_id)
+		*ppkey_base_id = ameth->pkey_base_id;
+	if (ppkey_flags)
+		*ppkey_flags = ameth->pkey_flags;
+	if (pinfo)
+		*pinfo = ameth->info;
+	if (ppem_str)
+		*ppem_str = ameth->pem_str;
+	return 1;
+	}
+
+const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
+	{
+	return pkey->ameth;
+	}
+
+EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
+					const char *pem_str, const char *info)
+	{
+	EVP_PKEY_ASN1_METHOD *ameth;
+	ameth = OPENSSL_malloc(sizeof(EVP_PKEY_ASN1_METHOD));
+	if (!ameth)
+		return NULL;
+
+	ameth->pkey_id = id;
+	ameth->pkey_base_id = id;
+	ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
+
+	if (info)
+		{
+		ameth->info = BUF_strdup(info);
+		if (!ameth->info)
+			goto err;
+		}
+	else
+		ameth->info = NULL;
+
+	if (pem_str)
+		{
+		ameth->pem_str = BUF_strdup(pem_str);
+		if (!ameth->pem_str)
+			goto err;
+		}
+	else
+		ameth->pem_str = NULL;
+
+	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 1958298..f7718b5 100644
--- a/crypto/asn1/asn1.h
+++ b/crypto/asn1/asn1.h
@@ -213,7 +213,7 @@
 	const char *sn,*ln;
 	int nid;
 	int length;
-	unsigned char *data;
+	const unsigned char *data;	/* data remains const after init */
 	int flags;	/* Should we free this one */
 	} ASN1_OBJECT;
 
@@ -228,8 +228,12 @@
  * complete and is a place holder for content when it had all been 
  * accessed. The flag will be reset when content has been written to it.
  */
-#define ASN1_STRING_FLAG_CONT 0x020 
 
+#define ASN1_STRING_FLAG_CONT 0x020 
+/* This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING
+ * type.
+ */
+#define ASN1_STRING_FLAG_MSTRING 0x040 
 /* This is the base type that holds just about everything :-) */
 typedef struct asn1_string_st
 	{
@@ -330,6 +334,13 @@
 	type *name##_new(void); \
 	void name##_free(type *a);
 
+#define DECLARE_ASN1_PRINT_FUNCTION(stname) \
+	DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname)
+
+#define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \
+	int fname##_print_ctx(BIO *out, stname *x, int indent, \
+					 const ASN1_PCTX *pctx);
+
 #define D2I_OF(type) type *(*)(type **,const unsigned char **,long)
 #define I2D_OF(type) int (*)(type *,unsigned char **)
 #define I2D_OF_const(type) int (*)(const type *,unsigned char **)
@@ -344,8 +355,6 @@
     ((void*) (1 ? p : (type*)0))
 #define CHECKED_PPTR_OF(type, p) \
     ((void**) (1 ? p : (type**)0))
-#define CHECKED_PTR_OF_TO_CHAR(type, p) \
-    ((char*) (1 ? p : (type*)0))
 
 #define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long)
 #define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **)
@@ -536,28 +545,23 @@
 		 * contain the set or sequence bytes */
 		ASN1_STRING *		set;
 		ASN1_STRING *		sequence;
-		ASN1_VALUE  *		asn1_value;
+		ASN1_VALUE *		asn1_value;
 		} value;
 	} ASN1_TYPE;
 
 DECLARE_STACK_OF(ASN1_TYPE)
 DECLARE_ASN1_SET_OF(ASN1_TYPE)
 
-typedef struct asn1_method_st
-	{
-	i2d_of_void *i2d;
-	d2i_of_void *d2i;
-	void *(*create)(void);
-	void (*destroy)(void *);
-	} ASN1_METHOD;
+typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY;
 
-/* This is used when parsing some Netscape objects */
-typedef struct asn1_header_st
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY)
+
+typedef struct NETSCAPE_X509_st
 	{
 	ASN1_OCTET_STRING *header;
-	void *data;
-	ASN1_METHOD *meth;
-	} ASN1_HEADER;
+	X509 *cert;
+	} NETSCAPE_X509;
 
 /* This is used to contain a list of bit names */
 typedef struct BIT_STRING_BITNAME_st {
@@ -577,32 +581,34 @@
 		ASN1_STRING_type_new(V_ASN1_BIT_STRING)
 #define M_ASN1_BIT_STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
 #define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\
-		ASN1_STRING_dup((ASN1_STRING *)a)
+		ASN1_STRING_dup((const ASN1_STRING *)a)
 #define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\
-		(ASN1_STRING *)a,(ASN1_STRING *)b)
+		(const ASN1_STRING *)a,(const ASN1_STRING *)b)
 #define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c)
 
 #define M_ASN1_INTEGER_new()	(ASN1_INTEGER *)\
 		ASN1_STRING_type_new(V_ASN1_INTEGER)
 #define M_ASN1_INTEGER_free(a)		ASN1_STRING_free((ASN1_STRING *)a)
-#define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)\
+		ASN1_STRING_dup((const ASN1_STRING *)a)
 #define M_ASN1_INTEGER_cmp(a,b)	ASN1_STRING_cmp(\
-		(ASN1_STRING *)a,(ASN1_STRING *)b)
+		(const ASN1_STRING *)a,(const ASN1_STRING *)b)
 
 #define M_ASN1_ENUMERATED_new()	(ASN1_ENUMERATED *)\
 		ASN1_STRING_type_new(V_ASN1_ENUMERATED)
 #define M_ASN1_ENUMERATED_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
-#define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)\
+		ASN1_STRING_dup((const ASN1_STRING *)a)
 #define M_ASN1_ENUMERATED_cmp(a,b)	ASN1_STRING_cmp(\
-		(ASN1_STRING *)a,(ASN1_STRING *)b)
+		(const ASN1_STRING *)a,(const ASN1_STRING *)b)
 
 #define M_ASN1_OCTET_STRING_new()	(ASN1_OCTET_STRING *)\
 		ASN1_STRING_type_new(V_ASN1_OCTET_STRING)
 #define M_ASN1_OCTET_STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
 #define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\
-		ASN1_STRING_dup((ASN1_STRING *)a)
+		ASN1_STRING_dup((const ASN1_STRING *)a)
 #define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\
-		(ASN1_STRING *)a,(ASN1_STRING *)b)
+		(const ASN1_STRING *)a,(const ASN1_STRING *)b)
 #define M_ASN1_OCTET_STRING_set(a,b,c)	ASN1_STRING_set((ASN1_STRING *)a,b,c)
 #define M_ASN1_OCTET_STRING_print(a,b)	ASN1_STRING_print(a,(ASN1_STRING *)b)
 #define M_i2d_ASN1_OCTET_STRING(a,pp) \
@@ -686,7 +692,7 @@
 		ASN1_STRING_type_new(V_ASN1_IA5STRING)
 #define M_ASN1_IA5STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
 #define M_ASN1_IA5STRING_dup(a)	\
-			(ASN1_IA5STRING *)ASN1_STRING_dup((ASN1_STRING *)a)
+		(ASN1_IA5STRING *)ASN1_STRING_dup((const ASN1_STRING *)a)
 #define M_i2d_ASN1_IA5STRING(a,pp) \
 		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\
 			V_ASN1_UNIVERSAL)
@@ -697,18 +703,20 @@
 #define M_ASN1_UTCTIME_new()	(ASN1_UTCTIME *)\
 		ASN1_STRING_type_new(V_ASN1_UTCTIME)
 #define M_ASN1_UTCTIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
-#define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)\
+		ASN1_STRING_dup((const ASN1_STRING *)a)
 
 #define M_ASN1_GENERALIZEDTIME_new()	(ASN1_GENERALIZEDTIME *)\
 		ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME)
 #define M_ASN1_GENERALIZEDTIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
 #define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\
-	(ASN1_STRING *)a)
+	(const ASN1_STRING *)a)
 
 #define M_ASN1_TIME_new()	(ASN1_TIME *)\
 		ASN1_STRING_type_new(V_ASN1_UTCTIME)
 #define M_ASN1_TIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
-#define M_ASN1_TIME_dup(a) (ASN1_TIME *)ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_TIME_dup(a) (ASN1_TIME *)\
+	ASN1_STRING_dup((const ASN1_STRING *)a)
 
 #define M_ASN1_GENERALSTRING_new()	(ASN1_GENERALSTRING *)\
 		ASN1_STRING_type_new(V_ASN1_GENERALSTRING)
@@ -769,6 +777,7 @@
 int ASN1_TYPE_get(ASN1_TYPE *a);
 void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
 int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
+int            ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b);
 
 ASN1_OBJECT *	ASN1_OBJECT_new(void );
 void		ASN1_OBJECT_free(ASN1_OBJECT *a);
@@ -785,14 +794,15 @@
 
 ASN1_STRING *	ASN1_STRING_new(void);
 void		ASN1_STRING_free(ASN1_STRING *a);
-ASN1_STRING *	ASN1_STRING_dup(ASN1_STRING *a);
+int		ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str);
+ASN1_STRING *	ASN1_STRING_dup(const ASN1_STRING *a);
 ASN1_STRING *	ASN1_STRING_type_new(int type );
-int 		ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b);
+int 		ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b);
   /* Since this is used to store all sorts of things, via macros, for now, make
      its data void * */
 int 		ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
 void		ASN1_STRING_set0(ASN1_STRING *str, void *data, int len);
-int ASN1_STRING_length(ASN1_STRING *x);
+int ASN1_STRING_length(const ASN1_STRING *x);
 void ASN1_STRING_length_set(ASN1_STRING *x, int n);
 int ASN1_STRING_type(ASN1_STRING *x);
 unsigned char * ASN1_STRING_data(ASN1_STRING *x);
@@ -805,6 +815,8 @@
 			int length );
 int		ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
 int		ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n);
+int            ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
+                                     unsigned char *flags, int flags_len);
 
 #ifndef OPENSSL_NO_BIO
 int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
@@ -823,13 +835,15 @@
 			long length);
 ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,const unsigned char **pp,
 			long length);
-ASN1_INTEGER *	ASN1_INTEGER_dup(ASN1_INTEGER *x);
-int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y);
+ASN1_INTEGER *	ASN1_INTEGER_dup(const ASN1_INTEGER *x);
+int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y);
 
 DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)
 
 int ASN1_UTCTIME_check(ASN1_UTCTIME *a);
 ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s,time_t t);
+ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
+				int offset_day, long offset_sec);
 int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str);
 int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t);
 #if 0
@@ -838,11 +852,13 @@
 
 int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *a);
 ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,time_t t);
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
+	     time_t t, int offset_day, long offset_sec);
 int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str);
 
 DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
-ASN1_OCTET_STRING *	ASN1_OCTET_STRING_dup(ASN1_OCTET_STRING *a);
-int 	ASN1_OCTET_STRING_cmp(ASN1_OCTET_STRING *a, ASN1_OCTET_STRING *b);
+ASN1_OCTET_STRING *	ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a);
+int 	ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b);
 int 	ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, int len);
 
 DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
@@ -869,14 +885,20 @@
 DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF)
 
 ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t);
+ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s,time_t t,
+				int offset_day, long offset_sec);
 int ASN1_TIME_check(ASN1_TIME *t);
 ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out);
+int ASN1_TIME_set_string(ASN1_TIME *s, const char *str);
 
-int i2d_ASN1_SET(STACK *a, unsigned char **pp,
-		 i2d_of_void *i2d, int ex_tag, int ex_class, int is_set);
-STACK *	d2i_ASN1_SET(STACK **a, const unsigned char **pp, long length,
-		     d2i_of_void *d2i, void (*free_func)(void *),
-		     int ex_tag, int ex_class);
+int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
+		 i2d_of_void *i2d, int ex_tag, int ex_class,
+		 int is_set);
+STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
+			      const unsigned char **pp,
+			      long length, d2i_of_void *d2i,
+			      void (*free_func)(OPENSSL_BLOCK), int ex_tag,
+			      int ex_class);
 
 #ifndef OPENSSL_NO_BIO
 int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
@@ -894,9 +916,9 @@
 	const char *sn, const char *ln);
 
 int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
-long ASN1_INTEGER_get(ASN1_INTEGER *a);
-ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai);
-BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai,BIGNUM *bn);
+long ASN1_INTEGER_get(const ASN1_INTEGER *a);
+ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai);
+BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai,BIGNUM *bn);
 
 int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v);
 long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a);
@@ -930,17 +952,17 @@
 int ASN1_object_size(int constructed, int length, int tag);
 
 /* Used to implement other functions */
-void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x);
+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x);
 
 #define ASN1_dup_of(type,i2d,d2i,x) \
     ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \
 		     CHECKED_D2I_OF(type, d2i), \
-		     CHECKED_PTR_OF_TO_CHAR(type, x)))
+		     CHECKED_PTR_OF(type, x)))
 
 #define ASN1_dup_of_const(type,i2d,d2i,x) \
     ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \
 		     CHECKED_D2I_OF(type, d2i), \
-		     CHECKED_PTR_OF_TO_CHAR(const type, x)))
+		     CHECKED_PTR_OF(const type, x)))
 
 void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
 
@@ -1001,30 +1023,24 @@
 		  CHECKED_PTR_OF(const type, x)))
 
 int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
-int ASN1_UTCTIME_print(BIO *fp,ASN1_UTCTIME *a);
-int ASN1_GENERALIZEDTIME_print(BIO *fp,ASN1_GENERALIZEDTIME *a);
-int ASN1_TIME_print(BIO *fp,ASN1_TIME *a);
-int ASN1_STRING_print(BIO *bp,ASN1_STRING *v);
+int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a);
+int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);
+int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
+int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
 int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
+int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
+				unsigned char *buf, int off);
 int ASN1_parse(BIO *bp,const unsigned char *pp,long len,int indent);
 int ASN1_parse_dump(BIO *bp,const unsigned char *pp,long len,int indent,int dump);
 #endif
 const char *ASN1_tag2str(int tag);
 
-/* Used to load and write netscape format cert/key */
-int i2d_ASN1_HEADER(ASN1_HEADER *a,unsigned char **pp);
-ASN1_HEADER *d2i_ASN1_HEADER(ASN1_HEADER **a,const unsigned char **pp, long length);
-ASN1_HEADER *ASN1_HEADER_new(void );
-void ASN1_HEADER_free(ASN1_HEADER *a);
+/* Used to load and write netscape format cert */
+
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_X509)
 
 int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s);
 
-/* Not used that much at this point, except for the first two */
-ASN1_METHOD *X509_asn1_meth(void);
-ASN1_METHOD *RSAPrivateKey_asn1_meth(void);
-ASN1_METHOD *ASN1_IA5STRING_asn1_meth(void);
-ASN1_METHOD *ASN1_BIT_STRING_asn1_meth(void);
-
 int ASN1_TYPE_set_octetstring(ASN1_TYPE *a,
 	unsigned char *data, int len);
 int ASN1_TYPE_get_octetstring(ASN1_TYPE *a,
@@ -1034,9 +1050,9 @@
 int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a,long *num,
 	unsigned char *data, int max_len);
 
-STACK *ASN1_seq_unpack(const unsigned char *buf, int len,
-		       d2i_of_void *d2i, void (*free_func)(void *));
-unsigned char *ASN1_seq_pack(STACK *safes, i2d_of_void *i2d,
+STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
+				 d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK));
+unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
 			     unsigned char **buf, int *len );
 void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i);
 void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it);
@@ -1079,15 +1095,58 @@
 ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
 ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);
 
-typedef int asn1_output_data_fn(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
-					const ASN1_ITEM *it);
+/* ASN1 Print flags */
 
-int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
+/* Indicate missing OPTIONAL fields */
+#define ASN1_PCTX_FLAGS_SHOW_ABSENT		0x001	
+/* Mark start and end of SEQUENCE */
+#define ASN1_PCTX_FLAGS_SHOW_SEQUENCE		0x002
+/* Mark start and end of SEQUENCE/SET OF */
+#define ASN1_PCTX_FLAGS_SHOW_SSOF		0x004
+/* Show the ASN1 type of primitives */
+#define ASN1_PCTX_FLAGS_SHOW_TYPE		0x008
+/* Don't show ASN1 type of ANY */
+#define ASN1_PCTX_FLAGS_NO_ANY_TYPE		0x010
+/* Don't show ASN1 type of MSTRINGs */
+#define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE		0x020
+/* Don't show field names in SEQUENCE */
+#define ASN1_PCTX_FLAGS_NO_FIELD_NAME		0x040
+/* Show structure names of each SEQUENCE field */
+#define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME	0x080
+/* Don't show structure name even at top level */
+#define ASN1_PCTX_FLAGS_NO_STRUCT_NAME		0x100
+
+int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
+				const ASN1_ITEM *it, const ASN1_PCTX *pctx);
+ASN1_PCTX *ASN1_PCTX_new(void);
+void ASN1_PCTX_free(ASN1_PCTX *p);
+unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags);
+
+BIO_METHOD *BIO_f_asn1(void);
+
+BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it);
+
+int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+				const ASN1_ITEM *it);
+int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+				const char *hdr,
+				const ASN1_ITEM *it);
+int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
 				int ctype_nid, int econt_nid,
 				STACK_OF(X509_ALGOR) *mdalgs,
-				asn1_output_data_fn *data_fn,
 				const ASN1_ITEM *it);
 ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it);
+int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
+int SMIME_text(BIO *in, BIO *out);
 
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -1118,6 +1177,7 @@
 #define ASN1_F_ASN1_ENUMERATED_TO_BN			 113
 #define ASN1_F_ASN1_EX_C2I				 204
 #define ASN1_F_ASN1_FIND_END				 190
+#define ASN1_F_ASN1_GENERALIZEDTIME_ADJ			 216
 #define ASN1_F_ASN1_GENERALIZEDTIME_SET			 185
 #define ASN1_F_ASN1_GENERATE_V3				 178
 #define ASN1_F_ASN1_GET_OBJECT				 114
@@ -1138,7 +1198,7 @@
 #define ASN1_F_ASN1_ITEM_VERIFY				 197
 #define ASN1_F_ASN1_MBSTRING_NCOPY			 122
 #define ASN1_F_ASN1_OBJECT_NEW				 123
-#define ASN1_F_ASN1_OUTPUT_DATA				 207
+#define ASN1_F_ASN1_OUTPUT_DATA				 214
 #define ASN1_F_ASN1_PACK_STRING				 124
 #define ASN1_F_ASN1_PCTX_NEW				 205
 #define ASN1_F_ASN1_PKCS5_PBE_SET			 125
@@ -1152,14 +1212,17 @@
 #define ASN1_F_ASN1_TEMPLATE_EX_D2I			 132
 #define ASN1_F_ASN1_TEMPLATE_NEW			 133
 #define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I			 131
+#define ASN1_F_ASN1_TIME_ADJ				 217
 #define ASN1_F_ASN1_TIME_SET				 175
 #define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING		 134
 #define ASN1_F_ASN1_TYPE_GET_OCTETSTRING		 135
 #define ASN1_F_ASN1_UNPACK_STRING			 136
+#define ASN1_F_ASN1_UTCTIME_ADJ				 218
 #define ASN1_F_ASN1_UTCTIME_SET				 187
 #define ASN1_F_ASN1_VERIFY				 137
-#define ASN1_F_B64_READ_ASN1				 208
-#define ASN1_F_B64_WRITE_ASN1				 209
+#define ASN1_F_B64_READ_ASN1				 209
+#define ASN1_F_B64_WRITE_ASN1				 210
+#define ASN1_F_BIO_NEW_NDEF				 208
 #define ASN1_F_BITSTR_CB				 180
 #define ASN1_F_BN_TO_ASN1_ENUMERATED			 138
 #define ASN1_F_BN_TO_ASN1_INTEGER			 139
@@ -1178,6 +1241,7 @@
 #define ASN1_F_D2I_ASN1_TYPE_BYTES			 149
 #define ASN1_F_D2I_ASN1_UINTEGER			 150
 #define ASN1_F_D2I_ASN1_UTCTIME				 151
+#define ASN1_F_D2I_AUTOPRIVATEKEY			 207
 #define ASN1_F_D2I_NETSCAPE_RSA				 152
 #define ASN1_F_D2I_NETSCAPE_RSA_2			 153
 #define ASN1_F_D2I_PRIVATEKEY				 154
@@ -1187,6 +1251,7 @@
 #define ASN1_F_D2I_X509					 156
 #define ASN1_F_D2I_X509_CINF				 157
 #define ASN1_F_D2I_X509_PKEY				 159
+#define ASN1_F_I2D_ASN1_BIO_STREAM			 211
 #define ASN1_F_I2D_ASN1_SET				 188
 #define ASN1_F_I2D_ASN1_TIME				 160
 #define ASN1_F_I2D_DSA_PUBKEY				 161
@@ -1198,10 +1263,11 @@
 #define ASN1_F_LONG_C2I					 166
 #define ASN1_F_OID_MODULE_INIT				 174
 #define ASN1_F_PARSE_TAGGING				 182
-#define ASN1_F_PKCS5_PBE2_SET				 167
+#define ASN1_F_PKCS5_PBE2_SET_IV			 167
 #define ASN1_F_PKCS5_PBE_SET				 202
-#define ASN1_F_SMIME_READ_ASN1				 210
-#define ASN1_F_SMIME_TEXT				 211
+#define ASN1_F_PKCS5_PBE_SET0_ALGOR			 215
+#define ASN1_F_SMIME_READ_ASN1				 212
+#define ASN1_F_SMIME_TEXT				 213
 #define ASN1_F_X509_CINF_NEW				 168
 #define ASN1_F_X509_CRL_ADD0_REVOKED			 169
 #define ASN1_F_X509_INFO_NEW				 170
@@ -1213,14 +1279,14 @@
 
 /* Reason codes. */
 #define ASN1_R_ADDING_OBJECT				 171
-#define ASN1_R_ASN1_PARSE_ERROR				 198
-#define ASN1_R_ASN1_SIG_PARSE_ERROR			 199
+#define ASN1_R_ASN1_PARSE_ERROR				 203
+#define ASN1_R_ASN1_SIG_PARSE_ERROR			 204
 #define ASN1_R_AUX_ERROR				 100
 #define ASN1_R_BAD_CLASS				 101
 #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_BMPSTRING_IS_WRONG_LENGTH		 214
 #define ASN1_R_BN_LIB					 105
 #define ASN1_R_BOOLEAN_IS_WRONG_LENGTH			 106
 #define ASN1_R_BUFFER_TOO_SMALL				 107
@@ -1229,6 +1295,7 @@
 #define ASN1_R_DECODE_ERROR				 110
 #define ASN1_R_DECODING_ERROR				 111
 #define ASN1_R_DEPTH_EXCEEDED				 174
+#define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED	 198
 #define ASN1_R_ENCODE_ERROR				 112
 #define ASN1_R_ERROR_GETTING_TIME			 173
 #define ASN1_R_ERROR_LOADING_SECTION			 172
@@ -1262,10 +1329,10 @@
 #define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG		 128
 #define ASN1_R_INVALID_BMPSTRING_LENGTH			 129
 #define ASN1_R_INVALID_DIGIT				 130
-#define ASN1_R_INVALID_MIME_TYPE			 200
+#define ASN1_R_INVALID_MIME_TYPE			 205
 #define ASN1_R_INVALID_MODIFIER				 186
 #define ASN1_R_INVALID_NUMBER				 187
-#define ASN1_R_INVALID_OBJECT_ENCODING			 212
+#define ASN1_R_INVALID_OBJECT_ENCODING			 216
 #define ASN1_R_INVALID_SEPARATOR			 131
 #define ASN1_R_INVALID_TIME_FORMAT			 132
 #define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH		 133
@@ -1273,9 +1340,9 @@
 #define ASN1_R_IV_TOO_LARGE				 135
 #define ASN1_R_LENGTH_ERROR				 136
 #define ASN1_R_LIST_ERROR				 188
-#define ASN1_R_MIME_NO_CONTENT_TYPE			 201
-#define ASN1_R_MIME_PARSE_ERROR				 202
-#define ASN1_R_MIME_SIG_PARSE_ERROR			 203
+#define ASN1_R_MIME_NO_CONTENT_TYPE			 206
+#define ASN1_R_MIME_PARSE_ERROR				 207
+#define ASN1_R_MIME_SIG_PARSE_ERROR			 208
 #define ASN1_R_MISSING_EOC				 137
 #define ASN1_R_MISSING_SECOND_NUMBER			 138
 #define ASN1_R_MISSING_VALUE				 189
@@ -1285,11 +1352,12 @@
 #define ASN1_R_NON_HEX_CHARACTERS			 141
 #define ASN1_R_NOT_ASCII_FORMAT				 190
 #define ASN1_R_NOT_ENOUGH_DATA				 142
-#define ASN1_R_NO_CONTENT_TYPE				 204
+#define ASN1_R_NO_CONTENT_TYPE				 209
+#define ASN1_R_NO_DEFAULT_DIGEST			 201
 #define ASN1_R_NO_MATCHING_CHOICE_TYPE			 143
-#define ASN1_R_NO_MULTIPART_BODY_FAILURE		 205
-#define ASN1_R_NO_MULTIPART_BOUNDARY			 206
-#define ASN1_R_NO_SIG_CONTENT_TYPE			 207
+#define ASN1_R_NO_MULTIPART_BODY_FAILURE		 210
+#define ASN1_R_NO_MULTIPART_BOUNDARY			 211
+#define ASN1_R_NO_SIG_CONTENT_TYPE			 212
 #define ASN1_R_NULL_IS_WRONG_LENGTH			 144
 #define ASN1_R_OBJECT_NOT_ASCII_FORMAT			 191
 #define ASN1_R_ODD_NUMBER_OF_CHARS			 145
@@ -1299,8 +1367,8 @@
 #define ASN1_R_SEQUENCE_NOT_CONSTRUCTED			 149
 #define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG		 192
 #define ASN1_R_SHORT_LINE				 150
-#define ASN1_R_SIG_INVALID_MIME_TYPE			 208
-#define ASN1_R_STREAMING_NOT_SUPPORTED			 209
+#define ASN1_R_SIG_INVALID_MIME_TYPE			 213
+#define ASN1_R_STREAMING_NOT_SUPPORTED			 202
 #define ASN1_R_STRING_TOO_LONG				 151
 #define ASN1_R_STRING_TOO_SHORT				 152
 #define ASN1_R_TAG_VALUE_TOO_HIGH			 153
@@ -1311,11 +1379,12 @@
 #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_UNIVERSALSTRING_IS_WRONG_LENGTH		 215
 #define ASN1_R_UNKNOWN_FORMAT				 160
 #define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM		 161
 #define ASN1_R_UNKNOWN_OBJECT_TYPE			 162
 #define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE			 163
+#define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM		 199
 #define ASN1_R_UNKNOWN_TAG				 194
 #define ASN1_R_UNKOWN_FORMAT				 195
 #define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE		 164
@@ -1323,6 +1392,7 @@
 #define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM		 166
 #define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE		 167
 #define ASN1_R_UNSUPPORTED_TYPE				 196
+#define ASN1_R_WRONG_PUBLIC_KEY_TYPE			 200
 #define ASN1_R_WRONG_TAG				 168
 #define ASN1_R_WRONG_TYPE				 169
 
diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c
index ba88eb3..6e04d08 100644
--- a/crypto/asn1/asn1_err.c
+++ b/crypto/asn1/asn1_err.c
@@ -1,6 +1,6 @@
 /* crypto/asn1/asn1_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2008 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2009 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -90,10 +90,11 @@
 {ERR_FUNC(ASN1_F_ASN1_ENUMERATED_TO_BN),	"ASN1_ENUMERATED_to_BN"},
 {ERR_FUNC(ASN1_F_ASN1_EX_C2I),	"ASN1_EX_C2I"},
 {ERR_FUNC(ASN1_F_ASN1_FIND_END),	"ASN1_FIND_END"},
+{ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_ADJ),	"ASN1_GENERALIZEDTIME_adj"},
 {ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_SET),	"ASN1_GENERALIZEDTIME_set"},
 {ERR_FUNC(ASN1_F_ASN1_GENERATE_V3),	"ASN1_generate_v3"},
 {ERR_FUNC(ASN1_F_ASN1_GET_OBJECT),	"ASN1_get_object"},
-{ERR_FUNC(ASN1_F_ASN1_HEADER_NEW),	"ASN1_HEADER_new"},
+{ERR_FUNC(ASN1_F_ASN1_HEADER_NEW),	"ASN1_HEADER_NEW"},
 {ERR_FUNC(ASN1_F_ASN1_I2D_BIO),	"ASN1_i2d_bio"},
 {ERR_FUNC(ASN1_F_ASN1_I2D_FP),	"ASN1_i2d_fp"},
 {ERR_FUNC(ASN1_F_ASN1_INTEGER_SET),	"ASN1_INTEGER_set"},
@@ -112,7 +113,7 @@
 {ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW),	"ASN1_OBJECT_new"},
 {ERR_FUNC(ASN1_F_ASN1_OUTPUT_DATA),	"ASN1_OUTPUT_DATA"},
 {ERR_FUNC(ASN1_F_ASN1_PACK_STRING),	"ASN1_pack_string"},
-{ERR_FUNC(ASN1_F_ASN1_PCTX_NEW),	"ASN1_PCTX_NEW"},
+{ERR_FUNC(ASN1_F_ASN1_PCTX_NEW),	"ASN1_PCTX_new"},
 {ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET),	"ASN1_PKCS5_PBE_SET"},
 {ERR_FUNC(ASN1_F_ASN1_SEQ_PACK),	"ASN1_seq_pack"},
 {ERR_FUNC(ASN1_F_ASN1_SEQ_UNPACK),	"ASN1_seq_unpack"},
@@ -124,14 +125,17 @@
 {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I),	"ASN1_TEMPLATE_EX_D2I"},
 {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW),	"ASN1_TEMPLATE_NEW"},
 {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I),	"ASN1_TEMPLATE_NOEXP_D2I"},
+{ERR_FUNC(ASN1_F_ASN1_TIME_ADJ),	"ASN1_TIME_adj"},
 {ERR_FUNC(ASN1_F_ASN1_TIME_SET),	"ASN1_TIME_set"},
 {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING),	"ASN1_TYPE_get_int_octetstring"},
 {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING),	"ASN1_TYPE_get_octetstring"},
 {ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING),	"ASN1_unpack_string"},
+{ERR_FUNC(ASN1_F_ASN1_UTCTIME_ADJ),	"ASN1_UTCTIME_adj"},
 {ERR_FUNC(ASN1_F_ASN1_UTCTIME_SET),	"ASN1_UTCTIME_set"},
 {ERR_FUNC(ASN1_F_ASN1_VERIFY),	"ASN1_verify"},
 {ERR_FUNC(ASN1_F_B64_READ_ASN1),	"B64_READ_ASN1"},
 {ERR_FUNC(ASN1_F_B64_WRITE_ASN1),	"B64_WRITE_ASN1"},
+{ERR_FUNC(ASN1_F_BIO_NEW_NDEF),	"BIO_new_NDEF"},
 {ERR_FUNC(ASN1_F_BITSTR_CB),	"BITSTR_CB"},
 {ERR_FUNC(ASN1_F_BN_TO_ASN1_ENUMERATED),	"BN_to_ASN1_ENUMERATED"},
 {ERR_FUNC(ASN1_F_BN_TO_ASN1_INTEGER),	"BN_to_ASN1_INTEGER"},
@@ -143,13 +147,14 @@
 {ERR_FUNC(ASN1_F_D2I_ASN1_BOOLEAN),	"d2i_ASN1_BOOLEAN"},
 {ERR_FUNC(ASN1_F_D2I_ASN1_BYTES),	"d2i_ASN1_bytes"},
 {ERR_FUNC(ASN1_F_D2I_ASN1_GENERALIZEDTIME),	"D2I_ASN1_GENERALIZEDTIME"},
-{ERR_FUNC(ASN1_F_D2I_ASN1_HEADER),	"d2i_ASN1_HEADER"},
+{ERR_FUNC(ASN1_F_D2I_ASN1_HEADER),	"D2I_ASN1_HEADER"},
 {ERR_FUNC(ASN1_F_D2I_ASN1_INTEGER),	"D2I_ASN1_INTEGER"},
 {ERR_FUNC(ASN1_F_D2I_ASN1_OBJECT),	"d2i_ASN1_OBJECT"},
 {ERR_FUNC(ASN1_F_D2I_ASN1_SET),	"d2i_ASN1_SET"},
 {ERR_FUNC(ASN1_F_D2I_ASN1_TYPE_BYTES),	"d2i_ASN1_type_bytes"},
 {ERR_FUNC(ASN1_F_D2I_ASN1_UINTEGER),	"d2i_ASN1_UINTEGER"},
 {ERR_FUNC(ASN1_F_D2I_ASN1_UTCTIME),	"D2I_ASN1_UTCTIME"},
+{ERR_FUNC(ASN1_F_D2I_AUTOPRIVATEKEY),	"d2i_AutoPrivateKey"},
 {ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA),	"d2i_Netscape_RSA"},
 {ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA_2),	"D2I_NETSCAPE_RSA_2"},
 {ERR_FUNC(ASN1_F_D2I_PRIVATEKEY),	"d2i_PrivateKey"},
@@ -159,6 +164,7 @@
 {ERR_FUNC(ASN1_F_D2I_X509),	"D2I_X509"},
 {ERR_FUNC(ASN1_F_D2I_X509_CINF),	"D2I_X509_CINF"},
 {ERR_FUNC(ASN1_F_D2I_X509_PKEY),	"d2i_X509_PKEY"},
+{ERR_FUNC(ASN1_F_I2D_ASN1_BIO_STREAM),	"i2d_ASN1_bio_stream"},
 {ERR_FUNC(ASN1_F_I2D_ASN1_SET),	"i2d_ASN1_SET"},
 {ERR_FUNC(ASN1_F_I2D_ASN1_TIME),	"I2D_ASN1_TIME"},
 {ERR_FUNC(ASN1_F_I2D_DSA_PUBKEY),	"i2d_DSA_PUBKEY"},
@@ -170,8 +176,9 @@
 {ERR_FUNC(ASN1_F_LONG_C2I),	"LONG_C2I"},
 {ERR_FUNC(ASN1_F_OID_MODULE_INIT),	"OID_MODULE_INIT"},
 {ERR_FUNC(ASN1_F_PARSE_TAGGING),	"PARSE_TAGGING"},
-{ERR_FUNC(ASN1_F_PKCS5_PBE2_SET),	"PKCS5_pbe2_set"},
+{ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_IV),	"PKCS5_pbe2_set_iv"},
 {ERR_FUNC(ASN1_F_PKCS5_PBE_SET),	"PKCS5_pbe_set"},
+{ERR_FUNC(ASN1_F_PKCS5_PBE_SET0_ALGOR),	"PKCS5_pbe_set0_algor"},
 {ERR_FUNC(ASN1_F_SMIME_READ_ASN1),	"SMIME_read_ASN1"},
 {ERR_FUNC(ASN1_F_SMIME_TEXT),	"SMIME_text"},
 {ERR_FUNC(ASN1_F_X509_CINF_NEW),	"X509_CINF_NEW"},
@@ -204,6 +211,7 @@
 {ERR_REASON(ASN1_R_DECODE_ERROR)         ,"decode error"},
 {ERR_REASON(ASN1_R_DECODING_ERROR)       ,"decoding error"},
 {ERR_REASON(ASN1_R_DEPTH_EXCEEDED)       ,"depth exceeded"},
+{ERR_REASON(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED),"digest and key type not supported"},
 {ERR_REASON(ASN1_R_ENCODE_ERROR)         ,"encode error"},
 {ERR_REASON(ASN1_R_ERROR_GETTING_TIME)   ,"error getting time"},
 {ERR_REASON(ASN1_R_ERROR_LOADING_SECTION),"error loading section"},
@@ -261,6 +269,7 @@
 {ERR_REASON(ASN1_R_NOT_ASCII_FORMAT)     ,"not ascii format"},
 {ERR_REASON(ASN1_R_NOT_ENOUGH_DATA)      ,"not enough data"},
 {ERR_REASON(ASN1_R_NO_CONTENT_TYPE)      ,"no content type"},
+{ERR_REASON(ASN1_R_NO_DEFAULT_DIGEST)    ,"no default digest"},
 {ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE),"no matching choice type"},
 {ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"},
 {ERR_REASON(ASN1_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"},
@@ -291,6 +300,7 @@
 {ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM),"unknown message digest algorithm"},
 {ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE)  ,"unknown object type"},
 {ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE),"unknown public key type"},
+{ERR_REASON(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM),"unknown signature algorithm"},
 {ERR_REASON(ASN1_R_UNKNOWN_TAG)          ,"unknown tag"},
 {ERR_REASON(ASN1_R_UNKOWN_FORMAT)        ,"unkown format"},
 {ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE),"unsupported any defined by type"},
@@ -298,6 +308,7 @@
 {ERR_REASON(ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM),"unsupported encryption algorithm"},
 {ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE),"unsupported public key type"},
 {ERR_REASON(ASN1_R_UNSUPPORTED_TYPE)     ,"unsupported type"},
+{ERR_REASON(ASN1_R_WRONG_PUBLIC_KEY_TYPE),"wrong public key type"},
 {ERR_REASON(ASN1_R_WRONG_TAG)            ,"wrong tag"},
 {ERR_REASON(ASN1_R_WRONG_TYPE)           ,"wrong type"},
 {0,NULL}
diff --git a/crypto/asn1/asn1_gen.c b/crypto/asn1/asn1_gen.c
index 213a8e9..4fc2419 100644
--- a/crypto/asn1/asn1_gen.c
+++ b/crypto/asn1/asn1_gen.c
@@ -247,8 +247,14 @@
 	/* If IMPLICIT, output tag */
 
 	if (asn1_tags.imp_tag != -1)
+		{
+		if (asn1_tags.imp_class == V_ASN1_UNIVERSAL 
+		    && (asn1_tags.imp_tag == V_ASN1_SEQUENCE
+		     || asn1_tags.imp_tag == V_ASN1_SET) )
+			hdr_constructed = V_ASN1_CONSTRUCTED;
 		ASN1_put_object(&p, hdr_constructed, hdr_len,
 					asn1_tags.imp_tag, asn1_tags.imp_class);
+		}
 
 	/* Copy across original encoding */
 	memcpy(p, cpy_start, cpy_len);
@@ -441,12 +447,12 @@
 
 static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
 	{
-	ASN1_TYPE *ret = NULL, *typ = NULL;
+	ASN1_TYPE *ret = NULL;
 	STACK_OF(ASN1_TYPE) *sk = NULL;
 	STACK_OF(CONF_VALUE) *sect = NULL;
-	unsigned char *der = NULL, *p;
+	unsigned char *der = NULL;
 	int derlen;
-	int i, is_set;
+	int i;
 	sk = sk_ASN1_TYPE_new_null();
 	if (!sk)
 		goto bad;
@@ -459,31 +465,23 @@
 			goto bad;
 		for (i = 0; i < sk_CONF_VALUE_num(sect); i++)
 			{
-			typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
+			ASN1_TYPE *typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
 			if (!typ)
 				goto bad;
 			if (!sk_ASN1_TYPE_push(sk, typ))
 				goto bad;
-			typ = NULL;
 			}
 		}
 
 	/* Now we has a STACK of the components, convert to the correct form */
 
 	if (utype == V_ASN1_SET)
-		is_set = 1;
+		derlen = i2d_ASN1_SET_ANY(sk, &der);
 	else
-		is_set = 0;
+		derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
 
-
-	derlen = i2d_ASN1_SET_OF_ASN1_TYPE(sk, NULL, i2d_ASN1_TYPE, utype,
-					   V_ASN1_UNIVERSAL, is_set);
-	der = OPENSSL_malloc(derlen);
-	if (!der)
+	if (derlen < 0)
 		goto bad;
-	p = der;
-	i2d_ASN1_SET_OF_ASN1_TYPE(sk, &p, i2d_ASN1_TYPE, utype,
-				  V_ASN1_UNIVERSAL, is_set);
 
 	if (!(ret = ASN1_TYPE_new()))
 		goto bad;
@@ -505,8 +503,6 @@
 
 	if (sk)
 		sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
-	if (typ)
-		ASN1_TYPE_free(typ);
 	if (sect)
 		X509V3_section_free(cnf, sect);
 
@@ -556,7 +552,7 @@
 static int asn1_str2tag(const char *tagstr, int len)
 	{
 	unsigned int i;
-	static struct tag_name_st *tntmp, tnst [] = {
+	static const struct tag_name_st *tntmp, tnst [] = {
 		ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN),
 		ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN),
 		ASN1_GEN_STR("NULL", V_ASN1_NULL),
@@ -591,6 +587,8 @@
 		ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING),
 		ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING),
 		ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING),
+		ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING),
+		ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING),
 
 		/* Special cases */
 		ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE),
@@ -736,6 +734,7 @@
 		case V_ASN1_VISIBLESTRING:
 		case V_ASN1_UNIVERSALSTRING:
 		case V_ASN1_GENERALSTRING:
+		case V_ASN1_NUMERICSTRING:
 
 		if (format == ASN1_GEN_FORMAT_ASCII)
 			format = MBSTRING_ASC;
diff --git a/crypto/asn1/asn1_lib.c b/crypto/asn1/asn1_lib.c
index 5af559e..1bcb44a 100644
--- a/crypto/asn1/asn1_lib.c
+++ b/crypto/asn1/asn1_lib.c
@@ -340,20 +340,31 @@
 	return(1);
 	}
 
-ASN1_STRING *ASN1_STRING_dup(ASN1_STRING *str)
+int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
+	{
+	if (str == NULL)
+		return 0;
+	dst->type = str->type;
+	if (!ASN1_STRING_set(dst,str->data,str->length))
+		return 0;
+	dst->flags = str->flags;
+	return 1;
+	}
+
+ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
 	{
 	ASN1_STRING *ret;
-
-	if (str == NULL) return(NULL);
-	if ((ret=ASN1_STRING_type_new(str->type)) == NULL)
-		return(NULL);
-	if (!ASN1_STRING_set(ret,str->data,str->length))
+	if (!str)
+		 return NULL;
+	ret=ASN1_STRING_new();
+	if (!ret)
+		return NULL;
+	if (!ASN1_STRING_copy(ret,str))
 		{
 		ASN1_STRING_free(ret);
-		return(NULL);
+		return NULL;
 		}
-	ret->flags = str->flags;
-	return(ret);
+	return ret;
 	}
 
 int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
@@ -427,11 +438,12 @@
 void ASN1_STRING_free(ASN1_STRING *a)
 	{
 	if (a == NULL) return;
-	if (a->data != NULL) OPENSSL_free(a->data);
+	if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
+		OPENSSL_free(a->data);
 	OPENSSL_free(a);
 	}
 
-int ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b)
+int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
 	{
 	int i;
 
@@ -457,7 +469,7 @@
 	ERR_add_error_data(4,"address=",buf1," offset=",buf2);
 	}
 
-int ASN1_STRING_length(ASN1_STRING *x)
+int ASN1_STRING_length(const ASN1_STRING *x)
 { return M_ASN1_STRING_length(x); }
 
 void ASN1_STRING_length_set(ASN1_STRING *x, int len)
diff --git a/crypto/asn1/asn1_locl.h b/crypto/asn1/asn1_locl.h
new file mode 100644
index 0000000..5aa65e2
--- /dev/null
+++ b/crypto/asn1/asn1_locl.h
@@ -0,0 +1,134 @@
+/* asn1t.h */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Internal ASN1 structures and functions: not for application use */
+
+/* ASN1 print context structure */
+
+struct asn1_pctx_st
+	{
+	unsigned long flags;
+	unsigned long nm_flags;
+	unsigned long cert_flags;
+	unsigned long oid_flags;
+	unsigned long str_flags;
+	} /* ASN1_PCTX */;
+
+/* ASN1 public key method structure */
+
+struct evp_pkey_asn1_method_st
+	{
+	int pkey_id;
+	int pkey_base_id;
+	unsigned long pkey_flags;
+
+	char *pem_str;
+	char *info;
+
+	int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub);
+	int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk);
+	int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
+	int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *pctx);
+
+	int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf);
+	int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk);
+	int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *pctx);
+
+	int (*pkey_size)(const EVP_PKEY *pk);
+	int (*pkey_bits)(const EVP_PKEY *pk);
+
+	int (*param_decode)(EVP_PKEY *pkey,
+				const unsigned char **pder, int derlen);
+	int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder);
+	int (*param_missing)(const EVP_PKEY *pk);
+	int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
+	int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
+	int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *pctx);
+
+	void (*pkey_free)(EVP_PKEY *pkey);
+	int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
+
+	/* Legacy functions for old PEM */
+
+	int (*old_priv_decode)(EVP_PKEY *pkey,
+				const unsigned char **pder, int derlen);
+	int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
+
+	} /* EVP_PKEY_ASN1_METHOD */;
+
+/* Method to handle CRL access.
+ * In general a CRL could be very large (several Mb) and can consume large
+ * amounts of resources if stored in memory by multiple processes.
+ * This method allows general CRL operations to be redirected to more
+ * efficient callbacks: for example a CRL entry database.
+ */
+
+#define X509_CRL_METHOD_DYNAMIC		1
+
+struct x509_crl_method_st
+	{
+	int flags;
+	int (*crl_init)(X509_CRL *crl);
+	int (*crl_free)(X509_CRL *crl);
+	int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
+				ASN1_INTEGER *ser, X509_NAME *issuer);
+	int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk);
+	};
diff --git a/crypto/asn1/asn1_mac.h b/crypto/asn1/asn1_mac.h
index d958ca6..87bd0e9 100644
--- a/crypto/asn1/asn1_mac.h
+++ b/crypto/asn1/asn1_mac.h
@@ -153,6 +153,13 @@
 		M_ASN1_D2I_get(b,func); \
 		}
 
+#define M_ASN1_D2I_get_int_opt(b,func,type) \
+	if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \
+		== (V_ASN1_UNIVERSAL|(type)))) \
+		{ \
+		M_ASN1_D2I_get_int(b,func); \
+		}
+
 #define M_ASN1_D2I_get_imp(b,func, type) \
 	M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \
 	c.q=c.p; \
diff --git a/crypto/asn1/asn1_par.c b/crypto/asn1/asn1_par.c
index cb08e15..aaca69a 100644
--- a/crypto/asn1/asn1_par.c
+++ b/crypto/asn1/asn1_par.c
@@ -70,9 +70,8 @@
 	     int indent)
 	{
 	static const char fmt[]="%-18s";
-	static const char fmt2[]="%2d %-15s";
 	char str[128];
-	const char *p,*p2=NULL;
+	const char *p;
 
 	if (constructed & V_ASN1_CONSTRUCTED)
 		p="cons: ";
@@ -93,14 +92,8 @@
 	else
 		p = ASN1_tag2str(tag);
 
-	if (p2 != NULL)
-		{
-		if (BIO_printf(bp,fmt2,tag,p2) <= 0) goto err;
-		}
-	else
-		{
-		if (BIO_printf(bp,fmt,p) <= 0) goto err;
-		}
+	if (BIO_printf(bp,fmt,p) <= 0)
+		goto err;
 	return(1);
 err:
 	return(0);
@@ -424,7 +417,7 @@
 
 const char *ASN1_tag2str(int tag)
 {
-	static const char *tag2str[] = {
+	static const char * const tag2str[] = {
 	 "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
 	 "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
 	 "ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>", 	    /* 10-13 */
diff --git a/crypto/asn1/asn1t.h b/crypto/asn1/asn1t.h
index ac14f94..d230e4b 100644
--- a/crypto/asn1/asn1t.h
+++ b/crypto/asn1/asn1t.h
@@ -3,7 +3,7 @@
  * project 2000.
  */
 /* ====================================================================
- * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 2000-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
@@ -218,6 +218,18 @@
 		#stname \
 	ASN1_ITEM_end(tname)
 
+#define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_NDEF_SEQUENCE,\
+		V_ASN1_SEQUENCE,\
+		tname##_seq_tt,\
+		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+		&tname##_aux,\
+		sizeof(stname),\
+		#stname \
+	ASN1_ITEM_end(tname)
+
 
 /* This pair helps declare a CHOICE type. We can do:
  *
@@ -651,8 +663,13 @@
 typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
 typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
 
+typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval, 
+						int indent, const char *fname, 
+						const ASN1_PCTX *pctx);
+
 typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
 typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
+typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
 
 typedef struct ASN1_COMPAT_FUNCS_st {
 	ASN1_new_func *asn1_new;
@@ -668,6 +685,7 @@
 	ASN1_ex_free_func *asn1_ex_clear;
 	ASN1_ex_d2i *asn1_ex_d2i;
 	ASN1_ex_i2d *asn1_ex_i2d;
+	ASN1_ex_print_func *asn1_ex_print;
 } ASN1_EXTERN_FUNCS;
 
 typedef struct ASN1_PRIMITIVE_FUNCS_st {
@@ -678,6 +696,7 @@
 	ASN1_ex_free_func *prim_clear;
 	ASN1_primitive_c2i *prim_c2i;
 	ASN1_primitive_i2c *prim_i2c;
+	ASN1_primitive_print *prim_print;
 } ASN1_PRIMITIVE_FUNCS;
 
 /* This is the ASN1_AUX structure: it handles various
@@ -697,7 +716,8 @@
  * then an external type is more appropriate.
  */
 
-typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it);
+typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it,
+				void *exarg);
 
 typedef struct ASN1_AUX_st {
 	void *app_data;
@@ -708,6 +728,23 @@
 	int enc_offset;		/* Offset of ASN1_ENCODING structure */
 } ASN1_AUX;
 
+/* For print related callbacks exarg points to this structure */
+typedef struct ASN1_PRINT_ARG_st {
+	BIO *out;
+	int indent;
+	const ASN1_PCTX *pctx;
+} ASN1_PRINT_ARG;
+
+/* For streaming related callbacks exarg points to this structure */
+typedef struct ASN1_STREAM_ARG_st {
+	/* BIO to stream through */
+	BIO *out;
+	/* BIO with filters appended */
+	BIO *ndef_bio;
+	/* Streaming I/O boundary */
+	unsigned char **boundary;
+} ASN1_STREAM_ARG;
+
 /* Flags in ASN1_AUX */
 
 /* Use a reference count */
@@ -727,6 +764,12 @@
 #define ASN1_OP_D2I_POST	5
 #define ASN1_OP_I2D_PRE		6
 #define ASN1_OP_I2D_POST	7
+#define ASN1_OP_PRINT_PRE	8
+#define ASN1_OP_PRINT_POST	9
+#define ASN1_OP_STREAM_PRE	10
+#define ASN1_OP_STREAM_POST	11
+#define ASN1_OP_DETACHED_PRE	12
+#define ASN1_OP_DETACHED_POST	13
 
 /* Macro to implement a primitive type */
 #define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)
@@ -782,9 +825,22 @@
 #define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \
 			IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)
 
+#define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \
+		IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname)
+
 #define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \
 		IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)
 
+#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \
+	pre stname *fname##_new(void) \
+	{ \
+		return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
+	} \
+	pre void fname##_free(stname *a) \
+	{ \
+		ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
+	}
+
 #define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \
 	stname *fname##_new(void) \
 	{ \
@@ -834,6 +890,17 @@
         return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \
         }
 
+#define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \
+	IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname)
+
+#define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \
+	int fname##_print_ctx(BIO *out, stname *x, int indent, \
+						const ASN1_PCTX *pctx) \
+	{ \
+		return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \
+			ASN1_ITEM_rptr(itname), pctx); \
+	} 
+
 #define IMPLEMENT_ASN1_FUNCTIONS_const(name) \
 		IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)
 
diff --git a/crypto/asn1/asn_mime.c b/crypto/asn1/asn_mime.c
index d8d9e76..c1d1b12 100644
--- a/crypto/asn1/asn_mime.c
+++ b/crypto/asn1/asn_mime.c
@@ -59,6 +59,7 @@
 #include <openssl/x509.h>
 #include <openssl/asn1.h>
 #include <openssl/asn1t.h>
+#include "asn1_locl.h"
 
 /* Generalised MIME like utilities for streaming ASN1. Although many
  * have a PKCS7/CMS like flavour others are more general purpose.
@@ -86,6 +87,8 @@
 DECLARE_STACK_OF(MIME_HEADER)
 IMPLEMENT_STACK_OF(MIME_HEADER)
 
+static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
+					const ASN1_ITEM *it);
 static char * strip_ends(char *name);
 static char * strip_start(char *name);
 static char * strip_end(char *name);
@@ -107,6 +110,39 @@
 #define MAX_SMLEN 1024
 #define mime_debug(x) /* x */
 
+/* Output an ASN1 structure in BER format streaming if necessary */
+
+int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+				const ASN1_ITEM *it)
+	{
+	/* If streaming create stream BIO and copy all content through it */
+	if (flags & SMIME_STREAM)
+		{
+		BIO *bio, *tbio;
+		bio = BIO_new_NDEF(out, val, it);
+		if (!bio)
+			{
+			ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM,ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		SMIME_crlf_copy(in, bio, flags);
+		(void)BIO_flush(bio);
+		/* Free up successive BIOs until we hit the old output BIO */
+		do
+			{
+			tbio = BIO_pop(bio);
+			BIO_free(bio);
+			bio = tbio;
+			} while (bio != out);
+		}
+	/* else just write out ASN1 structure which will have all content
+	 * stored internally
+	 */
+	else
+		ASN1_item_i2d_bio(it, out, val);
+	return 1;
+	}
+
 /* Base 64 read and write of ASN1 structure */
 
 static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
@@ -123,13 +159,26 @@
 	/* prepend the b64 BIO so all data is base64 encoded.
 	 */
 	out = BIO_push(b64, out);
-	r = ASN1_item_i2d_bio(it, out, val);
+	r = i2d_ASN1_bio_stream(out, val, in, flags, it);
 	(void)BIO_flush(out);
 	BIO_pop(out);
 	BIO_free(b64);
 	return r;
 	}
 
+/* Streaming ASN1 PEM write */
+
+int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+				const char *hdr,
+				const ASN1_ITEM *it)
+	{
+	int r;
+	BIO_printf(out, "-----BEGIN %s-----\n", hdr);
+	r = B64_write_ASN1(out, val, in, flags, it);
+	BIO_printf(out, "-----END %s-----\n", hdr);
+	return r;
+	}
+
 static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
 {
 	BIO *b64;
@@ -152,7 +201,8 @@
 
 static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
 	{
-	int i, have_unknown = 0, write_comma, md_nid;
+	const EVP_MD *md;
+	int i, have_unknown = 0, write_comma, ret = 0, md_nid;
 	have_unknown = 0;
 	write_comma = 0;
 	for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++)
@@ -161,6 +211,21 @@
 			BIO_write(out, ",", 1);
 		write_comma = 1;
 		md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm);
+		md = EVP_get_digestbynid(md_nid);
+		if (md && md->md_ctrl)
+			{
+			int rv;
+			char *micstr;
+			rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr);
+			if (rv > 0)
+				{
+				BIO_puts(out, micstr);
+				OPENSSL_free(micstr);
+				continue;
+				}
+			if (rv != -2)
+				goto err;
+			}
 		switch(md_nid)
 			{
 			case NID_sha1:
@@ -183,6 +248,11 @@
 			BIO_puts(out, "sha-512");
 			break;
 
+			case NID_id_GostR3411_94:
+			BIO_puts(out, "gostr3411-94");
+				goto err;
+			break;
+
 			default:
 			if (have_unknown)
 				write_comma = 0;
@@ -196,16 +266,18 @@
 			}
 		}
 
-	return 1;
+	ret = 1;
+	err:
+
+	return ret;
 
 	}
 
 /* SMIME sender */
 
-int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
+int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
 				int ctype_nid, int econt_nid,
 				STACK_OF(X509_ALGOR) *mdalgs,
-				asn1_output_data_fn *data_fn,
 				const ASN1_ITEM *it)
 {
 	char bound[33], c;
@@ -243,7 +315,7 @@
 						mime_eol, mime_eol);
 		/* Now write out the first part */
 		BIO_printf(bio, "------%s%s", bound, mime_eol);
-		if (!data_fn(bio, data, val, flags, it))
+		if (!asn1_output_data(bio, data, val, flags, it))
 			return 0;
 		BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
 
@@ -296,8 +368,6 @@
 	return 1;
 }
 
-#if 0
-
 /* Handle output of ASN1 data */
 
 
@@ -350,8 +420,6 @@
 
 	}
 
-#endif
-
 /* SMIME reader: handle multipart/signed and opaque signing.
  * in multipart case the content is placed in a memory BIO
  * pointed to by "bcont". In opaque this is set to NULL
diff --git a/crypto/asn1/asn_pack.c b/crypto/asn1/asn_pack.c
index f1a5a05..ad73821 100644
--- a/crypto/asn1/asn_pack.c
+++ b/crypto/asn1/asn_pack.c
@@ -66,10 +66,10 @@
 
 /* Turn an ASN1 encoded SEQUENCE OF into a STACK of structures */
 
-STACK *ASN1_seq_unpack(const unsigned char *buf, int len,
-		       d2i_of_void *d2i,void (*free_func)(void *))
+STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
+			 d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK))
 {
-    STACK *sk;
+    STACK_OF(OPENSSL_BLOCK) *sk;
     const unsigned char *pbuf;
     pbuf =  buf;
     if (!(sk = d2i_ASN1_SET(NULL, &pbuf, len, d2i, free_func,
@@ -82,7 +82,7 @@
  * OPENSSL_malloc'ed buffer
  */
 
-unsigned char *ASN1_seq_pack(STACK *safes, i2d_of_void *i2d,
+unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
 			     unsigned char **buf, int *len)
 {
 	int safelen;
diff --git a/crypto/asn1/bio_asn1.c b/crypto/asn1/bio_asn1.c
new file mode 100644
index 0000000..dc7efd5
--- /dev/null
+++ b/crypto/asn1/bio_asn1.c
@@ -0,0 +1,495 @@
+/* bio_asn1.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Experimental ASN1 BIO. When written through the data is converted
+ * to an ASN1 string type: default is OCTET STRING. Additional functions
+ * can be provided to add prefix and suffix data.
+ */
+
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+
+/* Must be large enough for biggest tag+length */
+#define DEFAULT_ASN1_BUF_SIZE 20
+
+typedef enum 
+	{
+	ASN1_STATE_START,
+	ASN1_STATE_PRE_COPY,
+	ASN1_STATE_HEADER,
+	ASN1_STATE_HEADER_COPY,
+	ASN1_STATE_DATA_COPY,
+	ASN1_STATE_POST_COPY,
+	ASN1_STATE_DONE
+	} asn1_bio_state_t;
+
+typedef struct BIO_ASN1_EX_FUNCS_st
+	{
+	asn1_ps_func	*ex_func;
+	asn1_ps_func	*ex_free_func;
+	} BIO_ASN1_EX_FUNCS;
+
+typedef struct BIO_ASN1_BUF_CTX_t
+	{
+	/* Internal state */
+	asn1_bio_state_t state;
+	/* Internal buffer */
+	unsigned char *buf;
+	/* Size of buffer */
+	int bufsize;
+	/* Current position in buffer */
+	int bufpos;
+	/* Current buffer length */
+	int buflen;
+	/* Amount of data to copy */
+	int copylen;
+	/* Class and tag to use */
+	int asn1_class, asn1_tag;
+	asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
+	/* Extra buffer for prefix and suffix data */
+	unsigned char *ex_buf;
+	int ex_len;
+	int ex_pos;
+	void *ex_arg;
+	} BIO_ASN1_BUF_CTX;
+
+
+static int asn1_bio_write(BIO *h, const char *buf,int num);
+static int asn1_bio_read(BIO *h, char *buf, int size);
+static int asn1_bio_puts(BIO *h, const char *str);
+static int asn1_bio_gets(BIO *h, char *str, int size);
+static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int asn1_bio_new(BIO *h);
+static int asn1_bio_free(BIO *data);
+static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
+static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+				asn1_ps_func *cleanup, asn1_bio_state_t next);
+static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+				asn1_ps_func *setup, 
+				asn1_bio_state_t ex_state,
+				asn1_bio_state_t other_state);
+
+static BIO_METHOD methods_asn1=
+	{
+	BIO_TYPE_ASN1,
+	"asn1",
+	asn1_bio_write,
+	asn1_bio_read,
+	asn1_bio_puts,
+	asn1_bio_gets,
+	asn1_bio_ctrl,
+	asn1_bio_new,
+	asn1_bio_free,
+	asn1_bio_callback_ctrl,
+	};
+
+BIO_METHOD *BIO_f_asn1(void)
+	{
+	return(&methods_asn1);
+	}
+
+
+static int asn1_bio_new(BIO *b)
+	{
+	BIO_ASN1_BUF_CTX *ctx;
+	ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX));
+	if (!ctx)
+		return 0;
+	if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE))
+		return 0;
+	b->init = 1;
+	b->ptr = (char *)ctx;
+	b->flags = 0;
+	return 1;
+	}
+
+static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
+	{
+	ctx->buf = OPENSSL_malloc(size);
+	if (!ctx->buf)
+		return 0;
+	ctx->bufsize = size;
+	ctx->bufpos = 0;
+	ctx->buflen = 0;
+	ctx->copylen = 0;
+	ctx->asn1_class = V_ASN1_UNIVERSAL;
+	ctx->asn1_tag = V_ASN1_OCTET_STRING;
+	ctx->ex_buf = 0;
+	ctx->ex_pos = 0;
+	ctx->ex_len = 0;
+	ctx->state = ASN1_STATE_START;
+	return 1;
+	}
+
+static int asn1_bio_free(BIO *b)
+	{
+	BIO_ASN1_BUF_CTX *ctx;
+	ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
+	if (ctx == NULL)
+		return 0;
+	if (ctx->buf)
+		OPENSSL_free(ctx->buf);
+	OPENSSL_free(ctx);
+	b->init = 0;
+	b->ptr = NULL;
+	b->flags = 0;
+	return 1;
+	}
+
+static int asn1_bio_write(BIO *b, const char *in , int inl)
+	{
+	BIO_ASN1_BUF_CTX *ctx;
+	int wrmax, wrlen, ret;
+	unsigned char *p;
+	if (!in || (inl < 0) || (b->next_bio == NULL))
+		return 0;
+	ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
+	if (ctx == NULL)
+		return 0;
+
+	wrlen = 0;
+	ret = -1;
+
+	for(;;)
+		{
+		switch (ctx->state)
+			{
+
+			/* Setup prefix data, call it */
+			case ASN1_STATE_START:
+			if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
+				ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
+				return 0;
+			break;
+
+			/* Copy any pre data first */
+			case ASN1_STATE_PRE_COPY:
+
+			ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
+							ASN1_STATE_HEADER);
+
+			if (ret <= 0)
+				goto done;
+
+			break;
+
+			case ASN1_STATE_HEADER:
+			ctx->buflen =
+				ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
+			OPENSSL_assert(ctx->buflen <= ctx->bufsize);
+			p = ctx->buf;
+			ASN1_put_object(&p, 0, inl,
+					ctx->asn1_tag, ctx->asn1_class);
+			ctx->copylen = inl;
+			ctx->state = ASN1_STATE_HEADER_COPY;
+
+			break;
+
+			case ASN1_STATE_HEADER_COPY:	
+			ret = BIO_write(b->next_bio,
+					ctx->buf + ctx->bufpos, ctx->buflen);
+			if (ret <= 0)
+				goto done;
+
+			ctx->buflen -= ret;
+			if (ctx->buflen)
+				ctx->bufpos += ret;
+			else
+				{
+				ctx->bufpos = 0;
+				ctx->state = ASN1_STATE_DATA_COPY;
+				}
+
+			break;
+
+			case ASN1_STATE_DATA_COPY:
+
+			if (inl > ctx->copylen)
+				wrmax = ctx->copylen;
+			else
+				wrmax = inl;
+			ret = BIO_write(b->next_bio, in, wrmax);
+			if (ret <= 0)
+				break;
+			wrlen += ret;
+			ctx->copylen -= ret;
+			in += ret;
+			inl -= ret;
+
+			if (ctx->copylen == 0)
+				ctx->state = ASN1_STATE_HEADER;
+
+			if (inl == 0)
+				goto done;
+
+			break;
+
+			default:
+			BIO_clear_retry_flags(b);
+			return 0;
+
+			}
+
+		}
+
+	done:
+	BIO_clear_retry_flags(b);
+	BIO_copy_next_retry(b);
+
+	return (wrlen > 0) ? wrlen : ret;
+
+	}
+
+static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+				asn1_ps_func *cleanup, asn1_bio_state_t next)
+	{
+	int ret;
+	if (ctx->ex_len <= 0)
+		return 1;
+	for(;;)
+		{
+		ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos,
+								ctx->ex_len);
+		if (ret <= 0)
+			break;
+		ctx->ex_len -= ret;
+		if (ctx->ex_len > 0)
+			ctx->ex_pos += ret;
+		else
+			{
+			if(cleanup)
+				cleanup(b, &ctx->ex_buf, &ctx->ex_len,
+								&ctx->ex_arg);
+			ctx->state = next;
+			ctx->ex_pos = 0;
+			break;
+			}
+		}
+	return ret;
+	}
+
+static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+				asn1_ps_func *setup, 
+				asn1_bio_state_t ex_state,
+				asn1_bio_state_t other_state)
+	{
+	if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg))
+		{
+		BIO_clear_retry_flags(b);
+		return 0;
+		}
+	if (ctx->ex_len > 0)
+		ctx->state = ex_state;
+	else
+		ctx->state = other_state;
+	return 1;
+	}
+
+static int asn1_bio_read(BIO *b, char *in , int inl)
+	{
+	if (!b->next_bio)
+		return 0;
+	return BIO_read(b->next_bio, in , inl);
+	}
+
+static int asn1_bio_puts(BIO *b, const char *str)
+	{
+	return asn1_bio_write(b, str, strlen(str));
+	}
+
+static int asn1_bio_gets(BIO *b, char *str, int size)
+	{
+	if (!b->next_bio)
+		return 0;
+	return BIO_gets(b->next_bio, str , size);
+	}
+
+static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+	{
+	if (b->next_bio == NULL) return(0);
+	return BIO_callback_ctrl(b->next_bio,cmd,fp);
+	}
+
+static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
+	{
+	BIO_ASN1_BUF_CTX *ctx;
+	BIO_ASN1_EX_FUNCS *ex_func;
+	long ret = 1;
+	ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
+	if (ctx == NULL)
+		return 0;
+	switch(cmd)
+		{
+
+		case BIO_C_SET_PREFIX:
+		ex_func = arg2;
+		ctx->prefix  = ex_func->ex_func;
+		ctx->prefix_free  = ex_func->ex_free_func;
+		break;
+
+		case BIO_C_GET_PREFIX:
+		ex_func = arg2;
+		ex_func->ex_func = ctx->prefix;
+		ex_func->ex_free_func = ctx->prefix_free;
+		break;
+
+		case BIO_C_SET_SUFFIX:
+		ex_func = arg2;
+		ctx->suffix  = ex_func->ex_func;
+		ctx->suffix_free  = ex_func->ex_free_func;
+		break;
+
+		case BIO_C_GET_SUFFIX:
+		ex_func = arg2;
+		ex_func->ex_func = ctx->suffix;
+		ex_func->ex_free_func = ctx->suffix_free;
+		break;
+
+		case BIO_C_SET_EX_ARG:
+		ctx->ex_arg = arg2;
+		break;
+
+		case BIO_C_GET_EX_ARG:
+		*(void **)arg2 = ctx->ex_arg;
+		break;
+
+		case BIO_CTRL_FLUSH:
+		if (!b->next_bio)
+			return 0;
+
+		/* Call post function if possible */
+		if (ctx->state == ASN1_STATE_HEADER)
+			{
+			if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
+				ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
+				return 0;
+			}
+
+		if (ctx->state == ASN1_STATE_POST_COPY)
+			{
+			ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
+							ASN1_STATE_DONE);
+			if (ret <= 0)
+				return ret;
+			}
+
+		if (ctx->state == ASN1_STATE_DONE)
+			return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
+		else
+			{
+			BIO_clear_retry_flags(b);
+			return 0;
+			}
+		break;
+
+
+		default:
+		if (!b->next_bio)
+			return 0;
+		return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
+
+		}
+
+	return ret;
+	}
+
+static int asn1_bio_set_ex(BIO *b, int cmd,
+		asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
+	{
+	BIO_ASN1_EX_FUNCS extmp;
+	extmp.ex_func = ex_func;
+	extmp.ex_free_func = ex_free_func;
+	return BIO_ctrl(b, cmd, 0, &extmp);
+	}
+
+static int asn1_bio_get_ex(BIO *b, int cmd,
+		asn1_ps_func **ex_func, asn1_ps_func **ex_free_func)
+	{
+	BIO_ASN1_EX_FUNCS extmp;
+	int ret;
+	ret = BIO_ctrl(b, cmd, 0, &extmp);
+	if (ret > 0)
+		{
+		*ex_func = extmp.ex_func;
+		*ex_free_func = extmp.ex_free_func;
+		}
+	return ret;
+	}
+
+int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, asn1_ps_func *prefix_free)
+	{
+	return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
+	}
+
+int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, asn1_ps_func **pprefix_free)
+	{
+	return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
+	}
+
+int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, asn1_ps_func *suffix_free)
+	{
+	return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
+	}
+
+int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_func **psuffix_free)
+	{
+	return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
+	}
diff --git a/crypto/asn1/bio_ndef.c b/crypto/asn1/bio_ndef.c
new file mode 100644
index 0000000..370389b
--- /dev/null
+++ b/crypto/asn1/bio_ndef.c
@@ -0,0 +1,246 @@
+/* bio_ndef.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+
+#ifndef OPENSSL_SYSNAME_NETWARE
+#include <memory.h>
+#endif
+#include <stdio.h>
+
+/* Experimental NDEF ASN1 BIO support routines */
+
+/* The usage is quite simple, initialize an ASN1 structure,
+ * get a BIO from it then any data written through the BIO
+ * will end up translated to approptiate format on the fly.
+ * The data is streamed out and does *not* need to be
+ * all held in memory at once.
+ *
+ * When the BIO is flushed the output is finalized and any
+ * signatures etc written out.
+ *
+ * The BIO is a 'proper' BIO and can handle non blocking I/O
+ * correctly.
+ *
+ * The usage is simple. The implementation is *not*...
+ */
+
+/* BIO support data stored in the ASN1 BIO ex_arg */
+
+typedef struct ndef_aux_st
+	{
+	/* ASN1 structure this BIO refers to */
+	ASN1_VALUE *val;
+	const ASN1_ITEM *it;
+	/* Top of the BIO chain */
+	BIO *ndef_bio;
+	/* Output BIO */
+	BIO *out;
+	/* Boundary where content is inserted */
+	unsigned char **boundary;
+	/* DER buffer start */
+	unsigned char *derbuf;
+	} NDEF_SUPPORT;
+
+static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+
+BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
+	{
+	NDEF_SUPPORT *ndef_aux = NULL;
+	BIO *asn_bio = NULL;
+	const ASN1_AUX *aux = it->funcs;
+	ASN1_STREAM_ARG sarg;
+
+	if (!aux || !aux->asn1_cb)
+		{
+		ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
+		return NULL;
+		}
+	ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
+	asn_bio = BIO_new(BIO_f_asn1());
+
+	/* ASN1 bio needs to be next to output BIO */
+
+	out = BIO_push(asn_bio, out);
+
+	if (!ndef_aux || !asn_bio || !out)
+		goto err;
+
+	BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
+	BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
+
+	/* Now let callback prepend any digest, cipher etc BIOs
+	 * ASN1 structure needs.
+	 */
+
+	sarg.out = out;
+	sarg.ndef_bio = NULL;
+	sarg.boundary = NULL;
+
+	if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
+		goto err;
+
+	ndef_aux->val = val;
+	ndef_aux->it = it;
+	ndef_aux->ndef_bio = sarg.ndef_bio;
+	ndef_aux->boundary = sarg.boundary;
+	ndef_aux->out = out;
+
+	BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
+
+	return sarg.ndef_bio;
+
+	err:
+	if (asn_bio)
+		BIO_free(asn_bio);
+	if (ndef_aux)
+		OPENSSL_free(ndef_aux);
+	return NULL;
+	}
+
+static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+	{
+	NDEF_SUPPORT *ndef_aux;
+	unsigned char *p;
+	int derlen;
+
+	if (!parg)
+		return 0;
+
+	ndef_aux = *(NDEF_SUPPORT **)parg;
+
+	derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+	p = OPENSSL_malloc(derlen);
+	ndef_aux->derbuf = p;
+	*pbuf = p;
+	derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+
+	if (!*ndef_aux->boundary)
+		return 0;
+
+	*plen = *ndef_aux->boundary - *pbuf;
+
+	return 1;
+	}
+
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+	{
+	NDEF_SUPPORT *ndef_aux;
+
+	if (!parg)
+		return 0;
+
+	ndef_aux = *(NDEF_SUPPORT **)parg;
+
+	if (ndef_aux->derbuf)
+		OPENSSL_free(ndef_aux->derbuf);
+
+	ndef_aux->derbuf = NULL;
+	*pbuf = NULL;
+	*plen = 0;
+	return 1;
+	}
+
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+	{
+	NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
+	if (!ndef_prefix_free(b, pbuf, plen, parg))
+		return 0;
+	OPENSSL_free(*pndef_aux);
+	*pndef_aux = NULL;
+	return 1;
+	}
+
+static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+	{
+	NDEF_SUPPORT *ndef_aux;
+	unsigned char *p;
+	int derlen;
+	const ASN1_AUX *aux;
+	ASN1_STREAM_ARG sarg;
+
+	if (!parg)
+		return 0;
+
+	ndef_aux = *(NDEF_SUPPORT **)parg;
+
+	aux = ndef_aux->it->funcs;
+
+	/* Finalize structures */
+	sarg.ndef_bio = ndef_aux->ndef_bio;
+	sarg.out = ndef_aux->out;
+	sarg.boundary = ndef_aux->boundary;
+	if (aux->asn1_cb(ASN1_OP_STREAM_POST,
+				&ndef_aux->val, ndef_aux->it, &sarg) <= 0)
+		return 0;
+
+	derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+	p = OPENSSL_malloc(derlen);
+	ndef_aux->derbuf = p;
+	*pbuf = p;
+	derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+
+	if (!*ndef_aux->boundary)
+		return 0;
+	*pbuf = *ndef_aux->boundary;
+	*plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
+
+	return 1;
+	}
diff --git a/crypto/asn1/charmap.h b/crypto/asn1/charmap.h
index bd020a9..b55e638 100644
--- a/crypto/asn1/charmap.h
+++ b/crypto/asn1/charmap.h
@@ -2,7 +2,7 @@
  * Mask of various character properties
  */
 
-static unsigned char char_type[] = {
+static const unsigned char char_type[] = {
  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 120, 0, 1,40, 0, 0, 0,16,16,16, 0,25,25,16,16,16,
diff --git a/crypto/asn1/d2i_pr.c b/crypto/asn1/d2i_pr.c
index 207ccda..2828944 100644
--- a/crypto/asn1/d2i_pr.c
+++ b/crypto/asn1/d2i_pr.c
@@ -61,16 +61,12 @@
 #include <openssl/bn.h>
 #include <openssl/evp.h>
 #include <openssl/objects.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/x509.h>
 #include <openssl/asn1.h>
-#ifndef OPENSSL_NO_RSA
-#include <openssl/rsa.h>
-#endif
-#ifndef OPENSSL_NO_DSA
-#include <openssl/dsa.h>
-#endif
-#ifndef OPENSSL_NO_EC
-#include <openssl/ec.h>
-#endif
+#include "asn1_locl.h"
 
 EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
 	     long length)
@@ -85,47 +81,43 @@
 			return(NULL);
 			}
 		}
-	else	ret= *a;
-
-	ret->save_type=type;
-	ret->type=EVP_PKEY_type(type);
-	switch (ret->type)
+	else
 		{
-#ifndef OPENSSL_NO_RSA
-	case EVP_PKEY_RSA:
-		if ((ret->pkey.rsa=d2i_RSAPrivateKey(NULL,
-			(const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */
+		ret= *a;
+#ifndef OPENSSL_NO_ENGINE
+		if (ret->engine)
 			{
-			ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB);
-			goto err;
+			ENGINE_finish(ret->engine);
+			ret->engine = NULL;
 			}
-		break;
 #endif
-#ifndef OPENSSL_NO_DSA
-	case EVP_PKEY_DSA:
-		if ((ret->pkey.dsa=d2i_DSAPrivateKey(NULL,
-			(const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */
-			{
-			ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB);
-			goto err;
-			}
-		break;
-#endif
-#ifndef OPENSSL_NO_EC
-	case EVP_PKEY_EC:
-		if ((ret->pkey.ec = d2i_ECPrivateKey(NULL, 
-			(const unsigned char **)pp, length)) == NULL)
-			{
-			ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
-			goto err;
-			}
-		break;
-#endif
-	default:
+		}
+
+	if (!EVP_PKEY_set_type(ret, type))
+		{
 		ASN1err(ASN1_F_D2I_PRIVATEKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
 		goto err;
-		/* break; */
 		}
+
+	if (!ret->ameth->old_priv_decode ||
+			!ret->ameth->old_priv_decode(ret, pp, length))
+		{
+		if (ret->ameth->priv_decode) 
+			{
+			PKCS8_PRIV_KEY_INFO *p8=NULL;
+			p8=d2i_PKCS8_PRIV_KEY_INFO(NULL,pp,length);
+			if (!p8) goto err;
+			EVP_PKEY_free(ret);
+			ret = EVP_PKCS82PKEY(p8);
+			PKCS8_PRIV_KEY_INFO_free(p8);
+
+			} 
+		else 
+			{
+			ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB);
+			goto err;
+			}
+		}	
 	if (a != NULL) (*a)=ret;
 	return(ret);
 err:
@@ -146,8 +138,7 @@
 	 * by analyzing it we can determine the passed structure: this
 	 * assumes the input is surrounded by an ASN1 SEQUENCE.
 	 */
-	inkey = d2i_ASN1_SET_OF_ASN1_TYPE(NULL, &p, length, d2i_ASN1_TYPE, 
-			ASN1_TYPE_free, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
+	inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
 	/* Since we only need to discern "traditional format" RSA and DSA
 	 * keys we can just count the elements.
          */
@@ -155,6 +146,24 @@
 		keytype = EVP_PKEY_DSA;
 	else if (sk_ASN1_TYPE_num(inkey) == 4)
 		keytype = EVP_PKEY_EC;
+	else if (sk_ASN1_TYPE_num(inkey) == 3)  
+		{ /* This seems to be PKCS8, not traditional format */
+			PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL,pp,length);
+			EVP_PKEY *ret;
+
+			sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
+			if (!p8) 
+				{
+				ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+				return NULL;
+				}
+			ret = EVP_PKCS82PKEY(p8);
+			PKCS8_PRIV_KEY_INFO_free(p8);
+			if (a) {
+				*a = ret;
+			}	
+			return ret;
+		}
 	else keytype = EVP_PKEY_RSA;
 	sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
 	return d2i_PrivateKey(keytype, a, pp, length);
diff --git a/crypto/asn1/d2i_pu.c b/crypto/asn1/d2i_pu.c
index 3694f51..c8f39ce 100644
--- a/crypto/asn1/d2i_pu.c
+++ b/crypto/asn1/d2i_pu.c
@@ -87,9 +87,13 @@
 		}
 	else	ret= *a;
 
-	ret->save_type=type;
-	ret->type=EVP_PKEY_type(type);
-	switch (ret->type)
+	if (!EVP_PKEY_set_type(ret, type))
+		{
+		ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_EVP_LIB);
+		goto err;
+		}
+
+	switch (EVP_PKEY_id(ret))
 		{
 #ifndef OPENSSL_NO_RSA
 	case EVP_PKEY_RSA:
diff --git a/crypto/asn1/i2d_pr.c b/crypto/asn1/i2d_pr.c
index 0be52c5..e398b62 100644
--- a/crypto/asn1/i2d_pr.c
+++ b/crypto/asn1/i2d_pr.c
@@ -58,41 +58,22 @@
 
 #include <stdio.h>
 #include "cryptlib.h"
-#include <openssl/bn.h>
 #include <openssl/evp.h>
-#include <openssl/objects.h>
-#ifndef OPENSSL_NO_RSA
-#include <openssl/rsa.h>
-#endif
-#ifndef OPENSSL_NO_DSA
-#include <openssl/dsa.h>
-#endif
-#ifndef OPENSSL_NO_EC
-#include <openssl/ec.h>
-#endif
+#include <openssl/x509.h>
+#include "asn1_locl.h"
 
 int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
 	{
-#ifndef OPENSSL_NO_RSA
-	if (a->type == EVP_PKEY_RSA)
+	if (a->ameth && a->ameth->old_priv_encode)
 		{
-		return(i2d_RSAPrivateKey(a->pkey.rsa,pp));
+		return a->ameth->old_priv_encode(a, pp);
 		}
-	else
-#endif
-#ifndef OPENSSL_NO_DSA
-	if (a->type == EVP_PKEY_DSA)
-		{
-		return(i2d_DSAPrivateKey(a->pkey.dsa,pp));
-		}
-#endif
-#ifndef OPENSSL_NO_EC
-	if (a->type == EVP_PKEY_EC)
-		{
-		return(i2d_ECPrivateKey(a->pkey.ec, pp));
-		}
-#endif
-
+	if (a->ameth && a->ameth->priv_encode) {
+		PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
+		int ret = i2d_PKCS8_PRIV_KEY_INFO(p8,pp);
+		PKCS8_PRIV_KEY_INFO_free(p8);
+		return ret;
+	}	
 	ASN1err(ASN1_F_I2D_PRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
 	return(-1);
 	}
diff --git a/crypto/asn1/nsseq.c b/crypto/asn1/nsseq.c
index e551c57..b8c4202 100644
--- a/crypto/asn1/nsseq.c
+++ b/crypto/asn1/nsseq.c
@@ -3,7 +3,7 @@
  * project 1999.
  */
 /* ====================================================================
- * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
@@ -62,7 +62,8 @@
 #include <openssl/x509.h>
 #include <openssl/objects.h>
 
-static int nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+							void *exarg)
 {
 	if(operation == ASN1_OP_NEW_POST) {
 		NETSCAPE_CERT_SEQUENCE *nsseq;
diff --git a/crypto/asn1/p5_pbe.c b/crypto/asn1/p5_pbe.c
index c4582f8..94bc38b 100644
--- a/crypto/asn1/p5_pbe.c
+++ b/crypto/asn1/p5_pbe.c
@@ -71,61 +71,78 @@
 
 IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM)
 
+
+/* Set an algorithm identifier for a PKCS#5 PBE algorithm */
+
+int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
+				const unsigned char *salt, int saltlen)
+	{
+	PBEPARAM *pbe=NULL;
+	ASN1_STRING *pbe_str=NULL;
+	unsigned char *sstr;
+
+	pbe = PBEPARAM_new();
+	if (!pbe)
+		{
+		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	if(iter <= 0)
+		iter = PKCS5_DEFAULT_ITER;
+	if (!ASN1_INTEGER_set(pbe->iter, iter))
+		{
+		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	if (!saltlen)
+		saltlen = PKCS5_SALT_LEN;
+	if (!ASN1_STRING_set(pbe->salt, NULL, saltlen))
+		{
+		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	sstr = ASN1_STRING_data(pbe->salt);
+	if (salt)
+		memcpy(sstr, salt, saltlen);
+	else if (RAND_pseudo_bytes(sstr, saltlen) < 0)
+		goto err;
+
+	if(!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str))
+		{
+		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	PBEPARAM_free(pbe);
+	pbe = NULL;
+
+	if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str))
+		return 1;
+
+err:
+	if (pbe != NULL)
+		PBEPARAM_free(pbe);
+	if (pbe_str != NULL)
+		ASN1_STRING_free(pbe_str);
+	return 0;
+	}
+
 /* Return an algorithm identifier for a PKCS#5 PBE algorithm */
 
-X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt,
-	     int saltlen)
-{
-	PBEPARAM *pbe=NULL;
-	ASN1_OBJECT *al;
-	X509_ALGOR *algor;
-	ASN1_TYPE *astype=NULL;
+X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
+				const unsigned char *salt, int saltlen)
+	{
+	X509_ALGOR *ret;
+	ret = X509_ALGOR_new();
+	if (!ret)
+		{
+		ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
 
-	if (!(pbe = PBEPARAM_new ())) {
-		ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE);
-		goto err;
-	}
-	if(iter <= 0) iter = PKCS5_DEFAULT_ITER;
-	if (!ASN1_INTEGER_set(pbe->iter, iter)) {
-		ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE);
-		goto err;
-	}
-	if (!saltlen) saltlen = PKCS5_SALT_LEN;
-	if (!(pbe->salt->data = OPENSSL_malloc (saltlen))) {
-		ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE);
-		goto err;
-	}
-	pbe->salt->length = saltlen;
-	if (salt) memcpy (pbe->salt->data, salt, saltlen);
-	else if (RAND_pseudo_bytes (pbe->salt->data, saltlen) < 0)
-		goto err;
+	if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen)) 
+		return ret;
 
-	if (!(astype = ASN1_TYPE_new())) {
-		ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE);
-		goto err;
-	}
-
-	astype->type = V_ASN1_SEQUENCE;
-	if(!ASN1_pack_string_of(PBEPARAM, pbe, i2d_PBEPARAM,
-				&astype->value.sequence)) {
-		ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE);
-		goto err;
-	}
-	PBEPARAM_free (pbe);
-	pbe = NULL;
-	
-	al = OBJ_nid2obj(alg); /* never need to free al */
-	if (!(algor = X509_ALGOR_new())) {
-		ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE);
-		goto err;
-	}
-	ASN1_OBJECT_free(algor->algorithm);
-	algor->algorithm = al;
-	algor->parameter = astype;
-
-	return (algor);
-err:
-	if (pbe != NULL) PBEPARAM_free(pbe);
-	if (astype != NULL) ASN1_TYPE_free(astype);
+	X509_ALGOR_free(ret);
 	return NULL;
-}
+	}
diff --git a/crypto/asn1/p5_pbev2.c b/crypto/asn1/p5_pbev2.c
index 2b0516a..cb49b66 100644
--- a/crypto/asn1/p5_pbev2.c
+++ b/crypto/asn1/p5_pbev2.c
@@ -82,10 +82,13 @@
 
 /* Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm:
  * yes I know this is horrible!
+ *
+ * Extended version to allow application supplied PRF NID and IV.
  */
 
-X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
-				 unsigned char *salt, int saltlen)
+X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
+				 unsigned char *salt, int saltlen,
+				 unsigned char *aiv, int prf_nid)
 {
 	X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
 	int alg_nid;
@@ -98,7 +101,7 @@
 
 	alg_nid = EVP_CIPHER_type(cipher);
 	if(alg_nid == NID_undef) {
-		ASN1err(ASN1_F_PKCS5_PBE2_SET,
+		ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
 				ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
 		goto err;
 	}
@@ -113,20 +116,33 @@
 	if(!(scheme->parameter = ASN1_TYPE_new())) goto merr;
 
 	/* Create random IV */
-	if (EVP_CIPHER_iv_length(cipher) &&
-		RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
-  		goto err;
+	if (EVP_CIPHER_iv_length(cipher))
+		{
+		if (aiv)
+			memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
+		else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
+  			goto err;
+		}
 
 	EVP_CIPHER_CTX_init(&ctx);
 
-	/* Dummy cipherinit to just setup the IV */
+	/* Dummy cipherinit to just setup the IV, and PRF */
 	EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0);
 	if(EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
-		ASN1err(ASN1_F_PKCS5_PBE2_SET,
+		ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
 					ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
 		EVP_CIPHER_CTX_cleanup(&ctx);
 		goto err;
 	}
+	/* If prf NID unspecified see if cipher has a preference.
+	 * An error is OK here: just means use default PRF.
+	 */
+	if ((prf_nid == -1) && 
+	EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0)
+		{
+		ERR_clear_error();
+		prf_nid = NID_hmacWithSHA1;
+		}
 	EVP_CIPHER_CTX_cleanup(&ctx);
 
 	if(!(kdf = PBKDF2PARAM_new())) goto merr;
@@ -154,7 +170,15 @@
 				 EVP_CIPHER_key_length(cipher))) goto merr;
 	}
 
-	/* prf can stay NULL because we are using hmacWithSHA1 */
+	/* prf can stay NULL if we are using hmacWithSHA1 */
+	if (prf_nid != NID_hmacWithSHA1)
+		{
+		kdf->prf = X509_ALGOR_new();
+		if (!kdf->prf)
+			goto merr;
+		X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid),
+					V_ASN1_NULL, NULL);
+		}
 
 	/* Now setup the PBE2PARAM keyfunc structure */
 
@@ -164,7 +188,7 @@
 
 	if(!(pbe2->keyfunc->parameter = ASN1_TYPE_new())) goto merr;
 
-	if(!ASN1_pack_string_of(PBKDF2PARAM, kdf, i2d_PBKDF2PARAM,
+	if(!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
 			 &pbe2->keyfunc->parameter->value.sequence)) goto merr;
 	pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE;
 
@@ -180,7 +204,7 @@
 
 	/* Encode PBE2PARAM into parameter */
 
-	if(!ASN1_pack_string_of(PBE2PARAM, pbe2, i2d_PBE2PARAM,
+	if(!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
 				 &ret->parameter->value.sequence)) goto merr;
 	ret->parameter->type = V_ASN1_SEQUENCE;
 
@@ -190,7 +214,7 @@
 	return ret;
 
 	merr:
-	ASN1err(ASN1_F_PKCS5_PBE2_SET,ERR_R_MALLOC_FAILURE);
+	ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,ERR_R_MALLOC_FAILURE);
 
 	err:
 	PBE2PARAM_free(pbe2);
@@ -203,3 +227,9 @@
 	return NULL;
 
 }
+
+X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
+				 unsigned char *salt, int saltlen)
+	{
+	return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1);
+	}
diff --git a/crypto/asn1/p8_key.c b/crypto/asn1/p8_key.c
deleted file mode 100644
index 3a31248..0000000
--- a/crypto/asn1/p8_key.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* crypto/asn1/p8_key.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#include <stdio.h>
-#include "cryptlib.h"
-#include <openssl/asn1_mac.h>
-#include <openssl/objects.h>
-
-int i2d_X509_KEY(X509 *a, unsigned char **pp)
-	{
-	M_ASN1_I2D_vars(a);
-
-	M_ASN1_I2D_len(a->cert_info,	i2d_X509_CINF);
-	M_ASN1_I2D_len(a->sig_alg,	i2d_X509_ALGOR);
-	M_ASN1_I2D_len(a->signature,	i2d_ASN1_BIT_STRING);
-
-	M_ASN1_I2D_seq_total();
-
-	M_ASN1_I2D_put(a->cert_info,	i2d_X509_CINF);
-	M_ASN1_I2D_put(a->sig_alg,	i2d_X509_ALGOR);
-	M_ASN1_I2D_put(a->signature,	i2d_ASN1_BIT_STRING);
-
-	M_ASN1_I2D_finish();
-	}
-
-X509 *d2i_X509_KEY(X509 **a, unsigned char **pp, long length)
-	{
-	M_ASN1_D2I_vars(a,X509 *,X509_new);
-
-	M_ASN1_D2I_Init();
-	M_ASN1_D2I_start_sequence();
-	M_ASN1_D2I_get(ret->cert_info,d2i_X509_CINF);
-	M_ASN1_D2I_get(ret->sig_alg,d2i_X509_ALGOR);
-	M_ASN1_D2I_get(ret->signature,d2i_ASN1_BIT_STRING);
-	M_ASN1_D2I_Finish(a,X509_free,ASN1_F_D2I_X509);
-	}
-
-X509 *X509_KEY_new(void)
-	{
-	X509_KEY *ret=NULL;
-
-	M_ASN1_New_OPENSSL_malloc(ret,X509_KEY);
-	ret->references=1;
-	ret->type=NID
-	M_ASN1_New(ret->cert_info,X509_CINF_new);
-	M_ASN1_New(ret->sig_alg,X509_ALGOR_new);
-	M_ASN1_New(ret->signature,ASN1_BIT_STRING_new);
-	return(ret);
-	M_ASN1_New_Error(ASN1_F_X509_NEW);
-	}
-
-void X509_KEY_free(X509 *a)
-	{
-	int i;
-
-	if (a == NULL) return;
-
-	i=CRYPTO_add_lock(&a->references,-1,CRYPTO_LOCK_X509_KEY);
-#ifdef REF_PRINT
-	REF_PRINT("X509_KEY",a);
-#endif
-	if (i > 0) return;
-#ifdef REF_CHECK
-	if (i < 0)
-		{
-		fprintf(stderr,"X509_KEY_free, bad reference count\n");
-		abort();
-		}
-#endif
-
-	X509_CINF_free(a->cert_info);
-	X509_ALGOR_free(a->sig_alg);
-	ASN1_BIT_STRING_free(a->signature);
-	OPENSSL_free(a);
-	}
-
diff --git a/crypto/asn1/p8_pkey.c b/crypto/asn1/p8_pkey.c
index 0a19575..17b68d3 100644
--- a/crypto/asn1/p8_pkey.c
+++ b/crypto/asn1/p8_pkey.c
@@ -3,7 +3,7 @@
  * project 1999.
  */
 /* ====================================================================
- * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
@@ -62,7 +62,8 @@
 #include <openssl/x509.h>
 
 /* Minor tweak to operation: zero private key data */
-static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+							void *exarg)
 {
 	/* Since the structure must still be valid use ASN1_OP_FREE_PRE */
 	if(operation == ASN1_OP_FREE_PRE) {
@@ -82,3 +83,73 @@
 } ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
 
 IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
+
+int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
+					int version,
+					int ptype, void *pval,
+					unsigned char *penc, int penclen)
+	{
+	unsigned char **ppenc = NULL;
+	if (version >= 0)
+		{
+		if (!ASN1_INTEGER_set(priv->version, version))
+			return 0;
+		}
+	if (penc)
+		{
+		int pmtype;
+		ASN1_OCTET_STRING *oct;
+		oct = ASN1_OCTET_STRING_new();
+		if (!oct)
+			return 0;
+		oct->data = penc;
+		ppenc = &oct->data;
+		oct->length = penclen;
+		if (priv->broken == PKCS8_NO_OCTET)
+			pmtype = V_ASN1_SEQUENCE;
+		else
+			pmtype = V_ASN1_OCTET_STRING;
+		ASN1_TYPE_set(priv->pkey, pmtype, oct);
+		}
+	if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval))
+		{
+		/* If call fails do not swallow 'enc' */
+		if (ppenc)
+			*ppenc = NULL;
+		return 0;
+		}
+	return 1;
+	}
+
+int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
+		const unsigned char **pk, int *ppklen,
+		X509_ALGOR **pa,
+		PKCS8_PRIV_KEY_INFO *p8)
+	{
+	if (ppkalg)
+		*ppkalg = p8->pkeyalg->algorithm;
+	if(p8->pkey->type == V_ASN1_OCTET_STRING)
+		{
+		p8->broken = PKCS8_OK;
+		if (pk)
+			{
+			*pk = p8->pkey->value.octet_string->data;
+			*ppklen = p8->pkey->value.octet_string->length;
+			}
+		}
+	else if (p8->pkey->type == V_ASN1_SEQUENCE)
+		{
+		p8->broken = PKCS8_NO_OCTET;
+		if (pk)
+			{
+			*pk = p8->pkey->value.sequence->data;
+			*ppklen = p8->pkey->value.sequence->length;
+			}
+		}
+	else
+		return 0;
+	if (pa)
+		*pa = p8->pkeyalg;
+	return 1;
+	}
+
diff --git a/crypto/asn1/t_pkey.c b/crypto/asn1/t_pkey.c
index afb95d6..9dd18f6 100644
--- a/crypto/asn1/t_pkey.c
+++ b/crypto/asn1/t_pkey.c
@@ -55,520 +55,15 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
-/* ====================================================================
- * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
- * Binary polynomial ECC support in OpenSSL originally developed by 
- * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
- */
 
 #include <stdio.h>
 #include "cryptlib.h"
 #include <openssl/objects.h>
 #include <openssl/buffer.h>
 #include <openssl/bn.h>
-#ifndef OPENSSL_NO_RSA
-#include <openssl/rsa.h>
-#endif
-#ifndef OPENSSL_NO_DH
-#include <openssl/dh.h>
-#endif
-#ifndef OPENSSL_NO_DSA
-#include <openssl/dsa.h>
-#endif
-#ifndef OPENSSL_NO_EC
-#include <openssl/ec.h>
-#endif
 
-static int print(BIO *fp,const char *str, const BIGNUM *num,
-		unsigned char *buf,int off);
-#ifndef OPENSSL_NO_EC
-static int print_bin(BIO *fp, const char *str, const unsigned char *num,
-		size_t len, int off);
-#endif
-#ifndef OPENSSL_NO_RSA
-#ifndef OPENSSL_NO_FP_API
-int RSA_print_fp(FILE *fp, const RSA *x, int off)
-	{
-	BIO *b;
-	int ret;
-
-	if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB);
-		return(0);
-		}
-	BIO_set_fp(b,fp,BIO_NOCLOSE);
-	ret=RSA_print(b,x,off);
-	BIO_free(b);
-	return(ret);
-	}
-#endif
-
-int RSA_print(BIO *bp, const RSA *x, int off)
-	{
-	char str[128];
-	const char *s;
-	unsigned char *m=NULL;
-	int ret=0, mod_len = 0;
-	size_t buf_len=0, i;
-
-	if (x->n)
-		buf_len = (size_t)BN_num_bytes(x->n);
-	if (x->e)
-		if (buf_len < (i = (size_t)BN_num_bytes(x->e)))
-			buf_len = i;
-	if (x->d)
-		if (buf_len < (i = (size_t)BN_num_bytes(x->d)))
-			buf_len = i;
-	if (x->p)
-		if (buf_len < (i = (size_t)BN_num_bytes(x->p)))
-			buf_len = i;
-	if (x->q)
-		if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
-			buf_len = i;
-	if (x->dmp1)
-		if (buf_len < (i = (size_t)BN_num_bytes(x->dmp1)))
-			buf_len = i;
-	if (x->dmq1)
-		if (buf_len < (i = (size_t)BN_num_bytes(x->dmq1)))
-			buf_len = i;
-	if (x->iqmp)
-		if (buf_len < (i = (size_t)BN_num_bytes(x->iqmp)))
-			buf_len = i;
-
-	m=(unsigned char *)OPENSSL_malloc(buf_len+10);
-	if (m == NULL)
-		{
-		RSAerr(RSA_F_RSA_PRINT,ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	if (x->n != NULL)
-		mod_len = BN_num_bits(x->n);
-
-	if (x->d != NULL)
-		{
-		if(!BIO_indent(bp,off,128))
-		   goto err;
-		if (BIO_printf(bp,"Private-Key: (%d bit)\n", mod_len)
-			<= 0) goto err;
-		}
-
-	if (x->d == NULL)
-		BIO_snprintf(str,sizeof str,"Modulus (%d bit):", mod_len);
-	else
-		BUF_strlcpy(str,"modulus:",sizeof str);
-	if (!print(bp,str,x->n,m,off)) goto err;
-	s=(x->d == NULL)?"Exponent:":"publicExponent:";
-	if ((x->e != NULL) && !print(bp,s,x->e,m,off))
-		goto err;
-	if ((x->d != NULL) && !print(bp,"privateExponent:",x->d,m,off))
-		goto err;
-	if ((x->p != NULL) && !print(bp,"prime1:",x->p,m,off))
-		goto err;
-	if ((x->q != NULL) && !print(bp,"prime2:",x->q,m,off))
-		goto err;
-	if ((x->dmp1 != NULL) && !print(bp,"exponent1:",x->dmp1,m,off))
-		goto err;
-	if ((x->dmq1 != NULL) && !print(bp,"exponent2:",x->dmq1,m,off))
-		goto err;
-	if ((x->iqmp != NULL) && !print(bp,"coefficient:",x->iqmp,m,off))
-		goto err;
-	ret=1;
-err:
-	if (m != NULL) OPENSSL_free(m);
-	return(ret);
-	}
-#endif /* OPENSSL_NO_RSA */
-
-#ifndef OPENSSL_NO_DSA
-#ifndef OPENSSL_NO_FP_API
-int DSA_print_fp(FILE *fp, const DSA *x, int off)
-	{
-	BIO *b;
-	int ret;
-
-	if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		DSAerr(DSA_F_DSA_PRINT_FP,ERR_R_BUF_LIB);
-		return(0);
-		}
-	BIO_set_fp(b,fp,BIO_NOCLOSE);
-	ret=DSA_print(b,x,off);
-	BIO_free(b);
-	return(ret);
-	}
-#endif
-
-int DSA_print(BIO *bp, const DSA *x, int off)
-	{
-	unsigned char *m=NULL;
-	int ret=0;
-	size_t buf_len=0,i;
-
-	if (x->p)
-		buf_len = (size_t)BN_num_bytes(x->p);
-	else
-		{
-		DSAerr(DSA_F_DSA_PRINT,DSA_R_MISSING_PARAMETERS);
-		goto err;
-		}
-	if (x->q)
-		if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
-			buf_len = i;
-	if (x->g)
-		if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
-			buf_len = i;
-	if (x->priv_key)
-		if (buf_len < (i = (size_t)BN_num_bytes(x->priv_key)))
-			buf_len = i;
-	if (x->pub_key)
-		if (buf_len < (i = (size_t)BN_num_bytes(x->pub_key)))
-			buf_len = i;
-
-	m=(unsigned char *)OPENSSL_malloc(buf_len+10);
-	if (m == NULL)
-		{
-		DSAerr(DSA_F_DSA_PRINT,ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	if (x->priv_key != NULL)
-		{
-		if(!BIO_indent(bp,off,128))
-		   goto err;
-		if (BIO_printf(bp,"Private-Key: (%d bit)\n",BN_num_bits(x->p))
-			<= 0) goto err;
-		}
-
-	if ((x->priv_key != NULL) && !print(bp,"priv:",x->priv_key,m,off))
-		goto err;
-	if ((x->pub_key  != NULL) && !print(bp,"pub: ",x->pub_key,m,off))
-		goto err;
-	if ((x->p != NULL) && !print(bp,"P:   ",x->p,m,off)) goto err;
-	if ((x->q != NULL) && !print(bp,"Q:   ",x->q,m,off)) goto err;
-	if ((x->g != NULL) && !print(bp,"G:   ",x->g,m,off)) goto err;
-	ret=1;
-err:
-	if (m != NULL) OPENSSL_free(m);
-	return(ret);
-	}
-#endif /* !OPENSSL_NO_DSA */
-
-#ifndef OPENSSL_NO_EC
-#ifndef OPENSSL_NO_FP_API
-int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
-	{
-	BIO *b;
-	int ret;
-
-	if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		ECerr(EC_F_ECPKPARAMETERS_PRINT_FP,ERR_R_BUF_LIB);
-		return(0);
-		}
-	BIO_set_fp(b, fp, BIO_NOCLOSE);
-	ret = ECPKParameters_print(b, x, off);
-	BIO_free(b);
-	return(ret);
-	}
-
-int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
-	{
-	BIO *b;
-	int ret;
- 
-	if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
-		return(0);
-		}
-	BIO_set_fp(b, fp, BIO_NOCLOSE);
-	ret = EC_KEY_print(b, x, off);
-	BIO_free(b);
-	return(ret);
-	}
-#endif
-
-int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
-	{
-	unsigned char *buffer=NULL;
-	size_t	buf_len=0, i;
-	int     ret=0, reason=ERR_R_BIO_LIB;
-	BN_CTX  *ctx=NULL;
-	const EC_POINT *point=NULL;
-	BIGNUM	*p=NULL, *a=NULL, *b=NULL, *gen=NULL,
-		*order=NULL, *cofactor=NULL;
-	const unsigned char *seed;
-	size_t	seed_len=0;
-	
-	static const char *gen_compressed = "Generator (compressed):";
-	static const char *gen_uncompressed = "Generator (uncompressed):";
-	static const char *gen_hybrid = "Generator (hybrid):";
- 
-	if (!x)
-		{
-		reason = ERR_R_PASSED_NULL_PARAMETER;
-		goto err;
-		}
-
-	if (EC_GROUP_get_asn1_flag(x))
-		{
-		/* the curve parameter are given by an asn1 OID */
-		int nid;
-
-		if (!BIO_indent(bp, off, 128))
-			goto err;
-
-		nid = EC_GROUP_get_curve_name(x);
-		if (nid == 0)
-			goto err;
-
-		if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
-			goto err;
-		if (BIO_printf(bp, "\n") <= 0)
-			goto err;
-		}
-	else
-		{
-		/* explicit parameters */
-		int is_char_two = 0;
-		point_conversion_form_t form;
-		int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
-
-		if (tmp_nid == NID_X9_62_characteristic_two_field)
-			is_char_two = 1;
-
-		if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
-			(b = BN_new()) == NULL || (order = BN_new()) == NULL ||
-			(cofactor = BN_new()) == NULL)
-			{
-			reason = ERR_R_MALLOC_FAILURE;
-			goto err;
-			}
-
-		if (is_char_two)
-			{
-			if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx))
-				{
-				reason = ERR_R_EC_LIB;
-				goto err;
-				}
-			}
-		else /* prime field */
-			{
-			if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx))
-				{
-				reason = ERR_R_EC_LIB;
-				goto err;
-				}
-			}
-
-		if ((point = EC_GROUP_get0_generator(x)) == NULL)
-			{
-			reason = ERR_R_EC_LIB;
-			goto err;
-			}
-		if (!EC_GROUP_get_order(x, order, NULL) || 
-            		!EC_GROUP_get_cofactor(x, cofactor, NULL))
-			{
-			reason = ERR_R_EC_LIB;
-			goto err;
-			}
-		
-		form = EC_GROUP_get_point_conversion_form(x);
-
-		if ((gen = EC_POINT_point2bn(x, point, 
-				form, NULL, ctx)) == NULL)
-			{
-			reason = ERR_R_EC_LIB;
-			goto err;
-			}
-
-		buf_len = (size_t)BN_num_bytes(p);
-		if (buf_len < (i = (size_t)BN_num_bytes(a)))
-			buf_len = i;
-		if (buf_len < (i = (size_t)BN_num_bytes(b)))
-			buf_len = i;
-		if (buf_len < (i = (size_t)BN_num_bytes(gen)))
-			buf_len = i;
-		if (buf_len < (i = (size_t)BN_num_bytes(order)))
-			buf_len = i;
-		if (buf_len < (i = (size_t)BN_num_bytes(cofactor))) 
-			buf_len = i;
-
-		if ((seed = EC_GROUP_get0_seed(x)) != NULL)
-			seed_len = EC_GROUP_get_seed_len(x);
-
-		buf_len += 10;
-		if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
-			{
-			reason = ERR_R_MALLOC_FAILURE;
-			goto err;
-			}
-
-		if (!BIO_indent(bp, off, 128))
-			goto err;
-
-		/* print the 'short name' of the field type */
-		if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
-			<= 0)
-			goto err;  
-
-		if (is_char_two)
-			{
-			/* print the 'short name' of the base type OID */
-			int basis_type = EC_GROUP_get_basis_type(x);
-			if (basis_type == 0)
-				goto err;
-
-			if (!BIO_indent(bp, off, 128))
-				goto err;
-
-			if (BIO_printf(bp, "Basis Type: %s\n", 
-				OBJ_nid2sn(basis_type)) <= 0)
-				goto err;
-
-			/* print the polynomial */
-			if ((p != NULL) && !print(bp, "Polynomial:", p, buffer,
-				off))
-				goto err;
-			}
-		else
-			{
-			if ((p != NULL) && !print(bp, "Prime:", p, buffer,off))
-				goto err;
-			}
-		if ((a != NULL) && !print(bp, "A:   ", a, buffer, off)) 
-			goto err;
-		if ((b != NULL) && !print(bp, "B:   ", b, buffer, off))
-			goto err;
-		if (form == POINT_CONVERSION_COMPRESSED)
-			{
-			if ((gen != NULL) && !print(bp, gen_compressed, gen,
-				buffer, off))
-				goto err;
-			}
-		else if (form == POINT_CONVERSION_UNCOMPRESSED)
-			{
-			if ((gen != NULL) && !print(bp, gen_uncompressed, gen,
-				buffer, off))
-				goto err;
-			}
-		else /* form == POINT_CONVERSION_HYBRID */
-			{
-			if ((gen != NULL) && !print(bp, gen_hybrid, gen,
-				buffer, off))
-				goto err;
-			}
-		if ((order != NULL) && !print(bp, "Order: ", order, 
-			buffer, off)) goto err;
-		if ((cofactor != NULL) && !print(bp, "Cofactor: ", cofactor, 
-			buffer, off)) goto err;
-		if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
-			goto err;
-		}
-	ret=1;
-err:
-	if (!ret)
- 		ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
-	if (p) 
-		BN_free(p);
-	if (a) 
-		BN_free(a);
-	if (b)
-		BN_free(b);
-	if (gen)
-		BN_free(gen);
-	if (order)
-		BN_free(order);
-	if (cofactor)
-		BN_free(cofactor);
-	if (ctx)
-		BN_CTX_free(ctx);
-	if (buffer != NULL) 
-		OPENSSL_free(buffer);
-	return(ret);	
-	}
-
-int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
-	{
-	unsigned char *buffer=NULL;
-	size_t	buf_len=0, i;
-	int     ret=0, reason=ERR_R_BIO_LIB;
-	BIGNUM  *pub_key=NULL, *order=NULL;
-	BN_CTX  *ctx=NULL;
-	const EC_GROUP *group;
-	const EC_POINT *public_key;
-	const BIGNUM *priv_key;
- 
-	if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
-		{
-		reason = ERR_R_PASSED_NULL_PARAMETER;
-		goto err;
-		}
-
-	public_key = EC_KEY_get0_public_key(x);
-	if ((pub_key = EC_POINT_point2bn(group, public_key,
-		EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
-		{
-		reason = ERR_R_EC_LIB;
-		goto err;
-		}
-
-	buf_len = (size_t)BN_num_bytes(pub_key);
-	priv_key = EC_KEY_get0_private_key(x);
-	if (priv_key != NULL)
-		{
-		if ((i = (size_t)BN_num_bytes(priv_key)) > buf_len)
-			buf_len = i;
-		}
-
-	buf_len += 10;
-	if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
-		{
-		reason = ERR_R_MALLOC_FAILURE;
-		goto err;
-		}
-
-	if (priv_key != NULL)
-		{
-		if (!BIO_indent(bp, off, 128))
-			goto err;
-		if ((order = BN_new()) == NULL)
-			goto err;
-		if (!EC_GROUP_get_order(group, order, NULL))
-			goto err;
-		if (BIO_printf(bp, "Private-Key: (%d bit)\n", 
-			BN_num_bits(order)) <= 0) goto err;
-		}
-  
-	if ((priv_key != NULL) && !print(bp, "priv:", priv_key, 
-		buffer, off))
-		goto err;
-	if ((pub_key != NULL) && !print(bp, "pub: ", pub_key,
-		buffer, off))
-		goto err;
-	if (!ECPKParameters_print(bp, group, off))
-		goto err;
-	ret=1;
-err:
-	if (!ret)
- 		ECerr(EC_F_EC_KEY_PRINT, reason);
-	if (pub_key) 
-		BN_free(pub_key);
-	if (order)
-		BN_free(order);
-	if (ctx)
-		BN_CTX_free(ctx);
-	if (buffer != NULL)
-		OPENSSL_free(buffer);
-	return(ret);
-	}
-#endif /* OPENSSL_NO_EC */
-
-static int print(BIO *bp, const char *number, const BIGNUM *num, unsigned char *buf,
-	     int off)
+int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
+			unsigned char *buf, int off)
 	{
 	int n,i;
 	const char *neg;
@@ -617,223 +112,3 @@
 		}
 	return(1);
 	}
-
-#ifndef OPENSSL_NO_EC
-static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
-		size_t len, int off)
-	{
-	size_t i;
-	char str[128];
-
-	if (buf == NULL)
-		return 1;
-	if (off)
-		{
-		if (off > 128)
-			off=128;
-		memset(str,' ',off);
-		if (BIO_write(fp, str, off) <= 0)
-			return 0;
-		}
-
-	if (BIO_printf(fp,"%s", name) <= 0)
-		return 0;
-
-	for (i=0; i<len; i++)
-		{
-		if ((i%15) == 0)
-			{
-			str[0]='\n';
-			memset(&(str[1]),' ',off+4);
-			if (BIO_write(fp, str, off+1+4) <= 0)
-				return 0;
-			}
-		if (BIO_printf(fp,"%02x%s",buf[i],((i+1) == len)?"":":") <= 0)
-			return 0;
-		}
-	if (BIO_write(fp,"\n",1) <= 0)
-		return 0;
-
-	return 1;
-	}
-#endif
-
-#ifndef OPENSSL_NO_DH
-#ifndef OPENSSL_NO_FP_API
-int DHparams_print_fp(FILE *fp, const DH *x)
-	{
-	BIO *b;
-	int ret;
-
-	if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		DHerr(DH_F_DHPARAMS_PRINT_FP,ERR_R_BUF_LIB);
-		return(0);
-		}
-	BIO_set_fp(b,fp,BIO_NOCLOSE);
-	ret=DHparams_print(b, x);
-	BIO_free(b);
-	return(ret);
-	}
-#endif
-
-int DHparams_print(BIO *bp, const DH *x)
-	{
-	unsigned char *m=NULL;
-	int reason=ERR_R_BUF_LIB,ret=0;
-	size_t buf_len=0, i;
-
-	if (x->p)
-		buf_len = (size_t)BN_num_bytes(x->p);
-	else
-		{
-		reason = ERR_R_PASSED_NULL_PARAMETER;
-		goto err;
-		}
-	if (x->g)
-		if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
-			buf_len = i;
-	m=(unsigned char *)OPENSSL_malloc(buf_len+10);
-	if (m == NULL)
-		{
-		reason=ERR_R_MALLOC_FAILURE;
-		goto err;
-		}
-
-	if (BIO_printf(bp,"Diffie-Hellman-Parameters: (%d bit)\n",
-		BN_num_bits(x->p)) <= 0)
-		goto err;
-	if (!print(bp,"prime:",x->p,m,4)) goto err;
-	if (!print(bp,"generator:",x->g,m,4)) goto err;
-	if (x->length != 0)
-		{
-		if (BIO_printf(bp,"    recommended-private-length: %d bits\n",
-			(int)x->length) <= 0) goto err;
-		}
-	ret=1;
-	if (0)
-		{
-err:
-		DHerr(DH_F_DHPARAMS_PRINT,reason);
-		}
-	if (m != NULL) OPENSSL_free(m);
-	return(ret);
-	}
-#endif
-
-#ifndef OPENSSL_NO_DSA
-#ifndef OPENSSL_NO_FP_API
-int DSAparams_print_fp(FILE *fp, const DSA *x)
-	{
-	BIO *b;
-	int ret;
-
-	if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		DSAerr(DSA_F_DSAPARAMS_PRINT_FP,ERR_R_BUF_LIB);
-		return(0);
-		}
-	BIO_set_fp(b,fp,BIO_NOCLOSE);
-	ret=DSAparams_print(b, x);
-	BIO_free(b);
-	return(ret);
-	}
-#endif
-
-int DSAparams_print(BIO *bp, const DSA *x)
-	{
-	unsigned char *m=NULL;
-	int ret=0;
-	size_t buf_len=0,i;
-
-	if (x->p)
-		buf_len = (size_t)BN_num_bytes(x->p);
-	else
-		{
-		DSAerr(DSA_F_DSAPARAMS_PRINT,DSA_R_MISSING_PARAMETERS);
-		goto err;
-		}
-	if (x->q)
-		if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
-			buf_len = i;
-	if (x->g)
-		if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
-			buf_len = i;
-	m=(unsigned char *)OPENSSL_malloc(buf_len+10);
-	if (m == NULL)
-		{
-		DSAerr(DSA_F_DSAPARAMS_PRINT,ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	if (BIO_printf(bp,"DSA-Parameters: (%d bit)\n",
-		BN_num_bits(x->p)) <= 0)
-		goto err;
-	if (!print(bp,"p:",x->p,m,4)) goto err;
-	if ((x->q != NULL) && !print(bp,"q:",x->q,m,4)) goto err;
-	if ((x->g != NULL) && !print(bp,"g:",x->g,m,4)) goto err;
-	ret=1;
-err:
-	if (m != NULL) OPENSSL_free(m);
-	return(ret);
-	}
-
-#endif /* !OPENSSL_NO_DSA */
-
-#ifndef OPENSSL_NO_EC
-#ifndef OPENSSL_NO_FP_API
-int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
-	{
-	BIO *b;
-	int ret;
- 
-	if ((b=BIO_new(BIO_s_file())) == NULL)
-		{
-		ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
-		return(0);
-		}
-	BIO_set_fp(b, fp, BIO_NOCLOSE);
-	ret = ECParameters_print(b, x);
-	BIO_free(b);
-	return(ret);
-	}
-#endif
-
-int ECParameters_print(BIO *bp, const EC_KEY *x)
-	{
-	int     reason=ERR_R_EC_LIB, ret=0;
-	BIGNUM	*order=NULL;
-	const EC_GROUP *group;
- 
-	if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
-		{
-		reason = ERR_R_PASSED_NULL_PARAMETER;;
-		goto err;
-		}
-
-	if ((order = BN_new()) == NULL)
-		{
-		reason = ERR_R_MALLOC_FAILURE;
-		goto err;
-		}
-
-	if (!EC_GROUP_get_order(group, order, NULL))
-		{
-		reason = ERR_R_EC_LIB;
-		goto err;
-		}
- 
-	if (BIO_printf(bp, "ECDSA-Parameters: (%d bit)\n", 
-		BN_num_bits(order)) <= 0)
-		goto err;
-	if (!ECPKParameters_print(bp, group, 4))
-		goto err;
-	ret=1;
-err:
-	if (order)
-		BN_free(order);
-	ECerr(EC_F_ECPARAMETERS_PRINT, reason);
-	return(ret);
-	}
-  
-#endif
diff --git a/crypto/asn1/t_req.c b/crypto/asn1/t_req.c
index 5557e06..ea1794e 100644
--- a/crypto/asn1/t_req.c
+++ b/crypto/asn1/t_req.c
@@ -149,34 +149,10 @@
 			ERR_print_errors(bp);
 			}
 		else
-#ifndef OPENSSL_NO_RSA
-		if (pkey->type == EVP_PKEY_RSA)
 			{
-			BIO_printf(bp,"%12sRSA Public Key: (%d bit)\n","",
-			BN_num_bits(pkey->pkey.rsa->n));
-			RSA_print(bp,pkey->pkey.rsa,16);
+			EVP_PKEY_print_public(bp, pkey, 16, NULL);
+			EVP_PKEY_free(pkey);
 			}
-		else
-#endif
-#ifndef OPENSSL_NO_DSA
-		if (pkey->type == EVP_PKEY_DSA)
-			{
-			BIO_printf(bp,"%12sDSA Public Key:\n","");
-			DSA_print(bp,pkey->pkey.dsa,16);
-			}
-		else
-#endif
-#ifndef OPENSSL_NO_EC
-		if (pkey->type == EVP_PKEY_EC)
-		{
-			BIO_printf(bp, "%12sEC Public Key: \n","");
-			EC_KEY_print(bp, pkey->pkey.ec, 16);
-		}
-	else
-#endif
-			BIO_printf(bp,"%12sUnknown Public Key:\n","");
-
-		EVP_PKEY_free(pkey);
 		}
 
 	if(!(cflag & X509_FLAG_NO_ATTRIBUTES))
diff --git a/crypto/asn1/t_spki.c b/crypto/asn1/t_spki.c
index a73369b..079c081 100644
--- a/crypto/asn1/t_spki.c
+++ b/crypto/asn1/t_spki.c
@@ -82,36 +82,11 @@
 				(i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i));
 	pkey = X509_PUBKEY_get(spki->spkac->pubkey);
 	if(!pkey) BIO_printf(out, "  Unable to load public key\n");
-	else {
-#ifndef OPENSSL_NO_RSA
-		if (pkey->type == EVP_PKEY_RSA)
-			{
-			BIO_printf(out,"  RSA Public Key: (%d bit)\n",
-				BN_num_bits(pkey->pkey.rsa->n));
-			RSA_print(out,pkey->pkey.rsa,2);
-			}
-		else 
-#endif
-#ifndef OPENSSL_NO_DSA
-		if (pkey->type == EVP_PKEY_DSA)
+	else
 		{
-		BIO_printf(out,"  DSA Public Key:\n");
-		DSA_print(out,pkey->pkey.dsa,2);
-		}
-		else
-#endif
-#ifndef OPENSSL_NO_EC
-		if (pkey->type == EVP_PKEY_EC)
-		{
-			BIO_printf(out, "  EC Public Key:\n");
-			EC_KEY_print(out, pkey->pkey.ec,2);
-		}
-		else
-#endif
-
-			BIO_printf(out,"  Unknown Public Key:\n");
+		EVP_PKEY_print_public(out, pkey, 4, NULL);
 		EVP_PKEY_free(pkey);
-	}
+		}
 	chal = spki->spkac->challenge;
 	if(chal->length)
 		BIO_printf(out, "  Challenge String: %s\n", chal->data);
diff --git a/crypto/asn1/t_x509.c b/crypto/asn1/t_x509.c
index 6f295b4..e061f2f 100644
--- a/crypto/asn1/t_x509.c
+++ b/crypto/asn1/t_x509.c
@@ -111,7 +111,6 @@
 	ASN1_INTEGER *bs;
 	EVP_PKEY *pkey=NULL;
 	const char *neg;
-	ASN1_STRING *str=NULL;
 
 	if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
 			mlch = '\n';
@@ -215,34 +214,10 @@
 			ERR_print_errors(bp);
 			}
 		else
-#ifndef OPENSSL_NO_RSA
-		if (pkey->type == EVP_PKEY_RSA)
 			{
-			BIO_printf(bp,"%12sRSA Public Key: (%d bit)\n","",
-			BN_num_bits(pkey->pkey.rsa->n));
-			RSA_print(bp,pkey->pkey.rsa,16);
+			EVP_PKEY_print_public(bp, pkey, 16, NULL);
+			EVP_PKEY_free(pkey);
 			}
-		else
-#endif
-#ifndef OPENSSL_NO_DSA
-		if (pkey->type == EVP_PKEY_DSA)
-			{
-			BIO_printf(bp,"%12sDSA Public Key:\n","");
-			DSA_print(bp,pkey->pkey.dsa,16);
-			}
-		else
-#endif
-#ifndef OPENSSL_NO_EC
-		if (pkey->type == EVP_PKEY_EC)
-			{
-			BIO_printf(bp, "%12sEC Public Key:\n","");
-			EC_KEY_print(bp, pkey->pkey.ec, 16);
-			}
-		else
-#endif
-			BIO_printf(bp,"%12sUnknown Public Key:\n","");
-
-		EVP_PKEY_free(pkey);
 		}
 
 	if (!(cflag & X509_FLAG_NO_EXTENSIONS))
@@ -259,7 +234,6 @@
 		}
 	ret=1;
 err:
-	if (str != NULL) ASN1_STRING_free(str);
 	if (m != NULL) OPENSSL_free(m);
 	return(ret);
 	}
@@ -329,14 +303,15 @@
 	return 1;
 }
 
-int ASN1_STRING_print(BIO *bp, ASN1_STRING *v)
+int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
 	{
 	int i,n;
-	char buf[80],*p;
+	char buf[80];
+	const char *p;
 
 	if (v == NULL) return(0);
 	n=0;
-	p=(char *)v->data;
+	p=(const char *)v->data;
 	for (i=0; i<v->length; i++)
 		{
 		if ((p[i] > '~') || ((p[i] < ' ') &&
@@ -358,7 +333,7 @@
 	return(1);
 	}
 
-int ASN1_TIME_print(BIO *bp, ASN1_TIME *tm)
+int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
 {
 	if(tm->type == V_ASN1_UTCTIME) return ASN1_UTCTIME_print(bp, tm);
 	if(tm->type == V_ASN1_GENERALIZEDTIME)
@@ -373,7 +348,7 @@
     "Jul","Aug","Sep","Oct","Nov","Dec"
     };
 
-int ASN1_GENERALIZEDTIME_print(BIO *bp, ASN1_GENERALIZEDTIME *tm)
+int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
 	{
 	char *v;
 	int gmt=0;
@@ -421,15 +396,15 @@
 	return(0);
 	}
 
-int ASN1_UTCTIME_print(BIO *bp, ASN1_UTCTIME *tm)
+int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
 	{
-	char *v;
+	const char *v;
 	int gmt=0;
 	int i;
 	int y=0,M=0,d=0,h=0,m=0,s=0;
 
 	i=tm->length;
-	v=(char *)tm->data;
+	v=(const char *)tm->data;
 
 	if (i < 10) goto err;
 	if (v[i-1] == 'Z') gmt=1;
diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c
index 48bc1c0..3bee439 100644
--- a/crypto/asn1/tasn_dec.c
+++ b/crypto/asn1/tasn_dec.c
@@ -114,6 +114,8 @@
 /* Macro to initialize and invalidate the cache */
 
 #define asn1_tlc_clear(c)	if (c) (c)->valid = 0
+/* Version to avoid compiler warning about 'c' always non-NULL */
+#define asn1_tlc_clear_nc(c)	(c)->valid = 0
 
 /* Decode an ASN1 item, this currently behaves just 
  * like a standard 'd2i' function. 'in' points to 
@@ -130,7 +132,7 @@
 	ASN1_VALUE *ptmpval = NULL;
 	if (!pval)
 		pval = &ptmpval;
-	c.valid = 0;
+	asn1_tlc_clear_nc(&c);
 	if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) 
 		return *pval;
 	return NULL;
@@ -140,7 +142,7 @@
 		const unsigned char **in, long len, const ASN1_TEMPLATE *tt)
 	{
 	ASN1_TLC c;
-	c.valid = 0;
+	asn1_tlc_clear_nc(&c);
 	return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
 	}
 
@@ -306,7 +308,7 @@
 
 
 		case ASN1_ITYPE_CHOICE:
-		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it))
+		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
 				goto auxerr;
 
 		/* Allocate structure */
@@ -356,7 +358,7 @@
 
 		asn1_set_choice_selector(pval, i, it);
 		*in = p;
-		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it))
+		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
 				goto auxerr;
 		return 1;
 
@@ -403,7 +405,7 @@
 			goto err;
 			}
 
-		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it))
+		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
 				goto auxerr;
 
 		/* Get each field entry */
@@ -505,7 +507,7 @@
 		if (!asn1_enc_save(pval, *in, p - *in, it))
 			goto auxerr;
 		*in = p;
-		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it))
+		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
 				goto auxerr;
 		return 1;
 
@@ -665,11 +667,12 @@
 		else
 			{
 			/* We've got a valid STACK: free up any items present */
-			STACK *sktmp = (STACK *)*val;
+			STACK_OF(ASN1_VALUE) *sktmp
+			    = (STACK_OF(ASN1_VALUE) *)*val;
 			ASN1_VALUE *vtmp;
-			while(sk_num(sktmp) > 0)
+			while(sk_ASN1_VALUE_num(sktmp) > 0)
 				{
-				vtmp = (ASN1_VALUE *)sk_pop(sktmp);
+				vtmp = sk_ASN1_VALUE_pop(sktmp);
 				ASN1_item_ex_free(&vtmp,
 						ASN1_ITEM_ptr(tt->item));
 				}
@@ -710,7 +713,8 @@
 				goto err;
 				}
 			len -= p - q;
-			if (!sk_push((STACK *)*val, (char *)skfield))
+			if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val,
+						skfield))
 				{
 				ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
 						ERR_R_MALLOC_FAILURE);
diff --git a/crypto/asn1/tasn_enc.c b/crypto/asn1/tasn_enc.c
index 2721f90..936ad1f 100644
--- a/crypto/asn1/tasn_enc.c
+++ b/crypto/asn1/tasn_enc.c
@@ -158,7 +158,7 @@
 		return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
 
 		case ASN1_ITYPE_CHOICE:
-		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it))
+		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
 				return 0;
 		i = asn1_get_choice_selector(pval, it);
 		if ((i >= 0) && (i < it->tcount))
@@ -171,7 +171,7 @@
 								-1, aclass);
 			}
 		/* Fixme: error condition if selector out of range */
-		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it))
+		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
 				return 0;
 		break;
 
@@ -216,7 +216,7 @@
 			aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
 					| V_ASN1_UNIVERSAL;
 			}
-		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it))
+		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
 				return 0;
 		/* First work out sequence content length */
 		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
@@ -250,7 +250,7 @@
 			}
 		if (ndef == 2)
 			ASN1_put_eoc(out);
-		if (asn1_cb  && !asn1_cb(ASN1_OP_I2D_POST, pval, it))
+		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
 				return 0;
 		return seqlen;
 
@@ -569,7 +569,8 @@
 	ASN1_STRING *strtmp;
 	ASN1_OBJECT *otmp;
 	int utype;
-	unsigned char *cont, c;
+	const unsigned char *cont;
+	unsigned char c;
 	int len;
 	const ASN1_PRIMITIVE_FUNCS *pf;
 	pf = it->funcs;
diff --git a/crypto/asn1/tasn_fre.c b/crypto/asn1/tasn_fre.c
index d7c017f..77d3092 100644
--- a/crypto/asn1/tasn_fre.c
+++ b/crypto/asn1/tasn_fre.c
@@ -110,7 +110,7 @@
 		case ASN1_ITYPE_CHOICE:
 		if (asn1_cb)
 			{
-			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it);
+			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
 			if (i == 2)
 				return;
 			}
@@ -123,7 +123,7 @@
 			ASN1_template_free(pchval, tt);
 			}
 		if (asn1_cb)
-			asn1_cb(ASN1_OP_FREE_POST, pval, it);
+			asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
 		if (!combine)
 			{
 			OPENSSL_free(*pval);
@@ -149,7 +149,7 @@
 			return;
 		if (asn1_cb)
 			{
-			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it);
+			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
 			if (i == 2)
 				return;
 			}		
@@ -170,7 +170,7 @@
 			ASN1_template_free(pseqval, seqtt);
 			}
 		if (asn1_cb)
-			asn1_cb(ASN1_OP_FREE_POST, pval, it);
+			asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
 		if (!combine)
 			{
 			OPENSSL_free(*pval);
diff --git a/crypto/asn1/tasn_new.c b/crypto/asn1/tasn_new.c
index 5c6a2eb..0d9e78c 100644
--- a/crypto/asn1/tasn_new.c
+++ b/crypto/asn1/tasn_new.c
@@ -68,7 +68,7 @@
 								int combine);
 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
-void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
 
 ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
 	{
@@ -146,7 +146,7 @@
 		case ASN1_ITYPE_CHOICE:
 		if (asn1_cb)
 			{
-			i = asn1_cb(ASN1_OP_NEW_PRE, pval, it);
+			i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
 			if (!i)
 				goto auxerr;
 			if (i==2)
@@ -166,7 +166,7 @@
 			memset(*pval, 0, it->size);
 			}
 		asn1_set_choice_selector(pval, -1, it);
-		if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it))
+		if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
 				goto auxerr;
 		break;
 
@@ -174,7 +174,7 @@
 		case ASN1_ITYPE_SEQUENCE:
 		if (asn1_cb)
 			{
-			i = asn1_cb(ASN1_OP_NEW_PRE, pval, it);
+			i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
 			if (!i)
 				goto auxerr;
 			if (i==2)
@@ -201,7 +201,7 @@
 			if (!ASN1_template_new(pseqval, tt))
 				goto memerr;
 			}
-		if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it))
+		if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
 				goto auxerr;
 		break;
 	}
@@ -325,6 +325,7 @@
 int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
 	{
 	ASN1_TYPE *typ;
+	ASN1_STRING *str;
 	int utype;
 
 	if (it && it->funcs)
@@ -345,10 +346,7 @@
 		return 1;
 
 		case V_ASN1_BOOLEAN:
-		if (it)
-			*(ASN1_BOOLEAN *)pval = it->size;
-		else
-			*(ASN1_BOOLEAN *)pval = -1;
+		*(ASN1_BOOLEAN *)pval = it->size;
 		return 1;
 
 		case V_ASN1_NULL:
@@ -365,7 +363,10 @@
 		break;
 
 		default:
-		*pval = (ASN1_VALUE *)ASN1_STRING_type_new(utype);
+		str = ASN1_STRING_type_new(utype);
+		if (it->itype == ASN1_ITYPE_MSTRING && str)
+			str->flags |= ASN1_STRING_FLAG_MSTRING;
+		*pval = (ASN1_VALUE *)str;
 		break;
 		}
 	if (*pval)
@@ -373,7 +374,7 @@
 	return 0;
 	}
 
-void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
+static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
 	{
 	int utype;
 	if (it && it->funcs)
diff --git a/crypto/asn1/tasn_prn.c b/crypto/asn1/tasn_prn.c
index b9c96a6..4536980 100644
--- a/crypto/asn1/tasn_prn.c
+++ b/crypto/asn1/tasn_prn.c
@@ -3,7 +3,7 @@
  * project 2000.
  */
 /* ====================================================================
- * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 2000,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
@@ -58,141 +58,570 @@
 
 
 #include <stddef.h>
+#include "cryptlib.h"
 #include <openssl/asn1.h>
+#include <openssl/asn1t.h>
 #include <openssl/objects.h>
 #include <openssl/buffer.h>
 #include <openssl/err.h>
-#include <openssl/nasn.h>
+#include <openssl/x509v3.h>
+#include "asn1_locl.h"
 
-/* Print routines. Print out a whole structure from a template.
+/* Print routines.
  */
 
-static int asn1_item_print_nm(BIO *out, void *fld, int indent, const ASN1_ITEM *it, const char *name);
+/* ASN1_PCTX routines */
 
-int ASN1_item_print(BIO *out, void *fld, int indent, const ASN1_ITEM *it)
-{
-	return asn1_item_print_nm(out, fld, indent, it, it->sname);
-}
+ASN1_PCTX default_pctx = 
+	{
+	ASN1_PCTX_FLAGS_SHOW_ABSENT,	/* flags */
+	0,	/* nm_flags */
+	0,	/* cert_flags */
+	0,	/* oid_flags */
+	0	/* str_flags */
+	};
+	
 
-static int asn1_item_print_nm(BIO *out, void *fld, int indent, const ASN1_ITEM *it, const char *name)
-{
-	ASN1_STRING *str;
-	const ASN1_TEMPLATE *tt;
-	void *tmpfld;
-	int i;
-	if(!fld) {
-		BIO_printf(out, "%*s%s ABSENT\n", indent, "", name);
-		return 1;
+ASN1_PCTX *ASN1_PCTX_new(void)
+	{
+	ASN1_PCTX *ret;
+	ret = OPENSSL_malloc(sizeof(ASN1_PCTX));
+	if (ret == NULL)
+		{
+		ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+	ret->flags = 0;
+	ret->nm_flags = 0;
+	ret->cert_flags = 0;
+	ret->oid_flags = 0;
+	ret->str_flags = 0;
+	return ret;
 	}
-	switch(it->itype) {
 
+void ASN1_PCTX_free(ASN1_PCTX *p)
+	{
+	OPENSSL_free(p);
+	}
+
+unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p)
+	{
+	return p->flags;
+	}
+
+void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
+	{
+	p->flags = flags;
+	}
+
+unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p)
+	{
+	return p->nm_flags;
+	}
+
+void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
+	{
+	p->nm_flags = flags;
+	}
+
+unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p)
+	{
+	return p->cert_flags;
+	}
+
+void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
+	{
+	p->cert_flags = flags;
+	}
+
+unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p)
+	{
+	return p->oid_flags;
+	}
+
+void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
+	{
+	p->oid_flags = flags;
+	}
+
+unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p)
+	{
+	return p->str_flags;
+	}
+
+void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
+	{
+	p->str_flags = flags;
+	}
+
+/* Main print routines */
+
+static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+				const ASN1_ITEM *it,
+				const char *fname, const char *sname,
+				int nohdr, const ASN1_PCTX *pctx);
+
+int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+				const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
+
+static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
+				const ASN1_ITEM *it, int indent,
+				const char *fname, const char *sname,
+				const ASN1_PCTX *pctx);
+
+static int asn1_print_fsname(BIO *out, int indent,
+			const char *fname, const char *sname,
+			const ASN1_PCTX *pctx);
+
+int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
+				const ASN1_ITEM *it, const ASN1_PCTX *pctx)
+	{
+	const char *sname;
+	if (pctx == NULL)
+		pctx = &default_pctx;
+	if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
+		sname = NULL;
+	else
+		sname = it->sname;
+	return asn1_item_print_ctx(out, &ifld, indent, it,
+							NULL, sname, 0, pctx);
+	}
+
+static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+				const ASN1_ITEM *it,
+				const char *fname, const char *sname,
+				int nohdr, const ASN1_PCTX *pctx)
+	{
+	const ASN1_TEMPLATE *tt;
+	const ASN1_EXTERN_FUNCS *ef;
+	ASN1_VALUE **tmpfld;
+	const ASN1_AUX *aux = it->funcs;
+	ASN1_aux_cb *asn1_cb;
+	ASN1_PRINT_ARG parg;
+	int i;
+	if (aux && aux->asn1_cb)
+		{
+		parg.out = out;
+		parg.indent = indent;
+		parg.pctx = pctx;
+		asn1_cb = aux->asn1_cb;
+		}
+	else asn1_cb = 0;
+
+	if(*fld == NULL)
+		{
+		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT)
+			{
+			if (!nohdr && !asn1_print_fsname(out, indent,
+							fname, sname, pctx))
+				return 0;
+			if (BIO_puts(out, "<ABSENT>\n") <= 0)
+				return 0;
+			}
+		return 1;
+		}
+
+	switch(it->itype)
+		{
 		case ASN1_ITYPE_PRIMITIVE:
 		if(it->templates)
-			return ASN1_template_print(out, fld, indent, it->templates);
-		return asn1_primitive_print(out, fld, it->utype, indent, name);
+			{
+			if (!asn1_template_print_ctx(out, fld, indent,
+							it->templates, pctx))
+				return 0;
+			}
+		/* fall thru */
+		case ASN1_ITYPE_MSTRING:
+		if (!asn1_primitive_print(out, fld, it,
+				indent, fname, sname,pctx))
+			return 0;
 		break;
 
-		case ASN1_ITYPE_MSTRING:
-		str = fld;
-		return asn1_primitive_print(out, fld, str->type, indent, name);
-
 		case ASN1_ITYPE_EXTERN:
-		BIO_printf(out, "%*s%s:EXTERNAL TYPE %s %s\n", indent, "", name, it->sname, fld ? "" : "ABSENT");
-		return 1;
-		case ASN1_ITYPE_COMPAT:
-		BIO_printf(out, "%*s%s:COMPATIBLE TYPE %s %s\n", indent, "", name, it->sname, fld ? "" : "ABSENT");
-		return 1;
-
+		if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+			return 0;
+		/* Use new style print routine if possible */
+		ef = it->funcs;
+		if (ef && ef->asn1_ex_print)
+			{
+			i = ef->asn1_ex_print(out, fld, indent, "", pctx);
+			if (!i)
+				return 0;
+			if ((i == 2) && (BIO_puts(out, "\n") <= 0))
+				return 0;
+			return 1;
+			}
+		else if (sname && 
+			BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
+			return 0;
+		break;
 
 		case ASN1_ITYPE_CHOICE:
+#if 0
+		if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+			return 0;
+#endif
 		/* CHOICE type, get selector */
 		i = asn1_get_choice_selector(fld, it);
 		/* This should never happen... */
-		if((i < 0) || (i >= it->tcount)) {
-			BIO_printf(out, "%s selector [%d] out of range\n", it->sname, i);
+		if((i < 0) || (i >= it->tcount))
+			{
+			if (BIO_printf(out,
+				"ERROR: selector [%d] invalid\n", i) <= 0)
+				return 0;
 			return 1;
-		}
+			}
 		tt = it->templates + i;
-		tmpfld = asn1_get_field(fld, tt);
-		return ASN1_template_print(out, tmpfld, indent, tt);
+		tmpfld = asn1_get_field_ptr(fld, tt);
+		if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
+			return 0;
+		break;
 
 		case ASN1_ITYPE_SEQUENCE:
-		BIO_printf(out, "%*s%s {\n", indent, "", name);
-		/* Get each field entry */
-		for(i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
-			tmpfld = asn1_get_field(fld, tt);
-			ASN1_template_print(out, tmpfld, indent + 2, tt);
-		}
-		BIO_printf(out, "%*s}\n", indent, "");
-		return 1;
+		case ASN1_ITYPE_NDEF_SEQUENCE:
+		if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+			return 0;
+		if (fname || sname)
+			{
+			if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
+				{
+				if (BIO_puts(out, " {\n") <= 0)
+					return 0;
+				}
+			else
+				{
+				if (BIO_puts(out, "\n") <= 0)
+					return 0;
+				}
+			}
+
+		if (asn1_cb)
+			{
+			i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
+			if (i == 0)
+				return 0;
+			if (i == 2)
+				return 1;
+			}
+
+		/* Print each field entry */
+		for(i = 0, tt = it->templates; i < it->tcount; i++, tt++)
+			{
+			const ASN1_TEMPLATE *seqtt;
+			seqtt = asn1_do_adb(fld, tt, 1);
+			tmpfld = asn1_get_field_ptr(fld, seqtt);
+			if (!asn1_template_print_ctx(out, tmpfld,
+						indent + 2, seqtt, pctx))
+				return 0;
+			}
+		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
+			{
+			if (BIO_printf(out, "%*s}\n", indent, "") < 0)
+				return 0;
+			}
+
+		if (asn1_cb)
+			{
+			i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
+			if (i == 0)
+				return 0;
+			}
+		break;
 
 		default:
+		BIO_printf(out, "Unprocessed type %d\n", it->itype);
 		return 0;
-	}
-}
-
-int ASN1_template_print(BIO *out, void *fld, int indent, const ASN1_TEMPLATE *tt)
-{
-	int i, flags;
-#if 0
-	if(!fld) return 0; 
-#endif
-	flags = tt->flags;
-	if(flags & ASN1_TFLG_SK_MASK) {
-		char *tname;
-		void *skitem;
-		/* SET OF, SEQUENCE OF */
-		if(flags & ASN1_TFLG_SET_OF) tname = "SET";
-		else tname = "SEQUENCE";
-		if(fld) {
-			BIO_printf(out, "%*s%s OF %s {\n", indent, "", tname, tt->field_name);
-			for(i = 0; i < sk_num(fld); i++) {
-				skitem = sk_value(fld, i);
-				asn1_item_print_nm(out, skitem, indent + 2, tt->item, "");
-			}
-			BIO_printf(out, "%*s}\n", indent, "");
-		} else 
-			BIO_printf(out, "%*s%s OF %s ABSENT\n", indent, "", tname, tt->field_name);
-		return 1;
-	}
-	return asn1_item_print_nm(out, fld, indent, tt->item, tt->field_name);
-}
-
-static int asn1_primitive_print(BIO *out, void *fld, long utype, int indent, const char *name)
-{
-	ASN1_STRING *str = fld;
-	if(fld) {
-		if(utype == V_ASN1_BOOLEAN) {
-			int *bool = fld;
-if(*bool == -1) printf("BOOL MISSING\n");
-			BIO_printf(out, "%*s%s:%s", indent, "", "BOOLEAN", *bool ? "TRUE" : "FALSE");
-		} else if((utype == V_ASN1_INTEGER) 
-			  || (utype == V_ASN1_ENUMERATED)) {
-			char *s, *nm;
-			s = i2s_ASN1_INTEGER(NULL, fld);
-			if(utype == V_ASN1_INTEGER) nm = "INTEGER";
-			else nm = "ENUMERATED";
-			BIO_printf(out, "%*s%s:%s", indent, "", nm, s);
-			OPENSSL_free(s);
-		} else if(utype == V_ASN1_NULL) {
-			BIO_printf(out, "%*s%s", indent, "", "NULL");
-		} else if(utype == V_ASN1_UTCTIME) {
-			BIO_printf(out, "%*s%s:%s:", indent, "", name, "UTCTIME");
-			ASN1_UTCTIME_print(out, str);
-		} else if(utype == V_ASN1_GENERALIZEDTIME) {
-			BIO_printf(out, "%*s%s:%s:", indent, "", name, "GENERALIZEDTIME");
-			ASN1_GENERALIZEDTIME_print(out, str);
-		} else if(utype == V_ASN1_OBJECT) {
-			char objbuf[80], *ln;
-			ln = OBJ_nid2ln(OBJ_obj2nid(fld));
-			if(!ln) ln = "";
-			OBJ_obj2txt(objbuf, sizeof objbuf, fld, 1);
-			BIO_printf(out, "%*s%s:%s (%s)", indent, "", "OBJECT", ln, objbuf);
-		} else {
-			BIO_printf(out, "%*s%s:", indent, "", name);
-			ASN1_STRING_print_ex(out, str, ASN1_STRFLGS_DUMP_UNKNOWN|ASN1_STRFLGS_SHOW_TYPE);
 		}
-		BIO_printf(out, "\n");
-	} else BIO_printf(out, "%*s%s [ABSENT]\n", indent, "", name);
+
 	return 1;
-}
+	}
+
+int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+				const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
+	{
+	int i, flags;
+	const char *sname, *fname;
+	flags = tt->flags;
+	if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
+		sname = ASN1_ITEM_ptr(tt->item)->sname;
+	else
+		sname = NULL;
+	if(pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
+		fname = NULL;
+	else
+		fname = tt->field_name;
+	if(flags & ASN1_TFLG_SK_MASK)
+		{
+		char *tname;
+		ASN1_VALUE *skitem;
+		STACK_OF(ASN1_VALUE) *stack;
+
+		/* SET OF, SEQUENCE OF */
+		if (fname)
+			{
+			if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF)
+				{
+				if(flags & ASN1_TFLG_SET_OF)
+					tname = "SET";
+				else
+					tname = "SEQUENCE";
+				if (BIO_printf(out, "%*s%s OF %s {\n",
+					indent, "", tname, tt->field_name) <= 0)
+					return 0;
+				}
+			else if (BIO_printf(out, "%*s%s:\n", indent, "",
+					fname) <= 0)
+				return 0;
+			}
+		stack = (STACK_OF(ASN1_VALUE) *)*fld;
+		for(i = 0; i < sk_ASN1_VALUE_num(stack); i++)
+			{
+			if ((i > 0) && (BIO_puts(out, "\n") <= 0))
+				return 0;
+
+			skitem = sk_ASN1_VALUE_value(stack, i);
+			if (!asn1_item_print_ctx(out, &skitem, indent + 2,
+				ASN1_ITEM_ptr(tt->item), NULL, NULL, 1, pctx))
+				return 0;
+			}
+		if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
+				return 0;
+		if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
+			{
+			if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
+				return 0;
+			}
+		return 1;
+		}
+	return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
+							fname, sname, 0, pctx);
+	}
+
+static int asn1_print_fsname(BIO *out, int indent,
+			const char *fname, const char *sname,
+			const ASN1_PCTX *pctx)
+	{
+	static char spaces[] = "                    ";
+	const int nspaces = sizeof(spaces) - 1;
+
+#if 0
+	if (!sname && !fname)
+		return 1;
+#endif
+
+	while (indent > nspaces)
+		{
+		if (BIO_write(out, spaces, nspaces) != nspaces)
+			return 0;
+		indent -= nspaces;
+		}
+	if (BIO_write(out, spaces, indent) != indent)
+		return 0;
+	if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
+		sname = NULL;
+	if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
+		fname = NULL;
+	if (!sname && !fname)
+		return 1;
+	if (fname)
+		{
+		if (BIO_puts(out, fname) <= 0)
+			return 0;
+		}
+	if (sname)
+		{
+		if (fname)
+			{
+			if (BIO_printf(out, " (%s)", sname) <= 0)
+				return 0;
+			}
+		else
+			{
+			if (BIO_puts(out, sname) <= 0)
+				return 0;
+			}
+		}
+	if (BIO_write(out, ": ", 2) != 2)
+		return 0;
+	return 1;
+	}
+
+static int asn1_print_boolean_ctx(BIO *out, const int bool,
+							const ASN1_PCTX *pctx)
+	{
+	const char *str;
+	switch (bool)
+		{
+		case -1:
+		str = "BOOL ABSENT";
+		break;
+
+		case 0:
+		str = "FALSE";
+		break;
+
+		default:
+		str = "TRUE";
+		break;
+
+		}
+
+	if (BIO_puts(out, str) <= 0)
+		return 0;
+	return 1;
+
+	}
+
+static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str,
+						const ASN1_PCTX *pctx)
+	{
+	char *s;
+	int ret = 1;
+	s = i2s_ASN1_INTEGER(NULL, str);
+	if (BIO_puts(out, s) <= 0)
+		ret = 0;
+	OPENSSL_free(s);
+	return ret;
+	}
+
+static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid,
+						const ASN1_PCTX *pctx)
+	{
+	char objbuf[80];
+	const char *ln;
+	ln = OBJ_nid2ln(OBJ_obj2nid(oid));
+	if(!ln)
+		ln = "";
+	OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
+	if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
+		return 0;
+	return 1;
+	}
+
+static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent,
+						const ASN1_PCTX *pctx)
+	{
+	if (str->type == V_ASN1_BIT_STRING)
+		{
+		if (BIO_printf(out, " (%ld unused bits)\n",
+					str->flags & 0x7) <= 0)
+				return 0;
+		}
+	else if (BIO_puts(out, "\n") <= 0)
+		return 0;
+	if ((str->length > 0)
+		&& BIO_dump_indent(out, (char *)str->data, str->length,
+				indent + 2) <= 0)
+		return 0;
+	return 1;
+	}
+
+static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
+				const ASN1_ITEM *it, int indent,
+				const char *fname, const char *sname,
+				const ASN1_PCTX *pctx)
+	{
+	long utype;
+	ASN1_STRING *str;
+	int ret = 1, needlf = 1;
+	const char *pname;
+	const ASN1_PRIMITIVE_FUNCS *pf;
+	pf = it->funcs;
+	if (!asn1_print_fsname(out, indent, fname, sname, pctx))
+			return 0;
+	if (pf && pf->prim_print)
+		return pf->prim_print(out, fld, it, indent, pctx);
+	str = (ASN1_STRING *)*fld;
+	if (it->itype == ASN1_ITYPE_MSTRING)
+		utype = str->type & ~V_ASN1_NEG;
+	else
+		utype = it->utype;
+	if (utype == V_ASN1_ANY)
+		{
+		ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
+		utype = atype->type;
+		fld = &atype->value.asn1_value;
+		str = (ASN1_STRING *)*fld;
+		if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
+			pname = NULL;
+		else 
+			pname = ASN1_tag2str(utype);
+		}
+	else
+		{
+		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
+			pname = ASN1_tag2str(utype);
+		else 
+			pname = NULL;
+		}
+
+	if (utype == V_ASN1_NULL)
+		{
+		if (BIO_puts(out, "NULL\n") <= 0)
+			return 0;
+		return 1;
+		}
+
+	if (pname)
+		{
+		if (BIO_puts(out, pname) <= 0)
+			return 0;
+		if (BIO_puts(out, ":") <= 0)
+			return 0;
+		}
+
+	switch (utype)
+		{
+		case V_ASN1_BOOLEAN:
+			{
+			int bool = *(int *)fld;
+			if (bool == -1)
+				bool = it->size;
+			ret = asn1_print_boolean_ctx(out, bool, pctx);
+			}
+		break;
+
+		case V_ASN1_INTEGER:
+		case V_ASN1_ENUMERATED:
+		ret = asn1_print_integer_ctx(out, str, pctx);
+		break;
+
+		case V_ASN1_UTCTIME:
+		ret = ASN1_UTCTIME_print(out, str);
+		break;
+
+		case V_ASN1_GENERALIZEDTIME:
+		ret = ASN1_GENERALIZEDTIME_print(out, str);
+		break;
+
+		case V_ASN1_OBJECT:
+		ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx);
+		break;
+
+		case V_ASN1_OCTET_STRING:
+		case V_ASN1_BIT_STRING:
+		ret = asn1_print_obstring_ctx(out, str, indent, pctx);
+		needlf = 0;
+		break;
+
+		case V_ASN1_SEQUENCE:
+		case V_ASN1_SET:
+		case V_ASN1_OTHER:
+		if (BIO_puts(out, "\n") <= 0)
+			return 0;
+		if (ASN1_parse_dump(out, str->data, str->length,
+						indent, 0) <= 0)
+			ret = 0;
+		needlf = 0;
+		break;
+
+		default:
+		ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
+
+		}
+	if (!ret)
+		return 0;
+	if (needlf && BIO_puts(out, "\n") <= 0)
+		return 0;
+	return 1;
+	}
diff --git a/crypto/asn1/tasn_typ.c b/crypto/asn1/tasn_typ.c
index 6252213..6fb1c37 100644
--- a/crypto/asn1/tasn_typ.c
+++ b/crypto/asn1/tasn_typ.c
@@ -135,3 +135,14 @@
 /* Special, OCTET STRING with indefinite length constructed support */
 
 IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF)
+
+ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY)
+ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY)
+
+ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY)
+ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY)
diff --git a/crypto/asn1/x_crl.c b/crypto/asn1/x_crl.c
index 70d56a6..c51c690 100644
--- a/crypto/asn1/x_crl.c
+++ b/crypto/asn1/x_crl.c
@@ -58,11 +58,14 @@
 
 #include <stdio.h>
 #include "cryptlib.h"
+#include "asn1_locl.h"
 #include <openssl/asn1t.h>
 #include <openssl/x509.h>
+#include <openssl/x509v3.h>
 
 static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
 				const X509_REVOKED * const *b);
+static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
 
 ASN1_SEQUENCE(X509_REVOKED) = {
 	ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
@@ -70,11 +73,26 @@
 	ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION)
 } ASN1_SEQUENCE_END(X509_REVOKED)
 
+static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r);
+static int def_crl_lookup(X509_CRL *crl,
+		X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer);
+
+static X509_CRL_METHOD int_crl_meth =
+	{
+	0,
+	0,0,
+	def_crl_lookup,
+	def_crl_verify
+	};
+
+static const X509_CRL_METHOD *default_crl_method = &int_crl_meth;
+
 /* The X509_CRL_INFO structure needs a bit of customisation.
  * Since we cache the original encoding the signature wont be affected by
  * reordering of the revoked field.
  */
-static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+								void *exarg)
 {
 	X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
 
@@ -101,7 +119,237 @@
 	ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
 } ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO)
 
-ASN1_SEQUENCE_ref(X509_CRL, 0, CRYPTO_LOCK_X509_CRL) = {
+/* Set CRL entry issuer according to CRL certificate issuer extension.
+ * Check for unhandled critical CRL entry extensions.
+ */
+
+static int crl_set_issuers(X509_CRL *crl)
+	{
+
+	int i, j;
+	GENERAL_NAMES *gens, *gtmp;
+	STACK_OF(X509_REVOKED) *revoked;
+
+	revoked = X509_CRL_get_REVOKED(crl);
+
+	gens = NULL;
+	for (i = 0; i < sk_X509_REVOKED_num(revoked); i++)
+		{
+		X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
+		STACK_OF(X509_EXTENSION) *exts;
+		ASN1_ENUMERATED *reason;
+		X509_EXTENSION *ext;
+		gtmp = X509_REVOKED_get_ext_d2i(rev, 
+						NID_certificate_issuer,
+						&j, NULL);
+		if (!gtmp && (j != -1))
+			{
+			crl->flags |= EXFLAG_INVALID;
+			return 1;
+			}
+
+		if (gtmp)
+			{
+			gens = gtmp;
+			if (!crl->issuers)
+				{
+				crl->issuers = sk_GENERAL_NAMES_new_null();
+				if (!crl->issuers)
+					return 0;
+				}
+			if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
+				return 0;
+			}
+		rev->issuer = gens;
+
+		reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason,
+								&j, NULL);
+		if (!reason && (j != -1))
+			{
+			crl->flags |= EXFLAG_INVALID;
+			return 1;
+			}
+
+		if (reason)
+			{
+			rev->reason = ASN1_ENUMERATED_get(reason);
+			ASN1_ENUMERATED_free(reason);
+			}
+		else
+			rev->reason = CRL_REASON_NONE;	
+
+		/* Check for critical CRL entry extensions */
+
+		exts = rev->extensions;
+
+		for (j = 0; j < sk_X509_EXTENSION_num(exts); j++)
+			{
+			ext = sk_X509_EXTENSION_value(exts, j);
+			if (ext->critical > 0)
+				{
+				if (OBJ_obj2nid(ext->object) ==
+					NID_certificate_issuer)
+					continue;
+				crl->flags |= EXFLAG_CRITICAL;
+				break;
+				}
+			}
+
+
+		}
+
+	return 1;
+
+	}
+
+/* The X509_CRL structure needs a bit of customisation. Cache some extensions
+ * and hash of the whole CRL.
+ */
+static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+								void *exarg)
+	{
+	X509_CRL *crl = (X509_CRL *)*pval;
+	STACK_OF(X509_EXTENSION) *exts;
+	X509_EXTENSION *ext;
+	int idx;
+
+	switch(operation)
+		{
+		case ASN1_OP_NEW_POST:
+		crl->idp = NULL;
+		crl->akid = NULL;
+		crl->flags = 0;
+		crl->idp_flags = 0;
+		crl->idp_reasons = CRLDP_ALL_REASONS;
+		crl->meth = default_crl_method;
+		crl->meth_data = NULL;
+		crl->issuers = NULL;
+		crl->crl_number = NULL;
+		crl->base_crl_number = NULL;
+		break;
+
+		case ASN1_OP_D2I_POST:
+#ifndef OPENSSL_NO_SHA
+		X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
+#endif
+		crl->idp = X509_CRL_get_ext_d2i(crl,
+				NID_issuing_distribution_point, NULL, NULL);
+		if (crl->idp)
+			setup_idp(crl, crl->idp);
+
+		crl->akid = X509_CRL_get_ext_d2i(crl,
+				NID_authority_key_identifier, NULL, NULL);	
+
+		crl->crl_number = X509_CRL_get_ext_d2i(crl,
+				NID_crl_number, NULL, NULL);	
+
+		crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
+				NID_delta_crl, NULL, NULL);	
+		/* Delta CRLs must have CRL number */
+		if (crl->base_crl_number && !crl->crl_number)
+			crl->flags |= EXFLAG_INVALID;
+
+		/* See if we have any unhandled critical CRL extensions and 
+		 * indicate this in a flag. We only currently handle IDP so
+		 * anything else critical sets the flag.
+		 *
+		 * This code accesses the X509_CRL structure directly:
+		 * applications shouldn't do this.
+		 */
+
+		exts = crl->crl->extensions;
+
+		for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++)
+			{
+			int nid;
+			ext = sk_X509_EXTENSION_value(exts, idx);
+			nid = OBJ_obj2nid(ext->object);
+			if (nid == NID_freshest_crl)
+				crl->flags |= EXFLAG_FRESHEST;
+			if (ext->critical > 0)
+				{
+				/* We handle IDP and deltas */
+				if ((nid == NID_issuing_distribution_point)
+					|| (nid == NID_delta_crl))
+					break;;
+				crl->flags |= EXFLAG_CRITICAL;
+				break;
+				}
+			}
+
+
+		if (!crl_set_issuers(crl))
+			return 0;
+
+		if (crl->meth->crl_init)
+			{
+			if (crl->meth->crl_init(crl) == 0)
+				return 0;
+			}
+		break;
+
+		case ASN1_OP_FREE_POST:
+		if (crl->meth->crl_free)
+			{
+			if (!crl->meth->crl_free(crl))
+				return 0;
+			}
+		if (crl->akid)
+			AUTHORITY_KEYID_free(crl->akid);
+		if (crl->idp)
+			ISSUING_DIST_POINT_free(crl->idp);
+		ASN1_INTEGER_free(crl->crl_number);
+		ASN1_INTEGER_free(crl->base_crl_number);
+		sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
+		break;
+		}
+	return 1;
+	}
+
+/* Convert IDP into a more convenient form */
+
+static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
+	{
+	int idp_only = 0;
+	/* Set various flags according to IDP */
+	crl->idp_flags |= IDP_PRESENT;
+	if (idp->onlyuser > 0)
+		{
+		idp_only++;
+		crl->idp_flags |= IDP_ONLYUSER;
+		}
+	if (idp->onlyCA > 0)
+		{
+		idp_only++;
+		crl->idp_flags |= IDP_ONLYCA;
+		}
+	if (idp->onlyattr > 0)
+		{
+		idp_only++;
+		crl->idp_flags |= IDP_ONLYATTR;
+		}
+
+	if (idp_only > 1)
+		crl->idp_flags |= IDP_INVALID;
+
+	if (idp->indirectCRL > 0)
+		crl->idp_flags |= IDP_INDIRECT;
+
+	if (idp->onlysomereasons)
+		{
+		crl->idp_flags |= IDP_REASONS;
+		if (idp->onlysomereasons->length > 0)
+			crl->idp_reasons = idp->onlysomereasons->data[0];
+		if (idp->onlysomereasons->length > 1)
+			crl->idp_reasons |=
+				(idp->onlysomereasons->data[1] << 8);
+		crl->idp_reasons &= CRLDP_ALL_REASONS;
+		}
+
+	DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
+	}
+
+ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = {
 	ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
 	ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
 	ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING)
@@ -134,6 +382,145 @@
 	return 1;
 }
 
+int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r)
+	{
+	if (crl->meth->crl_verify)
+		return crl->meth->crl_verify(crl, r);
+	return 0;
+	}
+
+int X509_CRL_get0_by_serial(X509_CRL *crl,
+		X509_REVOKED **ret, ASN1_INTEGER *serial)
+	{
+	if (crl->meth->crl_lookup)
+		return crl->meth->crl_lookup(crl, ret, serial, NULL);
+	return 0;
+	}
+
+int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)
+	{
+	if (crl->meth->crl_lookup)
+		return crl->meth->crl_lookup(crl, ret,
+						X509_get_serialNumber(x),
+						X509_get_issuer_name(x));
+	return 0;
+	}
+
+static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r)
+	{
+	return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
+		crl->sig_alg, crl->signature,crl->crl,r));
+	}
+
+static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm,
+						X509_REVOKED *rev)
+	{
+	int i;
+
+	if (!rev->issuer)
+		{
+		if (!nm)
+			return 1;
+		if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
+			return 1;
+		return 0;
+		}
+
+	if (!nm)
+		nm = X509_CRL_get_issuer(crl);
+
+	for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++)
+		{
+		GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
+		if (gen->type != GEN_DIRNAME)
+			continue;
+		if (!X509_NAME_cmp(nm, gen->d.directoryName))
+			return 1;
+		}
+	return 0;
+
+	}
+
+static int def_crl_lookup(X509_CRL *crl,
+		X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer)
+	{
+	X509_REVOKED rtmp, *rev;
+	int idx;
+	rtmp.serialNumber = serial;
+	/* Sort revoked into serial number order if not already sorted.
+	 * Do this under a lock to avoid race condition.
+ 	 */
+	if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))
+		{
+		CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
+		sk_X509_REVOKED_sort(crl->crl->revoked);
+		CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
+		}
+	idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);
+	if(idx < 0)
+		return 0;
+	/* Need to look for matching name */
+	for(;idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++)
+		{
+		rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
+		if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
+			return 0;
+		if (crl_revoked_issuer_match(crl, issuer, rev))
+			{
+			if (ret)
+				*ret = rev;
+			if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
+				return 2;
+			return 1;
+			}
+		}
+	return 0;
+	}
+
+void X509_CRL_set_default_method(const X509_CRL_METHOD *meth)
+	{
+	if (meth == NULL)
+		default_crl_method = &int_crl_meth;
+	else 
+		default_crl_method = meth;
+	}
+
+X509_CRL_METHOD *X509_CRL_METHOD_new(
+	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))
+	{
+	X509_CRL_METHOD *m;
+	m = OPENSSL_malloc(sizeof(X509_CRL_METHOD));
+	if (!m)
+		return NULL;
+	m->crl_init = crl_init;
+	m->crl_free = crl_free;
+	m->crl_lookup = crl_lookup;
+	m->crl_verify = crl_verify;
+	m->flags = X509_CRL_METHOD_DYNAMIC;
+	return m;
+	}
+
+void X509_CRL_METHOD_free(X509_CRL_METHOD *m)
+	{
+	if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
+		return;
+	OPENSSL_free(m);
+	}
+
+void X509_CRL_set_meth_data(X509_CRL *crl, void *dat)
+	{
+	crl->meth_data = dat;
+	}
+
+void *X509_CRL_get_meth_data(X509_CRL *crl)
+	{
+	return crl->meth_data;
+	}
+
 IMPLEMENT_STACK_OF(X509_REVOKED)
 IMPLEMENT_ASN1_SET_OF(X509_REVOKED)
 IMPLEMENT_STACK_OF(X509_CRL)
diff --git a/crypto/asn1/x_long.c b/crypto/asn1/x_long.c
index bf35457..7531741 100644
--- a/crypto/asn1/x_long.c
+++ b/crypto/asn1/x_long.c
@@ -71,6 +71,7 @@
 
 static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
 static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
+static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
 
 static ASN1_PRIMITIVE_FUNCS long_pf = {
 	NULL, 0,
@@ -78,7 +79,8 @@
 	long_free,
 	long_free,	/* Clear should set to initial value */
 	long_c2i,
-	long_i2c
+	long_i2c,
+	long_print
 };
 
 ASN1_ITEM_start(LONG)
@@ -169,3 +171,9 @@
 	memcpy(cp, &ltmp, sizeof(long));
 	return 1;
 }
+
+static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+			int indent, const ASN1_PCTX *pctx)
+	{
+	return BIO_printf(out, "%ld\n", *(long *)pval);
+	}
diff --git a/crypto/asn1/x_name.c b/crypto/asn1/x_name.c
index 04380ab..caa4409 100644
--- a/crypto/asn1/x_name.c
+++ b/crypto/asn1/x_name.c
@@ -57,18 +57,36 @@
  */
 
 #include <stdio.h>
+#include <ctype.h>
 #include "cryptlib.h"
 #include <openssl/asn1t.h>
 #include <openssl/x509.h>
+#include "asn1_locl.h"
 
-static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it,
-					int tag, int aclass, char opt, ASN1_TLC *ctx);
+typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
+DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
 
-static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
+static int x509_name_ex_d2i(ASN1_VALUE **val,
+				const unsigned char **in, long len,
+				const ASN1_ITEM *it,
+				int tag, int aclass, char opt, ASN1_TLC *ctx);
+
+static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
+				const ASN1_ITEM *it, int tag, int aclass);
 static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
 static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
 
 static int x509_name_encode(X509_NAME *a);
+static int x509_name_canon(X509_NAME *a);
+static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in);
+static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname,
+			  unsigned char **in);
+
+
+static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
+						int indent,
+						const char *fname, 
+						const ASN1_PCTX *pctx);
 
 ASN1_SEQUENCE(X509_NAME_ENTRY) = {
 	ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
@@ -102,7 +120,8 @@
 	x509_name_ex_free,
 	0,	/* Default clear behaviour is OK */
 	x509_name_ex_d2i,
-	x509_name_ex_i2d
+	x509_name_ex_i2d,
+	x509_name_ex_print
 };
 
 IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) 
@@ -118,6 +137,8 @@
 	if ((ret->entries=sk_X509_NAME_ENTRY_new_null()) == NULL)
 		goto memerr;
 	if((ret->bytes = BUF_MEM_new()) == NULL) goto memerr;
+	ret->canon_enc = NULL;
+	ret->canon_enclen = 0;
 	ret->modified=1;
 	*val = (ASN1_VALUE *)ret;
 	return 1;
@@ -142,25 +163,19 @@
 
 	BUF_MEM_free(a->bytes);
 	sk_X509_NAME_ENTRY_pop_free(a->entries,X509_NAME_ENTRY_free);
+	if (a->canon_enc)
+		OPENSSL_free(a->canon_enc);
 	OPENSSL_free(a);
 	*pval = NULL;
 }
 
-/* Used with sk_pop_free() to free up the internal representation.
- * NB: we only free the STACK and not its contents because it is
- * already present in the X509_NAME structure.
- */
-
-static void sk_internal_free(void *a)
-{
-	sk_free(a);
-}
-
-static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it,
-					int tag, int aclass, char opt, ASN1_TLC *ctx)
+static int x509_name_ex_d2i(ASN1_VALUE **val,
+			const unsigned char **in, long len, const ASN1_ITEM *it,
+				int tag, int aclass, char opt, ASN1_TLC *ctx)
 {
 	const unsigned char *p = *in, *q;
-	union { STACK *s; ASN1_VALUE *a; } intname = {NULL};
+	union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
+		ASN1_VALUE *a; } intname = {NULL};
 	union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL};
 	int i, j, ret;
 	STACK_OF(X509_NAME_ENTRY) *entries;
@@ -181,8 +196,8 @@
 	memcpy(nm.x->bytes->data, q, p - q);
 
 	/* Convert internal representation to X509_NAME structure */
-	for(i = 0; i < sk_num(intname.s); i++) {
-		entries = (STACK_OF(X509_NAME_ENTRY) *)sk_value(intname.s, i);
+	for(i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
+		entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
 		for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
 			entry = sk_X509_NAME_ENTRY_value(entries, j);
 			entry->set = i;
@@ -191,7 +206,10 @@
 		}
 		sk_X509_NAME_ENTRY_free(entries);
 	}
-	sk_free(intname.s);
+	sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
+	ret = x509_name_canon(nm.x);
+	if (!ret)
+		goto err;
 	nm.x->modified = 0;
 	*val = nm.a;
 	*in = p;
@@ -206,8 +224,12 @@
 	int ret;
 	X509_NAME *a = (X509_NAME *)*val;
 	if(a->modified) {
-		ret = x509_name_encode((X509_NAME *)a);
-		if(ret < 0) return ret;
+		ret = x509_name_encode(a);
+		if(ret < 0)
+			return ret;
+		ret = x509_name_canon(a);
+		if(ret < 0)
+			return ret;
 	}
 	ret = a->bytes->length;
 	if(out != NULL) {
@@ -217,22 +239,35 @@
 	return ret;
 }
 
+static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
+	{
+	sk_X509_NAME_ENTRY_free(ne);
+	}
+
+static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
+	{
+	sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
+	}
+
 static int x509_name_encode(X509_NAME *a)
 {
-	union { STACK *s; ASN1_VALUE *a; } intname = {NULL};
+	union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
+		ASN1_VALUE *a; } intname = {NULL};
 	int len;
 	unsigned char *p;
 	STACK_OF(X509_NAME_ENTRY) *entries = NULL;
 	X509_NAME_ENTRY *entry;
 	int i, set = -1;
-	intname.s = sk_new_null();
+	intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
 	if(!intname.s) goto memerr;
 	for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
 		entry = sk_X509_NAME_ENTRY_value(a->entries, i);
 		if(entry->set != set) {
 			entries = sk_X509_NAME_ENTRY_new_null();
 			if(!entries) goto memerr;
-			if(!sk_push(intname.s, (char *)entries)) goto memerr;
+			if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s,
+							     entries))
+				goto memerr;
 			set = entry->set;
 		}
 		if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr;
@@ -243,15 +278,222 @@
 	p=(unsigned char *)a->bytes->data;
 	ASN1_item_ex_i2d(&intname.a,
 			 &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
-	sk_pop_free(intname.s, sk_internal_free);
+	sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+					     local_sk_X509_NAME_ENTRY_free);
 	a->modified = 0;
 	return len;
-	memerr:
-	sk_pop_free(intname.s, sk_internal_free);
+memerr:
+	sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+					     local_sk_X509_NAME_ENTRY_free);
 	ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE);
 	return -1;
 }
 
+static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
+						int indent,
+						const char *fname, 
+						const ASN1_PCTX *pctx)
+	{
+	if (X509_NAME_print_ex(out, (X509_NAME *)*pval,
+					indent, pctx->nm_flags) <= 0)
+		return 0;
+	return 2;
+	}
+
+/* This function generates the canonical encoding of the Name structure.
+ * In it all strings are converted to UTF8, leading, trailing and
+ * multiple spaces collapsed, converted to lower case and the leading
+ * SEQUENCE header removed.
+ *
+ * In future we could also normalize the UTF8 too.
+ *
+ * By doing this comparison of Name structures can be rapidly
+ * perfomed by just using memcmp() of the canonical encoding.
+ * By omitting the leading SEQUENCE name constraints of type
+ * dirName can also be checked with a simple memcmp().
+ */
+
+static int x509_name_canon(X509_NAME *a)
+	{
+	unsigned char *p;
+	STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
+	STACK_OF(X509_NAME_ENTRY) *entries = NULL;
+	X509_NAME_ENTRY *entry, *tmpentry = NULL;
+	int i, set = -1, ret = 0;
+
+	if (a->canon_enc)
+		{
+		OPENSSL_free(a->canon_enc);
+		a->canon_enc = NULL;
+		}
+	/* Special case: empty X509_NAME => null encoding */
+	if (sk_X509_NAME_ENTRY_num(a->entries) == 0)
+		{
+		a->canon_enclen = 0;
+		return 1;
+		}
+	intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
+	if(!intname)
+		goto err;
+	for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++)
+		{
+		entry = sk_X509_NAME_ENTRY_value(a->entries, i);
+		if(entry->set != set)
+			{
+			entries = sk_X509_NAME_ENTRY_new_null();
+			if(!entries)
+				goto err;
+			if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries))
+				goto err;
+			set = entry->set;
+			}
+		tmpentry = X509_NAME_ENTRY_new();
+		tmpentry->object = OBJ_dup(entry->object);
+		if (!asn1_string_canon(tmpentry->value, entry->value))
+			goto err;
+		if(!sk_X509_NAME_ENTRY_push(entries, tmpentry))
+			goto err;
+		tmpentry = NULL;
+		}
+
+	/* Finally generate encoding */
+
+	a->canon_enclen = i2d_name_canon(intname, NULL);
+
+	p = OPENSSL_malloc(a->canon_enclen);
+
+	if (!p)
+		goto err;
+
+	a->canon_enc = p;
+
+	i2d_name_canon(intname, &p);
+
+	ret = 1;
+
+	err:
+
+	if (tmpentry)
+		X509_NAME_ENTRY_free(tmpentry);
+	if (intname)
+		sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
+					local_sk_X509_NAME_ENTRY_pop_free);
+	return ret;
+	}
+
+/* Bitmap of all the types of string that will be canonicalized. */
+
+#define ASN1_MASK_CANON	\
+	(B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
+	| B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
+	| B_ASN1_VISIBLESTRING)
+	
+
+static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
+	{
+	unsigned char *to, *from;
+	int len, i;
+
+	/* If type not in bitmask just copy string across */
+	if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON))
+		{
+		out->type = in->type;
+		if (!ASN1_STRING_set(out, in->data, in->length))
+			return 0;
+		return 1;
+		}
+
+	out->type = V_ASN1_UTF8STRING;
+	out->length = ASN1_STRING_to_UTF8(&out->data, in);
+	if (out->length == -1)
+		return 0;
+
+	to = out->data;
+	from = to;
+
+	len = out->length;
+
+	/* Convert string in place to canonical form.
+	 * Ultimately we may need to handle a wider range of characters
+	 * but for now ignore anything with MSB set and rely on the
+	 * isspace() and tolower() functions.
+	 */
+
+	/* Ignore leading spaces */
+	while((len > 0) && !(*from & 0x80) && isspace(*from))
+		{
+		from++;
+		len--;
+		}
+
+	to = from + len - 1;
+
+	/* Ignore trailing spaces */
+	while ((len > 0) && !(*to & 0x80) && isspace(*to))
+		{
+		to--;
+		len--;
+		}
+
+	to = out->data;
+
+	i = 0;
+	while(i < len)
+		{
+		/* If MSB set just copy across */
+		if (*from & 0x80)
+			{
+			*to++ = *from++;
+			i++;
+			}
+		/* Collapse multiple spaces */
+		else if (isspace(*from))
+			{
+			/* Copy one space across */
+			*to++ = ' ';
+			/* Ignore subsequent spaces. Note: don't need to
+			 * check len here because we know the last 
+			 * character is a non-space so we can't overflow.
+			 */
+			do
+				{
+				from++;
+				i++;
+				}
+			while(!(*from & 0x80) && isspace(*from));
+			}
+		else
+			{
+			*to++ = tolower(*from++);
+			i++;
+			}
+		}
+
+	out->length = to - out->data;
+
+	return 1;
+
+	}
+
+static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname,
+			  unsigned char **in)
+	{
+	int i, len, ltmp;
+	ASN1_VALUE *v;
+	STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
+
+	len = 0;
+	for (i = 0; i < sk_ASN1_VALUE_num(intname); i++)
+		{
+		v = sk_ASN1_VALUE_value(intname, i);
+		ltmp = ASN1_item_ex_i2d(&v, in,
+			ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
+		if (ltmp < 0)
+			return ltmp;
+		len += ltmp;
+		}
+	return len;
+	}
 
 int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
 	{
diff --git a/crypto/rc4/rc4_fblk.c b/crypto/asn1/x_nx509.c
similarity index 79%
rename from crypto/rc4/rc4_fblk.c
rename to crypto/asn1/x_nx509.c
index 1b2a429..fbd9a22 100644
--- a/crypto/rc4/rc4_fblk.c
+++ b/crypto/asn1/x_nx509.c
@@ -1,9 +1,9 @@
-/* crypto/rc4/rc4_fblk.c */
+/* x_nx509.c */
 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project.
+ * project 2005.
  */
 /* ====================================================================
- * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ * 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
@@ -49,27 +49,24 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
  */
 
+#include <stddef.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
 
-#include <openssl/rc4.h>
-#include "rc4_locl.h"
-#include <openssl/opensslv.h>
-#include <openssl/crypto.h>
-#ifdef OPENSSL_FIPS
-#include <openssl/fips.h>
-#endif
+/* Old netscape certificate wrapper format */
 
-/* FIPS mode blocking for RC4 has to be done separately since RC4_set_key
- * may be implemented in an assembly language file.
- */
+ASN1_SEQUENCE(NETSCAPE_X509) = {
+	ASN1_SIMPLE(NETSCAPE_X509, header, ASN1_OCTET_STRING),
+	ASN1_OPT(NETSCAPE_X509, cert, X509)
+} ASN1_SEQUENCE_END(NETSCAPE_X509)
 
-#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
+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_X509)
 
diff --git a/crypto/asn1/x_pubkey.c b/crypto/asn1/x_pubkey.c
index 91c2756..d42b6a2 100644
--- a/crypto/asn1/x_pubkey.c
+++ b/crypto/asn1/x_pubkey.c
@@ -60,6 +60,7 @@
 #include "cryptlib.h"
 #include <openssl/asn1t.h>
 #include <openssl/x509.h>
+#include "asn1_locl.h"
 #ifndef OPENSSL_NO_RSA
 #include <openssl/rsa.h>
 #endif
@@ -68,7 +69,8 @@
 #endif
 
 /* Minor tweak to operation: free up EVP_PKEY */
-static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+			void *exarg)
 	{
 	if (operation == ASN1_OP_FREE_POST)
 		{
@@ -88,169 +90,42 @@
 int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
 	{
 	X509_PUBKEY *pk=NULL;
-	X509_ALGOR *a;
-	ASN1_OBJECT *o;
-	unsigned char *s,*p = NULL;
-	int i;
 
 	if (x == NULL) return(0);
 
-	if ((pk=X509_PUBKEY_new()) == NULL) goto err;
-	a=pk->algor;
+	if ((pk=X509_PUBKEY_new()) == NULL) goto error;
 
-	/* set the algorithm id */
-	if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err;
-	ASN1_OBJECT_free(a->algorithm);
-	a->algorithm=o;
-
-	/* Set the parameter list */
-	if (!pkey->save_parameters || (pkey->type == EVP_PKEY_RSA))
+	if (pkey->ameth)
 		{
-		if ((a->parameter == NULL) ||
-			(a->parameter->type != V_ASN1_NULL))
+		if (pkey->ameth->pub_encode)
 			{
-			ASN1_TYPE_free(a->parameter);
-			if (!(a->parameter=ASN1_TYPE_new()))
+			if (!pkey->ameth->pub_encode(pk, pkey))
 				{
-				X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
-				goto err;
+				X509err(X509_F_X509_PUBKEY_SET,
+					X509_R_PUBLIC_KEY_ENCODE_ERROR);
+				goto error;
 				}
-			a->parameter->type=V_ASN1_NULL;
+			}
+		else
+			{
+			X509err(X509_F_X509_PUBKEY_SET,
+				X509_R_METHOD_NOT_SUPPORTED);
+			goto error;
 			}
 		}
-#ifndef OPENSSL_NO_DSA
-	else if (pkey->type == EVP_PKEY_DSA)
-		{
-		unsigned char *pp;
-		DSA *dsa;
-		
-		dsa=pkey->pkey.dsa;
-		dsa->write_params=0;
-		ASN1_TYPE_free(a->parameter);
-		if ((i=i2d_DSAparams(dsa,NULL)) <= 0)
-			goto err;
-		if (!(p=(unsigned char *)OPENSSL_malloc(i)))
-			{
-			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
-			goto err;
-			}
-		pp=p;
-		i2d_DSAparams(dsa,&pp);
-		if (!(a->parameter=ASN1_TYPE_new()))
-			{
-			OPENSSL_free(p);
-			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
-			goto err;
-			}
-		a->parameter->type=V_ASN1_SEQUENCE;
-		if (!(a->parameter->value.sequence=ASN1_STRING_new()))
-			{
-			OPENSSL_free(p);
-			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
-			goto err;
-			}
-		if (!ASN1_STRING_set(a->parameter->value.sequence,p,i))
-			{
-			OPENSSL_free(p);
-			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
-			goto err;
-			}
-		OPENSSL_free(p);
-		}
-#endif
-#ifndef OPENSSL_NO_EC
-	else if (pkey->type == EVP_PKEY_EC)
-		{
-		int nid=0;
-		unsigned char *pp;
-		EC_KEY *ec_key;
-		const EC_GROUP *group;
-		
-		ec_key = pkey->pkey.ec;
-		ASN1_TYPE_free(a->parameter);
-
-		if ((a->parameter = ASN1_TYPE_new()) == NULL)
-			{
-			X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB);
-			goto err;
-			}
-
-		group = EC_KEY_get0_group(ec_key);
-		if (EC_GROUP_get_asn1_flag(group)
-                     && (nid = EC_GROUP_get_curve_name(group)))
-			{
-			/* just set the OID */
-			a->parameter->type = V_ASN1_OBJECT;
-			a->parameter->value.object = OBJ_nid2obj(nid);
-			}
-		else /* explicit parameters */
-			{
-			if ((i = i2d_ECParameters(ec_key, NULL)) == 0)
-				{
-				X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB);
-				goto err;
-				}
-			if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL)
-				{
-				X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
-				goto err;
-				}	
-			pp = p;
-			if (!i2d_ECParameters(ec_key, &pp))
-				{
-				X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB);
-				OPENSSL_free(p);
-				goto err;
-				}
-			a->parameter->type = V_ASN1_SEQUENCE;
-			if ((a->parameter->value.sequence = ASN1_STRING_new()) == NULL)
-				{
-				X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB);
-				OPENSSL_free(p);
-				goto err;
-				}
-			ASN1_STRING_set(a->parameter->value.sequence, p, i);
-			OPENSSL_free(p);
-			}
-		}
-#endif
-	else if (1)
+	else
 		{
 		X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM);
-		goto err;
+		goto error;
 		}
 
-	if ((i=i2d_PublicKey(pkey,NULL)) <= 0) goto err;
-	if ((s=(unsigned char *)OPENSSL_malloc(i+1)) == NULL)
-		{
-		X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
-	p=s;
-	i2d_PublicKey(pkey,&p);
-	if (!M_ASN1_BIT_STRING_set(pk->public_key,s,i))
-		{
-		X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
-  	/* Set number of unused bits to zero */
-	pk->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
-	pk->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT;
-
-	OPENSSL_free(s);
-
-#if 0
-	CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
-	pk->pkey=pkey;
-#endif
-
 	if (*x != NULL)
 		X509_PUBKEY_free(*x);
 
 	*x=pk;
 
 	return 1;
-err:
+error:
 	if (pk != NULL) X509_PUBKEY_free(pk);
 	return 0;
 	}
@@ -258,119 +133,50 @@
 EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
 	{
 	EVP_PKEY *ret=NULL;
-	long j;
-	int type;
-	const unsigned char *p;
-#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
-	const unsigned char *cp;
-	X509_ALGOR *a;
-#endif
 
-	if (key == NULL) goto err;
+	if (key == NULL) goto error;
 
 	if (key->pkey != NULL)
 		{
 		CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
-		return(key->pkey);
+		return key->pkey;
 		}
 
-	if (key->public_key == NULL) goto err;
+	if (key->public_key == NULL) goto error;
 
-	type=OBJ_obj2nid(key->algor->algorithm);
 	if ((ret = EVP_PKEY_new()) == NULL)
 		{
 		X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
-		goto err;
+		goto error;
 		}
-	ret->type = EVP_PKEY_type(type);
 
-	/* the parameters must be extracted before the public key (ECDSA!) */
-	
-#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
-	a=key->algor;
-#endif
-
-	if (0)
-		;
-#ifndef OPENSSL_NO_DSA
-	else if (ret->type == EVP_PKEY_DSA)
+	if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm)))
 		{
-		if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE))
-			{
-			if ((ret->pkey.dsa = DSA_new()) == NULL)
-				{
-				X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
-				goto err;
-				}
-			ret->pkey.dsa->write_params=0;
-			cp=p=a->parameter->value.sequence->data;
-			j=a->parameter->value.sequence->length;
-			if (!d2i_DSAparams(&ret->pkey.dsa, &cp, (long)j))
-				goto err;
-			}
-		ret->save_parameters=1;
+		X509err(X509_F_X509_PUBKEY_GET,X509_R_UNSUPPORTED_ALGORITHM);
+		goto error;
 		}
-#endif
-#ifndef OPENSSL_NO_EC
-	else if (ret->type == EVP_PKEY_EC)
-		{
-		if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE))
-			{
-			/* type == V_ASN1_SEQUENCE => we have explicit parameters
-                         * (e.g. parameters in the X9_62_EC_PARAMETERS-structure )
-			 */
-			if ((ret->pkey.ec= EC_KEY_new()) == NULL)
-				{
-				X509err(X509_F_X509_PUBKEY_GET, 
-					ERR_R_MALLOC_FAILURE);
-				goto err;
-				}
-			cp = p = a->parameter->value.sequence->data;
-			j = a->parameter->value.sequence->length;
-			if (!d2i_ECParameters(&ret->pkey.ec, &cp, (long)j))
-				{
-				X509err(X509_F_X509_PUBKEY_GET, ERR_R_EC_LIB);
-				goto err;
-				}
-			}
-		else if (a->parameter && (a->parameter->type == V_ASN1_OBJECT))
-			{
-			/* type == V_ASN1_OBJECT => the parameters are given
-			 * by an asn1 OID
-			 */
-			EC_KEY   *ec_key;
-			EC_GROUP *group;
 
-			if (ret->pkey.ec == NULL)
-				ret->pkey.ec = EC_KEY_new();
-			ec_key = ret->pkey.ec;
-			if (ec_key == NULL)
-				goto err;
-			group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object));
-			if (group == NULL)
-				goto err;
-			EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
-			if (EC_KEY_set_group(ec_key, group) == 0)
-				goto err;
-			EC_GROUP_free(group);
+	if (ret->ameth->pub_decode)
+		{
+		if (!ret->ameth->pub_decode(ret, key))
+			{
+			X509err(X509_F_X509_PUBKEY_GET,
+						X509_R_PUBLIC_KEY_DECODE_ERROR);
+			goto error;
 			}
-			/* the case implicitlyCA is currently not implemented */
-		ret->save_parameters = 1;
 		}
-#endif
-
-	p=key->public_key->data;
-        j=key->public_key->length;
-        if (!d2i_PublicKey(type, &ret, &p, (long)j))
+	else
 		{
-		X509err(X509_F_X509_PUBKEY_GET, X509_R_ERR_ASN1_LIB);
-		goto err;
+		X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED);
+		goto error;
 		}
 
 	key->pkey = ret;
 	CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
-	return(ret);
-err:
+
+	return ret;
+
+	error:
 	if (ret != NULL)
 		EVP_PKEY_free(ret);
 	return(NULL);
@@ -529,3 +335,39 @@
 	return(ret);
 	}
 #endif
+
+int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
+					int ptype, void *pval,
+					unsigned char *penc, int penclen)
+	{
+	if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
+		return 0;
+	if (penc)
+		{
+		if (pub->public_key->data)
+			OPENSSL_free(pub->public_key->data);
+		pub->public_key->data = penc;
+		pub->public_key->length = penclen;
+  		/* Set number of unused bits to zero */
+		pub->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
+		pub->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT;
+		}
+	return 1;
+	}
+
+int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
+		const unsigned char **pk, int *ppklen,
+		X509_ALGOR **pa,
+		X509_PUBKEY *pub)
+	{
+	if (ppkalg)
+		*ppkalg = pub->algor->algorithm;
+	if (pk)
+		{
+		*pk = pub->public_key->data;
+		*ppklen = pub->public_key->length;
+		}
+	if (pa)
+		*pa = pub->algor;
+	return 1;
+	}
diff --git a/crypto/asn1/x_req.c b/crypto/asn1/x_req.c
index 59ca8ce..d575558 100644
--- a/crypto/asn1/x_req.c
+++ b/crypto/asn1/x_req.c
@@ -79,7 +79,8 @@
  *
  */
 
-static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+							void *exarg)
 {
 	X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
 
diff --git a/crypto/asn1/x_x509.c b/crypto/asn1/x_x509.c
index e118696..dafd3cc 100644
--- a/crypto/asn1/x_x509.c
+++ b/crypto/asn1/x_x509.c
@@ -81,7 +81,8 @@
 
 extern void policy_cache_free(X509_POLICY_CACHE *cache);
 
-static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+								void *exarg)
 {
 	X509 *ret = (X509 *)*pval;
 
@@ -99,6 +100,7 @@
 		ret->rfc3779_asid = NULL;
 #endif
 		ret->aux = NULL;
+		ret->crldp = NULL;
 		CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
 		break;
 
@@ -112,7 +114,10 @@
 		X509_CERT_AUX_free(ret->aux);
 		ASN1_OCTET_STRING_free(ret->skid);
 		AUTHORITY_KEYID_free(ret->akid);
+		CRL_DIST_POINTS_free(ret->crldp);
 		policy_cache_free(ret->policy_cache);
+		GENERAL_NAMES_free(ret->altname);
+		NAME_CONSTRAINTS_free(ret->nc);
 #ifndef OPENSSL_NO_RFC3779
 		sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
 		ASIdentifiers_free(ret->rfc3779_asid);
@@ -136,19 +141,6 @@
 IMPLEMENT_ASN1_FUNCTIONS(X509)
 IMPLEMENT_ASN1_DUP_FUNCTION(X509)
 
-static ASN1_METHOD meth=
-    {
-    (I2D_OF(void))  i2d_X509,
-    (D2I_OF(void)) d2i_X509,
-    (void *(*)(void))X509_new,
-    (void (*)(void *)) X509_free
-    };
-
-ASN1_METHOD *X509_asn1_meth(void)
-	{
-	return(&meth);
-	}
-
 int X509_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/bio/Makefile b/crypto/bio/Makefile
deleted file mode 100644
index 1cd76ce..0000000
--- a/crypto/bio/Makefile
+++ /dev/null
@@ -1,221 +0,0 @@
-#
-# OpenSSL/crypto/bio/Makefile
-#
-
-DIR=	bio
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC= bio_lib.c bio_cb.c bio_err.c \
-	bss_mem.c bss_null.c bss_fd.c \
-	bss_file.c bss_sock.c bss_conn.c \
-	bf_null.c bf_buff.c b_print.c b_dump.c \
-	b_sock.c bss_acpt.c bf_nbio.c bss_log.c bss_bio.c \
-	bss_dgram.c
-#	bf_lbuf.c
-LIBOBJ= bio_lib.o bio_cb.o bio_err.o \
-	bss_mem.o bss_null.o bss_fd.o \
-	bss_file.o bss_sock.o bss_conn.o \
-	bf_null.o bf_buff.o b_print.o b_dump.o \
-	b_sock.o bss_acpt.o bf_nbio.o bss_log.o bss_bio.o \
-	bss_dgram.o
-#	bf_lbuf.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= bio.h
-HEADER=	bio_lcl.h $(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-b_dump.o: ../../e_os.h ../../include/openssl/bio.h
-b_dump.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-b_dump.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-b_dump.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-b_dump.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-b_dump.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-b_dump.o: ../../include/openssl/symhacks.h ../cryptlib.h b_dump.c bio_lcl.h
-b_print.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-b_print.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-b_print.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-b_print.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-b_print.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-b_print.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-b_print.o: ../../include/openssl/symhacks.h ../cryptlib.h b_print.c
-b_sock.o: ../../e_os.h ../../include/openssl/bio.h
-b_sock.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-b_sock.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-b_sock.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-b_sock.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-b_sock.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-b_sock.o: ../../include/openssl/symhacks.h ../cryptlib.h b_sock.c
-bf_buff.o: ../../e_os.h ../../include/openssl/bio.h
-bf_buff.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bf_buff.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bf_buff.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bf_buff.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bf_buff.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bf_buff.o: ../../include/openssl/symhacks.h ../cryptlib.h bf_buff.c
-bf_nbio.o: ../../e_os.h ../../include/openssl/bio.h
-bf_nbio.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bf_nbio.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bf_nbio.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bf_nbio.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bf_nbio.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-bf_nbio.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bf_nbio.o: ../cryptlib.h bf_nbio.c
-bf_null.o: ../../e_os.h ../../include/openssl/bio.h
-bf_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bf_null.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bf_null.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bf_null.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bf_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bf_null.o: ../../include/openssl/symhacks.h ../cryptlib.h bf_null.c
-bio_cb.o: ../../e_os.h ../../include/openssl/bio.h
-bio_cb.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bio_cb.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bio_cb.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bio_cb.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bio_cb.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bio_cb.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_cb.c
-bio_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
-bio_err.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bio_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bio_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bio_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bio_err.o: ../../include/openssl/symhacks.h bio_err.c
-bio_lib.o: ../../e_os.h ../../include/openssl/bio.h
-bio_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bio_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bio_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bio_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bio_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bio_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_lib.c
-bss_acpt.o: ../../e_os.h ../../include/openssl/bio.h
-bss_acpt.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bss_acpt.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bss_acpt.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bss_acpt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bss_acpt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bss_acpt.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_acpt.c
-bss_bio.o: ../../e_os.h ../../include/openssl/bio.h
-bss_bio.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-bss_bio.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-bss_bio.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-bss_bio.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-bss_bio.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bss_bio.o: bss_bio.c
-bss_conn.o: ../../e_os.h ../../include/openssl/bio.h
-bss_conn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bss_conn.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bss_conn.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bss_conn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bss_conn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bss_conn.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_conn.c
-bss_dgram.o: ../../e_os.h ../../include/openssl/bio.h
-bss_dgram.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bss_dgram.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bss_dgram.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bss_dgram.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bss_dgram.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bss_dgram.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_dgram.c
-bss_fd.o: ../../e_os.h ../../include/openssl/bio.h
-bss_fd.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bss_fd.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bss_fd.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bss_fd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bss_fd.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bss_fd.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_lcl.h bss_fd.c
-bss_file.o: ../../e_os.h ../../include/openssl/bio.h
-bss_file.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bss_file.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bss_file.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bss_file.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bss_file.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bss_file.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_lcl.h bss_file.c
-bss_log.o: ../../e_os.h ../../include/openssl/bio.h
-bss_log.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bss_log.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bss_log.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bss_log.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bss_log.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bss_log.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_log.c
-bss_mem.o: ../../e_os.h ../../include/openssl/bio.h
-bss_mem.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bss_mem.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bss_mem.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bss_mem.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bss_mem.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bss_mem.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_mem.c
-bss_null.o: ../../e_os.h ../../include/openssl/bio.h
-bss_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bss_null.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bss_null.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bss_null.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bss_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bss_null.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_null.c
-bss_sock.o: ../../e_os.h ../../include/openssl/bio.h
-bss_sock.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bss_sock.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bss_sock.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bss_sock.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bss_sock.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bss_sock.o: ../../include/openssl/symhacks.h ../cryptlib.h bss_sock.c
diff --git a/crypto/bio/b_print.c b/crypto/bio/b_print.c
index 3a87b0e..143a7cf 100644
--- a/crypto/bio/b_print.c
+++ b/crypto/bio/b_print.c
@@ -115,8 +115,8 @@
 #define LDOUBLE double
 #endif
 
-#if HAVE_LONG_LONG
-# if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__)
+#ifdef HAVE_LONG_LONG
+# if defined(_WIN32) && !defined(__GNUC__)
 # define LLONG __int64
 # else
 # define LLONG long long
diff --git a/crypto/bio/b_sock.c b/crypto/bio/b_sock.c
index ead477d..5ea621c 100644
--- a/crypto/bio/b_sock.c
+++ b/crypto/bio/b_sock.c
@@ -72,11 +72,9 @@
 
 #ifndef OPENSSL_NO_SOCK
 
-#ifdef OPENSSL_SYS_WIN16
-#define SOCKET_PROTOCOL 0 /* more microsoft stupidity */
-#else
+#include <openssl/dso.h>
+
 #define SOCKET_PROTOCOL IPPROTO_TCP
-#endif
 
 #ifdef SO_MAXCONN
 #define MAX_LISTEN  SO_MAXCONN
@@ -90,6 +88,17 @@
 static int wsa_init_done=0;
 #endif
 
+/*
+ * WSAAPI specifier is required to make indirect calls to run-time
+ * linked WinSock 2 functions used in this module, to be specific
+ * [get|free]addrinfo and getnameinfo. This is because WinSock uses
+ * uses non-C calling convention, __stdcall vs. __cdecl, on x86
+ * Windows. On non-WinSock platforms WSAAPI needs to be void.
+ */
+#ifndef WSAAPI
+#define WSAAPI
+#endif
+
 #if 0
 static unsigned long BIO_ghbn_hits=0L;
 static unsigned long BIO_ghbn_miss=0L;
@@ -226,6 +235,10 @@
 	int j,i;
 	int size;
 		 
+#if defined(OPENSSL_SYS_BEOS_R5)
+	return 0;
+#endif
+		 
 	size=sizeof(int);
 	/* Note: under Windows the third parameter is of type (char *)
 	 * whereas under other systems it is (void *) if you don't have
@@ -466,7 +479,12 @@
 	  
 		wsa_init_done=1;
 		memset(&wsa_state,0,sizeof(wsa_state));
-		if (WSAStartup(0x0101,&wsa_state)!=0)
+		/* Not making wsa_state available to the rest of the
+		 * code is formally wrong. But the structures we use
+		 * are [beleived to be] invariable among Winsock DLLs,
+		 * while API availability is [expected to be] probed
+		 * at run-time with DSO_global_lookup. */
+		if (WSAStartup(0x0202,&wsa_state)!=0)
 			{
 			err=WSAGetLastError();
 			SYSerr(SYS_F_WSASTARTUP,err);
@@ -510,8 +528,8 @@
 	if (wsa_init_done)
 		{
 		wsa_init_done=0;
-#ifndef OPENSSL_SYS_WINCE
-		WSACancelBlockingCall();	/* Winsock 1.1 specific */
+#if 0		/* this call is claimed to be non-present in Winsock2 */
+		WSACancelBlockingCall();
 #endif
 		WSACleanup();
 		}
@@ -581,12 +599,18 @@
 int BIO_get_accept_socket(char *host, int bind_mode)
 	{
 	int ret=0;
-	struct sockaddr_in server,client;
-	int s=INVALID_SOCKET,cs;
+	union {
+		struct sockaddr sa;
+		struct sockaddr_in sa_in;
+#if OPENSSL_USE_IPV6
+		struct sockaddr_in6 sa_in6;
+#endif
+	} server,client;
+	int s=INVALID_SOCKET,cs,addrlen;
 	unsigned char ip[4];
 	unsigned short port;
 	char *str=NULL,*e;
-	const char *h,*p;
+	char *h,*p;
 	unsigned long l;
 	int err_num;
 
@@ -600,8 +624,7 @@
 		{
 		if (*e == ':')
 			{
-			p= &(e[1]);
-			*e='\0';
+			p=e;
 			}
 		else if (*e == '/')
 			{
@@ -609,21 +632,70 @@
 			break;
 			}
 		}
+	if (p)	*p++='\0';	/* points at last ':', '::port' is special [see below] */
+	else	p=h,h=NULL;
 
-	if (p == NULL)
+#ifdef EAI_FAMILY
+	do {
+	static union {	void *p;
+			int (WSAAPI *f)(const char *,const char *,
+				 const struct addrinfo *,
+				 struct addrinfo **);
+			} p_getaddrinfo = {NULL};
+	static union {	void *p;
+			void (WSAAPI *f)(struct addrinfo *);
+			} p_freeaddrinfo = {NULL};
+	struct addrinfo *res,hint;
+
+	if (p_getaddrinfo.p==NULL)
 		{
-		p=h;
-		h="*";
+		if ((p_getaddrinfo.p=DSO_global_lookup("getaddrinfo"))==NULL ||
+		    (p_freeaddrinfo.p=DSO_global_lookup("freeaddrinfo"))==NULL)
+			p_getaddrinfo.p=(void*)-1;
 		}
+	if (p_getaddrinfo.p==(void *)-1) break;
+
+	/* '::port' enforces IPv6 wildcard listener. Some OSes,
+	 * e.g. Solaris, default to IPv6 without any hint. Also
+	 * note that commonly IPv6 wildchard socket can service
+	 * IPv4 connections just as well...  */
+	memset(&hint,0,sizeof(hint));
+	if (h)
+		{
+		if (strchr(h,':'))
+			{
+			if (h[1]=='\0') h=NULL;
+#if OPENSSL_USE_IPV6
+			hint.ai_family = AF_INET6;
+#else
+			h=NULL;
+#endif
+			}
+	    	else if (h[0]=='*' && h[1]=='\0')
+			h=NULL;
+		}
+
+	if ((*p_getaddrinfo.f)(h,p,&hint,&res)) break;
+
+	addrlen = res->ai_addrlen<=sizeof(server) ?
+			res->ai_addrlen :
+			sizeof(server);
+	memcpy(&server, res->ai_addr, addrlen);
+
+	(*p_freeaddrinfo.f)(res);
+	goto again;
+	} while (0);
+#endif
 
 	if (!BIO_get_port(p,&port)) goto err;
 
 	memset((char *)&server,0,sizeof(server));
-	server.sin_family=AF_INET;
-	server.sin_port=htons(port);
+	server.sa_in.sin_family=AF_INET;
+	server.sa_in.sin_port=htons(port);
+	addrlen = sizeof(server.sa_in);
 
-	if (strcmp(h,"*") == 0)
-		server.sin_addr.s_addr=INADDR_ANY;
+	if (h == NULL || strcmp(h,"*") == 0)
+		server.sa_in.sin_addr.s_addr=INADDR_ANY;
 	else
 		{
                 if (!BIO_get_host_ip(h,&(ip[0]))) goto err;
@@ -632,11 +704,11 @@
 			((unsigned long)ip[1]<<16L)|
 			((unsigned long)ip[2]<< 8L)|
 			((unsigned long)ip[3]);
-		server.sin_addr.s_addr=htonl(l);
+		server.sa_in.sin_addr.s_addr=htonl(l);
 		}
 
 again:
-	s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
+	s=socket(server.sa.sa_family,SOCK_STREAM,SOCKET_PROTOCOL);
 	if (s == INVALID_SOCKET)
 		{
 		SYSerr(SYS_F_SOCKET,get_last_socket_error());
@@ -654,22 +726,35 @@
 		bind_mode=BIO_BIND_NORMAL;
 		}
 #endif
-	if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1)
+	if (bind(s,&server.sa,addrlen) == -1)
 		{
 #ifdef SO_REUSEADDR
 		err_num=get_last_socket_error();
 		if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) &&
 			(err_num == EADDRINUSE))
 			{
-			memcpy((char *)&client,(char *)&server,sizeof(server));
-			if (strcmp(h,"*") == 0)
-				client.sin_addr.s_addr=htonl(0x7F000001);
-			cs=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
+			client = server;
+			if (h == NULL || strcmp(h,"*") == 0)
+				{
+#if OPENSSL_USE_IPV6
+				if (client.sa.sa_family == AF_INET6)
+					{
+					memset(&client.sa_in6.sin6_addr,0,sizeof(client.sa_in6.sin6_addr));
+					client.sa_in6.sin6_addr.s6_addr[15]=1;
+					}
+				else
+#endif
+				if (client.sa.sa_family == AF_INET)
+					{
+					client.sa_in.sin_addr.s_addr=htonl(0x7F000001);
+					}
+				else	goto err;
+				}
+			cs=socket(client.sa.sa_family,SOCK_STREAM,SOCKET_PROTOCOL);
 			if (cs != INVALID_SOCKET)
 				{
 				int ii;
-				ii=connect(cs,(struct sockaddr *)&client,
-					sizeof(client));
+				ii=connect(cs,&client.sa,addrlen);
 				closesocket(cs);
 				if (ii == INVALID_SOCKET)
 					{
@@ -708,20 +793,52 @@
 int BIO_accept(int sock, char **addr)
 	{
 	int ret=INVALID_SOCKET;
-	static struct sockaddr_in from;
 	unsigned long l;
 	unsigned short port;
-	int len;
 	char *p;
 
-	memset((char *)&from,0,sizeof(from));
-	len=sizeof(from);
-	/* Note: under VMS with SOCKETSHR the fourth parameter is currently
-	 * of type (int *) whereas under other systems it is (void *) if
-	 * you don't have a cast it will choke the compiler: if you do
-	 * have a cast then you can either go for (int *) or (void *).
+	struct {
+	/*
+	 * As for following union. Trouble is that there are platforms
+	 * that have socklen_t and there are platforms that don't, on
+	 * some platforms socklen_t is int and on some size_t. So what
+	 * one can do? One can cook #ifdef spaghetti, which is nothing
+	 * but masochistic. Or one can do union between int and size_t.
+	 * One naturally does it primarily for 64-bit platforms where
+	 * sizeof(int) != sizeof(size_t). But would it work? Note that
+	 * if size_t member is initialized to 0, then later int member
+	 * assignment naturally does the job on little-endian platforms
+	 * regardless accept's expectations! What about big-endians?
+	 * If accept expects int*, then it works, and if size_t*, then
+	 * length value would appear as unreasonably large. But this
+	 * won't prevent it from filling in the address structure. The
+	 * trouble of course would be if accept returns more data than
+	 * actual buffer can accomodate and overwrite stack... That's
+	 * where early OPENSSL_assert comes into picture. Besides, the
+	 * only 64-bit big-endian platform found so far that expects
+	 * size_t* is HP-UX, where stack grows towards higher address.
+	 * <appro>
 	 */
-	ret=accept(sock,(struct sockaddr *)&from,(void *)&len);
+	union { size_t s; int i; } len;
+	union {
+		struct sockaddr sa;
+		struct sockaddr_in sa_in;
+#if OPENSSL_USE_IPV6
+		struct sockaddr_in6 sa_in6;
+#endif
+		} from;
+	} sa;
+
+	sa.len.s=0;
+	sa.len.i=sizeof(sa.from);
+	memset(&sa.from,0,sizeof(sa.from));
+	ret=accept(sock,&sa.from.sa,(void *)&sa.len);
+	if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0)
+		{
+		OPENSSL_assert(sa.len.s<=sizeof(sa.from));
+		sa.len.i = (int)sa.len.s;
+		/* use sa.len.i from this point */
+		}
 	if (ret == INVALID_SOCKET)
 		{
 		if(BIO_sock_should_retry(ret)) return -2;
@@ -732,8 +849,46 @@
 
 	if (addr == NULL) goto end;
 
-	l=ntohl(from.sin_addr.s_addr);
-	port=ntohs(from.sin_port);
+#ifdef EAI_FAMILY
+	do {
+	char   h[NI_MAXHOST],s[NI_MAXSERV];
+	size_t nl;
+	static union {	void *p;
+			int (WSAAPI *f)(const struct sockaddr *,size_t/*socklen_t*/,
+				 char *,size_t,char *,size_t,int);
+			} p_getnameinfo = {NULL};
+			/* 2nd argument to getnameinfo is specified to
+			 * be socklen_t. Unfortunately there is a number
+			 * of environments where socklen_t is not defined.
+			 * As it's passed by value, it's safe to pass it
+			 * as size_t... <appro> */
+
+	if (p_getnameinfo.p==NULL)
+		{
+		if ((p_getnameinfo.p=DSO_global_lookup("getnameinfo"))==NULL)
+			p_getnameinfo.p=(void*)-1;
+		}
+	if (p_getnameinfo.p==(void *)-1) break;
+
+	if ((*p_getnameinfo.f)(&sa.from.sa,sa.len.i,h,sizeof(h),s,sizeof(s),
+	    NI_NUMERICHOST|NI_NUMERICSERV)) break;
+	nl = strlen(h)+strlen(s)+2;
+	p = *addr;
+	if (p)	{ *p = '\0'; p = OPENSSL_realloc(p,nl);	}
+	else	{ p = OPENSSL_malloc(nl);		}
+	if (p==NULL)
+		{
+		BIOerr(BIO_F_BIO_ACCEPT,ERR_R_MALLOC_FAILURE);
+		goto end;
+		}
+	*addr = p;
+	BIO_snprintf(*addr,nl,"%s:%s",h,s);
+	goto end;
+	} while(0);
+#endif
+	if (sa.from.sa.sa_family != AF_INET) goto end;
+	l=ntohl(sa.from.sa_in.sin_addr.s_addr);
+	port=ntohs(sa.from.sa_in.sin_port);
 	if (*addr == NULL)
 		{
 		if ((p=OPENSSL_malloc(24)) == NULL)
diff --git a/crypto/bio/bio.h b/crypto/bio/bio.h
index ebb4278..152802f 100644
--- a/crypto/bio/bio.h
+++ b/crypto/bio/bio.h
@@ -95,6 +95,7 @@
 #define BIO_TYPE_BIO		(19|0x0400)		/* (half a) BIO pair */
 #define BIO_TYPE_LINEBUFFER	(20|0x0200)		/* filter */
 #define BIO_TYPE_DGRAM		(21|0x0400|0x0100)
+#define BIO_TYPE_ASN1 		(22|0x0200)		/* filter */
 #define BIO_TYPE_COMP 		(23|0x0200)		/* filter */
 
 #define BIO_TYPE_DESCRIPTOR	0x0100	/* socket, fd, connect or accept */
@@ -265,7 +266,6 @@
 
 typedef void bio_info_cb(struct bio_st *, int, const char *, int, long, long);
 
-#ifndef OPENSSL_SYS_WIN16
 typedef struct bio_method_st
 	{
 	int type;
@@ -279,21 +279,6 @@
 	int (*destroy)(BIO *);
         long (*callback_ctrl)(BIO *, int, bio_info_cb *);
 	} BIO_METHOD;
-#else
-typedef struct bio_method_st
-	{
-	int type;
-	const char *name;
-	int (_far *bwrite)();
-	int (_far *bread)();
-	int (_far *bputs)();
-	int (_far *bgets)();
-	long (_far *ctrl)();
-	int (_far *create)();
-	int (_far *destroy)();
-	long (_far *callback_ctrl)();
-	} BIO_METHOD;
-#endif
 
 struct bio_st
 	{
@@ -334,6 +319,9 @@
 	int obuf_off;		/* write/read offset */
 	} BIO_F_BUFFER_CTX;
 
+/* Prefix and suffix callback in ASN1 BIO */
+typedef int asn1_ps_func(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+
 /* connect BIO stuff */
 #define BIO_CONN_S_BEFORE		1
 #define BIO_CONN_S_GET_IP		2
@@ -396,6 +384,13 @@
 #define BIO_C_RESET_READ_REQUEST		147
 #define BIO_C_SET_MD_CTX			148
 
+#define BIO_C_SET_PREFIX			149
+#define BIO_C_GET_PREFIX			150
+#define BIO_C_SET_SUFFIX			151
+#define BIO_C_GET_SUFFIX			152
+
+#define BIO_C_SET_EX_ARG			153
+#define BIO_C_GET_EX_ARG			154
 
 #define BIO_set_app_data(s,arg)		BIO_set_ex_data(s,0,arg)
 #define BIO_get_app_data(s)		BIO_get_ex_data(s,0)
@@ -559,22 +554,21 @@
 unsigned long BIO_number_read(BIO *bio);
 unsigned long BIO_number_written(BIO *bio);
 
+/* For BIO_f_asn1() */
+int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
+					asn1_ps_func *prefix_free);
+int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
+					asn1_ps_func **pprefix_free);
+int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
+					asn1_ps_func *suffix_free);
+int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
+					asn1_ps_func **psuffix_free);
+
 # ifndef OPENSSL_NO_FP_API
-#  if defined(OPENSSL_SYS_WIN16) && defined(_WINDLL)
-BIO_METHOD *BIO_s_file_internal(void);
-BIO *BIO_new_file_internal(char *filename, char *mode);
-BIO *BIO_new_fp_internal(FILE *stream, int close_flag);
-#    define BIO_s_file	BIO_s_file_internal
-#    define BIO_new_file	BIO_new_file_internal
-#    define BIO_new_fp	BIO_new_fp_internal
-#  else /* FP_API */
 BIO_METHOD *BIO_s_file(void );
 BIO *BIO_new_file(const char *filename, const char *mode);
 BIO *BIO_new_fp(FILE *stream, int close_flag);
-#    define BIO_s_file_internal		BIO_s_file
-#    define BIO_new_file_internal	BIO_new_file
-#    define BIO_new_fp_internal		BIO_s_file
-#  endif /* FP_API */
+# define BIO_s_file_internal	BIO_s_file
 # endif
 BIO *	BIO_new(BIO_METHOD *type);
 int	BIO_set(BIO *a,BIO_METHOD *type);
@@ -603,13 +597,8 @@
 int BIO_nwrite0(BIO *bio, char **buf);
 int BIO_nwrite(BIO *bio, char **buf, int num);
 
-#ifndef OPENSSL_SYS_WIN16
 long BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
 	long argl,long ret);
-#else
-long _far _loadds BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
-	long argl,long ret);
-#endif
 
 BIO_METHOD *BIO_s_mem(void);
 BIO *BIO_new_mem_buf(void *buf, int len);
diff --git a/crypto/bio/bio_cb.c b/crypto/bio/bio_cb.c
index 6f4254a..9bcbc32 100644
--- a/crypto/bio/bio_cb.c
+++ b/crypto/bio/bio_cb.c
@@ -85,28 +85,32 @@
 		break;
 	case BIO_CB_READ:
 		if (bio->method->type & BIO_TYPE_DESCRIPTOR)
-			BIO_snprintf(p,p_maxlen,"read(%d,%d) - %s fd=%d\n",
-				 bio->num,argi,bio->method->name,bio->num);
+			BIO_snprintf(p,p_maxlen,"read(%d,%lu) - %s fd=%d\n",
+				 bio->num,(unsigned long)argi,
+				 bio->method->name,bio->num);
 		else
-			BIO_snprintf(p,p_maxlen,"read(%d,%d) - %s\n",
-				 bio->num,argi,bio->method->name);
+			BIO_snprintf(p,p_maxlen,"read(%d,%lu) - %s\n",
+				 bio->num,(unsigned long)argi,
+				 bio->method->name);
 		break;
 	case BIO_CB_WRITE:
 		if (bio->method->type & BIO_TYPE_DESCRIPTOR)
-			BIO_snprintf(p,p_maxlen,"write(%d,%d) - %s fd=%d\n",
-				 bio->num,argi,bio->method->name,bio->num);
+			BIO_snprintf(p,p_maxlen,"write(%d,%lu) - %s fd=%d\n",
+				 bio->num,(unsigned long)argi,
+				 bio->method->name,bio->num);
 		else
-			BIO_snprintf(p,p_maxlen,"write(%d,%d) - %s\n",
-				 bio->num,argi,bio->method->name);
+			BIO_snprintf(p,p_maxlen,"write(%d,%lu) - %s\n",
+				 bio->num,(unsigned long)argi,
+				 bio->method->name);
 		break;
 	case BIO_CB_PUTS:
 		BIO_snprintf(p,p_maxlen,"puts() - %s\n",bio->method->name);
 		break;
 	case BIO_CB_GETS:
-		BIO_snprintf(p,p_maxlen,"gets(%d) - %s\n",argi,bio->method->name);
+		BIO_snprintf(p,p_maxlen,"gets(%lu) - %s\n",(unsigned long)argi,bio->method->name);
 		break;
 	case BIO_CB_CTRL:
-		BIO_snprintf(p,p_maxlen,"ctrl(%d) - %s\n",argi,bio->method->name);
+		BIO_snprintf(p,p_maxlen,"ctrl(%lu) - %s\n",(unsigned long)argi,bio->method->name);
 		break;
 	case BIO_CB_RETURN|BIO_CB_READ:
 		BIO_snprintf(p,p_maxlen,"read return %ld\n",ret);
diff --git a/crypto/bio/bio_err.c b/crypto/bio/bio_err.c
index 6603f1c..a224edd 100644
--- a/crypto/bio/bio_err.c
+++ b/crypto/bio/bio_err.c
@@ -1,6 +1,6 @@
 /* crypto/bio/bio_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
diff --git a/crypto/bio/bio_lcl.h b/crypto/bio/bio_lcl.h
index dba2919..e7f7ec8 100644
--- a/crypto/bio/bio_lcl.h
+++ b/crypto/bio/bio_lcl.h
@@ -18,11 +18,19 @@
 #define	UP_ftell	ftell
 #define	UP_fflush	fflush
 #define	UP_ferror	ferror
+#ifdef _WIN32
+#define	UP_fileno	_fileno
+#define	UP_open		_open
+#define	UP_read		_read
+#define	UP_write	_write
+#define	UP_lseek	_lseek
+#define	UP_close	_close
+#else
 #define	UP_fileno	fileno
-
 #define	UP_open		open
 #define	UP_read		read
 #define	UP_write	write
 #define	UP_lseek	lseek
 #define	UP_close	close
 #endif
+#endif
diff --git a/crypto/bio/bio_lib.c b/crypto/bio/bio_lib.c
index 3f52ae9..77f4de9 100644
--- a/crypto/bio/bio_lib.c
+++ b/crypto/bio/bio_lib.c
@@ -429,7 +429,7 @@
 	if (bio != NULL)
 		bio->prev_bio=lb;
 	/* called to do internal processing */
-	BIO_ctrl(b,BIO_CTRL_PUSH,0,NULL);
+	BIO_ctrl(b,BIO_CTRL_PUSH,0,lb);
 	return(b);
 	}
 
@@ -441,7 +441,7 @@
 	if (b == NULL) return(NULL);
 	ret=b->next_bio;
 
-	BIO_ctrl(b,BIO_CTRL_POP,0,NULL);
+	BIO_ctrl(b,BIO_CTRL_POP,0,b);
 
 	if (b->prev_bio != NULL)
 		b->prev_bio->next_bio=b->next_bio;
diff --git a/crypto/bio/bss_acpt.c b/crypto/bio/bss_acpt.c
index d090b72..826f761 100644
--- a/crypto/bio/bss_acpt.c
+++ b/crypto/bio/bss_acpt.c
@@ -100,8 +100,8 @@
 static int acpt_free(BIO *data);
 static int acpt_state(BIO *b, BIO_ACCEPT *c);
 static void acpt_close_socket(BIO *data);
-BIO_ACCEPT *BIO_ACCEPT_new(void );
-void BIO_ACCEPT_free(BIO_ACCEPT *a);
+static BIO_ACCEPT *BIO_ACCEPT_new(void );
+static void BIO_ACCEPT_free(BIO_ACCEPT *a);
 
 #define ACPT_S_BEFORE			1
 #define ACPT_S_GET_ACCEPT_SOCKET	2
@@ -141,7 +141,7 @@
 	return(1);
 	}
 
-BIO_ACCEPT *BIO_ACCEPT_new(void)
+static BIO_ACCEPT *BIO_ACCEPT_new(void)
 	{
 	BIO_ACCEPT *ret;
 
@@ -154,7 +154,7 @@
 	return(ret);
 	}
 
-void BIO_ACCEPT_free(BIO_ACCEPT *a)
+static void BIO_ACCEPT_free(BIO_ACCEPT *a)
 	{
 	if(a == NULL)
 	    return;
diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c
index 14ca854..eb7e365 100644
--- a/crypto/bio/bss_dgram.c
+++ b/crypto/bio/bss_dgram.c
@@ -108,7 +108,13 @@
 
 typedef struct bio_dgram_data_st
 	{
-	struct sockaddr peer;
+	union {
+		struct sockaddr sa;
+		struct sockaddr_in sa_in;
+#if OPENSSL_USE_IPV6
+		struct sockaddr_in6 sa_in6;
+#endif
+	} peer;
 	unsigned int connected;
 	unsigned int _errno;
 	unsigned int mtu;
@@ -274,24 +280,38 @@
 	int ret=0;
 	bio_dgram_data *data = (bio_dgram_data *)b->ptr;
 
-	struct sockaddr peer;
-	int peerlen = sizeof(peer);
+	struct	{
+	/*
+	 * See commentary in b_sock.c. <appro>
+	 */
+	union	{ size_t s; int i; } len;
+	union	{
+		struct sockaddr sa;
+		struct sockaddr_in sa_in;
+#if OPENSSL_USE_IPV6
+		struct sockaddr_in6 sa_in6;
+#endif
+		} peer;
+	} sa;
+
+	sa.len.s=0;
+	sa.len.i=sizeof(sa.peer);
 
 	if (out != NULL)
 		{
 		clear_socket_error();
-		memset(&peer, 0x00, peerlen);
-		/* Last arg in recvfrom is signed on some platforms and
-		 * unsigned on others. It is of type socklen_t on some
-		 * but this is not universal. Cast to (void *) to avoid
-		 * compiler warnings.
-		 */
+		memset(&sa.peer, 0x00, sizeof(sa.peer));
 		dgram_adjust_rcv_timeout(b);
-		ret=recvfrom(b->num,out,outl,0,&peer,(void *)&peerlen);
+		ret=recvfrom(b->num,out,outl,0,&sa.peer.sa,(void *)&sa.len);
+		if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0)
+			{
+			OPENSSL_assert(sa.len.s<=sizeof(sa.peer));
+			sa.len.i = (int)sa.len.s;
+			}
 		dgram_reset_rcv_timeout(b);
 
 		if ( ! data->connected  && ret >= 0)
-			BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &peer);
+			BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer);
 
 		BIO_clear_retry_flags(b);
 		if (ret < 0)
@@ -312,14 +332,24 @@
 	bio_dgram_data *data = (bio_dgram_data *)b->ptr;
 	clear_socket_error();
 
-    if ( data->connected )
-        ret=writesocket(b->num,in,inl);
-    else
-#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
-        ret=sendto(b->num, (char *)in, inl, 0, &data->peer, sizeof(data->peer));
-#else
-        ret=sendto(b->num, in, inl, 0, &data->peer, sizeof(data->peer));
+	if ( data->connected )
+		ret=writesocket(b->num,in,inl);
+	else
+		{
+		int peerlen = sizeof(data->peer);
+
+		if (data->peer.sa.sa_family == AF_INET)
+			peerlen = sizeof(data->peer.sa_in);
+#if OPENSSL_USE_IVP6
+		else if (data->peer.sa.sa_family == AF_INET6)
+			peerlen = sizeof(data->peer.sa_in6);
 #endif
+#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
+		ret=sendto(b->num, (char *)in, inl, 0, &data->peer.sa, peerlen);
+#else
+		ret=sendto(b->num, in, inl, 0, &data->peer.sa, peerlen);
+#endif
+		}
 
 	BIO_clear_retry_flags(b);
 	if (ret <= 0)
@@ -351,7 +381,13 @@
 #endif
 #ifdef OPENSSL_SYS_LINUX
 	socklen_t addr_len;
-	struct sockaddr_storage addr;
+	union	{
+		struct sockaddr	sa;
+		struct sockaddr_in s4;
+#if OPENSSL_USE_IPV6
+		struct sockaddr_in6 s6;
+#endif
+		} addr;
 #endif
 
 	data = (bio_dgram_data *)b->ptr;
@@ -405,7 +441,20 @@
 		else
 			{
 #endif
-			memcpy(&(data->peer),to, sizeof(struct sockaddr));
+			switch (to->sa_family)
+				{
+				case AF_INET:
+					memcpy(&data->peer,to,sizeof(data->peer.sa_in));
+					break;
+#if OPENSSL_USE_IPV6
+				case AF_INET6:
+					memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
+					break;
+#endif
+				default:
+					memcpy(&data->peer,to,sizeof(data->peer.sa));
+					break;
+				}
 #if 0
 			}
 #endif
@@ -413,15 +462,15 @@
 		/* (Linux)kernel sets DF bit on outgoing IP packets */
 	case BIO_CTRL_DGRAM_MTU_DISCOVER:
 #ifdef OPENSSL_SYS_LINUX
-		addr_len = (socklen_t)sizeof(struct sockaddr_storage);
-		memset((void *)&addr, 0, sizeof(struct sockaddr_storage));
-		if (getsockname(b->num, (void *)&addr, &addr_len) < 0)
+		addr_len = (socklen_t)sizeof(addr);
+		memset((void *)&addr, 0, sizeof(addr));
+		if (getsockname(b->num, &addr.sa, &addr_len) < 0)
 			{
 			ret = 0;
 			break;
 			}
 		sockopt_len = sizeof(sockopt_val);
-		switch (addr.ss_family)
+		switch (addr.sa.sa_family)
 			{
 		case AF_INET:
 			sockopt_val = IP_PMTUDISC_DO;
@@ -429,12 +478,14 @@
 				&sockopt_val, sizeof(sockopt_val))) < 0)
 				perror("setsockopt");
 			break;
+#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER)
 		case AF_INET6:
 			sockopt_val = IPV6_PMTUDISC_DO;
 			if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
 				&sockopt_val, sizeof(sockopt_val))) < 0)
 				perror("setsockopt");
 			break;
+#endif
 		default:
 			ret = -1;
 			break;
@@ -445,15 +496,15 @@
 #endif
 	case BIO_CTRL_DGRAM_QUERY_MTU:
 #ifdef OPENSSL_SYS_LINUX
-		addr_len = (socklen_t)sizeof(struct sockaddr_storage);
-		memset((void *)&addr, 0, sizeof(struct sockaddr_storage));
-		if (getsockname(b->num, (void *)&addr, &addr_len) < 0)
+		addr_len = (socklen_t)sizeof(addr);
+		memset((void *)&addr, 0, sizeof(addr));
+		if (getsockname(b->num, &addr.sa, &addr_len) < 0)
 			{
 			ret = 0;
 			break;
 			}
 		sockopt_len = sizeof(sockopt_val);
-		switch (addr.ss_family)
+		switch (addr.sa.sa_family)
 			{
 		case AF_INET:
 			if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
@@ -470,6 +521,7 @@
 				ret = data->mtu;
 				}
 			break;
+#if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
 		case AF_INET6:
 			if ((ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, (void *)&sockopt_val,
 				&sockopt_len)) < 0 || sockopt_val < 0)
@@ -485,6 +537,7 @@
 				ret = data->mtu;
 				}
 			break;
+#endif
 		default:
 			ret = 0;
 			break;
@@ -506,27 +559,65 @@
 		if ( to != NULL)
 			{
 			data->connected = 1;
-			memcpy(&(data->peer),to, sizeof(struct sockaddr));
+			switch (to->sa_family)
+				{
+				case AF_INET:
+					memcpy(&data->peer,to,sizeof(data->peer.sa_in));
+					break;
+#if OPENSSL_USE_IPV6
+				case AF_INET6:
+					memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
+					break;
+#endif
+				default:
+					memcpy(&data->peer,to,sizeof(data->peer.sa));
+					break;
+				}
 			}
 		else
 			{
 			data->connected = 0;
-			memset(&(data->peer), 0x00, sizeof(struct sockaddr));
+			memset(&(data->peer), 0x00, sizeof(data->peer));
 			}
 		break;
-    case BIO_CTRL_DGRAM_GET_PEER:
-        to = (struct sockaddr *) ptr;
-
-        memcpy(to, &(data->peer), sizeof(struct sockaddr));
-		ret = sizeof(struct sockaddr);
-        break;
-    case BIO_CTRL_DGRAM_SET_PEER:
-        to = (struct sockaddr *) ptr;
-
-        memcpy(&(data->peer), to, sizeof(struct sockaddr));
-        break;
+	case BIO_CTRL_DGRAM_GET_PEER:
+		switch (data->peer.sa.sa_family)
+			{
+			case AF_INET:
+				ret=sizeof(data->peer.sa_in);
+				break;
+#if OPENSSL_USE_IPV6
+			case AF_INET6:
+				ret=sizeof(data->peer.sa_in6);
+				break;
+#endif
+			default:
+				ret=sizeof(data->peer.sa);
+				break;
+			}
+		if (num==0 || num>ret)
+			num=ret;
+		memcpy(ptr,&data->peer,(ret=num));
+		break;
+	case BIO_CTRL_DGRAM_SET_PEER:
+		to = (struct sockaddr *) ptr;
+		switch (to->sa_family)
+			{
+			case AF_INET:
+				memcpy(&data->peer,to,sizeof(data->peer.sa_in));
+				break;
+#if OPENSSL_USE_IPV6
+			case AF_INET6:
+				memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
+				break;
+#endif
+			default:
+				memcpy(&data->peer,to,sizeof(data->peer.sa));
+				break;
+			}
+		break;
 	case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
-		memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));		
+		memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
 		break;
 #if defined(SO_RCVTIMEO)
 	case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
diff --git a/crypto/bio/bss_fd.c b/crypto/bio/bss_fd.c
index 4c229bf..d1bf85a 100644
--- a/crypto/bio/bss_fd.c
+++ b/crypto/bio/bss_fd.c
@@ -60,6 +60,13 @@
 #include <errno.h>
 #define USE_SOCKETS
 #include "cryptlib.h"
+
+#if defined(OPENSSL_NO_POSIX_IO)
+/*
+ * One can argue that one should implement dummy placeholder for
+ * BIO_s_fd here...
+ */
+#else
 /*
  * As for unconditional usage of "UPLINK" interface in this module.
  * Trouble is that unlike Unix file descriptors [which are indexes
@@ -77,6 +84,7 @@
 static int fd_write(BIO *h, const char *buf, int num);
 static int fd_read(BIO *h, char *buf, int size);
 static int fd_puts(BIO *h, const char *str);
+static int fd_gets(BIO *h, char *buf, int size);
 static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2);
 static int fd_new(BIO *h);
 static int fd_free(BIO *data);
@@ -88,7 +96,7 @@
 	fd_write,
 	fd_read,
 	fd_puts,
-	NULL, /* fd_gets, */
+	fd_gets,
 	fd_ctrl,
 	fd_new,
 	fd_free,
@@ -227,6 +235,22 @@
 	return(ret);
 	}
 
+static int fd_gets(BIO *bp, char *buf, int size)
+        {
+	int ret=0;
+	char *ptr=buf;
+	char *end=buf+size-1;
+
+	while ( (ptr < end) && (fd_read(bp, ptr, 1) > 0) && (ptr[0] != '\n') )
+		ptr++;
+
+	ptr[0]='\0';
+
+	if (buf[0] != '\0')
+		ret=strlen(buf);
+	return(ret);
+        }
+
 int BIO_fd_should_retry(int i)
 	{
 	int err;
@@ -292,3 +316,4 @@
 		}
 	return(0);
 	}
+#endif
diff --git a/crypto/bio/bss_file.c b/crypto/bio/bss_file.c
index 62c1073..ba4f8e9 100644
--- a/crypto/bio/bss_file.c
+++ b/crypto/bio/bss_file.c
@@ -131,7 +131,7 @@
 			BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB);
 		return(NULL);
 		}
-	if ((ret=BIO_new(BIO_s_file_internal())) == NULL)
+	if ((ret=BIO_new(BIO_s_file())) == NULL)
 		{
 		fclose(file);
 		return(NULL);
@@ -272,9 +272,9 @@
 			BIO_clear_flags(b,BIO_FLAGS_UPLINK);
 #endif
 #endif
-#ifdef UP_fsetmode
+#ifdef UP_fsetmod
 		if (b->flags&BIO_FLAGS_UPLINK)
-			UP_fsetmode(b->ptr,num&BIO_FP_TEXT?'t':'b');
+			UP_fsetmod(b->ptr,(char)((num&BIO_FP_TEXT)?'t':'b'));
 		else
 #endif
 		{
@@ -286,8 +286,7 @@
 			_setmode(fd,_O_BINARY);
 #elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
 		int fd = fileno((FILE*)ptr);
-         /* Under CLib there are differences in file modes
-         */
+		/* Under CLib there are differences in file modes */
 		if (num & BIO_FP_TEXT)
 			setmode(fd,O_TEXT);
 		else
@@ -308,7 +307,7 @@
 			else
 				_setmode(fd,_O_BINARY);
 			}
-#elif defined(OPENSSL_SYS_OS2)
+#elif defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
 		int fd = fileno((FILE*)ptr);
 		if (num & BIO_FP_TEXT)
 			setmode(fd, O_TEXT);
diff --git a/crypto/bio/bss_log.c b/crypto/bio/bss_log.c
index 6360dbc..7ead044 100644
--- a/crypto/bio/bss_log.c
+++ b/crypto/bio/bss_log.c
@@ -70,7 +70,6 @@
 
 #if defined(OPENSSL_SYS_WINCE)
 #elif defined(OPENSSL_SYS_WIN32)
-#  include <process.h>
 #elif defined(OPENSSL_SYS_VMS)
 #  include <opcdef.h>
 #  include <descrip.h>
@@ -122,18 +121,6 @@
 static void xopenlog(BIO* bp, char* name, int level);
 static void xsyslog(BIO* bp, int priority, const char* string);
 static void xcloselog(BIO* bp);
-#ifdef OPENSSL_SYS_WIN32
-LONG	(WINAPI *go_for_advapi)()	= RegOpenKeyEx;
-HANDLE	(WINAPI *register_event_source)()	= NULL;
-BOOL	(WINAPI *deregister_event_source)()	= NULL;
-BOOL	(WINAPI *report_event)()	= NULL;
-#define DL_PROC(m,f)	(GetProcAddress( m, f ))
-#ifdef UNICODE
-#define DL_PROC_X(m,f) DL_PROC( m, f "W" )
-#else
-#define DL_PROC_X(m,f) DL_PROC( m, f "A" )
-#endif
-#endif
 
 static BIO_METHOD methods_slg=
 	{
@@ -175,7 +162,7 @@
 	char* buf;
 	char* pp;
 	int priority, i;
-	static struct
+	static const struct
 		{
 		int strl;
 		char str[10];
@@ -249,35 +236,20 @@
 
 static void xopenlog(BIO* bp, char* name, int level)
 {
-	if ( !register_event_source )
-		{
-		HANDLE	advapi;
-		if ( !(advapi = GetModuleHandle("advapi32")) )
-			return;
-		register_event_source = (HANDLE (WINAPI *)())DL_PROC_X(advapi,
-			"RegisterEventSource" );
-		deregister_event_source = (BOOL (WINAPI *)())DL_PROC(advapi,
-			"DeregisterEventSource");
-		report_event = (BOOL (WINAPI *)())DL_PROC_X(advapi,
-			"ReportEvent" );
-		if ( !(register_event_source && deregister_event_source &&
-				report_event) )
-			{
-			register_event_source = NULL;
-			deregister_event_source = NULL;
-			report_event = NULL;
-			return;
-			}
-		}
-	bp->ptr= (char *)register_event_source(NULL, name);
+	if (GetVersion() < 0x80000000)
+		bp->ptr = RegisterEventSourceA(NULL,name);
+	else
+		bp->ptr = NULL;
 }
 
 static void xsyslog(BIO *bp, int priority, const char *string)
 {
 	LPCSTR lpszStrings[2];
 	WORD evtype= EVENTLOG_ERROR_TYPE;
-	int pid = _getpid();
-	char pidbuf[DECIMAL_SIZE(pid)+4];
+	char pidbuf[DECIMAL_SIZE(DWORD)+4];
+
+	if (bp->ptr == NULL)
+		return;
 
 	switch (priority)
 		{
@@ -301,19 +273,18 @@
 		break;
 		}
 
-	sprintf(pidbuf, "[%d] ", pid);
+	sprintf(pidbuf, "[%u] ", GetCurrentProcessId());
 	lpszStrings[0] = pidbuf;
 	lpszStrings[1] = string;
 
-	if(report_event && bp->ptr)
-		report_event(bp->ptr, evtype, 0, 1024, NULL, 2, 0,
+	ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0,
 				lpszStrings, NULL);
 }
 	
 static void xcloselog(BIO* bp)
 {
-	if(deregister_event_source && bp->ptr)
-		deregister_event_source((HANDLE)(bp->ptr));
+	if(bp->ptr)
+		DeregisterEventSource((HANDLE)(bp->ptr));
 	bp->ptr= NULL;
 }
 
diff --git a/crypto/bio/bss_mem.c b/crypto/bio/bss_mem.c
index e7ab9cb..37d4194 100644
--- a/crypto/bio/bss_mem.c
+++ b/crypto/bio/bss_mem.c
@@ -94,16 +94,18 @@
 {
 	BIO *ret;
 	BUF_MEM *b;
+	size_t sz;
+
 	if (!buf) {
 		BIOerr(BIO_F_BIO_NEW_MEM_BUF,BIO_R_NULL_PARAMETER);
 		return NULL;
 	}
-	if(len == -1) len = strlen(buf);
+	sz = (len<0) ? strlen(buf) : (size_t)len;
 	if(!(ret = BIO_new(BIO_s_mem())) ) return NULL;
 	b = (BUF_MEM *)ret->ptr;
 	b->data = buf;
-	b->length = len;
-	b->max = len;
+	b->length = sz;
+	b->max = sz;
 	ret->flags |= BIO_FLAGS_MEM_RDONLY;
 	/* Since this is static data retrying wont help */
 	ret->num = 0;
@@ -144,22 +146,16 @@
 	{
 	int ret= -1;
 	BUF_MEM *bm;
-	int i;
-	char *from,*to;
 
 	bm=(BUF_MEM *)b->ptr;
 	BIO_clear_retry_flags(b);
-	ret=(outl > bm->length)?bm->length:outl;
+	ret=(outl >=0 && (size_t)outl > bm->length)?(int)bm->length:outl;
 	if ((out != NULL) && (ret > 0)) {
 		memcpy(out,bm->data,ret);
 		bm->length-=ret;
-		/* memmove(&(bm->data[0]),&(bm->data[ret]), bm->length); */
 		if(b->flags & BIO_FLAGS_MEM_RDONLY) bm->data += ret;
 		else {
-			from=(char *)&(bm->data[ret]);
-			to=(char *)&(bm->data[0]);
-			for (i=0; i<bm->length; i++)
-				to[i]=from[i];
+			memmove(&(bm->data[0]),&(bm->data[ret]),bm->length);
 		}
 	} else if (bm->length == 0)
 		{
diff --git a/crypto/bio/bss_sock.c b/crypto/bio/bss_sock.c
index 30c3cea..3df3193 100644
--- a/crypto/bio/bss_sock.c
+++ b/crypto/bio/bss_sock.c
@@ -172,15 +172,6 @@
 
 	switch (cmd)
 		{
-	case BIO_CTRL_RESET:
-		num=0;
-	case BIO_C_FILE_SEEK:
-		ret=0;
-		break;
-	case BIO_C_FILE_TELL:
-	case BIO_CTRL_INFO:
-		ret=0;
-		break;
 	case BIO_C_SET_FD:
 		sock_free(b);
 		b->num= *((int *)ptr);
@@ -203,10 +194,6 @@
 	case BIO_CTRL_SET_CLOSE:
 		b->shutdown=(int)num;
 		break;
-	case BIO_CTRL_PENDING:
-	case BIO_CTRL_WPENDING:
-		ret=0;
-		break;
 	case BIO_CTRL_DUP:
 	case BIO_CTRL_FLUSH:
 		ret=1;
diff --git a/crypto/bn/Makefile b/crypto/bn/Makefile
deleted file mode 100644
index f5e8f65..0000000
--- a/crypto/bn/Makefile
+++ /dev/null
@@ -1,362 +0,0 @@
-#
-# OpenSSL/crypto/bn/Makefile
-#
-
-DIR=	bn
-TOP=	../..
-CC=	cc
-CPP=    $(CC) -E
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-BN_ASM=		bn_asm.o
-# or use
-#BN_ASM=	bn86-elf.o
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-ASFLAGS= $(INCLUDES) $(ASFLAG)
-AFLAGS= $(ASFLAGS)
-
-GENERAL=Makefile
-TEST=bntest.c exptest.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=	bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c bn_mod.c \
-	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_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_x931p.o bn_const.o bn_opt.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= bn.h
-HEADER=	bn_lcl.h bn_prime.h $(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-bn_prime.h: bn_prime.pl
-	$(PERL) bn_prime.pl >bn_prime.h
-
-divtest: divtest.c ../../libcrypto.a
-	cc -I../../include divtest.c -o divtest ../../libcrypto.a
-
-bnbug: bnbug.c ../../libcrypto.a top
-	cc -g -I../../include bnbug.c -o bnbug ../../libcrypto.a
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-# ELF
-bn86-elf.s:	asm/bn-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) bn-586.pl elf $(CFLAGS) > ../$@)
-co86-elf.s:	asm/co-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) co-586.pl elf $(CFLAGS) > ../$@)
-mo86-elf.s:	asm/mo-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) mo-586.pl elf $(CFLAGS) > ../$@)
-# COFF
-bn86-cof.s: asm/bn-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) bn-586.pl coff $(CFLAGS) > ../$@)
-co86-cof.s: asm/co-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) co-586.pl coff $(CFLAGS) > ../$@)
-mo86-cof.s: asm/mo-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) mo-586.pl coff $(CFLAGS) > ../$@)
-# a.out
-bn86-out.s: asm/bn-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) bn-586.pl a.out $(CFLAGS) > ../$@)
-co86-out.s: asm/co-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) co-586.pl a.out $(CFLAGS) > ../$@)
-mo86-out.s: asm/mo-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) mo-586.pl a.out $(CFLAGS) > ../$@)
-
-sparcv8.o:	asm/sparcv8.S
-	$(CC) $(CFLAGS) -c asm/sparcv8.S
-sparcv8plus.o:	asm/sparcv8plus.S
-	$(CC) $(CFLAGS) -c asm/sparcv8plus.S
-
-bn-mips3.o:	asm/mips3.s
-	@if [ "$(CC)" = "gcc" ]; then \
-		ABI=`expr "$(CFLAGS)" : ".*-mabi=\([n3264]*\)"` && \
-		as -$$ABI -O -o $@ asm/mips3.s; \
-	else	$(CC) -c $(CFLAGS) -o $@ asm/mips3.s; fi
-
-x86_64-gcc.o:	asm/x86_64-gcc.c
-	$(CC) $(CFLAGS) -c -o $@ asm/x86_64-gcc.c
-x86_64-mont.s:	asm/x86_64-mont.pl
-	$(PERL) asm/x86_64-mont.pl $@
-
-bn-ia64.s:	asm/ia64.S
-	$(CC) $(CFLAGS) -E asm/ia64.S > $@
-
-# GNU assembler fails to compile PA-RISC2 modules, insist on calling
-# vendor assembler...
-pa-risc2W.o: asm/pa-risc2W.s
-	/usr/ccs/bin/as -o pa-risc2W.o asm/pa-risc2W.s
-pa-risc2.o: asm/pa-risc2.s
-	/usr/ccs/bin/as -o pa-risc2.o asm/pa-risc2.s
-
-# ppc - AIX, Linux, MacOS X...
-linux_ppc32.s: asm/ppc.pl;	$(PERL) $< $@
-linux_ppc64.s: asm/ppc.pl;	$(PERL) $< $@
-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
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-exptest:
-	rm -f exptest
-	gcc -I../../include -g2 -ggdb -o exptest exptest.c ../../libcrypto.a
-
-div:
-	rm -f a.out
-	gcc -I.. -g div.c ../../libcrypto.a
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-bn_add.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_add.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_add.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_add.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_add.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_add.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_add.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_add.c bn_lcl.h
-bn_asm.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_asm.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_asm.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_asm.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_asm.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_asm.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_asm.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_asm.c bn_lcl.h
-bn_blind.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_blind.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_blind.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_blind.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_blind.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_blind.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_blind.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_blind.c bn_lcl.h
-bn_const.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-bn_const.o: ../../include/openssl/ossl_typ.h bn.h bn_const.c
-bn_ctx.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_ctx.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_ctx.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_ctx.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_ctx.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_ctx.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_ctx.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_ctx.c bn_lcl.h
-bn_depr.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_depr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_depr.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_depr.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_depr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_depr.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-bn_depr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bn_depr.o: ../cryptlib.h bn_depr.c bn_lcl.h
-bn_div.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_div.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_div.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_div.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_div.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_div.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_div.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_div.c bn_lcl.h
-bn_err.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-bn_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-bn_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-bn_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-bn_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bn_err.o: bn_err.c
-bn_exp.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_exp.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_exp.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_exp.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_exp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_exp.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_exp.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_exp.c bn_lcl.h
-bn_exp2.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_exp2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_exp2.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_exp2.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_exp2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_exp2.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_exp2.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_exp2.c bn_lcl.h
-bn_gcd.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_gcd.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_gcd.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_gcd.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_gcd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_gcd.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_gcd.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_gcd.c bn_lcl.h
-bn_gf2m.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_gf2m.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_gf2m.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_gf2m.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_gf2m.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_gf2m.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_gf2m.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_gf2m.c bn_lcl.h
-bn_kron.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_kron.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_kron.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_kron.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_kron.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_kron.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_kron.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_kron.c bn_lcl.h
-bn_lib.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_lib.c
-bn_mod.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_mod.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_mod.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_mod.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_mod.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_mod.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_mod.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_mod.c
-bn_mont.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_mont.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_mont.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_mont.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_mont.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_mont.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_mont.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_mont.c
-bn_mpi.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_mpi.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_mpi.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_mpi.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_mpi.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_mpi.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_mpi.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_mpi.c
-bn_mul.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_mul.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_mul.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_mul.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_mul.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_mul.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_mul.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_mul.c
-bn_nist.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_nist.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_nist.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_nist.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-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
-bn_prime.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_prime.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_prime.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-bn_prime.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bn_prime.o: ../cryptlib.h bn_lcl.h bn_prime.c bn_prime.h
-bn_print.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_print.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_print.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_print.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_print.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_print.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_print.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_print.c
-bn_rand.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_rand.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_rand.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_rand.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-bn_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bn_rand.o: ../cryptlib.h bn_lcl.h bn_rand.c
-bn_recp.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_recp.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_recp.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_recp.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_recp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_recp.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_recp.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_recp.c
-bn_shift.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_shift.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_shift.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_shift.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_shift.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_shift.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_shift.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_shift.c
-bn_sqr.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_sqr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_sqr.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_sqr.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_sqr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_sqr.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_sqr.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_sqr.c
-bn_sqrt.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_sqrt.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_sqrt.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_sqrt.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_sqrt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_sqrt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_sqrt.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_sqrt.c
-bn_word.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-bn_word.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-bn_word.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_word.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-bn_word.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bn_word.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_word.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_word.c
-bn_x931p.o: ../../include/openssl/bn.h ../../include/openssl/e_os2.h
-bn_x931p.o: ../../include/openssl/opensslconf.h
-bn_x931p.o: ../../include/openssl/ossl_typ.h bn_x931p.c
diff --git a/crypto/bn/asm/alpha-mont.pl b/crypto/bn/asm/alpha-mont.pl
new file mode 100644
index 0000000..7a2cc31
--- /dev/null
+++ b/crypto/bn/asm/alpha-mont.pl
@@ -0,0 +1,317 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# On 21264 RSA sign performance improves by 70/35/20/15 percent for
+# 512/1024/2048/4096 bit key lengths. This is against vendor compiler
+# instructed to '-tune host' code with in-line assembler. Other
+# benchmarks improve by 15-20%. To anchor it to something else, the
+# code provides approximately the same performance per GHz as AMD64.
+# I.e. if you compare 1GHz 21264 and 2GHz Opteron, you'll observe ~2x
+# difference.
+
+# int bn_mul_mont(
+$rp="a0";	# BN_ULONG *rp,
+$ap="a1";	# const BN_ULONG *ap,
+$bp="a2";	# const BN_ULONG *bp,
+$np="a3";	# const BN_ULONG *np,
+$n0="a4";	# const BN_ULONG *n0,
+$num="a5";	# int num);
+
+$lo0="t0";
+$hi0="t1";
+$lo1="t2";
+$hi1="t3";
+$aj="t4";
+$bi="t5";
+$nj="t6";
+$tp="t7";
+$alo="t8";
+$ahi="t9";
+$nlo="t10";
+$nhi="t11";
+$tj="t12";
+$i="s3";
+$j="s4";
+$m1="s5";
+
+$code=<<___;
+#include <asm.h>
+#include <regdef.h>
+
+.text
+
+.set	noat
+.set	noreorder
+
+.globl	bn_mul_mont
+.align	5
+.ent	bn_mul_mont
+bn_mul_mont:
+	lda	sp,-40(sp)
+	stq	ra,0(sp)
+	stq	s3,8(sp)
+	stq	s4,16(sp)
+	stq	s5,24(sp)
+	stq	fp,32(sp)
+	mov	sp,fp
+	.mask	0x0400f000,-40
+	.frame	fp,40,ra
+	.prologue 0
+
+	.align	4
+	.set	reorder
+	sextl	$num,$num
+	mov	0,v0
+	cmplt	$num,4,AT
+	bne	AT,.Lexit
+
+	ldq	$hi0,0($ap)	# ap[0]
+	s8addq	$num,16,AT
+	ldq	$aj,8($ap)
+	subq	sp,AT,sp
+	ldq	$bi,0($bp)	# bp[0]
+	mov	-4096,AT
+	ldq	$n0,0($n0)
+	and	sp,AT,sp
+
+	mulq	$hi0,$bi,$lo0
+	ldq	$hi1,0($np)	# np[0]
+	umulh	$hi0,$bi,$hi0
+	ldq	$nj,8($np)
+
+	mulq	$lo0,$n0,$m1
+
+	mulq	$hi1,$m1,$lo1
+	umulh	$hi1,$m1,$hi1
+
+	addq	$lo1,$lo0,$lo1
+	cmpult	$lo1,$lo0,AT
+	addq	$hi1,AT,$hi1
+
+	mulq	$aj,$bi,$alo
+	mov	2,$j
+	umulh	$aj,$bi,$ahi
+	mov	sp,$tp
+
+	mulq	$nj,$m1,$nlo
+	s8addq	$j,$ap,$aj
+	umulh	$nj,$m1,$nhi
+	s8addq	$j,$np,$nj
+.align	4
+.L1st:
+	.set	noreorder
+	ldq	$aj,($aj)
+	addl	$j,1,$j
+	ldq	$nj,($nj)
+	lda	$tp,8($tp)
+
+	addq	$alo,$hi0,$lo0
+	mulq	$aj,$bi,$alo
+	cmpult	$lo0,$hi0,AT
+	addq	$nlo,$hi1,$lo1
+
+	mulq	$nj,$m1,$nlo
+	addq	$ahi,AT,$hi0
+	cmpult	$lo1,$hi1,v0
+	cmplt	$j,$num,$tj
+
+	umulh	$aj,$bi,$ahi
+	addq	$nhi,v0,$hi1
+	addq	$lo1,$lo0,$lo1
+	s8addq	$j,$ap,$aj
+
+	umulh	$nj,$m1,$nhi
+	cmpult	$lo1,$lo0,v0
+	addq	$hi1,v0,$hi1
+	s8addq	$j,$np,$nj
+
+	stq	$lo1,-8($tp)
+	nop
+	unop
+	bne	$tj,.L1st
+	.set	reorder
+
+	addq	$alo,$hi0,$lo0
+	addq	$nlo,$hi1,$lo1
+	cmpult	$lo0,$hi0,AT
+	cmpult	$lo1,$hi1,v0
+	addq	$ahi,AT,$hi0
+	addq	$nhi,v0,$hi1
+
+	addq	$lo1,$lo0,$lo1
+	cmpult	$lo1,$lo0,v0
+	addq	$hi1,v0,$hi1
+
+	stq	$lo1,0($tp)
+
+	addq	$hi1,$hi0,$hi1
+	cmpult	$hi1,$hi0,AT
+	stq	$hi1,8($tp)
+	stq	AT,16($tp)
+
+	mov	1,$i
+.align	4
+.Louter:
+	s8addq	$i,$bp,$bi
+	ldq	$hi0,($ap)
+	ldq	$aj,8($ap)
+	ldq	$bi,($bi)
+	ldq	$hi1,($np)
+	ldq	$nj,8($np)
+	ldq	$tj,(sp)
+
+	mulq	$hi0,$bi,$lo0
+	umulh	$hi0,$bi,$hi0
+
+	addq	$lo0,$tj,$lo0
+	cmpult	$lo0,$tj,AT
+	addq	$hi0,AT,$hi0
+
+	mulq	$lo0,$n0,$m1
+
+	mulq	$hi1,$m1,$lo1
+	umulh	$hi1,$m1,$hi1
+
+	addq	$lo1,$lo0,$lo1
+	cmpult	$lo1,$lo0,AT
+	mov	2,$j
+	addq	$hi1,AT,$hi1
+
+	mulq	$aj,$bi,$alo
+	mov	sp,$tp
+	umulh	$aj,$bi,$ahi
+
+	mulq	$nj,$m1,$nlo
+	s8addq	$j,$ap,$aj
+	umulh	$nj,$m1,$nhi
+.align	4
+.Linner:
+	.set	noreorder
+	ldq	$tj,8($tp)	#L0
+	nop			#U1
+	ldq	$aj,($aj)	#L1
+	s8addq	$j,$np,$nj	#U0
+
+	ldq	$nj,($nj)	#L0
+	nop			#U1
+	addq	$alo,$hi0,$lo0	#L1
+	lda	$tp,8($tp)
+
+	mulq	$aj,$bi,$alo	#U1
+	cmpult	$lo0,$hi0,AT	#L0
+	addq	$nlo,$hi1,$lo1	#L1
+	addl	$j,1,$j
+
+	mulq	$nj,$m1,$nlo	#U1
+	addq	$ahi,AT,$hi0	#L0
+	addq	$lo0,$tj,$lo0	#L1
+	cmpult	$lo1,$hi1,v0	#U0
+
+	umulh	$aj,$bi,$ahi	#U1
+	cmpult	$lo0,$tj,AT	#L0
+	addq	$lo1,$lo0,$lo1	#L1
+	addq	$nhi,v0,$hi1	#U0
+
+	umulh	$nj,$m1,$nhi	#U1
+	s8addq	$j,$ap,$aj	#L0
+	cmpult	$lo1,$lo0,v0	#L1
+	cmplt	$j,$num,$tj	#U0	# borrow $tj
+
+	addq	$hi0,AT,$hi0	#L0
+	addq	$hi1,v0,$hi1	#U1
+	stq	$lo1,-8($tp)	#L1
+	bne	$tj,.Linner	#U0
+	.set	reorder
+
+	ldq	$tj,8($tp)
+	addq	$alo,$hi0,$lo0
+	addq	$nlo,$hi1,$lo1
+	cmpult	$lo0,$hi0,AT
+	cmpult	$lo1,$hi1,v0
+	addq	$ahi,AT,$hi0
+	addq	$nhi,v0,$hi1
+
+	addq	$lo0,$tj,$lo0
+	cmpult	$lo0,$tj,AT
+	addq	$hi0,AT,$hi0
+
+	ldq	$tj,16($tp)
+	addq	$lo1,$lo0,$j
+	cmpult	$j,$lo0,v0
+	addq	$hi1,v0,$hi1
+
+	addq	$hi1,$hi0,$lo1
+	stq	$j,($tp)
+	cmpult	$lo1,$hi0,$hi1
+	addq	$lo1,$tj,$lo1
+	cmpult	$lo1,$tj,AT
+	addl	$i,1,$i
+	addq	$hi1,AT,$hi1
+	stq	$lo1,8($tp)
+	cmplt	$i,$num,$tj	# borrow $tj
+	stq	$hi1,16($tp)
+	bne	$tj,.Louter
+
+	s8addq	$num,sp,$tj	# &tp[num]
+	mov	$rp,$bp		# put rp aside
+	mov	sp,$tp
+	mov	sp,$ap
+	mov	0,$hi0		# clear borrow bit
+
+.align	4
+.Lsub:	ldq	$lo0,($tp)
+	ldq	$lo1,($np)
+	lda	$tp,8($tp)
+	lda	$np,8($np)
+	subq	$lo0,$lo1,$lo1	# tp[i]-np[i]
+	cmpult	$lo0,$lo1,AT
+	subq	$lo1,$hi0,$lo0
+	cmpult	$lo1,$lo0,$hi0
+	or	$hi0,AT,$hi0
+	stq	$lo0,($rp)
+	cmpult	$tp,$tj,v0
+	lda	$rp,8($rp)
+	bne	v0,.Lsub
+
+	subq	$hi1,$hi0,$hi0	# handle upmost overflow bit
+	mov	sp,$tp
+	mov	$bp,$rp		# restore rp
+
+	and	sp,$hi0,$ap
+	bic	$bp,$hi0,$bp
+	bis	$bp,$ap,$ap	# ap=borrow?tp:rp
+
+.align	4
+.Lcopy:	ldq	$aj,($ap)	# copy or in-place refresh
+	lda	$tp,8($tp)
+	lda	$rp,8($rp)
+	lda	$ap,8($ap)
+	stq	zero,-8($tp)	# zap tp
+	cmpult	$tp,$tj,AT
+	stq	$aj,-8($rp)
+	bne	AT,.Lcopy
+	mov	1,v0
+
+.Lexit:
+	.set	noreorder
+	mov	fp,sp
+	/*ldq	ra,0(sp)*/
+	ldq	s3,8(sp)
+	ldq	s4,16(sp)
+	ldq	s5,24(sp)
+	ldq	fp,32(sp)
+	lda	sp,40(sp)
+	ret	(ra)
+.end	bn_mul_mont
+.rdata
+.asciiz	"Montgomery Multiplication for Alpha, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+print $code;
+close STDOUT;
diff --git a/crypto/0.9.9-dev/bn/armv4-mont.pl b/crypto/bn/asm/armv4-mont.pl
similarity index 99%
rename from crypto/0.9.9-dev/bn/armv4-mont.pl
rename to crypto/bn/asm/armv4-mont.pl
index 05d5dc1..14e0d2d 100644
--- a/crypto/0.9.9-dev/bn/armv4-mont.pl
+++ b/crypto/bn/asm/armv4-mont.pl
@@ -193,6 +193,7 @@
 	bx	lr			@ interoperable with Thumb ISA:-)
 .size	bn_mul_mont,.-bn_mul_mont
 .asciz	"Montgomery multiplication for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
+.align	2
 ___
 
 $code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
diff --git a/crypto/0.9.9-dev/bn/armv4-mont.s b/crypto/bn/asm/armv4-mont.s
similarity index 100%
rename from crypto/0.9.9-dev/bn/armv4-mont.s
rename to crypto/bn/asm/armv4-mont.s
diff --git a/crypto/bn/asm/bn-586.pl b/crypto/bn/asm/bn-586.pl
index 26c2685..332ef3e 100644
--- a/crypto/bn/asm/bn-586.pl
+++ b/crypto/bn/asm/bn-586.pl
@@ -1,6 +1,7 @@
 #!/usr/local/bin/perl
 
-push(@INC,"perlasm","../../perlasm");
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
 require "x86asm.pl";
 
 &asm_init($ARGV[0],$0);
@@ -24,38 +25,25 @@
 	{
 	local($name)=@_;
 
-	&function_begin($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":"");
+	&function_begin_B($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":"");
 
-	&comment("");
-	$Low="eax";
-	$High="edx";
-	$a="ebx";
-	$w="ebp";
-	$r="edi";
-	$c="esi";
-
-	&xor($c,$c);		# clear carry
-	&mov($r,&wparam(0));	#
-
-	&mov("ecx",&wparam(2));	#
-	&mov($a,&wparam(1));	#
-
-	&and("ecx",0xfffffff8);	# num / 8
-	&mov($w,&wparam(3));	#
-
-	&push("ecx");		# Up the stack for a tmp variable
-
-	&jz(&label("maw_finish"));
+	$r="eax";
+	$a="edx";
+	$c="ecx";
 
 	if ($sse2) {
 		&picmeup("eax","OPENSSL_ia32cap_P");
 		&bt(&DWP(0,"eax"),26);
-		&jnc(&label("maw_loop"));
+		&jnc(&label("maw_non_sse2"));
 
-		&movd("mm0",$w);		# mm0 = w
+		&mov($r,&wparam(0));
+		&mov($a,&wparam(1));
+		&mov($c,&wparam(2));
+		&movd("mm0",&wparam(3));	# mm0 = w
 		&pxor("mm1","mm1");		# mm1 = carry_in
-
-		&set_label("maw_sse2_loop",0);
+		&jmp(&label("maw_sse2_entry"));
+		
+	&set_label("maw_sse2_unrolled",16);
 		&movd("mm3",&DWP(0,$r,"",0));	# mm3 = r[0]
 		&paddq("mm1","mm3");		# mm1 = carry_in + r[0]
 		&movd("mm2",&DWP(0,$a,"",0));	# mm2 = a[0]
@@ -112,42 +100,82 @@
 		&psrlq("mm1",32);		# mm1 = carry6
 		&paddq("mm1","mm3");		# mm1 = carry6 + r[7] + w*a[7]
 		&movd(&DWP(28,$r,"",0),"mm1");
-		&add($r,32);
+		&lea($r,&DWP(32,$r));
 		&psrlq("mm1",32);		# mm1 = carry_out
 
-		&sub("ecx",8);
+		&sub($c,8);
+		&jz(&label("maw_sse2_exit"));
+	&set_label("maw_sse2_entry");
+		&test($c,0xfffffff8);
+		&jnz(&label("maw_sse2_unrolled"));
+
+	&set_label("maw_sse2_loop",4);
+		&movd("mm2",&DWP(0,$a));	# mm2 = a[i]
+		&movd("mm3",&DWP(0,$r));	# mm3 = r[i]
+		&pmuludq("mm2","mm0");		# a[i] *= w
+		&lea($a,&DWP(4,$a));
+		&paddq("mm1","mm3");		# carry += r[i]
+		&paddq("mm1","mm2");		# carry += a[i]*w
+		&movd(&DWP(0,$r),"mm1");	# r[i] = carry_low
+		&sub($c,1);
+		&psrlq("mm1",32);		# carry = carry_high
+		&lea($r,&DWP(4,$r));
 		&jnz(&label("maw_sse2_loop"));
-
-		&movd($c,"mm1");		# c = carry_out
+	&set_label("maw_sse2_exit");
+		&movd("eax","mm1");		# c = carry_out
 		&emms();
+		&ret();
 
-		&jmp(&label("maw_finish"));
+	&set_label("maw_non_sse2",16);
 	}
 
-	&set_label("maw_loop",0);
+	# function_begin prologue
+	&push("ebp");
+	&push("ebx");
+	&push("esi");
+	&push("edi");
 
-	&mov(&swtmp(0),"ecx");	#
+	&comment("");
+	$Low="eax";
+	$High="edx";
+	$a="ebx";
+	$w="ebp";
+	$r="edi";
+	$c="esi";
+
+	&xor($c,$c);		# clear carry
+	&mov($r,&wparam(0));	#
+
+	&mov("ecx",&wparam(2));	#
+	&mov($a,&wparam(1));	#
+
+	&and("ecx",0xfffffff8);	# num / 8
+	&mov($w,&wparam(3));	#
+
+	&push("ecx");		# Up the stack for a tmp variable
+
+	&jz(&label("maw_finish"));
+
+	&set_label("maw_loop",16);
 
 	for ($i=0; $i<32; $i+=4)
 		{
 		&comment("Round $i");
 
-		 &mov("eax",&DWP($i,$a,"",0)); 	# *a
+		 &mov("eax",&DWP($i,$a)); 	# *a
 		&mul($w);			# *a * w
-		&add("eax",$c);		# L(t)+= *r
-		 &mov($c,&DWP($i,$r,"",0));	# L(t)+= *r
+		&add("eax",$c);			# L(t)+= c
 		&adc("edx",0);			# H(t)+=carry
-		 &add("eax",$c);		# L(t)+=c
+		 &add("eax",&DWP($i,$r));	# L(t)+= *r
 		&adc("edx",0);			# H(t)+=carry
-		 &mov(&DWP($i,$r,"",0),"eax");	# *r= L(t);
+		 &mov(&DWP($i,$r),"eax");	# *r= L(t);
 		&mov($c,"edx");			# c=  H(t);
 		}
 
 	&comment("");
-	&mov("ecx",&swtmp(0));	#
-	&add($a,32);
-	&add($r,32);
 	&sub("ecx",8);
+	&lea($a,&DWP(32,$a));
+	&lea($r,&DWP(32,$r));
 	&jnz(&label("maw_loop"));
 
 	&set_label("maw_finish",0);
@@ -160,16 +188,15 @@
 	for ($i=0; $i<7; $i++)
 		{
 		&comment("Tail Round $i");
-		 &mov("eax",&DWP($i*4,$a,"",0));# *a
+		 &mov("eax",&DWP($i*4,$a));	# *a
 		&mul($w);			# *a * w
 		&add("eax",$c);			# L(t)+=c
-		 &mov($c,&DWP($i*4,$r,"",0));	# L(t)+= *r
 		&adc("edx",0);			# H(t)+=carry
-		 &add("eax",$c);
+		 &add("eax",&DWP($i*4,$r));	# L(t)+= *r
 		&adc("edx",0);			# H(t)+=carry
 		 &dec("ecx") if ($i != 7-1);
-		&mov(&DWP($i*4,$r,"",0),"eax");	# *r= L(t);
-		 &mov($c,"edx");			# c=  H(t);
+		&mov(&DWP($i*4,$r),"eax");	# *r= L(t);
+		 &mov($c,"edx");		# c=  H(t);
 		&jz(&label("maw_end")) if ($i != 7-1);
 		}
 	&set_label("maw_end",0);
@@ -184,7 +211,45 @@
 	{
 	local($name)=@_;
 
-	&function_begin($name,"");
+	&function_begin_B($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":"");
+
+	$r="eax";
+	$a="edx";
+	$c="ecx";
+
+	if ($sse2) {
+		&picmeup("eax","OPENSSL_ia32cap_P");
+		&bt(&DWP(0,"eax"),26);
+		&jnc(&label("mw_non_sse2"));
+
+		&mov($r,&wparam(0));
+		&mov($a,&wparam(1));
+		&mov($c,&wparam(2));
+		&movd("mm0",&wparam(3));	# mm0 = w
+		&pxor("mm1","mm1");		# mm1 = carry = 0
+
+	&set_label("mw_sse2_loop",16);
+		&movd("mm2",&DWP(0,$a));	# mm2 = a[i]
+		&pmuludq("mm2","mm0");		# a[i] *= w
+		&lea($a,&DWP(4,$a));
+		&paddq("mm1","mm2");		# carry += a[i]*w
+		&movd(&DWP(0,$r),"mm1");	# r[i] = carry_low
+		&sub($c,1);
+		&psrlq("mm1",32);		# carry = carry_high
+		&lea($r,&DWP(4,$r));
+		&jnz(&label("mw_sse2_loop"));
+
+		&movd("eax","mm1");		# return carry
+		&emms();
+		&ret();
+	&set_label("mw_non_sse2",16);
+	}
+
+	# function_begin prologue
+	&push("ebp");
+	&push("ebx");
+	&push("esi");
+	&push("edi");
 
 	&comment("");
 	$Low="eax";
@@ -257,7 +322,40 @@
 	{
 	local($name)=@_;
 
-	&function_begin($name,"");
+	&function_begin_B($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":"");
+
+	$r="eax";
+	$a="edx";
+	$c="ecx";
+
+	if ($sse2) {
+		&picmeup("eax","OPENSSL_ia32cap_P");
+		&bt(&DWP(0,"eax"),26);
+		&jnc(&label("sqr_non_sse2"));
+
+		&mov($r,&wparam(0));
+		&mov($a,&wparam(1));
+		&mov($c,&wparam(2));
+
+	&set_label("sqr_sse2_loop",16);
+		&movd("mm0",&DWP(0,$a));	# mm0 = a[i]
+		&pmuludq("mm0","mm0");		# a[i] *= a[i]
+		&lea($a,&DWP(4,$a));		# a++
+		&movq(&QWP(0,$r),"mm0");	# r[i] = a[i]*a[i]
+		&sub($c,1);
+		&lea($r,&DWP(8,$r));		# r += 2
+		&jnz(&label("sqr_sse2_loop"));
+
+		&emms();
+		&ret();
+	&set_label("sqr_non_sse2",16);
+	}
+
+	# function_begin prologue
+	&push("ebp");
+	&push("ebx");
+	&push("esi");
+	&push("edi");
 
 	&comment("");
 	$r="esi";
@@ -313,12 +411,13 @@
 	{
 	local($name)=@_;
 
-	&function_begin($name,"");
+	&function_begin_B($name,"");
 	&mov("edx",&wparam(0));	#
 	&mov("eax",&wparam(1));	#
-	&mov("ebx",&wparam(2));	#
-	&div("ebx");
-	&function_end($name);
+	&mov("ecx",&wparam(2));	#
+	&div("ecx");
+	&ret();
+	&function_end_B($name);
 	}
 
 sub bn_add_words
diff --git a/crypto/bn/asm/co-586.pl b/crypto/bn/asm/co-586.pl
index 5d962cb..57101a6 100644
--- a/crypto/bn/asm/co-586.pl
+++ b/crypto/bn/asm/co-586.pl
@@ -1,6 +1,7 @@
 #!/usr/local/bin/perl
 
-push(@INC,"perlasm","../../perlasm");
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
 require "x86asm.pl";
 
 &asm_init($ARGV[0],$0);
diff --git a/crypto/bn/asm/mips3-mont.pl b/crypto/bn/asm/mips3-mont.pl
new file mode 100644
index 0000000..8f9156e
--- /dev/null
+++ b/crypto/bn/asm/mips3-mont.pl
@@ -0,0 +1,327 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# This module doesn't present direct interest for OpenSSL, because it
+# doesn't provide better performance for longer keys. While 512-bit
+# RSA private key operations are 40% faster, 1024-bit ones are hardly
+# faster at all, while longer key operations are slower by up to 20%.
+# It might be of interest to embedded system developers though, as
+# it's smaller than 1KB, yet offers ~3x improvement over compiler
+# generated code.
+#
+# The module targets N32 and N64 MIPS ABIs and currently is a bit
+# IRIX-centric, i.e. is likely to require adaptation for other OSes.
+
+# int bn_mul_mont(
+$rp="a0";	# BN_ULONG *rp,
+$ap="a1";	# const BN_ULONG *ap,
+$bp="a2";	# const BN_ULONG *bp,
+$np="a3";	# const BN_ULONG *np,
+$n0="a4";	# const BN_ULONG *n0,
+$num="a5";	# int num);
+
+$lo0="a6";
+$hi0="a7";
+$lo1="v0";
+$hi1="v1";
+$aj="t0";
+$bi="t1";
+$nj="t2";
+$tp="t3";
+$alo="s0";
+$ahi="s1";
+$nlo="s2";
+$nhi="s3";
+$tj="s4";
+$i="s5";
+$j="s6";
+$fp="t8";
+$m1="t9";
+
+$FRAME=8*(2+8);
+
+$code=<<___;
+#include <asm.h>
+#include <regdef.h>
+
+.text
+
+.set	noat
+.set	reorder
+
+.align	5
+.globl	bn_mul_mont
+.ent	bn_mul_mont
+bn_mul_mont:
+	.set	noreorder
+	PTR_SUB	sp,64
+	move	$fp,sp
+	.frame	$fp,64,ra
+	slt	AT,$num,4
+	li	v0,0
+	beqzl	AT,.Lproceed
+	nop
+	jr	ra
+	PTR_ADD	sp,$fp,64
+	.set	reorder
+.align	5
+.Lproceed:
+	ld	$n0,0($n0)
+	ld	$bi,0($bp)	# bp[0]
+	ld	$aj,0($ap)	# ap[0]
+	ld	$nj,0($np)	# np[0]
+	PTR_SUB	sp,16		# place for two extra words
+	sll	$num,3
+	li	AT,-4096
+	PTR_SUB	sp,$num
+	and	sp,AT
+
+	sd	s0,0($fp)
+	sd	s1,8($fp)
+	sd	s2,16($fp)
+	sd	s3,24($fp)
+	sd	s4,32($fp)
+	sd	s5,40($fp)
+	sd	s6,48($fp)
+	sd	s7,56($fp)
+
+	dmultu	$aj,$bi
+	ld	$alo,8($ap)
+	ld	$nlo,8($np)
+	mflo	$lo0
+	mfhi	$hi0
+	dmultu	$lo0,$n0
+	mflo	$m1
+
+	dmultu	$alo,$bi
+	mflo	$alo
+	mfhi	$ahi
+
+	dmultu	$nj,$m1
+	mflo	$lo1
+	mfhi	$hi1
+	dmultu	$nlo,$m1
+	daddu	$lo1,$lo0
+	sltu	AT,$lo1,$lo0
+	daddu	$hi1,AT
+	mflo	$nlo
+	mfhi	$nhi
+
+	move	$tp,sp
+	li	$j,16
+.align	4
+.L1st:
+	.set	noreorder
+	PTR_ADD	$aj,$ap,$j
+	ld	$aj,($aj)
+	PTR_ADD	$nj,$np,$j
+	ld	$nj,($nj)
+
+	dmultu	$aj,$bi
+	daddu	$lo0,$alo,$hi0
+	daddu	$lo1,$nlo,$hi1
+	sltu	AT,$lo0,$hi0
+	sltu	s7,$lo1,$hi1
+	daddu	$hi0,$ahi,AT
+	daddu	$hi1,$nhi,s7
+	mflo	$alo
+	mfhi	$ahi
+
+	daddu	$lo1,$lo0
+	sltu	AT,$lo1,$lo0
+	dmultu	$nj,$m1
+	daddu	$hi1,AT
+	addu	$j,8
+	sd	$lo1,($tp)
+	sltu	s7,$j,$num
+	mflo	$nlo
+	mfhi	$nhi
+
+	bnez	s7,.L1st
+	PTR_ADD	$tp,8
+	.set	reorder
+
+	daddu	$lo0,$alo,$hi0
+	sltu	AT,$lo0,$hi0
+	daddu	$hi0,$ahi,AT
+
+	daddu	$lo1,$nlo,$hi1
+	sltu	s7,$lo1,$hi1
+	daddu	$hi1,$nhi,s7
+	daddu	$lo1,$lo0
+	sltu	AT,$lo1,$lo0
+	daddu	$hi1,AT
+
+	sd	$lo1,($tp)
+
+	daddu	$hi1,$hi0
+	sltu	AT,$hi1,$hi0
+	sd	$hi1,8($tp)
+	sd	AT,16($tp)
+
+	li	$i,8
+.align	4
+.Louter:
+	PTR_ADD	$bi,$bp,$i
+	ld	$bi,($bi)
+	ld	$aj,($ap)
+	ld	$alo,8($ap)
+	ld	$tj,(sp)
+
+	dmultu	$aj,$bi
+	ld	$nj,($np)
+	ld	$nlo,8($np)
+	mflo	$lo0
+	mfhi	$hi0
+	daddu	$lo0,$tj
+	dmultu	$lo0,$n0
+	sltu	AT,$lo0,$tj
+	daddu	$hi0,AT
+	mflo	$m1
+
+	dmultu	$alo,$bi
+	mflo	$alo
+	mfhi	$ahi
+
+	dmultu	$nj,$m1
+	mflo	$lo1
+	mfhi	$hi1
+
+	dmultu	$nlo,$m1
+	daddu	$lo1,$lo0
+	sltu	AT,$lo1,$lo0
+	daddu	$hi1,AT
+	mflo	$nlo
+	mfhi	$nhi
+
+	move	$tp,sp
+	li	$j,16
+	ld	$tj,8($tp)
+.align	4
+.Linner:
+	.set	noreorder
+	PTR_ADD	$aj,$ap,$j
+	ld	$aj,($aj)
+	PTR_ADD	$nj,$np,$j
+	ld	$nj,($nj)
+
+	dmultu	$aj,$bi
+	daddu	$lo0,$alo,$hi0
+	daddu	$lo1,$nlo,$hi1
+	sltu	AT,$lo0,$hi0
+	sltu	s7,$lo1,$hi1
+	daddu	$hi0,$ahi,AT
+	daddu	$hi1,$nhi,s7
+	mflo	$alo
+	mfhi	$ahi
+
+	daddu	$lo0,$tj
+	addu	$j,8
+	dmultu	$nj,$m1
+	sltu	AT,$lo0,$tj
+	daddu	$lo1,$lo0
+	daddu	$hi0,AT
+	sltu	s7,$lo1,$lo0
+	ld	$tj,16($tp)
+	daddu	$hi1,s7
+	sltu	AT,$j,$num
+	mflo	$nlo
+	mfhi	$nhi
+	sd	$lo1,($tp)
+	bnez	AT,.Linner
+	PTR_ADD	$tp,8
+	.set	reorder
+
+	daddu	$lo0,$alo,$hi0
+	sltu	AT,$lo0,$hi0
+	daddu	$hi0,$ahi,AT
+	daddu	$lo0,$tj
+	sltu	s7,$lo0,$tj
+	daddu	$hi0,s7
+
+	ld	$tj,16($tp)
+	daddu	$lo1,$nlo,$hi1
+	sltu	AT,$lo1,$hi1
+	daddu	$hi1,$nhi,AT
+	daddu	$lo1,$lo0
+	sltu	s7,$lo1,$lo0
+	daddu	$hi1,s7
+	sd	$lo1,($tp)
+
+	daddu	$lo1,$hi1,$hi0
+	sltu	$hi1,$lo1,$hi0
+	daddu	$lo1,$tj
+	sltu	AT,$lo1,$tj
+	daddu	$hi1,AT
+	sd	$lo1,8($tp)
+	sd	$hi1,16($tp)
+
+	addu	$i,8
+	sltu	s7,$i,$num
+	bnez	s7,.Louter
+
+	.set	noreorder
+	PTR_ADD	$tj,sp,$num	# &tp[num]
+	move	$tp,sp
+	move	$ap,sp
+	li	$hi0,0		# clear borrow bit
+
+.align	4
+.Lsub:	ld	$lo0,($tp)
+	ld	$lo1,($np)
+	PTR_ADD	$tp,8
+	PTR_ADD	$np,8
+	dsubu	$lo1,$lo0,$lo1	# tp[i]-np[i]
+	sgtu	AT,$lo1,$lo0
+	dsubu	$lo0,$lo1,$hi0
+	sgtu	$hi0,$lo0,$lo1
+	sd	$lo0,($rp)
+	or	$hi0,AT
+	sltu	AT,$tp,$tj
+	bnez	AT,.Lsub
+	PTR_ADD	$rp,8
+
+	dsubu	$hi0,$hi1,$hi0	# handle upmost overflow bit
+	move	$tp,sp
+	PTR_SUB	$rp,$num	# restore rp
+	not	$hi1,$hi0
+
+	and	$ap,$hi0,sp
+	and	$bp,$hi1,$rp
+	or	$ap,$ap,$bp	# ap=borrow?tp:rp
+
+.align	4
+.Lcopy:	ld	$aj,($ap)
+	PTR_ADD	$ap,8
+	PTR_ADD	$tp,8
+	sd	zero,-8($tp)
+	sltu	AT,$tp,$tj
+	sd	$aj,($rp)
+	bnez	AT,.Lcopy
+	PTR_ADD	$rp,8
+
+	ld	s0,0($fp)
+	ld	s1,8($fp)
+	ld	s2,16($fp)
+	ld	s3,24($fp)
+	ld	s4,32($fp)
+	ld	s5,40($fp)
+	ld	s6,48($fp)
+	ld	s7,56($fp)
+	li	v0,1
+	jr	ra
+	PTR_ADD	sp,$fp,64
+	.set	reorder
+END(bn_mul_mont)
+.rdata
+.asciiz	"Montgomery Multiplication for MIPS III/IV, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+print $code;
+close STDOUT;
diff --git a/crypto/bn/asm/ppc-mont.pl b/crypto/bn/asm/ppc-mont.pl
new file mode 100644
index 0000000..7849eae
--- /dev/null
+++ b/crypto/bn/asm/ppc-mont.pl
@@ -0,0 +1,323 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# April 2006
+
+# "Teaser" Montgomery multiplication module for PowerPC. It's possible
+# to gain a bit more by modulo-scheduling outer loop, then dedicated
+# squaring procedure should give further 20% and code can be adapted
+# for 32-bit application running on 64-bit CPU. As for the latter.
+# It won't be able to achieve "native" 64-bit performance, because in
+# 32-bit application context every addc instruction will have to be
+# expanded as addc, twice right shift by 32 and finally adde, etc.
+# So far RSA *sign* performance improvement over pre-bn_mul_mont asm
+# for 64-bit application running on PPC970/G5 is:
+#
+# 512-bit	+65%	
+# 1024-bit	+35%
+# 2048-bit	+18%
+# 4096-bit	+4%
+
+$flavour = shift;
+
+if ($flavour =~ /32/) {
+	$BITS=	32;
+	$BNSZ=	$BITS/8;
+	$SIZE_T=4;
+	$RZONE=	224;
+	$FRAME=	$SIZE_T*16;
+
+	$LD=	"lwz";		# load
+	$LDU=	"lwzu";		# load and update
+	$LDX=	"lwzx";		# load indexed
+	$ST=	"stw";		# store
+	$STU=	"stwu";		# store and update
+	$STX=	"stwx";		# store indexed
+	$STUX=	"stwux";	# store indexed and update
+	$UMULL=	"mullw";	# unsigned multiply low
+	$UMULH=	"mulhwu";	# unsigned multiply high
+	$UCMP=	"cmplw";	# unsigned compare
+	$SHRI=	"srwi";		# unsigned shift right by immediate	
+	$PUSH=	$ST;
+	$POP=	$LD;
+} elsif ($flavour =~ /64/) {
+	$BITS=	64;
+	$BNSZ=	$BITS/8;
+	$SIZE_T=8;
+	$RZONE=	288;
+	$FRAME=	$SIZE_T*16;
+
+	# same as above, but 64-bit mnemonics...
+	$LD=	"ld";		# load
+	$LDU=	"ldu";		# load and update
+	$LDX=	"ldx";		# load indexed
+	$ST=	"std";		# store
+	$STU=	"stdu";		# store and update
+	$STX=	"stdx";		# store indexed
+	$STUX=	"stdux";	# store indexed and update
+	$UMULL=	"mulld";	# unsigned multiply low
+	$UMULH=	"mulhdu";	# unsigned multiply high
+	$UCMP=	"cmpld";	# unsigned compare
+	$SHRI=	"srdi";		# unsigned shift right by immediate	
+	$PUSH=	$ST;
+	$POP=	$LD;
+} else { die "nonsense $flavour"; }
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
+die "can't locate ppc-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
+
+$sp="r1";
+$toc="r2";
+$rp="r3";	$ovf="r3";
+$ap="r4";
+$bp="r5";
+$np="r6";
+$n0="r7";
+$num="r8";
+$rp="r9";	# $rp is reassigned
+$aj="r10";
+$nj="r11";
+$tj="r12";
+# non-volatile registers
+$i="r14";
+$j="r15";
+$tp="r16";
+$m0="r17";
+$m1="r18";
+$lo0="r19";
+$hi0="r20";
+$lo1="r21";
+$hi1="r22";
+$alo="r23";
+$ahi="r24";
+$nlo="r25";
+#
+$nhi="r0";
+
+$code=<<___;
+.machine "any"
+.text
+
+.globl	.bn_mul_mont
+.align	4
+.bn_mul_mont:
+	cmpwi	$num,4
+	mr	$rp,r3		; $rp is reassigned
+	li	r3,0
+	bltlr
+
+	slwi	$num,$num,`log($BNSZ)/log(2)`
+	li	$tj,-4096
+	addi	$ovf,$num,`$FRAME+$RZONE`
+	subf	$ovf,$ovf,$sp	; $sp-$ovf
+	and	$ovf,$ovf,$tj	; minimize TLB usage
+	subf	$ovf,$sp,$ovf	; $ovf-$sp
+	srwi	$num,$num,`log($BNSZ)/log(2)`
+	$STUX	$sp,$sp,$ovf
+
+	$PUSH	r14,`4*$SIZE_T`($sp)
+	$PUSH	r15,`5*$SIZE_T`($sp)
+	$PUSH	r16,`6*$SIZE_T`($sp)
+	$PUSH	r17,`7*$SIZE_T`($sp)
+	$PUSH	r18,`8*$SIZE_T`($sp)
+	$PUSH	r19,`9*$SIZE_T`($sp)
+	$PUSH	r20,`10*$SIZE_T`($sp)
+	$PUSH	r21,`11*$SIZE_T`($sp)
+	$PUSH	r22,`12*$SIZE_T`($sp)
+	$PUSH	r23,`13*$SIZE_T`($sp)
+	$PUSH	r24,`14*$SIZE_T`($sp)
+	$PUSH	r25,`15*$SIZE_T`($sp)
+
+	$LD	$n0,0($n0)	; pull n0[0] value
+	addi	$num,$num,-2	; adjust $num for counter register
+
+	$LD	$m0,0($bp)	; m0=bp[0]
+	$LD	$aj,0($ap)	; ap[0]
+	addi	$tp,$sp,$FRAME
+	$UMULL	$lo0,$aj,$m0	; ap[0]*bp[0]
+	$UMULH	$hi0,$aj,$m0
+
+	$LD	$aj,$BNSZ($ap)	; ap[1]
+	$LD	$nj,0($np)	; np[0]
+
+	$UMULL	$m1,$lo0,$n0	; "tp[0]"*n0
+
+	$UMULL	$alo,$aj,$m0	; ap[1]*bp[0]
+	$UMULH	$ahi,$aj,$m0
+
+	$UMULL	$lo1,$nj,$m1	; np[0]*m1
+	$UMULH	$hi1,$nj,$m1
+	$LD	$nj,$BNSZ($np)	; np[1]
+	addc	$lo1,$lo1,$lo0
+	addze	$hi1,$hi1
+
+	$UMULL	$nlo,$nj,$m1	; np[1]*m1
+	$UMULH	$nhi,$nj,$m1
+
+	mtctr	$num
+	li	$j,`2*$BNSZ`
+.align	4
+L1st:
+	$LDX	$aj,$ap,$j	; ap[j]
+	addc	$lo0,$alo,$hi0
+	$LDX	$nj,$np,$j	; np[j]
+	addze	$hi0,$ahi
+	$UMULL	$alo,$aj,$m0	; ap[j]*bp[0]
+	addc	$lo1,$nlo,$hi1
+	$UMULH	$ahi,$aj,$m0
+	addze	$hi1,$nhi
+	$UMULL	$nlo,$nj,$m1	; np[j]*m1
+	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[0]
+	$UMULH	$nhi,$nj,$m1
+	addze	$hi1,$hi1
+	$ST	$lo1,0($tp)	; tp[j-1]
+
+	addi	$j,$j,$BNSZ	; j++
+	addi	$tp,$tp,$BNSZ	; tp++
+	bdnz-	L1st
+;L1st
+	addc	$lo0,$alo,$hi0
+	addze	$hi0,$ahi
+
+	addc	$lo1,$nlo,$hi1
+	addze	$hi1,$nhi
+	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[0]
+	addze	$hi1,$hi1
+	$ST	$lo1,0($tp)	; tp[j-1]
+
+	li	$ovf,0
+	addc	$hi1,$hi1,$hi0
+	addze	$ovf,$ovf	; upmost overflow bit
+	$ST	$hi1,$BNSZ($tp)
+
+	li	$i,$BNSZ
+.align	4
+Louter:
+	$LDX	$m0,$bp,$i	; m0=bp[i]
+	$LD	$aj,0($ap)	; ap[0]
+	addi	$tp,$sp,$FRAME
+	$LD	$tj,$FRAME($sp)	; tp[0]
+	$UMULL	$lo0,$aj,$m0	; ap[0]*bp[i]
+	$UMULH	$hi0,$aj,$m0
+	$LD	$aj,$BNSZ($ap)	; ap[1]
+	$LD	$nj,0($np)	; np[0]
+	addc	$lo0,$lo0,$tj	; ap[0]*bp[i]+tp[0]
+	$UMULL	$alo,$aj,$m0	; ap[j]*bp[i]
+	addze	$hi0,$hi0
+	$UMULL	$m1,$lo0,$n0	; tp[0]*n0
+	$UMULH	$ahi,$aj,$m0
+	$UMULL	$lo1,$nj,$m1	; np[0]*m1
+	$UMULH	$hi1,$nj,$m1
+	$LD	$nj,$BNSZ($np)	; np[1]
+	addc	$lo1,$lo1,$lo0
+	$UMULL	$nlo,$nj,$m1	; np[1]*m1
+	addze	$hi1,$hi1
+	$UMULH	$nhi,$nj,$m1
+
+	mtctr	$num
+	li	$j,`2*$BNSZ`
+.align	4
+Linner:
+	$LDX	$aj,$ap,$j	; ap[j]
+	addc	$lo0,$alo,$hi0
+	$LD	$tj,$BNSZ($tp)	; tp[j]
+	addze	$hi0,$ahi
+	$LDX	$nj,$np,$j	; np[j]
+	addc	$lo1,$nlo,$hi1
+	$UMULL	$alo,$aj,$m0	; ap[j]*bp[i]
+	addze	$hi1,$nhi
+	$UMULH	$ahi,$aj,$m0
+	addc	$lo0,$lo0,$tj	; ap[j]*bp[i]+tp[j]
+	$UMULL	$nlo,$nj,$m1	; np[j]*m1
+	addze	$hi0,$hi0
+	$UMULH	$nhi,$nj,$m1
+	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[i]+tp[j]
+	addi	$j,$j,$BNSZ	; j++
+	addze	$hi1,$hi1
+	$ST	$lo1,0($tp)	; tp[j-1]
+	addi	$tp,$tp,$BNSZ	; tp++
+	bdnz-	Linner
+;Linner
+	$LD	$tj,$BNSZ($tp)	; tp[j]
+	addc	$lo0,$alo,$hi0
+	addze	$hi0,$ahi
+	addc	$lo0,$lo0,$tj	; ap[j]*bp[i]+tp[j]
+	addze	$hi0,$hi0
+
+	addc	$lo1,$nlo,$hi1
+	addze	$hi1,$nhi
+	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[i]+tp[j]
+	addze	$hi1,$hi1
+	$ST	$lo1,0($tp)	; tp[j-1]
+
+	addic	$ovf,$ovf,-1	; move upmost overflow to XER[CA]
+	li	$ovf,0
+	adde	$hi1,$hi1,$hi0
+	addze	$ovf,$ovf
+	$ST	$hi1,$BNSZ($tp)
+;
+	slwi	$tj,$num,`log($BNSZ)/log(2)`
+	$UCMP	$i,$tj
+	addi	$i,$i,$BNSZ
+	ble-	Louter
+
+	addi	$num,$num,2	; restore $num
+	subfc	$j,$j,$j	; j=0 and "clear" XER[CA]
+	addi	$tp,$sp,$FRAME
+	mtctr	$num
+
+.align	4
+Lsub:	$LDX	$tj,$tp,$j
+	$LDX	$nj,$np,$j
+	subfe	$aj,$nj,$tj	; tp[j]-np[j]
+	$STX	$aj,$rp,$j
+	addi	$j,$j,$BNSZ
+	bdnz-	Lsub
+
+	li	$j,0
+	mtctr	$num
+	subfe	$ovf,$j,$ovf	; handle upmost overflow bit
+	and	$ap,$tp,$ovf
+	andc	$np,$rp,$ovf
+	or	$ap,$ap,$np	; ap=borrow?tp:rp
+
+.align	4
+Lcopy:				; copy or in-place refresh
+	$LDX	$tj,$ap,$j
+	$STX	$tj,$rp,$j
+	$STX	$j,$tp,$j	; zap at once
+	addi	$j,$j,$BNSZ
+	bdnz-	Lcopy
+
+	$POP	r14,`4*$SIZE_T`($sp)
+	$POP	r15,`5*$SIZE_T`($sp)
+	$POP	r16,`6*$SIZE_T`($sp)
+	$POP	r17,`7*$SIZE_T`($sp)
+	$POP	r18,`8*$SIZE_T`($sp)
+	$POP	r19,`9*$SIZE_T`($sp)
+	$POP	r20,`10*$SIZE_T`($sp)
+	$POP	r21,`11*$SIZE_T`($sp)
+	$POP	r22,`12*$SIZE_T`($sp)
+	$POP	r23,`13*$SIZE_T`($sp)
+	$POP	r24,`14*$SIZE_T`($sp)
+	$POP	r25,`15*$SIZE_T`($sp)
+	$POP	$sp,0($sp)
+	li	r3,1
+	blr
+	.long	0
+.asciz  "Montgomery Multiplication for PPC, CRYPTOGAMS by <appro\@fy.chalmers.se>"
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/crypto/bn/asm/ppc.pl b/crypto/bn/asm/ppc.pl
index 08e0053..37c65d3 100644
--- a/crypto/bn/asm/ppc.pl
+++ b/crypto/bn/asm/ppc.pl
@@ -100,9 +100,9 @@
 #	me a note at schari@us.ibm.com
 #
 
-$opf = shift;
+$flavour = shift;
 
-if ($opf =~ /32\.s/) {
+if ($flavour =~ /32/) {
 	$BITS=	32;
 	$BNSZ=	$BITS/8;
 	$ISA=	"\"ppc\"";
@@ -125,7 +125,7 @@
 	$INSR=	"insrwi";	# insert right
 	$ROTL=	"rotlwi";	# rotate left by immediate
 	$TR=	"tw";		# conditional trap
-} elsif ($opf =~ /64\.s/) {
+} elsif ($flavour =~ /64/) {
 	$BITS=	64;
 	$BNSZ=	$BITS/8;
 	$ISA=	"\"ppc64\"";
@@ -149,93 +149,16 @@
 	$INSR=	"insrdi";	# insert right 
 	$ROTL=	"rotldi";	# rotate left by immediate
 	$TR=	"td";		# conditional trap
-} else { die "nonsense $opf"; }
+} else { die "nonsense $flavour"; }
 
-( defined shift || open STDOUT,">$opf" ) || die "can't open $opf: $!";
+$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";
 
-# function entry points from the AIX code
-#
-# There are other, more elegant, ways to handle this. We (IBM) chose
-# this approach as it plays well with scripts we run to 'namespace'
-# OpenSSL .i.e. we add a prefix to all the public symbols so we can
-# co-exist in the same process with other implementations of OpenSSL.
-# 'cleverer' ways of doing these substitutions tend to hide data we
-# need to be obvious.
-#
-my @items = ("bn_sqr_comba4",
-	     "bn_sqr_comba8",
-	     "bn_mul_comba4",
-	     "bn_mul_comba8",
-	     "bn_sub_words",
-	     "bn_add_words",
-	     "bn_div_words",
-	     "bn_sqr_words",
-	     "bn_mul_words",
-	     "bn_mul_add_words");
+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
 
-if    ($opf =~ /linux/)	{  do_linux();	}
-elsif ($opf =~ /aix/)	{  do_aix();	}
-elsif ($opf =~ /osx/)	{  do_osx();	}
-else			{  do_bsd();	}
-
-sub do_linux {
-    $d=&data();
-
-    if ($BITS==64) {
-      foreach $t (@items) {
-        $d =~ s/\.$t:/\
-\t.section\t".opd","aw"\
-\t.align\t3\
-\t.globl\t$t\
-$t:\
-\t.quad\t.$t,.TOC.\@tocbase,0\
-\t.size\t$t,24\
-\t.previous\n\
-\t.type\t.$t,\@function\
-\t.globl\t.$t\
-.$t:/g;
-      }
-    }
-    else {
-      foreach $t (@items) {
-        $d=~s/\.$t/$t/g;
-      }
-    }
-    # hide internal labels to avoid pollution of name table...
-    $d=~s/Lppcasm_/.Lppcasm_/gm;
-    print $d;
-}
-
-sub do_aix {
-    # AIX assembler is smart enough to please the linker without
-    # making us do something special...
-    print &data();
-}
-
-# MacOSX 32 bit
-sub do_osx {
-    $d=&data();
-    # Change the bn symbol prefix from '.' to '_'
-    foreach $t (@items) {
-      $d=~s/\.$t/_$t/g;
-    }
-    # Change .machine to something OS X asm will accept
-    $d=~s/\.machine.*/.text/g;
-    $d=~s/\#/;/g; # change comment from '#' to ';'
-    print $d;
-}
-
-# BSD (Untested)
-sub do_bsd {
-    $d=&data();
-    foreach $t (@items) {
-      $d=~s/\.$t/_$t/g;
-    }
-    print $d;
-}
-
-sub data {
-	local($data)=<<EOF;
+$data=<<EOF;
 #--------------------------------------------------------------------
 #
 #
@@ -297,33 +220,20 @@
 #
 #	Defines to be used in the assembly code.
 #	
-.set r0,0	# we use it as storage for value of 0
-.set SP,1	# preserved
-.set RTOC,2	# preserved 
-.set r3,3	# 1st argument/return value
-.set r4,4	# 2nd argument/volatile register
-.set r5,5	# 3rd argument/volatile register
-.set r6,6	# ...
-.set r7,7
-.set r8,8
-.set r9,9
-.set r10,10
-.set r11,11
-.set r12,12
-.set r13,13	# not used, nor any other "below" it...
-
-.set BO_IF_NOT,4
-.set BO_IF,12
-.set BO_dCTR_NZERO,16
-.set BO_dCTR_ZERO,18
-.set BO_ALWAYS,20
-.set CR0_LT,0;
-.set CR0_GT,1;
-.set CR0_EQ,2
-.set CR1_FX,4;
-.set CR1_FEX,5;
-.set CR1_VX,6
-.set LR,8
+#.set r0,0	# we use it as storage for value of 0
+#.set SP,1	# preserved
+#.set RTOC,2	# preserved 
+#.set r3,3	# 1st argument/return value
+#.set r4,4	# 2nd argument/volatile register
+#.set r5,5	# 3rd argument/volatile register
+#.set r6,6	# ...
+#.set r7,7
+#.set r8,8
+#.set r9,9
+#.set r10,10
+#.set r11,11
+#.set r12,12
+#.set r13,13	# not used, nor any other "below" it...
 
 #	Declare function names to be global
 #	NOTE:	For gcc these names MUST be changed to remove
@@ -344,7 +254,7 @@
 	
 # .text section
 	
-	.machine	$ISA
+	.machine	"any"
 
 #
 #	NOTE:	The following label name should be changed to
@@ -478,7 +388,7 @@
 
 	$ST		r9,`6*$BNSZ`(r3)	#r[6]=c1
 	$ST		r10,`7*$BNSZ`(r3)	#r[7]=c2
-	bclr	BO_ALWAYS,CR0_LT
+	blr
 	.long	0x00000000
 
 #
@@ -903,7 +813,7 @@
 	$ST		r9, `15*$BNSZ`(r3)	#r[15]=c1;
 
 
-	bclr	BO_ALWAYS,CR0_LT
+	blr
 
 	.long	0x00000000
 
@@ -1055,7 +965,7 @@
 
 	$ST	r10,`6*$BNSZ`(r3)	#r[6]=c1
 	$ST	r11,`7*$BNSZ`(r3)	#r[7]=c2
-	bclr	BO_ALWAYS,CR0_LT
+	blr
 	.long	0x00000000
 
 #
@@ -1591,7 +1501,7 @@
 	adde	r10,r10,r9
 	$ST	r12,`14*$BNSZ`(r3)	#r[14]=c3;
 	$ST	r10,`15*$BNSZ`(r3)	#r[15]=c1;
-	bclr	BO_ALWAYS,CR0_LT
+	blr
 	.long	0x00000000
 
 #
@@ -1623,7 +1533,7 @@
 	subfc.	r7,r0,r6        # If r6 is 0 then result is 0.
 				# if r6 > 0 then result !=0
 				# In either case carry bit is set.
-	bc	BO_IF,CR0_EQ,Lppcasm_sub_adios
+	beq	Lppcasm_sub_adios
 	addi	r4,r4,-$BNSZ
 	addi	r3,r3,-$BNSZ
 	addi	r5,r5,-$BNSZ
@@ -1635,11 +1545,11 @@
 				# if carry = 1 this is r7-r8. Else it
 				# is r7-r8 -1 as we need.
 	$STU	r6,$BNSZ(r3)
-	bc	BO_dCTR_NZERO,CR0_EQ,Lppcasm_sub_mainloop
+	bdnz-	Lppcasm_sub_mainloop
 Lppcasm_sub_adios:	
 	subfze	r3,r0		# if carry bit is set then r3 = 0 else -1
 	andi.	r3,r3,1         # keep only last bit.
-	bclr	BO_ALWAYS,CR0_LT
+	blr
 	.long	0x00000000
 
 
@@ -1670,7 +1580,7 @@
 #	check for r6 = 0. Is this needed?
 #
 	addic.	r6,r6,0		#test r6 and clear carry bit.
-	bc	BO_IF,CR0_EQ,Lppcasm_add_adios
+	beq	Lppcasm_add_adios
 	addi	r4,r4,-$BNSZ
 	addi	r3,r3,-$BNSZ
 	addi	r5,r5,-$BNSZ
@@ -1680,10 +1590,10 @@
 	$LDU	r8,$BNSZ(r5)
 	adde	r8,r7,r8
 	$STU	r8,$BNSZ(r3)
-	bc	BO_dCTR_NZERO,CR0_EQ,Lppcasm_add_mainloop
+	bdnz-	Lppcasm_add_mainloop
 Lppcasm_add_adios:	
 	addze	r3,r0			#return carry bit.
-	bclr	BO_ALWAYS,CR0_LT
+	blr
 	.long	0x00000000
 
 #
@@ -1707,24 +1617,24 @@
 #	r5 = d
 	
 	$UCMPI	0,r5,0			# compare r5 and 0
-	bc	BO_IF_NOT,CR0_EQ,Lppcasm_div1	# proceed if d!=0
+	bne	Lppcasm_div1		# proceed if d!=0
 	li	r3,-1			# d=0 return -1
-	bclr	BO_ALWAYS,CR0_LT	
+	blr
 Lppcasm_div1:
 	xor	r0,r0,r0		#r0=0
 	li	r8,$BITS
 	$CNTLZ.	r7,r5			#r7 = num leading 0s in d.
-	bc	BO_IF,CR0_EQ,Lppcasm_div2	#proceed if no leading zeros
+	beq	Lppcasm_div2		#proceed if no leading zeros
 	subf	r8,r7,r8		#r8 = BN_num_bits_word(d)
 	$SHR.	r9,r3,r8		#are there any bits above r8'th?
 	$TR	16,r9,r0		#if there're, signal to dump core...
 Lppcasm_div2:
 	$UCMP	0,r3,r5			#h>=d?
-	bc	BO_IF,CR0_LT,Lppcasm_div3	#goto Lppcasm_div3 if not
+	blt	Lppcasm_div3		#goto Lppcasm_div3 if not
 	subf	r3,r5,r3		#h-=d ; 
 Lppcasm_div3:				#r7 = BN_BITS2-i. so r7=i
 	cmpi	0,0,r7,0		# is (i == 0)?
-	bc	BO_IF,CR0_EQ,Lppcasm_div4
+	beq	Lppcasm_div4
 	$SHL	r3,r3,r7		# h = (h<< i)
 	$SHR	r8,r4,r8		# r8 = (l >> BN_BITS2 -i)
 	$SHL	r5,r5,r7		# d<<=i
@@ -1741,7 +1651,7 @@
 	$SHRI	r11,r4,`$BITS/2`	#r11= (l&BN_MASK2h)>>BN_BITS4
 					# compute here for innerloop.
 	$UCMP	0,r8,r9			# is (h>>BN_BITS4)==dh
-	bc	BO_IF_NOT,CR0_EQ,Lppcasm_div5	# goto Lppcasm_div5 if not
+	bne	Lppcasm_div5		# goto Lppcasm_div5 if not
 
 	li	r8,-1
 	$CLRU	r8,r8,`$BITS/2`		#q = BN_MASK2l 
@@ -1762,9 +1672,9 @@
 					# the following 2 instructions do that
 	$SHLI	r7,r10,`$BITS/2`	# r7 = (t<<BN_BITS4)
 	or	r7,r7,r11		# r7|=((l&BN_MASK2h)>>BN_BITS4)
-	$UCMP	1,r6,r7			# compare (tl <= r7)
-	bc	BO_IF_NOT,CR0_EQ,Lppcasm_divinnerexit
-	bc	BO_IF_NOT,CR1_FEX,Lppcasm_divinnerexit
+	$UCMP	cr1,r6,r7		# compare (tl <= r7)
+	bne	Lppcasm_divinnerexit
+	ble	cr1,Lppcasm_divinnerexit
 	addi	r8,r8,-1		#q--
 	subf	r12,r9,r12		#th -=dh
 	$CLRU	r10,r5,`$BITS/2`	#r10=dl. t is no longer needed in loop.
@@ -1773,14 +1683,14 @@
 Lppcasm_divinnerexit:
 	$SHRI	r10,r6,`$BITS/2`	#t=(tl>>BN_BITS4)
 	$SHLI	r11,r6,`$BITS/2`	#tl=(tl<<BN_BITS4)&BN_MASK2h;
-	$UCMP	1,r4,r11		# compare l and tl
+	$UCMP	cr1,r4,r11		# compare l and tl
 	add	r12,r12,r10		# th+=t
-	bc	BO_IF_NOT,CR1_FX,Lppcasm_div7  # if (l>=tl) goto Lppcasm_div7
+	bge	cr1,Lppcasm_div7	# if (l>=tl) goto Lppcasm_div7
 	addi	r12,r12,1		# th++
 Lppcasm_div7:
 	subf	r11,r11,r4		#r11=l-tl
-	$UCMP	1,r3,r12		#compare h and th
-	bc	BO_IF_NOT,CR1_FX,Lppcasm_div8	#if (h>=th) goto Lppcasm_div8
+	$UCMP	cr1,r3,r12		#compare h and th
+	bge	cr1,Lppcasm_div8	#if (h>=th) goto Lppcasm_div8
 	addi	r8,r8,-1		# q--
 	add	r3,r5,r3		# h+=d
 Lppcasm_div8:
@@ -1791,12 +1701,12 @@
 					# the following 2 instructions will do this.
 	$INSR	r11,r12,`$BITS/2`,`$BITS/2`	# r11 is the value we want rotated $BITS/2.
 	$ROTL	r3,r11,`$BITS/2`	# rotate by $BITS/2 and store in r3
-	bc	BO_dCTR_ZERO,CR0_EQ,Lppcasm_div9#if (count==0) break ;
+	bdz	Lppcasm_div9		#if (count==0) break ;
 	$SHLI	r0,r8,`$BITS/2`		#ret =q<<BN_BITS4
 	b	Lppcasm_divouterloop
 Lppcasm_div9:
 	or	r3,r8,r0
-	bclr	BO_ALWAYS,CR0_LT
+	blr
 	.long	0x00000000
 
 #
@@ -1822,7 +1732,7 @@
 #	No unrolling done here. Not performance critical.
 
 	addic.	r5,r5,0			#test r5.
-	bc	BO_IF,CR0_EQ,Lppcasm_sqr_adios
+	beq	Lppcasm_sqr_adios
 	addi	r4,r4,-$BNSZ
 	addi	r3,r3,-$BNSZ
 	mtctr	r5
@@ -1833,9 +1743,9 @@
 	$UMULH  r8,r6,r6
 	$STU	r7,$BNSZ(r3)
 	$STU	r8,$BNSZ(r3)
-	bc	BO_dCTR_NZERO,CR0_EQ,Lppcasm_sqr_mainloop
+	bdnz-	Lppcasm_sqr_mainloop
 Lppcasm_sqr_adios:	
-	bclr	BO_ALWAYS,CR0_LT
+	blr
 	.long	0x00000000
 
 
@@ -1858,7 +1768,7 @@
 	xor	r0,r0,r0
 	xor	r12,r12,r12		# used for carry
 	rlwinm.	r7,r5,30,2,31		# num >> 2
-	bc	BO_IF,CR0_EQ,Lppcasm_mw_REM
+	beq	Lppcasm_mw_REM
 	mtctr	r7
 Lppcasm_mw_LOOP:	
 					#mul(rp[0],ap[0],w,c1);
@@ -1896,11 +1806,11 @@
 	
 	addi	r3,r3,`4*$BNSZ`
 	addi	r4,r4,`4*$BNSZ`
-	bc	BO_dCTR_NZERO,CR0_EQ,Lppcasm_mw_LOOP
+	bdnz-	Lppcasm_mw_LOOP
 
 Lppcasm_mw_REM:
 	andi.	r5,r5,0x3
-	bc	BO_IF,CR0_EQ,Lppcasm_mw_OVER
+	beq	Lppcasm_mw_OVER
 					#mul(rp[0],ap[0],w,c1);
 	$LD	r8,`0*$BNSZ`(r4)
 	$UMULL	r9,r6,r8
@@ -1912,7 +1822,7 @@
 	
 	addi	r5,r5,-1
 	cmpli	0,0,r5,0
-	bc	BO_IF,CR0_EQ,Lppcasm_mw_OVER
+	beq	Lppcasm_mw_OVER
 
 	
 					#mul(rp[1],ap[1],w,c1);
@@ -1926,7 +1836,7 @@
 	
 	addi	r5,r5,-1
 	cmpli	0,0,r5,0
-	bc	BO_IF,CR0_EQ,Lppcasm_mw_OVER
+	beq	Lppcasm_mw_OVER
 	
 					#mul_add(rp[2],ap[2],w,c1);
 	$LD	r8,`2*$BNSZ`(r4)
@@ -1939,7 +1849,7 @@
 		
 Lppcasm_mw_OVER:	
 	addi	r3,r12,0
-	bclr	BO_ALWAYS,CR0_LT
+	blr
 	.long	0x00000000
 
 #
@@ -1964,7 +1874,7 @@
 	xor	r0,r0,r0		#r0 = 0
 	xor	r12,r12,r12  		#r12 = 0 . used for carry		
 	rlwinm.	r7,r5,30,2,31		# num >> 2
-	bc	BO_IF,CR0_EQ,Lppcasm_maw_leftover	# if (num < 4) go LPPCASM_maw_leftover
+	beq	Lppcasm_maw_leftover	# if (num < 4) go LPPCASM_maw_leftover
 	mtctr	r7
 Lppcasm_maw_mainloop:	
 					#mul_add(rp[0],ap[0],w,c1);
@@ -2017,11 +1927,11 @@
 	$ST	r11,`3*$BNSZ`(r3)
 	addi	r3,r3,`4*$BNSZ`
 	addi	r4,r4,`4*$BNSZ`
-	bc	BO_dCTR_NZERO,CR0_EQ,Lppcasm_maw_mainloop
+	bdnz-	Lppcasm_maw_mainloop
 	
 Lppcasm_maw_leftover:
 	andi.	r5,r5,0x3
-	bc	BO_IF,CR0_EQ,Lppcasm_maw_adios
+	beq	Lppcasm_maw_adios
 	addi	r3,r3,-$BNSZ
 	addi	r4,r4,-$BNSZ
 					#mul_add(rp[0],ap[0],w,c1);
@@ -2036,7 +1946,7 @@
 	addze	r12,r10
 	$ST	r9,0(r3)
 	
-	bc	BO_dCTR_ZERO,CR0_EQ,Lppcasm_maw_adios
+	bdz	Lppcasm_maw_adios
 					#mul_add(rp[1],ap[1],w,c1);
 	$LDU	r8,$BNSZ(r4)	
 	$UMULL	r9,r6,r8
@@ -2048,7 +1958,7 @@
 	addze	r12,r10
 	$ST	r9,0(r3)
 	
-	bc	BO_dCTR_ZERO,CR0_EQ,Lppcasm_maw_adios
+	bdz	Lppcasm_maw_adios
 					#mul_add(rp[2],ap[2],w,c1);
 	$LDU	r8,$BNSZ(r4)
 	$UMULL	r9,r6,r8
@@ -2062,17 +1972,10 @@
 		
 Lppcasm_maw_adios:	
 	addi	r3,r12,0
-	bclr	BO_ALWAYS,CR0_LT
+	blr
 	.long	0x00000000
 	.align	4
 EOF
-	$data =~ s/\`([^\`]*)\`/eval $1/gem;
-
-	# if some assembler chokes on some simplified mnemonic,
-	# this is the spot to fix it up, e.g.:
-	# GNU as doesn't seem to accept cmplw, 32-bit unsigned compare
-	$data =~ s/^(\s*)cmplw(\s+)([^,]+),(.*)/$1cmpl$2$3,0,$4/gm;
-	# assembler X doesn't accept li, load immediate value
-	#$data =~ s/^(\s*)li(\s+)([^,]+),(.*)/$1addi$2$3,0,$4/gm;
-	return($data);
-}
+$data =~ s/\`([^\`]*)\`/eval $1/gem;
+print $data;
+close STDOUT;
diff --git a/crypto/bn/asm/ppc64-mont.pl b/crypto/bn/asm/ppc64-mont.pl
new file mode 100644
index 0000000..3449b35
--- /dev/null
+++ b/crypto/bn/asm/ppc64-mont.pl
@@ -0,0 +1,918 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# December 2007
+
+# The reason for undertaken effort is basically following. Even though
+# Power 6 CPU operates at incredible 4.7GHz clock frequency, its PKI
+# performance was observed to be less than impressive, essentially as
+# fast as 1.8GHz PPC970, or 2.6 times(!) slower than one would hope.
+# Well, it's not surprising that IBM had to make some sacrifices to
+# boost the clock frequency that much, but no overall improvement?
+# Having observed how much difference did switching to FPU make on
+# UltraSPARC, playing same stunt on Power 6 appeared appropriate...
+# Unfortunately the resulting performance improvement is not as
+# impressive, ~30%, and in absolute terms is still very far from what
+# one would expect from 4.7GHz CPU. There is a chance that I'm doing
+# something wrong, but in the lack of assembler level micro-profiling
+# data or at least decent platform guide I can't tell... Or better
+# results might be achieved with VMX... Anyway, this module provides
+# *worse* performance on other PowerPC implementations, ~40-15% slower
+# on PPC970 depending on key length and ~40% slower on Power 5 for all
+# key lengths. As it's obviously inappropriate as "best all-round"
+# alternative, it has to be complemented with run-time CPU family
+# detection. Oh! It should also be noted that unlike other PowerPC
+# implementation IALU ppc-mont.pl module performs *suboptimaly* on
+# >=1024-bit key lengths on Power 6. It should also be noted that
+# *everything* said so far applies to 64-bit builds! As far as 32-bit
+# application executed on 64-bit CPU goes, this module is likely to
+# become preferred choice, because it's easy to adapt it for such
+# case and *is* faster than 32-bit ppc-mont.pl on *all* processors.
+
+# February 2008
+
+# Micro-profiling assisted optimization results in ~15% improvement
+# over original ppc64-mont.pl version, or overall ~50% improvement
+# over ppc.pl module on Power 6. If compared to ppc-mont.pl on same
+# Power 6 CPU, this module is 5-150% faster depending on key length,
+# [hereafter] more for longer keys. But if compared to ppc-mont.pl
+# on 1.8GHz PPC970, it's only 5-55% faster. Still far from impressive
+# in absolute terms, but it's apparently the way Power 6 is...
+
+$flavour = shift;
+
+if ($flavour =~ /32/) {
+	$SIZE_T=4;
+	$RZONE=	224;
+	$FRAME=	$SIZE_T*12+8*12;
+	$fname=	"bn_mul_mont_ppc64";
+
+	$STUX=	"stwux";	# store indexed and update
+	$PUSH=	"stw";
+	$POP=	"lwz";
+	die "not implemented yet";
+} elsif ($flavour =~ /64/) {
+	$SIZE_T=8;
+	$RZONE=	288;
+	$FRAME=	$SIZE_T*12+8*12;
+	$fname=	"bn_mul_mont";
+
+	# same as above, but 64-bit mnemonics...
+	$STUX=	"stdux";	# store indexed and update
+	$PUSH=	"std";
+	$POP=	"ld";
+} else { die "nonsense $flavour"; }
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
+die "can't locate ppc-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
+
+$FRAME=($FRAME+63)&~63;
+$TRANSFER=16*8;
+
+$carry="r0";
+$sp="r1";
+$toc="r2";
+$rp="r3";	$ovf="r3";
+$ap="r4";
+$bp="r5";
+$np="r6";
+$n0="r7";
+$num="r8";
+$rp="r9";	# $rp is reassigned
+$tp="r10";
+$j="r11";
+$i="r12";
+# non-volatile registers
+$nap_d="r14";	# interleaved ap and np in double format
+$a0="r15";	# ap[0]
+$t0="r16";	# temporary registers
+$t1="r17";
+$t2="r18";
+$t3="r19";
+$t4="r20";
+$t5="r21";
+$t6="r22";
+$t7="r23";
+
+# PPC offers enough register bank capacity to unroll inner loops twice
+#
+#     ..A3A2A1A0
+#           dcba
+#    -----------
+#            A0a
+#           A0b
+#          A0c
+#         A0d
+#          A1a
+#         A1b
+#        A1c
+#       A1d
+#        A2a
+#       A2b
+#      A2c
+#     A2d
+#      A3a
+#     A3b
+#    A3c
+#   A3d
+#    ..a
+#   ..b
+#
+$ba="f0";	$bb="f1";	$bc="f2";	$bd="f3";
+$na="f4";	$nb="f5";	$nc="f6";	$nd="f7";
+$dota="f8";	$dotb="f9";
+$A0="f10";	$A1="f11";	$A2="f12";	$A3="f13";
+$N0="f14";	$N1="f15";	$N2="f16";	$N3="f17";
+$T0a="f18";	$T0b="f19";
+$T1a="f20";	$T1b="f21";
+$T2a="f22";	$T2b="f23";
+$T3a="f24";	$T3b="f25";
+
+# sp----------->+-------------------------------+
+#		| saved sp			|
+#		+-------------------------------+
+#		|				|
+#		+-------------------------------+
+#		| 10 saved gpr, r14-r23		|
+#		.				.
+#		.				.
+#   +12*size_t	+-------------------------------+
+#		| 12 saved fpr, f14-f25		|
+#		.				.
+#		.				.
+#   +12*8	+-------------------------------+
+#		| padding to 64 byte boundary	|
+#		.				.
+#   +X		+-------------------------------+
+#		| 16 gpr<->fpr transfer zone	|
+#		.				.
+#		.				.
+#   +16*8	+-------------------------------+
+#		| __int64 tmp[-1]		|
+#		+-------------------------------+
+#		| __int64 tmp[num]		|
+#		.				.
+#		.				.
+#		.				.
+#   +(num+1)*8	+-------------------------------+
+#		| padding to 64 byte boundary	|
+#		.				.
+#   +X		+-------------------------------+
+#		| double nap_d[4*num]		|
+#		.				.
+#		.				.
+#		.				.
+#		+-------------------------------+
+
+$code=<<___;
+.machine "any"
+.text
+
+.globl	.$fname
+.align	5
+.$fname:
+	cmpwi	$num,4
+	mr	$rp,r3		; $rp is reassigned
+	li	r3,0		; possible "not handled" return code
+	bltlr-
+	andi.	r0,$num,1	; $num has to be even
+	bnelr-
+
+	slwi	$num,$num,3	; num*=8
+	li	$i,-4096
+	slwi	$tp,$num,2	; place for {an}p_{lh}[num], i.e. 4*num
+	add	$tp,$tp,$num	; place for tp[num+1]
+	addi	$tp,$tp,`$FRAME+$TRANSFER+8+64+$RZONE`
+	subf	$tp,$tp,$sp	; $sp-$tp
+	and	$tp,$tp,$i	; minimize TLB usage
+	subf	$tp,$sp,$tp	; $tp-$sp
+	$STUX	$sp,$sp,$tp	; alloca
+
+	$PUSH	r14,`2*$SIZE_T`($sp)
+	$PUSH	r15,`3*$SIZE_T`($sp)
+	$PUSH	r16,`4*$SIZE_T`($sp)
+	$PUSH	r17,`5*$SIZE_T`($sp)
+	$PUSH	r18,`6*$SIZE_T`($sp)
+	$PUSH	r19,`7*$SIZE_T`($sp)
+	$PUSH	r20,`8*$SIZE_T`($sp)
+	$PUSH	r21,`9*$SIZE_T`($sp)
+	$PUSH	r22,`10*$SIZE_T`($sp)
+	$PUSH	r23,`11*$SIZE_T`($sp)
+	stfd	f14,`12*$SIZE_T+0`($sp)
+	stfd	f15,`12*$SIZE_T+8`($sp)
+	stfd	f16,`12*$SIZE_T+16`($sp)
+	stfd	f17,`12*$SIZE_T+24`($sp)
+	stfd	f18,`12*$SIZE_T+32`($sp)
+	stfd	f19,`12*$SIZE_T+40`($sp)
+	stfd	f20,`12*$SIZE_T+48`($sp)
+	stfd	f21,`12*$SIZE_T+56`($sp)
+	stfd	f22,`12*$SIZE_T+64`($sp)
+	stfd	f23,`12*$SIZE_T+72`($sp)
+	stfd	f24,`12*$SIZE_T+80`($sp)
+	stfd	f25,`12*$SIZE_T+88`($sp)
+
+	ld	$a0,0($ap)	; pull ap[0] value
+	ld	$n0,0($n0)	; pull n0[0] value
+	ld	$t3,0($bp)	; bp[0]
+
+	addi	$tp,$sp,`$FRAME+$TRANSFER+8+64`
+	li	$i,-64
+	add	$nap_d,$tp,$num
+	and	$nap_d,$nap_d,$i	; align to 64 bytes
+
+	mulld	$t7,$a0,$t3	; ap[0]*bp[0]
+	; nap_d is off by 1, because it's used with stfdu/lfdu
+	addi	$nap_d,$nap_d,-8
+	srwi	$j,$num,`3+1`	; counter register, num/2
+	mulld	$t7,$t7,$n0	; tp[0]*n0
+	addi	$j,$j,-1
+	addi	$tp,$sp,`$FRAME+$TRANSFER-8`
+	li	$carry,0
+	mtctr	$j
+
+	; transfer bp[0] to FPU as 4x16-bit values
+	extrdi	$t0,$t3,16,48
+	extrdi	$t1,$t3,16,32
+	extrdi	$t2,$t3,16,16
+	extrdi	$t3,$t3,16,0
+	std	$t0,`$FRAME+0`($sp)
+	std	$t1,`$FRAME+8`($sp)
+	std	$t2,`$FRAME+16`($sp)
+	std	$t3,`$FRAME+24`($sp)
+	; transfer (ap[0]*bp[0])*n0 to FPU as 4x16-bit values
+	extrdi	$t4,$t7,16,48
+	extrdi	$t5,$t7,16,32
+	extrdi	$t6,$t7,16,16
+	extrdi	$t7,$t7,16,0
+	std	$t4,`$FRAME+32`($sp)
+	std	$t5,`$FRAME+40`($sp)
+	std	$t6,`$FRAME+48`($sp)
+	std	$t7,`$FRAME+56`($sp)
+	lwz	$t0,4($ap)		; load a[j] as 32-bit word pair
+	lwz	$t1,0($ap)
+	lwz	$t2,12($ap)		; load a[j+1] as 32-bit word pair
+	lwz	$t3,8($ap)
+	lwz	$t4,4($np)		; load n[j] as 32-bit word pair
+	lwz	$t5,0($np)
+	lwz	$t6,12($np)		; load n[j+1] as 32-bit word pair
+	lwz	$t7,8($np)
+	lfd	$ba,`$FRAME+0`($sp)
+	lfd	$bb,`$FRAME+8`($sp)
+	lfd	$bc,`$FRAME+16`($sp)
+	lfd	$bd,`$FRAME+24`($sp)
+	lfd	$na,`$FRAME+32`($sp)
+	lfd	$nb,`$FRAME+40`($sp)
+	lfd	$nc,`$FRAME+48`($sp)
+	lfd	$nd,`$FRAME+56`($sp)
+	std	$t0,`$FRAME+64`($sp)
+	std	$t1,`$FRAME+72`($sp)
+	std	$t2,`$FRAME+80`($sp)
+	std	$t3,`$FRAME+88`($sp)
+	std	$t4,`$FRAME+96`($sp)
+	std	$t5,`$FRAME+104`($sp)
+	std	$t6,`$FRAME+112`($sp)
+	std	$t7,`$FRAME+120`($sp)
+	fcfid	$ba,$ba
+	fcfid	$bb,$bb
+	fcfid	$bc,$bc
+	fcfid	$bd,$bd
+	fcfid	$na,$na
+	fcfid	$nb,$nb
+	fcfid	$nc,$nc
+	fcfid	$nd,$nd
+
+	lfd	$A0,`$FRAME+64`($sp)
+	lfd	$A1,`$FRAME+72`($sp)
+	lfd	$A2,`$FRAME+80`($sp)
+	lfd	$A3,`$FRAME+88`($sp)
+	lfd	$N0,`$FRAME+96`($sp)
+	lfd	$N1,`$FRAME+104`($sp)
+	lfd	$N2,`$FRAME+112`($sp)
+	lfd	$N3,`$FRAME+120`($sp)
+	fcfid	$A0,$A0
+	fcfid	$A1,$A1
+	fcfid	$A2,$A2
+	fcfid	$A3,$A3
+	fcfid	$N0,$N0
+	fcfid	$N1,$N1
+	fcfid	$N2,$N2
+	fcfid	$N3,$N3
+	addi	$ap,$ap,16
+	addi	$np,$np,16
+
+	fmul	$T1a,$A1,$ba
+	fmul	$T1b,$A1,$bb
+	stfd	$A0,8($nap_d)		; save a[j] in double format
+	stfd	$A1,16($nap_d)
+	fmul	$T2a,$A2,$ba
+	fmul	$T2b,$A2,$bb
+	stfd	$A2,24($nap_d)		; save a[j+1] in double format
+	stfd	$A3,32($nap_d)
+	fmul	$T3a,$A3,$ba
+	fmul	$T3b,$A3,$bb
+	stfd	$N0,40($nap_d)		; save n[j] in double format
+	stfd	$N1,48($nap_d)
+	fmul	$T0a,$A0,$ba
+	fmul	$T0b,$A0,$bb
+	stfd	$N2,56($nap_d)		; save n[j+1] in double format
+	stfdu	$N3,64($nap_d)
+
+	fmadd	$T1a,$A0,$bc,$T1a
+	fmadd	$T1b,$A0,$bd,$T1b
+	fmadd	$T2a,$A1,$bc,$T2a
+	fmadd	$T2b,$A1,$bd,$T2b
+	fmadd	$T3a,$A2,$bc,$T3a
+	fmadd	$T3b,$A2,$bd,$T3b
+	fmul	$dota,$A3,$bc
+	fmul	$dotb,$A3,$bd
+
+	fmadd	$T1a,$N1,$na,$T1a
+	fmadd	$T1b,$N1,$nb,$T1b
+	fmadd	$T2a,$N2,$na,$T2a
+	fmadd	$T2b,$N2,$nb,$T2b
+	fmadd	$T3a,$N3,$na,$T3a
+	fmadd	$T3b,$N3,$nb,$T3b
+	fmadd	$T0a,$N0,$na,$T0a
+	fmadd	$T0b,$N0,$nb,$T0b
+
+	fmadd	$T1a,$N0,$nc,$T1a
+	fmadd	$T1b,$N0,$nd,$T1b
+	fmadd	$T2a,$N1,$nc,$T2a
+	fmadd	$T2b,$N1,$nd,$T2b
+	fmadd	$T3a,$N2,$nc,$T3a
+	fmadd	$T3b,$N2,$nd,$T3b
+	fmadd	$dota,$N3,$nc,$dota
+	fmadd	$dotb,$N3,$nd,$dotb
+
+	fctid	$T0a,$T0a
+	fctid	$T0b,$T0b
+	fctid	$T1a,$T1a
+	fctid	$T1b,$T1b
+	fctid	$T2a,$T2a
+	fctid	$T2b,$T2b
+	fctid	$T3a,$T3a
+	fctid	$T3b,$T3b
+
+	stfd	$T0a,`$FRAME+0`($sp)
+	stfd	$T0b,`$FRAME+8`($sp)
+	stfd	$T1a,`$FRAME+16`($sp)
+	stfd	$T1b,`$FRAME+24`($sp)
+	stfd	$T2a,`$FRAME+32`($sp)
+	stfd	$T2b,`$FRAME+40`($sp)
+	stfd	$T3a,`$FRAME+48`($sp)
+	stfd	$T3b,`$FRAME+56`($sp)
+
+.align	5
+L1st:
+	lwz	$t0,4($ap)		; load a[j] as 32-bit word pair
+	lwz	$t1,0($ap)
+	lwz	$t2,12($ap)		; load a[j+1] as 32-bit word pair
+	lwz	$t3,8($ap)
+	lwz	$t4,4($np)		; load n[j] as 32-bit word pair
+	lwz	$t5,0($np)
+	lwz	$t6,12($np)		; load n[j+1] as 32-bit word pair
+	lwz	$t7,8($np)
+	std	$t0,`$FRAME+64`($sp)
+	std	$t1,`$FRAME+72`($sp)
+	std	$t2,`$FRAME+80`($sp)
+	std	$t3,`$FRAME+88`($sp)
+	std	$t4,`$FRAME+96`($sp)
+	std	$t5,`$FRAME+104`($sp)
+	std	$t6,`$FRAME+112`($sp)
+	std	$t7,`$FRAME+120`($sp)
+	ld	$t0,`$FRAME+0`($sp)
+	ld	$t1,`$FRAME+8`($sp)
+	ld	$t2,`$FRAME+16`($sp)
+	ld	$t3,`$FRAME+24`($sp)
+	ld	$t4,`$FRAME+32`($sp)
+	ld	$t5,`$FRAME+40`($sp)
+	ld	$t6,`$FRAME+48`($sp)
+	ld	$t7,`$FRAME+56`($sp)
+	lfd	$A0,`$FRAME+64`($sp)
+	lfd	$A1,`$FRAME+72`($sp)
+	lfd	$A2,`$FRAME+80`($sp)
+	lfd	$A3,`$FRAME+88`($sp)
+	lfd	$N0,`$FRAME+96`($sp)
+	lfd	$N1,`$FRAME+104`($sp)
+	lfd	$N2,`$FRAME+112`($sp)
+	lfd	$N3,`$FRAME+120`($sp)
+	fcfid	$A0,$A0
+	fcfid	$A1,$A1
+	fcfid	$A2,$A2
+	fcfid	$A3,$A3
+	fcfid	$N0,$N0
+	fcfid	$N1,$N1
+	fcfid	$N2,$N2
+	fcfid	$N3,$N3
+	addi	$ap,$ap,16
+	addi	$np,$np,16
+
+	fmul	$T1a,$A1,$ba
+	fmul	$T1b,$A1,$bb
+	fmul	$T2a,$A2,$ba
+	fmul	$T2b,$A2,$bb
+	stfd	$A0,8($nap_d)		; save a[j] in double format
+	stfd	$A1,16($nap_d)
+	fmul	$T3a,$A3,$ba
+	fmul	$T3b,$A3,$bb
+	fmadd	$T0a,$A0,$ba,$dota
+	fmadd	$T0b,$A0,$bb,$dotb
+	stfd	$A2,24($nap_d)		; save a[j+1] in double format
+	stfd	$A3,32($nap_d)
+
+	fmadd	$T1a,$A0,$bc,$T1a
+	fmadd	$T1b,$A0,$bd,$T1b
+	fmadd	$T2a,$A1,$bc,$T2a
+	fmadd	$T2b,$A1,$bd,$T2b
+	stfd	$N0,40($nap_d)		; save n[j] in double format
+	stfd	$N1,48($nap_d)
+	fmadd	$T3a,$A2,$bc,$T3a
+	fmadd	$T3b,$A2,$bd,$T3b
+	 add	$t0,$t0,$carry		; can not overflow
+	fmul	$dota,$A3,$bc
+	fmul	$dotb,$A3,$bd
+	stfd	$N2,56($nap_d)		; save n[j+1] in double format
+	stfdu	$N3,64($nap_d)
+	 srdi	$carry,$t0,16
+	 add	$t1,$t1,$carry
+	 srdi	$carry,$t1,16
+
+	fmadd	$T1a,$N1,$na,$T1a
+	fmadd	$T1b,$N1,$nb,$T1b
+	 insrdi	$t0,$t1,16,32
+	fmadd	$T2a,$N2,$na,$T2a
+	fmadd	$T2b,$N2,$nb,$T2b
+	 add	$t2,$t2,$carry
+	fmadd	$T3a,$N3,$na,$T3a
+	fmadd	$T3b,$N3,$nb,$T3b
+	 srdi	$carry,$t2,16
+	fmadd	$T0a,$N0,$na,$T0a
+	fmadd	$T0b,$N0,$nb,$T0b
+	 insrdi	$t0,$t2,16,16
+	 add	$t3,$t3,$carry
+	 srdi	$carry,$t3,16
+
+	fmadd	$T1a,$N0,$nc,$T1a
+	fmadd	$T1b,$N0,$nd,$T1b
+	 insrdi	$t0,$t3,16,0		; 0..63 bits
+	fmadd	$T2a,$N1,$nc,$T2a
+	fmadd	$T2b,$N1,$nd,$T2b
+	 add	$t4,$t4,$carry
+	fmadd	$T3a,$N2,$nc,$T3a
+	fmadd	$T3b,$N2,$nd,$T3b
+	 srdi	$carry,$t4,16
+	fmadd	$dota,$N3,$nc,$dota
+	fmadd	$dotb,$N3,$nd,$dotb
+	 add	$t5,$t5,$carry
+	 srdi	$carry,$t5,16
+	 insrdi	$t4,$t5,16,32
+
+	fctid	$T0a,$T0a
+	fctid	$T0b,$T0b
+	 add	$t6,$t6,$carry
+	fctid	$T1a,$T1a
+	fctid	$T1b,$T1b
+	 srdi	$carry,$t6,16
+	fctid	$T2a,$T2a
+	fctid	$T2b,$T2b
+	 insrdi	$t4,$t6,16,16
+	fctid	$T3a,$T3a
+	fctid	$T3b,$T3b
+	 add	$t7,$t7,$carry
+	 insrdi	$t4,$t7,16,0		; 64..127 bits
+	 srdi	$carry,$t7,16		; upper 33 bits
+
+	stfd	$T0a,`$FRAME+0`($sp)
+	stfd	$T0b,`$FRAME+8`($sp)
+	stfd	$T1a,`$FRAME+16`($sp)
+	stfd	$T1b,`$FRAME+24`($sp)
+	stfd	$T2a,`$FRAME+32`($sp)
+	stfd	$T2b,`$FRAME+40`($sp)
+	stfd	$T3a,`$FRAME+48`($sp)
+	stfd	$T3b,`$FRAME+56`($sp)
+	 std	$t0,8($tp)		; tp[j-1]
+	 stdu	$t4,16($tp)		; tp[j]
+	bdnz-	L1st
+
+	fctid	$dota,$dota
+	fctid	$dotb,$dotb
+
+	ld	$t0,`$FRAME+0`($sp)
+	ld	$t1,`$FRAME+8`($sp)
+	ld	$t2,`$FRAME+16`($sp)
+	ld	$t3,`$FRAME+24`($sp)
+	ld	$t4,`$FRAME+32`($sp)
+	ld	$t5,`$FRAME+40`($sp)
+	ld	$t6,`$FRAME+48`($sp)
+	ld	$t7,`$FRAME+56`($sp)
+	stfd	$dota,`$FRAME+64`($sp)
+	stfd	$dotb,`$FRAME+72`($sp)
+
+	add	$t0,$t0,$carry		; can not overflow
+	srdi	$carry,$t0,16
+	add	$t1,$t1,$carry
+	srdi	$carry,$t1,16
+	insrdi	$t0,$t1,16,32
+	add	$t2,$t2,$carry
+	srdi	$carry,$t2,16
+	insrdi	$t0,$t2,16,16
+	add	$t3,$t3,$carry
+	srdi	$carry,$t3,16
+	insrdi	$t0,$t3,16,0		; 0..63 bits
+	add	$t4,$t4,$carry
+	srdi	$carry,$t4,16
+	add	$t5,$t5,$carry
+	srdi	$carry,$t5,16
+	insrdi	$t4,$t5,16,32
+	add	$t6,$t6,$carry
+	srdi	$carry,$t6,16
+	insrdi	$t4,$t6,16,16
+	add	$t7,$t7,$carry
+	insrdi	$t4,$t7,16,0		; 64..127 bits
+	srdi	$carry,$t7,16		; upper 33 bits
+	ld	$t6,`$FRAME+64`($sp)
+	ld	$t7,`$FRAME+72`($sp)
+
+	std	$t0,8($tp)		; tp[j-1]
+	stdu	$t4,16($tp)		; tp[j]
+
+	add	$t6,$t6,$carry		; can not overflow
+	srdi	$carry,$t6,16
+	add	$t7,$t7,$carry
+	insrdi	$t6,$t7,48,0
+	srdi	$ovf,$t7,48
+	std	$t6,8($tp)		; tp[num-1]
+
+	slwi	$t7,$num,2
+	subf	$nap_d,$t7,$nap_d	; rewind pointer
+
+	li	$i,8			; i=1
+.align	5
+Louter:
+	ldx	$t3,$bp,$i	; bp[i]
+	ld	$t6,`$FRAME+$TRANSFER+8`($sp)	; tp[0]
+	mulld	$t7,$a0,$t3	; ap[0]*bp[i]
+
+	addi	$tp,$sp,`$FRAME+$TRANSFER`
+	add	$t7,$t7,$t6	; ap[0]*bp[i]+tp[0]
+	li	$carry,0
+	mulld	$t7,$t7,$n0	; tp[0]*n0
+	mtctr	$j
+
+	; transfer bp[i] to FPU as 4x16-bit values
+	extrdi	$t0,$t3,16,48
+	extrdi	$t1,$t3,16,32
+	extrdi	$t2,$t3,16,16
+	extrdi	$t3,$t3,16,0
+	std	$t0,`$FRAME+0`($sp)
+	std	$t1,`$FRAME+8`($sp)
+	std	$t2,`$FRAME+16`($sp)
+	std	$t3,`$FRAME+24`($sp)
+	; transfer (ap[0]*bp[i]+tp[0])*n0 to FPU as 4x16-bit values
+	extrdi	$t4,$t7,16,48
+	extrdi	$t5,$t7,16,32
+	extrdi	$t6,$t7,16,16
+	extrdi	$t7,$t7,16,0
+	std	$t4,`$FRAME+32`($sp)
+	std	$t5,`$FRAME+40`($sp)
+	std	$t6,`$FRAME+48`($sp)
+	std	$t7,`$FRAME+56`($sp)
+
+	lfd	$A0,8($nap_d)		; load a[j] in double format
+	lfd	$A1,16($nap_d)
+	lfd	$A2,24($nap_d)		; load a[j+1] in double format
+	lfd	$A3,32($nap_d)
+	lfd	$N0,40($nap_d)		; load n[j] in double format
+	lfd	$N1,48($nap_d)
+	lfd	$N2,56($nap_d)		; load n[j+1] in double format
+	lfdu	$N3,64($nap_d)
+
+	lfd	$ba,`$FRAME+0`($sp)
+	lfd	$bb,`$FRAME+8`($sp)
+	lfd	$bc,`$FRAME+16`($sp)
+	lfd	$bd,`$FRAME+24`($sp)
+	lfd	$na,`$FRAME+32`($sp)
+	lfd	$nb,`$FRAME+40`($sp)
+	lfd	$nc,`$FRAME+48`($sp)
+	lfd	$nd,`$FRAME+56`($sp)
+
+	fcfid	$ba,$ba
+	fcfid	$bb,$bb
+	fcfid	$bc,$bc
+	fcfid	$bd,$bd
+	fcfid	$na,$na
+	fcfid	$nb,$nb
+	fcfid	$nc,$nc
+	fcfid	$nd,$nd
+
+	fmul	$T1a,$A1,$ba
+	fmul	$T1b,$A1,$bb
+	fmul	$T2a,$A2,$ba
+	fmul	$T2b,$A2,$bb
+	fmul	$T3a,$A3,$ba
+	fmul	$T3b,$A3,$bb
+	fmul	$T0a,$A0,$ba
+	fmul	$T0b,$A0,$bb
+
+	fmadd	$T1a,$A0,$bc,$T1a
+	fmadd	$T1b,$A0,$bd,$T1b
+	fmadd	$T2a,$A1,$bc,$T2a
+	fmadd	$T2b,$A1,$bd,$T2b
+	fmadd	$T3a,$A2,$bc,$T3a
+	fmadd	$T3b,$A2,$bd,$T3b
+	fmul	$dota,$A3,$bc
+	fmul	$dotb,$A3,$bd
+
+	fmadd	$T1a,$N1,$na,$T1a
+	fmadd	$T1b,$N1,$nb,$T1b
+	 lfd	$A0,8($nap_d)		; load a[j] in double format
+	 lfd	$A1,16($nap_d)
+	fmadd	$T2a,$N2,$na,$T2a
+	fmadd	$T2b,$N2,$nb,$T2b
+	 lfd	$A2,24($nap_d)		; load a[j+1] in double format
+	 lfd	$A3,32($nap_d)
+	fmadd	$T3a,$N3,$na,$T3a
+	fmadd	$T3b,$N3,$nb,$T3b
+	fmadd	$T0a,$N0,$na,$T0a
+	fmadd	$T0b,$N0,$nb,$T0b
+
+	fmadd	$T1a,$N0,$nc,$T1a
+	fmadd	$T1b,$N0,$nd,$T1b
+	fmadd	$T2a,$N1,$nc,$T2a
+	fmadd	$T2b,$N1,$nd,$T2b
+	fmadd	$T3a,$N2,$nc,$T3a
+	fmadd	$T3b,$N2,$nd,$T3b
+	fmadd	$dota,$N3,$nc,$dota
+	fmadd	$dotb,$N3,$nd,$dotb
+
+	fctid	$T0a,$T0a
+	fctid	$T0b,$T0b
+	fctid	$T1a,$T1a
+	fctid	$T1b,$T1b
+	fctid	$T2a,$T2a
+	fctid	$T2b,$T2b
+	fctid	$T3a,$T3a
+	fctid	$T3b,$T3b
+
+	stfd	$T0a,`$FRAME+0`($sp)
+	stfd	$T0b,`$FRAME+8`($sp)
+	stfd	$T1a,`$FRAME+16`($sp)
+	stfd	$T1b,`$FRAME+24`($sp)
+	stfd	$T2a,`$FRAME+32`($sp)
+	stfd	$T2b,`$FRAME+40`($sp)
+	stfd	$T3a,`$FRAME+48`($sp)
+	stfd	$T3b,`$FRAME+56`($sp)
+
+.align	5
+Linner:
+	fmul	$T1a,$A1,$ba
+	fmul	$T1b,$A1,$bb
+	fmul	$T2a,$A2,$ba
+	fmul	$T2b,$A2,$bb
+	lfd	$N0,40($nap_d)		; load n[j] in double format
+	lfd	$N1,48($nap_d)
+	fmul	$T3a,$A3,$ba
+	fmul	$T3b,$A3,$bb
+	fmadd	$T0a,$A0,$ba,$dota
+	fmadd	$T0b,$A0,$bb,$dotb
+	lfd	$N2,56($nap_d)		; load n[j+1] in double format
+	lfdu	$N3,64($nap_d)
+
+	fmadd	$T1a,$A0,$bc,$T1a
+	fmadd	$T1b,$A0,$bd,$T1b
+	fmadd	$T2a,$A1,$bc,$T2a
+	fmadd	$T2b,$A1,$bd,$T2b
+	 lfd	$A0,8($nap_d)		; load a[j] in double format
+	 lfd	$A1,16($nap_d)
+	fmadd	$T3a,$A2,$bc,$T3a
+	fmadd	$T3b,$A2,$bd,$T3b
+	fmul	$dota,$A3,$bc
+	fmul	$dotb,$A3,$bd
+	 lfd	$A2,24($nap_d)		; load a[j+1] in double format
+	 lfd	$A3,32($nap_d)
+
+	fmadd	$T1a,$N1,$na,$T1a
+	fmadd	$T1b,$N1,$nb,$T1b
+	 ld	$t0,`$FRAME+0`($sp)
+	 ld	$t1,`$FRAME+8`($sp)
+	fmadd	$T2a,$N2,$na,$T2a
+	fmadd	$T2b,$N2,$nb,$T2b
+	 ld	$t2,`$FRAME+16`($sp)
+	 ld	$t3,`$FRAME+24`($sp)
+	fmadd	$T3a,$N3,$na,$T3a
+	fmadd	$T3b,$N3,$nb,$T3b
+	 add	$t0,$t0,$carry		; can not overflow
+	 ld	$t4,`$FRAME+32`($sp)
+	 ld	$t5,`$FRAME+40`($sp)
+	fmadd	$T0a,$N0,$na,$T0a
+	fmadd	$T0b,$N0,$nb,$T0b
+	 srdi	$carry,$t0,16
+	 add	$t1,$t1,$carry
+	 srdi	$carry,$t1,16
+	 ld	$t6,`$FRAME+48`($sp)
+	 ld	$t7,`$FRAME+56`($sp)
+
+	fmadd	$T1a,$N0,$nc,$T1a
+	fmadd	$T1b,$N0,$nd,$T1b
+	 insrdi	$t0,$t1,16,32
+	 ld	$t1,8($tp)		; tp[j]
+	fmadd	$T2a,$N1,$nc,$T2a
+	fmadd	$T2b,$N1,$nd,$T2b
+	 add	$t2,$t2,$carry
+	fmadd	$T3a,$N2,$nc,$T3a
+	fmadd	$T3b,$N2,$nd,$T3b
+	 srdi	$carry,$t2,16
+	 insrdi	$t0,$t2,16,16
+	fmadd	$dota,$N3,$nc,$dota
+	fmadd	$dotb,$N3,$nd,$dotb
+	 add	$t3,$t3,$carry
+	 ldu	$t2,16($tp)		; tp[j+1]
+	 srdi	$carry,$t3,16
+	 insrdi	$t0,$t3,16,0		; 0..63 bits
+	 add	$t4,$t4,$carry
+
+	fctid	$T0a,$T0a
+	fctid	$T0b,$T0b
+	 srdi	$carry,$t4,16
+	fctid	$T1a,$T1a
+	fctid	$T1b,$T1b
+	 add	$t5,$t5,$carry
+	fctid	$T2a,$T2a
+	fctid	$T2b,$T2b
+	 srdi	$carry,$t5,16
+	 insrdi	$t4,$t5,16,32
+	fctid	$T3a,$T3a
+	fctid	$T3b,$T3b
+	 add	$t6,$t6,$carry
+	 srdi	$carry,$t6,16
+	 insrdi	$t4,$t6,16,16
+
+	stfd	$T0a,`$FRAME+0`($sp)
+	stfd	$T0b,`$FRAME+8`($sp)
+	 add	$t7,$t7,$carry
+	 addc	$t3,$t0,$t1
+	stfd	$T1a,`$FRAME+16`($sp)
+	stfd	$T1b,`$FRAME+24`($sp)
+	 insrdi	$t4,$t7,16,0		; 64..127 bits
+	 srdi	$carry,$t7,16		; upper 33 bits
+	stfd	$T2a,`$FRAME+32`($sp)
+	stfd	$T2b,`$FRAME+40`($sp)
+	 adde	$t5,$t4,$t2
+	stfd	$T3a,`$FRAME+48`($sp)
+	stfd	$T3b,`$FRAME+56`($sp)
+	 addze	$carry,$carry
+	 std	$t3,-16($tp)		; tp[j-1]
+	 std	$t5,-8($tp)		; tp[j]
+	bdnz-	Linner
+
+	fctid	$dota,$dota
+	fctid	$dotb,$dotb
+	ld	$t0,`$FRAME+0`($sp)
+	ld	$t1,`$FRAME+8`($sp)
+	ld	$t2,`$FRAME+16`($sp)
+	ld	$t3,`$FRAME+24`($sp)
+	ld	$t4,`$FRAME+32`($sp)
+	ld	$t5,`$FRAME+40`($sp)
+	ld	$t6,`$FRAME+48`($sp)
+	ld	$t7,`$FRAME+56`($sp)
+	stfd	$dota,`$FRAME+64`($sp)
+	stfd	$dotb,`$FRAME+72`($sp)
+
+	add	$t0,$t0,$carry		; can not overflow
+	srdi	$carry,$t0,16
+	add	$t1,$t1,$carry
+	srdi	$carry,$t1,16
+	insrdi	$t0,$t1,16,32
+	add	$t2,$t2,$carry
+	ld	$t1,8($tp)		; tp[j]
+	srdi	$carry,$t2,16
+	insrdi	$t0,$t2,16,16
+	add	$t3,$t3,$carry
+	ldu	$t2,16($tp)		; tp[j+1]
+	srdi	$carry,$t3,16
+	insrdi	$t0,$t3,16,0		; 0..63 bits
+	add	$t4,$t4,$carry
+	srdi	$carry,$t4,16
+	add	$t5,$t5,$carry
+	srdi	$carry,$t5,16
+	insrdi	$t4,$t5,16,32
+	add	$t6,$t6,$carry
+	srdi	$carry,$t6,16
+	insrdi	$t4,$t6,16,16
+	add	$t7,$t7,$carry
+	insrdi	$t4,$t7,16,0		; 64..127 bits
+	srdi	$carry,$t7,16		; upper 33 bits
+	ld	$t6,`$FRAME+64`($sp)
+	ld	$t7,`$FRAME+72`($sp)
+
+	addc	$t3,$t0,$t1
+	adde	$t5,$t4,$t2
+	addze	$carry,$carry
+
+	std	$t3,-16($tp)		; tp[j-1]
+	std	$t5,-8($tp)		; tp[j]
+
+	add	$carry,$carry,$ovf	; comsume upmost overflow
+	add	$t6,$t6,$carry		; can not overflow
+	srdi	$carry,$t6,16
+	add	$t7,$t7,$carry
+	insrdi	$t6,$t7,48,0
+	srdi	$ovf,$t7,48
+	std	$t6,0($tp)		; tp[num-1]
+
+	slwi	$t7,$num,2
+	addi	$i,$i,8
+	subf	$nap_d,$t7,$nap_d	; rewind pointer
+	cmpw	$i,$num
+	blt-	Louter
+
+	subf	$np,$num,$np	; rewind np
+	addi	$j,$j,1		; restore counter
+	subfc	$i,$i,$i	; j=0 and "clear" XER[CA]
+	addi	$tp,$sp,`$FRAME+$TRANSFER+8`
+	addi	$t4,$sp,`$FRAME+$TRANSFER+16`
+	addi	$t5,$np,8
+	addi	$t6,$rp,8
+	mtctr	$j
+
+.align	4
+Lsub:	ldx	$t0,$tp,$i
+	ldx	$t1,$np,$i
+	ldx	$t2,$t4,$i
+	ldx	$t3,$t5,$i
+	subfe	$t0,$t1,$t0	; tp[j]-np[j]
+	subfe	$t2,$t3,$t2	; tp[j+1]-np[j+1]
+	stdx	$t0,$rp,$i
+	stdx	$t2,$t6,$i
+	addi	$i,$i,16
+	bdnz-	Lsub
+
+	li	$i,0
+	subfe	$ovf,$i,$ovf	; handle upmost overflow bit
+	and	$ap,$tp,$ovf
+	andc	$np,$rp,$ovf
+	or	$ap,$ap,$np	; ap=borrow?tp:rp
+	addi	$t7,$ap,8
+	mtctr	$j
+
+.align	4
+Lcopy:				; copy or in-place refresh
+	ldx	$t0,$ap,$i
+	ldx	$t1,$t7,$i
+	std	$i,8($nap_d)	; zap nap_d
+	std	$i,16($nap_d)
+	std	$i,24($nap_d)
+	std	$i,32($nap_d)
+	std	$i,40($nap_d)
+	std	$i,48($nap_d)
+	std	$i,56($nap_d)
+	stdu	$i,64($nap_d)
+	stdx	$t0,$rp,$i
+	stdx	$t1,$t6,$i
+	stdx	$i,$tp,$i	; zap tp at once
+	stdx	$i,$t4,$i
+	addi	$i,$i,16
+	bdnz-	Lcopy
+
+	$POP	r14,`2*$SIZE_T`($sp)
+	$POP	r15,`3*$SIZE_T`($sp)
+	$POP	r16,`4*$SIZE_T`($sp)
+	$POP	r17,`5*$SIZE_T`($sp)
+	$POP	r18,`6*$SIZE_T`($sp)
+	$POP	r19,`7*$SIZE_T`($sp)
+	$POP	r20,`8*$SIZE_T`($sp)
+	$POP	r21,`9*$SIZE_T`($sp)
+	$POP	r22,`10*$SIZE_T`($sp)
+	$POP	r23,`11*$SIZE_T`($sp)
+	lfd	f14,`12*$SIZE_T+0`($sp)
+	lfd	f15,`12*$SIZE_T+8`($sp)
+	lfd	f16,`12*$SIZE_T+16`($sp)
+	lfd	f17,`12*$SIZE_T+24`($sp)
+	lfd	f18,`12*$SIZE_T+32`($sp)
+	lfd	f19,`12*$SIZE_T+40`($sp)
+	lfd	f20,`12*$SIZE_T+48`($sp)
+	lfd	f21,`12*$SIZE_T+56`($sp)
+	lfd	f22,`12*$SIZE_T+64`($sp)
+	lfd	f23,`12*$SIZE_T+72`($sp)
+	lfd	f24,`12*$SIZE_T+80`($sp)
+	lfd	f25,`12*$SIZE_T+88`($sp)
+	$POP	$sp,0($sp)
+	li	r3,1	; signal "handled"
+	blr
+	.long	0
+.asciz  "Montgomery Multiplication for PPC64, CRYPTOGAMS by <appro\@fy.chalmers.se>"
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/crypto/bn/asm/s390x-mont.pl b/crypto/bn/asm/s390x-mont.pl
new file mode 100644
index 0000000..d232510
--- /dev/null
+++ b/crypto/bn/asm/s390x-mont.pl
@@ -0,0 +1,225 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# April 2007.
+#
+# Performance improvement over vanilla C code varies from 85% to 45%
+# depending on key length and benchmark. Unfortunately in this context
+# these are not very impressive results [for code that utilizes "wide"
+# 64x64=128-bit multiplication, which is not commonly available to C
+# programmers], at least hand-coded bn_asm.c replacement is known to
+# provide 30-40% better results for longest keys. Well, on a second
+# thought it's not very surprising, because z-CPUs are single-issue
+# and _strictly_ in-order execution, while bn_mul_mont is more or less
+# dependent on CPU ability to pipe-line instructions and have several
+# of them "in-flight" at the same time. I mean while other methods,
+# for example Karatsuba, aim to minimize amount of multiplications at
+# the cost of other operations increase, bn_mul_mont aim to neatly
+# "overlap" multiplications and the other operations [and on most
+# platforms even minimize the amount of the other operations, in
+# particular references to memory]. But it's possible to improve this
+# module performance by implementing dedicated squaring code-path and
+# possibly by unrolling loops...
+
+# January 2009.
+#
+# Reschedule to minimize/avoid Address Generation Interlock hazard,
+# make inner loops counter-based.
+
+$mn0="%r0";
+$num="%r1";
+
+# int bn_mul_mont(
+$rp="%r2";		# BN_ULONG *rp,
+$ap="%r3";		# const BN_ULONG *ap,
+$bp="%r4";		# const BN_ULONG *bp,
+$np="%r5";		# const BN_ULONG *np,
+$n0="%r6";		# const BN_ULONG *n0,
+#$num="160(%r15)"	# int num);
+
+$bi="%r2";	# zaps rp
+$j="%r7";
+
+$ahi="%r8";
+$alo="%r9";
+$nhi="%r10";
+$nlo="%r11";
+$AHI="%r12";
+$NHI="%r13";
+$count="%r14";
+$sp="%r15";
+
+$code.=<<___;
+.text
+.globl	bn_mul_mont
+.type	bn_mul_mont,\@function
+bn_mul_mont:
+	lgf	$num,164($sp)	# pull $num
+	sla	$num,3		# $num to enumerate bytes
+	la	$bp,0($num,$bp)
+
+	stg	%r2,16($sp)
+
+	cghi	$num,16		#
+	lghi	%r2,0		#
+	blr	%r14		# if($num<16) return 0;
+	cghi	$num,128	#
+	bhr	%r14		# if($num>128) return 0;
+
+	stmg	%r3,%r15,24($sp)
+
+	lghi	$rp,-160-8	# leave room for carry bit
+	lcgr	$j,$num		# -$num
+	lgr	%r0,$sp
+	la	$rp,0($rp,$sp)
+	la	$sp,0($j,$rp)	# alloca
+	stg	%r0,0($sp)	# back chain
+
+	sra	$num,3		# restore $num
+	la	$bp,0($j,$bp)	# restore $bp
+	ahi	$num,-1		# adjust $num for inner loop
+	lg	$n0,0($n0)	# pull n0
+
+	lg	$bi,0($bp)
+	lg	$alo,0($ap)
+	mlgr	$ahi,$bi	# ap[0]*bp[0]
+	lgr	$AHI,$ahi
+
+	lgr	$mn0,$alo	# "tp[0]"*n0
+	msgr	$mn0,$n0
+
+	lg	$nlo,0($np)	#
+	mlgr	$nhi,$mn0	# np[0]*m1
+	algr	$nlo,$alo	# +="tp[0]"
+	lghi	$NHI,0
+	alcgr	$NHI,$nhi
+
+	la	$j,8(%r0)	# j=1
+	lr	$count,$num
+
+.align	16
+.L1st:
+	lg	$alo,0($j,$ap)
+	mlgr	$ahi,$bi	# ap[j]*bp[0]
+	algr	$alo,$AHI
+	lghi	$AHI,0
+	alcgr	$AHI,$ahi
+
+	lg	$nlo,0($j,$np)
+	mlgr	$nhi,$mn0	# np[j]*m1
+	algr	$nlo,$NHI
+	lghi	$NHI,0
+	alcgr	$nhi,$NHI	# +="tp[j]"
+	algr	$nlo,$alo
+	alcgr	$NHI,$nhi
+
+	stg	$nlo,160-8($j,$sp)	# tp[j-1]=
+	la	$j,8($j)	# j++
+	brct	$count,.L1st
+
+	algr	$NHI,$AHI
+	lghi	$AHI,0
+	alcgr	$AHI,$AHI	# upmost overflow bit
+	stg	$NHI,160-8($j,$sp)
+	stg	$AHI,160($j,$sp)
+	la	$bp,8($bp)	# bp++
+
+.Louter:
+	lg	$bi,0($bp)	# bp[i]
+	lg	$alo,0($ap)
+	mlgr	$ahi,$bi	# ap[0]*bp[i]
+	alg	$alo,160($sp)	# +=tp[0]
+	lghi	$AHI,0
+	alcgr	$AHI,$ahi
+
+	lgr	$mn0,$alo
+	msgr	$mn0,$n0	# tp[0]*n0
+
+	lg	$nlo,0($np)	# np[0]
+	mlgr	$nhi,$mn0	# np[0]*m1
+	algr	$nlo,$alo	# +="tp[0]"
+	lghi	$NHI,0
+	alcgr	$NHI,$nhi
+
+	la	$j,8(%r0)	# j=1
+	lr	$count,$num
+
+.align	16
+.Linner:
+	lg	$alo,0($j,$ap)
+	mlgr	$ahi,$bi	# ap[j]*bp[i]
+	algr	$alo,$AHI
+	lghi	$AHI,0
+	alcgr	$ahi,$AHI
+	alg	$alo,160($j,$sp)# +=tp[j]
+	alcgr	$AHI,$ahi
+
+	lg	$nlo,0($j,$np)
+	mlgr	$nhi,$mn0	# np[j]*m1
+	algr	$nlo,$NHI
+	lghi	$NHI,0
+	alcgr	$nhi,$NHI
+	algr	$nlo,$alo	# +="tp[j]"
+	alcgr	$NHI,$nhi
+
+	stg	$nlo,160-8($j,$sp)	# tp[j-1]=
+	la	$j,8($j)	# j++
+	brct	$count,.Linner
+
+	algr	$NHI,$AHI
+	lghi	$AHI,0
+	alcgr	$AHI,$AHI
+	alg	$NHI,160($j,$sp)# accumulate previous upmost overflow bit
+	lghi	$ahi,0
+	alcgr	$AHI,$ahi	# new upmost overflow bit
+	stg	$NHI,160-8($j,$sp)
+	stg	$AHI,160($j,$sp)
+
+	la	$bp,8($bp)	# bp++
+	clg	$bp,160+8+32($j,$sp)	# compare to &bp[num]
+	jne	.Louter
+
+	lg	$rp,160+8+16($j,$sp)	# reincarnate rp
+	la	$ap,160($sp)
+	ahi	$num,1		# restore $num, incidentally clears "borrow"
+
+	la	$j,0(%r0)
+	lr	$count,$num
+.Lsub:	lg	$alo,0($j,$ap)
+	slbg	$alo,0($j,$np)
+	stg	$alo,0($j,$rp)
+	la	$j,8($j)
+	brct	$count,.Lsub
+	lghi	$ahi,0
+	slbgr	$AHI,$ahi	# handle upmost carry
+
+	ngr	$ap,$AHI
+	lghi	$np,-1
+	xgr	$np,$AHI
+	ngr	$np,$rp
+	ogr	$ap,$np		# ap=borrow?tp:rp
+
+	la	$j,0(%r0)
+	lgr	$count,$num
+.Lcopy:	lg	$alo,0($j,$ap)	# copy or in-place refresh
+	stg	$j,160($j,$sp)	# zap tp
+	stg	$alo,0($j,$rp)
+	la	$j,8($j)
+	brct	$count,.Lcopy
+
+	la	%r1,160+8+48($j,$sp)
+	lmg	%r6,%r15,0(%r1)
+	lghi	%r2,1		# signal "processed"
+	br	%r14
+.size	bn_mul_mont,.-bn_mul_mont
+.string	"Montgomery Multiplication for s390x, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+print $code;
+close STDOUT;
diff --git a/crypto/bn/asm/s390x.S b/crypto/bn/asm/s390x.S
new file mode 100755
index 0000000..8f45f5d
--- /dev/null
+++ b/crypto/bn/asm/s390x.S
@@ -0,0 +1,678 @@
+.ident "s390x.S, version 1.0"
+// ====================================================================
+// Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+// project.
+//
+// Rights for redistribution and usage in source and binary forms are
+// granted according to the OpenSSL license. Warranty of any kind is
+// disclaimed.
+// ====================================================================
+
+.text
+
+#define zero	%r0
+
+// BN_ULONG bn_mul_add_words(BN_ULONG *r2,BN_ULONG *r3,int r4,BN_ULONG r5);
+.globl	bn_mul_add_words
+.type	bn_mul_add_words,@function
+.align	4
+bn_mul_add_words:
+	lghi	zero,0		// zero = 0
+	la	%r1,0(%r2)	// put rp aside
+	lghi	%r2,0		// i=0;
+	ltgfr	%r4,%r4
+	bler	%r14		// if (len<=0) return 0;
+
+	stmg	%r6,%r10,48(%r15)
+	lghi	%r8,0		// carry = 0
+	srag	%r10,%r4,2	// cnt=len/4
+	jz	.Loop1_madd
+
+.Loop4_madd:
+	lg	%r7,0(%r2,%r3)	// ap[i]
+	mlgr	%r6,%r5		// *=w
+	algr	%r7,%r8		// +=carry
+	alcgr	%r6,zero
+	alg	%r7,0(%r2,%r1)	// +=rp[i]
+	alcgr	%r6,zero
+	stg	%r7,0(%r2,%r1)	// rp[i]=
+
+	lg	%r9,8(%r2,%r3)
+	mlgr	%r8,%r5
+	algr	%r9,%r6
+	alcgr	%r8,zero
+	alg	%r9,8(%r2,%r1)
+	alcgr	%r8,zero
+	stg	%r9,8(%r2,%r1)
+
+	lg	%r7,16(%r2,%r3)
+	mlgr	%r6,%r5
+	algr	%r7,%r8
+	alcgr	%r6,zero
+	alg	%r7,16(%r2,%r1)
+	alcgr	%r6,zero
+	stg	%r7,16(%r2,%r1)
+
+	lg	%r9,24(%r2,%r3)
+	mlgr	%r8,%r5
+	algr	%r9,%r6
+	alcgr	%r8,zero
+	alg	%r9,24(%r2,%r1)
+	alcgr	%r8,zero
+	stg	%r9,24(%r2,%r1)
+
+	la	%r2,32(%r2)	// i+=4
+	brct	%r10,.Loop4_madd
+
+	lghi	%r10,3
+	nr	%r4,%r10	// cnt=len%4
+	jz	.Lend_madd
+
+.Loop1_madd:
+	lg	%r7,0(%r2,%r3)	// ap[i]
+	mlgr	%r6,%r5		// *=w
+	algr	%r7,%r8		// +=carry
+	alcgr	%r6,zero
+	alg	%r7,0(%r2,%r1)	// +=rp[i]
+	alcgr	%r6,zero
+	stg	%r7,0(%r2,%r1)	// rp[i]=
+
+	lgr	%r8,%r6
+	la	%r2,8(%r2)	// i++
+	brct	%r4,.Loop1_madd
+
+.Lend_madd:
+	lgr	%r2,%r8
+	lmg	%r6,%r10,48(%r15)
+	br	%r14
+.size	bn_mul_add_words,.-bn_mul_add_words
+
+// BN_ULONG bn_mul_words(BN_ULONG *r2,BN_ULONG *r3,int r4,BN_ULONG r5);
+.globl	bn_mul_words
+.type	bn_mul_words,@function
+.align	4
+bn_mul_words:
+	lghi	zero,0		// zero = 0
+	la	%r1,0(%r2)	// put rp aside
+	lghi	%r2,0		// i=0;
+	ltgfr	%r4,%r4
+	bler	%r14		// if (len<=0) return 0;
+
+	stmg	%r6,%r10,48(%r15)
+	lghi	%r8,0		// carry = 0
+	srag	%r10,%r4,2	// cnt=len/4
+	jz	.Loop1_mul
+
+.Loop4_mul:
+	lg	%r7,0(%r2,%r3)	// ap[i]
+	mlgr	%r6,%r5		// *=w
+	algr	%r7,%r8		// +=carry
+	alcgr	%r6,zero
+	stg	%r7,0(%r2,%r1)	// rp[i]=
+
+	lg	%r9,8(%r2,%r3)
+	mlgr	%r8,%r5
+	algr	%r9,%r6
+	alcgr	%r8,zero
+	stg	%r9,8(%r2,%r1)
+
+	lg	%r7,16(%r2,%r3)
+	mlgr	%r6,%r5
+	algr	%r7,%r8
+	alcgr	%r6,zero
+	stg	%r7,16(%r2,%r1)
+
+	lg	%r9,24(%r2,%r3)
+	mlgr	%r8,%r5
+	algr	%r9,%r6
+	alcgr	%r8,zero
+	stg	%r9,24(%r2,%r1)
+
+	la	%r2,32(%r2)	// i+=4
+	brct	%r10,.Loop4_mul
+
+	lghi	%r10,3
+	nr	%r4,%r10	// cnt=len%4
+	jz	.Lend_mul
+
+.Loop1_mul:
+	lg	%r7,0(%r2,%r3)	// ap[i]
+	mlgr	%r6,%r5		// *=w
+	algr	%r7,%r8		// +=carry
+	alcgr	%r6,zero
+	stg	%r7,0(%r2,%r1)	// rp[i]=
+
+	lgr	%r8,%r6
+	la	%r2,8(%r2)	// i++
+	brct	%r4,.Loop1_mul
+
+.Lend_mul:
+	lgr	%r2,%r8
+	lmg	%r6,%r10,48(%r15)
+	br	%r14
+.size	bn_mul_words,.-bn_mul_words
+
+// void bn_sqr_words(BN_ULONG *r2,BN_ULONG *r2,int r4)
+.globl	bn_sqr_words
+.type	bn_sqr_words,@function
+.align	4
+bn_sqr_words:
+	ltgfr	%r4,%r4
+	bler	%r14
+
+	stmg	%r6,%r7,48(%r15)
+	srag	%r1,%r4,2	// cnt=len/4
+	jz	.Loop1_sqr
+
+.Loop4_sqr:
+	lg	%r7,0(%r3)
+	mlgr	%r6,%r7
+	stg	%r7,0(%r2)
+	stg	%r6,8(%r2)
+
+	lg	%r7,8(%r3)
+	mlgr	%r6,%r7
+	stg	%r7,16(%r2)
+	stg	%r6,24(%r2)
+
+	lg	%r7,16(%r3)
+	mlgr	%r6,%r7
+	stg	%r7,32(%r2)
+	stg	%r6,40(%r2)
+
+	lg	%r7,24(%r3)
+	mlgr	%r6,%r7
+	stg	%r7,48(%r2)
+	stg	%r6,56(%r2)
+
+	la	%r3,32(%r3)
+	la	%r2,64(%r2)
+	brct	%r1,.Loop4_sqr
+
+	lghi	%r1,3
+	nr	%r4,%r1		// cnt=len%4
+	jz	.Lend_sqr
+
+.Loop1_sqr:
+	lg	%r7,0(%r3)
+	mlgr	%r6,%r7
+	stg	%r7,0(%r2)
+	stg	%r6,8(%r2)
+
+	la	%r3,8(%r3)
+	la	%r2,16(%r2)
+	brct	%r4,.Loop1_sqr
+
+.Lend_sqr:
+	lmg	%r6,%r7,48(%r15)
+	br	%r14
+.size	bn_sqr_words,.-bn_sqr_words
+
+// BN_ULONG bn_div_words(BN_ULONG h,BN_ULONG l,BN_ULONG d);
+.globl	bn_div_words
+.type	bn_div_words,@function
+.align	4
+bn_div_words:
+	dlgr	%r2,%r4
+	lgr	%r2,%r3
+	br	%r14
+.size	bn_div_words,.-bn_div_words
+
+// BN_ULONG bn_add_words(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4,int r5);
+.globl	bn_add_words
+.type	bn_add_words,@function
+.align	4
+bn_add_words:
+	la	%r1,0(%r2)	// put rp aside
+	lghi	%r2,0		// i=0
+	ltgfr	%r5,%r5
+	bler	%r14		// if (len<=0) return 0;
+
+	stg	%r6,48(%r15)
+	lghi	%r6,3
+	nr	%r6,%r5		// len%4
+	sra	%r5,2		// len/4, use sra because it sets condition code
+	jz	.Loop1_add	// carry is incidentally cleared if branch taken
+	algr	%r2,%r2		// clear carry
+
+.Loop4_add:
+	lg	%r0,0(%r2,%r3)
+	alcg	%r0,0(%r2,%r4)
+	stg	%r0,0(%r2,%r1)
+	lg	%r0,8(%r2,%r3)
+	alcg	%r0,8(%r2,%r4)
+	stg	%r0,8(%r2,%r1)
+	lg	%r0,16(%r2,%r3)
+	alcg	%r0,16(%r2,%r4)
+	stg	%r0,16(%r2,%r1)
+	lg	%r0,24(%r2,%r3)
+	alcg	%r0,24(%r2,%r4)
+	stg	%r0,24(%r2,%r1)
+
+	la	%r2,32(%r2)	// i+=4
+	brct	%r5,.Loop4_add
+
+	la	%r6,1(%r6)	// see if len%4 is zero ...
+	brct	%r6,.Loop1_add	// without touching condition code:-)
+
+.Lexit_add:
+	lghi	%r2,0
+	alcgr	%r2,%r2
+	lg	%r6,48(%r15)
+	br	%r14
+
+.Loop1_add:
+	lg	%r0,0(%r2,%r3)
+	alcg	%r0,0(%r2,%r4)
+	stg	%r0,0(%r2,%r1)
+
+	la	%r2,8(%r2)	// i++
+	brct	%r6,.Loop1_add
+
+	j	.Lexit_add
+.size	bn_add_words,.-bn_add_words
+
+// BN_ULONG bn_sub_words(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4,int r5);
+.globl	bn_sub_words
+.type	bn_sub_words,@function
+.align	4
+bn_sub_words:
+	la	%r1,0(%r2)	// put rp aside
+	lghi	%r2,0		// i=0
+	ltgfr	%r5,%r5
+	bler	%r14		// if (len<=0) return 0;
+
+	stg	%r6,48(%r15)
+	lghi	%r6,3
+	nr	%r6,%r5		// len%4
+	sra	%r5,2		// len/4, use sra because it sets condition code
+	jnz	.Loop4_sub	// borrow is incidentally cleared if branch taken
+	slgr	%r2,%r2		// clear borrow
+
+.Loop1_sub:
+	lg	%r0,0(%r2,%r3)
+	slbg	%r0,0(%r2,%r4)
+	stg	%r0,0(%r2,%r1)
+
+	la	%r2,8(%r2)	// i++
+	brct	%r6,.Loop1_sub
+	j	.Lexit_sub
+
+.Loop4_sub:
+	lg	%r0,0(%r2,%r3)
+	slbg	%r0,0(%r2,%r4)
+	stg	%r0,0(%r2,%r1)
+	lg	%r0,8(%r2,%r3)
+	slbg	%r0,8(%r2,%r4)
+	stg	%r0,8(%r2,%r1)
+	lg	%r0,16(%r2,%r3)
+	slbg	%r0,16(%r2,%r4)
+	stg	%r0,16(%r2,%r1)
+	lg	%r0,24(%r2,%r3)
+	slbg	%r0,24(%r2,%r4)
+	stg	%r0,24(%r2,%r1)
+
+	la	%r2,32(%r2)	// i+=4
+	brct	%r5,.Loop4_sub
+
+	la	%r6,1(%r6)	// see if len%4 is zero ...
+	brct	%r6,.Loop1_sub	// without touching condition code:-)
+
+.Lexit_sub:
+	lghi	%r2,0
+	slbgr	%r2,%r2
+	lcgr	%r2,%r2
+	lg	%r6,48(%r15)
+	br	%r14
+.size	bn_sub_words,.-bn_sub_words
+
+#define c1	%r1
+#define c2	%r5
+#define c3	%r8
+
+#define mul_add_c(ai,bi,c1,c2,c3)	\
+	lg	%r7,ai*8(%r3);		\
+	mlg	%r6,bi*8(%r4);		\
+	algr	c1,%r7;			\
+	alcgr	c2,%r6;			\
+	alcgr	c3,zero
+
+// void bn_mul_comba8(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4);
+.globl	bn_mul_comba8
+.type	bn_mul_comba8,@function
+.align	4
+bn_mul_comba8:
+	stmg	%r6,%r8,48(%r15)
+
+	lghi	c1,0
+	lghi	c2,0
+	lghi	c3,0
+	lghi	zero,0
+
+	mul_add_c(0,0,c1,c2,c3);
+	stg	c1,0*8(%r2)
+	lghi	c1,0
+
+	mul_add_c(0,1,c2,c3,c1);
+	mul_add_c(1,0,c2,c3,c1);
+	stg	c2,1*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(2,0,c3,c1,c2);
+	mul_add_c(1,1,c3,c1,c2);
+	mul_add_c(0,2,c3,c1,c2);
+	stg	c3,2*8(%r2)
+	lghi	c3,0
+
+	mul_add_c(0,3,c1,c2,c3);
+	mul_add_c(1,2,c1,c2,c3);
+	mul_add_c(2,1,c1,c2,c3);
+	mul_add_c(3,0,c1,c2,c3);
+	stg	c1,3*8(%r2)
+	lghi	c1,0
+
+	mul_add_c(4,0,c2,c3,c1);
+	mul_add_c(3,1,c2,c3,c1);
+	mul_add_c(2,2,c2,c3,c1);
+	mul_add_c(1,3,c2,c3,c1);
+	mul_add_c(0,4,c2,c3,c1);
+	stg	c2,4*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(0,5,c3,c1,c2);
+	mul_add_c(1,4,c3,c1,c2);
+	mul_add_c(2,3,c3,c1,c2);
+	mul_add_c(3,2,c3,c1,c2);
+	mul_add_c(4,1,c3,c1,c2);
+	mul_add_c(5,0,c3,c1,c2);
+	stg	c3,5*8(%r2)
+	lghi	c3,0
+
+	mul_add_c(6,0,c1,c2,c3);
+	mul_add_c(5,1,c1,c2,c3);
+	mul_add_c(4,2,c1,c2,c3);
+	mul_add_c(3,3,c1,c2,c3);
+	mul_add_c(2,4,c1,c2,c3);
+	mul_add_c(1,5,c1,c2,c3);
+	mul_add_c(0,6,c1,c2,c3);
+	stg	c1,6*8(%r2)
+	lghi	c1,0
+
+	mul_add_c(0,7,c2,c3,c1);
+	mul_add_c(1,6,c2,c3,c1);
+	mul_add_c(2,5,c2,c3,c1);
+	mul_add_c(3,4,c2,c3,c1);
+	mul_add_c(4,3,c2,c3,c1);
+	mul_add_c(5,2,c2,c3,c1);
+	mul_add_c(6,1,c2,c3,c1);
+	mul_add_c(7,0,c2,c3,c1);
+	stg	c2,7*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(7,1,c3,c1,c2);
+	mul_add_c(6,2,c3,c1,c2);
+	mul_add_c(5,3,c3,c1,c2);
+	mul_add_c(4,4,c3,c1,c2);
+	mul_add_c(3,5,c3,c1,c2);
+	mul_add_c(2,6,c3,c1,c2);
+	mul_add_c(1,7,c3,c1,c2);
+	stg	c3,8*8(%r2)
+	lghi	c3,0
+
+	mul_add_c(2,7,c1,c2,c3);
+	mul_add_c(3,6,c1,c2,c3);
+	mul_add_c(4,5,c1,c2,c3);
+	mul_add_c(5,4,c1,c2,c3);
+	mul_add_c(6,3,c1,c2,c3);
+	mul_add_c(7,2,c1,c2,c3);
+	stg	c1,9*8(%r2)
+	lghi	c1,0
+
+	mul_add_c(7,3,c2,c3,c1);
+	mul_add_c(6,4,c2,c3,c1);
+	mul_add_c(5,5,c2,c3,c1);
+	mul_add_c(4,6,c2,c3,c1);
+	mul_add_c(3,7,c2,c3,c1);
+	stg	c2,10*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(4,7,c3,c1,c2);
+	mul_add_c(5,6,c3,c1,c2);
+	mul_add_c(6,5,c3,c1,c2);
+	mul_add_c(7,4,c3,c1,c2);
+	stg	c3,11*8(%r2)
+	lghi	c3,0
+
+	mul_add_c(7,5,c1,c2,c3);
+	mul_add_c(6,6,c1,c2,c3);
+	mul_add_c(5,7,c1,c2,c3);
+	stg	c1,12*8(%r2)
+	lghi	c1,0
+
+
+	mul_add_c(6,7,c2,c3,c1);
+	mul_add_c(7,6,c2,c3,c1);
+	stg	c2,13*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(7,7,c3,c1,c2);
+	stg	c3,14*8(%r2)
+	stg	c1,15*8(%r2)
+
+	lmg	%r6,%r8,48(%r15)
+	br	%r14
+.size	bn_mul_comba8,.-bn_mul_comba8
+
+// void bn_mul_comba4(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4);
+.globl	bn_mul_comba4
+.type	bn_mul_comba4,@function
+.align	4
+bn_mul_comba4:
+	stmg	%r6,%r8,48(%r15)
+
+	lghi	c1,0
+	lghi	c2,0
+	lghi	c3,0
+	lghi	zero,0
+
+	mul_add_c(0,0,c1,c2,c3);
+	stg	c1,0*8(%r3)
+	lghi	c1,0
+
+	mul_add_c(0,1,c2,c3,c1);
+	mul_add_c(1,0,c2,c3,c1);
+	stg	c2,1*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(2,0,c3,c1,c2);
+	mul_add_c(1,1,c3,c1,c2);
+	mul_add_c(0,2,c3,c1,c2);
+	stg	c3,2*8(%r2)
+	lghi	c3,0
+
+	mul_add_c(0,3,c1,c2,c3);
+	mul_add_c(1,2,c1,c2,c3);
+	mul_add_c(2,1,c1,c2,c3);
+	mul_add_c(3,0,c1,c2,c3);
+	stg	c1,3*8(%r2)
+	lghi	c1,0
+
+	mul_add_c(3,1,c2,c3,c1);
+	mul_add_c(2,2,c2,c3,c1);
+	mul_add_c(1,3,c2,c3,c1);
+	stg	c2,4*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(2,3,c3,c1,c2);
+	mul_add_c(3,2,c3,c1,c2);
+	stg	c3,5*8(%r2)
+	lghi	c3,0
+
+	mul_add_c(3,3,c1,c2,c3);
+	stg	c1,6*8(%r2)
+	stg	c2,7*8(%r2)
+
+	stmg	%r6,%r8,48(%r15)
+	br	%r14
+.size	bn_mul_comba4,.-bn_mul_comba4
+
+#define sqr_add_c(ai,c1,c2,c3)		\
+	lg	%r7,ai*8(%r3);		\
+	mlgr	%r6,%r7;		\
+	algr	c1,%r7;			\
+	alcgr	c2,%r6;			\
+	alcgr	c3,zero
+
+#define sqr_add_c2(ai,aj,c1,c2,c3)	\
+	lg	%r7,ai*8(%r3);		\
+	mlg	%r6,aj*8(%r3);		\
+	algr	c1,%r7;			\
+	alcgr	c2,%r6;			\
+	alcgr	c3,zero;		\
+	algr	c1,%r7;			\
+	alcgr	c2,%r6;			\
+	alcgr	c3,zero
+
+// void bn_sqr_comba8(BN_ULONG *r2,BN_ULONG *r3);
+.globl	bn_sqr_comba8
+.type	bn_sqr_comba8,@function
+.align	4
+bn_sqr_comba8:
+	stmg	%r6,%r8,48(%r15)
+
+	lghi	c1,0
+	lghi	c2,0
+	lghi	c3,0
+	lghi	zero,0
+
+	sqr_add_c(0,c1,c2,c3);
+	stg	c1,0*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c2(1,0,c2,c3,c1);
+	stg	c2,1*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c(1,c3,c1,c2);
+	sqr_add_c2(2,0,c3,c1,c2);
+	stg	c3,2*8(%r2)
+	lghi	c3,0
+
+	sqr_add_c2(3,0,c1,c2,c3);
+	sqr_add_c2(2,1,c1,c2,c3);
+	stg	c1,3*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c(2,c2,c3,c1);
+	sqr_add_c2(3,1,c2,c3,c1);
+	sqr_add_c2(4,0,c2,c3,c1);
+	stg	c2,4*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c2(5,0,c3,c1,c2);
+	sqr_add_c2(4,1,c3,c1,c2);
+	sqr_add_c2(3,2,c3,c1,c2);
+	stg	c3,5*8(%r2)
+	lghi	c3,0
+
+	sqr_add_c(3,c1,c2,c3);
+	sqr_add_c2(4,2,c1,c2,c3);
+	sqr_add_c2(5,1,c1,c2,c3);
+	sqr_add_c2(6,0,c1,c2,c3);
+	stg	c1,6*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c2(7,0,c2,c3,c1);
+	sqr_add_c2(6,1,c2,c3,c1);
+	sqr_add_c2(5,2,c2,c3,c1);
+	sqr_add_c2(4,3,c2,c3,c1);
+	stg	c2,7*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c(4,c3,c1,c2);
+	sqr_add_c2(5,3,c3,c1,c2);
+	sqr_add_c2(6,2,c3,c1,c2);
+	sqr_add_c2(7,1,c3,c1,c2);
+	stg	c3,8*8(%r2)
+	lghi	c3,0
+
+	sqr_add_c2(7,2,c1,c2,c3);
+	sqr_add_c2(6,3,c1,c2,c3);
+	sqr_add_c2(5,4,c1,c2,c3);
+	stg	c1,9*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c(5,c2,c3,c1);
+	sqr_add_c2(6,4,c2,c3,c1);
+	sqr_add_c2(7,3,c2,c3,c1);
+	stg	c2,10*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c2(7,4,c3,c1,c2);
+	sqr_add_c2(6,5,c3,c1,c2);
+	stg	c3,11*8(%r2)
+	lghi	c3,0
+
+	sqr_add_c(6,c1,c2,c3);
+	sqr_add_c2(7,5,c1,c2,c3);
+	stg	c1,12*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c2(7,6,c2,c3,c1);
+	stg	c2,13*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c(7,c3,c1,c2);
+	stg	c3,14*8(%r2)
+	stg	c1,15*8(%r2)
+
+	lmg	%r6,%r8,48(%r15)
+	br	%r14
+.size	bn_sqr_comba8,.-bn_sqr_comba8
+
+// void bn_sqr_comba4(BN_ULONG *r2,BN_ULONG *r3);
+.globl bn_sqr_comba4
+.type	bn_sqr_comba4,@function
+.align	4
+bn_sqr_comba4:
+	stmg	%r6,%r8,48(%r15)
+
+	lghi	c1,0
+	lghi	c2,0
+	lghi	c3,0
+	lghi	zero,0
+
+	sqr_add_c(0,c1,c2,c3);
+	stg	c1,0*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c2(1,0,c2,c3,c1);
+	stg	c2,1*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c(1,c3,c1,c2);
+	sqr_add_c2(2,0,c3,c1,c2);
+	stg	c3,2*8(%r2)
+	lghi	c3,0
+
+	sqr_add_c2(3,0,c1,c2,c3);
+	sqr_add_c2(2,1,c1,c2,c3);
+	stg	c1,3*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c(2,c2,c3,c1);
+	sqr_add_c2(3,1,c2,c3,c1);
+	stg	c2,4*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c2(3,2,c3,c1,c2);
+	stg	c3,5*8(%r2)
+	lghi	c3,0
+
+	sqr_add_c(3,c1,c2,c3);
+	stg	c1,6*8(%r2)
+	stg	c2,7*8(%r2)
+
+	lmg	%r6,%r8,48(%r15)
+	br	%r14
+.size	bn_sqr_comba4,.-bn_sqr_comba4
diff --git a/crypto/bn/asm/sparcv8plus.S b/crypto/bn/asm/sparcv8plus.S
index 8c56e2e..63de186 100644
--- a/crypto/bn/asm/sparcv8plus.S
+++ b/crypto/bn/asm/sparcv8plus.S
@@ -144,6 +144,19 @@
  *	    }
  */
 
+#if defined(__SUNPRO_C) && defined(__sparcv9)
+  /* They've said -xarch=v9 at command line */
+  .register	%g2,#scratch
+  .register	%g3,#scratch
+# define	FRAME_SIZE	-192
+#elif defined(__GNUC__) && defined(__arch64__)
+  /* They've said -m64 at command line */
+  .register	%g2,#scratch
+  .register	%g3,#scratch
+# define	FRAME_SIZE	-192
+#else 
+# define	FRAME_SIZE	-96
+#endif 
 /*
  * GNU assembler can't stand stuw:-(
  */
@@ -619,8 +632,6 @@
  *							Andy.
  */
 
-#define FRAME_SIZE	-96
-
 /*
  * Here is register usage map for *all* routines below.
  */
diff --git a/crypto/bn/asm/sparcv9-mont.pl b/crypto/bn/asm/sparcv9-mont.pl
new file mode 100644
index 0000000..b8fb1e8
--- /dev/null
+++ b/crypto/bn/asm/sparcv9-mont.pl
@@ -0,0 +1,606 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# December 2005
+#
+# Pure SPARCv9/8+ and IALU-only bn_mul_mont implementation. The reasons
+# for undertaken effort are multiple. First of all, UltraSPARC is not
+# the whole SPARCv9 universe and other VIS-free implementations deserve
+# optimized code as much. Secondly, newly introduced UltraSPARC T1,
+# a.k.a. Niagara, has shared FPU and concurrent FPU-intensive pathes,
+# such as sparcv9a-mont, will simply sink it. Yes, T1 is equipped with
+# several integrated RSA/DSA accelerator circuits accessible through
+# kernel driver [only(*)], but having decent user-land software
+# implementation is important too. Finally, reasons like desire to
+# experiment with dedicated squaring procedure. Yes, this module
+# implements one, because it was easiest to draft it in SPARCv9
+# instructions...
+
+# (*)	Engine accessing the driver in question is on my TODO list.
+#	For reference, acceleator is estimated to give 6 to 10 times
+#	improvement on single-threaded RSA sign. It should be noted
+#	that 6-10x improvement coefficient does not actually mean
+#	something extraordinary in terms of absolute [single-threaded]
+#	performance, as SPARCv9 instruction set is by all means least
+#	suitable for high performance crypto among other 64 bit
+#	platforms. 6-10x factor simply places T1 in same performance
+#	domain as say AMD64 and IA-64. Improvement of RSA verify don't
+#	appear impressive at all, but it's the sign operation which is
+#	far more critical/interesting.
+
+# You might notice that inner loops are modulo-scheduled:-) This has
+# essentially negligible impact on UltraSPARC performance, it's
+# Fujitsu SPARC64 V users who should notice and hopefully appreciate
+# the advantage... Currently this module surpasses sparcv9a-mont.pl
+# by ~20% on UltraSPARC-III and later cores, but recall that sparcv9a
+# module still have hidden potential [see TODO list there], which is
+# estimated to be larger than 20%...
+
+# int bn_mul_mont(
+$rp="%i0";	# BN_ULONG *rp,
+$ap="%i1";	# const BN_ULONG *ap,
+$bp="%i2";	# const BN_ULONG *bp,
+$np="%i3";	# const BN_ULONG *np,
+$n0="%i4";	# const BN_ULONG *n0,
+$num="%i5";	# int num);
+
+$bits=32;
+for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
+if ($bits==64)	{ $bias=2047; $frame=192; }
+else		{ $bias=0;    $frame=128; }
+
+$car0="%o0";
+$car1="%o1";
+$car2="%o2";	# 1 bit
+$acc0="%o3";
+$acc1="%o4";
+$mask="%g1";	# 32 bits, what a waste...
+$tmp0="%g4";
+$tmp1="%g5";
+
+$i="%l0";
+$j="%l1";
+$mul0="%l2";
+$mul1="%l3";
+$tp="%l4";
+$apj="%l5";
+$npj="%l6";
+$tpj="%l7";
+
+$fname="bn_mul_mont_int";
+
+$code=<<___;
+.section	".text",#alloc,#execinstr
+
+.global	$fname
+.align	32
+$fname:
+	cmp	%o5,4			! 128 bits minimum
+	bge,pt	%icc,.Lenter
+	sethi	%hi(0xffffffff),$mask
+	retl
+	clr	%o0
+.align	32
+.Lenter:
+	save	%sp,-$frame,%sp
+	sll	$num,2,$num		! num*=4
+	or	$mask,%lo(0xffffffff),$mask
+	ld	[$n0],$n0
+	cmp	$ap,$bp
+	and	$num,$mask,$num
+	ld	[$bp],$mul0		! bp[0]
+	nop
+
+	add	%sp,$bias,%o7		! real top of stack
+	ld	[$ap],$car0		! ap[0] ! redundant in squaring context
+	sub	%o7,$num,%o7
+	ld	[$ap+4],$apj		! ap[1]
+	and	%o7,-1024,%o7
+	ld	[$np],$car1		! np[0]
+	sub	%o7,$bias,%sp		! alloca
+	ld	[$np+4],$npj		! np[1]
+	be,pt	`$bits==32?"%icc":"%xcc"`,.Lbn_sqr_mont
+	mov	12,$j
+
+	mulx	$car0,$mul0,$car0	! ap[0]*bp[0]
+	mulx	$apj,$mul0,$tmp0	!prologue! ap[1]*bp[0]
+	and	$car0,$mask,$acc0
+	add	%sp,$bias+$frame,$tp
+	ld	[$ap+8],$apj		!prologue!
+
+	mulx	$n0,$acc0,$mul1		! "t[0]"*n0
+	and	$mul1,$mask,$mul1
+
+	mulx	$car1,$mul1,$car1	! np[0]*"t[0]"*n0
+	mulx	$npj,$mul1,$acc1	!prologue! np[1]*"t[0]"*n0
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	ld	[$np+8],$npj		!prologue!
+	srlx	$car1,32,$car1
+	mov	$tmp0,$acc0		!prologue!
+
+.L1st:
+	mulx	$apj,$mul0,$tmp0
+	mulx	$npj,$mul1,$tmp1
+	add	$acc0,$car0,$car0
+	ld	[$ap+$j],$apj		! ap[j]
+	and	$car0,$mask,$acc0
+	add	$acc1,$car1,$car1
+	ld	[$np+$j],$npj		! np[j]
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	add	$j,4,$j			! j++
+	mov	$tmp0,$acc0
+	st	$car1,[$tp]
+	cmp	$j,$num
+	mov	$tmp1,$acc1
+	srlx	$car1,32,$car1
+	bl	%icc,.L1st
+	add	$tp,4,$tp		! tp++
+!.L1st
+
+	mulx	$apj,$mul0,$tmp0	!epilogue!
+	mulx	$npj,$mul1,$tmp1
+	add	$acc0,$car0,$car0
+	and	$car0,$mask,$acc0
+	add	$acc1,$car1,$car1
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp]
+	srlx	$car1,32,$car1
+
+	add	$tmp0,$car0,$car0
+	and	$car0,$mask,$acc0
+	add	$tmp1,$car1,$car1
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp+4]
+	srlx	$car1,32,$car1
+
+	add	$car0,$car1,$car1
+	st	$car1,[$tp+8]
+	srlx	$car1,32,$car2
+
+	mov	4,$i			! i++
+	ld	[$bp+4],$mul0		! bp[1]
+.Louter:
+	add	%sp,$bias+$frame,$tp
+	ld	[$ap],$car0		! ap[0]
+	ld	[$ap+4],$apj		! ap[1]
+	ld	[$np],$car1		! np[0]
+	ld	[$np+4],$npj		! np[1]
+	ld	[$tp],$tmp1		! tp[0]
+	ld	[$tp+4],$tpj		! tp[1]
+	mov	12,$j
+
+	mulx	$car0,$mul0,$car0
+	mulx	$apj,$mul0,$tmp0	!prologue!
+	add	$tmp1,$car0,$car0
+	ld	[$ap+8],$apj		!prologue!
+	and	$car0,$mask,$acc0
+
+	mulx	$n0,$acc0,$mul1
+	and	$mul1,$mask,$mul1
+
+	mulx	$car1,$mul1,$car1
+	mulx	$npj,$mul1,$acc1	!prologue!
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	ld	[$np+8],$npj		!prologue!
+	srlx	$car1,32,$car1
+	mov	$tmp0,$acc0		!prologue!
+
+.Linner:
+	mulx	$apj,$mul0,$tmp0
+	mulx	$npj,$mul1,$tmp1
+	add	$tpj,$car0,$car0
+	ld	[$ap+$j],$apj		! ap[j]
+	add	$acc0,$car0,$car0
+	add	$acc1,$car1,$car1
+	ld	[$np+$j],$npj		! np[j]
+	and	$car0,$mask,$acc0
+	ld	[$tp+8],$tpj		! tp[j]
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	add	$j,4,$j			! j++
+	mov	$tmp0,$acc0
+	st	$car1,[$tp]		! tp[j-1]
+	srlx	$car1,32,$car1
+	mov	$tmp1,$acc1
+	cmp	$j,$num
+	bl	%icc,.Linner
+	add	$tp,4,$tp		! tp++
+!.Linner
+
+	mulx	$apj,$mul0,$tmp0	!epilogue!
+	mulx	$npj,$mul1,$tmp1
+	add	$tpj,$car0,$car0
+	add	$acc0,$car0,$car0
+	ld	[$tp+8],$tpj		! tp[j]
+	and	$car0,$mask,$acc0
+	add	$acc1,$car1,$car1
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp]		! tp[j-1]
+	srlx	$car1,32,$car1
+
+	add	$tpj,$car0,$car0
+	add	$tmp0,$car0,$car0
+	and	$car0,$mask,$acc0
+	add	$tmp1,$car1,$car1
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp+4]		! tp[j-1]
+	srlx	$car0,32,$car0
+	add	$i,4,$i			! i++
+	srlx	$car1,32,$car1
+
+	add	$car0,$car1,$car1
+	cmp	$i,$num
+	add	$car2,$car1,$car1
+	st	$car1,[$tp+8]
+
+	srlx	$car1,32,$car2
+	bl,a	%icc,.Louter
+	ld	[$bp+$i],$mul0		! bp[i]
+!.Louter
+
+	add	$tp,12,$tp
+
+.Ltail:
+	add	$np,$num,$np
+	add	$rp,$num,$rp
+	mov	$tp,$ap
+	sub	%g0,$num,%o7		! k=-num
+	ba	.Lsub
+	subcc	%g0,%g0,%g0		! clear %icc.c
+.align	16
+.Lsub:
+	ld	[$tp+%o7],%o0
+	ld	[$np+%o7],%o1
+	subccc	%o0,%o1,%o1		! tp[j]-np[j]
+	add	$rp,%o7,$i
+	add	%o7,4,%o7
+	brnz	%o7,.Lsub
+	st	%o1,[$i]
+	subc	$car2,0,$car2		! handle upmost overflow bit
+	and	$tp,$car2,$ap
+	andn	$rp,$car2,$np
+	or	$ap,$np,$ap
+	sub	%g0,$num,%o7
+
+.Lcopy:
+	ld	[$ap+%o7],%o0		! copy or in-place refresh
+	st	%g0,[$tp+%o7]		! zap tp
+	st	%o0,[$rp+%o7]
+	add	%o7,4,%o7
+	brnz	%o7,.Lcopy
+	nop
+	mov	1,%i0
+	ret
+	restore
+___
+
+########
+######## .Lbn_sqr_mont gives up to 20% *overall* improvement over
+######## code without following dedicated squaring procedure.
+########
+$sbit="%i2";		# re-use $bp!
+
+$code.=<<___;
+.align	32
+.Lbn_sqr_mont:
+	mulx	$mul0,$mul0,$car0		! ap[0]*ap[0]
+	mulx	$apj,$mul0,$tmp0		!prologue!
+	and	$car0,$mask,$acc0
+	add	%sp,$bias+$frame,$tp
+	ld	[$ap+8],$apj			!prologue!
+
+	mulx	$n0,$acc0,$mul1			! "t[0]"*n0
+	srlx	$car0,32,$car0
+	and	$mul1,$mask,$mul1
+
+	mulx	$car1,$mul1,$car1		! np[0]*"t[0]"*n0
+	mulx	$npj,$mul1,$acc1		!prologue!
+	and	$car0,1,$sbit
+	ld	[$np+8],$npj			!prologue!
+	srlx	$car0,1,$car0
+	add	$acc0,$car1,$car1
+	srlx	$car1,32,$car1
+	mov	$tmp0,$acc0			!prologue!
+
+.Lsqr_1st:
+	mulx	$apj,$mul0,$tmp0
+	mulx	$npj,$mul1,$tmp1
+	add	$acc0,$car0,$car0		! ap[j]*a0+c0
+	add	$acc1,$car1,$car1
+	ld	[$ap+$j],$apj			! ap[j]
+	and	$car0,$mask,$acc0
+	ld	[$np+$j],$npj			! np[j]
+	srlx	$car0,32,$car0
+	add	$acc0,$acc0,$acc0
+	or	$sbit,$acc0,$acc0
+	mov	$tmp1,$acc1
+	srlx	$acc0,32,$sbit
+	add	$j,4,$j				! j++
+	and	$acc0,$mask,$acc0
+	cmp	$j,$num
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp]
+	mov	$tmp0,$acc0
+	srlx	$car1,32,$car1
+	bl	%icc,.Lsqr_1st
+	add	$tp,4,$tp			! tp++
+!.Lsqr_1st
+
+	mulx	$apj,$mul0,$tmp0		! epilogue
+	mulx	$npj,$mul1,$tmp1
+	add	$acc0,$car0,$car0		! ap[j]*a0+c0
+	add	$acc1,$car1,$car1
+	and	$car0,$mask,$acc0
+	srlx	$car0,32,$car0
+	add	$acc0,$acc0,$acc0
+	or	$sbit,$acc0,$acc0
+	srlx	$acc0,32,$sbit
+	and	$acc0,$mask,$acc0
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp]
+	srlx	$car1,32,$car1
+
+	add	$tmp0,$car0,$car0		! ap[j]*a0+c0
+	add	$tmp1,$car1,$car1
+	and	$car0,$mask,$acc0
+	srlx	$car0,32,$car0
+	add	$acc0,$acc0,$acc0
+	or	$sbit,$acc0,$acc0
+	srlx	$acc0,32,$sbit
+	and	$acc0,$mask,$acc0
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp+4]
+	srlx	$car1,32,$car1
+
+	add	$car0,$car0,$car0
+	or	$sbit,$car0,$car0
+	add	$car0,$car1,$car1
+	st	$car1,[$tp+8]
+	srlx	$car1,32,$car2
+
+	ld	[%sp+$bias+$frame],$tmp0	! tp[0]
+	ld	[%sp+$bias+$frame+4],$tmp1	! tp[1]
+	ld	[%sp+$bias+$frame+8],$tpj	! tp[2]
+	ld	[$ap+4],$mul0			! ap[1]
+	ld	[$ap+8],$apj			! ap[2]
+	ld	[$np],$car1			! np[0]
+	ld	[$np+4],$npj			! np[1]
+	mulx	$n0,$tmp0,$mul1
+
+	mulx	$mul0,$mul0,$car0
+	and	$mul1,$mask,$mul1
+
+	mulx	$car1,$mul1,$car1
+	mulx	$npj,$mul1,$acc1
+	add	$tmp0,$car1,$car1
+	and	$car0,$mask,$acc0
+	ld	[$np+8],$npj			! np[2]
+	srlx	$car1,32,$car1
+	add	$tmp1,$car1,$car1
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	and	$car0,1,$sbit
+	add	$acc1,$car1,$car1
+	srlx	$car0,1,$car0
+	mov	12,$j
+	st	$car1,[%sp+$bias+$frame]	! tp[0]=
+	srlx	$car1,32,$car1
+	add	%sp,$bias+$frame+4,$tp
+
+.Lsqr_2nd:
+	mulx	$apj,$mul0,$acc0
+	mulx	$npj,$mul1,$acc1
+	add	$acc0,$car0,$car0
+	add	$tpj,$car1,$car1
+	ld	[$ap+$j],$apj			! ap[j]
+	and	$car0,$mask,$acc0
+	ld	[$np+$j],$npj			! np[j]
+	srlx	$car0,32,$car0
+	add	$acc1,$car1,$car1
+	ld	[$tp+8],$tpj			! tp[j]
+	add	$acc0,$acc0,$acc0
+	add	$j,4,$j				! j++
+	or	$sbit,$acc0,$acc0
+	srlx	$acc0,32,$sbit
+	and	$acc0,$mask,$acc0
+	cmp	$j,$num
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp]			! tp[j-1]
+	srlx	$car1,32,$car1
+	bl	%icc,.Lsqr_2nd
+	add	$tp,4,$tp			! tp++
+!.Lsqr_2nd
+
+	mulx	$apj,$mul0,$acc0
+	mulx	$npj,$mul1,$acc1
+	add	$acc0,$car0,$car0
+	add	$tpj,$car1,$car1
+	and	$car0,$mask,$acc0
+	srlx	$car0,32,$car0
+	add	$acc1,$car1,$car1
+	add	$acc0,$acc0,$acc0
+	or	$sbit,$acc0,$acc0
+	srlx	$acc0,32,$sbit
+	and	$acc0,$mask,$acc0
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp]			! tp[j-1]
+	srlx	$car1,32,$car1
+
+	add	$car0,$car0,$car0
+	or	$sbit,$car0,$car0
+	add	$car0,$car1,$car1
+	add	$car2,$car1,$car1
+	st	$car1,[$tp+4]
+	srlx	$car1,32,$car2
+
+	ld	[%sp+$bias+$frame],$tmp1	! tp[0]
+	ld	[%sp+$bias+$frame+4],$tpj	! tp[1]
+	ld	[$ap+8],$mul0			! ap[2]
+	ld	[$np],$car1			! np[0]
+	ld	[$np+4],$npj			! np[1]
+	mulx	$n0,$tmp1,$mul1
+	and	$mul1,$mask,$mul1
+	mov	8,$i
+
+	mulx	$mul0,$mul0,$car0
+	mulx	$car1,$mul1,$car1
+	and	$car0,$mask,$acc0
+	add	$tmp1,$car1,$car1
+	srlx	$car0,32,$car0
+	add	%sp,$bias+$frame,$tp
+	srlx	$car1,32,$car1
+	and	$car0,1,$sbit
+	srlx	$car0,1,$car0
+	mov	4,$j
+
+.Lsqr_outer:
+.Lsqr_inner1:
+	mulx	$npj,$mul1,$acc1
+	add	$tpj,$car1,$car1
+	add	$j,4,$j
+	ld	[$tp+8],$tpj
+	cmp	$j,$i
+	add	$acc1,$car1,$car1
+	ld	[$np+$j],$npj
+	st	$car1,[$tp]
+	srlx	$car1,32,$car1
+	bl	%icc,.Lsqr_inner1
+	add	$tp,4,$tp
+!.Lsqr_inner1
+
+	add	$j,4,$j
+	ld	[$ap+$j],$apj			! ap[j]
+	mulx	$npj,$mul1,$acc1
+	add	$tpj,$car1,$car1
+	ld	[$np+$j],$npj			! np[j]
+	add	$acc0,$car1,$car1
+	ld	[$tp+8],$tpj			! tp[j]
+	add	$acc1,$car1,$car1
+	st	$car1,[$tp]
+	srlx	$car1,32,$car1
+
+	add	$j,4,$j
+	cmp	$j,$num
+	be,pn	%icc,.Lsqr_no_inner2
+	add	$tp,4,$tp
+
+.Lsqr_inner2:
+	mulx	$apj,$mul0,$acc0
+	mulx	$npj,$mul1,$acc1
+	add	$tpj,$car1,$car1
+	add	$acc0,$car0,$car0
+	ld	[$ap+$j],$apj			! ap[j]
+	and	$car0,$mask,$acc0
+	ld	[$np+$j],$npj			! np[j]
+	srlx	$car0,32,$car0
+	add	$acc0,$acc0,$acc0
+	ld	[$tp+8],$tpj			! tp[j]
+	or	$sbit,$acc0,$acc0
+	add	$j,4,$j				! j++
+	srlx	$acc0,32,$sbit
+	and	$acc0,$mask,$acc0
+	cmp	$j,$num
+	add	$acc0,$car1,$car1
+	add	$acc1,$car1,$car1
+	st	$car1,[$tp]			! tp[j-1]
+	srlx	$car1,32,$car1
+	bl	%icc,.Lsqr_inner2
+	add	$tp,4,$tp			! tp++
+
+.Lsqr_no_inner2:
+	mulx	$apj,$mul0,$acc0
+	mulx	$npj,$mul1,$acc1
+	add	$tpj,$car1,$car1
+	add	$acc0,$car0,$car0
+	and	$car0,$mask,$acc0
+	srlx	$car0,32,$car0
+	add	$acc0,$acc0,$acc0
+	or	$sbit,$acc0,$acc0
+	srlx	$acc0,32,$sbit
+	and	$acc0,$mask,$acc0
+	add	$acc0,$car1,$car1
+	add	$acc1,$car1,$car1
+	st	$car1,[$tp]			! tp[j-1]
+	srlx	$car1,32,$car1
+
+	add	$car0,$car0,$car0
+	or	$sbit,$car0,$car0
+	add	$car0,$car1,$car1
+	add	$car2,$car1,$car1
+	st	$car1,[$tp+4]
+	srlx	$car1,32,$car2
+
+	add	$i,4,$i				! i++
+	ld	[%sp+$bias+$frame],$tmp1	! tp[0]
+	ld	[%sp+$bias+$frame+4],$tpj	! tp[1]
+	ld	[$ap+$i],$mul0			! ap[j]
+	ld	[$np],$car1			! np[0]
+	ld	[$np+4],$npj			! np[1]
+	mulx	$n0,$tmp1,$mul1
+	and	$mul1,$mask,$mul1
+	add	$i,4,$tmp0
+
+	mulx	$mul0,$mul0,$car0
+	mulx	$car1,$mul1,$car1
+	and	$car0,$mask,$acc0
+	add	$tmp1,$car1,$car1
+	srlx	$car0,32,$car0
+	add	%sp,$bias+$frame,$tp
+	srlx	$car1,32,$car1
+	and	$car0,1,$sbit
+	srlx	$car0,1,$car0
+
+	cmp	$tmp0,$num			! i<num-1
+	bl	%icc,.Lsqr_outer
+	mov	4,$j
+
+.Lsqr_last:
+	mulx	$npj,$mul1,$acc1
+	add	$tpj,$car1,$car1
+	add	$j,4,$j
+	ld	[$tp+8],$tpj
+	cmp	$j,$i
+	add	$acc1,$car1,$car1
+	ld	[$np+$j],$npj
+	st	$car1,[$tp]
+	srlx	$car1,32,$car1
+	bl	%icc,.Lsqr_last
+	add	$tp,4,$tp
+!.Lsqr_last
+
+	mulx	$npj,$mul1,$acc1
+	add	$tpj,$car1,$car1
+	add	$acc0,$car1,$car1
+	add	$acc1,$car1,$car1
+	st	$car1,[$tp]
+	srlx	$car1,32,$car1
+
+	add	$car0,$car0,$car0		! recover $car0
+	or	$sbit,$car0,$car0
+	add	$car0,$car1,$car1
+	add	$car2,$car1,$car1
+	st	$car1,[$tp+4]
+	srlx	$car1,32,$car2
+
+	ba	.Ltail
+	add	$tp,8,$tp
+.type	$fname,#function
+.size	$fname,(.-$fname)
+.asciz	"Montgomery Multipltication for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
+.align	32
+___
+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
+print $code;
+close STDOUT;
diff --git a/crypto/bn/asm/sparcv9a-mont.pl b/crypto/bn/asm/sparcv9a-mont.pl
new file mode 100755
index 0000000..a14205f
--- /dev/null
+++ b/crypto/bn/asm/sparcv9a-mont.pl
@@ -0,0 +1,882 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# October 2005
+#
+# "Teaser" Montgomery multiplication module for UltraSPARC. Why FPU?
+# Because unlike integer multiplier, which simply stalls whole CPU,
+# FPU is fully pipelined and can effectively emit 48 bit partial
+# product every cycle. Why not blended SPARC v9? One can argue that
+# making this module dependent on UltraSPARC VIS extension limits its
+# binary compatibility. Well yes, it does exclude SPARC64 prior-V(!)
+# implementations from compatibility matrix. But the rest, whole Sun
+# UltraSPARC family and brand new Fujitsu's SPARC64 V, all support
+# VIS extension instructions used in this module. This is considered
+# good enough to not care about HAL SPARC64 users [if any] who have
+# integer-only pure SPARCv9 module to "fall down" to.
+
+# USI&II cores currently exhibit uniform 2x improvement [over pre-
+# bn_mul_mont codebase] for all key lengths and benchmarks. On USIII
+# performance improves few percents for shorter keys and worsens few
+# percents for longer keys. This is because USIII integer multiplier
+# is >3x faster than USI&II one, which is harder to match [but see
+# TODO list below]. It should also be noted that SPARC64 V features
+# out-of-order execution, which *might* mean that integer multiplier
+# is pipelined, which in turn *might* be impossible to match... On
+# additional note, SPARC64 V implements FP Multiply-Add instruction,
+# which is perfectly usable in this context... In other words, as far
+# as Fujitsu SPARC64 V goes, talk to the author:-)
+
+# The implementation implies following "non-natural" limitations on
+# input arguments:
+# - num may not be less than 4;
+# - num has to be even;
+# Failure to meet either condition has no fatal effects, simply
+# doesn't give any performance gain.
+
+# TODO:
+# - modulo-schedule inner loop for better performance (on in-order
+#   execution core such as UltraSPARC this shall result in further
+#   noticeable(!) improvement);
+# - dedicated squaring procedure[?];
+
+######################################################################
+# November 2006
+#
+# Modulo-scheduled inner loops allow to interleave floating point and
+# integer instructions and minimize Read-After-Write penalties. This
+# results in *further* 20-50% perfromance improvement [depending on
+# key length, more for longer keys] on USI&II cores and 30-80% - on
+# USIII&IV.
+
+$fname="bn_mul_mont_fpu";
+$bits=32;
+for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
+
+if ($bits==64) {
+	$bias=2047;
+	$frame=192;
+} else {
+	$bias=0;
+	$frame=128;	# 96 rounded up to largest known cache-line
+}
+$locals=64;
+
+# In order to provide for 32-/64-bit ABI duality, I keep integers wider
+# than 32 bit in %g1-%g4 and %o0-%o5. %l0-%l7 and %i0-%i5 are used
+# exclusively for pointers, indexes and other small values...
+# int bn_mul_mont(
+$rp="%i0";	# BN_ULONG *rp,
+$ap="%i1";	# const BN_ULONG *ap,
+$bp="%i2";	# const BN_ULONG *bp,
+$np="%i3";	# const BN_ULONG *np,
+$n0="%i4";	# const BN_ULONG *n0,
+$num="%i5";	# int num);
+
+$tp="%l0";	# t[num]
+$ap_l="%l1";	# a[num],n[num] are smashed to 32-bit words and saved
+$ap_h="%l2";	# to these four vectors as double-precision FP values.
+$np_l="%l3";	# This way a bunch of fxtods are eliminated in second
+$np_h="%l4";	# loop and L1-cache aliasing is minimized...
+$i="%l5";
+$j="%l6";
+$mask="%l7";	# 16-bit mask, 0xffff
+
+$n0="%g4";	# reassigned(!) to "64-bit" register
+$carry="%i4";	# %i4 reused(!) for a carry bit
+
+# FP register naming chart
+#
+#     ..HILO
+#       dcba
+#   --------
+#        LOa
+#       LOb
+#      LOc
+#     LOd
+#      HIa
+#     HIb
+#    HIc
+#   HId
+#    ..a
+#   ..b
+$ba="%f0";    $bb="%f2";    $bc="%f4";    $bd="%f6";
+$na="%f8";    $nb="%f10";   $nc="%f12";   $nd="%f14";
+$alo="%f16";  $alo_="%f17"; $ahi="%f18";  $ahi_="%f19";
+$nlo="%f20";  $nlo_="%f21"; $nhi="%f22";  $nhi_="%f23";
+
+$dota="%f24"; $dotb="%f26";
+
+$aloa="%f32"; $alob="%f34"; $aloc="%f36"; $alod="%f38";
+$ahia="%f40"; $ahib="%f42"; $ahic="%f44"; $ahid="%f46";
+$nloa="%f48"; $nlob="%f50"; $nloc="%f52"; $nlod="%f54";
+$nhia="%f56"; $nhib="%f58"; $nhic="%f60"; $nhid="%f62";
+
+$ASI_FL16_P=0xD2;	# magic ASI value to engage 16-bit FP load
+
+$code=<<___;
+.section	".text",#alloc,#execinstr
+
+.global $fname
+.align  32
+$fname:
+	save	%sp,-$frame-$locals,%sp
+
+	cmp	$num,4
+	bl,a,pn %icc,.Lret
+	clr	%i0
+	andcc	$num,1,%g0		! $num has to be even...
+	bnz,a,pn %icc,.Lret
+	clr	%i0			! signal "unsupported input value"
+
+	srl	$num,1,$num
+	sethi	%hi(0xffff),$mask
+	ld	[%i4+0],$n0		! $n0 reassigned, remember?
+	or	$mask,%lo(0xffff),$mask
+	ld	[%i4+4],%o0
+	sllx	%o0,32,%o0
+	or	%o0,$n0,$n0		! $n0=n0[1].n0[0]
+
+	sll	$num,3,$num		! num*=8
+
+	add	%sp,$bias,%o0		! real top of stack
+	sll	$num,2,%o1
+	add	%o1,$num,%o1		! %o1=num*5
+	sub	%o0,%o1,%o0
+	and	%o0,-2048,%o0		! optimize TLB utilization
+	sub	%o0,$bias,%sp		! alloca(5*num*8)
+
+	rd	%asi,%o7		! save %asi
+	add	%sp,$bias+$frame+$locals,$tp
+	add	$tp,$num,$ap_l
+	add	$ap_l,$num,$ap_l	! [an]p_[lh] point at the vectors' ends !
+	add	$ap_l,$num,$ap_h
+	add	$ap_h,$num,$np_l
+	add	$np_l,$num,$np_h
+
+	wr	%g0,$ASI_FL16_P,%asi	! setup %asi for 16-bit FP loads
+
+	add	$rp,$num,$rp		! readjust input pointers to point
+	add	$ap,$num,$ap		! at the ends too...
+	add	$bp,$num,$bp
+	add	$np,$num,$np
+
+	stx	%o7,[%sp+$bias+$frame+48]	! save %asi
+
+	sub	%g0,$num,$i		! i=-num
+	sub	%g0,$num,$j		! j=-num
+
+	add	$ap,$j,%o3
+	add	$bp,$i,%o4
+
+	ld	[%o3+4],%g1		! bp[0]
+	ld	[%o3+0],%o0
+	ld	[%o4+4],%g5		! ap[0]
+	sllx	%g1,32,%g1
+	ld	[%o4+0],%o1
+	sllx	%g5,32,%g5
+	or	%g1,%o0,%o0
+	or	%g5,%o1,%o1
+
+	add	$np,$j,%o5
+
+	mulx	%o1,%o0,%o0		! ap[0]*bp[0]
+	mulx	$n0,%o0,%o0		! ap[0]*bp[0]*n0
+	stx	%o0,[%sp+$bias+$frame+0]
+
+	ld	[%o3+0],$alo_	! load a[j] as pair of 32-bit words
+	fzeros	$alo
+	ld	[%o3+4],$ahi_
+	fzeros	$ahi
+	ld	[%o5+0],$nlo_	! load n[j] as pair of 32-bit words
+	fzeros	$nlo
+	ld	[%o5+4],$nhi_
+	fzeros	$nhi
+
+	! transfer b[i] to FPU as 4x16-bit values
+	ldda	[%o4+2]%asi,$ba
+	fxtod	$alo,$alo
+	ldda	[%o4+0]%asi,$bb
+	fxtod	$ahi,$ahi
+	ldda	[%o4+6]%asi,$bc
+	fxtod	$nlo,$nlo
+	ldda	[%o4+4]%asi,$bd
+	fxtod	$nhi,$nhi
+
+	! transfer ap[0]*b[0]*n0 to FPU as 4x16-bit values
+	ldda	[%sp+$bias+$frame+6]%asi,$na
+	fxtod	$ba,$ba
+	ldda	[%sp+$bias+$frame+4]%asi,$nb
+	fxtod	$bb,$bb
+	ldda	[%sp+$bias+$frame+2]%asi,$nc
+	fxtod	$bc,$bc
+	ldda	[%sp+$bias+$frame+0]%asi,$nd
+	fxtod	$bd,$bd
+
+	std	$alo,[$ap_l+$j]		! save smashed ap[j] in double format
+	fxtod	$na,$na
+	std	$ahi,[$ap_h+$j]
+	fxtod	$nb,$nb
+	std	$nlo,[$np_l+$j]		! save smashed np[j] in double format
+	fxtod	$nc,$nc
+	std	$nhi,[$np_h+$j]
+	fxtod	$nd,$nd
+
+		fmuld	$alo,$ba,$aloa
+		fmuld	$nlo,$na,$nloa
+		fmuld	$alo,$bb,$alob
+		fmuld	$nlo,$nb,$nlob
+		fmuld	$alo,$bc,$aloc
+	faddd	$aloa,$nloa,$nloa
+		fmuld	$nlo,$nc,$nloc
+		fmuld	$alo,$bd,$alod
+	faddd	$alob,$nlob,$nlob
+		fmuld	$nlo,$nd,$nlod
+		fmuld	$ahi,$ba,$ahia
+	faddd	$aloc,$nloc,$nloc
+		fmuld	$nhi,$na,$nhia
+		fmuld	$ahi,$bb,$ahib
+	faddd	$alod,$nlod,$nlod
+		fmuld	$nhi,$nb,$nhib
+		fmuld	$ahi,$bc,$ahic
+	faddd	$ahia,$nhia,$nhia
+		fmuld	$nhi,$nc,$nhic
+		fmuld	$ahi,$bd,$ahid
+	faddd	$ahib,$nhib,$nhib
+		fmuld	$nhi,$nd,$nhid
+
+	faddd	$ahic,$nhic,$dota	! $nhic
+	faddd	$ahid,$nhid,$dotb	! $nhid
+
+	faddd	$nloc,$nhia,$nloc
+	faddd	$nlod,$nhib,$nlod
+
+	fdtox	$nloa,$nloa
+	fdtox	$nlob,$nlob
+	fdtox	$nloc,$nloc
+	fdtox	$nlod,$nlod
+
+	std	$nloa,[%sp+$bias+$frame+0]
+	add	$j,8,$j
+	std	$nlob,[%sp+$bias+$frame+8]
+	add	$ap,$j,%o4
+	std	$nloc,[%sp+$bias+$frame+16]
+	add	$np,$j,%o5
+	std	$nlod,[%sp+$bias+$frame+24]
+
+	ld	[%o4+0],$alo_	! load a[j] as pair of 32-bit words
+	fzeros	$alo
+	ld	[%o4+4],$ahi_
+	fzeros	$ahi
+	ld	[%o5+0],$nlo_	! load n[j] as pair of 32-bit words
+	fzeros	$nlo
+	ld	[%o5+4],$nhi_
+	fzeros	$nhi
+
+	fxtod	$alo,$alo
+	fxtod	$ahi,$ahi
+	fxtod	$nlo,$nlo
+	fxtod	$nhi,$nhi
+
+	ldx	[%sp+$bias+$frame+0],%o0
+		fmuld	$alo,$ba,$aloa
+	ldx	[%sp+$bias+$frame+8],%o1
+		fmuld	$nlo,$na,$nloa
+	ldx	[%sp+$bias+$frame+16],%o2
+		fmuld	$alo,$bb,$alob
+	ldx	[%sp+$bias+$frame+24],%o3
+		fmuld	$nlo,$nb,$nlob
+
+	srlx	%o0,16,%o7
+	std	$alo,[$ap_l+$j]		! save smashed ap[j] in double format
+		fmuld	$alo,$bc,$aloc
+	add	%o7,%o1,%o1
+	std	$ahi,[$ap_h+$j]
+		faddd	$aloa,$nloa,$nloa
+		fmuld	$nlo,$nc,$nloc
+	srlx	%o1,16,%o7
+	std	$nlo,[$np_l+$j]		! save smashed np[j] in double format
+		fmuld	$alo,$bd,$alod
+	add	%o7,%o2,%o2
+	std	$nhi,[$np_h+$j]
+		faddd	$alob,$nlob,$nlob
+		fmuld	$nlo,$nd,$nlod
+	srlx	%o2,16,%o7
+		fmuld	$ahi,$ba,$ahia
+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
+		faddd	$aloc,$nloc,$nloc
+		fmuld	$nhi,$na,$nhia
+	!and	%o0,$mask,%o0
+	!and	%o1,$mask,%o1
+	!and	%o2,$mask,%o2
+	!sllx	%o1,16,%o1
+	!sllx	%o2,32,%o2
+	!sllx	%o3,48,%o7
+	!or	%o1,%o0,%o0
+	!or	%o2,%o0,%o0
+	!or	%o7,%o0,%o0		! 64-bit result
+	srlx	%o3,16,%g1		! 34-bit carry
+		fmuld	$ahi,$bb,$ahib
+
+	faddd	$alod,$nlod,$nlod
+		fmuld	$nhi,$nb,$nhib
+		fmuld	$ahi,$bc,$ahic
+	faddd	$ahia,$nhia,$nhia
+		fmuld	$nhi,$nc,$nhic
+		fmuld	$ahi,$bd,$ahid
+	faddd	$ahib,$nhib,$nhib
+		fmuld	$nhi,$nd,$nhid
+
+	faddd	$dota,$nloa,$nloa
+	faddd	$dotb,$nlob,$nlob
+	faddd	$ahic,$nhic,$dota	! $nhic
+	faddd	$ahid,$nhid,$dotb	! $nhid
+
+	faddd	$nloc,$nhia,$nloc
+	faddd	$nlod,$nhib,$nlod
+
+	fdtox	$nloa,$nloa
+	fdtox	$nlob,$nlob
+	fdtox	$nloc,$nloc
+	fdtox	$nlod,$nlod
+
+	std	$nloa,[%sp+$bias+$frame+0]
+	std	$nlob,[%sp+$bias+$frame+8]
+	addcc	$j,8,$j
+	std	$nloc,[%sp+$bias+$frame+16]
+	bz,pn	%icc,.L1stskip
+	std	$nlod,[%sp+$bias+$frame+24]
+
+.align	32			! incidentally already aligned !
+.L1st:
+	add	$ap,$j,%o4
+	add	$np,$j,%o5
+	ld	[%o4+0],$alo_	! load a[j] as pair of 32-bit words
+	fzeros	$alo
+	ld	[%o4+4],$ahi_
+	fzeros	$ahi
+	ld	[%o5+0],$nlo_	! load n[j] as pair of 32-bit words
+	fzeros	$nlo
+	ld	[%o5+4],$nhi_
+	fzeros	$nhi
+
+	fxtod	$alo,$alo
+	fxtod	$ahi,$ahi
+	fxtod	$nlo,$nlo
+	fxtod	$nhi,$nhi
+
+	ldx	[%sp+$bias+$frame+0],%o0
+		fmuld	$alo,$ba,$aloa
+	ldx	[%sp+$bias+$frame+8],%o1
+		fmuld	$nlo,$na,$nloa
+	ldx	[%sp+$bias+$frame+16],%o2
+		fmuld	$alo,$bb,$alob
+	ldx	[%sp+$bias+$frame+24],%o3
+		fmuld	$nlo,$nb,$nlob
+
+	srlx	%o0,16,%o7
+	std	$alo,[$ap_l+$j]		! save smashed ap[j] in double format
+		fmuld	$alo,$bc,$aloc
+	add	%o7,%o1,%o1
+	std	$ahi,[$ap_h+$j]
+		faddd	$aloa,$nloa,$nloa
+		fmuld	$nlo,$nc,$nloc
+	srlx	%o1,16,%o7
+	std	$nlo,[$np_l+$j]		! save smashed np[j] in double format
+		fmuld	$alo,$bd,$alod
+	add	%o7,%o2,%o2
+	std	$nhi,[$np_h+$j]
+		faddd	$alob,$nlob,$nlob
+		fmuld	$nlo,$nd,$nlod
+	srlx	%o2,16,%o7
+		fmuld	$ahi,$ba,$ahia
+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
+	and	%o0,$mask,%o0
+		faddd	$aloc,$nloc,$nloc
+		fmuld	$nhi,$na,$nhia
+	and	%o1,$mask,%o1
+	and	%o2,$mask,%o2
+		fmuld	$ahi,$bb,$ahib
+	sllx	%o1,16,%o1
+		faddd	$alod,$nlod,$nlod
+		fmuld	$nhi,$nb,$nhib
+	sllx	%o2,32,%o2
+		fmuld	$ahi,$bc,$ahic
+	sllx	%o3,48,%o7
+	or	%o1,%o0,%o0
+		faddd	$ahia,$nhia,$nhia
+		fmuld	$nhi,$nc,$nhic
+	or	%o2,%o0,%o0
+		fmuld	$ahi,$bd,$ahid
+	or	%o7,%o0,%o0		! 64-bit result
+		faddd	$ahib,$nhib,$nhib
+		fmuld	$nhi,$nd,$nhid
+	addcc	%g1,%o0,%o0
+		faddd	$dota,$nloa,$nloa
+	srlx	%o3,16,%g1		! 34-bit carry
+		faddd	$dotb,$nlob,$nlob
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	stx	%o0,[$tp]		! tp[j-1]=
+
+	faddd	$ahic,$nhic,$dota	! $nhic
+	faddd	$ahid,$nhid,$dotb	! $nhid
+
+	faddd	$nloc,$nhia,$nloc
+	faddd	$nlod,$nhib,$nlod
+
+	fdtox	$nloa,$nloa
+	fdtox	$nlob,$nlob
+	fdtox	$nloc,$nloc
+	fdtox	$nlod,$nlod
+
+	std	$nloa,[%sp+$bias+$frame+0]
+	std	$nlob,[%sp+$bias+$frame+8]
+	std	$nloc,[%sp+$bias+$frame+16]
+	std	$nlod,[%sp+$bias+$frame+24]
+
+	addcc	$j,8,$j
+	bnz,pt	%icc,.L1st
+	add	$tp,8,$tp
+
+.L1stskip:
+	fdtox	$dota,$dota
+	fdtox	$dotb,$dotb
+
+	ldx	[%sp+$bias+$frame+0],%o0
+	ldx	[%sp+$bias+$frame+8],%o1
+	ldx	[%sp+$bias+$frame+16],%o2
+	ldx	[%sp+$bias+$frame+24],%o3
+
+	srlx	%o0,16,%o7
+	std	$dota,[%sp+$bias+$frame+32]
+	add	%o7,%o1,%o1
+	std	$dotb,[%sp+$bias+$frame+40]
+	srlx	%o1,16,%o7
+	add	%o7,%o2,%o2
+	srlx	%o2,16,%o7
+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
+	and	%o0,$mask,%o0
+	and	%o1,$mask,%o1
+	and	%o2,$mask,%o2
+	sllx	%o1,16,%o1
+	sllx	%o2,32,%o2
+	sllx	%o3,48,%o7
+	or	%o1,%o0,%o0
+	or	%o2,%o0,%o0
+	or	%o7,%o0,%o0		! 64-bit result
+	ldx	[%sp+$bias+$frame+32],%o4
+	addcc	%g1,%o0,%o0
+	ldx	[%sp+$bias+$frame+40],%o5
+	srlx	%o3,16,%g1		! 34-bit carry
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	stx	%o0,[$tp]		! tp[j-1]=
+	add	$tp,8,$tp
+
+	srlx	%o4,16,%o7
+	add	%o7,%o5,%o5
+	and	%o4,$mask,%o4
+	sllx	%o5,16,%o7
+	or	%o7,%o4,%o4
+	addcc	%g1,%o4,%o4
+	srlx	%o5,48,%g1
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	mov	%g1,$carry
+	stx	%o4,[$tp]		! tp[num-1]=
+
+	ba	.Louter
+	add	$i,8,$i
+.align	32
+.Louter:
+	sub	%g0,$num,$j		! j=-num
+	add	%sp,$bias+$frame+$locals,$tp
+
+	add	$ap,$j,%o3
+	add	$bp,$i,%o4
+
+	ld	[%o3+4],%g1		! bp[i]
+	ld	[%o3+0],%o0
+	ld	[%o4+4],%g5		! ap[0]
+	sllx	%g1,32,%g1
+	ld	[%o4+0],%o1
+	sllx	%g5,32,%g5
+	or	%g1,%o0,%o0
+	or	%g5,%o1,%o1
+
+	ldx	[$tp],%o2		! tp[0]
+	mulx	%o1,%o0,%o0
+	addcc	%o2,%o0,%o0
+	mulx	$n0,%o0,%o0		! (ap[0]*bp[i]+t[0])*n0
+	stx	%o0,[%sp+$bias+$frame+0]
+
+	! transfer b[i] to FPU as 4x16-bit values
+	ldda	[%o4+2]%asi,$ba
+	ldda	[%o4+0]%asi,$bb
+	ldda	[%o4+6]%asi,$bc
+	ldda	[%o4+4]%asi,$bd
+
+	! transfer (ap[0]*b[i]+t[0])*n0 to FPU as 4x16-bit values
+	ldda	[%sp+$bias+$frame+6]%asi,$na
+	fxtod	$ba,$ba
+	ldda	[%sp+$bias+$frame+4]%asi,$nb
+	fxtod	$bb,$bb
+	ldda	[%sp+$bias+$frame+2]%asi,$nc
+	fxtod	$bc,$bc
+	ldda	[%sp+$bias+$frame+0]%asi,$nd
+	fxtod	$bd,$bd
+	ldd	[$ap_l+$j],$alo		! load a[j] in double format
+	fxtod	$na,$na
+	ldd	[$ap_h+$j],$ahi
+	fxtod	$nb,$nb
+	ldd	[$np_l+$j],$nlo		! load n[j] in double format
+	fxtod	$nc,$nc
+	ldd	[$np_h+$j],$nhi
+	fxtod	$nd,$nd
+
+		fmuld	$alo,$ba,$aloa
+		fmuld	$nlo,$na,$nloa
+		fmuld	$alo,$bb,$alob
+		fmuld	$nlo,$nb,$nlob
+		fmuld	$alo,$bc,$aloc
+	faddd	$aloa,$nloa,$nloa
+		fmuld	$nlo,$nc,$nloc
+		fmuld	$alo,$bd,$alod
+	faddd	$alob,$nlob,$nlob
+		fmuld	$nlo,$nd,$nlod
+		fmuld	$ahi,$ba,$ahia
+	faddd	$aloc,$nloc,$nloc
+		fmuld	$nhi,$na,$nhia
+		fmuld	$ahi,$bb,$ahib
+	faddd	$alod,$nlod,$nlod
+		fmuld	$nhi,$nb,$nhib
+		fmuld	$ahi,$bc,$ahic
+	faddd	$ahia,$nhia,$nhia
+		fmuld	$nhi,$nc,$nhic
+		fmuld	$ahi,$bd,$ahid
+	faddd	$ahib,$nhib,$nhib
+		fmuld	$nhi,$nd,$nhid
+
+	faddd	$ahic,$nhic,$dota	! $nhic
+	faddd	$ahid,$nhid,$dotb	! $nhid
+
+	faddd	$nloc,$nhia,$nloc
+	faddd	$nlod,$nhib,$nlod
+
+	fdtox	$nloa,$nloa
+	fdtox	$nlob,$nlob
+	fdtox	$nloc,$nloc
+	fdtox	$nlod,$nlod
+
+	std	$nloa,[%sp+$bias+$frame+0]
+	std	$nlob,[%sp+$bias+$frame+8]
+	std	$nloc,[%sp+$bias+$frame+16]
+	add	$j,8,$j
+	std	$nlod,[%sp+$bias+$frame+24]
+
+	ldd	[$ap_l+$j],$alo		! load a[j] in double format
+	ldd	[$ap_h+$j],$ahi
+	ldd	[$np_l+$j],$nlo		! load n[j] in double format
+	ldd	[$np_h+$j],$nhi
+
+		fmuld	$alo,$ba,$aloa
+		fmuld	$nlo,$na,$nloa
+		fmuld	$alo,$bb,$alob
+		fmuld	$nlo,$nb,$nlob
+		fmuld	$alo,$bc,$aloc
+	ldx	[%sp+$bias+$frame+0],%o0
+		faddd	$aloa,$nloa,$nloa
+		fmuld	$nlo,$nc,$nloc
+	ldx	[%sp+$bias+$frame+8],%o1
+		fmuld	$alo,$bd,$alod
+	ldx	[%sp+$bias+$frame+16],%o2
+		faddd	$alob,$nlob,$nlob
+		fmuld	$nlo,$nd,$nlod
+	ldx	[%sp+$bias+$frame+24],%o3
+		fmuld	$ahi,$ba,$ahia
+
+	srlx	%o0,16,%o7
+		faddd	$aloc,$nloc,$nloc
+		fmuld	$nhi,$na,$nhia
+	add	%o7,%o1,%o1
+		fmuld	$ahi,$bb,$ahib
+	srlx	%o1,16,%o7
+		faddd	$alod,$nlod,$nlod
+		fmuld	$nhi,$nb,$nhib
+	add	%o7,%o2,%o2
+		fmuld	$ahi,$bc,$ahic
+	srlx	%o2,16,%o7
+		faddd	$ahia,$nhia,$nhia
+		fmuld	$nhi,$nc,$nhic
+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
+	! why?
+	and	%o0,$mask,%o0
+		fmuld	$ahi,$bd,$ahid
+	and	%o1,$mask,%o1
+	and	%o2,$mask,%o2
+		faddd	$ahib,$nhib,$nhib
+		fmuld	$nhi,$nd,$nhid
+	sllx	%o1,16,%o1
+		faddd	$dota,$nloa,$nloa
+	sllx	%o2,32,%o2
+		faddd	$dotb,$nlob,$nlob
+	sllx	%o3,48,%o7
+	or	%o1,%o0,%o0
+		faddd	$ahic,$nhic,$dota	! $nhic
+	or	%o2,%o0,%o0
+		faddd	$ahid,$nhid,$dotb	! $nhid
+	or	%o7,%o0,%o0		! 64-bit result
+	ldx	[$tp],%o7
+		faddd	$nloc,$nhia,$nloc
+	addcc	%o7,%o0,%o0
+	! end-of-why?
+		faddd	$nlod,$nhib,$nlod
+	srlx	%o3,16,%g1		! 34-bit carry
+		fdtox	$nloa,$nloa
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	fdtox	$nlob,$nlob
+	fdtox	$nloc,$nloc
+	fdtox	$nlod,$nlod
+
+	std	$nloa,[%sp+$bias+$frame+0]
+	std	$nlob,[%sp+$bias+$frame+8]
+	addcc	$j,8,$j
+	std	$nloc,[%sp+$bias+$frame+16]
+	bz,pn	%icc,.Linnerskip
+	std	$nlod,[%sp+$bias+$frame+24]
+
+	ba	.Linner
+	nop
+.align	32
+.Linner:
+	ldd	[$ap_l+$j],$alo		! load a[j] in double format
+	ldd	[$ap_h+$j],$ahi
+	ldd	[$np_l+$j],$nlo		! load n[j] in double format
+	ldd	[$np_h+$j],$nhi
+
+		fmuld	$alo,$ba,$aloa
+		fmuld	$nlo,$na,$nloa
+		fmuld	$alo,$bb,$alob
+		fmuld	$nlo,$nb,$nlob
+		fmuld	$alo,$bc,$aloc
+	ldx	[%sp+$bias+$frame+0],%o0
+		faddd	$aloa,$nloa,$nloa
+		fmuld	$nlo,$nc,$nloc
+	ldx	[%sp+$bias+$frame+8],%o1
+		fmuld	$alo,$bd,$alod
+	ldx	[%sp+$bias+$frame+16],%o2
+		faddd	$alob,$nlob,$nlob
+		fmuld	$nlo,$nd,$nlod
+	ldx	[%sp+$bias+$frame+24],%o3
+		fmuld	$ahi,$ba,$ahia
+
+	srlx	%o0,16,%o7
+		faddd	$aloc,$nloc,$nloc
+		fmuld	$nhi,$na,$nhia
+	add	%o7,%o1,%o1
+		fmuld	$ahi,$bb,$ahib
+	srlx	%o1,16,%o7
+		faddd	$alod,$nlod,$nlod
+		fmuld	$nhi,$nb,$nhib
+	add	%o7,%o2,%o2
+		fmuld	$ahi,$bc,$ahic
+	srlx	%o2,16,%o7
+		faddd	$ahia,$nhia,$nhia
+		fmuld	$nhi,$nc,$nhic
+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
+	and	%o0,$mask,%o0
+		fmuld	$ahi,$bd,$ahid
+	and	%o1,$mask,%o1
+	and	%o2,$mask,%o2
+		faddd	$ahib,$nhib,$nhib
+		fmuld	$nhi,$nd,$nhid
+	sllx	%o1,16,%o1
+		faddd	$dota,$nloa,$nloa
+	sllx	%o2,32,%o2
+		faddd	$dotb,$nlob,$nlob
+	sllx	%o3,48,%o7
+	or	%o1,%o0,%o0
+		faddd	$ahic,$nhic,$dota	! $nhic
+	or	%o2,%o0,%o0
+		faddd	$ahid,$nhid,$dotb	! $nhid
+	or	%o7,%o0,%o0		! 64-bit result
+		faddd	$nloc,$nhia,$nloc
+	addcc	%g1,%o0,%o0
+	ldx	[$tp+8],%o7		! tp[j]
+		faddd	$nlod,$nhib,$nlod
+	srlx	%o3,16,%g1		! 34-bit carry
+		fdtox	$nloa,$nloa
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+		fdtox	$nlob,$nlob
+	addcc	%o7,%o0,%o0
+		fdtox	$nloc,$nloc
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	stx	%o0,[$tp]		! tp[j-1]
+		fdtox	$nlod,$nlod
+
+	std	$nloa,[%sp+$bias+$frame+0]
+	std	$nlob,[%sp+$bias+$frame+8]
+	std	$nloc,[%sp+$bias+$frame+16]
+	addcc	$j,8,$j
+	std	$nlod,[%sp+$bias+$frame+24]
+	bnz,pt	%icc,.Linner
+	add	$tp,8,$tp
+
+.Linnerskip:
+	fdtox	$dota,$dota
+	fdtox	$dotb,$dotb
+
+	ldx	[%sp+$bias+$frame+0],%o0
+	ldx	[%sp+$bias+$frame+8],%o1
+	ldx	[%sp+$bias+$frame+16],%o2
+	ldx	[%sp+$bias+$frame+24],%o3
+
+	srlx	%o0,16,%o7
+	std	$dota,[%sp+$bias+$frame+32]
+	add	%o7,%o1,%o1
+	std	$dotb,[%sp+$bias+$frame+40]
+	srlx	%o1,16,%o7
+	add	%o7,%o2,%o2
+	srlx	%o2,16,%o7
+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
+	and	%o0,$mask,%o0
+	and	%o1,$mask,%o1
+	and	%o2,$mask,%o2
+	sllx	%o1,16,%o1
+	sllx	%o2,32,%o2
+	sllx	%o3,48,%o7
+	or	%o1,%o0,%o0
+	or	%o2,%o0,%o0
+	ldx	[%sp+$bias+$frame+32],%o4
+	or	%o7,%o0,%o0		! 64-bit result
+	ldx	[%sp+$bias+$frame+40],%o5
+	addcc	%g1,%o0,%o0
+	ldx	[$tp+8],%o7		! tp[j]
+	srlx	%o3,16,%g1		! 34-bit carry
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	addcc	%o7,%o0,%o0
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	stx	%o0,[$tp]		! tp[j-1]
+	add	$tp,8,$tp
+
+	srlx	%o4,16,%o7
+	add	%o7,%o5,%o5
+	and	%o4,$mask,%o4
+	sllx	%o5,16,%o7
+	or	%o7,%o4,%o4
+	addcc	%g1,%o4,%o4
+	srlx	%o5,48,%g1
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	addcc	$carry,%o4,%o4
+	stx	%o4,[$tp]		! tp[num-1]
+	mov	%g1,$carry
+	bcs,a	%xcc,.+8
+	add	$carry,1,$carry
+
+	addcc	$i,8,$i
+	bnz	%icc,.Louter
+	nop
+
+	add	$tp,8,$tp		! adjust tp to point at the end
+	orn	%g0,%g0,%g4
+	sub	%g0,$num,%o7		! n=-num
+	ba	.Lsub
+	subcc	%g0,%g0,%g0		! clear %icc.c
+
+.align	32
+.Lsub:
+	ldx	[$tp+%o7],%o0
+	add	$np,%o7,%g1
+	ld	[%g1+0],%o2
+	ld	[%g1+4],%o3
+	srlx	%o0,32,%o1
+	subccc	%o0,%o2,%o2
+	add	$rp,%o7,%g1
+	subccc	%o1,%o3,%o3
+	st	%o2,[%g1+0]
+	add	%o7,8,%o7
+	brnz,pt	%o7,.Lsub
+	st	%o3,[%g1+4]
+	subc	$carry,0,%g4
+	sub	%g0,$num,%o7		! n=-num
+	ba	.Lcopy
+	nop
+
+.align	32
+.Lcopy:
+	ldx	[$tp+%o7],%o0
+	add	$rp,%o7,%g1
+	ld	[%g1+0],%o2
+	ld	[%g1+4],%o3
+	stx	%g0,[$tp+%o7]
+	and	%o0,%g4,%o0
+	srlx	%o0,32,%o1
+	andn	%o2,%g4,%o2
+	andn	%o3,%g4,%o3
+	or	%o2,%o0,%o0
+	or	%o3,%o1,%o1
+	st	%o0,[%g1+0]
+	add	%o7,8,%o7
+	brnz,pt	%o7,.Lcopy
+	st	%o1,[%g1+4]
+	sub	%g0,$num,%o7		! n=-num
+
+.Lzap:
+	stx	%g0,[$ap_l+%o7]
+	stx	%g0,[$ap_h+%o7]
+	stx	%g0,[$np_l+%o7]
+	stx	%g0,[$np_h+%o7]
+	add	%o7,8,%o7
+	brnz,pt	%o7,.Lzap
+	nop
+
+	ldx	[%sp+$bias+$frame+48],%o7
+	wr	%g0,%o7,%asi		! restore %asi
+
+	mov	1,%i0
+.Lret:
+	ret
+	restore
+.type   $fname,#function
+.size	$fname,(.-$fname)
+.asciz	"Montgomery Multipltication for UltraSPARC, CRYPTOGAMS by <appro\@openssl.org>"
+.align	32
+___
+
+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
+
+# Below substitution makes it possible to compile without demanding
+# VIS extentions on command line, e.g. -xarch=v9 vs. -xarch=v9a. I
+# dare to do this, because VIS capability is detected at run-time now
+# and this routine is not called on CPU not capable to execute it. Do
+# note that fzeros is not the only VIS dependency! Another dependency
+# is implicit and is just _a_ numerical value loaded to %asi register,
+# which assembler can't recognize as VIS specific...
+$code =~ s/fzeros\s+%f([0-9]+)/
+	   sprintf(".word\t0x%x\t! fzeros %%f%d",0x81b00c20|($1<<25),$1)
+	  /gem;
+
+print $code;
+# flush
+close STDOUT;
diff --git a/crypto/bn/asm/via-mont.pl b/crypto/bn/asm/via-mont.pl
new file mode 100644
index 0000000..c046a51
--- /dev/null
+++ b/crypto/bn/asm/via-mont.pl
@@ -0,0 +1,242 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# Wrapper around 'rep montmul', VIA-specific instruction accessing
+# PadLock Montgomery Multiplier. The wrapper is designed as drop-in
+# replacement for OpenSSL bn_mul_mont [first implemented in 0.9.9].
+#
+# Below are interleaved outputs from 'openssl speed rsa dsa' for 4
+# different software configurations on 1.5GHz VIA Esther processor.
+# Lines marked with "software integer" denote performance of hand-
+# coded integer-only assembler found in OpenSSL 0.9.7. "Software SSE2"
+# refers to hand-coded SSE2 Montgomery multiplication procedure found
+# OpenSSL 0.9.9. "Hardware VIA SDK" refers to padlock_pmm routine from
+# Padlock SDK 2.0.1 available for download from VIA, which naturally
+# utilizes the magic 'repz montmul' instruction. And finally "hardware
+# this" refers to *this* implementation which also uses 'repz montmul'
+#
+#                   sign    verify    sign/s verify/s
+# rsa  512 bits 0.001720s 0.000140s    581.4   7149.7	software integer
+# rsa  512 bits 0.000690s 0.000086s   1450.3  11606.0	software SSE2
+# rsa  512 bits 0.006136s 0.000201s    163.0   4974.5	hardware VIA SDK
+# rsa  512 bits 0.000712s 0.000050s   1404.9  19858.5	hardware this
+#
+# rsa 1024 bits 0.008518s 0.000413s    117.4   2420.8	software integer
+# rsa 1024 bits 0.004275s 0.000277s    233.9   3609.7	software SSE2
+# rsa 1024 bits 0.012136s 0.000260s     82.4   3844.5	hardware VIA SDK
+# rsa 1024 bits 0.002522s 0.000116s    396.5   8650.9	hardware this
+#
+# rsa 2048 bits 0.050101s 0.001371s     20.0    729.6	software integer
+# rsa 2048 bits 0.030273s 0.001008s     33.0    991.9	software SSE2
+# rsa 2048 bits 0.030833s 0.000976s     32.4   1025.1	hardware VIA SDK
+# rsa 2048 bits 0.011879s 0.000342s     84.2   2921.7	hardware this
+#
+# rsa 4096 bits 0.327097s 0.004859s      3.1    205.8	software integer
+# rsa 4096 bits 0.229318s 0.003859s      4.4    259.2	software SSE2
+# rsa 4096 bits 0.233953s 0.003274s      4.3    305.4	hardware VIA SDK
+# rsa 4096 bits 0.070493s 0.001166s     14.2    857.6	hardware this
+#
+# dsa  512 bits 0.001342s 0.001651s    745.2    605.7	software integer
+# dsa  512 bits 0.000844s 0.000987s   1185.3   1013.1	software SSE2
+# dsa  512 bits 0.001902s 0.002247s    525.6    444.9	hardware VIA SDK
+# dsa  512 bits 0.000458s 0.000524s   2182.2   1909.1	hardware this
+#
+# dsa 1024 bits 0.003964s 0.004926s    252.3    203.0	software integer
+# dsa 1024 bits 0.002686s 0.003166s    372.3    315.8	software SSE2
+# dsa 1024 bits 0.002397s 0.002823s    417.1    354.3	hardware VIA SDK
+# dsa 1024 bits 0.000978s 0.001170s   1022.2    855.0	hardware this
+#
+# dsa 2048 bits 0.013280s 0.016518s     75.3     60.5	software integer
+# dsa 2048 bits 0.009911s 0.011522s    100.9     86.8	software SSE2
+# dsa 2048 bits 0.009542s 0.011763s    104.8     85.0	hardware VIA SDK
+# dsa 2048 bits 0.002884s 0.003352s    346.8    298.3	hardware this
+#
+# To give you some other reference point here is output for 2.4GHz P4
+# running hand-coded SSE2 bn_mul_mont found in 0.9.9, i.e. "software
+# SSE2" in above terms.
+#
+# rsa  512 bits 0.000407s 0.000047s   2454.2  21137.0
+# rsa 1024 bits 0.002426s 0.000141s    412.1   7100.0
+# rsa 2048 bits 0.015046s 0.000491s     66.5   2034.9
+# rsa 4096 bits 0.109770s 0.002379s      9.1    420.3
+# dsa  512 bits 0.000438s 0.000525s   2281.1   1904.1
+# dsa 1024 bits 0.001346s 0.001595s    742.7    627.0
+# dsa 2048 bits 0.004745s 0.005582s    210.7    179.1
+#
+# Conclusions: 
+# - VIA SDK leaves a *lot* of room for improvement (which this
+#   implementation successfully fills:-);
+# - 'rep montmul' gives up to >3x performance improvement depending on
+#   key length;
+# - in terms of absolute performance it delivers approximately as much
+#   as modern out-of-order 32-bit cores [again, for longer keys].
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"via-mont.pl");
+
+# int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
+$func="bn_mul_mont_padlock";
+
+$pad=16*1;	# amount of reserved bytes on top of every vector
+
+# stack layout
+$mZeroPrime=&DWP(0,"esp");		# these are specified by VIA
+$A=&DWP(4,"esp");
+$B=&DWP(8,"esp");
+$T=&DWP(12,"esp");
+$M=&DWP(16,"esp");
+$scratch=&DWP(20,"esp");
+$rp=&DWP(24,"esp");			# these are mine
+$sp=&DWP(28,"esp");
+# &DWP(32,"esp")			# 32 byte scratch area
+# &DWP(64+(4*$num+$pad)*0,"esp")	# padded tp[num]
+# &DWP(64+(4*$num+$pad)*1,"esp")	# padded copy of ap[num]
+# &DWP(64+(4*$num+$pad)*2,"esp")	# padded copy of bp[num]
+# &DWP(64+(4*$num+$pad)*3,"esp")	# padded copy of np[num]
+# Note that SDK suggests to unconditionally allocate 2K per vector. This
+# has quite an impact on performance. It naturally depends on key length,
+# but to give an example 1024 bit private RSA key operations suffer >30%
+# penalty. I allocate only as much as actually required...
+
+&function_begin($func);
+	&xor	("eax","eax");
+	&mov	("ecx",&wparam(5));	# num
+	# meet VIA's limitations for num [note that the specification
+	# expresses them in bits, while we work with amount of 32-bit words]
+	&test	("ecx",3);
+	&jnz	(&label("leave"));	# num % 4 != 0
+	&cmp	("ecx",8);
+	&jb	(&label("leave"));	# num < 8
+	&cmp	("ecx",1024);
+	&ja	(&label("leave"));	# num > 1024
+
+	&pushf	();
+	&cld	();
+
+	&mov	("edi",&wparam(0));	# rp
+	&mov	("eax",&wparam(1));	# ap
+	&mov	("ebx",&wparam(2));	# bp
+	&mov	("edx",&wparam(3));	# np
+	&mov	("esi",&wparam(4));	# n0
+	&mov	("esi",&DWP(0,"esi"));	# *n0
+
+	&lea	("ecx",&DWP($pad,"","ecx",4));	# ecx becomes vector size in bytes
+	&lea	("ebp",&DWP(64,"","ecx",4));	# allocate 4 vectors + 64 bytes
+	&neg	("ebp");
+	&add	("ebp","esp");
+	&and	("ebp",-64);		# align to cache-line
+	&xchg	("ebp","esp");		# alloca
+
+	&mov	($rp,"edi");		# save rp
+	&mov	($sp,"ebp");		# save esp
+
+	&mov	($mZeroPrime,"esi");
+	&lea	("esi",&DWP(64,"esp"));	# tp
+	&mov	($T,"esi");
+	&lea	("edi",&DWP(32,"esp"));	# scratch area
+	&mov	($scratch,"edi");
+	&mov	("esi","eax");
+
+	&lea	("ebp",&DWP(-$pad,"ecx"));
+	&shr	("ebp",2);		# restore original num value in ebp
+
+	&xor	("eax","eax");
+
+	&mov	("ecx","ebp");
+	&lea	("ecx",&DWP((32+$pad)/4,"ecx"));# padded tp + scratch
+	&data_byte(0xf3,0xab);		# rep stosl, bzero
+
+	&mov	("ecx","ebp");
+	&lea	("edi",&DWP(64+$pad,"esp","ecx",4));# pointer to ap copy
+	&mov	($A,"edi");
+	&data_byte(0xf3,0xa5);		# rep movsl, memcpy
+	&mov	("ecx",$pad/4);
+	&data_byte(0xf3,0xab);		# rep stosl, bzero pad
+	# edi points at the end of padded ap copy...
+
+	&mov	("ecx","ebp");
+	&mov	("esi","ebx");
+	&mov	($B,"edi");
+	&data_byte(0xf3,0xa5);		# rep movsl, memcpy
+	&mov	("ecx",$pad/4);
+	&data_byte(0xf3,0xab);		# rep stosl, bzero pad
+	# edi points at the end of padded bp copy...
+
+	&mov	("ecx","ebp");
+	&mov	("esi","edx");
+	&mov	($M,"edi");
+	&data_byte(0xf3,0xa5);		# rep movsl, memcpy
+	&mov	("ecx",$pad/4);
+	&data_byte(0xf3,0xab);		# rep stosl, bzero pad
+	# edi points at the end of padded np copy...
+
+	# let magic happen...
+	&mov	("ecx","ebp");
+	&mov	("esi","esp");
+	&shl	("ecx",5);		# convert word counter to bit counter
+	&align	(4);
+	&data_byte(0xf3,0x0f,0xa6,0xc0);# rep montmul
+
+	&mov	("ecx","ebp");
+	&lea	("esi",&DWP(64,"esp"));		# tp
+	# edi still points at the end of padded np copy...
+	&neg	("ebp");
+	&lea	("ebp",&DWP(-$pad,"edi","ebp",4));	# so just "rewind"
+	&mov	("edi",$rp);			# restore rp
+	&xor	("edx","edx");			# i=0 and clear CF
+
+&set_label("sub",8);
+	&mov	("eax",&DWP(0,"esi","edx",4));
+	&sbb	("eax",&DWP(0,"ebp","edx",4));
+	&mov	(&DWP(0,"edi","edx",4),"eax");	# rp[i]=tp[i]-np[i]
+	&lea	("edx",&DWP(1,"edx"));		# i++
+	&loop	(&label("sub"));		# doesn't affect CF!
+
+	&mov	("eax",&DWP(0,"esi","edx",4));	# upmost overflow bit
+	&sbb	("eax",0);
+	&and	("esi","eax");
+	&not	("eax");
+	&mov	("ebp","edi");
+	&and	("ebp","eax");
+	&or	("esi","ebp");			# tp=carry?tp:rp
+
+	&mov	("ecx","edx");			# num
+	&xor	("edx","edx");			# i=0
+
+&set_label("copy",8);
+	&mov	("eax",&DWP(0,"esi","edx",4));
+	&mov	(&DWP(64,"esp","edx",4),"ecx");	# zap tp
+	&mov	(&DWP(0,"edi","edx",4),"eax");
+	&lea	("edx",&DWP(1,"edx"));		# i++
+	&loop	(&label("copy"));
+
+	&mov	("ebp",$sp);
+	&xor	("eax","eax");
+
+	&mov	("ecx",64/4);
+	&mov	("edi","esp");		# zap frame including scratch area
+	&data_byte(0xf3,0xab);		# rep stosl, bzero
+
+	# zap copies of ap, bp and np
+	&lea	("edi",&DWP(64+$pad,"esp","edx",4));# pointer to ap
+	&lea	("ecx",&DWP(3*$pad/4,"edx","edx",2));
+	&data_byte(0xf3,0xab);		# rep stosl, bzero
+
+	&mov	("esp","ebp");
+	&inc	("eax");		# signal "done"
+	&popf	();
+&set_label("leave");
+&function_end($func);
+
+&asciz("Padlock Montgomery Multiplication, CRYPTOGAMS by <appro\@openssl.org>");
+
+&asm_finish();
diff --git a/crypto/bn/asm/mo-586.pl b/crypto/bn/asm/x86-mont.pl
old mode 100644
new mode 100755
similarity index 97%
rename from crypto/bn/asm/mo-586.pl
rename to crypto/bn/asm/x86-mont.pl
index 0982293..5cd3cd2
--- a/crypto/bn/asm/mo-586.pl
+++ b/crypto/bn/asm/x86-mont.pl
@@ -1,18 +1,5 @@
 #!/usr/bin/env perl
 
-# This is crypto/bn/asm/x86-mont.pl (with asciz from crypto/perlasm/x86asm.pl)
-# from OpenSSL 0.9.9-dev 
-
-sub ::asciz
-{ my @str=unpack("C*",shift);
-    push @str,0;
-    while ($#str>15) {
-	&data_byte(@str[0..15]);
-	foreach (0..15) { shift @str; }
-    }
-    &data_byte(@str) if (@str);
-}
-
 # ====================================================================
 # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
 # project. The module is, however, dual licensed under OpenSSL and
@@ -39,7 +26,8 @@
 # Integer-only code [being equipped with dedicated squaring procedure]
 # gives ~40% on rsa512 sign benchmark...
 
-push(@INC,"perlasm","../../perlasm");
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
 require "x86asm.pl";
 
 &asm_init($ARGV[0],$0);
diff --git a/crypto/bn/asm/x86_64-gcc.c b/crypto/bn/asm/x86_64-gcc.c
index 2b2bc1e..acb0b40 100644
--- a/crypto/bn/asm/x86_64-gcc.c
+++ b/crypto/bn/asm/x86_64-gcc.c
@@ -1,5 +1,5 @@
 #include "../bn_lcl.h"
-#ifdef __SUNPRO_C
+#if !(defined(__GNUC__) && __GNUC__>=2)
 # include "../bn_asm.c"	/* kind of dirty hack for Sun Studio */
 #else
 /*
@@ -55,10 +55,15 @@
  *    machine.
  */
 
+#ifdef _WIN64
+#define BN_ULONG unsigned long long
+#else
 #define BN_ULONG unsigned long
+#endif
 
 #undef mul
 #undef mul_add
+#undef sqr
 
 /*
  * "m"(a), "+m"(r)	is the way to favor DirectPath µ-code;
@@ -186,7 +191,7 @@
 
 	asm (
 	"	subq	%2,%2		\n"
-	".align 16			\n"
+	".p2align 4			\n"
 	"1:	movq	(%4,%2,8),%0	\n"
 	"	adcq	(%5,%2,8),%0	\n"
 	"	movq	%0,(%3,%2,8)	\n"
@@ -209,7 +214,7 @@
 
 	asm (
 	"	subq	%2,%2		\n"
-	".align 16			\n"
+	".p2align 4			\n"
 	"1:	movq	(%4,%2,8),%0	\n"
 	"	sbbq	(%5,%2,8),%0	\n"
 	"	movq	%0,(%3,%2,8)	\n"
diff --git a/crypto/bn/asm/x86_64-mont.pl b/crypto/bn/asm/x86_64-mont.pl
index c43b695..3b7a6f2 100755
--- a/crypto/bn/asm/x86_64-mont.pl
+++ b/crypto/bn/asm/x86_64-mont.pl
@@ -15,14 +15,18 @@
 # respectful 50%. It remains to be seen if loop unrolling and
 # dedicated squaring routine can provide further improvement...
 
-$output=shift;
+$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 $output";
+open STDOUT,"| $^X $xlate $flavour $output";
 
 # int bn_mul_mont(
 $rp="%rdi";	# BN_ULONG *rp,
@@ -55,13 +59,14 @@
 	push	%r15
 
 	mov	${num}d,${num}d
-	lea	2($num),%rax
-	mov	%rsp,%rbp
-	neg	%rax
-	lea	(%rsp,%rax,8),%rsp	# tp=alloca(8*(num+2))
+	lea	2($num),%r10
+	mov	%rsp,%r11
+	neg	%r10
+	lea	(%rsp,%r10,8),%rsp	# tp=alloca(8*(num+2))
 	and	\$-1024,%rsp		# minimize TLB usage
 
-	mov	%rbp,8(%rsp,$num,8)	# tp[num+1]=%rsp
+	mov	%r11,8(%rsp,$num,8)	# tp[num+1]=%rsp
+.Lprologue:
 	mov	%rdx,$bp		# $bp reassigned, remember?
 
 	mov	($n0),$n0		# pull n0[0] value
@@ -197,18 +202,129 @@
 	dec	$j
 	jge	.Lcopy
 
-	mov	8(%rsp,$num,8),%rsp	# restore %rsp
+	mov	8(%rsp,$num,8),%rsi	# restore %rsp
 	mov	\$1,%rax
+	mov	(%rsi),%r15
+	mov	8(%rsi),%r14
+	mov	16(%rsi),%r13
+	mov	24(%rsi),%r12
+	mov	32(%rsi),%rbp
+	mov	40(%rsi),%rbx
+	lea	48(%rsi),%rsp
+.Lepilogue:
+	ret
+.size	bn_mul_mont,.-bn_mul_mont
+.asciz	"Montgomery Multiplication for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
+.align	16
+___
+
+# 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	se_handler,\@abi-omnipotent
+.align	16
+se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	lea	.Lprologue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lprologue
+	jb	.Lin_prologue
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	lea	.Lepilogue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
+	jae	.Lin_prologue
+
+	mov	192($context),%r10	# pull $num
+	mov	8(%rax,%r10,8),%rax	# pull saved stack pointer
+	lea	48(%rax),%rax
+
+	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_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
+
+	mov	40($disp),%rdi		# disp->ContextRecord
+	mov	$context,%rsi		# context
+	mov	\$154,%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
+	add	\$64,%rsp
+	popfq
 	pop	%r15
 	pop	%r14
 	pop	%r13
 	pop	%r12
 	pop	%rbp
 	pop	%rbx
+	pop	%rdi
+	pop	%rsi
 	ret
-.size	bn_mul_mont,.-bn_mul_mont
-.asciz	"Montgomery Multiplication for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
+.size	se_handler,.-se_handler
+
+.section	.pdata
+.align	4
+	.rva	.LSEH_begin_bn_mul_mont
+	.rva	.LSEH_end_bn_mul_mont
+	.rva	.LSEH_info_bn_mul_mont
+
+.section	.xdata
+.align	8
+.LSEH_info_bn_mul_mont:
+	.byte	9,0,0,0
+	.rva	se_handler
 ___
+}
 
 print $code;
 close STDOUT;
diff --git a/crypto/bn/bn.h b/crypto/bn/bn.h
index f1719a5..e484b7f 100644
--- a/crypto/bn/bn.h
+++ b/crypto/bn/bn.h
@@ -56,6 +56,59 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
+ * Copyright (c) 1998-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
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
  *
  * Portions of the attached software ("Contribution") are developed by 
@@ -77,6 +130,7 @@
 #include <stdio.h> /* FILE */
 #endif
 #include <openssl/ossl_typ.h>
+#include <openssl/crypto.h>
 
 #ifdef  __cplusplus
 extern "C" {
@@ -94,9 +148,11 @@
 /* #define BN_DEBUG */
 /* #define BN_DEBUG_RAND */
 
+#ifndef OPENSSL_SMALL_FOOTPRINT
 #define BN_MUL_COMBA
 #define BN_SQR_COMBA
 #define BN_RECURSION
+#endif
 
 /* This next option uses the C libraries (2 word)/(1 word) function.
  * If it is not defined, I use my C version (which is slower).
@@ -137,6 +193,8 @@
 #define BN_DEC_FMT1	"%lu"
 #define BN_DEC_FMT2	"%019lu"
 #define BN_DEC_NUM	19
+#define BN_HEX_FMT1	"%lX"
+#define BN_HEX_FMT2	"%016lX"
 #endif
 
 /* This is where the long long data type is 64 bits, but long is 32.
@@ -162,83 +220,37 @@
 #define BN_DEC_FMT1	"%llu"
 #define BN_DEC_FMT2	"%019llu"
 #define BN_DEC_NUM	19
+#define BN_HEX_FMT1	"%llX"
+#define BN_HEX_FMT2	"%016llX"
 #endif
 
 #ifdef THIRTY_TWO_BIT
 #ifdef BN_LLONG
-# if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__)
+# if defined(_WIN32) && !defined(__GNUC__)
 #  define BN_ULLONG	unsigned __int64
+#  define BN_MASK	(0xffffffffffffffffI64)
 # else
 #  define BN_ULLONG	unsigned long long
+#  define BN_MASK	(0xffffffffffffffffLL)
 # endif
 #endif
-#define BN_ULONG	unsigned long
-#define BN_LONG		long
+#define BN_ULONG	unsigned int
+#define BN_LONG		int
 #define BN_BITS		64
 #define BN_BYTES	4
 #define BN_BITS2	32
 #define BN_BITS4	16
-#ifdef OPENSSL_SYS_WIN32
-/* VC++ doesn't like the LL suffix */
-#define BN_MASK		(0xffffffffffffffffL)
-#else
-#define BN_MASK		(0xffffffffffffffffLL)
-#endif
 #define BN_MASK2	(0xffffffffL)
 #define BN_MASK2l	(0xffff)
 #define BN_MASK2h1	(0xffff8000L)
 #define BN_MASK2h	(0xffff0000L)
 #define BN_TBIT		(0x80000000L)
 #define BN_DEC_CONV	(1000000000L)
-#define BN_DEC_FMT1	"%lu"
-#define BN_DEC_FMT2	"%09lu"
+#define BN_DEC_FMT1	"%u"
+#define BN_DEC_FMT2	"%09u"
 #define BN_DEC_NUM	9
-#endif
-
-#ifdef SIXTEEN_BIT
-#ifndef BN_DIV2W
-#define BN_DIV2W
-#endif
-#define BN_ULLONG	unsigned long
-#define BN_ULONG	unsigned short
-#define BN_LONG		short
-#define BN_BITS		32
-#define BN_BYTES	2
-#define BN_BITS2	16
-#define BN_BITS4	8
-#define BN_MASK		(0xffffffff)
-#define BN_MASK2	(0xffff)
-#define BN_MASK2l	(0xff)
-#define BN_MASK2h1	(0xff80)
-#define BN_MASK2h	(0xff00)
-#define BN_TBIT		(0x8000)
-#define BN_DEC_CONV	(100000)
-#define BN_DEC_FMT1	"%u"
-#define BN_DEC_FMT2	"%05u"
-#define BN_DEC_NUM	5
-#endif
-
-#ifdef EIGHT_BIT
-#ifndef BN_DIV2W
-#define BN_DIV2W
-#endif
-#define BN_ULLONG	unsigned short
-#define BN_ULONG	unsigned char
-#define BN_LONG		char
-#define BN_BITS		16
-#define BN_BYTES	1
-#define BN_BITS2	8
-#define BN_BITS4	4
-#define BN_MASK		(0xffff)
-#define BN_MASK2	(0xff)
-#define BN_MASK2l	(0xf)
-#define BN_MASK2h1	(0xf8)
-#define BN_MASK2h	(0xf0)
-#define BN_TBIT		(0x80)
-#define BN_DEC_CONV	(100)
-#define BN_DEC_FMT1	"%u"
-#define BN_DEC_FMT2	"%02u"
-#define BN_DEC_NUM	2
+#define BN_HEX_FMT1	"%X"
+#define BN_HEX_FMT2	"%08X"
 #endif
 
 #define BN_DEFAULT_BITS	1280
@@ -303,12 +315,8 @@
 	BIGNUM N;      /* The modulus */
 	BIGNUM Ni;     /* R*(1/R mod N) - N*Ni = 1
 	                * (Ni is only stored for bignum algorithm) */
-#if 0
-	/* OpenSSL 0.9.9 preview: */
-	BN_ULONG n0[2];/* least significant word(s) of Ni */
-#else
-	BN_ULONG n0;   /* least significant word of Ni */
-#endif
+	BN_ULONG n0[2];/* least significant word(s) of Ni;
+	                  (type changed with 0.9.9, was "BN_ULONG n0;" before) */
 	int flags;
 	};
 
@@ -504,6 +512,7 @@
 char *	BN_bn2dec(const BIGNUM *a);
 int 	BN_hex2bn(BIGNUM **a, const char *str);
 int 	BN_dec2bn(BIGNUM **a, const char *str);
+int	BN_asc2bn(BIGNUM **a, const char *str);
 int	BN_gcd(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx);
 int	BN_kronecker(const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx); /* returns -2 for error */
 BIGNUM *BN_mod_inverse(BIGNUM *ret,
@@ -531,17 +540,6 @@
 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,
@@ -560,19 +558,22 @@
 #define	BN_BLINDING_NO_UPDATE	0x00000001
 #define	BN_BLINDING_NO_RECREATE	0x00000002
 
-BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGNUM *mod);
+BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod);
 void BN_BLINDING_free(BN_BLINDING *b);
 int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
 int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
 int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
 int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *);
 int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *);
+#ifndef OPENSSL_NO_DEPRECATED
 unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
 void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
+#endif
+CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *);
 unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
 void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
 BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
-	const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx,
+	const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
 	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
 			  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
 	BN_MONT_CTX *m_ctx);
@@ -625,24 +626,24 @@
  *     t^p[0] + t^p[1] + ... + t^p[k]
  * where m = p[0] > p[1] > ... > p[k] = 0.
  */
-int	BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[]);
+int	BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]);
 	/* r = a mod p */
 int	BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
-	const unsigned int p[], BN_CTX *ctx); /* r = (a * b) mod p */
-int	BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[],
+	const int p[], BN_CTX *ctx); /* r = (a * b) mod p */
+int	BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[],
 	BN_CTX *ctx); /* r = (a * a) mod p */
-int	BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const unsigned int p[],
+int	BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[],
 	BN_CTX *ctx); /* r = (1 / b) mod p */
 int	BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
-	const unsigned int p[], BN_CTX *ctx); /* r = (a / b) mod p */
+	const int p[], BN_CTX *ctx); /* r = (a / b) mod p */
 int	BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
-	const unsigned int p[], BN_CTX *ctx); /* r = (a ^ b) mod p */
+	const int p[], BN_CTX *ctx); /* r = (a ^ b) mod p */
 int	BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a,
-	const unsigned int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */
+	const int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */
 int	BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a,
-	const unsigned int p[], BN_CTX *ctx); /* r^2 + r = a mod p */
-int	BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max);
-int	BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a);
+	const int p[], BN_CTX *ctx); /* r^2 + r = a mod p */
+int	BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max);
+int	BN_GF2m_arr2poly(const int p[], BIGNUM *a);
 
 /* faster mod functions for the 'NIST primes' 
  * 0 <= a < p^2 */
@@ -751,10 +752,12 @@
 #define bn_correct_top(a) \
         { \
         BN_ULONG *ftl; \
-	if ((a)->top > 0) \
+	int tmp_top = (a)->top; \
+	if (tmp_top > 0) \
 		{ \
-		for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \
-		if (*(ftl--)) break; \
+		for (ftl= &((a)->d[tmp_top-1]); tmp_top > 0; tmp_top--) \
+			if (*(ftl--)) break; \
+		(a)->top = tmp_top; \
 		} \
 	bn_pollute(a); \
 	}
diff --git a/crypto/bn/bn_asm.c b/crypto/bn/bn_asm.c
index 99bc2de..c43c91c 100644
--- a/crypto/bn/bn_asm.c
+++ b/crypto/bn/bn_asm.c
@@ -75,6 +75,7 @@
 	assert(num >= 0);
 	if (num <= 0) return(c1);
 
+#ifndef OPENSSL_SMALL_FOOTPRINT
 	while (num&~3)
 		{
 		mul_add(rp[0],ap[0],w,c1);
@@ -83,11 +84,11 @@
 		mul_add(rp[3],ap[3],w,c1);
 		ap+=4; rp+=4; num-=4;
 		}
-	if (num)
+#endif
+	while (num)
 		{
-		mul_add(rp[0],ap[0],w,c1); if (--num==0) return c1;
-		mul_add(rp[1],ap[1],w,c1); if (--num==0) return c1;
-		mul_add(rp[2],ap[2],w,c1); return c1;
+		mul_add(rp[0],ap[0],w,c1);
+		ap++; rp++; num--;
 		}
 	
 	return(c1);
@@ -100,6 +101,7 @@
 	assert(num >= 0);
 	if (num <= 0) return(c1);
 
+#ifndef OPENSSL_SMALL_FOOTPRINT
 	while (num&~3)
 		{
 		mul(rp[0],ap[0],w,c1);
@@ -108,11 +110,11 @@
 		mul(rp[3],ap[3],w,c1);
 		ap+=4; rp+=4; num-=4;
 		}
-	if (num)
+#endif
+	while (num)
 		{
-		mul(rp[0],ap[0],w,c1); if (--num == 0) return c1;
-		mul(rp[1],ap[1],w,c1); if (--num == 0) return c1;
-		mul(rp[2],ap[2],w,c1);
+		mul(rp[0],ap[0],w,c1);
+		ap++; rp++; num--;
 		}
 	return(c1);
 	} 
@@ -121,6 +123,8 @@
         {
 	assert(n >= 0);
 	if (n <= 0) return;
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
 	while (n&~3)
 		{
 		sqr(r[0],r[1],a[0]);
@@ -129,11 +133,11 @@
 		sqr(r[6],r[7],a[3]);
 		a+=4; r+=8; n-=4;
 		}
-	if (n)
+#endif
+	while (n)
 		{
-		sqr(r[0],r[1],a[0]); if (--n == 0) return;
-		sqr(r[2],r[3],a[1]); if (--n == 0) return;
-		sqr(r[4],r[5],a[2]);
+		sqr(r[0],r[1],a[0]);
+		a++; r+=2; n--;
 		}
 	}
 
@@ -150,18 +154,20 @@
 	bl=LBITS(w);
 	bh=HBITS(w);
 
-	for (;;)
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (num&~3)
 		{
 		mul_add(rp[0],ap[0],bl,bh,c);
-		if (--num == 0) break;
 		mul_add(rp[1],ap[1],bl,bh,c);
-		if (--num == 0) break;
 		mul_add(rp[2],ap[2],bl,bh,c);
-		if (--num == 0) break;
 		mul_add(rp[3],ap[3],bl,bh,c);
-		if (--num == 0) break;
-		ap+=4;
-		rp+=4;
+		ap+=4; rp+=4; num-=4;
+		}
+#endif
+	while (num)
+		{
+		mul_add(rp[0],ap[0],bl,bh,c);
+		ap++; rp++; num--;
 		}
 	return(c);
 	} 
@@ -177,18 +183,20 @@
 	bl=LBITS(w);
 	bh=HBITS(w);
 
-	for (;;)
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (num&~3)
 		{
 		mul(rp[0],ap[0],bl,bh,carry);
-		if (--num == 0) break;
 		mul(rp[1],ap[1],bl,bh,carry);
-		if (--num == 0) break;
 		mul(rp[2],ap[2],bl,bh,carry);
-		if (--num == 0) break;
 		mul(rp[3],ap[3],bl,bh,carry);
-		if (--num == 0) break;
-		ap+=4;
-		rp+=4;
+		ap+=4; rp+=4; num-=4;
+		}
+#endif
+	while (num)
+		{
+		mul(rp[0],ap[0],bl,bh,carry);
+		ap++; rp++; num--;
 		}
 	return(carry);
 	} 
@@ -197,22 +205,21 @@
         {
 	assert(n >= 0);
 	if (n <= 0) return;
-	for (;;)
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (n&~3)
 		{
 		sqr64(r[0],r[1],a[0]);
-		if (--n == 0) break;
-
 		sqr64(r[2],r[3],a[1]);
-		if (--n == 0) break;
-
 		sqr64(r[4],r[5],a[2]);
-		if (--n == 0) break;
-
 		sqr64(r[6],r[7],a[3]);
-		if (--n == 0) break;
-
-		a+=4;
-		r+=8;
+		a+=4; r+=8; n-=4;
+		}
+#endif
+	while (n)
+		{
+		sqr64(r[0],r[1],a[0]);
+		a++; r+=2; n--;
 		}
 	}
 
@@ -303,31 +310,30 @@
 	assert(n >= 0);
 	if (n <= 0) return((BN_ULONG)0);
 
-	for (;;)
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (n&~3)
 		{
 		ll+=(BN_ULLONG)a[0]+b[0];
 		r[0]=(BN_ULONG)ll&BN_MASK2;
 		ll>>=BN_BITS2;
-		if (--n <= 0) break;
-
 		ll+=(BN_ULLONG)a[1]+b[1];
 		r[1]=(BN_ULONG)ll&BN_MASK2;
 		ll>>=BN_BITS2;
-		if (--n <= 0) break;
-
 		ll+=(BN_ULLONG)a[2]+b[2];
 		r[2]=(BN_ULONG)ll&BN_MASK2;
 		ll>>=BN_BITS2;
-		if (--n <= 0) break;
-
 		ll+=(BN_ULLONG)a[3]+b[3];
 		r[3]=(BN_ULONG)ll&BN_MASK2;
 		ll>>=BN_BITS2;
-		if (--n <= 0) break;
-
-		a+=4;
-		b+=4;
-		r+=4;
+		a+=4; b+=4; r+=4; n-=4;
+		}
+#endif
+	while (n)
+		{
+		ll+=(BN_ULLONG)a[0]+b[0];
+		r[0]=(BN_ULONG)ll&BN_MASK2;
+		ll>>=BN_BITS2;
+		a++; b++; r++; n--;
 		}
 	return((BN_ULONG)ll);
 	}
@@ -340,7 +346,8 @@
 	if (n <= 0) return((BN_ULONG)0);
 
 	c=0;
-	for (;;)
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (n&~3)
 		{
 		t=a[0];
 		t=(t+c)&BN_MASK2;
@@ -348,35 +355,36 @@
 		l=(t+b[0])&BN_MASK2;
 		c+=(l < t);
 		r[0]=l;
-		if (--n <= 0) break;
-
 		t=a[1];
 		t=(t+c)&BN_MASK2;
 		c=(t < c);
 		l=(t+b[1])&BN_MASK2;
 		c+=(l < t);
 		r[1]=l;
-		if (--n <= 0) break;
-
 		t=a[2];
 		t=(t+c)&BN_MASK2;
 		c=(t < c);
 		l=(t+b[2])&BN_MASK2;
 		c+=(l < t);
 		r[2]=l;
-		if (--n <= 0) break;
-
 		t=a[3];
 		t=(t+c)&BN_MASK2;
 		c=(t < c);
 		l=(t+b[3])&BN_MASK2;
 		c+=(l < t);
 		r[3]=l;
-		if (--n <= 0) break;
-
-		a+=4;
-		b+=4;
-		r+=4;
+		a+=4; b+=4; r+=4; n-=4;
+		}
+#endif
+	while(n)
+		{
+		t=a[0];
+		t=(t+c)&BN_MASK2;
+		c=(t < c);
+		l=(t+b[0])&BN_MASK2;
+		c+=(l < t);
+		r[0]=l;
+		a++; b++; r++; n--;
 		}
 	return((BN_ULONG)c);
 	}
@@ -390,36 +398,35 @@
 	assert(n >= 0);
 	if (n <= 0) return((BN_ULONG)0);
 
-	for (;;)
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (n&~3)
 		{
 		t1=a[0]; t2=b[0];
 		r[0]=(t1-t2-c)&BN_MASK2;
 		if (t1 != t2) c=(t1 < t2);
-		if (--n <= 0) break;
-
 		t1=a[1]; t2=b[1];
 		r[1]=(t1-t2-c)&BN_MASK2;
 		if (t1 != t2) c=(t1 < t2);
-		if (--n <= 0) break;
-
 		t1=a[2]; t2=b[2];
 		r[2]=(t1-t2-c)&BN_MASK2;
 		if (t1 != t2) c=(t1 < t2);
-		if (--n <= 0) break;
-
 		t1=a[3]; t2=b[3];
 		r[3]=(t1-t2-c)&BN_MASK2;
 		if (t1 != t2) c=(t1 < t2);
-		if (--n <= 0) break;
-
-		a+=4;
-		b+=4;
-		r+=4;
+		a+=4; b+=4; r+=4; n-=4;
+		}
+#endif
+	while (n)
+		{
+		t1=a[0]; t2=b[0];
+		r[0]=(t1-t2-c)&BN_MASK2;
+		if (t1 != t2) c=(t1 < t2);
+		a++; b++; r++; n--;
 		}
 	return(c);
 	}
 
-#ifdef BN_MUL_COMBA
+#if defined(BN_MUL_COMBA) && !defined(OPENSSL_SMALL_FOOTPRINT)
 
 #undef bn_mul_comba8
 #undef bn_mul_comba4
@@ -820,18 +827,134 @@
 	r[6]=c1;
 	r[7]=c2;
 	}
+
+#ifdef OPENSSL_NO_ASM
+#ifdef OPENSSL_BN_ASM_MONT
+#include <alloca.h>
+/*
+ * This is essentially reference implementation, which may or may not
+ * result in performance improvement. E.g. on IA-32 this routine was
+ * observed to give 40% faster rsa1024 private key operations and 10%
+ * faster rsa4096 ones, while on AMD64 it improves rsa1024 sign only
+ * by 10% and *worsens* rsa4096 sign by 15%. Once again, it's a
+ * reference implementation, one to be used as starting point for
+ * platform-specific assembler. Mentioned numbers apply to compiler
+ * generated code compiled with and without -DOPENSSL_BN_ASM_MONT and
+ * can vary not only from platform to platform, but even for compiler
+ * versions. Assembler vs. assembler improvement coefficients can
+ * [and are known to] differ and are to be documented elsewhere.
+ */
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0p, int num)
+	{
+	BN_ULONG c0,c1,ml,*tp,n0;
+#ifdef mul64
+	BN_ULONG mh;
+#endif
+	volatile BN_ULONG *vp;
+	int i=0,j;
+
+#if 0	/* template for platform-specific implementation */
+	if (ap==bp)	return bn_sqr_mont(rp,ap,np,n0p,num);
+#endif
+	vp = tp = alloca((num+2)*sizeof(BN_ULONG));
+
+	n0 = *n0p;
+
+	c0 = 0;
+	ml = bp[0];
+#ifdef mul64
+	mh = HBITS(ml);
+	ml = LBITS(ml);
+	for (j=0;j<num;++j)
+		mul(tp[j],ap[j],ml,mh,c0);
+#else
+	for (j=0;j<num;++j)
+		mul(tp[j],ap[j],ml,c0);
+#endif
+
+	tp[num]   = c0;
+	tp[num+1] = 0;
+	goto enter;
+
+	for(i=0;i<num;i++)
+		{
+		c0 = 0;
+		ml = bp[i];
+#ifdef mul64
+		mh = HBITS(ml);
+		ml = LBITS(ml);
+		for (j=0;j<num;++j)
+			mul_add(tp[j],ap[j],ml,mh,c0);
+#else
+		for (j=0;j<num;++j)
+			mul_add(tp[j],ap[j],ml,c0);
+#endif
+		c1 = (tp[num] + c0)&BN_MASK2;
+		tp[num]   = c1;
+		tp[num+1] = (c1<c0?1:0);
+	enter:
+		c1  = tp[0];
+		ml = (c1*n0)&BN_MASK2;
+		c0 = 0;
+#ifdef mul64
+		mh = HBITS(ml);
+		ml = LBITS(ml);
+		mul_add(c1,np[0],ml,mh,c0);
+#else
+		mul_add(c1,ml,np[0],c0);
+#endif
+		for(j=1;j<num;j++)
+			{
+			c1 = tp[j];
+#ifdef mul64
+			mul_add(c1,np[j],ml,mh,c0);
+#else
+			mul_add(c1,ml,np[j],c0);
+#endif
+			tp[j-1] = c1&BN_MASK2;
+			}
+		c1        = (tp[num] + c0)&BN_MASK2;
+		tp[num-1] = c1;
+		tp[num]   = tp[num+1] + (c1<c0?1:0);
+		}
+
+	if (tp[num]!=0 || tp[num-1]>=np[num-1])
+		{
+		c0 = bn_sub_words(rp,tp,np,num);
+		if (tp[num]!=0 || c0==0)
+			{
+			for(i=0;i<num+2;i++)	vp[i] = 0;
+			return 1;
+			}
+		}
+	for(i=0;i<num;i++)	rp[i] = tp[i],	vp[i] = 0;
+	vp[num]   = 0;
+	vp[num+1] = 0;
+	return 1;
+	}
+#else
+/*
+ * Return value of 0 indicates that multiplication/convolution was not
+ * performed to signal the caller to fall down to alternative/original
+ * code-path.
+ */
+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)
+{	return 0;	}
+#endif /* OPENSSL_BN_ASM_MONT */
+#endif
+
 #else /* !BN_MUL_COMBA */
 
 /* hmm... is it faster just to do a multiply? */
 #undef bn_sqr_comba4
-void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
+void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
 	{
 	BN_ULONG t[8];
 	bn_sqr_normal(r,a,4,t);
 	}
 
 #undef bn_sqr_comba8
-void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
+void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
 	{
 	BN_ULONG t[16];
 	bn_sqr_normal(r,a,8,t);
@@ -857,4 +980,51 @@
 	r[15]=bn_mul_add_words(&(r[7]),a,8,b[7]);
 	}
 
+#ifdef OPENSSL_NO_ASM
+#ifdef OPENSSL_BN_ASM_MONT
+#include <alloca.h>
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0p, int num)
+	{
+	BN_ULONG c0,c1,*tp,n0=*n0p;
+	volatile BN_ULONG *vp;
+	int i=0,j;
+
+	vp = tp = alloca((num+2)*sizeof(BN_ULONG));
+
+	for(i=0;i<=num;i++)	tp[i]=0;
+
+	for(i=0;i<num;i++)
+		{
+		c0         = bn_mul_add_words(tp,ap,num,bp[i]);
+		c1         = (tp[num] + c0)&BN_MASK2;
+		tp[num]    = c1;
+		tp[num+1]  = (c1<c0?1:0);
+
+		c0         = bn_mul_add_words(tp,np,num,tp[0]*n0);
+		c1         = (tp[num] + c0)&BN_MASK2;
+		tp[num]    = c1;
+		tp[num+1] += (c1<c0?1:0);
+		for(j=0;j<=num;j++)	tp[j]=tp[j+1];
+		}
+
+	if (tp[num]!=0 || tp[num-1]>=np[num-1])
+		{
+		c0 = bn_sub_words(rp,tp,np,num);
+		if (tp[num]!=0 || c0==0)
+			{
+			for(i=0;i<num+2;i++)	vp[i] = 0;
+			return 1;
+			}
+		}
+	for(i=0;i<num;i++)	rp[i] = tp[i],	vp[i] = 0;
+	vp[num]   = 0;
+	vp[num+1] = 0;
+	return 1;
+	}
+#else
+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)
+{	return 0;	}
+#endif /* OPENSSL_BN_ASM_MONT */
+#endif
+
 #endif /* !BN_MUL_COMBA */
diff --git a/crypto/bn/bn_blind.c b/crypto/bn/bn_blind.c
index c11fb4c..e060592 100644
--- a/crypto/bn/bn_blind.c
+++ b/crypto/bn/bn_blind.c
@@ -1,6 +1,6 @@
 /* crypto/bn/bn_blind.c */
 /* ====================================================================
- * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -121,8 +121,11 @@
 	BIGNUM *Ai;
 	BIGNUM *e;
 	BIGNUM *mod; /* just a reference */
+#ifndef OPENSSL_NO_DEPRECATED
 	unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b;
 				  * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */
+#endif
+	CRYPTO_THREADID tid;
 	unsigned int  counter;
 	unsigned long flags;
 	BN_MONT_CTX *m_ctx;
@@ -131,7 +134,7 @@
 			  BN_MONT_CTX *m_ctx);
 	};
 
-BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGNUM *mod)
+BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
 	{
 	BN_BLINDING *ret=NULL;
 
@@ -158,6 +161,7 @@
 		BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
 
 	ret->counter = BN_BLINDING_COUNTER;
+	CRYPTO_THREADID_current(&ret->tid);
 	return(ret);
 err:
 	if (ret != NULL) BN_BLINDING_free(ret);
@@ -263,6 +267,7 @@
 	return(ret);
 	}
 
+#ifndef OPENSSL_NO_DEPRECATED
 unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b)
 	{
 	return b->thread_id;
@@ -272,6 +277,12 @@
 	{
 	b->thread_id = n;
 	}
+#endif
+
+CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *b)
+	{
+	return &b->tid;
+	}
 
 unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b)
 	{
@@ -284,7 +295,7 @@
 	}
 
 BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
-	const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx,
+	const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
 	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
 			  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
 	BN_MONT_CTX *m_ctx)
diff --git a/crypto/bn/bn_ctx.c b/crypto/bn/bn_ctx.c
index b3452f1..3f2256f 100644
--- a/crypto/bn/bn_ctx.c
+++ b/crypto/bn/bn_ctx.c
@@ -161,7 +161,7 @@
 	fprintf(stderr,"(%08x): ", (unsigned int)ctx);
 	while(bnidx < ctx->used)
 		{
-		fprintf(stderr,"%02x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax);
+		fprintf(stderr,"%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax);
 		if(!(bnidx % BN_CTX_POOL_SIZE))
 			item = item->next;
 		}
@@ -171,8 +171,8 @@
 	while(fpidx < stack->depth)
 		{
 		while(bnidx++ < stack->indexes[fpidx])
-			fprintf(stderr,"   ");
-		fprintf(stderr,"^^ ");
+			fprintf(stderr,"    ");
+		fprintf(stderr,"^^^ ");
 		bnidx++;
 		fpidx++;
 		}
diff --git a/crypto/bn/bn_div.c b/crypto/bn/bn_div.c
index 7c35545..802a43d 100644
--- a/crypto/bn/bn_div.c
+++ b/crypto/bn/bn_div.c
@@ -337,7 +337,7 @@
 				t2 -= d1;
 				}
 #else /* !BN_LLONG */
-			BN_ULONG t2l,t2h,ql,qh;
+			BN_ULONG t2l,t2h;
 
 			q=bn_div_words(n0,n1,d0);
 #ifdef BN_DEBUG_LEVITTE
@@ -355,9 +355,12 @@
 			t2l = d1 * q;
 			t2h = BN_UMULT_HIGH(d1,q);
 #else
+			{
+			BN_ULONG ql, qh;
 			t2l=LBITS(d1); t2h=HBITS(d1);
 			ql =LBITS(q);  qh =HBITS(q);
 			mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
+			}
 #endif
 
 			for (;;)
@@ -561,7 +564,7 @@
 				t2 -= d1;
 				}
 #else /* !BN_LLONG */
-			BN_ULONG t2l,t2h,ql,qh;
+			BN_ULONG t2l,t2h;
 
 			q=bn_div_words(n0,n1,d0);
 #ifdef BN_DEBUG_LEVITTE
@@ -579,9 +582,12 @@
 			t2l = d1 * q;
 			t2h = BN_UMULT_HIGH(d1,q);
 #else
+			{
+			BN_ULONG ql, qh;
 			t2l=LBITS(d1); t2h=HBITS(d1);
 			ql =LBITS(q);  qh =HBITS(q);
 			mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
+			}
 #endif
 
 			for (;;)
diff --git a/crypto/bn/bn_gf2m.c b/crypto/bn/bn_gf2m.c
index ae642cc..527b0fa 100644
--- a/crypto/bn/bn_gf2m.c
+++ b/crypto/bn/bn_gf2m.c
@@ -121,74 +121,12 @@
     SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >>  8 & 0xF] << 16 | \
     SQR_tb[(w) >>  4 & 0xF] <<  8 | SQR_tb[(w)       & 0xF]
 #endif
-#ifdef SIXTEEN_BIT
-#define SQR1(w) \
-    SQR_tb[(w) >> 12 & 0xF] <<  8 | SQR_tb[(w) >>  8 & 0xF]
-#define SQR0(w) \
-    SQR_tb[(w) >>  4 & 0xF] <<  8 | SQR_tb[(w)       & 0xF]
-#endif
-#ifdef EIGHT_BIT
-#define SQR1(w) \
-    SQR_tb[(w) >>  4 & 0xF]
-#define SQR0(w) \
-    SQR_tb[(w)       & 15]
-#endif
 
 /* Product of two polynomials a, b each with degree < BN_BITS2 - 1,
  * result is a polynomial r with degree < 2 * BN_BITS - 1
  * The caller MUST ensure that the variables have the right amount
  * of space allocated.
  */
-#ifdef EIGHT_BIT
-static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b)
-	{
-	register BN_ULONG h, l, s;
-	BN_ULONG tab[4], top1b = a >> 7;
-	register BN_ULONG a1, a2;
-
-	a1 = a & (0x7F); a2 = a1 << 1;
-
-	tab[0] = 0; tab[1] = a1; tab[2] = a2; tab[3] = a1^a2;
-
-	s = tab[b      & 0x3]; l  = s;
-	s = tab[b >> 2 & 0x3]; l ^= s << 2; h  = s >> 6;
-	s = tab[b >> 4 & 0x3]; l ^= s << 4; h ^= s >> 4;
-	s = tab[b >> 6      ]; l ^= s << 6; h ^= s >> 2;
-	
-	/* compensate for the top bit of a */
-
-	if (top1b & 01) { l ^= b << 7; h ^= b >> 1; } 
-
-	*r1 = h; *r0 = l;
-	} 
-#endif
-#ifdef SIXTEEN_BIT
-static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b)
-	{
-	register BN_ULONG h, l, s;
-	BN_ULONG tab[4], top1b = a >> 15; 
-	register BN_ULONG a1, a2;
-
-	a1 = a & (0x7FFF); a2 = a1 << 1;
-
-	tab[0] = 0; tab[1] = a1; tab[2] = a2; tab[3] = a1^a2;
-
-	s = tab[b      & 0x3]; l  = s;
-	s = tab[b >> 2 & 0x3]; l ^= s <<  2; h  = s >> 14;
-	s = tab[b >> 4 & 0x3]; l ^= s <<  4; h ^= s >> 12;
-	s = tab[b >> 6 & 0x3]; l ^= s <<  6; h ^= s >> 10;
-	s = tab[b >> 8 & 0x3]; l ^= s <<  8; h ^= s >>  8;
-	s = tab[b >>10 & 0x3]; l ^= s << 10; h ^= s >>  6;
-	s = tab[b >>12 & 0x3]; l ^= s << 12; h ^= s >>  4;
-	s = tab[b >>14      ]; l ^= s << 14; h ^= s >>  2;
-
-	/* compensate for the top bit of a */
-
-	if (top1b & 01) { l ^= b << 15; h ^= b >> 1; } 
-
-	*r1 = h; *r0 = l;
-	} 
-#endif
 #ifdef THIRTY_TWO_BIT
 static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b)
 	{
@@ -321,7 +259,7 @@
 
 
 /* Performs modular reduction of a and store result in r.  r could be a. */
-int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[])
+int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[])
 	{
 	int j, k;
 	int n, dN, d0, d1;
@@ -422,11 +360,11 @@
 int	BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p)
 	{
 	int ret = 0;
-	const int max = BN_num_bits(p);
-	unsigned int *arr=NULL;
+	const int max = BN_num_bits(p) + 1;
+	int *arr=NULL;
 	bn_check_top(a);
 	bn_check_top(p);
-	if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
+	if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
 	ret = BN_GF2m_poly2arr(p, arr, max);
 	if (!ret || ret > max)
 		{
@@ -444,7 +382,7 @@
 /* Compute the product of two polynomials a and b, reduce modulo p, and store
  * the result in r.  r could be a or b; a could be b.
  */
-int	BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsigned int p[], BN_CTX *ctx)
+int	BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p[], BN_CTX *ctx)
 	{
 	int zlen, i, j, k, ret = 0;
 	BIGNUM *s;
@@ -500,12 +438,12 @@
 int	BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx)
 	{
 	int ret = 0;
-	const int max = BN_num_bits(p);
-	unsigned int *arr=NULL;
+	const int max = BN_num_bits(p) + 1;
+	int *arr=NULL;
 	bn_check_top(a);
 	bn_check_top(b);
 	bn_check_top(p);
-	if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
+	if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
 	ret = BN_GF2m_poly2arr(p, arr, max);
 	if (!ret || ret > max)
 		{
@@ -521,7 +459,7 @@
 
 
 /* Square a, reduce the result mod p, and store it in a.  r could be a. */
-int	BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_CTX *ctx)
+int	BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], BN_CTX *ctx)
 	{
 	int i, ret = 0;
 	BIGNUM *s;
@@ -556,12 +494,12 @@
 int	BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
 	{
 	int ret = 0;
-	const int max = BN_num_bits(p);
-	unsigned int *arr=NULL;
+	const int max = BN_num_bits(p) + 1;
+	int *arr=NULL;
 
 	bn_check_top(a);
 	bn_check_top(p);
-	if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
+	if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
 	ret = BN_GF2m_poly2arr(p, arr, max);
 	if (!ret || ret > max)
 		{
@@ -643,7 +581,7 @@
  * function is only provided for convenience; for best performance, use the 
  * BN_GF2m_mod_inv function.
  */
-int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const unsigned int p[], BN_CTX *ctx)
+int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const int p[], BN_CTX *ctx)
 	{
 	BIGNUM *field;
 	int ret = 0;
@@ -769,7 +707,7 @@
  * function is only provided for convenience; for best performance, use the 
  * BN_GF2m_mod_div function.
  */
-int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx, const unsigned int p[], BN_CTX *ctx)
+int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx, const int p[], BN_CTX *ctx)
 	{
 	BIGNUM *field;
 	int ret = 0;
@@ -794,7 +732,7 @@
  * the result in r.  r could be a.
  * Uses simple square-and-multiply algorithm A.5.1 from IEEE P1363.
  */
-int	BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsigned int p[], BN_CTX *ctx)
+int	BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p[], BN_CTX *ctx)
 	{
 	int ret = 0, i, n;
 	BIGNUM *u;
@@ -840,12 +778,12 @@
 int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx)
 	{
 	int ret = 0;
-	const int max = BN_num_bits(p);
-	unsigned int *arr=NULL;
+	const int max = BN_num_bits(p) + 1;
+	int *arr=NULL;
 	bn_check_top(a);
 	bn_check_top(b);
 	bn_check_top(p);
-	if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
+	if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
 	ret = BN_GF2m_poly2arr(p, arr, max);
 	if (!ret || ret > max)
 		{
@@ -863,7 +801,7 @@
  * the result in r.  r could be a.
  * Uses exponentiation as in algorithm A.4.1 from IEEE P1363.
  */
-int	BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_CTX *ctx)
+int	BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const int p[], BN_CTX *ctx)
 	{
 	int ret = 0;
 	BIGNUM *u;
@@ -899,11 +837,11 @@
 int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
 	{
 	int ret = 0;
-	const int max = BN_num_bits(p);
-	unsigned int *arr=NULL;
+	const int max = BN_num_bits(p) + 1;
+	int *arr=NULL;
 	bn_check_top(a);
 	bn_check_top(p);
-	if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
+	if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err;
 	ret = BN_GF2m_poly2arr(p, arr, max);
 	if (!ret || ret > max)
 		{
@@ -920,10 +858,9 @@
 /* Find r such that r^2 + r = a mod p.  r could be a. If no r exists returns 0.
  * Uses algorithms A.4.7 and A.4.6 from IEEE P1363.
  */
-int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const unsigned int p[], BN_CTX *ctx)
+int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[], BN_CTX *ctx)
 	{
-	int ret = 0, count = 0;
-	unsigned int j;
+	int ret = 0, count = 0, j;
 	BIGNUM *a, *z, *rho, *w, *w2, *tmp;
 
 	bn_check_top(a_);
@@ -1018,11 +955,11 @@
 int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
 	{
 	int ret = 0;
-	const int max = BN_num_bits(p);
-	unsigned int *arr=NULL;
+	const int max = BN_num_bits(p) + 1;
+	int *arr=NULL;
 	bn_check_top(a);
 	bn_check_top(p);
-	if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) *
+	if ((arr = (int *)OPENSSL_malloc(sizeof(int) *
 						max)) == NULL) goto err;
 	ret = BN_GF2m_poly2arr(p, arr, max);
 	if (!ret || ret > max)
@@ -1038,20 +975,17 @@
 	}
 
 /* Convert the bit-string representation of a polynomial
- * ( \sum_{i=0}^n a_i * x^i , where a_0 is *not* zero) into an array
- * of integers corresponding to the bits with non-zero coefficient.
+ * ( \sum_{i=0}^n a_i * x^i) into an array of integers corresponding 
+ * to the bits with non-zero coefficient.  Array is terminated with -1.
  * Up to max elements of the array will be filled.  Return value is total
- * number of coefficients that would be extracted if array was large enough.
+ * number of array elements that would be filled if array was large enough.
  */
-int BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max)
+int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max)
 	{
 	int i, j, k = 0;
 	BN_ULONG mask;
 
-	if (BN_is_zero(a) || !BN_is_bit_set(a, 0))
-		/* a_0 == 0 => return error (the unsigned int array
-		 * must be terminated by 0)
-		 */
+	if (BN_is_zero(a))
 		return 0;
 
 	for (i = a->top - 1; i >= 0; i--)
@@ -1071,24 +1005,28 @@
 			}
 		}
 
+	if (k < max) {
+		p[k] = -1;
+		k++;
+	}
+
 	return k;
 	}
 
 /* Convert the coefficient array representation of a polynomial to a 
- * bit-string.  The array must be terminated by 0.
+ * bit-string.  The array must be terminated by -1.
  */
-int BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a)
+int BN_GF2m_arr2poly(const int p[], BIGNUM *a)
 	{
 	int i;
 
 	bn_check_top(a);
 	BN_zero(a);
-	for (i = 0; p[i] != 0; i++)
+	for (i = 0; p[i] != -1; i++)
 		{
 		if (BN_set_bit(a, p[i]) == 0)
 			return 0;
 		}
-	BN_set_bit(a, 0);
 	bn_check_top(a);
 
 	return 1;
diff --git a/crypto/bn/bn_lcl.h b/crypto/bn/bn_lcl.h
index 27ac439..8e5e98e 100644
--- a/crypto/bn/bn_lcl.h
+++ b/crypto/bn/bn_lcl.h
@@ -255,7 +255,8 @@
 	     : "r"(a), "r"(b));		\
 	ret;			})
 #  endif	/* compiler */
-# elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG)
+# elif (defined(__x86_64) || defined(__x86_64__)) && \
+       (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
 #  if defined(__GNUC__)
 #   define BN_UMULT_HIGH(a,b)	({	\
 	register BN_ULONG ret,discard;	\
diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c
index 32a8fba..5470fbe 100644
--- a/crypto/bn/bn_lib.c
+++ b/crypto/bn/bn_lib.c
@@ -133,15 +133,34 @@
 
 const BIGNUM *BN_value_one(void)
 	{
-	static BN_ULONG data_one=1L;
-	static BIGNUM const_one={&data_one,1,1,0,BN_FLG_STATIC_DATA};
+	static const BN_ULONG data_one=1L;
+	static const BIGNUM const_one={(BN_ULONG *)&data_one,1,1,0,BN_FLG_STATIC_DATA};
 
 	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]={
+	static const unsigned char bits[256]={
 		0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
 		5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
 		6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
@@ -216,7 +235,7 @@
 		else
 #endif
 			{
-#if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
 			if (l & 0xff00L)
 				return(bits[(int)(l>>8)]+8);
 			else	
@@ -744,7 +763,7 @@
 	i=n/BN_BITS2;
 	j=n%BN_BITS2;
 	if (a->top <= i) return 0;
-	return(((a->d[i])>>j)&((BN_ULONG)1));
+	return (int)(((a->d[i])>>j)&((BN_ULONG)1));
 	}
 
 int BN_mask_bits(BIGNUM *a, int n)
diff --git a/crypto/bn/bn_mont.c b/crypto/bn/bn_mont.c
index 4799b15..7224637 100644
--- a/crypto/bn/bn_mont.c
+++ b/crypto/bn/bn_mont.c
@@ -122,26 +122,10 @@
 
 #define MONT_WORD /* use the faster word-based algorithm */
 
-#if defined(MONT_WORD) && defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)
-/* This condition means we have a specific non-default build:
- * In the 0.9.8 branch, OPENSSL_BN_ASM_MONT is normally not set for any
- * BN_BITS2<=32 platform; an explicit "enable-montasm" is required.
- * I.e., if we are here, the user intentionally deviates from the
- * normal stable build to get better Montgomery performance from
- * the 0.9.9-dev backport.
- *
- * In this case only, we also enable BN_from_montgomery_word()
- * (another non-stable feature from 0.9.9-dev).
- */
-#define MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD
-#endif
-
-#ifdef MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD
+#ifdef MONT_WORD
 static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
 #endif
 
-
-
 int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
 			  BN_MONT_CTX *mont, BN_CTX *ctx)
 	{
@@ -153,11 +137,7 @@
 	if (num>1 && a->top==num && b->top==num)
 		{
 		if (bn_wexpand(r,num) == NULL) return(0);
-#if 0 /* for OpenSSL 0.9.9 mont->n0 */
 		if (bn_mul_mont(r->d,a->d,b->d,mont->N.d,mont->n0,num))
-#else
-		if (bn_mul_mont(r->d,a->d,b->d,mont->N.d,&mont->n0,num))
-#endif
 			{
 			r->neg = a->neg^b->neg;
 			r->top = num;
@@ -181,7 +161,7 @@
 		if (!BN_mul(tmp,a,b,ctx)) goto err;
 		}
 	/* reduce from aRR to aR */
-#ifdef MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD
+#ifdef MONT_WORD
 	if (!BN_from_montgomery_word(r,tmp,mont)) goto err;
 #else
 	if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err;
@@ -193,7 +173,7 @@
 	return(ret);
 	}
 
-#ifdef MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD
+#ifdef MONT_WORD
 static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
 	{
 	BIGNUM *n;
@@ -217,15 +197,15 @@
 	nrp= &(r->d[nl]);
 
 	/* clear the top words of T */
+#if 1
 	for (i=r->top; i<max; i++) /* memset? XXX */
 		r->d[i]=0;
+#else
+	memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); 
+#endif
 
 	r->top=max;
-#if 0 /* for OpenSSL 0.9.9 mont->n0 */
 	n0=mont->n0[0];
-#else
-	n0=mont->n0;
-#endif
 
 #ifdef BN_COUNT
 	fprintf(stderr,"word BN_from_montgomery_word %d * %d\n",nl,nl);
@@ -270,6 +250,8 @@
 		}
 	al=r->top-ri;
 
+#define BRANCH_FREE 1
+#if BRANCH_FREE
 	if (bn_wexpand(ret,ri) == NULL) return(0);
 	x=0-(((al-ri)>>(sizeof(al)*8-1))&1);
 	ret->top=x=(ri&~x)|(al&x);	/* min(ri,al) */
@@ -317,164 +299,8 @@
 		rp[i]=nrp[i], ap[i]=0;
 	bn_correct_top(r);
 	bn_correct_top(ret);
-	bn_check_top(ret);
-
-	return(1);
-	}
-
-int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
-	     BN_CTX *ctx)
-	{
-	int retn=0;
-	BIGNUM *t;
-
-	BN_CTX_start(ctx);
-	if ((t = BN_CTX_get(ctx)) && BN_copy(t,a))
-		retn = BN_from_montgomery_word(ret,t,mont);
-	BN_CTX_end(ctx);
-	return retn;
-	}
-
-#else /* !MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD */
-
-int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
-	     BN_CTX *ctx)
-	{
-	int retn=0;
-
-#ifdef MONT_WORD
-	BIGNUM *n,*r;
-	BN_ULONG *ap,*np,*rp,n0,v,*nrp;
-	int al,nl,max,i,x,ri;
-
-	BN_CTX_start(ctx);
-	if ((r = BN_CTX_get(ctx)) == NULL) goto err;
-
-	if (!BN_copy(r,a)) goto err;
-	n= &(mont->N);
-
-	ap=a->d;
-	/* mont->ri is the size of mont->N in bits (rounded up
-	   to the word size) */
-	al=ri=mont->ri/BN_BITS2;
-	
-	nl=n->top;
-	if ((al == 0) || (nl == 0)) { r->top=0; return(1); }
-
-	max=(nl+al+1); /* allow for overflow (no?) XXX */
-	if (bn_wexpand(r,max) == NULL) goto err;
-
-	r->neg=a->neg^n->neg;
-	np=n->d;
-	rp=r->d;
-	nrp= &(r->d[nl]);
-
-	/* clear the top words of T */
-#if 1
-	for (i=r->top; i<max; i++) /* memset? XXX */
-		r->d[i]=0;
 #else
-	memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); 
-#endif
-
-	r->top=max;
-	n0=mont->n0;
-
-#ifdef BN_COUNT
-	fprintf(stderr,"word BN_from_montgomery %d * %d\n",nl,nl);
-#endif
-	for (i=0; i<nl; i++)
-		{
-#ifdef __TANDEM
-                {
-                   long long t1;
-                   long long t2;
-                   long long t3;
-                   t1 = rp[0] * (n0 & 0177777);
-                   t2 = 037777600000l;
-                   t2 = n0 & t2;
-                   t3 = rp[0] & 0177777;
-                   t2 = (t3 * t2) & BN_MASK2;
-                   t1 = t1 + t2;
-                   v=bn_mul_add_words(rp,np,nl,(BN_ULONG) t1);
-                }
-#else
-		v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
-#endif
-		nrp++;
-		rp++;
-		if (((nrp[-1]+=v)&BN_MASK2) >= v)
-			continue;
-		else
-			{
-			if (((++nrp[0])&BN_MASK2) != 0) continue;
-			if (((++nrp[1])&BN_MASK2) != 0) continue;
-			for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ;
-			}
-		}
-	bn_correct_top(r);
-	
-	/* mont->ri will be a multiple of the word size and below code
-	 * is kind of BN_rshift(ret,r,mont->ri) equivalent */
-	if (r->top <= ri)
-		{
-		ret->top=0;
-		retn=1;
-		goto err;
-		}
-	al=r->top-ri;
-
-# define BRANCH_FREE 1
-# if BRANCH_FREE
-	if (bn_wexpand(ret,ri) == NULL) goto err;
-	x=0-(((al-ri)>>(sizeof(al)*8-1))&1);
-	ret->top=x=(ri&~x)|(al&x);	/* min(ri,al) */
-	ret->neg=r->neg;
-
-	rp=ret->d;
-	ap=&(r->d[ri]);
-
-	{
-	size_t m1,m2;
-
-	v=bn_sub_words(rp,ap,np,ri);
-	/* this ----------------^^ works even in al<ri case
-	 * thanks to zealous zeroing of top of the vector in the
-	 * beginning. */
-
-	/* if (al==ri && !v) || al>ri) nrp=rp; else nrp=ap; */
-	/* in other words if subtraction result is real, then
-	 * trick unconditional memcpy below to perform in-place
-	 * "refresh" instead of actual copy. */
-	m1=0-(size_t)(((al-ri)>>(sizeof(al)*8-1))&1);	/* al<ri */
-	m2=0-(size_t)(((ri-al)>>(sizeof(al)*8-1))&1);	/* al>ri */
-	m1|=m2;			/* (al!=ri) */
-	m1|=(0-(size_t)v);	/* (al!=ri || v) */
-	m1&=~m2;		/* (al!=ri || v) && !al>ri */
-	nrp=(BN_ULONG *)(((size_t)rp&~m1)|((size_t)ap&m1));
-	}
-
-	/* 'i<ri' is chosen to eliminate dependency on input data, even
-	 * though it results in redundant copy in al<ri case. */
-	for (i=0,ri-=4; i<ri; i+=4)
-		{
-		BN_ULONG t1,t2,t3,t4;
-		
-		t1=nrp[i+0];
-		t2=nrp[i+1];
-		t3=nrp[i+2];	ap[i+0]=0;
-		t4=nrp[i+3];	ap[i+1]=0;
-		rp[i+0]=t1;	ap[i+2]=0;
-		rp[i+1]=t2;	ap[i+3]=0;
-		rp[i+2]=t3;
-		rp[i+3]=t4;
-		}
-	for (ri+=4; i<ri; i++)
-		rp[i]=nrp[i], ap[i]=0;
-	bn_correct_top(r);
-	bn_correct_top(ret);
-# else
-	if (bn_wexpand(ret,al) == NULL) goto err;
+	if (bn_wexpand(ret,al) == NULL) return(0);
 	ret->top=al;
 	ret->neg=r->neg;
 
@@ -497,8 +323,30 @@
 	al+=4;
 	for (; i<al; i++)
 		rp[i]=ap[i];
-# endif
-#else /* !MONT_WORD */ 
+
+	if (BN_ucmp(ret, &(mont->N)) >= 0)
+		{
+		if (!BN_usub(ret,ret,&(mont->N))) return(0);
+		}
+#endif
+	bn_check_top(ret);
+
+	return(1);
+	}
+#endif	/* MONT_WORD */
+
+int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
+	     BN_CTX *ctx)
+	{
+	int retn=0;
+#ifdef MONT_WORD
+	BIGNUM *t;
+
+	BN_CTX_start(ctx);
+	if ((t = BN_CTX_get(ctx)) && BN_copy(t,a))
+		retn = BN_from_montgomery_word(ret,t,mont);
+	BN_CTX_end(ctx);
+#else /* !MONT_WORD */
 	BIGNUM *t1,*t2;
 
 	BN_CTX_start(ctx);
@@ -515,21 +363,18 @@
 	if (!BN_mul(t1,t2,&mont->N,ctx)) goto err;
 	if (!BN_add(t2,a,t1)) goto err;
 	if (!BN_rshift(ret,t2,mont->ri)) goto err;
-#endif /* MONT_WORD */
 
-#if !defined(BRANCH_FREE) || BRANCH_FREE==0
 	if (BN_ucmp(ret, &(mont->N)) >= 0)
 		{
 		if (!BN_usub(ret,ret,&(mont->N))) goto err;
 		}
-#endif
 	retn=1;
 	bn_check_top(ret);
  err:
 	BN_CTX_end(ctx);
+#endif /* MONT_WORD */
 	return(retn);
 	}
-#endif /* MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD */
 
 BN_MONT_CTX *BN_MONT_CTX_new(void)
 	{
@@ -549,11 +394,7 @@
 	BN_init(&(ctx->RR));
 	BN_init(&(ctx->N));
 	BN_init(&(ctx->Ni));
-#if 0 /* for OpenSSL 0.9.9 mont->n0 */
 	ctx->n0[0] = ctx->n0[1] = 0;
-#else
-	ctx->n0 = 0;
-#endif
 	ctx->flags=0;
 	}
 
@@ -585,26 +426,22 @@
 		BIGNUM tmod;
 		BN_ULONG buf[2];
 
-		mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
-		BN_zero(R);
-#if 0 /* for OpenSSL 0.9.9 mont->n0, would be "#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)",
-         only certain BN_BITS2<=32 platforms actually need this */
-		if (!(BN_set_bit(R,2*BN_BITS2))) goto err;	/* R */
-#else
-		if (!(BN_set_bit(R,BN_BITS2))) goto err;	/* R */
-#endif
-
-		buf[0]=mod->d[0]; /* tmod = N mod word size */
-		buf[1]=0;
-
 		BN_init(&tmod);
 		tmod.d=buf;
-		tmod.top = buf[0] != 0 ? 1 : 0;
 		tmod.dmax=2;
 		tmod.neg=0;
 
-#if 0 /* for OpenSSL 0.9.9 mont->n0, would be "#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)";
-         only certain BN_BITS2<=32 platforms actually need this */
+		mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
+
+#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)
+		/* Only certain BN_BITS2<=32 platforms actually make use of
+		 * n0[1], and we could use the #else case (with a shorter R
+		 * value) for the others.  However, currently only the assembler
+		 * files do know which is which. */
+
+		BN_zero(R);
+		if (!(BN_set_bit(R,2*BN_BITS2))) goto err;
+
 								tmod.top=0;
 		if ((buf[0] = mod->d[0]))			tmod.top=1;
 		if ((buf[1] = mod->top>1 ? mod->d[1] : 0))	tmod.top=2;
@@ -632,6 +469,12 @@
 		mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
 		mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0;
 #else
+		BN_zero(R);
+		if (!(BN_set_bit(R,BN_BITS2))) goto err;	/* R */
+
+		buf[0]=mod->d[0]; /* tmod = N mod word size */
+		buf[1]=0;
+		tmod.top = buf[0] != 0 ? 1 : 0;
 							/* Ri = R^-1 mod N*/
 		if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL)
 			goto err;
@@ -647,12 +490,8 @@
 		if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err;
 		/* Ni = (R*Ri-1)/N,
 		 * keep only least significant word: */
-# if 0 /* for OpenSSL 0.9.9 mont->n0 */
 		mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
 		mont->n0[1] = 0;
-# else
-		mont->n0 = (Ri->top > 0) ? Ri->d[0] : 0;
-# endif
 #endif
 		}
 #else /* !MONT_WORD */
@@ -689,12 +528,8 @@
 	if (!BN_copy(&(to->N),&(from->N))) return NULL;
 	if (!BN_copy(&(to->Ni),&(from->Ni))) return NULL;
 	to->ri=from->ri;
-#if 0 /* for OpenSSL 0.9.9 mont->n0 */
 	to->n0[0]=from->n0[0];
 	to->n0[1]=from->n0[1];
-#else
-	to->n0=from->n0;
-#endif
 	return(to);
 	}
 
diff --git a/crypto/bn/bn_opt.c b/crypto/bn/bn_opt.c
deleted file mode 100644
index 21cbb38..0000000
--- a/crypto/bn/bn_opt.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* crypto/bn/bn_opt.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#ifndef BN_DEBUG
-# undef NDEBUG /* avoid conflicting definitions */
-# define NDEBUG
-#endif
-
-#include <assert.h>
-#include <limits.h>
-#include <stdio.h>
-#include "cryptlib.h"
-#include "bn_lcl.h"
-
-char *BN_options(void)
-	{
-	static int init=0;
-	static char data[16];
-
-	if (!init)
-		{
-		init++;
-#ifdef BN_LLONG
-		BIO_snprintf(data,sizeof data,"bn(%d,%d)",
-			     (int)sizeof(BN_ULLONG)*8,(int)sizeof(BN_ULONG)*8);
-#else
-		BIO_snprintf(data,sizeof data,"bn(%d,%d)",
-			     (int)sizeof(BN_ULONG)*8,(int)sizeof(BN_ULONG)*8);
-#endif
-		}
-	return(data);
-	}
diff --git a/crypto/bn/bn_print.c b/crypto/bn/bn_print.c
index 810dde3..bebb466 100644
--- a/crypto/bn/bn_print.c
+++ b/crypto/bn/bn_print.c
@@ -294,6 +294,27 @@
 	return(0);
 	}
 
+int BN_asc2bn(BIGNUM **bn, const char *a)
+	{
+	const char *p = a;
+	if (*p == '-')
+		p++;
+
+	if (p[0] == '0' && (p[1] == 'X' || p[1] == 'x'))
+		{		
+		if (!BN_hex2bn(bn, p + 2))
+			return 0;
+		}
+	else
+		{
+		if (!BN_dec2bn(bn, p))
+			return 0;
+		}
+	if (*a == '-')
+		(*bn)->neg = 1;
+	return 1;
+	}
+
 #ifndef OPENSSL_NO_BIO
 #ifndef OPENSSL_NO_FP_API
 int BN_print_fp(FILE *fp, const BIGNUM *a)
diff --git a/crypto/bn/bn_x931p.c b/crypto/bn/bn_x931p.c
deleted file mode 100644
index 04c5c87..0000000
--- a/crypto/bn/bn_x931p.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/* bn_x931p.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2005.
- */
-/* ====================================================================
- * Copyright (c) 2005 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#include <stdio.h>
-#include <openssl/bn.h>
-
-/* X9.31 routines for prime derivation */
-
-/* X9.31 prime derivation. This is used to generate the primes pi
- * (p1, p2, q1, q2) from a parameter Xpi by checking successive odd
- * integers.
- */
-
-static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx,
-			BN_GENCB *cb)
-	{
-	int i = 0;
-	if (!BN_copy(pi, Xpi))
-		return 0;
-	if (!BN_is_odd(pi) && !BN_add_word(pi, 1))
-		return 0;
-	for(;;)
-		{
-		i++;
-		BN_GENCB_call(cb, 0, i);
-		/* NB 27 MR is specificed in X9.31 */
-		if (BN_is_prime_fasttest_ex(pi, 27, ctx, 1, cb))
-			break;
-		if (!BN_add_word(pi, 2))
-			return 0;
-		}
-	BN_GENCB_call(cb, 2, i);
-	return 1;
-	}
-
-/* This is the main X9.31 prime derivation function. From parameters
- * Xp1, Xp2 and Xp derive the prime p. If the parameters p1 or p2 are
- * not NULL they will be returned too: this is needed for testing.
- */
-
-int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
-			const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2,
-			const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb)
-	{
-	int ret = 0;
-
-	BIGNUM *t, *p1p2, *pm1;
-
-	/* Only even e supported */
-	if (!BN_is_odd(e))
-		return 0;
-
-	BN_CTX_start(ctx);
-	if (!p1)
-		p1 = BN_CTX_get(ctx);
-
-	if (!p2)
-		p2 = BN_CTX_get(ctx);
-
-	t = BN_CTX_get(ctx);
-
-	p1p2 = BN_CTX_get(ctx);
-
-	pm1 = BN_CTX_get(ctx);
-
-	if (!bn_x931_derive_pi(p1, Xp1, ctx, cb))
-		goto err;
-
-	if (!bn_x931_derive_pi(p2, Xp2, ctx, cb))
-		goto err;
-
-	if (!BN_mul(p1p2, p1, p2, ctx))
-		goto err;
-
-	/* First set p to value of Rp */
-
-	if (!BN_mod_inverse(p, p2, p1, ctx))
-		goto err;
-
-	if (!BN_mul(p, p, p2, ctx))
-		goto err;
-
-	if (!BN_mod_inverse(t, p1, p2, ctx))
-		goto err;
-
-	if (!BN_mul(t, t, p1, ctx))
-		goto err;
-
-	if (!BN_sub(p, p, t))
-		goto err;
-
-	if (p->neg && !BN_add(p, p, p1p2))
-		goto err;
-
-	/* p now equals Rp */
-
-	if (!BN_mod_sub(p, p, Xp, p1p2, ctx))
-		goto err;
-
-	if (!BN_add(p, p, Xp))
-		goto err;
-
-	/* p now equals Yp0 */
-
-	for (;;)
-		{
-		int i = 1;
-		BN_GENCB_call(cb, 0, i++);
-		if (!BN_copy(pm1, p))
-			goto err;
-		if (!BN_sub_word(pm1, 1))
-			goto err;
-		if (!BN_gcd(t, pm1, e, ctx))
-			goto err;
-		if (BN_is_one(t)
-		/* X9.31 specifies 8 MR and 1 Lucas test or any prime test
-		 * offering similar or better guarantees 50 MR is considerably 
-		 * better.
-		 */
-			&& BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb))
-			break;
-		if (!BN_add(p, p, p1p2))
-			goto err;
-		}
-
-	BN_GENCB_call(cb, 3, 0);
-
-	ret = 1;
-
-	err:
-
-	BN_CTX_end(ctx);
-
-	return ret;
-	}
-
-/* Generate pair of paramters Xp, Xq for X9.31 prime generation.
- * Note: nbits paramter is sum of number of bits in both.
- */
-
-int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx)
-	{
-	BIGNUM *t;
-	int i;
-	/* Number of bits for each prime is of the form
-	 * 512+128s for s = 0, 1, ...
-	 */
-	if ((nbits < 1024) || (nbits & 0xff))
-		return 0;
-	nbits >>= 1;
-	/* The random value Xp must be between sqrt(2) * 2^(nbits-1) and
-	 * 2^nbits - 1. By setting the top two bits we ensure that the lower
-	 * bound is exceeded.
-	 */
-	if (!BN_rand(Xp, nbits, 1, 0))
-		return 0;
-
-	BN_CTX_start(ctx);
-	t = BN_CTX_get(ctx);
-
-	for (i = 0; i < 1000; i++)
-		{
-		if (!BN_rand(Xq, nbits, 1, 0))
-			return 0;
-		/* Check that |Xp - Xq| > 2^(nbits - 100) */
-		BN_sub(t, Xp, Xq);
-		if (BN_num_bits(t) > (nbits - 100))
-			break;
-		}
-
-	BN_CTX_end(ctx);
-
-	if (i < 1000)
-		return 1;
-
-	return 0;
-
-	}
-
-/* Generate primes using X9.31 algorithm. Of the values p, p1, p2, Xp1
- * and Xp2 only 'p' needs to be non-NULL. If any of the others are not NULL
- * the relevant parameter will be stored in it.
- *
- * Due to the fact that |Xp - Xq| > 2^(nbits - 100) must be satisfied Xp and Xq
- * are generated using the previous function and supplied as input.
- */
-
-int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
-			BIGNUM *Xp1, BIGNUM *Xp2,
-			const BIGNUM *Xp,
-			const BIGNUM *e, BN_CTX *ctx,
-			BN_GENCB *cb)
-	{
-	int ret = 0;
-
-	BN_CTX_start(ctx);
-	if (!Xp1)
-		Xp1 = BN_CTX_get(ctx);
-	if (!Xp2)
-		Xp2 = BN_CTX_get(ctx);
-
-	if (!BN_rand(Xp1, 101, 0, 0))
-		goto error;
-	if (!BN_rand(Xp2, 101, 0, 0))
-		goto error;
-	if (!BN_X931_derive_prime_ex(p, p1, p2, Xp, Xp1, Xp2, e, ctx, cb))
-		goto error;
-
-	ret = 1;
-
-	error:
-	BN_CTX_end(ctx);
-
-	return ret;
-
-	}
-
diff --git a/crypto/bn/bntest.c b/crypto/bn/bntest.c
index d41daac..0cd99c5 100644
--- a/crypto/bn/bntest.c
+++ b/crypto/bn/bntest.c
@@ -486,7 +486,7 @@
 		return;
 		}
 #endif
-	BIO_printf(bp,"%lX",w);
+	BIO_printf(bp,BN_HEX_FMT1,w);
 	}
 
 int test_div_word(BIO *bp)
@@ -732,6 +732,8 @@
 	BN_init(&n);
 
 	mont=BN_MONT_CTX_new();
+	if (mont == NULL)
+		return 0;
 
 	BN_bntest_rand(&a,100,0,0); /**/
 	BN_bntest_rand(&b,100,0,0); /**/
@@ -1116,8 +1118,8 @@
 	{
 	BIGNUM *a,*b[2],*c,*d,*e;
 	int i, j, ret = 0;
-	unsigned int p0[] = {163,7,6,3,0};
-	unsigned int p1[] = {193,15,0};
+	int p0[] = {163,7,6,3,0,-1};
+	int p1[] = {193,15,0,-1};
 
 	a=BN_new();
 	b[0]=BN_new();
@@ -1174,8 +1176,8 @@
 	{
 	BIGNUM *a,*b[2],*c,*d,*e,*f,*g,*h;
 	int i, j, ret = 0;
-	unsigned int p0[] = {163,7,6,3,0};
-	unsigned int p1[] = {193,15,0};
+	int p0[] = {163,7,6,3,0,-1};
+	int p1[] = {193,15,0,-1};
 
 	a=BN_new();
 	b[0]=BN_new();
@@ -1245,8 +1247,8 @@
 	{
 	BIGNUM *a,*b[2],*c,*d;
 	int i, j, ret = 0;
-	unsigned int p0[] = {163,7,6,3,0};
-	unsigned int p1[] = {193,15,0};
+	int p0[] = {163,7,6,3,0,-1};
+	int p1[] = {193,15,0,-1};
 
 	a=BN_new();
 	b[0]=BN_new();
@@ -1304,8 +1306,8 @@
 	{
 	BIGNUM *a,*b[2],*c,*d;
 	int i, j, ret = 0;
-	unsigned int p0[] = {163,7,6,3,0};
-	unsigned int p1[] = {193,15,0};
+	int p0[] = {163,7,6,3,0,-1};
+	int p1[] = {193,15,0,-1};
 
 	a=BN_new();
 	b[0]=BN_new();
@@ -1359,8 +1361,8 @@
 	{
 	BIGNUM *a,*b[2],*c,*d,*e,*f;
 	int i, j, ret = 0;
-	unsigned int p0[] = {163,7,6,3,0};
-	unsigned int p1[] = {193,15,0};
+	int p0[] = {163,7,6,3,0,-1};
+	int p1[] = {193,15,0,-1};
 
 	a=BN_new();
 	b[0]=BN_new();
@@ -1422,8 +1424,8 @@
 	{
 	BIGNUM *a,*b[2],*c,*d,*e,*f;
 	int i, j, ret = 0;
-	unsigned int p0[] = {163,7,6,3,0};
-	unsigned int p1[] = {193,15,0};
+	int p0[] = {163,7,6,3,0,-1};
+	int p1[] = {193,15,0,-1};
 
 	a=BN_new();
 	b[0]=BN_new();
@@ -1493,8 +1495,8 @@
 	{
 	BIGNUM *a,*b[2],*c,*d,*e,*f;
 	int i, j, ret = 0;
-	unsigned int p0[] = {163,7,6,3,0};
-	unsigned int p1[] = {193,15,0};
+	int p0[] = {163,7,6,3,0,-1};
+	int p1[] = {193,15,0,-1};
 
 	a=BN_new();
 	b[0]=BN_new();
@@ -1552,8 +1554,8 @@
 	{
 	BIGNUM *a,*b[2],*c,*d,*e;
 	int i, j, s = 0, t, ret = 0;
-	unsigned int p0[] = {163,7,6,3,0};
-	unsigned int p1[] = {193,15,0};
+	int p0[] = {163,7,6,3,0,-1};
+	int p1[] = {193,15,0,-1};
 
 	a=BN_new();
 	b[0]=BN_new();
diff --git a/crypto/bn/exptest.c b/crypto/bn/exptest.c
index f598a07..074a8e8 100644
--- a/crypto/bn/exptest.c
+++ b/crypto/bn/exptest.c
@@ -163,7 +163,7 @@
 		  	{
 			if (BN_cmp(r_simple,r_mont) != 0)
 				printf("\nsimple and mont results differ\n");
-			if (BN_cmp(r_simple,r_mont) != 0)
+			if (BN_cmp(r_simple,r_mont_const) != 0)
 				printf("\nsimple and mont const time results differ\n");
 			if (BN_cmp(r_simple,r_recp) != 0)
 				printf("\nsimple and recp results differ\n");
@@ -187,7 +187,7 @@
 	BN_free(b);
 	BN_free(m);
 	BN_CTX_free(ctx);
-	ERR_remove_state(0);
+	ERR_remove_thread_state(NULL);
 	CRYPTO_mem_leaks(out);
 	BIO_free(out);
 	printf(" done\n");
diff --git a/crypto/buffer/Makefile b/crypto/buffer/Makefile
deleted file mode 100644
index 9e0f46e..0000000
--- a/crypto/buffer/Makefile
+++ /dev/null
@@ -1,97 +0,0 @@
-#
-# OpenSSL/crypto/buffer/Makefile
-#
-
-DIR=	buffer
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC= buffer.c buf_str.c buf_err.c
-LIBOBJ= buffer.o buf_str.o buf_err.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= buffer.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-buf_err.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-buf_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-buf_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-buf_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-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
-buffer.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-buffer.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-buffer.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-buffer.o: ../../include/openssl/symhacks.h ../cryptlib.h buffer.c
diff --git a/crypto/buffer/buf_err.c b/crypto/buffer/buf_err.c
index 3e25bbe..8f1de61 100644
--- a/crypto/buffer/buf_err.c
+++ b/crypto/buffer/buf_err.c
@@ -1,6 +1,6 @@
 /* crypto/buffer/buf_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
diff --git a/crypto/buffer/buffer.c b/crypto/buffer/buffer.c
index b3e9477..620ea8d 100644
--- a/crypto/buffer/buffer.c
+++ b/crypto/buffer/buffer.c
@@ -89,10 +89,10 @@
 	OPENSSL_free(a);
 	}
 
-int BUF_MEM_grow(BUF_MEM *str, int len)
+int BUF_MEM_grow(BUF_MEM *str, size_t len)
 	{
 	char *ret;
-	unsigned int n;
+	size_t n;
 
 	if (str->length >= len)
 		{
@@ -125,10 +125,10 @@
 	return(len);
 	}
 
-int BUF_MEM_grow_clean(BUF_MEM *str, int len)
+int BUF_MEM_grow_clean(BUF_MEM *str, size_t len)
 	{
 	char *ret;
-	unsigned int n;
+	size_t n;
 
 	if (str->length >= len)
 		{
@@ -161,3 +161,84 @@
 		}
 	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);
+	}
+
+void BUF_reverse(unsigned char *out, unsigned char *in, size_t size)
+	{
+	size_t i;
+	if (in)
+		{
+		out += size - 1;
+		for (i = 0; i < size; i++)
+			*in++ = *out--;
+		}
+	else
+		{
+		unsigned char *q;
+		char c;
+		q = out + size - 1;
+		for (i = 0; i < size/2; i++)
+			{
+			c = *q;
+			*q-- = *out;
+			*out++ = c;
+			}
+		}
+	}
diff --git a/crypto/buffer/buffer.h b/crypto/buffer/buffer.h
index 1db9607..178e418 100644
--- a/crypto/buffer/buffer.h
+++ b/crypto/buffer/buffer.h
@@ -76,18 +76,19 @@
 
 struct buf_mem_st
 	{
-	int length;	/* current number of bytes */
+	size_t length;	/* current number of bytes */
 	char *data;
-	int max;	/* size of buffer */
+	size_t max;	/* size of buffer */
 	};
 
 BUF_MEM *BUF_MEM_new(void);
 void	BUF_MEM_free(BUF_MEM *a);
-int	BUF_MEM_grow(BUF_MEM *str, int len);
-int	BUF_MEM_grow_clean(BUF_MEM *str, int len);
+int	BUF_MEM_grow(BUF_MEM *str, size_t len);
+int	BUF_MEM_grow_clean(BUF_MEM *str, size_t len);
 char *	BUF_strdup(const char *str);
 char *	BUF_strndup(const char *str, size_t siz);
 void *	BUF_memdup(const void *data, size_t siz);
+void	BUF_reverse(unsigned char *out, unsigned char *in, size_t siz);
 
 /* safe string functions */
 size_t BUF_strlcpy(char *dst,const char *src,size_t siz);
diff --git a/crypto/camellia/Makefile b/crypto/camellia/Makefile
deleted file mode 100644
index dfd1a75..0000000
--- a/crypto/camellia/Makefile
+++ /dev/null
@@ -1,106 +0,0 @@
-#
-# crypto/camellia/Makefile
-#
-
-DIR= camellia
-TOP=	../..
-CC=	cc
-CPP=	$(CC) -E
-INCLUDES=
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CAMELLIA_ASM_OBJ=
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-ASFLAGS= $(INCLUDES) $(ASFLAG)
-AFLAGS= $(ASFLAGS)
-
-GENERAL=Makefile
-#TEST=camelliatest.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=camellia.c cmll_misc.c cmll_ecb.c cmll_cbc.c cmll_ofb.c \
-	   cmll_cfb.c cmll_ctr.c 
-
-LIBOBJ= camellia.o cmll_misc.o cmll_ecb.o cmll_cbc.o cmll_ofb.o \
-		cmll_cfb.o cmll_ctr.o $(CAMELLIA_ASM_OBJ)
-
-SRC= $(LIBSRC)
-
-EXHEADER= camellia.h
-HEADER= cmll_locl.h $(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-$(LIBOBJ): $(LIBSRC)
-
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-camellia.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-camellia.o: camellia.c camellia.h cmll_locl.h
-cmll_cbc.o: ../../include/openssl/camellia.h ../../include/openssl/e_os2.h
-cmll_cbc.o: ../../include/openssl/opensslconf.h cmll_cbc.c cmll_locl.h
-cmll_cfb.o: ../../e_os.h ../../include/openssl/camellia.h
-cmll_cfb.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-cmll_cfb.o: cmll_cfb.c cmll_locl.h
-cmll_ctr.o: ../../include/openssl/camellia.h ../../include/openssl/e_os2.h
-cmll_ctr.o: ../../include/openssl/opensslconf.h cmll_ctr.c cmll_locl.h
-cmll_ecb.o: ../../include/openssl/camellia.h ../../include/openssl/e_os2.h
-cmll_ecb.o: ../../include/openssl/opensslconf.h cmll_ecb.c cmll_locl.h
-cmll_misc.o: ../../include/openssl/camellia.h ../../include/openssl/crypto.h
-cmll_misc.o: ../../include/openssl/e_os2.h ../../include/openssl/fips.h
-cmll_misc.o: ../../include/openssl/opensslconf.h
-cmll_misc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-cmll_misc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-cmll_misc.o: ../../include/openssl/symhacks.h cmll_locl.h cmll_misc.c
-cmll_ofb.o: ../../include/openssl/camellia.h ../../include/openssl/e_os2.h
-cmll_ofb.o: ../../include/openssl/opensslconf.h cmll_locl.h cmll_ofb.c
diff --git a/crypto/camellia/camellia.c b/crypto/camellia/camellia.c
deleted file mode 100644
index 491c26b..0000000
--- a/crypto/camellia/camellia.c
+++ /dev/null
@@ -1,1624 +0,0 @@
-/* crypto/camellia/camellia.c -*- mode:C; c-file-style: "eay" -*- */
-/* ====================================================================
- * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . 
- * ALL RIGHTS RESERVED.
- *
- * Intellectual Property information for Camellia:
- *     http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
- *
- * News Release for Announcement of Camellia open source:
- *     http://www.ntt.co.jp/news/news06e/0604/060413a.html
- *
- * The Camellia Code included herein is developed by
- * NTT (Nippon Telegraph and Telephone Corporation), and is contributed
- * to the OpenSSL project.
- *
- * The Camellia Code is licensed pursuant to the OpenSSL open source
- * license provided below.
- */
-/* ====================================================================
- * 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
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- */
-
-/* Algorithm Specification 
-   http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
-*/
-
-
-#include <string.h>
-#include <stdlib.h>
-
-#include "camellia.h"
-#include "cmll_locl.h"
-
-/* key constants */
-#define CAMELLIA_SIGMA1L (0xA09E667FL)
-#define CAMELLIA_SIGMA1R (0x3BCC908BL)
-#define CAMELLIA_SIGMA2L (0xB67AE858L)
-#define CAMELLIA_SIGMA2R (0x4CAA73B2L)
-#define CAMELLIA_SIGMA3L (0xC6EF372FL)
-#define CAMELLIA_SIGMA3R (0xE94F82BEL)
-#define CAMELLIA_SIGMA4L (0x54FF53A5L)
-#define CAMELLIA_SIGMA4R (0xF1D36F1CL)
-#define CAMELLIA_SIGMA5L (0x10E527FAL)
-#define CAMELLIA_SIGMA5R (0xDE682D1DL)
-#define CAMELLIA_SIGMA6L (0xB05688C2L)
-#define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
-
-/*
- *  macros
- */
-
-/* e is pointer of subkey */
-#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2])
-#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1])
-
-/* rotation right shift 1byte */
-#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))
-/* rotation left shift 1bit */
-#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31))
-/* rotation left shift 1byte */
-#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24))
-
-#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits)	\
-do							\
-	{						\
-	w0 = ll;					\
-	ll = (ll << bits) + (lr >> (32 - bits));	\
-	lr = (lr << bits) + (rl >> (32 - bits));	\
-	rl = (rl << bits) + (rr >> (32 - bits));	\
-	rr = (rr << bits) + (w0 >> (32 - bits));	\
-	} while(0)
-
-#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits)	\
-do							\
-	{						\
-	w0 = ll;					\
-	w1 = lr;					\
-	ll = (lr << (bits - 32)) + (rl >> (64 - bits));	\
-	lr = (rl << (bits - 32)) + (rr >> (64 - bits));	\
-	rl = (rr << (bits - 32)) + (w0 >> (64 - bits));	\
-	rr = (w0 << (bits - 32)) + (w1 >> (64 - bits));	\
-	} while(0)
-
-#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])
-#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])
-#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])
-#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])
-
-#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)		\
-do									\
-	{								\
-	il = xl ^ kl;							\
-	ir = xr ^ kr;							\
-	t0 = il >> 16;							\
-	t1 = ir >> 16;							\
-	yl = CAMELLIA_SP1110(ir & 0xff)					\
-		^ CAMELLIA_SP0222((t1 >> 8) & 0xff)			\
-		^ CAMELLIA_SP3033(t1 & 0xff)				\
-		^ CAMELLIA_SP4404((ir >> 8) & 0xff);			\
-	yr = CAMELLIA_SP1110((t0 >> 8) & 0xff)				\
-		^ CAMELLIA_SP0222(t0 & 0xff)				\
-		^ CAMELLIA_SP3033((il >> 8) & 0xff)			\
-		^ CAMELLIA_SP4404(il & 0xff);				\
-	yl ^= yr;							\
-	yr = CAMELLIA_RR8(yr);						\
-	yr ^= yl;							\
-	} while(0)
-
-
-/*
- * for speed up
- *
- */
-#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
-do									\
-	{								\
-	t0 = kll;							\
-	t0 &= ll;							\
-	lr ^= CAMELLIA_RL1(t0);						\
-	t1 = klr;							\
-	t1 |= lr;							\
-	ll ^= t1;							\
-									\
-	t2 = krr;							\
-	t2 |= rr;							\
-	rl ^= t2;							\
-	t3 = krl;							\
-	t3 &= rl;							\
-	rr ^= CAMELLIA_RL1(t3);						\
-	} while(0)
-
-#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)	\
-do									\
-	{								\
-	il = xl;							\
-	ir = xr;							\
-	t0 = il >> 16;							\
-	t1 = ir >> 16;							\
-	ir = CAMELLIA_SP1110(ir & 0xff)					\
-		^ CAMELLIA_SP0222((t1 >> 8) & 0xff)			\
-		^ CAMELLIA_SP3033(t1 & 0xff)				\
-		^ CAMELLIA_SP4404((ir >> 8) & 0xff);			\
-	il = CAMELLIA_SP1110((t0 >> 8) & 0xff)				\
-		^ CAMELLIA_SP0222(t0 & 0xff)				\
-		^ CAMELLIA_SP3033((il >> 8) & 0xff)			\
-		^ CAMELLIA_SP4404(il & 0xff);				\
-	il ^= kl;							\
-	ir ^= kr;							\
-	ir ^= il;							\
-	il = CAMELLIA_RR8(il);						\
-	il ^= ir;							\
-	yl ^= ir;							\
-	yr ^= il;							\
-	} while(0)
-
-static const u32 camellia_sp1110[256] =
-	{
-	0x70707000,0x82828200,0x2c2c2c00,0xececec00,
-	0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
-	0xe4e4e400,0x85858500,0x57575700,0x35353500,
-	0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
-	0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
-	0x45454500,0x19191900,0xa5a5a500,0x21212100,
-	0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
-	0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
-	0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
-	0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
-	0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
-	0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
-	0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
-	0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
-	0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
-	0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
-	0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
-	0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
-	0x74747400,0x12121200,0x2b2b2b00,0x20202000,
-	0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
-	0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
-	0x34343400,0x7e7e7e00,0x76767600,0x05050500,
-	0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
-	0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
-	0x14141400,0x58585800,0x3a3a3a00,0x61616100,
-	0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
-	0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
-	0x53535300,0x18181800,0xf2f2f200,0x22222200,
-	0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
-	0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
-	0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
-	0x60606000,0xfcfcfc00,0x69696900,0x50505000,
-	0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
-	0xa1a1a100,0x89898900,0x62626200,0x97979700,
-	0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
-	0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
-	0x10101000,0xc4c4c400,0x00000000,0x48484800,
-	0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
-	0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
-	0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
-	0x87878700,0x5c5c5c00,0x83838300,0x02020200,
-	0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
-	0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
-	0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
-	0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
-	0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
-	0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
-	0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
-	0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
-	0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
-	0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
-	0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
-	0x78787800,0x98989800,0x06060600,0x6a6a6a00,
-	0xe7e7e700,0x46464600,0x71717100,0xbababa00,
-	0xd4d4d400,0x25252500,0xababab00,0x42424200,
-	0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
-	0x72727200,0x07070700,0xb9b9b900,0x55555500,
-	0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
-	0x36363600,0x49494900,0x2a2a2a00,0x68686800,
-	0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
-	0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
-	0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
-	0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
-	0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
-	};
-
-static const u32 camellia_sp0222[256] =
-	{
-	0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
-	0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
-	0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
-	0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,
-	0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,
-	0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,
-	0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,
-	0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,
-	0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,
-	0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,
-	0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,
-	0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,
-	0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,
-	0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,
-	0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,
-	0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,
-	0x00171717,0x001a1a1a,0x00353535,0x00cccccc,
-	0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,
-	0x00e8e8e8,0x00242424,0x00565656,0x00404040,
-	0x00e1e1e1,0x00636363,0x00090909,0x00333333,
-	0x00bfbfbf,0x00989898,0x00979797,0x00858585,
-	0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,
-	0x00dadada,0x006f6f6f,0x00535353,0x00626262,
-	0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,
-	0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,
-	0x00bdbdbd,0x00363636,0x00222222,0x00383838,
-	0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,
-	0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,
-	0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,
-	0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,
-	0x00484848,0x00101010,0x00d1d1d1,0x00515151,
-	0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,
-	0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,
-	0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,
-	0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,
-	0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,
-	0x00202020,0x00898989,0x00000000,0x00909090,
-	0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,
-	0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,
-	0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,
-	0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,
-	0x009b9b9b,0x00949494,0x00212121,0x00666666,
-	0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,
-	0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,
-	0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,
-	0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,
-	0x00030303,0x002d2d2d,0x00dedede,0x00969696,
-	0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,
-	0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,
-	0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,
-	0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,
-	0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,
-	0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,
-	0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,
-	0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,
-	0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,
-	0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,
-	0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,
-	0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,
-	0x00787878,0x00707070,0x00e3e3e3,0x00494949,
-	0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,
-	0x00777777,0x00939393,0x00868686,0x00838383,
-	0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,
-	0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
-	};
-
-static const u32 camellia_sp3033[256] =
-	{
-	0x38003838,0x41004141,0x16001616,0x76007676,
-	0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
-	0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
-	0x75007575,0x06000606,0x57005757,0xa000a0a0,
-	0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,
-	0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,
-	0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,
-	0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,
-	0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,
-	0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,
-	0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,
-	0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,
-	0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,
-	0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,
-	0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,
-	0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,
-	0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,
-	0xfd00fdfd,0x66006666,0x58005858,0x96009696,
-	0x3a003a3a,0x09000909,0x95009595,0x10001010,
-	0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,
-	0xef00efef,0x26002626,0xe500e5e5,0x61006161,
-	0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,
-	0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,
-	0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,
-	0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,
-	0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,
-	0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,
-	0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,
-	0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,
-	0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,
-	0x12001212,0x04000404,0x74007474,0x54005454,
-	0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,
-	0x55005555,0x68006868,0x50005050,0xbe00bebe,
-	0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,
-	0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,
-	0x70007070,0xff00ffff,0x32003232,0x69006969,
-	0x08000808,0x62006262,0x00000000,0x24002424,
-	0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,
-	0x45004545,0x81008181,0x73007373,0x6d006d6d,
-	0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,
-	0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,
-	0xe600e6e6,0x25002525,0x48004848,0x99009999,
-	0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,
-	0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,
-	0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,
-	0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,
-	0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,
-	0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,
-	0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,
-	0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,
-	0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,
-	0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,
-	0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
-	0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
-	0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
-	0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
-	0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
-	0x7c007c7c,0x77007777,0x56005656,0x05000505,
-	0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
-	0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
-	0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
-	0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
-	0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
-	0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
-	};
-
-static const u32 camellia_sp4404[256] =
-	{
-	0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
-	0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
-	0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
-	0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
-	0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
-	0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
-	0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
-	0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
-	0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
-	0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
-	0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
-	0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
-	0x14140014,0x3a3a003a,0xdede00de,0x11110011,
-	0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
-	0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
-	0x24240024,0xe8e800e8,0x60600060,0x69690069,
-	0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
-	0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
-	0x10100010,0x00000000,0xa3a300a3,0x75750075,
-	0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
-	0x87870087,0x83830083,0xcdcd00cd,0x90900090,
-	0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
-	0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
-	0x81810081,0x6f6f006f,0x13130013,0x63630063,
-	0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
-	0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
-	0x78780078,0x06060006,0xe7e700e7,0x71710071,
-	0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
-	0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
-	0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
-	0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
-	0x15150015,0xadad00ad,0x77770077,0x80800080,
-	0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
-	0x85850085,0x35350035,0x0c0c000c,0x41410041,
-	0xefef00ef,0x93930093,0x19190019,0x21210021,
-	0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
-	0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
-	0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
-	0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
-	0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
-	0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
-	0x12120012,0x20200020,0xb1b100b1,0x99990099,
-	0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
-	0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
-	0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
-	0x0f0f000f,0x16160016,0x18180018,0x22220022,
-	0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
-	0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
-	0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
-	0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
-	0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
-	0x03030003,0xdada00da,0x3f3f003f,0x94940094,
-	0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
-	0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
-	0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
-	0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
-	0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
-	0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
-	0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
-	0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
-	0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
-	0x49490049,0x68680068,0x38380038,0xa4a400a4,
-	0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
-	0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
-	};
-
-/**
- * Stuff related to the Camellia key schedule
- */
-#define subl(x) subL[(x)]
-#define subr(x) subR[(x)]
-
-void camellia_setup128(const u8 *key, u32 *subkey)
-	{
-	u32 kll, klr, krl, krr;
-	u32 il, ir, t0, t1, w0, w1;
-	u32 kw4l, kw4r, dw, tl, tr;
-	u32 subL[26];
-	u32 subR[26];
-
-	/**
-	 *  k == kll || klr || krl || krr (|| is concatination)
-	 */
-	kll = GETU32(key     );
-	klr = GETU32(key +  4);
-	krl = GETU32(key +  8);
-	krr = GETU32(key + 12);
-	/**
-	 * generate KL dependent subkeys
-	 */
-	/* kw1 */
-	subl(0) = kll; subr(0) = klr;
-	/* kw2 */
-	subl(1) = krl; subr(1) = krr;
-	/* rotation left shift 15bit */
-	CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
-	/* k3 */
-	subl(4) = kll; subr(4) = klr;
-	/* k4 */
-	subl(5) = krl; subr(5) = krr;
-	/* rotation left shift 15+30bit */
-	CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
-	/* k7 */
-	subl(10) = kll; subr(10) = klr;
-	/* k8 */
-	subl(11) = krl; subr(11) = krr;
-	/* rotation left shift 15+30+15bit */
-	CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
-	/* k10 */
-	subl(13) = krl; subr(13) = krr;
-	/* rotation left shift 15+30+15+17 bit */
-	CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
-	/* kl3 */
-	subl(16) = kll; subr(16) = klr;
-	/* kl4 */
-	subl(17) = krl; subr(17) = krr;
-	/* rotation left shift 15+30+15+17+17 bit */
-	CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
-	/* k13 */
-	subl(18) = kll; subr(18) = klr;
-	/* k14 */
-	subl(19) = krl; subr(19) = krr;
-	/* rotation left shift 15+30+15+17+17+17 bit */
-	CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
-	/* k17 */
-	subl(22) = kll; subr(22) = klr;
-	/* k18 */
-	subl(23) = krl; subr(23) = krr;
-
-	/* generate KA */
-	kll = subl(0); klr = subr(0);
-	krl = subl(1); krr = subr(1);
-	CAMELLIA_F(kll, klr,
-		CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
-		w0, w1, il, ir, t0, t1);
-	krl ^= w0; krr ^= w1;
-	CAMELLIA_F(krl, krr,
-		CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
-		kll, klr, il, ir, t0, t1);
-	/* current status == (kll, klr, w0, w1) */
-	CAMELLIA_F(kll, klr,
-		CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
-		krl, krr, il, ir, t0, t1);
-	krl ^= w0; krr ^= w1;
-	CAMELLIA_F(krl, krr,
-		CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
-		w0, w1, il, ir, t0, t1);
-	kll ^= w0; klr ^= w1;
-
-	/* generate KA dependent subkeys */
-	/* k1, k2 */
-	subl(2) = kll; subr(2) = klr;
-	subl(3) = krl; subr(3) = krr;
-	CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
-	/* k5,k6 */
-	subl(6) = kll; subr(6) = klr;
-	subl(7) = krl; subr(7) = krr;
-	CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
-	/* kl1, kl2 */
-	subl(8) = kll; subr(8) = klr;
-	subl(9) = krl; subr(9) = krr;
-	CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
-	/* k9 */
-	subl(12) = kll; subr(12) = klr;
-	CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
-	/* k11, k12 */
-	subl(14) = kll; subr(14) = klr;
-	subl(15) = krl; subr(15) = krr;
-	CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
-	/* k15, k16 */
-	subl(20) = kll; subr(20) = klr;
-	subl(21) = krl; subr(21) = krr;
-	CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
-	/* kw3, kw4 */
-	subl(24) = kll; subr(24) = klr;
-	subl(25) = krl; subr(25) = krr;
-
-
-	/* absorb kw2 to other subkeys */
-/* round 2 */
-	subl(3) ^= subl(1); subr(3) ^= subr(1);
-/* round 4 */
-	subl(5) ^= subl(1); subr(5) ^= subr(1);
-/* round 6 */
-	subl(7) ^= subl(1); subr(7) ^= subr(1);
-	subl(1) ^= subr(1) & ~subr(9);
-	dw = subl(1) & subl(9),
-		subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl2) */
-/* round 8 */
-	subl(11) ^= subl(1); subr(11) ^= subr(1);
-/* round 10 */
-	subl(13) ^= subl(1); subr(13) ^= subr(1);
-/* round 12 */
-	subl(15) ^= subl(1); subr(15) ^= subr(1);
-	subl(1) ^= subr(1) & ~subr(17);
-	dw = subl(1) & subl(17),
-		subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl4) */
-/* round 14 */
-	subl(19) ^= subl(1); subr(19) ^= subr(1);
-/* round 16 */
-	subl(21) ^= subl(1); subr(21) ^= subr(1);
-/* round 18 */
-	subl(23) ^= subl(1); subr(23) ^= subr(1);
-/* kw3 */
-	subl(24) ^= subl(1); subr(24) ^= subr(1);
-
-	/* absorb kw4 to other subkeys */
-	kw4l = subl(25); kw4r = subr(25);
-/* round 17 */
-	subl(22) ^= kw4l; subr(22) ^= kw4r;
-/* round 15 */
-	subl(20) ^= kw4l; subr(20) ^= kw4r;
-/* round 13 */
-	subl(18) ^= kw4l; subr(18) ^= kw4r;
-	kw4l ^= kw4r & ~subr(16);
-	dw = kw4l & subl(16),
-		kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl3) */
-/* round 11 */
-	subl(14) ^= kw4l; subr(14) ^= kw4r;
-/* round 9 */
-	subl(12) ^= kw4l; subr(12) ^= kw4r;
-/* round 7 */
-	subl(10) ^= kw4l; subr(10) ^= kw4r;
-	kw4l ^= kw4r & ~subr(8);
-	dw = kw4l & subl(8),
-		kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl1) */
-/* round 5 */
-	subl(6) ^= kw4l; subr(6) ^= kw4r;
-/* round 3 */
-	subl(4) ^= kw4l; subr(4) ^= kw4r;
-/* round 1 */
-	subl(2) ^= kw4l; subr(2) ^= kw4r;
-/* kw1 */
-	subl(0) ^= kw4l; subr(0) ^= kw4r;
-
-
-	/* key XOR is end of F-function */
-	CamelliaSubkeyL(0) = subl(0) ^ subl(2);/* kw1 */
-	CamelliaSubkeyR(0) = subr(0) ^ subr(2);
-	CamelliaSubkeyL(2) = subl(3);       /* round 1 */
-	CamelliaSubkeyR(2) = subr(3);
-	CamelliaSubkeyL(3) = subl(2) ^ subl(4); /* round 2 */
-	CamelliaSubkeyR(3) = subr(2) ^ subr(4);
-	CamelliaSubkeyL(4) = subl(3) ^ subl(5); /* round 3 */
-	CamelliaSubkeyR(4) = subr(3) ^ subr(5);
-	CamelliaSubkeyL(5) = subl(4) ^ subl(6); /* round 4 */
-	CamelliaSubkeyR(5) = subr(4) ^ subr(6);
-	CamelliaSubkeyL(6) = subl(5) ^ subl(7); /* round 5 */
-	CamelliaSubkeyR(6) = subr(5) ^ subr(7);
-	tl = subl(10) ^ (subr(10) & ~subr(8));
-	dw = tl & subl(8),  /* FL(kl1) */
-		tr = subr(10) ^ CAMELLIA_RL1(dw);
-	CamelliaSubkeyL(7) = subl(6) ^ tl; /* round 6 */
-	CamelliaSubkeyR(7) = subr(6) ^ tr;
-	CamelliaSubkeyL(8) = subl(8);       /* FL(kl1) */
-	CamelliaSubkeyR(8) = subr(8);
-	CamelliaSubkeyL(9) = subl(9);       /* FLinv(kl2) */
-	CamelliaSubkeyR(9) = subr(9);
-	tl = subl(7) ^ (subr(7) & ~subr(9));
-	dw = tl & subl(9),  /* FLinv(kl2) */
-		tr = subr(7) ^ CAMELLIA_RL1(dw);
-	CamelliaSubkeyL(10) = tl ^ subl(11); /* round 7 */
-	CamelliaSubkeyR(10) = tr ^ subr(11);
-	CamelliaSubkeyL(11) = subl(10) ^ subl(12); /* round 8 */
-	CamelliaSubkeyR(11) = subr(10) ^ subr(12);
-	CamelliaSubkeyL(12) = subl(11) ^ subl(13); /* round 9 */
-	CamelliaSubkeyR(12) = subr(11) ^ subr(13);
-	CamelliaSubkeyL(13) = subl(12) ^ subl(14); /* round 10 */
-	CamelliaSubkeyR(13) = subr(12) ^ subr(14);
-	CamelliaSubkeyL(14) = subl(13) ^ subl(15); /* round 11 */
-	CamelliaSubkeyR(14) = subr(13) ^ subr(15);
-	tl = subl(18) ^ (subr(18) & ~subr(16));
-	dw = tl & subl(16), /* FL(kl3) */
-		tr = subr(18) ^ CAMELLIA_RL1(dw);
-	CamelliaSubkeyL(15) = subl(14) ^ tl; /* round 12 */
-	CamelliaSubkeyR(15) = subr(14) ^ tr;
-	CamelliaSubkeyL(16) = subl(16);     /* FL(kl3) */
-	CamelliaSubkeyR(16) = subr(16);
-	CamelliaSubkeyL(17) = subl(17);     /* FLinv(kl4) */
-	CamelliaSubkeyR(17) = subr(17);
-	tl = subl(15) ^ (subr(15) & ~subr(17));
-	dw = tl & subl(17), /* FLinv(kl4) */
-		tr = subr(15) ^ CAMELLIA_RL1(dw);
-	CamelliaSubkeyL(18) = tl ^ subl(19); /* round 13 */
-	CamelliaSubkeyR(18) = tr ^ subr(19);
-	CamelliaSubkeyL(19) = subl(18) ^ subl(20); /* round 14 */
-	CamelliaSubkeyR(19) = subr(18) ^ subr(20);
-	CamelliaSubkeyL(20) = subl(19) ^ subl(21); /* round 15 */
-	CamelliaSubkeyR(20) = subr(19) ^ subr(21);
-	CamelliaSubkeyL(21) = subl(20) ^ subl(22); /* round 16 */
-	CamelliaSubkeyR(21) = subr(20) ^ subr(22);
-	CamelliaSubkeyL(22) = subl(21) ^ subl(23); /* round 17 */
-	CamelliaSubkeyR(22) = subr(21) ^ subr(23);
-	CamelliaSubkeyL(23) = subl(22);     /* round 18 */
-	CamelliaSubkeyR(23) = subr(22);
-	CamelliaSubkeyL(24) = subl(24) ^ subl(23); /* kw3 */
-	CamelliaSubkeyR(24) = subr(24) ^ subr(23);
-
-	/* apply the inverse of the last half of P-function */
-	dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2),
-		dw = CAMELLIA_RL8(dw);/* round 1 */
-	CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw,
-		CamelliaSubkeyL(2) = dw;
-	dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3),
-		dw = CAMELLIA_RL8(dw);/* round 2 */
-	CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw,
-		CamelliaSubkeyL(3) = dw;
-	dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4),
-		dw = CAMELLIA_RL8(dw);/* round 3 */
-	CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw,
-		CamelliaSubkeyL(4) = dw;
-	dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5),
-		dw = CAMELLIA_RL8(dw);/* round 4 */
-	CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw,
-		CamelliaSubkeyL(5) = dw;
-	dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6),
-		dw = CAMELLIA_RL8(dw);/* round 5 */
-	CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw,
-		CamelliaSubkeyL(6) = dw;
-	dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7),
-		dw = CAMELLIA_RL8(dw);/* round 6 */
-	CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw,
-		CamelliaSubkeyL(7) = dw;
-	dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10),
-		dw = CAMELLIA_RL8(dw);/* round 7 */
-	CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw,
-		CamelliaSubkeyL(10) = dw;
-	dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11),
-		dw = CAMELLIA_RL8(dw);/* round 8 */
-	CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw,
-		CamelliaSubkeyL(11) = dw;
-	dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12),
-		dw = CAMELLIA_RL8(dw);/* round 9 */
-	CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw,
-		CamelliaSubkeyL(12) = dw;
-	dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13),
-		dw = CAMELLIA_RL8(dw);/* round 10 */
-	CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw,
-		CamelliaSubkeyL(13) = dw;
-	dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14),
-		dw = CAMELLIA_RL8(dw);/* round 11 */
-	CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw,
-		CamelliaSubkeyL(14) = dw;
-	dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15),
-		dw = CAMELLIA_RL8(dw);/* round 12 */
-	CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw,
-		CamelliaSubkeyL(15) = dw;
-	dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18),
-		dw = CAMELLIA_RL8(dw);/* round 13 */
-	CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw,
-		CamelliaSubkeyL(18) = dw;
-	dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19),
-		dw = CAMELLIA_RL8(dw);/* round 14 */
-	CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw,
-		CamelliaSubkeyL(19) = dw;
-	dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20),
-		dw = CAMELLIA_RL8(dw);/* round 15 */
-	CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw,
-		CamelliaSubkeyL(20) = dw;
-	dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21),
-		dw = CAMELLIA_RL8(dw);/* round 16 */
-	CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw,
-		CamelliaSubkeyL(21) = dw;
-	dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22),
-		dw = CAMELLIA_RL8(dw);/* round 17 */
-	CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw,
-		CamelliaSubkeyL(22) = dw;
-	dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23),
-		dw = CAMELLIA_RL8(dw);/* round 18 */
-	CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw,
-		CamelliaSubkeyL(23) = dw;
-
-	return;
-	}
-
-void camellia_setup256(const u8 *key, u32 *subkey)
-	{
-	u32 kll,klr,krl,krr;           /* left half of key */
-	u32 krll,krlr,krrl,krrr;       /* right half of key */
-	u32 il, ir, t0, t1, w0, w1;    /* temporary variables */
-	u32 kw4l, kw4r, dw, tl, tr;
-	u32 subL[34];
-	u32 subR[34];
-
-	/**
-	 *  key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
-	 *  (|| is concatination)
-	 */
-
-	kll  = GETU32(key     );
-	klr  = GETU32(key +  4);
-	krl  = GETU32(key +  8);
-	krr  = GETU32(key + 12);
-	krll = GETU32(key + 16);
-	krlr = GETU32(key + 20);
-	krrl = GETU32(key + 24);
-	krrr = GETU32(key + 28);
-
-	/* generate KL dependent subkeys */
-	/* kw1 */
-	subl(0) = kll; subr(0) = klr;
-	/* kw2 */
-	subl(1) = krl; subr(1) = krr;
-	CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
-	/* k9 */
-	subl(12) = kll; subr(12) = klr;
-	/* k10 */
-	subl(13) = krl; subr(13) = krr;
-	CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
-	/* kl3 */
-	subl(16) = kll; subr(16) = klr;
-	/* kl4 */
-	subl(17) = krl; subr(17) = krr;
-	CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
-	/* k17 */
-	subl(22) = kll; subr(22) = klr;
-	/* k18 */
-	subl(23) = krl; subr(23) = krr;
-	CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
-	/* k23 */
-	subl(30) = kll; subr(30) = klr;
-	/* k24 */
-	subl(31) = krl; subr(31) = krr;
-
-	/* generate KR dependent subkeys */
-	CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
-	/* k3 */
-	subl(4) = krll; subr(4) = krlr;
-	/* k4 */
-	subl(5) = krrl; subr(5) = krrr;
-	CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
-	/* kl1 */
-	subl(8) = krll; subr(8) = krlr;
-	/* kl2 */
-	subl(9) = krrl; subr(9) = krrr;
-	CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
-	/* k13 */
-	subl(18) = krll; subr(18) = krlr;
-	/* k14 */
-	subl(19) = krrl; subr(19) = krrr;
-	CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
-	/* k19 */
-	subl(26) = krll; subr(26) = krlr;
-	/* k20 */
-	subl(27) = krrl; subr(27) = krrr;
-	CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
-
-	/* generate KA */
-	kll = subl(0) ^ krll; klr = subr(0) ^ krlr;
-	krl = subl(1) ^ krrl; krr = subr(1) ^ krrr;
-	CAMELLIA_F(kll, klr,
-		CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
-		w0, w1, il, ir, t0, t1);
-	krl ^= w0; krr ^= w1;
-	CAMELLIA_F(krl, krr,
-		CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
-		kll, klr, il, ir, t0, t1);
-	kll ^= krll; klr ^= krlr;
-	CAMELLIA_F(kll, klr,
-		CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
-		krl, krr, il, ir, t0, t1);
-	krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
-	CAMELLIA_F(krl, krr,
-		CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
-		w0, w1, il, ir, t0, t1);
-	kll ^= w0; klr ^= w1;
-
-	/* generate KB */
-	krll ^= kll; krlr ^= klr;
-	krrl ^= krl; krrr ^= krr;
-	CAMELLIA_F(krll, krlr,
-		CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
-		w0, w1, il, ir, t0, t1);
-	krrl ^= w0; krrr ^= w1;
-	CAMELLIA_F(krrl, krrr,
-		CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
-		w0, w1, il, ir, t0, t1);
-	krll ^= w0; krlr ^= w1;
-
-	/* generate KA dependent subkeys */
-	CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
-	/* k5 */
-	subl(6) = kll; subr(6) = klr;
-	/* k6 */
-	subl(7) = krl; subr(7) = krr;
-	CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
-	/* k11 */
-	subl(14) = kll; subr(14) = klr;
-	/* k12 */
-	subl(15) = krl; subr(15) = krr;
-	/* rotation left shift 32bit */
-	/* kl5 */
-	subl(24) = klr; subr(24) = krl;
-	/* kl6 */
-	subl(25) = krr; subr(25) = kll;
-	/* rotation left shift 49 from k11,k12 -> k21,k22 */
-	CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
-	/* k21 */
-	subl(28) = kll; subr(28) = klr;
-	/* k22 */
-	subl(29) = krl; subr(29) = krr;
-
-	/* generate KB dependent subkeys */
-	/* k1 */
-	subl(2) = krll; subr(2) = krlr;
-	/* k2 */
-	subl(3) = krrl; subr(3) = krrr;
-	CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
-	/* k7 */
-	subl(10) = krll; subr(10) = krlr;
-	/* k8 */
-	subl(11) = krrl; subr(11) = krrr;
-	CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
-	/* k15 */
-	subl(20) = krll; subr(20) = krlr;
-	/* k16 */
-	subl(21) = krrl; subr(21) = krrr;
-	CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
-	/* kw3 */
-	subl(32) = krll; subr(32) = krlr;
-	/* kw4 */
-	subl(33) = krrl; subr(33) = krrr;
-
-	/* absorb kw2 to other subkeys */
-/* round 2 */
-	subl(3) ^= subl(1); subr(3) ^= subr(1);
-/* round 4 */
-	subl(5) ^= subl(1); subr(5) ^= subr(1);
-/* round 6 */
-	subl(7) ^= subl(1); subr(7) ^= subr(1);
-	subl(1) ^= subr(1) & ~subr(9);
-	dw = subl(1) & subl(9),
-		subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl2) */
-/* round 8 */
-	subl(11) ^= subl(1); subr(11) ^= subr(1);
-/* round 10 */
-	subl(13) ^= subl(1); subr(13) ^= subr(1);
-/* round 12 */
-	subl(15) ^= subl(1); subr(15) ^= subr(1);
-	subl(1) ^= subr(1) & ~subr(17);
-	dw = subl(1) & subl(17),
-		subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl4) */
-/* round 14 */
-	subl(19) ^= subl(1); subr(19) ^= subr(1);
-/* round 16 */
-	subl(21) ^= subl(1); subr(21) ^= subr(1);
-/* round 18 */
-	subl(23) ^= subl(1); subr(23) ^= subr(1);
-	subl(1) ^= subr(1) & ~subr(25);
-	dw = subl(1) & subl(25),
-		subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl6) */
-/* round 20 */
-	subl(27) ^= subl(1); subr(27) ^= subr(1);
-/* round 22 */
-	subl(29) ^= subl(1); subr(29) ^= subr(1);
-/* round 24 */
-	subl(31) ^= subl(1); subr(31) ^= subr(1);
-/* kw3 */
-	subl(32) ^= subl(1); subr(32) ^= subr(1);
-
-
-	/* absorb kw4 to other subkeys */
-	kw4l = subl(33); kw4r = subr(33);
-/* round 23 */
-	subl(30) ^= kw4l; subr(30) ^= kw4r;
-/* round 21 */
-	subl(28) ^= kw4l; subr(28) ^= kw4r;
-/* round 19 */
-	subl(26) ^= kw4l; subr(26) ^= kw4r;
-	kw4l ^= kw4r & ~subr(24);
-	dw = kw4l & subl(24),
-		kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl5) */
-/* round 17 */
-	subl(22) ^= kw4l; subr(22) ^= kw4r;
-/* round 15 */
-	subl(20) ^= kw4l; subr(20) ^= kw4r;
-/* round 13 */
-	subl(18) ^= kw4l; subr(18) ^= kw4r;
-	kw4l ^= kw4r & ~subr(16);
-	dw = kw4l & subl(16),
-		kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl3) */
-/* round 11 */
-	subl(14) ^= kw4l; subr(14) ^= kw4r;
-/* round 9 */
-	subl(12) ^= kw4l; subr(12) ^= kw4r;
-/* round 7 */
-	subl(10) ^= kw4l; subr(10) ^= kw4r;
-	kw4l ^= kw4r & ~subr(8);
-	dw = kw4l & subl(8),
-		kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl1) */
-/* round 5 */
-	subl(6) ^= kw4l; subr(6) ^= kw4r;
-/* round 3 */
-	subl(4) ^= kw4l; subr(4) ^= kw4r;
-/* round 1 */
-	subl(2) ^= kw4l; subr(2) ^= kw4r;
-/* kw1 */
-	subl(0) ^= kw4l; subr(0) ^= kw4r;
-
-	/* key XOR is end of F-function */
-	CamelliaSubkeyL(0) = subl(0) ^ subl(2);/* kw1 */
-	CamelliaSubkeyR(0) = subr(0) ^ subr(2);
-	CamelliaSubkeyL(2) = subl(3);       /* round 1 */
-	CamelliaSubkeyR(2) = subr(3);
-	CamelliaSubkeyL(3) = subl(2) ^ subl(4); /* round 2 */
-	CamelliaSubkeyR(3) = subr(2) ^ subr(4);
-	CamelliaSubkeyL(4) = subl(3) ^ subl(5); /* round 3 */
-	CamelliaSubkeyR(4) = subr(3) ^ subr(5);
-	CamelliaSubkeyL(5) = subl(4) ^ subl(6); /* round 4 */
-	CamelliaSubkeyR(5) = subr(4) ^ subr(6);
-	CamelliaSubkeyL(6) = subl(5) ^ subl(7); /* round 5 */
-	CamelliaSubkeyR(6) = subr(5) ^ subr(7);
-	tl = subl(10) ^ (subr(10) & ~subr(8));
-	dw = tl & subl(8),  /* FL(kl1) */
-		tr = subr(10) ^ CAMELLIA_RL1(dw);
-	CamelliaSubkeyL(7) = subl(6) ^ tl; /* round 6 */
-	CamelliaSubkeyR(7) = subr(6) ^ tr;
-	CamelliaSubkeyL(8) = subl(8);       /* FL(kl1) */
-	CamelliaSubkeyR(8) = subr(8);
-	CamelliaSubkeyL(9) = subl(9);       /* FLinv(kl2) */
-	CamelliaSubkeyR(9) = subr(9);
-	tl = subl(7) ^ (subr(7) & ~subr(9));
-	dw = tl & subl(9),  /* FLinv(kl2) */
-		tr = subr(7) ^ CAMELLIA_RL1(dw);
-	CamelliaSubkeyL(10) = tl ^ subl(11); /* round 7 */
-	CamelliaSubkeyR(10) = tr ^ subr(11);
-	CamelliaSubkeyL(11) = subl(10) ^ subl(12); /* round 8 */
-	CamelliaSubkeyR(11) = subr(10) ^ subr(12);
-	CamelliaSubkeyL(12) = subl(11) ^ subl(13); /* round 9 */
-	CamelliaSubkeyR(12) = subr(11) ^ subr(13);
-	CamelliaSubkeyL(13) = subl(12) ^ subl(14); /* round 10 */
-	CamelliaSubkeyR(13) = subr(12) ^ subr(14);
-	CamelliaSubkeyL(14) = subl(13) ^ subl(15); /* round 11 */
-	CamelliaSubkeyR(14) = subr(13) ^ subr(15);
-	tl = subl(18) ^ (subr(18) & ~subr(16));
-	dw = tl & subl(16), /* FL(kl3) */
-		tr = subr(18) ^ CAMELLIA_RL1(dw);
-	CamelliaSubkeyL(15) = subl(14) ^ tl; /* round 12 */
-	CamelliaSubkeyR(15) = subr(14) ^ tr;
-	CamelliaSubkeyL(16) = subl(16);     /* FL(kl3) */
-	CamelliaSubkeyR(16) = subr(16);
-	CamelliaSubkeyL(17) = subl(17);     /* FLinv(kl4) */
-	CamelliaSubkeyR(17) = subr(17);
-	tl = subl(15) ^ (subr(15) & ~subr(17));
-	dw = tl & subl(17), /* FLinv(kl4) */
-		tr = subr(15) ^ CAMELLIA_RL1(dw);
-	CamelliaSubkeyL(18) = tl ^ subl(19); /* round 13 */
-	CamelliaSubkeyR(18) = tr ^ subr(19);
-	CamelliaSubkeyL(19) = subl(18) ^ subl(20); /* round 14 */
-	CamelliaSubkeyR(19) = subr(18) ^ subr(20);
-	CamelliaSubkeyL(20) = subl(19) ^ subl(21); /* round 15 */
-	CamelliaSubkeyR(20) = subr(19) ^ subr(21);
-	CamelliaSubkeyL(21) = subl(20) ^ subl(22); /* round 16 */
-	CamelliaSubkeyR(21) = subr(20) ^ subr(22);
-	CamelliaSubkeyL(22) = subl(21) ^ subl(23); /* round 17 */
-	CamelliaSubkeyR(22) = subr(21) ^ subr(23);
-	tl = subl(26) ^ (subr(26)
-		& ~subr(24));
-	dw = tl & subl(24), /* FL(kl5) */
-		tr = subr(26) ^ CAMELLIA_RL1(dw);
-	CamelliaSubkeyL(23) = subl(22) ^ tl; /* round 18 */
-	CamelliaSubkeyR(23) = subr(22) ^ tr;
-	CamelliaSubkeyL(24) = subl(24);     /* FL(kl5) */
-	CamelliaSubkeyR(24) = subr(24);
-	CamelliaSubkeyL(25) = subl(25);     /* FLinv(kl6) */
-	CamelliaSubkeyR(25) = subr(25);
-	tl = subl(23) ^ (subr(23) &
-		~subr(25));
-	dw = tl & subl(25), /* FLinv(kl6) */
-		tr = subr(23) ^ CAMELLIA_RL1(dw);
-	CamelliaSubkeyL(26) = tl ^ subl(27); /* round 19 */
-	CamelliaSubkeyR(26) = tr ^ subr(27);
-	CamelliaSubkeyL(27) = subl(26) ^ subl(28); /* round 20 */
-	CamelliaSubkeyR(27) = subr(26) ^ subr(28);
-	CamelliaSubkeyL(28) = subl(27) ^ subl(29); /* round 21 */
-	CamelliaSubkeyR(28) = subr(27) ^ subr(29);
-	CamelliaSubkeyL(29) = subl(28) ^ subl(30); /* round 22 */
-	CamelliaSubkeyR(29) = subr(28) ^ subr(30);
-	CamelliaSubkeyL(30) = subl(29) ^ subl(31); /* round 23 */
-	CamelliaSubkeyR(30) = subr(29) ^ subr(31);
-	CamelliaSubkeyL(31) = subl(30);     /* round 24 */
-	CamelliaSubkeyR(31) = subr(30);
-	CamelliaSubkeyL(32) = subl(32) ^ subl(31); /* kw3 */
-	CamelliaSubkeyR(32) = subr(32) ^ subr(31);
-
-	/* apply the inverse of the last half of P-function */
-	dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2),
-		dw = CAMELLIA_RL8(dw);/* round 1 */
-	CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw,
-		CamelliaSubkeyL(2) = dw;
-	dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3),
-		dw = CAMELLIA_RL8(dw);/* round 2 */
-	CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw,
-		CamelliaSubkeyL(3) = dw;
-	dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4),
-		dw = CAMELLIA_RL8(dw);/* round 3 */
-	CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw,
-		CamelliaSubkeyL(4) = dw;
-	dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5),
-		dw = CAMELLIA_RL8(dw);/* round 4 */
-	CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw,
-		CamelliaSubkeyL(5) = dw;
-	dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6),
-		dw = CAMELLIA_RL8(dw);/* round 5 */
-	CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw,
-		CamelliaSubkeyL(6) = dw;
-	dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7),
-		dw = CAMELLIA_RL8(dw);/* round 6 */
-	CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw,
-		CamelliaSubkeyL(7) = dw;
-	dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10),
-		dw = CAMELLIA_RL8(dw);/* round 7 */
-	CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw,
-		CamelliaSubkeyL(10) = dw;
-	dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11),
-		dw = CAMELLIA_RL8(dw);/* round 8 */
-	CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw,
-		CamelliaSubkeyL(11) = dw;
-	dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12),
-		dw = CAMELLIA_RL8(dw);/* round 9 */
-	CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw,
-		CamelliaSubkeyL(12) = dw;
-	dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13),
-		dw = CAMELLIA_RL8(dw);/* round 10 */
-	CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw,
-		CamelliaSubkeyL(13) = dw;
-	dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14),
-		dw = CAMELLIA_RL8(dw);/* round 11 */
-	CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw,
-		CamelliaSubkeyL(14) = dw;
-	dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15),
-		dw = CAMELLIA_RL8(dw);/* round 12 */
-	CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw,
-		CamelliaSubkeyL(15) = dw;
-	dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18),
-		dw = CAMELLIA_RL8(dw);/* round 13 */
-	CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw,
-		CamelliaSubkeyL(18) = dw;
-	dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19),
-		dw = CAMELLIA_RL8(dw);/* round 14 */
-	CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw,
-		CamelliaSubkeyL(19) = dw;
-	dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20),
-		dw = CAMELLIA_RL8(dw);/* round 15 */
-	CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw,
-		CamelliaSubkeyL(20) = dw;
-	dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21),
-		dw = CAMELLIA_RL8(dw);/* round 16 */
-	CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw,
-		CamelliaSubkeyL(21) = dw;
-	dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22),
-		dw = CAMELLIA_RL8(dw);/* round 17 */
-	CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw,
-		CamelliaSubkeyL(22) = dw;
-	dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23),
-		dw = CAMELLIA_RL8(dw);/* round 18 */
-	CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw,
-		CamelliaSubkeyL(23) = dw;
-	dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26),
-		dw = CAMELLIA_RL8(dw);/* round 19 */
-	CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw,
-		CamelliaSubkeyL(26) = dw;
-	dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27),
-		dw = CAMELLIA_RL8(dw);/* round 20 */
-	CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw,
-		CamelliaSubkeyL(27) = dw;
-	dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28),
-		dw = CAMELLIA_RL8(dw);/* round 21 */
-	CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw,
-		CamelliaSubkeyL(28) = dw;
-	dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29),
-		dw = CAMELLIA_RL8(dw);/* round 22 */
-	CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw,
-		CamelliaSubkeyL(29) = dw;
-	dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30),
-		dw = CAMELLIA_RL8(dw);/* round 23 */
-	CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw,
-		CamelliaSubkeyL(30) = dw;
-	dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31),
-		dw = CAMELLIA_RL8(dw);/* round 24 */
-	CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,
-		CamelliaSubkeyL(31) = dw;
-
-    
-	return;
-	}
-
-void camellia_setup192(const u8 *key, u32 *subkey)
-	{
-	u8 kk[32];
-	u32 krll, krlr, krrl,krrr;
-
-	memcpy(kk, key, 24);
-	memcpy((u8 *)&krll, key+16,4);
-	memcpy((u8 *)&krlr, key+20,4);
-	krrl = ~krll;
-	krrr = ~krlr;
-	memcpy(kk+24, (u8 *)&krrl, 4);
-	memcpy(kk+28, (u8 *)&krrr, 4);
-	camellia_setup256(kk, subkey);
-	return;
-	}
-
-
-/**
- * Stuff related to camellia encryption/decryption
- */
-void camellia_encrypt128(const u32 *subkey, u32 *io)
-	{
-	u32 il, ir, t0, t1;
-
-	/* pre whitening but absorb kw2*/
-	io[0] ^= CamelliaSubkeyL(0);
-	io[1] ^= CamelliaSubkeyR(0);
-	/* main iteration */
-
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(2),CamelliaSubkeyR(2),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(3),CamelliaSubkeyR(3),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(4),CamelliaSubkeyR(4),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(5),CamelliaSubkeyR(5),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(6),CamelliaSubkeyR(6),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(7),CamelliaSubkeyR(7),
-		io[0],io[1],il,ir,t0,t1);
-
-	CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-		CamelliaSubkeyL(8),CamelliaSubkeyR(8),
-		CamelliaSubkeyL(9),CamelliaSubkeyR(9),
-		t0,t1,il,ir);
-
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(10),CamelliaSubkeyR(10),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(11),CamelliaSubkeyR(11),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(12),CamelliaSubkeyR(12),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(13),CamelliaSubkeyR(13),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(14),CamelliaSubkeyR(14),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(15),CamelliaSubkeyR(15),
-		io[0],io[1],il,ir,t0,t1);
-
-	CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-		CamelliaSubkeyL(16),CamelliaSubkeyR(16),
-		CamelliaSubkeyL(17),CamelliaSubkeyR(17),
-		t0,t1,il,ir);
-
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(18),CamelliaSubkeyR(18),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(19),CamelliaSubkeyR(19),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(20),CamelliaSubkeyR(20),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(21),CamelliaSubkeyR(21),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(22),CamelliaSubkeyR(22),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(23),CamelliaSubkeyR(23),
-		io[0],io[1],il,ir,t0,t1);
-
-	/* post whitening but kw4 */
-	io[2] ^= CamelliaSubkeyL(24);
-	io[3] ^= CamelliaSubkeyR(24);
-
-	t0 = io[0];
-	t1 = io[1];
-	io[0] = io[2];
-	io[1] = io[3];
-	io[2] = t0;
-	io[3] = t1;
-
-	return;
-	}
-
-void camellia_decrypt128(const u32 *subkey, u32 *io)
-	{
-	u32 il,ir,t0,t1;               /* temporary valiables */
-
-	/* pre whitening but absorb kw2*/
-	io[0] ^= CamelliaSubkeyL(24);
-	io[1] ^= CamelliaSubkeyR(24);
-
-	/* main iteration */
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(23),CamelliaSubkeyR(23),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(22),CamelliaSubkeyR(22),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(21),CamelliaSubkeyR(21),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(20),CamelliaSubkeyR(20),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(19),CamelliaSubkeyR(19),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(18),CamelliaSubkeyR(18),
-		io[0],io[1],il,ir,t0,t1);
-
-	CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-		CamelliaSubkeyL(17),CamelliaSubkeyR(17),
-		CamelliaSubkeyL(16),CamelliaSubkeyR(16),
-		t0,t1,il,ir);
-
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(15),CamelliaSubkeyR(15),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(14),CamelliaSubkeyR(14),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(13),CamelliaSubkeyR(13),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(12),CamelliaSubkeyR(12),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(11),CamelliaSubkeyR(11),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(10),CamelliaSubkeyR(10),
-		io[0],io[1],il,ir,t0,t1);
-
-	CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-		CamelliaSubkeyL(9),CamelliaSubkeyR(9),
-		CamelliaSubkeyL(8),CamelliaSubkeyR(8),
-		t0,t1,il,ir);
-
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(7),CamelliaSubkeyR(7),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(6),CamelliaSubkeyR(6),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(5),CamelliaSubkeyR(5),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(4),CamelliaSubkeyR(4),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(3),CamelliaSubkeyR(3),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(2),CamelliaSubkeyR(2),
-		io[0],io[1],il,ir,t0,t1);
-
-	/* post whitening but kw4 */
-	io[2] ^= CamelliaSubkeyL(0);
-	io[3] ^= CamelliaSubkeyR(0);
-
-	t0 = io[0];
-	t1 = io[1];
-	io[0] = io[2];
-	io[1] = io[3];
-	io[2] = t0;
-	io[3] = t1;
-
-	return;
-	}
-
-/**
- * stuff for 192 and 256bit encryption/decryption
- */
-void camellia_encrypt256(const u32 *subkey, u32 *io)
-	{
-	u32 il,ir,t0,t1;           /* temporary valiables */
-
-	/* pre whitening but absorb kw2*/
-	io[0] ^= CamelliaSubkeyL(0);
-	io[1] ^= CamelliaSubkeyR(0);
-
-	/* main iteration */
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(2),CamelliaSubkeyR(2),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(3),CamelliaSubkeyR(3),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(4),CamelliaSubkeyR(4),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(5),CamelliaSubkeyR(5),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(6),CamelliaSubkeyR(6),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(7),CamelliaSubkeyR(7),
-		io[0],io[1],il,ir,t0,t1);
-
-	CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-		CamelliaSubkeyL(8),CamelliaSubkeyR(8),
-		CamelliaSubkeyL(9),CamelliaSubkeyR(9),
-		t0,t1,il,ir);
-
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(10),CamelliaSubkeyR(10),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(11),CamelliaSubkeyR(11),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(12),CamelliaSubkeyR(12),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(13),CamelliaSubkeyR(13),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(14),CamelliaSubkeyR(14),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(15),CamelliaSubkeyR(15),
-		io[0],io[1],il,ir,t0,t1);
-
-	CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-		CamelliaSubkeyL(16),CamelliaSubkeyR(16),
-		CamelliaSubkeyL(17),CamelliaSubkeyR(17),
-		t0,t1,il,ir);
-
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(18),CamelliaSubkeyR(18),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(19),CamelliaSubkeyR(19),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(20),CamelliaSubkeyR(20),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(21),CamelliaSubkeyR(21),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(22),CamelliaSubkeyR(22),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(23),CamelliaSubkeyR(23),
-		io[0],io[1],il,ir,t0,t1);
-
-	CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-		CamelliaSubkeyL(24),CamelliaSubkeyR(24),
-		CamelliaSubkeyL(25),CamelliaSubkeyR(25),
-		t0,t1,il,ir);
-
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(26),CamelliaSubkeyR(26),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(27),CamelliaSubkeyR(27),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(28),CamelliaSubkeyR(28),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(29),CamelliaSubkeyR(29),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(30),CamelliaSubkeyR(30),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(31),CamelliaSubkeyR(31),
-		io[0],io[1],il,ir,t0,t1);
-
-	/* post whitening but kw4 */
-	io[2] ^= CamelliaSubkeyL(32);
-	io[3] ^= CamelliaSubkeyR(32);
-
-	t0 = io[0];
-	t1 = io[1];
-	io[0] = io[2];
-	io[1] = io[3];
-	io[2] = t0;
-	io[3] = t1;
-
-	return;
-	}
-
-void camellia_decrypt256(const u32 *subkey, u32 *io)
-	{
-	u32 il,ir,t0,t1;           /* temporary valiables */
-
-	/* pre whitening but absorb kw2*/
-	io[0] ^= CamelliaSubkeyL(32);
-	io[1] ^= CamelliaSubkeyR(32);
-	
-	/* main iteration */
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(31),CamelliaSubkeyR(31),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(30),CamelliaSubkeyR(30),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(29),CamelliaSubkeyR(29),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(28),CamelliaSubkeyR(28),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(27),CamelliaSubkeyR(27),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(26),CamelliaSubkeyR(26),
-		io[0],io[1],il,ir,t0,t1);
-
-	CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-		CamelliaSubkeyL(25),CamelliaSubkeyR(25),
-		CamelliaSubkeyL(24),CamelliaSubkeyR(24),
-		t0,t1,il,ir);
-
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(23),CamelliaSubkeyR(23),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(22),CamelliaSubkeyR(22),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(21),CamelliaSubkeyR(21),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(20),CamelliaSubkeyR(20),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(19),CamelliaSubkeyR(19),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(18),CamelliaSubkeyR(18),
-		io[0],io[1],il,ir,t0,t1);
-
-	CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-		CamelliaSubkeyL(17),CamelliaSubkeyR(17),
-		CamelliaSubkeyL(16),CamelliaSubkeyR(16),
-		t0,t1,il,ir);
-
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(15),CamelliaSubkeyR(15),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(14),CamelliaSubkeyR(14),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(13),CamelliaSubkeyR(13),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(12),CamelliaSubkeyR(12),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(11),CamelliaSubkeyR(11),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(10),CamelliaSubkeyR(10),
-		io[0],io[1],il,ir,t0,t1);
-
-	CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-		CamelliaSubkeyL(9),CamelliaSubkeyR(9),
-		CamelliaSubkeyL(8),CamelliaSubkeyR(8),
-		t0,t1,il,ir);
-
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(7),CamelliaSubkeyR(7),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(6),CamelliaSubkeyR(6),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(5),CamelliaSubkeyR(5),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(4),CamelliaSubkeyR(4),
-		io[0],io[1],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[0],io[1],
-		CamelliaSubkeyL(3),CamelliaSubkeyR(3),
-		io[2],io[3],il,ir,t0,t1);
-	CAMELLIA_ROUNDSM(io[2],io[3],
-		CamelliaSubkeyL(2),CamelliaSubkeyR(2),
-		io[0],io[1],il,ir,t0,t1);
-
-	/* post whitening but kw4 */
-	io[2] ^= CamelliaSubkeyL(0);
-	io[3] ^= CamelliaSubkeyR(0);
-
-	t0 = io[0];
-	t1 = io[1];
-	io[0] = io[2];
-	io[1] = io[3];
-	io[2] = t0;
-	io[3] = t1;
-
-	return;
-	}
-
diff --git a/crypto/camellia/camellia.h b/crypto/camellia/camellia.h
deleted file mode 100644
index b8a8b6e..0000000
--- a/crypto/camellia/camellia.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/* crypto/camellia/camellia.h -*- mode:C; c-file-style: "eay" -*- */
-/* ====================================================================
- * 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
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- */
-
-#ifndef HEADER_CAMELLIA_H
-#define HEADER_CAMELLIA_H
-
-#include <openssl/opensslconf.h>
-
-#ifdef OPENSSL_NO_CAMELLIA
-#error CAMELLIA is disabled.
-#endif
-
-#define CAMELLIA_ENCRYPT	1
-#define CAMELLIA_DECRYPT	0
-
-/* Because array size can't be a const in C, the following two are macros.
-   Both sizes are in bytes. */
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-/* This should be a hidden type, but EVP requires that the size be known */
-
-#define CAMELLIA_BLOCK_SIZE 16
-#define CAMELLIA_TABLE_BYTE_LEN 272
-#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
-
- /* to match with WORD */
-typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];
-
-struct camellia_key_st 
-	{
-	KEY_TABLE_TYPE rd_key;
-	int bitLength;
-	void (*enc)(const unsigned int *subkey, unsigned int *io);
-	void (*dec)(const unsigned int *subkey, unsigned int *io);
-	};
-
-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);
-
-void Camellia_encrypt(const unsigned char *in, unsigned char *out,
-	const CAMELLIA_KEY *key);
-void Camellia_decrypt(const unsigned char *in, unsigned char *out,
-	const CAMELLIA_KEY *key);
-
-void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out,
-	const CAMELLIA_KEY *key, const int enc);
-void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const CAMELLIA_KEY *key,
-	unsigned char *ivec, const int enc);
-void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const CAMELLIA_KEY *key,
-	unsigned char *ivec, int *num, const int enc);
-void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const CAMELLIA_KEY *key,
-	unsigned char *ivec, int *num, const int enc);
-void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const CAMELLIA_KEY *key,
-	unsigned char *ivec, int *num, const int enc);
-void Camellia_cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
-	const int nbits,const CAMELLIA_KEY *key,
-	unsigned char *ivec,const int enc);
-void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const CAMELLIA_KEY *key,
-	unsigned char *ivec, int *num);
-void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const CAMELLIA_KEY *key,
-	unsigned char ivec[CAMELLIA_BLOCK_SIZE],
-	unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE],
-	unsigned int *num);
-
-#ifdef  __cplusplus
-}
-#endif
-
-#endif /* !HEADER_Camellia_H */
-
diff --git a/crypto/camellia/cmll_cbc.c b/crypto/camellia/cmll_cbc.c
deleted file mode 100644
index 4141a7b..0000000
--- a/crypto/camellia/cmll_cbc.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/* crypto/camellia/camellia_cbc.c -*- mode:C; c-file-style: "eay" -*- */
-/* ====================================================================
- * 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
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- */
-
-#ifndef CAMELLIA_DEBUG
-# ifndef NDEBUG
-#  define NDEBUG
-# endif
-#endif
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <openssl/camellia.h>
-#include "cmll_locl.h"
-
-void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
-		     const unsigned long length, const CAMELLIA_KEY *key,
-		     unsigned char *ivec, const int enc) {
-
-	unsigned long n;
-	unsigned long len = length;
-	const unsigned char *iv = ivec;
-	union {	u32 t32[CAMELLIA_BLOCK_SIZE/sizeof(u32)];
-		u8  t8 [CAMELLIA_BLOCK_SIZE]; } tmp;
-	const union { long one; char little; } camellia_endian = {1};
-
-
-	assert(in && out && key && ivec);
-	assert((CAMELLIA_ENCRYPT == enc)||(CAMELLIA_DECRYPT == enc));
-
-	if(((size_t)in|(size_t)out|(size_t)ivec) % sizeof(u32) == 0)
-		{
-		if (CAMELLIA_ENCRYPT == enc)
-			{
-			while (len >= CAMELLIA_BLOCK_SIZE)
-				{
-				XOR4WORD2((u32 *)out,
-					(u32 *)in, (u32 *)iv);
-				if (camellia_endian.little)
-					SWAP4WORD((u32 *)out);
-				key->enc(key->rd_key, (u32 *)out);
-				if (camellia_endian.little)
-					SWAP4WORD((u32 *)out);
-				iv = out;
-				len -= CAMELLIA_BLOCK_SIZE;
-				in += CAMELLIA_BLOCK_SIZE;
-				out += CAMELLIA_BLOCK_SIZE;
-				}
-			if (len)
-				{
-				for(n=0; n < len; ++n)
-					out[n] = in[n] ^ iv[n];
-				for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
-					out[n] = iv[n];
-				if (camellia_endian.little)
-					SWAP4WORD((u32 *)out);
-				key->enc(key->rd_key, (u32 *)out);
-				if (camellia_endian.little)
-					SWAP4WORD((u32 *)out);
-				iv = out;
-				}
-			memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
-			}
-		else if (in != out)
-			{
-			while (len >= CAMELLIA_BLOCK_SIZE)
-				{
-				memcpy(out,in,CAMELLIA_BLOCK_SIZE);
-				if (camellia_endian.little)
-					SWAP4WORD((u32 *)out);
-				key->dec(key->rd_key,(u32 *)out);
-				if (camellia_endian.little)
-					SWAP4WORD((u32 *)out);
-				XOR4WORD((u32 *)out, (u32 *)iv);
-				iv = in;
-				len -= CAMELLIA_BLOCK_SIZE;
-				in  += CAMELLIA_BLOCK_SIZE;
-				out += CAMELLIA_BLOCK_SIZE;
-				}
-			if (len)
-				{
-				memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE);
-				if (camellia_endian.little)
-					SWAP4WORD(tmp.t32);
-				key->dec(key->rd_key, tmp.t32);
-				if (camellia_endian.little)
-					SWAP4WORD(tmp.t32);
-				for(n=0; n < len; ++n)
-					out[n] = tmp.t8[n] ^ iv[n];
-				iv = in;
-				}
-			memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
-			}
-		else /* in == out */
-			{
-			while (len >= CAMELLIA_BLOCK_SIZE)
-				{
-				memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE);
-				if (camellia_endian.little)
-					SWAP4WORD((u32 *)out);
-				key->dec(key->rd_key, (u32 *)out);
-				if (camellia_endian.little)
-					SWAP4WORD((u32 *)out);
-				XOR4WORD((u32 *)out, (u32 *)ivec);
-				memcpy(ivec, tmp.t8, CAMELLIA_BLOCK_SIZE);
-				len -= CAMELLIA_BLOCK_SIZE;
-				in += CAMELLIA_BLOCK_SIZE;
-				out += CAMELLIA_BLOCK_SIZE;
-				}
-			if (len)
-				{
-				memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE);
-				if (camellia_endian.little)
-					SWAP4WORD((u32 *)out);
-				key->dec(key->rd_key,(u32 *)out);
-				if (camellia_endian.little)
-					SWAP4WORD((u32 *)out);
-				for(n=0; n < len; ++n)
-					out[n] ^= ivec[n];
-				for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
-					out[n] = tmp.t8[n];
-				memcpy(ivec, tmp.t8, CAMELLIA_BLOCK_SIZE);
-				}
-			}
-		}
-	else /* no aligned */
-		{
-		if (CAMELLIA_ENCRYPT == enc)
-			{
-			while (len >= CAMELLIA_BLOCK_SIZE)
-				{
-				for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
-					tmp.t8[n] = in[n] ^ iv[n];
-				if (camellia_endian.little)
-					SWAP4WORD(tmp.t32);
-				key->enc(key->rd_key, tmp.t32);
-				if (camellia_endian.little)
-					SWAP4WORD(tmp.t32);
-				memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE);
-				iv = out;
-				len -= CAMELLIA_BLOCK_SIZE;
-				in += CAMELLIA_BLOCK_SIZE;
-				out += CAMELLIA_BLOCK_SIZE;
-				}
-			if (len)
-				{
-				for(n=0; n < len; ++n)
-					tmp.t8[n] = in[n] ^ iv[n];
-				for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
-					tmp.t8[n] = iv[n];
-				if (camellia_endian.little)
-					SWAP4WORD(tmp.t32);
-				key->enc(key->rd_key, tmp.t32);
-				if (camellia_endian.little)
-					SWAP4WORD(tmp.t32);
-				memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE);
-				iv = out;
-				}
-			memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
-			}
-		else if (in != out)
-			{
-			while (len >= CAMELLIA_BLOCK_SIZE)
-				{
-				memcpy(tmp.t8,in,CAMELLIA_BLOCK_SIZE);
-				if (camellia_endian.little)
-					SWAP4WORD(tmp.t32);
-				key->dec(key->rd_key,tmp.t32);
-				if (camellia_endian.little)
-					SWAP4WORD(tmp.t32);
-				for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
-					out[n] = tmp.t8[n] ^ iv[n];
-				iv = in;
-				len -= CAMELLIA_BLOCK_SIZE;
-				in  += CAMELLIA_BLOCK_SIZE;
-				out += CAMELLIA_BLOCK_SIZE;
-				}
-			if (len)
-				{
-				memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE);
-				if (camellia_endian.little)
-					SWAP4WORD(tmp.t32);
-				key->dec(key->rd_key, tmp.t32);
-				if (camellia_endian.little)
-					SWAP4WORD(tmp.t32);
-				for(n=0; n < len; ++n)
-					out[n] = tmp.t8[n] ^ iv[n];
-				iv = in;
-				}
-			memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
-			}
-		else
-			{
-			while (len >= CAMELLIA_BLOCK_SIZE)
-				{
-				memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE);
-				if (camellia_endian.little)
-					SWAP4WORD(tmp.t32);
-				key->dec(key->rd_key, tmp.t32);
-				if (camellia_endian.little)
-					SWAP4WORD(tmp.t32);
-				for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
-					tmp.t8[n] ^= ivec[n];
-				memcpy(ivec, in, CAMELLIA_BLOCK_SIZE);
-				memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE);
-				len -= CAMELLIA_BLOCK_SIZE;
-				in += CAMELLIA_BLOCK_SIZE;
-				out += CAMELLIA_BLOCK_SIZE;
-				}
-			if (len)
-				{
-				memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE);
-				if (camellia_endian.little)
-					SWAP4WORD(tmp.t32);
-				key->dec(key->rd_key,tmp.t32);
-				if (camellia_endian.little)
-					SWAP4WORD(tmp.t32);
-				for(n=0; n < len; ++n)
-					tmp.t8[n] ^= ivec[n];
-				memcpy(ivec, in, CAMELLIA_BLOCK_SIZE);
-				memcpy(out,tmp.t8,len);
-				}
-			}
-		}
-}
diff --git a/crypto/camellia/cmll_cfb.c b/crypto/camellia/cmll_cfb.c
deleted file mode 100644
index af0f9f4..0000000
--- a/crypto/camellia/cmll_cfb.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/* crypto/camellia/camellia_cfb.c -*- mode:C; c-file-style: "eay" -*- */
-/* ====================================================================
- * 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
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#ifndef CAMELLIA_DEBUG
-# ifndef NDEBUG
-#  define NDEBUG
-# endif
-#endif
-#include <assert.h>
-#include <string.h>
-
-#include <openssl/camellia.h>
-#include "cmll_locl.h"
-#include "e_os.h"
-
-
-/* The input and output encrypted as though 128bit cfb mode is being
- * used.  The extra state information to record how much of the
- * 128bit block we have used is contained in *num;
- */
-
-void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const CAMELLIA_KEY *key,
-	unsigned char *ivec, int *num, const int enc)
-	{
-
-	unsigned int n;
-	unsigned long l = length;
-	unsigned char c;
-
-	assert(in && out && key && ivec && num);
-
-	n = *num;
-
-	if (enc) 
-		{
-		while (l--) 
-			{
-			if (n == 0) 
-				{
-				Camellia_encrypt(ivec, ivec, key);
-				}
-			ivec[n] = *(out++) = *(in++) ^ ivec[n];
-			n = (n+1) % CAMELLIA_BLOCK_SIZE;
-			}
-		} 
-	else 
-		{
-		while (l--) 
-			{
-			if (n == 0) 
-				{
-				Camellia_encrypt(ivec, ivec, key);
-				}
-			c = *(in);
-			*(out++) = *(in++) ^ ivec[n];
-			ivec[n] = c;
-			n = (n+1) % CAMELLIA_BLOCK_SIZE;
-			}
-		}
-
-	*num=n;
-	}
-
-/* This expects a single block of size nbits for both in and out. Note that
-   it corrupts any extra bits in the last byte of out */
-void Camellia_cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
-	const int nbits,const CAMELLIA_KEY *key,
-	unsigned char *ivec,const int enc)
-	{
-	int n,rem,num;
-	unsigned char ovec[CAMELLIA_BLOCK_SIZE*2];
-
-	if (nbits<=0 || nbits>128) return;
-
-	/* fill in the first half of the new IV with the current IV */
-	memcpy(ovec,ivec,CAMELLIA_BLOCK_SIZE);
-	/* construct the new IV */
-	Camellia_encrypt(ivec,ivec,key);
-	num = (nbits+7)/8;
-	if (enc)	/* encrypt the input */
-		for(n=0 ; n < num ; ++n)
-			out[n] = (ovec[CAMELLIA_BLOCK_SIZE+n] = in[n] ^ ivec[n]);
-	else		/* decrypt the input */
-		for(n=0 ; n < num ; ++n)
-			out[n] = (ovec[CAMELLIA_BLOCK_SIZE+n] = in[n]) ^ ivec[n];
-	/* shift ovec left... */
-	rem = nbits%8;
-	num = nbits/8;
-	if(rem==0)
-		memcpy(ivec,ovec+num,CAMELLIA_BLOCK_SIZE);
-	else
-		for(n=0 ; n < CAMELLIA_BLOCK_SIZE ; ++n)
-			ivec[n] = ovec[n+num]<<rem | ovec[n+num+1]>>(8-rem);
-
-	/* it is not necessary to cleanse ovec, since the IV is not secret */
-	}
-
-/* N.B. This expects the input to be packed, MS bit first */
-void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const CAMELLIA_KEY *key,
-	unsigned char *ivec, int *num, const int enc)
-	{
-	unsigned int n;
-	unsigned char c[1],d[1];
-
-	assert(in && out && key && ivec && num);
-	assert(*num == 0);
-
-	memset(out,0,(length+7)/8);
-	for(n=0 ; n < length ; ++n)
-		{
-		c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
-		Camellia_cfbr_encrypt_block(c,d,1,key,ivec,enc);
-		out[n/8]=(out[n/8]&~(1 << (7-n%8)))|((d[0]&0x80) >> (n%8));
-		}
-	}
-
-void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const CAMELLIA_KEY *key,
-	unsigned char *ivec, int *num, const int enc)
-	{
-	unsigned int n;
-
-	assert(in && out && key && ivec && num);
-	assert(*num == 0);
-
-	for(n=0 ; n < length ; ++n)
-		Camellia_cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc);
-	}
-
diff --git a/crypto/camellia/cmll_ctr.c b/crypto/camellia/cmll_ctr.c
deleted file mode 100644
index cc21b70..0000000
--- a/crypto/camellia/cmll_ctr.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/* crypto/camellia/camellia_ctr.c -*- mode:C; c-file-style: "eay" -*- */
-/* ====================================================================
- * 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
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- */
-
-#ifndef CAMELLIA_DEBUG
-# ifndef NDEBUG
-#  define NDEBUG
-# endif
-#endif
-#include <assert.h>
-
-#include <openssl/camellia.h>
-#include "cmll_locl.h"
-
-/* NOTE: the IV/counter CTR mode is big-endian.  The rest of the Camellia code
- * is endian-neutral. */
-/* increment counter (128-bit int) by 1 */
-static void Camellia_ctr128_inc(unsigned char *counter) 
-	{
-	unsigned long c;
-
-	/* Grab bottom dword of counter and increment */
-	c = GETU32(counter + 12);
-	c++;	c &= 0xFFFFFFFF;
-	PUTU32(counter + 12, c);
-
-	/* if no overflow, we're done */
-	if (c)
-		return;
-
-	/* Grab 1st dword of counter and increment */
-	c = GETU32(counter +  8);
-	c++;	c &= 0xFFFFFFFF;
-	PUTU32(counter +  8, c);
-
-	/* if no overflow, we're done */
-	if (c)
-		return;
-
-	/* Grab 2nd dword of counter and increment */
-	c = GETU32(counter +  4);
-	c++;	c &= 0xFFFFFFFF;
-	PUTU32(counter +  4, c);
-
-	/* if no overflow, we're done */
-	if (c)
-		return;
-
-	/* Grab top dword of counter and increment */
-	c = GETU32(counter +  0);
-	c++;	c &= 0xFFFFFFFF;
-	PUTU32(counter +  0, c);
-	}
-
-/* The input encrypted as though 128bit counter mode is being
- * used.  The extra state information to record how much of the
- * 128bit block we have used is contained in *num, and the
- * encrypted counter is kept in ecount_buf.  Both *num and
- * ecount_buf must be initialised with zeros before the first
- * call to Camellia_ctr128_encrypt().
- *
- * This algorithm assumes that the counter is in the x lower bits
- * of the IV (ivec), and that the application has full control over
- * overflow and the rest of the IV.  This implementation takes NO
- * responsability for checking that the counter doesn't overflow
- * into the rest of the IV when incremented.
- */
-void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const CAMELLIA_KEY *key,
-	unsigned char ivec[CAMELLIA_BLOCK_SIZE],
-	unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE],
-	unsigned int *num) 
-	{
-
-	unsigned int n;
-	unsigned long l=length;
-
-	assert(in && out && key && counter && num);
-	assert(*num < CAMELLIA_BLOCK_SIZE);
-
-	n = *num;
-
-	while (l--) 
-		{
-		if (n == 0) 
-			{
-			Camellia_encrypt(ivec, ecount_buf, key);
-			Camellia_ctr128_inc(ivec);
-			}
-		*(out++) = *(in++) ^ ecount_buf[n];
-		n = (n+1) % CAMELLIA_BLOCK_SIZE;
-		}
-
-	*num=n;
-	}
-
diff --git a/crypto/camellia/cmll_locl.h b/crypto/camellia/cmll_locl.h
deleted file mode 100644
index 2ac2e95..0000000
--- a/crypto/camellia/cmll_locl.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/* crypto/camellia/camellia_locl.h -*- mode:C; c-file-style: "eay" -*- */
-/* ====================================================================
- * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . 
- * ALL RIGHTS RESERVED.
- *
- * Intellectual Property information for Camellia:
- *     http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
- *
- * News Release for Announcement of Camellia open source:
- *     http://www.ntt.co.jp/news/news06e/0604/060413a.html
- *
- * The Camellia Code included herein is developed by
- * NTT (Nippon Telegraph and Telephone Corporation), and is contributed
- * to the OpenSSL project.
- *
- * The Camellia Code is licensed pursuant to the OpenSSL open source
- * license provided below.
- */
-/* ====================================================================
- * 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
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- */
-
-#ifndef HEADER_CAMELLIA_LOCL_H
-#define HEADER_CAMELLIA_LOCL_H
-
-#include "openssl/e_os2.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-typedef unsigned char u8;
-typedef unsigned int u32;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
-# define SWAP(x) ( _lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00 )
-# define GETU32(p) SWAP(*((u32 *)(p)))
-# define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
-# define CAMELLIA_SWAP4(x) (x = ( _lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) )
-
-#else /* not windows */
-# define GETU32(pt) (((u32)(pt)[0] << 24) \
-	^ ((u32)(pt)[1] << 16) \
-	^ ((u32)(pt)[2] <<  8) \
-	^ ((u32)(pt)[3]))
-
-# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); \
-	(ct)[1] = (u8)((st) >> 16); \
-	(ct)[2] = (u8)((st) >>  8); \
-	(ct)[3] = (u8)(st); }
-
-#if (defined (__GNUC__) && (defined(__x86_64__) || defined(__x86_64)))
-#define CAMELLIA_SWAP4(x) \
-  do{\
-    asm("bswap %1" : "+r" (x));\
-  }while(0)
-#else
-#define CAMELLIA_SWAP4(x) \
-   do{\
-     x = ((u32)x << 16) + ((u32)x >> 16);\
-     x = (((u32)x & 0xff00ff) << 8) + (((u32)x >> 8) & 0xff00ff);\
-   } while(0)
-#endif
-#endif
-
-#define COPY4WORD(dst, src)	 \
-	     do			 \
-		     {		 \
-		     (dst)[0]=(src)[0];		\
-		     (dst)[1]=(src)[1];		\
-		     (dst)[2]=(src)[2];		\
-		     (dst)[3]=(src)[3];		\
-		     }while(0)
-
-#define SWAP4WORD(word)				\
-   do						\
-	   {					\
-	   CAMELLIA_SWAP4((word)[0]);			\
-	   CAMELLIA_SWAP4((word)[1]);			\
-	   CAMELLIA_SWAP4((word)[2]);			\
-	   CAMELLIA_SWAP4((word)[3]);			\
-	   }while(0)
-
-#define XOR4WORD(a, b)/* a = a ^ b */		\
-   do						\
-	{					\
-	(a)[0]^=(b)[0];				\
-	(a)[1]^=(b)[1];				\
-	(a)[2]^=(b)[2];				\
-	(a)[3]^=(b)[3];				\
-	}while(0)
-
-#define XOR4WORD2(a, b, c)/* a = b ^ c */	\
-   do						\
-	{					\
-	(a)[0]=(b)[0]^(c)[0];			\
-	(a)[1]=(b)[1]^(c)[1];				\
-	(a)[2]=(b)[2]^(c)[2];				\
-	(a)[3]=(b)[3]^(c)[3];				\
-	}while(0)
-
-
-void camellia_setup128(const u8 *key, u32 *subkey);
-void camellia_setup192(const u8 *key, u32 *subkey);
-void camellia_setup256(const u8 *key, u32 *subkey);
-
-void camellia_encrypt128(const u32 *subkey, u32 *io);
-void camellia_decrypt128(const u32 *subkey, u32 *io);
-void camellia_encrypt256(const u32 *subkey, u32 *io);
-void camellia_decrypt256(const u32 *subkey, u32 *io);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* #ifndef HEADER_CAMELLIA_LOCL_H */
-
diff --git a/crypto/camellia/cmll_misc.c b/crypto/camellia/cmll_misc.c
deleted file mode 100644
index 2cd7aba..0000000
--- a/crypto/camellia/cmll_misc.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/* crypto/camellia/camellia_misc.c -*- mode:C; c-file-style: "eay" -*- */
-/* ====================================================================
- * 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
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- */
- 
-#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)
-		{
-		return -1;
-		}
-	
-	switch(bits)
-		{
-	case 128:
-		camellia_setup128(userKey, (unsigned int *)key->rd_key);
-		key->enc = camellia_encrypt128;
-		key->dec = camellia_decrypt128;
-		break;
-	case 192:
-		camellia_setup192(userKey, (unsigned int *)key->rd_key);
-		key->enc = camellia_encrypt256;
-		key->dec = camellia_decrypt256;
-		break;
-	case 256:
-		camellia_setup256(userKey, (unsigned int *)key->rd_key);
-		key->enc = camellia_encrypt256;
-		key->dec = camellia_decrypt256;
-		break;
-	default:
-		return -2;
-		}
-	
-	key->bitLength = bits;
-	return 0;
-	}
-
-void Camellia_encrypt(const unsigned char *in, unsigned char *out,
-	const CAMELLIA_KEY *key)
-	{
-	u32 tmp[CAMELLIA_BLOCK_SIZE/sizeof(u32)];
-	const union { long one; char little; } camellia_endian = {1};
-
-	memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
-	if (camellia_endian.little) SWAP4WORD(tmp);
-	key->enc(key->rd_key, tmp);
-	if (camellia_endian.little) SWAP4WORD(tmp);
-	memcpy(out, tmp, CAMELLIA_BLOCK_SIZE);
-	}
-
-void Camellia_decrypt(const unsigned char *in, unsigned char *out,
-	const CAMELLIA_KEY *key)
-	{
-	u32 tmp[CAMELLIA_BLOCK_SIZE/sizeof(u32)];
-	const union { long one; char little; } camellia_endian = {1};
-
-	memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
-	if (camellia_endian.little) SWAP4WORD(tmp);
-	key->dec(key->rd_key, tmp);
-	if (camellia_endian.little) SWAP4WORD(tmp);
-	memcpy(out, tmp, CAMELLIA_BLOCK_SIZE);
-	}
-
diff --git a/crypto/camellia/cmll_ofb.c b/crypto/camellia/cmll_ofb.c
deleted file mode 100644
index d89cf9f..0000000
--- a/crypto/camellia/cmll_ofb.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/* crypto/camellia/camellia_ofb.c -*- mode:C; c-file-style: "eay" -*- */
-/* ====================================================================
- * 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
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#ifndef CAMELLIA_DEBUG
-# ifndef NDEBUG
-#  define NDEBUG
-# endif
-#endif
-#include <assert.h>
-#include <openssl/camellia.h>
-#include "cmll_locl.h"
-
-/* The input and output encrypted as though 128bit ofb mode is being
- * used.  The extra state information to record how much of the
- * 128bit block we have used is contained in *num;
- */
-void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const CAMELLIA_KEY *key,
-	unsigned char *ivec, int *num) {
-
-	unsigned int n;
-	unsigned long l=length;
-
-	assert(in && out && key && ivec && num);
-
-	n = *num;
-
-	while (l--) {
-		if (n == 0) {
-			Camellia_encrypt(ivec, ivec, key);
-		}
-		*(out++) = *(in++) ^ ivec[n];
-		n = (n+1) % CAMELLIA_BLOCK_SIZE;
-	}
-
-	*num=n;
-}
diff --git a/crypto/comp/Makefile b/crypto/comp/Makefile
deleted file mode 100644
index 5d364b8..0000000
--- a/crypto/comp/Makefile
+++ /dev/null
@@ -1,108 +0,0 @@
-#
-# OpenSSL/crypto/comp/Makefile
-#
-
-DIR=	comp
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC= comp_lib.c comp_err.c \
-	c_rle.c c_zlib.c
-
-LIBOBJ=	comp_lib.o comp_err.o \
-	c_rle.o c_zlib.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= comp.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-depend:
-	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
-	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(LIBSRC)
-
-dclean:
-	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
-	mv -f Makefile.new $(MAKEFILE)
-
-clean:
-	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-c_rle.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-c_rle.o: ../../include/openssl/comp.h ../../include/openssl/crypto.h
-c_rle.o: ../../include/openssl/e_os2.h ../../include/openssl/obj_mac.h
-c_rle.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-c_rle.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-c_rle.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-c_rle.o: ../../include/openssl/symhacks.h c_rle.c
-c_zlib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-c_zlib.o: ../../include/openssl/comp.h ../../include/openssl/crypto.h
-c_zlib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-c_zlib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-c_zlib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-c_zlib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-c_zlib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-c_zlib.o: ../../include/openssl/symhacks.h c_zlib.c
-comp_err.o: ../../include/openssl/bio.h ../../include/openssl/comp.h
-comp_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-comp_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-comp_err.o: ../../include/openssl/opensslconf.h
-comp_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-comp_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-comp_err.o: ../../include/openssl/symhacks.h comp_err.c
-comp_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-comp_lib.o: ../../include/openssl/comp.h ../../include/openssl/crypto.h
-comp_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/obj_mac.h
-comp_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-comp_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-comp_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-comp_lib.o: ../../include/openssl/symhacks.h comp_lib.c
diff --git a/crypto/comp/c_zlib.c b/crypto/comp/c_zlib.c
index 8df7792..8adf35f 100644
--- a/crypto/comp/c_zlib.c
+++ b/crypto/comp/c_zlib.c
@@ -781,6 +781,7 @@
 	default:
 		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
 		break;
+
 		}
 
 	return ret;
diff --git a/crypto/comp/comp_err.c b/crypto/comp/comp_err.c
index 187d68b..661c94c 100644
--- a/crypto/comp/comp_err.c
+++ b/crypto/comp/comp_err.c
@@ -1,6 +1,6 @@
 /* crypto/comp/comp_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2008 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
diff --git a/crypto/conf/Makefile b/crypto/conf/Makefile
deleted file mode 100644
index ccd0721..0000000
--- a/crypto/conf/Makefile
+++ /dev/null
@@ -1,153 +0,0 @@
-#
-# OpenSSL/crypto/conf/Makefile
-#
-
-DIR=	conf
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC= conf_err.c conf_lib.c conf_api.c conf_def.c conf_mod.c \
-	 conf_mall.c conf_sap.c
-
-LIBOBJ=	conf_err.o conf_lib.o conf_api.o conf_def.o conf_mod.o \
-	conf_mall.o conf_sap.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= conf.h conf_api.h
-HEADER=	conf_def.h $(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-depend:
-	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
-	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(LIBSRC)
-
-dclean:
-	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
-	mv -f Makefile.new $(MAKEFILE)
-
-clean:
-	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-conf_api.o: ../../e_os.h ../../include/openssl/bio.h
-conf_api.o: ../../include/openssl/conf.h ../../include/openssl/conf_api.h
-conf_api.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-conf_api.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-conf_api.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-conf_api.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-conf_api.o: ../../include/openssl/symhacks.h conf_api.c
-conf_def.o: ../../e_os.h ../../include/openssl/bio.h
-conf_def.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
-conf_def.o: ../../include/openssl/conf_api.h ../../include/openssl/crypto.h
-conf_def.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-conf_def.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-conf_def.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-conf_def.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-conf_def.o: ../../include/openssl/symhacks.h ../cryptlib.h conf_def.c
-conf_def.o: conf_def.h
-conf_err.o: ../../include/openssl/bio.h ../../include/openssl/conf.h
-conf_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-conf_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-conf_err.o: ../../include/openssl/opensslconf.h
-conf_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-conf_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-conf_err.o: ../../include/openssl/symhacks.h conf_err.c
-conf_lib.o: ../../include/openssl/bio.h ../../include/openssl/conf.h
-conf_lib.o: ../../include/openssl/conf_api.h ../../include/openssl/crypto.h
-conf_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-conf_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-conf_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-conf_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-conf_lib.o: ../../include/openssl/symhacks.h conf_lib.c
-conf_mall.o: ../../e_os.h ../../include/openssl/asn1.h
-conf_mall.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-conf_mall.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-conf_mall.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
-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/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
-conf_mall.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-conf_mall.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-conf_mall.o: ../../include/openssl/x509_vfy.h ../cryptlib.h conf_mall.c
-conf_mod.o: ../../e_os.h ../../include/openssl/asn1.h
-conf_mod.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-conf_mod.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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
-conf_mod.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-conf_mod.o: ../../include/openssl/x509_vfy.h ../cryptlib.h conf_mod.c
-conf_sap.o: ../../e_os.h ../../include/openssl/asn1.h
-conf_sap.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-conf_sap.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-conf_sap.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
-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/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
-conf_sap.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-conf_sap.o: ../../include/openssl/x509_vfy.h ../cryptlib.h conf_sap.c
diff --git a/crypto/conf/README b/crypto/conf/README
index ca58d02..96e53b3 100644
--- a/crypto/conf/README
+++ b/crypto/conf/README
@@ -1,8 +1,3 @@
-WARNING WARNING WARNING!!!
-
-This stuff is experimental, may change radically or be deleted altogether
-before OpenSSL 0.9.7 release. You have been warned!
-
 Configuration modules. These are a set of modules which can perform
 various configuration functions.
 
@@ -13,7 +8,7 @@
 
 -----
 #default section
-openssl_init=init_section
+openssl_conf=init_section
 
 [init_section]
 
@@ -30,29 +25,27 @@
 other_stuff=other_value
 ----
 
-When this file is loaded a configuration module with the specified
-string (module* in the above example) is looked up and its init
-function called as:
+When this file is loaded a configuration module with the specified string
+(module* in the above example) is looked up and its init function called as:
 
 int conf_init_func(CONF_IMODULE *md, CONF *cnf);
 
-The function can then take whatever action is appropriate, for example
-further lookups based on the value. Multiple instances of the same 
-config module can be loaded.
+The function can then take whatever action is appropriate, for example further
+lookups based on the value. Multiple instances of the same config module can be
+loaded.
 
-When the application closes down the modules are cleaned up by calling
-an optional finish function:
+When the application closes down the modules are cleaned up by calling an
+optional finish function:
 
 void conf_finish_func(CONF_IMODULE *md);
 
 The finish functions are called in reverse order: that is the last module
 loaded is the first one cleaned up.
 
-If no module exists with a given name then an attempt is made to load
-a DSO with the supplied name. This might mean that "module3" attempts
-to load a DSO called libmodule3.so or module3.dll for example. An explicit
-DSO name can be given by including a separate section as in the module4 example
-above.
+If no module exists with a given name then an attempt is made to load a DSO
+with the supplied name. This might mean that "module3" attempts to load a DSO
+called libmodule3.so or module3.dll for example. An explicit DSO name can be
+given by including a separate section as in the module4 example above.
 
 The DSO is expected to at least contain an initialization function:
 
@@ -64,15 +57,17 @@
 
 Static modules can also be added using,
 
-int CONF_module_add(char *name, dso_mod_init_func *ifunc, dso_mod_finish_func *ffunc);
+int CONF_module_add(char *name, dso_mod_init_func *ifunc, dso_mod_finish_func
+*ffunc);
 
-where "name" is the name in the configuration file this function corresponds to.
+where "name" is the name in the configuration file this function corresponds
+to.
 
-A set of builtin modules (currently only an ASN1 non functional test module) can be 
-added by calling OPENSSL_load_builtin_modules(). 
+A set of builtin modules (currently only an ASN1 non functional test module)
+can be added by calling OPENSSL_load_builtin_modules(). 
 
-The function OPENSSL_config() is intended as a simple configuration function that
-any application can call to perform various default configuration tasks. It uses the
-file openssl.cnf in the usual locations.
+The function OPENSSL_config() is intended as a simple configuration function
+that any application can call to perform various default configuration tasks.
+It uses the file openssl.cnf in the usual locations.
 
 
diff --git a/crypto/conf/conf.h b/crypto/conf/conf.h
index 8aa06bc..c219997 100644
--- a/crypto/conf/conf.h
+++ b/crypto/conf/conf.h
@@ -79,8 +79,7 @@
 	} CONF_VALUE;
 
 DECLARE_STACK_OF(CONF_VALUE)
-DECLARE_STACK_OF(CONF_MODULE)
-DECLARE_STACK_OF(CONF_IMODULE)
+DECLARE_LHASH_OF(CONF_VALUE);
 
 struct conf_st;
 struct conf_method_st;
@@ -105,6 +104,9 @@
 typedef struct conf_imodule_st CONF_IMODULE;
 typedef struct conf_module_st CONF_MODULE;
 
+DECLARE_STACK_OF(CONF_MODULE)
+DECLARE_STACK_OF(CONF_IMODULE)
+
 /* DSO module function typedefs */
 typedef int conf_init_func(CONF_IMODULE *md, const CONF *cnf);
 typedef void conf_finish_func(CONF_IMODULE *md);
@@ -117,18 +119,23 @@
 #define CONF_MFLAGS_DEFAULT_SECTION	0x20
 
 int CONF_set_default_method(CONF_METHOD *meth);
-void CONF_set_nconf(CONF *conf,LHASH *hash);
-LHASH *CONF_load(LHASH *conf,const char *file,long *eline);
+void CONF_set_nconf(CONF *conf,LHASH_OF(CONF_VALUE) *hash);
+LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf,const char *file,
+				long *eline);
 #ifndef OPENSSL_NO_FP_API
-LHASH *CONF_load_fp(LHASH *conf, FILE *fp,long *eline);
+LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
+				   long *eline);
 #endif
-LHASH *CONF_load_bio(LHASH *conf, BIO *bp,long *eline);
-STACK_OF(CONF_VALUE) *CONF_get_section(LHASH *conf,const char *section);
-char *CONF_get_string(LHASH *conf,const char *group,const char *name);
-long CONF_get_number(LHASH *conf,const char *group,const char *name);
-void CONF_free(LHASH *conf);
-int CONF_dump_fp(LHASH *conf, FILE *out);
-int CONF_dump_bio(LHASH *conf, BIO *out);
+LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,long *eline);
+STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
+				       const char *section);
+char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf,const char *group,
+		      const char *name);
+long CONF_get_number(LHASH_OF(CONF_VALUE) *conf,const char *group,
+		     const char *name);
+void CONF_free(LHASH_OF(CONF_VALUE) *conf);
+int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out);
+int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out);
 
 void OPENSSL_config(const char *config_name);
 void OPENSSL_no_config(void);
@@ -140,7 +147,7 @@
 	{
 	CONF_METHOD *meth;
 	void *meth_data;
-	LHASH *data;
+	LHASH_OF(CONF_VALUE) *data;
 	};
 
 CONF *NCONF_new(CONF_METHOD *meth);
@@ -214,6 +221,7 @@
 #define CONF_F_CONF_LOAD_BIO				 102
 #define CONF_F_CONF_LOAD_FP				 103
 #define CONF_F_CONF_MODULES_LOAD			 116
+#define CONF_F_CONF_PARSE_LIST				 119
 #define CONF_F_DEF_LOAD					 120
 #define CONF_F_DEF_LOAD_BIO				 121
 #define CONF_F_MODULE_INIT				 115
@@ -233,6 +241,7 @@
 
 /* Reason codes. */
 #define CONF_R_ERROR_LOADING_DSO			 110
+#define CONF_R_LIST_CANNOT_BE_NULL			 115
 #define CONF_R_MISSING_CLOSE_SQUARE_BRACKET		 100
 #define CONF_R_MISSING_EQUAL_SIGN			 101
 #define CONF_R_MISSING_FINISH_FUNCTION			 111
diff --git a/crypto/conf/conf_api.c b/crypto/conf/conf_api.c
index 909d72b..22617e5 100644
--- a/crypto/conf/conf_api.c
+++ b/crypto/conf/conf_api.c
@@ -69,16 +69,12 @@
 #include <openssl/conf_api.h>
 #include "e_os.h"
 
-static void value_free_hash(CONF_VALUE *a, LHASH *conf);
-static void value_free_stack(CONF_VALUE *a,LHASH *conf);
-static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE *, LHASH *)
-static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_stack, CONF_VALUE *, LHASH *)
-/* We don't use function pointer casting or wrapper functions - but cast each
- * callback parameter inside the callback functions. */
-/* static unsigned long hash(CONF_VALUE *v); */
-static unsigned long hash(const void *v_void);
-/* static int cmp_conf(CONF_VALUE *a,CONF_VALUE *b); */
-static int cmp_conf(const void *a_void,const void *b_void);
+static void value_free_hash_doall_arg(CONF_VALUE *a,
+				      LHASH_OF(CONF_VALUE) *conf);
+static void value_free_stack_doall(CONF_VALUE *a);
+static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE,
+				    LHASH_OF(CONF_VALUE))
+static IMPLEMENT_LHASH_DOALL_FN(value_free_stack, CONF_VALUE)
 
 /* Up until OpenSSL 0.9.5a, this was get_section */
 CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section)
@@ -88,7 +84,7 @@
 	if ((conf == NULL) || (section == NULL)) return(NULL);
 	vv.name=NULL;
 	vv.section=(char *)section;
-	v=(CONF_VALUE *)lh_retrieve(conf->data,&vv);
+	v=lh_CONF_VALUE_retrieve(conf->data,&vv);
 	return(v);
 	}
 
@@ -118,7 +114,7 @@
 		return 0;
 		}
 
-	v = (CONF_VALUE *)lh_insert(conf->data, value);
+	v = lh_CONF_VALUE_insert(conf->data, value);
 	if (v != NULL)
 		{
 		(void)sk_CONF_VALUE_delete_ptr(ts,v);
@@ -141,24 +137,24 @@
 			{
 			vv.name=(char *)name;
 			vv.section=(char *)section;
-			v=(CONF_VALUE *)lh_retrieve(conf->data,&vv);
+			v=lh_CONF_VALUE_retrieve(conf->data,&vv);
 			if (v != NULL) return(v->value);
 			if (strcmp(section,"ENV") == 0)
 				{
-				p=Getenv(name);
+				p=getenv(name);
 				if (p != NULL) return(p);
 				}
 			}
 		vv.section="default";
 		vv.name=(char *)name;
-		v=(CONF_VALUE *)lh_retrieve(conf->data,&vv);
+		v=lh_CONF_VALUE_retrieve(conf->data,&vv);
 		if (v != NULL)
 			return(v->value);
 		else
 			return(NULL);
 		}
 	else
-		return(Getenv(name));
+		return(getenv(name));
 	}
 
 #if 0 /* There's no way to provide error checking with this function, so
@@ -182,79 +178,15 @@
 	}
 #endif
 
-int _CONF_new_data(CONF *conf)
+static unsigned long conf_value_hash(const CONF_VALUE *v)
 	{
-	if (conf == NULL)
-		{
-		return 0;
-		}
-	if (conf->data == NULL)
-		if ((conf->data = lh_new(hash, cmp_conf)) == NULL)
-			{
-			return 0;
-			}
-	return 1;
+	return (lh_strhash(v->section)<<2)^lh_strhash(v->name);
 	}
+static IMPLEMENT_LHASH_HASH_FN(conf_value, CONF_VALUE)
 
-void _CONF_free_data(CONF *conf)
-	{
-	if (conf == NULL || conf->data == NULL) return;
-
-	conf->data->down_load=0; /* evil thing to make sure the 'OPENSSL_free()'
-				  * works as expected */
-	lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(value_free_hash),
-			conf->data);
-
-	/* We now have only 'section' entries in the hash table.
-	 * Due to problems with */
-
-	lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(value_free_stack),
-			conf->data);
-	lh_free(conf->data);
-	}
-
-static void value_free_hash(CONF_VALUE *a, LHASH *conf)
-	{
-	if (a->name != NULL)
-		{
-		a=(CONF_VALUE *)lh_delete(conf,a);
-		}
-	}
-
-static void value_free_stack(CONF_VALUE *a, LHASH *conf)
-	{
-	CONF_VALUE *vv;
-	STACK *sk;
-	int i;
-
-	if (a->name != NULL) return;
-
-	sk=(STACK *)a->value;
-	for (i=sk_num(sk)-1; i>=0; i--)
-		{
-		vv=(CONF_VALUE *)sk_value(sk,i);
-		OPENSSL_free(vv->value);
-		OPENSSL_free(vv->name);
-		OPENSSL_free(vv);
-		}
-	if (sk != NULL) sk_free(sk);
-	OPENSSL_free(a->section);
-	OPENSSL_free(a);
-	}
-
-/* static unsigned long hash(CONF_VALUE *v) */
-static unsigned long hash(const void *v_void)
-	{
-	CONF_VALUE *v = (CONF_VALUE *)v_void;
-	return((lh_strhash(v->section)<<2)^lh_strhash(v->name));
-	}
-
-/* static int cmp_conf(CONF_VALUE *a, CONF_VALUE *b) */
-static int cmp_conf(const void *a_void,const  void *b_void)
+static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b)
 	{
 	int i;
-	CONF_VALUE *a = (CONF_VALUE *)a_void;
-	CONF_VALUE *b = (CONF_VALUE *)b_void;
 
 	if (a->section != b->section)
 		{
@@ -272,33 +204,93 @@
 	else
 		return((a->name == NULL)?-1:1);
 	}
+static IMPLEMENT_LHASH_COMP_FN(conf_value, CONF_VALUE)
+
+int _CONF_new_data(CONF *conf)
+	{
+	if (conf == NULL)
+		{
+		return 0;
+		}
+	if (conf->data == NULL)
+		if ((conf->data = lh_CONF_VALUE_new()) == NULL)
+			{
+			return 0;
+			}
+	return 1;
+	}
+
+void _CONF_free_data(CONF *conf)
+	{
+	if (conf == NULL || conf->data == NULL) return;
+
+	lh_CONF_VALUE_down_load(conf->data)=0; /* evil thing to make
+				  * sure the 'OPENSSL_free()' works as
+				  * expected */
+	lh_CONF_VALUE_doall_arg(conf->data,
+				LHASH_DOALL_ARG_FN(value_free_hash),
+				LHASH_OF(CONF_VALUE), conf->data);
+
+	/* We now have only 'section' entries in the hash table.
+	 * Due to problems with */
+
+	lh_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack));
+	lh_CONF_VALUE_free(conf->data);
+	}
+
+static void value_free_hash_doall_arg(CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf)
+	{
+	if (a->name != NULL)
+		(void)lh_CONF_VALUE_delete(conf,a);
+	}
+
+static void value_free_stack_doall(CONF_VALUE *a)
+	{
+	CONF_VALUE *vv;
+	STACK_OF(CONF_VALUE) *sk;
+	int i;
+
+	if (a->name != NULL) return;
+
+	sk=(STACK_OF(CONF_VALUE) *)a->value;
+	for (i=sk_CONF_VALUE_num(sk)-1; i>=0; i--)
+		{
+		vv=sk_CONF_VALUE_value(sk,i);
+		OPENSSL_free(vv->value);
+		OPENSSL_free(vv->name);
+		OPENSSL_free(vv);
+		}
+	if (sk != NULL) sk_CONF_VALUE_free(sk);
+	OPENSSL_free(a->section);
+	OPENSSL_free(a);
+	}
 
 /* Up until OpenSSL 0.9.5a, this was new_section */
 CONF_VALUE *_CONF_new_section(CONF *conf, const char *section)
 	{
-	STACK *sk=NULL;
+	STACK_OF(CONF_VALUE) *sk=NULL;
 	int ok=0,i;
 	CONF_VALUE *v=NULL,*vv;
 
-	if ((sk=sk_new_null()) == NULL)
+	if ((sk=sk_CONF_VALUE_new_null()) == NULL)
 		goto err;
-	if ((v=(CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL)
+	if ((v=OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL)
 		goto err;
 	i=strlen(section)+1;
-	if ((v->section=(char *)OPENSSL_malloc(i)) == NULL)
+	if ((v->section=OPENSSL_malloc(i)) == NULL)
 		goto err;
 
 	memcpy(v->section,section,i);
 	v->name=NULL;
 	v->value=(char *)sk;
 	
-	vv=(CONF_VALUE *)lh_insert(conf->data,v);
+	vv=lh_CONF_VALUE_insert(conf->data,v);
 	assert(vv == NULL);
 	ok=1;
 err:
 	if (!ok)
 		{
-		if (sk != NULL) sk_free(sk);
+		if (sk != NULL) sk_CONF_VALUE_free(sk);
 		if (v != NULL) OPENSSL_free(v);
 		v=NULL;
 		}
diff --git a/crypto/conf/conf_def.c b/crypto/conf/conf_def.c
index d8bce87..0b571b0 100644
--- a/crypto/conf/conf_def.c
+++ b/crypto/conf/conf_def.c
@@ -129,7 +129,7 @@
 	{
 	CONF *ret;
 
-	ret = (CONF *)OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *));
+	ret = OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *));
 	if (ret)
 		if (meth->init(ret) == 0)
 			{
@@ -145,7 +145,7 @@
 		return 0;
 
 	conf->meth = &default_method;
-	conf->meth_data = (void *)CONF_type_default;
+	conf->meth_data = CONF_type_default;
 	conf->data = NULL;
 
 	return 1;
@@ -722,7 +722,7 @@
 	return(p);
 	}
 
-static void dump_value(CONF_VALUE *a, BIO *out)
+static void dump_value_doall_arg(CONF_VALUE *a, BIO *out)
 	{
 	if (a->name)
 		BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value);
@@ -730,11 +730,12 @@
 		BIO_printf(out, "[[%s]]\n", a->section);
 	}
 
-static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE *, BIO *)
+static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE, BIO)
 
 static int def_dump(const CONF *conf, BIO *out)
 	{
-	lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value), out);
+	lh_CONF_VALUE_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value),
+				BIO, out);
 	return 1;
 	}
 
diff --git a/crypto/conf/conf_err.c b/crypto/conf/conf_err.c
index a16a5e0..25bb5dc 100644
--- a/crypto/conf/conf_err.c
+++ b/crypto/conf/conf_err.c
@@ -1,6 +1,6 @@
 /* crypto/conf/conf_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
@@ -75,6 +75,7 @@
 {ERR_FUNC(CONF_F_CONF_LOAD_BIO),	"CONF_load_bio"},
 {ERR_FUNC(CONF_F_CONF_LOAD_FP),	"CONF_load_fp"},
 {ERR_FUNC(CONF_F_CONF_MODULES_LOAD),	"CONF_modules_load"},
+{ERR_FUNC(CONF_F_CONF_PARSE_LIST),	"CONF_parse_list"},
 {ERR_FUNC(CONF_F_DEF_LOAD),	"DEF_LOAD"},
 {ERR_FUNC(CONF_F_DEF_LOAD_BIO),	"DEF_LOAD_BIO"},
 {ERR_FUNC(CONF_F_MODULE_INIT),	"MODULE_INIT"},
@@ -97,6 +98,7 @@
 static ERR_STRING_DATA CONF_str_reasons[]=
 	{
 {ERR_REASON(CONF_R_ERROR_LOADING_DSO)    ,"error loading dso"},
+{ERR_REASON(CONF_R_LIST_CANNOT_BE_NULL)  ,"list cannot be null"},
 {ERR_REASON(CONF_R_MISSING_CLOSE_SQUARE_BRACKET),"missing close square bracket"},
 {ERR_REASON(CONF_R_MISSING_EQUAL_SIGN)   ,"missing equal sign"},
 {ERR_REASON(CONF_R_MISSING_FINISH_FUNCTION),"missing finish function"},
diff --git a/crypto/conf/conf_lib.c b/crypto/conf/conf_lib.c
index 2a3399d..54046de 100644
--- a/crypto/conf/conf_lib.c
+++ b/crypto/conf/conf_lib.c
@@ -69,7 +69,7 @@
 
 /* Init a 'CONF' structure from an old LHASH */
 
-void CONF_set_nconf(CONF *conf, LHASH *hash)
+void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash)
 	{
 	if (default_CONF_method == NULL)
 		default_CONF_method = NCONF_default();
@@ -87,9 +87,10 @@
 	return 1;
 	}
 
-LHASH *CONF_load(LHASH *conf, const char *file, long *eline)
+LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file,
+				long *eline)
 	{
-	LHASH *ltmp;
+	LHASH_OF(CONF_VALUE) *ltmp;
 	BIO *in=NULL;
 
 #ifdef OPENSSL_SYS_VMS
@@ -110,10 +111,11 @@
 	}
 
 #ifndef OPENSSL_NO_FP_API
-LHASH *CONF_load_fp(LHASH *conf, FILE *fp,long *eline)
+LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
+				   long *eline)
 	{
 	BIO *btmp;
-	LHASH *ltmp;
+	LHASH_OF(CONF_VALUE) *ltmp;
 	if(!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) {
 		CONFerr(CONF_F_CONF_LOAD_FP,ERR_R_BUF_LIB);
 		return NULL;
@@ -124,7 +126,8 @@
 	}
 #endif
 
-LHASH *CONF_load_bio(LHASH *conf, BIO *bp,long *eline)
+LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,
+				    long *eline)
 	{
 	CONF ctmp;
 	int ret;
@@ -137,7 +140,8 @@
 	return NULL;
 	}
 
-STACK_OF(CONF_VALUE) *CONF_get_section(LHASH *conf,const char *section)
+STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
+				       const char *section)
 	{
 	if (conf == NULL)
 		{
@@ -151,7 +155,8 @@
 		}
 	}
 
-char *CONF_get_string(LHASH *conf,const char *group,const char *name)
+char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf,const char *group,
+		      const char *name)
 	{
 	if (conf == NULL)
 		{
@@ -165,7 +170,8 @@
 		}
 	}
 
-long CONF_get_number(LHASH *conf,const char *group,const char *name)
+long CONF_get_number(LHASH_OF(CONF_VALUE) *conf,const char *group,
+		     const char *name)
 	{
 	int status;
 	long result = 0;
@@ -189,7 +195,7 @@
 	return result;
 	}
 
-void CONF_free(LHASH *conf)
+void CONF_free(LHASH_OF(CONF_VALUE) *conf)
 	{
 	CONF ctmp;
 	CONF_set_nconf(&ctmp, conf);
@@ -197,7 +203,7 @@
 	}
 
 #ifndef OPENSSL_NO_FP_API
-int CONF_dump_fp(LHASH *conf, FILE *out)
+int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out)
 	{
 	BIO *btmp;
 	int ret;
@@ -212,7 +218,7 @@
 	}
 #endif
 
-int CONF_dump_bio(LHASH *conf, BIO *out)
+int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out)
 	{
 	CONF ctmp;
 	CONF_set_nconf(&ctmp, conf);
diff --git a/crypto/conf/conf_mall.c b/crypto/conf/conf_mall.c
index 1cc1fd5..c6f4cb2 100644
--- a/crypto/conf/conf_mall.c
+++ b/crypto/conf/conf_mall.c
@@ -63,7 +63,6 @@
 #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
@@ -77,6 +76,5 @@
 #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 ee9c677..df1642a 100644
--- a/crypto/conf/conf_mod.c
+++ b/crypto/conf/conf_mod.c
@@ -582,8 +582,14 @@
 	{
 	int ret;
 	const char *lstart, *tmpend, *p;
-	lstart = list_;
 
+	if(list_ == NULL)
+		{
+		CONFerr(CONF_F_CONF_PARSE_LIST, CONF_R_LIST_CANNOT_BE_NULL);
+		return 0;
+		}
+
+	lstart = list_;
 	for(;;)
 		{
 		if (nospc)
diff --git a/crypto/cpt_err.c b/crypto/cpt_err.c
index 9fd41ff..139b928 100644
--- a/crypto/cpt_err.c
+++ b/crypto/cpt_err.c
@@ -1,6 +1,6 @@
 /* crypto/cpt_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c
index 497d003..9a39d7e 100644
--- a/crypto/cryptlib.c
+++ b/crypto/cryptlib.c
@@ -1,6 +1,6 @@
 /* crypto/cryptlib.c */
 /* ====================================================================
- * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -121,17 +121,279 @@
 static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */
 #endif
 
+DECLARE_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",
+	"fips",
+	"fips2",
+#if CRYPTO_NUM_LOCKS != 41
+# 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_OF(OPENSSL_STRING) *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;
+	const char *file,int line)=0;
 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;
+	int type,const char *file,int line)=0;
+#ifndef OPENSSL_NO_DEPRECATED
+static unsigned long (MS_FAR *id_callback)(void)=0;
+#endif
+static void (MS_FAR *threadid_callback)(CRYPTO_THREADID *)=0;
+static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
+	(const char *file,int line)=0;
+static void (MS_FAR *dynlock_lock_callback)(int mode,
+	struct CRYPTO_dynlock_value *l, const char *file,int line)=0;
+static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l,
+	const char *file,int line)=0;
+
+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
+	 * any 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_OPENSSL_STRING_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_OPENSSL_STRING_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)
 	{
@@ -156,6 +418,108 @@
 	add_lock_callback=func;
 	}
 
+/* the memset() here and in set_pointer() seem overkill, but for the sake of
+ * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause two
+ * "equal" THREADID structs to not be memcmp()-identical. */
+void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val)
+	{
+	memset(id, 0, sizeof(*id));
+	id->val = val;
+	}
+
+static const unsigned char hash_coeffs[] = { 3, 5, 7, 11, 13, 17, 19, 23 };
+void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr)
+	{
+	unsigned char *dest = (void *)&id->val;
+	unsigned int accum = 0;
+	unsigned char dnum = sizeof(id->val);
+
+	memset(id, 0, sizeof(*id));
+	id->ptr = ptr;
+	if (sizeof(id->val) >= sizeof(id->ptr))
+		{
+		/* 'ptr' can be embedded in 'val' without loss of uniqueness */
+		id->val = (unsigned long)id->ptr;
+		return;
+		}
+	/* hash ptr ==> val. Each byte of 'val' gets the mod-256 total of a
+	 * linear function over the bytes in 'ptr', the co-efficients of which
+	 * are a sequence of low-primes (hash_coeffs is an 8-element cycle) -
+	 * the starting prime for the sequence varies for each byte of 'val'
+	 * (unique polynomials unless pointers are >64-bit). For added spice,
+	 * the totals accumulate rather than restarting from zero, and the index
+	 * of the 'val' byte is added each time (position dependence). If I was
+	 * a black-belt, I'd scan big-endian pointers in reverse to give
+	 * low-order bits more play, but this isn't crypto and I'd prefer nobody
+	 * mistake it as such. Plus I'm lazy. */
+	while (dnum--)
+		{
+		const unsigned char *src = (void *)&id->ptr;
+		unsigned char snum = sizeof(id->ptr);
+		while (snum--)
+			accum += *(src++) * hash_coeffs[(snum + dnum) & 7];
+		accum += dnum;
+		*(dest++) = accum & 255;
+		}
+	}
+
+int CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *))
+	{
+	if (threadid_callback)
+		return 0;
+	threadid_callback = func;
+	return 1;
+	}
+
+void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *)
+	{
+	return threadid_callback;
+	}
+
+void CRYPTO_THREADID_current(CRYPTO_THREADID *id)
+	{
+	if (threadid_callback)
+		{
+		threadid_callback(id);
+		return;
+		}
+#ifndef OPENSSL_NO_DEPRECATED
+	/* If the deprecated callback was set, fall back to that */
+	if (id_callback)
+		{
+		CRYPTO_THREADID_set_numeric(id, id_callback());
+		return;
+		}
+#endif
+	/* Else pick a backup */
+#ifdef OPENSSL_SYS_WIN16
+	CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentTask());
+#elif defined(OPENSSL_SYS_WIN32)
+	CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentThreadId());
+#elif defined(OPENSSL_SYS_BEOS)
+	CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL));
+#else
+	/* For everything else, default to using the address of 'errno' */
+	CRYPTO_THREADID_set_pointer(id, &errno);
+#endif
+	}
+
+int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b)
+	{
+	return memcmp(a, b, sizeof(*a));
+	}
+
+void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src)
+	{
+	memcpy(dest, src, sizeof(*src));
+	}
+
+unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id)
+	{
+	return id->val;
+	}
+
+#ifndef OPENSSL_NO_DEPRECATED
 unsigned long (*CRYPTO_get_id_callback(void))(void)
 	{
 	return(id_callback);
@@ -178,6 +542,8 @@
 		ret=(unsigned long)GetCurrentThreadId();
 #elif defined(GETPID_IS_MEANINGLESS)
 		ret=1L;
+#elif defined(OPENSSL_SYS_BEOS)
+		ret=(unsigned long)find_thread(NULL);
 #else
 		ret=(unsigned long)getpid();
 #endif
@@ -186,19 +552,13 @@
 		ret=id_callback();
 	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;
-	}
+#endif
 
 void CRYPTO_lock(int mode, int type, const char *file, int line)
 	{
 #ifdef LOCK_DEBUG
 		{
+		CRYPTO_THREADID id;
 		char *rw_text,*operation_text;
 
 		if (mode & CRYPTO_LOCK)
@@ -215,15 +575,25 @@
 		else
 			rw_text="ERROR";
 
+		CRYPTO_THREADID_current(&id);
 		fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n",
-			CRYPTO_thread_id(), rw_text, operation_text,
+			CRYPTO_THREADID_hash(&id), rw_text, operation_text,
 			CRYPTO_get_lock_name(type), file, line);
 		}
 #endif
 	if (type < 0)
 		{
-		if (do_dynlock_cb)
-			do_dynlock_cb(mode, type, file, 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);
+			}
 		}
 	else
 		if (locking_callback != NULL)
@@ -243,11 +613,14 @@
 
 		ret=add_lock_callback(pointer,amount,type,file,line);
 #ifdef LOCK_DEBUG
+		{
+		CRYPTO_THREADID id;
+		CRYPTO_THREADID_current(&id);
 		fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
-			CRYPTO_thread_id(),
-			before,amount,ret,
+			CRYPTO_THREADID_hash(&id), before,amount,ret,
 			CRYPTO_get_lock_name(type),
 			file,line);
+		}
 #endif
 		}
 	else
@@ -256,11 +629,15 @@
 
 		ret= *pointer+amount;
 #ifdef LOCK_DEBUG
+		{
+		CRYPTO_THREADID id;
+		CRYPTO_THREADID_current(&id);
 		fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
-			CRYPTO_thread_id(),
+			CRYPTO_THREADID_hash(&id),
 			*pointer,amount,ret,
 			CRYPTO_get_lock_name(type),
 			file,line);
+		}
 #endif
 		*pointer=ret;
 		CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line);
@@ -268,6 +645,18 @@
 	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_OPENSSL_STRING_num(app_locks))
+		return("ERROR");
+	else
+		return(sk_OPENSSL_STRING_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(_M_X64)
@@ -301,70 +690,16 @@
 unsigned long *OPENSSL_ia32cap_loc(void) { return NULL; }
 #endif
 int OPENSSL_NONPIC_relocated = 0;
-#if !defined(OPENSSL_CPUID_SETUP)
+#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
 void OPENSSL_cpuid_setup(void) {}
 #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>
+/* this has side-effect of _WIN32 getting defined, which otherwise
+ * is mutually exclusive with __CYGWIN__... */
 #endif
 
 /* All we really need to do is remove the 'error' state when a thread
@@ -405,10 +740,9 @@
 	}
 #endif
 
-#endif
-
 #if defined(_WIN32) && !defined(__CYGWIN__)
 #include <tchar.h>
+#include <signal.h>
 
 #if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
 int OPENSSL_isservice(void)
@@ -539,7 +873,13 @@
 	OPENSSL_showfatal(
 		"%s(%d): OpenSSL internal error, assertion failed: %s\n",
 		file,line,assertion);
+#if !defined(_WIN32) || defined(__CYGWIN__)
 	abort();
+#else
+	/* Win32 abort() customarily shows a dialog, but we just did that... */
+	raise(SIGABRT);
+	_exit(3);
+#endif
 	}
 
 void *OPENSSL_stderr(void)	{ return stderr; }
diff --git a/crypto/crypto-lib.com b/crypto/crypto-lib.com
index 99609d0..8fa56dd 100644
--- a/crypto/crypto-lib.com
+++ b/crypto/crypto-lib.com
@@ -82,13 +82,13 @@
 $!
 $ ENCRYPT_TYPES = "Basic,"+ -
 		  "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,"+ -
+		  "MD2,MD4,MD5,SHA,MDC2,HMAC,RIPEMD,WHRLPOOL,"+ -
+		  "DES,AES,RC2,RC4,RC5,IDEA,BF,CAST,CAMELLIA,SEED,MODES,"+ -
+		  "BN,EC,RSA,DSA,ECDSA,DH,ECDH,DSO,ENGINE,"+ -
 		  "BUFFER,BIO,STACK,LHASH,RAND,ERR,"+ -
-		  "EVP,EVP_2,ASN1,ASN1_2,PEM,X509,X509V3,"+ -
+		  "EVP,EVP_2,EVP_3,ASN1,ASN1_2,PEM,X509,X509V3,"+ -
 		  "CONF,TXT_DB,PKCS7,PKCS12,COMP,OCSP,UI,KRB5,"+ -
-		  "STORE,CMS,PQUEUE,JPAKE"
+		  "STORE,CMS,PQUEUE,TS,JPAKE"
 $! Define The OBJ Directory.
 $!
 $ OBJ_DIR := SYS$DISK:[-.'ARCH'.OBJ.CRYPTO]
@@ -166,15 +166,16 @@
 $ APPS_DES = "DES/DES,CBC3_ENC"
 $ APPS_PKCS7 = "ENC/ENC;DEC/DEC;SIGN/SIGN;VERIFY/VERIFY,EXAMPLE"
 $
-$ 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_ = "cryptlib,mem,mem_clr,mem_dbg,cversion,ex_data,cpt_err,ebcdic,uid,o_time,o_str,o_dir"
 $ LIB_MD2 = "md2_dgst,md2_one"
 $ LIB_MD4 = "md4_dgst,md4_one"
 $ LIB_MD5 = "md5_dgst,md5_one"
 $ LIB_SHA = "sha_dgst,sha1dgst,sha_one,sha1_one,sha256,sha512"
 $ LIB_MDC2 = "mdc2dgst,mdc2_one"
-$ LIB_HMAC = "hmac"
+$ LIB_HMAC = "hmac,hm_ameth,hm_pmeth"
 $ LIB_RIPEMD = "rmd_dgst,rmd_one"
-$ LIB_DES = "des_lib,set_key,ecb_enc,cbc_enc,"+ -
+$ LIB_WHRLPOOL = "wp_dgst,wp_block"
+$ LIB_DES = "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,"+ -
@@ -189,7 +190,8 @@
 $ LIB_CAST = "c_skey,c_ecb,c_enc,c_cfb64,c_ofb64"
 $ LIB_CAMELLIA = "camellia,cmll_misc,cmll_ecb,cmll_cbc,cmll_ofb,"+ -
 	"cmll_cfb,cmll_ctr"
-$ LIB_SEED = "seed,seed_cbc,seed_ecb,seed_cfb,seed_ofb"
+$ LIB_SEED = "seed,seed_ecb,seed_cbc,seed_cfb,seed_ofb"
+$ LIB_MODES = "cbc128,ctr128,cfb128,ofb128"
 $ LIB_BN_ASM = "[.asm]vms.mar,vms-helper"
 $ IF F$TRNLNM("OPENSSL_NO_ASM") .OR. ARCH .NES. "VAX" THEN -
      LIB_BN_ASM = "bn_asm"
@@ -197,28 +199,30 @@
 	"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_x931p,bn_const,bn_opt"
+	"bn_depr,bn_const"
 $ 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"
+	"ec2_smpl,ec2_mult,ec_ameth,ec_pmeth,eck_prn"
 $ 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_x931g,rsa_asn1,rsa_depr,rsa_eng"
+	"rsa_pss,rsa_x931,rsa_asn1,rsa_depr,rsa_ameth,rsa_prn,"+ -
+	"rsa_pmeth"
 $ LIB_DSA = "dsa_gen,dsa_key,dsa_lib,dsa_asn1,dsa_vrf,dsa_sign,"+ -
-	"dsa_err,dsa_ossl,dsa_depr,dsa_utl"
+	"dsa_err,dsa_ossl,dsa_depr,dsa_ameth,dsa_pmeth,dsa_prn"
 $ 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_DH = "dh_asn1,dh_gen,dh_key,dh_lib,dh_check,dh_err,dh_depr,"+ -
+	"dh_ameth,dh_pmeth,dh_prn"
 $ LIB_ECDH = "ech_lib,ech_ossl,ech_key,ech_err"
 $ LIB_DSO = "dso_dl,dso_dlfcn,dso_err,dso_lib,dso_null,"+ -
-	"dso_openssl,dso_win32,dso_vms"
+	"dso_openssl,dso_win32,dso_vms,dso_beos"
 $ LIB_ENGINE = "eng_err,eng_lib,eng_list,eng_init,eng_ctrl,"+ -
 	"eng_table,eng_pkey,eng_fat,eng_all,"+ -
 	"tb_rsa,tb_dsa,tb_ecdsa,tb_dh,tb_ecdh,tb_rand,tb_store,"+ -
-	"tb_cipher,tb_digest,"+ -
-	"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_str,buf_err"
+	"tb_cipher,tb_digest,tb_pkmeth,tb_asnmth,"+ -
+	"eng_openssl,eng_dyn,eng_cnf,eng_cryptodev"
+$ 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_BIO = "bio_lib,bio_cb,bio_err,"+ -
 	"bss_mem,bss_null,bss_fd,"+ -
 	"bss_file,bss_sock,bss_conn,"+ -
@@ -230,33 +234,34 @@
 $ LIB_LHASH = "lhash,lh_stats"
 $ LIB_RAND = "md_rand,randfile,rand_lib,rand_err,rand_egd,"+ -
 	"rand_vms"
-$ 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,dig_eng,evp_enc,evp_key,evp_acnf,evp_cnf,"+ -
+$ LIB_ERR = "err,err_all,err_prn"
+$ LIB_OBJECTS = "o_names,obj_dat,obj_lib,obj_err,obj_xref"
+$ LIB_EVP = "encode,digest,evp_enc,evp_key,evp_acnf,"+ -
 	"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," + -
+	"e_xcbc_d,e_rc2,e_cast,e_rc5"
+$ LIB_EVP_2 = "m_null,m_md2,m_md4,m_md5,m_sha,m_sha1,m_wp," + -
 	"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_EVP_3 = "e_old,pmeth_lib,pmeth_fn,pmeth_gn,m_sigver"
 $ 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,"+ -
 	"x_algor,x_val,x_pubkey,x_sig,x_req,x_attrib,x_bignum,"+ -
 	"x_long,x_name,x_x509,x_x509a,x_crl,x_info,x_spki,nsseq,"+ -
-	"d2i_pu,d2i_pr,i2d_pu,i2d_pr"
+	"x_nx509,d2i_pu,d2i_pr,i2d_pu,i2d_pr"
 $ LIB_ASN1_2 = "t_req,t_x509,t_x509a,t_crl,t_pkey,t_spki,t_bitst,"+ -
 	"tasn_new,tasn_fre,tasn_enc,tasn_dec,tasn_utl,tasn_typ,"+ -
+	"tasn_prn,ameth_lib,"+ -
 	"f_int,f_string,n_pkey,"+ -
-	"f_enum,a_hdr,x_pkey,a_bool,x_exten,asn_mime,"+ -
-	"asn1_gen,asn1_par,asn1_lib,asn1_err,a_meth,a_bytes,a_strnid,"+ -
+	"f_enum,x_pkey,a_bool,x_exten,bio_asn1,bio_ndef,asn_mime,"+ -
+	"asn1_gen,asn1_par,asn1_lib,asn1_err,a_bytes,a_strnid,"+ -
 	"evp_asn1,asn_pack,p5_pbe,p5_pbev2,p8_pkey,asn_moid"
 $ LIB_PEM = "pem_sign,pem_seal,pem_info,pem_lib,pem_all,pem_err,"+ -
-	"pem_x509,pem_xaux,pem_oth,pem_pk8,pem_pkey"
+	"pem_x509,pem_xaux,pem_oth,pem_pk8,pem_pkey,pvkfmt"
 $ LIB_X509 = "x509_def,x509_d2,x509_r2x,x509_cmp,"+ -
 	"x509_obj,x509_req,x509spki,x509_vfy,"+ -
 	"x509_set,x509cset,x509rset,x509_err,"+ -
@@ -272,7 +277,7 @@
 $ LIB_CONF = "conf_err,conf_lib,conf_api,conf_def,conf_mod,conf_mall,conf_sap"
 $ LIB_TXT_DB = "txt_db"
 $ LIB_PKCS7 = "pk7_asn1,pk7_lib,pkcs7err,pk7_doit,pk7_smime,pk7_attr,"+ -
-	"pk7_mime"
+	"pk7_mime,bio_pk7"
 $ LIB_PKCS12 = "p12_add,p12_asn,p12_attr,p12_crpt,p12_crt,p12_decr,"+ -
 	"p12_init,p12_key,p12_kiss,p12_mutl,"+ -
 	"p12_utl,p12_npas,pk12err,p12_p8d,p12_p8e"
@@ -287,6 +292,9 @@
 $ 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_TS = "ts_err,ts_req_utils,ts_req_print,ts_rsp_utils,ts_rsp_print,"+ -
+	"ts_rsp_sign,ts_rsp_verify,ts_verify_ctx,ts_lib,ts_conf,"+ -
+	"ts_asn1"
 $ LIB_JPAKE = "jpake,jpake_err"
 $!
 $! Setup exceptional compilations
@@ -1026,7 +1034,7 @@
 	 THEN CC = "CC/DECC"
 $     CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/STANDARD=ANSI89" + -
            "/NOLIST/PREFIX=ALL" + -
-	   "/INCLUDE=(SYS$DISK:[],SYS$DISK:[.''ARCH'],SYS$DISK:[-],SYS$DISK:[.ENGINE.VENDOR_DEFNS],SYS$DISK:[.EVP])" + -
+	   "/INCLUDE=(SYS$DISK:[],SYS$DISK:[.''ARCH'],SYS$DISK:[-],SYS$DISK:[.ENGINE.VENDOR_DEFNS],SYS$DISK:[.EVP],SYS$DISK:[.ASN1])" + -
 	   CCEXTRAFLAGS
 $!
 $!    Define The Linker Options File Name.
@@ -1060,7 +1068,7 @@
 $     ENDIF
 $     IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
 $     CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
-	   "/INCLUDE=(SYS$DISK:[],SYS$DISK:[.''ARCH'],SYS$DISK:[-],SYS$DISK:[.ENGINE.VENDOR_DEFNS])" + -
+	   "/INCLUDE=(SYS$DISK:[],SYS$DISK:[.''ARCH'],SYS$DISK:[-],SYS$DISK:[.ENGINE.VENDOR_DEFNS],SYS$DISK:[.EVP],SYS$DISK:[.ASN1])" + -
 	   CCEXTRAFLAGS
 $     CCDEFS = """VAXC""," + CCDEFS
 $!
@@ -1092,7 +1100,7 @@
 $!    Use GNU C...
 $!
 $     CC = "GCC/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
-	   "/INCLUDE=(SYS$DISK:[],SYS$DISK:[.''ARCH'],SYS$DISK:[-],SYS$DISK:[.ENGINE.VENDOR_DEFNS])" + -
+	   "/INCLUDE=(SYS$DISK:[],SYS$DISK:[.''ARCH'],SYS$DISK:[-],SYS$DISK:[.ENGINE.VENDOR_DEFNS],SYS$DISK:[.EVP],SYS$DISK:[.ASN1])" + -
 	   CCEXTRAFLAGS
 $!
 $!    Define The Linker Options File Name.
diff --git a/crypto/crypto.h b/crypto/crypto.h
index 0e4fb07..b0360ce 100644
--- a/crypto/crypto.h
+++ b/crypto/crypto.h
@@ -1,6 +1,6 @@
 /* crypto/crypto.h */
 /* ====================================================================
- * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -219,13 +219,9 @@
 #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
@@ -288,9 +284,10 @@
 
 struct crypto_ex_data_st
 	{
-	STACK *sk;
+	STACK_OF(void) *sk;
 	int dummy; /* gcc is screwing up this data structure :-( */
 	};
+DECLARE_STACK_OF(void)
 
 /* This stuff is basically class callback functions
  * The current classes are SSL_CTX, SSL, SSL_SESSION, and a few more */
@@ -347,7 +344,14 @@
 
 /* Set standard debugging functions (not done by default
  * unless CRYPTO_MDEBUG is defined) */
-void CRYPTO_malloc_debug_init(void);
+#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)
 
 int CRYPTO_mem_ctrl(int mode);
 int CRYPTO_is_mem_check_on(void);
@@ -420,16 +424,32 @@
 					      const char *file, int line));
 int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
 					  const char *file,int line);
+
+/* Don't use this structure directly. */
+typedef struct crypto_threadid_st
+	{
+	void *ptr;
+	unsigned long val;
+	} CRYPTO_THREADID;
+/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */
+void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val);
+void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
+int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *));
+void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *);
+void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
+int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b);
+void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src);
+unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id);
+#ifndef OPENSSL_NO_DEPRECATED
 void CRYPTO_set_id_callback(unsigned long (*func)(void));
 unsigned long (*CRYPTO_get_id_callback(void))(void);
 unsigned long CRYPTO_thread_id(void);
+#endif
+
 const char *CRYPTO_get_lock_name(int type);
 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);
@@ -454,10 +474,6 @@
 				   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),
@@ -514,9 +530,6 @@
 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 *);
@@ -534,69 +547,12 @@
 #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
  * made after this point may be overwritten when the script is next run.
  */
 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
deleted file mode 100644
index 786e688..0000000
--- a/crypto/des/Makefile
+++ /dev/null
@@ -1,297 +0,0 @@
-#
-# OpenSSL/crypto/des/Makefile
-#
-
-DIR=	des
-TOP=	../..
-CC=	cc
-CPP=	$(CC) -E
-INCLUDES=-I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-RANLIB=		ranlib
-DES_ENC=	des_enc.o fcrypt_b.o
-# or use
-#DES_ENC=	dx86-elf.o yx86-elf.o
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-ASFLAGS= $(INCLUDES) $(ASFLAG)
-AFLAGS= $(ASFLAGS)
-
-GENERAL=Makefile
-TEST=destest.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-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  \
-	des_enc.c fcrypt_b.c \
-	xcbc_enc.c \
-	str2key.c  cfb64ede.c ofb64ede.c ede_cbcm_enc.c des_old.c des_old2.c \
-	read2pwd.c
-
-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 \
-	${DES_ENC} \
-	fcrypt.o xcbc_enc.o rpc_enc.o  cbc_cksm.o \
-	ede_cbcm_enc.o des_old.o des_old2.o read2pwd.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= des.h des_old.h
-HEADER=	des_locl.h rpc_des.h spr.h des_ver.h $(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-des: des.o cbc3_enc.o lib
-	$(CC) $(CFLAGS) -o des des.o cbc3_enc.o $(LIB)
-
-des_enc-sparc.S:	asm/des_enc.m4
-	m4 -B 8192 asm/des_enc.m4 > des_enc-sparc.S
-
-# ELF
-dx86-elf.s:	asm/des-586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
-	(cd asm; $(PERL) des-586.pl elf $(CFLAGS) > ../$@)
-yx86-elf.s:	asm/crypt586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
-	(cd asm; $(PERL) crypt586.pl elf $(CFLAGS) > ../$@)
-# COFF
-dx86-cof.s: asm/des-586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
-	(cd asm; $(PERL) des-586.pl coff $(CFLAGS) > ../$@)
-yx86-cof.s: asm/crypt586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
-	(cd asm; $(PERL) crypt586.pl coff $(CFLAGS) > ../$@)
-# a.out
-dx86-out.s: asm/des-586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
-	(cd asm; $(PERL) des-586.pl a.out $(CFLAGS) > ../$@)
-yx86-out.s: asm/crypt586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
-	(cd asm; $(PERL) crypt586.pl a.out $(CFLAGS) > ../$@)
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-# We need to use force because 'install' matches 'INSTALL' on case
-# insensitive systems
-FRC.install:
-install: FRC.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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-cbc_cksm.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-cbc_cksm.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-cbc_cksm.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-cbc_cksm.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-cbc_cksm.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-cbc_cksm.o: cbc_cksm.c des_locl.h
-cbc_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-cbc_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-cbc_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-cbc_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-cbc_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-cbc_enc.o: cbc_enc.c des_locl.h ncbc_enc.c
-cfb64ede.o: ../../e_os.h ../../include/openssl/des.h
-cfb64ede.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
-cfb64ede.o: ../../include/openssl/opensslconf.h
-cfb64ede.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-cfb64ede.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-cfb64ede.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-cfb64ede.o: cfb64ede.c des_locl.h
-cfb64enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-cfb64enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-cfb64enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-cfb64enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-cfb64enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-cfb64enc.o: cfb64enc.c des_locl.h
-cfb_enc.o: ../../e_os.h ../../include/openssl/des.h
-cfb_enc.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
-cfb_enc.o: ../../include/openssl/opensslconf.h ../../include/openssl/ossl_typ.h
-cfb_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-cfb_enc.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
-cfb_enc.o: ../../include/openssl/ui_compat.h cfb_enc.c des_locl.h
-des_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-des_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-des_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-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
-des_old.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-des_old.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
-des_old.o: ../../include/openssl/ui_compat.h des_old.c
-des_old2.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-des_old2.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-des_old2.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-des_old2.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-des_old2.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
-des_old2.o: ../../include/openssl/ui_compat.h des_old2.c
-ecb3_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-ecb3_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-ecb3_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-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/des.h ../../include/openssl/des_old.h
-ecb_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.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
-ede_cbcm_enc.o: ../../include/openssl/ossl_typ.h
-ede_cbcm_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ede_cbcm_enc.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
-ede_cbcm_enc.o: ../../include/openssl/ui_compat.h des_locl.h ede_cbcm_enc.c
-enc_read.o: ../../e_os.h ../../include/openssl/bio.h
-enc_read.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-enc_read.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-enc_read.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-enc_read.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-enc_read.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-enc_read.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-enc_read.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
-enc_read.o: ../../include/openssl/ui_compat.h ../cryptlib.h des_locl.h
-enc_read.o: enc_read.c
-enc_writ.o: ../../e_os.h ../../include/openssl/bio.h
-enc_writ.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-enc_writ.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-enc_writ.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-enc_writ.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-enc_writ.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-enc_writ.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-enc_writ.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-enc_writ.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-enc_writ.o: ../cryptlib.h des_locl.h enc_writ.c
-fcrypt.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-fcrypt.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-fcrypt.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-fcrypt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-fcrypt.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-fcrypt.o: des_locl.h fcrypt.c
-fcrypt_b.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-fcrypt_b.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-fcrypt_b.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-fcrypt_b.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-fcrypt_b.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-fcrypt_b.o: des_locl.h fcrypt_b.c
-ofb64ede.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-ofb64ede.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-ofb64ede.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-ofb64ede.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-ofb64ede.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-ofb64ede.o: des_locl.h ofb64ede.c
-ofb64enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-ofb64enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-ofb64enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-ofb64enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-ofb64enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-ofb64enc.o: des_locl.h ofb64enc.c
-ofb_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-ofb_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-ofb_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-ofb_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-ofb_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-ofb_enc.o: des_locl.h ofb_enc.c
-pcbc_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-pcbc_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-pcbc_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-pcbc_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-pcbc_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-pcbc_enc.o: des_locl.h pcbc_enc.c
-qud_cksm.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-qud_cksm.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-qud_cksm.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-qud_cksm.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-qud_cksm.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-qud_cksm.o: des_locl.h qud_cksm.c
-rand_key.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-rand_key.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-rand_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-rand_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-rand_key.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
-rand_key.o: ../../include/openssl/ui_compat.h rand_key.c
-read2pwd.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
-read2pwd.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
-read2pwd.o: ../../include/openssl/opensslconf.h
-read2pwd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-read2pwd.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-read2pwd.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
-read2pwd.o: ../../include/openssl/ui_compat.h read2pwd.c
-rpc_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-rpc_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-rpc_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-rpc_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-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/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
-str2key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-str2key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-str2key.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-str2key.o: des_locl.h str2key.c
-xcbc_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-xcbc_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-xcbc_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-xcbc_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-xcbc_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-xcbc_enc.o: des_locl.h xcbc_enc.c
diff --git a/crypto/des/asm/crypt586.pl b/crypto/des/asm/crypt586.pl
index 1d04ed6..e36f7d4 100644
--- a/crypto/des/asm/crypt586.pl
+++ b/crypto/des/asm/crypt586.pl
@@ -6,7 +6,8 @@
 # things perfect.
 #
 
-push(@INC,"perlasm","../../perlasm");
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
 require "x86asm.pl";
 
 &asm_init($ARGV[0],"crypt586.pl");
@@ -22,7 +23,7 @@
 	{
 	local($name,$do_ip)=@_;
 
-	&function_begin($name,"EXTRN   _DES_SPtrans:DWORD");
+	&function_begin($name);
 
 	&comment("");
 	&comment("Load the 2 words");
diff --git a/crypto/des/asm/des-586.pl b/crypto/des/asm/des-586.pl
index b75d3c6..5b5f39c 100644
--- a/crypto/des/asm/des-586.pl
+++ b/crypto/des/asm/des-586.pl
@@ -4,7 +4,8 @@
 # Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
 #
 
-push(@INC,"perlasm","../../perlasm");
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
 require "x86asm.pl";
 require "cbc.pl";
 require "desboth.pl";
@@ -18,29 +19,110 @@
 
 $L="edi";
 $R="esi";
+$trans="ebp";
+$small_footprint=1 if (grep(/\-DOPENSSL_SMALL_FOOTPRINT/,@ARGV));
+# one can discuss setting this variable to 1 unconditionally, as
+# the folded loop is only 3% slower than unrolled, but >7 times smaller
 
-&external_label("DES_SPtrans");
+&public_label("DES_SPtrans");
+
+&DES_encrypt_internal();
+&DES_decrypt_internal();
 &DES_encrypt("DES_encrypt1",1);
 &DES_encrypt("DES_encrypt2",0);
 &DES_encrypt3("DES_encrypt3",1);
 &DES_encrypt3("DES_decrypt3",0);
 &cbc("DES_ncbc_encrypt","DES_encrypt1","DES_encrypt1",0,4,5,3,5,-1);
 &cbc("DES_ede3_cbc_encrypt","DES_encrypt3","DES_decrypt3",0,6,7,3,4,5);
+&DES_SPtrans();
 
 &asm_finish();
 
+sub DES_encrypt_internal()
+	{
+	&function_begin_B("_x86_DES_encrypt");
+
+	if ($small_footprint)
+	    {
+	    &lea("edx",&DWP(128,"ecx"));
+	    &push("edx");
+	    &push("ecx");
+	    &set_label("eloop");
+		&D_ENCRYPT(0,$L,$R,0,$trans,"eax","ebx","ecx","edx",&swtmp(0));
+		&comment("");
+		&D_ENCRYPT(1,$R,$L,2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
+		&comment("");
+		&add("ecx",16);
+		&cmp("ecx",&swtmp(1));
+		&mov(&swtmp(0),"ecx");
+		&jb(&label("eloop"));
+	    &add("esp",8);
+	    }
+	else
+	    {
+	    &push("ecx");
+	    for ($i=0; $i<16; $i+=2)
+		{
+		&comment("Round $i");
+		&D_ENCRYPT($i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
+		&comment("Round ".sprintf("%d",$i+1));
+		&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
+		}
+	    &add("esp",4);
+	}
+	&ret();
+
+	&function_end_B("_x86_DES_encrypt");
+	}
+	
+sub DES_decrypt_internal()
+	{
+	&function_begin_B("_x86_DES_decrypt");
+
+	if ($small_footprint)
+	    {
+	    &push("ecx");
+	    &lea("ecx",&DWP(128,"ecx"));
+	    &push("ecx");
+	    &set_label("dloop");
+		&D_ENCRYPT(0,$L,$R,-2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
+		&comment("");
+		&D_ENCRYPT(1,$R,$L,-4,$trans,"eax","ebx","ecx","edx",&swtmp(0));
+		&comment("");
+		&sub("ecx",16);
+		&cmp("ecx",&swtmp(1));
+		&mov(&swtmp(0),"ecx");
+		&ja(&label("dloop"));
+	    &add("esp",8);
+	    }
+	else
+	    {
+	    &push("ecx");
+	    for ($i=15; $i>0; $i-=2)
+		{
+		&comment("Round $i");
+		&D_ENCRYPT(15-$i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
+		&comment("Round ".sprintf("%d",$i-1));
+		&D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
+		}
+	    &add("esp",4);
+	    }
+	&ret();
+
+	&function_end_B("_x86_DES_decrypt");
+	}
+	
 sub DES_encrypt
 	{
 	local($name,$do_ip)=@_;
 
-	&function_begin_B($name,"EXTRN   _DES_SPtrans:DWORD");
+	&function_begin_B($name);
 
 	&push("esi");
 	&push("edi");
 
 	&comment("");
 	&comment("Load the 2 words");
-	$trans="ebp";
 
 	if ($do_ip)
 		{
@@ -73,39 +155,20 @@
 		}
 
 	# PIC-ification:-)
-	&picmeup($trans,"DES_SPtrans");
-	#if ($cpp)	{ &picmeup($trans,"DES_SPtrans");   }
-	#else		{ &lea($trans,&DWP("DES_SPtrans")); }
+	&call	(&label("pic_point"));
+	&set_label("pic_point");
+	&blindpop($trans);
+	&lea	($trans,&DWP(&label("DES_SPtrans")."-".&label("pic_point"),$trans));
 
 	&mov(	"ecx",	&wparam(1)	);
+
 	&cmp("ebx","0");
-	&je(&label("start_decrypt"));
-
-	for ($i=0; $i<16; $i+=2)
-		{
-		&comment("");
-		&comment("Round $i");
-		&D_ENCRYPT($i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx");
-
-		&comment("");
-		&comment("Round ".sprintf("%d",$i+1));
-		&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$trans,"eax","ebx","ecx","edx");
-		}
-	&jmp(&label("end"));
-
-	&set_label("start_decrypt");
-
-	for ($i=15; $i>0; $i-=2)
-		{
-		&comment("");
-		&comment("Round $i");
-		&D_ENCRYPT(15-$i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx");
-		&comment("");
-		&comment("Round ".sprintf("%d",$i-1));
-		&D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$trans,"eax","ebx","ecx","edx");
-		}
-
-	&set_label("end");
+	&je(&label("decrypt"));
+	&call("_x86_DES_encrypt");
+	&jmp(&label("done"));
+	&set_label("decrypt");
+	&call("_x86_DES_decrypt");
+	&set_label("done");
 
 	if ($do_ip)
 		{
@@ -139,7 +202,7 @@
 
 sub D_ENCRYPT
 	{
-	local($r,$L,$R,$S,$trans,$u,$tmp1,$tmp2,$t)=@_;
+	local($r,$L,$R,$S,$trans,$u,$tmp1,$tmp2,$t,$wp1)=@_;
 
 	 &mov(	$u,		&DWP(&n2a($S*4),$tmp2,"",0));
 	&xor(	$tmp1,		$tmp1);
@@ -166,7 +229,7 @@
 	&and(	$t,		"0xff"	);
 	 &xor(	$L,		&DWP("0x600",$trans,$tmp1,0));
 	 &xor(	$L,		&DWP("0x700",$trans,$tmp2,0));
-	&mov(	$tmp2,		&wparam(1)	);
+	&mov(	$tmp2,		$wp1	);
 	 &xor(	$L,		&DWP("0x400",$trans,$u,0));
 	 &xor(	$L,		&DWP("0x500",$trans,$t,0));
 	}
@@ -249,3 +312,142 @@
 	&rotr($tt	, 4);
 	}
 
+sub DES_SPtrans
+	{
+	&set_label("DES_SPtrans",64);
+	&data_word(0x02080800, 0x00080000, 0x02000002, 0x02080802);
+	&data_word(0x02000000, 0x00080802, 0x00080002, 0x02000002);
+	&data_word(0x00080802, 0x02080800, 0x02080000, 0x00000802);
+	&data_word(0x02000802, 0x02000000, 0x00000000, 0x00080002);
+	&data_word(0x00080000, 0x00000002, 0x02000800, 0x00080800);
+	&data_word(0x02080802, 0x02080000, 0x00000802, 0x02000800);
+	&data_word(0x00000002, 0x00000800, 0x00080800, 0x02080002);
+	&data_word(0x00000800, 0x02000802, 0x02080002, 0x00000000);
+	&data_word(0x00000000, 0x02080802, 0x02000800, 0x00080002);
+	&data_word(0x02080800, 0x00080000, 0x00000802, 0x02000800);
+	&data_word(0x02080002, 0x00000800, 0x00080800, 0x02000002);
+	&data_word(0x00080802, 0x00000002, 0x02000002, 0x02080000);
+	&data_word(0x02080802, 0x00080800, 0x02080000, 0x02000802);
+	&data_word(0x02000000, 0x00000802, 0x00080002, 0x00000000);
+	&data_word(0x00080000, 0x02000000, 0x02000802, 0x02080800);
+	&data_word(0x00000002, 0x02080002, 0x00000800, 0x00080802);
+	# nibble 1
+	&data_word(0x40108010, 0x00000000, 0x00108000, 0x40100000);
+	&data_word(0x40000010, 0x00008010, 0x40008000, 0x00108000);
+	&data_word(0x00008000, 0x40100010, 0x00000010, 0x40008000);
+	&data_word(0x00100010, 0x40108000, 0x40100000, 0x00000010);
+	&data_word(0x00100000, 0x40008010, 0x40100010, 0x00008000);
+	&data_word(0x00108010, 0x40000000, 0x00000000, 0x00100010);
+	&data_word(0x40008010, 0x00108010, 0x40108000, 0x40000010);
+	&data_word(0x40000000, 0x00100000, 0x00008010, 0x40108010);
+	&data_word(0x00100010, 0x40108000, 0x40008000, 0x00108010);
+	&data_word(0x40108010, 0x00100010, 0x40000010, 0x00000000);
+	&data_word(0x40000000, 0x00008010, 0x00100000, 0x40100010);
+	&data_word(0x00008000, 0x40000000, 0x00108010, 0x40008010);
+	&data_word(0x40108000, 0x00008000, 0x00000000, 0x40000010);
+	&data_word(0x00000010, 0x40108010, 0x00108000, 0x40100000);
+	&data_word(0x40100010, 0x00100000, 0x00008010, 0x40008000);
+	&data_word(0x40008010, 0x00000010, 0x40100000, 0x00108000);
+	# nibble 2
+	&data_word(0x04000001, 0x04040100, 0x00000100, 0x04000101);
+	&data_word(0x00040001, 0x04000000, 0x04000101, 0x00040100);
+	&data_word(0x04000100, 0x00040000, 0x04040000, 0x00000001);
+	&data_word(0x04040101, 0x00000101, 0x00000001, 0x04040001);
+	&data_word(0x00000000, 0x00040001, 0x04040100, 0x00000100);
+	&data_word(0x00000101, 0x04040101, 0x00040000, 0x04000001);
+	&data_word(0x04040001, 0x04000100, 0x00040101, 0x04040000);
+	&data_word(0x00040100, 0x00000000, 0x04000000, 0x00040101);
+	&data_word(0x04040100, 0x00000100, 0x00000001, 0x00040000);
+	&data_word(0x00000101, 0x00040001, 0x04040000, 0x04000101);
+	&data_word(0x00000000, 0x04040100, 0x00040100, 0x04040001);
+	&data_word(0x00040001, 0x04000000, 0x04040101, 0x00000001);
+	&data_word(0x00040101, 0x04000001, 0x04000000, 0x04040101);
+	&data_word(0x00040000, 0x04000100, 0x04000101, 0x00040100);
+	&data_word(0x04000100, 0x00000000, 0x04040001, 0x00000101);
+	&data_word(0x04000001, 0x00040101, 0x00000100, 0x04040000);
+	# nibble 3
+	&data_word(0x00401008, 0x10001000, 0x00000008, 0x10401008);
+	&data_word(0x00000000, 0x10400000, 0x10001008, 0x00400008);
+	&data_word(0x10401000, 0x10000008, 0x10000000, 0x00001008);
+	&data_word(0x10000008, 0x00401008, 0x00400000, 0x10000000);
+	&data_word(0x10400008, 0x00401000, 0x00001000, 0x00000008);
+	&data_word(0x00401000, 0x10001008, 0x10400000, 0x00001000);
+	&data_word(0x00001008, 0x00000000, 0x00400008, 0x10401000);
+	&data_word(0x10001000, 0x10400008, 0x10401008, 0x00400000);
+	&data_word(0x10400008, 0x00001008, 0x00400000, 0x10000008);
+	&data_word(0x00401000, 0x10001000, 0x00000008, 0x10400000);
+	&data_word(0x10001008, 0x00000000, 0x00001000, 0x00400008);
+	&data_word(0x00000000, 0x10400008, 0x10401000, 0x00001000);
+	&data_word(0x10000000, 0x10401008, 0x00401008, 0x00400000);
+	&data_word(0x10401008, 0x00000008, 0x10001000, 0x00401008);
+	&data_word(0x00400008, 0x00401000, 0x10400000, 0x10001008);
+	&data_word(0x00001008, 0x10000000, 0x10000008, 0x10401000);
+	# nibble 4
+	&data_word(0x08000000, 0x00010000, 0x00000400, 0x08010420);
+	&data_word(0x08010020, 0x08000400, 0x00010420, 0x08010000);
+	&data_word(0x00010000, 0x00000020, 0x08000020, 0x00010400);
+	&data_word(0x08000420, 0x08010020, 0x08010400, 0x00000000);
+	&data_word(0x00010400, 0x08000000, 0x00010020, 0x00000420);
+	&data_word(0x08000400, 0x00010420, 0x00000000, 0x08000020);
+	&data_word(0x00000020, 0x08000420, 0x08010420, 0x00010020);
+	&data_word(0x08010000, 0x00000400, 0x00000420, 0x08010400);
+	&data_word(0x08010400, 0x08000420, 0x00010020, 0x08010000);
+	&data_word(0x00010000, 0x00000020, 0x08000020, 0x08000400);
+	&data_word(0x08000000, 0x00010400, 0x08010420, 0x00000000);
+	&data_word(0x00010420, 0x08000000, 0x00000400, 0x00010020);
+	&data_word(0x08000420, 0x00000400, 0x00000000, 0x08010420);
+	&data_word(0x08010020, 0x08010400, 0x00000420, 0x00010000);
+	&data_word(0x00010400, 0x08010020, 0x08000400, 0x00000420);
+	&data_word(0x00000020, 0x00010420, 0x08010000, 0x08000020);
+	# nibble 5
+	&data_word(0x80000040, 0x00200040, 0x00000000, 0x80202000);
+	&data_word(0x00200040, 0x00002000, 0x80002040, 0x00200000);
+	&data_word(0x00002040, 0x80202040, 0x00202000, 0x80000000);
+	&data_word(0x80002000, 0x80000040, 0x80200000, 0x00202040);
+	&data_word(0x00200000, 0x80002040, 0x80200040, 0x00000000);
+	&data_word(0x00002000, 0x00000040, 0x80202000, 0x80200040);
+	&data_word(0x80202040, 0x80200000, 0x80000000, 0x00002040);
+	&data_word(0x00000040, 0x00202000, 0x00202040, 0x80002000);
+	&data_word(0x00002040, 0x80000000, 0x80002000, 0x00202040);
+	&data_word(0x80202000, 0x00200040, 0x00000000, 0x80002000);
+	&data_word(0x80000000, 0x00002000, 0x80200040, 0x00200000);
+	&data_word(0x00200040, 0x80202040, 0x00202000, 0x00000040);
+	&data_word(0x80202040, 0x00202000, 0x00200000, 0x80002040);
+	&data_word(0x80000040, 0x80200000, 0x00202040, 0x00000000);
+	&data_word(0x00002000, 0x80000040, 0x80002040, 0x80202000);
+	&data_word(0x80200000, 0x00002040, 0x00000040, 0x80200040);
+	# nibble 6
+	&data_word(0x00004000, 0x00000200, 0x01000200, 0x01000004);
+	&data_word(0x01004204, 0x00004004, 0x00004200, 0x00000000);
+	&data_word(0x01000000, 0x01000204, 0x00000204, 0x01004000);
+	&data_word(0x00000004, 0x01004200, 0x01004000, 0x00000204);
+	&data_word(0x01000204, 0x00004000, 0x00004004, 0x01004204);
+	&data_word(0x00000000, 0x01000200, 0x01000004, 0x00004200);
+	&data_word(0x01004004, 0x00004204, 0x01004200, 0x00000004);
+	&data_word(0x00004204, 0x01004004, 0x00000200, 0x01000000);
+	&data_word(0x00004204, 0x01004000, 0x01004004, 0x00000204);
+	&data_word(0x00004000, 0x00000200, 0x01000000, 0x01004004);
+	&data_word(0x01000204, 0x00004204, 0x00004200, 0x00000000);
+	&data_word(0x00000200, 0x01000004, 0x00000004, 0x01000200);
+	&data_word(0x00000000, 0x01000204, 0x01000200, 0x00004200);
+	&data_word(0x00000204, 0x00004000, 0x01004204, 0x01000000);
+	&data_word(0x01004200, 0x00000004, 0x00004004, 0x01004204);
+	&data_word(0x01000004, 0x01004200, 0x01004000, 0x00004004);
+	# nibble 7
+	&data_word(0x20800080, 0x20820000, 0x00020080, 0x00000000);
+	&data_word(0x20020000, 0x00800080, 0x20800000, 0x20820080);
+	&data_word(0x00000080, 0x20000000, 0x00820000, 0x00020080);
+	&data_word(0x00820080, 0x20020080, 0x20000080, 0x20800000);
+	&data_word(0x00020000, 0x00820080, 0x00800080, 0x20020000);
+	&data_word(0x20820080, 0x20000080, 0x00000000, 0x00820000);
+	&data_word(0x20000000, 0x00800000, 0x20020080, 0x20800080);
+	&data_word(0x00800000, 0x00020000, 0x20820000, 0x00000080);
+	&data_word(0x00800000, 0x00020000, 0x20000080, 0x20820080);
+	&data_word(0x00020080, 0x20000000, 0x00000000, 0x00820000);
+	&data_word(0x20800080, 0x20020080, 0x20020000, 0x00800080);
+	&data_word(0x20820000, 0x00000080, 0x00800080, 0x20020000);
+	&data_word(0x20820080, 0x00800000, 0x20800000, 0x20000080);
+	&data_word(0x00820000, 0x00020080, 0x20020080, 0x20800000);
+	&data_word(0x00000080, 0x20820000, 0x00820080, 0x00000000);
+	&data_word(0x20000000, 0x20800080, 0x00020000, 0x00820080);
+	}
diff --git a/crypto/des/asm/des686.pl b/crypto/des/asm/des686.pl
deleted file mode 100644
index d3ad5d5..0000000
--- a/crypto/des/asm/des686.pl
+++ /dev/null
@@ -1,230 +0,0 @@
-#!/usr/local/bin/perl
-
-$prog="des686.pl";
-
-# base code is in microsft
-# op dest, source
-# format.
-#
-
-# WILL NOT WORK ANYMORE WITH desboth.pl
-require "desboth.pl";
-
-if (	($ARGV[0] eq "elf"))
-	{ require "x86unix.pl"; }
-elsif (	($ARGV[0] eq "a.out"))
-	{ $aout=1; require "x86unix.pl"; }
-elsif (	($ARGV[0] eq "sol"))
-	{ $sol=1; require "x86unix.pl"; }
-elsif ( ($ARGV[0] eq "cpp"))
-	{ $cpp=1; require "x86unix.pl"; }
-elsif (	($ARGV[0] eq "win32"))
-	{ require "x86ms.pl"; }
-else
-	{
-	print STDERR <<"EOF";
-Pick one target type from
-	elf	- linux, FreeBSD etc
-	a.out	- old linux
-	sol	- x86 solaris
-	cpp	- format so x86unix.cpp can be used
-	win32	- Windows 95/Windows NT
-EOF
-	exit(1);
-	}
-
-&comment("Don't even think of reading this code");
-&comment("It was automatically generated by $prog");
-&comment("Which is a perl program used to generate the x86 assember for");
-&comment("any of elf, a.out, Win32, or Solaris");
-&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");
-&comment("eric <eay\@cryptsoft.com>");
-&comment("");
-
-&file("dx86xxxx");
-
-$L="edi";
-$R="esi";
-
-&DES_encrypt("DES_encrypt1",1);
-&DES_encrypt("DES_encrypt2",0);
-
-&DES_encrypt3("DES_encrypt3",1);
-&DES_encrypt3("DES_decrypt3",0);
-
-&file_end();
-
-sub DES_encrypt
-	{
-	local($name,$do_ip)=@_;
-
-	&function_begin($name,"EXTRN   _DES_SPtrans:DWORD");
-
-	&comment("");
-	&comment("Load the 2 words");
-	&mov("eax",&wparam(0));
-	&mov($L,&DWP(0,"eax","",0));
-	&mov($R,&DWP(4,"eax","",0));
-
-	$ksp=&wparam(1);
-
-	if ($do_ip)
-		{
-		&comment("");
-		&comment("IP");
-		&IP_new($L,$R,"eax");
-		}
-
-	&comment("");
-	&comment("fixup rotate");
-	&rotl($R,3);
-	&rotl($L,3);
-	&exch($L,$R);
-
-	&comment("");
-	&comment("load counter, key_schedule and enc flag");
-	&mov("eax",&wparam(2));	# get encrypt flag
-	&mov("ebp",&wparam(1));	# get ks
-	&cmp("eax","0");
-	&je(&label("start_decrypt"));
-
-	# encrypting part
-
-	for ($i=0; $i<16; $i+=2)
-		{
-		&comment("");
-		&comment("Round $i");
-		&D_ENCRYPT($L,$R,$i*2,"ebp","DES_SPtrans","ecx","edx","eax","ebx");
-
-		&comment("");
-		&comment("Round ".sprintf("%d",$i+1));
-		&D_ENCRYPT($R,$L,($i+1)*2,"ebp","DES_SPtrans","ecx","edx","eax","ebx");
-		}
-	&jmp(&label("end"));
-
-	&set_label("start_decrypt");
-
-	for ($i=15; $i>0; $i-=2)
-		{
-		&comment("");
-		&comment("Round $i");
-		&D_ENCRYPT($L,$R,$i*2,"ebp","DES_SPtrans","ecx","edx","eax","ebx");
-		&comment("");
-		&comment("Round ".sprintf("%d",$i-1));
-		&D_ENCRYPT($R,$L,($i-1)*2,"ebp","DES_SPtrans","ecx","edx","eax","ebx");
-		}
-
-	&set_label("end");
-
-	&comment("");
-	&comment("Fixup");
-	&rotr($L,3);		# r
-	&rotr($R,3);		# l
-
-	if ($do_ip)
-		{
-		&comment("");
-		&comment("FP");
-		&FP_new($R,$L,"eax");
-		}
-
-	&mov("eax",&wparam(0));
-	&mov(&DWP(0,"eax","",0),$L);
-	&mov(&DWP(4,"eax","",0),$R);
-
-	&function_end($name);
-	}
-
-
-# The logic is to load R into 2 registers and operate on both at the same time.
-# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte'
-# while also masking the other copy and doing a lookup.  We then also accumulate the
-# L value in 2 registers then combine them at the end.
-sub D_ENCRYPT
-	{
-	local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_;
-
-	&mov(	$u,		&DWP(&n2a($S*4),$ks,"",0));
-	&mov(	$t,		&DWP(&n2a(($S+1)*4),$ks,"",0));
-	&xor(	$u,		$R		);
-	&xor(	$t,		$R		);
-	&rotr(	$t,		4		);
-
-	# the numbers at the end of the line are origional instruction order
-	&mov(	$tmp2,		$u		);			# 1 2
-	&mov(	$tmp1,		$t		);			# 1 1
-	&and(	$tmp2,		"0xfc"		);			# 1 4
-	&and(	$tmp1,		"0xfc"		);			# 1 3
-	&shr(	$t,		8		);			# 1 5
-	&xor(	$L,		&DWP("0x100+$desSP",$tmp1,"",0));	# 1 7
-	&shr(	$u,		8		);			# 1 6
-	&mov(	$tmp1,		&DWP("      $desSP",$tmp2,"",0));	# 1 8
-
-	&mov(	$tmp2,		$u		);			# 2 2
-	&xor(	$L,		$tmp1		);			# 1 9
-	&and(	$tmp2,		"0xfc"		);			# 2 4
-	&mov(	$tmp1,		$t		);			# 2 1
-	&and(	$tmp1,		"0xfc"		);			# 2 3
-	&shr(	$t,		8		);			# 2 5
-	&xor(	$L,		&DWP("0x300+$desSP",$tmp1,"",0));	# 2 7
-	&shr(	$u,		8		);			# 2 6
-	&mov(	$tmp1,		&DWP("0x200+$desSP",$tmp2,"",0));	# 2 8
-	&mov(	$tmp2,		$u		);			# 3 2
-
-	&xor(	$L,		$tmp1		);			# 2 9
-	&and(	$tmp2,		"0xfc"		);			# 3 4
-
-	&mov(	$tmp1,		$t		);			# 3 1 
-	&shr(	$u,		8		);			# 3 6
-	&and(	$tmp1,		"0xfc"		);			# 3 3
-	&shr(	$t,		8		);			# 3 5
-	&xor(	$L,		&DWP("0x500+$desSP",$tmp1,"",0));	# 3 7
-	&mov(	$tmp1,		&DWP("0x400+$desSP",$tmp2,"",0));	# 3 8
-
-	&and(	$t,		"0xfc"		);			# 4 1
-	&xor(	$L,		$tmp1		);			# 3 9
-
-	&and(	$u,		"0xfc"		);			# 4 2
-	&xor(	$L,		&DWP("0x700+$desSP",$t,"",0));		# 4 3
-	&xor(	$L,		&DWP("0x600+$desSP",$u,"",0));		# 4 4
-	}
-
-sub PERM_OP
-	{
-	local($a,$b,$tt,$shift,$mask)=@_;
-
-	&mov(	$tt,		$a		);
-	&shr(	$tt,		$shift		);
-	&xor(	$tt,		$b		);
-	&and(	$tt,		$mask		);
-	&xor(	$b,		$tt		);
-	&shl(	$tt,		$shift		);
-	&xor(	$a,		$tt		);
-	}
-
-sub IP_new
-	{
-	local($l,$r,$tt)=@_;
-
-	&PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");
-	&PERM_OP($l,$r,$tt,16,"0x0000ffff");
-	&PERM_OP($r,$l,$tt, 2,"0x33333333");
-	&PERM_OP($l,$r,$tt, 8,"0x00ff00ff");
-	&PERM_OP($r,$l,$tt, 1,"0x55555555");
-	}
-
-sub FP_new
-	{
-	local($l,$r,$tt)=@_;
-
-	&PERM_OP($l,$r,$tt, 1,"0x55555555");
-        &PERM_OP($r,$l,$tt, 8,"0x00ff00ff");
-        &PERM_OP($l,$r,$tt, 2,"0x33333333");
-        &PERM_OP($r,$l,$tt,16,"0x0000ffff");
-        &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");
-	}
-
-sub n2a
-	{
-	sprintf("%d",$_[0]);
-	}
diff --git a/crypto/des/asm/des_enc.m4 b/crypto/des/asm/des_enc.m4
index f59333a..3280595 100644
--- a/crypto/des/asm/des_enc.m4
+++ b/crypto/des/asm/des_enc.m4
@@ -1954,9 +1954,11 @@
 	.word	LOOPS                     ! 280
 	.word	0x0000FC00                ! 284
 
-	.type	.PIC.DES_SPtrans,#object
-	.size	.PIC.DES_SPtrans,2048
+	.global	DES_SPtrans
+	.type	DES_SPtrans,#object
+	.size	DES_SPtrans,2048
 .align	64
+DES_SPtrans:
 .PIC.DES_SPtrans:
 	! nibble 0
 	.word	0x02080800, 0x00080000, 0x02000002, 0x02080802
diff --git a/crypto/des/des_enc.c b/crypto/des/des_enc.c
index cf71965..828feba 100644
--- a/crypto/des/des_enc.c
+++ b/crypto/des/des_enc.c
@@ -57,6 +57,7 @@
  */
 
 #include "des_locl.h"
+#include "spr.h"
 
 void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
 	{
@@ -107,12 +108,10 @@
 		D_ENCRYPT(l,r,28); /*  15 */
 		D_ENCRYPT(r,l,30); /*  16 */
 #else
-		for (i=0; i<32; i+=8)
+		for (i=0; i<32; i+=4)
 			{
 			D_ENCRYPT(l,r,i+0); /*  1 */
 			D_ENCRYPT(r,l,i+2); /*  2 */
-			D_ENCRYPT(l,r,i+4); /*  3 */
-			D_ENCRYPT(r,l,i+6); /*  4 */
 			}
 #endif
 		}
@@ -136,12 +135,10 @@
 		D_ENCRYPT(l,r, 2); /*  2 */
 		D_ENCRYPT(r,l, 0); /*  1 */
 #else
-		for (i=30; i>0; i-=8)
+		for (i=30; i>0; i-=4)
 			{
 			D_ENCRYPT(l,r,i-0); /* 16 */
 			D_ENCRYPT(r,l,i-2); /* 15 */
-			D_ENCRYPT(l,r,i-4); /* 14 */
-			D_ENCRYPT(r,l,i-6); /* 13 */
 			}
 #endif
 		}
@@ -203,12 +200,10 @@
 		D_ENCRYPT(l,r,28); /*  15 */
 		D_ENCRYPT(r,l,30); /*  16 */
 #else
-		for (i=0; i<32; i+=8)
+		for (i=0; i<32; i+=4)
 			{
 			D_ENCRYPT(l,r,i+0); /*  1 */
 			D_ENCRYPT(r,l,i+2); /*  2 */
-			D_ENCRYPT(l,r,i+4); /*  3 */
-			D_ENCRYPT(r,l,i+6); /*  4 */
 			}
 #endif
 		}
@@ -232,12 +227,10 @@
 		D_ENCRYPT(l,r, 2); /*  2 */
 		D_ENCRYPT(r,l, 0); /*  1 */
 #else
-		for (i=30; i>0; i-=8)
+		for (i=30; i>0; i-=4)
 			{
 			D_ENCRYPT(l,r,i-0); /* 16 */
 			D_ENCRYPT(r,l,i-2); /* 15 */
-			D_ENCRYPT(l,r,i-4); /* 14 */
-			D_ENCRYPT(r,l,i-6); /* 13 */
 			}
 #endif
 		}
@@ -289,8 +282,6 @@
 
 #ifndef DES_DEFAULT_OPTIONS
 
-#if !defined(OPENSSL_FIPS_DES_ASM)
-
 #undef CBC_ENC_C__DONT_UPDATE_IV
 #include "ncbc_enc.c" /* DES_ncbc_encrypt */
 
@@ -406,6 +397,4 @@
 	tin[0]=tin[1]=0;
 	}
 
-#endif
-
 #endif /* DES_DEFAULT_OPTIONS */
diff --git a/crypto/des/des_lib.c b/crypto/des/des_lib.c
deleted file mode 100644
index d4b3047..0000000
--- a/crypto/des/des_lib.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/* crypto/des/ecb_enc.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#include "des_locl.h"
-#include "des_ver.h"
-#include <openssl/opensslv.h>
-#include <openssl/bio.h>
-
-OPENSSL_GLOBAL const char libdes_version[]="libdes" OPENSSL_VERSION_PTEXT;
-OPENSSL_GLOBAL const char DES_version[]="DES" OPENSSL_VERSION_PTEXT;
-
-const char *DES_options(void)
-	{
-	static int init=1;
-	static char buf[32];
-
-	if (init)
-		{
-		const char *ptr,*unroll,*risc,*size;
-
-#ifdef DES_PTR
-		ptr="ptr";
-#else
-		ptr="idx";
-#endif
-#if defined(DES_RISC1) || defined(DES_RISC2)
-#ifdef DES_RISC1
-		risc="risc1";
-#endif
-#ifdef DES_RISC2
-		risc="risc2";
-#endif
-#else
-		risc="cisc";
-#endif
-#ifdef DES_UNROLL
-		unroll="16";
-#else
-		unroll="4";
-#endif
-		if (sizeof(DES_LONG) != sizeof(long))
-			size="int";
-		else
-			size="long";
-		BIO_snprintf(buf,sizeof buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,
-			     size);
-		init=0;
-		}
-	return(buf);
-	}
-
diff --git a/crypto/des/des_locl.h b/crypto/des/des_locl.h
index 4b9ecff..a3b512e 100644
--- a/crypto/des/des_locl.h
+++ b/crypto/des/des_locl.h
@@ -61,7 +61,7 @@
 
 #include <openssl/e_os2.h>
 
-#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
+#if defined(OPENSSL_SYS_WIN32)
 #ifndef OPENSSL_SYS_MSDOS
 #define OPENSSL_SYS_MSDOS
 #endif
@@ -425,4 +425,8 @@
 
 void fcrypt_body(DES_LONG *out,DES_key_schedule *ks,
 		 DES_LONG Eswap0, DES_LONG Eswap1);
+
+#ifdef OPENSSL_SMALL_FOOTPRINT
+#undef DES_UNROLL
+#endif
 #endif
diff --git a/crypto/des/ecb_enc.c b/crypto/des/ecb_enc.c
index 75ae6cf..0684e76 100644
--- a/crypto/des/ecb_enc.c
+++ b/crypto/des/ecb_enc.c
@@ -57,7 +57,53 @@
  */
 
 #include "des_locl.h"
-#include "spr.h"
+#include "des_ver.h"
+#include <openssl/opensslv.h>
+#include <openssl/bio.h>
+
+OPENSSL_GLOBAL const char libdes_version[]="libdes" OPENSSL_VERSION_PTEXT;
+OPENSSL_GLOBAL const char DES_version[]="DES" OPENSSL_VERSION_PTEXT;
+
+const char *DES_options(void)
+	{
+	static int init=1;
+	static char buf[32];
+
+	if (init)
+		{
+		const char *ptr,*unroll,*risc,*size;
+
+#ifdef DES_PTR
+		ptr="ptr";
+#else
+		ptr="idx";
+#endif
+#if defined(DES_RISC1) || defined(DES_RISC2)
+#ifdef DES_RISC1
+		risc="risc1";
+#endif
+#ifdef DES_RISC2
+		risc="risc2";
+#endif
+#else
+		risc="cisc";
+#endif
+#ifdef DES_UNROLL
+		unroll="16";
+#else
+		unroll="2";
+#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 e7da2ec..edb6620 100644
--- a/crypto/des/enc_read.c
+++ b/crypto/des/enc_read.c
@@ -63,7 +63,7 @@
 
 /* This has some uglies in it but it works - even over sockets. */
 /*extern int errno;*/
-OPENSSL_IMPLEMENT_GLOBAL(int,DES_rw_mode)=DES_PCBC_MODE;
+OPENSSL_IMPLEMENT_GLOBAL(int,DES_rw_mode,DES_PCBC_MODE)
 
 
 /*
@@ -87,6 +87,9 @@
 int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched,
 		 DES_cblock *iv)
 	{
+#if defined(OPENSSL_NO_POSIX_IO)
+	return(0);
+#else
 	/* data to be unencrypted */
 	int net_num=0;
 	static unsigned char *net=NULL;
@@ -147,7 +150,7 @@
 	/* first - get the length */
 	while (net_num < HDRSIZE) 
 		{
-#ifndef _WIN32
+#ifndef OPENSSL_SYS_WIN32
 		i=read(fd,(void *)&(net[net_num]),HDRSIZE-net_num);
 #else
 		i=_read(fd,(void *)&(net[net_num]),HDRSIZE-net_num);
@@ -173,7 +176,11 @@
 	net_num=0;
 	while (net_num < rnum)
 		{
+#ifndef OPENSSL_SYS_WIN32
 		i=read(fd,(void *)&(net[net_num]),rnum-net_num);
+#else
+		i=_read(fd,(void *)&(net[net_num]),rnum-net_num);
+#endif
 #ifdef EINTR
 		if ((i == -1) && (errno == EINTR)) continue;
 #endif
@@ -228,5 +235,6 @@
 			}
 		}
 	return num;
+#endif /* OPENSSL_NO_POSIX_IO */
 	}
 
diff --git a/crypto/des/enc_writ.c b/crypto/des/enc_writ.c
index c2f032c..2353ac1 100644
--- a/crypto/des/enc_writ.c
+++ b/crypto/des/enc_writ.c
@@ -80,6 +80,9 @@
 int DES_enc_write(int fd, const void *_buf, int len,
 		  DES_key_schedule *sched, DES_cblock *iv)
 	{
+#if defined(OPENSSL_NO_POSIX_IO)
+	return (-1);
+#else
 #ifdef _LIBC
 	extern unsigned long time();
 	extern int write();
@@ -172,4 +175,5 @@
 		}
 
 	return(len);
+#endif /* OPENSSL_NO_POSIX_IO */
 	}
diff --git a/crypto/des/fcrypt_b.c b/crypto/des/fcrypt_b.c
index 1390138..8822816 100644
--- a/crypto/des/fcrypt_b.c
+++ b/crypto/des/fcrypt_b.c
@@ -100,12 +100,10 @@
 #ifndef DES_UNROLL
 		register int i;
 
-		for (i=0; i<32; i+=8)
+		for (i=0; i<32; i+=4)
 			{
 			D_ENCRYPT(l,r,i+0); /*  1 */
 			D_ENCRYPT(r,l,i+2); /*  2 */
-			D_ENCRYPT(l,r,i+4); /*  1 */
-			D_ENCRYPT(r,l,i+6); /*  2 */
 			}
 #else
 		D_ENCRYPT(l,r, 0); /*  1 */
diff --git a/crypto/des/set_key.c b/crypto/des/set_key.c
index c0806d5..3004cc3 100644
--- a/crypto/des/set_key.c
+++ b/crypto/des/set_key.c
@@ -64,12 +64,8 @@
  * 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 */
+OPENSSL_IMPLEMENT_GLOBAL(int,DES_check_key,0)	/* defaults to false */
 
 static const unsigned char odd_parity[256]={
   1,  1,  2,  2,  4,  4,  7,  7,  8,  8, 11, 11, 13, 13, 14, 14,
@@ -340,7 +336,7 @@
 
 void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
 	{
-	static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
+	static const int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
 	register DES_LONG c,d,t,s,t2;
 	register const unsigned char *in;
 	register DES_LONG *k;
@@ -353,10 +349,6 @@
 	k = &schedule->ks->deslong[0];
 	in = &(*key)[0];
 
-#ifdef OPENSSL_FIPS
-	FIPS_selftest_check();
-#endif
-
 	c2l(in,c);
 	c2l(in,d);
 
@@ -413,4 +405,3 @@
 	des_set_odd_parity(key);
 	}
 */
-
diff --git a/crypto/des/xcbc_enc.c b/crypto/des/xcbc_enc.c
index dc0c761..058cab6 100644
--- a/crypto/des/xcbc_enc.c
+++ b/crypto/des/xcbc_enc.c
@@ -61,7 +61,7 @@
 /* RSA's DESX */
 
 #if 0 /* broken code, preserved just in case anyone specifically looks for this */
-static unsigned char desx_white_in2out[256]={
+static const unsigned char desx_white_in2out[256]={
 0xBD,0x56,0xEA,0xF2,0xA2,0xF1,0xAC,0x2A,0xB0,0x93,0xD1,0x9C,0x1B,0x33,0xFD,0xD0,
 0x30,0x04,0xB6,0xDC,0x7D,0xDF,0x32,0x4B,0xF7,0xCB,0x45,0x9B,0x31,0xBB,0x21,0x5A,
 0x41,0x9F,0xE1,0xD9,0x4A,0x4D,0x9E,0xDA,0xA0,0x68,0x2C,0xC3,0x27,0x5F,0x80,0x36,
diff --git a/crypto/dh/Makefile b/crypto/dh/Makefile
deleted file mode 100644
index d01fa96..0000000
--- a/crypto/dh/Makefile
+++ /dev/null
@@ -1,139 +0,0 @@
-#
-# OpenSSL/crypto/dh/Makefile
-#
-
-DIR=	dh
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST= dhtest.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC= dh_asn1.c dh_gen.c dh_key.c dh_lib.c dh_check.c dh_err.c dh_depr.c
-LIBOBJ= dh_asn1.o dh_gen.o dh_key.o dh_lib.o dh_check.o dh_err.o dh_depr.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= dh.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-dh_asn1.o: ../../e_os.h ../../include/openssl/asn1.h
-dh_asn1.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-dh_asn1.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-dh_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
-dh_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-dh_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-dh_asn1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-dh_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-dh_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-dh_asn1.o: ../../include/openssl/symhacks.h ../cryptlib.h dh_asn1.c
-dh_check.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-dh_check.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-dh_check.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
-dh_check.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-dh_check.o: ../../include/openssl/opensslconf.h
-dh_check.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-dh_check.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-dh_check.o: ../../include/openssl/symhacks.h ../cryptlib.h dh_check.c
-dh_depr.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-dh_depr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-dh_depr.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
-dh_depr.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-dh_depr.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-dh_depr.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-dh_depr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-dh_depr.o: ../cryptlib.h dh_depr.c
-dh_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
-dh_err.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
-dh_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-dh_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-dh_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-dh_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-dh_err.o: dh_err.c
-dh_gen.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-dh_gen.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-dh_gen.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
-dh_gen.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-dh_gen.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-dh_gen.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-dh_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-dh_gen.o: ../cryptlib.h dh_gen.c
-dh_key.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-dh_key.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-dh_key.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
-dh_key.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-dh_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-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/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/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/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 10475ac..849309a 100644
--- a/crypto/dh/dh.h
+++ b/crypto/dh/dh.h
@@ -77,8 +77,6 @@
 # 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
@@ -159,7 +157,6 @@
    this for backward compatibility: */
 #define DH_CHECK_P_NOT_STRONG_PRIME	DH_CHECK_P_NOT_SAFE_PRIME
 
-#define DHparams_dup(x) ASN1_dup_of_const(DH,i2d_DHparams,d2i_DHparams,x)
 #define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
 		(char *(*)())d2i_DHparams,(fp),(unsigned char **)(x))
 #define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \
@@ -167,12 +164,9 @@
 #define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x)
 #define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x)
 
-const DH_METHOD *DH_OpenSSL(void);
+DH *DHparams_dup(DH *);
 
-#ifdef OPENSSL_FIPS
-DH *	FIPS_dh_new(void);
-void	FIPS_dh_free(DH *dh);
-#endif
+const DH_METHOD *DH_OpenSSL(void);
 
 void DH_set_default_method(const DH_METHOD *meth);
 const DH_METHOD *DH_get_default_method(void);
@@ -212,6 +206,18 @@
 int	DHparams_print(char *bp, const DH *x);
 #endif
 
+#define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+			EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL)
+
+#define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+			EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL)
+
+#define	EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN	(EVP_PKEY_ALG_CTRL + 1)
+#define	EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR	(EVP_PKEY_ALG_CTRL + 2)
+		
+
 /* 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.
@@ -222,22 +228,31 @@
 
 /* Function codes. */
 #define DH_F_COMPUTE_KEY				 102
-#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_DH_PARAM_DECODE				 107
+#define DH_F_DH_PRIV_DECODE				 110
+#define DH_F_DH_PRIV_ENCODE				 111
+#define DH_F_DH_PUB_DECODE				 108
+#define DH_F_DH_PUB_ENCODE				 109
+#define DH_F_DO_DH_PRINT				 100
 #define DH_F_GENERATE_KEY				 103
 #define DH_F_GENERATE_PARAMETERS			 104
+#define DH_F_PKEY_DH_DERIVE				 112
+#define DH_F_PKEY_DH_KEYGEN				 113
 
 /* Reason codes. */
 #define DH_R_BAD_GENERATOR				 101
+#define DH_R_BN_DECODE_ERROR				 109
+#define DH_R_BN_ERROR					 106
+#define DH_R_DECODE_ERROR				 104
 #define DH_R_INVALID_PUBKEY				 102
-#define DH_R_KEY_SIZE_TOO_SMALL				 104
+#define DH_R_KEYS_NOT_SET				 108
 #define DH_R_MODULUS_TOO_LARGE				 103
+#define DH_R_NO_PARAMETERS_SET				 107
 #define DH_R_NO_PRIVATE_VALUE				 100
+#define DH_R_PARAMETER_ENCODING_ERROR			 105
 
 #ifdef  __cplusplus
 }
diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c
new file mode 100644
index 0000000..377caf9
--- /dev/null
+++ b/crypto/dh/dh_ameth.c
@@ -0,0 +1,500 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/dh.h>
+#include <openssl/bn.h>
+#include "asn1_locl.h"
+
+static void int_dh_free(EVP_PKEY *pkey)
+	{
+	DH_free(pkey->pkey.dh);
+	}
+
+static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+	{
+	const unsigned char *p, *pm;
+	int pklen, pmlen;
+	int ptype;
+	void *pval;
+	ASN1_STRING *pstr;
+	X509_ALGOR *palg;
+	ASN1_INTEGER *public_key = NULL;
+
+	DH *dh = NULL;
+
+	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
+		return 0;
+	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+	if (ptype != V_ASN1_SEQUENCE)
+		{
+		DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR);
+		goto err;
+		}
+
+	pstr = pval;	
+	pm = pstr->data;
+	pmlen = pstr->length;
+
+	if (!(dh = d2i_DHparams(NULL, &pm, pmlen)))
+		{
+		DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
+		goto err;
+		}
+
+	if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen)))
+		{
+		DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
+		goto err;
+		}
+
+	/* We have parameters now set public key */
+	if (!(dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)))
+		{
+		DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR);
+		goto err;
+		}
+
+	ASN1_INTEGER_free(public_key);
+	EVP_PKEY_assign_DH(pkey, dh);
+	return 1;
+
+	err:
+	if (public_key)
+		ASN1_INTEGER_free(public_key);
+	if (dh)
+		DH_free(dh);
+	return 0;
+
+	}
+
+static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
+	{
+	DH *dh;
+	void *pval = NULL;
+	int ptype;
+	unsigned char *penc = NULL;
+	int penclen;
+	ASN1_STRING *str;
+	ASN1_INTEGER *pub_key = NULL;
+
+	dh=pkey->pkey.dh;
+
+	str = ASN1_STRING_new();
+	str->length = i2d_DHparams(dh, &str->data);
+	if (str->length <= 0)
+		{
+		DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	pval = str;
+	ptype = V_ASN1_SEQUENCE;
+
+	pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL);
+	if (!pub_key)
+		goto err;
+
+	penclen = i2d_ASN1_INTEGER(pub_key, &penc);
+
+	ASN1_INTEGER_free(pub_key);
+
+	if (penclen <= 0)
+		{
+		DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DH),
+				ptype, pval, penc, penclen))
+		return 1;
+
+	err:
+	if (penc)
+		OPENSSL_free(penc);
+	if (pval)
+		ASN1_STRING_free(pval);
+
+	return 0;
+	}
+
+
+/* PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in
+ * that the AlgorithmIdentifier contains the paramaters, the private key
+ * is explcitly included and the pubkey must be recalculated.
+ */
+	
+static int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
+	{
+	const unsigned char *p, *pm;
+	int pklen, pmlen;
+	int ptype;
+	void *pval;
+	ASN1_STRING *pstr;
+	X509_ALGOR *palg;
+	ASN1_INTEGER *privkey = NULL;
+
+	DH *dh = NULL;
+
+	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
+		return 0;
+
+	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+	if (ptype != V_ASN1_SEQUENCE)
+			goto decerr;
+
+	if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
+		goto decerr;
+
+
+	pstr = pval;	
+	pm = pstr->data;
+	pmlen = pstr->length;
+	if (!(dh = d2i_DHparams(NULL, &pm, pmlen)))
+		goto decerr;
+	/* We have parameters now set private key */
+	if (!(dh->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)))
+		{
+		DHerr(DH_F_DH_PRIV_DECODE,DH_R_BN_ERROR);
+		goto dherr;
+		}
+	/* Calculate public key */
+	if (!DH_generate_key(dh))
+		goto dherr;
+
+	EVP_PKEY_assign_DH(pkey, dh);
+
+	ASN1_INTEGER_free(privkey);
+
+	return 1;
+
+	decerr:
+	DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR);
+	dherr:
+	DH_free(dh);
+	return 0;
+	}
+
+static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+{
+	ASN1_STRING *params = NULL;
+	ASN1_INTEGER *prkey = NULL;
+	unsigned char *dp = NULL;
+	int dplen;
+
+	params = ASN1_STRING_new();
+
+	if (!params)
+		{
+		DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	params->length = i2d_DHparams(pkey->pkey.dh, &params->data);
+	if (params->length <= 0)
+		{
+		DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	params->type = V_ASN1_SEQUENCE;
+
+	/* Get private key into integer */
+	prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL);
+
+	if (!prkey)
+		{
+		DHerr(DH_F_DH_PRIV_ENCODE,DH_R_BN_ERROR);
+		goto err;
+		}
+
+	dplen = i2d_ASN1_INTEGER(prkey, &dp);
+
+	ASN1_INTEGER_free(prkey);
+
+	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dhKeyAgreement), 0,
+				V_ASN1_SEQUENCE, params, dp, dplen))
+		goto err;
+
+	return 1;
+
+err:
+	if (dp != NULL)
+		OPENSSL_free(dp);
+	if (params != NULL)
+		ASN1_STRING_free(params);
+	if (prkey != NULL)
+		ASN1_INTEGER_free(prkey);
+	return 0;
+}
+
+
+static void update_buflen(const BIGNUM *b, size_t *pbuflen)
+	{
+	size_t i;
+	if (!b)
+		return;
+	if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
+			*pbuflen = i;
+	}
+
+static int dh_param_decode(EVP_PKEY *pkey,
+					const unsigned char **pder, int derlen)
+	{
+	DH *dh;
+	if (!(dh = d2i_DHparams(NULL, pder, derlen)))
+		{
+		DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB);
+		return 0;
+		}
+	EVP_PKEY_assign_DH(pkey, dh);
+	return 1;
+	}
+
+static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
+	{
+	return i2d_DHparams(pkey->pkey.dh, pder);
+	}
+
+static int do_dh_print(BIO *bp, const DH *x, int indent,
+						ASN1_PCTX *ctx, int ptype)
+	{
+	unsigned char *m=NULL;
+	int reason=ERR_R_BUF_LIB,ret=0;
+	size_t buf_len=0;
+
+	const char *ktype = NULL;
+
+	BIGNUM *priv_key, *pub_key;
+
+	if (ptype == 2)
+		priv_key = x->priv_key;
+	else
+		priv_key = NULL;
+
+	if (ptype > 0)
+		pub_key = x->pub_key;
+	else
+		pub_key = NULL;
+
+	update_buflen(x->p, &buf_len);
+
+	if (buf_len == 0)
+		{
+		reason = ERR_R_PASSED_NULL_PARAMETER;
+		goto err;
+		}
+
+	update_buflen(x->g, &buf_len);
+	update_buflen(pub_key, &buf_len);
+	update_buflen(priv_key, &buf_len);
+
+	if (ptype == 2)
+		ktype = "PKCS#3 DH Private-Key";
+	else if (ptype == 1)
+		ktype = "PKCS#3 DH Public-Key";
+	else
+		ktype = "PKCS#3 DH Parameters";
+
+	m= OPENSSL_malloc(buf_len+10);
+	if (m == NULL)
+		{
+		reason=ERR_R_MALLOC_FAILURE;
+		goto err;
+		}
+
+	BIO_indent(bp, indent, 128);
+	if (BIO_printf(bp,"%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0)
+		goto err;
+	indent += 4;
+
+	if (!ASN1_bn_print(bp,"private-key:",priv_key,m,indent)) goto err;
+	if (!ASN1_bn_print(bp,"public-key:",pub_key,m,indent)) goto err;
+
+	if (!ASN1_bn_print(bp,"prime:",x->p,m,indent)) goto err;
+	if (!ASN1_bn_print(bp,"generator:",x->g,m,indent)) goto err;
+	if (x->length != 0)
+		{
+		BIO_indent(bp, indent, 128);
+		if (BIO_printf(bp,"recommended-private-length: %d bits\n",
+			(int)x->length) <= 0) goto err;
+		}
+
+
+	ret=1;
+	if (0)
+		{
+err:
+		DHerr(DH_F_DO_DH_PRINT,reason);
+		}
+	if (m != NULL) OPENSSL_free(m);
+	return(ret);
+	}
+
+static int int_dh_size(const EVP_PKEY *pkey)
+	{
+	return(DH_size(pkey->pkey.dh));
+	}
+
+static int dh_bits(const EVP_PKEY *pkey)
+	{
+	return BN_num_bits(pkey->pkey.dh->p);
+	}
+
+static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
+	{
+	if (	BN_cmp(a->pkey.dh->p,b->pkey.dh->p) ||
+		BN_cmp(a->pkey.dh->g,b->pkey.dh->g))
+		return 0;
+	else
+		return 1;
+	}
+
+static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+	{
+	BIGNUM *a;
+
+	if ((a=BN_dup(from->pkey.dh->p)) == NULL)
+		return 0;
+	if (to->pkey.dh->p != NULL)
+		BN_free(to->pkey.dh->p);
+	to->pkey.dh->p=a;
+
+	if ((a=BN_dup(from->pkey.dh->g)) == NULL)
+		return 0;
+	if (to->pkey.dh->g != NULL)
+		BN_free(to->pkey.dh->g);
+	to->pkey.dh->g=a;
+
+	return 1;
+	}
+
+static int dh_missing_parameters(const EVP_PKEY *a)
+	{
+	if (!a->pkey.dh->p || !a->pkey.dh->g)
+		return 1;
+	return 0;
+	}
+
+static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+	{
+	if (dh_cmp_parameters(a, b) == 0)
+		return 0;
+	if (BN_cmp(b->pkey.dh->pub_key,a->pkey.dh->pub_key) != 0)
+		return 0;
+	else
+		return 1;
+	}
+
+static int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 0);
+	}
+
+static int dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 1);
+	}
+
+static int dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 2);
+	}
+
+int DHparams_print(BIO *bp, const DH *x)
+	{
+	return do_dh_print(bp, x, 4, NULL, 0);
+	}
+
+const EVP_PKEY_ASN1_METHOD dh_asn1_meth = 
+	{
+	EVP_PKEY_DH,
+	EVP_PKEY_DH,
+	0,
+
+	"DH",
+	"OpenSSL PKCS#3 DH method",
+
+	dh_pub_decode,
+	dh_pub_encode,
+	dh_pub_cmp,
+	dh_public_print,
+
+	dh_priv_decode,
+	dh_priv_encode,
+	dh_private_print,
+
+	int_dh_size,
+	dh_bits,
+
+	dh_param_decode,
+	dh_param_encode,
+	dh_missing_parameters,
+	dh_copy_parameters,
+	dh_cmp_parameters,
+	dh_param_print,
+
+	int_dh_free,
+	0
+	};
+
diff --git a/crypto/dh/dh_asn1.c b/crypto/dh/dh_asn1.c
index 76740af..0b4357d 100644
--- a/crypto/dh/dh_asn1.c
+++ b/crypto/dh/dh_asn1.c
@@ -3,7 +3,7 @@
  * project 2000.
  */
 /* ====================================================================
- * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 2000-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
@@ -64,7 +64,8 @@
 #include <openssl/asn1t.h>
 
 /* Override the default free and new methods */
-static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+						void *exarg)
 {
 	if(operation == ASN1_OP_NEW_PRE) {
 		*pval = (ASN1_VALUE *)DH_new();
@@ -85,3 +86,8 @@
 } ASN1_SEQUENCE_END_cb(DH, DHparams)
 
 IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams)
+
+DH *DHparams_dup(DH *dh)
+	{
+	return ASN1_item_dup(ASN1_ITEM_rptr(DHparams), dh);
+	}
diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c
index 316cb92..0668981 100644
--- a/crypto/dh/dh_check.c
+++ b/crypto/dh/dh_check.c
@@ -70,8 +70,6 @@
  * should hold.
  */
 
-#ifndef OPENSSL_FIPS
-
 int DH_check(const DH *dh, int *ret)
 	{
 	int ok=0;
@@ -130,11 +128,11 @@
 	q=BN_new();
 	if (q == NULL) goto err;
 	BN_set_word(q,1);
-	if (BN_cmp(pub_key,q) <= 0)
+	if (BN_cmp(pub_key,q)<=0)
 		*ret|=DH_CHECK_PUBKEY_TOO_SMALL;
 	BN_copy(q,dh->p);
 	BN_sub_word(q,1);
-	if (BN_cmp(pub_key,q) >= 0)
+	if (BN_cmp(pub_key,q)>=0)
 		*ret|=DH_CHECK_PUBKEY_TOO_LARGE;
 
 	ok = 1;
@@ -142,5 +140,3 @@
 	if (q != NULL) BN_free(q);
 	return(ok);
 	}
-
-#endif
diff --git a/crypto/dh/dh_err.c b/crypto/dh/dh_err.c
index 13263c8..d5cf0c2 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-2007 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
@@ -71,25 +71,34 @@
 static ERR_STRING_DATA DH_str_functs[]=
 	{
 {ERR_FUNC(DH_F_COMPUTE_KEY),	"COMPUTE_KEY"},
-{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_DH_PARAM_DECODE),	"DH_PARAM_DECODE"},
+{ERR_FUNC(DH_F_DH_PRIV_DECODE),	"DH_PRIV_DECODE"},
+{ERR_FUNC(DH_F_DH_PRIV_ENCODE),	"DH_PRIV_ENCODE"},
+{ERR_FUNC(DH_F_DH_PUB_DECODE),	"DH_PUB_DECODE"},
+{ERR_FUNC(DH_F_DH_PUB_ENCODE),	"DH_PUB_ENCODE"},
+{ERR_FUNC(DH_F_DO_DH_PRINT),	"DO_DH_PRINT"},
 {ERR_FUNC(DH_F_GENERATE_KEY),	"GENERATE_KEY"},
 {ERR_FUNC(DH_F_GENERATE_PARAMETERS),	"GENERATE_PARAMETERS"},
+{ERR_FUNC(DH_F_PKEY_DH_DERIVE),	"PKEY_DH_DERIVE"},
+{ERR_FUNC(DH_F_PKEY_DH_KEYGEN),	"PKEY_DH_KEYGEN"},
 {0,NULL}
 	};
 
 static ERR_STRING_DATA DH_str_reasons[]=
 	{
 {ERR_REASON(DH_R_BAD_GENERATOR)          ,"bad generator"},
+{ERR_REASON(DH_R_BN_DECODE_ERROR)        ,"bn decode error"},
+{ERR_REASON(DH_R_BN_ERROR)               ,"bn error"},
+{ERR_REASON(DH_R_DECODE_ERROR)           ,"decode error"},
 {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_KEYS_NOT_SET)           ,"keys not set"},
 {ERR_REASON(DH_R_MODULUS_TOO_LARGE)      ,"modulus too large"},
+{ERR_REASON(DH_R_NO_PARAMETERS_SET)      ,"no parameters set"},
 {ERR_REASON(DH_R_NO_PRIVATE_VALUE)       ,"no private value"},
+{ERR_REASON(DH_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
 {0,NULL}
 	};
 
diff --git a/crypto/dh/dh_gen.c b/crypto/dh/dh_gen.c
index 999e1de..cfd5b11 100644
--- a/crypto/dh/dh_gen.c
+++ b/crypto/dh/dh_gen.c
@@ -66,8 +66,6 @@
 #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)
@@ -175,5 +173,3 @@
 		}
 	return ok;
 	}
-
-#endif
diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c
index 79dd331..e7db440 100644
--- a/crypto/dh/dh_key.c
+++ b/crypto/dh/dh_key.c
@@ -62,8 +62,6 @@
 #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,
@@ -263,5 +261,3 @@
 		BN_MONT_CTX_free(dh->method_mont_p);
 	return(1);
 	}
-
-#endif
diff --git a/crypto/dh/dh_pmeth.c b/crypto/dh/dh_pmeth.c
new file mode 100644
index 0000000..5ae72b7
--- /dev/null
+++ b/crypto/dh/dh_pmeth.c
@@ -0,0 +1,254 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/evp.h>
+#include <openssl/dh.h>
+#include <openssl/bn.h>
+#include "evp_locl.h"
+
+/* DH pkey context structure */
+
+typedef struct
+	{
+	/* Parameter gen parameters */
+	int prime_len;
+	int generator;
+	int use_dsa;
+	/* Keygen callback info */
+	int gentmp[2];
+	/* message digest */
+	} DH_PKEY_CTX;
+
+static int pkey_dh_init(EVP_PKEY_CTX *ctx)
+	{
+	DH_PKEY_CTX *dctx;
+	dctx = OPENSSL_malloc(sizeof(DH_PKEY_CTX));
+	if (!dctx)
+		return 0;
+	dctx->prime_len = 1024;
+	dctx->generator = 2;
+	dctx->use_dsa = 0;
+
+	ctx->data = dctx;
+	ctx->keygen_info = dctx->gentmp;
+	ctx->keygen_info_count = 2;
+	
+	return 1;
+	}
+
+static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+	{
+	DH_PKEY_CTX *dctx, *sctx;
+	if (!pkey_dh_init(dst))
+		return 0;
+       	sctx = src->data;
+	dctx = dst->data;
+	dctx->prime_len = sctx->prime_len;
+	dctx->generator = sctx->generator;
+	dctx->use_dsa = sctx->use_dsa;
+	return 1;
+	}
+
+static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
+	{
+	DH_PKEY_CTX *dctx = ctx->data;
+	if (dctx)
+		OPENSSL_free(dctx);
+	}
+
+static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+	{
+	DH_PKEY_CTX *dctx = ctx->data;
+	switch (type)
+		{
+		case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
+		if (p1 < 256)
+			return -2;
+		dctx->prime_len = p1;
+		return 1;
+
+		case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
+		dctx->generator = p1;
+		return 1;
+
+		case EVP_PKEY_CTRL_PEER_KEY:
+		/* Default behaviour is OK */
+		return 1;
+
+		default:
+		return -2;
+
+		}
+	}
+
+			
+static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
+			const char *type, const char *value)
+	{
+	if (!strcmp(type, "dh_paramgen_prime_len"))
+		{
+		int len;
+		len = atoi(value);
+		return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
+		}
+	if (!strcmp(type, "dh_paramgen_generator"))
+		{
+		int len;
+		len = atoi(value);
+		return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
+		}
+	return -2;
+	}
+
+static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+	{
+	DH *dh = NULL;
+	DH_PKEY_CTX *dctx = ctx->data;
+	BN_GENCB *pcb, cb;
+	int ret;
+	if (ctx->pkey_gencb)
+		{
+		pcb = &cb;
+		evp_pkey_set_cb_translate(pcb, ctx);
+		}
+	else
+		pcb = NULL;
+	dh = DH_new();
+	if (!dh)
+		return 0;
+	ret = DH_generate_parameters_ex(dh,
+					dctx->prime_len, dctx->generator, pcb);
+	if (ret)
+		EVP_PKEY_assign_DH(pkey, dh);
+	else
+		DH_free(dh);
+	return ret;
+	}
+
+static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+	{
+	DH *dh = NULL;
+	if (ctx->pkey == NULL)
+		{
+		DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
+		return 0;
+		}
+	dh = DH_new();
+	if (!dh)
+		return 0;
+	EVP_PKEY_assign_DH(pkey, dh);
+	/* Note: if error return, pkey is freed by parent routine */
+	if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
+		return 0;
+	return DH_generate_key(pkey->pkey.dh);
+	}
+
+static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
+	{
+	int ret;
+	if (!ctx->pkey || !ctx->peerkey)
+		{
+		DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
+		return 0;
+		}
+	ret = DH_compute_key(key, ctx->peerkey->pkey.dh->pub_key,
+							ctx->pkey->pkey.dh);
+	if (ret < 0)
+		return ret;
+	*keylen = ret;
+	return 1;
+	}
+
+const EVP_PKEY_METHOD dh_pkey_meth = 
+	{
+	EVP_PKEY_DH,
+	EVP_PKEY_FLAG_AUTOARGLEN,
+	pkey_dh_init,
+	pkey_dh_copy,
+	pkey_dh_cleanup,
+
+	0,
+	pkey_dh_paramgen,
+
+	0,
+	pkey_dh_keygen,
+
+	0,
+	0,
+
+	0,
+	0,
+
+	0,0,
+
+	0,0,0,0,
+
+	0,0,
+
+	0,0,
+
+	0,
+	pkey_dh_derive,
+
+	pkey_dh_ctrl,
+	pkey_dh_ctrl_str
+
+	};
diff --git a/crypto/dsa/Makefile b/crypto/dsa/Makefile
deleted file mode 100644
index 6c9578c..0000000
--- a/crypto/dsa/Makefile
+++ /dev/null
@@ -1,188 +0,0 @@
-#
-# OpenSSL/crypto/dsa/Makefile
-#
-
-DIR=	dsa
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=dsatest.c
-APPS=
-
-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_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_utl.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= dsa.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-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/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/rand.h ../../include/openssl/safestack.h
-dsa_asn1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-dsa_asn1.o: ../cryptlib.h dsa_asn1.c
-dsa_depr.o: ../../e_os.h ../../include/openssl/asn1.h
-dsa_depr.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-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/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
-dsa_depr.o: ../../include/openssl/symhacks.h ../cryptlib.h dsa_depr.c
-dsa_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
-dsa_err.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
-dsa_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-dsa_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-dsa_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-dsa_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-dsa_err.o: dsa_err.c
-dsa_gen.o: ../../e_os.h ../../include/openssl/asn1.h
-dsa_gen.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-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/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
-dsa_key.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-dsa_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-dsa_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-dsa_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-dsa_key.o: ../../include/openssl/symhacks.h ../cryptlib.h dsa_key.c
-dsa_lib.o: ../../e_os.h ../../include/openssl/asn1.h
-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/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
-dsa_ossl.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
-dsa_ossl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-dsa_ossl.o: ../../include/openssl/opensslconf.h
-dsa_ossl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-dsa_ossl.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-dsa_ossl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-dsa_ossl.o: ../cryptlib.h dsa_ossl.c
-dsa_sign.o: ../../e_os.h ../../include/openssl/asn1.h
-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/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/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 702c50d..ac50a5c 100644
--- a/crypto/dsa/dsa.h
+++ b/crypto/dsa/dsa.h
@@ -88,8 +88,6 @@
 # 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
@@ -99,25 +97,6 @@
                                               * 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
@@ -139,7 +118,7 @@
 	int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
 								BIGNUM **rp);
 	int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len,
-							DSA_SIG *sig, DSA *dsa);
+			     DSA_SIG *sig, DSA *dsa);
 	int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
 			BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
 			BN_MONT_CTX *in_mont);
@@ -152,7 +131,7 @@
 	char *app_data;
 	/* If this is non-NULL, it is used to generate DSA parameters */
 	int (*dsa_paramgen)(DSA *dsa, int bits,
-			unsigned char *seed, int seed_len,
+			const unsigned char *seed, int seed_len,
 			int *counter_ret, unsigned long *h_ret,
 			BN_GENCB *cb);
 	/* If this is non-NULL, it is used to generate DSA keys */
@@ -186,7 +165,6 @@
 	ENGINE *engine;
 	};
 
-#define DSAparams_dup(x) ASN1_dup_of_const(DSA,i2d_DSAparams,d2i_DSAparams,x)
 #define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \
 		(char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x))
 #define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \
@@ -195,6 +173,7 @@
 #define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x)
 
 
+DSA *DSAparams_dup(DSA *x);
 DSA_SIG * DSA_SIG_new(void);
 void	DSA_SIG_free(DSA_SIG *a);
 int	i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp);
@@ -210,11 +189,6 @@
 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);
@@ -246,7 +220,7 @@
 
 /* New version */
 int	DSA_generate_parameters_ex(DSA *dsa, int bits,
-		unsigned char *seed,int seed_len,
+		const unsigned char *seed,int seed_len,
 		int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
 
 int	DSA_generate_key(DSA *a);
@@ -275,10 +249,13 @@
 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
+#define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \
+				EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL)
+
+#define	EVP_PKEY_CTRL_DSA_PARAMGEN_BITS		(EVP_PKEY_ALG_CTRL + 1)
+#define	EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS	(EVP_PKEY_ALG_CTRL + 2)
+#define	EVP_PKEY_CTRL_DSA_PARAMGEN_MD		(EVP_PKEY_ALG_CTRL + 3)
 
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -290,33 +267,39 @@
 
 /* Function codes. */
 #define DSA_F_D2I_DSA_SIG				 110
+#define DSA_F_DO_DSA_PRINT				 104
 #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_PARAM_DECODE				 119
 #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_PRIV_DECODE				 115
+#define DSA_F_DSA_PRIV_ENCODE				 116
+#define DSA_F_DSA_PUB_DECODE				 117
+#define DSA_F_DSA_PUB_ENCODE				 118
 #define DSA_F_DSA_SIGN					 106
 #define DSA_F_DSA_SIGN_SETUP				 107
 #define DSA_F_DSA_SIG_NEW				 109
 #define DSA_F_DSA_VERIFY				 108
 #define DSA_F_I2D_DSA_SIG				 111
+#define DSA_F_OLD_DSA_PRIV_DECODE			 122
+#define DSA_F_PKEY_DSA_CTRL				 120
+#define DSA_F_PKEY_DSA_KEYGEN				 121
 #define DSA_F_SIG_CB					 114
 
 /* Reason codes. */
 #define DSA_R_BAD_Q_VALUE				 102
+#define DSA_R_BN_DECODE_ERROR				 108
+#define DSA_R_BN_ERROR					 109
 #define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE		 100
-#define DSA_R_KEY_SIZE_TOO_SMALL			 106
+#define DSA_R_DECODE_ERROR				 104
+#define DSA_R_INVALID_DIGEST_TYPE			 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
+#define DSA_R_NO_PARAMETERS_SET				 107
+#define DSA_R_PARAMETER_ENCODING_ERROR			 105
 
 #ifdef  __cplusplus
 }
diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c
new file mode 100644
index 0000000..5482330
--- /dev/null
+++ b/crypto/dsa/dsa_ameth.c
@@ -0,0 +1,657 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/dsa.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_CMS
+#include <openssl/cms.h>
+#endif
+#include "asn1_locl.h"
+
+static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+	{
+	const unsigned char *p, *pm;
+	int pklen, pmlen;
+	int ptype;
+	void *pval;
+	ASN1_STRING *pstr;
+	X509_ALGOR *palg;
+	ASN1_INTEGER *public_key = NULL;
+
+	DSA *dsa = NULL;
+
+	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
+		return 0;
+	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+
+	if (ptype == V_ASN1_SEQUENCE)
+		{
+		pstr = pval;	
+		pm = pstr->data;
+		pmlen = pstr->length;
+
+		if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
+			{
+			DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
+			goto err;
+			}
+
+		}
+	else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF))
+		{
+		if (!(dsa = DSA_new()))
+			{
+			DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+	else
+		{
+		DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR);
+		goto err;
+		}
+
+	if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen)))
+		{
+		DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
+		goto err;
+		}
+
+	if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)))
+		{
+		DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR);
+		goto err;
+		}
+
+	ASN1_INTEGER_free(public_key);
+	EVP_PKEY_assign_DSA(pkey, dsa);
+	return 1;
+
+	err:
+	if (public_key)
+		ASN1_INTEGER_free(public_key);
+	if (dsa)
+		DSA_free(dsa);
+	return 0;
+
+	}
+
+static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
+	{
+	DSA *dsa;
+	void *pval = NULL;
+	int ptype;
+	unsigned char *penc = NULL;
+	int penclen;
+
+	dsa=pkey->pkey.dsa;
+	if (pkey->save_parameters && dsa->p && dsa->q && dsa->g)
+		{
+		ASN1_STRING *str;
+		str = ASN1_STRING_new();
+		str->length = i2d_DSAparams(dsa, &str->data);
+		if (str->length <= 0)
+			{
+			DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		pval = str;
+		ptype = V_ASN1_SEQUENCE;
+		}
+	else
+		ptype = V_ASN1_UNDEF;
+
+	dsa->write_params=0;
+
+	penclen = i2d_DSAPublicKey(dsa, &penc);
+
+	if (penclen <= 0)
+		{
+		DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA),
+				ptype, pval, penc, penclen))
+		return 1;
+
+	err:
+	if (penc)
+		OPENSSL_free(penc);
+	if (pval)
+		ASN1_STRING_free(pval);
+
+	return 0;
+	}
+
+/* In PKCS#8 DSA: you just get a private key integer and parameters in the
+ * AlgorithmIdentifier the pubkey must be recalculated.
+ */
+	
+static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
+	{
+	const unsigned char *p, *pm;
+	int pklen, pmlen;
+	int ptype;
+	void *pval;
+	ASN1_STRING *pstr;
+	X509_ALGOR *palg;
+	ASN1_INTEGER *privkey = NULL;
+	BN_CTX *ctx = NULL;
+
+	STACK_OF(ASN1_TYPE) *ndsa = NULL;
+	DSA *dsa = NULL;
+
+	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
+		return 0;
+	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+	/* Check for broken DSA PKCS#8, UGH! */
+	if (*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED))
+		{
+		ASN1_TYPE *t1, *t2;
+	    	if(!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen)));
+			goto decerr;
+		if (sk_ASN1_TYPE_num(ndsa) != 2)
+			goto decerr;
+		/* Handle Two broken types:
+	    	 * SEQUENCE {parameters, priv_key}
+		 * SEQUENCE {pub_key, priv_key}
+		 */
+
+		t1 = sk_ASN1_TYPE_value(ndsa, 0);
+		t2 = sk_ASN1_TYPE_value(ndsa, 1);
+		if (t1->type == V_ASN1_SEQUENCE)
+			{
+			p8->broken = PKCS8_EMBEDDED_PARAM;
+			pval = t1->value.ptr;
+			}
+		else if (ptype == V_ASN1_SEQUENCE)
+			p8->broken = PKCS8_NS_DB;
+		else
+			goto decerr;
+
+		if (t2->type != V_ASN1_INTEGER)
+			goto decerr;
+
+		privkey = t2->value.integer;
+		}
+	else
+		{
+		const unsigned char *q = p;
+		if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
+			goto decerr;
+		if (privkey->type == V_ASN1_NEG_INTEGER)
+			{
+			p8->broken = PKCS8_NEG_PRIVKEY;
+			ASN1_INTEGER_free(privkey);
+			if (!(privkey=d2i_ASN1_UINTEGER(NULL, &q, pklen)))
+				goto decerr;
+			}
+		if (ptype != V_ASN1_SEQUENCE)
+			goto decerr;
+		}
+
+	pstr = pval;	
+	pm = pstr->data;
+	pmlen = pstr->length;
+	if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
+		goto decerr;
+	/* We have parameters now set private key */
+	if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)))
+		{
+		DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
+		goto dsaerr;
+		}
+	/* Calculate public key */
+	if (!(dsa->pub_key = BN_new()))
+		{
+		DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
+		goto dsaerr;
+		}
+	if (!(ctx = BN_CTX_new()))
+		{
+		DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
+		goto dsaerr;
+		}
+			
+	if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx))
+		{
+		DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
+		goto dsaerr;
+		}
+
+	EVP_PKEY_assign_DSA(pkey, dsa);
+	BN_CTX_free (ctx);
+	if(ndsa)
+		sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
+	else
+		ASN1_INTEGER_free(privkey);
+
+	return 1;
+
+	decerr:
+	DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR);
+	dsaerr:
+	BN_CTX_free (ctx);
+	if (privkey)
+		ASN1_INTEGER_free(privkey);
+	sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
+	DSA_free(dsa);
+	return 0;
+	}
+
+static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+{
+	ASN1_STRING *params = NULL;
+	ASN1_INTEGER *prkey = NULL;
+	unsigned char *dp = NULL;
+	int dplen;
+
+	params = ASN1_STRING_new();
+
+	if (!params)
+		{
+		DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
+	if (params->length <= 0)
+		{
+		DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	params->type = V_ASN1_SEQUENCE;
+
+	/* Get private key into integer */
+	prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
+
+	if (!prkey)
+		{
+		DSAerr(DSA_F_DSA_PRIV_ENCODE,DSA_R_BN_ERROR);
+		goto err;
+		}
+
+	dplen = i2d_ASN1_INTEGER(prkey, &dp);
+
+	ASN1_INTEGER_free(prkey);
+
+	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0,
+				V_ASN1_SEQUENCE, params, dp, dplen))
+		goto err;
+
+	return 1;
+
+err:
+	if (dp != NULL)
+		OPENSSL_free(dp);
+	if (params != NULL)
+		ASN1_STRING_free(params);
+	if (prkey != NULL)
+		ASN1_INTEGER_free(prkey);
+	return 0;
+}
+
+static int int_dsa_size(const EVP_PKEY *pkey)
+	{
+	return(DSA_size(pkey->pkey.dsa));
+	}
+
+static int dsa_bits(const EVP_PKEY *pkey)
+	{
+	return BN_num_bits(pkey->pkey.dsa->p);
+	}
+
+static int dsa_missing_parameters(const EVP_PKEY *pkey)
+	{
+	DSA *dsa;
+	dsa=pkey->pkey.dsa;
+	if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
+			return 1;
+	return 0;
+	}
+
+static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+	{
+	BIGNUM *a;
+
+	if ((a=BN_dup(from->pkey.dsa->p)) == NULL)
+		return 0;
+	if (to->pkey.dsa->p != NULL)
+		BN_free(to->pkey.dsa->p);
+	to->pkey.dsa->p=a;
+
+	if ((a=BN_dup(from->pkey.dsa->q)) == NULL)
+		return 0;
+	if (to->pkey.dsa->q != NULL)
+		BN_free(to->pkey.dsa->q);
+	to->pkey.dsa->q=a;
+
+	if ((a=BN_dup(from->pkey.dsa->g)) == NULL)
+		return 0;
+	if (to->pkey.dsa->g != NULL)
+		BN_free(to->pkey.dsa->g);
+	to->pkey.dsa->g=a;
+	return 1;
+	}
+
+static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
+	{
+	if (	BN_cmp(a->pkey.dsa->p,b->pkey.dsa->p) ||
+		BN_cmp(a->pkey.dsa->q,b->pkey.dsa->q) ||
+		BN_cmp(a->pkey.dsa->g,b->pkey.dsa->g))
+		return 0;
+	else
+		return 1;
+	}
+
+static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+	{
+	if (BN_cmp(b->pkey.dsa->pub_key,a->pkey.dsa->pub_key) != 0)
+		return 0;
+	else
+		return 1;
+	}
+
+static void int_dsa_free(EVP_PKEY *pkey)
+	{
+	DSA_free(pkey->pkey.dsa);
+	}
+
+static void update_buflen(const BIGNUM *b, size_t *pbuflen)
+	{
+	size_t i;
+	if (!b)
+		return;
+	if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
+			*pbuflen = i;
+	}
+
+static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
+	{
+	unsigned char *m=NULL;
+	int ret=0;
+	size_t buf_len=0;
+	const char *ktype = NULL;
+
+	const BIGNUM *priv_key, *pub_key;
+
+	if (ptype == 2)
+		priv_key = x->priv_key;
+	else
+		priv_key = NULL;
+
+	if (ptype > 0)
+		pub_key = x->pub_key;
+	else
+		pub_key = NULL;
+
+	if (ptype == 2)
+		ktype = "Private-Key";
+	else if (ptype == 1)
+		ktype = "Public-Key";
+	else
+		ktype = "DSA-Parameters";
+
+	update_buflen(x->p, &buf_len);
+	update_buflen(x->q, &buf_len);
+	update_buflen(x->g, &buf_len);
+	update_buflen(priv_key, &buf_len);
+	update_buflen(pub_key, &buf_len);
+
+	m=(unsigned char *)OPENSSL_malloc(buf_len+10);
+	if (m == NULL)
+		{
+		DSAerr(DSA_F_DO_DSA_PRINT,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (priv_key)
+		{
+		if(!BIO_indent(bp,off,128))
+		   goto err;
+		if (BIO_printf(bp,"%s: (%d bit)\n",ktype, BN_num_bits(x->p))
+			<= 0) goto err;
+		}
+
+	if (!ASN1_bn_print(bp,"priv:",priv_key,m,off))
+		goto err;
+	if (!ASN1_bn_print(bp,"pub: ",pub_key,m,off))
+		goto err;
+	if (!ASN1_bn_print(bp,"P:   ",x->p,m,off)) goto err;
+	if (!ASN1_bn_print(bp,"Q:   ",x->q,m,off)) goto err;
+	if (!ASN1_bn_print(bp,"G:   ",x->g,m,off)) goto err;
+	ret=1;
+err:
+	if (m != NULL) OPENSSL_free(m);
+	return(ret);
+	}
+
+static int dsa_param_decode(EVP_PKEY *pkey,
+					const unsigned char **pder, int derlen)
+	{
+	DSA *dsa;
+	if (!(dsa = d2i_DSAparams(NULL, pder, derlen)))
+		{
+		DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB);
+		return 0;
+		}
+	EVP_PKEY_assign_DSA(pkey, dsa);
+	return 1;
+	}
+
+static int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
+	{
+	return i2d_DSAparams(pkey->pkey.dsa, pder);
+	}
+
+static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
+	}
+
+static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
+	}
+
+
+static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
+	}
+
+static int old_dsa_priv_decode(EVP_PKEY *pkey,
+					const unsigned char **pder, int derlen)
+	{
+	DSA *dsa;
+	if (!(dsa = d2i_DSAPrivateKey (NULL, pder, derlen)))
+		{
+		DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB);
+		return 0;
+		}
+	EVP_PKEY_assign_DSA(pkey, dsa);
+	return 1;
+	}
+
+static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
+	{
+	return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
+	}
+
+static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+	{
+	switch (op)
+		{
+		case ASN1_PKEY_CTRL_PKCS7_SIGN:
+		if (arg1 == 0)
+			{
+			int snid, hnid;
+			X509_ALGOR *alg1, *alg2;
+			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
+			if (alg1 == NULL || alg1->algorithm == NULL)
+				return -1;
+			hnid = OBJ_obj2nid(alg1->algorithm);
+			if (hnid == NID_undef)
+				return -1;
+			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
+				return -1; 
+			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
+			}
+		return 1;
+#ifndef OPENSSL_NO_CMS
+		case ASN1_PKEY_CTRL_CMS_SIGN:
+		if (arg1 == 0)
+			{
+			int snid, hnid;
+			X509_ALGOR *alg1, *alg2;
+			CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
+			if (alg1 == NULL || alg1->algorithm == NULL)
+				return -1;
+			hnid = OBJ_obj2nid(alg1->algorithm);
+			if (hnid == NID_undef)
+				return -1;
+			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
+				return -1; 
+			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
+			}
+		return 1;
+#endif
+
+		case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+		*(int *)arg2 = NID_sha1;
+		return 2;
+
+		default:
+		return -2;
+
+		}
+
+	}
+
+/* NB these are sorted in pkey_id order, lowest first */
+
+const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = 
+	{
+
+		{
+		EVP_PKEY_DSA2,
+		EVP_PKEY_DSA,
+		ASN1_PKEY_ALIAS
+		},
+
+		{
+		EVP_PKEY_DSA1,
+		EVP_PKEY_DSA,
+		ASN1_PKEY_ALIAS
+		},
+
+		{
+		EVP_PKEY_DSA4,
+		EVP_PKEY_DSA,
+		ASN1_PKEY_ALIAS
+		},
+
+		{
+		EVP_PKEY_DSA3,
+		EVP_PKEY_DSA,
+		ASN1_PKEY_ALIAS
+		},
+
+		{
+		EVP_PKEY_DSA,
+		EVP_PKEY_DSA,
+		0,
+
+		"DSA",
+		"OpenSSL DSA method",
+
+		dsa_pub_decode,
+		dsa_pub_encode,
+		dsa_pub_cmp,
+		dsa_pub_print,
+
+		dsa_priv_decode,
+		dsa_priv_encode,
+		dsa_priv_print,
+
+		int_dsa_size,
+		dsa_bits,
+
+		dsa_param_decode,
+		dsa_param_encode,
+		dsa_missing_parameters,
+		dsa_copy_parameters,
+		dsa_cmp_parameters,
+		dsa_param_print,
+
+		int_dsa_free,
+		dsa_pkey_ctrl,
+		old_dsa_priv_decode,
+		old_dsa_priv_encode
+		}
+	};
+
diff --git a/crypto/dsa/dsa_asn1.c b/crypto/dsa/dsa_asn1.c
index bc7d7a0..c37460b 100644
--- a/crypto/dsa/dsa_asn1.c
+++ b/crypto/dsa/dsa_asn1.c
@@ -3,7 +3,7 @@
  * project 2000.
  */
 /* ====================================================================
- * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 2000-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
@@ -61,25 +61,23 @@
 #include <openssl/dsa.h>
 #include <openssl/asn1.h>
 #include <openssl/asn1t.h>
-#include <openssl/bn.h>
-#include <openssl/rand.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)
+static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+								void *exarg)
 {
 	if(operation == ASN1_OP_NEW_PRE) {
 		DSA_SIG *sig;
 		sig = OPENSSL_malloc(sizeof(DSA_SIG));
+		if (!sig)
+			{
+			DSAerr(DSA_F_SIG_CB, ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
 		sig->r = NULL;
 		sig->s = NULL;
 		*pval = (ASN1_VALUE *)sig;
-		if(sig) return 2;
-		DSAerr(DSA_F_SIG_CB, ERR_R_MALLOC_FAILURE);
-		return 0;
+		return 2;
 	}
 	return 1;
 }
@@ -89,10 +87,11 @@
 	ASN1_SIMPLE(DSA_SIG, s, CBIGNUM)
 } ASN1_SEQUENCE_END_cb(DSA_SIG, DSA_SIG)
 
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG,DSA_SIG,DSA_SIG)
+IMPLEMENT_ASN1_FUNCTIONS_const(DSA_SIG)
 
 /* Override the default free and new methods */
-static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+							void *exarg)
 {
 	if(operation == ASN1_OP_NEW_PRE) {
 		*pval = (ASN1_VALUE *)DSA_new();
@@ -145,76 +144,7 @@
 
 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 *DSAparams_dup(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
-	RAND_seed(dgst, dlen);
-	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);
+	return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa);
 	}
-
-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 872839a..bba984e 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-2007 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
@@ -71,23 +71,26 @@
 static ERR_STRING_DATA DSA_str_functs[]=
 	{
 {ERR_FUNC(DSA_F_D2I_DSA_SIG),	"d2i_DSA_SIG"},
+{ERR_FUNC(DSA_F_DO_DSA_PRINT),	"DO_DSA_PRINT"},
 {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_PARAM_DECODE),	"DSA_PARAM_DECODE"},
 {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_PRIV_DECODE),	"DSA_PRIV_DECODE"},
+{ERR_FUNC(DSA_F_DSA_PRIV_ENCODE),	"DSA_PRIV_ENCODE"},
+{ERR_FUNC(DSA_F_DSA_PUB_DECODE),	"DSA_PUB_DECODE"},
+{ERR_FUNC(DSA_F_DSA_PUB_ENCODE),	"DSA_PUB_ENCODE"},
 {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"},
 {ERR_FUNC(DSA_F_DSA_VERIFY),	"DSA_verify"},
 {ERR_FUNC(DSA_F_I2D_DSA_SIG),	"i2d_DSA_SIG"},
+{ERR_FUNC(DSA_F_OLD_DSA_PRIV_DECODE),	"OLD_DSA_PRIV_DECODE"},
+{ERR_FUNC(DSA_F_PKEY_DSA_CTRL),	"PKEY_DSA_CTRL"},
+{ERR_FUNC(DSA_F_PKEY_DSA_KEYGEN),	"PKEY_DSA_KEYGEN"},
 {ERR_FUNC(DSA_F_SIG_CB),	"SIG_CB"},
 {0,NULL}
 	};
@@ -95,12 +98,15 @@
 static ERR_STRING_DATA DSA_str_reasons[]=
 	{
 {ERR_REASON(DSA_R_BAD_Q_VALUE)           ,"bad q value"},
+{ERR_REASON(DSA_R_BN_DECODE_ERROR)       ,"bn decode error"},
+{ERR_REASON(DSA_R_BN_ERROR)              ,"bn error"},
 {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_DECODE_ERROR)          ,"decode error"},
+{ERR_REASON(DSA_R_INVALID_DIGEST_TYPE)   ,"invalid digest type"},
 {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"},
+{ERR_REASON(DSA_R_NO_PARAMETERS_SET)     ,"no parameters set"},
+{ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
 {0,NULL}
 	};
 
diff --git a/crypto/dsa/dsa_gen.c b/crypto/dsa/dsa_gen.c
index 6f1728e..0fcd25f 100644
--- a/crypto/dsa/dsa_gen.c
+++ b/crypto/dsa/dsa_gen.c
@@ -74,69 +74,88 @@
 #ifndef OPENSSL_NO_SHA
 
 #include <stdio.h>
-#include <time.h>
 #include "cryptlib.h"
 #include <openssl/evp.h>
 #include <openssl/bn.h>
-#include <openssl/dsa.h>
 #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);
+#include "dsa_locl.h"
 
 int DSA_generate_parameters_ex(DSA *ret, int bits,
-		unsigned char *seed_in, int seed_len,
+		const unsigned char *seed_in, int seed_len,
 		int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
 	{
 	if(ret->meth->dsa_paramgen)
 		return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
 				counter_ret, h_ret, cb);
-	return dsa_builtin_paramgen(ret, bits, seed_in, seed_len,
-			counter_ret, h_ret, cb);
+	else
+		{
+		const EVP_MD *evpmd;
+		size_t qbits = bits >= 2048 ? 256 : 160;
+
+		if (bits >= 2048)
+			{
+			qbits = 256;
+			evpmd = EVP_sha256();
+			}
+		else
+			{
+			qbits = 160;
+			evpmd = EVP_sha1();
+			}
+
+		return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
+				seed_in, seed_len, counter_ret, h_ret, cb);
+		}
 	}
 
-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)
+int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
+	const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
+	int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
 	{
 	int ok=0;
-	unsigned char seed[SHA_DIGEST_LENGTH];
-	unsigned char md[SHA_DIGEST_LENGTH];
-	unsigned char buf[SHA_DIGEST_LENGTH],buf2[SHA_DIGEST_LENGTH];
+	unsigned char seed[SHA256_DIGEST_LENGTH];
+	unsigned char md[SHA256_DIGEST_LENGTH];
+	unsigned char buf[SHA256_DIGEST_LENGTH],buf2[SHA256_DIGEST_LENGTH];
 	BIGNUM *r0,*W,*X,*c,*test;
 	BIGNUM *g=NULL,*q=NULL,*p=NULL;
 	BN_MONT_CTX *mont=NULL;
-	int k,n=0,i,b,m=0;
+	int i, k,n=0,b,m=0, qsize = qbits >> 3;
 	int counter=0;
 	int r=0;
 	BN_CTX *ctx=NULL;
 	unsigned int h=2;
 
-	if (bits < 512) bits=512;
-	bits=(bits+63)/64*64;
+	if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
+	    qsize != SHA256_DIGEST_LENGTH)
+		/* invalid q size */
+		return 0;
+
+	if (evpmd == NULL)
+		/* use SHA1 as default */
+		evpmd = EVP_sha1();
+
+	if (bits < 512)
+		bits = 512;
+
+	bits = (bits+63)/64*64;
 
 	/* NB: seed_len == 0 is special case: copy generated seed to
  	 * seed_in if it is not NULL.
  	 */
-	if (seed_len && (seed_len < 20))
-		seed_in = NULL; /* seed buffer too small -- ignore */
-	if (seed_len > 20) 
-		seed_len = 20; /* App. 2.2 of FIPS PUB 186 allows larger SEED,
-		                * but our internal buffers are restricted to 160 bits*/
-	if ((seed_in != NULL) && (seed_len == 20))
-		{
-		memcpy(seed,seed_in,seed_len);
-		/* set seed_in to NULL to avoid it being copied back */
-		seed_in = NULL;
-		}
+	if (seed_len && (seed_len < (size_t)qsize))
+		seed_in = NULL;		/* seed buffer too small -- ignore */
+	if (seed_len > (size_t)qsize) 
+		seed_len = qsize;	/* App. 2.2 of FIPS PUB 186 allows larger SEED,
+					 * but our internal buffers are restricted to 160 bits*/
+	if (seed_in != NULL)
+		memcpy(seed, seed_in, seed_len);
 
-	if ((ctx=BN_CTX_new()) == NULL) goto err;
+	if ((ctx=BN_CTX_new()) == NULL)
+		goto err;
 
-	if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
+	if ((mont=BN_MONT_CTX_new()) == NULL)
+		goto err;
 
 	BN_CTX_start(ctx);
 	r0 = BN_CTX_get(ctx);
@@ -163,7 +182,7 @@
 
 			if (!seed_len)
 				{
-				RAND_pseudo_bytes(seed,SHA_DIGEST_LENGTH);
+				RAND_pseudo_bytes(seed, qsize);
 				seed_is_random = 1;
 				}
 			else
@@ -171,25 +190,27 @@
 				seed_is_random = 0;
 				seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/
 				}
-			memcpy(buf,seed,SHA_DIGEST_LENGTH);
-			memcpy(buf2,seed,SHA_DIGEST_LENGTH);
+			memcpy(buf , seed, qsize);
+			memcpy(buf2, seed, qsize);
 			/* precompute "SEED + 1" for step 7: */
-			for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)
+			for (i = qsize-1; i >= 0; i--)
 				{
 				buf[i]++;
-				if (buf[i] != 0) break;
+				if (buf[i] != 0)
+					break;
 				}
 
 			/* step 2 */
-			EVP_Digest(seed,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL);
-			EVP_Digest(buf,SHA_DIGEST_LENGTH,buf2,NULL,HASH, NULL);
-			for (i=0; i<SHA_DIGEST_LENGTH; i++)
+			EVP_Digest(seed, qsize, md,   NULL, evpmd, NULL);
+			EVP_Digest(buf,  qsize, buf2, NULL, evpmd, NULL);
+			for (i = 0; i < qsize; i++)
 				md[i]^=buf2[i];
 
 			/* step 3 */
-			md[0]|=0x80;
-			md[SHA_DIGEST_LENGTH-1]|=0x01;
-			if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,q)) goto err;
+			md[0] |= 0x80;
+			md[qsize-1] |= 0x01;
+			if (!BN_bin2bn(md, qsize, q))
+				goto err;
 
 			/* step 4 */
 			r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
@@ -224,18 +245,19 @@
 			for (k=0; k<=n; k++)
 				{
 				/* obtain "SEED + offset + k" by incrementing: */
-				for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)
+				for (i = qsize-1; i >= 0; i--)
 					{
 					buf[i]++;
-					if (buf[i] != 0) break;
+					if (buf[i] != 0)
+						break;
 					}
 
-				EVP_Digest(buf,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL);
+				EVP_Digest(buf, qsize, md ,NULL, evpmd, NULL);
 
 				/* step 8 */
-				if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,r0))
+				if (!BN_bin2bn(md, qsize, r0))
 					goto err;
-				if (!BN_lshift(r0,r0,160*k)) goto err;
+				if (!BN_lshift(r0,r0,(qsize << 3)*k)) goto err;
 				if (!BN_add(W,W,r0)) goto err;
 				}
 
@@ -309,7 +331,6 @@
 			ok=0;
 			goto err;
 			}
-		if (seed_in != NULL) memcpy(seed_in,seed,20);
 		if (counter_ret != NULL) *counter_ret=counter;
 		if (h_ret != NULL) *h_ret=h;
 		}
@@ -322,4 +343,3 @@
 	return ok;
 	}
 #endif
-#endif
diff --git a/crypto/dsa/dsa_key.c b/crypto/dsa/dsa_key.c
index 5e39124..c4aa86b 100644
--- a/crypto/dsa/dsa_key.c
+++ b/crypto/dsa/dsa_key.c
@@ -64,8 +64,6 @@
 #include <openssl/dsa.h>
 #include <openssl/rand.h>
 
-#ifndef OPENSSL_FIPS
-
 static int dsa_builtin_keygen(DSA *dsa);
 
 int DSA_generate_key(DSA *dsa)
@@ -128,5 +126,3 @@
 	return(ok);
 	}
 #endif
-
-#endif
diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c
index 85556d1..e9b7590 100644
--- a/crypto/dsa/dsa_lib.c
+++ b/crypto/dsa/dsa_lib.c
@@ -76,14 +76,6 @@
 
 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;
 	}
 
@@ -104,13 +96,6 @@
 	/* 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
@@ -162,18 +147,6 @@
 			}
 		}
 #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;
@@ -190,7 +163,7 @@
 	ret->method_mont_p=NULL;
 
 	ret->references=1;
-	ret->flags=ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
+	ret->flags=ret->meth->flags;
 	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data);
 	if ((ret->meth->init != NULL) && !ret->meth->init(ret))
 		{
@@ -260,6 +233,28 @@
 	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/camellia/cmll_ecb.c b/crypto/dsa/dsa_locl.h
similarity index 79%
rename from crypto/camellia/cmll_ecb.c
rename to crypto/dsa/dsa_locl.h
index 70dc0e5..2b8cfee 100644
--- a/crypto/camellia/cmll_ecb.c
+++ b/crypto/dsa/dsa_locl.h
@@ -1,6 +1,5 @@
-/* crypto/camellia/camellia_ecb.c -*- mode:C; c-file-style: "eay" -*- */
 /* ====================================================================
- * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ * 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
@@ -47,28 +46,14 @@
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  * ====================================================================
  *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
  */
 
-#ifndef CAMELLIA_DEBUG
-# ifndef NDEBUG
-#  define NDEBUG
-# endif
-#endif
-#include <assert.h>
+#include <openssl/dsa.h>
 
-#include <openssl/camellia.h>
-#include "cmll_locl.h"
-
-void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out,
-	const CAMELLIA_KEY *key, const int enc) 
-	{
-
-	assert(in && out && key);
-	assert((CAMELLIA_ENCRYPT == enc)||(CAMELLIA_DECRYPT == enc));
-
-	if (CAMELLIA_ENCRYPT == enc)
-		Camellia_encrypt(in, out, key);
-	else
-		Camellia_decrypt(in, out, key);
-	}
-
+int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
+	const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
+	int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c
index 412cf1d..4fead07 100644
--- a/crypto/dsa/dsa_ossl.c
+++ b/crypto/dsa/dsa_ossl.c
@@ -61,16 +61,15 @@
 #include <stdio.h>
 #include "cryptlib.h"
 #include <openssl/bn.h>
+#include <openssl/sha.h>
 #include <openssl/dsa.h>
 #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,
-		  DSA *dsa);
+			 DSA *dsa);
 static int dsa_init(DSA *dsa);
 static int dsa_finish(DSA *dsa);
 
@@ -135,7 +134,7 @@
 	BIGNUM m;
 	BIGNUM xr;
 	BN_CTX *ctx=NULL;
-	int i,reason=ERR_R_BN_LIB;
+	int reason=ERR_R_BN_LIB;
 	DSA_SIG *ret=NULL;
 
 	BN_init(&m);
@@ -150,8 +149,9 @@
 	s=BN_new();
 	if (s == NULL) goto err;
 
-	i=BN_num_bytes(dsa->q); /* should be 20 */
-	if ((dlen > i) || (dlen > 50))
+	/* reject a excessive digest length (currently at most
+	 * dsa-with-SHA256 is supported) */
+	if (dlen > SHA256_DIGEST_LENGTH)
 		{
 		reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE;
 		goto err;
@@ -172,7 +172,14 @@
 		dsa->r=NULL;
 		}
 
-	if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err;
+	
+	if (dlen > BN_num_bytes(dsa->q))
+		/* if the digest length is greater than the size of q use the
+		 * BN_num_bits(dsa->q) leftmost bits of the digest, see
+		 * fips 186-3, 4.2 */
+		dlen = BN_num_bytes(dsa->q);
+	if (BN_bin2bn(dgst,dlen,&m) == NULL)
+		goto err;
 
 	/* Compute  s = inv(k) (m + xr) mod q */
 	if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */
@@ -283,30 +290,31 @@
 	if (!ret)
 		{
 		DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB);
-		if (kinv != NULL) BN_clear_free(kinv);
-		if (r != NULL) BN_clear_free(r);
+		if (r != NULL)
+			BN_clear_free(r);
 		}
 	if (ctx_in == NULL) BN_CTX_free(ctx);
-	if (kinv != NULL) BN_clear_free(kinv);
 	BN_clear_free(&k);
 	BN_clear_free(&kq);
 	return(ret);
 	}
 
 static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
-		  DSA *dsa)
+			 DSA *dsa)
 	{
 	BN_CTX *ctx;
 	BIGNUM u1,u2,t1;
 	BN_MONT_CTX *mont=NULL;
-	int ret = -1;
+	int ret = -1, i;
 	if (!dsa->p || !dsa->q || !dsa->g)
 		{
 		DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS);
 		return -1;
 		}
 
-	if (BN_num_bits(dsa->q) != 160)
+	i = BN_num_bits(dsa->q);
+	/* fips 186-3 allows only different sizes for q */
+	if (i != 160 && i != 224 && i != 256)
 		{
 		DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE);
 		return -1;
@@ -318,6 +326,14 @@
 		return -1;
 		}
 
+	/* reject a excessive digest length (currently at most
+	 * dsa-with-SHA256 is supported) */
+	if (dgst_len > SHA256_DIGEST_LENGTH)
+		{
+		DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		return -1;
+		}
+
 	BN_init(&u1);
 	BN_init(&u2);
 	BN_init(&t1);
@@ -342,6 +358,11 @@
 	if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err;
 
 	/* save M in u1 */
+	if (dgst_len > (i >> 3))
+		/* if the digest length is greater than the size of q use the
+		 * BN_num_bits(dsa->q) leftmost bits of the digest, see
+		 * fips 186-3, 4.2 */
+		dgst_len = (i >> 3);
 	if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err;
 
 	/* u1 = M * w mod q */
@@ -393,4 +414,3 @@
 	return(1);
 }
 
-#endif
diff --git a/crypto/dsa/dsa_pmeth.c b/crypto/dsa/dsa_pmeth.c
new file mode 100644
index 0000000..4ce91e2
--- /dev/null
+++ b/crypto/dsa/dsa_pmeth.c
@@ -0,0 +1,315 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include "evp_locl.h"
+#include "dsa_locl.h"
+
+/* DSA pkey context structure */
+
+typedef struct
+	{
+	/* Parameter gen parameters */
+	int nbits;		/* size of p in bits (default: 1024) */
+	int qbits;		/* size of q in bits (default: 160)  */
+	const EVP_MD *pmd;	/* MD for parameter generation */
+	/* Keygen callback info */
+	int gentmp[2];
+	/* message digest */
+	const EVP_MD *md;	/* MD for the signature */
+	} DSA_PKEY_CTX;
+
+static int pkey_dsa_init(EVP_PKEY_CTX *ctx)
+	{
+	DSA_PKEY_CTX *dctx;
+	dctx = OPENSSL_malloc(sizeof(DSA_PKEY_CTX));
+	if (!dctx)
+		return 0;
+	dctx->nbits = 1024;
+	dctx->qbits = 160;
+	dctx->pmd = NULL;
+	dctx->md = NULL;
+
+	ctx->data = dctx;
+	ctx->keygen_info = dctx->gentmp;
+	ctx->keygen_info_count = 2;
+	
+	return 1;
+	}
+
+static int pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+	{
+	DSA_PKEY_CTX *dctx, *sctx;
+	if (!pkey_dsa_init(dst))
+		return 0;
+       	sctx = src->data;
+	dctx = dst->data;
+	dctx->nbits = sctx->nbits;
+	dctx->qbits = sctx->qbits;
+	dctx->pmd = sctx->pmd;
+	dctx->md  = sctx->md;
+	return 1;
+	}
+
+static void pkey_dsa_cleanup(EVP_PKEY_CTX *ctx)
+	{
+	DSA_PKEY_CTX *dctx = ctx->data;
+	if (dctx)
+		OPENSSL_free(dctx);
+	}
+
+static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					const unsigned char *tbs, size_t tbslen)
+	{
+	int ret, type;
+	unsigned int sltmp;
+	DSA_PKEY_CTX *dctx = ctx->data;
+	DSA *dsa = ctx->pkey->pkey.dsa;
+
+	if (dctx->md)
+		type = EVP_MD_type(dctx->md);
+	else
+		type = NID_sha1;
+
+	ret = DSA_sign(type, tbs, tbslen, sig, &sltmp, dsa);
+
+	if (ret <= 0)
+		return ret;
+	*siglen = sltmp;
+	return 1;
+	}
+
+static int pkey_dsa_verify(EVP_PKEY_CTX *ctx,
+					const unsigned char *sig, size_t siglen,
+					const unsigned char *tbs, size_t tbslen)
+	{
+	int ret, type;
+	DSA_PKEY_CTX *dctx = ctx->data;
+	DSA *dsa = ctx->pkey->pkey.dsa;
+
+	if (dctx->md)
+		type = EVP_MD_type(dctx->md);
+	else
+		type = NID_sha1;
+
+	ret = DSA_verify(type, tbs, tbslen, sig, siglen, dsa);
+
+	return ret;
+	}
+
+static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+	{
+	DSA_PKEY_CTX *dctx = ctx->data;
+	switch (type)
+		{
+		case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS:
+		if (p1 < 256)
+			return -2;
+		dctx->nbits = p1;
+		return 1;
+
+		case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS:
+		if (p1 != 160 && p1 != 224 && p1 && p1 != 256)
+			return -2;
+		dctx->qbits = p1;
+		return 1;
+
+		case EVP_PKEY_CTRL_DSA_PARAMGEN_MD:
+		if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1   &&
+		    EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
+		    EVP_MD_type((const EVP_MD *)p2) != NID_sha256)
+			{
+			DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
+			return 0;
+			}
+		dctx->md = p2;
+		return 1;
+
+		case EVP_PKEY_CTRL_MD:
+		if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1   &&
+		    EVP_MD_type((const EVP_MD *)p2) != NID_dsa    &&
+		    EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
+		    EVP_MD_type((const EVP_MD *)p2) != NID_sha256)
+			{
+			DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
+			return 0;
+			}
+		dctx->md = p2;
+		return 1;
+
+		case EVP_PKEY_CTRL_DIGESTINIT:
+		case EVP_PKEY_CTRL_PKCS7_SIGN:
+		case EVP_PKEY_CTRL_CMS_SIGN:
+		return 1;
+		
+		case EVP_PKEY_CTRL_PEER_KEY:
+			DSAerr(DSA_F_PKEY_DSA_CTRL,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+			return -2;	
+		default:
+		return -2;
+
+		}
+	}
+			
+static int pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx,
+			const char *type, const char *value)
+	{
+	if (!strcmp(type, "dsa_paramgen_bits"))
+		{
+		int nbits;
+		nbits = atoi(value);
+		return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits);
+		}
+	if (!strcmp(type, "dsa_paramgen_q_bits"))
+		{
+		int qbits = atoi(value);
+		return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
+		                         EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits, NULL);
+		}
+	if (!strcmp(type, "dsa_paramgen_md"))
+		{
+		return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
+		                         EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, 
+		                         (void *)EVP_get_digestbyname(value));
+		}
+	return -2;
+	}
+
+static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+	{
+	DSA *dsa = NULL;
+	DSA_PKEY_CTX *dctx = ctx->data;
+	BN_GENCB *pcb, cb;
+	int ret;
+	if (ctx->pkey_gencb)
+		{
+		pcb = &cb;
+		evp_pkey_set_cb_translate(pcb, ctx);
+		}
+	else
+		pcb = NULL;
+	dsa = DSA_new();
+	if (!dsa)
+		return 0;
+	ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd,
+	                           NULL, 0, NULL, NULL, pcb);
+	if (ret)
+		EVP_PKEY_assign_DSA(pkey, dsa);
+	else
+		DSA_free(dsa);
+	return ret;
+	}
+
+static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+	{
+	DSA *dsa = NULL;
+	if (ctx->pkey == NULL)
+		{
+		DSAerr(DSA_F_PKEY_DSA_KEYGEN, DSA_R_NO_PARAMETERS_SET);
+		return 0;
+		}
+	dsa = DSA_new();
+	if (!dsa)
+		return 0;
+	EVP_PKEY_assign_DSA(pkey, dsa);
+	/* Note: if error return, pkey is freed by parent routine */
+	if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
+		return 0;
+	return DSA_generate_key(pkey->pkey.dsa);
+	}
+
+const EVP_PKEY_METHOD dsa_pkey_meth = 
+	{
+	EVP_PKEY_DSA,
+	EVP_PKEY_FLAG_AUTOARGLEN,
+	pkey_dsa_init,
+	pkey_dsa_copy,
+	pkey_dsa_cleanup,
+
+	0,
+	pkey_dsa_paramgen,
+
+	0,
+	pkey_dsa_keygen,
+
+	0,
+	pkey_dsa_sign,
+
+	0,
+	pkey_dsa_verify,
+
+	0,0,
+
+	0,0,0,0,
+
+	0,0,
+
+	0,0,
+
+	0,0,
+
+	pkey_dsa_ctrl,
+	pkey_dsa_ctrl_str
+
+
+	};
diff --git a/crypto/buffer/buf_str.c b/crypto/dsa/dsa_prn.c
similarity index 68%
rename from crypto/buffer/buf_str.c
rename to crypto/dsa/dsa_prn.c
index 28dd1e4..6f29f5e 100644
--- a/crypto/buffer/buf_str.c
+++ b/crypto/dsa/dsa_prn.c
@@ -1,6 +1,9 @@
-/* crypto/buffer/buf_str.c */
+/* crypto/dsa/dsa_prn.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
 /* ====================================================================
- * Copyright (c) 2007 The OpenSSL Project.  All rights reserved.
+ * 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
@@ -55,62 +58,64 @@
 
 #include <stdio.h>
 #include "cryptlib.h"
-#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include <openssl/dsa.h>
 
-char *BUF_strdup(const char *str)
+#ifndef OPENSSL_NO_FP_API
+int DSA_print_fp(FILE *fp, const DSA *x, int off)
 	{
-	if (str == NULL) return(NULL);
-	return BUF_strndup(str, strlen(str));
-	}
+	BIO *b;
+	int ret;
 
-char *BUF_strndup(const char *str, size_t siz)
-	{
-	char *ret;
-
-	if (str == NULL) return(NULL);
-
-	ret=OPENSSL_malloc(siz+1);
-	if (ret == NULL) 
+	if ((b=BIO_new(BIO_s_file())) == NULL)
 		{
-		BUFerr(BUF_F_BUF_STRNDUP,ERR_R_MALLOC_FAILURE);
-		return(NULL);
+		DSAerr(DSA_F_DSA_PRINT_FP,ERR_R_BUF_LIB);
+		return(0);
 		}
-	BUF_strlcpy(ret,str,siz+1);
+	BIO_set_fp(b,fp,BIO_NOCLOSE);
+	ret=DSA_print(b,x,off);
+	BIO_free(b);
 	return(ret);
 	}
 
-void *BUF_memdup(const void *data, size_t siz)
+int DSAparams_print_fp(FILE *fp, const DSA *x)
 	{
-	void *ret;
+	BIO *b;
+	int ret;
 
-	if (data == NULL) return(NULL);
-
-	ret=OPENSSL_malloc(siz);
-	if (ret == NULL) 
+	if ((b=BIO_new(BIO_s_file())) == NULL)
 		{
-		BUFerr(BUF_F_BUF_MEMDUP,ERR_R_MALLOC_FAILURE);
-		return(NULL);
+		DSAerr(DSA_F_DSAPARAMS_PRINT_FP,ERR_R_BUF_LIB);
+		return(0);
 		}
-	return memcpy(ret, data, siz);
-	}	
+	BIO_set_fp(b,fp,BIO_NOCLOSE);
+	ret=DSAparams_print(b, x);
+	BIO_free(b);
+	return(ret);
+	}
+#endif
 
-size_t BUF_strlcpy(char *dst, const char *src, size_t size)
+int DSA_print(BIO *bp, const DSA *x, int off)
 	{
-	size_t l = 0;
-	for(; size > 1 && *src; size--)
-		{
-		*dst++ = *src++;
-		l++;
-		}
-	if (size)
-		*dst = '\0';
-	return l + strlen(src);
+	EVP_PKEY *pk;
+	int ret;
+	pk = EVP_PKEY_new();
+	if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x))
+		return 0;
+	ret = EVP_PKEY_print_private(bp, pk, off, NULL);
+	EVP_PKEY_free(pk);
+	return ret;
 	}
 
-size_t BUF_strlcat(char *dst, const char *src, size_t size)
+int DSAparams_print(BIO *bp, const DSA *x)
 	{
-	size_t l = 0;
-	for(; size > 0 && *dst; size--, dst++)
-		l++;
-	return l + BUF_strlcpy(dst, src, size);
+	EVP_PKEY *pk;
+	int ret;
+	pk = EVP_PKEY_new();
+	if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x))
+		return 0;
+	ret = EVP_PKEY_print_params(bp, pk, 4, NULL);
+	EVP_PKEY_free(pk);
+	return ret;
 	}
+
diff --git a/crypto/dsa/dsa_sign.c b/crypto/dsa/dsa_sign.c
index 4cfbbe5..17555e5 100644
--- a/crypto/dsa/dsa_sign.c
+++ b/crypto/dsa/dsa_sign.c
@@ -58,38 +58,33 @@
 
 /* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
 
-#include <stdio.h>
 #include "cryptlib.h"
-#include <openssl/bn.h>
 #include <openssl/dsa.h>
 #include <openssl/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)
 	{
-#ifdef OPENSSL_FIPS
-	if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
-		{
-		DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
-		return NULL;
-		}
-#endif
 	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;
+	RAND_seed(dgst, dlen);
+	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_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
 	{
-#ifdef OPENSSL_FIPS
-	if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
-		{
-		DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
-		return 0;
-		}
-#endif
 	return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
 	}
 
diff --git a/crypto/dsa/dsa_utl.c b/crypto/dsa/dsa_utl.c
deleted file mode 100644
index 24c021d..0000000
--- a/crypto/dsa/dsa_utl.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* crypto/dsa/dsa_lib.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
-
-#include <stdio.h>
-#include "cryptlib.h"
-#include <openssl/bn.h>
-#include <openssl/dsa.h>
-#include <openssl/asn1.h>
-#ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
-#endif
-#ifndef OPENSSL_NO_DH
-#include <openssl/dh.h>
-#endif
-
-DSA_SIG *DSA_SIG_new(void)
-	{
-	DSA_SIG *sig;
-	sig = OPENSSL_malloc(sizeof(DSA_SIG));
-	if (!sig)
-		return NULL;
-	sig->r = NULL;
-	sig->s = NULL;
-	return sig;
-	}
-
-void DSA_SIG_free(DSA_SIG *sig)
-	{
-	if (sig)
-		{
-		if (sig->r)
-			BN_free(sig->r);
-		if (sig->s)
-			BN_free(sig->s);
-		OPENSSL_free(sig);
-		}
-	}
-
diff --git a/crypto/dsa/dsa_vrf.c b/crypto/dsa/dsa_vrf.c
index c75e423..226a75f 100644
--- a/crypto/dsa/dsa_vrf.c
+++ b/crypto/dsa/dsa_vrf.c
@@ -58,27 +58,32 @@
 
 /* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
 
-#include <stdio.h>
 #include "cryptlib.h"
-#include <openssl/bn.h>
 #include <openssl/dsa.h>
-#include <openssl/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/dsa/dsatest.c b/crypto/dsa/dsatest.c
index 912317b..edffd24 100644
--- a/crypto/dsa/dsatest.c
+++ b/crypto/dsa/dsatest.c
@@ -169,7 +169,6 @@
 		}
 	BIO_printf(bio_err,"\ncounter=%d h=%ld\n",counter,h);
 		
-	if (dsa == NULL) goto end;
 	DSA_print(bio_err,dsa,0);
 	if (counter != 105) 
 		{
@@ -223,7 +222,7 @@
 		ERR_print_errors(bio_err);
 	if (dsa != NULL) DSA_free(dsa);
 	CRYPTO_cleanup_all_ex_data();
-	ERR_remove_state(0);
+	ERR_remove_thread_state(NULL);
 	ERR_free_strings();
 	CRYPTO_mem_leaks(bio_err);
 	if (bio_err != NULL)
diff --git a/crypto/dso/Makefile b/crypto/dso/Makefile
deleted file mode 100644
index 52f1528..0000000
--- a/crypto/dso/Makefile
+++ /dev/null
@@ -1,142 +0,0 @@
-#
-# OpenSSL/crypto/dso/Makefile
-#
-
-DIR=	dso
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC= dso_dl.c dso_dlfcn.c dso_err.c dso_lib.c dso_null.c \
-	dso_openssl.c dso_win32.c dso_vms.c
-LIBOBJ= dso_dl.o dso_dlfcn.o dso_err.o dso_lib.o dso_null.o \
-	dso_openssl.o dso_win32.o dso_vms.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= dso.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-dso_dl.o: ../../e_os.h ../../include/openssl/bio.h
-dso_dl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-dso_dl.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
-dso_dl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-dso_dl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-dso_dl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-dso_dl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-dso_dl.o: ../cryptlib.h dso_dl.c
-dso_dlfcn.o: ../../e_os.h ../../include/openssl/bio.h
-dso_dlfcn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-dso_dlfcn.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
-dso_dlfcn.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-dso_dlfcn.o: ../../include/openssl/opensslconf.h
-dso_dlfcn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-dso_dlfcn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-dso_dlfcn.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_dlfcn.c
-dso_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
-dso_err.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
-dso_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-dso_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-dso_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-dso_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-dso_err.o: dso_err.c
-dso_lib.o: ../../e_os.h ../../include/openssl/bio.h
-dso_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-dso_lib.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
-dso_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-dso_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-dso_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-dso_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-dso_lib.o: ../cryptlib.h dso_lib.c
-dso_null.o: ../../e_os.h ../../include/openssl/bio.h
-dso_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-dso_null.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
-dso_null.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-dso_null.o: ../../include/openssl/opensslconf.h
-dso_null.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-dso_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-dso_null.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_null.c
-dso_openssl.o: ../../e_os.h ../../include/openssl/bio.h
-dso_openssl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-dso_openssl.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
-dso_openssl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-dso_openssl.o: ../../include/openssl/opensslconf.h
-dso_openssl.o: ../../include/openssl/opensslv.h
-dso_openssl.o: ../../include/openssl/ossl_typ.h
-dso_openssl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-dso_openssl.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_openssl.c
-dso_vms.o: ../../e_os.h ../../include/openssl/bio.h
-dso_vms.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-dso_vms.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
-dso_vms.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-dso_vms.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-dso_vms.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-dso_vms.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-dso_vms.o: ../cryptlib.h dso_vms.c
-dso_win32.o: ../../e_os.h ../../include/openssl/bio.h
-dso_win32.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-dso_win32.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
-dso_win32.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-dso_win32.o: ../../include/openssl/opensslconf.h
-dso_win32.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-dso_win32.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-dso_win32.o: ../../include/openssl/symhacks.h ../cryptlib.h dso_win32.c
diff --git a/crypto/dso/dso.h b/crypto/dso/dso.h
index 3e51913..839f2e0 100644
--- a/crypto/dso/dso.h
+++ b/crypto/dso/dso.h
@@ -170,6 +170,11 @@
 	/* [De]Initialisation handlers. */
 	int (*init)(DSO *dso);
 	int (*finish)(DSO *dso);
+
+	/* Return pathname of the module containing location */
+	int (*pathbyaddr)(void *addr,char *path,int sz);
+	/* Perform global symbol lookup, i.e. among *all* modules */
+	void *(*globallookup)(const char *symname);
 	} DSO_METHOD;
 
 /**********************************************************************/
@@ -183,7 +188,7 @@
 	 * for use in the dso_bind handler. All in all, let each
 	 * method control its own destiny. "Handles" and such go in
 	 * a STACK. */
-	STACK *meth_data;
+	STACK_OF(void) *meth_data;
 	int references;
 	int flags;
 	/* For use by applications etc ... use this for your bits'n'pieces,
@@ -296,6 +301,30 @@
 /* If VMS is defined, use shared images. If not, return NULL. */
 DSO_METHOD *DSO_METHOD_vms(void);
 
+/* This function writes null-terminated pathname of DSO module
+ * containing 'addr' into 'sz' large caller-provided 'path' and
+ * returns the number of characters [including trailing zero]
+ * written to it. If 'sz' is 0 or negative, 'path' is ignored and
+ * required amount of charachers [including trailing zero] to
+ * accomodate pathname is returned. If 'addr' is NULL, then
+ * pathname of cryptolib itself is returned. Negative or zero
+ * return value denotes error.
+ */
+int DSO_pathbyaddr(void *addr,char *path,int sz);
+
+/* This function should be used with caution! It looks up symbols in
+ * *all* loaded modules and if module gets unloaded by somebody else
+ * attempt to dereference the pointer is doomed to have fatal
+ * consequences. Primary usage for this function is to probe *core*
+ * system functionality, e.g. check if getnameinfo(3) is available
+ * at run-time without bothering about OS-specific details such as
+ * libc.so.versioning or where does it actually reside: in libc
+ * itself or libsocket. */
+void *DSO_global_lookup(const char *name);
+
+/* If BeOS is defined, use shared images. If not, return NULL. */
+DSO_METHOD *DSO_METHOD_beos(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.
@@ -305,6 +334,11 @@
 /* Error codes for the DSO functions. */
 
 /* Function codes. */
+#define DSO_F_BEOS_BIND_FUNC				 144
+#define DSO_F_BEOS_BIND_VAR				 145
+#define DSO_F_BEOS_LOAD					 146
+#define DSO_F_BEOS_NAME_CONVERTER			 147
+#define DSO_F_BEOS_UNLOAD				 148
 #define DSO_F_DLFCN_BIND_FUNC				 100
 #define DSO_F_DLFCN_BIND_VAR				 101
 #define DSO_F_DLFCN_LOAD				 102
@@ -324,22 +358,29 @@
 #define DSO_F_DSO_FREE					 111
 #define DSO_F_DSO_GET_FILENAME				 127
 #define DSO_F_DSO_GET_LOADED_FILENAME			 128
+#define DSO_F_DSO_GLOBAL_LOOKUP				 139
 #define DSO_F_DSO_LOAD					 112
 #define DSO_F_DSO_MERGE					 132
 #define DSO_F_DSO_NEW_METHOD				 113
+#define DSO_F_DSO_PATHBYADDR				 140
 #define DSO_F_DSO_SET_FILENAME				 129
 #define DSO_F_DSO_SET_NAME_CONVERTER			 122
 #define DSO_F_DSO_UP_REF				 114
+#define DSO_F_GLOBAL_LOOKUP_FUNC			 138
+#define DSO_F_PATHBYADDR				 137
 #define DSO_F_VMS_BIND_SYM				 115
 #define DSO_F_VMS_LOAD					 116
 #define DSO_F_VMS_MERGER				 133
 #define DSO_F_VMS_UNLOAD				 117
 #define DSO_F_WIN32_BIND_FUNC				 118
 #define DSO_F_WIN32_BIND_VAR				 119
+#define DSO_F_WIN32_GLOBALLOOKUP			 142
+#define DSO_F_WIN32_GLOBALLOOKUP_FUNC			 143
 #define DSO_F_WIN32_JOINER				 135
 #define DSO_F_WIN32_LOAD				 120
 #define DSO_F_WIN32_MERGER				 134
 #define DSO_F_WIN32_NAME_CONVERTER			 125
+#define DSO_F_WIN32_PATHBYADDR				 141
 #define DSO_F_WIN32_SPLITTER				 136
 #define DSO_F_WIN32_UNLOAD				 121
 
diff --git a/crypto/dso/dso_dl.c b/crypto/dso/dso_dl.c
index 417abb6..fc4236b 100644
--- a/crypto/dso/dso_dl.c
+++ b/crypto/dso/dso_dl.c
@@ -85,6 +85,8 @@
 #endif
 static char *dl_name_converter(DSO *dso, const char *filename);
 static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2);
+static int dl_pathbyaddr(void *addr,char *path,int sz);
+static void *dl_globallookup(const char *name);
 
 static DSO_METHOD dso_meth_dl = {
 	"OpenSSL 'dl' shared library method",
@@ -101,7 +103,9 @@
 	dl_name_converter,
 	dl_merger,
 	NULL, /* init */
-	NULL  /* finish */
+	NULL, /* finish */
+	dl_pathbyaddr,
+	dl_globallookup
 	};
 
 DSO_METHOD *DSO_METHOD_dl(void)
@@ -350,4 +354,40 @@
 	return(translated);
 	}
 
+static int dl_pathbyaddr(void *addr,char *path,int sz)
+	{
+	struct shl_descriptor inf;
+	int i,len;
+
+	if (addr == NULL)
+		{
+		union	{ int(*f)(void*,char*,int); void *p; } t =
+			{ dl_pathbyaddr };
+		addr = t.p;
+		}
+
+	for (i=-1;shl_get_r(i,&inf)==0;i++)
+		{
+		if (((size_t)addr >= inf.tstart && (size_t)addr < inf.tend) ||
+		    ((size_t)addr >= inf.dstart && (size_t)addr < inf.dend))
+			{
+			len = (int)strlen(inf.filename);
+			if (sz <= 0) return len+1;
+			if (len >= sz) len=sz-1;
+			memcpy(path,inf.filename,len);
+			path[len++] = 0;
+			return len;
+			}
+		}
+
+	return -1;
+	}
+
+static void *dl_globallookup(const char *name)
+	{
+	void *ret;
+	shl_t h = NULL;
+
+	return shl_findsym(&h,name,TYPE_UNDEFINED,&ret) ? NULL : ret;
+	}
 #endif /* DSO_DL */
diff --git a/crypto/dso/dso_dlfcn.c b/crypto/dso/dso_dlfcn.c
index d91e821..14bd322 100644
--- a/crypto/dso/dso_dlfcn.c
+++ b/crypto/dso/dso_dlfcn.c
@@ -56,6 +56,16 @@
  *
  */
 
+/* We need to do this early, because stdio.h includes the header files
+   that handle _GNU_SOURCE and other similar macros.  Defining it later
+   is simply too late, because those headers are protected from re-
+   inclusion.  */
+#ifdef __linux
+# ifndef _GNU_SOURCE
+#  define _GNU_SOURCE	/* make sure dladdr is declared */
+# endif
+#endif
+
 #include <stdio.h>
 #include "cryptlib.h"
 #include <openssl/dso.h>
@@ -68,7 +78,16 @@
 #else
 
 #ifdef HAVE_DLFCN_H
-#include <dlfcn.h>
+# ifdef __osf__
+#  define __EXTENSIONS__
+# endif
+# include <dlfcn.h>
+# define HAVE_DLINFO 1
+# if defined(_AIX) || defined(__CYGWIN__) || \
+     defined(__SCO_VERSION__) || defined(_SCO_ELF) || \
+     (defined(__OpenBSD__) && !defined(RTLD_SELF))
+#  undef HAVE_DLINFO
+# endif
 #endif
 
 /* Part of the hack in "dlfcn_load" ... */
@@ -87,6 +106,8 @@
 static char *dlfcn_name_converter(DSO *dso, const char *filename);
 static char *dlfcn_merger(DSO *dso, const char *filespec1,
 	const char *filespec2);
+static int dlfcn_pathbyaddr(void *addr,char *path,int sz);
+static void *dlfcn_globallookup(const char *name);
 
 static DSO_METHOD dso_meth_dlfcn = {
 	"OpenSSL 'dlfcn' shared library method",
@@ -103,7 +124,9 @@
 	dlfcn_name_converter,
 	dlfcn_merger,
 	NULL, /* init */
-	NULL  /* finish */
+	NULL, /* finish */
+	dlfcn_pathbyaddr,
+	dlfcn_globallookup
 	};
 
 DSO_METHOD *DSO_METHOD_dlfcn(void)
@@ -163,7 +186,7 @@
 		ERR_add_error_data(4, "filename(", filename, "): ", dlerror());
 		goto err;
 		}
-	if(!sk_push(dso->meth_data, (char *)ptr))
+	if(!sk_void_push(dso->meth_data, (char *)ptr))
 		{
 		DSOerr(DSO_F_DLFCN_LOAD,DSO_R_STACK_ERROR);
 		goto err;
@@ -188,15 +211,15 @@
 		DSOerr(DSO_F_DLFCN_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
 		return(0);
 		}
-	if(sk_num(dso->meth_data) < 1)
+	if(sk_void_num(dso->meth_data) < 1)
 		return(1);
-	ptr = (void *)sk_pop(dso->meth_data);
+	ptr = sk_void_pop(dso->meth_data);
 	if(ptr == NULL)
 		{
 		DSOerr(DSO_F_DLFCN_UNLOAD,DSO_R_NULL_HANDLE);
 		/* Should push the value back onto the stack in
 		 * case of a retry. */
-		sk_push(dso->meth_data, (char *)ptr);
+		sk_void_push(dso->meth_data, ptr);
 		return(0);
 		}
 	/* For now I'm not aware of any errors associated with dlclose() */
@@ -213,12 +236,12 @@
 		DSOerr(DSO_F_DLFCN_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
 		return(NULL);
 		}
-	if(sk_num(dso->meth_data) < 1)
+	if(sk_void_num(dso->meth_data) < 1)
 		{
 		DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_STACK_ERROR);
 		return(NULL);
 		}
-	ptr = (void *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
+	ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
 	if(ptr == NULL)
 		{
 		DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_NULL_HANDLE);
@@ -247,12 +270,12 @@
 		DSOerr(DSO_F_DLFCN_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
 		return(NULL);
 		}
-	if(sk_num(dso->meth_data) < 1)
+	if(sk_void_num(dso->meth_data) < 1)
 		{
 		DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_STACK_ERROR);
 		return(NULL);
 		}
-	ptr = (void *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
+	ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
 	if(ptr == NULL)
 		{
 		DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE);
@@ -281,13 +304,12 @@
 		}
 	/* If the first file specification is a rooted path, it rules.
 	   same goes if the second file specification is missing. */
-	if (!filespec2 || filespec1[0] == '/')
+	if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/'))
 		{
 		merged = OPENSSL_malloc(strlen(filespec1) + 1);
 		if(!merged)
 			{
-			DSOerr(DSO_F_DLFCN_MERGER,
-				ERR_R_MALLOC_FAILURE);
+			DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
 			return(NULL);
 			}
 		strcpy(merged, filespec1);
@@ -313,7 +335,7 @@
 		{
 		int spec2len, len;
 
-		spec2len = (filespec2 ? strlen(filespec2) : 0);
+		spec2len = strlen(filespec2);
 		len = spec2len + (filespec1 ? strlen(filespec1) : 0);
 
 		if(filespec2 && filespec2[spec2len - 1] == '/')
@@ -378,4 +400,83 @@
 	return(translated);
 	}
 
+#ifdef __sgi
+/*
+This is a quote from IRIX manual for dladdr(3c):
+
+     <dlfcn.h> does not contain a prototype for dladdr or definition of
+     Dl_info.  The #include <dlfcn.h>  in the SYNOPSIS line is traditional,
+     but contains no dladdr prototype and no IRIX library contains an
+     implementation.  Write your own declaration based on the code below.
+
+     The following code is dependent on internal interfaces that are not
+     part of the IRIX compatibility guarantee; however, there is no future
+     intention to change this interface, so on a practical level, the code
+     below is safe to use on IRIX.
+*/
+#include <rld_interface.h>
+#ifndef _RLD_INTERFACE_DLFCN_H_DLADDR
+#define _RLD_INTERFACE_DLFCN_H_DLADDR
+typedef struct Dl_info {
+    const char * dli_fname;
+    void       * dli_fbase;
+    const char * dli_sname;
+    void       * dli_saddr;
+    int          dli_version;
+    int          dli_reserved1;
+    long         dli_reserved[4];
+} Dl_info;
+#else
+typedef struct Dl_info Dl_info;
+#endif
+#define _RLD_DLADDR             14
+
+static int dladdr(void *address, Dl_info *dl)
+{
+	void *v;
+	v = _rld_new_interface(_RLD_DLADDR,address,dl);
+	return (int)v;
+}
+#endif /* __sgi */
+
+static int dlfcn_pathbyaddr(void *addr,char *path,int sz)
+	{
+#ifdef HAVE_DLINFO
+	Dl_info dli;
+	int len;
+
+	if (addr == NULL)
+		{
+		union	{ int(*f)(void*,char*,int); void *p; } t =
+			{ dlfcn_pathbyaddr };
+		addr = t.p;
+		}
+
+	if (dladdr(addr,&dli))
+		{
+		len = (int)strlen(dli.dli_fname);
+		if (sz <= 0) return len+1;
+		if (len >= sz) len=sz-1;
+		memcpy(path,dli.dli_fname,len);
+		path[len++]=0;
+		return len;
+		}
+
+	ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror());
+#endif
+	return -1;
+	}
+
+static void *dlfcn_globallookup(const char *name)
+	{
+	void *ret = NULL,*handle = dlopen(NULL,RTLD_LAZY);
+	
+	if (handle)
+		{
+		ret = dlsym(handle,name);
+		dlclose(handle);
+		}
+
+	return ret;
+	}
 #endif /* DSO_DLFCN */
diff --git a/crypto/dso/dso_err.c b/crypto/dso/dso_err.c
index a8b0a21..2bb07c2 100644
--- a/crypto/dso/dso_err.c
+++ b/crypto/dso/dso_err.c
@@ -1,6 +1,6 @@
 /* crypto/dso/dso_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
@@ -70,6 +70,11 @@
 
 static ERR_STRING_DATA DSO_str_functs[]=
 	{
+{ERR_FUNC(DSO_F_BEOS_BIND_FUNC),	"BEOS_BIND_FUNC"},
+{ERR_FUNC(DSO_F_BEOS_BIND_VAR),	"BEOS_BIND_VAR"},
+{ERR_FUNC(DSO_F_BEOS_LOAD),	"BEOS_LOAD"},
+{ERR_FUNC(DSO_F_BEOS_NAME_CONVERTER),	"BEOS_NAME_CONVERTER"},
+{ERR_FUNC(DSO_F_BEOS_UNLOAD),	"BEOS_UNLOAD"},
 {ERR_FUNC(DSO_F_DLFCN_BIND_FUNC),	"DLFCN_BIND_FUNC"},
 {ERR_FUNC(DSO_F_DLFCN_BIND_VAR),	"DLFCN_BIND_VAR"},
 {ERR_FUNC(DSO_F_DLFCN_LOAD),	"DLFCN_LOAD"},
@@ -89,22 +94,29 @@
 {ERR_FUNC(DSO_F_DSO_FREE),	"DSO_free"},
 {ERR_FUNC(DSO_F_DSO_GET_FILENAME),	"DSO_get_filename"},
 {ERR_FUNC(DSO_F_DSO_GET_LOADED_FILENAME),	"DSO_get_loaded_filename"},
+{ERR_FUNC(DSO_F_DSO_GLOBAL_LOOKUP),	"DSO_global_lookup"},
 {ERR_FUNC(DSO_F_DSO_LOAD),	"DSO_load"},
 {ERR_FUNC(DSO_F_DSO_MERGE),	"DSO_merge"},
 {ERR_FUNC(DSO_F_DSO_NEW_METHOD),	"DSO_new_method"},
+{ERR_FUNC(DSO_F_DSO_PATHBYADDR),	"DSO_pathbyaddr"},
 {ERR_FUNC(DSO_F_DSO_SET_FILENAME),	"DSO_set_filename"},
 {ERR_FUNC(DSO_F_DSO_SET_NAME_CONVERTER),	"DSO_set_name_converter"},
 {ERR_FUNC(DSO_F_DSO_UP_REF),	"DSO_up_ref"},
+{ERR_FUNC(DSO_F_GLOBAL_LOOKUP_FUNC),	"GLOBAL_LOOKUP_FUNC"},
+{ERR_FUNC(DSO_F_PATHBYADDR),	"PATHBYADDR"},
 {ERR_FUNC(DSO_F_VMS_BIND_SYM),	"VMS_BIND_SYM"},
 {ERR_FUNC(DSO_F_VMS_LOAD),	"VMS_LOAD"},
 {ERR_FUNC(DSO_F_VMS_MERGER),	"VMS_MERGER"},
 {ERR_FUNC(DSO_F_VMS_UNLOAD),	"VMS_UNLOAD"},
 {ERR_FUNC(DSO_F_WIN32_BIND_FUNC),	"WIN32_BIND_FUNC"},
 {ERR_FUNC(DSO_F_WIN32_BIND_VAR),	"WIN32_BIND_VAR"},
+{ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP),	"WIN32_GLOBALLOOKUP"},
+{ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP_FUNC),	"WIN32_GLOBALLOOKUP_FUNC"},
 {ERR_FUNC(DSO_F_WIN32_JOINER),	"WIN32_JOINER"},
 {ERR_FUNC(DSO_F_WIN32_LOAD),	"WIN32_LOAD"},
 {ERR_FUNC(DSO_F_WIN32_MERGER),	"WIN32_MERGER"},
 {ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER),	"WIN32_NAME_CONVERTER"},
+{ERR_FUNC(DSO_F_WIN32_PATHBYADDR),	"WIN32_PATHBYADDR"},
 {ERR_FUNC(DSO_F_WIN32_SPLITTER),	"WIN32_SPLITTER"},
 {ERR_FUNC(DSO_F_WIN32_UNLOAD),	"WIN32_UNLOAD"},
 {0,NULL}
diff --git a/crypto/dso/dso_lib.c b/crypto/dso/dso_lib.c
index 49bdd71..8a15b79 100644
--- a/crypto/dso/dso_lib.c
+++ b/crypto/dso/dso_lib.c
@@ -107,7 +107,7 @@
 		return(NULL);
 		}
 	memset(ret, 0, sizeof(DSO));
-	ret->meth_data = sk_new_null();
+	ret->meth_data = sk_void_new_null();
 	if(ret->meth_data == NULL)
 		{
 		/* sk_new doesn't generate any errors so we do */
@@ -163,7 +163,7 @@
 		return(0);
 		}
 	
-	sk_free(dso->meth_data);
+	sk_void_free(dso->meth_data);
 	if(dso->filename != NULL)
 		OPENSSL_free(dso->filename);
 	if(dso->loaded_filename != NULL)
@@ -399,13 +399,6 @@
 		DSOerr(DSO_F_DSO_MERGE,ERR_R_PASSED_NULL_PARAMETER);
 		return(NULL);
 		}
-	if(filespec1 == NULL)
-		filespec1 = dso->filename;
-	if(filespec1 == NULL)
-		{
-		DSOerr(DSO_F_DSO_MERGE,DSO_R_NO_FILE_SPECIFICATION);
-		return(NULL);
-		}
 	if((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0)
 		{
 		if(dso->merger != NULL)
@@ -464,3 +457,27 @@
 		}
 	return(dso->loaded_filename);
 	}
+
+int DSO_pathbyaddr(void *addr,char *path,int sz)
+	{
+	DSO_METHOD *meth = default_DSO_meth;
+	if (meth == NULL) meth = DSO_METHOD_openssl();
+	if (meth->pathbyaddr == NULL)
+		{
+		DSOerr(DSO_F_DSO_PATHBYADDR,DSO_R_UNSUPPORTED);
+		return -1;
+		}
+	return (*meth->pathbyaddr)(addr,path,sz);
+	}
+
+void *DSO_global_lookup(const char *name)
+	{
+	DSO_METHOD *meth = default_DSO_meth;
+	if (meth == NULL) meth = DSO_METHOD_openssl();
+	if (meth->globallookup == NULL)
+		{
+		DSOerr(DSO_F_DSO_GLOBAL_LOOKUP,DSO_R_UNSUPPORTED);
+		return NULL;
+		}
+	return (*meth->globallookup)(name);
+	}
diff --git a/crypto/dso/dso_null.c b/crypto/dso/dso_null.c
index 4972984..49d842d 100644
--- a/crypto/dso/dso_null.c
+++ b/crypto/dso/dso_null.c
@@ -78,7 +78,9 @@
 	NULL, /* dso_name_converter */
 	NULL, /* dso_merger */
 	NULL, /* init */
-	NULL  /* finish */
+	NULL, /* finish */
+	NULL, /* pathbyaddr */
+	NULL  /* globallookup */
 	};
 
 DSO_METHOD *DSO_METHOD_null(void)
diff --git a/crypto/dso/dso_openssl.c b/crypto/dso/dso_openssl.c
index a4395eb..b17e8e8 100644
--- a/crypto/dso/dso_openssl.c
+++ b/crypto/dso/dso_openssl.c
@@ -74,6 +74,8 @@
 	return(DSO_METHOD_win32());
 #elif defined(DSO_VMS)
 	return(DSO_METHOD_vms());
+#elif defined(DSO_BEOS)
+	return(DSO_METHOD_beos());
 #else
 	return(DSO_METHOD_null());
 #endif
diff --git a/crypto/dso/dso_vms.c b/crypto/dso/dso_vms.c
index 2c434ee..3215127 100644
--- a/crypto/dso/dso_vms.c
+++ b/crypto/dso/dso_vms.c
@@ -215,7 +215,7 @@
 	p->imagename_dsc.dsc$b_class = DSC$K_CLASS_S;
 	p->imagename_dsc.dsc$a_pointer = p->imagename;
 
-	if(!sk_push(dso->meth_data, (char *)p))
+	if(!sk_void_push(dso->meth_data, (char *)p))
 		{
 		DSOerr(DSO_F_VMS_LOAD,DSO_R_STACK_ERROR);
 		goto err;
@@ -245,9 +245,9 @@
 		DSOerr(DSO_F_VMS_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
 		return(0);
 		}
-	if(sk_num(dso->meth_data) < 1)
+	if(sk_void_num(dso->meth_data) < 1)
 		return(1);
-	p = (DSO_VMS_INTERNAL *)sk_pop(dso->meth_data);
+	p = (DSO_VMS_INTERNAL *)sk_void_pop(dso->meth_data);
 	if(p == NULL)
 		{
 		DSOerr(DSO_F_VMS_UNLOAD,DSO_R_NULL_HANDLE);
@@ -302,13 +302,13 @@
 		DSOerr(DSO_F_VMS_BIND_SYM,ERR_R_PASSED_NULL_PARAMETER);
 		return;
 		}
-	if(sk_num(dso->meth_data) < 1)
+	if(sk_void_num(dso->meth_data) < 1)
 		{
 		DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_STACK_ERROR);
 		return;
 		}
-	ptr = (DSO_VMS_INTERNAL *)sk_value(dso->meth_data,
-		sk_num(dso->meth_data) - 1);
+	ptr = (DSO_VMS_INTERNAL *)sk_void_value(dso->meth_data,
+		sk_void_num(dso->meth_data) - 1);
 	if(ptr == NULL)
 		{
 		DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_NULL_HANDLE);
diff --git a/crypto/dso/dso_win32.c b/crypto/dso/dso_win32.c
index f340052..6fb6c54 100644
--- a/crypto/dso/dso_win32.c
+++ b/crypto/dso/dso_win32.c
@@ -96,7 +96,11 @@
 #else
 	fnamw = (WCHAR *)alloca (len_0*sizeof(WCHAR));
 #endif
-	if (fnamw == NULL) return NULL;
+	if (fnamw == NULL)
+		{
+		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+		return NULL;
+		}
 
 #if defined(_WIN32_WCE) && _WIN32_WCE>=101
 	if (!MultiByteToWideChar(CP_ACP,0,lpLibFileName,len_0,fnamw,len_0))
@@ -124,6 +128,8 @@
 static char *win32_name_converter(DSO *dso, const char *filename);
 static char *win32_merger(DSO *dso, const char *filespec1,
 	const char *filespec2);
+static int win32_pathbyaddr(void *addr,char *path,int sz);
+static void *win32_globallookup(const char *name);
 
 static const char *openssl_strnchr(const char *string, int c, size_t len);
 
@@ -142,7 +148,9 @@
 	win32_name_converter,
 	win32_merger,
 	NULL, /* init */
-	NULL  /* finish */
+	NULL, /* finish */
+	win32_pathbyaddr,
+	win32_globallookup
 	};
 
 DSO_METHOD *DSO_METHOD_win32(void)
@@ -180,7 +188,7 @@
 		goto err;
 		}
 	*p = h;
-	if(!sk_push(dso->meth_data, (char *)p))
+	if(!sk_void_push(dso->meth_data, p))
 		{
 		DSOerr(DSO_F_WIN32_LOAD,DSO_R_STACK_ERROR);
 		goto err;
@@ -207,9 +215,9 @@
 		DSOerr(DSO_F_WIN32_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
 		return(0);
 		}
-	if(sk_num(dso->meth_data) < 1)
+	if(sk_void_num(dso->meth_data) < 1)
 		return(1);
-	p = (HINSTANCE *)sk_pop(dso->meth_data);
+	p = sk_void_pop(dso->meth_data);
 	if(p == NULL)
 		{
 		DSOerr(DSO_F_WIN32_UNLOAD,DSO_R_NULL_HANDLE);
@@ -220,7 +228,7 @@
 		DSOerr(DSO_F_WIN32_UNLOAD,DSO_R_UNLOAD_FAILED);
 		/* We should push the value back onto the stack in
 		 * case of a retry. */
-		sk_push(dso->meth_data, (char *)p);
+		sk_void_push(dso->meth_data, p);
 		return(0);
 		}
 	/* Cleanup */
@@ -240,12 +248,12 @@
 		DSOerr(DSO_F_WIN32_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
 		return(NULL);
 		}
-	if(sk_num(dso->meth_data) < 1)
+	if(sk_void_num(dso->meth_data) < 1)
 		{
 		DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_STACK_ERROR);
 		return(NULL);
 		}
-	ptr = (HINSTANCE *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
+	ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
 	if(ptr == NULL)
 		{
 		DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_NULL_HANDLE);
@@ -271,12 +279,12 @@
 		DSOerr(DSO_F_WIN32_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
 		return(NULL);
 		}
-	if(sk_num(dso->meth_data) < 1)
+	if(sk_void_num(dso->meth_data) < 1)
 		{
 		DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_STACK_ERROR);
 		return(NULL);
 		}
-	ptr = (HINSTANCE *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
+	ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
 	if(ptr == NULL)
 		{
 		DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_NULL_HANDLE);
@@ -351,7 +359,7 @@
 				return(NULL);
 				}
 			result->device = start;
-			result->devicelen = filename - start;
+			result->devicelen = (int)(filename - start);
 			position = IN_FILE;
 			start = ++filename;
 			result->dir = start;
@@ -360,7 +368,7 @@
 		case '/':
 			if(position == IN_NODE)
 				{
-				result->nodelen = filename - start;
+				result->nodelen = (int)(filename - start);
 				position = IN_FILE;
 				start = ++filename;
 				result->dir = start;
@@ -370,20 +378,20 @@
 				position = IN_FILE;
 				filename++;
 				result->dir = start;
-				result->dirlen = filename - start;
+				result->dirlen = (int)(filename - start);
 				start = filename;
 				}
 			else
 				{
 				filename++;
-				result->dirlen += filename - start;
+				result->dirlen += (int)(filename - start);
 				start = filename;
 				}
 			break;
 		case '\0':
 			if(position == IN_NODE)
 				{
-				result->nodelen = filename - start;
+				result->nodelen = (int)(filename - start);
 				}
 			else
 				{
@@ -397,13 +405,13 @@
 							result->dirlen = 0;
 							}
 						result->dirlen +=
-							filename - start;
+							(int)(filename - start);
 						}
 					else
 						{
 						result->file = start;
 						result->filelen =
-							filename - start;
+							(int)(filename - start);
 						}
 					}
 				}
@@ -497,7 +505,7 @@
 				+ file_split->predirlen
 				- (start - file_split->predir);
 		strncpy(&result[offset], start,
-			end - start); offset += end - start;
+			end - start); offset += (int)(end - start);
 		result[offset] = '\\'; offset++;
 		start = end + 1;
 		}
@@ -518,7 +526,7 @@
 				+ file_split->dirlen
 				- (start - file_split->dir);
 		strncpy(&result[offset], start,
-			end - start); offset += end - start;
+			end - start); offset += (int)(end - start);
 		result[offset] = '\\'; offset++;
 		start = end + 1;
 		}
@@ -659,5 +667,178 @@
 	return NULL;
 	}
 
+#include <tlhelp32.h>
+#ifdef _WIN32_WCE
+# define DLLNAME "TOOLHELP.DLL"
+#else
+# ifdef MODULEENTRY32
+# undef MODULEENTRY32	/* unmask the ASCII version! */
+# endif
+# define DLLNAME "KERNEL32.DLL"
+#endif
 
-#endif /* OPENSSL_SYS_WIN32 */
+typedef HANDLE (WINAPI *CREATETOOLHELP32SNAPSHOT)(DWORD, DWORD);
+typedef BOOL (WINAPI *CLOSETOOLHELP32SNAPSHOT)(HANDLE);
+typedef BOOL (WINAPI *MODULE32)(HANDLE, MODULEENTRY32 *);
+
+static int win32_pathbyaddr(void *addr,char *path,int sz)
+	{
+	HMODULE dll;
+	HANDLE hModuleSnap = INVALID_HANDLE_VALUE; 
+	MODULEENTRY32 me32; 
+	CREATETOOLHELP32SNAPSHOT create_snap;
+	CLOSETOOLHELP32SNAPSHOT  close_snap;
+	MODULE32 module_first, module_next;
+	int len;
+ 
+	if (addr == NULL)
+		{
+		union	{ int(*f)(void*,char*,int); void *p; } t =
+			{ win32_pathbyaddr };
+		addr = t.p;
+		}
+
+	dll = LoadLibrary(TEXT(DLLNAME));
+	if (dll == NULL)
+		{
+		DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED);
+		return -1;
+		}
+
+	create_snap = (CREATETOOLHELP32SNAPSHOT)
+		GetProcAddress(dll,"CreateToolhelp32Snapshot");
+	if (create_snap == NULL)
+		{
+		FreeLibrary(dll);
+		DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED);
+		return -1;
+		}
+	/* We take the rest for granted... */
+#ifdef _WIN32_WCE
+	close_snap = (CLOSETOOLHELP32SNAPSHOT)
+		GetProcAddress(dll,"CloseToolhelp32Snapshot");
+#else
+	close_snap = (CLOSETOOLHELP32SNAPSHOT)CloseHandle;
+#endif
+	module_first = (MODULE32)GetProcAddress(dll,"Module32First");
+	module_next  = (MODULE32)GetProcAddress(dll,"Module32Next");
+
+	hModuleSnap = (*create_snap)(TH32CS_SNAPMODULE,0); 
+	if( hModuleSnap == INVALID_HANDLE_VALUE ) 
+		{ 
+		FreeLibrary(dll);
+		DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED);
+		return -1;
+		} 
+ 
+	me32.dwSize = sizeof(me32); 
+ 
+	if(!(*module_first)(hModuleSnap,&me32)) 
+		{ 
+		(*close_snap)(hModuleSnap);
+		FreeLibrary(dll);
+		DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_FAILURE);
+		return -1;
+		}
+ 
+	do	{ 
+		if ((BYTE *)addr >= me32.modBaseAddr &&
+		    (BYTE *)addr <  me32.modBaseAddr+me32.modBaseSize)
+			{
+			(*close_snap)(hModuleSnap);
+			FreeLibrary(dll);
+#ifdef _WIN32_WCE
+# if _WIN32_WCE >= 101
+			return WideCharToMultiByte(CP_ACP,0,me32.szExePath,-1,
+							path,sz,NULL,NULL);
+# else
+			len = (int)wcslen(me32.szExePath);
+			if (sz <= 0) return len+1;
+			if (len >= sz) len=sz-1;
+			for(i=0;i<len;i++)
+				path[i] = (char)me32.szExePath[i];
+			path[len++] = 0;
+			return len;
+# endif
+#else
+			len = (int)strlen(me32.szExePath);
+			if (sz <= 0) return len+1;
+			if (len >= sz) len=sz-1;
+			memcpy(path,me32.szExePath,len);
+			path[len++] = 0;
+			return len;
+#endif
+			} 
+		} while((*module_next)(hModuleSnap, &me32)); 
+ 
+	(*close_snap)(hModuleSnap); 
+	FreeLibrary(dll);
+	return 0;
+	}
+
+static void *win32_globallookup(const char *name)
+	{
+	HMODULE dll;
+	HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
+	MODULEENTRY32 me32;
+	CREATETOOLHELP32SNAPSHOT create_snap;
+	CLOSETOOLHELP32SNAPSHOT  close_snap;
+	MODULE32 module_first, module_next;
+	FARPROC ret=NULL;
+
+	dll = LoadLibrary(TEXT(DLLNAME));
+	if (dll == NULL)
+		{
+		DSOerr(DSO_F_WIN32_GLOBALLOOKUP,DSO_R_UNSUPPORTED);
+		return NULL;
+		}
+
+	create_snap = (CREATETOOLHELP32SNAPSHOT)
+		GetProcAddress(dll,"CreateToolhelp32Snapshot");
+	if (create_snap == NULL)
+		{
+		FreeLibrary(dll);
+		DSOerr(DSO_F_WIN32_GLOBALLOOKUP,DSO_R_UNSUPPORTED);
+		return NULL;
+		}
+	/* We take the rest for granted... */
+#ifdef _WIN32_WCE
+	close_snap = (CLOSETOOLHELP32SNAPSHOT)
+		GetProcAddress(dll,"CloseToolhelp32Snapshot");
+#else
+	close_snap = (CLOSETOOLHELP32SNAPSHOT)CloseHandle;
+#endif
+	module_first = (MODULE32)GetProcAddress(dll,"Module32First");
+	module_next  = (MODULE32)GetProcAddress(dll,"Module32Next");
+
+	hModuleSnap = (*create_snap)(TH32CS_SNAPMODULE,0);
+	if( hModuleSnap == INVALID_HANDLE_VALUE )
+		{
+		FreeLibrary(dll);
+		DSOerr(DSO_F_WIN32_GLOBALLOOKUP,DSO_R_UNSUPPORTED);
+		return NULL;
+		}
+
+	me32.dwSize = sizeof(me32);
+
+	if (!(*module_first)(hModuleSnap,&me32))
+		{
+		(*close_snap)(hModuleSnap);
+		FreeLibrary(dll);
+		return NULL;
+		}
+
+	do	{
+		if ((ret = GetProcAddress(me32.hModule,name)))
+			{
+			(*close_snap)(hModuleSnap);
+			FreeLibrary(dll);
+			return ret;
+			}
+		} while((*module_next)(hModuleSnap,&me32));
+
+	(*close_snap)(hModuleSnap); 
+	FreeLibrary(dll);
+	return NULL;
+	}
+#endif /* DSO_WIN32 */
diff --git a/crypto/dyn_lck.c b/crypto/dyn_lck.c
deleted file mode 100644
index 7f82c41..0000000
--- a/crypto/dyn_lck.c
+++ /dev/null
@@ -1,428 +0,0 @@
-/* crypto/cryptlib.c */
-/* ====================================================================
- * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-/* ====================================================================
- * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
- * ECDH support in OpenSSL originally developed by 
- * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
- */
-
-#include "cryptlib.h"
-#include <openssl/safestack.h>
-
-#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
-static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */
-#endif
-
-DECLARE_STACK_OF(CRYPTO_dynlock)
-IMPLEMENT_STACK_OF(CRYPTO_dynlock)
-
-/* real #defines in crypto.h, keep these upto date */
-static const char* const lock_names[CRYPTO_NUM_LOCKS] =
-	{
-	"<<ERROR>>",
-	"err",
-	"ex_data",
-	"x509",
-	"x509_info",
-	"x509_pkey",
-	"x509_crl",
-	"x509_req",
-	"dsa",
-	"rsa",
-	"evp_pkey",
-	"x509_store",
-	"ssl_ctx",
-	"ssl_cert",
-	"ssl_session",
-	"ssl_sess_cert",
-	"ssl",
-	"ssl_method",
-	"rand",
-	"rand2",
-	"debug_malloc",
-	"BIO",
-	"gethostbyname",
-	"getservbyname",
-	"readdir",
-	"RSA_blinding",
-	"dh",
-	"debug_malloc2",
-	"dso",
-	"dynlock",
-	"engine",
-	"ui",
-	"ecdsa",
-	"ec",
-	"ecdh",
-	"bn",
-	"ec_pre_comp",
-	"store",
-	"comp",
-#ifndef OPENSSL_FIPS
-# if CRYPTO_NUM_LOCKS != 39
-#  error "Inconsistency between crypto.h and cryptlib.c"
-# endif
-#else
-	"fips",
-	"fips2",
-# if CRYPTO_NUM_LOCKS != 41
-#  error "Inconsistency between crypto.h and cryptlib.c"
-# endif
-#endif
-	};
-
-/* This is for applications to allocate new type names in the non-dynamic
-   array of lock names.  These are numbered with positive numbers.  */
-static STACK *app_locks=NULL;
-
-/* For applications that want a more dynamic way of handling threads, the
-   following stack is used.  These are externally numbered with negative
-   numbers.  */
-static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL;
-
-
-static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
-	(const char *file,int line)=NULL;
-static void (MS_FAR *dynlock_lock_callback)(int mode,
-	struct CRYPTO_dynlock_value *l, const char *file,int line)=NULL;
-static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l,
-	const char *file,int line)=NULL;
-
-int CRYPTO_get_new_lockid(char *name)
-	{
-	char *str;
-	int i;
-
-#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
-	/* A hack to make Visual C++ 5.0 work correctly when linking as
-	 * a DLL using /MT. Without this, the application cannot use
-	 * and floating point printf's.
-	 * It also seems to be needed for Visual C 1.5 (win16) */
-	SSLeay_MSVC5_hack=(double)name[0]*(double)name[1];
-#endif
-
-	if ((app_locks == NULL) && ((app_locks=sk_new_null()) == NULL))
-		{
-		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
-		return(0);
-		}
-	if ((str=BUF_strdup(name)) == NULL)
-		{
-		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
-		return(0);
-		}
-	i=sk_push(app_locks,str);
-	if (!i)
-		OPENSSL_free(str);
-	else
-		i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */
-	return(i);
-	}
-
-int CRYPTO_get_new_dynlockid(void)
-	{
-	int i = 0;
-	CRYPTO_dynlock *pointer = NULL;
-
-	if (dynlock_create_callback == NULL)
-		{
-		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
-		return(0);
-		}
-	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
-	if ((dyn_locks == NULL)
-		&& ((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL))
-		{
-		CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
-		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
-		return(0);
-		}
-	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
-
-	pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock));
-	if (pointer == NULL)
-		{
-		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
-		return(0);
-		}
-	pointer->references = 1;
-	pointer->data = dynlock_create_callback(__FILE__,__LINE__);
-	if (pointer->data == NULL)
-		{
-		OPENSSL_free(pointer);
-		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
-		return(0);
-		}
-
-	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
-	/* First, try to find an existing empty slot */
-	i=sk_CRYPTO_dynlock_find(dyn_locks,NULL);
-	/* If there was none, push, thereby creating a new one */
-	if (i == -1)
-		/* Since sk_push() returns the number of items on the
-		   stack, not the location of the pushed item, we need
-		   to transform the returned number into a position,
-		   by decreasing it.  */
-		i=sk_CRYPTO_dynlock_push(dyn_locks,pointer) - 1;
-	else
-		/* If we found a place with a NULL pointer, put our pointer
-		   in it.  */
-		(void)sk_CRYPTO_dynlock_set(dyn_locks,i,pointer);
-	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
-
-	if (i == -1)
-		{
-		dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
-		OPENSSL_free(pointer);
-		}
-	else
-		i += 1; /* to avoid 0 */
-	return -i;
-	}
-
-void CRYPTO_destroy_dynlockid(int i)
-	{
-	CRYPTO_dynlock *pointer = NULL;
-	if (i)
-		i = -i-1;
-	if (dynlock_destroy_callback == NULL)
-		return;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
-
-	if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks))
-		{
-		CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
-		return;
-		}
-	pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
-	if (pointer != NULL)
-		{
-		--pointer->references;
-#ifdef REF_CHECK
-		if (pointer->references < 0)
-			{
-			fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference count\n");
-			abort();
-			}
-		else
-#endif
-			if (pointer->references <= 0)
-				{
-				(void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
-				}
-			else
-				pointer = NULL;
-		}
-	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
-
-	if (pointer)
-		{
-		dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
-		OPENSSL_free(pointer);
-		}
-	}
-
-struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)
-	{
-	CRYPTO_dynlock *pointer = NULL;
-	if (i)
-		i = -i-1;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
-
-	if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
-		pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
-	if (pointer)
-		pointer->references++;
-
-	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
-
-	if (pointer)
-		return pointer->data;
-	return NULL;
-	}
-
-struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))
-	(const char *file,int line)
-	{
-	return(dynlock_create_callback);
-	}
-
-void (*CRYPTO_get_dynlock_lock_callback(void))(int mode,
-	struct CRYPTO_dynlock_value *l, const char *file,int line)
-	{
-	return(dynlock_lock_callback);
-	}
-
-void (*CRYPTO_get_dynlock_destroy_callback(void))
-	(struct CRYPTO_dynlock_value *l, const char *file,int line)
-	{
-	return(dynlock_destroy_callback);
-	}
-
-void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
-	(const char *file, int line))
-	{
-	dynlock_create_callback=func;
-	}
-
-static void do_dynlock(int mode, int type, const char *file, int line)
-	{
-	if (dynlock_lock_callback != NULL)
-		{
-		struct CRYPTO_dynlock_value *pointer
-				= CRYPTO_get_dynlock_value(type);
-
-		OPENSSL_assert(pointer != NULL);
-
-		dynlock_lock_callback(mode, pointer, file, line);
-
-		CRYPTO_destroy_dynlockid(type);
-		}
-	}
-
-void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode,
-	struct CRYPTO_dynlock_value *l, const char *file, int line))
-	{
-	/* Set callback so CRYPTO_lock() can now handle dynamic locks.
-	 * This is OK because at this point and application shouldn't be using
-	 * OpenSSL from multiple threads because it is setting up the locking
-	 * callbacks.
-	 */
-	static int done = 0;
-	if (!done)
-		{
-		int_CRYPTO_set_do_dynlock_callback(do_dynlock);
-		done = 1;
-		}
-		
-	dynlock_lock_callback=func;
-	}
-
-void CRYPTO_set_dynlock_destroy_callback(void (*func)
-	(struct CRYPTO_dynlock_value *l, const char *file, int line))
-	{
-	dynlock_destroy_callback=func;
-	}
-
-const char *CRYPTO_get_lock_name(int type)
-	{
-	if (type < 0)
-		return("dynamic");
-	else if (type < CRYPTO_NUM_LOCKS)
-		return(lock_names[type]);
-	else if (type-CRYPTO_NUM_LOCKS > sk_num(app_locks))
-		return("ERROR");
-	else
-		return(sk_value(app_locks,type-CRYPTO_NUM_LOCKS));
-	}
-
diff --git a/crypto/ec/Makefile b/crypto/ec/Makefile
deleted file mode 100644
index b5bbc9f..0000000
--- a/crypto/ec/Makefile
+++ /dev/null
@@ -1,193 +0,0 @@
-#
-# crypto/ec/Makefile
-#
-
-DIR=	ec
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=ectest.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=	ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c\
-	ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c\
-	ec2_smpl.c ec2_smpt.c ec2_mult.c
-
-LIBOBJ=	ec_lib.o ecp_smpl.o ecp_mont.o ecp_nist.o ec_cvt.o ec_mult.o\
-	ec_err.o ec_curve.o ec_check.o ec_print.o ec_asn1.o ec_key.o\
-	ec2_smpl.o ec2_mult.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= ec.h
-HEADER=	ec_lcl.h $(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-ec2_mult.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ec2_mult.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-ec2_mult.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ec2_mult.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-ec2_mult.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
-ec2_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ec2_mult.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ec2_mult.o: ../../include/openssl/symhacks.h ec2_mult.c ec_lcl.h
-ec2_smpl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ec2_smpl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-ec2_smpl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ec2_smpl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-ec2_smpl.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
-ec2_smpl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ec2_smpl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ec2_smpl.o: ../../include/openssl/symhacks.h ec2_smpl.c ec2_smpt.c ec_lcl.h
-ec2_smpt.o: ec2_smpt.c
-ec_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
-ec_asn1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-ec_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-ec_asn1.o: ../../include/openssl/ec.h ../../include/openssl/err.h
-ec_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-ec_asn1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-ec_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ec_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ec_asn1.o: ../../include/openssl/symhacks.h ec_asn1.c ec_lcl.h
-ec_check.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ec_check.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-ec_check.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ec_check.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-ec_check.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
-ec_check.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ec_check.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ec_check.o: ../../include/openssl/symhacks.h ec_check.c ec_lcl.h
-ec_curve.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ec_curve.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-ec_curve.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ec_curve.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-ec_curve.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
-ec_curve.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ec_curve.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ec_curve.o: ../../include/openssl/symhacks.h ec_curve.c ec_lcl.h
-ec_cvt.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ec_cvt.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-ec_cvt.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ec_cvt.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-ec_cvt.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
-ec_cvt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ec_cvt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ec_cvt.o: ../../include/openssl/symhacks.h ec_cvt.c ec_lcl.h
-ec_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ec_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-ec_err.o: ../../include/openssl/ec.h ../../include/openssl/err.h
-ec_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-ec_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ec_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ec_err.o: ../../include/openssl/symhacks.h ec_err.c
-ec_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ec_key.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-ec_key.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ec_key.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-ec_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
-ec_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ec_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ec_key.o: ../../include/openssl/symhacks.h ec_key.c ec_lcl.h
-ec_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ec_lib.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-ec_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ec_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-ec_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
-ec_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ec_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ec_lib.o: ../../include/openssl/symhacks.h ec_lcl.h ec_lib.c
-ec_mult.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ec_mult.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-ec_mult.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ec_mult.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-ec_mult.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
-ec_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ec_mult.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ec_mult.o: ../../include/openssl/symhacks.h ec_lcl.h ec_mult.c
-ec_print.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ec_print.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-ec_print.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ec_print.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
-ec_print.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ec_print.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ec_print.o: ../../include/openssl/symhacks.h ec_lcl.h ec_print.c
-ecp_mont.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ecp_mont.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-ecp_mont.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ecp_mont.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-ecp_mont.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
-ecp_mont.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ecp_mont.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ecp_mont.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_mont.c
-ecp_nist.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ecp_nist.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-ecp_nist.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ecp_nist.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-ecp_nist.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
-ecp_nist.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ecp_nist.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ecp_nist.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_nist.c
-ecp_smpl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ecp_smpl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-ecp_smpl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ecp_smpl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-ecp_smpl.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
-ecp_smpl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ecp_smpl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ecp_smpl.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_smpl.c
diff --git a/crypto/ec/ec.h b/crypto/ec/ec.h
index 8bc2a23..ee70781 100644
--- a/crypto/ec/ec.h
+++ b/crypto/ec/ec.h
@@ -2,8 +2,12 @@
 /*
  * Originally written by Bodo Moeller for the OpenSSL project.
  */
+/**
+ * \file crypto/ec/ec.h Include file for the OpenSSL EC functions
+ * \author Originally written by Bodo Moeller for the OpenSSL project
+ */
 /* ====================================================================
- * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -92,15 +96,21 @@
 # endif
 #endif
 
-
+  
 #ifndef OPENSSL_ECC_MAX_FIELD_BITS
 # define OPENSSL_ECC_MAX_FIELD_BITS 661
 #endif
 
+/** Enum for the point conversion form as defined in X9.62 (ECDSA)
+ *  for the encoding of a elliptic curve point (x,y) */
 typedef enum {
-	/* values as defined in X9.62 (ECDSA) and elsewhere */
+	/** the point is encoded as z||x, where the octet z specifies 
+	 *  which solution of the quadratic equation y is  */
 	POINT_CONVERSION_COMPRESSED = 2,
+	/** the point is encoded as z||x||y, where z is the octet 0x02  */
 	POINT_CONVERSION_UNCOMPRESSED = 4,
+	/** the point is encoded as z||x||y, where the octet z specifies
+         *  which solution of the quadratic equation y is  */
 	POINT_CONVERSION_HYBRID = 6
 } point_conversion_form_t;
 
@@ -121,37 +131,129 @@
 typedef struct ec_point_st EC_POINT;
 
 
-/* EC_METHODs for curves over GF(p).
- * EC_GFp_simple_method provides the basis for the optimized methods.
+/********************************************************************/
+/*               EC_METHODs for curves over GF(p)                   */       
+/********************************************************************/
+
+/** Returns the basic GFp ec methods which provides the basis for the
+ *  optimized methods. 
+ *  \return  EC_METHOD object
  */
 const EC_METHOD *EC_GFp_simple_method(void);
+
+/** Returns GFp methods using montgomery multiplication.
+ *  \return  EC_METHOD object
+ */
 const EC_METHOD *EC_GFp_mont_method(void);
+
+/** Returns GFp methods using optimized methods for NIST recommended curves
+ *  \return  EC_METHOD object
+ */
 const EC_METHOD *EC_GFp_nist_method(void);
 
-/* EC_METHOD for curves over GF(2^m).
+
+/********************************************************************/ 
+/*           EC_METHOD for curves over GF(2^m)                      */
+/********************************************************************/
+
+/** Returns the basic GF2m ec method 
+ *  \return  EC_METHOD object
  */
 const EC_METHOD *EC_GF2m_simple_method(void);
 
 
-EC_GROUP *EC_GROUP_new(const EC_METHOD *);
-void EC_GROUP_free(EC_GROUP *);
-void EC_GROUP_clear_free(EC_GROUP *);
-int EC_GROUP_copy(EC_GROUP *, const EC_GROUP *);
-EC_GROUP *EC_GROUP_dup(const EC_GROUP *);
+/********************************************************************/
+/*                   EC_GROUP functions                             */
+/********************************************************************/
 
-const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *);
-int EC_METHOD_get_field_type(const EC_METHOD *);
+/** Creates a new EC_GROUP object
+ *  \param   meth  EC_METHOD to use
+ *  \return  newly created EC_GROUP object or NULL in case of an error.
+ */
+EC_GROUP *EC_GROUP_new(const EC_METHOD *meth);
 
-int EC_GROUP_set_generator(EC_GROUP *, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor);
-const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *);
-int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *);
-int EC_GROUP_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *);
+/** Frees a EC_GROUP object
+ *  \param  group  EC_GROUP object to be freed.
+ */
+void EC_GROUP_free(EC_GROUP *group);
 
-void EC_GROUP_set_curve_name(EC_GROUP *, int nid);
-int EC_GROUP_get_curve_name(const EC_GROUP *);
+/** Clears and frees a EC_GROUP object
+ *  \param  group  EC_GROUP object to be cleared and freed.
+ */
+void EC_GROUP_clear_free(EC_GROUP *group);
 
-void EC_GROUP_set_asn1_flag(EC_GROUP *, int flag);
-int EC_GROUP_get_asn1_flag(const EC_GROUP *);
+/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD.
+ *  \param  dst  destination EC_GROUP object
+ *  \param  src  source EC_GROUP object
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src);
+
+/** Creates a new EC_GROUP object and copies the copies the content
+ *  form src to the newly created EC_KEY object
+ *  \param  src  source EC_GROUP object
+ *  \return newly created EC_GROUP object or NULL in case of an error.
+ */
+EC_GROUP *EC_GROUP_dup(const EC_GROUP *src);
+
+/** Returns the EC_METHOD of the EC_GROUP object.
+ *  \param  group  EC_GROUP object 
+ *  \return EC_METHOD used in this EC_GROUP object.
+ */
+const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group);
+
+/** Returns the field type of the EC_METHOD.
+ *  \param  meth  EC_METHOD object
+ *  \return NID of the underlying field type OID.
+ */
+int EC_METHOD_get_field_type(const EC_METHOD *meth);
+
+/** Sets the generator and it's order/cofactor of a EC_GROUP object.
+ *  \param  group      EC_GROUP object 
+ *  \param  generator  EC_POINT object with the generator.
+ *  \param  order      the order of the group generated by the generator.
+ *  \param  cofactor   the index of the sub-group generated by the generator
+ *                     in the group of all points on the elliptic curve.
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor);
+
+/** Returns the generator of a EC_GROUP object.
+ *  \param  group  EC_GROUP object
+ *  \return the currently used generator (possibly NULL).
+ */
+const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);
+
+/** Gets the order of a EC_GROUP
+ *  \param  group  EC_GROUP object
+ *  \param  order  BIGNUM to which the order is copied
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx);
+
+/** Gets the cofactor of a EC_GROUP
+ *  \param  group     EC_GROUP object
+ *  \param  cofactor  BIGNUM to which the cofactor is copied
+ *  \param  ctx       BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx);
+
+/** Sets the name of a EC_GROUP object
+ *  \param  group  EC_GROUP object
+ *  \param  nid    NID of the curve name OID
+ */
+void EC_GROUP_set_curve_name(EC_GROUP *group, int nid);
+
+/** Returns the curve name of a EC_GROUP object
+ *  \param  group  EC_GROUP object
+ *  \return NID of the curve name OID or 0 if not set.
+ */
+int EC_GROUP_get_curve_name(const EC_GROUP *group);
+
+void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
+int EC_GROUP_get_asn1_flag(const EC_GROUP *group);
 
 void EC_GROUP_set_point_conversion_form(EC_GROUP *, point_conversion_form_t);
 point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
@@ -160,36 +262,114 @@
 size_t EC_GROUP_get_seed_len(const EC_GROUP *);
 size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
 
-int EC_GROUP_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
-int EC_GROUP_get_curve_GFp(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
-int EC_GROUP_set_curve_GF2m(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
-int EC_GROUP_get_curve_GF2m(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
+/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM with the prime number
+ *  \param  a      BIGNUM with parameter a of the equation
+ *  \param  b      BIGNUM with parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
 
-/* returns the number of bits needed to represent a field element */
-int EC_GROUP_get_degree(const EC_GROUP *);
+/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM for the prime number
+ *  \param  a      BIGNUM for parameter a of the equation
+ *  \param  b      BIGNUM for parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
 
-/* EC_GROUP_check() returns 1 if 'group' defines a valid group, 0 otherwise */
+/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM with the polynomial defining the underlying field
+ *  \param  a      BIGNUM with parameter a of the equation
+ *  \param  b      BIGNUM with parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+
+/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM for the polynomial defining the underlying field
+ *  \param  a      BIGNUM for parameter a of the equation
+ *  \param  b      BIGNUM for parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
+
+/** Returns the number of bits needed to represent a field element 
+ *  \param  group  EC_GROUP object
+ *  \return number of bits needed to represent a field element
+ */
+int EC_GROUP_get_degree(const EC_GROUP *group);
+
+/** Checks whether the parameter in the EC_GROUP define a valid ec group
+ *  \param  group  EC_GROUP object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 if group is a valid ec group and 0 otherwise
+ */
 int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
-/* EC_GROUP_check_discriminant() returns 1 if the discriminant of the
- * elliptic curve is not zero, 0 otherwise */
-int EC_GROUP_check_discriminant(const EC_GROUP *, BN_CTX *);
 
-/* EC_GROUP_cmp() returns 0 if both groups are equal and 1 otherwise */
-int EC_GROUP_cmp(const EC_GROUP *, const EC_GROUP *, BN_CTX *);
+/** Checks whether the discriminant of the elliptic curve is zero or not
+ *  \param  group  EC_GROUP object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 if the discriminant is not zero and 0 otherwise
+ */
+int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx);
+
+/** Compares two EC_GROUP objects
+ *  \param  a    first EC_GROUP object
+ *  \param  b    second EC_GROUP object
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return 0 if both groups are equal and 1 otherwise
+ */
+int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx);
 
 /* EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*()
  * after choosing an appropriate EC_METHOD */
-EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
-EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
 
-/* EC_GROUP_new_by_curve_name() creates a EC_GROUP structure
- * specified by a curve name (in form of a NID) */
+/** Creates a new EC_GROUP object with the specified parameters defined
+ *  over GFp (defined by the equation y^2 = x^3 + a*x + b)
+ *  \param  p    BIGNUM with the prime number
+ *  \param  a    BIGNUM with the parameter a of the equation
+ *  \param  b    BIGNUM with the parameter b of the equation
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return newly created EC_GROUP object with the specified parameters
+ */
+EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+
+/** Creates a new EC_GROUP object with the specified parameters defined
+ *  over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b)
+ *  \param  p    BIGNUM with the polynomial defining the underlying field
+ *  \param  a    BIGNUM with the parameter a of the equation
+ *  \param  b    BIGNUM with the parameter b of the equation
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return newly created EC_GROUP object with the specified parameters
+ */
+EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+
+/** Creates a EC_GROUP object with a curve specified by a NID
+ *  \param  nid  NID of the OID of the curve name
+ *  \return newly created EC_GROUP object with specified curve or NULL
+ *          if an error occurred
+ */
 EC_GROUP *EC_GROUP_new_by_curve_name(int nid);
-/* handling of internal curves */
+
+
+/********************************************************************/
+/*               handling of internal curves                        */
+/********************************************************************/
+
 typedef struct { 
 	int nid;
 	const char *comment;
 	} EC_builtin_curve;
+
 /* EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number 
  * of all available curves or zero if a error occurred. 
  * In case r ist not zero nitems EC_builtin_curve structures 
@@ -197,39 +377,168 @@
 size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);
 
 
-/* EC_POINT functions */
+/********************************************************************/
+/*                    EC_POINT functions                            */
+/********************************************************************/
 
-EC_POINT *EC_POINT_new(const EC_GROUP *);
-void EC_POINT_free(EC_POINT *);
-void EC_POINT_clear_free(EC_POINT *);
-int EC_POINT_copy(EC_POINT *, const EC_POINT *);
-EC_POINT *EC_POINT_dup(const EC_POINT *, const EC_GROUP *);
+/** Creates a new EC_POINT object for the specified EC_GROUP
+ *  \param  group  EC_GROUP the underlying EC_GROUP object
+ *  \return newly created EC_POINT object or NULL if an error occurred
+ */
+EC_POINT *EC_POINT_new(const EC_GROUP *group);
+
+/** Frees a EC_POINT object
+ *  \param  point  EC_POINT object to be freed
+ */
+void EC_POINT_free(EC_POINT *point);
+
+/** Clears and frees a EC_POINT object
+ *  \param  point  EC_POINT object to be cleared and freed
+ */
+void EC_POINT_clear_free(EC_POINT *point);
+
+/** Copies EC_POINT object
+ *  \param  dst  destination EC_POINT object
+ *  \param  src  source EC_POINT object
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src);
+
+/** Creates a new EC_POINT object and copies the content of the supplied
+ *  EC_POINT
+ *  \param  src    source EC_POINT object
+ *  \param  group  underlying the EC_GROUP object
+ *  \return newly created EC_POINT object or NULL if an error occurred 
+ */
+EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group);
  
-const EC_METHOD *EC_POINT_method_of(const EC_POINT *);
+/** Returns the EC_METHOD used in EC_POINT object 
+ *  \param  point  EC_POINT object
+ *  \return the EC_METHOD used
+ */
+const EC_METHOD *EC_POINT_method_of(const EC_POINT *point);
 
-int EC_POINT_set_to_infinity(const EC_GROUP *, EC_POINT *);
-int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *,
-	const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
-int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
-	BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
-int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *, EC_POINT *,
-	const BIGNUM *x, const BIGNUM *y, BN_CTX *);
-int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
-	BIGNUM *x, BIGNUM *y, BN_CTX *);
-int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *, EC_POINT *,
-	const BIGNUM *x, int y_bit, BN_CTX *);
+/** Sets a point to infinity (neutral element)
+ *  \param  group  underlying EC_GROUP object
+ *  \param  point  EC_POINT to set to infinity
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point);
 
-int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *, EC_POINT *,
-	const BIGNUM *x, const BIGNUM *y, BN_CTX *);
-int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *, const EC_POINT *,
-	BIGNUM *x, BIGNUM *y, BN_CTX *);
-int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *, EC_POINT *,
-	const BIGNUM *x, int y_bit, BN_CTX *);
+/** Sets the jacobian projective coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with the x-coordinate
+ *  \param  y      BIGNUM with the y-coordinate
+ *  \param  z      BIGNUM with the z-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
+	const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx);
 
-size_t EC_POINT_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
-        unsigned char *buf, size_t len, BN_CTX *);
-int EC_POINT_oct2point(const EC_GROUP *, EC_POINT *,
-        const unsigned char *buf, size_t len, BN_CTX *);
+/** Gets the jacobian projective coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM for the x-coordinate
+ *  \param  y      BIGNUM for the y-coordinate
+ *  \param  z      BIGNUM for the z-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
+	const EC_POINT *p, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx);
+
+/** Sets the affine coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with the x-coordinate
+ *  \param  y      BIGNUM with the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
+	const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
+
+/** Gets the affine coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM for the x-coordinate
+ *  \param  y      BIGNUM for the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
+	const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
+
+/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with x-coordinate
+ *  \param  y_bit  integer with the y-Bit (either 0 or 1)
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
+	const BIGNUM *x, int y_bit, BN_CTX *ctx);
+
+/** Sets the affine coordinates of a EC_POINT over GF2m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with the x-coordinate
+ *  \param  y      BIGNUM with the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
+	const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
+
+/** Gets the affine coordinates of a EC_POINT over GF2m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM for the x-coordinate
+ *  \param  y      BIGNUM for the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
+	const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
+
+/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with x-coordinate
+ *  \param  y_bit  integer with the y-Bit (either 0 or 1)
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
+	const BIGNUM *x, int y_bit, BN_CTX *ctx);
+
+/** Encodes a EC_POINT object to a octet string
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  form   point conversion form
+ *  \param  buf    memory buffer for the result. If NULL the function returns
+ *                 required buffer size.
+ *  \param  len    length of the memory buffer
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return the length of the encoded octet string or 0 if an error occurred
+ */
+size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p,
+	point_conversion_form_t form,
+        unsigned char *buf, size_t len, BN_CTX *ctx);
+
+/** Decodes a EC_POINT from a octet string
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  buf    memory buffer with the encoded ec point
+ *  \param  len    length of the encoded ec point
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p,
+        const unsigned char *buf, size_t len, BN_CTX *ctx);
 
 /* other interfaces to point2oct/oct2point: */
 BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
@@ -241,29 +550,105 @@
 EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *,
 	EC_POINT *, BN_CTX *);
 
-int EC_POINT_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
-int EC_POINT_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
-int EC_POINT_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
 
-int EC_POINT_is_at_infinity(const EC_GROUP *, const EC_POINT *);
-int EC_POINT_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
-int EC_POINT_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
+/********************************************************************/
+/*         functions for doing EC_POINT arithmetic                  */
+/********************************************************************/
+
+/** Computes the sum of two EC_POINT 
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result (r = a + b)
+ *  \param  a      EC_POINT object with the first summand
+ *  \param  b      EC_POINT object with the second summand
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
+
+/** Computes the double of a EC_POINT
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result (r = 2 * a)
+ *  \param  a      EC_POINT object 
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx);
+
+/** Computes the inverse of a EC_POINT
+ *  \param  group  underlying EC_GROUP object
+ *  \param  a      EC_POINT object to be inverted (it's used for the result as well)
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx);
+
+/** Checks whether the point is the neutral element of the group
+ *  \param  group  the underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \return 1 if the point is the neutral element and 0 otherwise
+ */
+int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p);
+
+/** Checks whether the point is on the curve 
+ *  \param  group  underlying EC_GROUP object
+ *  \param  point  EC_POINT object to check
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 if point if on the curve and 0 otherwise
+ */
+int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx);
+
+/** Compares two EC_POINTs 
+ *  \param  group  underlying EC_GROUP object
+ *  \param  a      first EC_POINT object
+ *  \param  b      second EC_POINT object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 0 if both points are equal and a value != 0 otherwise
+ */
+int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
 
 int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
 int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
 
+/** Computes r = generator * n sum_{i=0}^num p[i] * m[i]
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result
+ *  \param  n      BIGNUM with the multiplier for the group generator (optional)
+ *  \param  num    number futher summands
+ *  \param  p      array of size num of EC_POINT objects
+ *  \param  m      array of size num of BIGNUM objects
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, size_t num, const EC_POINT *p[], const BIGNUM *m[], BN_CTX *ctx);
 
-int EC_POINTs_mul(const EC_GROUP *, EC_POINT *r, const BIGNUM *, size_t num, const EC_POINT *[], const BIGNUM *[], BN_CTX *);
-int EC_POINT_mul(const EC_GROUP *, EC_POINT *r, const BIGNUM *, const EC_POINT *, const BIGNUM *, BN_CTX *);
+/** Computes r = generator * n + q * m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result
+ *  \param  n      BIGNUM with the multiplier for the group generator (optional)
+ *  \param  q      EC_POINT object with the first factor of the second summand
+ *  \param  m      BIGNUM with the second factor of the second summand
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
 
-/* EC_GROUP_precompute_mult() stores multiples of generator for faster point multiplication */
-int EC_GROUP_precompute_mult(EC_GROUP *, BN_CTX *);
-/* EC_GROUP_have_precompute_mult() reports whether such precomputation has been done */
-int EC_GROUP_have_precompute_mult(const EC_GROUP *);
+/** Stores multiples of generator for faster point multiplication
+ *  \param  group  EC_GROUP object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+
+/** Reports whether a precomputation has been done
+ *  \param  group  EC_GROUP object
+ *  \return 1 if a pre-computation has been done and 0 otherwise
+ */
+int EC_GROUP_have_precompute_mult(const EC_GROUP *group);
 
 
-
-/* ASN1 stuff */
+/********************************************************************/
+/*                       ASN1 stuff                                 */
+/********************************************************************/
 
 /* EC_GROUP_get_basis_type() returns the NID of the basis type
  * used to represent the field elements */
@@ -293,28 +678,96 @@
 int     ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
 #endif
 
-/* the EC_KEY stuff */
+
+/********************************************************************/
+/*                      EC_KEY functions                            */
+/********************************************************************/
+
 typedef struct ec_key_st EC_KEY;
 
 /* some values for the encoding_flag */
 #define EC_PKEY_NO_PARAMETERS	0x001
 #define EC_PKEY_NO_PUBKEY	0x002
 
+/** Creates a new EC_KEY object.
+ *  \return EC_KEY object or NULL if an error occurred.
+ */
 EC_KEY *EC_KEY_new(void);
+
+/** Creates a new EC_KEY object using a named curve as underlying
+ *  EC_GROUP object.
+ *  \param  nid  NID of the named curve.
+ *  \return EC_KEY object or NULL if an error occurred. 
+ */
 EC_KEY *EC_KEY_new_by_curve_name(int nid);
-void EC_KEY_free(EC_KEY *);
-EC_KEY *EC_KEY_copy(EC_KEY *, const EC_KEY *);
-EC_KEY *EC_KEY_dup(const EC_KEY *);
 
-int EC_KEY_up_ref(EC_KEY *);
+/** Frees a EC_KEY object.
+ *  \param  key  EC_KEY object to be freed.
+ */
+void EC_KEY_free(EC_KEY *key);
 
-const EC_GROUP *EC_KEY_get0_group(const EC_KEY *);
-int EC_KEY_set_group(EC_KEY *, const EC_GROUP *);
-const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *);
-int EC_KEY_set_private_key(EC_KEY *, const BIGNUM *);
-const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *);
-int EC_KEY_set_public_key(EC_KEY *, const EC_POINT *);
-unsigned EC_KEY_get_enc_flags(const EC_KEY *);
+/** Copies a EC_KEY object.
+ *  \param  dst  destination EC_KEY object
+ *  \param  src  src EC_KEY object
+ *  \return dst or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src);
+
+/** Creates a new EC_KEY object and copies the content from src to it.
+ *  \param  src  the source EC_KEY object
+ *  \return newly created EC_KEY object or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_dup(const EC_KEY *src);
+
+/** Increases the internal reference count of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_up_ref(EC_KEY *key);
+
+/** Returns the EC_GROUP object of a EC_KEY object
+ *  \param  key  EC_KEY object
+ *  \return the EC_GROUP object (possibly NULL).
+ */
+const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key);
+
+/** Sets the EC_GROUP of a EC_KEY object.
+ *  \param  key    EC_KEY object
+ *  \param  group  EC_GROUP to use in the EC_KEY object (note: the EC_KEY
+ *                 object will use an own copy of the EC_GROUP).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group);
+
+/** Returns the private key of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \return a BIGNUM with the private key (possibly NULL).
+ */
+const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key);
+
+/** Sets the private key of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \param  prv  BIGNUM with the private key (note: the EC_KEY object
+ *               will use an own copy of the BIGNUM).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv);
+
+/** Returns the public key of a EC_KEY object.
+ *  \param  key  the EC_KEY object
+ *  \return a EC_POINT object with the public key (possibly NULL)
+ */
+const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
+
+/** Sets the public key of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \param  pub  EC_POINT object with the public key (note: the EC_KEY object
+ *               will use an own copy of the EC_POINT object).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
+
+unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
 void EC_KEY_set_enc_flags(EC_KEY *, unsigned int);
 point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *);
 void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t);
@@ -325,31 +778,126 @@
 	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
 /* wrapper functions for the underlying EC_GROUP object */
 void EC_KEY_set_asn1_flag(EC_KEY *, int);
-int EC_KEY_precompute_mult(EC_KEY *, BN_CTX *ctx);
 
-/* EC_KEY_generate_key() creates a ec private (public) key */
-int EC_KEY_generate_key(EC_KEY *);
-/* EC_KEY_check_key() */
-int EC_KEY_check_key(const EC_KEY *);
+/** Creates a table of pre-computed multiples of the generator to 
+ *  accelerate further EC_KEY operations.
+ *  \param  key  EC_KEY object
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);
 
-/* de- and encoding functions for SEC1 ECPrivateKey */
-EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len);
-int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out);
-/* de- and encoding functions for EC parameters */
-EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len);
-int i2d_ECParameters(EC_KEY *a, unsigned char **out);
-/* de- and encoding functions for EC public key
- * (octet string, not DER -- hence 'o2i' and 'i2o') */
-EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len);
-int i2o_ECPublicKey(EC_KEY *a, unsigned char **out);
+/** Creates a new ec private (and optional a new public) key.
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_generate_key(EC_KEY *key);
+
+/** Verifies that a private and/or public key is valid.
+ *  \param  key  the EC_KEY object
+ *  \return 1 on success and 0 otherwise.
+ */
+int EC_KEY_check_key(const EC_KEY *key);
+
+
+/********************************************************************/
+/*        de- and encoding functions for SEC1 ECPrivateKey          */
+/********************************************************************/
+
+/** Decodes a private key from a memory buffer.
+ *  \param  key  a pointer to a EC_KEY object which should be used (or NULL)
+ *  \param  in   pointer to memory with the DER encoded private key
+ *  \param  len  length of the DER encoded private key
+ *  \return the decoded private key or NULL if an error occurred.
+ */
+EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len);
+
+/** Encodes a private key object and stores the result in a buffer.
+ *  \param  key  the EC_KEY object to encode
+ *  \param  out  the buffer for the result (if NULL the function returns number
+ *               of bytes needed).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out);
+
+
+/********************************************************************/
+/*        de- and encoding functions for EC parameters              */
+/********************************************************************/
+
+/** Decodes ec parameter from a memory buffer.
+ *  \param  key  a pointer to a EC_KEY object which should be used (or NULL)
+ *  \param  in   pointer to memory with the DER encoded ec parameters
+ *  \param  len  length of the DER encoded ec parameters
+ *  \return a EC_KEY object with the decoded parameters or NULL if an error
+ *          occurred.
+ */
+EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len);
+
+/** Encodes ec parameter and stores the result in a buffer.
+ *  \param  key  the EC_KEY object with ec paramters to encode
+ *  \param  out  the buffer for the result (if NULL the function returns number
+ *               of bytes needed).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int i2d_ECParameters(EC_KEY *key, unsigned char **out);
+
+
+/********************************************************************/
+/*         de- and encoding functions for EC public key             */
+/*         (octet string, not DER -- hence 'o2i' and 'i2o')         */
+/********************************************************************/
+
+/** Decodes a ec public key from a octet string.
+ *  \param  key  a pointer to a EC_KEY object which should be used
+ *  \param  in   memory buffer with the encoded public key
+ *  \param  len  length of the encoded public key
+ *  \return EC_KEY object with decoded public key or NULL if an error
+ *          occurred.
+ */
+EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len);
+
+/** Encodes a ec public key in an octet string.
+ *  \param  key  the EC_KEY object with the public key
+ *  \param  out  the buffer for the result (if NULL the function returns number
+ *               of bytes needed).
+ *  \return 1 on success and 0 if an error occurred
+ */
+int i2o_ECPublicKey(EC_KEY *key, unsigned char **out);
 
 #ifndef OPENSSL_NO_BIO
-int	ECParameters_print(BIO *bp, const EC_KEY *x);
-int	EC_KEY_print(BIO *bp, const EC_KEY *x, int off);
+/** Prints out the ec parameters on human readable form.
+ *  \param  bp   BIO object to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred
+ */
+int	ECParameters_print(BIO *bp, const EC_KEY *key);
+
+/** Prints out the contents of a EC_KEY object
+ *  \param  bp   BIO object to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \param  off  line offset 
+ *  \return 1 on success and 0 if an error occurred
+ */
+int	EC_KEY_print(BIO *bp, const EC_KEY *key, int off);
+
 #endif
 #ifndef OPENSSL_NO_FP_API
-int	ECParameters_print_fp(FILE *fp, const EC_KEY *x);
-int	EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off);
+/** Prints out the ec parameters on human readable form.
+ *  \param  fp   file descriptor to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred
+ */
+int	ECParameters_print_fp(FILE *fp, const EC_KEY *key);
+
+/** Prints out the contents of a EC_KEY object
+ *  \param  fp   file descriptor to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \param  off  line offset 
+ *  \return 1 on success and 0 if an error occurred
+ */
+int	EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);
+
 #endif
 
 #define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x)
@@ -362,6 +910,13 @@
 # endif
 #endif
 
+#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_PARAMGEN, \
+				EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL)
+
+
+#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID		(EVP_PKEY_ALG_CTRL + 1)
+
 /* 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.
@@ -375,6 +930,14 @@
 #define EC_F_D2I_ECPARAMETERS				 144
 #define EC_F_D2I_ECPKPARAMETERS				 145
 #define EC_F_D2I_ECPRIVATEKEY				 146
+#define EC_F_DO_EC_KEY_PRINT				 221
+#define EC_F_ECKEY_PARAM2TYPE				 223
+#define EC_F_ECKEY_PARAM_DECODE				 212
+#define EC_F_ECKEY_PRIV_DECODE				 213
+#define EC_F_ECKEY_PRIV_ENCODE				 214
+#define EC_F_ECKEY_PUB_DECODE				 215
+#define EC_F_ECKEY_PUB_ENCODE				 216
+#define EC_F_ECKEY_TYPE2PARAM				 220
 #define EC_F_ECPARAMETERS_PRINT				 147
 #define EC_F_ECPARAMETERS_PRINT_FP			 148
 #define EC_F_ECPKPARAMETERS_PRINT			 149
@@ -448,7 +1011,6 @@
 #define EC_F_EC_KEY_PRINT				 180
 #define EC_F_EC_KEY_PRINT_FP				 181
 #define EC_F_EC_POINTS_MAKE_AFFINE			 136
-#define EC_F_EC_POINTS_MUL				 138
 #define EC_F_EC_POINT_ADD				 112
 #define EC_F_EC_POINT_CMP				 113
 #define EC_F_EC_POINT_COPY				 114
@@ -479,21 +1041,31 @@
 #define EC_F_I2D_ECPRIVATEKEY				 192
 #define EC_F_I2O_ECPUBLICKEY				 151
 #define EC_F_O2I_ECPUBLICKEY				 152
+#define EC_F_OLD_EC_PRIV_DECODE				 222
+#define EC_F_PKEY_EC_CTRL				 197
+#define EC_F_PKEY_EC_CTRL_STR				 198
+#define EC_F_PKEY_EC_DERIVE				 217
+#define EC_F_PKEY_EC_KEYGEN				 199
+#define EC_F_PKEY_EC_PARAMGEN				 219
+#define EC_F_PKEY_EC_SIGN				 218
 
 /* Reason codes. */
 #define EC_R_ASN1_ERROR					 115
 #define EC_R_ASN1_UNKNOWN_FIELD				 116
 #define EC_R_BUFFER_TOO_SMALL				 100
 #define EC_R_D2I_ECPKPARAMETERS_FAILURE			 117
+#define EC_R_DECODE_ERROR				 142
 #define EC_R_DISCRIMINANT_IS_ZERO			 118
 #define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE		 119
-#define EC_R_FIELD_TOO_LARGE				 138
+#define EC_R_FIELD_TOO_LARGE				 143
 #define EC_R_GROUP2PKPARAMETERS_FAILURE			 120
 #define EC_R_I2D_ECPKPARAMETERS_FAILURE			 121
 #define EC_R_INCOMPATIBLE_OBJECTS			 101
 #define EC_R_INVALID_ARGUMENT				 112
 #define EC_R_INVALID_COMPRESSED_POINT			 110
 #define EC_R_INVALID_COMPRESSION_BIT			 109
+#define EC_R_INVALID_CURVE				 141
+#define EC_R_INVALID_DIGEST_TYPE			 138
 #define EC_R_INVALID_ENCODING				 102
 #define EC_R_INVALID_FIELD				 103
 #define EC_R_INVALID_FORM				 104
@@ -501,6 +1073,7 @@
 #define EC_R_INVALID_PENTANOMIAL_BASIS			 132
 #define EC_R_INVALID_PRIVATE_KEY			 123
 #define EC_R_INVALID_TRINOMIAL_BASIS			 137
+#define EC_R_KEYS_NOT_SET				 140
 #define EC_R_MISSING_PARAMETERS				 124
 #define EC_R_MISSING_PRIVATE_KEY			 125
 #define EC_R_NOT_A_NIST_PRIME				 135
@@ -508,6 +1081,7 @@
 #define EC_R_NOT_IMPLEMENTED				 126
 #define EC_R_NOT_INITIALIZED				 111
 #define EC_R_NO_FIELD_MOD				 133
+#define EC_R_NO_PARAMETERS_SET				 139
 #define EC_R_PASSED_NULL_PARAMETER			 134
 #define EC_R_PKPARAMETERS2GROUP_FAILURE			 127
 #define EC_R_POINT_AT_INFINITY				 106
diff --git a/crypto/ec/ec2_mult.c b/crypto/ec/ec2_mult.c
index ff368fd..ab631a5 100644
--- a/crypto/ec/ec2_mult.c
+++ b/crypto/ec/ec2_mult.c
@@ -76,7 +76,7 @@
  * coordinates.
  * Uses algorithm Mdouble in appendix of 
  *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
- *     GF(2^m) without precomputation".
+ *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
  * modified to not require precomputation of c=b^{2^{m-1}}.
  */
 static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, BN_CTX *ctx)
@@ -107,8 +107,8 @@
 /* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery 
  * projective coordinates.
  * Uses algorithm Madd in appendix of 
- *     Lopex, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
- *     GF(2^m) without precomputation".
+ *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
+ *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
  */
 static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, BIGNUM *z1, 
 	const BIGNUM *x2, const BIGNUM *z2, BN_CTX *ctx)
@@ -140,8 +140,8 @@
 
 /* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2) 
  * using Montgomery point multiplication algorithm Mxy() in appendix of 
- *     Lopex, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
- *     GF(2^m) without precomputation".
+ *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
+ *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
  * Returns:
  *     0 on error
  *     1 if return value should be the point at infinity
@@ -209,15 +209,15 @@
 /* Computes scalar*point and stores the result in r.
  * point can not equal r.
  * Uses algorithm 2P of
- *     Lopex, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
- *     GF(2^m) without precomputation".
+ *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
+ *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
  */
 static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
 	const EC_POINT *point, BN_CTX *ctx)
 	{
 	BIGNUM *x1, *x2, *z1, *z2;
-	int ret = 0, i, j;
-	BN_ULONG mask;
+	int ret = 0, i;
+	BN_ULONG mask,word;
 
 	if (r == point)
 		{
@@ -251,22 +251,24 @@
 	if (!BN_GF2m_add(x2, x2, &group->b)) goto err; /* x2 = x^4 + b */
 
 	/* find top most bit and go one past it */
-	i = scalar->top - 1; j = BN_BITS2 - 1;
+	i = scalar->top - 1;
 	mask = BN_TBIT;
-	while (!(scalar->d[i] & mask)) { mask >>= 1; j--; }
-	mask >>= 1; j--;
+	word = scalar->d[i];
+	while (!(word & mask)) mask >>= 1;
+	mask >>= 1;
 	/* if top most bit was at word break, go to next word */
 	if (!mask) 
 		{
-		i--; j = BN_BITS2 - 1;
+		i--;
 		mask = BN_TBIT;
 		}
 
 	for (; i >= 0; i--)
 		{
-		for (; j >= 0; j--)
+		word = scalar->d[i];
+		while (mask)
 			{
-			if (scalar->d[i] & mask)
+			if (word & mask)
 				{
 				if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err;
 				if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err;
@@ -278,7 +280,6 @@
 				}
 			mask >>= 1;
 			}
-		j = BN_BITS2 - 1;
 		mask = BN_TBIT;
 		}
 
diff --git a/crypto/ec/ec2_smpl.c b/crypto/ec/ec2_smpl.c
index 522d036..cf357b4 100644
--- a/crypto/ec/ec2_smpl.c
+++ b/crypto/ec/ec2_smpl.c
@@ -14,7 +14,7 @@
  *
  */
 /* ====================================================================
- * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -157,6 +157,7 @@
 	group->poly[2] = 0;
 	group->poly[3] = 0;
 	group->poly[4] = 0;
+	group->poly[5] = -1;
 	}
 
 
@@ -174,10 +175,9 @@
 	dest->poly[2] = src->poly[2];
 	dest->poly[3] = src->poly[3];
 	dest->poly[4] = src->poly[4];
-	if(bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL)
-		return 0;
-	if(bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL)
-		return 0;
+	dest->poly[5] = src->poly[5];
+	if (bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0;
+	if (bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0;
 	for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0;
 	for (i = dest->b.top; i < dest->b.dmax; i++) dest->b.d[i] = 0;
 	return 1;
@@ -192,7 +192,7 @@
 
 	/* group->field */
 	if (!BN_copy(&group->field, p)) goto err;
-	i = BN_GF2m_poly2arr(&group->field, group->poly, 5);
+	i = BN_GF2m_poly2arr(&group->field, group->poly, 6) - 1;
 	if ((i != 5) && (i != 3))
 		{
 		ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD);
@@ -406,18 +406,94 @@
 	}
 
 
-/* Include patented algorithms. */
-#include "ec2_smpt.c"
+/* Calculates and sets the affine coordinates of an EC_POINT from the given
+ * compressed coordinates.  Uses algorithm 2.3.4 of SEC 1. 
+ * Note that the simple implementation only uses affine coordinates.
+ *
+ * The method is from the following publication:
+ * 
+ *     Harper, Menezes, Vanstone:
+ *     "Public-Key Cryptosystems with Very Small Key Lengths",
+ *     EUROCRYPT '92, Springer-Verlag LNCS 658,
+ *     published February 1993
+ *
+ * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
+ * the same method, but claim no priority date earlier than July 29, 1994
+ * (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
+ */
+int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
+	const BIGNUM *x_, int y_bit, BN_CTX *ctx)
+	{
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *tmp, *x, *y, *z;
+	int ret = 0, z0;
+
+	/* clear error queue */
+	ERR_clear_error();
+
+	if (ctx == NULL)
+		{
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+		}
+
+	y_bit = (y_bit != 0) ? 1 : 0;
+
+	BN_CTX_start(ctx);
+	tmp = BN_CTX_get(ctx);
+	x = BN_CTX_get(ctx);
+	y = BN_CTX_get(ctx);
+	z = BN_CTX_get(ctx);
+	if (z == NULL) goto err;
+
+	if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err;
+	if (BN_is_zero(x))
+		{
+		if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err;
+		}
+	else
+		{
+		if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err;
+		if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err;
+		if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err;
+		if (!BN_GF2m_add(tmp, x, tmp)) goto err;
+		if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx))
+			{
+			unsigned long err = ERR_peek_last_error();
+			
+			if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION)
+				{
+				ERR_clear_error();
+				ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
+				}
+			else
+				ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
+			goto err;
+			}
+		z0 = (BN_is_odd(z)) ? 1 : 0;
+		if (!group->meth->field_mul(group, y, x, z, ctx)) goto err;
+		if (z0 != y_bit)
+			{
+			if (!BN_GF2m_add(y, y, x)) goto err;
+			}
+		}
+
+	if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
+
+	ret = 1;
+
+ err:
+	BN_CTX_end(ctx);
+	if (new_ctx != NULL)
+		BN_CTX_free(new_ctx);
+	return ret;
+	}
 
 
 /* Converts an EC_POINT to an octet string.  
  * If buf is NULL, the encoded length will be returned.
  * If the length len of buf is smaller than required an error will be returned.
- *
- * The point compression section of this function is patented by Certicom Corp. 
- * under US Patent 6,141,420.  Point compression is disabled by default and can 
- * be enabled by defining the preprocessor macro OPENSSL_EC_BIN_PT_COMP at 
- * Configure-time.
  */
 size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
 	unsigned char *buf, size_t len, BN_CTX *ctx)
@@ -428,14 +504,6 @@
 	BIGNUM *x, *y, *yxi;
 	size_t field_len, i, skip;
 
-#ifndef OPENSSL_EC_BIN_PT_COMP
-	if ((form == POINT_CONVERSION_COMPRESSED) || (form == POINT_CONVERSION_HYBRID)) 
-		{
-		ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_DISABLED);
-		goto err;
-		}
-#endif
-
 	if ((form != POINT_CONVERSION_COMPRESSED)
 		&& (form != POINT_CONVERSION_UNCOMPRESSED)
 		&& (form != POINT_CONVERSION_HYBRID))
@@ -490,13 +558,11 @@
 		if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
 
 		buf[0] = form;
-#ifdef OPENSSL_EC_BIN_PT_COMP
 		if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x))
 			{
 			if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
 			if (BN_is_odd(yxi)) buf[0]++;
 			}
-#endif
 
 		i = 1;
 		
diff --git a/crypto/ec/ec2_smpt.c b/crypto/ec/ec2_smpt.c
deleted file mode 100644
index 72a8d57..0000000
--- a/crypto/ec/ec2_smpt.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/* crypto/ec/ec2_smpt.c */
-/* This code was originally written by Douglas Stebila 
- * <dstebila@student.math.uwaterloo.ca> for the OpenSSL project.
- */
-/* ====================================================================
- * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-
-/* Calaculates and sets the affine coordinates of an EC_POINT from the given
- * compressed coordinates.  Uses algorithm 2.3.4 of SEC 1. 
- * Note that the simple implementation only uses affine coordinates.
- *
- * This algorithm is patented by Certicom Corp. under US Patent 6,141,420
- * (for licensing information, contact licensing@certicom.com).
- * This function is disabled by default and can be enabled by defining the 
- * preprocessor macro OPENSSL_EC_BIN_PT_COMP at Configure-time.
- */
-int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
-	const BIGNUM *x_, int y_bit, BN_CTX *ctx)
-	{
-#ifndef OPENSSL_EC_BIN_PT_COMP	
-	ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_DISABLED);
-	return 0;
-#else
-	BN_CTX *new_ctx = NULL;
-	BIGNUM *tmp, *x, *y, *z;
-	int ret = 0, z0;
-
-	/* clear error queue */
-	ERR_clear_error();
-
-	if (ctx == NULL)
-		{
-		ctx = new_ctx = BN_CTX_new();
-		if (ctx == NULL)
-			return 0;
-		}
-
-	y_bit = (y_bit != 0) ? 1 : 0;
-
-	BN_CTX_start(ctx);
-	tmp = BN_CTX_get(ctx);
-	x = BN_CTX_get(ctx);
-	y = BN_CTX_get(ctx);
-	z = BN_CTX_get(ctx);
-	if (z == NULL) goto err;
-
-	if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err;
-	if (BN_is_zero(x))
-		{
-		if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err;
-		}
-	else
-		{
-		if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err;
-		if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err;
-		if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err;
-		if (!BN_GF2m_add(tmp, x, tmp)) goto err;
-		if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx))
-			{
-			unsigned long err = ERR_peek_last_error();
-			
-			if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION)
-				{
-				ERR_clear_error();
-				ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
-				}
-			else
-				ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
-			goto err;
-			}
-		z0 = (BN_is_odd(z)) ? 1 : 0;
-		if (!group->meth->field_mul(group, y, x, z, ctx)) goto err;
-		if (z0 != y_bit)
-			{
-			if (!BN_GF2m_add(y, y, x)) goto err;
-			}
-		}
-
-	if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
-
-	ret = 1;
-
- err:
-	BN_CTX_end(ctx);
-	if (new_ctx != NULL)
-		BN_CTX_free(new_ctx);
-	return ret;
-#endif
-	}
diff --git a/crypto/ec/ec_curve.c b/crypto/ec/ec_curve.c
index beac209..23274e4 100644
--- a/crypto/ec/ec_curve.c
+++ b/crypto/ec/ec_curve.c
@@ -73,926 +73,1690 @@
 #include <openssl/err.h>
 #include <openssl/obj_mac.h>
 
-typedef struct ec_curve_data_st {
-	int	field_type;	/* either NID_X9_62_prime_field or
+typedef struct {
+	int	field_type,	/* either NID_X9_62_prime_field or
 				 * NID_X9_62_characteristic_two_field */
-	const char *p;		/* either a prime number or a polynomial */
-	const char *a;
-	const char *b;
-	const char *x;		/* the x coordinate of the generator */
-	const char *y;		/* the y coordinate of the generator */
-	const char *order;	/* the order of the group generated by the
-				 * generator */
-	const BN_ULONG cofactor;/* the cofactor */
-	const unsigned char *seed;/* the seed (optional) */
-	size_t	seed_len;
-	const char *comment;	/* a short description of the curve */
+		seed_len,
+		param_len;
+	unsigned int cofactor;	/* promoted to BN_ULONG */
 } EC_CURVE_DATA;
 
 /* the nist prime curves */
-static const unsigned char _EC_NIST_PRIME_192_SEED[] = {
-	0x30,0x45,0xAE,0x6F,0xC8,0x42,0x2F,0x64,0xED,0x57,
-	0x95,0x28,0xD3,0x81,0x20,0xEA,0xE1,0x21,0x96,0xD5};
-static const EC_CURVE_DATA _EC_NIST_PRIME_192 = {
-	NID_X9_62_prime_field,
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
-	"64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
-	"188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
-	"07192b95ffc8da78631011ed6b24cdd573f977a11e794811",
-	"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",1,
-	_EC_NIST_PRIME_192_SEED, 20,
-	"NIST/X9.62/SECG curve over a 192 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
+	_EC_NIST_PRIME_192 = {
+	{ NID_X9_62_prime_field,20,24,1 },
+	{ 0x30,0x45,0xAE,0x6F,0xC8,0x42,0x2F,0x64,0xED,0x57,	/* seed */
+	  0x95,0x28,0xD3,0x81,0x20,0xEA,0xE1,0x21,0x96,0xD5,
+
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFC,
+	  0x64,0x21,0x05,0x19,0xE5,0x9C,0x80,0xE7,0x0F,0xA7,	/* b */
+	  0xE9,0xAB,0x72,0x24,0x30,0x49,0xFE,0xB8,0xDE,0xEC,
+	  0xC1,0x46,0xB9,0xB1,
+	  0x18,0x8D,0xA8,0x0E,0xB0,0x30,0x90,0xF6,0x7C,0xBF,	/* x */
+	  0x20,0xEB,0x43,0xA1,0x88,0x00,0xF4,0xFF,0x0A,0xFD,
+	  0x82,0xFF,0x10,0x12,
+	  0x07,0x19,0x2b,0x95,0xff,0xc8,0xda,0x78,0x63,0x10,	/* y */
+	  0x11,0xed,0x6b,0x24,0xcd,0xd5,0x73,0xf9,0x77,0xa1,
+	  0x1e,0x79,0x48,0x11,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0x99,0xDE,0xF8,0x36,0x14,0x6B,0xC9,0xB1,
+	  0xB4,0xD2,0x28,0x31 }
 	};
 
-static const unsigned char _EC_NIST_PRIME_224_SEED[] = {
-	0xBD,0x71,0x34,0x47,0x99,0xD5,0xC7,0xFC,0xDC,0x45,
-	0xB5,0x9F,0xA3,0xB9,0xAB,0x8F,0x6A,0x94,0x8B,0xC5};
-static const EC_CURVE_DATA _EC_NIST_PRIME_224 = {
-	NID_X9_62_prime_field,
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
-	"B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
-	"B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
-	"bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",1,
-	_EC_NIST_PRIME_224_SEED, 20,
-	"NIST/SECG curve over a 224 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+28*6]; }
+	_EC_NIST_PRIME_224 = {
+	{ NID_X9_62_prime_field,20,28,1 },
+	{ 0xBD,0x71,0x34,0x47,0x99,0xD5,0xC7,0xFC,0xDC,0x45,	/* seed */
+	  0xB5,0x9F,0xA3,0xB9,0xAB,0x8F,0x6A,0x94,0x8B,0xC5,
+
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
+	  0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41,	/* b */
+	  0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA,
+	  0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4,
+	  0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13,	/* x */
+	  0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22,
+	  0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21,
+	  0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22,	/* y */
+	  0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64,
+	  0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0x16,0xA2,0xE0,0xB8,0xF0,0x3E,
+	  0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D }
 	};
 
-static const unsigned char _EC_NIST_PRIME_384_SEED[] = {
-	0xA3,0x35,0x92,0x6A,0xA3,0x19,0xA2,0x7A,0x1D,0x00,
-	0x89,0x6A,0x67,0x73,0xA4,0x82,0x7A,0xCD,0xAC,0x73};
-static const EC_CURVE_DATA _EC_NIST_PRIME_384 = {
-	NID_X9_62_prime_field,
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFF"
-	"FFF0000000000000000FFFFFFFF",
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFF"
-	"FFF0000000000000000FFFFFFFC",
-	"B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC6563"
-	"98D8A2ED19D2A85C8EDD3EC2AEF",
-	"AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F"
-	"25DBF55296C3A545E3872760AB7",
-	"3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b"
-	"1ce1d7e819d7a431d7c90ea0e5f",
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0"
-	"DB248B0A77AECEC196ACCC52973",1,
-	_EC_NIST_PRIME_384_SEED, 20,
-	"NIST/SECG curve over a 384 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+48*6]; }
+	_EC_NIST_PRIME_384 = {
+	{ NID_X9_62_prime_field,20,48,1 },
+	{ 0xA3,0x35,0x92,0x6A,0xA3,0x19,0xA2,0x7A,0x1D,0x00,	/* seed */
+	  0x89,0x6A,0x67,0x73,0xA4,0x82,0x7A,0xCD,0xAC,0x73,
+
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFC,
+	  0xB3,0x31,0x2F,0xA7,0xE2,0x3E,0xE7,0xE4,0x98,0x8E,	/* b */
+	  0x05,0x6B,0xE3,0xF8,0x2D,0x19,0x18,0x1D,0x9C,0x6E,
+	  0xFE,0x81,0x41,0x12,0x03,0x14,0x08,0x8F,0x50,0x13,
+	  0x87,0x5A,0xC6,0x56,0x39,0x8D,0x8A,0x2E,0xD1,0x9D,
+	  0x2A,0x85,0xC8,0xED,0xD3,0xEC,0x2A,0xEF,
+	  0xAA,0x87,0xCA,0x22,0xBE,0x8B,0x05,0x37,0x8E,0xB1,	/* x */
+	  0xC7,0x1E,0xF3,0x20,0xAD,0x74,0x6E,0x1D,0x3B,0x62,
+	  0x8B,0xA7,0x9B,0x98,0x59,0xF7,0x41,0xE0,0x82,0x54,
+	  0x2A,0x38,0x55,0x02,0xF2,0x5D,0xBF,0x55,0x29,0x6C,
+	  0x3A,0x54,0x5E,0x38,0x72,0x76,0x0A,0xB7,
+	  0x36,0x17,0xde,0x4a,0x96,0x26,0x2c,0x6f,0x5d,0x9e,	/* y */
+	  0x98,0xbf,0x92,0x92,0xdc,0x29,0xf8,0xf4,0x1d,0xbd,
+	  0x28,0x9a,0x14,0x7c,0xe9,0xda,0x31,0x13,0xb5,0xf0,
+	  0xb8,0xc0,0x0a,0x60,0xb1,0xce,0x1d,0x7e,0x81,0x9d,
+	  0x7a,0x43,0x1d,0x7c,0x90,0xea,0x0e,0x5f,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xC7,0x63,0x4D,0x81,0xF4,0x37,
+	  0x2D,0xDF,0x58,0x1A,0x0D,0xB2,0x48,0xB0,0xA7,0x7A,
+	  0xEC,0xEC,0x19,0x6A,0xCC,0xC5,0x29,0x73 }
 	};
 
-static const unsigned char _EC_NIST_PRIME_521_SEED[] = {
-	0xD0,0x9E,0x88,0x00,0x29,0x1C,0xB8,0x53,0x96,0xCC,
-	0x67,0x17,0x39,0x32,0x84,0xAA,0xA0,0xDA,0x64,0xBA};
-static const EC_CURVE_DATA _EC_NIST_PRIME_521 = {
-	NID_X9_62_prime_field,
-	"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
-	"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
-	"051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156"
-	"193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
-	"C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14"
-	"B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
-	"011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c9"
-	"7ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
-	"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51"
-	"868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",1,
-	_EC_NIST_PRIME_521_SEED, 20,
-	"NIST/SECG curve over a 521 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+66*6]; }
+	_EC_NIST_PRIME_521 = {
+	{ NID_X9_62_prime_field,20,66,1 },
+	{ 0xD0,0x9E,0x88,0x00,0x29,0x1C,0xB8,0x53,0x96,0xCC,	/* seed */
+	  0x67,0x17,0x39,0x32,0x84,0xAA,0xA0,0xDA,0x64,0xBA,
+
+	  0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,
+	  0x00,0x51,0x95,0x3E,0xB9,0x61,0x8E,0x1C,0x9A,0x1F,	/* b */
+	  0x92,0x9A,0x21,0xA0,0xB6,0x85,0x40,0xEE,0xA2,0xDA,
+	  0x72,0x5B,0x99,0xB3,0x15,0xF3,0xB8,0xB4,0x89,0x91,
+	  0x8E,0xF1,0x09,0xE1,0x56,0x19,0x39,0x51,0xEC,0x7E,
+	  0x93,0x7B,0x16,0x52,0xC0,0xBD,0x3B,0xB1,0xBF,0x07,
+	  0x35,0x73,0xDF,0x88,0x3D,0x2C,0x34,0xF1,0xEF,0x45,
+	  0x1F,0xD4,0x6B,0x50,0x3F,0x00,
+	  0x00,0xC6,0x85,0x8E,0x06,0xB7,0x04,0x04,0xE9,0xCD,	/* x */
+	  0x9E,0x3E,0xCB,0x66,0x23,0x95,0xB4,0x42,0x9C,0x64,
+	  0x81,0x39,0x05,0x3F,0xB5,0x21,0xF8,0x28,0xAF,0x60,
+	  0x6B,0x4D,0x3D,0xBA,0xA1,0x4B,0x5E,0x77,0xEF,0xE7,
+	  0x59,0x28,0xFE,0x1D,0xC1,0x27,0xA2,0xFF,0xA8,0xDE,
+	  0x33,0x48,0xB3,0xC1,0x85,0x6A,0x42,0x9B,0xF9,0x7E,
+	  0x7E,0x31,0xC2,0xE5,0xBD,0x66,
+	  0x01,0x18,0x39,0x29,0x6a,0x78,0x9a,0x3b,0xc0,0x04,	/* y */
+	  0x5c,0x8a,0x5f,0xb4,0x2c,0x7d,0x1b,0xd9,0x98,0xf5,
+	  0x44,0x49,0x57,0x9b,0x44,0x68,0x17,0xaf,0xbd,0x17,
+	  0x27,0x3e,0x66,0x2c,0x97,0xee,0x72,0x99,0x5e,0xf4,
+	  0x26,0x40,0xc5,0x50,0xb9,0x01,0x3f,0xad,0x07,0x61,
+	  0x35,0x3c,0x70,0x86,0xa2,0x72,0xc2,0x40,0x88,0xbe,
+	  0x94,0x76,0x9f,0xd1,0x66,0x50,
+	  0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFA,0x51,0x86,0x87,0x83,0xBF,0x2F,
+	  0x96,0x6B,0x7F,0xCC,0x01,0x48,0xF7,0x09,0xA5,0xD0,
+	  0x3B,0xB5,0xC9,0xB8,0x89,0x9C,0x47,0xAE,0xBB,0x6F,
+	  0xB7,0x1E,0x91,0x38,0x64,0x09 }
 	};
+
 /* the x9.62 prime curves (minus the nist prime curves) */
-static const unsigned char _EC_X9_62_PRIME_192V2_SEED[] = {
-	0x31,0xA9,0x2E,0xE2,0x02,0x9F,0xD1,0x0D,0x90,0x1B,
-	0x11,0x3E,0x99,0x07,0x10,0xF0,0xD2,0x1A,0xC6,0xB6};
-static const EC_CURVE_DATA _EC_X9_62_PRIME_192V2 = {
-	NID_X9_62_prime_field,
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
-	"CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953",
-	"EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A",
-	"6574d11d69b6ec7a672bb82a083df2f2b0847de970b2de15",
-	"FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31",1,
-	_EC_X9_62_PRIME_192V2_SEED, 20,
-	"X9.62 curve over a 192 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
+	_EC_X9_62_PRIME_192V2 = {
+	{ NID_X9_62_prime_field,20,24,1 },
+	{ 0x31,0xA9,0x2E,0xE2,0x02,0x9F,0xD1,0x0D,0x90,0x1B,	/* seed */
+	  0x11,0x3E,0x99,0x07,0x10,0xF0,0xD2,0x1A,0xC6,0xB6,
+
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFC,
+	  0xCC,0x22,0xD6,0xDF,0xB9,0x5C,0x6B,0x25,0xE4,0x9C,	/* b */
+	  0x0D,0x63,0x64,0xA4,0xE5,0x98,0x0C,0x39,0x3A,0xA2,
+	  0x16,0x68,0xD9,0x53,
+	  0xEE,0xA2,0xBA,0xE7,0xE1,0x49,0x78,0x42,0xF2,0xDE,	/* x */
+	  0x77,0x69,0xCF,0xE9,0xC9,0x89,0xC0,0x72,0xAD,0x69,
+	  0x6F,0x48,0x03,0x4A,
+	  0x65,0x74,0xd1,0x1d,0x69,0xb6,0xec,0x7a,0x67,0x2b,	/* y */
+	  0xb8,0x2a,0x08,0x3d,0xf2,0xf2,0xb0,0x84,0x7d,0xe9,
+	  0x70,0xb2,0xde,0x15,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFE,0x5F,0xB1,0xA7,0x24,0xDC,0x80,0x41,0x86,
+	  0x48,0xD8,0xDD,0x31 }
 	};
 
-static const unsigned char _EC_X9_62_PRIME_192V3_SEED[] = {
-	0xC4,0x69,0x68,0x44,0x35,0xDE,0xB3,0x78,0xC4,0xB6,
-	0x5C,0xA9,0x59,0x1E,0x2A,0x57,0x63,0x05,0x9A,0x2E};
-static const EC_CURVE_DATA _EC_X9_62_PRIME_192V3 = {
-	NID_X9_62_prime_field,
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
-	"22123DC2395A05CAA7423DAECCC94760A7D462256BD56916",
-	"7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896",
-	"38a90f22637337334b49dcb66a6dc8f9978aca7648a943b0",
-	"FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13",1,
-	_EC_X9_62_PRIME_192V3_SEED, 20,
-	"X9.62 curve over a 192 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
+	_EC_X9_62_PRIME_192V3 = {
+	{ NID_X9_62_prime_field,20,24,1 },
+	{ 0xC4,0x69,0x68,0x44,0x35,0xDE,0xB3,0x78,0xC4,0xB6,	/* seed */
+	  0x5C,0xA9,0x59,0x1E,0x2A,0x57,0x63,0x05,0x9A,0x2E,
+
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFC,
+	  0x22,0x12,0x3D,0xC2,0x39,0x5A,0x05,0xCA,0xA7,0x42,	/* b */
+	  0x3D,0xAE,0xCC,0xC9,0x47,0x60,0xA7,0xD4,0x62,0x25,
+	  0x6B,0xD5,0x69,0x16,
+	  0x7D,0x29,0x77,0x81,0x00,0xC6,0x5A,0x1D,0xA1,0x78,	/* x */
+	  0x37,0x16,0x58,0x8D,0xCE,0x2B,0x8B,0x4A,0xEE,0x8E,
+	  0x22,0x8F,0x18,0x96,
+	  0x38,0xa9,0x0f,0x22,0x63,0x73,0x37,0x33,0x4b,0x49,	/* y */
+	  0xdc,0xb6,0x6a,0x6d,0xc8,0xf9,0x97,0x8a,0xca,0x76,
+	  0x48,0xa9,0x43,0xb0,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0x7A,0x62,0xD0,0x31,0xC8,0x3F,0x42,0x94,
+	  0xF6,0x40,0xEC,0x13 }
 	};
 
-static const unsigned char _EC_X9_62_PRIME_239V1_SEED[] = {
-	0xE4,0x3B,0xB4,0x60,0xF0,0xB8,0x0C,0xC0,0xC0,0xB0,
-	0x75,0x79,0x8E,0x94,0x80,0x60,0xF8,0x32,0x1B,0x7D};
-static const EC_CURVE_DATA _EC_X9_62_PRIME_239V1 = {
-	NID_X9_62_prime_field,
-	"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
-	"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
-	"6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A",
-	"0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF",
-	"7debe8e4e90a5dae6e4054ca530ba04654b36818ce226b39fccb7b02f1ae",
-	"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B",1,
-	_EC_X9_62_PRIME_239V1_SEED, 20,
-	"X9.62 curve over a 239 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
+	_EC_X9_62_PRIME_239V1 = {
+	{ NID_X9_62_prime_field,20,30,1 },
+	{ 0xE4,0x3B,0xB4,0x60,0xF0,0xB8,0x0C,0xC0,0xC0,0xB0,	/* seed */
+	  0x75,0x79,0x8E,0x94,0x80,0x60,0xF8,0x32,0x1B,0x7D,
+
+	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
+	  0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
+
+	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
+	  0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,
+
+	  0x6B,0x01,0x6C,0x3B,0xDC,0xF1,0x89,0x41,0xD0,0xD6,	/* b */
+	  0x54,0x92,0x14,0x75,0xCA,0x71,0xA9,0xDB,0x2F,0xB2,
+	  0x7D,0x1D,0x37,0x79,0x61,0x85,0xC2,0x94,0x2C,0x0A,
+
+	  0x0F,0xFA,0x96,0x3C,0xDC,0xA8,0x81,0x6C,0xCC,0x33,	/* x */
+	  0xB8,0x64,0x2B,0xED,0xF9,0x05,0xC3,0xD3,0x58,0x57,
+	  0x3D,0x3F,0x27,0xFB,0xBD,0x3B,0x3C,0xB9,0xAA,0xAF,
+
+	  0x7d,0xeb,0xe8,0xe4,0xe9,0x0a,0x5d,0xae,0x6e,0x40,	/* y */
+	  0x54,0xca,0x53,0x0b,0xa0,0x46,0x54,0xb3,0x68,0x18,
+	  0xce,0x22,0x6b,0x39,0xfc,0xcb,0x7b,0x02,0xf1,0xae,
+
+	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0x7F,0xFF,0xFF,0x9E,0x5E,0x9A,0x9F,0x5D,
+	  0x90,0x71,0xFB,0xD1,0x52,0x26,0x88,0x90,0x9D,0x0B }
 	};
 
-static const unsigned char _EC_X9_62_PRIME_239V2_SEED[] = {
-	0xE8,0xB4,0x01,0x16,0x04,0x09,0x53,0x03,0xCA,0x3B,
-	0x80,0x99,0x98,0x2B,0xE0,0x9F,0xCB,0x9A,0xE6,0x16};
-static const EC_CURVE_DATA _EC_X9_62_PRIME_239V2 = {
-	NID_X9_62_prime_field,
-	"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
-	"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
-	"617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C",
-	"38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7",
-	"5b0125e4dbea0ec7206da0fc01d9b081329fb555de6ef460237dff8be4ba",
-	"7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063",1,
-	_EC_X9_62_PRIME_239V2_SEED, 20,
-	"X9.62 curve over a 239 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
+	_EC_X9_62_PRIME_239V2 = {
+	{ NID_X9_62_prime_field,20,30,1 },
+	{ 0xE8,0xB4,0x01,0x16,0x04,0x09,0x53,0x03,0xCA,0x3B,	/* seed */
+	  0x80,0x99,0x98,0x2B,0xE0,0x9F,0xCB,0x9A,0xE6,0x16,
+
+	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
+	  0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
+
+	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
+	  0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,
+
+	  0x61,0x7F,0xAB,0x68,0x32,0x57,0x6C,0xBB,0xFE,0xD5,	/* b */
+	  0x0D,0x99,0xF0,0x24,0x9C,0x3F,0xEE,0x58,0xB9,0x4B,
+	  0xA0,0x03,0x8C,0x7A,0xE8,0x4C,0x8C,0x83,0x2F,0x2C,
+
+	  0x38,0xAF,0x09,0xD9,0x87,0x27,0x70,0x51,0x20,0xC9,	/* x */
+	  0x21,0xBB,0x5E,0x9E,0x26,0x29,0x6A,0x3C,0xDC,0xF2,
+	  0xF3,0x57,0x57,0xA0,0xEA,0xFD,0x87,0xB8,0x30,0xE7,
+
+	  0x5b,0x01,0x25,0xe4,0xdb,0xea,0x0e,0xc7,0x20,0x6d,	/* y */
+	  0xa0,0xfc,0x01,0xd9,0xb0,0x81,0x32,0x9f,0xb5,0x55,
+	  0xde,0x6e,0xf4,0x60,0x23,0x7d,0xff,0x8b,0xe4,0xba,
+
+	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0x80,0x00,0x00,0xCF,0xA7,0xE8,0x59,0x43,
+	  0x77,0xD4,0x14,0xC0,0x38,0x21,0xBC,0x58,0x20,0x63 }
 	};
 
-static const unsigned char _EC_X9_62_PRIME_239V3_SEED[] = {
-	0x7D,0x73,0x74,0x16,0x8F,0xFE,0x34,0x71,0xB6,0x0A,
-	0x85,0x76,0x86,0xA1,0x94,0x75,0xD3,0xBF,0xA2,0xFF};
-static const EC_CURVE_DATA _EC_X9_62_PRIME_239V3 = {
-	NID_X9_62_prime_field,
-	"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
-	"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
-	"255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E",
-	"6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A",
-	"1607e6898f390c06bc1d552bad226f3b6fcfe48b6e818499af18e3ed6cf3",
-	"7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551",1,
-	_EC_X9_62_PRIME_239V3_SEED, 20,
-	"X9.62 curve over a 239 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
+	_EC_X9_62_PRIME_239V3 = {
+	{ NID_X9_62_prime_field,20,30,1 },
+	{ 0x7D,0x73,0x74,0x16,0x8F,0xFE,0x34,0x71,0xB6,0x0A,	/* seed */
+	  0x85,0x76,0x86,0xA1,0x94,0x75,0xD3,0xBF,0xA2,0xFF,
+
+	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
+	  0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,
+
+	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
+	  0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFC,
+
+	  0x25,0x57,0x05,0xFA,0x2A,0x30,0x66,0x54,0xB1,0xF4,	/* b */
+	  0xCB,0x03,0xD6,0xA7,0x50,0xA3,0x0C,0x25,0x01,0x02,
+	  0xD4,0x98,0x87,0x17,0xD9,0xBA,0x15,0xAB,0x6D,0x3E,
+
+	  0x67,0x68,0xAE,0x8E,0x18,0xBB,0x92,0xCF,0xCF,0x00,	/* x */
+	  0x5C,0x94,0x9A,0xA2,0xC6,0xD9,0x48,0x53,0xD0,0xE6,
+	  0x60,0xBB,0xF8,0x54,0xB1,0xC9,0x50,0x5F,0xE9,0x5A,
+
+	  0x16,0x07,0xe6,0x89,0x8f,0x39,0x0c,0x06,0xbc,0x1d,	/* y */
+	  0x55,0x2b,0xad,0x22,0x6f,0x3b,0x6f,0xcf,0xe4,0x8b,
+	  0x6e,0x81,0x84,0x99,0xaf,0x18,0xe3,0xed,0x6c,0xf3,
+
+	  0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0x7F,0xFF,0xFF,0x97,0x5D,0xEB,0x41,0xB3,
+	  0xA6,0x05,0x7C,0x3C,0x43,0x21,0x46,0x52,0x65,0x51 }
 	};
 
-static const unsigned char _EC_X9_62_PRIME_256V1_SEED[] = {
-	0xC4,0x9D,0x36,0x08,0x86,0xE7,0x04,0x93,0x6A,0x66,
-	0x78,0xE1,0x13,0x9D,0x26,0xB7,0x81,0x9F,0x7E,0x90};
-static const EC_CURVE_DATA _EC_X9_62_PRIME_256V1 = {
-	NID_X9_62_prime_field,
-	"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
-	"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
-	"5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
-	"6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
-	"4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
-	"FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",1,
-	_EC_X9_62_PRIME_256V1_SEED, 20,
-	"X9.62/SECG curve over a 256 bit prime field"
+
+static const struct { EC_CURVE_DATA h; unsigned char data[20+32*6]; }
+	_EC_X9_62_PRIME_256V1 = {
+	{ NID_X9_62_prime_field,20,32,1 },
+	{ 0xC4,0x9D,0x36,0x08,0x86,0xE7,0x04,0x93,0x6A,0x66,	/* seed */
+	  0x78,0xE1,0x13,0x9D,0x26,0xB7,0x81,0x9F,0x7E,0x90,
+
+	  0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFC,
+	  0x5A,0xC6,0x35,0xD8,0xAA,0x3A,0x93,0xE7,0xB3,0xEB,	/* b */
+	  0xBD,0x55,0x76,0x98,0x86,0xBC,0x65,0x1D,0x06,0xB0,
+	  0xCC,0x53,0xB0,0xF6,0x3B,0xCE,0x3C,0x3E,0x27,0xD2,
+	  0x60,0x4B,
+	  0x6B,0x17,0xD1,0xF2,0xE1,0x2C,0x42,0x47,0xF8,0xBC,	/* x */
+	  0xE6,0xE5,0x63,0xA4,0x40,0xF2,0x77,0x03,0x7D,0x81,
+	  0x2D,0xEB,0x33,0xA0,0xF4,0xA1,0x39,0x45,0xD8,0x98,
+	  0xC2,0x96,
+	  0x4f,0xe3,0x42,0xe2,0xfe,0x1a,0x7f,0x9b,0x8e,0xe7,	/* y */
+	  0xeb,0x4a,0x7c,0x0f,0x9e,0x16,0x2b,0xce,0x33,0x57,
+	  0x6b,0x31,0x5e,0xce,0xcb,0xb6,0x40,0x68,0x37,0xbf,
+	  0x51,0xf5,
+	  0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBC,0xE6,0xFA,0xAD,
+	  0xA7,0x17,0x9E,0x84,0xF3,0xB9,0xCA,0xC2,0xFC,0x63,
+	  0x25,0x51 }
 	};
+
 /* the secg prime curves (minus the nist and x9.62 prime curves) */
-static const unsigned char _EC_SECG_PRIME_112R1_SEED[] = {
-	0x00,0xF5,0x0B,0x02,0x8E,0x4D,0x69,0x6E,0x67,0x68,
-	0x75,0x61,0x51,0x75,0x29,0x04,0x72,0x78,0x3F,0xB1};
-static const EC_CURVE_DATA _EC_SECG_PRIME_112R1 = {
-	NID_X9_62_prime_field,
-	"DB7C2ABF62E35E668076BEAD208B",
-	"DB7C2ABF62E35E668076BEAD2088",
-	"659EF8BA043916EEDE8911702B22",
-	"09487239995A5EE76B55F9C2F098",
-	"a89ce5af8724c0a23e0e0ff77500",
-	"DB7C2ABF62E35E7628DFAC6561C5",1,
-	_EC_SECG_PRIME_112R1_SEED, 20,
-	"SECG/WTLS curve over a 112 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+14*6]; }
+	_EC_SECG_PRIME_112R1 = {
+	{ NID_X9_62_prime_field,20,14,1 },
+	{ 0x00,0xF5,0x0B,0x02,0x8E,0x4D,0x69,0x6E,0x67,0x68,	/* seed */
+	  0x75,0x61,0x51,0x75,0x29,0x04,0x72,0x78,0x3F,0xB1,
+
+	  0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76,	/* p */
+	  0xBE,0xAD,0x20,0x8B,
+	  0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76,	/* a */
+	  0xBE,0xAD,0x20,0x88,
+	  0x65,0x9E,0xF8,0xBA,0x04,0x39,0x16,0xEE,0xDE,0x89,	/* b */
+	  0x11,0x70,0x2B,0x22,
+	  0x09,0x48,0x72,0x39,0x99,0x5A,0x5E,0xE7,0x6B,0x55,	/* x */
+	  0xF9,0xC2,0xF0,0x98,
+	  0xa8,0x9c,0xe5,0xaf,0x87,0x24,0xc0,0xa2,0x3e,0x0e,	/* y */
+	  0x0f,0xf7,0x75,0x00,
+	  0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x76,0x28,0xDF,	/* order */
+	  0xAC,0x65,0x61,0xC5 }
 	};
 
-static const unsigned char _EC_SECG_PRIME_112R2_SEED[] = {
-	0x00,0x27,0x57,0xA1,0x11,0x4D,0x69,0x6E,0x67,0x68,
-	0x75,0x61,0x51,0x75,0x53,0x16,0xC0,0x5E,0x0B,0xD4};
-static const EC_CURVE_DATA _EC_SECG_PRIME_112R2 = {
-	NID_X9_62_prime_field,
-	"DB7C2ABF62E35E668076BEAD208B",
-	"6127C24C05F38A0AAAF65C0EF02C",
-	"51DEF1815DB5ED74FCC34C85D709",
-	"4BA30AB5E892B4E1649DD0928643",
-	"adcd46f5882e3747def36e956e97",
-	"36DF0AAFD8B8D7597CA10520D04B",4, 
-	_EC_SECG_PRIME_112R2_SEED, 20,
-	"SECG curve over a 112 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+14*6]; }
+	_EC_SECG_PRIME_112R2 = {
+	{ NID_X9_62_prime_field,20,14,4 },
+	{ 0x00,0x27,0x57,0xA1,0x11,0x4D,0x69,0x6E,0x67,0x68,	/* seed */
+	  0x75,0x61,0x51,0x75,0x53,0x16,0xC0,0x5E,0x0B,0xD4,
+
+	  0xDB,0x7C,0x2A,0xBF,0x62,0xE3,0x5E,0x66,0x80,0x76,	/* p */
+	  0xBE,0xAD,0x20,0x8B,
+	  0x61,0x27,0xC2,0x4C,0x05,0xF3,0x8A,0x0A,0xAA,0xF6,	/* a */
+	  0x5C,0x0E,0xF0,0x2C,
+	  0x51,0xDE,0xF1,0x81,0x5D,0xB5,0xED,0x74,0xFC,0xC3,	/* b */
+	  0x4C,0x85,0xD7,0x09,
+	  0x4B,0xA3,0x0A,0xB5,0xE8,0x92,0xB4,0xE1,0x64,0x9D,	/* x */
+	  0xD0,0x92,0x86,0x43,
+	  0xad,0xcd,0x46,0xf5,0x88,0x2e,0x37,0x47,0xde,0xf3,	/* y */
+	  0x6e,0x95,0x6e,0x97,
+	  0x36,0xDF,0x0A,0xAF,0xD8,0xB8,0xD7,0x59,0x7C,0xA1,	/* order */
+	  0x05,0x20,0xD0,0x4B }
 	};
 
-static const unsigned char _EC_SECG_PRIME_128R1_SEED[] = {
-	0x00,0x0E,0x0D,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,
-	0x51,0x75,0x0C,0xC0,0x3A,0x44,0x73,0xD0,0x36,0x79};
-static const EC_CURVE_DATA _EC_SECG_PRIME_128R1 = {
-	NID_X9_62_prime_field,
-	"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
-	"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC",
-	"E87579C11079F43DD824993C2CEE5ED3",
-	"161FF7528B899B2D0C28607CA52C5B86",
-	"cf5ac8395bafeb13c02da292dded7a83",
-	"FFFFFFFE0000000075A30D1B9038A115",1,
-	_EC_SECG_PRIME_128R1_SEED, 20,
-	"SECG curve over a 128 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+16*6]; }
+	_EC_SECG_PRIME_128R1 = {
+	{ NID_X9_62_prime_field,20,16,1 },
+	{ 0x00,0x0E,0x0D,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,	/* seed */
+	  0x51,0x75,0x0C,0xC0,0x3A,0x44,0x73,0xD0,0x36,0x79,
+
+	  0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,
+	  0xE8,0x75,0x79,0xC1,0x10,0x79,0xF4,0x3D,0xD8,0x24,	/* b */
+	  0x99,0x3C,0x2C,0xEE,0x5E,0xD3,
+	  0x16,0x1F,0xF7,0x52,0x8B,0x89,0x9B,0x2D,0x0C,0x28,	/* x */
+	  0x60,0x7C,0xA5,0x2C,0x5B,0x86,
+	  0xcf,0x5a,0xc8,0x39,0x5b,0xaf,0xeb,0x13,0xc0,0x2d,	/* y */
+	  0xa2,0x92,0xdd,0xed,0x7a,0x83,
+	  0xFF,0xFF,0xFF,0xFE,0x00,0x00,0x00,0x00,0x75,0xA3,	/* order */
+	  0x0D,0x1B,0x90,0x38,0xA1,0x15 }
 	};
 
-static const unsigned char _EC_SECG_PRIME_128R2_SEED[] = {
-	0x00,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,
-	0x12,0xD8,0xF0,0x34,0x31,0xFC,0xE6,0x3B,0x88,0xF4};
-static const EC_CURVE_DATA _EC_SECG_PRIME_128R2 = {
-	NID_X9_62_prime_field,
-	"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
-	"D6031998D1B3BBFEBF59CC9BBFF9AEE1",
-	"5EEEFCA380D02919DC2C6558BB6D8A5D",
-	"7B6AA5D85E572983E6FB32A7CDEBC140",
-	"27b6916a894d3aee7106fe805fc34b44",
-	"3FFFFFFF7FFFFFFFBE0024720613B5A3",4,
-	_EC_SECG_PRIME_128R2_SEED, 20,
-	"SECG curve over a 128 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+16*6]; }
+	_EC_SECG_PRIME_128R2 = {
+	{ NID_X9_62_prime_field,20,16,4 },
+	{ 0x00,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,	/* seed */
+	  0x12,0xD8,0xF0,0x34,0x31,0xFC,0xE6,0x3B,0x88,0xF4,
+
+	  0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xD6,0x03,0x19,0x98,0xD1,0xB3,0xBB,0xFE,0xBF,0x59,	/* a */
+	  0xCC,0x9B,0xBF,0xF9,0xAE,0xE1,
+	  0x5E,0xEE,0xFC,0xA3,0x80,0xD0,0x29,0x19,0xDC,0x2C,	/* b */
+	  0x65,0x58,0xBB,0x6D,0x8A,0x5D,
+	  0x7B,0x6A,0xA5,0xD8,0x5E,0x57,0x29,0x83,0xE6,0xFB,	/* x */
+	  0x32,0xA7,0xCD,0xEB,0xC1,0x40,
+	  0x27,0xb6,0x91,0x6a,0x89,0x4d,0x3a,0xee,0x71,0x06,	/* y */
+	  0xfe,0x80,0x5f,0xc3,0x4b,0x44,
+	  0x3F,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xBE,0x00,	/* order */
+	  0x24,0x72,0x06,0x13,0xB5,0xA3 }
 	};
 
-static const EC_CURVE_DATA _EC_SECG_PRIME_160K1 = {
-	NID_X9_62_prime_field,
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
-	"0",
-	"7",
-	"3B4C382CE37AA192A4019E763036F4F5DD4D7EBB",
-	"938cf935318fdced6bc28286531733c3f03c4fee",
-	"0100000000000000000001B8FA16DFAB9ACA16B6B3",1,
-	NULL, 0,
-	"SECG curve over a 160 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
+	_EC_SECG_PRIME_160K1 = {
+	{ NID_X9_62_prime_field,0,21,1 },
+	{							/* no seed */
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC,
+	  0x73,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x07,
+	  0x00,0x3B,0x4C,0x38,0x2C,0xE3,0x7A,0xA1,0x92,0xA4,	/* x */
+	  0x01,0x9E,0x76,0x30,0x36,0xF4,0xF5,0xDD,0x4D,0x7E,
+	  0xBB,
+	  0x00,0x93,0x8c,0xf9,0x35,0x31,0x8f,0xdc,0xed,0x6b,	/* y */
+	  0xc2,0x82,0x86,0x53,0x17,0x33,0xc3,0xf0,0x3c,0x4f,
+	  0xee,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x01,0xB8,0xFA,0x16,0xDF,0xAB,0x9A,0xCA,0x16,0xB6,
+	  0xB3 }
 	};
 
-static const unsigned char _EC_SECG_PRIME_160R1_SEED[] = {
-	0x10,0x53,0xCD,0xE4,0x2C,0x14,0xD6,0x96,0xE6,0x76,
-	0x87,0x56,0x15,0x17,0x53,0x3B,0xF3,0xF8,0x33,0x45};
-static const EC_CURVE_DATA _EC_SECG_PRIME_160R1 = {
-	NID_X9_62_prime_field,
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
-	"1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
-	"4A96B5688EF573284664698968C38BB913CBFC82",
-	"23a628553168947d59dcc912042351377ac5fb32",
-	"0100000000000000000001F4C8F927AED3CA752257",1,
-	_EC_SECG_PRIME_160R1_SEED, 20,
-	"SECG curve over a 160 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
+	_EC_SECG_PRIME_160R1 = {
+	{ NID_X9_62_prime_field,20,21,1 },
+	{ 0x10,0x53,0xCD,0xE4,0x2C,0x14,0xD6,0x96,0xE6,0x76,	/* seed */
+	  0x87,0x56,0x15,0x17,0x53,0x3B,0xF3,0xF8,0x33,0x45,
+
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,
+	  0xFF,
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,
+	  0xFC,
+	  0x00,0x1C,0x97,0xBE,0xFC,0x54,0xBD,0x7A,0x8B,0x65,	/* b */
+	  0xAC,0xF8,0x9F,0x81,0xD4,0xD4,0xAD,0xC5,0x65,0xFA,
+	  0x45,
+	  0x00,0x4A,0x96,0xB5,0x68,0x8E,0xF5,0x73,0x28,0x46,	/* x */
+	  0x64,0x69,0x89,0x68,0xC3,0x8B,0xB9,0x13,0xCB,0xFC,
+	  0x82,
+	  0x00,0x23,0xa6,0x28,0x55,0x31,0x68,0x94,0x7d,0x59,	/* y */
+	  0xdc,0xc9,0x12,0x04,0x23,0x51,0x37,0x7a,0xc5,0xfb,
+	  0x32,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x01,0xF4,0xC8,0xF9,0x27,0xAE,0xD3,0xCA,0x75,0x22,
+	  0x57 }
 	};
 
-static const unsigned char _EC_SECG_PRIME_160R2_SEED[] = {
-	0xB9,0x9B,0x99,0xB0,0x99,0xB3,0x23,0xE0,0x27,0x09,
-	0xA4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x51};
-static const EC_CURVE_DATA _EC_SECG_PRIME_160R2 = {
-	NID_X9_62_prime_field,
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70",
-	"B4E134D3FB59EB8BAB57274904664D5AF50388BA",
-	"52DCB034293A117E1F4FF11B30F7199D3144CE6D",
-	"feaffef2e331f296e071fa0df9982cfea7d43f2e",
-	"0100000000000000000000351EE786A818F3A1A16B",1,
-	_EC_SECG_PRIME_160R2_SEED, 20,
-	"SECG/WTLS curve over a 160 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
+	_EC_SECG_PRIME_160R2 = {
+	{ NID_X9_62_prime_field,20,21,1 },
+	{ 0xB9,0x9B,0x99,0xB0,0x99,0xB3,0x23,0xE0,0x27,0x09,	/* seed */
+	  0xA4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x51,
+
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC,
+	  0x73,
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xAC,
+	  0x70,
+	  0x00,0xB4,0xE1,0x34,0xD3,0xFB,0x59,0xEB,0x8B,0xAB,	/* b */
+	  0x57,0x27,0x49,0x04,0x66,0x4D,0x5A,0xF5,0x03,0x88,
+	  0xBA,
+	  0x00,0x52,0xDC,0xB0,0x34,0x29,0x3A,0x11,0x7E,0x1F,	/* x */
+	  0x4F,0xF1,0x1B,0x30,0xF7,0x19,0x9D,0x31,0x44,0xCE,
+	  0x6D,
+	  0x00,0xfe,0xaf,0xfe,0xf2,0xe3,0x31,0xf2,0x96,0xe0,	/* y */
+	  0x71,0xfa,0x0d,0xf9,0x98,0x2c,0xfe,0xa7,0xd4,0x3f,
+	  0x2e,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x35,0x1E,0xE7,0x86,0xA8,0x18,0xF3,0xA1,0xA1,
+	  0x6B }
 	};
 
-static const EC_CURVE_DATA _EC_SECG_PRIME_192K1 = {
-	NID_X9_62_prime_field,
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37",
-	"0",
-	"3",
-	"DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D",
-	"9b2f2f6d9c5628a7844163d015be86344082aa88d95e2f9d",
-	"FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D",1,
-	NULL, 20,
-	"SECG curve over a 192 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+24*6]; }
+	_EC_SECG_PRIME_192K1 = {
+	{ NID_X9_62_prime_field,0,24,1 },
+	{							/* no seed */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
+	  0xFF,0xFF,0xEE,0x37,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x03,
+	  0xDB,0x4F,0xF1,0x0E,0xC0,0x57,0xE9,0xAE,0x26,0xB0,	/* x */
+	  0x7D,0x02,0x80,0xB7,0xF4,0x34,0x1D,0xA5,0xD1,0xB1,
+	  0xEA,0xE0,0x6C,0x7D,
+	  0x9b,0x2f,0x2f,0x6d,0x9c,0x56,0x28,0xa7,0x84,0x41,	/* y */
+	  0x63,0xd0,0x15,0xbe,0x86,0x34,0x40,0x82,0xaa,0x88,
+	  0xd9,0x5e,0x2f,0x9d,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFE,0x26,0xF2,0xFC,0x17,0x0F,0x69,0x46,0x6A,
+	  0x74,0xDE,0xFD,0x8D }
 	};
 
-static const EC_CURVE_DATA _EC_SECG_PRIME_224K1 = {
-	NID_X9_62_prime_field,
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D",
-	"0",
-	"5",
-	"A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C",
-	"7e089fed7fba344282cafbd6f7e319f7c0b0bd59e2ca4bdb556d61a5",
-	"010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",1,
-	NULL, 20,
-	"SECG curve over a 224 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+29*6]; }
+	_EC_SECG_PRIME_224K1 = {
+	{ NID_X9_62_prime_field,0,29,1 },
+	{							/* no seed */
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xE5,0x6D,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
+	  0x00,0xA1,0x45,0x5B,0x33,0x4D,0xF0,0x99,0xDF,0x30,	/* x */
+	  0xFC,0x28,0xA1,0x69,0xA4,0x67,0xE9,0xE4,0x70,0x75,
+	  0xA9,0x0F,0x7E,0x65,0x0E,0xB6,0xB7,0xA4,0x5C,
+	  0x00,0x7e,0x08,0x9f,0xed,0x7f,0xba,0x34,0x42,0x82,	/* y */
+	  0xca,0xfb,0xd6,0xf7,0xe3,0x19,0xf7,0xc0,0xb0,0xbd,
+	  0x59,0xe2,0xca,0x4b,0xdb,0x55,0x6d,0x61,0xa5,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x00,0x00,0x01,0xDC,0xE8,0xD2,0xEC,0x61,
+	  0x84,0xCA,0xF0,0xA9,0x71,0x76,0x9F,0xB1,0xF7 }
 	};
 
-static const EC_CURVE_DATA _EC_SECG_PRIME_256K1 = {
-	NID_X9_62_prime_field,
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
-	"0",
-	"7",
-	"79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
-	"483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",1,
-	NULL, 20,
-	"SECG curve over a 256 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+32*6]; }
+	_EC_SECG_PRIME_256K1 = {
+	{ NID_X9_62_prime_field,0,32,1 },
+	{							/* no seed */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,
+	  0xFC,0x2F,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x07,
+	  0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,	/* x */
+	  0x62,0x95,0xCE,0x87,0x0B,0x07,0x02,0x9B,0xFC,0xDB,
+	  0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
+	  0x17,0x98,
+	  0x48,0x3a,0xda,0x77,0x26,0xa3,0xc4,0x65,0x5d,0xa4,	/* y */
+	  0xfb,0xfc,0x0e,0x11,0x08,0xa8,0xfd,0x17,0xb4,0x48,
+	  0xa6,0x85,0x54,0x19,0x9c,0x47,0xd0,0x8f,0xfb,0x10,
+	  0xd4,0xb8,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,
+	  0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,0x8C,0xD0,0x36,
+	  0x41,0x41 }
 	};
 
 /* some wap/wtls curves */
-static const EC_CURVE_DATA _EC_WTLS_8 = {
-	NID_X9_62_prime_field,
-	"FFFFFFFFFFFFFFFFFFFFFFFFFDE7",
-	"0",
-	"3",
-	"1",
-	"2",
-	"0100000000000001ECEA551AD837E9",1,
-	NULL, 20,
-	"WTLS curve over a 112 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+15*6]; }
+	_EC_WTLS_8 = {
+	{ NID_X9_62_prime_field,0,15,1 },
+	{							/* no seed */
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFD,0xE7,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x03,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* x */
+	  0x00,0x00,0x00,0x00,0x01,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* y */
+	  0x00,0x00,0x00,0x00,0x02,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xEC,0xEA,	/* order */
+	  0x55,0x1A,0xD8,0x37,0xE9 }
 	};
 
-static const EC_CURVE_DATA _EC_WTLS_9 = {
-	NID_X9_62_prime_field,
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC808F",
-	"0",
-	"3",
-	"1",
-	"2",
-	"0100000000000000000001CDC98AE0E2DE574ABF33",1,
-	NULL, 20,
-	"WTLS curve over a 160 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
+	_EC_WTLS_9 = {
+	{ NID_X9_62_prime_field,0,21,1 },
+	{							/* no seed */
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0x80,
+	  0x8F,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x03,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* x */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x01,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* y */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x02,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x01,0xCD,0xC9,0x8A,0xE0,0xE2,0xDE,0x57,0x4A,0xBF,
+	  0x33 }
 	};
 
-static const EC_CURVE_DATA _EC_WTLS_12 = {
-	NID_X9_62_prime_field,
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
-	"B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
-	"B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
-	"bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
-	"FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", 1,
-	NULL, 0,
-	"WTLS curvs over a 224 bit prime field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+28*6]; }
+	_EC_WTLS_12 = {
+	{ NID_X9_62_prime_field,0,28,1 },
+	{							/* no seed */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* p */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* a */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
+	  0xB4,0x05,0x0A,0x85,0x0C,0x04,0xB3,0xAB,0xF5,0x41,	/* b */
+	  0x32,0x56,0x50,0x44,0xB0,0xB7,0xD7,0xBF,0xD8,0xBA,
+	  0x27,0x0B,0x39,0x43,0x23,0x55,0xFF,0xB4,
+	  0xB7,0x0E,0x0C,0xBD,0x6B,0xB4,0xBF,0x7F,0x32,0x13,	/* x */
+	  0x90,0xB9,0x4A,0x03,0xC1,0xD3,0x56,0xC2,0x11,0x22,
+	  0x34,0x32,0x80,0xD6,0x11,0x5C,0x1D,0x21,
+	  0xbd,0x37,0x63,0x88,0xb5,0xf7,0x23,0xfb,0x4c,0x22,	/* y */
+	  0xdf,0xe6,0xcd,0x43,0x75,0xa0,0x5a,0x07,0x47,0x64,
+	  0x44,0xd5,0x81,0x99,0x85,0x00,0x7e,0x34,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0x16,0xA2,0xE0,0xB8,0xF0,0x3E,
+	  0x13,0xDD,0x29,0x45,0x5C,0x5C,0x2A,0x3D }
 	};
 
 /* characteristic two curves */
-static const unsigned char _EC_SECG_CHAR2_113R1_SEED[] = {
-	0x10,0xE7,0x23,0xAB,0x14,0xD6,0x96,0xE6,0x76,0x87,
-	0x56,0x15,0x17,0x56,0xFE,0xBF,0x8F,0xCB,0x49,0xA9};
-static const EC_CURVE_DATA _EC_SECG_CHAR2_113R1 = {
-	NID_X9_62_characteristic_two_field,
-	"020000000000000000000000000201",
-	"003088250CA6E7C7FE649CE85820F7",
-	"00E8BEE4D3E2260744188BE0E9C723",
-	"009D73616F35F4AB1407D73562C10F",
-	"00A52830277958EE84D1315ED31886",
-	"0100000000000000D9CCEC8A39E56F", 2,
-	_EC_SECG_CHAR2_113R1_SEED, 20,
-	"SECG curve over a 113 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+15*6]; }
+	_EC_SECG_CHAR2_113R1 = {
+	{ NID_X9_62_characteristic_two_field,20,15,2 },
+	{ 0x10,0xE7,0x23,0xAB,0x14,0xD6,0x96,0xE6,0x76,0x87,	/* seed */
+	  0x56,0x15,0x17,0x56,0xFE,0xBF,0x8F,0xCB,0x49,0xA9,
+
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x02,0x01,
+	  0x00,0x30,0x88,0x25,0x0C,0xA6,0xE7,0xC7,0xFE,0x64,	/* a */
+	  0x9C,0xE8,0x58,0x20,0xF7,
+	  0x00,0xE8,0xBE,0xE4,0xD3,0xE2,0x26,0x07,0x44,0x18,	/* b */
+	  0x8B,0xE0,0xE9,0xC7,0x23,
+	  0x00,0x9D,0x73,0x61,0x6F,0x35,0xF4,0xAB,0x14,0x07,	/* x */
+	  0xD7,0x35,0x62,0xC1,0x0F,
+	  0x00,0xA5,0x28,0x30,0x27,0x79,0x58,0xEE,0x84,0xD1,	/* y */
+	  0x31,0x5E,0xD3,0x18,0x86,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD9,0xCC,	/* order */
+	  0xEC,0x8A,0x39,0xE5,0x6F }
 	};
 
-static const unsigned char _EC_SECG_CHAR2_113R2_SEED[] = {
-	0x10,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE,
-	0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x5D};
-static const EC_CURVE_DATA _EC_SECG_CHAR2_113R2 = {
-	NID_X9_62_characteristic_two_field,
-	"020000000000000000000000000201",
-	"00689918DBEC7E5A0DD6DFC0AA55C7",
-	"0095E9A9EC9B297BD4BF36E059184F",
-	"01A57A6A7B26CA5EF52FCDB8164797",
-	"00B3ADC94ED1FE674C06E695BABA1D",
-	"010000000000000108789B2496AF93", 2,
-	_EC_SECG_CHAR2_113R2_SEED, 20,
-	"SECG curve over a 113 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+15*6]; }
+	_EC_SECG_CHAR2_113R2 = {
+	{ NID_X9_62_characteristic_two_field,20,15,2 },
+	{ 0x10,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE,	/* seed */
+	  0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x5D,
+
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x02,0x01,
+	  0x00,0x68,0x99,0x18,0xDB,0xEC,0x7E,0x5A,0x0D,0xD6,	/* a */
+	  0xDF,0xC0,0xAA,0x55,0xC7,
+	  0x00,0x95,0xE9,0xA9,0xEC,0x9B,0x29,0x7B,0xD4,0xBF,	/* b */
+	  0x36,0xE0,0x59,0x18,0x4F,
+	  0x01,0xA5,0x7A,0x6A,0x7B,0x26,0xCA,0x5E,0xF5,0x2F,	/* x */
+	  0xCD,0xB8,0x16,0x47,0x97,
+	  0x00,0xB3,0xAD,0xC9,0x4E,0xD1,0xFE,0x67,0x4C,0x06,	/* y */
+	  0xE6,0x95,0xBA,0xBA,0x1D,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x08,0x78,	/* order */
+	  0x9B,0x24,0x96,0xAF,0x93 }
 	};
 
-static const unsigned char _EC_SECG_CHAR2_131R1_SEED[] = {
-	0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,0x98,
-	0x5B,0xD3,0xAD,0xBA,0xDA,0x21,0xB4,0x3A,0x97,0xE2};
-static const EC_CURVE_DATA _EC_SECG_CHAR2_131R1 = {
-	NID_X9_62_characteristic_two_field,
-	"080000000000000000000000000000010D",
-	"07A11B09A76B562144418FF3FF8C2570B8",
-	"0217C05610884B63B9C6C7291678F9D341",
-	"0081BAF91FDF9833C40F9C181343638399",
-	"078C6E7EA38C001F73C8134B1B4EF9E150",
-	"0400000000000000023123953A9464B54D", 2,
-	_EC_SECG_CHAR2_131R1_SEED, 20,
-	"SECG/WTLS curve over a 131 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+17*6]; }
+	_EC_SECG_CHAR2_131R1 = {
+	{ NID_X9_62_characteristic_two_field,20,17,2 },
+	{ 0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,0x98,	/* seed */
+	  0x5B,0xD3,0xAD,0xBA,0xDA,0x21,0xB4,0x3A,0x97,0xE2,
+
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x01,0x0D,
+	  0x07,0xA1,0x1B,0x09,0xA7,0x6B,0x56,0x21,0x44,0x41,	/* a */
+	  0x8F,0xF3,0xFF,0x8C,0x25,0x70,0xB8,
+	  0x02,0x17,0xC0,0x56,0x10,0x88,0x4B,0x63,0xB9,0xC6,	/* b */
+	  0xC7,0x29,0x16,0x78,0xF9,0xD3,0x41,
+	  0x00,0x81,0xBA,0xF9,0x1F,0xDF,0x98,0x33,0xC4,0x0F,	/* x */
+	  0x9C,0x18,0x13,0x43,0x63,0x83,0x99,
+	  0x07,0x8C,0x6E,0x7E,0xA3,0x8C,0x00,0x1F,0x73,0xC8,	/* y */
+	  0x13,0x4B,0x1B,0x4E,0xF9,0xE1,0x50,
+	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x31,	/* order */
+	  0x23,0x95,0x3A,0x94,0x64,0xB5,0x4D }
 	};
 
-static const unsigned char _EC_SECG_CHAR2_131R2_SEED[] = {
-	0x98,0x5B,0xD3,0xAD,0xBA,0xD4,0xD6,0x96,0xE6,0x76,
-	0x87,0x56,0x15,0x17,0x5A,0x21,0xB4,0x3A,0x97,0xE3};
-static const EC_CURVE_DATA _EC_SECG_CHAR2_131R2 = {
-	NID_X9_62_characteristic_two_field,
-	"080000000000000000000000000000010D",
-	"03E5A88919D7CAFCBF415F07C2176573B2",
-	"04B8266A46C55657AC734CE38F018F2192",
-	"0356DCD8F2F95031AD652D23951BB366A8",
-	"0648F06D867940A5366D9E265DE9EB240F",
-	"0400000000000000016954A233049BA98F", 2,
-	_EC_SECG_CHAR2_131R2_SEED, 20,
-	"SECG curve over a 131 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+17*6]; }
+	_EC_SECG_CHAR2_131R2 = {
+	{ NID_X9_62_characteristic_two_field,20,17,2 },
+	{ 0x98,0x5B,0xD3,0xAD,0xBA,0xD4,0xD6,0x96,0xE6,0x76,	/* seed */
+	  0x87,0x56,0x15,0x17,0x5A,0x21,0xB4,0x3A,0x97,0xE3,
+
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x01,0x0D,
+	  0x03,0xE5,0xA8,0x89,0x19,0xD7,0xCA,0xFC,0xBF,0x41,	/* a */
+	  0x5F,0x07,0xC2,0x17,0x65,0x73,0xB2,
+	  0x04,0xB8,0x26,0x6A,0x46,0xC5,0x56,0x57,0xAC,0x73,	/* b */
+	  0x4C,0xE3,0x8F,0x01,0x8F,0x21,0x92,
+	  0x03,0x56,0xDC,0xD8,0xF2,0xF9,0x50,0x31,0xAD,0x65,	/* x */
+	  0x2D,0x23,0x95,0x1B,0xB3,0x66,0xA8,
+	  0x06,0x48,0xF0,0x6D,0x86,0x79,0x40,0xA5,0x36,0x6D,	/* y */
+	  0x9E,0x26,0x5D,0xE9,0xEB,0x24,0x0F,
+	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x69,	/* order */
+	  0x54,0xA2,0x33,0x04,0x9B,0xA9,0x8F }
 	};
 
-static const EC_CURVE_DATA _EC_NIST_CHAR2_163K = {
-	NID_X9_62_characteristic_two_field,
-	"0800000000000000000000000000000000000000C9",
-	"1",
-	"1",
-	"02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
-	"0289070FB05D38FF58321F2E800536D538CCDAA3D9",
-	"04000000000000000000020108A2E0CC0D99F8A5EF", 2,
-	NULL, 0,
-	"NIST/SECG/WTLS curve over a 163 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
+	_EC_NIST_CHAR2_163K = {
+	{ NID_X9_62_characteristic_two_field,0,21,2 },
+	{							/* no seed */
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0xC9,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x01,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x01,
+	  0x02,0xFE,0x13,0xC0,0x53,0x7B,0xBC,0x11,0xAC,0xAA,	/* x */
+	  0x07,0xD7,0x93,0xDE,0x4E,0x6D,0x5E,0x5C,0x94,0xEE,
+	  0xE8,
+	  0x02,0x89,0x07,0x0F,0xB0,0x5D,0x38,0xFF,0x58,0x32,	/* y */
+	  0x1F,0x2E,0x80,0x05,0x36,0xD5,0x38,0xCC,0xDA,0xA3,
+	  0xD9,
+	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x02,0x01,0x08,0xA2,0xE0,0xCC,0x0D,0x99,0xF8,0xA5,
+	  0xEF }
 	};
 
-static const unsigned char _EC_SECG_CHAR2_163R1_SEED[] = {
-	0x24,0xB7,0xB1,0x37,0xC8,0xA1,0x4D,0x69,0x6E,0x67,
-	0x68,0x75,0x61,0x51,0x75,0x6F,0xD0,0xDA,0x2E,0x5C};
-static const EC_CURVE_DATA _EC_SECG_CHAR2_163R1 = {
-	NID_X9_62_characteristic_two_field,
-	"0800000000000000000000000000000000000000C9",
-	"07B6882CAAEFA84F9554FF8428BD88E246D2782AE2",
-	"0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9",
-	"0369979697AB43897789566789567F787A7876A654",
-	"00435EDB42EFAFB2989D51FEFCE3C80988F41FF883",
-	"03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B", 2,
+static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
+	_EC_SECG_CHAR2_163R1 = {
+	{ NID_X9_62_characteristic_two_field,0,21,2 },
+	{							/* no seed */
+#if 0
 /* The algorithm used to derive the curve parameters from
  * the seed used here is slightly different than the
- * algorithm described in X9.62 .
- */
-#if 0
-	_EC_SECG_CHAR2_163R1_SEED, 20,
-#else
-	NULL, 0,
+ * algorithm described in X9.62 . */
+	  0x24,0xB7,0xB1,0x37,0xC8,0xA1,0x4D,0x69,0x6E,0x67,
+	  0x68,0x75,0x61,0x51,0x75,0x6F,0xD0,0xDA,0x2E,0x5C,
 #endif
-	"SECG curve over a 163 bit binary field"
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0xC9,
+	  0x07,0xB6,0x88,0x2C,0xAA,0xEF,0xA8,0x4F,0x95,0x54,	/* a */
+	  0xFF,0x84,0x28,0xBD,0x88,0xE2,0x46,0xD2,0x78,0x2A,
+	  0xE2,
+	  0x07,0x13,0x61,0x2D,0xCD,0xDC,0xB4,0x0A,0xAB,0x94,	/* b */
+	  0x6B,0xDA,0x29,0xCA,0x91,0xF7,0x3A,0xF9,0x58,0xAF,
+	  0xD9,
+	  0x03,0x69,0x97,0x96,0x97,0xAB,0x43,0x89,0x77,0x89,	/* x */
+	  0x56,0x67,0x89,0x56,0x7F,0x78,0x7A,0x78,0x76,0xA6,
+	  0x54,
+	  0x00,0x43,0x5E,0xDB,0x42,0xEF,0xAF,0xB2,0x98,0x9D,	/* y */
+	  0x51,0xFE,0xFC,0xE3,0xC8,0x09,0x88,0xF4,0x1F,0xF8,
+	  0x83,
+	  0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0x48,0xAA,0xB6,0x89,0xC2,0x9C,0xA7,0x10,0x27,
+	  0x9B }
 	};
 
-static const unsigned char _EC_NIST_CHAR2_163B_SEED[] = {
-	0x85,0xE2,0x5B,0xFE,0x5C,0x86,0x22,0x6C,0xDB,0x12,
-	0x01,0x6F,0x75,0x53,0xF9,0xD0,0xE6,0x93,0xA2,0x68};
-static const EC_CURVE_DATA _EC_NIST_CHAR2_163B ={
-	NID_X9_62_characteristic_two_field,
-	"0800000000000000000000000000000000000000C9",
-	"1",
-	"020A601907B8C953CA1481EB10512F78744A3205FD",
-	"03F0EBA16286A2D57EA0991168D4994637E8343E36",
-	"00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
-	"040000000000000000000292FE77E70C12A4234C33", 2,
+static const struct { EC_CURVE_DATA h; unsigned char data[0+21*6]; }
+	_EC_NIST_CHAR2_163B = {
+	{ NID_X9_62_characteristic_two_field,0,21,2 },
+	{							/* no seed */
+#if 0
 /* The seed here was used to created the curve parameters in normal
- * basis representation (and not the polynomial representation used here) 
- */
-#if 0
-	_EC_NIST_CHAR2_163B_SEED, 20,
-#else
-	NULL, 0,
+ * basis representation (and not the polynomial representation used here) */
+	  0x85,0xE2,0x5B,0xFE,0x5C,0x86,0x22,0x6C,0xDB,0x12,
+	  0x01,0x6F,0x75,0x53,0xF9,0xD0,0xE6,0x93,0xA2,0x68,
 #endif
-	"NIST/SECG curve over a 163 bit binary field"
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0xC9,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x01,
+	  0x02,0x0A,0x60,0x19,0x07,0xB8,0xC9,0x53,0xCA,0x14,	/* b */
+	  0x81,0xEB,0x10,0x51,0x2F,0x78,0x74,0x4A,0x32,0x05,
+	  0xFD,
+	  0x03,0xF0,0xEB,0xA1,0x62,0x86,0xA2,0xD5,0x7E,0xA0,	/* x */
+	  0x99,0x11,0x68,0xD4,0x99,0x46,0x37,0xE8,0x34,0x3E,
+	  0x36,
+	  0x00,0xD5,0x1F,0xBC,0x6C,0x71,0xA0,0x09,0x4F,0xA2,	/* y */
+	  0xCD,0xD5,0x45,0xB1,0x1C,0x5C,0x0C,0x79,0x73,0x24,
+	  0xF1,
+	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x02,0x92,0xFE,0x77,0xE7,0x0C,0x12,0xA4,0x23,0x4C,
+	  0x33 }
 	};
 
-static const unsigned char _EC_SECG_CHAR2_193R1_SEED[] = {
-	0x10,0x3F,0xAE,0xC7,0x4D,0x69,0x6E,0x67,0x68,0x75,
-	0x61,0x51,0x75,0x77,0x7F,0xC5,0xB1,0x91,0xEF,0x30};
-static const EC_CURVE_DATA _EC_SECG_CHAR2_193R1 = {
-	NID_X9_62_characteristic_two_field,
-	"02000000000000000000000000000000000000000000008001",
-	"0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01",
-	"00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814",
-	"01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1",
-	"0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05",
-	"01000000000000000000000000C7F34A778F443ACC920EBA49", 2,
-	_EC_SECG_CHAR2_193R1_SEED, 20,
-	"SECG curve over a 193 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+25*6]; }
+	_EC_SECG_CHAR2_193R1 = {
+	{ NID_X9_62_characteristic_two_field,20,25,2 },
+	{ 0x10,0x3F,0xAE,0xC7,0x4D,0x69,0x6E,0x67,0x68,0x75,	/* seed */
+	  0x61,0x51,0x75,0x77,0x7F,0xC5,0xB1,0x91,0xEF,0x30,
+
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x80,0x01,
+	  0x00,0x17,0x85,0x8F,0xEB,0x7A,0x98,0x97,0x51,0x69,	/* a */
+	  0xE1,0x71,0xF7,0x7B,0x40,0x87,0xDE,0x09,0x8A,0xC8,
+	  0xA9,0x11,0xDF,0x7B,0x01,
+	  0x00,0xFD,0xFB,0x49,0xBF,0xE6,0xC3,0xA8,0x9F,0xAC,	/* b */
+	  0xAD,0xAA,0x7A,0x1E,0x5B,0xBC,0x7C,0xC1,0xC2,0xE5,
+	  0xD8,0x31,0x47,0x88,0x14,
+	  0x01,0xF4,0x81,0xBC,0x5F,0x0F,0xF8,0x4A,0x74,0xAD,	/* x */
+	  0x6C,0xDF,0x6F,0xDE,0xF4,0xBF,0x61,0x79,0x62,0x53,
+	  0x72,0xD8,0xC0,0xC5,0xE1,
+	  0x00,0x25,0xE3,0x99,0xF2,0x90,0x37,0x12,0xCC,0xF3,	/* y */
+	  0xEA,0x9E,0x3A,0x1A,0xD1,0x7F,0xB0,0xB3,0x20,0x1B,
+	  0x6A,0xF7,0xCE,0x1B,0x05,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x00,0xC7,0xF3,0x4A,0x77,0x8F,0x44,0x3A,
+	  0xCC,0x92,0x0E,0xBA,0x49 }
 	};
 
-static const unsigned char _EC_SECG_CHAR2_193R2_SEED[] = {
-	0x10,0xB7,0xB4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,
-	0x17,0x51,0x37,0xC8,0xA1,0x6F,0xD0,0xDA,0x22,0x11};
-static const EC_CURVE_DATA _EC_SECG_CHAR2_193R2 = {
-	NID_X9_62_characteristic_two_field,
-	"02000000000000000000000000000000000000000000008001",
-	"0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B",
-	"00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE",
-	"00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F",
-	"01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C",
-	"010000000000000000000000015AAB561B005413CCD4EE99D5", 2,
-	_EC_SECG_CHAR2_193R2_SEED, 20,
-	"SECG curve over a 193 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+25*6]; }
+	_EC_SECG_CHAR2_193R2 = {
+	{ NID_X9_62_characteristic_two_field,20,25,2 },
+	{ 0x10,0xB7,0xB4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,	/* seed */
+	  0x17,0x51,0x37,0xC8,0xA1,0x6F,0xD0,0xDA,0x22,0x11,
+
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x80,0x01,
+	  0x01,0x63,0xF3,0x5A,0x51,0x37,0xC2,0xCE,0x3E,0xA6,	/* a */
+	  0xED,0x86,0x67,0x19,0x0B,0x0B,0xC4,0x3E,0xCD,0x69,
+	  0x97,0x77,0x02,0x70,0x9B,
+	  0x00,0xC9,0xBB,0x9E,0x89,0x27,0xD4,0xD6,0x4C,0x37,	/* b */
+	  0x7E,0x2A,0xB2,0x85,0x6A,0x5B,0x16,0xE3,0xEF,0xB7,
+	  0xF6,0x1D,0x43,0x16,0xAE,
+	  0x00,0xD9,0xB6,0x7D,0x19,0x2E,0x03,0x67,0xC8,0x03,	/* x */
+	  0xF3,0x9E,0x1A,0x7E,0x82,0xCA,0x14,0xA6,0x51,0x35,
+	  0x0A,0xAE,0x61,0x7E,0x8F,
+	  0x01,0xCE,0x94,0x33,0x56,0x07,0xC3,0x04,0xAC,0x29,	/* y */
+	  0xE7,0xDE,0xFB,0xD9,0xCA,0x01,0xF5,0x96,0xF9,0x27,
+	  0x22,0x4C,0xDE,0xCF,0x6C,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x01,0x5A,0xAB,0x56,0x1B,0x00,0x54,0x13,
+	  0xCC,0xD4,0xEE,0x99,0xD5 }
 	};
 
-static const EC_CURVE_DATA _EC_NIST_CHAR2_233K = {
-	NID_X9_62_characteristic_two_field,
-	"020000000000000000000000000000000000000004000000000000000001",
-	"0",
-	"1",
-	"017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
-	"01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
-	"008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 4,
-	NULL, 0,
-	"NIST/SECG/WTLS curve over a 233 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+30*6]; }
+	_EC_NIST_CHAR2_233K = {
+	{ NID_X9_62_characteristic_two_field,0,30,4 },
+	{							/* no seed */
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+
+	  0x01,0x72,0x32,0xBA,0x85,0x3A,0x7E,0x73,0x1A,0xF1,	/* x */
+	  0x29,0xF2,0x2F,0xF4,0x14,0x95,0x63,0xA4,0x19,0xC2,
+	  0x6B,0xF5,0x0A,0x4C,0x9D,0x6E,0xEF,0xAD,0x61,0x26,
+
+	  0x01,0xDB,0x53,0x7D,0xEC,0xE8,0x19,0xB7,0xF7,0x0F,	/* y */
+	  0x55,0x5A,0x67,0xC4,0x27,0xA8,0xCD,0x9B,0xF1,0x8A,
+	  0xEB,0x9B,0x56,0xE0,0xC1,0x10,0x56,0xFA,0xE6,0xA3,
+
+	  0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x00,0x00,0x00,0x06,0x9D,0x5B,0xB9,0x15,
+	  0xBC,0xD4,0x6E,0xFB,0x1A,0xD5,0xF1,0x73,0xAB,0xDF }
 	};
 
-static const unsigned char _EC_NIST_CHAR2_233B_SEED[] = {
-	0x74,0xD5,0x9F,0xF0,0x7F,0x6B,0x41,0x3D,0x0E,0xA1,
-	0x4B,0x34,0x4B,0x20,0xA2,0xDB,0x04,0x9B,0x50,0xC3};
-static const EC_CURVE_DATA _EC_NIST_CHAR2_233B = {
-	NID_X9_62_characteristic_two_field,
-	"020000000000000000000000000000000000000004000000000000000001",
-	"000000000000000000000000000000000000000000000000000000000001",
-	"0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
-	"00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
-	"01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
-	"01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 2,
-	_EC_NIST_CHAR2_233B_SEED, 20,
-	"NIST/SECG/WTLS curve over a 233 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
+	_EC_NIST_CHAR2_233B = {
+	{ NID_X9_62_characteristic_two_field,20,30,2 },
+	{ 0x74,0xD5,0x9F,0xF0,0x7F,0x6B,0x41,0x3D,0x0E,0xA1,	/* seed */
+	  0x4B,0x34,0x4B,0x20,0xA2,0xDB,0x04,0x9B,0x50,0xC3,
+
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+
+	  0x00,0x66,0x64,0x7E,0xDE,0x6C,0x33,0x2C,0x7F,0x8C,	/* b */
+	  0x09,0x23,0xBB,0x58,0x21,0x3B,0x33,0x3B,0x20,0xE9,
+	  0xCE,0x42,0x81,0xFE,0x11,0x5F,0x7D,0x8F,0x90,0xAD,
+
+	  0x00,0xFA,0xC9,0xDF,0xCB,0xAC,0x83,0x13,0xBB,0x21,	/* x */
+	  0x39,0xF1,0xBB,0x75,0x5F,0xEF,0x65,0xBC,0x39,0x1F,
+	  0x8B,0x36,0xF8,0xF8,0xEB,0x73,0x71,0xFD,0x55,0x8B,
+
+	  0x01,0x00,0x6A,0x08,0xA4,0x19,0x03,0x35,0x06,0x78,	/* y */
+	  0xE5,0x85,0x28,0xBE,0xBF,0x8A,0x0B,0xEF,0xF8,0x67,
+	  0xA7,0xCA,0x36,0x71,0x6F,0x7E,0x01,0xF8,0x10,0x52,
+
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x00,0x00,0x00,0x13,0xE9,0x74,0xE7,0x2F,
+	  0x8A,0x69,0x22,0x03,0x1D,0x26,0x03,0xCF,0xE0,0xD7 }
 	};
 
-static const EC_CURVE_DATA _EC_SECG_CHAR2_239K1 = {
-	NID_X9_62_characteristic_two_field,
-	"800000000000000000004000000000000000000000000000000000000001",
-	"0",
-	"1",
-	"29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC",
-	"76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA",
-	"2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5", 4,
-	NULL, 0,
-	"SECG curve over a 239 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+30*6]; }
+	_EC_SECG_CHAR2_239K1 = {
+	{ NID_X9_62_characteristic_two_field,0,30,4 },
+	{							/* no seed */
+	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+
+	  0x29,0xA0,0xB6,0xA8,0x87,0xA9,0x83,0xE9,0x73,0x09,	/* x */
+	  0x88,0xA6,0x87,0x27,0xA8,0xB2,0xD1,0x26,0xC4,0x4C,
+	  0xC2,0xCC,0x7B,0x2A,0x65,0x55,0x19,0x30,0x35,0xDC,
+
+	  0x76,0x31,0x08,0x04,0xF1,0x2E,0x54,0x9B,0xDB,0x01,	/* y */
+	  0x1C,0x10,0x30,0x89,0xE7,0x35,0x10,0xAC,0xB2,0x75,
+	  0xFC,0x31,0x2A,0x5D,0xC6,0xB7,0x65,0x53,0xF0,0xCA,
+
+	  0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x00,0x00,0x00,0x5A,0x79,0xFE,0xC6,0x7C,
+	  0xB6,0xE9,0x1F,0x1C,0x1D,0xA8,0x00,0xE4,0x78,0xA5 }
 	};
 
-static const EC_CURVE_DATA _EC_NIST_CHAR2_283K = {
-	NID_X9_62_characteristic_two_field,
-	"080000000000000000000000000000000000000000000000000000000000000000001"
-	"0A1",
-	"0",
-	"1",
-	"0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492"
-	"836",
-	"01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2"
-	"259",
-	"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163"
-	"C61", 4,
-	NULL, 20,
-	"NIST/SECG curve over a 283 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+36*6]; }
+	_EC_NIST_CHAR2_283K = {
+	{ NID_X9_62_characteristic_two_field,0,36,4 },
+	{							/* no seed */
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x10,0xA1,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x01,
+	  0x05,0x03,0x21,0x3F,0x78,0xCA,0x44,0x88,0x3F,0x1A,	/* x */
+	  0x3B,0x81,0x62,0xF1,0x88,0xE5,0x53,0xCD,0x26,0x5F,
+	  0x23,0xC1,0x56,0x7A,0x16,0x87,0x69,0x13,0xB0,0xC2,
+	  0xAC,0x24,0x58,0x49,0x28,0x36,
+	  0x01,0xCC,0xDA,0x38,0x0F,0x1C,0x9E,0x31,0x8D,0x90,	/* y */
+	  0xF9,0x5D,0x07,0xE5,0x42,0x6F,0xE8,0x7E,0x45,0xC0,
+	  0xE8,0x18,0x46,0x98,0xE4,0x59,0x62,0x36,0x4E,0x34,
+	  0x11,0x61,0x77,0xDD,0x22,0x59,
+	  0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE9,0xAE,
+	  0x2E,0xD0,0x75,0x77,0x26,0x5D,0xFF,0x7F,0x94,0x45,
+	  0x1E,0x06,0x1E,0x16,0x3C,0x61 }
 	};
 
-static const unsigned char _EC_NIST_CHAR2_283B_SEED[] = {
-	0x77,0xE2,0xB0,0x73,0x70,0xEB,0x0F,0x83,0x2A,0x6D,
-	0xD5,0xB6,0x2D,0xFC,0x88,0xCD,0x06,0xBB,0x84,0xBE};
-static const EC_CURVE_DATA _EC_NIST_CHAR2_283B = {
-	NID_X9_62_characteristic_two_field,
-	"080000000000000000000000000000000000000000000000000000000000000000001"
-	"0A1",
-	"000000000000000000000000000000000000000000000000000000000000000000000"
-	"001",
-	"027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A"
-	"2F5",
-	"05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12"
-	"053",
-	"03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE811"
-	"2F4",
-	"03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB"
-	"307", 2,
-	_EC_NIST_CHAR2_283B_SEED, 20,
-	"NIST/SECG curve over a 283 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+36*6]; }
+	_EC_NIST_CHAR2_283B = {
+	{ NID_X9_62_characteristic_two_field,20,36,2 },
+	{ 0x77,0xE2,0xB0,0x73,0x70,0xEB,0x0F,0x83,0x2A,0x6D,	/* no seed */
+	  0xD5,0xB6,0x2D,0xFC,0x88,0xCD,0x06,0xBB,0x84,0xBE,
+
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x10,0xA1,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x01,
+	  0x02,0x7B,0x68,0x0A,0xC8,0xB8,0x59,0x6D,0xA5,0xA4,	/* b */
+	  0xAF,0x8A,0x19,0xA0,0x30,0x3F,0xCA,0x97,0xFD,0x76,
+	  0x45,0x30,0x9F,0xA2,0xA5,0x81,0x48,0x5A,0xF6,0x26,
+	  0x3E,0x31,0x3B,0x79,0xA2,0xF5,
+	  0x05,0xF9,0x39,0x25,0x8D,0xB7,0xDD,0x90,0xE1,0x93,	/* x */
+	  0x4F,0x8C,0x70,0xB0,0xDF,0xEC,0x2E,0xED,0x25,0xB8,
+	  0x55,0x7E,0xAC,0x9C,0x80,0xE2,0xE1,0x98,0xF8,0xCD,
+	  0xBE,0xCD,0x86,0xB1,0x20,0x53,
+	  0x03,0x67,0x68,0x54,0xFE,0x24,0x14,0x1C,0xB9,0x8F,	/* y */
+	  0xE6,0xD4,0xB2,0x0D,0x02,0xB4,0x51,0x6F,0xF7,0x02,
+	  0x35,0x0E,0xDD,0xB0,0x82,0x67,0x79,0xC8,0x13,0xF0,
+	  0xDF,0x45,0xBE,0x81,0x12,0xF4,
+	  0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0x90,
+	  0x39,0x96,0x60,0xFC,0x93,0x8A,0x90,0x16,0x5B,0x04,
+	  0x2A,0x7C,0xEF,0xAD,0xB3,0x07 }
 	};
 
-static const EC_CURVE_DATA _EC_NIST_CHAR2_409K = {
-	NID_X9_62_characteristic_two_field,
-	"020000000000000000000000000000000000000000000000000000000000000000000"
-	"00000000000008000000000000000000001",
-	"0",
-	"1",
-	"0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C4601"
-	"89EB5AAAA62EE222EB1B35540CFE9023746",
-	"01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6"
-	"C42E9C55215AA9CA27A5863EC48D8E0286B",
-	"007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400"
-	"EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", 4,
-	NULL, 0,
-	"NIST/SECG curve over a 409 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+52*6]; }
+	_EC_NIST_CHAR2_409K = {
+	{ NID_X9_62_characteristic_two_field,0,52,4 },
+	{							/* no seed */
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x01,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x01,
+	  0x00,0x60,0xF0,0x5F,0x65,0x8F,0x49,0xC1,0xAD,0x3A,	/* x */
+	  0xB1,0x89,0x0F,0x71,0x84,0x21,0x0E,0xFD,0x09,0x87,
+	  0xE3,0x07,0xC8,0x4C,0x27,0xAC,0xCF,0xB8,0xF9,0xF6,
+	  0x7C,0xC2,0xC4,0x60,0x18,0x9E,0xB5,0xAA,0xAA,0x62,
+	  0xEE,0x22,0x2E,0xB1,0xB3,0x55,0x40,0xCF,0xE9,0x02,
+	  0x37,0x46,
+	  0x01,0xE3,0x69,0x05,0x0B,0x7C,0x4E,0x42,0xAC,0xBA,	/* y */
+	  0x1D,0xAC,0xBF,0x04,0x29,0x9C,0x34,0x60,0x78,0x2F,
+	  0x91,0x8E,0xA4,0x27,0xE6,0x32,0x51,0x65,0xE9,0xEA,
+	  0x10,0xE3,0xDA,0x5F,0x6C,0x42,0xE9,0xC5,0x52,0x15,
+	  0xAA,0x9C,0xA2,0x7A,0x58,0x63,0xEC,0x48,0xD8,0xE0,
+	  0x28,0x6B,
+	  0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x5F,0x83,0xB2,
+	  0xD4,0xEA,0x20,0x40,0x0E,0xC4,0x55,0x7D,0x5E,0xD3,
+	  0xE3,0xE7,0xCA,0x5B,0x4B,0x5C,0x83,0xB8,0xE0,0x1E,
+	  0x5F,0xCF }
 	};
 
-static const unsigned char _EC_NIST_CHAR2_409B_SEED[] = {
-	0x40,0x99,0xB5,0xA4,0x57,0xF9,0xD6,0x9F,0x79,0x21,
-	0x3D,0x09,0x4C,0x4B,0xCD,0x4D,0x42,0x62,0x21,0x0B};
-static const EC_CURVE_DATA _EC_NIST_CHAR2_409B = {
-	NID_X9_62_characteristic_two_field,
-	"020000000000000000000000000000000000000000000000000000000000000000000"
-	"00000000000008000000000000000000001",
-	"000000000000000000000000000000000000000000000000000000000000000000000"
-	"00000000000000000000000000000000001",
-	"0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A19"
-	"7B272822F6CD57A55AA4F50AE317B13545F",
-	"015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255"
-	"A868A1180515603AEAB60794E54BB7996A7",
-	"0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514"
-	"F1FDF4B4F40D2181B3681C364BA0273C706",
-	"010000000000000000000000000000000000000000000000000001E2AAD6A612F3330"
-	"7BE5FA47C3C9E052F838164CD37D9A21173", 2,
-	_EC_NIST_CHAR2_409B_SEED, 20,
-	"NIST/SECG curve over a 409 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+52*6]; }
+	_EC_NIST_CHAR2_409B = {
+	{ NID_X9_62_characteristic_two_field,20,52,2 },
+	{ 0x40,0x99,0xB5,0xA4,0x57,0xF9,0xD6,0x9F,0x79,0x21,	/* seed */
+	  0x3D,0x09,0x4C,0x4B,0xCD,0x4D,0x42,0x62,0x21,0x0B,
+
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x01,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x01,
+	  0x00,0x21,0xA5,0xC2,0xC8,0xEE,0x9F,0xEB,0x5C,0x4B,	/* b */
+	  0x9A,0x75,0x3B,0x7B,0x47,0x6B,0x7F,0xD6,0x42,0x2E,
+	  0xF1,0xF3,0xDD,0x67,0x47,0x61,0xFA,0x99,0xD6,0xAC,
+	  0x27,0xC8,0xA9,0xA1,0x97,0xB2,0x72,0x82,0x2F,0x6C,
+	  0xD5,0x7A,0x55,0xAA,0x4F,0x50,0xAE,0x31,0x7B,0x13,
+	  0x54,0x5F,
+	  0x01,0x5D,0x48,0x60,0xD0,0x88,0xDD,0xB3,0x49,0x6B,	/* x */
+	  0x0C,0x60,0x64,0x75,0x62,0x60,0x44,0x1C,0xDE,0x4A,
+	  0xF1,0x77,0x1D,0x4D,0xB0,0x1F,0xFE,0x5B,0x34,0xE5,
+	  0x97,0x03,0xDC,0x25,0x5A,0x86,0x8A,0x11,0x80,0x51,
+	  0x56,0x03,0xAE,0xAB,0x60,0x79,0x4E,0x54,0xBB,0x79,
+	  0x96,0xA7,
+	  0x00,0x61,0xB1,0xCF,0xAB,0x6B,0xE5,0xF3,0x2B,0xBF,	/* y */
+	  0xA7,0x83,0x24,0xED,0x10,0x6A,0x76,0x36,0xB9,0xC5,
+	  0xA7,0xBD,0x19,0x8D,0x01,0x58,0xAA,0x4F,0x54,0x88,
+	  0xD0,0x8F,0x38,0x51,0x4F,0x1F,0xDF,0x4B,0x4F,0x40,
+	  0xD2,0x18,0x1B,0x36,0x81,0xC3,0x64,0xBA,0x02,0x73,
+	  0xC7,0x06,
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xE2,0xAA,0xD6,
+	  0xA6,0x12,0xF3,0x33,0x07,0xBE,0x5F,0xA4,0x7C,0x3C,
+	  0x9E,0x05,0x2F,0x83,0x81,0x64,0xCD,0x37,0xD9,0xA2,
+	  0x11,0x73 }
 	};
 
-static const EC_CURVE_DATA _EC_NIST_CHAR2_571K = {
-	NID_X9_62_characteristic_two_field,
-	"800000000000000000000000000000000000000000000000000000000000000000000"
-	"000000000000000000000000000000000000000000000000000000000000000000000"
-	"00425",
-	"0",
-	"1",
-	"026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA443709"
-	"58493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A0"
-	"1C8972",
-	"0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D497"
-	"9C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143E"
-	"F1C7A3",
-	"020000000000000000000000000000000000000000000000000000000000000000000"
-	"000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F63"
-	"7C1001", 4,
-	NULL, 0,
-	"NIST/SECG curve over a 571 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+72*6]; }
+	_EC_NIST_CHAR2_571K = {
+	{ NID_X9_62_characteristic_two_field,0,72,4 },
+	{							/* no seed */
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x04,0x25,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x01,
+	  0x02,0x6E,0xB7,0xA8,0x59,0x92,0x3F,0xBC,0x82,0x18,	/* x */
+	  0x96,0x31,0xF8,0x10,0x3F,0xE4,0xAC,0x9C,0xA2,0x97,
+	  0x00,0x12,0xD5,0xD4,0x60,0x24,0x80,0x48,0x01,0x84,
+	  0x1C,0xA4,0x43,0x70,0x95,0x84,0x93,0xB2,0x05,0xE6,
+	  0x47,0xDA,0x30,0x4D,0xB4,0xCE,0xB0,0x8C,0xBB,0xD1,
+	  0xBA,0x39,0x49,0x47,0x76,0xFB,0x98,0x8B,0x47,0x17,
+	  0x4D,0xCA,0x88,0xC7,0xE2,0x94,0x52,0x83,0xA0,0x1C,
+	  0x89,0x72,
+	  0x03,0x49,0xDC,0x80,0x7F,0x4F,0xBF,0x37,0x4F,0x4A,	/* y */
+	  0xEA,0xDE,0x3B,0xCA,0x95,0x31,0x4D,0xD5,0x8C,0xEC,
+	  0x9F,0x30,0x7A,0x54,0xFF,0xC6,0x1E,0xFC,0x00,0x6D,
+	  0x8A,0x2C,0x9D,0x49,0x79,0xC0,0xAC,0x44,0xAE,0xA7,
+	  0x4F,0xBE,0xBB,0xB9,0xF7,0x72,0xAE,0xDC,0xB6,0x20,
+	  0xB0,0x1A,0x7B,0xA7,0xAF,0x1B,0x32,0x04,0x30,0xC8,
+	  0x59,0x19,0x84,0xF6,0x01,0xCD,0x4C,0x14,0x3E,0xF1,
+	  0xC7,0xA3,
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x18,0x50,0xE1,
+	  0xF1,0x9A,0x63,0xE4,0xB3,0x91,0xA8,0xDB,0x91,0x7F,
+	  0x41,0x38,0xB6,0x30,0xD8,0x4B,0xE5,0xD6,0x39,0x38,
+	  0x1E,0x91,0xDE,0xB4,0x5C,0xFE,0x77,0x8F,0x63,0x7C,
+	  0x10,0x01 }
 	};
 
-static const unsigned char _EC_NIST_CHAR2_571B_SEED[] = {
-	0x2A,0xA0,0x58,0xF7,0x3A,0x0E,0x33,0xAB,0x48,0x6B,
-	0x0F,0x61,0x04,0x10,0xC5,0x3A,0x7F,0x13,0x23,0x10};
-static const EC_CURVE_DATA _EC_NIST_CHAR2_571B = {
-	NID_X9_62_characteristic_two_field,
-	"800000000000000000000000000000000000000000000000000000000000000000000"
-	"000000000000000000000000000000000000000000000000000000000000000000000"
-	"00425",
-	"000000000000000000000000000000000000000000000000000000000000000000000"
-	"000000000000000000000000000000000000000000000000000000000000000000000"
-	"000001",
-	"02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFA"
-	"BBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F29"
-	"55727A",
-	"0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53"
-	"950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8E"
-	"EC2D19",
-	"037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423"
-	"E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B"
-	"8AC15B",
-	"03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-	"FFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2F"
-	"E84E47", 2,
-	_EC_NIST_CHAR2_571B_SEED, 20,
-	"NIST/SECG curve over a 571 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+72*6]; }
+	_EC_NIST_CHAR2_571B = {
+	{ NID_X9_62_characteristic_two_field,20,72,2 },
+	{ 0x2A,0xA0,0x58,0xF7,0x3A,0x0E,0x33,0xAB,0x48,0x6B,	/* seed */
+	  0x0F,0x61,0x04,0x10,0xC5,0x3A,0x7F,0x13,0x23,0x10,
+
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x04,0x25,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x01,
+	  0x02,0xF4,0x0E,0x7E,0x22,0x21,0xF2,0x95,0xDE,0x29,	/* b */
+	  0x71,0x17,0xB7,0xF3,0xD6,0x2F,0x5C,0x6A,0x97,0xFF,
+	  0xCB,0x8C,0xEF,0xF1,0xCD,0x6B,0xA8,0xCE,0x4A,0x9A,
+	  0x18,0xAD,0x84,0xFF,0xAB,0xBD,0x8E,0xFA,0x59,0x33,
+	  0x2B,0xE7,0xAD,0x67,0x56,0xA6,0x6E,0x29,0x4A,0xFD,
+	  0x18,0x5A,0x78,0xFF,0x12,0xAA,0x52,0x0E,0x4D,0xE7,
+	  0x39,0xBA,0xCA,0x0C,0x7F,0xFE,0xFF,0x7F,0x29,0x55,
+	  0x72,0x7A,
+	  0x03,0x03,0x00,0x1D,0x34,0xB8,0x56,0x29,0x6C,0x16,	/* x */
+	  0xC0,0xD4,0x0D,0x3C,0xD7,0x75,0x0A,0x93,0xD1,0xD2,
+	  0x95,0x5F,0xA8,0x0A,0xA5,0xF4,0x0F,0xC8,0xDB,0x7B,
+	  0x2A,0xBD,0xBD,0xE5,0x39,0x50,0xF4,0xC0,0xD2,0x93,
+	  0xCD,0xD7,0x11,0xA3,0x5B,0x67,0xFB,0x14,0x99,0xAE,
+	  0x60,0x03,0x86,0x14,0xF1,0x39,0x4A,0xBF,0xA3,0xB4,
+	  0xC8,0x50,0xD9,0x27,0xE1,0xE7,0x76,0x9C,0x8E,0xEC,
+	  0x2D,0x19,
+	  0x03,0x7B,0xF2,0x73,0x42,0xDA,0x63,0x9B,0x6D,0xCC,	/* y */
+	  0xFF,0xFE,0xB7,0x3D,0x69,0xD7,0x8C,0x6C,0x27,0xA6,
+	  0x00,0x9C,0xBB,0xCA,0x19,0x80,0xF8,0x53,0x39,0x21,
+	  0xE8,0xA6,0x84,0x42,0x3E,0x43,0xBA,0xB0,0x8A,0x57,
+	  0x62,0x91,0xAF,0x8F,0x46,0x1B,0xB2,0xA8,0xB3,0x53,
+	  0x1D,0x2F,0x04,0x85,0xC1,0x9B,0x16,0xE2,0xF1,0x51,
+	  0x6E,0x23,0xDD,0x3C,0x1A,0x48,0x27,0xAF,0x1B,0x8A,
+	  0xC1,0x5B,
+	  0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+	  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6,0x61,0xCE,0x18,
+	  0xFF,0x55,0x98,0x73,0x08,0x05,0x9B,0x18,0x68,0x23,
+	  0x85,0x1E,0xC7,0xDD,0x9C,0xA1,0x16,0x1D,0xE9,0x3D,
+	  0x51,0x74,0xD6,0x6E,0x83,0x82,0xE9,0xBB,0x2F,0xE8,
+	  0x4E,0x47 }
 	};
 
-static const unsigned char _EC_X9_62_CHAR2_163V1_SEED[] = {
-	0xD2,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE,
-	0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x54};
-static const EC_CURVE_DATA _EC_X9_62_CHAR2_163V1 = {
-	NID_X9_62_characteristic_two_field,
-	"080000000000000000000000000000000000000107",
-	"072546B5435234A422E0789675F432C89435DE5242",
-	"00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9",
-	"07AF69989546103D79329FCC3D74880F33BBE803CB",
-	"01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F",
-	"0400000000000000000001E60FC8821CC74DAEAFC1", 2,
-	_EC_X9_62_CHAR2_163V1_SEED, 20,
-	"X9.62 curve over a 163 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
+	_EC_X9_62_CHAR2_163V1 = {
+	{ NID_X9_62_characteristic_two_field,20,21,2 },
+	{ 0xD2,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE,
+	  0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x54,	/* seed */
+
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+	  0x07,
+	  0x07,0x25,0x46,0xB5,0x43,0x52,0x34,0xA4,0x22,0xE0,	/* a */
+	  0x78,0x96,0x75,0xF4,0x32,0xC8,0x94,0x35,0xDE,0x52,
+	  0x42,
+	  0x00,0xC9,0x51,0x7D,0x06,0xD5,0x24,0x0D,0x3C,0xFF,	/* b */
+	  0x38,0xC7,0x4B,0x20,0xB6,0xCD,0x4D,0x6F,0x9D,0xD4,
+	  0xD9,
+	  0x07,0xAF,0x69,0x98,0x95,0x46,0x10,0x3D,0x79,0x32,	/* x */
+	  0x9F,0xCC,0x3D,0x74,0x88,0x0F,0x33,0xBB,0xE8,0x03,
+	  0xCB,
+	  0x01,0xEC,0x23,0x21,0x1B,0x59,0x66,0xAD,0xEA,0x1D,	/* y */
+	  0x3F,0x87,0xF7,0xEA,0x58,0x48,0xAE,0xF0,0xB7,0xCA,
+	  0x9F,
+	  0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x01,0xE6,0x0F,0xC8,0x82,0x1C,0xC7,0x4D,0xAE,0xAF,
+	  0xC1 }
 	};
 
-static const unsigned char _EC_X9_62_CHAR2_163V2_SEED[] = {
-	0x53,0x81,0x4C,0x05,0x0D,0x44,0xD6,0x96,0xE6,0x76,
-	0x87,0x56,0x15,0x17,0x58,0x0C,0xA4,0xE2,0x9F,0xFD};
-static const EC_CURVE_DATA _EC_X9_62_CHAR2_163V2 = {
-	NID_X9_62_characteristic_two_field,
- 	"080000000000000000000000000000000000000107",
-	"0108B39E77C4B108BED981ED0E890E117C511CF072",
-	"0667ACEB38AF4E488C407433FFAE4F1C811638DF20",
-	"0024266E4EB5106D0A964D92C4860E2671DB9B6CC5",
-	"079F684DDF6684C5CD258B3890021B2386DFD19FC5",
-	"03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", 2,
-	_EC_X9_62_CHAR2_163V2_SEED, 20,
-	"X9.62 curve over a 163 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
+	_EC_X9_62_CHAR2_163V2 = {
+	{ NID_X9_62_characteristic_two_field,20,21,2 },
+	{ 0x53,0x81,0x4C,0x05,0x0D,0x44,0xD6,0x96,0xE6,0x76,	/* seed */
+	  0x87,0x56,0x15,0x17,0x58,0x0C,0xA4,0xE2,0x9F,0xFD,
+
+ 	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+	  0x07,
+	  0x01,0x08,0xB3,0x9E,0x77,0xC4,0xB1,0x08,0xBE,0xD9,	/* a */
+	  0x81,0xED,0x0E,0x89,0x0E,0x11,0x7C,0x51,0x1C,0xF0,
+	  0x72,
+	  0x06,0x67,0xAC,0xEB,0x38,0xAF,0x4E,0x48,0x8C,0x40,	/* b */
+	  0x74,0x33,0xFF,0xAE,0x4F,0x1C,0x81,0x16,0x38,0xDF,
+	  0x20,
+	  0x00,0x24,0x26,0x6E,0x4E,0xB5,0x10,0x6D,0x0A,0x96,	/* x */
+	  0x4D,0x92,0xC4,0x86,0x0E,0x26,0x71,0xDB,0x9B,0x6C,
+	  0xC5,
+	  0x07,0x9F,0x68,0x4D,0xDF,0x66,0x84,0xC5,0xCD,0x25,	/* y */
+	  0x8B,0x38,0x90,0x02,0x1B,0x23,0x86,0xDF,0xD1,0x9F,
+	  0xC5,
+	  0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFD,0xF6,0x4D,0xE1,0x15,0x1A,0xDB,0xB7,0x8F,0x10,
+	  0xA7 }
 	};
 
-static const unsigned char _EC_X9_62_CHAR2_163V3_SEED[] = {
-	0x50,0xCB,0xF1,0xD9,0x5C,0xA9,0x4D,0x69,0x6E,0x67,
-	0x68,0x75,0x61,0x51,0x75,0xF1,0x6A,0x36,0xA3,0xB8};
-static const EC_CURVE_DATA _EC_X9_62_CHAR2_163V3 = {
-	NID_X9_62_characteristic_two_field,
-	"080000000000000000000000000000000000000107",
-	"07A526C63D3E25A256A007699F5447E32AE456B50E",
-	"03F7061798EB99E238FD6F1BF95B48FEEB4854252B",
-	"02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB",
-	"05B935590C155E17EA48EB3FF3718B893DF59A05D0",
-	"03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", 2,
-	_EC_X9_62_CHAR2_163V3_SEED, 20,
-	"X9.62 curve over a 163 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+21*6]; }
+	_EC_X9_62_CHAR2_163V3 = {
+	{ NID_X9_62_characteristic_two_field,20,21,2 },
+	{ 0x50,0xCB,0xF1,0xD9,0x5C,0xA9,0x4D,0x69,0x6E,0x67,	/* seed */
+	  0x68,0x75,0x61,0x51,0x75,0xF1,0x6A,0x36,0xA3,0xB8,
+
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+	  0x07,
+	  0x07,0xA5,0x26,0xC6,0x3D,0x3E,0x25,0xA2,0x56,0xA0,	/* a */
+	  0x07,0x69,0x9F,0x54,0x47,0xE3,0x2A,0xE4,0x56,0xB5,
+	  0x0E,
+	  0x03,0xF7,0x06,0x17,0x98,0xEB,0x99,0xE2,0x38,0xFD,	/* b */
+	  0x6F,0x1B,0xF9,0x5B,0x48,0xFE,0xEB,0x48,0x54,0x25,
+	  0x2B,
+	  0x02,0xF9,0xF8,0x7B,0x7C,0x57,0x4D,0x0B,0xDE,0xCF,	/* x */
+	  0x8A,0x22,0xE6,0x52,0x47,0x75,0xF9,0x8C,0xDE,0xBD,
+	  0xCB,
+	  0x05,0xB9,0x35,0x59,0x0C,0x15,0x5E,0x17,0xEA,0x48,	/* y */
+	  0xEB,0x3F,0xF3,0x71,0x8B,0x89,0x3D,0xF5,0x9A,0x05,
+	  0xD0,
+	  0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFE,0x1A,0xEE,0x14,0x0F,0x11,0x0A,0xFF,0x96,0x13,
+	  0x09 }
 	};
 
-static const EC_CURVE_DATA _EC_X9_62_CHAR2_176V1 = {
-	NID_X9_62_characteristic_two_field,
-	"0100000000000000000000000000000000080000000007",
-	"E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B",
-	"5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2",
-	"8D16C2866798B600F9F08BB4A8E860F3298CE04A5798",
-	"6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C",
-	"00010092537397ECA4F6145799D62B0A19CE06FE26AD", 0xFF6E,
-	NULL, 0,
-	"X9.62 curve over a 176 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+23*6]; }
+	_EC_X9_62_CHAR2_176V1 = {
+	{ NID_X9_62_characteristic_two_field,0,23,0xFF6E },
+	{							/* no seed */
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,
+	  0x00,0x00,0x07,
+	  0x00,0xE4,0xE6,0xDB,0x29,0x95,0x06,0x5C,0x40,0x7D,	/* a */
+	  0x9D,0x39,0xB8,0xD0,0x96,0x7B,0x96,0x70,0x4B,0xA8,
+	  0xE9,0xC9,0x0B,
+	  0x00,0x5D,0xDA,0x47,0x0A,0xBE,0x64,0x14,0xDE,0x8E,	/* b */
+	  0xC1,0x33,0xAE,0x28,0xE9,0xBB,0xD7,0xFC,0xEC,0x0A,
+	  0xE0,0xFF,0xF2,
+	  0x00,0x8D,0x16,0xC2,0x86,0x67,0x98,0xB6,0x00,0xF9,	/* x */
+	  0xF0,0x8B,0xB4,0xA8,0xE8,0x60,0xF3,0x29,0x8C,0xE0,
+	  0x4A,0x57,0x98,
+	  0x00,0x6F,0xA4,0x53,0x9C,0x2D,0xAD,0xDD,0xD6,0xBA,	/* y */
+	  0xB5,0x16,0x7D,0x61,0xB4,0x36,0xE1,0xD9,0x2B,0xB1,
+	  0x6A,0x56,0x2C,
+	  0x00,0x00,0x01,0x00,0x92,0x53,0x73,0x97,0xEC,0xA4,	/* order */
+	  0xF6,0x14,0x57,0x99,0xD6,0x2B,0x0A,0x19,0xCE,0x06,
+	  0xFE,0x26,0xAD }
 	};
 
-static const unsigned char _EC_X9_62_CHAR2_191V1_SEED[] = {
-	0x4E,0x13,0xCA,0x54,0x27,0x44,0xD6,0x96,0xE6,0x76,
-	0x87,0x56,0x15,0x17,0x55,0x2F,0x27,0x9A,0x8C,0x84};
-static const EC_CURVE_DATA _EC_X9_62_CHAR2_191V1 = {
-	NID_X9_62_characteristic_two_field,
-	"800000000000000000000000000000000000000000000201",
-	"2866537B676752636A68F56554E12640276B649EF7526267",
-	"2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC",
-	"36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D",
-	"765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB",
-	"40000000000000000000000004A20E90C39067C893BBB9A5", 2,
-	_EC_X9_62_CHAR2_191V1_SEED, 20,
-	"X9.62 curve over a 191 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
+	_EC_X9_62_CHAR2_191V1 = {
+	{ NID_X9_62_characteristic_two_field,20,24,2 },
+	{ 0x4E,0x13,0xCA,0x54,0x27,0x44,0xD6,0x96,0xE6,0x76,	/* seed */
+	  0x87,0x56,0x15,0x17,0x55,0x2F,0x27,0x9A,0x8C,0x84,
+
+	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x02,0x01,
+	  0x28,0x66,0x53,0x7B,0x67,0x67,0x52,0x63,0x6A,0x68,	/* a */
+	  0xF5,0x65,0x54,0xE1,0x26,0x40,0x27,0x6B,0x64,0x9E,
+	  0xF7,0x52,0x62,0x67,
+	  0x2E,0x45,0xEF,0x57,0x1F,0x00,0x78,0x6F,0x67,0xB0,	/* b */
+	  0x08,0x1B,0x94,0x95,0xA3,0xD9,0x54,0x62,0xF5,0xDE,
+	  0x0A,0xA1,0x85,0xEC,
+	  0x36,0xB3,0xDA,0xF8,0xA2,0x32,0x06,0xF9,0xC4,0xF2,	/* x */
+	  0x99,0xD7,0xB2,0x1A,0x9C,0x36,0x91,0x37,0xF2,0xC8,
+	  0x4A,0xE1,0xAA,0x0D,
+	  0x76,0x5B,0xE7,0x34,0x33,0xB3,0xF9,0x5E,0x33,0x29,	/* y */
+	  0x32,0xE7,0x0E,0xA2,0x45,0xCA,0x24,0x18,0xEA,0x0E,
+	  0xF9,0x80,0x18,0xFB,
+	  0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x04,0xA2,0x0E,0x90,0xC3,0x90,0x67,0xC8,
+	  0x93,0xBB,0xB9,0xA5 }
 	};
 
-static const unsigned char _EC_X9_62_CHAR2_191V2_SEED[] = {
-	0x08,0x71,0xEF,0x2F,0xEF,0x24,0xD6,0x96,0xE6,0x76,
-	0x87,0x56,0x15,0x17,0x58,0xBE,0xE0,0xD9,0x5C,0x15};
-static const EC_CURVE_DATA _EC_X9_62_CHAR2_191V2 = {
-	NID_X9_62_characteristic_two_field,
-	"800000000000000000000000000000000000000000000201",
-	"401028774D7777C7B7666D1366EA432071274F89FF01E718",
-	"0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01",
-	"3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10",
-	"17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A",
-	"20000000000000000000000050508CB89F652824E06B8173", 4,
-	_EC_X9_62_CHAR2_191V2_SEED, 20,
-	"X9.62 curve over a 191 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
+	_EC_X9_62_CHAR2_191V2 = {
+	{ NID_X9_62_characteristic_two_field,20,24,4 },
+	{ 0x08,0x71,0xEF,0x2F,0xEF,0x24,0xD6,0x96,0xE6,0x76,	/* seed */
+	  0x87,0x56,0x15,0x17,0x58,0xBE,0xE0,0xD9,0x5C,0x15,
+
+	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x02,0x01,
+	  0x40,0x10,0x28,0x77,0x4D,0x77,0x77,0xC7,0xB7,0x66,	/* a */
+	  0x6D,0x13,0x66,0xEA,0x43,0x20,0x71,0x27,0x4F,0x89,
+	  0xFF,0x01,0xE7,0x18,
+	  0x06,0x20,0x04,0x8D,0x28,0xBC,0xBD,0x03,0xB6,0x24,	/* b */
+	  0x9C,0x99,0x18,0x2B,0x7C,0x8C,0xD1,0x97,0x00,0xC3,
+	  0x62,0xC4,0x6A,0x01,
+	  0x38,0x09,0xB2,0xB7,0xCC,0x1B,0x28,0xCC,0x5A,0x87,	/* x */
+	  0x92,0x6A,0xAD,0x83,0xFD,0x28,0x78,0x9E,0x81,0xE2,
+	  0xC9,0xE3,0xBF,0x10,
+	  0x17,0x43,0x43,0x86,0x62,0x6D,0x14,0xF3,0xDB,0xF0,	/* y */
+	  0x17,0x60,0xD9,0x21,0x3A,0x3E,0x1C,0xF3,0x7A,0xEC,
+	  0x43,0x7D,0x66,0x8A,
+	  0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x50,0x50,0x8C,0xB8,0x9F,0x65,0x28,0x24,
+	  0xE0,0x6B,0x81,0x73 }
 	};
 
-static const unsigned char _EC_X9_62_CHAR2_191V3_SEED[] = {
-	0xE0,0x53,0x51,0x2D,0xC6,0x84,0xD6,0x96,0xE6,0x76,
-	0x87,0x56,0x15,0x17,0x50,0x67,0xAE,0x78,0x6D,0x1F};
-static const EC_CURVE_DATA _EC_X9_62_CHAR2_191V3 = {
-	NID_X9_62_characteristic_two_field,
-	"800000000000000000000000000000000000000000000201",
-	"6C01074756099122221056911C77D77E77A777E7E7E77FCB",
-	"71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8",
-	"375D4CE24FDE434489DE8746E71786015009E66E38A926DD",
-	"545A39176196575D985999366E6AD34CE0A77CD7127B06BE",
-	"155555555555555555555555610C0B196812BFB6288A3EA3", 6,
-	_EC_X9_62_CHAR2_191V3_SEED, 20,
-	"X9.62 curve over a 191 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+24*6]; }
+	_EC_X9_62_CHAR2_191V3 = {
+	{ NID_X9_62_characteristic_two_field,20,24,6 },
+	{ 0xE0,0x53,0x51,0x2D,0xC6,0x84,0xD6,0x96,0xE6,0x76,	/* seed */
+	  0x87,0x56,0x15,0x17,0x50,0x67,0xAE,0x78,0x6D,0x1F,
+
+	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x02,0x01,
+	  0x6C,0x01,0x07,0x47,0x56,0x09,0x91,0x22,0x22,0x10,	/* a */
+	  0x56,0x91,0x1C,0x77,0xD7,0x7E,0x77,0xA7,0x77,0xE7,
+	  0xE7,0xE7,0x7F,0xCB,
+	  0x71,0xFE,0x1A,0xF9,0x26,0xCF,0x84,0x79,0x89,0xEF,	/* b */
+	  0xEF,0x8D,0xB4,0x59,0xF6,0x63,0x94,0xD9,0x0F,0x32,
+	  0xAD,0x3F,0x15,0xE8,
+	  0x37,0x5D,0x4C,0xE2,0x4F,0xDE,0x43,0x44,0x89,0xDE,	/* x */
+	  0x87,0x46,0xE7,0x17,0x86,0x01,0x50,0x09,0xE6,0x6E,
+	  0x38,0xA9,0x26,0xDD,
+	  0x54,0x5A,0x39,0x17,0x61,0x96,0x57,0x5D,0x98,0x59,	/* y */
+	  0x99,0x36,0x6E,0x6A,0xD3,0x4C,0xE0,0xA7,0x7C,0xD7,
+	  0x12,0x7B,0x06,0xBE,
+	  0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,	/* order */
+	  0x55,0x55,0x61,0x0C,0x0B,0x19,0x68,0x12,0xBF,0xB6,
+	  0x28,0x8A,0x3E,0xA3 }
 	};
 
-static const EC_CURVE_DATA _EC_X9_62_CHAR2_208W1 = {
-	NID_X9_62_characteristic_two_field,
-	"010000000000000000000000000000000800000000000000000007",
-	"0000000000000000000000000000000000000000000000000000",
-	"C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E",
-	"89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A",
-	"0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3",
-	"000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", 0xFE48,
-	NULL, 0,
-	"X9.62 curve over a 208 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+27*6]; }
+	_EC_X9_62_CHAR2_208W1 = {
+	{ NID_X9_62_characteristic_two_field,0,27,0xFE48 },
+	{							/* no seed */
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0xC8,0x61,0x9E,0xD4,0x5A,0x62,0xE6,0x21,0x2E,	/* b */
+	  0x11,0x60,0x34,0x9E,0x2B,0xFA,0x84,0x44,0x39,0xFA,
+	  0xFC,0x2A,0x3F,0xD1,0x63,0x8F,0x9E,
+	  0x00,0x89,0xFD,0xFB,0xE4,0xAB,0xE1,0x93,0xDF,0x95,	/* x */
+	  0x59,0xEC,0xF0,0x7A,0xC0,0xCE,0x78,0x55,0x4E,0x27,
+	  0x84,0xEB,0x8C,0x1E,0xD1,0xA5,0x7A,
+	  0x00,0x0F,0x55,0xB5,0x1A,0x06,0xE7,0x8E,0x9A,0xC3,	/* y */
+	  0x8A,0x03,0x5F,0xF5,0x20,0xD8,0xB0,0x17,0x81,0xBE,
+	  0xB1,0xA6,0xBB,0x08,0x61,0x7D,0xE3,
+	  0x00,0x00,0x01,0x01,0xBA,0xF9,0x5C,0x97,0x23,0xC5,	/* order */
+	  0x7B,0x6C,0x21,0xDA,0x2E,0xFF,0x2D,0x5E,0xD5,0x88,
+	  0xBD,0xD5,0x71,0x7E,0x21,0x2F,0x9D }
 	};
 
-static const unsigned char _EC_X9_62_CHAR2_239V1_SEED[] = {
-	0xD3,0x4B,0x9A,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,
-	0x51,0x75,0xCA,0x71,0xB9,0x20,0xBF,0xEF,0xB0,0x5D};
-static const EC_CURVE_DATA _EC_X9_62_CHAR2_239V1 = {
-	NID_X9_62_characteristic_two_field,
-	"800000000000000000000000000000000000000000000000001000000001",
-	"32010857077C5431123A46B808906756F543423E8D27877578125778AC76",
-	"790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16",
-	"57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D",
-	"61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305",
-	"2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", 4,
-	_EC_X9_62_CHAR2_239V1_SEED, 20,
-	"X9.62 curve over a 239 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
+	_EC_X9_62_CHAR2_239V1 = {
+	{ NID_X9_62_characteristic_two_field,20,30,4 },
+	{ 0xD3,0x4B,0x9A,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,	/* seed */
+	  0x51,0x75,0xCA,0x71,0xB9,0x20,0xBF,0xEF,0xB0,0x5D,
+
+	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,
+
+	  0x32,0x01,0x08,0x57,0x07,0x7C,0x54,0x31,0x12,0x3A,	/* a */
+	  0x46,0xB8,0x08,0x90,0x67,0x56,0xF5,0x43,0x42,0x3E,
+	  0x8D,0x27,0x87,0x75,0x78,0x12,0x57,0x78,0xAC,0x76,
+
+	  0x79,0x04,0x08,0xF2,0xEE,0xDA,0xF3,0x92,0xB0,0x12,	/* b */
+	  0xED,0xEF,0xB3,0x39,0x2F,0x30,0xF4,0x32,0x7C,0x0C,
+	  0xA3,0xF3,0x1F,0xC3,0x83,0xC4,0x22,0xAA,0x8C,0x16,
+
+	  0x57,0x92,0x70,0x98,0xFA,0x93,0x2E,0x7C,0x0A,0x96,	/* x */
+	  0xD3,0xFD,0x5B,0x70,0x6E,0xF7,0xE5,0xF5,0xC1,0x56,
+	  0xE1,0x6B,0x7E,0x7C,0x86,0x03,0x85,0x52,0xE9,0x1D,
+
+	  0x61,0xD8,0xEE,0x50,0x77,0xC3,0x3F,0xEC,0xF6,0xF1,	/* y */
+	  0xA1,0x6B,0x26,0x8D,0xE4,0x69,0xC3,0xC7,0x74,0x4E,
+	  0xA9,0xA9,0x71,0x64,0x9F,0xC7,0xA9,0x61,0x63,0x05,
+
+	  0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* order */
+	  0x00,0x00,0x00,0x00,0x00,0x0F,0x4D,0x42,0xFF,0xE1,
+	  0x49,0x2A,0x49,0x93,0xF1,0xCA,0xD6,0x66,0xE4,0x47 }
 	};
 
-static const unsigned char _EC_X9_62_CHAR2_239V2_SEED[] = {
-	0x2A,0xA6,0x98,0x2F,0xDF,0xA4,0xD6,0x96,0xE6,0x76,
-	0x87,0x56,0x15,0x17,0x5D,0x26,0x67,0x27,0x27,0x7D};
-static const EC_CURVE_DATA _EC_X9_62_CHAR2_239V2 = {
-	NID_X9_62_characteristic_two_field,
-	"800000000000000000000000000000000000000000000000001000000001",
-	"4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F",
-	"5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B",
-	"28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205",
-	"5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833",
-	"1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", 6,
-	_EC_X9_62_CHAR2_239V2_SEED, 20,
-	"X9.62 curve over a 239 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
+	_EC_X9_62_CHAR2_239V2 = {
+	{ NID_X9_62_characteristic_two_field,20,30,6 },
+	{ 0x2A,0xA6,0x98,0x2F,0xDF,0xA4,0xD6,0x96,0xE6,0x76,	/* seed */
+	  0x87,0x56,0x15,0x17,0x5D,0x26,0x67,0x27,0x27,0x7D,
+
+	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,
+
+	  0x42,0x30,0x01,0x77,0x57,0xA7,0x67,0xFA,0xE4,0x23,	/* a */
+	  0x98,0x56,0x9B,0x74,0x63,0x25,0xD4,0x53,0x13,0xAF,
+	  0x07,0x66,0x26,0x64,0x79,0xB7,0x56,0x54,0xE6,0x5F,
+
+	  0x50,0x37,0xEA,0x65,0x41,0x96,0xCF,0xF0,0xCD,0x82,	/* b */
+	  0xB2,0xC1,0x4A,0x2F,0xCF,0x2E,0x3F,0xF8,0x77,0x52,
+	  0x85,0xB5,0x45,0x72,0x2F,0x03,0xEA,0xCD,0xB7,0x4B,
+
+	  0x28,0xF9,0xD0,0x4E,0x90,0x00,0x69,0xC8,0xDC,0x47,	/* x */
+	  0xA0,0x85,0x34,0xFE,0x76,0xD2,0xB9,0x00,0xB7,0xD7,
+	  0xEF,0x31,0xF5,0x70,0x9F,0x20,0x0C,0x4C,0xA2,0x05,
+
+	  0x56,0x67,0x33,0x4C,0x45,0xAF,0xF3,0xB5,0xA0,0x3B,	/* y */
+	  0xAD,0x9D,0xD7,0x5E,0x2C,0x71,0xA9,0x93,0x62,0x56,
+	  0x7D,0x54,0x53,0xF7,0xFA,0x6E,0x22,0x7E,0xC8,0x33,
+
+	  0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,	/* order */
+	  0x55,0x55,0x55,0x55,0x55,0x3C,0x6F,0x28,0x85,0x25,
+	  0x9C,0x31,0xE3,0xFC,0xDF,0x15,0x46,0x24,0x52,0x2D }
 	};
 
-static const unsigned char _EC_X9_62_CHAR2_239V3_SEED[] = {
-	0x9E,0x07,0x6F,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,
-	0x51,0x75,0xE1,0x1E,0x9F,0xDD,0x77,0xF9,0x20,0x41};
-static const EC_CURVE_DATA _EC_X9_62_CHAR2_239V3 = {
-	NID_X9_62_characteristic_two_field,
-	"800000000000000000000000000000000000000000000000001000000001",
-	"01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F",
-	"6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40",
-	"70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92",
-	"2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461",
-	"0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", 0xA,
-	_EC_X9_62_CHAR2_239V3_SEED, 20,
-	"X9.62 curve over a 239 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+30*6]; }
+	_EC_X9_62_CHAR2_239V3 = {
+	{ NID_X9_62_characteristic_two_field,20,30,0xA },
+	{ 0x9E,0x07,0x6F,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,	/* seed */
+	  0x51,0x75,0xE1,0x1E,0x9F,0xDD,0x77,0xF9,0x20,0x41,
+
+	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,
+
+	  0x01,0x23,0x87,0x74,0x66,0x6A,0x67,0x76,0x6D,0x66,	/* a */
+	  0x76,0xF7,0x78,0xE6,0x76,0xB6,0x69,0x99,0x17,0x66,
+	  0x66,0xE6,0x87,0x66,0x6D,0x87,0x66,0xC6,0x6A,0x9F,
+
+	  0x6A,0x94,0x19,0x77,0xBA,0x9F,0x6A,0x43,0x51,0x99,	/* b */
+	  0xAC,0xFC,0x51,0x06,0x7E,0xD5,0x87,0xF5,0x19,0xC5,
+	  0xEC,0xB5,0x41,0xB8,0xE4,0x41,0x11,0xDE,0x1D,0x40,
+
+	  0x70,0xF6,0xE9,0xD0,0x4D,0x28,0x9C,0x4E,0x89,0x91,	/* x */
+	  0x3C,0xE3,0x53,0x0B,0xFD,0xE9,0x03,0x97,0x7D,0x42,
+	  0xB1,0x46,0xD5,0x39,0xBF,0x1B,0xDE,0x4E,0x9C,0x92,
+
+	  0x2E,0x5A,0x0E,0xAF,0x6E,0x5E,0x13,0x05,0xB9,0x00,	/* y */
+	  0x4D,0xCE,0x5C,0x0E,0xD7,0xFE,0x59,0xA3,0x56,0x08,
+	  0xF3,0x38,0x37,0xC8,0x16,0xD8,0x0B,0x79,0xF4,0x61,
+
+	  0x0C,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,	/* order */
+	  0xCC,0xCC,0xCC,0xCC,0xCC,0xAC,0x49,0x12,0xD2,0xD9,
+	  0xDF,0x90,0x3E,0xF9,0x88,0x8B,0x8A,0x0E,0x4C,0xFF }
 	};
 
-static const EC_CURVE_DATA _EC_X9_62_CHAR2_272W1 = {
-	NID_X9_62_characteristic_two_field,
-	"010000000000000000000000000000000000000000000000000000010000000000000"
-	"B",
-	"91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20",
-	"7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7",
-	"6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D",
-	"10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23",
-	"000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521",
-	0xFF06,
-	NULL, 0,
-	"X9.62 curve over a 272 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+35*6]; }
+	_EC_X9_62_CHAR2_272W1 = {
+	{ NID_X9_62_characteristic_two_field,0,35,0xFF06 },
+	{							/* no seed */
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x0B,
+	  0x00,0x91,0xA0,0x91,0xF0,0x3B,0x5F,0xBA,0x4A,0xB2,	/* a */
+	  0xCC,0xF4,0x9C,0x4E,0xDD,0x22,0x0F,0xB0,0x28,0x71,
+	  0x2D,0x42,0xBE,0x75,0x2B,0x2C,0x40,0x09,0x4D,0xBA,
+	  0xCD,0xB5,0x86,0xFB,0x20,
+	  0x00,0x71,0x67,0xEF,0xC9,0x2B,0xB2,0xE3,0xCE,0x7C,	/* b */
+	  0x8A,0xAA,0xFF,0x34,0xE1,0x2A,0x9C,0x55,0x70,0x03,
+	  0xD7,0xC7,0x3A,0x6F,0xAF,0x00,0x3F,0x99,0xF6,0xCC,
+	  0x84,0x82,0xE5,0x40,0xF7,
+	  0x00,0x61,0x08,0xBA,0xBB,0x2C,0xEE,0xBC,0xF7,0x87,	/* x */
+	  0x05,0x8A,0x05,0x6C,0xBE,0x0C,0xFE,0x62,0x2D,0x77,
+	  0x23,0xA2,0x89,0xE0,0x8A,0x07,0xAE,0x13,0xEF,0x0D,
+	  0x10,0xD1,0x71,0xDD,0x8D,
+	  0x00,0x10,0xC7,0x69,0x57,0x16,0x85,0x1E,0xEF,0x6B,	/* y */
+	  0xA7,0xF6,0x87,0x2E,0x61,0x42,0xFB,0xD2,0x41,0xB8,
+	  0x30,0xFF,0x5E,0xFC,0xAC,0xEC,0xCA,0xB0,0x5E,0x02,
+	  0x00,0x5D,0xDE,0x9D,0x23,
+	  0x00,0x00,0x01,0x00,0xFA,0xF5,0x13,0x54,0xE0,0xE3,	/* order */
+	  0x9E,0x48,0x92,0xDF,0x6E,0x31,0x9C,0x72,0xC8,0x16,
+	  0x16,0x03,0xFA,0x45,0xAA,0x7B,0x99,0x8A,0x16,0x7B,
+	  0x8F,0x1E,0x62,0x95,0x21 }
 	};
 
-static const EC_CURVE_DATA _EC_X9_62_CHAR2_304W1 = {
-	NID_X9_62_characteristic_two_field,
-	"010000000000000000000000000000000000000000000000000000000000000000000"
-	"000000807",
-	"FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A039"
-	"6C8E681",
-	"BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E558"
-	"27340BE",
-	"197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F7"
-	"40A2614",
-	"E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1"
-	"B92C03B",
-	"000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164"
-	"443051D", 0xFE2E,
-	NULL, 0,
-	"X9.62 curve over a 304 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+39*6]; }
+	_EC_X9_62_CHAR2_304W1 = {
+	{ NID_X9_62_characteristic_two_field,0,39,0xFE2E },
+	{							/* no seed */
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x07,
+	  0x00,0xFD,0x0D,0x69,0x31,0x49,0xA1,0x18,0xF6,0x51,	/* a */
+	  0xE6,0xDC,0xE6,0x80,0x20,0x85,0x37,0x7E,0x5F,0x88,
+	  0x2D,0x1B,0x51,0x0B,0x44,0x16,0x00,0x74,0xC1,0x28,
+	  0x80,0x78,0x36,0x5A,0x03,0x96,0xC8,0xE6,0x81,
+	  0x00,0xBD,0xDB,0x97,0xE5,0x55,0xA5,0x0A,0x90,0x8E,	/* b */
+	  0x43,0xB0,0x1C,0x79,0x8E,0xA5,0xDA,0xA6,0x78,0x8F,
+	  0x1E,0xA2,0x79,0x4E,0xFC,0xF5,0x71,0x66,0xB8,0xC1,
+	  0x40,0x39,0x60,0x1E,0x55,0x82,0x73,0x40,0xBE,
+	  0x00,0x19,0x7B,0x07,0x84,0x5E,0x9B,0xE2,0xD9,0x6A,	/* x */
+	  0xDB,0x0F,0x5F,0x3C,0x7F,0x2C,0xFF,0xBD,0x7A,0x3E,
+	  0xB8,0xB6,0xFE,0xC3,0x5C,0x7F,0xD6,0x7F,0x26,0xDD,
+	  0xF6,0x28,0x5A,0x64,0x4F,0x74,0x0A,0x26,0x14,
+	  0x00,0xE1,0x9F,0xBE,0xB7,0x6E,0x0D,0xA1,0x71,0x51,	/* y */
+	  0x7E,0xCF,0x40,0x1B,0x50,0x28,0x9B,0xF0,0x14,0x10,
+	  0x32,0x88,0x52,0x7A,0x9B,0x41,0x6A,0x10,0x5E,0x80,
+	  0x26,0x0B,0x54,0x9F,0xDC,0x1B,0x92,0xC0,0x3B,
+	  0x00,0x00,0x01,0x01,0xD5,0x56,0x57,0x2A,0xAB,0xAC,	/* order */
+	  0x80,0x01,0x01,0xD5,0x56,0x57,0x2A,0xAB,0xAC,0x80,
+	  0x01,0x02,0x2D,0x5C,0x91,0xDD,0x17,0x3F,0x8F,0xB5,
+	  0x61,0xDA,0x68,0x99,0x16,0x44,0x43,0x05,0x1D }
 	};
 
-static const unsigned char _EC_X9_62_CHAR2_359V1_SEED[] = {
-	0x2B,0x35,0x49,0x20,0xB7,0x24,0xD6,0x96,0xE6,0x76,
-	0x87,0x56,0x15,0x17,0x58,0x5B,0xA1,0x33,0x2D,0xC6};
-static const EC_CURVE_DATA _EC_X9_62_CHAR2_359V1 = {
-	NID_X9_62_characteristic_two_field,
-	"800000000000000000000000000000000000000000000000000000000000000000000"
-	"000100000000000000001",
-	"5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05"
-	"656FB549016A96656A557",
-	"2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC34562608968"
-	"7742B6329E70680231988",
-	"3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE9"
-	"8E8E707C07A2239B1B097",
-	"53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E"
-	"4AE2DE211305A407104BD",
-	"01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB9"
-	"64FE7719E74F490758D3B", 0x4C,
-	_EC_X9_62_CHAR2_359V1_SEED, 20,
-	"X9.62 curve over a 359 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[20+45*6]; }
+	_EC_X9_62_CHAR2_359V1 = {
+	{ NID_X9_62_characteristic_two_field,20,45,0x4C },
+	{ 0x2B,0x35,0x49,0x20,0xB7,0x24,0xD6,0x96,0xE6,0x76,	/* seed */
+	  0x87,0x56,0x15,0x17,0x58,0x5B,0xA1,0x33,0x2D,0xC6,
+
+	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x01,
+	  0x56,0x67,0x67,0x6A,0x65,0x4B,0x20,0x75,0x4F,0x35,	/* a */
+	  0x6E,0xA9,0x20,0x17,0xD9,0x46,0x56,0x7C,0x46,0x67,
+	  0x55,0x56,0xF1,0x95,0x56,0xA0,0x46,0x16,0xB5,0x67,
+	  0xD2,0x23,0xA5,0xE0,0x56,0x56,0xFB,0x54,0x90,0x16,
+	  0xA9,0x66,0x56,0xA5,0x57,
+	  0x24,0x72,0xE2,0xD0,0x19,0x7C,0x49,0x36,0x3F,0x1F,	/* b */
+	  0xE7,0xF5,0xB6,0xDB,0x07,0x5D,0x52,0xB6,0x94,0x7D,
+	  0x13,0x5D,0x8C,0xA4,0x45,0x80,0x5D,0x39,0xBC,0x34,
+	  0x56,0x26,0x08,0x96,0x87,0x74,0x2B,0x63,0x29,0xE7,
+	  0x06,0x80,0x23,0x19,0x88,
+	  0x3C,0x25,0x8E,0xF3,0x04,0x77,0x67,0xE7,0xED,0xE0,	/* x */
+	  0xF1,0xFD,0xAA,0x79,0xDA,0xEE,0x38,0x41,0x36,0x6A,
+	  0x13,0x2E,0x16,0x3A,0xCE,0xD4,0xED,0x24,0x01,0xDF,
+	  0x9C,0x6B,0xDC,0xDE,0x98,0xE8,0xE7,0x07,0xC0,0x7A,
+	  0x22,0x39,0xB1,0xB0,0x97,
+	  0x53,0xD7,0xE0,0x85,0x29,0x54,0x70,0x48,0x12,0x1E,	/* y */
+	  0x9C,0x95,0xF3,0x79,0x1D,0xD8,0x04,0x96,0x39,0x48,
+	  0xF3,0x4F,0xAE,0x7B,0xF4,0x4E,0xA8,0x23,0x65,0xDC,
+	  0x78,0x68,0xFE,0x57,0xE4,0xAE,0x2D,0xE2,0x11,0x30,
+	  0x5A,0x40,0x71,0x04,0xBD,
+	  0x01,0xAF,0x28,0x6B,0xCA,0x1A,0xF2,0x86,0xBC,0xA1,	/* order */
+	  0xAF,0x28,0x6B,0xCA,0x1A,0xF2,0x86,0xBC,0xA1,0xAF,
+	  0x28,0x6B,0xC9,0xFB,0x8F,0x6B,0x85,0xC5,0x56,0x89,
+	  0x2C,0x20,0xA7,0xEB,0x96,0x4F,0xE7,0x71,0x9E,0x74,
+	  0xF4,0x90,0x75,0x8D,0x3B }
 	};
 
-static const EC_CURVE_DATA _EC_X9_62_CHAR2_368W1 = {
-	NID_X9_62_characteristic_two_field,
-	"010000000000000000000000000000000000000000000000000000000000000000000"
-	"0002000000000000000000007",
-	"E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62"
-	"F0AB7519CCD2A1A906AE30D",
-	"FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112"
-	"D84D164F444F8F74786046A",
-	"1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E78"
-	"9E927BE216F02E1FB136A5F",
-	"7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855"
-	"ADAA81E2A0750B80FDA2310",
-	"00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E90"
-	"9AE40A6F131E9CFCE5BD967", 0xFF70,
-	NULL, 0,
-	"X9.62 curve over a 368 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+47*6]; }
+	_EC_X9_62_CHAR2_368W1 = {
+	{ NID_X9_62_characteristic_two_field,0,47,0xFF70 },
+	{							/* no seed */
+	  0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+	  0x00,0xE0,0xD2,0xEE,0x25,0x09,0x52,0x06,0xF5,0xE2,	/* a */
+	  0xA4,0xF9,0xED,0x22,0x9F,0x1F,0x25,0x6E,0x79,0xA0,
+	  0xE2,0xB4,0x55,0x97,0x0D,0x8D,0x0D,0x86,0x5B,0xD9,
+	  0x47,0x78,0xC5,0x76,0xD6,0x2F,0x0A,0xB7,0x51,0x9C,
+	  0xCD,0x2A,0x1A,0x90,0x6A,0xE3,0x0D,
+	  0x00,0xFC,0x12,0x17,0xD4,0x32,0x0A,0x90,0x45,0x2C,	/* b */
+	  0x76,0x0A,0x58,0xED,0xCD,0x30,0xC8,0xDD,0x06,0x9B,
+	  0x3C,0x34,0x45,0x38,0x37,0xA3,0x4E,0xD5,0x0C,0xB5,
+	  0x49,0x17,0xE1,0xC2,0x11,0x2D,0x84,0xD1,0x64,0xF4,
+	  0x44,0xF8,0xF7,0x47,0x86,0x04,0x6A,
+	  0x00,0x10,0x85,0xE2,0x75,0x53,0x81,0xDC,0xCC,0xE3,	/* x */
+	  0xC1,0x55,0x7A,0xFA,0x10,0xC2,0xF0,0xC0,0xC2,0x82,
+	  0x56,0x46,0xC5,0xB3,0x4A,0x39,0x4C,0xBC,0xFA,0x8B,
+	  0xC1,0x6B,0x22,0xE7,0xE7,0x89,0xE9,0x27,0xBE,0x21,
+	  0x6F,0x02,0xE1,0xFB,0x13,0x6A,0x5F,
+	  0x00,0x7B,0x3E,0xB1,0xBD,0xDC,0xBA,0x62,0xD5,0xD8,	/* y */
+	  0xB2,0x05,0x9B,0x52,0x57,0x97,0xFC,0x73,0x82,0x2C,
+	  0x59,0x05,0x9C,0x62,0x3A,0x45,0xFF,0x38,0x43,0xCE,
+	  0xE8,0xF8,0x7C,0xD1,0x85,0x5A,0xDA,0xA8,0x1E,0x2A,
+	  0x07,0x50,0xB8,0x0F,0xDA,0x23,0x10,
+	  0x00,0x00,0x01,0x00,0x90,0x51,0x2D,0xA9,0xAF,0x72,	/* order */
+	  0xB0,0x83,0x49,0xD9,0x8A,0x5D,0xD4,0xC7,0xB0,0x53,
+	  0x2E,0xCA,0x51,0xCE,0x03,0xE2,0xD1,0x0F,0x3B,0x7A,
+	  0xC5,0x79,0xBD,0x87,0xE9,0x09,0xAE,0x40,0xA6,0xF1,
+	  0x31,0xE9,0xCF,0xCE,0x5B,0xD9,0x67 }
 	};
 
-static const EC_CURVE_DATA _EC_X9_62_CHAR2_431R1 = {
-	NID_X9_62_characteristic_two_field,
-	"800000000000000000000000000000000000000000000000000000000000000000000"
-	"000000001000000000000000000000000000001",
-	"1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0E"
-	"B9906D0957F6C6FEACD615468DF104DE296CD8F",
-	"10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B6"
-	"26D4E50A8DD731B107A9962381FB5D807BF2618",
-	"120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C2"
-	"1E7C5EFE965361F6C2999C0C247B0DBD70CE6B7",
-	"20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6"
-	"ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760",
-	"0340340340340340340340340340340340340340340340340340340323C313FAB5058"
-	"9703B5EC68D3587FEC60D161CC149C1AD4A91", 0x2760,
-	NULL, 0,
-	"X9.62 curve over a 431 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+54*6]; }
+	_EC_X9_62_CHAR2_431R1 = {
+	{ NID_X9_62_characteristic_two_field,0,54,0x2760 },
+	{							/* no seed */
+	  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x01,
+	  0x1A,0x82,0x7E,0xF0,0x0D,0xD6,0xFC,0x0E,0x23,0x4C,	/* a */
+	  0xAF,0x04,0x6C,0x6A,0x5D,0x8A,0x85,0x39,0x5B,0x23,
+	  0x6C,0xC4,0xAD,0x2C,0xF3,0x2A,0x0C,0xAD,0xBD,0xC9,
+	  0xDD,0xF6,0x20,0xB0,0xEB,0x99,0x06,0xD0,0x95,0x7F,
+	  0x6C,0x6F,0xEA,0xCD,0x61,0x54,0x68,0xDF,0x10,0x4D,
+	  0xE2,0x96,0xCD,0x8F,
+	  0x10,0xD9,0xB4,0xA3,0xD9,0x04,0x7D,0x8B,0x15,0x43,	/* b */
+	  0x59,0xAB,0xFB,0x1B,0x7F,0x54,0x85,0xB0,0x4C,0xEB,
+	  0x86,0x82,0x37,0xDD,0xC9,0xDE,0xDA,0x98,0x2A,0x67,
+	  0x9A,0x5A,0x91,0x9B,0x62,0x6D,0x4E,0x50,0xA8,0xDD,
+	  0x73,0x1B,0x10,0x7A,0x99,0x62,0x38,0x1F,0xB5,0xD8,
+	  0x07,0xBF,0x26,0x18,
+	  0x12,0x0F,0xC0,0x5D,0x3C,0x67,0xA9,0x9D,0xE1,0x61,	/* x */
+	  0xD2,0xF4,0x09,0x26,0x22,0xFE,0xCA,0x70,0x1B,0xE4,
+	  0xF5,0x0F,0x47,0x58,0x71,0x4E,0x8A,0x87,0xBB,0xF2,
+	  0xA6,0x58,0xEF,0x8C,0x21,0xE7,0xC5,0xEF,0xE9,0x65,
+	  0x36,0x1F,0x6C,0x29,0x99,0xC0,0xC2,0x47,0xB0,0xDB,
+	  0xD7,0x0C,0xE6,0xB7,
+	  0x20,0xD0,0xAF,0x89,0x03,0xA9,0x6F,0x8D,0x5F,0xA2,	/* y */
+	  0xC2,0x55,0x74,0x5D,0x3C,0x45,0x1B,0x30,0x2C,0x93,
+	  0x46,0xD9,0xB7,0xE4,0x85,0xE7,0xBC,0xE4,0x1F,0x6B,
+	  0x59,0x1F,0x3E,0x8F,0x6A,0xDD,0xCB,0xB0,0xBC,0x4C,
+	  0x2F,0x94,0x7A,0x7D,0xE1,0xA8,0x9B,0x62,0x5D,0x6A,
+	  0x59,0x8B,0x37,0x60,
+	  0x00,0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,	/* order */
+	  0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,0x03,
+	  0x40,0x34,0x03,0x40,0x34,0x03,0x40,0x34,0x03,0x23,
+	  0xC3,0x13,0xFA,0xB5,0x05,0x89,0x70,0x3B,0x5E,0xC6,
+	  0x8D,0x35,0x87,0xFE,0xC6,0x0D,0x16,0x1C,0xC1,0x49,
+	  0xC1,0xAD,0x4A,0x91 }
 	};
 
-static const EC_CURVE_DATA _EC_WTLS_1 = {
-	NID_X9_62_characteristic_two_field,
-	"020000000000000000000000000201",
-	"1",
-	"1",
-	"01667979A40BA497E5D5C270780617",
-	"00F44B4AF1ECC2630E08785CEBCC15",
-	"00FFFFFFFFFFFFFFFDBF91AF6DEA73", 2,
-	NULL, 0,
-	"WTLS curve over a 113 bit binary field"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+15*6]; }
+	_EC_WTLS_1 = {
+	{ NID_X9_62_characteristic_two_field,0,15,2 },
+	{							/* no seed */
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x02,0x01,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x01,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x01,
+	  0x01,0x66,0x79,0x79,0xA4,0x0B,0xA4,0x97,0xE5,0xD5,	/* x */
+	  0xC2,0x70,0x78,0x06,0x17,
+	  0x00,0xF4,0x4B,0x4A,0xF1,0xEC,0xC2,0x63,0x0E,0x08,	/* y */
+	  0x78,0x5C,0xEB,0xCC,0x15,
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xBF,	/* order */
+	  0x91,0xAF,0x6D,0xEA,0x73 }
 	};
 
 /* IPSec curves */
@@ -1001,17 +1765,27 @@
  * As the group order is not a prime this curve is not suitable
  * for ECDSA.
  */
-static const EC_CURVE_DATA _EC_IPSEC_155_ID3 = {
-	NID_X9_62_characteristic_two_field,
-	"0800000000000000000000004000000000000001",
-	"0",
-	"07338f",
-	"7b",
-	"1c8",
-	"2AAAAAAAAAAAAAAAAAAC7F3C7881BD0868FA86C",3,
-	NULL, 0,
-	"\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n"
-	"\tNot suitable for ECDSA.\n\tQuestionable extension field!"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+20*6]; }
+	_EC_IPSEC_155_ID3 = {
+	{ NID_X9_62_characteristic_two_field,0,20,3 },
+	{							/* no seed */
+	  0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x33,0x8f,
+
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* x */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7b,
+
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* y */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xc8,
+
+	  0x02,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,	/* order */
+	  0xC7,0xF3,0xC7,0x88,0x1B,0xD0,0x86,0x8F,0xA8,0x6C }
 	};
 
 /* NOTE: The of curves over a extension field of non prime degree
@@ -1019,106 +1793,118 @@
  * As the group order is not a prime this curve is not suitable
  * for ECDSA.
  */
-static const EC_CURVE_DATA _EC_IPSEC_185_ID4 = {
-	NID_X9_62_characteristic_two_field,
-	"020000000000000000000000000000200000000000000001",
-	"0",
-	"1ee9",
-	"18",
-	"0d",
-	"FFFFFFFFFFFFFFFFFFFFFFEDF97C44DB9F2420BAFCA75E",2,
-	NULL, 0,
-	"\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n"
-	"\tNot suitable for ECDSA.\n\tQuestionable extension field!"
+static const struct { EC_CURVE_DATA h; unsigned char data[0+24*6]; }
+	_EC_IPSEC_185_ID4 = {
+	{ NID_X9_62_characteristic_two_field,0,24,2 },
+	{							/* no seed */
+	  0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* p */
+	  0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x01,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* a */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* b */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x1e,0xe9,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* x */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x18,
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	/* y */
+	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	  0x00,0x00,0x00,0x0d,
+	  0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	/* order */
+	  0xFF,0xFF,0xED,0xF9,0x7C,0x44,0xDB,0x9F,0x24,0x20,
+	  0xBA,0xFC,0xA7,0x5E }
 	};
 
 typedef struct _ec_list_element_st {
 	int	nid;
 	const EC_CURVE_DATA *data;
+	const char *comment;
 	} ec_list_element;
 
 static const ec_list_element curve_list[] = {
 	/* prime field curves */	
 	/* secg curves */
-	{ NID_secp112r1, &_EC_SECG_PRIME_112R1},
-	{ NID_secp112r2, &_EC_SECG_PRIME_112R2},
-	{ NID_secp128r1, &_EC_SECG_PRIME_128R1},
-	{ NID_secp128r2, &_EC_SECG_PRIME_128R2},
-	{ NID_secp160k1, &_EC_SECG_PRIME_160K1},
-	{ NID_secp160r1, &_EC_SECG_PRIME_160R1},
-	{ NID_secp160r2, &_EC_SECG_PRIME_160R2},
+	{ NID_secp112r1, &_EC_SECG_PRIME_112R1.h, "SECG/WTLS curve over a 112 bit prime field"},
+	{ NID_secp112r2, &_EC_SECG_PRIME_112R2.h, "SECG curve over a 112 bit prime field"},
+	{ NID_secp128r1, &_EC_SECG_PRIME_128R1.h, "SECG curve over a 128 bit prime field"},
+	{ NID_secp128r2, &_EC_SECG_PRIME_128R2.h, "SECG curve over a 128 bit prime field"},
+	{ NID_secp160k1, &_EC_SECG_PRIME_160K1.h, "SECG curve over a 160 bit prime field"},
+	{ NID_secp160r1, &_EC_SECG_PRIME_160R1.h, "SECG curve over a 160 bit prime field"},
+	{ NID_secp160r2, &_EC_SECG_PRIME_160R2.h, "SECG/WTLS curve over a 160 bit prime field"},
 	/* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */
-	{ NID_secp192k1, &_EC_SECG_PRIME_192K1},
-	{ NID_secp224k1, &_EC_SECG_PRIME_224K1},
-	{ NID_secp224r1, &_EC_NIST_PRIME_224},
-	{ NID_secp256k1, &_EC_SECG_PRIME_256K1},
+	{ NID_secp192k1, &_EC_SECG_PRIME_192K1.h, "SECG curve over a 192 bit prime field"},
+	{ NID_secp224k1, &_EC_SECG_PRIME_224K1.h, "SECG curve over a 224 bit prime field"},
+	{ NID_secp224r1, &_EC_NIST_PRIME_224.h,   "NIST/SECG curve over a 224 bit prime field"},
+	{ NID_secp256k1, &_EC_SECG_PRIME_256K1.h, "SECG curve over a 256 bit prime field"},
 	/* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
-	{ NID_secp384r1, &_EC_NIST_PRIME_384},
-	{ NID_secp521r1, &_EC_NIST_PRIME_521},
+	{ NID_secp384r1, &_EC_NIST_PRIME_384.h, "NIST/SECG curve over a 384 bit prime field"},
+	{ NID_secp521r1, &_EC_NIST_PRIME_521.h, "NIST/SECG curve over a 521 bit prime field"},
 	/* X9.62 curves */
-	{ NID_X9_62_prime192v1, &_EC_NIST_PRIME_192},
-	{ NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2},
-	{ NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3},
-	{ NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1},
-	{ NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2},
-	{ NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3},
-	{ NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1},
+	{ NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, "NIST/X9.62/SECG curve over a 192 bit prime field"},
+	{ NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, "X9.62 curve over a 192 bit prime field"},
+	{ NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, "X9.62 curve over a 192 bit prime field"},
+	{ NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, "X9.62 curve over a 239 bit prime field"},
+	{ NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, "X9.62 curve over a 239 bit prime field"},
+	{ NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, "X9.62 curve over a 239 bit prime field"},
+	{ NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, "X9.62/SECG curve over a 256 bit prime field"},
 	/* characteristic two field curves */
 	/* NIST/SECG curves */
-	{ NID_sect113r1, &_EC_SECG_CHAR2_113R1},
-	{ NID_sect113r2, &_EC_SECG_CHAR2_113R2},
-	{ NID_sect131r1, &_EC_SECG_CHAR2_131R1},
-	{ NID_sect131r2, &_EC_SECG_CHAR2_131R2},
-	{ NID_sect163k1, &_EC_NIST_CHAR2_163K },
-	{ NID_sect163r1, &_EC_SECG_CHAR2_163R1},
-	{ NID_sect163r2, &_EC_NIST_CHAR2_163B },
-	{ NID_sect193r1, &_EC_SECG_CHAR2_193R1},
-	{ NID_sect193r2, &_EC_SECG_CHAR2_193R2},
-	{ NID_sect233k1, &_EC_NIST_CHAR2_233K },
-	{ NID_sect233r1, &_EC_NIST_CHAR2_233B },
-	{ NID_sect239k1, &_EC_SECG_CHAR2_239K1},
-	{ NID_sect283k1, &_EC_NIST_CHAR2_283K },
-	{ NID_sect283r1, &_EC_NIST_CHAR2_283B },
-	{ NID_sect409k1, &_EC_NIST_CHAR2_409K },
-	{ NID_sect409r1, &_EC_NIST_CHAR2_409B },
-	{ NID_sect571k1, &_EC_NIST_CHAR2_571K },
-	{ NID_sect571r1, &_EC_NIST_CHAR2_571B },
+	{ NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, "SECG curve over a 113 bit binary field"},
+	{ NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, "SECG curve over a 113 bit binary field"},
+	{ NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, "SECG/WTLS curve over a 131 bit binary field"},
+	{ NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, "SECG curve over a 131 bit binary field"},
+	{ NID_sect163k1, &_EC_NIST_CHAR2_163K.h,  "NIST/SECG/WTLS curve over a 163 bit binary field" },
+	{ NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, "SECG curve over a 163 bit binary field"},
+	{ NID_sect163r2, &_EC_NIST_CHAR2_163B.h,  "NIST/SECG curve over a 163 bit binary field" },
+	{ NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, "SECG curve over a 193 bit binary field"},
+	{ NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, "SECG curve over a 193 bit binary field"},
+	{ NID_sect233k1, &_EC_NIST_CHAR2_233K.h,  "NIST/SECG/WTLS curve over a 233 bit binary field" },
+	{ NID_sect233r1, &_EC_NIST_CHAR2_233B.h,  "NIST/SECG/WTLS curve over a 233 bit binary field" },
+	{ NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, "SECG curve over a 239 bit binary field"},
+	{ NID_sect283k1, &_EC_NIST_CHAR2_283K.h,  "NIST/SECG curve over a 283 bit binary field" },
+	{ NID_sect283r1, &_EC_NIST_CHAR2_283B.h,  "NIST/SECG curve over a 283 bit binary field" },
+	{ NID_sect409k1, &_EC_NIST_CHAR2_409K.h,  "NIST/SECG curve over a 409 bit binary field" },
+	{ NID_sect409r1, &_EC_NIST_CHAR2_409B.h,  "NIST/SECG curve over a 409 bit binary field" },
+	{ NID_sect571k1, &_EC_NIST_CHAR2_571K.h,  "NIST/SECG curve over a 571 bit binary field" },
+	{ NID_sect571r1, &_EC_NIST_CHAR2_571B.h,  "NIST/SECG curve over a 571 bit binary field" },
 	/* X9.62 curves */
-	{ NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1},
-	{ NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2},
-	{ NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3},
-	{ NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1},
-	{ NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1},
-	{ NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2},
-	{ NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3},
-	{ NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1},
-	{ NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1},
-	{ NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2},
-	{ NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3},
-	{ NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1},
-	{ NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1},
-	{ NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1},
-	{ NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1},
-	{ NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1},
+	{ NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, "X9.62 curve over a 163 bit binary field"},
+	{ NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, "X9.62 curve over a 163 bit binary field"},
+	{ NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, "X9.62 curve over a 163 bit binary field"},
+	{ NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, "X9.62 curve over a 176 bit binary field"},
+	{ NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, "X9.62 curve over a 191 bit binary field"},
+	{ NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, "X9.62 curve over a 191 bit binary field"},
+	{ NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, "X9.62 curve over a 191 bit binary field"},
+	{ NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, "X9.62 curve over a 208 bit binary field"},
+	{ NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, "X9.62 curve over a 239 bit binary field"},
+	{ NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, "X9.62 curve over a 239 bit binary field"},
+	{ NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, "X9.62 curve over a 239 bit binary field"},
+	{ NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, "X9.62 curve over a 272 bit binary field"},
+	{ NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, "X9.62 curve over a 304 bit binary field"},
+	{ NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, "X9.62 curve over a 359 bit binary field"},
+	{ NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, "X9.62 curve over a 368 bit binary field"},
+	{ NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, "X9.62 curve over a 431 bit binary field"},
 	/* the WAP/WTLS curves
 	 * [unlike SECG, spec has its own OIDs for curves from X9.62] */
-	{ NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1},
-	{ NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K},
-	{ NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1},
-	{ NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1},
-	{ NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1},
-	{ NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2},
-	{ NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8},
-	{ NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9 },
-	{ NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K},
-	{ NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B},
-	{ NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12},
+	{ NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, "WTLS curve over a 113 bit binary field"},
+	{ NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h,   "NIST/SECG/WTLS curve over a 163 bit binary field"},
+	{ NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h,  "SECG curve over a 113 bit binary field"},
+	{ NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, "X9.62 curve over a 163 bit binary field"},
+	{ NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h,  "SECG/WTLS curve over a 112 bit prime field"},
+	{ NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h,  "SECG/WTLS curve over a 160 bit prime field"},
+	{ NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, "WTLS curve over a 112 bit prime field"},
+	{ NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, "WTLS curve over a 160 bit prime field" },
+	{ NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, "NIST/SECG/WTLS curve over a 233 bit binary field"},
+	{ NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, "NIST/SECG/WTLS curve over a 233 bit binary field"},
+	{ NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, "WTLS curvs over a 224 bit prime field"},
 	/* IPSec curves */
-	{ NID_ipsec3, &_EC_IPSEC_155_ID3},
-	{ NID_ipsec4, &_EC_IPSEC_185_ID4},
+	{ NID_ipsec3, &_EC_IPSEC_155_ID3.h, "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n""\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
+	{ NID_ipsec4, &_EC_IPSEC_185_ID4.h, "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n""\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
 };
 
-static size_t curve_list_length = sizeof(curve_list)/sizeof(ec_list_element);
+#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element))
 
 static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data)
 	{
@@ -1127,22 +1913,23 @@
 	BN_CTX	 *ctx=NULL;
 	BIGNUM 	 *p=NULL, *a=NULL, *b=NULL, *x=NULL, *y=NULL, *order=NULL;
 	int	 ok=0;
+	int	 seed_len,param_len;
+	const unsigned char *params;
 
 	if ((ctx = BN_CTX_new()) == NULL)
 		{
 		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
 		goto err;
 		}
-	if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || 
-		(b = BN_new()) == NULL || (x = BN_new()) == NULL ||
-		(y = BN_new()) == NULL || (order = BN_new()) == NULL)
-		{
-		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
-		goto err;
-		}
-	
-	if (!BN_hex2bn(&p, data->p) || !BN_hex2bn(&a, data->a)
-		|| !BN_hex2bn(&b, data->b))
+
+	seed_len  = data->seed_len;
+	param_len = data->param_len;
+	params    = (const unsigned char *)(data+1);	/* skip header */
+	params   += seed_len;				/* skip seed   */
+
+	if (!(p = BN_bin2bn(params+0*param_len, param_len, NULL))
+		|| !(a = BN_bin2bn(params+1*param_len, param_len, NULL))
+		|| !(b = BN_bin2bn(params+2*param_len, param_len, NULL)))
 		{
 		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
 		goto err;
@@ -1156,8 +1943,8 @@
 			goto err;
 			}
 		}
-		else
-		{ /* field_type == NID_X9_62_characteristic_two_field */
+	else	/* field_type == NID_X9_62_characteristic_two_field */
+		{
 		if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL)
 			{
 			ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
@@ -1171,7 +1958,8 @@
 		goto err;
 		}
 	
-	if (!BN_hex2bn(&x, data->x) || !BN_hex2bn(&y, data->y))
+	if (!(x = BN_bin2bn(params+3*param_len, param_len, NULL))
+		|| !(y = BN_bin2bn(params+4*param_len, param_len, NULL)))
 		{
 		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
 		goto err;
@@ -1181,7 +1969,8 @@
 		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
 		goto err;
 		}
-	if (!BN_hex2bn(&order, data->order) || !BN_set_word(x, data->cofactor))
+	if (!(order = BN_bin2bn(params+5*param_len, param_len, NULL))
+		|| !BN_set_word(x, (BN_ULONG)data->cofactor))
 		{
 		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
 		goto err;
@@ -1191,9 +1980,9 @@
 		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
 		goto err;
 		}
-	if (data->seed)
+	if (seed_len)
 		{
-		if (!EC_GROUP_set_seed(group, data->seed, data->seed_len))
+		if (!EC_GROUP_set_seed(group, params-seed_len, seed_len))
 			{
 			ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
 			goto err;
@@ -1263,7 +2052,7 @@
 	for (i = 0; i < min; i++)
 		{
 		r[i].nid = curve_list[i].nid;
-		r[i].comment = curve_list[i].data->comment;
+		r[i].comment = curve_list[i].comment;
 		}
 
 	return curve_list_length;
diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c
index d04c895..84b4833 100644
--- a/crypto/ec/ec_err.c
+++ b/crypto/ec/ec_err.c
@@ -74,6 +74,14 @@
 {ERR_FUNC(EC_F_D2I_ECPARAMETERS),	"d2i_ECParameters"},
 {ERR_FUNC(EC_F_D2I_ECPKPARAMETERS),	"d2i_ECPKParameters"},
 {ERR_FUNC(EC_F_D2I_ECPRIVATEKEY),	"d2i_ECPrivateKey"},
+{ERR_FUNC(EC_F_DO_EC_KEY_PRINT),	"DO_EC_KEY_PRINT"},
+{ERR_FUNC(EC_F_ECKEY_PARAM2TYPE),	"ECKEY_PARAM2TYPE"},
+{ERR_FUNC(EC_F_ECKEY_PARAM_DECODE),	"ECKEY_PARAM_DECODE"},
+{ERR_FUNC(EC_F_ECKEY_PRIV_DECODE),	"ECKEY_PRIV_DECODE"},
+{ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE),	"ECKEY_PRIV_ENCODE"},
+{ERR_FUNC(EC_F_ECKEY_PUB_DECODE),	"ECKEY_PUB_DECODE"},
+{ERR_FUNC(EC_F_ECKEY_PUB_ENCODE),	"ECKEY_PUB_ENCODE"},
+{ERR_FUNC(EC_F_ECKEY_TYPE2PARAM),	"ECKEY_TYPE2PARAM"},
 {ERR_FUNC(EC_F_ECPARAMETERS_PRINT),	"ECParameters_print"},
 {ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP),	"ECParameters_print_fp"},
 {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT),	"ECPKParameters_print"},
@@ -147,7 +155,6 @@
 {ERR_FUNC(EC_F_EC_KEY_PRINT),	"EC_KEY_print"},
 {ERR_FUNC(EC_F_EC_KEY_PRINT_FP),	"EC_KEY_print_fp"},
 {ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE),	"EC_POINTs_make_affine"},
-{ERR_FUNC(EC_F_EC_POINTS_MUL),	"EC_POINTs_mul"},
 {ERR_FUNC(EC_F_EC_POINT_ADD),	"EC_POINT_add"},
 {ERR_FUNC(EC_F_EC_POINT_CMP),	"EC_POINT_cmp"},
 {ERR_FUNC(EC_F_EC_POINT_COPY),	"EC_POINT_copy"},
@@ -178,6 +185,13 @@
 {ERR_FUNC(EC_F_I2D_ECPRIVATEKEY),	"i2d_ECPrivateKey"},
 {ERR_FUNC(EC_F_I2O_ECPUBLICKEY),	"i2o_ECPublicKey"},
 {ERR_FUNC(EC_F_O2I_ECPUBLICKEY),	"o2i_ECPublicKey"},
+{ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE),	"OLD_EC_PRIV_DECODE"},
+{ERR_FUNC(EC_F_PKEY_EC_CTRL),	"PKEY_EC_CTRL"},
+{ERR_FUNC(EC_F_PKEY_EC_CTRL_STR),	"PKEY_EC_CTRL_STR"},
+{ERR_FUNC(EC_F_PKEY_EC_DERIVE),	"PKEY_EC_DERIVE"},
+{ERR_FUNC(EC_F_PKEY_EC_KEYGEN),	"PKEY_EC_KEYGEN"},
+{ERR_FUNC(EC_F_PKEY_EC_PARAMGEN),	"PKEY_EC_PARAMGEN"},
+{ERR_FUNC(EC_F_PKEY_EC_SIGN),	"PKEY_EC_SIGN"},
 {0,NULL}
 	};
 
@@ -187,6 +201,7 @@
 {ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD)     ,"asn1 unknown field"},
 {ERR_REASON(EC_R_BUFFER_TOO_SMALL)       ,"buffer too small"},
 {ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),"d2i ecpkparameters failure"},
+{ERR_REASON(EC_R_DECODE_ERROR)           ,"decode error"},
 {ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO)   ,"discriminant is zero"},
 {ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),"ec group new by name failure"},
 {ERR_REASON(EC_R_FIELD_TOO_LARGE)        ,"field too large"},
@@ -196,6 +211,8 @@
 {ERR_REASON(EC_R_INVALID_ARGUMENT)       ,"invalid argument"},
 {ERR_REASON(EC_R_INVALID_COMPRESSED_POINT),"invalid compressed point"},
 {ERR_REASON(EC_R_INVALID_COMPRESSION_BIT),"invalid compression bit"},
+{ERR_REASON(EC_R_INVALID_CURVE)          ,"invalid curve"},
+{ERR_REASON(EC_R_INVALID_DIGEST_TYPE)    ,"invalid digest type"},
 {ERR_REASON(EC_R_INVALID_ENCODING)       ,"invalid encoding"},
 {ERR_REASON(EC_R_INVALID_FIELD)          ,"invalid field"},
 {ERR_REASON(EC_R_INVALID_FORM)           ,"invalid form"},
@@ -203,6 +220,7 @@
 {ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS),"invalid pentanomial basis"},
 {ERR_REASON(EC_R_INVALID_PRIVATE_KEY)    ,"invalid private key"},
 {ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS),"invalid trinomial basis"},
+{ERR_REASON(EC_R_KEYS_NOT_SET)           ,"keys not set"},
 {ERR_REASON(EC_R_MISSING_PARAMETERS)     ,"missing parameters"},
 {ERR_REASON(EC_R_MISSING_PRIVATE_KEY)    ,"missing private key"},
 {ERR_REASON(EC_R_NOT_A_NIST_PRIME)       ,"not a NIST prime"},
@@ -210,6 +228,7 @@
 {ERR_REASON(EC_R_NOT_IMPLEMENTED)        ,"not implemented"},
 {ERR_REASON(EC_R_NOT_INITIALIZED)        ,"not initialized"},
 {ERR_REASON(EC_R_NO_FIELD_MOD)           ,"no field mod"},
+{ERR_REASON(EC_R_NO_PARAMETERS_SET)      ,"no parameters set"},
 {ERR_REASON(EC_R_PASSED_NULL_PARAMETER)  ,"passed null parameter"},
 {ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE),"pkparameters2group failure"},
 {ERR_REASON(EC_R_POINT_AT_INFINITY)      ,"point at infinity"},
diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h
index fdd7aa2..3e2c34b 100644
--- a/crypto/ec/ec_lcl.h
+++ b/crypto/ec/ec_lcl.h
@@ -205,11 +205,14 @@
 	               * irreducible polynomial defining the field.
 	               */
 
-	unsigned int poly[5]; /* Field specification for curves over GF(2^m).
-	                       * The irreducible f(t) is then of the form:
-	                       *     t^poly[0] + t^poly[1] + ... + t^poly[k]
-	                       * where m = poly[0] > poly[1] > ... > poly[k] = 0.
-	                       */
+	int poly[6]; /* Field specification for curves over GF(2^m).
+	              * The irreducible f(t) is then of the form:
+	              *     t^poly[0] + t^poly[1] + ... + t^poly[k]
+	              * where m = poly[0] > poly[1] > ... > poly[k] = 0.
+	              * The array is terminated with poly[k+1]=-1.
+	              * All elliptic curve irreducibles have at most 5
+	              * non-zero terms.
+	              */
 
 	BIGNUM a, b; /* Curve coefficients.
 	              * (Here the assumption is that BIGNUMs can be used
diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c
index 5af8437..dd7da0f 100644
--- a/crypto/ec/ec_lib.c
+++ b/crypto/ec/ec_lib.c
@@ -79,7 +79,7 @@
 
 	if (meth == NULL)
 		{
-		ECerr(EC_F_EC_GROUP_NEW, ERR_R_PASSED_NULL_PARAMETER);
+		ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL);
 		return NULL;
 		}
 	if (meth->group_init == 0)
@@ -740,7 +740,7 @@
 
 	if (point->meth->point_clear_finish != 0)
 		point->meth->point_clear_finish(point);
-	else if (point->meth != NULL && point->meth->point_finish != 0)
+	else if (point->meth->point_finish != 0)
 		point->meth->point_finish(point);
 	OPENSSL_cleanse(point, sizeof *point);
 	OPENSSL_free(point);
diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c
index 2ba173e..f05df53 100644
--- a/crypto/ec/ec_mult.c
+++ b/crypto/ec/ec_mult.c
@@ -224,6 +224,12 @@
 		sign = -1;
 		}
 
+	if (scalar->d == NULL || scalar->top == 0)
+		{
+		ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+		goto err;
+		}
+
 	len = BN_num_bits(scalar);
 	r = OPENSSL_malloc(len + 1); /* modified wNAF may be one digit longer than binary representation
 	                              * (*ret_len will be set to the actual length, i.e. at most
@@ -233,12 +239,6 @@
 		ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
 		goto err;
 		}
-
-	if (scalar->d == NULL || scalar->top == 0)
-		{
-		ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
-		goto err;
-		}
 	window_val = scalar->d[0] & mask;
 	j = 0;
 	while ((window_val != 0) || (j + w + 1 < len)) /* if j+w+1 >= len, window_val will not increase */
@@ -419,7 +419,7 @@
 			if (numblocks > pre_comp->numblocks)
 				numblocks = pre_comp->numblocks;
 
-			pre_points_per_block = 1u << (pre_comp->w - 1);
+			pre_points_per_block = (size_t)1 << (pre_comp->w - 1);
 
 			/* check that pre_comp looks sane */
 			if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block))
@@ -461,7 +461,7 @@
 
 		bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);
 		wsize[i] = EC_window_bits_for_scalar_size(bits);
-		num_val += 1u << (wsize[i] - 1);
+		num_val += (size_t)1 << (wsize[i] - 1);
 		wNAF[i + 1] = NULL; /* make sure we always have a pivot */
 		wNAF[i] = compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i]);
 		if (wNAF[i] == NULL)
@@ -600,7 +600,7 @@
 	for (i = 0; i < num + num_scalar; i++)
 		{
 		val_sub[i] = v;
-		for (j = 0; j < (1u << (wsize[i] - 1)); j++)
+		for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++)
 			{
 			*v = EC_POINT_new(group);
 			if (*v == NULL) goto err;
@@ -636,7 +636,7 @@
 		if (wsize[i] > 1)
 			{
 			if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx)) goto err;
-			for (j = 1; j < (1u << (wsize[i] - 1)); j++)
+			for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++)
 				{
 				if (!EC_POINT_add(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) goto err;
 				}
@@ -820,7 +820,7 @@
 
 	numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks to use for wNAF splitting */
 	
-	pre_points_per_block = 1u << (w - 1);
+	pre_points_per_block = (size_t)1 << (w - 1);
 	num = pre_points_per_block * numblocks; /* number of points to compute and store */
 
 	points = OPENSSL_malloc(sizeof (EC_POINT*)*(num + 1));
diff --git a/crypto/ec/ecp_nist.c b/crypto/ec/ecp_nist.c
index 71893d5..2a5682e 100644
--- a/crypto/ec/ecp_nist.c
+++ b/crypto/ec/ecp_nist.c
@@ -112,10 +112,6 @@
 	return &ret;
 	}
 
-#if BN_BITS2 == 64
-#define	NO_32_BIT_TYPE
-#endif
-
 int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
 	{
 	dest->field_mod_func = src->field_mod_func;
@@ -139,34 +135,12 @@
 	if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
 		group->field_mod_func = BN_nist_mod_192;
 	else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
-		{
-#ifndef NO_32_BIT_TYPE
 		group->field_mod_func = BN_nist_mod_224;
-#else
-		ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_SUPPORTED_NIST_PRIME);
-		goto err;
-#endif
-		}
 	else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
-		{
-#ifndef NO_32_BIT_TYPE
 		group->field_mod_func = BN_nist_mod_256;
-#else
-		ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_SUPPORTED_NIST_PRIME);
-		goto err;
-#endif
-		}
 	else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
-		{
-#ifndef NO_32_BIT_TYPE
 		group->field_mod_func = BN_nist_mod_384;
-#else
-		ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_SUPPORTED_NIST_PRIME);
-		goto err;
-#endif
-		}
 	else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
-		/* this one works in the NO_32_BIT_TYPE case */
 		group->field_mod_func = BN_nist_mod_521;
 	else
 		{
diff --git a/crypto/ec/ectest.c b/crypto/ec/ectest.c
index 6148d55..7509cb9 100644
--- a/crypto/ec/ectest.c
+++ b/crypto/ec/ectest.c
@@ -432,9 +432,7 @@
 	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
 	fprintf(stdout, ".");
 	fflush(stdout);
-#if 0
 	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
-#endif
 	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
 	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
 	fprintf(stdout, " ok\n");
@@ -478,9 +476,7 @@
 	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
 	fprintf(stdout, ".");
 	fflush(stdout);
-#if 0
 	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
-#endif
 	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
 	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
 	fprintf(stdout, " ok\n");
@@ -525,9 +521,7 @@
 	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
 	fprintf(stdout, ".");
 	fflush(stdout);
-#if 0
 	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
-#endif
 	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
 	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
 	fprintf(stdout, " ok\n");
@@ -577,9 +571,7 @@
 	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
 	fprintf(stdout, ".");
 	fflush(stdout);
-#if 0
 	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
-#endif
 	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
 	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
 	fprintf(stdout, " ok\n");
@@ -635,9 +627,7 @@
 	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
 	fprintf(stdout, ".");
 	fflush(stdout);
-#if 0
 	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
-#endif
 	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
 	if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
 	fprintf(stdout, " ok\n");
@@ -809,7 +799,7 @@
 	if (!EC_POINT_is_at_infinity(group, Q)) ABORT; \
 	fprintf(stdout, "."); \
 	fflush(stdout); \
-	/* if (!EC_GROUP_precompute_mult(group, ctx)) ABORT; */ \
+	if (!EC_GROUP_precompute_mult(group, ctx)) ABORT; \
 	if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT; \
 	if (!EC_POINT_is_at_infinity(group, Q)) ABORT; \
 	fprintf(stdout, " ok\n"); \
@@ -1336,7 +1326,7 @@
 #endif
 	CRYPTO_cleanup_all_ex_data();
 	ERR_free_strings();
-	ERR_remove_state(0);
+	ERR_remove_thread_state(NULL);
 	CRYPTO_mem_leaks_fp(stderr);
 	
 	return 0;
diff --git a/crypto/ecdh/Makefile b/crypto/ecdh/Makefile
deleted file mode 100644
index 7a7b618..0000000
--- a/crypto/ecdh/Makefile
+++ /dev/null
@@ -1,122 +0,0 @@
-#
-# crypto/ecdh/Makefile
-#
-
-DIR=	ecdh
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g -Wall
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=ecdhtest.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=	ech_lib.c ech_ossl.c ech_key.c ech_err.c
-
-LIBOBJ=	ech_lib.o ech_ossl.o ech_key.o ech_err.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= ecdh.h
-HEADER=	ech_locl.h $(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-ech_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ech_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-ech_err.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
-ech_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-ech_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-ech_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-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/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/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/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/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
-ech_ossl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ech_ossl.o: ../../include/openssl/ecdh.h ../../include/openssl/err.h
-ech_ossl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-ech_ossl.o: ../../include/openssl/opensslconf.h
-ech_ossl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ech_ossl.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-ech_ossl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-ech_ossl.o: ../cryptlib.h ech_locl.h ech_ossl.c
diff --git a/crypto/ecdh/ecdhtest.c b/crypto/ecdh/ecdhtest.c
index 1575006..212a87e 100644
--- a/crypto/ecdh/ecdhtest.c
+++ b/crypto/ecdh/ecdhtest.c
@@ -343,7 +343,7 @@
 	if (ctx) BN_CTX_free(ctx);
 	BIO_free(out);
 	CRYPTO_cleanup_all_ex_data();
-	ERR_remove_state(0);
+	ERR_remove_thread_state(NULL);
 	CRYPTO_mem_leaks_fp(stderr);
 	EXIT(ret);
 	return(ret);
diff --git a/crypto/ecdh/ech_err.c b/crypto/ecdh/ech_err.c
index 4d2ede7..6f4b0c9 100644
--- a/crypto/ecdh/ech_err.c
+++ b/crypto/ecdh/ech_err.c
@@ -1,6 +1,6 @@
 /* crypto/ecdh/ech_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
@@ -71,7 +71,7 @@
 static ERR_STRING_DATA ECDH_str_functs[]=
 	{
 {ERR_FUNC(ECDH_F_ECDH_COMPUTE_KEY),	"ECDH_compute_key"},
-{ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD),	"ECDH_DATA_NEW_METHOD"},
+{ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD),	"ECDH_DATA_new_method"},
 {0,NULL}
 	};
 
diff --git a/crypto/ecdsa/Makefile b/crypto/ecdsa/Makefile
deleted file mode 100644
index 49e2681..0000000
--- a/crypto/ecdsa/Makefile
+++ /dev/null
@@ -1,143 +0,0 @@
-#
-# crypto/ecdsa/Makefile
-#
-
-DIR=	ecdsa
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g -Wall
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=ecdsatest.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=	ecs_lib.c ecs_asn1.c ecs_ossl.c ecs_sign.c ecs_vrf.c ecs_err.c
-
-LIBOBJ=	ecs_lib.o ecs_asn1.o ecs_ossl.o ecs_sign.o ecs_vrf.o ecs_err.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= ecdsa.h
-HEADER=	ecs_locl.h $(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-ecs_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
-ecs_asn1.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
-ecs_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ecs_asn1.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-ecs_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-ecs_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ecs_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ecs_asn1.o: ../../include/openssl/symhacks.h ecs_asn1.c ecs_locl.h
-ecs_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ecs_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-ecs_err.o: ../../include/openssl/ec.h ../../include/openssl/ecdsa.h
-ecs_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-ecs_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-ecs_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-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/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/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/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
-ecs_ossl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ecs_ossl.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-ecs_ossl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-ecs_ossl.o: ../../include/openssl/opensslconf.h
-ecs_ossl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-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/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/pkcs7.h ../../include/openssl/rand.h
-ecs_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-ecs_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-ecs_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-ecs_sign.o: ecs_locl.h ecs_sign.c
-ecs_vrf.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-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/ecdsa/ecdsa.h b/crypto/ecdsa/ecdsa.h
index f20c8ee..e61c539 100644
--- a/crypto/ecdsa/ecdsa.h
+++ b/crypto/ecdsa/ecdsa.h
@@ -4,7 +4,7 @@
  * \author Written by Nils Larsch for the OpenSSL project
  */
 /* ====================================================================
- * Copyright (c) 2000-2003 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 2000-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
@@ -81,156 +81,143 @@
 	BIGNUM *s;
 	} ECDSA_SIG;
 
-/** ECDSA_SIG *ECDSA_SIG_new(void)
- * allocates and initialize a ECDSA_SIG structure
- * \return pointer to a ECDSA_SIG structure or NULL if an error occurred
+/** Allocates and initialize a ECDSA_SIG structure
+ *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
  */
 ECDSA_SIG *ECDSA_SIG_new(void);
 
-/** ECDSA_SIG_free
- * frees a ECDSA_SIG structure
- * \param a pointer to the ECDSA_SIG structure
+/** frees a ECDSA_SIG structure
+ *  \param  sig  pointer to the ECDSA_SIG structure
  */
-void	  ECDSA_SIG_free(ECDSA_SIG *a);
+void	  ECDSA_SIG_free(ECDSA_SIG *sig);
 
-/** i2d_ECDSA_SIG
- * DER encode content of ECDSA_SIG object (note: this function modifies *pp
- * (*pp += length of the DER encoded signature)).
- * \param a  pointer to the ECDSA_SIG object
- * \param pp pointer to a unsigned char pointer for the output or NULL
- * \return the length of the DER encoded ECDSA_SIG object or 0 
+/** DER encode content of ECDSA_SIG object (note: this function modifies *pp
+ *  (*pp += length of the DER encoded signature)).
+ *  \param  sig  pointer to the ECDSA_SIG object
+ *  \param  pp   pointer to a unsigned char pointer for the output or NULL
+ *  \return the length of the DER encoded ECDSA_SIG object or 0 
  */
-int	  i2d_ECDSA_SIG(const ECDSA_SIG *a, unsigned char **pp);
+int	  i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
 
-/** d2i_ECDSA_SIG
- * decodes a DER encoded ECDSA signature (note: this function changes *pp
- * (*pp += len)). 
- * \param v pointer to ECDSA_SIG pointer (may be NULL)
- * \param pp buffer with the DER encoded signature
- * \param len bufferlength
- * \return pointer to the decoded ECDSA_SIG structure (or NULL)
+/** Decodes a DER encoded ECDSA signature (note: this function changes *pp
+ *  (*pp += len)). 
+ *  \param  sig  pointer to ECDSA_SIG pointer (may be NULL)
+ *  \param  pp   memory buffer with the DER encoded signature
+ *  \param  len  length of the buffer
+ *  \return pointer to the decoded ECDSA_SIG structure (or NULL)
  */
-ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **v, const unsigned char **pp, long len);
+ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len);
 
-/** ECDSA_do_sign
- * computes the ECDSA signature of the given hash value using
- * the supplied private key and returns the created signature.
- * \param dgst pointer to the hash value
- * \param dgst_len length of the hash value
- * \param eckey pointer to the EC_KEY object containing a private EC key
- * \return pointer to a ECDSA_SIG structure or NULL
+/** Computes the ECDSA signature of the given hash value using
+ *  the supplied private key and returns the created signature.
+ *  \param  dgst      pointer to the hash value
+ *  \param  dgst_len  length of the hash value
+ *  \param  eckey     EC_KEY object containing a private EC key
+ *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
  */
 ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst,int dgst_len,EC_KEY *eckey);
 
-/** ECDSA_do_sign_ex
- * computes ECDSA signature of a given hash value using the supplied
- * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
- * \param dgst pointer to the hash value to sign
- * \param dgstlen length of the hash value
- * \param kinv optional pointer to a pre-computed inverse k
- * \param rp optional pointer to the pre-computed rp value (see 
- *        ECDSA_sign_setup
- * \param eckey pointer to the EC_KEY object containing a private EC key
- * \return pointer to a ECDSA_SIG structure or NULL
+/** Computes ECDSA signature of a given hash value using the supplied
+ *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ *  \param  dgst     pointer to the hash value to sign
+ *  \param  dgstlen  length of the hash value
+ *  \param  kinv     BIGNUM with a pre-computed inverse k (optional)
+ *  \param  rp       BIGNUM with a pre-computed rp value (optioanl), 
+ *                   see ECDSA_sign_setup
+ *  \param  eckey    EC_KEY object containing a private EC key
+ *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
  */
 ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, 
 		const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey);
 
-/** ECDSA_do_verify
- * verifies that the supplied signature is a valid ECDSA
- * signature of the supplied hash value using the supplied public key.
- * \param dgst pointer to the hash value
- * \param dgst_len length of the hash value
- * \param sig  pointer to the ECDSA_SIG structure
- * \param eckey pointer to the EC_KEY object containing a public EC key
- * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error
+/** Verifies that the supplied signature is a valid ECDSA
+ *  signature of the supplied hash value using the supplied public key.
+ *  \param  dgst      pointer to the hash value
+ *  \param  dgst_len  length of the hash value
+ *  \param  sig       ECDSA_SIG structure
+ *  \param  eckey     EC_KEY object containing a public EC key
+ *  \return 1 if the signature is valid, 0 if the signature is invalid
+ *          and -1 on error
  */
 int	  ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
 		const ECDSA_SIG *sig, EC_KEY* eckey);
 
 const ECDSA_METHOD *ECDSA_OpenSSL(void);
 
-/** ECDSA_set_default_method
- * sets the default ECDSA method
- * \param meth the new default ECDSA_METHOD
+/** Sets the default ECDSA method
+ *  \param  meth  new default ECDSA_METHOD
  */
 void	  ECDSA_set_default_method(const ECDSA_METHOD *meth);
 
-/** ECDSA_get_default_method
- * returns the default ECDSA method
- * \return pointer to ECDSA_METHOD structure containing the default method
+/** Returns the default ECDSA method
+ *  \return pointer to ECDSA_METHOD structure containing the default method
  */
 const ECDSA_METHOD *ECDSA_get_default_method(void);
 
-/** ECDSA_set_method
- * sets method to be used for the ECDSA operations
- * \param eckey pointer to the EC_KEY object
- * \param meth  pointer to the new method
- * \return 1 on success and 0 otherwise 
+/** Sets method to be used for the ECDSA operations
+ *  \param  eckey  EC_KEY object
+ *  \param  meth   new method
+ *  \return 1 on success and 0 otherwise 
  */
 int 	  ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth);
 
-/** ECDSA_size
- * returns the maximum length of the DER encoded signature
- * \param  eckey pointer to a EC_KEY object
- * \return numbers of bytes required for the DER encoded signature
+/** Returns the maximum length of the DER encoded signature
+ *  \param  eckey  EC_KEY object
+ *  \return numbers of bytes required for the DER encoded signature
  */
 int	  ECDSA_size(const EC_KEY *eckey);
 
-/** ECDSA_sign_setup
- * precompute parts of the signing operation. 
- * \param eckey pointer to the EC_KEY object containing a private EC key
- * \param ctx  pointer to a BN_CTX object (may be NULL)
- * \param kinv pointer to a BIGNUM pointer for the inverse of k
- * \param rp   pointer to a BIGNUM pointer for x coordinate of k * generator
- * \return 1 on success and 0 otherwise
+/** Precompute parts of the signing operation
+ *  \param  eckey  EC_KEY object containing a private EC key
+ *  \param  ctx    BN_CTX object (optional)
+ *  \param  kinv   BIGNUM pointer for the inverse of k
+ *  \param  rp     BIGNUM pointer for x coordinate of k * generator
+ *  \return 1 on success and 0 otherwise
  */
 int 	  ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, 
 		BIGNUM **rp);
 
-/** ECDSA_sign
- * computes ECDSA signature of a given hash value using the supplied
- * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
- * \param type this parameter is ignored
- * \param dgst pointer to the hash value to sign
- * \param dgstlen length of the hash value
- * \param sig buffer to hold the DER encoded signature
- * \param siglen pointer to the length of the returned signature
- * \param eckey pointer to the EC_KEY object containing a private EC key
- * \return 1 on success and 0 otherwise
+/** Computes ECDSA signature of a given hash value using the supplied
+ *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ *  \param  type     this parameter is ignored
+ *  \param  dgst     pointer to the hash value to sign
+ *  \param  dgstlen  length of the hash value
+ *  \param  sig      memory for the DER encoded created signature
+ *  \param  siglen   pointer to the length of the returned signature
+ *  \param  eckey    EC_KEY object containing a private EC key
+ *  \return 1 on success and 0 otherwise
  */
 int	  ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, 
 		unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);
 
 
-/** ECDSA_sign_ex
- * computes ECDSA signature of a given hash value using the supplied
- * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
- * \param type this parameter is ignored
- * \param dgst pointer to the hash value to sign
- * \param dgstlen length of the hash value
- * \param sig buffer to hold the DER encoded signature
- * \param siglen pointer to the length of the returned signature
- * \param kinv optional pointer to a pre-computed inverse k
- * \param rp optional pointer to the pre-computed rp value (see 
- *        ECDSA_sign_setup
- * \param eckey pointer to the EC_KEY object containing a private EC key
- * \return 1 on success and 0 otherwise
+/** Computes ECDSA signature of a given hash value using the supplied
+ *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ *  \param  type     this parameter is ignored
+ *  \param  dgst     pointer to the hash value to sign
+ *  \param  dgstlen  length of the hash value
+ *  \param  sig      buffer to hold the DER encoded signature
+ *  \param  siglen   pointer to the length of the returned signature
+ *  \param  kinv     BIGNUM with a pre-computed inverse k (optional)
+ *  \param  rp       BIGNUM with a pre-computed rp value (optioanl), 
+ *                   see ECDSA_sign_setup
+ *  \param  eckey    EC_KEY object containing a private EC key
+ *  \return 1 on success and 0 otherwise
  */
 int	  ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, 
 		unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv,
 		const BIGNUM *rp, EC_KEY *eckey);
 
-/** ECDSA_verify
- * verifies that the given signature is valid ECDSA signature
- * of the supplied hash value using the specified public key.
- * \param type this parameter is ignored
- * \param dgst pointer to the hash value 
- * \param dgstlen length of the hash value
- * \param sig  pointer to the DER encoded signature
- * \param siglen length of the DER encoded signature
- * \param eckey pointer to the EC_KEY object containing a public EC key
- * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error
+/** Verifies that the given signature is valid ECDSA signature
+ *  of the supplied hash value using the specified public key.
+ *  \param  type     this parameter is ignored
+ *  \param  dgst     pointer to the hash value 
+ *  \param  dgstlen  length of the hash value
+ *  \param  sig      pointer to the DER encoded signature
+ *  \param  siglen   length of the DER encoded signature
+ *  \param  eckey    EC_KEY object containing a public EC key
+ *  \return 1 if the signature is valid, 0 if the signature is invalid
+ *          and -1 on error
  */
 int 	  ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, 
 		const unsigned char *sig, int siglen, EC_KEY *eckey);
diff --git a/crypto/ecdsa/ecdsatest.c b/crypto/ecdsa/ecdsatest.c
index b07e312..aa4e148 100644
--- a/crypto/ecdsa/ecdsatest.c
+++ b/crypto/ecdsa/ecdsatest.c
@@ -490,7 +490,7 @@
 	if (ret)
 		ERR_print_errors(out);
 	CRYPTO_cleanup_all_ex_data();
-	ERR_remove_state(0);
+	ERR_remove_thread_state(NULL);
 	ERR_free_strings();
 	CRYPTO_mem_leaks(out);
 	if (out != NULL)
diff --git a/crypto/ecdsa/ecs_err.c b/crypto/ecdsa/ecs_err.c
index d2a5373..98e38d5 100644
--- a/crypto/ecdsa/ecs_err.c
+++ b/crypto/ecdsa/ecs_err.c
@@ -1,6 +1,6 @@
 /* crypto/ecdsa/ecs_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
diff --git a/crypto/engine/Makefile b/crypto/engine/Makefile
deleted file mode 100644
index b52fa48..0000000
--- a/crypto/engine/Makefile
+++ /dev/null
@@ -1,415 +0,0 @@
-#
-# OpenSSL/crypto/engine/Makefile
-#
-
-DIR=	engine
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST= enginetest.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC= eng_err.c eng_lib.c eng_list.c eng_init.c eng_ctrl.c \
-	eng_table.c eng_pkey.c eng_fat.c eng_all.c \
-	tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
-	tb_cipher.c tb_digest.c \
-	eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c
-LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
-	eng_table.o eng_pkey.o eng_fat.o eng_all.o \
-	tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
-	tb_cipher.o tb_digest.o \
-	eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= engine.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-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/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/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/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/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/buffer.h
-eng_cryptodev.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
-eng_cryptodev.o: ../../include/openssl/dsa.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/err.h ../../include/openssl/evp.h
-eng_cryptodev.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-eng_cryptodev.o: ../../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 ../../include/openssl/pkcs7.h
-eng_cryptodev.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-eng_cryptodev.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-eng_cryptodev.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-eng_cryptodev.o: ../../include/openssl/x509_vfy.h eng_cryptodev.c
-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/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/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/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/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/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/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/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/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
-eng_openssl.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
-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/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
-eng_openssl.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
-eng_openssl.o: ../../include/openssl/rand.h ../../include/openssl/rc4.h
-eng_openssl.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-eng_openssl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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 d29cd57..22c1204 100644
--- a/crypto/engine/eng_all.c
+++ b/crypto/engine/eng_all.c
@@ -61,15 +61,15 @@
 
 void ENGINE_load_builtin_engines(void)
 	{
+#if 0
 	/* There's no longer any need for an "openssl" ENGINE unless, one day,
 	 * it is the *only* way for standard builtin implementations to be be
 	 * accessed (ie. it would be possible to statically link binaries with
 	 * *no* builtin implementations). */
-#if 0
 	ENGINE_load_openssl();
 #endif
-#if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
-	ENGINE_load_padlock();
+#if !defined(OPENSSL_NO_HW) && (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
+	ENGINE_load_cryptodev();
 #endif
 	ENGINE_load_dynamic();
 #ifndef OPENSSL_NO_STATIC_ENGINE
@@ -98,22 +98,23 @@
 #ifndef OPENSSL_NO_HW_UBSEC
 	ENGINE_load_ubsec();
 #endif
+#ifndef OPENSSL_NO_HW_PADLOCK
+	ENGINE_load_padlock();
 #endif
-#if !defined(OPENSSL_NO_GMP) && !defined(OPENSSL_NO_HW_GMP)
+#endif
+#ifndef OPENSSL_NO_GOST
+	ENGINE_load_gost();
+#endif
+#ifndef OPENSSL_NO_GMP
 	ENGINE_load_gmp();
 #endif
-#endif
-#ifndef OPENSSL_NO_HW
-#if defined(__OpenBSD__) || defined(__FreeBSD__)
-	ENGINE_load_cryptodev();
-#endif
 #if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
 	ENGINE_load_capi();
 #endif
 #endif
 	}
 
-#if defined(__OpenBSD__) || defined(__FreeBSD__)
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
 void ENGINE_setup_bsd_cryptodev(void) {
 	static int bsd_cryptodev_default_loaded = 0;
 	if (!bsd_cryptodev_default_loaded) {
diff --git a/crypto/engine/eng_cryptodev.c b/crypto/engine/eng_cryptodev.c
index 1a1e1c2..52f4ca3 100644
--- a/crypto/engine/eng_cryptodev.c
+++ b/crypto/engine/eng_cryptodev.c
@@ -30,10 +30,6 @@
 #include <openssl/engine.h>
 #include <openssl/evp.h>
 #include <openssl/bn.h>
-#include <openssl/dsa.h>
-#include <openssl/rsa.h>
-#include <openssl/dh.h>
-#include <openssl/err.h>
 
 #if (defined(__unix__) || defined(unix)) && !defined(USG) && \
 	(defined(OpenBSD) || defined(__FreeBSD__))
@@ -59,6 +55,10 @@
  
 #include <sys/types.h>
 #include <crypto/cryptodev.h>
+#include <crypto/dh/dh.h>
+#include <crypto/dsa/dsa.h>
+#include <crypto/err/err.h>
+#include <crypto/rsa/rsa.h>
 #include <sys/ioctl.h>
 #include <errno.h>
 #include <stdio.h>
@@ -72,6 +72,16 @@
 struct dev_crypto_state {
 	struct session_op d_sess;
 	int d_fd;
+
+#ifdef USE_CRYPTODEV_DIGESTS
+	char dummy_mac_key[HASH_MAX_LEN];
+
+	unsigned char digest_res[HASH_MAX_LEN];
+	char *mac_data;
+	int mac_len;
+
+	int copy;
+#endif
 };
 
 static u_int32_t cryptodev_asymfeat = 0;
@@ -79,15 +89,14 @@
 static int get_asym_dev_crypto(void);
 static int open_dev_crypto(void);
 static int get_dev_crypto(void);
-static int cryptodev_max_iv(int cipher);
-static int cryptodev_key_length_valid(int cipher, int len);
-static int cipher_nid_to_cryptodev(int nid);
 static int get_cryptodev_ciphers(const int **cnids);
-/*static int get_cryptodev_digests(const int **cnids);*/
+#ifdef USE_CRYPTODEV_DIGESTS
+static int get_cryptodev_digests(const int **cnids);
+#endif
 static int cryptodev_usable_ciphers(const int **nids);
 static int cryptodev_usable_digests(const int **nids);
 static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-    const unsigned char *in, unsigned int inl);
+    const unsigned char *in, size_t inl);
 static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
     const unsigned char *iv, int enc);
 static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx);
@@ -121,7 +130,7 @@
 static int cryptodev_dh_compute_key(unsigned char *key,
     const BIGNUM *pub_key, DH *dh);
 static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p,
-    void (*f)());
+    void (*f)(void));
 void ENGINE_load_cryptodev(void);
 
 static const ENGINE_CMD_DEFN cryptodev_defns[] = {
@@ -134,27 +143,32 @@
 	int	ivmax;
 	int	keylen;
 } ciphers[] = {
+	{ CRYPTO_ARC4,			NID_rc4,		0,	16, },
 	{ CRYPTO_DES_CBC,		NID_des_cbc,		8,	 8, },
 	{ CRYPTO_3DES_CBC,		NID_des_ede3_cbc,	8,	24, },
 	{ CRYPTO_AES_CBC,		NID_aes_128_cbc,	16,	16, },
+	{ CRYPTO_AES_CBC,		NID_aes_192_cbc,	16,	24, },
+	{ CRYPTO_AES_CBC,		NID_aes_256_cbc,	16,	32, },
 	{ CRYPTO_BLF_CBC,		NID_bf_cbc,		8,	16, },
 	{ CRYPTO_CAST_CBC,		NID_cast5_cbc,		8,	16, },
 	{ CRYPTO_SKIPJACK_CBC,		NID_undef,		0,	 0, },
 	{ 0,				NID_undef,		0,	 0, },
 };
 
-#if 0
+#ifdef USE_CRYPTODEV_DIGESTS
 static struct {
 	int	id;
 	int	nid;
+	int 	keylen;
 } digests[] = {
-	{ CRYPTO_SHA1_HMAC,		NID_hmacWithSHA1,	},
-	{ CRYPTO_RIPEMD160_HMAC,	NID_ripemd160,		},
-	{ CRYPTO_MD5_KPDK,		NID_undef,		},
-	{ CRYPTO_SHA1_KPDK,		NID_undef,		},
-	{ CRYPTO_MD5,			NID_md5,		},
-	{ CRYPTO_SHA1,			NID_undef,		},
-	{ 0,				NID_undef,		},
+	{ CRYPTO_MD5_HMAC,		NID_hmacWithMD5,	16},
+	{ CRYPTO_SHA1_HMAC,		NID_hmacWithSHA1,	20},
+	{ CRYPTO_RIPEMD160_HMAC,	NID_ripemd160,		16/*?*/},
+	{ CRYPTO_MD5_KPDK,		NID_undef,		0},
+	{ CRYPTO_SHA1_KPDK,		NID_undef,		0},
+	{ CRYPTO_MD5,			NID_md5,		16},
+	{ CRYPTO_SHA1,			NID_sha1,		20},
+	{ 0,				NID_undef,		0},
 };
 #endif
 
@@ -209,50 +223,6 @@
 }
 
 /*
- * XXXX this needs to be set for each alg - and determined from
- * a running card.
- */
-static int
-cryptodev_max_iv(int cipher)
-{
-	int i;
-
-	for (i = 0; ciphers[i].id; i++)
-		if (ciphers[i].id == cipher)
-			return (ciphers[i].ivmax);
-	return (0);
-}
-
-/*
- * XXXX this needs to be set for each alg - and determined from
- * a running card. For now, fake it out - but most of these
- * for real devices should return 1 for the supported key
- * sizes the device can handle.
- */
-static int
-cryptodev_key_length_valid(int cipher, int len)
-{
-	int i;
-
-	for (i = 0; ciphers[i].id; i++)
-		if (ciphers[i].id == cipher)
-			return (ciphers[i].keylen == len);
-	return (0);
-}
-
-/* convert libcrypto nids to cryptodev */
-static int
-cipher_nid_to_cryptodev(int nid)
-{
-	int i;
-
-	for (i = 0; ciphers[i].id; i++)
-		if (ciphers[i].nid == nid)
-			return (ciphers[i].id);
-	return (0);
-}
-
-/*
  * Find out what ciphers /dev/crypto will let us have a session for.
  * XXX note, that some of these openssl doesn't deal with yet!
  * returning them here is harmless, as long as we return NULL
@@ -270,7 +240,7 @@
 		return (0);
 	}
 	memset(&sess, 0, sizeof(sess));
-	sess.key = (caddr_t)"123456781234567812345678";
+	sess.key = (caddr_t)"123456789abcdefghijklmno";
 
 	for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
 		if (ciphers[i].nid == NID_undef)
@@ -291,7 +261,7 @@
 	return (count);
 }
 
-#if 0  /* unused */
+#ifdef USE_CRYPTODEV_DIGESTS
 /*
  * Find out what digests /dev/crypto will let us have a session for.
  * XXX note, that some of these openssl doesn't deal with yet!
@@ -310,10 +280,12 @@
 		return (0);
 	}
 	memset(&sess, 0, sizeof(sess));
+	sess.mackey = (caddr_t)"123456789abcdefghijklmno";
 	for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
 		if (digests[i].nid == NID_undef)
 			continue;
 		sess.mac = digests[i].id;
+		sess.mackeylen = digests[i].keylen;
 		sess.cipher = 0;
 		if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
 		    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
@@ -327,8 +299,7 @@
 		*cnids = NULL;
 	return (count);
 }
-
-#endif
+#endif  /* 0 */
 
 /*
  * Find the useable ciphers|digests from dev/crypto - this is the first
@@ -360,6 +331,9 @@
 static int
 cryptodev_usable_digests(const int **nids)
 {
+#ifdef USE_CRYPTODEV_DIGESTS
+	return (get_cryptodev_digests(nids));
+#else
 	/*
 	 * XXXX just disable all digests for now, because it sucks.
 	 * we need a better way to decide this - i.e. I may not
@@ -374,11 +348,12 @@
 	 */
 	*nids = NULL;
 	return (0);
+#endif
 }
 
 static int
 cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-    const unsigned char *in, unsigned int inl)
+    const unsigned char *in, size_t inl)
 {
 	struct crypt_op cryp;
 	struct dev_crypto_state *state = ctx->cipher_data;
@@ -436,23 +411,27 @@
 {
 	struct dev_crypto_state *state = ctx->cipher_data;
 	struct session_op *sess = &state->d_sess;
-	int cipher;
+	int cipher = -1, i;
 
-	if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef)
-		return (0);
+	for (i = 0; ciphers[i].id; i++)
+		if (ctx->cipher->nid == ciphers[i].nid &&
+		    ctx->cipher->iv_len <= ciphers[i].ivmax &&
+		    ctx->key_len == ciphers[i].keylen) {
+			cipher = ciphers[i].id;
+			break;
+		}
 
-	if (ctx->cipher->iv_len > cryptodev_max_iv(cipher))
+	if (!ciphers[i].id) {
+		state->d_fd = -1;
 		return (0);
-
-	if (!cryptodev_key_length_valid(cipher, ctx->key_len))
-		return (0);
+	}
 
 	memset(sess, 0, sizeof(struct session_op));
 
 	if ((state->d_fd = get_dev_crypto()) < 0)
 		return (0);
 
-	sess->key = (char *)key;
+	sess->key = (caddr_t)key;
 	sess->keylen = ctx->key_len;
 	sess->cipher = cipher;
 
@@ -505,6 +484,20 @@
  * gets called when libcrypto requests a cipher NID.
  */
 
+/* RC4 */
+const EVP_CIPHER cryptodev_rc4 = {
+	NID_rc4,
+	1, 16, 0,
+	EVP_CIPH_VARIABLE_LENGTH,
+	cryptodev_init_key,
+	cryptodev_cipher,
+	cryptodev_cleanup,
+	sizeof(struct dev_crypto_state),
+	NULL,
+	NULL,
+	NULL
+};
+
 /* DES CBC EVP */
 const EVP_CIPHER cryptodev_des_cbc = {
 	NID_des_cbc,
@@ -572,6 +565,32 @@
 	NULL
 };
 
+const EVP_CIPHER cryptodev_aes_192_cbc = {
+	NID_aes_192_cbc,
+	16, 24, 16,
+	EVP_CIPH_CBC_MODE,
+	cryptodev_init_key,
+	cryptodev_cipher,
+	cryptodev_cleanup,
+	sizeof(struct dev_crypto_state),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+};
+
+const EVP_CIPHER cryptodev_aes_256_cbc = {
+	NID_aes_256_cbc,
+	16, 32, 16,
+	EVP_CIPH_CBC_MODE,
+	cryptodev_init_key,
+	cryptodev_cipher,
+	cryptodev_cleanup,
+	sizeof(struct dev_crypto_state),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+};
+
 /*
  * Registered by the ENGINE when used to find out how to deal with
  * a particular NID in the ENGINE. this says what we'll do at the
@@ -585,6 +604,9 @@
 		return (cryptodev_usable_ciphers(nids));
 
 	switch (nid) {
+	case NID_rc4:
+		*cipher = &cryptodev_rc4;
+		break;
 	case NID_des_ede3_cbc:
 		*cipher = &cryptodev_3des_cbc;
 		break;
@@ -600,6 +622,12 @@
 	case NID_aes_128_cbc:
 		*cipher = &cryptodev_aes_cbc;
 		break;
+	case NID_aes_192_cbc:
+		*cipher = &cryptodev_aes_192_cbc;
+		break;
+	case NID_aes_256_cbc:
+		*cipher = &cryptodev_aes_256_cbc;
+		break;
 	default:
 		*cipher = NULL;
 		break;
@@ -607,6 +635,234 @@
 	return (*cipher != NULL);
 }
 
+
+#ifdef USE_CRYPTODEV_DIGESTS
+
+/* convert digest type to cryptodev */
+static int
+digest_nid_to_cryptodev(int nid)
+{
+	int i;
+
+	for (i = 0; digests[i].id; i++)
+		if (digests[i].nid == nid)
+			return (digests[i].id);
+	return (0);
+}
+
+
+static int
+digest_key_length(int nid)
+{
+	int i;
+
+	for (i = 0; digests[i].id; i++)
+		if (digests[i].nid == nid)
+			return digests[i].keylen;
+	return (0);
+}
+
+
+static int cryptodev_digest_init(EVP_MD_CTX *ctx)
+{
+	struct dev_crypto_state *state = ctx->md_data;
+	struct session_op *sess = &state->d_sess;
+	int digest;
+
+	if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef){
+		printf("cryptodev_digest_init: Can't get digest \n");
+		return (0);
+	}
+
+	memset(state, 0, sizeof(struct dev_crypto_state));
+
+	if ((state->d_fd = get_dev_crypto()) < 0) {
+		printf("cryptodev_digest_init: Can't get Dev \n");
+		return (0);
+	}
+
+	sess->mackey = state->dummy_mac_key;
+	sess->mackeylen = digest_key_length(ctx->digest->type);
+	sess->mac = digest;
+
+	if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) {
+		close(state->d_fd);
+		state->d_fd = -1;
+		printf("cryptodev_digest_init: Open session failed\n");
+		return (0);
+	}
+
+	return (1);
+}
+
+static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data,
+		size_t count)
+{
+	struct crypt_op cryp;
+	struct dev_crypto_state *state = ctx->md_data;
+	struct session_op *sess = &state->d_sess;
+
+	if (!data || state->d_fd < 0) {
+		printf("cryptodev_digest_update: illegal inputs \n");
+		return (0);
+	}
+
+	if (!count) {
+		return (0);
+	}
+
+	if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) {
+		/* if application doesn't support one buffer */
+		state->mac_data = OPENSSL_realloc(state->mac_data, state->mac_len + count);
+
+		if (!state->mac_data) {
+			printf("cryptodev_digest_update: realloc failed\n");
+			return (0);
+		}
+
+		memcpy(state->mac_data + state->mac_len, data, count);
+   		state->mac_len += count;
+	
+		return (1);
+	}
+
+	memset(&cryp, 0, sizeof(cryp));
+
+	cryp.ses = sess->ses;
+	cryp.flags = 0;
+	cryp.len = count;
+	cryp.src = (caddr_t) data;
+	cryp.dst = NULL;
+	cryp.mac = (caddr_t) state->digest_res;
+	if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
+		printf("cryptodev_digest_update: digest failed\n");
+		return (0);
+	}
+	return (1);
+}
+
+
+static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+	struct crypt_op cryp;
+	struct dev_crypto_state *state = ctx->md_data;
+	struct session_op *sess = &state->d_sess;
+
+	int ret = 1;
+
+	if (!md || state->d_fd < 0) {
+		printf("cryptodev_digest_final: illegal input\n");
+		return(0);
+	}
+
+	if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) {
+		/* if application doesn't support one buffer */
+		memset(&cryp, 0, sizeof(cryp));
+
+		cryp.ses = sess->ses;
+		cryp.flags = 0;
+		cryp.len = state->mac_len;
+		cryp.src = state->mac_data;
+		cryp.dst = NULL;
+		cryp.mac = (caddr_t)md;
+
+		if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
+			printf("cryptodev_digest_final: digest failed\n");
+			return (0);
+		}
+
+		return 1;
+	}
+
+	memcpy(md, state->digest_res, ctx->digest->md_size);
+
+	return (ret);
+}
+
+
+static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
+{
+	int ret = 1;
+	struct dev_crypto_state *state = ctx->md_data;
+	struct session_op *sess = &state->d_sess;
+
+	if (state->d_fd < 0) {
+		printf("cryptodev_digest_cleanup: illegal input\n");
+		return (0);
+	}
+
+	if (state->mac_data) {
+		OPENSSL_free(state->mac_data);
+		state->mac_data = NULL;
+		state->mac_len = 0;
+	}
+
+	if (state->copy)
+		return 1;
+
+	if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
+		printf("cryptodev_digest_cleanup: failed to close session\n");
+		ret = 0;
+	} else {
+		ret = 1;
+	}
+	close(state->d_fd);	
+	state->d_fd = -1;
+
+	return (ret);
+}
+
+static int cryptodev_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
+{
+	struct dev_crypto_state *fstate = from->md_data;
+	struct dev_crypto_state *dstate = to->md_data;
+
+	memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
+
+	if (fstate->mac_len != 0) {
+		dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
+		memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
+	}
+
+	dstate->copy = 1;
+
+	return 1;
+}
+
+
+const EVP_MD cryptodev_sha1 = {
+	NID_sha1,
+	NID_undef, 
+	SHA_DIGEST_LENGTH, 
+	EVP_MD_FLAG_ONESHOT,
+	cryptodev_digest_init,
+	cryptodev_digest_update,
+	cryptodev_digest_final,
+	cryptodev_digest_copy,
+	cryptodev_digest_cleanup,
+	EVP_PKEY_NULL_method,
+	SHA_CBLOCK,
+	sizeof(struct dev_crypto_state),
+};
+
+const EVP_MD cryptodev_md5 = {
+	NID_md5,
+	NID_undef, 
+	16 /* MD5_DIGEST_LENGTH */, 
+	EVP_MD_FLAG_ONESHOT,
+	cryptodev_digest_init,
+	cryptodev_digest_update,
+	cryptodev_digest_final,
+	cryptodev_digest_copy,
+	cryptodev_digest_cleanup,
+	EVP_PKEY_NULL_method,
+	64 /* MD5_CBLOCK */,
+	sizeof(struct dev_crypto_state),
+};
+
+#endif /* USE_CRYPTODEV_DIGESTS */
+
+
 static int
 cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
     const int **nids, int nid)
@@ -615,10 +871,15 @@
 		return (cryptodev_usable_digests(nids));
 
 	switch (nid) {
+#ifdef USE_CRYPTODEV_DIGESTS
 	case NID_md5:
-		*digest = NULL; /* need to make a clean md5 critter */
+		*digest = &cryptodev_md5; 
 		break;
+	case NID_sha1:
+		*digest = &cryptodev_sha1;
+ 		break;
 	default:
+#endif /* USE_CRYPTODEV_DIGESTS */
 		*digest = NULL;
 		break;
 	}
@@ -646,8 +907,9 @@
 	b = malloc(bytes);
 	if (b == NULL)
 		return (1);
+	memset(b, 0, bytes);
 
-	crp->crp_p = (char *)b;
+	crp->crp_p = (caddr_t) b;
 	crp->crp_nbits = bits;
 
 	for (i = 0, j = 0; i < a->top; i++) {
@@ -690,7 +952,7 @@
 {
 	int i;
 
-	for (i = 0; i <= kop->crk_iparams + kop->crk_oparams; i++) {
+	for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) {
 		if (kop->crk_param[i].crp_p)
 			free(kop->crk_param[i].crp_p);
 		kop->crk_param[i].crp_p = NULL;
@@ -755,10 +1017,18 @@
 		goto err;
 	kop.crk_iparams = 3;
 
-	if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL) == -1) {
+	if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) {
 		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
+		printf("OCF asym process failed, Running in software\n");
+		ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
+
+	} else if (ECANCELED == kop.crk_status) {
+		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
+		printf("OCF hardware operation cancelled. Running in Software\n");
 		ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
 	}
+	/* else cryptodev operation worked ok ==> ret = 1*/
+
 err:
 	zapparams(&kop);
 	return (ret);
@@ -768,8 +1038,9 @@
 cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
 {
 	int r;
-
+	ctx = BN_CTX_new();
 	r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL);
+	BN_CTX_free(ctx);
 	return (r);
 }
 
@@ -801,10 +1072,18 @@
 		goto err;
 	kop.crk_iparams = 6;
 
-	if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL) == -1) {
+	if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) {
 		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
+		printf("OCF asym process failed, running in Software\n");
+		ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
+
+	} else if (ECANCELED == kop.crk_status) {
+		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
+		printf("OCF hardware operation cancelled. Running in Software\n");
 		ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
 	}
+	/* else cryptodev operation worked ok ==> ret = 1*/
+
 err:
 	zapparams(&kop);
 	return (ret);
@@ -940,7 +1219,8 @@
 	kop.crk_iparams = 7;
 
 	if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
-		dsaret = kop.crk_status;
+/*OCF success value is 0, if not zero, change dsaret to fail*/
+		if(0 != kop.crk_status) dsaret  = 0;
 	} else {
 		const DSA_METHOD *meth = DSA_OpenSSL();
 
@@ -1000,7 +1280,7 @@
 		goto err;
 	kop.crk_iparams = 3;
 
-	kop.crk_param[3].crp_p = (char *)key;
+	kop.crk_param[3].crp_p = (caddr_t) key;
 	kop.crk_param[3].crp_nbits = keylen * 8;
 	kop.crk_oparams = 1;
 
@@ -1031,7 +1311,7 @@
  * but I expect we'll want some options soon.
  */
 static int
-cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
+cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
 {
 #ifdef HAVE_SYSLOG_R
 	struct syslog_data sd = SYSLOG_DATA_INIT;
diff --git a/crypto/engine/eng_dyn.c b/crypto/engine/eng_dyn.c
index acb30c3..807da7a 100644
--- a/crypto/engine/eng_dyn.c
+++ b/crypto/engine/eng_dyn.c
@@ -146,14 +146,14 @@
 	 * 'dirs' for loading. Default is to use 'dirs' as a fallback. */
 	int dir_load;
 	/* A stack of directories from which ENGINEs could be loaded */
-	STACK *dirs;
+	STACK_OF(OPENSSL_STRING) *dirs;
 	};
 
 /* This is the "ex_data" index we obtain and reserve for use with our context
  * structure. */
 static int dynamic_ex_data_idx = -1;
 
-static void int_free_str(void *s) { OPENSSL_free(s); }
+static void int_free_str(char *s) { OPENSSL_free(s); }
 /* Because our ex_data element may or may not get allocated depending on whether
  * a "first-use" occurs before the ENGINE is freed, we have a memory leak
  * problem to solve. We can't declare a "new" handler for the ex_data as we
@@ -174,7 +174,7 @@
 		if(ctx->engine_id)
 			OPENSSL_free((void*)ctx->engine_id);
 		if(ctx->dirs)
-			sk_pop_free(ctx->dirs, int_free_str);
+			sk_OPENSSL_STRING_pop_free(ctx->dirs, int_free_str);
 		OPENSSL_free(ctx);
 		}
 	}
@@ -203,7 +203,7 @@
 	c->DYNAMIC_F1 = "v_check";
 	c->DYNAMIC_F2 = "bind_engine";
 	c->dir_load = 1;
-	c->dirs = sk_new_null();
+	c->dirs = sk_OPENSSL_STRING_new_null();
 	if(!c->dirs)
 		{
 		ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
@@ -393,7 +393,7 @@
 				ERR_R_MALLOC_FAILURE);
 			return 0;
 			}
-		sk_insert(ctx->dirs, tmp_str, -1);
+		sk_OPENSSL_STRING_insert(ctx->dirs, tmp_str, -1);
 		}
 		return 1;
 	default:
@@ -411,11 +411,11 @@
 				ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL)
 		return 1;
 	/* If we're not allowed to use 'dirs' or we have none, fail */
-	if(!ctx->dir_load || ((num = sk_num(ctx->dirs)) < 1))
+	if(!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1)
 		return 0;
 	for(loop = 0; loop < num; loop++)
 		{
-		const char *s = sk_value(ctx->dirs, loop);
+		const char *s = sk_OPENSSL_STRING_value(ctx->dirs, loop);
 		char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s);
 		if(!merge)
 			return 0;
diff --git a/crypto/engine/eng_err.c b/crypto/engine/eng_err.c
index ac74dd1..81c70ac 100644
--- a/crypto/engine/eng_err.c
+++ b/crypto/engine/eng_err.c
@@ -86,6 +86,8 @@
 {ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE),	"ENGINE_GET_DEFAULT_TYPE"},
 {ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST),	"ENGINE_get_digest"},
 {ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT),	"ENGINE_get_next"},
+{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH),	"ENGINE_get_pkey_asn1_meth"},
+{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_METH),	"ENGINE_get_pkey_meth"},
 {ERR_FUNC(ENGINE_F_ENGINE_GET_PREV),	"ENGINE_get_prev"},
 {ERR_FUNC(ENGINE_F_ENGINE_INIT),	"ENGINE_init"},
 {ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD),	"ENGINE_LIST_ADD"},
@@ -151,6 +153,7 @@
 {ERR_REASON(ENGINE_R_RSA_NOT_IMPLEMENTED),"rsa not implemented"},
 {ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER),"unimplemented cipher"},
 {ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST),"unimplemented digest"},
+{ERR_REASON(ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD),"unimplemented public key method"},
 {ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY),"version incompatibility"},
 {0,NULL}
 	};
diff --git a/crypto/engine/eng_fat.c b/crypto/engine/eng_fat.c
index 27c1662..db66e62 100644
--- a/crypto/engine/eng_fat.c
+++ b/crypto/engine/eng_fat.c
@@ -89,6 +89,12 @@
 #endif
 	if((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e))
 		return 0;
+	if((flags & ENGINE_METHOD_PKEY_METHS)
+				&& !ENGINE_set_default_pkey_meths(e))
+		return 0;
+	if((flags & ENGINE_METHOD_PKEY_ASN1_METHS)
+				&& !ENGINE_set_default_pkey_asn1_meths(e))
+		return 0;
 	return 1;
 	}
 
@@ -115,6 +121,13 @@
 		*pflags |= ENGINE_METHOD_CIPHERS;
 	else if (!strncmp(alg, "DIGESTS", len))
 		*pflags |= ENGINE_METHOD_DIGESTS;
+	else if (!strncmp(alg, "PKEY", len))
+		*pflags |=
+			ENGINE_METHOD_PKEY_METHS|ENGINE_METHOD_PKEY_ASN1_METHS;
+	else if (!strncmp(alg, "PKEY_CRYPTO", len))
+		*pflags |= ENGINE_METHOD_PKEY_METHS;
+	else if (!strncmp(alg, "PKEY_ASN1", len))
+		*pflags |= ENGINE_METHOD_PKEY_ASN1_METHS;
 	else
 		return 0;
 	return 1;
@@ -154,6 +167,7 @@
 	ENGINE_register_ECDSA(e);
 #endif
 	ENGINE_register_RAND(e);
+	ENGINE_register_pkey_meths(e);
 	return 1;
 	}
 
diff --git a/crypto/engine/eng_int.h b/crypto/engine/eng_int.h
index a66f107..451ef8f 100644
--- a/crypto/engine/eng_int.h
+++ b/crypto/engine/eng_int.h
@@ -127,6 +127,8 @@
 ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l);
 #define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__)
 #endif
+typedef void (engine_table_doall_cb)(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg);
+void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, void *arg);
 
 /* Internal versions of API functions that have control over locking. These are
  * used between C files when functionality needs to be shared but the caller may
@@ -143,6 +145,11 @@
 /* NB: Bitwise OR-able values for the "flags" variable in ENGINE are now exposed
  * in engine.h. */
 
+/* Free up dynamically allocated public key methods associated with ENGINE */
+
+void engine_pkey_meths_free(ENGINE *e);
+void engine_pkey_asn1_meths_free(ENGINE *e);
+
 /* This is a structure for storing implementations of various crypto
  * algorithms and functions. */
 struct engine_st
@@ -160,7 +167,10 @@
 	ENGINE_CIPHERS_PTR ciphers;
 	/* Digest handling is via this callback */
 	ENGINE_DIGESTS_PTR digests;
-
+	/* Public key handling via this callback */
+	ENGINE_PKEY_METHS_PTR pkey_meths;
+	/* ASN1 public key handling via this callback */
+	ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths;
 
 	ENGINE_GEN_INT_FUNC_PTR	destroy;
 
diff --git a/crypto/engine/eng_lib.c b/crypto/engine/eng_lib.c
index 5815b86..18a6664 100644
--- a/crypto/engine/eng_lib.c
+++ b/crypto/engine/eng_lib.c
@@ -125,6 +125,9 @@
 		abort();
 		}
 #endif
+	/* Free up any dynamically allocated public key methods */
+	engine_pkey_meths_free(e);
+	engine_pkey_asn1_meths_free(e);
 	/* Give the ENGINE a chance to do any structural cleanup corresponding
 	 * to allocation it did in its constructor (eg. unload error strings) */
 	if(e->destroy)
diff --git a/crypto/engine/eng_list.c b/crypto/engine/eng_list.c
index bd51194..27846ed 100644
--- a/crypto/engine/eng_list.c
+++ b/crypto/engine/eng_list.c
@@ -336,6 +336,7 @@
 	dest->store_meth = src->store_meth;
 	dest->ciphers = src->ciphers;
 	dest->digests = src->digests;
+	dest->pkey_meths = src->pkey_meths;
 	dest->destroy = src->destroy;
 	dest->init = src->init;
 	dest->finish = src->finish;
@@ -412,6 +413,7 @@
 		return iterator;
 		}
 notfound:
+	ENGINE_free(iterator);
 	ENGINEerr(ENGINE_F_ENGINE_BY_ID,ENGINE_R_NO_SUCH_ENGINE);
 	ERR_add_error_data(2, "id=", id);
 	return NULL;
diff --git a/crypto/engine/eng_openssl.c b/crypto/engine/eng_openssl.c
index 7c139ae..9abb95c 100644
--- a/crypto/engine/eng_openssl.c
+++ b/crypto/engine/eng_openssl.c
@@ -238,7 +238,7 @@
 	return 1;
 	}
 static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-		      const unsigned char *in, unsigned int inl)
+		      const unsigned char *in, size_t inl)
 	{
 #ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
 	fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
diff --git a/crypto/engine/eng_padlock.c b/crypto/engine/eng_padlock.c
deleted file mode 100644
index 743558a..0000000
--- a/crypto/engine/eng_padlock.c
+++ /dev/null
@@ -1,1219 +0,0 @@
-/* 
- * Support for VIA PadLock Advanced Cryptography Engine (ACE)
- * Written by Michal Ludvig <michal@logix.cz>
- *            http://www.logix.cz/michal
- *
- * Big thanks to Andy Polyakov for a help with optimization, 
- * assembler fixes, port to MS Windows and a lot of other 
- * valuable work on this engine!
- */
-
-/* ====================================================================
- * Copyright (c) 1999-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
- *    licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-
-#include <stdio.h>
-#include <string.h>
-
-#include <openssl/opensslconf.h>
-#include <openssl/crypto.h>
-#include <openssl/dso.h>
-#include <openssl/engine.h>
-#include <openssl/evp.h>
-#ifndef OPENSSL_NO_AES
-#include <openssl/aes.h>
-#endif
-#include <openssl/rand.h>
-#include <openssl/err.h>
-
-#ifndef OPENSSL_NO_HW
-#ifndef OPENSSL_NO_HW_PADLOCK
-
-/* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */
-#if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
-#  ifndef OPENSSL_NO_DYNAMIC_ENGINE
-#    define DYNAMIC_ENGINE
-#  endif
-#elif (OPENSSL_VERSION_NUMBER >= 0x00907000L)
-#  ifdef ENGINE_DYNAMIC_SUPPORT
-#    define DYNAMIC_ENGINE
-#  endif
-#else
-#  error "Only OpenSSL >= 0.9.7 is supported"
-#endif
-
-/* VIA PadLock AES is available *ONLY* on some x86 CPUs.
-   Not only that it doesn't exist elsewhere, but it
-   even can't be compiled on other platforms!
- 
-   In addition, because of the heavy use of inline assembler,
-   compiler choice is limited to GCC and Microsoft C. */
-#undef COMPILE_HW_PADLOCK
-#if !defined(I386_ONLY) && !defined(OPENSSL_NO_INLINE_ASM)
-# if (defined(__GNUC__) && (defined(__i386__) || defined(__i386))) || \
-     (defined(_MSC_VER) && defined(_M_IX86))
-#  define COMPILE_HW_PADLOCK
-static ENGINE *ENGINE_padlock (void);
-# endif
-#endif
-
-void ENGINE_load_padlock (void)
-{
-/* On non-x86 CPUs it just returns. */
-#ifdef COMPILE_HW_PADLOCK
-	ENGINE *toadd = ENGINE_padlock ();
-	if (!toadd) return;
-	ENGINE_add (toadd);
-	ENGINE_free (toadd);
-	ERR_clear_error ();
-#endif
-}
-
-#ifdef COMPILE_HW_PADLOCK
-/* We do these includes here to avoid header problems on platforms that
-   do not have the VIA padlock anyway... */
-#ifdef _MSC_VER
-# include <malloc.h>
-# define alloca _alloca
-#elif defined(NETWARE_CLIB) && defined(__GNUC__)
-  void *alloca(size_t);
-# define alloca(s) __builtin_alloca(s)
-#else
-# include <stdlib.h>
-#endif
-
-/* Function for ENGINE detection and control */
-static int padlock_available(void);
-static int padlock_init(ENGINE *e);
-
-/* RNG Stuff */
-static RAND_METHOD padlock_rand;
-
-/* Cipher Stuff */
-#ifndef OPENSSL_NO_AES
-static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
-#endif
-
-/* Engine names */
-static const char *padlock_id = "padlock";
-static char padlock_name[100];
-
-/* Available features */
-static int padlock_use_ace = 0;	/* Advanced Cryptography Engine */
-static int padlock_use_rng = 0;	/* Random Number Generator */
-#ifndef OPENSSL_NO_AES
-static int padlock_aes_align_required = 1;
-#endif
-
-/* ===== Engine "management" functions ===== */
-
-/* Prepare the ENGINE structure for registration */
-static int
-padlock_bind_helper(ENGINE *e)
-{
-	/* Check available features */
-	padlock_available();
-
-#if 1	/* disable RNG for now, see commentary in vicinity of RNG code */
-	padlock_use_rng=0;
-#endif
-
-	/* Generate a nice engine name with available features */
-	BIO_snprintf(padlock_name, sizeof(padlock_name),
-		"VIA PadLock (%s, %s)", 
-		 padlock_use_rng ? "RNG" : "no-RNG",
-		 padlock_use_ace ? "ACE" : "no-ACE");
-
-	/* Register everything or return with an error */ 
-	if (!ENGINE_set_id(e, padlock_id) ||
-	    !ENGINE_set_name(e, padlock_name) ||
-
-	    !ENGINE_set_init_function(e, padlock_init) ||
-#ifndef OPENSSL_NO_AES
-	    (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) ||
-#endif
-	    (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) {
-		return 0;
-	}
-
-	/* Everything looks good */
-	return 1;
-}
-
-/* Constructor */
-static ENGINE *
-ENGINE_padlock(void)
-{
-	ENGINE *eng = ENGINE_new();
-
-	if (!eng) {
-		return NULL;
-	}
-
-	if (!padlock_bind_helper(eng)) {
-		ENGINE_free(eng);
-		return NULL;
-	}
-
-	return eng;
-}
-
-/* Check availability of the engine */
-static int
-padlock_init(ENGINE *e)
-{
-	return (padlock_use_rng || padlock_use_ace);
-}
-
-/* This stuff is needed if this ENGINE is being compiled into a self-contained
- * shared-library.
- */
-#ifdef DYNAMIC_ENGINE
-static int
-padlock_bind_fn(ENGINE *e, const char *id)
-{
-	if (id && (strcmp(id, padlock_id) != 0)) {
-		return 0;
-	}
-
-	if (!padlock_bind_helper(e))  {
-		return 0;
-	}
-
-	return 1;
-}
-
-IMPLEMENT_DYNAMIC_CHECK_FN ()
-IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn)
-#endif /* DYNAMIC_ENGINE */
-
-/* ===== Here comes the "real" engine ===== */
-
-#ifndef OPENSSL_NO_AES
-/* Some AES-related constants */
-#define AES_BLOCK_SIZE		16
-#define AES_KEY_SIZE_128	16
-#define AES_KEY_SIZE_192	24
-#define AES_KEY_SIZE_256	32
-
-/* Here we store the status information relevant to the 
-   current context. */
-/* BIG FAT WARNING:
- * 	Inline assembler in PADLOCK_XCRYPT_ASM()
- * 	depends on the order of items in this structure.
- * 	Don't blindly modify, reorder, etc!
- */
-struct padlock_cipher_data
-{
-	unsigned char iv[AES_BLOCK_SIZE];	/* Initialization vector */
-	union {	unsigned int pad[4];
-		struct {
-			int rounds:4;
-			int dgst:1;	/* n/a in C3 */
-			int align:1;	/* n/a in C3 */
-			int ciphr:1;	/* n/a in C3 */
-			unsigned int keygen:1;
-			int interm:1;
-			unsigned int encdec:1;
-			int ksize:2;
-		} b;
-	} cword;		/* Control word */
-	AES_KEY ks;		/* Encryption key */
-};
-
-/*
- * Essentially this variable belongs in thread local storage.
- * Having this variable global on the other hand can only cause
- * few bogus key reloads [if any at all on single-CPU system],
- * so we accept the penatly...
- */
-static volatile struct padlock_cipher_data *padlock_saved_context;
-#endif
-
-/*
- * =======================================================
- * Inline assembler section(s).
- * =======================================================
- * Order of arguments is chosen to facilitate Windows port
- * using __fastcall calling convention. If you wish to add
- * more routines, keep in mind that first __fastcall
- * argument is passed in %ecx and second - in %edx.
- * =======================================================
- */
-#if defined(__GNUC__) && __GNUC__>=2
-/*
- * As for excessive "push %ebx"/"pop %ebx" found all over.
- * When generating position-independent code GCC won't let
- * us use "b" in assembler templates nor even respect "ebx"
- * in "clobber description." Therefore the trouble...
- */
-
-/* Helper function - check if a CPUID instruction
-   is available on this CPU */
-static int
-padlock_insn_cpuid_available(void)
-{
-	int result = -1;
-
-	/* We're checking if the bit #21 of EFLAGS 
-	   can be toggled. If yes = CPUID is available. */
-	asm volatile (
-		"pushf\n"
-		"popl %%eax\n"
-		"xorl $0x200000, %%eax\n"
-		"movl %%eax, %%ecx\n"
-		"andl $0x200000, %%ecx\n"
-		"pushl %%eax\n"
-		"popf\n"
-		"pushf\n"
-		"popl %%eax\n"
-		"andl $0x200000, %%eax\n"
-		"xorl %%eax, %%ecx\n"
-		"movl %%ecx, %0\n"
-		: "=r" (result) : : "eax", "ecx");
-	
-	return (result == 0);
-}
-
-/* Load supported features of the CPU to see if
-   the PadLock is available. */
-static int
-padlock_available(void)
-{
-	char vendor_string[16];
-	unsigned int eax, edx;
-
-	/* First check if the CPUID instruction is available at all... */
-	if (! padlock_insn_cpuid_available())
-		return 0;
-
-	/* Are we running on the Centaur (VIA) CPU? */
-	eax = 0x00000000;
-	vendor_string[12] = 0;
-	asm volatile (
-		"pushl	%%ebx\n"
-		"cpuid\n"
-		"movl	%%ebx,(%%edi)\n"
-		"movl	%%edx,4(%%edi)\n"
-		"movl	%%ecx,8(%%edi)\n"
-		"popl	%%ebx"
-		: "+a"(eax) : "D"(vendor_string) : "ecx", "edx");
-	if (strcmp(vendor_string, "CentaurHauls") != 0)
-		return 0;
-
-	/* Check for Centaur Extended Feature Flags presence */
-	eax = 0xC0000000;
-	asm volatile ("pushl %%ebx; cpuid; popl	%%ebx"
-		: "+a"(eax) : : "ecx", "edx");
-	if (eax < 0xC0000001)
-		return 0;
-
-	/* Read the Centaur Extended Feature Flags */
-	eax = 0xC0000001;
-	asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
-		: "+a"(eax), "=d"(edx) : : "ecx");
-
-	/* Fill up some flags */
-	padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6));
-	padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2));
-
-	return padlock_use_ace + padlock_use_rng;
-}
-
-#ifndef OPENSSL_NO_AES
-/* Our own htonl()/ntohl() */
-static inline void
-padlock_bswapl(AES_KEY *ks)
-{
-	size_t i = sizeof(ks->rd_key)/sizeof(ks->rd_key[0]);
-	unsigned int *key = ks->rd_key;
-
-	while (i--) {
-		asm volatile ("bswapl %0" : "+r"(*key));
-		key++;
-	}
-}
-#endif
-
-/* Force key reload from memory to the CPU microcode.
-   Loading EFLAGS from the stack clears EFLAGS[30] 
-   which does the trick. */
-static inline void
-padlock_reload_key(void)
-{
-	asm volatile ("pushfl; popfl");
-}
-
-#ifndef OPENSSL_NO_AES
-/*
- * This is heuristic key context tracing. At first one
- * believes that one should use atomic swap instructions,
- * but it's not actually necessary. Point is that if
- * padlock_saved_context was changed by another thread
- * after we've read it and before we compare it with cdata,
- * our key *shall* be reloaded upon thread context switch
- * and we are therefore set in either case...
- */
-static inline void
-padlock_verify_context(struct padlock_cipher_data *cdata)
-{
-	asm volatile (
-	"pushfl\n"
-"	btl	$30,(%%esp)\n"
-"	jnc	1f\n"
-"	cmpl	%2,%1\n"
-"	je	1f\n"
-"	popfl\n"
-"	subl	$4,%%esp\n"
-"1:	addl	$4,%%esp\n"
-"	movl	%2,%0"
-	:"+m"(padlock_saved_context)
-	: "r"(padlock_saved_context), "r"(cdata) : "cc");
-}
-
-/* Template for padlock_xcrypt_* modes */
-/* BIG FAT WARNING: 
- * 	The offsets used with 'leal' instructions
- * 	describe items of the 'padlock_cipher_data'
- * 	structure.
- */
-#define PADLOCK_XCRYPT_ASM(name,rep_xcrypt)	\
-static inline void *name(size_t cnt,		\
-	struct padlock_cipher_data *cdata,	\
-	void *out, const void *inp) 		\
-{	void *iv; 				\
-	asm volatile ( "pushl	%%ebx\n"	\
-		"	leal	16(%0),%%edx\n"	\
-		"	leal	32(%0),%%ebx\n"	\
-			rep_xcrypt "\n"		\
-		"	popl	%%ebx"		\
-		: "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \
-		: "0"(cdata), "1"(cnt), "2"(out), "3"(inp)  \
-		: "edx", "cc", "memory");	\
-	return iv;				\
-}
-
-/* Generate all functions with appropriate opcodes */
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8")	/* rep xcryptecb */
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0")	/* rep xcryptcbc */
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0")	/* rep xcryptcfb */
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8")	/* rep xcryptofb */
-#endif
-
-/* The RNG call itself */
-static inline unsigned int
-padlock_xstore(void *addr, unsigned int edx_in)
-{
-	unsigned int eax_out;
-
-	asm volatile (".byte 0x0f,0xa7,0xc0"	/* xstore */
-	    : "=a"(eax_out),"=m"(*(unsigned *)addr)
-	    : "D"(addr), "d" (edx_in)
-	    );
-
-	return eax_out;
-}
-
-/* Why not inline 'rep movsd'? I failed to find information on what
- * value in Direction Flag one can expect and consequently have to
- * apply "better-safe-than-sorry" approach and assume "undefined."
- * I could explicitly clear it and restore the original value upon
- * return from padlock_aes_cipher, but it's presumably too much
- * trouble for too little gain...
- *
- * In case you wonder 'rep xcrypt*' instructions above are *not*
- * affected by the Direction Flag and pointers advance toward
- * larger addresses unconditionally.
- */ 
-static inline unsigned char *
-padlock_memcpy(void *dst,const void *src,size_t n)
-{
-	long       *d=dst;
-	const long *s=src;
-
-	n /= sizeof(*d);
-	do { *d++ = *s++; } while (--n);
-
-	return dst;
-}
-
-#elif defined(_MSC_VER)
-/*
- * Unlike GCC these are real functions. In order to minimize impact
- * on performance we adhere to __fastcall calling convention in
- * order to get two first arguments passed through %ecx and %edx.
- * Which kind of suits very well, as instructions in question use
- * both %ecx and %edx as input:-)
- */
-#define REP_XCRYPT(code)		\
-	_asm _emit 0xf3			\
-	_asm _emit 0x0f _asm _emit 0xa7	\
-	_asm _emit code
-
-/* BIG FAT WARNING: 
- * 	The offsets used with 'lea' instructions
- * 	describe items of the 'padlock_cipher_data'
- * 	structure.
- */
-#define PADLOCK_XCRYPT_ASM(name,code)	\
-static void * __fastcall 		\
-	name (size_t cnt, void *cdata,	\
-	void *outp, const void *inp)	\
-{	_asm	mov	eax,edx		\
-	_asm	lea	edx,[eax+16]	\
-	_asm	lea	ebx,[eax+32]	\
-	_asm	mov	edi,outp	\
-	_asm	mov	esi,inp		\
-	REP_XCRYPT(code)		\
-}
-
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb,0xc8)
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc,0xd0)
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb,0xe0)
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb,0xe8)
-
-static int __fastcall
-padlock_xstore(void *outp,unsigned int code)
-{	_asm	mov	edi,ecx
-	_asm _emit 0x0f _asm _emit 0xa7 _asm _emit 0xc0
-}
-
-static void __fastcall
-padlock_reload_key(void)
-{	_asm pushfd _asm popfd		}
-
-static void __fastcall
-padlock_verify_context(void *cdata)
-{	_asm	{
-		pushfd
-		bt	DWORD PTR[esp],30
-		jnc	skip
-		cmp	ecx,padlock_saved_context
-		je	skip
-		popfd
-		sub	esp,4
-	skip:	add	esp,4
-		mov	padlock_saved_context,ecx
-		}
-}
-
-static int
-padlock_available(void)
-{	_asm	{
-		pushfd
-		pop	eax
-		mov	ecx,eax
-		xor	eax,1<<21
-		push	eax
-		popfd
-		pushfd
-		pop	eax
-		xor	eax,ecx
-		bt	eax,21
-		jnc	noluck
-		mov	eax,0
-		cpuid
-		xor	eax,eax
-		cmp	ebx,'tneC'
-		jne	noluck
-		cmp	edx,'Hrua'
-		jne	noluck
-		cmp	ecx,'slua'
-		jne	noluck
-		mov	eax,0xC0000000
-		cpuid
-		mov	edx,eax
-		xor	eax,eax
-		cmp	edx,0xC0000001
-		jb	noluck
-		mov	eax,0xC0000001
-		cpuid
-		xor	eax,eax
-		bt	edx,6
-		jnc	skip_a
-		bt	edx,7
-		jnc	skip_a
-		mov	padlock_use_ace,1
-		inc	eax
-	skip_a:	bt	edx,2
-		jnc	skip_r
-		bt	edx,3
-		jnc	skip_r
-		mov	padlock_use_rng,1
-		inc	eax
-	skip_r:
-	noluck:
-		}
-}
-
-static void __fastcall
-padlock_bswapl(void *key)
-{	_asm	{
-		pushfd
-		cld
-		mov	esi,ecx
-		mov	edi,ecx
-		mov	ecx,60
-	up:	lodsd
-		bswap	eax
-		stosd
-		loop	up
-		popfd
-		}
-}
-
-/* MS actually specifies status of Direction Flag and compiler even
- * manages to compile following as 'rep movsd' all by itself...
- */
-#define padlock_memcpy(o,i,n) ((unsigned char *)memcpy((o),(i),(n)&~3U))
-#endif
-
-/* ===== AES encryption/decryption ===== */
-#ifndef OPENSSL_NO_AES
-
-#if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)
-#define NID_aes_128_cfb	NID_aes_128_cfb128
-#endif
-
-#if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb)
-#define NID_aes_128_ofb	NID_aes_128_ofb128
-#endif
-
-#if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb)
-#define NID_aes_192_cfb	NID_aes_192_cfb128
-#endif
-
-#if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb)
-#define NID_aes_192_ofb	NID_aes_192_ofb128
-#endif
-
-#if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb)
-#define NID_aes_256_cfb	NID_aes_256_cfb128
-#endif
-
-#if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb)
-#define NID_aes_256_ofb	NID_aes_256_ofb128
-#endif
-
-/* List of supported ciphers. */
-static int padlock_cipher_nids[] = {
-	NID_aes_128_ecb,
-	NID_aes_128_cbc,
-	NID_aes_128_cfb,
-	NID_aes_128_ofb,
-
-	NID_aes_192_ecb,
-	NID_aes_192_cbc,
-	NID_aes_192_cfb,
-	NID_aes_192_ofb,
-
-	NID_aes_256_ecb,
-	NID_aes_256_cbc,
-	NID_aes_256_cfb,
-	NID_aes_256_ofb,
-};
-static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/
-				      sizeof(padlock_cipher_nids[0]));
-
-/* Function prototypes ... */
-static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-				const unsigned char *iv, int enc);
-static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-			      const unsigned char *in, size_t nbytes);
-
-#define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) +		\
-	( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F )	)
-#define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\
-	NEAREST_ALIGNED(ctx->cipher_data))
-
-#define EVP_CIPHER_block_size_ECB	AES_BLOCK_SIZE
-#define EVP_CIPHER_block_size_CBC	AES_BLOCK_SIZE
-#define EVP_CIPHER_block_size_OFB	1
-#define EVP_CIPHER_block_size_CFB	1
-
-/* Declaring so many ciphers by hand would be a pain.
-   Instead introduce a bit of preprocessor magic :-) */
-#define	DECLARE_AES_EVP(ksize,lmode,umode)	\
-static const EVP_CIPHER padlock_aes_##ksize##_##lmode = {	\
-	NID_aes_##ksize##_##lmode,		\
-	EVP_CIPHER_block_size_##umode,	\
-	AES_KEY_SIZE_##ksize,		\
-	AES_BLOCK_SIZE,			\
-	0 | EVP_CIPH_##umode##_MODE,	\
-	padlock_aes_init_key,		\
-	padlock_aes_cipher,		\
-	NULL,				\
-	sizeof(struct padlock_cipher_data) + 16,	\
-	EVP_CIPHER_set_asn1_iv,		\
-	EVP_CIPHER_get_asn1_iv,		\
-	NULL,				\
-	NULL				\
-}
-
-DECLARE_AES_EVP(128,ecb,ECB);
-DECLARE_AES_EVP(128,cbc,CBC);
-DECLARE_AES_EVP(128,cfb,CFB);
-DECLARE_AES_EVP(128,ofb,OFB);
-
-DECLARE_AES_EVP(192,ecb,ECB);
-DECLARE_AES_EVP(192,cbc,CBC);
-DECLARE_AES_EVP(192,cfb,CFB);
-DECLARE_AES_EVP(192,ofb,OFB);
-
-DECLARE_AES_EVP(256,ecb,ECB);
-DECLARE_AES_EVP(256,cbc,CBC);
-DECLARE_AES_EVP(256,cfb,CFB);
-DECLARE_AES_EVP(256,ofb,OFB);
-
-static int
-padlock_ciphers (ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid)
-{
-	/* No specific cipher => return a list of supported nids ... */
-	if (!cipher) {
-		*nids = padlock_cipher_nids;
-		return padlock_cipher_nids_num;
-	}
-
-	/* ... or the requested "cipher" otherwise */
-	switch (nid) {
-	  case NID_aes_128_ecb:
-	    *cipher = &padlock_aes_128_ecb;
-	    break;
-	  case NID_aes_128_cbc:
-	    *cipher = &padlock_aes_128_cbc;
-	    break;
-	  case NID_aes_128_cfb:
-	    *cipher = &padlock_aes_128_cfb;
-	    break;
-	  case NID_aes_128_ofb:
-	    *cipher = &padlock_aes_128_ofb;
-	    break;
-
-	  case NID_aes_192_ecb:
-	    *cipher = &padlock_aes_192_ecb;
-	    break;
-	  case NID_aes_192_cbc:
-	    *cipher = &padlock_aes_192_cbc;
-	    break;
-	  case NID_aes_192_cfb:
-	    *cipher = &padlock_aes_192_cfb;
-	    break;
-	  case NID_aes_192_ofb:
-	    *cipher = &padlock_aes_192_ofb;
-	    break;
-
-	  case NID_aes_256_ecb:
-	    *cipher = &padlock_aes_256_ecb;
-	    break;
-	  case NID_aes_256_cbc:
-	    *cipher = &padlock_aes_256_cbc;
-	    break;
-	  case NID_aes_256_cfb:
-	    *cipher = &padlock_aes_256_cfb;
-	    break;
-	  case NID_aes_256_ofb:
-	    *cipher = &padlock_aes_256_ofb;
-	    break;
-
-	  default:
-	    /* Sorry, we don't support this NID */
-	    *cipher = NULL;
-	    return 0;
-	}
-
-	return 1;
-}
-
-/* Prepare the encryption key for PadLock usage */
-static int
-padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key,
-		      const unsigned char *iv, int enc)
-{
-	struct padlock_cipher_data *cdata;
-	int key_len = EVP_CIPHER_CTX_key_length(ctx) * 8;
-
-	if (key==NULL) return 0;	/* ERROR */
-
-	cdata = ALIGNED_CIPHER_DATA(ctx);
-	memset(cdata, 0, sizeof(struct padlock_cipher_data));
-
-	/* Prepare Control word. */
-	if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE)
-		cdata->cword.b.encdec = 0;
-	else
-		cdata->cword.b.encdec = (ctx->encrypt == 0);
-	cdata->cword.b.rounds = 10 + (key_len - 128) / 32;
-	cdata->cword.b.ksize = (key_len - 128) / 64;
-
-	switch(key_len) {
-		case 128:
-			/* PadLock can generate an extended key for
-			   AES128 in hardware */
-			memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128);
-			cdata->cword.b.keygen = 0;
-			break;
-
-		case 192:
-		case 256:
-			/* Generate an extended AES key in software.
-			   Needed for AES192/AES256 */
-			/* Well, the above applies to Stepping 8 CPUs
-			   and is listed as hardware errata. They most
-			   likely will fix it at some point and then
-			   a check for stepping would be due here. */
-			if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE ||
-			    EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE ||
-			    enc)
-				AES_set_encrypt_key(key, key_len, &cdata->ks);
-			else
-				AES_set_decrypt_key(key, key_len, &cdata->ks);
-#ifndef AES_ASM
-			/* OpenSSL C functions use byte-swapped extended key. */
-			padlock_bswapl(&cdata->ks);
-#endif
-			cdata->cword.b.keygen = 1;
-			break;
-
-		default:
-			/* ERROR */
-			return 0;
-	}
-
-	/*
-	 * This is done to cover for cases when user reuses the
-	 * context for new key. The catch is that if we don't do
-	 * this, padlock_eas_cipher might proceed with old key...
-	 */
-	padlock_reload_key ();
-
-	return 1;
-}
-
-/* 
- * Simplified version of padlock_aes_cipher() used when
- * 1) both input and output buffers are at aligned addresses.
- * or when
- * 2) running on a newer CPU that doesn't require aligned buffers.
- */
-static int
-padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
-		const unsigned char *in_arg, size_t nbytes)
-{
-	struct padlock_cipher_data *cdata;
-	void  *iv;
-
-	cdata = ALIGNED_CIPHER_DATA(ctx);
-	padlock_verify_context(cdata);
-
-	switch (EVP_CIPHER_CTX_mode(ctx)) {
-	case EVP_CIPH_ECB_MODE:
-		padlock_xcrypt_ecb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
-		break;
-
-	case EVP_CIPH_CBC_MODE:
-		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
-		iv = padlock_xcrypt_cbc(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
-		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
-		break;
-
-	case EVP_CIPH_CFB_MODE:
-		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
-		iv = padlock_xcrypt_cfb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
-		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
-		break;
-
-	case EVP_CIPH_OFB_MODE:
-		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
-		padlock_xcrypt_ofb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
-		memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
-		break;
-
-	default:
-		return 0;
-	}
-
-	memset(cdata->iv, 0, AES_BLOCK_SIZE);
-
-	return 1;
-}
-
-#ifndef  PADLOCK_CHUNK
-# define PADLOCK_CHUNK	512	/* Must be a power of 2 larger than 16 */
-#endif
-#if PADLOCK_CHUNK<16 || PADLOCK_CHUNK&(PADLOCK_CHUNK-1)
-# error "insane PADLOCK_CHUNK..."
-#endif
-
-/* Re-align the arguments to 16-Bytes boundaries and run the 
-   encryption function itself. This function is not AES-specific. */
-static int
-padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
-		   const unsigned char *in_arg, size_t nbytes)
-{
-	struct padlock_cipher_data *cdata;
-	const  void *inp;
-	unsigned char  *out;
-	void  *iv;
-	int    inp_misaligned, out_misaligned, realign_in_loop;
-	size_t chunk, allocated=0;
-
-	/* ctx->num is maintained in byte-oriented modes,
-	   such as CFB and OFB... */
-	if ((chunk = ctx->num)) { /* borrow chunk variable */
-		unsigned char *ivp=ctx->iv;
-
-		switch (EVP_CIPHER_CTX_mode(ctx)) {
-		case EVP_CIPH_CFB_MODE:
-			if (chunk >= AES_BLOCK_SIZE)
-				return 0; /* bogus value */
-
-			if (ctx->encrypt)
-				while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
-					ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk];
-					chunk++, nbytes--;
-				}
-			else	while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
-					unsigned char c = *(in_arg++);
-					*(out_arg++) = c ^ ivp[chunk];
-					ivp[chunk++] = c, nbytes--;
-				}
-
-			ctx->num = chunk%AES_BLOCK_SIZE;
-			break;
-		case EVP_CIPH_OFB_MODE:
-			if (chunk >= AES_BLOCK_SIZE)
-				return 0; /* bogus value */
-
-			while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
-				*(out_arg++) = *(in_arg++) ^ ivp[chunk];
-				chunk++, nbytes--;
-			}
-
-			ctx->num = chunk%AES_BLOCK_SIZE;
-			break;
-		}
-	}
-
-	if (nbytes == 0)
-		return 1;
-#if 0
-	if (nbytes % AES_BLOCK_SIZE)
-		return 0; /* are we expected to do tail processing? */
-#else
-	/* nbytes is always multiple of AES_BLOCK_SIZE in ECB and CBC
-	   modes and arbitrary value in byte-oriented modes, such as
-	   CFB and OFB... */
-#endif
-
-	/* VIA promises CPUs that won't require alignment in the future.
-	   For now padlock_aes_align_required is initialized to 1 and
-	   the condition is never met... */
-	/* C7 core is capable to manage unaligned input in non-ECB[!]
-	   mode, but performance penalties appear to be approximately
-	   same as for software alignment below or ~3x. They promise to
-	   improve it in the future, but for now we can just as well
-	   pretend that it can only handle aligned input... */
-	if (!padlock_aes_align_required && (nbytes%AES_BLOCK_SIZE)==0)
-		return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
-
-	inp_misaligned = (((size_t)in_arg) & 0x0F);
-	out_misaligned = (((size_t)out_arg) & 0x0F);
-
-	/* Note that even if output is aligned and input not,
-	 * I still prefer to loop instead of copy the whole
-	 * input and then encrypt in one stroke. This is done
-	 * in order to improve L1 cache utilization... */
-	realign_in_loop = out_misaligned|inp_misaligned;
-
-	if (!realign_in_loop && (nbytes%AES_BLOCK_SIZE)==0)
-		return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
-
-	/* this takes one "if" out of the loops */
-	chunk  = nbytes;
-	chunk %= PADLOCK_CHUNK;
-	if (chunk==0) chunk = PADLOCK_CHUNK;
-
-	if (out_misaligned) {
-		/* optmize for small input */
-		allocated = (chunk<nbytes?PADLOCK_CHUNK:nbytes);
-		out = alloca(0x10 + allocated);
-		out = NEAREST_ALIGNED(out);
-	}
-	else
-		out = out_arg;
-
-	cdata = ALIGNED_CIPHER_DATA(ctx);
-	padlock_verify_context(cdata);
-
-	switch (EVP_CIPHER_CTX_mode(ctx)) {
-	case EVP_CIPH_ECB_MODE:
-		do	{
-			if (inp_misaligned)
-				inp = padlock_memcpy(out, in_arg, chunk);
-			else
-				inp = in_arg;
-			in_arg += chunk;
-
-			padlock_xcrypt_ecb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
-
-			if (out_misaligned)
-				out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
-			else
-				out     = out_arg+=chunk;
-
-			nbytes -= chunk;
-			chunk   = PADLOCK_CHUNK;
-		} while (nbytes);
-		break;
-
-	case EVP_CIPH_CBC_MODE:
-		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
-		goto cbc_shortcut;
-		do	{
-			if (iv != cdata->iv)
-				memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
-			chunk = PADLOCK_CHUNK;
-		cbc_shortcut: /* optimize for small input */
-			if (inp_misaligned)
-				inp = padlock_memcpy(out, in_arg, chunk);
-			else
-				inp = in_arg;
-			in_arg += chunk;
-
-			iv = padlock_xcrypt_cbc(chunk/AES_BLOCK_SIZE, cdata, out, inp);
-
-			if (out_misaligned)
-				out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
-			else
-				out     = out_arg+=chunk;
-
-		} while (nbytes -= chunk);
-		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
-		break;
-
-	case EVP_CIPH_CFB_MODE:
-		memcpy (iv = cdata->iv, ctx->iv, AES_BLOCK_SIZE);
-		chunk &= ~(AES_BLOCK_SIZE-1);
-		if (chunk)	goto cfb_shortcut;
-		else		goto cfb_skiploop;
-		do	{
-			if (iv != cdata->iv)
-				memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
-			chunk = PADLOCK_CHUNK;
-		cfb_shortcut: /* optimize for small input */
-			if (inp_misaligned)
-				inp = padlock_memcpy(out, in_arg, chunk);
-			else
-				inp = in_arg;
-			in_arg += chunk;
-
-			iv = padlock_xcrypt_cfb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
-
-			if (out_misaligned)
-				out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
-			else
-				out     = out_arg+=chunk;
-
-			nbytes -= chunk;
-		} while (nbytes >= AES_BLOCK_SIZE);
-
-		cfb_skiploop:
-		if (nbytes) {
-			unsigned char *ivp = cdata->iv;
-
-			if (iv != ivp) {
-				memcpy(ivp, iv, AES_BLOCK_SIZE);
-				iv = ivp;
-			}
-			ctx->num = nbytes;
-			if (cdata->cword.b.encdec) {
-				cdata->cword.b.encdec=0;
-				padlock_reload_key();
-				padlock_xcrypt_ecb(1,cdata,ivp,ivp);
-				cdata->cword.b.encdec=1;
-				padlock_reload_key();
-				while(nbytes) {
-					unsigned char c = *(in_arg++);
-					*(out_arg++) = c ^ *ivp;
-					*(ivp++) = c, nbytes--;
-				}
-			}
-			else {	padlock_reload_key();
-				padlock_xcrypt_ecb(1,cdata,ivp,ivp);
-				padlock_reload_key();
-				while (nbytes) {
-					*ivp = *(out_arg++) = *(in_arg++) ^ *ivp;
-					ivp++, nbytes--;
-				}
-			}
-		}
-
-		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
-		break;
-
-	case EVP_CIPH_OFB_MODE:
-		memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
-		chunk &= ~(AES_BLOCK_SIZE-1);
-		if (chunk) do	{
-			if (inp_misaligned)
-				inp = padlock_memcpy(out, in_arg, chunk);
-			else
-				inp = in_arg;
-			in_arg += chunk;
-
-			padlock_xcrypt_ofb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
-
-			if (out_misaligned)
-				out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
-			else
-				out     = out_arg+=chunk;
-
-			nbytes -= chunk;
-			chunk   = PADLOCK_CHUNK;
-		} while (nbytes >= AES_BLOCK_SIZE);
-
-		if (nbytes) {
-			unsigned char *ivp = cdata->iv;
-
-			ctx->num = nbytes;
-			padlock_reload_key();	/* empirically found */
-			padlock_xcrypt_ecb(1,cdata,ivp,ivp);
-			padlock_reload_key();	/* empirically found */
-			while (nbytes) {
-				*(out_arg++) = *(in_arg++) ^ *ivp;
-				ivp++, nbytes--;
-			}
-		}
-
-		memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
-		break;
-
-	default:
-		return 0;
-	}
-
-	/* Clean the realign buffer if it was used */
-	if (out_misaligned) {
-		volatile unsigned long *p=(void *)out;
-		size_t   n = allocated/sizeof(*p);
-		while (n--) *p++=0;
-	}
-
-	memset(cdata->iv, 0, AES_BLOCK_SIZE);
-
-	return 1;
-}
-
-#endif /* OPENSSL_NO_AES */
-
-/* ===== Random Number Generator ===== */
-/*
- * This code is not engaged. The reason is that it does not comply
- * with recommendations for VIA RNG usage for secure applications
- * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it
- * provide meaningful error control...
- */
-/* Wrapper that provides an interface between the API and 
-   the raw PadLock RNG */
-static int
-padlock_rand_bytes(unsigned char *output, int count)
-{
-	unsigned int eax, buf;
-
-	while (count >= 8) {
-		eax = padlock_xstore(output, 0);
-		if (!(eax&(1<<6)))	return 0; /* RNG disabled */
-		/* this ---vv--- covers DC bias, Raw Bits and String Filter */
-		if (eax&(0x1F<<10))	return 0;
-		if ((eax&0x1F)==0)	continue; /* no data, retry... */
-		if ((eax&0x1F)!=8)	return 0; /* fatal failure...  */
-		output += 8;
-		count  -= 8;
-	}
-	while (count > 0) {
-		eax = padlock_xstore(&buf, 3);
-		if (!(eax&(1<<6)))	return 0; /* RNG disabled */
-		/* this ---vv--- covers DC bias, Raw Bits and String Filter */
-		if (eax&(0x1F<<10))	return 0;
-		if ((eax&0x1F)==0)	continue; /* no data, retry... */
-		if ((eax&0x1F)!=1)	return 0; /* fatal failure...  */
-		*output++ = (unsigned char)buf;
-		count--;
-	}
-	*(volatile unsigned int *)&buf=0;
-
-	return 1;
-}
-
-/* Dummy but necessary function */
-static int
-padlock_rand_status(void)
-{
-	return 1;
-}
-
-/* Prepare structure for registration */
-static RAND_METHOD padlock_rand = {
-	NULL,			/* seed */
-	padlock_rand_bytes,	/* bytes */
-	NULL,			/* cleanup */
-	NULL,			/* add */
-	padlock_rand_bytes,	/* pseudorand */
-	padlock_rand_status,	/* rand status */
-};
-
-#endif /* COMPILE_HW_PADLOCK */
-
-#endif /* !OPENSSL_NO_HW_PADLOCK */
-#endif /* !OPENSSL_NO_HW */
diff --git a/crypto/engine/eng_table.c b/crypto/engine/eng_table.c
index 8fc47b3..4fde948 100644
--- a/crypto/engine/eng_table.c
+++ b/crypto/engine/eng_table.c
@@ -70,12 +70,22 @@
 	int uptodate;
 	} ENGINE_PILE;
 
+DECLARE_LHASH_OF(ENGINE_PILE);
+
 /* The type exposed in eng_int.h */
 struct st_engine_table
 	{
-	LHASH piles;
+	LHASH_OF(ENGINE_PILE) piles;
 	}; /* ENGINE_TABLE */
 
+
+typedef struct st_engine_pile_doall
+	{
+	engine_table_doall_cb *cb;
+	void *arg;
+	} ENGINE_PILE_DOALL;
+	
+
 /* Global flags (ENGINE_TABLE_FLAG_***). */
 static unsigned int table_flags = 0;
 
@@ -84,6 +94,7 @@
 	{
 	return table_flags;
 	}
+
 void ENGINE_set_table_flags(unsigned int flags)
 	{
 	table_flags = flags;
@@ -94,19 +105,21 @@
 	{
 	return c->nid;
 	}
+
 static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b)
 	{
 	return a->nid - b->nid;
 	}
-static IMPLEMENT_LHASH_HASH_FN(engine_pile_hash, const ENGINE_PILE *)
-static IMPLEMENT_LHASH_COMP_FN(engine_pile_cmp, const ENGINE_PILE *)
+static IMPLEMENT_LHASH_HASH_FN(engine_pile, ENGINE_PILE)
+static IMPLEMENT_LHASH_COMP_FN(engine_pile, ENGINE_PILE)
+
 static int int_table_check(ENGINE_TABLE **t, int create)
 	{
-	LHASH *lh;
+	LHASH_OF(ENGINE_PILE) *lh;
+
 	if(*t) return 1;
 	if(!create) return 0;
-	if((lh = lh_new(LHASH_HASH_FN(engine_pile_hash),
-			LHASH_COMP_FN(engine_pile_cmp))) == NULL)
+	if((lh = lh_ENGINE_PILE_new()) == NULL)
 		return 0;
 	*t = (ENGINE_TABLE *)lh;
 	return 1;
@@ -130,7 +143,7 @@
 	while(num_nids--)
 		{
 		tmplate.nid = *nids;
-		fnd = lh_retrieve(&(*table)->piles, &tmplate);
+		fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
 		if(!fnd)
 			{
 			fnd = OPENSSL_malloc(sizeof(ENGINE_PILE));
@@ -144,7 +157,7 @@
 				goto end;
 				}
 			fnd->funct = NULL;
-			lh_insert(&(*table)->piles, fnd);
+			(void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd);
 			}
 		/* A registration shouldn't add duplciate entries */
 		(void)sk_ENGINE_delete_ptr(fnd->sk, e);
@@ -173,7 +186,7 @@
 	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
 	return ret;
 	}
-static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e)
+static void int_unregister_cb_doall_arg(ENGINE_PILE *pile, ENGINE *e)
 	{
 	int n;
 	/* Iterate the 'c->sk' stack removing any occurance of 'e' */
@@ -188,31 +201,35 @@
 		pile->funct = NULL;
 		}
 	}
-static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb,ENGINE_PILE *,ENGINE *)
+static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb, ENGINE_PILE, ENGINE)
+
 void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e)
 	{
 	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
 	if(int_table_check(table, 0))
-		lh_doall_arg(&(*table)->piles,
-			LHASH_DOALL_ARG_FN(int_unregister_cb), e);
+		lh_ENGINE_PILE_doall_arg(&(*table)->piles,
+					 LHASH_DOALL_ARG_FN(int_unregister_cb),
+					 ENGINE, e);
 	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
 	}
 
-static void int_cleanup_cb(ENGINE_PILE *p)
+static void int_cleanup_cb_doall(ENGINE_PILE *p)
 	{
 	sk_ENGINE_free(p->sk);
 	if(p->funct)
 		engine_unlocked_finish(p->funct, 0);
 	OPENSSL_free(p);
 	}
-static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb,ENGINE_PILE *)
+static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb, ENGINE_PILE)
+
 void engine_table_cleanup(ENGINE_TABLE **table)
 	{
 	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
 	if(*table)
 		{
-		lh_doall(&(*table)->piles, LHASH_DOALL_FN(int_cleanup_cb));
-		lh_free(&(*table)->piles);
+		lh_ENGINE_PILE_doall(&(*table)->piles,
+				     LHASH_DOALL_FN(int_cleanup_cb));
+		lh_ENGINE_PILE_free(&(*table)->piles);
 		*table = NULL;
 		}
 	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
@@ -243,7 +260,7 @@
 	 * operations. But don't worry about a fprintf(stderr). */
 	if(!int_table_check(table, 0)) goto end;
 	tmplate.nid = nid;
-	fnd = lh_retrieve(&(*table)->piles, &tmplate);
+	fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
 	if(!fnd) goto end;
 	if(fnd->funct && engine_unlocked_init(fnd->funct))
 		{
@@ -314,3 +331,21 @@
 	ERR_pop_to_mark();
 	return ret;
 	}
+
+/* Table enumeration */
+
+static void int_cb_doall_arg(ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall)
+	{
+	dall->cb(pile->nid, pile->sk, pile->funct, dall->arg);
+	}
+static IMPLEMENT_LHASH_DOALL_ARG_FN(int_cb, ENGINE_PILE,ENGINE_PILE_DOALL)
+
+void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb,
+								void *arg)
+	{
+	ENGINE_PILE_DOALL dall;
+	dall.cb = cb;
+	dall.arg = arg;
+	lh_ENGINE_PILE_doall_arg(&table->piles, LHASH_DOALL_ARG_FN(int_cb),
+				 ENGINE_PILE_DOALL, &dall);
+	}
diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h
index d4bc1ef..7fbd95f 100644
--- a/crypto/engine/engine.h
+++ b/crypto/engine/engine.h
@@ -88,16 +88,15 @@
 #include <openssl/ecdsa.h>
 #endif
 #include <openssl/rand.h>
-#include <openssl/store.h>
 #include <openssl/ui.h>
 #include <openssl/err.h>
 #endif
 
-#include <openssl/x509.h>
-
 #include <openssl/ossl_typ.h>
 #include <openssl/symhacks.h>
 
+#include <openssl/x509.h>
+
 #ifdef  __cplusplus
 extern "C" {
 #endif
@@ -113,6 +112,8 @@
 #define ENGINE_METHOD_CIPHERS		(unsigned int)0x0040
 #define ENGINE_METHOD_DIGESTS		(unsigned int)0x0080
 #define ENGINE_METHOD_STORE		(unsigned int)0x0100
+#define ENGINE_METHOD_PKEY_METHS	(unsigned int)0x0200
+#define ENGINE_METHOD_PKEY_ASN1_METHS	(unsigned int)0x0400
 /* Obvious all-or-nothing cases. */
 #define ENGINE_METHOD_ALL		(unsigned int)0xFFFF
 #define ENGINE_METHOD_NONE		(unsigned int)0x0000
@@ -297,7 +298,8 @@
  * parameter is non-NULL it is set to the size of the returned array. */
 typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int);
 typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int);
-
+typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, EVP_PKEY_METHOD **, const int **, int);
+typedef int (*ENGINE_PKEY_ASN1_METHS_PTR)(ENGINE *, EVP_PKEY_ASN1_METHOD **, const int **, int);
 /* STRUCTURE functions ... all of these functions deal with pointers to ENGINE
  * structures where the pointers have a "structural reference". This means that
  * their reference is to allowed access to the structure but it does not imply
@@ -329,21 +331,20 @@
 void ENGINE_load_atalla(void);
 void ENGINE_load_chil(void);
 void ENGINE_load_cswift(void);
-#ifndef OPENSSL_NO_GMP
-void ENGINE_load_gmp(void);
-#endif
 void ENGINE_load_nuron(void);
 void ENGINE_load_sureware(void);
 void ENGINE_load_ubsec(void);
+void ENGINE_load_padlock(void);
+void ENGINE_load_capi(void);
+#ifndef OPENSSL_NO_GMP
+void ENGINE_load_gmp(void);
+#endif
+#ifndef OPENSSL_NO_GOST
+void ENGINE_load_gost(void);
+#endif
 #endif
 void ENGINE_load_cryptodev(void);
-void ENGINE_load_padlock(void);
 void ENGINE_load_builtin_engines(void);
-#ifdef OPENSSL_SYS_WIN32
-#ifndef OPENSSL_NO_CAPIENG
-void ENGINE_load_capi(void);
-#endif
-#endif
 
 /* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
  * "registry" handling. */
@@ -394,6 +395,14 @@
 void ENGINE_unregister_digests(ENGINE *e);
 void ENGINE_register_all_digests(void);
 
+int ENGINE_register_pkey_meths(ENGINE *e);
+void ENGINE_unregister_pkey_meths(ENGINE *e);
+void ENGINE_register_all_pkey_meths(void);
+
+int ENGINE_register_pkey_asn1_meths(ENGINE *e);
+void ENGINE_unregister_pkey_asn1_meths(ENGINE *e);
+void ENGINE_register_all_pkey_asn1_meths(void);
+
 /* These functions register all support from the above categories. Note, use of
  * these functions can result in static linkage of code your application may not
  * need. If you only need a subset of functionality, consider using more
@@ -473,6 +482,8 @@
 				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_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f);
+int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f);
 int ENGINE_set_flags(ENGINE *e, int flags);
 int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
 /* These functions allow control over any per-structure ENGINE data. */
@@ -509,8 +520,16 @@
 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);
+ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e);
+ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e);
 const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
 const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
+const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
+					const char *str, int len);
+const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
+					const char *str, int len);
 const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
 int ENGINE_get_flags(const ENGINE *e);
 
@@ -562,6 +581,8 @@
  * ciphering or digesting corresponding to "nid". */
 ENGINE *ENGINE_get_cipher_engine(int nid);
 ENGINE *ENGINE_get_digest_engine(int nid);
+ENGINE *ENGINE_get_pkey_meth_engine(int nid);
+ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid);
 
 /* This sets a new default ENGINE structure for performing RSA
  * operations. If the result is non-zero (success) then the ENGINE
@@ -577,6 +598,8 @@
 int ENGINE_set_default_RAND(ENGINE *e);
 int ENGINE_set_default_ciphers(ENGINE *e);
 int ENGINE_set_default_digests(ENGINE *e);
+int ENGINE_set_default_pkey_meths(ENGINE *e);
+int ENGINE_set_default_pkey_asn1_meths(ENGINE *e);
 
 /* The combination "set" - the flags are bitwise "OR"d from the
  * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
@@ -705,7 +728,7 @@
  * values. */
 void *ENGINE_get_static_state(void);
 
-#if defined(__OpenBSD__) || defined(__FreeBSD__)
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
 void ENGINE_setup_bsd_cryptodev(void);
 #endif
 
@@ -734,13 +757,15 @@
 #define ENGINE_F_ENGINE_GET_DEFAULT_TYPE		 177
 #define ENGINE_F_ENGINE_GET_DIGEST			 186
 #define ENGINE_F_ENGINE_GET_NEXT			 115
+#define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH		 193
+#define ENGINE_F_ENGINE_GET_PKEY_METH			 192
 #define ENGINE_F_ENGINE_GET_PREV			 116
 #define ENGINE_F_ENGINE_INIT				 119
 #define ENGINE_F_ENGINE_LIST_ADD			 120
 #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_LOAD_SSL_CLIENT_CERT		 194
 #define ENGINE_F_ENGINE_NEW				 122
 #define ENGINE_F_ENGINE_REMOVE				 123
 #define ENGINE_F_ENGINE_SET_DEFAULT_STRING		 189
@@ -769,7 +794,7 @@
 #define ENGINE_R_DSO_FAILURE				 104
 #define ENGINE_R_DSO_NOT_FOUND				 132
 #define ENGINE_R_ENGINES_SECTION_ERROR			 148
-#define ENGINE_R_ENGINE_CONFIGURATION_ERROR		 101
+#define ENGINE_R_ENGINE_CONFIGURATION_ERROR		 102
 #define ENGINE_R_ENGINE_IS_NOT_IN_LIST			 105
 #define ENGINE_R_ENGINE_SECTION_ERROR			 149
 #define ENGINE_R_FAILED_LOADING_PRIVATE_KEY		 128
@@ -796,6 +821,7 @@
 #define ENGINE_R_RSA_NOT_IMPLEMENTED			 141
 #define ENGINE_R_UNIMPLEMENTED_CIPHER			 146
 #define ENGINE_R_UNIMPLEMENTED_DIGEST			 147
+#define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD	 101
 #define ENGINE_R_VERSION_INCOMPATIBILITY		 145
 
 #ifdef  __cplusplus
diff --git a/crypto/engine/enginetest.c b/crypto/engine/enginetest.c
index e383461..f4d70e7 100644
--- a/crypto/engine/enginetest.c
+++ b/crypto/engine/enginetest.c
@@ -276,7 +276,7 @@
 	ENGINE_cleanup();
 	CRYPTO_cleanup_all_ex_data();
 	ERR_free_strings();
-	ERR_remove_state(0);
+	ERR_remove_thread_state(NULL);
 	CRYPTO_mem_leaks_fp(stderr);
 	return to_return;
 	}
diff --git a/crypto/err/Makefile b/crypto/err/Makefile
deleted file mode 100644
index 96d8a1a..0000000
--- a/crypto/err/Makefile
+++ /dev/null
@@ -1,131 +0,0 @@
-#
-# OpenSSL/crypto/err/Makefile
-#
-
-DIR=	err
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-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)
-
-EXHEADER= err.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-err.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/buffer.h
-err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-err.o: ../cryptlib.h err.c
-err_all.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-err_all.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-err_all.o: ../../include/openssl/comp.h ../../include/openssl/conf.h
-err_all.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
-err_all.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
-err_all.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-err_all.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
-err_all.o: ../../include/openssl/engine.h ../../include/openssl/err.h
-err_all.o: ../../include/openssl/evp.h ../../include/openssl/fips.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_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
-err_prn.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-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 292404a..69713a6 100644
--- a/crypto/err/err.c
+++ b/crypto/err/err.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -119,9 +119,507 @@
 #include <openssl/bio.h>
 #include <openssl/err.h>
 
-static unsigned long get_error_values(int inc,int top,
-					const char **file,int *line,
-					const char **data,int *flags);
+DECLARE_LHASH_OF(ERR_STRING_DATA);
+DECLARE_LHASH_OF(ERR_STATE);
+
+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_TS,0,0)		,"time stamp 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_HMAC,0,0)		,"HMAC 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_TS_LIB				,"TS 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_OF(ERR_STRING_DATA) *(*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_OF(ERR_STATE) *(*cb_thread_get)(int create);
+	void (*cb_thread_release)(LHASH_OF(ERR_STATE) **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_OF(ERR_STRING_DATA) *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_OF(ERR_STATE) *int_thread_get(int create);
+static void int_thread_release(LHASH_OF(ERR_STATE) **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_OF(ERR_STRING_DATA) *int_error_hash = NULL;
+static LHASH_OF(ERR_STATE) *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 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 unsigned long err_string_data_hash(const ERR_STRING_DATA *a)
+	{
+	unsigned long ret,l;
+
+	l=a->error;
+	ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
+	return(ret^ret%19*13);
+	}
+static IMPLEMENT_LHASH_HASH_FN(err_string_data, ERR_STRING_DATA)
+
+static int err_string_data_cmp(const ERR_STRING_DATA *a,
+			       const ERR_STRING_DATA *b)
+	{
+	return (int)(a->error - b->error);
+	}
+static IMPLEMENT_LHASH_COMP_FN(err_string_data, ERR_STRING_DATA)
+
+static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create)
+	{
+	LHASH_OF(ERR_STRING_DATA) *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_ERR_STRING_DATA_new();
+		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_ERR_STRING_DATA_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_OF(ERR_STRING_DATA) *hash;
+
+	err_fns_check();
+	hash = ERRFN(err_get)(0);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
+	p = lh_ERR_STRING_DATA_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_OF(ERR_STRING_DATA) *hash;
+
+	err_fns_check();
+	hash = ERRFN(err_get)(1);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	p = lh_ERR_STRING_DATA_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_OF(ERR_STRING_DATA) *hash;
+
+	err_fns_check();
+	hash = ERRFN(err_get)(0);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	p = lh_ERR_STRING_DATA_delete(hash, d);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	return p;
+	}
+
+static unsigned long err_state_hash(const ERR_STATE *a)
+	{
+	return CRYPTO_THREADID_hash(&a->tid) * 13;
+	}
+static IMPLEMENT_LHASH_HASH_FN(err_state, ERR_STATE)
+
+static int err_state_cmp(const ERR_STATE *a, const ERR_STATE *b)
+	{
+	return CRYPTO_THREADID_cmp(&a->tid, &b->tid);
+	}
+static IMPLEMENT_LHASH_COMP_FN(err_state, ERR_STATE)
+
+static LHASH_OF(ERR_STATE) *int_thread_get(int create)
+	{
+	LHASH_OF(ERR_STATE) *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_ERR_STATE_new();
+		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_OF(ERR_STATE) **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_OF(ERR_STATE) *hash;
+
+	err_fns_check();
+	hash = ERRFN(thread_get)(0);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
+	p = lh_ERR_STATE_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_OF(ERR_STATE) *hash;
+
+	err_fns_check();
+	hash = ERRFN(thread_get)(1);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	p = lh_ERR_STATE_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_OF(ERR_STATE) *hash;
+
+	err_fns_check();
+	hash = ERRFN(thread_get)(0);
+	if (!hash)
+		return;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	p = lh_ERR_STATE_delete(hash, d);
+	/* make sure we don't leak memory */
+	if (int_thread_hash_references == 1
+	    && int_thread_hash && lh_ERR_STATE_num_items(int_thread_hash) == 0)
+		{
+		lh_ERR_STATE_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
 
 #define err_clear_data(p,i) \
 	do { \
@@ -143,6 +641,68 @@
 	(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)
 	{
@@ -297,6 +857,196 @@
 	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_OF(ERR_STRING_DATA) *ERR_get_string_table(void)
+	{
+	err_fns_check();
+	return ERRFN(err_get)(0);
+	}
+
+LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void)
+	{
+	err_fns_check();
+	return ERRFN(thread_get)(0);
+	}
+
+void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **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);
+	}
+
+void ERR_remove_thread_state(const CRYPTO_THREADID *id)
+	{
+	ERR_STATE tmp;
+
+	if (id)
+		CRYPTO_THREADID_cpy(&tmp.tid, id);
+	else
+		CRYPTO_THREADID_current(&tmp.tid);
+	err_fns_check();
+	/* thread_del_item automatically destroys the LHASH if the number of
+	 * items reaches zero. */
+	ERRFN(thread_del_item)(&tmp);
+	}
+
+#ifndef OPENSSL_NO_DEPRECATED
+void ERR_remove_state(unsigned long pid)
+	{
+	ERR_remove_thread_state(NULL);
+	}
+#endif
+
+ERR_STATE *ERR_get_state(void)
+	{
+	static ERR_STATE fallback;
+	ERR_STATE *ret,tmp,*tmpp=NULL;
+	int i;
+	CRYPTO_THREADID tid;
+
+	err_fns_check();
+	CRYPTO_THREADID_current(&tid);
+	CRYPTO_THREADID_cpy(&tmp.tid, &tid);
+	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);
+		CRYPTO_THREADID_cpy(&ret->tid, &tid);
+		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;
@@ -383,34 +1133,3 @@
 	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 dcac415..b9f8c16 100644
--- a/crypto/err/err.h
+++ b/crypto/err/err.h
@@ -55,6 +55,59 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
+/* ====================================================================
+ * Copyright (c) 1998-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
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
 
 #ifndef HEADER_ERR_H
 #define HEADER_ERR_H
@@ -94,7 +147,7 @@
 #define ERR_NUM_ERRORS	16
 typedef struct err_state_st
 	{
-	unsigned long pid;
+	CRYPTO_THREADID tid;
 	int err_flags[ERR_NUM_ERRORS];
 	unsigned long err_buffer[ERR_NUM_ERRORS];
 	char *err_data[ERR_NUM_ERRORS];
@@ -142,7 +195,9 @@
 #define ERR_LIB_STORE           44
 #define ERR_LIB_FIPS		45
 #define ERR_LIB_CMS		46
-#define ERR_LIB_JPAKE		47
+#define ERR_LIB_TS		47
+#define ERR_LIB_HMAC		48
+#define ERR_LIB_JPAKE		49
 
 #define ERR_LIB_USER		128
 
@@ -176,6 +231,8 @@
 #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 TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),__FILE__,__LINE__)
+#define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(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
@@ -232,6 +289,7 @@
 #define ERR_R_ECDSA_LIB ERR_LIB_ECDSA	 /* 42 */
 #define ERR_R_ECDH_LIB  ERR_LIB_ECDH	 /* 43 */
 #define ERR_R_STORE_LIB ERR_LIB_STORE    /* 44 */
+#define ERR_R_TS_LIB	ERR_LIB_TS       /* 45 */
 
 #define ERR_R_NESTED_ASN1_ERROR			58
 #define ERR_R_BAD_ASN1_OBJECT_HEADER		59
@@ -294,13 +352,16 @@
 void ERR_load_crypto_strings(void);
 void ERR_free_strings(void);
 
+void ERR_remove_thread_state(const CRYPTO_THREADID *tid);
+#ifndef OPENSSL_NO_DEPRECATED
 void ERR_remove_state(unsigned long pid); /* if zero we look it up */
+#endif
 ERR_STATE *ERR_get_state(void);
 
 #ifndef OPENSSL_NO_LHASH
-LHASH *ERR_get_string_table(void);
-LHASH *ERR_get_err_state_table(void);
-void ERR_release_err_state_table(LHASH **hash);
+LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void);
+LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void);
+void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash);
 #endif
 
 int ERR_get_next_error_library(void);
@@ -308,12 +369,6 @@
 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 39796f7..fc049e8 100644
--- a/crypto/err/err_all.c
+++ b/crypto/err/err_all.c
@@ -64,6 +64,7 @@
 #endif
 #include <openssl/buffer.h>
 #include <openssl/bio.h>
+#include <openssl/comp.h>
 #ifndef OPENSSL_NO_RSA
 #include <openssl/rsa.h>
 #endif
@@ -94,10 +95,7 @@
 #include <openssl/ui.h>
 #include <openssl/ocsp.h>
 #include <openssl/err.h>
-#ifdef OPENSSL_FIPS
-#include <openssl/fips.h>
-#endif
-
+#include <openssl/ts.h>
 #ifndef OPENSSL_NO_CMS
 #include <openssl/cms.h>
 #endif
@@ -128,6 +126,7 @@
 	ERR_load_ASN1_strings();
 	ERR_load_CONF_strings();
 	ERR_load_CRYPTO_strings();
+	ERR_load_COMP_strings();
 #ifndef OPENSSL_NO_EC
 	ERR_load_EC_strings();
 #endif
@@ -144,14 +143,12 @@
 	ERR_load_PKCS12_strings();
 	ERR_load_RAND_strings();
 	ERR_load_DSO_strings();
+	ERR_load_TS_strings();
 #ifndef OPENSSL_NO_ENGINE
 	ERR_load_ENGINE_strings();
 #endif
 	ERR_load_OCSP_strings();
 	ERR_load_UI_strings();
-#ifdef OPENSSL_FIPS
-	ERR_load_FIPS_strings();
-#endif
 #ifndef OPENSSL_NO_CMS
 	ERR_load_CMS_strings();
 #endif
diff --git a/crypto/err/err_bio.c b/crypto/err/err_bio.c
deleted file mode 100644
index a42f804..0000000
--- a/crypto/err/err_bio.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/* crypto/err/err_prn.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#include <stdio.h>
-#include "cryptlib.h"
-#include <openssl/lhash.h>
-#include <openssl/crypto.h>
-#include <openssl/buffer.h>
-#include <openssl/err.h>
-
-static int print_bio(const char *str, size_t len, void *bp)
-	{
-	return BIO_write((BIO *)bp, str, len);
-	}
-void ERR_print_errors(BIO *bp)
-	{
-	ERR_print_errors_cb(print_bio, bp);
-	}
-
-	
diff --git a/crypto/err/err_def.c b/crypto/err/err_def.c
deleted file mode 100644
index 7ed3d84..0000000
--- a/crypto/err/err_def.c
+++ /dev/null
@@ -1,665 +0,0 @@
-/* crypto/err/err_def.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-/* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include "cryptlib.h"
-#include <openssl/lhash.h>
-#include <openssl/crypto.h>
-#include <openssl/buffer.h>
-#include <openssl/bio.h>
-#include <openssl/err.h>
-
-#define err_clear_data(p,i) \
-	do { \
-	if (((p)->err_data[i] != NULL) && \
-		(p)->err_data_flags[i] & ERR_TXT_MALLOCED) \
-		{  \
-		OPENSSL_free((p)->err_data[i]); \
-		(p)->err_data[i]=NULL; \
-		} \
-	(p)->err_data_flags[i]=0; \
-	} while(0)
-
-#define err_clear(p,i) \
-	do { \
-	(p)->err_flags[i]=0; \
-	(p)->err_buffer[i]=0; \
-	err_clear_data(p,i); \
-	(p)->err_file[i]=NULL; \
-	(p)->err_line[i]= -1; \
-	} while(0)
-
-static void err_load_strings(int lib, ERR_STRING_DATA *str);
-
-static void ERR_STATE_free(ERR_STATE *s);
-
-/* Define the predeclared (but externally opaque) "ERR_FNS" type */
-struct st_ERR_FNS
-	{
-	/* Works on the "error_hash" string table */
-	LHASH *(*cb_err_get)(int create);
-	void (*cb_err_del)(void);
-	ERR_STRING_DATA *(*cb_err_get_item)(const ERR_STRING_DATA *);
-	ERR_STRING_DATA *(*cb_err_set_item)(ERR_STRING_DATA *);
-	ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *);
-	/* Works on the "thread_hash" error-state table */
-	LHASH *(*cb_thread_get)(int create);
-	void (*cb_thread_release)(LHASH **hash);
-	ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *);
-	ERR_STATE *(*cb_thread_set_item)(ERR_STATE *);
-	void (*cb_thread_del_item)(const ERR_STATE *);
-	/* Returns the next available error "library" numbers */
-	int (*cb_get_next_lib)(void);
-	};
-
-/* Predeclarations of the "err_defaults" functions */
-static LHASH *int_err_get(int create);
-static void int_err_del(void);
-static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
-static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *);
-static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *);
-static LHASH *int_thread_get(int create);
-static void int_thread_release(LHASH **hash);
-static ERR_STATE *int_thread_get_item(const ERR_STATE *);
-static ERR_STATE *int_thread_set_item(ERR_STATE *);
-static void int_thread_del_item(const ERR_STATE *);
-static int int_err_get_next_lib(void);
-/* The static ERR_FNS table using these defaults functions */
-static const ERR_FNS err_defaults =
-	{
-	int_err_get,
-	int_err_del,
-	int_err_get_item,
-	int_err_set_item,
-	int_err_del_item,
-	int_thread_get,
-	int_thread_release,
-	int_thread_get_item,
-	int_thread_set_item,
-	int_thread_del_item,
-	int_err_get_next_lib
-	};
-
-/* The replacable table of ERR_FNS functions we use at run-time */
-static const ERR_FNS *err_fns = NULL;
-
-/* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */
-#define ERRFN(a) err_fns->cb_##a
-
-/* The internal state used by "err_defaults" - as such, the setting, reading,
- * creating, and deleting of this data should only be permitted via the
- * "err_defaults" functions. This way, a linked module can completely defer all
- * ERR state operation (together with requisite locking) to the implementations
- * and state in the loading application. */
-static LHASH *int_error_hash = NULL;
-static LHASH *int_thread_hash = NULL;
-static int int_thread_hash_references = 0;
-static int int_err_library_number= ERR_LIB_USER;
-
-/* Internal function that checks whether "err_fns" is set and if not, sets it to
- * the defaults. */
-static void err_fns_check(void)
-	{
-	if (err_fns) return;
-	
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	if (!err_fns)
-		err_fns = &err_defaults;
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-	}
-
-/* API functions to get or set the underlying ERR functions. */
-
-const ERR_FNS *ERR_get_implementation(void)
-	{
-	err_fns_check();
-	return err_fns;
-	}
-
-int ERR_set_implementation(const ERR_FNS *fns)
-	{
-	int ret = 0;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	/* It's too late if 'err_fns' is non-NULL. BTW: not much point setting
-	 * an error is there?! */
-	if (!err_fns)
-		{
-		err_fns = fns;
-		ret = 1;
-		}
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-	return ret;
-	}
-
-/* These are the callbacks provided to "lh_new()" when creating the LHASH tables
- * internal to the "err_defaults" implementation. */
-
-/* static unsigned long err_hash(ERR_STRING_DATA *a); */
-static unsigned long err_hash(const void *a_void);
-/* static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b); */
-static int err_cmp(const void *a_void, const void *b_void);
-/* static unsigned long pid_hash(ERR_STATE *pid); */
-static unsigned long pid_hash(const void *pid_void);
-/* static int pid_cmp(ERR_STATE *a,ERR_STATE *pid); */
-static int pid_cmp(const void *a_void,const void *pid_void);
-
-/* The internal functions used in the "err_defaults" implementation */
-
-static LHASH *int_err_get(int create)
-	{
-	LHASH *ret = NULL;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	if (!int_error_hash && create)
-		{
-		CRYPTO_push_info("int_err_get (err.c)");
-		int_error_hash = lh_new(err_hash, err_cmp);
-		CRYPTO_pop_info();
-		}
-	if (int_error_hash)
-		ret = int_error_hash;
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-
-	return ret;
-	}
-
-static void int_err_del(void)
-	{
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	if (int_error_hash)
-		{
-		lh_free(int_error_hash);
-		int_error_hash = NULL;
-		}
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-	}
-
-static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d)
-	{
-	ERR_STRING_DATA *p;
-	LHASH *hash;
-
-	err_fns_check();
-	hash = ERRFN(err_get)(0);
-	if (!hash)
-		return NULL;
-
-	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
-	p = (ERR_STRING_DATA *)lh_retrieve(hash, d);
-	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
-
-	return p;
-	}
-
-static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d)
-	{
-	ERR_STRING_DATA *p;
-	LHASH *hash;
-
-	err_fns_check();
-	hash = ERRFN(err_get)(1);
-	if (!hash)
-		return NULL;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	p = (ERR_STRING_DATA *)lh_insert(hash, d);
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-
-	return p;
-	}
-
-static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d)
-	{
-	ERR_STRING_DATA *p;
-	LHASH *hash;
-
-	err_fns_check();
-	hash = ERRFN(err_get)(0);
-	if (!hash)
-		return NULL;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	p = (ERR_STRING_DATA *)lh_delete(hash, d);
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-
-	return p;
-	}
-
-static LHASH *int_thread_get(int create)
-	{
-	LHASH *ret = NULL;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	if (!int_thread_hash && create)
-		{
-		CRYPTO_push_info("int_thread_get (err.c)");
-		int_thread_hash = lh_new(pid_hash, pid_cmp);
-		CRYPTO_pop_info();
-		}
-	if (int_thread_hash)
-		{
-		int_thread_hash_references++;
-		ret = int_thread_hash;
-		}
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-	return ret;
-	}
-
-static void int_thread_release(LHASH **hash)
-	{
-	int i;
-
-	if (hash == NULL || *hash == NULL)
-		return;
-
-	i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR);
-
-#ifdef REF_PRINT
-	fprintf(stderr,"%4d:%s\n",int_thread_hash_references,"ERR");
-#endif
-	if (i > 0) return;
-#ifdef REF_CHECK
-	if (i < 0)
-		{
-		fprintf(stderr,"int_thread_release, bad reference count\n");
-		abort(); /* ok */
-		}
-#endif
-	*hash = NULL;
-	}
-
-static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
-	{
-	ERR_STATE *p;
-	LHASH *hash;
-
-	err_fns_check();
-	hash = ERRFN(thread_get)(0);
-	if (!hash)
-		return NULL;
-
-	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
-	p = (ERR_STATE *)lh_retrieve(hash, d);
-	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
-
-	ERRFN(thread_release)(&hash);
-	return p;
-	}
-
-static ERR_STATE *int_thread_set_item(ERR_STATE *d)
-	{
-	ERR_STATE *p;
-	LHASH *hash;
-
-	err_fns_check();
-	hash = ERRFN(thread_get)(1);
-	if (!hash)
-		return NULL;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	p = (ERR_STATE *)lh_insert(hash, d);
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-
-	ERRFN(thread_release)(&hash);
-	return p;
-	}
-
-static void int_thread_del_item(const ERR_STATE *d)
-	{
-	ERR_STATE *p;
-	LHASH *hash;
-
-	err_fns_check();
-	hash = ERRFN(thread_get)(0);
-	if (!hash)
-		return;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	p = (ERR_STATE *)lh_delete(hash, d);
-	/* make sure we don't leak memory */
-	if (int_thread_hash_references == 1
-		&& int_thread_hash && (lh_num_items(int_thread_hash) == 0))
-		{
-		lh_free(int_thread_hash);
-		int_thread_hash = NULL;
-		}
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-
-	ERRFN(thread_release)(&hash);
-	if (p)
-		ERR_STATE_free(p);
-	}
-
-static int int_err_get_next_lib(void)
-	{
-	int ret;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	ret = int_err_library_number++;
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-
-	return ret;
-	}
-
-static void ERR_STATE_free(ERR_STATE *s)
-	{
-	int i;
-
-	if (s == NULL)
-	    return;
-
-	for (i=0; i<ERR_NUM_ERRORS; i++)
-		{
-		err_clear_data(s,i);
-		}
-	OPENSSL_free(s);
-	}
-
-static void err_load_strings(int lib, ERR_STRING_DATA *str)
-	{
-	while (str->error)
-		{
-		if (lib)
-			str->error|=ERR_PACK(lib,0,0);
-		ERRFN(err_set_item)(str);
-		str++;
-		}
-	}
-
-void ERR_load_strings(int lib, ERR_STRING_DATA *str)
-	{
-	err_fns_check();
-	err_load_strings(lib, str);
-	}
-
-void ERR_unload_strings(int lib, ERR_STRING_DATA *str)
-	{
-	while (str->error)
-		{
-		if (lib)
-			str->error|=ERR_PACK(lib,0,0);
-		ERRFN(err_del_item)(str);
-		str++;
-		}
-	}
-
-void ERR_free_strings(void)
-	{
-	err_fns_check();
-	ERRFN(err_del)();
-	}
-
-LHASH *ERR_get_string_table(void)
-	{
-	err_fns_check();
-	return ERRFN(err_get)(0);
-	}
-
-LHASH *ERR_get_err_state_table(void)
-	{
-	err_fns_check();
-	return ERRFN(thread_get)(0);
-	}
-
-void ERR_release_err_state_table(LHASH **hash)
-	{
-	err_fns_check();
-	ERRFN(thread_release)(hash);
-	}
-
-const char *ERR_lib_error_string(unsigned long e)
-	{
-	ERR_STRING_DATA d,*p;
-	unsigned long l;
-
-	err_fns_check();
-	l=ERR_GET_LIB(e);
-	d.error=ERR_PACK(l,0,0);
-	p=ERRFN(err_get_item)(&d);
-	return((p == NULL)?NULL:p->string);
-	}
-
-const char *ERR_func_error_string(unsigned long e)
-	{
-	ERR_STRING_DATA d,*p;
-	unsigned long l,f;
-
-	err_fns_check();
-	l=ERR_GET_LIB(e);
-	f=ERR_GET_FUNC(e);
-	d.error=ERR_PACK(l,f,0);
-	p=ERRFN(err_get_item)(&d);
-	return((p == NULL)?NULL:p->string);
-	}
-
-const char *ERR_reason_error_string(unsigned long e)
-	{
-	ERR_STRING_DATA d,*p=NULL;
-	unsigned long l,r;
-
-	err_fns_check();
-	l=ERR_GET_LIB(e);
-	r=ERR_GET_REASON(e);
-	d.error=ERR_PACK(l,0,r);
-	p=ERRFN(err_get_item)(&d);
-	if (!p)
-		{
-		d.error=ERR_PACK(0,0,r);
-		p=ERRFN(err_get_item)(&d);
-		}
-	return((p == NULL)?NULL:p->string);
-	}
-
-/* static unsigned long err_hash(ERR_STRING_DATA *a) */
-static unsigned long err_hash(const void *a_void)
-	{
-	unsigned long ret,l;
-
-	l=((const ERR_STRING_DATA *)a_void)->error;
-	ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
-	return(ret^ret%19*13);
-	}
-
-/* static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b) */
-static int err_cmp(const void *a_void, const void *b_void)
-	{
-	return((int)(((const ERR_STRING_DATA *)a_void)->error -
-			((const ERR_STRING_DATA *)b_void)->error));
-	}
-
-/* static unsigned long pid_hash(ERR_STATE *a) */
-static unsigned long pid_hash(const void *a_void)
-	{
-	return(((const ERR_STATE *)a_void)->pid*13);
-	}
-
-/* static int pid_cmp(ERR_STATE *a, ERR_STATE *b) */
-static int pid_cmp(const void *a_void, const void *b_void)
-	{
-	return((int)((long)((const ERR_STATE *)a_void)->pid -
-			(long)((const ERR_STATE *)b_void)->pid));
-	}
-#ifdef OPENSSL_FIPS
-static void int_err_remove_state(unsigned long pid)
-#else
-void ERR_remove_state(unsigned long pid)
-#endif
-	{
-	ERR_STATE tmp;
-
-	err_fns_check();
-	if (pid == 0)
-		pid=(unsigned long)CRYPTO_thread_id();
-	tmp.pid=pid;
-	/* thread_del_item automatically destroys the LHASH if the number of
-	 * items reaches zero. */
-	ERRFN(thread_del_item)(&tmp);
-	}
-
-#ifdef OPENSSL_FIPS
-	static ERR_STATE *int_err_get_state(void)
-#else
-ERR_STATE *ERR_get_state(void)
-#endif
-	{
-	static ERR_STATE fallback;
-	ERR_STATE *ret,tmp,*tmpp=NULL;
-	int i;
-	unsigned long pid;
-
-	err_fns_check();
-	pid=(unsigned long)CRYPTO_thread_id();
-	tmp.pid=pid;
-	ret=ERRFN(thread_get_item)(&tmp);
-
-	/* ret == the error state, if NULL, make a new one */
-	if (ret == NULL)
-		{
-		ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE));
-		if (ret == NULL) return(&fallback);
-		ret->pid=pid;
-		ret->top=0;
-		ret->bottom=0;
-		for (i=0; i<ERR_NUM_ERRORS; i++)
-			{
-			ret->err_data[i]=NULL;
-			ret->err_data_flags[i]=0;
-			}
-		tmpp = ERRFN(thread_set_item)(ret);
-		/* To check if insertion failed, do a get. */
-		if (ERRFN(thread_get_item)(ret) != ret)
-			{
-			ERR_STATE_free(ret); /* could not insert it */
-			return(&fallback);
-			}
-		/* If a race occured in this function and we came second, tmpp
-		 * is the first one that we just replaced. */
-		if (tmpp)
-			ERR_STATE_free(tmpp);
-		}
-	return ret;
-	}
-
-#ifdef OPENSSL_FIPS
-void int_ERR_lib_init(void)
-	{
-	int_ERR_set_state_func(int_err_get_state, int_err_remove_state);
-	}
-#endif
-
-int ERR_get_next_error_library(void)
-	{
-	err_fns_check();
-	return ERRFN(get_next_lib)();
-	}
diff --git a/crypto/err/err_prn.c b/crypto/err/err_prn.c
index 4cdf342..de32f33 100644
--- a/crypto/err/err_prn.c
+++ b/crypto/err/err_prn.c
@@ -72,8 +72,10 @@
 	const char *file,*data;
 	int line,flags;
 	unsigned long es;
+	CRYPTO_THREADID cur;
 
-	es=CRYPTO_thread_id();
+	CRYPTO_THREADID_current(&cur);
+	es=CRYPTO_THREADID_hash(&cur);
 	while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
 		{
 		ERR_error_string_n(l, buf, sizeof buf);
@@ -86,7 +88,12 @@
 #ifndef OPENSSL_NO_FP_API
 static int print_fp(const char *str, size_t len, void *fp)
 	{
-	return fwrite(str, 1, len, fp);
+	BIO bio;
+
+	BIO_set(&bio,BIO_s_file());
+	BIO_set_fp(&bio,fp,BIO_NOCLOSE);
+
+	return BIO_printf(&bio, "%s", str);
 	}
 void ERR_print_errors_fp(FILE *fp)
 	{
@@ -94,64 +101,13 @@
 	}
 #endif
 
-void ERR_error_string_n(unsigned long e, char *buf, size_t len)
+static int print_bio(const char *str, size_t len, void *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;
-				}
-			}
-		}
+	return BIO_write((BIO *)bp, str, len);
+	}
+void ERR_print_errors(BIO *bp)
+	{
+	ERR_print_errors_cb(print_bio, bp);
 	}
 
-/* 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
deleted file mode 100644
index d390408..0000000
--- a/crypto/err/err_str.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/* crypto/err/err_str.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-/* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include "cryptlib.h"
-#include <openssl/lhash.h>
-#include <openssl/crypto.h>
-#include <openssl/buffer.h>
-#include <openssl/bio.h>
-#include <openssl/err.h>
-
-#ifndef OPENSSL_NO_ERR
-static ERR_STRING_DATA ERR_str_libraries[]=
-	{
-{ERR_PACK(ERR_LIB_NONE,0,0)		,"unknown library"},
-{ERR_PACK(ERR_LIB_SYS,0,0)		,"system library"},
-{ERR_PACK(ERR_LIB_BN,0,0)		,"bignum routines"},
-{ERR_PACK(ERR_LIB_RSA,0,0)		,"rsa routines"},
-{ERR_PACK(ERR_LIB_DH,0,0)		,"Diffie-Hellman routines"},
-{ERR_PACK(ERR_LIB_EVP,0,0)		,"digital envelope routines"},
-{ERR_PACK(ERR_LIB_BUF,0,0)		,"memory buffer routines"},
-{ERR_PACK(ERR_LIB_OBJ,0,0)		,"object identifier routines"},
-{ERR_PACK(ERR_LIB_PEM,0,0)		,"PEM routines"},
-{ERR_PACK(ERR_LIB_DSA,0,0)		,"dsa routines"},
-{ERR_PACK(ERR_LIB_X509,0,0)		,"x509 certificate routines"},
-{ERR_PACK(ERR_LIB_ASN1,0,0)		,"asn1 encoding routines"},
-{ERR_PACK(ERR_LIB_CONF,0,0)		,"configuration file routines"},
-{ERR_PACK(ERR_LIB_CRYPTO,0,0)		,"common libcrypto routines"},
-{ERR_PACK(ERR_LIB_EC,0,0)		,"elliptic curve routines"},
-{ERR_PACK(ERR_LIB_SSL,0,0)		,"SSL routines"},
-{ERR_PACK(ERR_LIB_BIO,0,0)		,"BIO routines"},
-{ERR_PACK(ERR_LIB_PKCS7,0,0)		,"PKCS7 routines"},
-{ERR_PACK(ERR_LIB_X509V3,0,0)		,"X509 V3 routines"},
-{ERR_PACK(ERR_LIB_PKCS12,0,0)		,"PKCS12 routines"},
-{ERR_PACK(ERR_LIB_RAND,0,0)		,"random number generator"},
-{ERR_PACK(ERR_LIB_DSO,0,0)		,"DSO support routines"},
-{ERR_PACK(ERR_LIB_ENGINE,0,0)		,"engine routines"},
-{ERR_PACK(ERR_LIB_OCSP,0,0)		,"OCSP routines"},
-{ERR_PACK(ERR_LIB_FIPS,0,0)		,"FIPS routines"},
-{ERR_PACK(ERR_LIB_CMS,0,0)		,"CMS routines"},
-{ERR_PACK(ERR_LIB_JPAKE,0,0)		,"JPAKE routines"},
-{0,NULL},
-	};
-
-static ERR_STRING_DATA ERR_str_functs[]=
-	{
-	{ERR_PACK(0,SYS_F_FOPEN,0),     	"fopen"},
-	{ERR_PACK(0,SYS_F_CONNECT,0),		"connect"},
-	{ERR_PACK(0,SYS_F_GETSERVBYNAME,0),	"getservbyname"},
-	{ERR_PACK(0,SYS_F_SOCKET,0),		"socket"}, 
-	{ERR_PACK(0,SYS_F_IOCTLSOCKET,0),	"ioctlsocket"},
-	{ERR_PACK(0,SYS_F_BIND,0),		"bind"},
-	{ERR_PACK(0,SYS_F_LISTEN,0),		"listen"},
-	{ERR_PACK(0,SYS_F_ACCEPT,0),		"accept"},
-#ifdef OPENSSL_SYS_WINDOWS
-	{ERR_PACK(0,SYS_F_WSASTARTUP,0),	"WSAstartup"},
-#endif
-	{ERR_PACK(0,SYS_F_OPENDIR,0),		"opendir"},
-	{ERR_PACK(0,SYS_F_FREAD,0),		"fread"},
-	{0,NULL},
-	};
-
-static ERR_STRING_DATA ERR_str_reasons[]=
-	{
-{ERR_R_SYS_LIB				,"system lib"},
-{ERR_R_BN_LIB				,"BN lib"},
-{ERR_R_RSA_LIB				,"RSA lib"},
-{ERR_R_DH_LIB				,"DH lib"},
-{ERR_R_EVP_LIB				,"EVP lib"},
-{ERR_R_BUF_LIB				,"BUF lib"},
-{ERR_R_OBJ_LIB				,"OBJ lib"},
-{ERR_R_PEM_LIB				,"PEM lib"},
-{ERR_R_DSA_LIB				,"DSA lib"},
-{ERR_R_X509_LIB				,"X509 lib"},
-{ERR_R_ASN1_LIB				,"ASN1 lib"},
-{ERR_R_CONF_LIB				,"CONF lib"},
-{ERR_R_CRYPTO_LIB			,"CRYPTO lib"},
-{ERR_R_EC_LIB				,"EC lib"},
-{ERR_R_SSL_LIB				,"SSL lib"},
-{ERR_R_BIO_LIB				,"BIO lib"},
-{ERR_R_PKCS7_LIB			,"PKCS7 lib"},
-{ERR_R_X509V3_LIB			,"X509V3 lib"},
-{ERR_R_PKCS12_LIB			,"PKCS12 lib"},
-{ERR_R_RAND_LIB				,"RAND lib"},
-{ERR_R_DSO_LIB				,"DSO lib"},
-{ERR_R_ENGINE_LIB			,"ENGINE lib"},
-{ERR_R_OCSP_LIB				,"OCSP lib"},
-
-{ERR_R_NESTED_ASN1_ERROR		,"nested asn1 error"},
-{ERR_R_BAD_ASN1_OBJECT_HEADER		,"bad asn1 object header"},
-{ERR_R_BAD_GET_ASN1_OBJECT_CALL		,"bad get asn1 object call"},
-{ERR_R_EXPECTING_AN_ASN1_SEQUENCE	,"expecting an asn1 sequence"},
-{ERR_R_ASN1_LENGTH_MISMATCH		,"asn1 length mismatch"},
-{ERR_R_MISSING_ASN1_EOS			,"missing asn1 eos"},
-
-{ERR_R_FATAL                            ,"fatal"},
-{ERR_R_MALLOC_FAILURE			,"malloc failure"},
-{ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED	,"called a function you should not call"},
-{ERR_R_PASSED_NULL_PARAMETER		,"passed a null parameter"},
-{ERR_R_INTERNAL_ERROR			,"internal error"},
-{ERR_R_DISABLED				,"called a function that was disabled at compile-time"},
-
-{0,NULL},
-	};
-#endif
-
-#ifndef OPENSSL_NO_ERR
-#define NUM_SYS_STR_REASONS 127
-#define LEN_SYS_STR_REASON 32
-
-static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
-/* SYS_str_reasons is filled with copies of strerror() results at
- * initialization.
- * 'errno' values up to 127 should cover all usual errors,
- * others will be displayed numerically by ERR_error_string.
- * It is crucial that we have something for each reason code
- * that occurs in ERR_str_reasons, or bogus reason strings
- * will be returned for SYSerr, which always gets an errno
- * value and never one of those 'standard' reason codes. */
-
-static void build_SYS_str_reasons(void)
-	{
-	/* OPENSSL_malloc cannot be used here, use static storage instead */
-	static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
-	int i;
-	static int init = 1;
-
-	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
-	if (!init)
-		{
-		CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
-		return;
-		}
-	
-	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	if (!init)
-		{
-		CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-		return;
-		}
-
-	for (i = 1; i <= NUM_SYS_STR_REASONS; i++)
-		{
-		ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
-
-		str->error = (unsigned long)i;
-		if (str->string == NULL)
-			{
-			char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]);
-			char *src = strerror(i);
-			if (src != NULL)
-				{
-				strncpy(*dest, src, sizeof *dest);
-				(*dest)[sizeof *dest - 1] = '\0';
-				str->string = *dest;
-				}
-			}
-		if (str->string == NULL)
-			str->string = "unknown";
-		}
-
-	/* Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL},
-	 * as required by ERR_load_strings. */
-
-	init = 0;
-	
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-	}
-#endif
-
-void ERR_load_ERR_strings(void)
-	{
-#ifndef OPENSSL_NO_ERR
-	if (ERR_func_error_string(ERR_str_functs[0].error) == NULL)
-		{
-		ERR_load_strings(0,ERR_str_libraries);
-		ERR_load_strings(0,ERR_str_reasons);
-		ERR_load_strings(ERR_LIB_SYS,ERR_str_functs);
-		build_SYS_str_reasons();
-		ERR_load_strings(ERR_LIB_SYS,SYS_str_reasons);
-		}
-#endif
-	}
-
diff --git a/crypto/err/openssl.ec b/crypto/err/openssl.ec
index 8688266..e0554b4 100644
--- a/crypto/err/openssl.ec
+++ b/crypto/err/openssl.ec
@@ -31,13 +31,15 @@
 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 TS		crypto/ts/ts.h			crypto/ts/ts_err.c
+L HMAC		crypto/hmac/hmac.h		crypto/hmac/hmac_err.c
 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
 L NONE		crypto/ec/ec_lcl.h		NONE
+L NONE		crypto/asn1/asn_lcl.h		NONE
 L NONE		crypto/cms/cms_lcl.h		NONE
 
 
@@ -71,6 +73,11 @@
 R SSL_R_TLSV1_ALERT_INTERNAL_ERROR		1080
 R SSL_R_TLSV1_ALERT_USER_CANCELLED		1090
 R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION		1100
+R SSL_R_TLSV1_UNSUPPORTED_EXTENSION		1110
+R SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE		1111
+R SSL_R_TLSV1_UNRECOGNIZED_NAME			1112
+R SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE	1113
+R SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE	1114
 
 R RSAREF_R_CONTENT_ENCODING			0x0400
 R RSAREF_R_DATA					0x0401
diff --git a/crypto/evp/Makefile b/crypto/evp/Makefile
deleted file mode 100644
index c204f84..0000000
--- a/crypto/evp/Makefile
+++ /dev/null
@@ -1,727 +0,0 @@
-#
-# OpenSSL/crypto/evp/Makefile
-#
-
-DIR=	evp
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=evp_test.c
-TESTDATA=evptests.txt
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-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 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 \
-	bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \
-	c_all.c c_allc.c c_alld.c evp_lib.c bio_ok.c \
-	evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c \
-	e_old.c
-
-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 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 \
-	bio_md.o bio_b64.o bio_enc.o evp_err.o e_null.o \
-	c_all.o c_allc.o c_alld.o evp_lib.o bio_ok.o \
-	evp_pkey.o evp_pbe.o p5_crpt.o p5_crpt2.o \
-	e_old.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= evp.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	cp $(TESTDATA) ../../test
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-depend:
-	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
-	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(LIBSRC)
-
-dclean:
-	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
-	mv -f Makefile.new $(MAKEFILE)
-
-clean:
-	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-bio_b64.o: ../../e_os.h ../../include/openssl/asn1.h
-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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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
-e_rc5.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-e_rc5.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-e_rc5.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-e_rc5.o: ../../include/openssl/symhacks.h ../cryptlib.h e_rc5.c
-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/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/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/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/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/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/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/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/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/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/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/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
-evp_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-evp_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-evp_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_pkey.c
-m_dss.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-m_dss.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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/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/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/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/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/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 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/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/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
-m_ripemd.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-m_ripemd.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-m_ripemd.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_ripemd.c
-m_sha.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-m_sha.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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/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/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/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/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
-p5_crpt2.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-p5_crpt2.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p5_crpt2.c
-p_dec.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-p_dec.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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/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
-p_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
-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/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/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/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/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/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
-p_verify.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-p_verify.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p_verify.c
diff --git a/crypto/evp/bio_enc.c b/crypto/evp/bio_enc.c
index f6ac94c..b6efb5f 100644
--- a/crypto/evp/bio_enc.c
+++ b/crypto/evp/bio_enc.c
@@ -361,8 +361,10 @@
 	case BIO_CTRL_DUP:
 		dbio=(BIO *)ptr;
 		dctx=(BIO_ENC_CTX *)dbio->ptr;
-		memcpy(&(dctx->cipher),&(ctx->cipher),sizeof(ctx->cipher));
-		dbio->init=1;
+		EVP_CIPHER_CTX_init(&dctx->cipher);
+		ret = EVP_CIPHER_CTX_copy(&dctx->cipher,&ctx->cipher);
+		if (ret)
+			dbio->init=1;
 		break;
 	default:
 		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
diff --git a/crypto/evp/bio_md.c b/crypto/evp/bio_md.c
index ed5c113..9841e32 100644
--- a/crypto/evp/bio_md.c
+++ b/crypto/evp/bio_md.c
@@ -130,8 +130,8 @@
 		{
 		if (ret > 0)
 			{
-			EVP_DigestUpdate(ctx,(unsigned char *)out,
-				(unsigned int)ret);
+			if (EVP_DigestUpdate(ctx,(unsigned char *)out,
+				(unsigned int)ret)<=0) return (-1);
 			}
 		}
 	BIO_clear_retry_flags(b);
@@ -157,8 +157,11 @@
 				(unsigned int)ret);
 			}
 		}
-	BIO_clear_retry_flags(b);
-	BIO_copy_next_retry(b);
+	if(b->next_bio != NULL)
+		{
+		BIO_clear_retry_flags(b);
+		BIO_copy_next_retry(b);
+		}
 	return(ret);
 	}
 
@@ -194,6 +197,7 @@
 	case BIO_C_GET_MD_CTX:
 		pctx=ptr;
 		*pctx=ctx;
+		b->init = 1;
 		break;
 	case BIO_C_SET_MD_CTX:
 		if (b->init)
@@ -249,7 +253,9 @@
 	ctx=bp->ptr;
 	if (size < ctx->digest->md_size)
 		return(0);
-	EVP_DigestFinal_ex(ctx,(unsigned char *)buf,&ret);
+	if (EVP_DigestFinal_ex(ctx,(unsigned char *)buf,&ret)<=0) 
+		return -1;
+		
 	return((int)ret);
 	}
 
diff --git a/crypto/evp/c_all.c b/crypto/evp/c_all.c
index a5da52e..766c4ce 100644
--- a/crypto/evp/c_all.c
+++ b/crypto/evp/c_all.c
@@ -83,7 +83,7 @@
 	OpenSSL_add_all_ciphers();
 	OpenSSL_add_all_digests();
 #ifndef OPENSSL_NO_ENGINE
-# if defined(__OpenBSD__) || defined(__FreeBSD__)
+# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
 	ENGINE_setup_bsd_cryptodev();
 # endif
 #endif
diff --git a/crypto/evp/c_allc.c b/crypto/evp/c_allc.c
index e45cee8..c5f9268 100644
--- a/crypto/evp/c_allc.c
+++ b/crypto/evp/c_allc.c
@@ -221,7 +221,4 @@
 	EVP_add_cipher_alias(SN_camellia_256_cbc,"CAMELLIA256");
 	EVP_add_cipher_alias(SN_camellia_256_cbc,"camellia256");
 #endif
-
-	PKCS12_PBE_add();
-	PKCS5_PBE_add();
 	}
diff --git a/crypto/evp/c_alld.c b/crypto/evp/c_alld.c
index e0841d1..311e1fe 100644
--- a/crypto/evp/c_alld.c
+++ b/crypto/evp/c_alld.c
@@ -78,7 +78,7 @@
 	EVP_add_digest(EVP_dss());
 #endif
 #endif
-#ifndef OPENSSL_NO_SHA
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
 	EVP_add_digest(EVP_sha1());
 	EVP_add_digest_alias(SN_sha1,"ssl3-sha1");
 	EVP_add_digest_alias(SN_sha1WithRSAEncryption,SN_sha1WithRSA);
@@ -108,4 +108,7 @@
 	EVP_add_digest(EVP_sha384());
 	EVP_add_digest(EVP_sha512());
 #endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+	EVP_add_digest(EVP_whirlpool());
+#endif
 	}
diff --git a/crypto/evp/dig_eng.c b/crypto/evp/dig_eng.c
deleted file mode 100644
index 64cdf93..0000000
--- a/crypto/evp/dig_eng.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/* crypto/evp/digest.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-/* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#include <stdio.h>
-#include "cryptlib.h"
-#include <openssl/objects.h>
-#include <openssl/evp.h>
-#ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
-#endif
-#include "evp_locl.h"
-
-#ifndef OPENSSL_NO_ENGINE
-
-#ifdef OPENSSL_FIPS
-
-static int do_evp_md_engine_full(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)
-	{
-	if (*ptype)
-		{
-		/* Ensure an ENGINE left lying around from last time is cleared
-		 * (the previous check attempted to avoid this if the same
-		 * ENGINE and EVP_MD could be used). */
-		if(ctx->engine)
-			ENGINE_finish(ctx->engine);
-		if(impl)
-			{
-			if (!ENGINE_init(impl))
-				{
-				EVPerr(EVP_F_DO_EVP_MD_ENGINE_FULL,EVP_R_INITIALIZATION_ERROR);
-				return 0;
-				}
-			}
-		else
-			/* Ask if an ENGINE is reserved for this job */
-			impl = ENGINE_get_digest_engine((*ptype)->type);
-		if(impl)
-			{
-			/* There's an ENGINE for this job ... (apparently) */
-			const EVP_MD *d = ENGINE_get_digest(impl, (*ptype)->type);
-			if(!d)
-				{
-				/* Same comment from evp_enc.c */
-				EVPerr(EVP_F_DO_EVP_MD_ENGINE_FULL,EVP_R_INITIALIZATION_ERROR);
-				return 0;
-				}
-			/* We'll use the ENGINE's private digest definition */
-			*ptype = d;
-			/* Store the ENGINE functional reference so we know
-			 * 'type' came from an ENGINE and we need to release
-			 * it when done. */
-			ctx->engine = impl;
-			}
-		else
-			ctx->engine = NULL;
-		}
-	else
-	if(!ctx->digest)
-		{
-		EVPerr(EVP_F_DO_EVP_MD_ENGINE_FULL,EVP_R_NO_DIGEST_SET);
-		return 0;
-		}
-	return 1;
-	}
-
-void int_EVP_MD_init_engine_callbacks(void)
-	{
-	int_EVP_MD_set_engine_callbacks(
-		ENGINE_init, ENGINE_finish, do_evp_md_engine_full);
-	}
-#endif
-#endif
diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c
index 6a8f39b..982ba2b 100644
--- a/crypto/evp/digest.c
+++ b/crypto/evp/digest.c
@@ -116,7 +116,6 @@
 #ifndef OPENSSL_NO_ENGINE
 #include <openssl/engine.h>
 #endif
-#include "evp_locl.h"
 
 void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
 	{
@@ -139,77 +138,18 @@
 	return EVP_DigestInit_ex(ctx, type, 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_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 =
+int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
 	{
-	0,
-	0,
-	0,
-	0,
-	bad_init,
-	bad_update,
-	bad_final,
-	NULL,
-	NULL,
-	NULL,
-	0,
-	{0,0,0,0},
-	};
-
-#endif
-
+	EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
 #ifndef OPENSSL_NO_ENGINE
-
-#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)
+	/* 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)
 		{
 		/* Ensure an ENGINE left lying around from last time is cleared
 		 * (the previous check attempted to avoid this if the same
@@ -220,25 +160,26 @@
 			{
 			if (!ENGINE_init(impl))
 				{
-				EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_INITIALIZATION_ERROR);
+				EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR);
 				return 0;
 				}
 			}
 		else
 			/* Ask if an ENGINE is reserved for this job */
-			impl = ENGINE_get_digest_engine((*ptype)->type);
+			impl = ENGINE_get_digest_engine(type->type);
 		if(impl)
 			{
 			/* There's an ENGINE for this job ... (apparently) */
-			const EVP_MD *d = ENGINE_get_digest(impl, (*ptype)->type);
+			const EVP_MD *d = ENGINE_get_digest(impl, type->type);
 			if(!d)
 				{
 				/* Same comment from evp_enc.c */
-				EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_INITIALIZATION_ERROR);
+				EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR);
+				ENGINE_finish(impl);
 				return 0;
 				}
 			/* We'll use the ENGINE's private digest definition */
-			*ptype = d;
+			type = d;
 			/* Store the ENGINE functional reference so we know
 			 * 'type' came from an ENGINE and we need to release
 			 * it when done. */
@@ -250,78 +191,46 @@
 	else
 	if(!ctx->digest)
 		{
-		EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_NO_DIGEST_SET);
+		EVPerr(EVP_F_EVP_DIGESTINIT_EX,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;
-		if (type->ctx_size)
+		if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size)
 			{
+			ctx->update = type->update;
 			ctx->md_data=OPENSSL_malloc(type->ctx_size);
-			if (!ctx->md_data)
+			if (ctx->md_data == NULL)
 				{
-				EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE);
+				EVPerr(EVP_F_EVP_DIGESTINIT_EX,
+							ERR_R_MALLOC_FAILURE);
 				return 0;
 				}
 			}
 		}
 #ifndef OPENSSL_NO_ENGINE
-	skip_to_init:
+skip_to_init:
 #endif
+	if (ctx->pctx)
+		{
+		int r;
+		r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
+					EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
+		if (r <= 0 && (r != -2))
+			return 0;
+		}
+	if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
+		return 1;
 	return ctx->digest->init(ctx);
 	}
 
-int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data,
-	     size_t count)
+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);
+	return ctx->update(ctx,data,count);
 	}
 
 /* The caller can assume that this removes any secret data from the context */
@@ -337,9 +246,6 @@
 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);
@@ -348,7 +254,7 @@
 	if (ctx->digest->cleanup)
 		{
 		ctx->digest->cleanup(ctx);
-		M_EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
+		EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
 		}
 	memset(ctx->md_data,0,ctx->digest->ctx_size);
 	return ret;
@@ -370,7 +276,7 @@
 		}
 #ifndef OPENSSL_NO_ENGINE
 	/* Make sure it's safe to copy a digest context using an ENGINE */
-	if (in->engine && !do_engine_init(in->engine))
+	if (in->engine && !ENGINE_init(in->engine))
 		{
 		EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_ENGINE_LIB);
 		return 0;
@@ -380,13 +286,13 @@
 	if (out->digest == in->digest)
 		{
 		tmp_buf = out->md_data;
-	    	M_EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE);
+	    	EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE);
 		}
 	else tmp_buf = NULL;
 	EVP_MD_CTX_cleanup(out);
 	memcpy(out,in,sizeof *out);
 
-	if (out->digest->ctx_size)
+	if (in->md_data && out->digest->ctx_size)
 		{
 		if (tmp_buf)
 			out->md_data = tmp_buf;
@@ -402,6 +308,18 @@
 		memcpy(out->md_data,in->md_data,out->digest->ctx_size);
 		}
 
+	out->update = in->update;
+
+	if (in->pctx)
+		{
+		out->pctx = EVP_PKEY_CTX_dup(in->pctx);
+		if (!out->pctx)
+			{
+			EVP_MD_CTX_cleanup(out);
+			return 0;
+			}
+		}
+
 	if (out->digest->copy)
 		return out->digest->copy(out,in);
 	
@@ -415,7 +333,7 @@
 	int ret;
 
 	EVP_MD_CTX_init(&ctx);
-	M_EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT);
+	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);
@@ -437,19 +355,21 @@
 	 * because sometimes only copies of the context are ever finalised.
 	 */
 	if (ctx->digest && ctx->digest->cleanup
-	    && !M_EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED))
+	    && !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
-	    && !M_EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE))
+	    && !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);
 		}
+	if (ctx->pctx)
+		EVP_PKEY_CTX_free(ctx->pctx);
 #ifndef OPENSSL_NO_ENGINE
 	if(ctx->engine)
 		/* The EVP_MD we used belongs to an ENGINE, release the
 		 * functional reference we held for this reason. */
-		do_engine_finish(ctx->engine);
+		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 c9a5ee8..bd6c0a3 100644
--- a/crypto/evp/e_aes.c
+++ b/crypto/evp/e_aes.c
@@ -69,29 +69,32 @@
 
 IMPLEMENT_BLOCK_CIPHER(aes_128, ks, AES, EVP_AES_KEY,
 		       NID_aes_128, 16, 16, 16, 128,
-		       EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
-		       aes_init_key,
-		       NULL, NULL, NULL, NULL)
+		       0, aes_init_key, NULL, 
+		       EVP_CIPHER_set_asn1_iv,
+		       EVP_CIPHER_get_asn1_iv,
+		       NULL)
 IMPLEMENT_BLOCK_CIPHER(aes_192, ks, AES, EVP_AES_KEY,
 		       NID_aes_192, 16, 24, 16, 128,
-		       EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
-		       aes_init_key,
-		       NULL, NULL, NULL, NULL)
+		       0, aes_init_key, NULL, 
+		       EVP_CIPHER_set_asn1_iv,
+		       EVP_CIPHER_get_asn1_iv,
+		       NULL)
 IMPLEMENT_BLOCK_CIPHER(aes_256, ks, AES, EVP_AES_KEY,
 		       NID_aes_256, 16, 32, 16, 128,
-		       EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
-		       aes_init_key,
-		       NULL, NULL, NULL, NULL)
+		       0, aes_init_key, NULL, 
+		       EVP_CIPHER_set_asn1_iv,
+		       EVP_CIPHER_get_asn1_iv,
+		       NULL)
 
-#define IMPLEMENT_AES_CFBR(ksize,cbits,flags)	IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16,flags)
+#define IMPLEMENT_AES_CFBR(ksize,cbits)	IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16)
 
-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,1)
+IMPLEMENT_AES_CFBR(192,1)
+IMPLEMENT_AES_CFBR(256,1)
 
-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)
+IMPLEMENT_AES_CFBR(128,8)
+IMPLEMENT_AES_CFBR(192,8)
+IMPLEMENT_AES_CFBR(256,8)
 
 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 365d397..a7b40d1 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,0)
+#define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits)	IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16)
 
 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 04376df..ca009f2 100644
--- a/crypto/evp/e_des.c
+++ b/crypto/evp/e_des.c
@@ -72,7 +72,7 @@
 /* Because of various casts and different names can't use IMPLEMENT_BLOCK_CIPHER */
 
 static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-			  const unsigned char *in, unsigned int inl)
+			  const unsigned char *in, size_t inl)
 {
 	BLOCK_CIPHER_ecb_loop()
 		DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), ctx->cipher_data, ctx->encrypt);
@@ -80,24 +80,52 @@
 }
 
 static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-			  const unsigned char *in, unsigned int inl)
+			  const unsigned char *in, size_t inl)
 {
-	DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data, (DES_cblock *)ctx->iv, &ctx->num);
+	while(inl>=EVP_MAXCHUNK)
+		{
+		DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
+				(DES_cblock *)ctx->iv, &ctx->num);
+		inl-=EVP_MAXCHUNK;
+		in +=EVP_MAXCHUNK;
+		out+=EVP_MAXCHUNK;
+		}
+	if (inl)
+		DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data,
+				(DES_cblock *)ctx->iv, &ctx->num);
 	return 1;
 }
 
 static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-			  const unsigned char *in, unsigned int inl)
+			  const unsigned char *in, size_t inl)
 {
-	DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data,
-			 (DES_cblock *)ctx->iv, ctx->encrypt);
+	while(inl>=EVP_MAXCHUNK)
+		{
+		DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
+				(DES_cblock *)ctx->iv, ctx->encrypt);
+		inl-=EVP_MAXCHUNK;
+		in +=EVP_MAXCHUNK;
+		out+=EVP_MAXCHUNK;
+		}
+	if (inl)
+		DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data,
+				(DES_cblock *)ctx->iv, ctx->encrypt);
 	return 1;
 }
 
 static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-			    const unsigned char *in, unsigned int inl)
+			    const unsigned char *in, size_t inl)
 {
-	DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data,
+	while(inl>=EVP_MAXCHUNK)
+		{
+		DES_cfb64_encrypt(in,out, (long)EVP_MAXCHUNK, ctx->cipher_data,
+				(DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
+		inl-=EVP_MAXCHUNK;
+		in +=EVP_MAXCHUNK;
+		out+=EVP_MAXCHUNK;
+		}
+	if (inl)
+		DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data,
 			  (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
 	return 1;
 }
@@ -105,45 +133,62 @@
 /* Although we have a CFB-r implementation for DES, it doesn't pack the right
    way, so wrap it here */
 static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-			   const unsigned char *in, unsigned int inl)
+			   const unsigned char *in, size_t inl)
     {
-    unsigned int n;
+    size_t n,chunk=EVP_MAXCHUNK/8;
     unsigned char c[1],d[1];
 
-    for(n=0 ; n < inl ; ++n)
+    if (inl<chunk) chunk=inl;
+
+    while (inl && inl>=chunk)
 	{
-	c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
-	DES_cfb_encrypt(c,d,1,1,ctx->cipher_data,(DES_cblock *)ctx->iv,
+	for(n=0 ; n < chunk*8; ++n)
+	    {
+	    c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
+	    DES_cfb_encrypt(c,d,1,1,ctx->cipher_data,(DES_cblock *)ctx->iv,
 			ctx->encrypt);
-	out[n/8]=(out[n/8]&~(0x80 >> (n%8)))|((d[0]&0x80) >> (n%8));
+	    out[n/8]=(out[n/8]&~(0x80 >> (unsigned int)(n%8))) |
+		     ((d[0]&0x80) >> (unsigned int)(n%8));
+	    }
+	inl-=chunk;
+	in +=chunk;
+	out+=chunk;
+	if (inl<chunk) chunk=inl;
 	}
+
     return 1;
     }
 
 static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-			   const unsigned char *in, unsigned int inl)
+			   const unsigned char *in, size_t inl)
     {
-    DES_cfb_encrypt(in,out,8,inl,ctx->cipher_data,(DES_cblock *)ctx->iv,
-		    ctx->encrypt);
+    while (inl>=EVP_MAXCHUNK)
+	{
+	DES_cfb_encrypt(in,out,8,(long)EVP_MAXCHUNK,ctx->cipher_data,
+			(DES_cblock *)ctx->iv,ctx->encrypt);
+	inl-=EVP_MAXCHUNK;
+	in +=EVP_MAXCHUNK;
+	out+=EVP_MAXCHUNK;
+	}
+    if (inl)
+	DES_cfb_encrypt(in,out,8,(long)inl,ctx->cipher_data,
+			(DES_cblock *)ctx->iv,ctx->encrypt);
     return 1;
     }
 
 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 f910af1..3232cfe 100644
--- a/crypto/evp/e_des3.c
+++ b/crypto/evp/e_des3.c
@@ -85,7 +85,7 @@
 /* Because of various casts and different args can't use IMPLEMENT_BLOCK_CIPHER */
 
 static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-			      const unsigned char *in, unsigned int inl)
+			      const unsigned char *in, size_t inl)
 {
 	BLOCK_CIPHER_ecb_loop()
 		DES_ecb3_encrypt((const_DES_cblock *)(in + i),
@@ -97,48 +97,80 @@
 }
 
 static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-			      const unsigned char *in, unsigned int inl)
+			      const unsigned char *in, size_t inl)
 {
-	DES_ede3_ofb64_encrypt(in, out, (long)inl,
+	if (inl>=EVP_MAXCHUNK)
+		{
+		DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK,
 			       &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
 			       (DES_cblock *)ctx->iv, &ctx->num);
+		inl-=EVP_MAXCHUNK;
+		in +=EVP_MAXCHUNK;
+		out+=EVP_MAXCHUNK;
+		}
+	if (inl)
+		DES_ede3_ofb64_encrypt(in, out, (long)inl,
+				&data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+                               (DES_cblock *)ctx->iv, &ctx->num);
+
 	return 1;
 }
 
 static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-			      const unsigned char *in, unsigned int inl)
+			      const unsigned char *in, size_t inl)
 {
 #ifdef KSSL_DEBUG
 	{
         int i;
-	printf("des_ede_cbc_cipher(ctx=%lx, buflen=%d)\n", (unsigned long)ctx, ctx->buf_len);
+        char *cp;
+	printf("des_ede_cbc_cipher(ctx=%lx, buflen=%d)\n", ctx, ctx->buf_len);
 	printf("\t iv= ");
         for(i=0;i<8;i++)
                 printf("%02X",ctx->iv[i]);
 	printf("\n");
 	}
 #endif    /* KSSL_DEBUG */
-	DES_ede3_cbc_encrypt(in, out, (long)inl,
+	if (inl>=EVP_MAXCHUNK)
+		{
+		DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK,
 			     &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
 			     (DES_cblock *)ctx->iv, ctx->encrypt);
+		inl-=EVP_MAXCHUNK;
+		in +=EVP_MAXCHUNK;
+		out+=EVP_MAXCHUNK;
+		}
+	if (inl)
+		DES_ede3_cbc_encrypt(in, out, (long)inl,
+			     &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+                             (DES_cblock *)ctx->iv, ctx->encrypt);
 	return 1;
 }
 
 static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-			      const unsigned char *in, unsigned int inl)
+			      const unsigned char *in, size_t inl)
 {
-	DES_ede3_cfb64_encrypt(in, out, (long)inl, 
+	if (inl>=EVP_MAXCHUNK)
+		{
+		DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, 
 			       &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
 			       (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
+		inl-=EVP_MAXCHUNK;
+		in +=EVP_MAXCHUNK;
+		out+=EVP_MAXCHUNK;
+		}
+	if (inl)
+		DES_ede3_cfb64_encrypt(in, out, (long)inl,
+			       &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+                               (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
 	return 1;
 }
 
 /* Although we have a CFB-r implementation for 3-DES, it doesn't pack the right
    way, so wrap it here */
 static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-				const unsigned char *in, unsigned int inl)
+				const unsigned char *in, size_t inl)
     {
-    unsigned int n;
+    size_t n;
     unsigned char c[1],d[1];
 
     for(n=0 ; n < inl ; ++n)
@@ -147,25 +179,36 @@
 	DES_ede3_cfb_encrypt(c,d,1,1,
 			     &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3,
 			     (DES_cblock *)ctx->iv,ctx->encrypt);
-	out[n/8]=(out[n/8]&~(0x80 >> (n%8)))|((d[0]&0x80) >> (n%8));
+	out[n/8]=(out[n/8]&~(0x80 >> (unsigned int)(n%8))) |
+		 ((d[0]&0x80) >> (unsigned int)(n%8));
 	}
 
     return 1;
     }
 
 static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-				const unsigned char *in, unsigned int inl)
+				const unsigned char *in, size_t inl)
     {
-    DES_ede3_cfb_encrypt(in,out,8,inl,
+    while (inl>=EVP_MAXCHUNK)
+	{
+	DES_ede3_cfb_encrypt(in,out,8,(long)EVP_MAXCHUNK,
 			 &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3,
 			 (DES_cblock *)ctx->iv,ctx->encrypt);
+	inl-=EVP_MAXCHUNK;
+	in +=EVP_MAXCHUNK;
+	out+=EVP_MAXCHUNK;
+	}
+    if (inl)
+	DES_ede3_cfb_encrypt(in,out,8,(long)inl,
+			&data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3,
+			(DES_cblock *)ctx->iv,ctx->encrypt);
     return 1;
     }
 
 BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64,
-		EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
-			des_ede_init_key,
-			NULL, NULL, NULL,
+			EVP_CIPH_RAND_KEY, des_ede_init_key, NULL, 
+			EVP_CIPHER_set_asn1_iv,
+			EVP_CIPHER_get_asn1_iv,
 			des3_ctrl)
 
 #define des_ede3_cfb64_cipher des_ede_cfb64_cipher
@@ -174,21 +217,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|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
-			des_ede3_init_key,
-			NULL, NULL, NULL,
+			EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, 
+			EVP_CIPHER_set_asn1_iv,
+			EVP_CIPHER_get_asn1_iv,
 			des3_ctrl)
 
 BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,1,
-		EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
-		     des_ede3_init_key,
-		     NULL, NULL, NULL,
+		     EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL,
+		     EVP_CIPHER_set_asn1_iv,
+		     EVP_CIPHER_get_asn1_iv,
 		     des3_ctrl)
 
 BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,8,
-		EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
-		     des_ede3_init_key,
-		     NULL, NULL, NULL,
+		     EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL,
+		     EVP_CIPHER_set_asn1_iv,
+		     EVP_CIPHER_get_asn1_iv,
 		     des3_ctrl)
 
 static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
@@ -215,7 +258,7 @@
 #ifdef KSSL_DEBUG
 	{
         int i;
-        printf("des_ede3_init_key(ctx=%lx)\n", (unsigned long)ctx);
+        printf("des_ede3_init_key(ctx=%lx)\n", ctx);
 	printf("\tKEY= ");
         for(i=0;i<24;i++) printf("%02X",key[i]); printf("\n");
 	printf("\t IV= ");
diff --git a/crypto/evp/e_idea.c b/crypto/evp/e_idea.c
index 48c33a7..806b080 100644
--- a/crypto/evp/e_idea.c
+++ b/crypto/evp/e_idea.c
@@ -73,7 +73,7 @@
  */
 
 static int idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-			   const unsigned char *in, unsigned int inl)
+			   const unsigned char *in, size_t inl)
 {
 	BLOCK_CIPHER_ecb_loop()
 		idea_ecb_encrypt(in + i, out + i, ctx->cipher_data);
diff --git a/crypto/evp/e_null.c b/crypto/evp/e_null.c
index 0872d73..7cf50e1 100644
--- a/crypto/evp/e_null.c
+++ b/crypto/evp/e_null.c
@@ -64,12 +64,12 @@
 static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
 	const unsigned char *iv,int enc);
 static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-	const unsigned char *in, unsigned int inl);
+	const unsigned char *in, size_t inl);
 static const EVP_CIPHER n_cipher=
 	{
 	NID_undef,
 	1,0,0,
-	EVP_CIPH_FLAG_FIPS,
+	0,
 	null_init_key,
 	null_cipher,
 	NULL,
@@ -93,10 +93,10 @@
 	}
 
 static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-	     const unsigned char *in, unsigned int inl)
+	     const unsigned char *in, size_t inl)
 	{
 	if (in != out)
-		memcpy((char *)out,(const char *)in,(size_t)inl);
+		memcpy((char *)out,(const char *)in,inl);
 	return 1;
 	}
 
diff --git a/crypto/evp/e_rc2.c b/crypto/evp/e_rc2.c
index d37726f..f78d781 100644
--- a/crypto/evp/e_rc2.c
+++ b/crypto/evp/e_rc2.c
@@ -223,6 +223,11 @@
 			return 1;
 			}
 		return 0;
+#ifdef PBE_PRF_TEST
+	case EVP_CTRL_PBE_PRF_NID:
+		*(int *)ptr = NID_hmacWithMD5;
+		return 1;
+#endif
 
 	default:
 		return -1;
diff --git a/crypto/evp/e_rc4.c b/crypto/evp/e_rc4.c
index 55baad7..8b5175e 100644
--- a/crypto/evp/e_rc4.c
+++ b/crypto/evp/e_rc4.c
@@ -64,7 +64,6 @@
 #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
@@ -79,7 +78,7 @@
 static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
 			const unsigned char *iv,int enc);
 static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-		      const unsigned char *in, unsigned int inl);
+		      const unsigned char *in, size_t inl);
 static const EVP_CIPHER r4_cipher=
 	{
 	NID_rc4,
@@ -129,7 +128,7 @@
 	}
 
 static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-		      const unsigned char *in, unsigned int inl)
+		      const unsigned char *in, size_t inl)
 	{
 	RC4(&data(ctx)->ks,inl,in,out);
 	return 1;
diff --git a/crypto/evp/e_seed.c b/crypto/evp/e_seed.c
index 8c1ec0d..2d1759d 100644
--- a/crypto/evp/e_seed.c
+++ b/crypto/evp/e_seed.c
@@ -54,11 +54,11 @@
  */
 
 #include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_SEED
 #include <openssl/evp.h>
 #include <openssl/err.h>
 #include <string.h>
 #include <assert.h>
-#ifndef OPENSSL_NO_SEED
 #include <openssl/seed.h>
 #include "evp_locl.h"
 
diff --git a/crypto/evp/e_xcbc_d.c b/crypto/evp/e_xcbc_d.c
index 8832da2..250e88c 100644
--- a/crypto/evp/e_xcbc_d.c
+++ b/crypto/evp/e_xcbc_d.c
@@ -63,12 +63,13 @@
 
 #include <openssl/evp.h>
 #include <openssl/objects.h>
+#include "evp_locl.h"
 #include <openssl/des.h>
 
 static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
 			     const unsigned char *iv,int enc);
 static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-			   const unsigned char *in, unsigned int inl);
+			   const unsigned char *in, size_t inl);
 
 
 typedef struct
@@ -113,13 +114,25 @@
 	}
 
 static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-			   const unsigned char *in, unsigned int inl)
+			   const unsigned char *in, size_t inl)
 	{
-	DES_xcbc_encrypt(in,out,inl,&data(ctx)->ks,
+	while (inl>=EVP_MAXCHUNK)
+		{
+		DES_xcbc_encrypt(in,out,(long)EVP_MAXCHUNK,&data(ctx)->ks,
 			 (DES_cblock *)&(ctx->iv[0]),
 			 &data(ctx)->inw,
 			 &data(ctx)->outw,
 			 ctx->encrypt);
+		inl-=EVP_MAXCHUNK;
+		in +=EVP_MAXCHUNK;
+		out+=EVP_MAXCHUNK;
+		}
+	if (inl)
+		DES_xcbc_encrypt(in,out,(long)inl,&data(ctx)->ks,
+			(DES_cblock *)&(ctx->iv[0]),
+			&data(ctx)->inw,
+			&data(ctx)->outw,
+			ctx->encrypt);
 	return 1;
 	}
 #endif
diff --git a/crypto/evp/enc_min.c b/crypto/evp/enc_min.c
deleted file mode 100644
index 7fba38e..0000000
--- a/crypto/evp/enc_min.c
+++ /dev/null
@@ -1,390 +0,0 @@
-/* crypto/evp/enc_min.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#include <stdio.h>
-#include "cryptlib.h"
-#include <openssl/evp.h>
-#include <openssl/err.h>
-#include <openssl/rand.h>
-#ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
-#endif
-#include "evp_locl.h"
-
-void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
-	{
-#ifdef OPENSSL_FIPS
-	FIPS_selftest_check();
-#endif
-	memset(ctx,0,sizeof(EVP_CIPHER_CTX));
-	/* ctx->cipher=NULL; */
-	}
-
-#ifdef OPENSSL_FIPS
-
-/* The purpose of these is to trap programs that attempt to use non FIPS
- * algorithms in FIPS mode and ignore the errors.
- */
-
-static int bad_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-		    const unsigned char *iv, int enc)
-	{ FIPS_ERROR_IGNORED("Cipher init"); return 0;}
-
-static int bad_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-			 const unsigned char *in, unsigned int inl)
-	{ FIPS_ERROR_IGNORED("Cipher update"); return 0;}
-
-/* NB: no cleanup because it is allowed after failed init */
-
-static int bad_set_asn1(EVP_CIPHER_CTX *ctx, ASN1_TYPE *typ)
-	{ FIPS_ERROR_IGNORED("Cipher set_asn1"); return 0;}
-static int bad_get_asn1(EVP_CIPHER_CTX *ctx, ASN1_TYPE *typ)
-	{ FIPS_ERROR_IGNORED("Cipher get_asn1"); return 0;}
-static int bad_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
-	{ FIPS_ERROR_IGNORED("Cipher ctrl"); return 0;}
-
-static const EVP_CIPHER bad_cipher =
-	{
-	0,
-	0,
-	0,
-	0,
-	0,
-	bad_init,
-	bad_do_cipher,
-	NULL,
-	0,
-	bad_set_asn1,
-	bad_get_asn1,
-	bad_ctrl,
-	NULL
-	};
-
-#endif
-
-#ifndef OPENSSL_NO_ENGINE
-
-#ifdef OPENSSL_FIPS
-
-static int do_engine_null(ENGINE *impl) { return 0;}
-static int do_evp_enc_engine_null(EVP_CIPHER_CTX *ctx,
-				const EVP_CIPHER **pciph, ENGINE *impl)
-	{ return 1; }
-
-static int (*do_engine_finish)(ENGINE *impl)
-		= do_engine_null;
-
-static int (*do_evp_enc_engine)
-	(EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pciph, ENGINE *impl)
-		= do_evp_enc_engine_null;
-
-void int_EVP_CIPHER_set_engine_callbacks(
-	int (*eng_ciph_fin)(ENGINE *impl),
-	int (*eng_ciph_evp)
-		(EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pciph, ENGINE *impl))
-	{
-	do_engine_finish = eng_ciph_fin;
-	do_evp_enc_engine = eng_ciph_evp;
-	}
-
-#else
-
-#define do_engine_finish ENGINE_finish
-
-static int do_evp_enc_engine(EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pcipher, ENGINE *impl)
-	{
-	if(impl)
-		{
-		if (!ENGINE_init(impl))
-			{
-			EVPerr(EVP_F_DO_EVP_ENC_ENGINE, EVP_R_INITIALIZATION_ERROR);
-			return 0;
-			}
-		}
-	else
-		/* Ask if an ENGINE is reserved for this job */
-		impl = ENGINE_get_cipher_engine((*pcipher)->nid);
-	if(impl)
-		{
-		/* There's an ENGINE for this job ... (apparently) */
-		const EVP_CIPHER *c = ENGINE_get_cipher(impl, (*pcipher)->nid);
-		if(!c)
-			{
-			/* One positive side-effect of US's export
-			 * control history, is that we should at least
-			 * be able to avoid using US mispellings of
-			 * "initialisation"? */
-			EVPerr(EVP_F_DO_EVP_ENC_ENGINE, EVP_R_INITIALIZATION_ERROR);
-			return 0;
-			}
-		/* We'll use the ENGINE's private cipher definition */
-		*pcipher = c;
-		/* Store the ENGINE functional reference so we know
-		 * 'cipher' came from an ENGINE and we need to release
-		 * it when done. */
-		ctx->engine = impl;
-		}
-	else
-		ctx->engine = NULL;
-	return 1;
-	}
-
-#endif
-
-#endif
-
-int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
-	     const unsigned char *key, const unsigned char *iv, int enc)
-	{
-	if (enc == -1)
-		enc = ctx->encrypt;
-	else
-		{
-		if (enc)
-			enc = 1;
-		ctx->encrypt = enc;
-		}
-#ifdef OPENSSL_FIPS
-	if(FIPS_selftest_failed())
-		{
-		FIPSerr(FIPS_F_EVP_CIPHERINIT_EX,FIPS_R_FIPS_SELFTEST_FAILED);
-		ctx->cipher = &bad_cipher;
-		return 0;
-		}
-#endif
-#ifndef OPENSSL_NO_ENGINE
-	/* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
-	 * so this context may already have an ENGINE! Try to avoid releasing
-	 * the previous handle, re-querying for an ENGINE, and having a
-	 * reinitialisation, when it may all be unecessary. */
-	if (ctx->engine && ctx->cipher && (!cipher ||
-			(cipher && (cipher->nid == ctx->cipher->nid))))
-		goto skip_to_init;
-#endif
-	if (cipher)
-		{
-		/* Ensure a context left lying around from last time is cleared
-		 * (the previous check attempted to avoid this if the same
-		 * ENGINE and EVP_CIPHER could be used). */
-		EVP_CIPHER_CTX_cleanup(ctx);
-
-		/* Restore encrypt field: it is zeroed by cleanup */
-		ctx->encrypt = enc;
-#ifndef OPENSSL_NO_ENGINE
-		if (!do_evp_enc_engine(ctx, &cipher, impl))
-			return 0;
-#endif
-
-		ctx->cipher=cipher;
-		if (ctx->cipher->ctx_size)
-			{
-			ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
-			if (!ctx->cipher_data)
-				{
-				EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
-				return 0;
-				}
-			}
-		else
-			{
-			ctx->cipher_data = NULL;
-			}
-		ctx->key_len = cipher->key_len;
-		ctx->flags = 0;
-		if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
-			{
-			if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
-				{
-				EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
-				return 0;
-				}
-			}
-		}
-	else if(!ctx->cipher)
-		{
-		EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
-		return 0;
-		}
-#ifndef OPENSSL_NO_ENGINE
-skip_to_init:
-#endif
-	/* we assume block size is a power of 2 in *cryptUpdate */
-	OPENSSL_assert(ctx->cipher->block_size == 1
-	    || ctx->cipher->block_size == 8
-	    || ctx->cipher->block_size == 16);
-
-	if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
-		switch(EVP_CIPHER_CTX_mode(ctx)) {
-
-			case EVP_CIPH_STREAM_CIPHER:
-			case EVP_CIPH_ECB_MODE:
-			break;
-
-			case EVP_CIPH_CFB_MODE:
-			case EVP_CIPH_OFB_MODE:
-
-			ctx->num = 0;
-
-			case EVP_CIPH_CBC_MODE:
-
-			OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <=
-					(int)sizeof(ctx->iv));
-			if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
-			memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
-			break;
-
-			default:
-			return 0;
-			break;
-		}
-	}
-
-#ifdef OPENSSL_FIPS
-	/* After 'key' is set no further parameters changes are permissible.
-	 * So only check for non FIPS enabling at this point.
-	 */
-	if (key && FIPS_mode())
-		{
-		if (!(ctx->cipher->flags & EVP_CIPH_FLAG_FIPS)
-			& !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW))
-			{
-			EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_DISABLED_FOR_FIPS);
-#if 0
-			ERR_add_error_data(2, "cipher=",
-						EVP_CIPHER_name(ctx->cipher));
-#endif
-			ctx->cipher = &bad_cipher;
-			return 0;
-			}
-		}
-#endif
-
-	if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
-		if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
-	}
-	ctx->buf_len=0;
-	ctx->final_used=0;
-	ctx->block_mask=ctx->cipher->block_size-1;
-	return 1;
-	}
-
-int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
-	{
-	if (c->cipher != NULL)
-		{
-		if(c->cipher->cleanup && !c->cipher->cleanup(c))
-			return 0;
-		/* Cleanse cipher context data */
-		if (c->cipher_data)
-			OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
-		}
-	if (c->cipher_data)
-		OPENSSL_free(c->cipher_data);
-#ifndef OPENSSL_NO_ENGINE
-	if (c->engine)
-		/* The EVP_CIPHER we used belongs to an ENGINE, release the
-		 * functional reference we held for this reason. */
-		do_engine_finish(c->engine);
-#endif
-	memset(c,0,sizeof(EVP_CIPHER_CTX));
-	return 1;
-	}
-
-int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl)
-	{
-#ifdef OPENSSL_FIPS
-	FIPS_selftest_check();
-#endif
-	return ctx->cipher->do_cipher(ctx,out,in,inl);
-	}
-
-int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
-{
-	int ret;
-	if(!ctx->cipher) {
-		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
-		return 0;
-	}
-
-	if(!ctx->cipher->ctrl) {
-		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
-		return 0;
-	}
-
-	ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
-	if(ret == -1) {
-		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
-		return 0;
-	}
-	return ret;
-}
-
-unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
-	{
-	return ctx->cipher->flags;
-	}
-
-int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
-	{
-	return ctx->cipher->iv_len;
-	}
-
-int EVP_CIPHER_nid(const EVP_CIPHER *cipher)
-	{
-	return cipher->nid;
-	}
diff --git a/crypto/evp/encode.c b/crypto/evp/encode.c
index 5921f0d..b42c747 100644
--- a/crypto/evp/encode.c
+++ b/crypto/evp/encode.c
@@ -85,7 +85,7 @@
 #define CHUNKS_PER_LINE (64/4)
 #define CHAR_PER_LINE   (64+1)
 
-static unsigned char data_bin2ascii[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+static const unsigned char data_bin2ascii[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZ\
 abcdefghijklmnopqrstuvwxyz0123456789+/";
 
 /* 0xF0 is a EOLN
@@ -102,7 +102,7 @@
 #define B64_ERROR       	0xFF
 #define B64_NOT_BASE64(a)	(((a)|0x13) == 0xF3)
 
-static unsigned char data_ascii2bin[128]={
+static const unsigned char data_ascii2bin[128]={
 	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
 	0xFF,0xE0,0xF0,0xFF,0xFF,0xF1,0xFF,0xFF,
 	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h
index 79c0971..9f9795e 100644
--- a/crypto/evp/evp.h
+++ b/crypto/evp/evp.h
@@ -75,10 +75,6 @@
 #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
@@ -119,6 +115,7 @@
 #define EVP_PKEY_DSA4	NID_dsaWithSHA1_2
 #define EVP_PKEY_DH	NID_dhKeyAgreement
 #define EVP_PKEY_EC	NID_X9_62_id_ecPublicKey
+#define EVP_PKEY_HMAC	NID_hmac
 
 #ifdef	__cplusplus
 extern "C" {
@@ -132,6 +129,8 @@
 	int type;
 	int save_type;
 	int references;
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	ENGINE *engine;
 	union	{
 		char *ptr;
 #ifndef OPENSSL_NO_RSA
@@ -156,73 +155,6 @@
 #define EVP_PKEY_MO_ENCRYPT	0x0004
 #define EVP_PKEY_MO_DECRYPT	0x0008
 
-#if 0
-/* This structure is required to tie the message digest and signing together.
- * The lookup can be done by md/pkey_method, oid, oid/pkey_method, or
- * oid, md and pkey.
- * This is required because for various smart-card perform the digest and
- * signing/verification on-board.  To handle this case, the specific
- * EVP_MD and EVP_PKEY_METHODs need to be closely associated.
- * When a PKEY is created, it will have a EVP_PKEY_METHOD associated with it.
- * This can either be software or a token to provide the required low level
- * routines.
- */
-typedef struct evp_pkey_md_st
-	{
-	int oid;
-	EVP_MD *md;
-	EVP_PKEY_METHOD *pkey;
-	} EVP_PKEY_MD;
-
-#define EVP_rsa_md2() \
-		EVP_PKEY_MD_add(NID_md2WithRSAEncryption,\
-			EVP_rsa_pkcs1(),EVP_md2())
-#define EVP_rsa_md5() \
-		EVP_PKEY_MD_add(NID_md5WithRSAEncryption,\
-			EVP_rsa_pkcs1(),EVP_md5())
-#define EVP_rsa_sha0() \
-		EVP_PKEY_MD_add(NID_shaWithRSAEncryption,\
-			EVP_rsa_pkcs1(),EVP_sha())
-#define EVP_rsa_sha1() \
-		EVP_PKEY_MD_add(NID_sha1WithRSAEncryption,\
-			EVP_rsa_pkcs1(),EVP_sha1())
-#define EVP_rsa_ripemd160() \
-		EVP_PKEY_MD_add(NID_ripemd160WithRSA,\
-			EVP_rsa_pkcs1(),EVP_ripemd160())
-#define EVP_rsa_mdc2() \
-		EVP_PKEY_MD_add(NID_mdc2WithRSA,\
-			EVP_rsa_octet_string(),EVP_mdc2())
-#define EVP_dsa_sha() \
-		EVP_PKEY_MD_add(NID_dsaWithSHA,\
-			EVP_dsa(),EVP_sha())
-#define EVP_dsa_sha1() \
-		EVP_PKEY_MD_add(NID_dsaWithSHA1,\
-			EVP_dsa(),EVP_sha1())
-
-typedef struct evp_pkey_method_st
-	{
-	char *name;
-	int flags;
-	int type;		/* RSA, DSA, an SSLeay specific constant */
-	int oid;		/* For the pub-key type */
-	int encrypt_oid;	/* pub/priv key encryption */
-
-	int (*sign)();
-	int (*verify)();
-	struct	{
-		int (*set)();	/* get and/or set the underlying type */
-		int (*get)();
-		int (*encrypt)();
-		int (*decrypt)();
-		int (*i2d)();
-		int (*d2i)();
-		int (*dup)();
-		} pub,priv;
-	int (*set_asn1_parameters)();
-	int (*get_asn1_parameters)();
-	} EVP_PKEY_METHOD;
-#endif
-
 #ifndef EVP_MD
 struct env_md_st
 	{
@@ -245,6 +177,8 @@
 	int required_pkey_type[5]; /*EVP_PKEY_xxx */
 	int block_size;
 	int ctx_size; /* how big does the ctx->md_data need to be */
+	/* control function */
+	int (*md_ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
 	} /* EVP_MD */;
 
 typedef int evp_sign_method(int type,const unsigned char *m,
@@ -254,18 +188,42 @@
 			    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_PKEY_DIGEST	0x0002 /* digest is a "clone" digest used
+					* which is a copy of an existing
+					* one for a specific public key type.
+					* EVP_dss1() etc */
 
-#define EVP_MD_FLAG_SVCTX	0x0800 /* pass EVP_MD_SVCTX to sign/verify */
+/* Digest uses EVP_PKEY_METHOD for signing instead of MD specific signing */
+
+#define EVP_MD_FLAG_PKEY_METHOD_SIGNATURE	0x0004
+
+/* DigestAlgorithmIdentifier flags... */
+
+#define EVP_MD_FLAG_DIGALGID_MASK		0x0018
+
+/* NULL or absent parameter accepted. Use NULL */
+
+#define EVP_MD_FLAG_DIGALGID_NULL		0x0000
+
+/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */
+
+#define EVP_MD_FLAG_DIGALGID_ABSENT		0x0008
+
+/* Custom handling via ctrl */
+
+#define EVP_MD_FLAG_DIGALGID_CUSTOM		0x0018
+
+/* Digest ctrls */
+
+#define	EVP_MD_CTRL_DIGALGID			0x1
+#define	EVP_MD_CTRL_MICALG			0x2
+
+/* Minimum Algorithm specific ctrl value */
+
+#define	EVP_MD_CTRL_ALG_CTRL			0x1000
 
 #define EVP_PKEY_NULL_method	NULL,NULL,{0,0,0,0}
 
@@ -307,6 +265,10 @@
 	ENGINE *engine; /* functional reference if 'digest' is ENGINE-provided */
 	unsigned long flags;
 	void *md_data;
+	/* Public key context for sign/verify */
+	EVP_PKEY_CTX *pctx;
+	/* Update function: usually copied from EVP_MD */
+	int (*update)(EVP_MD_CTX *ctx,const void *data,size_t count);
 	} /* EVP_MD_CTX */;
 
 /* values for EVP_MD_CTX flags */
@@ -317,17 +279,23 @@
 						* cleaned */
 #define EVP_MD_CTX_FLAG_REUSE		0x0004 /* Don't free up ctx->md_data
 						* in EVP_MD_CTX_cleanup */
+/* FIPS and pad options are ignored in 1.0.0, definitions are here
+ * so we don't accidentally reuse the values for other purposes.
+ */
+
 #define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW	0x0008	/* Allow use of non FIPS digest
 						 * in FIPS mode */
 
+/* The following PAD options are also currently ignored in 1.0.0, digest
+ * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*()
+ * instead.
+ */
 #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 */
+
+#define EVP_MD_CTX_FLAG_NO_INIT		0x0100 /* Don't initialize md_data */
 
 struct evp_cipher_st
 	{
@@ -339,7 +307,7 @@
 	int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key,
 		    const unsigned char *iv, int enc);	/* init key */
 	int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out,
-			 const unsigned char *in, unsigned int inl);/* encrypt/decrypt data */
+			 const unsigned char *in, size_t inl);/* encrypt/decrypt data */
 	int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */
 	int ctx_size;		/* how big ctx->cipher_data needs to be */
 	int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */
@@ -357,7 +325,7 @@
 #define		EVP_CIPH_CBC_MODE		0x2
 #define		EVP_CIPH_CFB_MODE		0x3
 #define		EVP_CIPH_OFB_MODE		0x4
-#define 	EVP_CIPH_MODE			0x7
+#define 	EVP_CIPH_MODE			0xF0007
 /* Set if variable length cipher */
 #define 	EVP_CIPH_VARIABLE_LENGTH	0x8
 /* Set if the iv handling should be done by the cipher itself */
@@ -372,10 +340,8 @@
 #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
+/* cipher has its own additional copying logic */
+#define 	EVP_CIPH_CUSTOM_COPY		0x400
 /* Allow use default ASN1 get/set iv */
 #define		EVP_CIPH_FLAG_DEFAULT_ASN1	0x1000
 /* Buffer length in bits not bytes: CFB1 mode only */
@@ -390,6 +356,8 @@
 #define 	EVP_CTRL_GET_RC5_ROUNDS		0x4
 #define 	EVP_CTRL_SET_RC5_ROUNDS		0x5
 #define 	EVP_CTRL_RAND_KEY		0x6
+#define 	EVP_CTRL_PBE_PRF_NID		0x7
+#define 	EVP_CTRL_COPY			0x8
 
 typedef struct evp_cipher_info_st
 	{
@@ -462,26 +430,15 @@
 #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))
 int EVP_MD_pkey_type(const EVP_MD *md);	
 int EVP_MD_size(const EVP_MD *md);
 int EVP_MD_block_size(const EVP_MD *md);
+unsigned long EVP_MD_flags(const EVP_MD *md);
 
-const EVP_MD * EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
+const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
 #define EVP_MD_CTX_size(e)		EVP_MD_size(EVP_MD_CTX_md(e))
 #define EVP_MD_CTX_block_size(e)	EVP_MD_block_size(EVP_MD_CTX_md(e))
 #define EVP_MD_CTX_type(e)		EVP_MD_type(EVP_MD_CTX_md(e))
@@ -499,6 +456,7 @@
 int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx);
 int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx);
 int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in);
 void * EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx);
 void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data);
 #define EVP_CIPHER_CTX_type(c)         EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c))
@@ -516,6 +474,8 @@
 #define	EVP_VerifyUpdate(a,b,c)		EVP_DigestUpdate(a,b,c)
 #define EVP_OpenUpdate(a,b,c,d,e)	EVP_DecryptUpdate(a,b,c,d,e)
 #define EVP_SealUpdate(a,b,c,d,e)	EVP_EncryptUpdate(a,b,c,d,e)	
+#define EVP_DigestSignUpdate(a,b,c)	EVP_DigestUpdate(a,b,c)
+#define EVP_DigestVerifyUpdate(a,b,c)	EVP_DigestUpdate(a,b,c)
 
 #ifdef CONST_STRICT
 void BIO_set_md(BIO *,const EVP_MD *md);
@@ -562,6 +522,7 @@
 int	EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);
 
 int	EVP_read_pw_string(char *buf,int length,const char *prompt,int verify);
+int	EVP_read_pw_string_min(char *buf,int minlen,int maxlen,const char *prompt,int verify);
 void	EVP_set_pw_prompt(const char *prompt);
 char *	EVP_get_pw_prompt(void);
 
@@ -608,6 +569,16 @@
 int	EVP_VerifyFinal(EVP_MD_CTX *ctx,const unsigned char *sigbuf,
 		unsigned int siglen,EVP_PKEY *pkey);
 
+int	EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
+int	EVP_DigestSignFinal(EVP_MD_CTX *ctx,
+			unsigned char *sigret, size_t *siglen);
+
+int	EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
+int	EVP_DigestVerifyFinal(EVP_MD_CTX *ctx,
+			unsigned char *sig, size_t siglen);
+
 int	EVP_OpenInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type,
 		const unsigned char *ek, int ekl, const unsigned char *iv,
 		EVP_PKEY *priv);
@@ -680,6 +651,9 @@
 #ifndef OPENSSL_NO_RIPEMD
 const EVP_MD *EVP_ripemd160(void);
 #endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+const EVP_MD *EVP_whirlpool(void);
+#endif
 const EVP_CIPHER *EVP_enc_null(void);		/* does nothing :-) */
 #ifndef OPENSSL_NO_DES
 const EVP_CIPHER *EVP_des_ecb(void);
@@ -847,16 +821,31 @@
 const EVP_MD *EVP_get_digestbyname(const char *name);
 void EVP_cleanup(void);
 
-int		EVP_PKEY_decrypt(unsigned char *dec_key,
+void EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph,
+		const char *from, const char *to, void *x), void *arg);
+void EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph,
+		const char *from, const char *to, void *x), void *arg);
+
+void EVP_MD_do_all(void (*fn)(const EVP_MD *ciph,
+		const char *from, const char *to, void *x), void *arg);
+void EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *ciph,
+		const char *from, const char *to, void *x), void *arg);
+
+int		EVP_PKEY_decrypt_old(unsigned char *dec_key,
 			const unsigned char *enc_key,int enc_key_len,
 			EVP_PKEY *private_key);
-int		EVP_PKEY_encrypt(unsigned char *enc_key,
+int		EVP_PKEY_encrypt_old(unsigned char *enc_key,
 			const unsigned char *key,int key_len,
 			EVP_PKEY *pub_key);
 int		EVP_PKEY_type(int type);
+int		EVP_PKEY_id(const EVP_PKEY *pkey);
+int		EVP_PKEY_base_id(const EVP_PKEY *pkey);
 int		EVP_PKEY_bits(EVP_PKEY *pkey);
 int		EVP_PKEY_size(EVP_PKEY *pkey);
-int 		EVP_PKEY_assign(EVP_PKEY *pkey,int type,char *key);
+int 		EVP_PKEY_set_type(EVP_PKEY *pkey,int type);
+int		EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len);
+int 		EVP_PKEY_assign(EVP_PKEY *pkey,int type,void *key);
+void *		EVP_PKEY_get0(EVP_PKEY *pkey);
 
 #ifndef OPENSSL_NO_RSA
 struct rsa_st;
@@ -899,6 +888,15 @@
 
 int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
 
+int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
+				int indent, ASN1_PCTX *pctx);
+int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
+				int indent, ASN1_PCTX *pctx);
+int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
+				int indent, ASN1_PCTX *pctx);
+
+int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
+
 int EVP_CIPHER_type(const EVP_CIPHER *ctx);
 
 /* calls methods */
@@ -916,6 +914,10 @@
 int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
 			   const unsigned char *salt, int saltlen, int iter,
 			   int keylen, unsigned char *out);
+int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
+			   const unsigned char *salt, int saltlen, int iter,
+			   const EVP_MD *digest,
+		      int keylen, unsigned char *out);
 int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
 			 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md,
 			 int en_de);
@@ -924,27 +926,260 @@
 
 int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
 	     ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de);
+
+/* PBE type */
+
+/* Can appear as the outermost AlgorithmIdentifier */
+#define EVP_PBE_TYPE_OUTER	0x0
+/* Is an PRF type OID */
+#define EVP_PBE_TYPE_PRF	0x1
+
+int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid,
+	     EVP_PBE_KEYGEN *keygen);
 int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
 		    EVP_PBE_KEYGEN *keygen);
+int EVP_PBE_find(int type, int pbe_nid,
+			int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen);
 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
+#define ASN1_PKEY_ALIAS		0x1
+#define ASN1_PKEY_DYNAMIC	0x2
+#define ASN1_PKEY_SIGPARAM_NULL	0x4
 
-void EVP_add_alg_module(void);
+#define ASN1_PKEY_CTRL_PKCS7_SIGN	0x1
+#define ASN1_PKEY_CTRL_PKCS7_ENCRYPT	0x2
+#define ASN1_PKEY_CTRL_DEFAULT_MD_NID	0x3
+#define ASN1_PKEY_CTRL_CMS_SIGN		0x5
+#define ASN1_PKEY_CTRL_CMS_ENVELOPE	0x7
+
+int EVP_PKEY_asn1_get_count(void);
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx);
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type);
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
+					const char *str, int len);
+int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth);
+int EVP_PKEY_asn1_add_alias(int to, int from);
+int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, int *ppkey_flags,
+				const char **pinfo, const char **ppem_str,
+					const EVP_PKEY_ASN1_METHOD *ameth);
+
+const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey);
+EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
+					const char *pem_str, const char *info);
+void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, 
+			const EVP_PKEY_ASN1_METHOD *src);
+void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *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));
+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));
+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));
+
+void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
+		void (*pkey_free)(EVP_PKEY *pkey));
+void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
+		int (*pkey_ctrl)(EVP_PKEY *pkey, int op,
+							long arg1, void *arg2));
+
+
+#define EVP_PKEY_OP_UNDEFINED		0
+#define EVP_PKEY_OP_PARAMGEN		(1<<1)
+#define EVP_PKEY_OP_KEYGEN		(1<<2)
+#define EVP_PKEY_OP_SIGN		(1<<3)
+#define EVP_PKEY_OP_VERIFY		(1<<4)
+#define EVP_PKEY_OP_VERIFYRECOVER	(1<<5)
+#define EVP_PKEY_OP_SIGNCTX		(1<<6)
+#define EVP_PKEY_OP_VERIFYCTX		(1<<7)
+#define EVP_PKEY_OP_ENCRYPT		(1<<8)
+#define EVP_PKEY_OP_DECRYPT		(1<<9)
+#define EVP_PKEY_OP_DERIVE		(1<<10)
+
+#define EVP_PKEY_OP_TYPE_SIG	\
+	(EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \
+		| EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX)
+
+#define EVP_PKEY_OP_TYPE_CRYPT \
+	(EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT)
+
+#define EVP_PKEY_OP_TYPE_NOGEN \
+	(EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE)
+
+#define EVP_PKEY_OP_TYPE_GEN \
+		(EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)
+
+#define	 EVP_PKEY_CTX_set_signature_md(ctx, md)	\
+		EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,  \
+					EVP_PKEY_CTRL_MD, 0, (void *)md)
+
+#define EVP_PKEY_CTRL_MD		1
+#define EVP_PKEY_CTRL_PEER_KEY		2
+
+#define EVP_PKEY_CTRL_PKCS7_ENCRYPT	3
+#define EVP_PKEY_CTRL_PKCS7_DECRYPT	4
+
+#define EVP_PKEY_CTRL_PKCS7_SIGN	5
+
+#define EVP_PKEY_CTRL_SET_MAC_KEY	6
+
+#define EVP_PKEY_CTRL_DIGESTINIT	7
+
+/* Used by GOST key encryption in TLS */
+#define EVP_PKEY_CTRL_SET_IV 		8
+
+#define EVP_PKEY_CTRL_CMS_ENCRYPT	9
+#define EVP_PKEY_CTRL_CMS_DECRYPT	10
+#define EVP_PKEY_CTRL_CMS_SIGN		11
+
+#define EVP_PKEY_ALG_CTRL		0x1000
+
+
+#define EVP_PKEY_FLAG_AUTOARGLEN	2
+
+const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type);
+EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags);
+void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth);
+int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth);
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
+EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
+EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx);
+void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
+				int cmd, int p1, void *p2);
+int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
+						const char *value);
+
+int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx);
+void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen);
+
+EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
+				unsigned char *key, int keylen);
+
+void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data);
+void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx);
+EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx);
+
+EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx);
+
+void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data);
+void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
+			unsigned char *sig, size_t *siglen,
+			const unsigned char *tbs, size_t tbslen);
+int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
+			const unsigned char *sig, size_t siglen,
+			const unsigned char *tbs, size_t tbslen);
+int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
+			unsigned char *rout, size_t *routlen,
+			const unsigned char *sig, size_t siglen);
+int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
+			unsigned char *out, size_t *outlen,
+			const unsigned char *in, size_t inlen);
+int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
+			unsigned char *out, size_t *outlen,
+			const unsigned char *in, size_t inlen);
+
+int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
+int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
+
+typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
+int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
+
+void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb);
+EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx);
+
+void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
+	int (*init)(EVP_PKEY_CTX *ctx));
+
+void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
+	int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src));
+
+void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
+	void (*cleanup)(EVP_PKEY_CTX *ctx));
+
+void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
+	int (*paramgen_init)(EVP_PKEY_CTX *ctx),
+	int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey));
+
+void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
+	int (*keygen_init)(EVP_PKEY_CTX *ctx),
+	int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey));
+
+void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
+	int (*sign_init)(EVP_PKEY_CTX *ctx),
+	int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					const unsigned char *tbs, size_t tbslen));
+
+void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
+	int (*verify_init)(EVP_PKEY_CTX *ctx),
+	int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
+					const unsigned char *tbs, size_t tbslen));
+
+void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
+	int (*verify_recover_init)(EVP_PKEY_CTX *ctx),
+	int (*verify_recover)(EVP_PKEY_CTX *ctx,
+					unsigned char *sig, size_t *siglen,
+					const unsigned char *tbs, size_t tbslen));
+
+void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
+	int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
+	int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					EVP_MD_CTX *mctx));
+
+void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
+	int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
+	int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,int siglen,
+					EVP_MD_CTX *mctx));
+
+void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
+	int (*encrypt_init)(EVP_PKEY_CTX *ctx),
+	int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+					const unsigned char *in, size_t inlen));
+
+void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
+	int (*decrypt_init)(EVP_PKEY_CTX *ctx),
+	int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+					const unsigned char *in, size_t inlen));
+
+void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
+	int (*derive_init)(EVP_PKEY_CTX *ctx),
+	int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen));
+
+void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
+	int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2),
+	int (*ctrl_str)(EVP_PKEY_CTX *ctx,
+					const char *type, const char *value));
 
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -956,46 +1191,66 @@
 
 /* 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_DO_SIGVER_INIT				 161
 #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_COPY			 163
 #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
+#define EVP_F_EVP_MD_SIZE				 162
 #define EVP_F_EVP_OPENINIT				 102
 #define EVP_F_EVP_PBE_ALG_ADD				 115
+#define EVP_F_EVP_PBE_ALG_ADD_TYPE			 160
 #define EVP_F_EVP_PBE_CIPHERINIT			 116
 #define EVP_F_EVP_PKCS82PKEY				 111
+#define EVP_F_EVP_PKCS82PKEY_BROKEN			 136
 #define EVP_F_EVP_PKEY2PKCS8_BROKEN			 113
 #define EVP_F_EVP_PKEY_COPY_PARAMETERS			 103
+#define EVP_F_EVP_PKEY_CTX_CTRL				 137
+#define EVP_F_EVP_PKEY_CTX_CTRL_STR			 150
+#define EVP_F_EVP_PKEY_CTX_DUP				 156
 #define EVP_F_EVP_PKEY_DECRYPT				 104
+#define EVP_F_EVP_PKEY_DECRYPT_INIT			 138
+#define EVP_F_EVP_PKEY_DECRYPT_OLD			 151
+#define EVP_F_EVP_PKEY_DERIVE				 153
+#define EVP_F_EVP_PKEY_DERIVE_INIT			 154
+#define EVP_F_EVP_PKEY_DERIVE_SET_PEER			 155
 #define EVP_F_EVP_PKEY_ENCRYPT				 105
+#define EVP_F_EVP_PKEY_ENCRYPT_INIT			 139
+#define EVP_F_EVP_PKEY_ENCRYPT_OLD			 152
 #define EVP_F_EVP_PKEY_GET1_DH				 119
 #define EVP_F_EVP_PKEY_GET1_DSA				 120
 #define EVP_F_EVP_PKEY_GET1_ECDSA			 130
 #define EVP_F_EVP_PKEY_GET1_EC_KEY			 131
 #define EVP_F_EVP_PKEY_GET1_RSA				 121
+#define EVP_F_EVP_PKEY_KEYGEN				 146
+#define EVP_F_EVP_PKEY_KEYGEN_INIT			 147
 #define EVP_F_EVP_PKEY_NEW				 106
+#define EVP_F_EVP_PKEY_PARAMGEN				 148
+#define EVP_F_EVP_PKEY_PARAMGEN_INIT			 149
+#define EVP_F_EVP_PKEY_SIGN				 140
+#define EVP_F_EVP_PKEY_SIGN_INIT			 141
+#define EVP_F_EVP_PKEY_VERIFY				 142
+#define EVP_F_EVP_PKEY_VERIFY_INIT			 143
+#define EVP_F_EVP_PKEY_VERIFY_RECOVER			 144
+#define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT		 145
 #define EVP_F_EVP_RIJNDAEL				 126
 #define EVP_F_EVP_SIGNFINAL				 107
 #define EVP_F_EVP_VERIFYFINAL				 108
+#define EVP_F_INT_CTX_NEW				 157
 #define EVP_F_PKCS5_PBE_KEYIVGEN			 117
 #define EVP_F_PKCS5_V2_PBE_KEYIVGEN			 118
 #define EVP_F_PKCS8_SET_BROKEN				 112
+#define EVP_F_PKEY_SET_TYPE				 158
 #define EVP_F_RC2_MAGIC_TO_METH				 109
 #define EVP_F_RC5_CTRL					 125
 
@@ -1007,41 +1262,52 @@
 #define EVP_R_BAD_KEY_LENGTH				 137
 #define EVP_R_BN_DECODE_ERROR				 112
 #define EVP_R_BN_PUBKEY_ERROR				 113
+#define EVP_R_BUFFER_TOO_SMALL				 155
 #define EVP_R_CAMELLIA_KEY_SETUP_FAILED			 157
 #define EVP_R_CIPHER_PARAMETER_ERROR			 122
+#define EVP_R_COMMAND_NOT_SUPPORTED			 147
 #define EVP_R_CTRL_NOT_IMPLEMENTED			 132
 #define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED		 133
 #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_DIFFERENT_PARAMETERS			 153
 #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_DIGEST				 152
 #define EVP_R_INVALID_KEY_LENGTH			 130
+#define EVP_R_INVALID_OPERATION				 148
 #define EVP_R_IV_TOO_LARGE				 102
 #define EVP_R_KEYGEN_FAILURE				 120
+#define EVP_R_MESSAGE_DIGEST_IS_NULL			 159
+#define EVP_R_METHOD_NOT_SUPPORTED			 144
 #define EVP_R_MISSING_PARAMETERS			 103
 #define EVP_R_NO_CIPHER_SET				 131
+#define EVP_R_NO_DEFAULT_DIGEST				 158
 #define EVP_R_NO_DIGEST_SET				 139
 #define EVP_R_NO_DSA_PARAMETERS				 116
+#define EVP_R_NO_KEY_SET				 154
+#define EVP_R_NO_OPERATION_SET				 149
 #define EVP_R_NO_SIGN_FUNCTION_CONFIGURED		 104
 #define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED		 105
+#define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE	 150
+#define EVP_R_OPERATON_NOT_INITIALIZED			 151
 #define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE			 117
+#define EVP_R_PRIVATE_KEY_DECODE_ERROR			 145
+#define EVP_R_PRIVATE_KEY_ENCODE_ERROR			 146
 #define EVP_R_PUBLIC_KEY_NOT_RSA			 106
-#define EVP_R_UNKNOWN_OPTION				 149
+#define EVP_R_UNKNOWN_CIPHER				 160
+#define EVP_R_UNKNOWN_DIGEST				 161
 #define EVP_R_UNKNOWN_PBE_ALGORITHM			 121
 #define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS		 135
+#define EVP_R_UNSUPPORTED_ALGORITHM			 156
 #define EVP_R_UNSUPPORTED_CIPHER			 107
 #define EVP_R_UNSUPPORTED_KEYLENGTH			 123
 #define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION	 124
@@ -1051,7 +1317,6 @@
 #define EVP_R_UNSUPPORTED_SALT_TYPE			 126
 #define EVP_R_WRONG_FINAL_BLOCK_LENGTH			 109
 #define EVP_R_WRONG_PUBLIC_KEY_TYPE			 110
-#define EVP_R_SEED_KEY_SETUP_FAILED			 162
 
 #ifdef  __cplusplus
 }
diff --git a/crypto/evp/evp_cnf.c b/crypto/evp/evp_cnf.c
deleted file mode 100644
index 2e4db30..0000000
--- a/crypto/evp/evp_cnf.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/* evp_cnf.c */
-/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
- * project 2007.
- */
-/* ====================================================================
- * Copyright (c) 2007 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#include <stdio.h>
-#include <ctype.h>
-#include <openssl/crypto.h>
-#include "cryptlib.h"
-#include <openssl/conf.h>
-#include <openssl/dso.h>
-#include <openssl/x509.h>
-#include <openssl/x509v3.h>
-#ifdef OPENSSL_FIPS
-#include <openssl/fips.h>
-#endif
-
-
-/* Algorithm configuration module. */
-
-static int alg_module_init(CONF_IMODULE *md, const CONF *cnf)
-	{
-	int i;
-	const char *oid_section;
-	STACK_OF(CONF_VALUE) *sktmp;
-	CONF_VALUE *oval;
-	oid_section = CONF_imodule_get_value(md);
-	if(!(sktmp = NCONF_get_section(cnf, oid_section)))
-		{
-		EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION);
-		return 0;
-		}
-	for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++)
-		{
-		oval = sk_CONF_VALUE_value(sktmp, i);
-		if (!strcmp(oval->name, "fips_mode"))
-			{
-			int m;
-			if (!X509V3_get_value_bool(oval, &m))
-				{
-				EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE);
-				return 0;
-				}
-			if (m > 0)
-				{
-#ifdef OPENSSL_FIPS
-				if (!FIPS_mode() && !FIPS_mode_set(1))
-					{
-					EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_SETTING_FIPS_MODE);
-					return 0;
-					}
-#else
-				EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED);
-				return 0;
-#endif
-				}
-			}
-		else
-			{
-			EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION);
-			ERR_add_error_data(4, "name=", oval->name,
-						", value=", oval->value);
-			}
-				
-		}
-	return 1;
-	}
-
-void EVP_add_alg_module(void)
-	{
-	CONF_module_add("alg_section", alg_module_init, 0);
-	}
diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
index 30e0ca4..bead6a2 100644
--- a/crypto/evp/evp_enc.c
+++ b/crypto/evp/evp_enc.c
@@ -66,16 +66,14 @@
 #endif
 #include "evp_locl.h"
 
-#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
-
 const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT;
 
+void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
+	{
+	memset(ctx,0,sizeof(EVP_CIPHER_CTX));
+	/* ctx->cipher=NULL; */
+	}
+
 EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
 	{
 	EVP_CIPHER_CTX *ctx=OPENSSL_malloc(sizeof *ctx);
@@ -92,6 +90,144 @@
 	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)
 	{
@@ -151,7 +287,7 @@
 
 	if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0)
 		{
-		if(M_do_cipher(ctx,out,in,inl))
+		if(ctx->cipher->do_cipher(ctx,out,in,inl))
 			{
 			*outl=inl;
 			return 1;
@@ -178,7 +314,7 @@
 			{
 			j=bl-i;
 			memcpy(&(ctx->buf[i]),in,j);
-			if(!M_do_cipher(ctx,out,ctx->buf,bl)) return 0;
+			if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0;
 			inl-=j;
 			in+=j;
 			out+=bl;
@@ -191,7 +327,7 @@
 	inl-=i;
 	if (inl > 0)
 		{
-		if(!M_do_cipher(ctx,out,in,inl)) return 0;
+		if(!ctx->cipher->do_cipher(ctx,out,in,inl)) return 0;
 		*outl+=inl;
 		}
 
@@ -235,7 +371,7 @@
 	n=b-bl;
 	for (i=bl; i<b; i++)
 		ctx->buf[i]=n;
-	ret=M_do_cipher(ctx,out,ctx->buf,b);
+	ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b);
 
 
 	if(ret)
@@ -357,6 +493,28 @@
 		}
 	}
 
+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) 
@@ -378,6 +536,27 @@
 	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)
@@ -387,54 +566,38 @@
 	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)
+int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
 	{
-	if(impl)
+	if ((in == NULL) || (in->cipher == NULL))
 		{
-		if (!ENGINE_init(impl))
+		EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED);
+		return 0;
+		}
+#ifndef OPENSSL_NO_ENGINE
+	/* Make sure it's safe to copy a cipher context using an ENGINE */
+	if (in->engine && !ENGINE_init(in->engine))
+		{
+		EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_ENGINE_LIB);
+		return 0;
+		}
+#endif
+
+	EVP_CIPHER_CTX_cleanup(out);
+	memcpy(out,in,sizeof *out);
+
+	if (in->cipher_data && in->cipher->ctx_size)
+		{
+		out->cipher_data=OPENSSL_malloc(in->cipher->ctx_size);
+		if (!out->cipher_data)
 			{
-			EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR);
+			EVPerr(EVP_F_EVP_CIPHER_CTX_COPY,ERR_R_MALLOC_FAILURE);
 			return 0;
 			}
+		memcpy(out->cipher_data,in->cipher_data,in->cipher->ctx_size);
 		}
-	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;
+
+	if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY)
+		return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out);
 	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 b5b900d..d8bfec0 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-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
@@ -71,46 +71,66 @@
 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_DO_SIGVER_INIT),	"DO_SIGVER_INIT"},
 {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_COPY),	"EVP_CIPHER_CTX_copy"},
 {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"},
+{ERR_FUNC(EVP_F_EVP_MD_SIZE),	"EVP_MD_SIZE"},
 {ERR_FUNC(EVP_F_EVP_OPENINIT),	"EVP_OpenInit"},
 {ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD),	"EVP_PBE_alg_add"},
+{ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD_TYPE),	"EVP_PBE_alg_add_type"},
 {ERR_FUNC(EVP_F_EVP_PBE_CIPHERINIT),	"EVP_PBE_CipherInit"},
 {ERR_FUNC(EVP_F_EVP_PKCS82PKEY),	"EVP_PKCS82PKEY"},
+{ERR_FUNC(EVP_F_EVP_PKCS82PKEY_BROKEN),	"EVP_PKCS82PKEY_BROKEN"},
 {ERR_FUNC(EVP_F_EVP_PKEY2PKCS8_BROKEN),	"EVP_PKEY2PKCS8_broken"},
 {ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS),	"EVP_PKEY_copy_parameters"},
+{ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL),	"EVP_PKEY_CTX_ctrl"},
+{ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL_STR),	"EVP_PKEY_CTX_ctrl_str"},
+{ERR_FUNC(EVP_F_EVP_PKEY_CTX_DUP),	"EVP_PKEY_CTX_dup"},
 {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT),	"EVP_PKEY_decrypt"},
+{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_INIT),	"EVP_PKEY_decrypt_init"},
+{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_OLD),	"EVP_PKEY_decrypt_old"},
+{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE),	"EVP_PKEY_derive"},
+{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_INIT),	"EVP_PKEY_derive_init"},
+{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_SET_PEER),	"EVP_PKEY_derive_set_peer"},
 {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT),	"EVP_PKEY_encrypt"},
+{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_INIT),	"EVP_PKEY_encrypt_init"},
+{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_OLD),	"EVP_PKEY_encrypt_old"},
 {ERR_FUNC(EVP_F_EVP_PKEY_GET1_DH),	"EVP_PKEY_get1_DH"},
 {ERR_FUNC(EVP_F_EVP_PKEY_GET1_DSA),	"EVP_PKEY_get1_DSA"},
 {ERR_FUNC(EVP_F_EVP_PKEY_GET1_ECDSA),	"EVP_PKEY_GET1_ECDSA"},
 {ERR_FUNC(EVP_F_EVP_PKEY_GET1_EC_KEY),	"EVP_PKEY_get1_EC_KEY"},
 {ERR_FUNC(EVP_F_EVP_PKEY_GET1_RSA),	"EVP_PKEY_get1_RSA"},
+{ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN),	"EVP_PKEY_keygen"},
+{ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN_INIT),	"EVP_PKEY_keygen_init"},
 {ERR_FUNC(EVP_F_EVP_PKEY_NEW),	"EVP_PKEY_new"},
+{ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN),	"EVP_PKEY_paramgen"},
+{ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN_INIT),	"EVP_PKEY_paramgen_init"},
+{ERR_FUNC(EVP_F_EVP_PKEY_SIGN),	"EVP_PKEY_sign"},
+{ERR_FUNC(EVP_F_EVP_PKEY_SIGN_INIT),	"EVP_PKEY_sign_init"},
+{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY),	"EVP_PKEY_verify"},
+{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_INIT),	"EVP_PKEY_verify_init"},
+{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER),	"EVP_PKEY_verify_recover"},
+{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT),	"EVP_PKEY_verify_recover_init"},
 {ERR_FUNC(EVP_F_EVP_RIJNDAEL),	"EVP_RIJNDAEL"},
 {ERR_FUNC(EVP_F_EVP_SIGNFINAL),	"EVP_SignFinal"},
 {ERR_FUNC(EVP_F_EVP_VERIFYFINAL),	"EVP_VerifyFinal"},
+{ERR_FUNC(EVP_F_INT_CTX_NEW),	"INT_CTX_NEW"},
 {ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN),	"PKCS5_PBE_keyivgen"},
 {ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN),	"PKCS5_v2_PBE_keyivgen"},
 {ERR_FUNC(EVP_F_PKCS8_SET_BROKEN),	"PKCS8_set_broken"},
+{ERR_FUNC(EVP_F_PKEY_SET_TYPE),	"PKEY_SET_TYPE"},
 {ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH),	"RC2_MAGIC_TO_METH"},
 {ERR_FUNC(EVP_F_RC5_CTRL),	"RC5_CTRL"},
 {0,NULL}
@@ -125,42 +145,52 @@
 {ERR_REASON(EVP_R_BAD_KEY_LENGTH)        ,"bad key length"},
 {ERR_REASON(EVP_R_BN_DECODE_ERROR)       ,"bn decode error"},
 {ERR_REASON(EVP_R_BN_PUBKEY_ERROR)       ,"bn pubkey error"},
+{ERR_REASON(EVP_R_BUFFER_TOO_SMALL)      ,"buffer too small"},
 {ERR_REASON(EVP_R_CAMELLIA_KEY_SETUP_FAILED),"camellia key setup failed"},
 {ERR_REASON(EVP_R_CIPHER_PARAMETER_ERROR),"cipher parameter error"},
+{ERR_REASON(EVP_R_COMMAND_NOT_SUPPORTED) ,"command not supported"},
 {ERR_REASON(EVP_R_CTRL_NOT_IMPLEMENTED)  ,"ctrl not implemented"},
 {ERR_REASON(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED),"ctrl operation not implemented"},
 {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_DIFFERENT_PARAMETERS)  ,"different parameters"},
 {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_DIGEST)        ,"invalid digest"},
 {ERR_REASON(EVP_R_INVALID_KEY_LENGTH)    ,"invalid key length"},
+{ERR_REASON(EVP_R_INVALID_OPERATION)     ,"invalid operation"},
 {ERR_REASON(EVP_R_IV_TOO_LARGE)          ,"iv too large"},
 {ERR_REASON(EVP_R_KEYGEN_FAILURE)        ,"keygen failure"},
+{ERR_REASON(EVP_R_MESSAGE_DIGEST_IS_NULL),"message digest is null"},
+{ERR_REASON(EVP_R_METHOD_NOT_SUPPORTED)  ,"method not supported"},
 {ERR_REASON(EVP_R_MISSING_PARAMETERS)    ,"missing parameters"},
 {ERR_REASON(EVP_R_NO_CIPHER_SET)         ,"no cipher set"},
+{ERR_REASON(EVP_R_NO_DEFAULT_DIGEST)     ,"no default digest"},
 {ERR_REASON(EVP_R_NO_DIGEST_SET)         ,"no digest set"},
 {ERR_REASON(EVP_R_NO_DSA_PARAMETERS)     ,"no dsa parameters"},
+{ERR_REASON(EVP_R_NO_KEY_SET)            ,"no key set"},
+{ERR_REASON(EVP_R_NO_OPERATION_SET)      ,"no operation set"},
 {ERR_REASON(EVP_R_NO_SIGN_FUNCTION_CONFIGURED),"no sign function configured"},
 {ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED),"no verify function configured"},
+{ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),"operation not supported for this keytype"},
+{ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED),"operaton not initialized"},
 {ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE),"pkcs8 unknown broken type"},
+{ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR),"private key decode error"},
+{ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR),"private key encode error"},
 {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_CIPHER)        ,"unknown cipher"},
+{ERR_REASON(EVP_R_UNKNOWN_DIGEST)        ,"unknown digest"},
 {ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"},
 {ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"},
+{ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM) ,"unsupported algorithm"},
 {ERR_REASON(EVP_R_UNSUPPORTED_CIPHER)    ,"unsupported cipher"},
 {ERR_REASON(EVP_R_UNSUPPORTED_KEYLENGTH) ,"unsupported keylength"},
 {ERR_REASON(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION),"unsupported key derivation function"},
diff --git a/crypto/evp/evp_key.c b/crypto/evp/evp_key.c
index 361ea69..839d6a3 100644
--- a/crypto/evp/evp_key.c
+++ b/crypto/evp/evp_key.c
@@ -90,6 +90,11 @@
  * this function will fail */
 int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify)
 	{
+	return EVP_read_pw_string_min(buf, 0, len, prompt, verify);
+	}
+
+int EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, int verify)
+	{
 	int ret;
 	char buff[BUFSIZ];
 	UI *ui;
@@ -97,10 +102,10 @@
 	if ((prompt == NULL) && (prompt_string[0] != '\0'))
 		prompt=prompt_string;
 	ui = UI_new();
-	UI_add_input_string(ui,prompt,0,buf,0,(len>=BUFSIZ)?BUFSIZ-1:len);
+	UI_add_input_string(ui,prompt,0,buf,min,(len>=BUFSIZ)?BUFSIZ-1:len);
 	if (verify)
 		UI_add_verify_string(ui,prompt,0,
-			buff,0,(len>=BUFSIZ)?BUFSIZ-1:len,buf);
+			buff,min,(len>=BUFSIZ)?BUFSIZ-1:len,buf);
 	ret = UI_process(ui);
 	UI_free(ui);
 	OPENSSL_cleanse(buff,BUFSIZ);
diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c
index 9c20061..40951a0 100644
--- a/crypto/evp/evp_lib.c
+++ b/crypto/evp/evp_lib.c
@@ -67,8 +67,6 @@
 
 	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);
@@ -80,8 +78,6 @@
 
 	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);
@@ -188,6 +184,11 @@
 	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;
@@ -198,6 +199,11 @@
 	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,6 +219,11 @@
 	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;
@@ -223,6 +234,11 @@
 	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;
@@ -245,11 +261,23 @@
 
 int EVP_MD_size(const EVP_MD *md)
 	{
+	if (!md)
+		{
+		EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL);
+		return -1;
+		}
 	return md->md_size;
 	}
 
-const EVP_MD * EVP_MD_CTX_md(const EVP_MD_CTX *ctx)
+unsigned long EVP_MD_flags(const EVP_MD *md)
 	{
+	return md->flags;
+	}
+
+const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx)
+	{
+	if (!ctx)
+		return NULL;
 	return ctx->digest;
 	}
 
diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h
index 72105b0..292d74c 100644
--- a/crypto/evp/evp_locl.h
+++ b/crypto/evp/evp_locl.h
@@ -61,38 +61,66 @@
 /* Wrapper functions for each cipher mode */
 
 #define BLOCK_CIPHER_ecb_loop() \
-	unsigned int i, bl; \
+	size_t i, bl; \
 	bl = ctx->cipher->block_size;\
 	if(inl < bl) return 1;\
 	inl -= bl; \
 	for(i=0; i <= inl; i+=bl) 
 
 #define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
-static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
+static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
 {\
 	BLOCK_CIPHER_ecb_loop() \
 		cprefix##_ecb_encrypt(in + i, out + i, &((kstruct *)ctx->cipher_data)->ksched, ctx->encrypt);\
 	return 1;\
 }
 
+#define EVP_MAXCHUNK ((size_t)1<<(sizeof(long)*8-2))
+
 #define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \
-static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
+static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
 {\
-	cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
+	while(inl>=EVP_MAXCHUNK)\
+	    {\
+	    cprefix##_ofb##cbits##_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
+	    inl-=EVP_MAXCHUNK;\
+	    in +=EVP_MAXCHUNK;\
+	    out+=EVP_MAXCHUNK;\
+	    }\
+	if (inl)\
+	    cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
 	return 1;\
 }
 
 #define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
-static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
+static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
 {\
-	cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
+	while(inl>=EVP_MAXCHUNK) \
+	    {\
+	    cprefix##_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
+	    inl-=EVP_MAXCHUNK;\
+	    in +=EVP_MAXCHUNK;\
+	    out+=EVP_MAXCHUNK;\
+	    }\
+	if (inl)\
+	    cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
 	return 1;\
 }
 
 #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) \
+static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
 {\
-	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);\
+	size_t chunk=EVP_MAXCHUNK;\
+	if (cbits==1)  chunk>>=3;\
+	if (inl<chunk) chunk=inl;\
+	while(inl && inl>=chunk)\
+	    {\
+            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);\
+	    inl-=chunk;\
+	    in +=chunk;\
+	    out+=chunk;\
+	    if(inl<chunk) chunk=inl;\
+	    }\
 	return 1;\
 }
 
@@ -127,9 +155,9 @@
 #define BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, \
 			     iv_len, cbits, flags, init_key, cleanup, \
 			     set_asn1, get_asn1, ctrl) \
-BLOCK_CIPHER_def1(cname, cfb##cbits, cfb##cbits, CFB, kstruct, nid, \
-			(cbits + 7)/8, key_len, iv_len, \
-		flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
+BLOCK_CIPHER_def1(cname, cfb##cbits, cfb##cbits, CFB, kstruct, nid, 1, \
+		  key_len, iv_len, flags, init_key, cleanup, set_asn1, \
+		  get_asn1, ctrl)
 
 #define BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, \
 			     iv_len, cbits, flags, init_key, cleanup, \
@@ -226,27 +254,92 @@
 
 #define EVP_C_DATA(kstruct, ctx)	((kstruct *)(ctx)->cipher_data)
 
-#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len,fl) \
+#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len) \
 	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, \
-			     (fl)|EVP_CIPH_FLAG_DEFAULT_ASN1, \
-			     cipher##_init_key, NULL, NULL, NULL, NULL)
+			     0, cipher##_init_key, NULL, \
+			     EVP_CIPHER_set_asn1_iv, \
+			     EVP_CIPHER_get_asn1_iv, \
+			     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
+struct evp_pkey_ctx_st
+	{
+	/* Method associated with this operation */
+	const EVP_PKEY_METHOD *pmeth;
+	/* Engine that implements this method or NULL if builtin */
+	ENGINE *engine;
+	/* Key: may be NULL */
+	EVP_PKEY *pkey;
+	/* Peer key for key agreement, may be NULL */
+	EVP_PKEY *peerkey;
+	/* Actual operation */
+	int operation;
+	/* Algorithm specific data */
+	void *data;
+	/* Application specific data */
+	void *app_data;
+	/* Keygen callback */
+	EVP_PKEY_gen_cb *pkey_gencb;
+	/* implementation specific keygen data */
+	int *keygen_info;
+	int keygen_info_count;
+	} /* EVP_PKEY_CTX */;
 
-#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
+#define EVP_PKEY_FLAG_DYNAMIC	1
 
-#endif
+struct evp_pkey_method_st
+	{
+	int pkey_id;
+	int flags;
 
+	int (*init)(EVP_PKEY_CTX *ctx);
+	int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src);
+	void (*cleanup)(EVP_PKEY_CTX *ctx);
+
+	int (*paramgen_init)(EVP_PKEY_CTX *ctx);
+	int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
+
+	int (*keygen_init)(EVP_PKEY_CTX *ctx);
+	int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
+
+	int (*sign_init)(EVP_PKEY_CTX *ctx);
+	int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+				const unsigned char *tbs, size_t tbslen);
+
+	int (*verify_init)(EVP_PKEY_CTX *ctx);
+	int (*verify)(EVP_PKEY_CTX *ctx,
+				const unsigned char *sig, size_t siglen,
+				const unsigned char *tbs, size_t tbslen);
+
+	int (*verify_recover_init)(EVP_PKEY_CTX *ctx);
+	int (*verify_recover)(EVP_PKEY_CTX *ctx,
+				unsigned char *rout, size_t *routlen,
+				const unsigned char *sig, size_t siglen);
+
+	int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
+	int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					EVP_MD_CTX *mctx);
+
+	int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
+	int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,int siglen,
+					EVP_MD_CTX *mctx);
+
+	int (*encrypt_init)(EVP_PKEY_CTX *ctx);
+	int (*encrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+					const unsigned char *in, size_t inlen);
+
+	int (*decrypt_init)(EVP_PKEY_CTX *ctx);
+	int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+					const unsigned char *in, size_t inlen);
+
+	int (*derive_init)(EVP_PKEY_CTX *ctx);
+	int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
+
+	int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
+	int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value);
+
+
+	} /* EVP_PKEY_METHOD */;
+
+void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx);
diff --git a/crypto/evp/evp_pbe.c b/crypto/evp/evp_pbe.c
index 5e830be..c9d932d 100644
--- a/crypto/evp/evp_pbe.c
+++ b/crypto/evp/evp_pbe.c
@@ -3,7 +3,7 @@
  * project 1999.
  */
 /* ====================================================================
- * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
@@ -59,79 +59,253 @@
 #include <stdio.h>
 #include "cryptlib.h"
 #include <openssl/evp.h>
+#include <openssl/pkcs12.h>
 #include <openssl/x509.h>
 
 /* Password based encryption (PBE) functions */
 
-static STACK *pbe_algs;
+DECLARE_STACK_OF(EVP_PBE_CTL)
+static STACK_OF(EVP_PBE_CTL) *pbe_algs;
 
 /* Setup a cipher context from a PBE algorithm */
 
-typedef struct {
-int pbe_nid;
-const EVP_CIPHER *cipher;
-const EVP_MD *md;
-EVP_PBE_KEYGEN *keygen;
-} EVP_PBE_CTL;
+typedef struct
+	{
+	int pbe_type;
+	int pbe_nid;
+	int cipher_nid;
+	int md_nid;
+	EVP_PBE_KEYGEN *keygen;
+	} EVP_PBE_CTL;
+
+static const EVP_PBE_CTL builtin_pbe[] = 
+	{
+	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC,
+			NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC,
+			NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC,
+			NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen},
+
+	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4,
+			NID_rc4, NID_sha1, PKCS12_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4,
+			NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
+		 	NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC, 
+			NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC,
+			NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC,
+			NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+
+#ifndef OPENSSL_NO_HMAC
+	{EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen},
+#endif
+	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC,
+			NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC,
+			NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC,
+			NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen},
+
+
+	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0},
+	{EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0},
+	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0},
+	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0},
+	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0},
+	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0},
+	{EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0},
+	};
+
+#ifdef TEST
+int main(int argc, char **argv)
+	{
+	int i, nid_md, nid_cipher;
+	EVP_PBE_CTL *tpbe, *tpbe2;
+	/*OpenSSL_add_all_algorithms();*/
+
+	for (i = 0; i < sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL); i++)
+		{
+		tpbe = builtin_pbe + i;
+		fprintf(stderr, "%d %d %s ", tpbe->pbe_type, tpbe->pbe_nid,
+						OBJ_nid2sn(tpbe->pbe_nid));
+		if (EVP_PBE_find(tpbe->pbe_type, tpbe->pbe_nid,
+					&nid_cipher ,&nid_md,0))
+			fprintf(stderr, "Found %s %s\n",
+					OBJ_nid2sn(nid_cipher),
+					OBJ_nid2sn(nid_md));
+		else
+			fprintf(stderr, "Find ERROR!!\n");
+		}
+
+	return 0;
+	}
+#endif
+		
+
 
 int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
-	     ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
-{
+		       ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
+	{
+	const EVP_CIPHER *cipher;
+	const EVP_MD *md;
+	int cipher_nid, md_nid;
+	EVP_PBE_KEYGEN *keygen;
 
-	EVP_PBE_CTL *pbetmp, pbelu;
-	int i;
-	pbelu.pbe_nid = OBJ_obj2nid(pbe_obj);
-	if (pbelu.pbe_nid != NID_undef) i = sk_find(pbe_algs, (char *)&pbelu);
-	else i = -1;
-
-	if (i == -1) {
+	if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj),
+					&cipher_nid, &md_nid, &keygen))
+		{
 		char obj_tmp[80];
 		EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_PBE_ALGORITHM);
 		if (!pbe_obj) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp);
 		else i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj);
 		ERR_add_error_data(2, "TYPE=", obj_tmp);
 		return 0;
-	}
-	if(!pass) passlen = 0;
-	else if (passlen == -1) passlen = strlen(pass);
-	pbetmp = (EVP_PBE_CTL *)sk_value (pbe_algs, i);
-	i = (*pbetmp->keygen)(ctx, pass, passlen, param, pbetmp->cipher,
-						 pbetmp->md, en_de);
-	if (!i) {
+		}
+
+	if(!pass)
+		passlen = 0;
+	else if (passlen == -1)
+		passlen = strlen(pass);
+
+	if (cipher_nid == -1)
+		cipher = NULL;
+	else
+		{
+		cipher = EVP_get_cipherbynid(cipher_nid);
+		if (!cipher)
+			{
+			EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_CIPHER);
+			return 0;
+			}
+		}
+
+	if (md_nid == -1)
+		md = NULL;
+	else
+		{
+		md = EVP_get_digestbynid(md_nid);
+		if (!md)
+			{
+			EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_DIGEST);
+			return 0;
+			}
+		}
+
+	if (!keygen(ctx, pass, passlen, param, cipher, md, en_de))
+		{
 		EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_KEYGEN_FAILURE);
 		return 0;
-	}
+		}
 	return 1;	
 }
 
-static int pbe_cmp(const char * const *a, const char * const *b)
-{
-	const EVP_PBE_CTL * const *pbe1 = (const EVP_PBE_CTL * const *) a,
-			* const *pbe2 = (const EVP_PBE_CTL * const *)b;
-	return ((*pbe1)->pbe_nid - (*pbe2)->pbe_nid);
-}
+DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
+
+static int pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2)
+	{
+	int ret = pbe1->pbe_type - pbe2->pbe_type;
+	if (ret)
+		return ret;
+	else
+		return pbe1->pbe_nid - pbe2->pbe_nid;
+	}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
+
+static int pbe_cmp(const EVP_PBE_CTL * const *a, const EVP_PBE_CTL * const *b)
+	{
+	int ret = (*a)->pbe_type - (*b)->pbe_type;
+	if (ret)
+		return ret;
+	else
+		return (*a)->pbe_nid - (*b)->pbe_nid;
+	}
 
 /* Add a PBE algorithm */
 
-int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
-	     EVP_PBE_KEYGEN *keygen)
-{
+int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid,
+			 EVP_PBE_KEYGEN *keygen)
+	{
 	EVP_PBE_CTL *pbe_tmp;
-	if (!pbe_algs) pbe_algs = sk_new(pbe_cmp);
-	if (!(pbe_tmp = (EVP_PBE_CTL*) OPENSSL_malloc (sizeof(EVP_PBE_CTL)))) {
-		EVPerr(EVP_F_EVP_PBE_ALG_ADD,ERR_R_MALLOC_FAILURE);
+	if (!pbe_algs)
+		pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp);
+	if (!(pbe_tmp = (EVP_PBE_CTL*) OPENSSL_malloc (sizeof(EVP_PBE_CTL))))
+		{
+		EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE,ERR_R_MALLOC_FAILURE);
 		return 0;
-	}
-	pbe_tmp->pbe_nid = nid;
-	pbe_tmp->cipher = cipher;
-	pbe_tmp->md = md;
+		}
+	pbe_tmp->pbe_type = pbe_type;
+	pbe_tmp->pbe_nid = pbe_nid;
+	pbe_tmp->cipher_nid = cipher_nid;
+	pbe_tmp->md_nid = md_nid;
 	pbe_tmp->keygen = keygen;
-	sk_push (pbe_algs, (char *)pbe_tmp);
+
+
+	sk_EVP_PBE_CTL_push (pbe_algs, pbe_tmp);
 	return 1;
-}
+	}
+
+int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
+		    EVP_PBE_KEYGEN *keygen)
+	{
+	int cipher_nid, md_nid;
+	if (cipher)
+		cipher_nid = EVP_CIPHER_type(cipher);
+	else
+		cipher_nid = -1;
+	if (md)
+		md_nid = EVP_MD_type(md);
+	else
+		md_nid = -1;
+
+	return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid,
+					cipher_nid, md_nid, keygen);
+	}
+
+int EVP_PBE_find(int type, int pbe_nid,
+		 int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen)
+	{
+	EVP_PBE_CTL *pbetmp = NULL, pbelu;
+	int i;
+	if (pbe_nid == NID_undef)
+		return 0;
+
+	pbelu.pbe_type = type;
+	pbelu.pbe_nid = pbe_nid;
+
+	if (pbe_algs)
+		{
+		i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu);
+		if (i != -1)
+			pbetmp = sk_EVP_PBE_CTL_value (pbe_algs, i);
+		}
+	if (pbetmp == NULL)
+		{
+		pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe,
+				     sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL));
+		}
+	if (pbetmp == NULL)
+		return 0;
+	if (pcnid)
+		*pcnid = pbetmp->cipher_nid;
+	if (pmnid)
+		*pmnid = pbetmp->md_nid;
+	if (pkeygen)
+		*pkeygen = pbetmp->keygen;
+	return 1;
+	}
+
+static void free_evp_pbe_ctl(EVP_PBE_CTL *pbe)
+	 {
+	 OPENSSL_freeFunc(pbe);
+	 }
 
 void EVP_PBE_cleanup(void)
-{
-	sk_pop_free(pbe_algs, OPENSSL_freeFunc);
+	{
+	sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl);
 	pbe_algs = NULL;
-}
+	}
diff --git a/crypto/evp/evp_pkey.c b/crypto/evp/evp_pkey.c
index 10d9e9e..ceebf69 100644
--- a/crypto/evp/evp_pkey.c
+++ b/crypto/evp/evp_pkey.c
@@ -3,7 +3,7 @@
  * project 1999.
  */
 /* ====================================================================
- * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
@@ -61,287 +61,52 @@
 #include "cryptlib.h"
 #include <openssl/x509.h>
 #include <openssl/rand.h>
-#ifndef OPENSSL_NO_RSA
-#include <openssl/rsa.h>
-#endif
-#ifndef OPENSSL_NO_DSA
-#include <openssl/dsa.h>
-#endif
-#include <openssl/bn.h>
-
-#ifndef OPENSSL_NO_DSA
-static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8inf, EVP_PKEY *pkey);
-#endif
-#ifndef OPENSSL_NO_EC
-static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8inf, EVP_PKEY *pkey);
-#endif
+#include "asn1_locl.h"
 
 /* Extract a private key from a PKCS8 structure */
 
 EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
 {
 	EVP_PKEY *pkey = NULL;
-#ifndef OPENSSL_NO_RSA
-	RSA *rsa = NULL;
-#endif
-#ifndef OPENSSL_NO_DSA
-	DSA *dsa = NULL;
-	ASN1_TYPE *t1, *t2;
-	ASN1_INTEGER *privkey;
-	STACK_OF(ASN1_TYPE) *ndsa = NULL;
-#endif
-#ifndef OPENSSL_NO_EC
-	EC_KEY *eckey = NULL;
-	const unsigned char *p_tmp;
-#endif
-#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC)
-	ASN1_TYPE    *param = NULL;	
-	BN_CTX *ctx = NULL;
-	int plen;
-#endif
-	X509_ALGOR *a;
-	const unsigned char *p;
-	const unsigned char *cp;
-	int pkeylen;
-	int  nid;
+	ASN1_OBJECT *algoid;
 	char obj_tmp[80];
 
-	if(p8->pkey->type == V_ASN1_OCTET_STRING) {
-		p8->broken = PKCS8_OK;
-		p = p8->pkey->value.octet_string->data;
-		pkeylen = p8->pkey->value.octet_string->length;
-	} else {
-		p8->broken = PKCS8_NO_OCTET;
-		p = p8->pkey->value.sequence->data;
-		pkeylen = p8->pkey->value.sequence->length;
-	}
+	if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8))
+		return NULL;
+
 	if (!(pkey = EVP_PKEY_new())) {
 		EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
 		return NULL;
 	}
-	a = p8->pkeyalg;
-	nid = OBJ_obj2nid(a->algorithm);
-	switch(nid)
-	{
-#ifndef OPENSSL_NO_RSA
-		case NID_rsaEncryption:
-		cp = p;
-		if (!(rsa = d2i_RSAPrivateKey (NULL,&cp, pkeylen))) {
-			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
-			return NULL;
-		}
-		EVP_PKEY_assign_RSA (pkey, rsa);
-		break;
-#endif
-#ifndef OPENSSL_NO_DSA
-		case NID_dsa:
-		/* PKCS#8 DSA is weird: you just get a private key integer
-	         * and parameters in the AlgorithmIdentifier the pubkey must
-		 * be recalculated.
-		 */
-	
-		/* Check for broken DSA PKCS#8, UGH! */
-		if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) {
-		    if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pkeylen, 
-							  d2i_ASN1_TYPE,
-							  ASN1_TYPE_free))) {
-			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
-			goto dsaerr;
-		    }
-		    if(sk_ASN1_TYPE_num(ndsa) != 2 ) {
-			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
-			goto dsaerr;
-		    }
-		    /* Handle Two broken types:
-		     * SEQUENCE {parameters, priv_key}
-		     * SEQUENCE {pub_key, priv_key}
-		     */
 
-		    t1 = sk_ASN1_TYPE_value(ndsa, 0);
-		    t2 = sk_ASN1_TYPE_value(ndsa, 1);
-		    if(t1->type == V_ASN1_SEQUENCE) {
-			p8->broken = PKCS8_EMBEDDED_PARAM;
-			param = t1;
-		    } else if(a->parameter->type == V_ASN1_SEQUENCE) {
-			p8->broken = PKCS8_NS_DB;
-			param = a->parameter;
-		    } else {
-			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
-			goto dsaerr;
-		    }
-
-		    if(t2->type != V_ASN1_INTEGER) {
-			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
-			goto dsaerr;
-		    }
-		    privkey = t2->value.integer;
-		} else {
-			if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) {
-				EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
-				goto dsaerr;
-			}
-			param = p8->pkeyalg->parameter;
-		}
-		if (!param || (param->type != V_ASN1_SEQUENCE)) {
-			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
-			goto dsaerr;
-		}
-		cp = p = param->value.sequence->data;
-		plen = param->value.sequence->length;
-		if (!(dsa = d2i_DSAparams (NULL, &cp, plen))) {
-			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
-			goto dsaerr;
-		}
-		/* We have parameters now set private key */
-		if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {
-			EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR);
-			goto dsaerr;
-		}
-		/* Calculate public key (ouch!) */
-		if (!(dsa->pub_key = BN_new())) {
-			EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
-			goto dsaerr;
-		}
-		if (!(ctx = BN_CTX_new())) {
-			EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
-			goto dsaerr;
-		}
-			
-		if (!BN_mod_exp(dsa->pub_key, dsa->g,
-						 dsa->priv_key, dsa->p, ctx)) {
-			
-			EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR);
-			goto dsaerr;
-		}
-
-		EVP_PKEY_assign_DSA(pkey, dsa);
-		BN_CTX_free (ctx);
-		if(ndsa) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
-		else ASN1_INTEGER_free(privkey);
-		break;
-		dsaerr:
-		BN_CTX_free (ctx);
-		sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
-		DSA_free(dsa);
-		EVP_PKEY_free(pkey);
-		return NULL;
-		break;
-#endif
-#ifndef OPENSSL_NO_EC
-		case NID_X9_62_id_ecPublicKey:
-		p_tmp = p;
-		/* extract the ec parameters */
-		param = p8->pkeyalg->parameter;
-
-		if (!param || ((param->type != V_ASN1_SEQUENCE) &&
-		    (param->type != V_ASN1_OBJECT)))
+	if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid)))
 		{
-			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
-			goto ecerr;
-		}
-
-		if (param->type == V_ASN1_SEQUENCE)
-		{
-			cp = p = param->value.sequence->data;
-			plen = param->value.sequence->length;
-
-			if (!(eckey = d2i_ECParameters(NULL, &cp, plen)))
-			{
-				EVPerr(EVP_F_EVP_PKCS82PKEY,
-					EVP_R_DECODE_ERROR);
-				goto ecerr;
-			}
-		}
-		else
-		{
-			EC_GROUP *group;
-			cp = p = param->value.object->data;
-			plen = param->value.object->length;
-
-			/* type == V_ASN1_OBJECT => the parameters are given
-			 * by an asn1 OID
-			 */
-			if ((eckey = EC_KEY_new()) == NULL)
-			{
-				EVPerr(EVP_F_EVP_PKCS82PKEY,
-					ERR_R_MALLOC_FAILURE);
-				goto ecerr;
-			}
-			group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object));
-			if (group == NULL)
-				goto ecerr;
-			EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
-			if (EC_KEY_set_group(eckey, group) == 0)
-				goto ecerr;
-			EC_GROUP_free(group);
-		}
-
-		/* We have parameters now set private key */
-		if (!d2i_ECPrivateKey(&eckey, &p_tmp, pkeylen))
-		{
-			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
-			goto ecerr;
-		}
-
-		/* calculate public key (if necessary) */
-		if (EC_KEY_get0_public_key(eckey) == NULL)
-		{
-			const BIGNUM *priv_key;
-			const EC_GROUP *group;
-			EC_POINT *pub_key;
-			/* the public key was not included in the SEC1 private
-			 * key => calculate the public key */
-			group   = EC_KEY_get0_group(eckey);
-			pub_key = EC_POINT_new(group);
-			if (pub_key == NULL)
-			{
-				EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
-				goto ecerr;
-			}
-			if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group)))
-			{
-				EC_POINT_free(pub_key);
-				EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
-				goto ecerr;
-			}
-			priv_key = EC_KEY_get0_private_key(eckey);
-			if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
-			{
-				EC_POINT_free(pub_key);
-				EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
-				goto ecerr;
-			}
-			if (EC_KEY_set_public_key(eckey, pub_key) == 0)
-			{
-				EC_POINT_free(pub_key);
-				EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
-				goto ecerr;
-			}
-			EC_POINT_free(pub_key);
-		}
-
-		EVP_PKEY_assign_EC_KEY(pkey, eckey);
-		if (ctx)
-			BN_CTX_free(ctx);
-		break;
-ecerr:
-		if (ctx)
-			BN_CTX_free(ctx);
-		if (eckey)
-			EC_KEY_free(eckey);
-		if (pkey)
-			EVP_PKEY_free(pkey);
-		return NULL;
-#endif
-		default:
 		EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
-		if (!a->algorithm) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp);
-		else i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm);
+		i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
 		ERR_add_error_data(2, "TYPE=", obj_tmp);
-		EVP_PKEY_free (pkey);
-		return NULL;
-	}
+		goto error;
+		}
+
+	if (pkey->ameth->priv_decode)
+		{
+		if (!pkey->ameth->priv_decode(pkey, p8))
+			{
+			EVPerr(EVP_F_EVP_PKCS82PKEY,
+					EVP_R_PRIVATE_KEY_DECODE_ERROR);
+			goto error;
+			}
+		}
+	else
+		{
+		EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED);
+		goto error;
+		}
+
 	return pkey;
+
+	error:
+	EVP_PKEY_free (pkey);
+	return NULL;
 }
 
 PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
@@ -360,59 +125,37 @@
 		return NULL;
 	}
 	p8->broken = broken;
-	if (!ASN1_INTEGER_set(p8->version, 0)) {
-		EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
-		PKCS8_PRIV_KEY_INFO_free (p8);
-		return NULL;
-	}
-	if (!(p8->pkeyalg->parameter = ASN1_TYPE_new ())) {
-		EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
-		PKCS8_PRIV_KEY_INFO_free (p8);
-		return NULL;
-	}
-	p8->pkey->type = V_ASN1_OCTET_STRING;
-	switch (EVP_PKEY_type(pkey->type)) {
-#ifndef OPENSSL_NO_RSA
-		case EVP_PKEY_RSA:
 
-		if(p8->broken == PKCS8_NO_OCTET) p8->pkey->type = V_ASN1_SEQUENCE;
-
-		p8->pkeyalg->algorithm = OBJ_nid2obj(NID_rsaEncryption);
-		p8->pkeyalg->parameter->type = V_ASN1_NULL;
-		if (!ASN1_pack_string_of (EVP_PKEY,pkey, i2d_PrivateKey,
-					 &p8->pkey->value.octet_string)) {
-			EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
-			PKCS8_PRIV_KEY_INFO_free (p8);
-			return NULL;
-		}
-		break;
-#endif
-#ifndef OPENSSL_NO_DSA
-		case EVP_PKEY_DSA:
-		if(!dsa_pkey2pkcs8(p8, pkey)) {
-			PKCS8_PRIV_KEY_INFO_free (p8);
-			return NULL;
-		}
-
-		break;
-#endif
-#ifndef OPENSSL_NO_EC
-		case EVP_PKEY_EC:
-		if (!eckey_pkey2pkcs8(p8, pkey))
+	if (pkey->ameth)
 		{
-			PKCS8_PRIV_KEY_INFO_free(p8);
-			return(NULL);
+		if (pkey->ameth->priv_encode)
+			{
+			if (!pkey->ameth->priv_encode(p8, pkey))
+				{
+				EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
+					EVP_R_PRIVATE_KEY_ENCODE_ERROR);
+				goto error;
+				}
+			}
+		else
+			{
+			EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
+					EVP_R_METHOD_NOT_SUPPORTED);
+			goto error;
+			}
 		}
-		break;
-#endif
-		default:
-		EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
-		PKCS8_PRIV_KEY_INFO_free (p8);
-		return NULL;
-	}
+	else
+		{
+		EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
+				EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
+		goto error;
+		}
 	RAND_add(p8->pkey->value.octet_string->data,
 		 p8->pkey->value.octet_string->length, 0.0);
 	return p8;
+	error:
+	PKCS8_PRIV_KEY_INFO_free(p8);
+	return NULL;
 }
 
 PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
@@ -436,301 +179,6 @@
 	}
 }
 
-#ifndef OPENSSL_NO_DSA
-static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
-{
-	ASN1_STRING *params = NULL;
-	ASN1_INTEGER *prkey = NULL;
-	ASN1_TYPE *ttmp = NULL;
-	STACK_OF(ASN1_TYPE) *ndsa = NULL;
-	unsigned char *p = NULL, *q;
-	int len;
-
-	p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa);
-	len = i2d_DSAparams (pkey->pkey.dsa, NULL);
-	if (!(p = OPENSSL_malloc(len))) {
-		EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-		goto err;
-	}
-	q = p;
-	i2d_DSAparams (pkey->pkey.dsa, &q);
-	if (!(params = ASN1_STRING_new())) {
-		EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-		goto err;
-	}
-	if (!ASN1_STRING_set(params, p, len)) {
-		EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-		goto err;
-	}
-	OPENSSL_free(p);
-	p = NULL;
-	/* Get private key into integer */
-	if (!(prkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) {
-		EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
-		goto err;
-	}
-
-	switch(p8->broken) {
-
-		case PKCS8_OK:
-		case PKCS8_NO_OCTET:
-
-		if (!ASN1_pack_string_of(ASN1_INTEGER,prkey, i2d_ASN1_INTEGER,
-					 &p8->pkey->value.octet_string)) {
-			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-
-		M_ASN1_INTEGER_free (prkey);
-		prkey = NULL;
-		p8->pkeyalg->parameter->value.sequence = params;
-		params = NULL;
-		p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
-
-		break;
-
-		case PKCS8_NS_DB:
-
-		p8->pkeyalg->parameter->value.sequence = params;
-		params = NULL;
-		p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
-		if (!(ndsa = sk_ASN1_TYPE_new_null())) {
-			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-		if (!(ttmp = ASN1_TYPE_new())) {
-			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-		if (!(ttmp->value.integer =
-			BN_to_ASN1_INTEGER(pkey->pkey.dsa->pub_key, NULL))) {
-			EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
-			goto err;
-		}
-		ttmp->type = V_ASN1_INTEGER;
-		if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
-			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-
-		if (!(ttmp = ASN1_TYPE_new())) {
-			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-		ttmp->value.integer = prkey;
-		prkey = NULL;
-		ttmp->type = V_ASN1_INTEGER;
-		if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
-			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-		ttmp = NULL;
-
-		if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
-			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-
-		if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
-					 &p8->pkey->value.octet_string->data,
-					 &p8->pkey->value.octet_string->length)) {
-
-			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-		sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
-		break;
-
-		case PKCS8_EMBEDDED_PARAM:
-
-		p8->pkeyalg->parameter->type = V_ASN1_NULL;
-		if (!(ndsa = sk_ASN1_TYPE_new_null())) {
-			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-		if (!(ttmp = ASN1_TYPE_new())) {
-			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-		ttmp->value.sequence = params;
-		params = NULL;
-		ttmp->type = V_ASN1_SEQUENCE;
-		if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
-			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-
-		if (!(ttmp = ASN1_TYPE_new())) {
-			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-		ttmp->value.integer = prkey;
-		prkey = NULL;
-		ttmp->type = V_ASN1_INTEGER;
-		if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
-			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-		ttmp = NULL;
-
-		if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
-			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-
-		if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
-					 &p8->pkey->value.octet_string->data,
-					 &p8->pkey->value.octet_string->length)) {
-
-			EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
-			goto err;
-		}
-		sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
-		break;
-	}
-	return 1;
-err:
-	if (p != NULL) OPENSSL_free(p);
-	if (params != NULL) ASN1_STRING_free(params);
-	if (prkey != NULL) M_ASN1_INTEGER_free(prkey);
-	if (ttmp != NULL) ASN1_TYPE_free(ttmp);
-	if (ndsa != NULL) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
-	return 0;
-}
-#endif
-
-#ifndef OPENSSL_NO_EC
-static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
-{
-	EC_KEY		*ec_key;
-	const EC_GROUP  *group;
-	unsigned char	*p, *pp;
-	int 		nid, i, ret = 0;
-	unsigned int    tmp_flags, old_flags;
-
-	ec_key = pkey->pkey.ec;
-	if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) 
-	{
-		EVPerr(EVP_F_ECKEY_PKEY2PKCS8, EVP_R_MISSING_PARAMETERS);
-		return 0;
-	}
-
-	/* set the ec parameters OID */
-	if (p8->pkeyalg->algorithm)
-		ASN1_OBJECT_free(p8->pkeyalg->algorithm);
-
-	p8->pkeyalg->algorithm = OBJ_nid2obj(NID_X9_62_id_ecPublicKey);
-
-	/* set the ec parameters */
-
-	if (p8->pkeyalg->parameter)
-	{
-		ASN1_TYPE_free(p8->pkeyalg->parameter);
-		p8->pkeyalg->parameter = NULL;
-	}
-
-	if ((p8->pkeyalg->parameter = ASN1_TYPE_new()) == NULL)
-	{
-		EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
-		return 0;
-	}
-	
-	if (EC_GROUP_get_asn1_flag(group)
-                     && (nid = EC_GROUP_get_curve_name(group)))
-	{
-		/* we have a 'named curve' => just set the OID */
-		p8->pkeyalg->parameter->type = V_ASN1_OBJECT;
-		p8->pkeyalg->parameter->value.object = OBJ_nid2obj(nid);
-	}
-	else	/* explicit parameters */
-	{
-		if ((i = i2d_ECParameters(ec_key, NULL)) == 0)
-		{
-			EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
-			return 0;
-		}
-		if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL)
-		{
-			EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
-			return 0;
-		}	
-		pp = p;
-		if (!i2d_ECParameters(ec_key, &pp))
-		{
-			EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
-			OPENSSL_free(p);
-			return 0;
-		}
-		p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
-		if ((p8->pkeyalg->parameter->value.sequence 
-			= ASN1_STRING_new()) == NULL)
-		{
-			EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_ASN1_LIB);
-			OPENSSL_free(p);
-			return 0;
-		}
-		ASN1_STRING_set(p8->pkeyalg->parameter->value.sequence, p, i);
-		OPENSSL_free(p);
-	}
-
-	/* set the private key */
-
-	/* do not include the parameters in the SEC1 private key
-	 * see PKCS#11 12.11 */
-	old_flags = EC_KEY_get_enc_flags(pkey->pkey.ec);
-	tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
-	EC_KEY_set_enc_flags(pkey->pkey.ec, tmp_flags);
-	i = i2d_ECPrivateKey(pkey->pkey.ec, NULL);
-	if (!i)
-	{
-		EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
-		EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
-		return 0;
-	}
-	p = (unsigned char *) OPENSSL_malloc(i);
-	if (!p)
-	{
-		EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
-		EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
-		return 0;
-	}
-	pp = p;
-	if (!i2d_ECPrivateKey(pkey->pkey.ec, &pp))
-	{
-		EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
-		EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
-		OPENSSL_free(p);
-		return 0;
-	}
-	/* restore old encoding flags */
-	EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
-
-	switch(p8->broken) {
-
-		case PKCS8_OK:
-		p8->pkey->value.octet_string = ASN1_OCTET_STRING_new();
-		if (!p8->pkey->value.octet_string ||
-		    !M_ASN1_OCTET_STRING_set(p8->pkey->value.octet_string,
-		    (const void *)p, i))
-
-		{
-			EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
-		}
-		else
-			ret = 1;
-		break;
-		case PKCS8_NO_OCTET:		/* RSA specific */
-		case PKCS8_NS_DB:		/* DSA specific */
-		case PKCS8_EMBEDDED_PARAM:	/* DSA specific */
-		default:
-			EVPerr(EVP_F_ECKEY_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
-	}
-	OPENSSL_cleanse(p, (size_t)i);
-	OPENSSL_free(p);
-	return ret;
-}
-#endif
-
 /* EVP_PKEY attribute functions */
 
 int EVP_PKEY_get_attr_count(const EVP_PKEY *key)
diff --git a/crypto/evp/evp_test.c b/crypto/evp/evp_test.c
index 436be20..902efac 100644
--- a/crypto/evp/evp_test.c
+++ b/crypto/evp/evp_test.c
@@ -153,8 +153,8 @@
     
     if(kn != c->key_len)
 	{
-	fprintf(stderr,"Key length doesn't match, got %d expected %d\n",kn,
-		c->key_len);
+	fprintf(stderr,"Key length doesn't match, got %d expected %lu\n",kn,
+		(unsigned long)c->key_len);
 	test1_exit(5);
 	}
     EVP_CIPHER_CTX_init(&ctx);
@@ -441,7 +441,7 @@
 #endif
     EVP_cleanup();
     CRYPTO_cleanup_all_ex_data();
-    ERR_remove_state(0);
+    ERR_remove_thread_state(NULL);
     ERR_free_strings();
     CRYPTO_mem_leaks_fp(stderr);
 
diff --git a/crypto/evp/m_dss.c b/crypto/evp/m_dss.c
index 6b0c0aa..48c2689 100644
--- a/crypto/evp/m_dss.c
+++ b/crypto/evp/m_dss.c
@@ -81,7 +81,7 @@
 	NID_dsaWithSHA,
 	NID_dsaWithSHA,
 	SHA_DIGEST_LENGTH,
-	EVP_MD_FLAG_FIPS,
+	EVP_MD_FLAG_PKEY_DIGEST,
 	init,
 	update,
 	final,
diff --git a/crypto/evp/m_dss1.c b/crypto/evp/m_dss1.c
index da8babc..4f03fb7 100644
--- a/crypto/evp/m_dss1.c
+++ b/crypto/evp/m_dss1.c
@@ -68,8 +68,6 @@
 #include <openssl/dsa.h>
 #endif
 
-#ifndef OPENSSL_FIPS
-
 static int init(EVP_MD_CTX *ctx)
 	{ return SHA1_Init(ctx->md_data); }
 
@@ -84,7 +82,7 @@
 	NID_dsa,
 	NID_dsaWithSHA1,
 	SHA_DIGEST_LENGTH,
-	0,
+	EVP_MD_FLAG_PKEY_DIGEST,
 	init,
 	update,
 	final,
@@ -100,4 +98,3 @@
 	return(&dss1_md);
 	}
 #endif
-#endif
diff --git a/crypto/evp/m_ecdsa.c b/crypto/evp/m_ecdsa.c
index fad270f..8d87a49 100644
--- a/crypto/evp/m_ecdsa.c
+++ b/crypto/evp/m_ecdsa.c
@@ -130,7 +130,7 @@
 	NID_ecdsa_with_SHA1,
 	NID_ecdsa_with_SHA1,
 	SHA_DIGEST_LENGTH,
-	0,
+	EVP_MD_FLAG_PKEY_DIGEST,
 	init,
 	update,
 	final,
diff --git a/crypto/evp/m_md2.c b/crypto/evp/m_md2.c
index 8eee623..5ce849f 100644
--- a/crypto/evp/m_md2.c
+++ b/crypto/evp/m_md2.c
@@ -58,7 +58,6 @@
 
 #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 5cd2ab5..1e0b7c5 100644
--- a/crypto/evp/m_md4.c
+++ b/crypto/evp/m_md4.c
@@ -58,7 +58,6 @@
 
 #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 6455829..63c1421 100644
--- a/crypto/evp/m_md5.c
+++ b/crypto/evp/m_md5.c
@@ -62,7 +62,6 @@
 #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 9f9bcf0..b08d559 100644
--- a/crypto/evp/m_mdc2.c
+++ b/crypto/evp/m_mdc2.c
@@ -58,7 +58,6 @@
 
 #include <stdio.h>
 #include "cryptlib.h"
-#include "evp_locl.h"
 
 #ifndef OPENSSL_NO_MDC2
 
@@ -66,7 +65,9 @@
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 #include <openssl/mdc2.h>
+#ifndef OPENSSL_NO_RSA
 #include <openssl/rsa.h>
+#endif
 
 static int init(EVP_MD_CTX *ctx)
 	{ return MDC2_Init(ctx->md_data); }
diff --git a/crypto/evp/m_sha.c b/crypto/evp/m_sha.c
index 3f30dfc..acccc8f 100644
--- a/crypto/evp/m_sha.c
+++ b/crypto/evp/m_sha.c
@@ -58,7 +58,6 @@
 
 #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 471ec30..9a2790f 100644
--- a/crypto/evp/m_sha1.c
+++ b/crypto/evp/m_sha1.c
@@ -68,8 +68,6 @@
 #include <openssl/rsa.h>
 #endif
 
-#ifndef OPENSSL_FIPS
-
 static int init(EVP_MD_CTX *ctx)
 	{ return SHA1_Init(ctx->md_data); }
 
@@ -84,7 +82,7 @@
 	NID_sha1,
 	NID_sha1WithRSAEncryption,
 	SHA_DIGEST_LENGTH,
-	0,
+	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
 	init,
 	update,
 	final,
@@ -99,6 +97,7 @@
 	{
 	return(&sha1_md);
 	}
+#endif
 
 #ifndef OPENSSL_NO_SHA256
 static int init224(EVP_MD_CTX *ctx)
@@ -120,7 +119,7 @@
 	NID_sha224,
 	NID_sha224WithRSAEncryption,
 	SHA224_DIGEST_LENGTH,
-	0,
+	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
 	init224,
 	update256,
 	final256,
@@ -139,7 +138,7 @@
 	NID_sha256,
 	NID_sha256WithRSAEncryption,
 	SHA256_DIGEST_LENGTH,
-	0,
+	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
 	init256,
 	update256,
 	final256,
@@ -170,7 +169,7 @@
 	NID_sha384,
 	NID_sha384WithRSAEncryption,
 	SHA384_DIGEST_LENGTH,
-	0,
+	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
 	init384,
 	update512,
 	final512,
@@ -189,7 +188,7 @@
 	NID_sha512,
 	NID_sha512WithRSAEncryption,
 	SHA512_DIGEST_LENGTH,
-	0,
+	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
 	init512,
 	update512,
 	final512,
@@ -203,7 +202,3 @@
 const EVP_MD *EVP_sha512(void)
 	{ return(&sha512_md); }
 #endif	/* ifndef OPENSSL_NO_SHA512 */
-
-#endif
-
-#endif
diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c
new file mode 100644
index 0000000..f0b7f95
--- /dev/null
+++ b/crypto/evp/m_sigver.c
@@ -0,0 +1,200 @@
+/* m_sigver.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006,2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include "evp_locl.h"
+
+static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+			  const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey,
+			  int ver)
+	{
+	if (ctx->pctx == NULL)
+		ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
+	if (ctx->pctx == NULL)
+		return 0;
+
+	if (type == NULL)
+		{
+		int def_nid;
+		if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
+			type = EVP_get_digestbynid(def_nid);
+		}
+
+	if (type == NULL)
+		{
+		EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST);
+		return 0;
+		}
+
+	if (ver)
+		{
+		if (ctx->pctx->pmeth->verifyctx_init)
+			{
+			if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <=0)
+				return 0;
+			ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
+			}
+		else if (EVP_PKEY_verify_init(ctx->pctx) <= 0)
+			return 0;
+		}
+	else
+		{
+		if (ctx->pctx->pmeth->signctx_init)
+			{
+			if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0)
+				return 0;
+			ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
+			}
+		else if (EVP_PKEY_sign_init(ctx->pctx) <= 0)
+			return 0;
+		}
+	if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
+		return 0;
+	if (pctx)
+		*pctx = ctx->pctx;
+	if (!EVP_DigestInit_ex(ctx, type, e))
+		return 0;
+	return 1;
+	}
+
+int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
+	{
+	return do_sigver_init(ctx, pctx, type, e, pkey, 0);
+	}
+
+int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
+	{
+	return do_sigver_init(ctx, pctx, type, e, pkey, 1);
+	}
+
+int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen)
+	{
+	int sctx, r = 0;
+	if (ctx->pctx->pmeth->signctx)
+		sctx = 1;
+	else
+		sctx = 0;
+	if (sigret)
+		{
+		MS_STATIC EVP_MD_CTX tmp_ctx;
+		unsigned char md[EVP_MAX_MD_SIZE];
+		unsigned int mdlen;
+		EVP_MD_CTX_init(&tmp_ctx);
+		if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
+		     	return 0;
+		if (sctx)
+			r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx,
+					sigret, siglen, &tmp_ctx);
+		else
+			r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen);
+		EVP_MD_CTX_cleanup(&tmp_ctx);
+		if (sctx || !r)
+			return r;
+		if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0)
+			return 0;
+		}
+	else
+		{
+		if (sctx)
+			{
+			if (ctx->pctx->pmeth->signctx(ctx->pctx, sigret, siglen, ctx) <= 0)
+				return 0;
+			}
+		else
+			{
+			int s = EVP_MD_size(ctx->digest);
+			if (s < 0 || EVP_PKEY_sign(ctx->pctx, sigret, siglen, NULL, s) <= 0)
+				return 0;
+			}
+		}
+	return 1;
+	}
+
+int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen)
+	{
+	MS_STATIC EVP_MD_CTX tmp_ctx;
+	unsigned char md[EVP_MAX_MD_SIZE];
+	int r;
+	unsigned int mdlen;
+	int vctx;
+
+	if (ctx->pctx->pmeth->verifyctx)
+		vctx = 1;
+	else
+		vctx = 0;
+	EVP_MD_CTX_init(&tmp_ctx);
+	if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
+		return -1;	
+	if (vctx)
+		{
+		r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx,
+					sig, siglen, &tmp_ctx);
+		}
+	else
+		r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen);
+	EVP_MD_CTX_cleanup(&tmp_ctx);
+	if (vctx || !r)
+		return r;
+	return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen);
+	}
diff --git a/crypto/evp/m_wp.c b/crypto/evp/m_wp.c
new file mode 100644
index 0000000..1ce47c0
--- /dev/null
+++ b/crypto/evp/m_wp.c
@@ -0,0 +1,42 @@
+/* crypto/evp/m_wp.c */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_WHIRLPOOL
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/whrlpool.h>
+
+static int init(EVP_MD_CTX *ctx)
+	{ return WHIRLPOOL_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{ return WHIRLPOOL_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+	{ return WHIRLPOOL_Final(md,ctx->md_data); }
+
+static const EVP_MD whirlpool_md=
+	{
+	NID_whirlpool,
+	0,
+	WHIRLPOOL_DIGEST_LENGTH,
+	0,
+	init,
+	update,
+	final,
+	NULL,
+	NULL,
+	EVP_PKEY_NULL_method,
+	WHIRLPOOL_BBLOCK/8,
+	sizeof(EVP_MD *)+sizeof(WHIRLPOOL_CTX),
+	};
+
+const EVP_MD *EVP_whirlpool(void)
+	{
+	return(&whirlpool_md);
+	}
+#endif
diff --git a/crypto/evp/names.c b/crypto/evp/names.c
index e2e04c3..f2869f5 100644
--- a/crypto/evp/names.c
+++ b/crypto/evp/names.c
@@ -66,35 +66,32 @@
 	{
 	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);
+	check_defer(c->nid);
 	r=OBJ_NAME_add(OBJ_nid2ln(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c);
 	return(r);
 	}
 
+
 int EVP_add_digest(const EVP_MD *md)
 	{
 	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);
+	check_defer(md->type);
 	r=OBJ_NAME_add(OBJ_nid2ln(md->type),OBJ_NAME_TYPE_MD_METH,(const char *)md);
 	if (r == 0) return(0);
 
-	if (md->type != md->pkey_type)
+	if (md->pkey_type && md->type != md->pkey_type)
 		{
 		r=OBJ_NAME_add(OBJ_nid2sn(md->pkey_type),
 			OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name);
 		if (r == 0) return(0);
+		check_defer(md->pkey_type);
 		r=OBJ_NAME_add(OBJ_nid2ln(md->pkey_type),
 			OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name);
 		}
@@ -127,4 +124,78 @@
 	OBJ_NAME_cleanup(-1);
 
 	EVP_PBE_cleanup();
+	if (obj_cleanup_defer == 2)
+		{
+		obj_cleanup_defer = 0;
+		OBJ_cleanup();
+		}
+	OBJ_sigid_free();
+	}
+
+struct doall_cipher
+	{
+	void *arg;
+	void (*fn)(const EVP_CIPHER *ciph,
+			const char *from, const char *to, void *arg);
+	};
+
+static void do_all_cipher_fn(const OBJ_NAME *nm, void *arg)
+	{
+	struct doall_cipher *dc = arg;
+	if (nm->alias)
+		dc->fn(NULL, nm->name, nm->data, dc->arg);
+	else
+		dc->fn((const EVP_CIPHER *)nm->data, nm->name, NULL, dc->arg);
+	}
+
+void EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph,
+		const char *from, const char *to, void *x), void *arg)
+	{
+	struct doall_cipher dc;
+	dc.fn = fn;
+	dc.arg = arg;
+	OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc);
+	}
+
+void EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph,
+		const char *from, const char *to, void *x), void *arg)
+	{
+	struct doall_cipher dc;
+	dc.fn = fn;
+	dc.arg = arg;
+	OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn,&dc);
+	}
+
+struct doall_md
+	{
+	void *arg;
+	void (*fn)(const EVP_MD *ciph,
+			const char *from, const char *to, void *arg);
+	};
+
+static void do_all_md_fn(const OBJ_NAME *nm, void *arg)
+	{
+	struct doall_md *dc = arg;
+	if (nm->alias)
+		dc->fn(NULL, nm->name, nm->data, dc->arg);
+	else
+		dc->fn((const EVP_MD *)nm->data, nm->name, NULL, dc->arg);
+	}
+
+void EVP_MD_do_all(void (*fn)(const EVP_MD *md,
+		const char *from, const char *to, void *x), void *arg)
+	{
+	struct doall_md dc;
+	dc.fn = fn;
+	dc.arg = arg;
+	OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
+	}
+
+void EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *md,
+		const char *from, const char *to, void *x), void *arg)
+	{
+	struct doall_md dc;
+	dc.fn = fn;
+	dc.arg = arg;
+	OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
 	}
diff --git a/crypto/evp/p5_crpt.c b/crypto/evp/p5_crpt.c
index 2a265fd..7ecfa8d 100644
--- a/crypto/evp/p5_crpt.c
+++ b/crypto/evp/p5_crpt.c
@@ -62,42 +62,11 @@
 #include <openssl/x509.h>
 #include <openssl/evp.h>
 
-/* PKCS#5 v1.5 compatible PBE functions: see PKCS#5 v2.0 for more info.
+/* Doesn't do anything now: Builtin PBE algorithms in static table.
  */
 
 void PKCS5_PBE_add(void)
 {
-#ifndef OPENSSL_NO_DES
-#  ifndef OPENSSL_NO_MD5
-EVP_PBE_alg_add(NID_pbeWithMD5AndDES_CBC, EVP_des_cbc(), EVP_md5(),
-							 PKCS5_PBE_keyivgen);
-#  endif
-#  ifndef OPENSSL_NO_MD2
-EVP_PBE_alg_add(NID_pbeWithMD2AndDES_CBC, EVP_des_cbc(), EVP_md2(),
-							 PKCS5_PBE_keyivgen);
-#  endif
-#  ifndef OPENSSL_NO_SHA
-EVP_PBE_alg_add(NID_pbeWithSHA1AndDES_CBC, EVP_des_cbc(), EVP_sha1(),
-							 PKCS5_PBE_keyivgen);
-#  endif
-#endif
-#ifndef OPENSSL_NO_RC2
-#  ifndef OPENSSL_NO_MD5
-EVP_PBE_alg_add(NID_pbeWithMD5AndRC2_CBC, EVP_rc2_64_cbc(), EVP_md5(),
-							 PKCS5_PBE_keyivgen);
-#  endif
-#  ifndef OPENSSL_NO_MD2
-EVP_PBE_alg_add(NID_pbeWithMD2AndRC2_CBC, EVP_rc2_64_cbc(), EVP_md2(),
-							 PKCS5_PBE_keyivgen);
-#  endif
-#  ifndef OPENSSL_NO_SHA
-EVP_PBE_alg_add(NID_pbeWithSHA1AndRC2_CBC, EVP_rc2_64_cbc(), EVP_sha1(),
-							 PKCS5_PBE_keyivgen);
-#  endif
-#endif
-#ifndef OPENSSL_NO_HMAC
-EVP_PBE_alg_add(NID_pbes2, NULL, NULL, PKCS5_v2_PBE_keyivgen);
-#endif
 }
 
 int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
@@ -112,6 +81,7 @@
 	int saltlen, iter;
 	unsigned char *salt;
 	const unsigned char *pbuf;
+	int mdsize;
 
 	/* Extract useful info from parameter */
 	if (param == NULL || param->type != V_ASN1_SEQUENCE ||
@@ -140,9 +110,12 @@
 	EVP_DigestUpdate(&ctx, salt, saltlen);
 	PBEPARAM_free(pbe);
 	EVP_DigestFinal_ex(&ctx, md_tmp, NULL);
+	mdsize = EVP_MD_size(md);
+	if (mdsize < 0)
+	    return 0;
 	for (i = 1; i < iter; i++) {
 		EVP_DigestInit_ex(&ctx, md, NULL);
-		EVP_DigestUpdate(&ctx, md_tmp, EVP_MD_size(md));
+		EVP_DigestUpdate(&ctx, md_tmp, mdsize);
 		EVP_DigestFinal_ex (&ctx, md_tmp, NULL);
 	}
 	EVP_MD_CTX_cleanup(&ctx);
diff --git a/crypto/evp/p5_crpt2.c b/crypto/evp/p5_crpt2.c
index 6bec77b..334379f 100644
--- a/crypto/evp/p5_crpt2.c
+++ b/crypto/evp/p5_crpt2.c
@@ -3,7 +3,7 @@
  * project 1999.
  */
 /* ====================================================================
- * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
@@ -71,28 +71,38 @@
 #endif
 
 /* This is an implementation of PKCS#5 v2.0 password based encryption key
- * derivation function PBKDF2 using the only currently defined function HMAC
- * with SHA1. Verified against test vectors posted by Peter Gutmann
+ * derivation function PBKDF2.
+ * SHA1 version verified against test vectors posted by Peter Gutmann
  * <pgut001@cs.auckland.ac.nz> to the PKCS-TNG <pkcs-tng@rsa.com> mailing list.
  */
 
-int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
+int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
 			   const unsigned char *salt, int saltlen, int iter,
+			   const EVP_MD *digest,
 			   int keylen, unsigned char *out)
-{
-	unsigned char digtmp[SHA_DIGEST_LENGTH], *p, itmp[4];
-	int cplen, j, k, tkeylen;
+	{
+	unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
+	int cplen, j, k, tkeylen, mdlen;
 	unsigned long i = 1;
 	HMAC_CTX hctx;
 
+	mdlen = EVP_MD_size(digest);
+	if (mdlen < 0)
+		return 0;
+
 	HMAC_CTX_init(&hctx);
 	p = out;
 	tkeylen = keylen;
-	if(!pass) passlen = 0;
-	else if(passlen == -1) passlen = strlen(pass);
-	while(tkeylen) {
-		if(tkeylen > SHA_DIGEST_LENGTH) cplen = SHA_DIGEST_LENGTH;
-		else cplen = tkeylen;
+	if(!pass)
+		passlen = 0;
+	else if(passlen == -1)
+		passlen = strlen(pass);
+	while(tkeylen)
+		{
+		if(tkeylen > mdlen)
+			cplen = mdlen;
+		else
+			cplen = tkeylen;
 		/* We are unlikely to ever use more than 256 blocks (5120 bits!)
 		 * but just in case...
 		 */
@@ -100,20 +110,22 @@
 		itmp[1] = (unsigned char)((i >> 16) & 0xff);
 		itmp[2] = (unsigned char)((i >> 8) & 0xff);
 		itmp[3] = (unsigned char)(i & 0xff);
-		HMAC_Init_ex(&hctx, pass, passlen, EVP_sha1(), NULL);
+		HMAC_Init_ex(&hctx, pass, passlen, digest, NULL);
 		HMAC_Update(&hctx, salt, saltlen);
 		HMAC_Update(&hctx, itmp, 4);
 		HMAC_Final(&hctx, digtmp, NULL);
 		memcpy(p, digtmp, cplen);
-		for(j = 1; j < iter; j++) {
-			HMAC(EVP_sha1(), pass, passlen,
-				 digtmp, SHA_DIGEST_LENGTH, digtmp, NULL);
-			for(k = 0; k < cplen; k++) p[k] ^= digtmp[k];
-		}
+		for(j = 1; j < iter; j++)
+			{
+			HMAC(digest, pass, passlen,
+				 digtmp, mdlen, digtmp, NULL);
+			for(k = 0; k < cplen; k++)
+				p[k] ^= digtmp[k];
+			}
 		tkeylen-= cplen;
 		i++;
 		p+= cplen;
-	}
+		}
 	HMAC_CTX_cleanup(&hctx);
 #ifdef DEBUG_PKCS5V2
 	fprintf(stderr, "Password:\n");
@@ -125,7 +137,15 @@
 	h__dump (out, keylen);
 #endif
 	return 1;
-}
+	}
+
+int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
+			   const unsigned char *salt, int saltlen, int iter,
+			   int keylen, unsigned char *out)
+	{
+	return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(),
+					keylen, out);
+	}
 
 #ifdef DO_TEST
 main()
@@ -155,6 +175,8 @@
 	PBE2PARAM *pbe2 = NULL;
 	const EVP_CIPHER *cipher;
 	PBKDF2PARAM *kdf = NULL;
+	const EVP_MD *prfmd;
+	int prf_nid, hmac_md_nid;
 
 	if (param == NULL || param->type != V_ASN1_SEQUENCE ||
 	    param->value.sequence == NULL) {
@@ -180,8 +202,7 @@
 	/* lets see if we recognise the encryption algorithm.
 	 */
 
-	cipher = EVP_get_cipherbyname(
-			OBJ_nid2sn(OBJ_obj2nid(pbe2->encryption->algorithm)));
+	cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm);
 
 	if(!cipher) {
 		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
@@ -226,10 +247,23 @@
 		goto err;
 	}
 
-	if(kdf->prf && (OBJ_obj2nid(kdf->prf->algorithm) != NID_hmacWithSHA1)) {
+	if (kdf->prf)
+		prf_nid = OBJ_obj2nid(kdf->prf->algorithm);
+	else
+		prf_nid = NID_hmacWithSHA1;
+
+	if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0))
+		{
 		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
 		goto err;
-	}
+		}
+
+	prfmd = EVP_get_digestbynid(hmac_md_nid);
+	if (prfmd == NULL)
+		{
+		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
+		goto err;
+		}
 
 	if(kdf->salt->type != V_ASN1_OCTET_STRING) {
 		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
@@ -241,7 +275,9 @@
 	salt = kdf->salt->value.octet_string->data;
 	saltlen = kdf->salt->value.octet_string->length;
 	iter = ASN1_INTEGER_get(kdf->iter);
-	PKCS5_PBKDF2_HMAC_SHA1(pass, passlen, salt, saltlen, iter, keylen, key);
+	if(!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd,
+						   keylen, key))
+		goto err;
 	EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
 	OPENSSL_cleanse(key, keylen);
 	PBKDF2PARAM_free(kdf);
diff --git a/crypto/evp/p_dec.c b/crypto/evp/p_dec.c
index f64901f..4201dcb 100644
--- a/crypto/evp/p_dec.c
+++ b/crypto/evp/p_dec.c
@@ -66,7 +66,7 @@
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 
-int EVP_PKEY_decrypt(unsigned char *key, const unsigned char *ek, int ekl,
+int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl,
 	     EVP_PKEY *priv)
 	{
 	int ret= -1;
@@ -75,7 +75,7 @@
 	if (priv->type != EVP_PKEY_RSA)
 		{
 #endif
-		EVPerr(EVP_F_EVP_PKEY_DECRYPT,EVP_R_PUBLIC_KEY_NOT_RSA);
+		EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD,EVP_R_PUBLIC_KEY_NOT_RSA);
 #ifndef OPENSSL_NO_RSA
 		goto err;
                 }
diff --git a/crypto/evp/p_enc.c b/crypto/evp/p_enc.c
index c2dfdc5..b5a3a84 100644
--- a/crypto/evp/p_enc.c
+++ b/crypto/evp/p_enc.c
@@ -66,7 +66,7 @@
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 
-int EVP_PKEY_encrypt(unsigned char *ek, const unsigned char *key, int key_len,
+int EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key, int key_len,
 	     EVP_PKEY *pubk)
 	{
 	int ret=0;
@@ -75,7 +75,7 @@
 	if (pubk->type != EVP_PKEY_RSA)
 		{
 #endif
-		EVPerr(EVP_F_EVP_PKEY_ENCRYPT,EVP_R_PUBLIC_KEY_NOT_RSA);
+		EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD,EVP_R_PUBLIC_KEY_NOT_RSA);
 #ifndef OPENSSL_NO_RSA
 		goto err;
 		}
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index 22155ec..1916c61 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -74,66 +74,26 @@
 #include <openssl/dh.h>
 #endif
 
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+#include "asn1_locl.h"
+
 static void EVP_PKEY_free_it(EVP_PKEY *x);
 
 int EVP_PKEY_bits(EVP_PKEY *pkey)
 	{
-	if (0)
-		return 0;
-#ifndef OPENSSL_NO_RSA
-	else if (pkey->type == EVP_PKEY_RSA)
-		return(BN_num_bits(pkey->pkey.rsa->n));
-#endif
-#ifndef OPENSSL_NO_DSA
-	else if (pkey->type == EVP_PKEY_DSA)
-		return(BN_num_bits(pkey->pkey.dsa->p));
-#endif
-#ifndef OPENSSL_NO_EC
-	else if (pkey->type == EVP_PKEY_EC)
-		{
-		BIGNUM *order = BN_new();
-		const EC_GROUP *group;
-		int ret;
-
-		if (!order)
-			{
-			ERR_clear_error();
-			return 0;
-			}
-		group = EC_KEY_get0_group(pkey->pkey.ec);
-		if (!EC_GROUP_get_order(group, order, NULL))
-			{
-			ERR_clear_error();
-			return 0;
-			}
-
-		ret = BN_num_bits(order);
-		BN_free(order);
-		return ret;
-		}
-#endif
-	return(0);
+	if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
+		return pkey->ameth->pkey_bits(pkey);
+	return 0;
 	}
 
 int EVP_PKEY_size(EVP_PKEY *pkey)
 	{
-	if (pkey == NULL)
-		return(0);
-#ifndef OPENSSL_NO_RSA
-	if (pkey->type == EVP_PKEY_RSA)
-		return(RSA_size(pkey->pkey.rsa));
-	else
-#endif
-#ifndef OPENSSL_NO_DSA
-		if (pkey->type == EVP_PKEY_DSA)
-		return(DSA_size(pkey->pkey.dsa));
-#endif
-#ifndef OPENSSL_NO_ECDSA
-		if (pkey->type == EVP_PKEY_EC)
-		return(ECDSA_size(pkey->pkey.ec));
-#endif
-
-	return(0);
+	if (pkey && pkey->ameth && pkey->ameth->pkey_size)
+		return pkey->ameth->pkey_size(pkey);
+	return 0;
 	}
 
 int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
@@ -174,88 +134,26 @@
 		EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_MISSING_PARAMETERS);
 		goto err;
 		}
-#ifndef OPENSSL_NO_DSA
-	if (to->type == EVP_PKEY_DSA)
-		{
-		BIGNUM *a;
-
-		if ((a=BN_dup(from->pkey.dsa->p)) == NULL) goto err;
-		if (to->pkey.dsa->p != NULL) BN_free(to->pkey.dsa->p);
-		to->pkey.dsa->p=a;
-
-		if ((a=BN_dup(from->pkey.dsa->q)) == NULL) goto err;
-		if (to->pkey.dsa->q != NULL) BN_free(to->pkey.dsa->q);
-		to->pkey.dsa->q=a;
-
-		if ((a=BN_dup(from->pkey.dsa->g)) == NULL) goto err;
-		if (to->pkey.dsa->g != NULL) BN_free(to->pkey.dsa->g);
-		to->pkey.dsa->g=a;
-		}
-#endif
-#ifndef OPENSSL_NO_EC
-	if (to->type == EVP_PKEY_EC)
-		{
-		EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
-		if (group == NULL)
-			goto err;
-		if (EC_KEY_set_group(to->pkey.ec, group) == 0)
-			goto err;
-		EC_GROUP_free(group);
-		}
-#endif
-	return(1);
+	if (from->ameth && from->ameth->param_copy)
+		return from->ameth->param_copy(to, from);
 err:
-	return(0);
+	return 0;
 	}
 
 int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
 	{
-#ifndef OPENSSL_NO_DSA
-	if (pkey->type == EVP_PKEY_DSA)
-		{
-		DSA *dsa;
-
-		dsa=pkey->pkey.dsa;
-		if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
-			return(1);
-		}
-#endif
-#ifndef OPENSSL_NO_EC
-	if (pkey->type == EVP_PKEY_EC)
-		{
-		if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
-			return(1);
-		}
-#endif
-
-	return(0);
+	if (pkey->ameth && pkey->ameth->param_missing)
+		return pkey->ameth->param_missing(pkey);
+	return 0;
 	}
 
 int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
 	{
-#ifndef OPENSSL_NO_DSA
-	if ((a->type == EVP_PKEY_DSA) && (b->type == EVP_PKEY_DSA))
-		{
-		if (	BN_cmp(a->pkey.dsa->p,b->pkey.dsa->p) ||
-			BN_cmp(a->pkey.dsa->q,b->pkey.dsa->q) ||
-			BN_cmp(a->pkey.dsa->g,b->pkey.dsa->g))
-			return(0);
-		else
-			return(1);
-		}
-#endif
-#ifndef OPENSSL_NO_EC
-	if (a->type == EVP_PKEY_EC && b->type == EVP_PKEY_EC)
-		{
-		const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
-		               *group_b = EC_KEY_get0_group(b->pkey.ec);
-		if (EC_GROUP_cmp(group_a, group_b, NULL))
-			return 0;
-		else
-			return 1;
-		}
-#endif
-	return(-1);
+	if (a->type != b->type)
+		return -1;
+	if (a->ameth && a->ameth->param_cmp)
+		return a->ameth->param_cmp(a, b);
+	return -2;
 	}
 
 int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
@@ -263,51 +161,22 @@
 	if (a->type != b->type)
 		return -1;
 
-	if (EVP_PKEY_cmp_parameters(a, b) == 0)
-		return 0;
-
-	switch (a->type)
+	if (a->ameth)
 		{
-#ifndef OPENSSL_NO_RSA
-	case EVP_PKEY_RSA:
-		if (BN_cmp(b->pkey.rsa->n,a->pkey.rsa->n) != 0
-			|| BN_cmp(b->pkey.rsa->e,a->pkey.rsa->e) != 0)
-			return 0;
-		break;
-#endif
-#ifndef OPENSSL_NO_DSA
-	case EVP_PKEY_DSA:
-		if (BN_cmp(b->pkey.dsa->pub_key,a->pkey.dsa->pub_key) != 0)
-			return 0;
-		break;
-#endif
-#ifndef OPENSSL_NO_EC
-	case EVP_PKEY_EC:
-		{
-		int  r;
-		const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
-		const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
-		               *pb = EC_KEY_get0_public_key(b->pkey.ec);
-		r = EC_POINT_cmp(group, pa, pb, NULL);
-		if (r != 0)
+		int ret;
+		/* Compare parameters if the algorithm has them */
+		if (a->ameth->param_cmp)
 			{
-			if (r == 1)
-				return 0;
-			else
-				return -2;
+			ret = a->ameth->param_cmp(a, b);
+			if (ret <= 0)
+				return ret;
 			}
-		}
- 		break;
-#endif
-#ifndef OPENSSL_NO_DH
-	case EVP_PKEY_DH:
-		return -2;
-#endif
-	default:
-		return -2;
+
+		if (a->ameth->pub_cmp)
+			return a->ameth->pub_cmp(a, b);
 		}
 
-	return 1;
+	return -2;
 	}
 
 EVP_PKEY *EVP_PKEY_new(void)
@@ -321,22 +190,87 @@
 		return(NULL);
 		}
 	ret->type=EVP_PKEY_NONE;
+	ret->save_type=EVP_PKEY_NONE;
 	ret->references=1;
+	ret->ameth=NULL;
+	ret->engine=NULL;
 	ret->pkey.ptr=NULL;
 	ret->attributes=NULL;
 	ret->save_parameters=1;
 	return(ret);
 	}
 
-int EVP_PKEY_assign(EVP_PKEY *pkey, int type, char *key)
+/* Setup a public key ASN1 method and ENGINE from a NID or a string.
+ * If pkey is NULL just return 1 or 0 if the algorithm exists.
+ */
+
+static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
 	{
-	if (pkey == NULL) return(0);
-	if (pkey->pkey.ptr != NULL)
-		EVP_PKEY_free_it(pkey);
-	pkey->type=EVP_PKEY_type(type);
-	pkey->save_type=type;
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	ENGINE *e = NULL;
+	if (pkey)
+		{
+		if (pkey->pkey.ptr)
+			EVP_PKEY_free_it(pkey);
+		/* If key type matches and a method exists then this
+		 * lookup has succeeded once so just indicate success.
+		 */
+		if ((type == pkey->save_type) && pkey->ameth)
+			return 1;
+#ifndef OPENSSL_NO_ENGINE
+		/* If we have an ENGINE release it */
+		if (pkey->engine)
+			{
+			ENGINE_finish(pkey->engine);
+			pkey->engine = NULL;
+			}
+#endif
+		}
+	if (str)
+		ameth = EVP_PKEY_asn1_find_str(&e, str, len);
+	else
+		ameth = EVP_PKEY_asn1_find(&e, type);
+#ifndef OPENSSL_NO_ENGINE
+	if (!pkey && e)
+		ENGINE_finish(e);
+#endif
+	if (!ameth)
+		{
+		EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
+		return 0;
+		}
+	if (pkey)
+		{
+		pkey->ameth = ameth;
+		pkey->engine = e;
+
+		pkey->type = pkey->ameth->pkey_id;
+		pkey->save_type=type;
+		}
+	return 1;
+	}
+
+int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
+	{
+	return pkey_set_type(pkey, type, NULL, -1);
+	}
+
+int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
+	{
+	return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
+	}
+
+int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
+	{
+	if (!EVP_PKEY_set_type(pkey, type))
+		return 0;
 	pkey->pkey.ptr=key;
-	return(key != NULL);
+	return (key != NULL);
+	}
+
+void *EVP_PKEY_get0(EVP_PKEY *pkey)
+	{
+	return pkey->pkey.ptr;
 	}
 
 #ifndef OPENSSL_NO_RSA
@@ -425,24 +359,29 @@
 
 int EVP_PKEY_type(int type)
 	{
-	switch (type)
-		{
-	case EVP_PKEY_RSA:
-	case EVP_PKEY_RSA2:
-		return(EVP_PKEY_RSA);
-	case EVP_PKEY_DSA:
-	case EVP_PKEY_DSA1:
-	case EVP_PKEY_DSA2:
-	case EVP_PKEY_DSA3:
-	case EVP_PKEY_DSA4:
-		return(EVP_PKEY_DSA);
-	case EVP_PKEY_DH:
-		return(EVP_PKEY_DH);
-	case EVP_PKEY_EC:
-		return(EVP_PKEY_EC);
-	default:
-		return(NID_undef);
-		}
+	int ret;
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	ENGINE *e;
+	ameth = EVP_PKEY_asn1_find(&e, type);
+	if (ameth)
+		ret = ameth->pkey_id;
+	else
+		ret = NID_undef;
+#ifndef OPENSSL_NO_ENGINE
+	if (e)
+		ENGINE_finish(e);
+#endif
+	return ret;
+	}
+
+int EVP_PKEY_id(const EVP_PKEY *pkey)
+	{
+	return pkey->type;
+	}
+
+int EVP_PKEY_base_id(const EVP_PKEY *pkey)
+	{
+	return EVP_PKEY_type(pkey->type);
 	}
 
 void EVP_PKEY_free(EVP_PKEY *x)
@@ -471,32 +410,57 @@
 
 static void EVP_PKEY_free_it(EVP_PKEY *x)
 	{
-	switch (x->type)
+	if (x->ameth && x->ameth->pkey_free)
+		x->ameth->pkey_free(x);
+#ifndef OPENSSL_NO_ENGINE
+	if (x->engine)
 		{
-#ifndef OPENSSL_NO_RSA
-	case EVP_PKEY_RSA:
-	case EVP_PKEY_RSA2:
-		RSA_free(x->pkey.rsa);
-		break;
-#endif
-#ifndef OPENSSL_NO_DSA
-	case EVP_PKEY_DSA:
-	case EVP_PKEY_DSA2:
-	case EVP_PKEY_DSA3:
-	case EVP_PKEY_DSA4:
-		DSA_free(x->pkey.dsa);
-		break;
-#endif
-#ifndef OPENSSL_NO_EC
-	case EVP_PKEY_EC:
-		EC_KEY_free(x->pkey.ec);
-		break;
-#endif
-#ifndef OPENSSL_NO_DH
-	case EVP_PKEY_DH:
-		DH_free(x->pkey.dh);
-		break;
-#endif
+		ENGINE_finish(x->engine);
+		x->engine = NULL;
 		}
+#endif
+	}
+
+static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
+				const char *kstr)
+	{
+	BIO_indent(out, indent, 128);
+	BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
+						kstr, OBJ_nid2ln(pkey->type));
+	return 1;
+	}
+
+int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
+				int indent, ASN1_PCTX *pctx)
+	{
+	if (pkey->ameth && pkey->ameth->pub_print)
+		return pkey->ameth->pub_print(out, pkey, indent, pctx);
+	
+	return unsup_alg(out, pkey, indent, "Public Key");
+	}
+
+int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
+				int indent, ASN1_PCTX *pctx)
+	{
+	if (pkey->ameth && pkey->ameth->priv_print)
+		return pkey->ameth->priv_print(out, pkey, indent, pctx);
+	
+	return unsup_alg(out, pkey, indent, "Private Key");
+	}
+
+int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
+				int indent, ASN1_PCTX *pctx)
+	{
+	if (pkey->ameth && pkey->ameth->param_print)
+		return pkey->ameth->param_print(out, pkey, indent, pctx);
+	return unsup_alg(out, pkey, indent, "Parameters");
+	}
+
+int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
+	{
+	if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
+		return -2;
+	return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
+						0, pnid);
 	}
 
diff --git a/crypto/evp/p_open.c b/crypto/evp/p_open.c
index 9935206..53a59a2 100644
--- a/crypto/evp/p_open.c
+++ b/crypto/evp/p_open.c
@@ -95,7 +95,7 @@
 		goto err;
 		}
 
-	i=EVP_PKEY_decrypt(key,ek,ekl,priv);
+	i=EVP_PKEY_decrypt_old(key,ek,ekl,priv);
 	if ((i <= 0) || !EVP_CIPHER_CTX_set_key_length(ctx, i))
 		{
 		/* ERROR */
diff --git a/crypto/evp/p_seal.c b/crypto/evp/p_seal.c
index 8cc8fcb..d832452 100644
--- a/crypto/evp/p_seal.c
+++ b/crypto/evp/p_seal.c
@@ -87,7 +87,7 @@
 
 	for (i=0; i<npubk; i++)
 		{
-		ekl[i]=EVP_PKEY_encrypt(ek[i],key,EVP_CIPHER_CTX_key_length(ctx),
+		ekl[i]=EVP_PKEY_encrypt_old(ek[i],key,EVP_CIPHER_CTX_key_length(ctx),
 			pubk[i]);
 		if (ekl[i] <= 0) return(-1);
 		}
diff --git a/crypto/evp/p_sign.c b/crypto/evp/p_sign.c
index bf41a0d..8df6d48 100644
--- a/crypto/evp/p_sign.c
+++ b/crypto/evp/p_sign.c
@@ -84,6 +84,32 @@
 	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);
+
+	if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
+		{
+		EVP_PKEY_CTX *pkctx = NULL;
+		size_t sltmp = (size_t)EVP_PKEY_size(pkey);
+		i = 0;
+		pkctx = EVP_PKEY_CTX_new(pkey, NULL);
+		if (!pkctx)
+			goto err;
+		if (EVP_PKEY_sign_init(pkctx) <= 0)
+			goto err;
+		if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
+			goto err;
+		if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0)
+			goto err;
+		*siglen = sltmp;
+		i = 1;
+		err:
+		EVP_PKEY_CTX_free(pkctx);
+		return i;
+		}
+
 	for (i=0; i<4; i++)
 		{
 		v=ctx->digest->required_pkey_type[i];
@@ -99,28 +125,13 @@
 		EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE);
 		return(0);
 		}
+
 	if (ctx->digest->sign == NULL)
 		{
 		EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_NO_SIGN_FUNCTION_CONFIGURED);
 		return(0);
 		}
-	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;
+	return(ctx->digest->sign(ctx->digest->type,m,m_len,sigret,siglen,
+		pkey->pkey.ptr));
 	}
 
diff --git a/crypto/evp/p_verify.c b/crypto/evp/p_verify.c
index 2d46dff..8db4641 100644
--- a/crypto/evp/p_verify.c
+++ b/crypto/evp/p_verify.c
@@ -70,6 +70,28 @@
 	int i,ok=0,v;
 	MS_STATIC EVP_MD_CTX tmp_ctx;
 
+	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->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
+		{
+		EVP_PKEY_CTX *pkctx = NULL;
+		i = -1;
+		pkctx = EVP_PKEY_CTX_new(pkey, NULL);
+		if (!pkctx)
+			goto err;
+		if (EVP_PKEY_verify_init(pkctx) <= 0)
+			goto err;
+		if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
+			goto err;
+		i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len);
+		err:
+		EVP_PKEY_CTX_free(pkctx);
+		return i;
+		}
+
 	for (i=0; i<4; i++)
 		{
 		v=ctx->digest->required_pkey_type[i];
@@ -85,29 +107,13 @@
 		EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE);
 		return(-1);
 		}
-	if (ctx->digest->verify == NULL)
+        if (ctx->digest->verify == NULL)
                 {
 		EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_NO_VERIFY_FUNCTION_CONFIGURED);
 		return(0);
 		}
 
-	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;
+	return(ctx->digest->verify(ctx->digest->type,m,m_len,
+		sigbuf,siglen,pkey->pkey.ptr));
 	}
 
diff --git a/crypto/evp/pmeth_fn.c b/crypto/evp/pmeth_fn.c
new file mode 100644
index 0000000..c4676f2
--- /dev/null
+++ b/crypto/evp/pmeth_fn.c
@@ -0,0 +1,368 @@
+/* pmeth_fn.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include "evp_locl.h"
+
+#define M_check_autoarg(ctx, arg, arglen, err) \
+	if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \
+		{ \
+		size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
+		if (!arg) \
+			{ \
+			*arglen = pksize; \
+			return 1; \
+			} \
+		else if (*arglen < pksize) \
+			{ \
+			EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\
+			return 0; \
+			} \
+		}
+
+int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
+		{
+		EVPerr(EVP_F_EVP_PKEY_SIGN_INIT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	ctx->operation = EVP_PKEY_OP_SIGN;
+	if (!ctx->pmeth->sign_init)
+		return 1;
+	ret = ctx->pmeth->sign_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+	}
+
+int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
+			unsigned char *sig, size_t *siglen,
+			const unsigned char *tbs, size_t tbslen)
+	{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
+		{
+		EVPerr(EVP_F_EVP_PKEY_SIGN,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	if (ctx->operation != EVP_PKEY_OP_SIGN)
+		{
+		EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+		}
+	M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
+	return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
+	}
+
+int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
+		{
+		EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	ctx->operation = EVP_PKEY_OP_VERIFY;
+	if (!ctx->pmeth->verify_init)
+		return 1;
+	ret = ctx->pmeth->verify_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+	}
+
+int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
+			const unsigned char *sig, size_t siglen,
+			const unsigned char *tbs, size_t tbslen)
+	{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
+		{
+		EVPerr(EVP_F_EVP_PKEY_VERIFY,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	if (ctx->operation != EVP_PKEY_OP_VERIFY)
+		{
+		EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+		}
+	return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
+	}
+
+int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
+		{
+		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
+	if (!ctx->pmeth->verify_recover_init)
+		return 1;
+	ret = ctx->pmeth->verify_recover_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+	}
+
+int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
+			unsigned char *rout, size_t *routlen,
+			const unsigned char *sig, size_t siglen)
+	{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
+		{
+		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER)
+		{
+		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+		}
+	M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
+	return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
+	}
+
+int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
+		{
+		EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	ctx->operation = EVP_PKEY_OP_ENCRYPT;
+	if (!ctx->pmeth->encrypt_init)
+		return 1;
+	ret = ctx->pmeth->encrypt_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+	}
+
+int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
+			unsigned char *out, size_t *outlen,
+			const unsigned char *in, size_t inlen)
+	{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
+		{
+		EVPerr(EVP_F_EVP_PKEY_ENCRYPT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	if (ctx->operation != EVP_PKEY_OP_ENCRYPT)
+		{
+		EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+		}
+	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
+	return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
+	}
+
+int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	ctx->operation = EVP_PKEY_OP_DECRYPT;
+	if (!ctx->pmeth->decrypt_init)
+		return 1;
+	ret = ctx->pmeth->decrypt_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+	}
+
+int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
+			unsigned char *out, size_t *outlen,
+			const unsigned char *in, size_t inlen)
+	{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DECRYPT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	if (ctx->operation != EVP_PKEY_OP_DECRYPT)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+		}
+	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
+	return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
+	}
+
+
+int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	ctx->operation = EVP_PKEY_OP_DERIVE;
+	if (!ctx->pmeth->derive_init)
+		return 1;
+	ret = ctx->pmeth->derive_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+	}
+
+int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive||ctx->pmeth->encrypt||ctx->pmeth->decrypt) || !ctx->pmeth->ctrl)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	if (ctx->operation != EVP_PKEY_OP_DERIVE && ctx->operation != EVP_PKEY_OP_ENCRYPT && ctx->operation != EVP_PKEY_OP_DECRYPT)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
+					EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+		}
+
+	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
+
+	if (ret <= 0)
+		return ret;
+
+	if (ret == 2)
+		return 1;
+
+	if (!ctx->pkey)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
+		return -1;
+		}
+
+	if (ctx->pkey->type != peer->type)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
+						EVP_R_DIFFERENT_KEY_TYPES);
+		return -1;
+		}
+
+	/* ran@cryptocom.ru: For clarity.  The error is if parameters in peer are
+	 * present (!missing) but don't match.  EVP_PKEY_cmp_parameters may return
+	 * 1 (match), 0 (don't match) and -2 (comparison is not defined).  -1
+	 * (different key types) is impossible here because it is checked earlier.
+	 * -2 is OK for us here, as well as 1, so we can check for 0 only. */
+	if (!EVP_PKEY_missing_parameters(peer) &&
+		!EVP_PKEY_cmp_parameters(ctx->pkey, peer))
+		{
+		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
+						EVP_R_DIFFERENT_PARAMETERS);
+		return -1;
+		}
+
+	if (ctx->peerkey)
+		EVP_PKEY_free(ctx->peerkey);
+	ctx->peerkey = peer;
+
+	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
+
+	if (ret <= 0)
+		{
+		ctx->peerkey = NULL;
+		return ret;
+		}
+
+	CRYPTO_add(&peer->references,1,CRYPTO_LOCK_EVP_PKEY);
+	return 1;
+	}
+
+
+int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
+	{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DERIVE,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	if (ctx->operation != EVP_PKEY_OP_DERIVE)
+		{
+		EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+		}
+	M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
+	return ctx->pmeth->derive(ctx, key, pkeylen);
+	}
+
diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c
new file mode 100644
index 0000000..5d74161
--- /dev/null
+++ b/crypto/evp/pmeth_gn.c
@@ -0,0 +1,220 @@
+/* pmeth_gn.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include "evp_locl.h"
+
+int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen)
+		{
+		EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	ctx->operation = EVP_PKEY_OP_PARAMGEN;
+	if (!ctx->pmeth->paramgen_init)
+		return 1;
+	ret = ctx->pmeth->paramgen_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+	}
+
+int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen)
+		{
+		EVPerr(EVP_F_EVP_PKEY_PARAMGEN,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+
+	if (ctx->operation != EVP_PKEY_OP_PARAMGEN)
+		{
+		EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+		}
+
+	if (!ppkey)
+		return -1;
+
+	if (!*ppkey)
+		*ppkey = EVP_PKEY_new();
+
+	ret = ctx->pmeth->paramgen(ctx, *ppkey);
+	if (ret <= 0)
+		{
+		EVP_PKEY_free(*ppkey);
+		*ppkey = NULL;
+		}
+	return ret;
+	}
+
+int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen)
+		{
+		EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	ctx->operation = EVP_PKEY_OP_KEYGEN;
+	if (!ctx->pmeth->keygen_init)
+		return 1;
+	ret = ctx->pmeth->keygen_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+	}
+
+int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
+	{
+	int ret;
+
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen)
+		{
+		EVPerr(EVP_F_EVP_PKEY_KEYGEN,
+			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+		}
+	if (ctx->operation != EVP_PKEY_OP_KEYGEN)
+		{
+		EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+		}
+
+	if (!ppkey)
+		return -1;
+
+	if (!*ppkey)
+		*ppkey = EVP_PKEY_new();
+
+	ret = ctx->pmeth->keygen(ctx, *ppkey);
+	if (ret <= 0)
+		{
+		EVP_PKEY_free(*ppkey);
+		*ppkey = NULL;
+		}
+	return ret;
+	}
+
+void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb)
+	{
+	ctx->pkey_gencb = cb;
+	}
+
+EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx)
+	{
+	return ctx->pkey_gencb;
+	}
+
+/* "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB
+ * style callbacks.
+ */
+
+static int trans_cb(int a, int b, BN_GENCB *gcb)
+	{
+	EVP_PKEY_CTX *ctx = gcb->arg;
+	ctx->keygen_info[0] = a;
+	ctx->keygen_info[1] = b;
+	return ctx->pkey_gencb(ctx);
+	}	
+
+void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx)
+	{
+	BN_GENCB_set(cb, trans_cb, ctx)
+	}
+
+int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx)
+	{
+	if (idx == -1)
+		return ctx->keygen_info_count; 
+	if (idx < 0 || idx > ctx->keygen_info_count)
+		return 0;
+	return ctx->keygen_info[idx];
+	}
+
+EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
+				unsigned char *key, int keylen)
+	{
+	EVP_PKEY_CTX *mac_ctx = NULL;
+	EVP_PKEY *mac_key = NULL;
+	mac_ctx = EVP_PKEY_CTX_new_id(type, e);
+	if (!mac_ctx)
+		return NULL;
+	if (EVP_PKEY_keygen_init(mac_ctx) <= 0)
+		goto merr;
+	if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN,
+				EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key) <= 0)
+		goto merr;
+	if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0)
+		goto merr;
+	merr:
+	if (mac_ctx)
+		EVP_PKEY_CTX_free(mac_ctx);
+	return mac_key;
+	}
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
new file mode 100644
index 0000000..4a05f0b
--- /dev/null
+++ b/crypto/evp/pmeth_lib.c
@@ -0,0 +1,537 @@
+/* pmeth_lib.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include "asn1_locl.h"
+#include "evp_locl.h"
+
+typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
+
+DECLARE_STACK_OF(EVP_PKEY_METHOD)
+STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
+
+extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth;
+extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth;
+
+static const EVP_PKEY_METHOD *standard_methods[] =
+	{
+#ifndef OPENSSL_NO_RSA
+	&rsa_pkey_meth,
+#endif
+#ifndef OPENSSL_NO_DH
+	&dh_pkey_meth,
+#endif
+#ifndef OPENSSL_NO_DSA
+	&dsa_pkey_meth,
+#endif
+#ifndef OPENSSL_NO_EC
+	&ec_pkey_meth,
+#endif
+	&hmac_pkey_meth,
+	};
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
+			   pmeth);
+
+static int pmeth_cmp(const EVP_PKEY_METHOD * const *a,
+		     const EVP_PKEY_METHOD * const *b)
+	{
+        return ((*a)->pkey_id - (*b)->pkey_id);
+	}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
+			     pmeth);
+
+const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type)
+	{
+	EVP_PKEY_METHOD tmp;
+	const EVP_PKEY_METHOD *t = &tmp, **ret;
+	tmp.pkey_id = type;
+	if (app_pkey_methods)
+		{
+		int idx;
+		idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp);
+		if (idx >= 0)
+			return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx);
+		}
+	ret = OBJ_bsearch_pmeth(&t, standard_methods,
+			  sizeof(standard_methods)/sizeof(EVP_PKEY_METHOD *));
+	if (!ret || !*ret)
+		return NULL;
+	return *ret;
+	}
+
+static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
+	{
+	EVP_PKEY_CTX *ret;
+	const EVP_PKEY_METHOD *pmeth;
+	if (id == -1)
+		{
+		if (!pkey || !pkey->ameth)
+			return NULL;
+		id = pkey->ameth->pkey_id;
+		}
+#ifndef OPENSSL_NO_ENGINE
+	/* Try to find an ENGINE which implements this method */
+	if (e)
+		{
+		if (!ENGINE_init(e))
+			{
+			EVPerr(EVP_F_INT_CTX_NEW,ERR_R_ENGINE_LIB);
+			return NULL;
+			}
+		}
+	else
+		e = ENGINE_get_pkey_meth_engine(id);
+
+	/* If an ENGINE handled this method look it up. Othewise
+	 * use internal tables.
+	 */
+
+	if (e)
+		pmeth = ENGINE_get_pkey_meth(e, id);
+	else
+#endif
+		pmeth = EVP_PKEY_meth_find(id);
+
+	if (pmeth == NULL)
+		{
+		EVPerr(EVP_F_INT_CTX_NEW,EVP_R_UNSUPPORTED_ALGORITHM);
+		return NULL;
+		}
+
+	ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
+	if (!ret)
+		{
+#ifndef OPENSSL_NO_ENGINE
+		if (e)
+			ENGINE_finish(e);
+#endif
+		EVPerr(EVP_F_INT_CTX_NEW,ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+	ret->engine = e;
+	ret->pmeth = pmeth;
+	ret->operation = EVP_PKEY_OP_UNDEFINED;
+	ret->pkey = pkey;
+	ret->peerkey = NULL;
+	if (pkey)
+		CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
+	ret->data = NULL;
+
+	if (pmeth->init)
+		{
+		if (pmeth->init(ret) <= 0)
+			{
+			EVP_PKEY_CTX_free(ret);
+			return NULL;
+			}
+		}
+
+	return ret;
+	}
+
+EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags)
+	{
+	EVP_PKEY_METHOD *pmeth;
+	pmeth = OPENSSL_malloc(sizeof(EVP_PKEY_METHOD));
+	if (!pmeth)
+		return NULL;
+
+	pmeth->pkey_id = id;
+	pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
+
+	pmeth->init = 0;
+	pmeth->copy = 0;
+	pmeth->cleanup = 0;
+	pmeth->paramgen_init = 0;
+	pmeth->paramgen = 0;
+	pmeth->keygen_init = 0;
+	pmeth->keygen = 0;
+	pmeth->sign_init = 0;
+	pmeth->sign = 0;
+	pmeth->verify_init = 0;
+	pmeth->verify = 0;
+	pmeth->verify_recover_init = 0;
+	pmeth->verify_recover = 0;
+	pmeth->signctx_init = 0;
+	pmeth->signctx = 0;
+	pmeth->verifyctx_init = 0;
+	pmeth->verifyctx = 0;
+	pmeth->encrypt_init = 0;
+	pmeth->encrypt = 0;
+	pmeth->decrypt_init = 0;
+	pmeth->decrypt = 0;
+	pmeth->derive_init = 0;
+	pmeth->derive = 0;
+	pmeth->ctrl = 0;
+	pmeth->ctrl_str = 0;
+
+	return pmeth;
+	}
+
+void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
+	{
+	if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC))
+		OPENSSL_free(pmeth);
+	}
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
+	{
+	return int_ctx_new(pkey, e, -1);
+	}
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
+	{
+	return int_ctx_new(NULL, e, id);
+	}
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
+	{
+	EVP_PKEY_CTX *rctx;
+	if (!pctx->pmeth || !pctx->pmeth->copy)
+		return NULL;
+#ifndef OPENSSL_NO_ENGINE
+	/* Make sure it's safe to copy a pkey context using an ENGINE */
+	if (pctx->engine && !ENGINE_init(pctx->engine))
+		{
+		EVPerr(EVP_F_EVP_PKEY_CTX_DUP,ERR_R_ENGINE_LIB);
+		return 0;
+		}
+#endif
+	rctx = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
+	if (!rctx)
+		return NULL;
+
+	rctx->pmeth = pctx->pmeth;
+#ifndef OPENSSL_NO_ENGINE
+	rctx->engine = pctx->engine;
+#endif
+
+	if (pctx->pkey)
+		CRYPTO_add(&pctx->pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
+
+	rctx->pkey = pctx->pkey;
+
+	if (pctx->peerkey)
+		CRYPTO_add(&pctx->peerkey->references,1,CRYPTO_LOCK_EVP_PKEY);
+
+	rctx->peerkey = pctx->peerkey;
+
+	rctx->data = NULL;
+	rctx->app_data = NULL;
+	rctx->operation = pctx->operation;
+
+	if (pctx->pmeth->copy(rctx, pctx) > 0)
+		return rctx;
+
+	EVP_PKEY_CTX_free(rctx);
+	return NULL;
+
+	}
+
+int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)
+	{
+	if (app_pkey_methods == NULL)
+		{
+		app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp);
+		if (!app_pkey_methods)
+			return 0;
+		}
+	if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth))
+		return 0;
+	sk_EVP_PKEY_METHOD_sort(app_pkey_methods);
+	return 1;
+	}
+
+void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
+	{
+	if (ctx == NULL)
+		return;
+	if (ctx->pmeth && ctx->pmeth->cleanup)
+		ctx->pmeth->cleanup(ctx);
+	if (ctx->pkey)
+		EVP_PKEY_free(ctx->pkey);
+	if (ctx->peerkey)
+		EVP_PKEY_free(ctx->peerkey);
+#ifndef OPENSSL_NO_ENGINE
+	if(ctx->engine)
+		/* The EVP_PKEY_CTX we used belongs to an ENGINE, release the
+		 * functional reference we held for this reason. */
+		ENGINE_finish(ctx->engine);
+#endif
+	OPENSSL_free(ctx);
+	}
+
+int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
+				int cmd, int p1, void *p2)
+	{
+	int ret;
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl)
+		{
+		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
+		return -2;
+		}
+	if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype))
+		return -1;
+
+	if (ctx->operation == EVP_PKEY_OP_UNDEFINED)
+		{
+		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET);
+		return -1;
+		}
+
+	if ((optype != -1) && !(ctx->operation & optype))
+		{
+		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION);
+		return -1;
+		}
+
+	ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2);
+
+	if (ret == -2)
+		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
+
+	return ret;
+
+	}
+
+int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
+					const char *name, const char *value)
+	{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str)
+		{
+		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR,
+						EVP_R_COMMAND_NOT_SUPPORTED);
+		return -2;
+		}
+	if (!strcmp(name, "digest"))
+		{
+		const EVP_MD *md;
+		if (!value || !(md = EVP_get_digestbyname(value)))
+			{
+			EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR,
+						EVP_R_INVALID_DIGEST);
+			return 0;
+			}
+		return EVP_PKEY_CTX_set_signature_md(ctx, md);
+		}
+	return ctx->pmeth->ctrl_str(ctx, name, value);
+	}
+
+int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx)
+	{
+	return ctx->operation;
+	}
+
+void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen)
+	{
+	ctx->keygen_info = dat;
+	ctx->keygen_info_count = datlen;
+	}
+
+void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
+	{
+	ctx->data = data;
+	}
+
+void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
+	{
+	return ctx->data;
+	}
+
+EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx)
+	{
+	return ctx->pkey;
+	}
+
+EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx)
+	{
+	return ctx->peerkey;
+	}
+	
+void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
+	{
+	ctx->app_data = data;
+	}
+
+void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
+	{
+	return ctx->app_data;
+	}
+
+void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
+	int (*init)(EVP_PKEY_CTX *ctx))
+	{
+	pmeth->init = init;
+	}
+
+void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
+	int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src))
+	{
+	pmeth->copy = copy;
+	}
+
+void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
+	void (*cleanup)(EVP_PKEY_CTX *ctx))
+	{
+	pmeth->cleanup = cleanup;
+	}
+
+void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
+	int (*paramgen_init)(EVP_PKEY_CTX *ctx),
+	int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey))
+	{
+	pmeth->paramgen_init = paramgen_init;
+	pmeth->paramgen = paramgen;
+	}
+
+void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
+	int (*keygen_init)(EVP_PKEY_CTX *ctx),
+	int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey))
+	{
+	pmeth->keygen_init = keygen_init;
+	pmeth->keygen = keygen;
+	}
+
+void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
+	int (*sign_init)(EVP_PKEY_CTX *ctx),
+	int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					const unsigned char *tbs, size_t tbslen))
+	{
+	pmeth->sign_init = sign_init;
+	pmeth->sign = sign;
+	}
+
+void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
+	int (*verify_init)(EVP_PKEY_CTX *ctx),
+	int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
+					const unsigned char *tbs, size_t tbslen))
+	{
+	pmeth->verify_init = verify_init;
+	pmeth->verify = verify;
+	}
+
+void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
+	int (*verify_recover_init)(EVP_PKEY_CTX *ctx),
+	int (*verify_recover)(EVP_PKEY_CTX *ctx,
+					unsigned char *sig, size_t *siglen,
+					const unsigned char *tbs, size_t tbslen))
+	{
+	pmeth->verify_recover_init = verify_recover_init;
+	pmeth->verify_recover = verify_recover;
+	}
+
+void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
+	int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
+	int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					EVP_MD_CTX *mctx))
+	{
+	pmeth->signctx_init = signctx_init;
+	pmeth->signctx = signctx;
+	}
+
+void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
+	int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
+	int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,int siglen,
+					EVP_MD_CTX *mctx))
+	{
+	pmeth->verifyctx_init = verifyctx_init;
+	pmeth->verifyctx = verifyctx;
+	}
+
+void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
+	int (*encrypt_init)(EVP_PKEY_CTX *ctx),
+	int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+					const unsigned char *in, size_t inlen))
+	{
+	pmeth->encrypt_init = encrypt_init;
+	pmeth->encrypt = encryptfn;
+	}
+
+void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
+	int (*decrypt_init)(EVP_PKEY_CTX *ctx),
+	int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+					const unsigned char *in, size_t inlen))
+	{
+	pmeth->decrypt_init = decrypt_init;
+	pmeth->decrypt = decrypt;
+	}
+
+void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
+	int (*derive_init)(EVP_PKEY_CTX *ctx),
+	int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen))
+	{
+	pmeth->derive_init = derive_init;
+	pmeth->derive = derive;
+	}
+
+void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
+	int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2),
+	int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value))
+	{
+	pmeth->ctrl = ctrl;
+	pmeth->ctrl_str = ctrl_str;
+	}
diff --git a/crypto/ex_data.c b/crypto/ex_data.c
index 3b11e7a..e2bc829 100644
--- a/crypto/ex_data.c
+++ b/crypto/ex_data.c
@@ -245,18 +245,21 @@
 static int ex_class = CRYPTO_EX_INDEX_USER;
 
 /* The global hash table of EX_CLASS_ITEM items */
-static LHASH *ex_data = NULL;
+DECLARE_LHASH_OF(EX_CLASS_ITEM);
+static LHASH_OF(EX_CLASS_ITEM) *ex_data = NULL;
 
 /* The callbacks required in the "ex_data" hash table */
-static unsigned long ex_hash_cb(const void *a_void)
+static unsigned long ex_class_item_hash(const EX_CLASS_ITEM *a)
 	{
-	return ((const EX_CLASS_ITEM *)a_void)->class_index;
+	return a->class_index;
 	}
-static int ex_cmp_cb(const void *a_void, const void *b_void)
+static IMPLEMENT_LHASH_HASH_FN(ex_class_item, EX_CLASS_ITEM)
+
+static int ex_class_item_cmp(const EX_CLASS_ITEM *a, const EX_CLASS_ITEM *b)
 	{
-	return (((const EX_CLASS_ITEM *)a_void)->class_index -
-		((const EX_CLASS_ITEM *)b_void)->class_index);
+	return a->class_index - b->class_index;
 	}
+static IMPLEMENT_LHASH_COMP_FN(ex_class_item, EX_CLASS_ITEM)
 
 /* Internal functions used by the "impl_default" implementation to access the
  * state */
@@ -265,7 +268,8 @@
 	{
 	int toret = 1;
 	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
-	if(!ex_data && ((ex_data = lh_new(ex_hash_cb, ex_cmp_cb)) == NULL))
+	if(!ex_data
+	   && (ex_data = lh_EX_CLASS_ITEM_new()) == NULL)
 		toret = 0;
 	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
 	return toret;
@@ -298,7 +302,7 @@
 	EX_DATA_CHECK(return NULL;)
 	d.class_index = class_index;
 	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
-	p = lh_retrieve(ex_data, &d);
+	p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d);
 	if(!p)
 		{
 		gen = OPENSSL_malloc(sizeof(EX_CLASS_ITEM));
@@ -313,7 +317,7 @@
 				{
 				/* Because we're inside the ex_data lock, the
 				 * return value from the insert will be NULL */
-				lh_insert(ex_data, gen);
+				(void)lh_EX_CLASS_ITEM_insert(ex_data, gen);
 				p = gen;
 				}
 			}
@@ -375,8 +379,8 @@
 static void int_cleanup(void)
 	{
 	EX_DATA_CHECK(return;)
-	lh_doall(ex_data, def_cleanup_cb);
-	lh_free(ex_data);
+	lh_EX_CLASS_ITEM_doall(ex_data, def_cleanup_cb);
+	lh_EX_CLASS_ITEM_free(ex_data);
 	ex_data = NULL;
 	impl = NULL;
 	}
@@ -452,7 +456,7 @@
 		return 0;
 	CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
 	mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
-	j = sk_num(from->sk);
+	j = sk_void_num(from->sk);
 	if(j < mx)
 		mx = j;
 	if(mx > 0)
@@ -523,7 +527,7 @@
 		OPENSSL_free(storage);
 	if(ad->sk)
 		{
-		sk_free(ad->sk);
+		sk_void_free(ad->sk);
 		ad->sk=NULL;
 		}
 	}
@@ -596,24 +600,24 @@
 
 	if (ad->sk == NULL)
 		{
-		if ((ad->sk=sk_new_null()) == NULL)
+		if ((ad->sk=sk_void_new_null()) == NULL)
 			{
 			CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE);
 			return(0);
 			}
 		}
-	i=sk_num(ad->sk);
+	i=sk_void_num(ad->sk);
 
 	while (i <= idx)
 		{
-		if (!sk_push(ad->sk,NULL))
+		if (!sk_void_push(ad->sk,NULL))
 			{
 			CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,ERR_R_MALLOC_FAILURE);
 			return(0);
 			}
 		i++;
 		}
-	sk_set(ad->sk,idx,val);
+	sk_void_set(ad->sk,idx,val);
 	return(1);
 	}
 
@@ -623,10 +627,10 @@
 	{
 	if (ad->sk == NULL)
 		return(0);
-	else if (idx >= sk_num(ad->sk))
+	else if (idx >= sk_void_num(ad->sk))
 		return(0);
 	else
-		return(sk_value(ad->sk,idx));
+		return(sk_void_value(ad->sk,idx));
 	}
 
 IMPLEMENT_STACK_OF(CRYPTO_EX_DATA_FUNCS)
diff --git a/crypto/fips_err.c b/crypto/fips_err.c
deleted file mode 100644
index 09f1174..0000000
--- a/crypto/fips_err.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#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
deleted file mode 100644
index b328616..0000000
--- a/crypto/fips_err.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* crypto/fips_err.h */
-/* ====================================================================
- * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    openssl-core@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-/* NOTE: this file was auto generated by the mkerr.pl script: any changes
- * made to it will be overwritten when the script next updates this file,
- * only reason strings will be preserved.
- */
-
-#include <stdio.h>
-#include <openssl/err.h>
-#include <openssl/fips.h>
-
-/* BEGIN ERROR CODES */
-#ifndef OPENSSL_NO_ERR
-
-#define ERR_FUNC(func) ERR_PACK(ERR_LIB_FIPS,func,0)
-#define ERR_REASON(reason) ERR_PACK(ERR_LIB_FIPS,0,reason)
-
-static ERR_STRING_DATA FIPS_str_functs[]=
-	{
-{ERR_FUNC(FIPS_F_DH_BUILTIN_GENPARAMS),	"DH_BUILTIN_GENPARAMS"},
-{ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN),	"DSA_BUILTIN_PARAMGEN"},
-{ERR_FUNC(FIPS_F_DSA_DO_SIGN),	"DSA_do_sign"},
-{ERR_FUNC(FIPS_F_DSA_DO_VERIFY),	"DSA_do_verify"},
-{ERR_FUNC(FIPS_F_EVP_CIPHERINIT_EX),	"EVP_CipherInit_ex"},
-{ERR_FUNC(FIPS_F_EVP_DIGESTINIT_EX),	"EVP_DigestInit_ex"},
-{ERR_FUNC(FIPS_F_FIPS_CHECK_DSA),	"FIPS_CHECK_DSA"},
-{ERR_FUNC(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT),	"FIPS_CHECK_INCORE_FINGERPRINT"},
-{ERR_FUNC(FIPS_F_FIPS_CHECK_RSA),	"FIPS_CHECK_RSA"},
-{ERR_FUNC(FIPS_F_FIPS_DSA_CHECK),	"FIPS_DSA_CHECK"},
-{ERR_FUNC(FIPS_F_FIPS_MODE_SET),	"FIPS_mode_set"},
-{ERR_FUNC(FIPS_F_FIPS_PKEY_SIGNATURE_TEST),	"fips_pkey_signature_test"},
-{ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES),	"FIPS_selftest_aes"},
-{ERR_FUNC(FIPS_F_FIPS_SELFTEST_DES),	"FIPS_selftest_des"},
-{ERR_FUNC(FIPS_F_FIPS_SELFTEST_DSA),	"FIPS_selftest_dsa"},
-{ERR_FUNC(FIPS_F_FIPS_SELFTEST_HMAC),	"FIPS_selftest_hmac"},
-{ERR_FUNC(FIPS_F_FIPS_SELFTEST_RNG),	"FIPS_selftest_rng"},
-{ERR_FUNC(FIPS_F_FIPS_SELFTEST_SHA1),	"FIPS_selftest_sha1"},
-{ERR_FUNC(FIPS_F_HASH_FINAL),	"HASH_FINAL"},
-{ERR_FUNC(FIPS_F_RSA_BUILTIN_KEYGEN),	"RSA_BUILTIN_KEYGEN"},
-{ERR_FUNC(FIPS_F_RSA_EAY_PRIVATE_DECRYPT),	"RSA_EAY_PRIVATE_DECRYPT"},
-{ERR_FUNC(FIPS_F_RSA_EAY_PRIVATE_ENCRYPT),	"RSA_EAY_PRIVATE_ENCRYPT"},
-{ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_DECRYPT),	"RSA_EAY_PUBLIC_DECRYPT"},
-{ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT),	"RSA_EAY_PUBLIC_ENCRYPT"},
-{ERR_FUNC(FIPS_F_RSA_X931_GENERATE_KEY_EX),	"RSA_X931_generate_key_ex"},
-{ERR_FUNC(FIPS_F_SSLEAY_RAND_BYTES),	"SSLEAY_RAND_BYTES"},
-{0,NULL}
-	};
-
-static ERR_STRING_DATA FIPS_str_reasons[]=
-	{
-{ERR_REASON(FIPS_R_CANNOT_READ_EXE)      ,"cannot read exe"},
-{ERR_REASON(FIPS_R_CANNOT_READ_EXE_DIGEST),"cannot read exe digest"},
-{ERR_REASON(FIPS_R_CONTRADICTING_EVIDENCE),"contradicting evidence"},
-{ERR_REASON(FIPS_R_EXE_DIGEST_DOES_NOT_MATCH),"exe digest does not match"},
-{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH),"fingerprint does not match"},
-{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED),"fingerprint does not match nonpic relocated"},
-{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING),"fingerprint does not match segment aliasing"},
-{ERR_REASON(FIPS_R_FIPS_MODE_ALREADY_SET),"fips mode already set"},
-{ERR_REASON(FIPS_R_FIPS_SELFTEST_FAILED) ,"fips selftest failed"},
-{ERR_REASON(FIPS_R_INVALID_KEY_LENGTH)   ,"invalid key length"},
-{ERR_REASON(FIPS_R_KEY_TOO_SHORT)        ,"key too short"},
-{ERR_REASON(FIPS_R_NON_FIPS_METHOD)      ,"non fips method"},
-{ERR_REASON(FIPS_R_PAIRWISE_TEST_FAILED) ,"pairwise test failed"},
-{ERR_REASON(FIPS_R_RSA_DECRYPT_ERROR)    ,"rsa decrypt error"},
-{ERR_REASON(FIPS_R_RSA_ENCRYPT_ERROR)    ,"rsa encrypt error"},
-{ERR_REASON(FIPS_R_SELFTEST_FAILED)      ,"selftest failed"},
-{ERR_REASON(FIPS_R_TEST_FAILURE)         ,"test failure"},
-{ERR_REASON(FIPS_R_UNSUPPORTED_PLATFORM) ,"unsupported platform"},
-{0,NULL}
-	};
-
-#endif
-
-void ERR_load_FIPS_strings(void)
-	{
-#ifndef OPENSSL_NO_ERR
-
-	if (ERR_func_error_string(FIPS_str_functs[0].error) == NULL)
-		{
-		ERR_load_strings(0,FIPS_str_functs);
-		ERR_load_strings(0,FIPS_str_reasons);
-		}
-#endif
-	}
diff --git a/crypto/hmac/Makefile b/crypto/hmac/Makefile
deleted file mode 100644
index 5cfa37d..0000000
--- a/crypto/hmac/Makefile
+++ /dev/null
@@ -1,86 +0,0 @@
-#
-# OpenSSL/crypto/md/Makefile
-#
-
-DIR=	hmac
-TOP=	../..
-CC=	cc
-INCLUDES=
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=hmactest.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=hmac.c
-LIBOBJ=hmac.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= hmac.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-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/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/hm_ameth.c b/crypto/hmac/hm_ameth.c
new file mode 100644
index 0000000..6d8a891
--- /dev/null
+++ b/crypto/hmac/hm_ameth.c
@@ -0,0 +1,167 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include "asn1_locl.h"
+
+#define HMAC_TEST_PRIVATE_KEY_FORMAT
+
+/* HMAC "ASN1" method. This is just here to indicate the
+ * maximum HMAC output length and to free up an HMAC
+ * key.
+ */
+
+static int hmac_size(const EVP_PKEY *pkey)
+	{
+	return EVP_MAX_MD_SIZE;
+	}
+
+static void hmac_key_free(EVP_PKEY *pkey)
+	{
+	ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
+	if (os)
+		{
+		if (os->data)
+			OPENSSL_cleanse(os->data, os->length);
+		ASN1_OCTET_STRING_free(os);
+		}
+	}
+
+
+static int hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+	{
+	switch (op)
+		{
+		case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+		*(int *)arg2 = NID_sha1;
+		return 1;
+
+		default:
+		return -2;
+		}
+	}
+
+#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT
+/* A bogus private key format for test purposes. This is simply the
+ * HMAC key with "HMAC PRIVATE KEY" in the headers. When enabled the
+ * genpkey utility can be used to "generate" HMAC keys.
+ */
+
+static int old_hmac_decode(EVP_PKEY *pkey,
+					const unsigned char **pder, int derlen)
+	{
+	ASN1_OCTET_STRING *os;
+	os = ASN1_OCTET_STRING_new();
+	if (!os || !ASN1_OCTET_STRING_set(os, *pder, derlen))
+		return 0;
+	EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, os);
+	return 1;
+	}
+
+static int old_hmac_encode(const EVP_PKEY *pkey, unsigned char **pder)
+	{
+	int inc;
+	ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
+	if (pder)
+		{
+		if (!*pder)
+			{
+			*pder = OPENSSL_malloc(os->length);
+			inc = 0;
+			}
+		else inc = 1;
+
+		memcpy(*pder, os->data, os->length);
+
+		if (inc)
+			*pder += os->length;
+		}
+			
+	return os->length;
+	}
+
+#endif
+
+const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = 
+	{
+	EVP_PKEY_HMAC,
+	EVP_PKEY_HMAC,
+	0,
+
+	"HMAC",
+	"OpenSSL HMAC method",
+
+	0,0,0,0,
+
+	0,0,0,
+
+	hmac_size,
+	0,
+	0,0,0,0,0,0,
+
+	hmac_key_free,
+	hmac_pkey_ctrl,
+#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT
+	old_hmac_decode,
+	old_hmac_encode
+#else
+	0,0
+#endif
+	};
+
diff --git a/crypto/hmac/hm_pmeth.c b/crypto/hmac/hm_pmeth.c
new file mode 100644
index 0000000..985921c
--- /dev/null
+++ b/crypto/hmac/hm_pmeth.c
@@ -0,0 +1,265 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include "evp_locl.h"
+
+/* HMAC pkey context structure */
+
+typedef struct
+	{
+	const EVP_MD *md;	/* MD for HMAC use */
+	ASN1_OCTET_STRING ktmp; /* Temp storage for key */
+	HMAC_CTX ctx;
+	} HMAC_PKEY_CTX;
+
+static int pkey_hmac_init(EVP_PKEY_CTX *ctx)
+	{
+	HMAC_PKEY_CTX *hctx;
+	hctx = OPENSSL_malloc(sizeof(HMAC_PKEY_CTX));
+	if (!hctx)
+		return 0;
+	hctx->md = NULL;
+	hctx->ktmp.data = NULL;
+	hctx->ktmp.length = 0;
+	hctx->ktmp.flags = 0;
+	hctx->ktmp.type = V_ASN1_OCTET_STRING;
+	HMAC_CTX_init(&hctx->ctx);
+
+	ctx->data = hctx;
+	ctx->keygen_info_count = 0;
+
+	return 1;
+	}
+
+static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+	{
+	HMAC_PKEY_CTX *sctx, *dctx;
+	if (!pkey_hmac_init(dst))
+		return 0;
+       	sctx = src->data;
+	dctx = dst->data;
+	dctx->md = sctx->md;
+	HMAC_CTX_init(&dctx->ctx);
+	HMAC_CTX_copy(&dctx->ctx, &sctx->ctx);
+	if (sctx->ktmp.data)
+		{
+		if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
+					sctx->ktmp.data, sctx->ktmp.length))
+			return 0;
+		}
+	return 1;
+	}
+
+static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx)
+	{
+	HMAC_PKEY_CTX *hctx = ctx->data;
+	HMAC_CTX_cleanup(&hctx->ctx);
+	if (hctx->ktmp.data)
+		{
+		if (hctx->ktmp.length)
+			OPENSSL_cleanse(hctx->ktmp.data, hctx->ktmp.length);
+		OPENSSL_free(hctx->ktmp.data);
+		hctx->ktmp.data = NULL;
+		}
+	OPENSSL_free(hctx);
+	}
+
+static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+	{
+	ASN1_OCTET_STRING *hkey = NULL;
+	HMAC_PKEY_CTX *hctx = ctx->data;
+	if (!hctx->ktmp.data)
+		return 0;
+	hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp);
+	if (!hkey)
+		return 0;
+	EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey);
+	
+	return 1;
+	}
+
+static int int_update(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{
+	HMAC_PKEY_CTX *hctx = ctx->pctx->data;
+	HMAC_Update(&hctx->ctx, data, count);
+	return 1;
+	}
+
+static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
+	{
+	EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
+	mctx->update = int_update;
+	return 1;
+	}
+
+static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					EVP_MD_CTX *mctx)
+	{
+	unsigned int hlen;
+	HMAC_PKEY_CTX *hctx = ctx->data;
+	int l = EVP_MD_CTX_size(mctx);
+
+	if (l < 0)
+		return 0;
+	*siglen = l;
+	if (!sig)
+		return 1;
+
+	HMAC_Final(&hctx->ctx, sig, &hlen);
+	*siglen = (size_t)hlen;
+	return 1;
+	}
+
+static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+	{
+	HMAC_PKEY_CTX *hctx = ctx->data;
+	ASN1_OCTET_STRING *key;
+	switch (type)
+		{
+
+		case EVP_PKEY_CTRL_SET_MAC_KEY:
+		if ((!p2 && p1 > 0) || (p1 < -1))
+			return 0;
+		if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1))
+			return 0;
+		break;
+
+		case EVP_PKEY_CTRL_MD:
+		hctx->md = p2;
+		break;
+
+		case EVP_PKEY_CTRL_DIGESTINIT:
+		key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
+		HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md,
+				ctx->engine);
+		break;
+
+		default:
+		return -2;
+
+		}
+	return 1;
+	}
+
+static int pkey_hmac_ctrl_str(EVP_PKEY_CTX *ctx,
+			const char *type, const char *value)
+	{
+	if (!value)
+		{
+		return 0;
+		}
+	if (!strcmp(type, "key"))
+		{
+		void *p = (void *)value;
+		return pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
+				-1, p);
+		}
+	if (!strcmp(type, "hexkey"))
+		{
+		unsigned char *key;
+		int r;
+		long keylen;
+		key = string_to_hex(value, &keylen);
+		if (!key)
+			return 0;
+		r = pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key);
+		OPENSSL_free(key);
+		return r;
+		}
+	return -2;
+	}
+
+const EVP_PKEY_METHOD hmac_pkey_meth = 
+	{
+	EVP_PKEY_HMAC,
+	0,
+	pkey_hmac_init,
+	pkey_hmac_copy,
+	pkey_hmac_cleanup,
+
+	0, 0,
+
+	0,
+	pkey_hmac_keygen,
+
+	0, 0,
+
+	0, 0,
+
+	0,0,
+
+	hmac_signctx_init,
+	hmac_signctx,
+
+	0,0,
+
+	0,0,
+
+	0,0,
+
+	0,0,
+
+	pkey_hmac_ctrl,
+	pkey_hmac_ctrl_str
+
+	};
diff --git a/crypto/hmac/hmac.c b/crypto/hmac/hmac.c
index cbc1c76..45015fe 100644
--- a/crypto/hmac/hmac.c
+++ b/crypto/hmac/hmac.c
@@ -61,9 +61,7 @@
 #include "cryptlib.h"
 #include <openssl/hmac.h>
 
-#ifndef OPENSSL_FIPS
-
-void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
+int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
 		  const EVP_MD *md, ENGINE *impl)
 	{
 	int i,j,reset=0;
@@ -84,10 +82,13 @@
 		OPENSSL_assert(j <= (int)sizeof(ctx->key));
 		if (j < len)
 			{
-			EVP_DigestInit_ex(&ctx->md_ctx,md, impl);
-			EVP_DigestUpdate(&ctx->md_ctx,key,len);
-			EVP_DigestFinal_ex(&(ctx->md_ctx),ctx->key,
-				&ctx->key_length);
+			if (!EVP_DigestInit_ex(&ctx->md_ctx,md, impl))
+				goto err;
+			if (!EVP_DigestUpdate(&ctx->md_ctx,key,len))
+				goto err;
+			if (!EVP_DigestFinal_ex(&(ctx->md_ctx),ctx->key,
+				&ctx->key_length))
+				goto err;
 			}
 		else
 			{
@@ -104,31 +105,38 @@
 		{
 		for (i=0; i<HMAC_MAX_MD_CBLOCK; i++)
 			pad[i]=0x36^ctx->key[i];
-		EVP_DigestInit_ex(&ctx->i_ctx,md, impl);
-		EVP_DigestUpdate(&ctx->i_ctx,pad,EVP_MD_block_size(md));
+		if (!EVP_DigestInit_ex(&ctx->i_ctx,md, impl))
+			goto err;
+		if (!EVP_DigestUpdate(&ctx->i_ctx,pad,EVP_MD_block_size(md)))
+			goto err;
 
 		for (i=0; i<HMAC_MAX_MD_CBLOCK; i++)
 			pad[i]=0x5c^ctx->key[i];
-		EVP_DigestInit_ex(&ctx->o_ctx,md, impl);
-		EVP_DigestUpdate(&ctx->o_ctx,pad,EVP_MD_block_size(md));
+		if (!EVP_DigestInit_ex(&ctx->o_ctx,md, impl))
+			goto err;
+		if (!EVP_DigestUpdate(&ctx->o_ctx,pad,EVP_MD_block_size(md)))
+			goto err;
 		}
-	EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->i_ctx);
+	if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->i_ctx))
+			goto err;
+	return 1;
+	err:
+	return 0;
 	}
 
-void HMAC_Init(HMAC_CTX *ctx, const void *key, int len,
-	       const EVP_MD *md)
+int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md)
 	{
 	if(key && md)
 	    HMAC_CTX_init(ctx);
-	HMAC_Init_ex(ctx,key,len,md, NULL);
+	return HMAC_Init_ex(ctx,key,len,md, NULL);
 	}
 
-void HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
+int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
 	{
-	EVP_DigestUpdate(&ctx->md_ctx,data,len);
+	return EVP_DigestUpdate(&ctx->md_ctx,data,len);
 	}
 
-void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
+int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
 	{
 	int j;
 	unsigned int i;
@@ -136,10 +144,17 @@
 
 	j=EVP_MD_block_size(ctx->md);
 
-	EVP_DigestFinal_ex(&ctx->md_ctx,buf,&i);
-	EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->o_ctx);
-	EVP_DigestUpdate(&ctx->md_ctx,buf,i);
-	EVP_DigestFinal_ex(&ctx->md_ctx,md,len);
+	if (!EVP_DigestFinal_ex(&ctx->md_ctx,buf,&i))
+		goto err;
+	if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->o_ctx))
+		goto err;
+	if (!EVP_DigestUpdate(&ctx->md_ctx,buf,i))
+		goto err;
+	if (!EVP_DigestFinal_ex(&ctx->md_ctx,md,len))
+		goto err;
+	return 1;
+	err:
+	return 0;
 	}
 
 void HMAC_CTX_init(HMAC_CTX *ctx)
@@ -149,6 +164,22 @@
 	EVP_MD_CTX_init(&ctx->md_ctx);
 	}
 
+int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
+	{
+	if (!EVP_MD_CTX_copy(&dctx->i_ctx, &sctx->i_ctx))
+		goto err;
+	if (!EVP_MD_CTX_copy(&dctx->o_ctx, &sctx->o_ctx))
+		goto err;
+	if (!EVP_MD_CTX_copy(&dctx->md_ctx, &sctx->md_ctx))
+		goto err;
+	memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK);
+	dctx->key_length = sctx->key_length;
+	dctx->md = sctx->md;
+	return 1;
+	err:
+	return 0;
+	}
+
 void HMAC_CTX_cleanup(HMAC_CTX *ctx)
 	{
 	EVP_MD_CTX_cleanup(&ctx->i_ctx);
@@ -166,11 +197,16 @@
 
 	if (md == NULL) md=m;
 	HMAC_CTX_init(&c);
-	HMAC_Init(&c,key,key_len,evp_md);
-	HMAC_Update(&c,d,n);
-	HMAC_Final(&c,md,md_len);
+	if (!HMAC_Init(&c,key,key_len,evp_md))
+		goto err;
+	if (!HMAC_Update(&c,d,n))
+		goto err;
+	if (!HMAC_Final(&c,md,md_len))
+		goto err;
 	HMAC_CTX_cleanup(&c);
-	return(md);
+	return md;
+	err:
+	return NULL;
 	}
 
 void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags)
@@ -179,5 +215,3 @@
 	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 fc38ffb..1be0022 100644
--- a/crypto/hmac/hmac.h
+++ b/crypto/hmac/hmac.h
@@ -90,15 +90,16 @@
 
 #define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx) /* deprecated */
 
-void HMAC_Init(HMAC_CTX *ctx, const void *key, int len,
+int HMAC_Init(HMAC_CTX *ctx, const void *key, int len,
 	       const EVP_MD *md); /* deprecated */
-void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
+int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
 		  const EVP_MD *md, ENGINE *impl);
-void HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len);
-void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
+int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len);
+int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
 unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
 		    const unsigned char *d, size_t n, unsigned char *md,
 		    unsigned int *md_len);
+int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx);
 
 void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags);
 
diff --git a/crypto/ia64cpuid.S b/crypto/ia64cpuid.S
index 04fbb34..d705fff 100644
--- a/crypto/ia64cpuid.S
+++ b/crypto/ia64cpuid.S
@@ -1,6 +1,13 @@
 // Works on all IA-64 platforms: Linux, HP-UX, Win64i...
 // On Win64i compile with ias.exe.
 .text
+
+.global	OPENSSL_cpuid_setup#
+.proc	OPENSSL_cpuid_setup#
+OPENSSL_cpuid_setup:
+{ .mib;	br.ret.sptk.many	b0		};;
+.endp	OPENSSL_cpuid_setup#
+
 .global	OPENSSL_rdtsc#
 .proc	OPENSSL_rdtsc#
 OPENSSL_rdtsc:
@@ -119,3 +126,42 @@
 	mov		ar.lc=r3
 	br.ret.sptk	b0		};;
 .endp	OPENSSL_wipe_cpu#
+
+.global	OPENSSL_cleanse#
+.proc	OPENSSL_cleanse#
+OPENSSL_cleanse:
+{ .mib;	cmp.eq		p6,p0=0,r33	    // len==0
+#if defined(_HPUX_SOURCE) && !defined(_LP64)
+	addp4		r32=0,r32
+#endif
+(p6)	br.ret.spnt	b0		};;
+{ .mib;	and		r2=7,r32
+	cmp.leu		p6,p0=15,r33	    // len>=15
+(p6)	br.cond.dptk	.Lot		};;
+
+.Little:
+{ .mib;	st1		[r32]=r0,1
+	cmp.ltu		p6,p7=1,r33	}  // len>1
+{ .mbb;	add		r33=-1,r33	   // len--
+(p6)	br.cond.dptk	.Little
+(p7)	br.ret.sptk.many	b0	};;
+
+.Lot:
+{ .mib;	cmp.eq		p6,p0=0,r2
+(p6)	br.cond.dptk	.Laligned	};;
+{ .mmi;	st1		[r32]=r0,1;;
+	and		r2=7,r32	}
+{ .mib;	add		r33=-1,r33
+	br		.Lot		};;
+
+.Laligned:
+{ .mmi;	st8		[r32]=r0,8
+	and		r2=-8,r33	    // len&~7
+	add		r33=-8,r33	};; // len-=8
+{ .mib;	cmp.ltu		p6,p0=8,r2	    // ((len+8)&~7)>8
+(p6)	br.cond.dptk	.Laligned	};;
+
+{ .mbb;	cmp.eq		p6,p7=r0,r33
+(p7)	br.cond.dpnt	.Little
+(p6)	br.ret.sptk.many	b0	};;
+.endp	OPENSSL_cleanse#
diff --git a/crypto/install.com b/crypto/install.com
index 5e6d97e..ad3e4d4 100644
--- a/crypto/install.com
+++ b/crypto/install.com
@@ -41,16 +41,17 @@
 	   CREATE/DIR/LOG WRK_SSLINCLUDE:
 $
 $	SDIRS := ,-
+		 _'ARCH',-
 		 OBJECTS,-
-		 MD2,MD4,MD5,SHA,MDC2,HMAC,RIPEMD,-
+		 MD2,MD4,MD5,SHA,MDC2,HMAC,RIPEMD,WHRLPOOL,-
 		 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,PQUEUE,JPAKE
-$	EXHEADER_ := crypto.h,tmdiff.h,opensslv.h,opensslconf.h,ebcdic.h,-
-		symhacks.h,ossl_typ.h
+		 STORE,CMS,PQUEUE,TS,JPAKE
+$	EXHEADER_ := crypto.h,opensslv.h,ebcdic.h,symhacks.h,ossl_typ.h
+$	EXHEADER__'ARCH' := opensslconf.h
 $	EXHEADER_OBJECTS := objects.h,obj_mac.h
 $	EXHEADER_MD2 := md2.h
 $	EXHEADER_MD4 := md4.h
@@ -59,6 +60,7 @@
 $	EXHEADER_MDC2 := mdc2.h
 $	EXHEADER_HMAC := hmac.h
 $	EXHEADER_RIPEMD := ripemd.h
+$	EXHEADER_WHRLPOOL := whrlpool.h
 $	EXHEADER_DES := des.h,des_old.h
 $	EXHEADER_AES := aes.h
 $	EXHEADER_RC2 := rc2.h
@@ -69,6 +71,7 @@
 $	EXHEADER_CAST := cast.h
 $	EXHEADER_CAMELLIA := camellia.h
 $	EXHEADER_SEED := seed.h
+$	EXHEADER_MODES := modes.h
 $	EXHEADER_BN := bn.h
 $	EXHEADER_EC := ec.h
 $	EXHEADER_RSA := rsa.h
@@ -99,7 +102,9 @@
 $	EXHEADER_KRB5 := krb5_asn.h
 $!	EXHEADER_STORE := store.h,str_compat.h
 $	EXHEADER_STORE := store.h
-$	EXHEADER_PQUEUE := pqueue.h,pq_compat.h
+$	EXHEADER_CMS := cms.h
+$	EXHEADER_PQUEUE := pqueue.h
+$	EXHEADER_TS := ts.h
 $	EXHEADER_JPAKE := jpake.h
 $	LIBS := LIBCRYPTO
 $
@@ -115,7 +120,12 @@
 $	THEN
 $	  COPY 'tmp' WRK_SSLINCLUDE: /LOG
 $	ELSE
-$	  COPY [.'D']'tmp' WRK_SSLINCLUDE: /LOG
+$	  IF D .EQS. "_''ARCH'"
+$	  THEN
+$	    COPY [-.'ARCH'.CRYPTO]'tmp' WRK_SSLINCLUDE: /LOG
+$	  ELSE
+$	    COPY [.'D']'tmp' WRK_SSLINCLUDE: /LOG
+$	  ENDIF
 $	ENDIF
 $	SET FILE/PROT=WORLD:RE WRK_SSLINCLUDE:'tmp'
 $	GOTO LOOP_SDIRS
diff --git a/crypto/jpake/Makefile b/crypto/jpake/Makefile
deleted file mode 100644
index a4a1402..0000000
--- a/crypto/jpake/Makefile
+++ /dev/null
@@ -1,64 +0,0 @@
-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
index 577b7ef..086d9f4 100644
--- a/crypto/jpake/jpake.c
+++ b/crypto/jpake/jpake.c
@@ -4,7 +4,6 @@
 #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
@@ -134,7 +133,7 @@
     {
     unsigned char b[2];
 
-    assert(l <= 0xffff);
+    OPENSSL_assert(l <= 0xffff);
     b[0] = l >> 8;
     b[1] = l&0xff;
     SHA1_Update(sha, b, 2);
@@ -172,7 +171,7 @@
     */
     SHA1_Init(&sha);
     hashbn(&sha, zkpg);
-    assert(!BN_is_zero(p->zkpx.gr));
+    OPENSSL_assert(!BN_is_zero(p->zkpx.gr));
     hashbn(&sha, p->zkpx.gr);
     hashbn(&sha, p->gx);
     hashstring(&sha, proof_name);
diff --git a/crypto/jpake/jpaketest.c b/crypto/jpake/jpaketest.c
index 792fc49..eaba75e 100644
--- a/crypto/jpake/jpaketest.c
+++ b/crypto/jpake/jpaketest.c
@@ -182,7 +182,7 @@
     BN_free(p);
 
     CRYPTO_cleanup_all_ex_data();
-    ERR_remove_state(0);
+    ERR_remove_thread_state(NULL);
     ERR_free_strings();
     CRYPTO_mem_leaks(bio_err);
 
diff --git a/crypto/krb5/Makefile b/crypto/krb5/Makefile
deleted file mode 100644
index 8efb9e8..0000000
--- a/crypto/krb5/Makefile
+++ /dev/null
@@ -1,84 +0,0 @@
-#
-# OpenSSL/krb5/Makefile
-#
-
-DIR=	krb5
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile README
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC= krb5_asn.c
-
-LIBOBJ= krb5_asn.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= krb5_asn.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-depend:
-	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
-	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(LIBSRC)
-
-dclean:
-	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
-	mv -f Makefile.new $(MAKEFILE)
-
-clean:
-	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-krb5_asn.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
-krb5_asn.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
-krb5_asn.o: ../../include/openssl/e_os2.h ../../include/openssl/krb5_asn.h
-krb5_asn.o: ../../include/openssl/opensslconf.h
-krb5_asn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-krb5_asn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-krb5_asn.o: ../../include/openssl/symhacks.h krb5_asn.c
diff --git a/crypto/lhash/Makefile b/crypto/lhash/Makefile
deleted file mode 100644
index 35f0932..0000000
--- a/crypto/lhash/Makefile
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# OpenSSL/crypto/lhash/Makefile
-#
-
-DIR=	lhash
-TOP=	../..
-CC=	cc
-INCLUDES=
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=lhash.c lh_stats.c
-LIBOBJ=lhash.o lh_stats.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= lhash.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-lh_stats.o: ../../e_os.h ../../include/openssl/bio.h
-lh_stats.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-lh_stats.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-lh_stats.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-lh_stats.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-lh_stats.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-lh_stats.o: ../../include/openssl/symhacks.h ../cryptlib.h lh_stats.c
-lhash.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
-lhash.o: ../../include/openssl/e_os2.h ../../include/openssl/lhash.h
-lhash.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-lhash.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-lhash.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h lhash.c
diff --git a/crypto/lhash/lh_stats.c b/crypto/lhash/lh_stats.c
index 5aa7766..815615e 100644
--- a/crypto/lhash/lh_stats.c
+++ b/crypto/lhash/lh_stats.c
@@ -139,7 +139,7 @@
 #else
 
 #ifndef OPENSSL_NO_FP_API
-void lh_stats(const LHASH *lh, FILE *fp)
+void lh_stats(const _LHASH *lh, FILE *fp)
 	{
 	BIO *bp;
 
@@ -151,7 +151,7 @@
 end:;
 	}
 
-void lh_node_stats(const LHASH *lh, FILE *fp)
+void lh_node_stats(const _LHASH *lh, FILE *fp)
 	{
 	BIO *bp;
 
@@ -163,7 +163,7 @@
 end:;
 	}
 
-void lh_node_usage_stats(const LHASH *lh, FILE *fp)
+void lh_node_usage_stats(const _LHASH *lh, FILE *fp)
 	{
 	BIO *bp;
 
@@ -177,7 +177,7 @@
 
 #endif
 
-void lh_stats_bio(const LHASH *lh, BIO *out)
+void lh_stats_bio(const _LHASH *lh, BIO *out)
 	{
 	BIO_printf(out,"num_items             = %lu\n",lh->num_items);
 	BIO_printf(out,"num_nodes             = %u\n",lh->num_nodes);
@@ -205,7 +205,7 @@
 #endif
 	}
 
-void lh_node_stats_bio(const LHASH *lh, BIO *out)
+void lh_node_stats_bio(const _LHASH *lh, BIO *out)
 	{
 	LHASH_NODE *n;
 	unsigned int i,num;
@@ -218,7 +218,7 @@
 		}
 	}
 
-void lh_node_usage_stats_bio(const LHASH *lh, BIO *out)
+void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out)
 	{
 	LHASH_NODE *n;
 	unsigned long num;
diff --git a/crypto/lhash/lhash.c b/crypto/lhash/lhash.c
index 0b41f87..47f7480 100644
--- a/crypto/lhash/lhash.c
+++ b/crypto/lhash/lhash.c
@@ -107,18 +107,18 @@
 #define UP_LOAD		(2*LH_LOAD_MULT) /* load times 256  (default 2) */
 #define DOWN_LOAD	(LH_LOAD_MULT)   /* load times 256  (default 1) */
 
-static void expand(LHASH *lh);
-static void contract(LHASH *lh);
-static LHASH_NODE **getrn(LHASH *lh, const void *data, unsigned long *rhash);
+static void expand(_LHASH *lh);
+static void contract(_LHASH *lh);
+static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash);
 
-LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c)
+_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c)
 	{
-	LHASH *ret;
+	_LHASH *ret;
 	int i;
 
-	if ((ret=(LHASH *)OPENSSL_malloc(sizeof(LHASH))) == NULL)
+	if ((ret=OPENSSL_malloc(sizeof(_LHASH))) == NULL)
 		goto err0;
-	if ((ret->b=(LHASH_NODE **)OPENSSL_malloc(sizeof(LHASH_NODE *)*MIN_NODES)) == NULL)
+	if ((ret->b=OPENSSL_malloc(sizeof(LHASH_NODE *)*MIN_NODES)) == NULL)
 		goto err1;
 	for (i=0; i<MIN_NODES; i++)
 		ret->b[i]=NULL;
@@ -154,7 +154,7 @@
 	return(NULL);
 	}
 
-void lh_free(LHASH *lh)
+void lh_free(_LHASH *lh)
 	{
 	unsigned int i;
 	LHASH_NODE *n,*nn;
@@ -176,7 +176,7 @@
 	OPENSSL_free(lh);
 	}
 
-void *lh_insert(LHASH *lh, void *data)
+void *lh_insert(_LHASH *lh, void *data)
 	{
 	unsigned long hash;
 	LHASH_NODE *nn,**rn;
@@ -214,7 +214,7 @@
 	return(ret);
 	}
 
-void *lh_delete(LHASH *lh, const void *data)
+void *lh_delete(_LHASH *lh, const void *data)
 	{
 	unsigned long hash;
 	LHASH_NODE *nn,**rn;
@@ -245,7 +245,7 @@
 	return(ret);
 	}
 
-void *lh_retrieve(LHASH *lh, const void *data)
+void *lh_retrieve(_LHASH *lh, const void *data)
 	{
 	unsigned long hash;
 	LHASH_NODE **rn;
@@ -267,12 +267,15 @@
 	return(ret);
 	}
 
-static void doall_util_fn(LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func,
+static void doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func,
 			  LHASH_DOALL_ARG_FN_TYPE func_arg, void *arg)
 	{
 	int i;
 	LHASH_NODE *a,*n;
 
+	if (lh == NULL)
+		return;
+
 	/* reverse the order so we search from 'top to bottom'
 	 * We were having memory leaks otherwise */
 	for (i=lh->num_nodes-1; i>=0; i--)
@@ -282,6 +285,8 @@
 			{
 			/* 28/05/91 - eay - n added so items can be deleted
 			 * via lh_doall */
+			/* 22/05/08 - ben - eh? since a is not passed,
+			 * this should not be needed */
 			n=a->next;
 			if(use_arg)
 				func_arg(a->data,arg);
@@ -292,53 +297,29 @@
 		}
 	}
 
-void lh_doall(LHASH *lh, LHASH_DOALL_FN_TYPE func)
+void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func)
 	{
 	doall_util_fn(lh, 0, func, (LHASH_DOALL_ARG_FN_TYPE)0, NULL);
 	}
 
-void lh_doall_arg(LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg)
+void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg)
 	{
 	doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg);
 	}
 
-static void expand(LHASH *lh)
+static void expand(_LHASH *lh)
 	{
 	LHASH_NODE **n,**n1,**n2,*np;
-	unsigned int p,i,j,pmax;
+	unsigned int p,i,j;
 	unsigned long hash,nni;
 
-	p=(int)lh->p++;
-	nni=lh->num_alloc_nodes;
-	pmax=lh->pmax;
-
-	if ((lh->p) >= lh->pmax)
-		{
-		j=(int)lh->num_alloc_nodes*2;
-		n=(LHASH_NODE **)OPENSSL_realloc(lh->b,
-			(int)sizeof(LHASH_NODE *)*j);
-		if (n == NULL)
-			{
-/*			fputs("realloc error in lhash",stderr); */
-			lh->error++;
-			lh->p=0;
-			return;
-			}
-		/* else */
-		for (i=(int)lh->num_alloc_nodes; i<j; i++)/* 26/02/92 eay */
-			n[i]=NULL;			  /* 02/03/92 eay */
-		lh->pmax=lh->num_alloc_nodes;
-		lh->num_alloc_nodes=j;
-		lh->num_expand_reallocs++;
-		lh->p=0;
-		lh->b=n;
-		}
-
 	lh->num_nodes++;
 	lh->num_expands++;
+	p=(int)lh->p++;
 	n1= &(lh->b[p]);
-	n2= &(lh->b[p+pmax]);
+	n2= &(lh->b[p+(int)lh->pmax]);
 	*n2=NULL;        /* 27/07/92 - eay - undefined pointer bug */
+	nni=lh->num_alloc_nodes;
 	
 	for (np= *n1; np != NULL; )
 		{
@@ -359,14 +340,35 @@
 		np= *n1;
 		}
 
+	if ((lh->p) >= lh->pmax)
+		{
+		j=(int)lh->num_alloc_nodes*2;
+		n=(LHASH_NODE **)OPENSSL_realloc(lh->b,
+			(int)(sizeof(LHASH_NODE *)*j));
+		if (n == NULL)
+			{
+/*			fputs("realloc error in lhash",stderr); */
+			lh->error++;
+			lh->p=0;
+			return;
+			}
+		/* else */
+		for (i=(int)lh->num_alloc_nodes; i<j; i++)/* 26/02/92 eay */
+			n[i]=NULL;			  /* 02/03/92 eay */
+		lh->pmax=lh->num_alloc_nodes;
+		lh->num_alloc_nodes=j;
+		lh->num_expand_reallocs++;
+		lh->p=0;
+		lh->b=n;
+		}
 	}
 
-static void contract(LHASH *lh)
+static void contract(_LHASH *lh)
 	{
 	LHASH_NODE **n,*n1,*np;
-	int idx = lh->p+lh->pmax-1;
 
-	np=lh->b[idx];
+	np=lh->b[lh->p+lh->pmax-1];
+	lh->b[lh->p+lh->pmax-1]=NULL; /* 24/07-92 - eay - weird but :-( */
 	if (lh->p == 0)
 		{
 		n=(LHASH_NODE **)OPENSSL_realloc(lh->b,
@@ -386,7 +388,6 @@
 	else
 		lh->p--;
 
-	lh->b[idx] = NULL;
 	lh->num_nodes--;
 	lh->num_contracts++;
 
@@ -401,7 +402,7 @@
 		}
 	}
 
-static LHASH_NODE **getrn(LHASH *lh, const void *data, unsigned long *rhash)
+static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash)
 	{
 	LHASH_NODE **ret,*n1;
 	unsigned long hash,nn;
@@ -468,7 +469,7 @@
 	return((ret>>16)^ret);
 	}
 
-unsigned long lh_num_items(const LHASH *lh)
+unsigned long lh_num_items(const _LHASH *lh)
 	{
 	return lh ? lh->num_items : 0;
 	}
diff --git a/crypto/lhash/lhash.h b/crypto/lhash/lhash.h
index d392d0c..e7d8763 100644
--- a/crypto/lhash/lhash.h
+++ b/crypto/lhash/lhash.h
@@ -98,42 +98,42 @@
  * macros if the functions are strictly internal. */
 
 /* First: "hash" functions */
-#define DECLARE_LHASH_HASH_FN(f_name,o_type) \
-	unsigned long f_name##_LHASH_HASH(const void *);
-#define IMPLEMENT_LHASH_HASH_FN(f_name,o_type) \
-	unsigned long f_name##_LHASH_HASH(const void *arg) { \
-		o_type a = (o_type)arg; \
-		return f_name(a); }
-#define LHASH_HASH_FN(f_name) f_name##_LHASH_HASH
+#define DECLARE_LHASH_HASH_FN(name, o_type) \
+	unsigned long name##_LHASH_HASH(const void *);
+#define IMPLEMENT_LHASH_HASH_FN(name, o_type) \
+	unsigned long name##_LHASH_HASH(const void *arg) { \
+		const o_type *a = arg; \
+		return name##_hash(a); }
+#define LHASH_HASH_FN(name) name##_LHASH_HASH
 
 /* Second: "compare" functions */
-#define DECLARE_LHASH_COMP_FN(f_name,o_type) \
-	int f_name##_LHASH_COMP(const void *, const void *);
-#define IMPLEMENT_LHASH_COMP_FN(f_name,o_type) \
-	int f_name##_LHASH_COMP(const void *arg1, const void *arg2) { \
-		o_type a = (o_type)arg1; \
-		o_type b = (o_type)arg2; \
-		return f_name(a,b); }
-#define LHASH_COMP_FN(f_name) f_name##_LHASH_COMP
+#define DECLARE_LHASH_COMP_FN(name, o_type) \
+	int name##_LHASH_COMP(const void *, const void *);
+#define IMPLEMENT_LHASH_COMP_FN(name, o_type) \
+	int name##_LHASH_COMP(const void *arg1, const void *arg2) { \
+		const o_type *a = arg1;		    \
+		const o_type *b = arg2; \
+		return name##_cmp(a,b); }
+#define LHASH_COMP_FN(name) name##_LHASH_COMP
 
 /* Third: "doall" functions */
-#define DECLARE_LHASH_DOALL_FN(f_name,o_type) \
-	void f_name##_LHASH_DOALL(void *);
-#define IMPLEMENT_LHASH_DOALL_FN(f_name,o_type) \
-	void f_name##_LHASH_DOALL(void *arg) { \
-		o_type a = (o_type)arg; \
-		f_name(a); }
-#define LHASH_DOALL_FN(f_name) f_name##_LHASH_DOALL
+#define DECLARE_LHASH_DOALL_FN(name, o_type) \
+	void name##_LHASH_DOALL(void *);
+#define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \
+	void name##_LHASH_DOALL(void *arg) { \
+		o_type *a = arg; \
+		name##_doall(a); }
+#define LHASH_DOALL_FN(name) name##_LHASH_DOALL
 
 /* Fourth: "doall_arg" functions */
-#define DECLARE_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \
-	void f_name##_LHASH_DOALL_ARG(void *, void *);
-#define IMPLEMENT_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \
-	void f_name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
-		o_type a = (o_type)arg1; \
-		a_type b = (a_type)arg2; \
-		f_name(a,b); }
-#define LHASH_DOALL_ARG_FN(f_name) f_name##_LHASH_DOALL_ARG
+#define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
+	void name##_LHASH_DOALL_ARG(void *, void *);
+#define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
+	void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
+		o_type *a = arg1; \
+		a_type *b = arg2; \
+		name##_doall_arg(a, b); }
+#define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG
 
 typedef struct lhash_st
 	{
@@ -163,7 +163,8 @@
 	unsigned long num_hash_comps;
 
 	int error;
-	} LHASH;
+	} _LHASH;	/* Do not use _LHASH directly, use LHASH_OF
+			 * and friends */
 
 #define LH_LOAD_MULT	256
 
@@ -171,27 +172,67 @@
  * in lh_insert(). */
 #define lh_error(lh)	((lh)->error)
 
-LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c);
-void lh_free(LHASH *lh);
-void *lh_insert(LHASH *lh, void *data);
-void *lh_delete(LHASH *lh, const void *data);
-void *lh_retrieve(LHASH *lh, const void *data);
-void lh_doall(LHASH *lh, LHASH_DOALL_FN_TYPE func);
-void lh_doall_arg(LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg);
+_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c);
+void lh_free(_LHASH *lh);
+void *lh_insert(_LHASH *lh, void *data);
+void *lh_delete(_LHASH *lh, const void *data);
+void *lh_retrieve(_LHASH *lh, const void *data);
+void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func);
+void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg);
 unsigned long lh_strhash(const char *c);
-unsigned long lh_num_items(const LHASH *lh);
+unsigned long lh_num_items(const _LHASH *lh);
 
 #ifndef OPENSSL_NO_FP_API
-void lh_stats(const LHASH *lh, FILE *out);
-void lh_node_stats(const LHASH *lh, FILE *out);
-void lh_node_usage_stats(const LHASH *lh, FILE *out);
+void lh_stats(const _LHASH *lh, FILE *out);
+void lh_node_stats(const _LHASH *lh, FILE *out);
+void lh_node_usage_stats(const _LHASH *lh, FILE *out);
 #endif
 
 #ifndef OPENSSL_NO_BIO
-void lh_stats_bio(const LHASH *lh, BIO *out);
-void lh_node_stats_bio(const LHASH *lh, BIO *out);
-void lh_node_usage_stats_bio(const LHASH *lh, BIO *out);
+void lh_stats_bio(const _LHASH *lh, BIO *out);
+void lh_node_stats_bio(const _LHASH *lh, BIO *out);
+void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out);
 #endif
+
+/* Type checking... */
+
+#define LHASH_OF(type) struct lhash_st_##type
+
+#define DECLARE_LHASH_OF(type) LHASH_OF(type) { int dummy; }
+
+#define CHECKED_LHASH_OF(type,lh) \
+  ((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh))
+
+/* Define wrapper functions. */
+#define LHM_lh_new(type, name) \
+  ((LHASH_OF(type) *)lh_new(LHASH_HASH_FN(name), LHASH_COMP_FN(name)))
+#define LHM_lh_error(type, lh) \
+  lh_error(CHECKED_LHASH_OF(type,lh))
+#define LHM_lh_insert(type, lh, inst) \
+  ((type *)lh_insert(CHECKED_LHASH_OF(type, lh), \
+		     CHECKED_PTR_OF(type, inst)))
+#define LHM_lh_retrieve(type, lh, inst) \
+  ((type *)lh_retrieve(CHECKED_LHASH_OF(type, lh), \
+		       CHECKED_PTR_OF(type, inst)))
+#define LHM_lh_delete(type, lh, inst) \
+  ((type *)lh_delete(CHECKED_LHASH_OF(type, lh),			\
+		     CHECKED_PTR_OF(type, inst)))
+#define LHM_lh_doall(type, lh,fn) lh_doall(CHECKED_LHASH_OF(type, lh), fn)
+#define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \
+  lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg))
+#define LHM_lh_num_items(type, lh) lh_num_items(CHECKED_LHASH_OF(type, lh))
+#define LHM_lh_down_load(type, lh) (CHECKED_LHASH_OF(type, lh)->down_load)
+#define LHM_lh_node_stats_bio(type, lh, out) \
+  lh_node_stats_bio(CHECKED_LHASH_OF(type, lh), out)
+#define LHM_lh_node_usage_stats_bio(type, lh, out) \
+  lh_node_usage_stats_bio(CHECKED_LHASH_OF(type, lh), out)
+#define LHM_lh_stats_bio(type, lh, out) \
+  lh_stats_bio(CHECKED_LHASH_OF(type, lh), out)
+#define LHM_lh_free(type, lh) lh_free(CHECKED_LHASH_OF(type, lh))
+
+DECLARE_LHASH_OF(OPENSSL_STRING);
+DECLARE_LHASH_OF(OPENSSL_CSTRING);
+
 #ifdef  __cplusplus
 }
 #endif
diff --git a/crypto/md32_common.h b/crypto/md32_common.h
index 61bcd97..1cb7839 100644
--- a/crypto/md32_common.h
+++ b/crypto/md32_common.h
@@ -241,11 +241,11 @@
 #ifndef PEDANTIC
 # if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
 #  if defined(__s390x__)
-#   define HOST_c2l(c,l)	({ asm ("lrv	%0,0(%1)"		\
-					:"=r"(l) : "r"(c));		\
+#   define HOST_c2l(c,l)	({ asm ("lrv	%0,%1"			\
+				   :"=d"(l) :"m"(*(const unsigned int *)(c)));\
 				   (c)+=4; (l);				})
-#   define HOST_l2c(l,c)	({ asm ("strv	%0,0(%1)"		\
-					: : "r"(l),"r"(c) : "memory");	\
+#   define HOST_l2c(l,c)	({ asm ("strv	%1,%0"			\
+				   :"=m"(*(unsigned int *)(c)) :"d"(l));\
 				   (c)+=4; (l);				})
 #  endif
 # endif
@@ -293,7 +293,7 @@
 	 * Wei Dai <weidai@eskimo.com> for pointing it out. */
 	if (l < c->Nl) /* overflow */
 		c->Nh++;
-	c->Nh+=(len>>29);	/* might cause compiler warning on 16-bit */
+	c->Nh+=(HASH_LONG)(len>>29);	/* might cause compiler warning on 16-bit */
 	c->Nl=l;
 
 	n = c->num;
@@ -331,7 +331,7 @@
 	if (len != 0)
 		{
 		p = (unsigned char *)c->data;
-		c->num = len;
+		c->num = (unsigned int)len;
 		memcpy (p,data,len);
 		}
 	return 1;
diff --git a/crypto/md4/Makefile b/crypto/md4/Makefile
deleted file mode 100644
index 0bc4896..0000000
--- a/crypto/md4/Makefile
+++ /dev/null
@@ -1,90 +0,0 @@
-#
-# OpenSSL/crypto/md4/Makefile
-#
-
-DIR=    md4
-TOP=    ../..
-CC=     cc
-CPP=    $(CC) -E
-INCLUDES=
-CFLAG=-g
-MAKEFILE=       Makefile
-AR=             ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=md4test.c
-APPS=md4.c
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=md4_dgst.c md4_one.c
-LIBOBJ=md4_dgst.o md4_one.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= md4.h
-HEADER= md4_locl.h $(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:    lib
-
-lib:    $(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 asm/mx86unix.cpp *.o asm/*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-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
-md4_one.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-md4_one.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-md4_one.o: ../../include/openssl/symhacks.h md4_one.c
diff --git a/crypto/md4/md4.h b/crypto/md4/md4.h
index ba1fe4a..c3ed9b3 100644
--- a/crypto/md4/md4.h
+++ b/crypto/md4/md4.h
@@ -77,7 +77,7 @@
  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  */
 
-#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#if defined(__LP32__)
 #define MD4_LONG unsigned long
 #elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
 #define MD4_LONG unsigned long
@@ -105,9 +105,6 @@
 	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 0f54486..e0c42e8 100644
--- a/crypto/md4/md4_dgst.c
+++ b/crypto/md4/md4_dgst.c
@@ -59,11 +59,6 @@
 #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;
 
@@ -75,15 +70,13 @@
 #define INIT_DATA_C (unsigned long)0x98badcfeL
 #define INIT_DATA_D (unsigned long)0x10325476L
 
-FIPS_NON_FIPS_MD_Init(MD4)
+int MD4_Init(MD4_CTX *c)
 	{
+	memset (c,0,sizeof(*c));
 	c->A=INIT_DATA_A;
 	c->B=INIT_DATA_B;
 	c->C=INIT_DATA_C;
 	c->D=INIT_DATA_D;
-	c->Nl=0;
-	c->Nh=0;
-	c->num=0;
 	return 1;
 	}
 
diff --git a/crypto/md5/Makefile b/crypto/md5/Makefile
deleted file mode 100644
index 3c450fc..0000000
--- a/crypto/md5/Makefile
+++ /dev/null
@@ -1,106 +0,0 @@
-#
-# OpenSSL/crypto/md5/Makefile
-#
-
-DIR=    md5
-TOP=    ../..
-CC=     cc
-CPP=    $(CC) -E
-INCLUDES=-I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=       Makefile
-AR=             ar r
-
-MD5_ASM_OBJ=
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-ASFLAGS= $(INCLUDES) $(ASFLAG)
-AFLAGS= $(ASFLAGS)
-
-GENERAL=Makefile
-TEST=md5test.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=md5_dgst.c md5_one.c
-LIBOBJ=md5_dgst.o md5_one.o $(MD5_ASM_OBJ)
-
-SRC= $(LIBSRC)
-
-EXHEADER= md5.h
-HEADER= md5_locl.h $(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:    lib
-
-lib:    $(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-# ELF
-mx86-elf.s: asm/md5-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) md5-586.pl elf $(CFLAGS) > ../$@)
-# COFF
-mx86-cof.s: asm/md5-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) md5-586.pl coff $(CFLAGS) > ../$@)
-# a.out
-mx86-out.s: asm/md5-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) md5-586.pl a.out $(CFLAGS) > ../$@)
-
-md5-x86_64.s:	asm/md5-x86_64.pl;	$(PERL) asm/md5-x86_64.pl $@
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-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
-md5_one.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-md5_one.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-md5_one.o: ../../include/openssl/symhacks.h md5_one.c
diff --git a/crypto/md5/asm/md5-586.pl b/crypto/md5/asm/md5-586.pl
index 76ac235..6cb66bb 100644
--- a/crypto/md5/asm/md5-586.pl
+++ b/crypto/md5/asm/md5-586.pl
@@ -7,7 +7,8 @@
 
 $normal=0;
 
-push(@INC,"perlasm","../../perlasm");
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
 require "x86asm.pl";
 
 &asm_init($ARGV[0],$0);
diff --git a/crypto/md5/asm/md5-ia64.S b/crypto/md5/asm/md5-ia64.S
new file mode 100644
index 0000000..2f9818a
--- /dev/null
+++ b/crypto/md5/asm/md5-ia64.S
@@ -0,0 +1,992 @@
+/* Copyright (c) 2005 Hewlett-Packard Development Company, L.P.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+//	Common registers are assigned as follows:
+//
+//	COMMON
+//
+//	t0		Const Tbl Ptr	TPtr
+//	t1		Round Constant	TRound
+//	t4		Block residual	LenResid
+//	t5		Residual Data	DTmp
+//
+//	{in,out}0	Block 0 Cycle	RotateM0
+//	{in,out}1	Block Value 12	M12
+//	{in,out}2	Block Value 8	M8
+//	{in,out}3	Block Value 4	M4
+//	{in,out}4	Block Value 0	M0
+//	{in,out}5	Block 1 Cycle	RotateM1
+//	{in,out}6	Block Value 13	M13
+//	{in,out}7	Block Value 9	M9
+//	{in,out}8	Block Value 5	M5
+//	{in,out}9	Block Value 1	M1
+//	{in,out}10	Block 2 Cycle	RotateM2
+//	{in,out}11	Block Value 14	M14
+//	{in,out}12	Block Value 10	M10
+//	{in,out}13	Block Value 6	M6
+//	{in,out}14	Block Value 2	M2
+//	{in,out}15	Block 3 Cycle	RotateM3
+//	{in,out}16	Block Value 15	M15
+//	{in,out}17	Block Value 11	M11
+//	{in,out}18	Block Value 7	M7
+//	{in,out}19	Block Value 3	M3
+//	{in,out}20	Scratch			Z
+//	{in,out}21	Scratch			Y
+//	{in,out}22	Scratch			X
+//	{in,out}23	Scratch			W
+//	{in,out}24	Digest A		A
+//	{in,out}25	Digest B		B
+//	{in,out}26	Digest C		C
+//	{in,out}27	Digest D		D
+//	{in,out}28	Active Data Ptr	DPtr
+//	in28		Dummy Value		-
+//	out28		Dummy Value		-
+//	bt0			Coroutine Link	QUICK_RTN
+//
+///	These predicates are used for computing the padding block(s) and
+///	are shared between the driver and digest co-routines
+//
+//	pt0			Extra Pad Block	pExtra
+//	pt1			Load next word	pLoad
+//	pt2			Skip next word	pSkip
+//	pt3			Search for Pad	pNoPad
+//	pt4			Pad Word 0		pPad0
+//	pt5			Pad Word 1		pPad1
+//	pt6			Pad Word 2		pPad2
+//	pt7			Pad Word 3		pPad3
+
+#define	DTmp		r19
+#define	LenResid	r18
+#define	QUICK_RTN	b6
+#define	TPtr		r14
+#define	TRound		r15
+#define	pExtra		p6
+#define	pLoad		p7
+#define	pNoPad		p9
+#define	pPad0		p10
+#define	pPad1		p11
+#define	pPad2		p12
+#define	pPad3		p13
+#define	pSkip		p8
+
+#define	A_		out24
+#define	B_		out25
+#define	C_		out26
+#define	D_		out27
+#define	DPtr_		out28
+#define	M0_		out4
+#define	M1_		out9
+#define	M10_		out12
+#define	M11_		out17
+#define	M12_		out1
+#define	M13_		out6
+#define	M14_		out11
+#define	M15_		out16
+#define	M2_		out14
+#define	M3_		out19
+#define	M4_		out3
+#define	M5_		out8
+#define	M6_		out13
+#define	M7_		out18
+#define	M8_		out2
+#define	M9_		out7
+#define	RotateM0_	out0
+#define	RotateM1_	out5
+#define	RotateM2_	out10
+#define	RotateM3_	out15
+#define	W_		out23
+#define	X_		out22
+#define	Y_		out21
+#define	Z_		out20
+
+#define	A		in24
+#define	B		in25
+#define	C		in26
+#define	D		in27
+#define	DPtr		in28
+#define	M0		in4
+#define	M1		in9
+#define	M10		in12
+#define	M11		in17
+#define	M12		in1
+#define	M13		in6
+#define	M14		in11
+#define	M15		in16
+#define	M2		in14
+#define	M3		in19
+#define	M4		in3
+#define	M5		in8
+#define	M6		in13
+#define	M7		in18
+#define	M8		in2
+#define	M9		in7
+#define	RotateM0	in0
+#define	RotateM1	in5
+#define	RotateM2	in10
+#define	RotateM3	in15
+#define	W		in23
+#define	X		in22
+#define	Y		in21
+#define	Z		in20
+
+/* register stack configuration for md5_block_asm_data_order(): */
+#define	MD5_NINP	3
+#define	MD5_NLOC	0
+#define MD5_NOUT	29
+#define MD5_NROT	0
+
+/* register stack configuration for helpers: */
+#define	_NINPUTS	MD5_NOUT
+#define	_NLOCALS	0
+#define _NOUTPUT	0
+#define	_NROTATE	24	/* this must be <= _NINPUTS */
+
+#if defined(_HPUX_SOURCE) && !defined(_LP64)
+#define	ADDP	addp4
+#else
+#define	ADDP	add
+#endif
+
+#if defined(_HPUX_SOURCE) || defined(B_ENDIAN)
+#define HOST_IS_BIG_ENDIAN
+#endif
+
+//	Macros for getting the left and right portions of little-endian words
+
+#define	GETLW(dst, src, align)	dep.z dst = src, 32 - 8 * align, 8 * align
+#define	GETRW(dst, src, align)	extr.u dst = src, 8 * align, 32 - 8 * align
+
+//	MD5 driver
+//
+//		Reads an input block, then calls the digest block
+//		subroutine and adds the results to the accumulated
+//		digest.  It allocates 32 outs which the subroutine
+//		uses as it's inputs and rotating
+//		registers. Initializes the round constant pointer and
+//		takes care of saving/restoring ar.lc
+//
+///	INPUT
+//
+//	in0		Context Ptr		CtxPtr0
+//	in1		Input Data Ptr		DPtrIn
+//	in2		Integral Blocks		BlockCount
+//	rp		Return Address		-
+//
+///	CODE
+//
+//	v2		Input Align		InAlign
+//	t0		Shared w/digest		-
+//	t1		Shared w/digest		-
+//	t2		Shared w/digest		-
+//	t3		Shared w/digest		-
+//	t4		Shared w/digest		-
+//	t5		Shared w/digest		-
+//	t6		PFS Save		PFSSave
+//	t7		ar.lc Save		LCSave
+//	t8		Saved PR		PRSave
+//	t9		2nd CtxPtr		CtxPtr1
+//	t10		Table Base		CTable
+//	t11		Table[0]		CTable0
+//	t13		Accumulator A		AccumA
+//	t14		Accumulator B		AccumB
+//	t15		Accumulator C		AccumC
+//	t16		Accumulator D		AccumD
+//	pt0		Shared w/digest		-
+//	pt1		Shared w/digest		-
+//	pt2		Shared w/digest		-
+//	pt3		Shared w/digest		-
+//	pt4		Shared w/digest		-
+//	pt5		Shared w/digest		-
+//	pt6		Shared w/digest		-
+//	pt7		Shared w/digest		-
+//	pt8		Not Aligned		pOff
+//	pt8		Blocks Left		pAgain
+
+#define	AccumA		r27
+#define	AccumB		r28
+#define	AccumC		r29
+#define	AccumD		r30
+#define	CTable		r24
+#define	CTable0		r25
+#define	CtxPtr0		in0
+#define	CtxPtr1		r23
+#define	DPtrIn		in1
+#define	BlockCount	in2
+#define	InAlign		r10
+#define	LCSave		r21
+#define	PFSSave		r20
+#define	PRSave		r22
+#define	pAgain		p63
+#define	pOff		p63
+
+	.text
+
+/* md5_block_asm_data_order(MD5_CTX *c, const void *data, size_t num)
+
+     where:
+      c: a pointer to a structure of this type:
+
+	   typedef struct MD5state_st
+	     {
+	       MD5_LONG A,B,C,D;
+	       MD5_LONG Nl,Nh;
+	       MD5_LONG data[MD5_LBLOCK];
+	       unsigned int num;
+	     }
+	   MD5_CTX;
+
+      data: a pointer to the input data (may be misaligned)
+      num:  the number of 16-byte blocks to hash (i.e., the length
+            of DATA is 16*NUM.
+
+   */
+
+	.type	md5_block_asm_data_order, @function
+	.global	md5_block_asm_data_order
+	.align	32
+	.proc	md5_block_asm_data_order
+md5_block_asm_data_order:
+.md5_block:
+	.prologue
+{	.mmi
+	.save	ar.pfs, PFSSave
+	alloc	PFSSave = ar.pfs, MD5_NINP, MD5_NLOC, MD5_NOUT, MD5_NROT
+	ADDP	CtxPtr1 = 8, CtxPtr0
+	mov	CTable = ip
+}
+{	.mmi
+	ADDP	DPtrIn = 0, DPtrIn
+	ADDP	CtxPtr0 = 0, CtxPtr0
+	.save	ar.lc, LCSave
+	mov	LCSave = ar.lc
+}
+;;
+{	.mmi
+	add	CTable = .md5_tbl_data_order#-.md5_block#, CTable
+	and	InAlign = 0x3, DPtrIn
+}
+
+{	.mmi
+	ld4	AccumA = [CtxPtr0], 4
+	ld4	AccumC = [CtxPtr1], 4
+	.save pr, PRSave
+	mov	PRSave = pr
+	.body
+}
+;;
+{	.mmi
+	ld4	AccumB = [CtxPtr0]
+	ld4	AccumD = [CtxPtr1]
+	dep	DPtr_ = 0, DPtrIn, 0, 2
+} ;;
+#ifdef HOST_IS_BIG_ENDIAN
+	rum	psr.be;;	// switch to little-endian
+#endif
+{	.mmb
+	ld4	CTable0 = [CTable], 4
+	cmp.ne	pOff, p0 = 0, InAlign
+(pOff)	br.cond.spnt.many .md5_unaligned
+} ;;
+
+//	The FF load/compute loop rotates values three times, so that
+//	loading into M12 here produces the M0 value, M13 -> M1, etc.
+
+.md5_block_loop0:
+{	.mmi
+	ld4	M12_ = [DPtr_], 4
+	mov	TPtr = CTable
+	mov	TRound = CTable0
+} ;;
+{	.mmi
+	ld4	M13_ = [DPtr_], 4
+	mov	A_ = AccumA
+	mov	B_ = AccumB
+} ;;
+{	.mmi
+	ld4	M14_ = [DPtr_], 4
+	mov	C_ = AccumC
+	mov	D_ = AccumD
+} ;;
+{	.mmb
+	ld4	M15_ = [DPtr_], 4
+	add	BlockCount = -1, BlockCount
+	br.call.sptk.many QUICK_RTN = md5_digest_block0
+} ;;
+
+//	Now, we add the new digest values and do some clean-up
+//	before checking if there's another full block to process
+
+{	.mmi
+	add	AccumA = AccumA, A_
+	add	AccumB = AccumB, B_
+	cmp.ne	pAgain, p0 = 0, BlockCount
+}
+{	.mib
+	add	AccumC = AccumC, C_
+	add	AccumD = AccumD, D_
+(pAgain) br.cond.dptk.many .md5_block_loop0
+} ;;
+
+.md5_exit:
+#ifdef HOST_IS_BIG_ENDIAN
+	sum	psr.be;;	// switch back to big-endian mode
+#endif
+{	.mmi
+	st4	[CtxPtr0] = AccumB, -4
+	st4	[CtxPtr1] = AccumD, -4
+	mov	pr = PRSave, 0x1ffff ;;
+}
+{	.mmi
+	st4	[CtxPtr0] = AccumA
+	st4	[CtxPtr1] = AccumC
+	mov	ar.lc = LCSave
+} ;;
+{	.mib
+	mov	ar.pfs = PFSSave
+	br.ret.sptk.few	rp
+} ;;
+
+#define	MD5UNALIGNED(offset)						\
+.md5_process##offset:							\
+{	.mib ;								\
+	nop	0x0	;						\
+	GETRW(DTmp, DTmp, offset) ;					\
+} ;;									\
+.md5_block_loop##offset:						\
+{	.mmi ;								\
+	ld4	Y_ = [DPtr_], 4 ;					\
+	mov	TPtr = CTable ;						\
+	mov	TRound = CTable0 ;					\
+} ;;									\
+{	.mmi ;								\
+	ld4	M13_ = [DPtr_], 4 ;					\
+	mov	A_ = AccumA ;						\
+	mov	B_ = AccumB ;						\
+} ;;									\
+{	.mii ;								\
+	ld4	M14_ = [DPtr_], 4 ;					\
+	GETLW(W_, Y_, offset) ;						\
+	mov	C_ = AccumC ;						\
+}									\
+{	.mmi ;								\
+	mov	D_ = AccumD ;;						\
+	or	M12_ = W_, DTmp ;					\
+	GETRW(DTmp, Y_, offset) ;					\
+}									\
+{	.mib ;								\
+	ld4	M15_ = [DPtr_], 4 ;					\
+	add	BlockCount = -1, BlockCount ;				\
+	br.call.sptk.many QUICK_RTN = md5_digest_block##offset;		\
+} ;;									\
+{	.mmi ;								\
+	add	AccumA = AccumA, A_ ;					\
+	add	AccumB = AccumB, B_ ;					\
+	cmp.ne	pAgain, p0 = 0, BlockCount ;				\
+}									\
+{	.mib ;								\
+	add	AccumC = AccumC, C_ ;					\
+	add	AccumD = AccumD, D_ ;					\
+(pAgain) br.cond.dptk.many .md5_block_loop##offset ;			\
+} ;;									\
+{	.mib ;								\
+	nop	0x0 ;							\
+	nop	0x0 ;							\
+	br.cond.sptk.many .md5_exit ;					\
+} ;;
+
+	.align	32
+.md5_unaligned:
+//
+//	Because variable shifts are expensive, we special case each of
+//	the four alignements. In practice, this won't hurt too much
+//	since only one working set of code will be loaded.
+//
+{	.mib
+	ld4	DTmp = [DPtr_], 4
+	cmp.eq	pOff, p0 = 1, InAlign
+(pOff)	br.cond.dpnt.many .md5_process1
+} ;;
+{	.mib
+	cmp.eq	pOff, p0 = 2, InAlign
+	nop	0x0
+(pOff)	br.cond.dpnt.many .md5_process2
+} ;;
+	MD5UNALIGNED(3)
+	MD5UNALIGNED(1)
+	MD5UNALIGNED(2)
+
+	.endp md5_block_asm_data_order
+
+
+// MD5 Perform the F function and load
+//
+// Passed the first 4 words (M0 - M3) and initial (A, B, C, D) values,
+// computes the FF() round of functions, then branches to the common
+// digest code to finish up with GG(), HH, and II().
+//
+// INPUT
+//
+// rp Return Address -
+//
+// CODE
+//
+// v0 PFS bit bucket PFS
+// v1 Loop Trip Count LTrip
+// pt0 Load next word pMore
+
+/* For F round: */
+#define LTrip	r9
+#define PFS	r8
+#define pMore	p6
+
+/* For GHI rounds: */
+#define T	r9
+#define U	r10
+#define V	r11
+
+#define COMPUTE(a, b, s, M, R)			\
+{						\
+	.mii ;					\
+	ld4 TRound = [TPtr], 4 ;		\
+	dep.z Y = Z, 32, 32 ;;			\
+	shrp Z = Z, Y, 64 - s ;			\
+} ;;						\
+{						\
+	.mmi ;					\
+	add a = Z, b ;				\
+	mov R = M ;				\
+	nop 0x0 ;				\
+} ;;
+
+#define LOOP(a, b, s, M, R, label)		\
+{	.mii ;					\
+	ld4 TRound = [TPtr], 4 ;		\
+	dep.z Y = Z, 32, 32 ;;			\
+	shrp Z = Z, Y, 64 - s ;			\
+} ;;						\
+{	.mib ;					\
+	add a = Z, b ;				\
+	mov R = M ;				\
+	br.ctop.sptk.many label ;		\
+} ;;
+
+// G(B, C, D) = (B & D) | (C & ~D)
+
+#define G(a, b, c, d, M)			\
+{	.mmi ;					\
+	add Z = M, TRound ;			\
+	and Y = b, d ;				\
+	andcm X = c, d ;			\
+} ;;						\
+{	.mii ;					\
+	add Z = Z, a ;				\
+	or Y = Y, X ;;				\
+	add Z = Z, Y ;				\
+} ;;
+
+// H(B, C, D) = B ^ C ^ D
+
+#define H(a, b, c, d, M)			\
+{	.mmi ;					\
+	add Z = M, TRound ;			\
+	xor Y = b, c ;				\
+	nop 0x0 ;				\
+} ;;						\
+{	.mii ;					\
+	add Z = Z, a ;				\
+	xor Y = Y, d ;;				\
+	add Z = Z, Y ;				\
+} ;;
+
+// I(B, C, D) = C ^ (B | ~D)
+//
+// However, since we have an andcm operator, we use the fact that
+//
+// Y ^ Z == ~Y ^ ~Z
+//
+// to rewrite the expression as
+//
+// I(B, C, D) = ~C ^ (~B & D)
+
+#define I(a, b, c, d, M)			\
+{	.mmi ;					\
+	add Z = M, TRound ;			\
+	andcm Y = d, b ;			\
+	andcm X = -1, c ;			\
+} ;;						\
+{	.mii ;					\
+	add Z = Z, a ;				\
+	xor Y = Y, X ;;				\
+	add Z = Z, Y ;				\
+} ;;
+
+#define GG4(label)				\
+	G(A, B, C, D, M0)			\
+	COMPUTE(A, B, 5, M0, RotateM0)		\
+	G(D, A, B, C, M1)			\
+	COMPUTE(D, A, 9, M1, RotateM1)		\
+	G(C, D, A, B, M2)			\
+	COMPUTE(C, D, 14, M2, RotateM2)		\
+	G(B, C, D, A, M3)			\
+	LOOP(B, C, 20, M3, RotateM3, label)
+
+#define HH4(label)				\
+	H(A, B, C, D, M0)			\
+	COMPUTE(A, B, 4, M0, RotateM0)		\
+	H(D, A, B, C, M1)			\
+	COMPUTE(D, A, 11, M1, RotateM1)		\
+	H(C, D, A, B, M2)			\
+	COMPUTE(C, D, 16, M2, RotateM2)		\
+	H(B, C, D, A, M3)			\
+	LOOP(B, C, 23, M3, RotateM3, label)
+
+#define II4(label)				\
+	I(A, B, C, D, M0)			\
+	COMPUTE(A, B, 6, M0, RotateM0)		\
+	I(D, A, B, C, M1)			\
+	COMPUTE(D, A, 10, M1, RotateM1)		\
+	I(C, D, A, B, M2)			\
+	COMPUTE(C, D, 15, M2, RotateM2)		\
+	I(B, C, D, A, M3)			\
+	LOOP(B, C, 21, M3, RotateM3, label)
+
+#define FFLOAD(a, b, c, d, M, N, s)		\
+{	.mii ;					\
+(pMore) ld4 N = [DPtr], 4 ;			\
+	add Z = M, TRound ;			\
+	and Y = c, b ;				\
+}						\
+{	.mmi ;					\
+	andcm X = d, b ;;			\
+	add Z = Z, a ;				\
+	or Y = Y, X ;				\
+} ;;						\
+{	.mii ;					\
+	ld4 TRound = [TPtr], 4 ;		\
+	add Z = Z, Y ;;				\
+	dep.z Y = Z, 32, 32 ;			\
+} ;;						\
+{	.mii ;					\
+	nop 0x0 ;				\
+	shrp Z = Z, Y, 64 - s ;;		\
+	add a = Z, b ;				\
+} ;;
+
+#define FFLOOP(a, b, c, d, M, N, s, dest)	\
+{	.mii ;					\
+(pMore)	ld4 N = [DPtr], 4 ;			\
+	add Z = M, TRound ;			\
+	and Y = c, b ;				\
+}						\
+{	.mmi ;					\
+	andcm X = d, b ;;			\
+	add Z = Z, a ;				\
+	or Y = Y, X ;				\
+} ;;						\
+{	.mii ;					\
+	ld4 TRound = [TPtr], 4 ;		\
+	add Z = Z, Y ;;				\
+	dep.z Y = Z, 32, 32 ;			\
+} ;;						\
+{	.mii ;					\
+	nop 0x0 ;				\
+	shrp Z = Z, Y, 64 - s ;;		\
+	add a = Z, b ;				\
+}						\
+{	.mib ;					\
+	cmp.ne pMore, p0 = 0, LTrip ;		\
+	add LTrip = -1, LTrip ;			\
+	br.ctop.dptk.many dest ;		\
+} ;;
+
+	.type md5_digest_block0, @function
+	.align 32
+
+	.proc md5_digest_block0
+	.prologue
+md5_digest_block0:
+	.altrp QUICK_RTN
+	.body
+{	.mmi
+	alloc PFS = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE
+	mov LTrip = 2
+	mov ar.lc = 3
+} ;;
+{	.mii
+	cmp.eq pMore, p0 = r0, r0
+	mov ar.ec = 0
+	nop 0x0
+} ;;
+
+.md5_FF_round0:
+	FFLOAD(A, B, C, D, M12, RotateM0, 7)
+	FFLOAD(D, A, B, C, M13, RotateM1, 12)
+	FFLOAD(C, D, A, B, M14, RotateM2, 17)
+	FFLOOP(B, C, D, A, M15, RotateM3, 22, .md5_FF_round0)
+	//
+	// !!! Fall through to md5_digest_GHI
+	//
+	.endp md5_digest_block0
+
+	.type md5_digest_GHI, @function
+	.align 32
+
+	.proc md5_digest_GHI
+	.prologue
+	.regstk _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE
+md5_digest_GHI:
+	.altrp QUICK_RTN
+	.body
+//
+// The following sequence shuffles the block counstants round for the
+// next round:
+//
+// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+// 1 6 11 0 5 10 14 4 9 14 3 8 13 2 7 12
+//
+{	.mmi
+	mov Z = M0
+	mov Y = M15
+	mov ar.lc = 3
+}
+{	.mmi
+	mov X = M2
+	mov W = M9
+	mov V = M4
+} ;;
+
+{	.mmi
+	mov M0 = M1
+	mov M15 = M12
+	mov ar.ec = 1
+}
+{	.mmi
+	mov M2 = M11
+	mov M9 = M14
+	mov M4 = M5
+} ;;
+
+{	.mmi
+	mov M1 = M6
+	mov M12 = M13
+	mov U = M3
+}
+{	.mmi
+	mov M11 = M8
+	mov M14 = M7
+	mov M5 = M10
+} ;;
+
+{	.mmi
+	mov M6 = Y
+	mov M13 = X
+	mov M3 = Z
+}
+{	.mmi
+	mov M8 = W
+	mov M7 = V
+	mov M10 = U
+} ;;
+
+.md5_GG_round:
+	GG4(.md5_GG_round)
+
+// The following sequence shuffles the block constants round for the
+// next round:
+//
+// 1 6 11 0 5 10 14 4 9 14 3 8 13 2 7 12
+// 5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2
+
+{	.mmi
+	mov Z = M0
+	mov Y = M1
+	mov ar.lc = 3
+}
+{	.mmi
+	mov X = M3
+	mov W = M5
+	mov V = M6
+} ;;
+
+{	.mmi
+	mov M0 = M4
+	mov M1 = M11
+	mov ar.ec = 1
+}
+{	.mmi
+	mov M3 = M9
+	mov U = M8
+	mov T = M13
+} ;;
+
+{	.mmi
+	mov M4 = Z
+	mov M11 = Y
+	mov M5 = M7
+}
+{	.mmi
+	mov M6 = M14
+	mov M8 = M12
+	mov M13 = M15
+} ;;
+
+{	.mmi
+	mov M7 = W
+	mov M14 = V
+	nop 0x0
+}
+{	.mmi
+	mov M9 = X
+	mov M12 = U
+	mov M15 = T
+} ;;
+
+.md5_HH_round:
+	HH4(.md5_HH_round)
+
+// The following sequence shuffles the block constants round for the
+// next round:
+//
+// 5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2
+// 0 7 14 5 12 3 10 1 8 15 6 13 4 11 2 9
+
+{	.mmi
+	mov Z = M0
+	mov Y = M15
+	mov ar.lc = 3
+}
+{	.mmi
+	mov X = M10
+	mov W = M1
+	mov V = M4
+} ;;
+
+{	.mmi
+	mov M0 = M9
+	mov M15 = M12
+	mov ar.ec = 1
+}
+{	.mmi
+	mov M10 = M11
+	mov M1 = M6
+	mov M4 = M13
+} ;;
+
+{	.mmi
+	mov M9 = M14
+	mov M12 = M5
+	mov U = M3
+}
+{	.mmi
+	mov M11 = M8
+	mov M6 = M7
+	mov M13 = M2
+} ;;
+
+{	.mmi
+	mov M14 = Y
+	mov M5 = X
+	mov M3 = Z
+}
+{	.mmi
+	mov M8 = W
+	mov M7 = V
+	mov M2 = U
+} ;;
+
+.md5_II_round:
+	II4(.md5_II_round)
+
+{	.mib
+	nop 0x0
+	nop 0x0
+	br.ret.sptk.many QUICK_RTN
+} ;;
+
+	.endp md5_digest_GHI
+
+#define FFLOADU(a, b, c, d, M, P, N, s, offset)	\
+{	.mii ;					\
+(pMore) ld4 N = [DPtr], 4 ;			\
+	add Z = M, TRound ;			\
+	and Y = c, b ;				\
+}						\
+{	.mmi ;					\
+	andcm X = d, b ;;			\
+	add Z = Z, a ;				\
+	or Y = Y, X ;				\
+} ;;						\
+{	.mii ;					\
+	ld4 TRound = [TPtr], 4 ;		\
+	GETLW(W, P, offset) ;			\
+	add Z = Z, Y ;				\
+} ;;						\
+{	.mii ;					\
+	or W = W, DTmp ;			\
+	dep.z Y = Z, 32, 32 ;;			\
+	shrp Z = Z, Y, 64 - s ;			\
+} ;;						\
+{	.mii ;					\
+	add a = Z, b ;				\
+	GETRW(DTmp, P, offset) ;		\
+	mov P = W ;				\
+} ;;
+
+#define FFLOOPU(a, b, c, d, M, P, N, s, offset)		\
+{	.mii ;						\
+(pMore) ld4 N = [DPtr], 4 ;				\
+	add Z = M, TRound ;				\
+	and Y = c, b ;					\
+}							\
+{	.mmi ;						\
+	andcm X = d, b ;;				\
+	add Z = Z, a ;					\
+	or Y = Y, X ;					\
+} ;;							\
+{	.mii ;						\
+	ld4 TRound = [TPtr], 4 ;			\
+(pMore) GETLW(W, P, offset) 	;			\
+	add Z = Z, Y ;					\
+} ;;							\
+{	.mii ;						\
+(pMore) or W = W, DTmp ;				\
+	dep.z Y = Z, 32, 32 ;;				\
+	shrp Z = Z, Y, 64 - s ;				\
+} ;;							\
+{	.mii ;						\
+	add a = Z, b ;					\
+(pMore) GETRW(DTmp, P, offset) 	;			\
+(pMore) mov P = W ;					\
+}							\
+{	.mib ;						\
+	cmp.ne pMore, p0 = 0, LTrip ;			\
+	add LTrip = -1, LTrip ;				\
+	br.ctop.sptk.many .md5_FF_round##offset ;	\
+} ;;
+
+#define MD5FBLOCK(offset)						\
+	.type md5_digest_block##offset, @function ;			\
+									\
+	.align 32 ;							\
+	.proc md5_digest_block##offset ;				\
+	.prologue ;							\
+	.altrp QUICK_RTN ;						\
+	.body ;								\
+md5_digest_block##offset:						\
+{	.mmi ;								\
+	alloc PFS = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE ;	\
+	mov LTrip = 2 ;							\
+	mov ar.lc = 3 ;							\
+} ;;									\
+{	.mii ;								\
+	cmp.eq pMore, p0 = r0, r0 ;					\
+	mov ar.ec = 0 ;							\
+	nop 0x0 ;							\
+} ;;									\
+									\
+	.pred.rel "mutex", pLoad, pSkip ;				\
+.md5_FF_round##offset:							\
+	FFLOADU(A, B, C, D, M12, M13, RotateM0, 7, offset)		\
+	FFLOADU(D, A, B, C, M13, M14, RotateM1, 12, offset)		\
+	FFLOADU(C, D, A, B, M14, M15, RotateM2, 17, offset)		\
+	FFLOOPU(B, C, D, A, M15, RotateM0, RotateM3, 22, offset)	\
+									\
+{	.mib ;								\
+	nop 0x0 ;							\
+	nop 0x0 ;							\
+	br.cond.sptk.many md5_digest_GHI ;				\
+} ;;									\
+	.endp md5digestBlock ## offset
+
+MD5FBLOCK(1)
+MD5FBLOCK(2)
+MD5FBLOCK(3)
+
+	.align 64
+	.type md5_constants, @object
+md5_constants:
+.md5_tbl_data_order:			// To ensure little-endian data
+					// order, code as bytes.
+	data1 0x78, 0xa4, 0x6a, 0xd7	//     0
+	data1 0x56, 0xb7, 0xc7, 0xe8	//     1
+	data1 0xdb, 0x70, 0x20, 0x24	//     2
+	data1 0xee, 0xce, 0xbd, 0xc1	//     3
+	data1 0xaf, 0x0f, 0x7c, 0xf5	//     4
+	data1 0x2a, 0xc6, 0x87, 0x47	//     5
+	data1 0x13, 0x46, 0x30, 0xa8	//     6
+	data1 0x01, 0x95, 0x46, 0xfd	//     7
+	data1 0xd8, 0x98, 0x80, 0x69	//     8
+	data1 0xaf, 0xf7, 0x44, 0x8b	//     9
+	data1 0xb1, 0x5b, 0xff, 0xff	//    10
+	data1 0xbe, 0xd7, 0x5c, 0x89	//    11
+	data1 0x22, 0x11, 0x90, 0x6b	//    12
+	data1 0x93, 0x71, 0x98, 0xfd	//    13
+	data1 0x8e, 0x43, 0x79, 0xa6	//    14
+	data1 0x21, 0x08, 0xb4, 0x49	//    15
+	data1 0x62, 0x25, 0x1e, 0xf6	//    16
+	data1 0x40, 0xb3, 0x40, 0xc0	//    17
+	data1 0x51, 0x5a, 0x5e, 0x26	//    18
+	data1 0xaa, 0xc7, 0xb6, 0xe9	//    19
+	data1 0x5d, 0x10, 0x2f, 0xd6	//    20
+	data1 0x53, 0x14, 0x44, 0x02	//    21
+	data1 0x81, 0xe6, 0xa1, 0xd8	//    22
+	data1 0xc8, 0xfb, 0xd3, 0xe7	//    23
+	data1 0xe6, 0xcd, 0xe1, 0x21	//    24
+	data1 0xd6, 0x07, 0x37, 0xc3	//    25
+	data1 0x87, 0x0d, 0xd5, 0xf4	//    26
+	data1 0xed, 0x14, 0x5a, 0x45	//    27
+	data1 0x05, 0xe9, 0xe3, 0xa9	//    28
+	data1 0xf8, 0xa3, 0xef, 0xfc	//    29
+	data1 0xd9, 0x02, 0x6f, 0x67	//    30
+	data1 0x8a, 0x4c, 0x2a, 0x8d	//    31
+	data1 0x42, 0x39, 0xfa, 0xff	//    32
+	data1 0x81, 0xf6, 0x71, 0x87	//    33
+	data1 0x22, 0x61, 0x9d, 0x6d	//    34
+	data1 0x0c, 0x38, 0xe5, 0xfd	//    35
+	data1 0x44, 0xea, 0xbe, 0xa4	//    36
+	data1 0xa9, 0xcf, 0xde, 0x4b	//    37
+	data1 0x60, 0x4b, 0xbb, 0xf6	//    38
+	data1 0x70, 0xbc, 0xbf, 0xbe	//    39
+	data1 0xc6, 0x7e, 0x9b, 0x28	//    40
+	data1 0xfa, 0x27, 0xa1, 0xea	//    41
+	data1 0x85, 0x30, 0xef, 0xd4	//    42
+	data1 0x05, 0x1d, 0x88, 0x04	//    43
+	data1 0x39, 0xd0, 0xd4, 0xd9	//    44
+	data1 0xe5, 0x99, 0xdb, 0xe6	//    45
+	data1 0xf8, 0x7c, 0xa2, 0x1f	//    46
+	data1 0x65, 0x56, 0xac, 0xc4	//    47
+	data1 0x44, 0x22, 0x29, 0xf4	//    48
+	data1 0x97, 0xff, 0x2a, 0x43	//    49
+	data1 0xa7, 0x23, 0x94, 0xab	//    50
+	data1 0x39, 0xa0, 0x93, 0xfc	//    51
+	data1 0xc3, 0x59, 0x5b, 0x65	//    52
+	data1 0x92, 0xcc, 0x0c, 0x8f	//    53
+	data1 0x7d, 0xf4, 0xef, 0xff	//    54
+	data1 0xd1, 0x5d, 0x84, 0x85	//    55
+	data1 0x4f, 0x7e, 0xa8, 0x6f	//    56
+	data1 0xe0, 0xe6, 0x2c, 0xfe	//    57
+	data1 0x14, 0x43, 0x01, 0xa3	//    58
+	data1 0xa1, 0x11, 0x08, 0x4e	//    59
+	data1 0x82, 0x7e, 0x53, 0xf7	//    60
+	data1 0x35, 0xf2, 0x3a, 0xbd	//    61
+	data1 0xbb, 0xd2, 0xd7, 0x2a	//    62
+	data1 0x91, 0xd3, 0x86, 0xeb	//    63
+.size	md5_constants#,64*4
diff --git a/crypto/md5/asm/md5-x86_64.pl b/crypto/md5/asm/md5-x86_64.pl
index 05d040f..8678854 100755
--- a/crypto/md5/asm/md5-x86_64.pl
+++ b/crypto/md5/asm/md5-x86_64.pl
@@ -15,11 +15,10 @@
 #   dst = x + ((dst + F(x,y,z) + X[k] + T_i) <<< s)
 #   %r10d = X[k_next]
 #   %r11d = z' (copy of z for the next step)
-# Each round1_step() takes about 5.71 clocks (9 instructions, 1.58 IPC)
+# Each round1_step() takes about 5.3 clocks (9 instructions, 1.7 IPC)
 sub round1_step
 {
     my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
-    $T_i = unpack("l",pack("l", hex($T_i))); # convert to 32-bit signed decimal
     $code .= " mov	0*4(%rsi),	%r10d		/* (NEXT STEP) X[0] */\n" if ($pos == -1);
     $code .= " mov	%edx,		%r11d		/* (NEXT STEP) z' = %edx */\n" if ($pos == -1);
     $code .= <<EOF;
@@ -38,23 +37,26 @@
 # round2_step() does:
 #   dst = x + ((dst + G(x,y,z) + X[k] + T_i) <<< s)
 #   %r10d = X[k_next]
-#   %r11d = y' (copy of y for the next step)
-# Each round2_step() takes about 6.22 clocks (9 instructions, 1.45 IPC)
+#   %r11d = z' (copy of z for the next step)
+#   %r12d = z' (copy of z for the next step)
+# Each round2_step() takes about 5.4 clocks (11 instructions, 2.0 IPC)
 sub round2_step
 {
     my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
-    $T_i = unpack("l",pack("l", hex($T_i))); # convert to 32-bit signed decimal
     $code .= " mov	1*4(%rsi),	%r10d		/* (NEXT STEP) X[1] */\n" if ($pos == -1);
-    $code .= " mov	%ecx,		%r11d		/* (NEXT STEP) y' = %ecx */\n" if ($pos == -1);
+    $code .= " mov	%edx,		%r11d		/* (NEXT STEP) z' = %edx */\n" if ($pos == -1);
+    $code .= " mov	%edx,		%r12d		/* (NEXT STEP) z' = %edx */\n" if ($pos == -1);
     $code .= <<EOF;
-	xor	$x,		%r11d		/* x ^ ... */
+	not	%r11d				/* not z */
 	lea	$T_i($dst,%r10d),$dst		/* Const + dst + ... */
-	and	$z,		%r11d		/* z & ... */
-	xor	$y,		%r11d		/* y ^ ... */
+	and	$x,		%r12d		/* x & z */
+	and	$y,		%r11d		/* y & (not z) */
 	mov	$k_next*4(%rsi),%r10d		/* (NEXT STEP) X[$k_next] */
-	add	%r11d,		$dst		/* dst += ... */
+	or	%r11d,		%r12d		/* (y & (not z)) | (x & z) */
+	mov	$y,		%r11d		/* (NEXT STEP) z' = $y */
+	add	%r12d,		$dst		/* dst += ... */
+	mov	$y,		%r12d		/* (NEXT STEP) z' = $y */
 	rol	\$$s,		$dst		/* dst <<< s */
-	mov	$x,		%r11d		/* (NEXT STEP) y' = $x */
 	add	$x,		$dst		/* dst += x */
 EOF
 }
@@ -63,11 +65,10 @@
 #   dst = x + ((dst + H(x,y,z) + X[k] + T_i) <<< s)
 #   %r10d = X[k_next]
 #   %r11d = y' (copy of y for the next step)
-# Each round3_step() takes about 4.26 clocks (8 instructions, 1.88 IPC)
+# Each round3_step() takes about 4.2 clocks (8 instructions, 1.9 IPC)
 sub round3_step
 {
     my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
-    $T_i = unpack("l",pack("l", hex($T_i))); # convert to 32-bit signed decimal
     $code .= " mov	5*4(%rsi),	%r10d		/* (NEXT STEP) X[5] */\n" if ($pos == -1);
     $code .= " mov	%ecx,		%r11d		/* (NEXT STEP) y' = %ecx */\n" if ($pos == -1);
     $code .= <<EOF;
@@ -86,11 +87,10 @@
 #   dst = x + ((dst + I(x,y,z) + X[k] + T_i) <<< s)
 #   %r10d = X[k_next]
 #   %r11d = not z' (copy of not z for the next step)
-# Each round4_step() takes about 5.27 clocks (9 instructions, 1.71 IPC)
+# Each round4_step() takes about 5.2 clocks (9 instructions, 1.7 IPC)
 sub round4_step
 {
     my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
-    $T_i = unpack("l",pack("l", hex($T_i))); # convert to 32-bit signed decimal
     $code .= " mov	0*4(%rsi),	%r10d		/* (NEXT STEP) X[0] */\n" if ($pos == -1);
     $code .= " mov	\$0xffffffff,	%r11d\n" if ($pos == -1);
     $code .= " xor	%edx,		%r11d		/* (NEXT STEP) not z' = not %edx*/\n"
@@ -108,8 +108,19 @@
 EOF
 }
 
-my $output = shift;
-open STDOUT,"| $^X ../perlasm/x86_64-xlate.pl $output";
+my $flavour = shift;
+my $output  = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
+( $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";
+
+no warnings qw(uninitialized);
+open STDOUT,"| $^X $xlate $flavour $output";
 
 $code .= <<EOF;
 .text
@@ -120,8 +131,10 @@
 md5_block_asm_data_order:
 	push	%rbp
 	push	%rbx
+	push	%r12
 	push	%r14
 	push	%r15
+.Lprologue:
 
 	# rdi = arg #1 (ctx, MD5_CTX pointer)
 	# rsi = arg #2 (ptr, data pointer)
@@ -236,14 +249,121 @@
 	mov	%ecx,		2*4(%rbp)	# ctx->C = C
 	mov	%edx,		3*4(%rbp)	# ctx->D = D
 
-	pop	%r15
-	pop	%r14
-	pop	%rbx
-	pop	%rbp
+	mov	(%rsp),%r15
+	mov	8(%rsp),%r14
+	mov	16(%rsp),%r12
+	mov	24(%rsp),%rbx
+	mov	32(%rsp),%rbp
+	add	\$40,%rsp
+.Lepilogue:
 	ret
 .size md5_block_asm_data_order,.-md5_block_asm_data_order
 EOF
 
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+my $rec="%rcx";
+my $frame="%rdx";
+my $context="%r8";
+my $disp="%r9";
+
+$code.=<<___;
+.extern	__imp_RtlVirtualUnwind
+.type	se_handler,\@abi-omnipotent
+.align	16
+se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	lea	.Lprologue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lprologue
+	jb	.Lin_prologue
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	lea	.Lepilogue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
+	jae	.Lin_prologue
+
+	lea	40(%rax),%rax
+
+	mov	-8(%rax),%rbp
+	mov	-16(%rax),%rbx
+	mov	-24(%rax),%r12
+	mov	-32(%rax),%r14
+	mov	-40(%rax),%r15
+	mov	%rbx,144($context)	# restore context->Rbx
+	mov	%rbp,160($context)	# restore context->Rbp
+	mov	%r12,216($context)	# restore context->R12
+	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
+
+	mov	40($disp),%rdi		# disp->ContextRecord
+	mov	$context,%rsi		# context
+	mov	\$154,%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
+	add	\$64,%rsp
+	popfq
+	pop	%r15
+	pop	%r14
+	pop	%r13
+	pop	%r12
+	pop	%rbp
+	pop	%rbx
+	pop	%rdi
+	pop	%rsi
+	ret
+.size	se_handler,.-se_handler
+
+.section	.pdata
+.align	4
+	.rva	.LSEH_begin_md5_block_asm_data_order
+	.rva	.LSEH_end_md5_block_asm_data_order
+	.rva	.LSEH_info_md5_block_asm_data_order
+
+.section	.xdata
+.align	8
+.LSEH_info_md5_block_asm_data_order:
+	.byte	9,0,0,0
+	.rva	se_handler
+___
+}
+
 print $code;
 
 close STDOUT;
diff --git a/crypto/md5/md5.h b/crypto/md5/md5.h
index 0761f84..4cbf843 100644
--- a/crypto/md5/md5.h
+++ b/crypto/md5/md5.h
@@ -77,7 +77,7 @@
  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  */
 
-#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#if defined(__LP32__)
 #define MD5_LONG unsigned long
 #elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
 #define MD5_LONG unsigned long
@@ -105,9 +105,6 @@
 	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 47bb902..beace63 100644
--- a/crypto/md5/md5_dgst.c
+++ b/crypto/md5/md5_dgst.c
@@ -59,11 +59,6 @@
 #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;
 
@@ -75,15 +70,13 @@
 #define INIT_DATA_C (unsigned long)0x98badcfeL
 #define INIT_DATA_D (unsigned long)0x10325476L
 
-FIPS_NON_FIPS_MD_Init(MD5)
+int MD5_Init(MD5_CTX *c)
 	{
+	memset (c,0,sizeof(*c));
 	c->A=INIT_DATA_A;
 	c->B=INIT_DATA_B;
 	c->C=INIT_DATA_C;
 	c->D=INIT_DATA_D;
-	c->Nl=0;
-	c->Nh=0;
-	c->num=0;
 	return 1;
 	}
 
diff --git a/crypto/md5/md5_locl.h b/crypto/md5/md5_locl.h
index 84e81b9..968d577 100644
--- a/crypto/md5/md5_locl.h
+++ b/crypto/md5/md5_locl.h
@@ -69,6 +69,8 @@
 # if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) || \
      defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
 #  define md5_block_data_order md5_block_asm_data_order
+# elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
+#  define md5_block_data_order md5_block_asm_data_order
 # endif
 #endif
 
diff --git a/crypto/mdc2/Makefile b/crypto/mdc2/Makefile
deleted file mode 100644
index ea25688..0000000
--- a/crypto/mdc2/Makefile
+++ /dev/null
@@ -1,93 +0,0 @@
-#
-# OpenSSL/crypto/mdc2/Makefile
-#
-
-DIR=	mdc2
-TOP=	../..
-CC=	cc
-INCLUDES=
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST= mdc2test.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=mdc2dgst.c mdc2_one.c
-LIBOBJ=mdc2dgst.o mdc2_one.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= mdc2.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-mdc2_one.o: ../../e_os.h ../../include/openssl/bio.h
-mdc2_one.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-mdc2_one.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-mdc2_one.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-mdc2_one.o: ../../include/openssl/lhash.h ../../include/openssl/mdc2.h
-mdc2_one.o: ../../include/openssl/opensslconf.h
-mdc2_one.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-mdc2_one.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-mdc2_one.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
-mdc2_one.o: ../../include/openssl/ui_compat.h ../cryptlib.h mdc2_one.c
-mdc2dgst.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-mdc2dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/mdc2.h
-mdc2dgst.o: ../../include/openssl/opensslconf.h
-mdc2dgst.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-mdc2dgst.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-mdc2dgst.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-mdc2dgst.o: mdc2dgst.c
diff --git a/crypto/mdc2/mdc2.h b/crypto/mdc2/mdc2.h
index 7e13541..72778a5 100644
--- a/crypto/mdc2/mdc2.h
+++ b/crypto/mdc2/mdc2.h
@@ -80,9 +80,7 @@
 	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 a36b3f5..4aa406e 100644
--- a/crypto/mdc2/mdc2dgst.c
+++ b/crypto/mdc2/mdc2dgst.c
@@ -61,11 +61,6 @@
 #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)++)))    , \
@@ -80,7 +75,7 @@
 			*((c)++)=(unsigned char)(((l)>>24L)&0xff))
 
 static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len);
-FIPS_NON_FIPS_MD_Init(MDC2)
+int MDC2_Init(MDC2_CTX *c)
 	{
 	c->num=0;
 	c->pad_type=1;
diff --git a/crypto/mem.c b/crypto/mem.c
index 00ebaf0..6f80dd3 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 */
-#if defined(CRYPTO_MDEBUG) && !defined(OPENSSL_FIPS)
+#ifdef CRYPTO_MDEBUG
 /* use default functions from mem_dbg.c */
 static void (*malloc_debug_func)(void *,int,const char *,int,int)
 	= CRYPTO_dbg_malloc;
@@ -110,14 +110,6 @@
 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 */
@@ -127,13 +119,6 @@
 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
 
 
@@ -209,15 +194,6 @@
 	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 *))
@@ -274,7 +250,6 @@
 void *CRYPTO_malloc_locked(int num, const char *file, int line)
 	{
 	void *ret = NULL;
-	extern unsigned char cleanse_ctr;
 
 	if (num <= 0) return NULL;
 
@@ -291,11 +266,15 @@
 	if (malloc_debug_func != NULL)
 		malloc_debug_func(ret, num, file, line, 1);
 
+#ifndef OPENSSL_CPUID_OBJ
         /* Create a dependency on the value of 'cleanse_ctr' so our memory
          * sanitisation function can't be optimised out. NB: We only do
          * this for >2Kb so the overhead doesn't bother us. */
         if(ret && (num > 2048))
+	{	extern unsigned char cleanse_ctr;
 		((unsigned char *)ret)[0] = cleanse_ctr;
+	}
+#endif
 
 	return ret;
 	}
@@ -315,7 +294,6 @@
 void *CRYPTO_malloc(int num, const char *file, int line)
 	{
 	void *ret = NULL;
-	extern unsigned char cleanse_ctr;
 
 	if (num <= 0) return NULL;
 
@@ -332,14 +310,25 @@
 	if (malloc_debug_func != NULL)
 		malloc_debug_func(ret, num, file, line, 1);
 
+#ifndef OPENSSL_CPUID_OBJ
         /* Create a dependency on the value of 'cleanse_ctr' so our memory
          * sanitisation function can't be optimised out. NB: We only do
          * this for >2Kb so the overhead doesn't bother us. */
         if(ret && (num > 2048))
+	{	extern unsigned char cleanse_ctr;
                 ((unsigned char *)ret)[0] = cleanse_ctr;
+	}
+#endif
 
 	return ret;
 	}
+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;
+	}
 
 void *CRYPTO_realloc(void *str, int num, const char *file, int line)
 	{
@@ -423,24 +412,3 @@
 		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 dfeb084..ac79339 100644
--- a/crypto/mem_dbg.c
+++ b/crypto/mem_dbg.c
@@ -55,6 +55,59 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
+/* ====================================================================
+ * Copyright (c) 1998-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
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -81,8 +134,11 @@
  */
 
 static unsigned long order = 0; /* number of memory requests */
-static LHASH *mh=NULL; /* hash-table of memory requests (address as key);
-                        * access requires MALLOC2 lock */
+
+DECLARE_LHASH_OF(MEM);
+static LHASH_OF(MEM) *mh=NULL; /* hash-table of memory requests
+				* (address as key); access requires
+				* MALLOC2 lock */
 
 
 typedef struct app_mem_info_st
@@ -93,8 +149,8 @@
  *   CRYPTO_pop_info()           to pop an entry,
  *   CRYPTO_remove_all_info()    to pop all entries.
  */
-	{	
-	unsigned long thread;
+	{
+	CRYPTO_THREADID threadid;
 	const char *file;
 	int line;
 	const char *info;
@@ -104,10 +160,13 @@
 
 static void app_info_free(APP_INFO *);
 
-static LHASH *amih=NULL; /* hash-table with those app_mem_info_st's
-                          * that are at the top of their thread's stack
-                          * (with `thread' as key);
-                          * access requires MALLOC2 lock */
+DECLARE_LHASH_OF(APP_INFO);
+static LHASH_OF(APP_INFO) *amih=NULL; /* hash-table with those
+				       * app_mem_info_st's that are at
+				       * the top of their thread's
+				       * stack (with `thread' as key);
+				       * access requires MALLOC2
+				       * lock */
 
 typedef struct mem_st
 /* memory-block description */
@@ -116,7 +175,7 @@
 	int num;
 	const char *file;
 	int line;
-	unsigned long thread;
+	CRYPTO_THREADID threadid;
 	unsigned long order;
 	time_t time;
 	APP_INFO *app_info;
@@ -136,11 +195,11 @@
                                       *     iff
                                       * mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE)
                                       */
-static unsigned long disabling_thread = 0; /* Valid iff num_disable > 0.
-                                            * CRYPTO_LOCK_MALLOC2 is locked
-                                            * exactly in this case (by the
-                                            * thread named in disabling_thread).
-                                            */
+
+/* Valid iff num_disable > 0.  CRYPTO_LOCK_MALLOC2 is locked exactly in this
+ * case (by the thread named in disabling_thread).
+ */
+static CRYPTO_THREADID disabling_threadid;
 
 static void app_info_free(APP_INFO *inf)
 	{
@@ -177,7 +236,9 @@
 	case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
 		if (mh_mode & CRYPTO_MEM_CHECK_ON)
 			{
-			if (!num_disable || (disabling_thread != CRYPTO_thread_id())) /* otherwise we already have the MALLOC2 lock */
+			CRYPTO_THREADID cur;
+			CRYPTO_THREADID_current(&cur);
+			if (!num_disable || CRYPTO_THREADID_cmp(&disabling_threadid, &cur)) /* otherwise we already have the MALLOC2 lock */
 				{
 				/* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
 				 * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
@@ -195,7 +256,7 @@
 				CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
 				CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
 				mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
-				disabling_thread=CRYPTO_thread_id();
+				CRYPTO_THREADID_cpy(&disabling_threadid, &cur);
 				}
 			num_disable++;
 			}
@@ -228,10 +289,12 @@
 
 	if (mh_mode & CRYPTO_MEM_CHECK_ON)
 		{
+		CRYPTO_THREADID cur;
+		CRYPTO_THREADID_current(&cur);
 		CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
 
 		ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
-			|| (disabling_thread != CRYPTO_thread_id());
+		        || CRYPTO_THREADID_cmp(&disabling_threadid, &cur);
 
 		CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
 		}
@@ -249,49 +312,49 @@
 	return options;
 	}
 
-/* static int mem_cmp(MEM *a, MEM *b) */
-static int mem_cmp(const void *a_void, const void *b_void)
+static int mem_cmp(const MEM *a, const MEM *b)
 	{
 #ifdef _WIN64
-	const char *a=(const char *)((const MEM *)a_void)->addr,
-		   *b=(const char *)((const MEM *)b_void)->addr;
-	if (a==b)	return 0;
-	else if (a>b)	return 1;
+	const char *ap=(const char *)a->addr,
+		   *bp=(const char *)b->addr;
+	if (ap==bp)	return 0;
+	else if (ap>bp)	return 1;
 	else		return -1;
 #else
-	return((const char *)((const MEM *)a_void)->addr
-		- (const char *)((const MEM *)b_void)->addr);
+	return (const char *)a->addr - (const char *)b->addr;
 #endif
 	}
+static IMPLEMENT_LHASH_COMP_FN(mem, MEM)
 
-/* static unsigned long mem_hash(MEM *a) */
-static unsigned long mem_hash(const void *a_void)
+static unsigned long mem_hash(const MEM *a)
 	{
 	unsigned long ret;
 
-	ret=(unsigned long)((const MEM *)a_void)->addr;
+	ret=(unsigned long)a->addr;
 
 	ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
 	return(ret);
 	}
+static IMPLEMENT_LHASH_HASH_FN(mem, MEM)
 
 /* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
 static int app_info_cmp(const void *a_void, const void *b_void)
 	{
-	return(((const APP_INFO *)a_void)->thread
-		!= ((const APP_INFO *)b_void)->thread);
+	return CRYPTO_THREADID_cmp(&((const APP_INFO *)a_void)->threadid,
+				&((const APP_INFO *)b_void)->threadid);
 	}
+static IMPLEMENT_LHASH_COMP_FN(app_info, APP_INFO)
 
-/* static unsigned long app_info_hash(APP_INFO *a) */
-static unsigned long app_info_hash(const void *a_void)
+static unsigned long app_info_hash(const APP_INFO *a)
 	{
 	unsigned long ret;
 
-	ret=(unsigned long)((const APP_INFO *)a_void)->thread;
-
+	ret = CRYPTO_THREADID_hash(&a->threadid);
+	/* This is left in as a "who am I to question legacy?" measure */
 	ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
 	return(ret);
 	}
+static IMPLEMENT_LHASH_HASH_FN(app_info, APP_INFO)
 
 static APP_INFO *pop_info(void)
 	{
@@ -300,21 +363,22 @@
 
 	if (amih != NULL)
 		{
-		tmp.thread=CRYPTO_thread_id();
-		if ((ret=(APP_INFO *)lh_delete(amih,&tmp)) != NULL)
+		CRYPTO_THREADID_current(&tmp.threadid);
+		if ((ret=lh_APP_INFO_delete(amih,&tmp)) != NULL)
 			{
 			APP_INFO *next=ret->next;
 
 			if (next != NULL)
 				{
 				next->references++;
-				lh_insert(amih,(char *)next);
+				(void)lh_APP_INFO_insert(amih,next);
 				}
 #ifdef LEVITTE_DEBUG_MEM
-			if (ret->thread != tmp.thread)
+			if (CRYPTO_THREADID_cmp(&ret->threadid, &tmp.threadid))
 				{
 				fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
-					ret->thread, tmp.thread);
+					CRYPTO_THREADID_hash(&ret->threadid),
+					CRYPTO_THREADID_hash(&tmp.threadid));
 				abort();
 				}
 #endif
@@ -330,7 +394,7 @@
 	return(ret);
 	}
 
-int CRYPTO_dbg_push_info(const char *info, const char *file, int line)
+int CRYPTO_push_info_(const char *info, const char *file, int line)
 	{
 	APP_INFO *ami, *amim;
 	int ret=0;
@@ -346,7 +410,7 @@
 			}
 		if (amih == NULL)
 			{
-			if ((amih=lh_new(app_info_hash, app_info_cmp)) == NULL)
+			if ((amih=lh_APP_INFO_new()) == NULL)
 				{
 				OPENSSL_free(ami);
 				ret=0;
@@ -354,20 +418,21 @@
 				}
 			}
 
-		ami->thread=CRYPTO_thread_id();
+		CRYPTO_THREADID_current(&ami->threadid);
 		ami->file=file;
 		ami->line=line;
 		ami->info=info;
 		ami->references=1;
 		ami->next=NULL;
 
-		if ((amim=(APP_INFO *)lh_insert(amih,(char *)ami)) != NULL)
+		if ((amim=lh_APP_INFO_insert(amih,ami)) != NULL)
 			{
 #ifdef LEVITTE_DEBUG_MEM
-			if (ami->thread != amim->thread)
+			if (CRYPTO_THREADID_cmp(&ami->threadid, &amim->threadid))
 				{
 				fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
-					amim->thread, ami->thread);
+					CRYPTO_THREADID_hash(&amim->threadid),
+					CRYPTO_THREADID_hash(&ami->threadid));
 				abort();
 				}
 #endif
@@ -380,7 +445,7 @@
 	return(ret);
 	}
 
-int CRYPTO_dbg_pop_info(void)
+int CRYPTO_pop_info(void)
 	{
 	int ret=0;
 
@@ -395,7 +460,7 @@
 	return(ret);
 	}
 
-int CRYPTO_dbg_remove_all_info(void)
+int CRYPTO_remove_all_info(void)
 	{
 	int ret=0;
 
@@ -439,7 +504,7 @@
 				}
 			if (mh == NULL)
 				{
-				if ((mh=lh_new(mem_hash, mem_cmp)) == NULL)
+				if ((mh=lh_MEM_new()) == NULL)
 					{
 					OPENSSL_free(addr);
 					OPENSSL_free(m);
@@ -453,9 +518,9 @@
 			m->line=line;
 			m->num=num;
 			if (options & V_CRYPTO_MDEBUG_THREAD)
-				m->thread=CRYPTO_thread_id();
+				CRYPTO_THREADID_current(&m->threadid);
 			else
-				m->thread=0;
+				memset(&m->threadid, 0, sizeof(m->threadid));
 
 			if (order == break_order_num)
 				{
@@ -464,7 +529,7 @@
 				}
 			m->order=order++;
 #ifdef LEVITTE_DEBUG_MEM
-			fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] %c 0x%p (%d)\n",
+			fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] %c 0x%p (%d)\n",
 				m->order,
 				(before_p & 128) ? '*' : '+',
 				m->addr, m->num);
@@ -474,16 +539,16 @@
 			else
 				m->time=0;
 
-			tmp.thread=CRYPTO_thread_id();
+			CRYPTO_THREADID_current(&tmp.threadid);
 			m->app_info=NULL;
 			if (amih != NULL
-				&& (amim=(APP_INFO *)lh_retrieve(amih,(char *)&tmp)) != NULL)
+			    && (amim=lh_APP_INFO_retrieve(amih,&tmp)) != NULL)
 				{
 				m->app_info = amim;
 				amim->references++;
 				}
 
-			if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL)
+			if ((mm=lh_MEM_insert(mh, m)) != NULL)
 				{
 				/* Not good, but don't sweat it */
 				if (mm->app_info != NULL)
@@ -516,11 +581,11 @@
 			MemCheck_off(); /* make sure we hold MALLOC2 lock */
 
 			m.addr=addr;
-			mp=(MEM *)lh_delete(mh,(char *)&m);
+			mp=lh_MEM_delete(mh,&m);
 			if (mp != NULL)
 				{
 #ifdef LEVITTE_DEBUG_MEM
-			fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] - 0x%p (%d)\n",
+			fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] - 0x%p (%d)\n",
 				mp->order, mp->addr, mp->num);
 #endif
 				if (mp->app_info != NULL)
@@ -566,18 +631,18 @@
 			MemCheck_off(); /* make sure we hold MALLOC2 lock */
 
 			m.addr=addr1;
-			mp=(MEM *)lh_delete(mh,(char *)&m);
+			mp=lh_MEM_delete(mh,&m);
 			if (mp != NULL)
 				{
 #ifdef LEVITTE_DEBUG_MEM
-				fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] * 0x%p (%d) -> 0x%p (%d)\n",
+				fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] * 0x%p (%d) -> 0x%p (%d)\n",
 					mp->order,
 					mp->addr, mp->num,
 					addr2, num);
 #endif
 				mp->addr=addr2;
 				mp->num=num;
-				lh_insert(mh,(char *)mp);
+				(void)lh_MEM_insert(mh,mp);
 				}
 
 			MemCheck_on(); /* release MALLOC2 lock
@@ -596,14 +661,14 @@
 	long bytes;
 	} MEM_LEAK;
 
-static void print_leak(const MEM *m, MEM_LEAK *l)
+static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
 	{
 	char buf[1024];
 	char *bufp = buf;
 	APP_INFO *amip;
 	int ami_cnt;
 	struct tm *lcl = NULL;
-	unsigned long ti;
+	CRYPTO_THREADID ti;
 
 #define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
 
@@ -625,7 +690,8 @@
 
 	if (options & V_CRYPTO_MDEBUG_THREAD)
 		{
-		BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", m->thread);
+		BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ",
+			CRYPTO_THREADID_hash(&m->threadid));
 		bufp += strlen(bufp);
 		}
 
@@ -642,8 +708,8 @@
 	ami_cnt=0;
 	if (!amip)
 		return;
-	ti=amip->thread;
-	
+	CRYPTO_THREADID_cpy(&ti, &amip->threadid);
+
 	do
 		{
 		int buf_len;
@@ -653,7 +719,8 @@
 		memset(buf,'>',ami_cnt);
 		BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
 			" thread=%lu, file=%s, line=%d, info=\"",
-			amip->thread, amip->file, amip->line);
+			CRYPTO_THREADID_hash(&amip->threadid), amip->file,
+			amip->line);
 		buf_len=strlen(buf);
 		info_len=strlen(amip->info);
 		if (128 - buf_len - 3 < info_len)
@@ -673,8 +740,8 @@
 
 		amip = amip->next;
 		}
-	while(amip && amip->thread == ti);
-		
+	while(amip && !CRYPTO_THREADID_cmp(&amip->threadid, &ti));
+
 #ifdef LEVITTE_DEBUG_MEM
 	if (amip)
 		{
@@ -684,7 +751,7 @@
 #endif
 	}
 
-static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM *, MEM_LEAK *)
+static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM, MEM_LEAK)
 
 void CRYPTO_mem_leaks(BIO *b)
 	{
@@ -699,12 +766,15 @@
 	ml.bytes=0;
 	ml.chunks=0;
 	if (mh != NULL)
-		lh_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak),
-				(char *)&ml);
+		lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak), MEM_LEAK,
+				 &ml);
 	if (ml.chunks != 0)
 		{
 		BIO_printf(b,"%ld bytes leaked in %d chunks\n",
 			   ml.bytes,ml.chunks);
+#ifdef CRYPTO_MDEBUG_ABORT
+		abort();
+#endif
 		}
 	else
 		{
@@ -717,7 +787,7 @@
 		 * XXX    This should be in CRYPTO_mem_leaks_cb,
 		 * and CRYPTO_mem_leaks should be implemented by
 		 * using CRYPTO_mem_leaks_cb.
-		 * (Also their should be a variant of lh_doall_arg
+		 * (Also there should be a variant of lh_doall_arg
 		 * that takes a function pointer instead of a void *;
 		 * this would obviate the ugly and illegal
 		 * void_fn_to_char kludge in CRYPTO_mem_leaks_cb.
@@ -734,14 +804,14 @@
 
 		if (mh != NULL)
 			{
-			lh_free(mh);
+			lh_MEM_free(mh);
 			mh = NULL;
 			}
 		if (amih != NULL)
 			{
-			if (lh_num_items(amih) == 0) 
+			if (lh_APP_INFO_num_items(amih) == 0) 
 				{
-				lh_free(amih);
+				lh_APP_INFO_free(amih);
 				amih = NULL;
 				}
 			}
@@ -779,39 +849,26 @@
 /* NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside crypto.h
  * If this code is restructured, remove the callback type if it is no longer
  * needed. -- Geoff Thorpe */
-static void cb_leak(const MEM *m, CRYPTO_MEM_LEAK_CB **cb)
+
+/* Can't pass CRYPTO_MEM_LEAK_CB directly to lh_MEM_doall_arg because it
+ * is a function pointer and conversion to void * is prohibited. Instead
+ * pass its address
+ */
+
+typedef CRYPTO_MEM_LEAK_CB *PCRYPTO_MEM_LEAK_CB;
+
+static void cb_leak_doall_arg(const MEM *m, PCRYPTO_MEM_LEAK_CB *cb)
 	{
-	(**cb)(m->order,m->file,m->line,m->num,m->addr);
+	(*cb)(m->order,m->file,m->line,m->num,m->addr);
 	}
 
-static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM *, CRYPTO_MEM_LEAK_CB **)
+static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM, PCRYPTO_MEM_LEAK_CB)
 
 void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb)
 	{
 	if (mh == NULL) return;
 	CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
-	lh_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), &cb);
+	lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), PCRYPTO_MEM_LEAK_CB,
+			 &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/modes/cbc128.c b/crypto/modes/cbc128.c
new file mode 100644
index 0000000..8f8bd56
--- /dev/null
+++ b/crypto/modes/cbc128.c
@@ -0,0 +1,206 @@
+/* ====================================================================
+ * 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
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include "modes.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+#define STRICT_ALIGNMENT 1
+#if defined(__i386) || defined(__i386__) || \
+    defined(__x86_64) || defined(__x86_64__) || \
+    defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
+    defined(__s390__) || defined(__s390x__)
+#  undef STRICT_ALIGNMENT
+#  define STRICT_ALIGNMENT 0
+#endif
+
+void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], block128_f block)
+{
+	size_t n;
+	const unsigned char *iv = ivec;
+
+	assert(in && out && key && ivec);
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (STRICT_ALIGNMENT &&
+	    ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
+		while (len>=16) {
+			for(n=0; n<16; ++n)
+				out[n] = in[n] ^ iv[n];
+			(*block)(out, out, key);
+			iv = out;
+			len -= 16;
+			in  += 16;
+			out += 16;
+		}
+	} else {
+		while (len>=16) {
+			for(n=0; n<16; n+=sizeof(size_t))
+				*(size_t*)(out+n) =
+				*(size_t*)(in+n) ^ *(size_t*)(iv+n);
+			(*block)(out, out, key);
+			iv = out;
+			len -= 16;
+			in  += 16;
+			out += 16;
+		}
+	}
+#endif
+	while (len) {
+		for(n=0; n<16 && n<len; ++n)
+			out[n] = in[n] ^ iv[n];
+		for(; n<16; ++n)
+			out[n] = iv[n];
+		(*block)(out, out, key);
+		iv = out;
+		if (len<=16) break;
+		len -= 16;
+		in  += 16;
+		out += 16;
+	}
+	memcpy(ivec,iv,16);
+}
+
+void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], block128_f block)
+{
+	size_t n;
+	union { size_t align; unsigned char c[16]; } tmp;
+
+	assert(in && out && key && ivec);
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (in != out) {
+		const unsigned char *iv = ivec;
+
+		if (STRICT_ALIGNMENT &&
+		    ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
+			while (len>=16) {
+				(*block)(in, out, key);
+				for(n=0; n<16; ++n)
+					out[n] ^= iv[n];
+				iv = in;
+				len -= 16;
+				in  += 16;
+				out += 16;
+			}
+		}
+		else {
+			while (len>=16) {
+				(*block)(in, out, key);
+				for(n=0; n<16; n+=sizeof(size_t))
+					*(size_t *)(out+n) ^= *(size_t *)(iv+n);
+				iv = in;
+				len -= 16;
+				in  += 16;
+				out += 16;
+			}
+		}
+		memcpy(ivec,iv,16);
+	} else {
+		if (STRICT_ALIGNMENT &&
+		    ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
+			unsigned char c;
+			while (len>=16) {
+				(*block)(in, tmp.c, key);
+				for(n=0; n<16; ++n) {
+					c = in[n];
+					out[n] = tmp.c[n] ^ ivec[n];
+					ivec[n] = c;
+				}
+				len -= 16;
+				in  += 16;
+				out += 16;
+			}
+		}
+		else {
+			size_t c;
+			while (len>=16) {
+				(*block)(in, tmp.c, key);
+				for(n=0; n<16; n+=sizeof(size_t)) {
+					c = *(size_t *)(in+n);
+					*(size_t *)(out+n) =
+					*(size_t *)(tmp.c+n) ^ *(size_t *)(ivec+n);
+					*(size_t *)(ivec+n) = c;
+				}
+				len -= 16;
+				in  += 16;
+				out += 16;
+			}
+		}
+	}
+#endif
+	while (len) {
+		unsigned char c;
+		(*block)(in, tmp.c, key);
+		for(n=0; n<16 && n<len; ++n) {
+			c = in[n];
+			out[n] = tmp.c[n] ^ ivec[n];
+			ivec[n] = c;
+		}
+		if (len<=16) {
+			for (; n<16; ++n)
+				ivec[n] = in[n];
+			break;
+		}
+		len -= 16;
+		in  += 16;
+		out += 16;
+	}
+}
diff --git a/crypto/modes/cfb128.c b/crypto/modes/cfb128.c
new file mode 100644
index 0000000..98f4cf3
--- /dev/null
+++ b/crypto/modes/cfb128.c
@@ -0,0 +1,249 @@
+/* ====================================================================
+ * 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
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include "modes.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+#define STRICT_ALIGNMENT
+#if defined(__i386) || defined(__i386__) || \
+    defined(__x86_64) || defined(__x86_64__) || \
+    defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
+    defined(__s390__) || defined(__s390x__)
+#  undef STRICT_ALIGNMENT
+#endif
+
+/* The input and output encrypted as though 128bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 128bit block we have used is contained in *num;
+ */
+void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], int *num,
+			int enc, block128_f block)
+{
+    unsigned int n;
+    size_t l = 0;
+
+    assert(in && out && key && ivec && num);
+
+    n = *num;
+
+    if (enc) {
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (16%sizeof(size_t) == 0) do {	/* always true actually */
+		while (n && len) {
+			*(out++) = ivec[n] ^= *(in++);
+			--len;
+			n = (n+1) % 16;
+		}
+#if defined(STRICT_ALIGNMENT)
+		if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
+			break;
+#endif
+		while (len>=16) {
+			(*block)(ivec, ivec, key);
+			for (n=0; n<16; n+=sizeof(size_t)) {
+				*(size_t*)(out+n) =
+				*(size_t*)(ivec+n) ^= *(size_t*)(in+n);
+			}
+			len -= 16;
+			out += 16;
+			in  += 16;
+		}
+		n = 0;
+		if (len) {
+			(*block)(ivec, ivec, key);
+			while (len--) {
+				out[n] = ivec[n] ^= in[n];
+				++n;
+			}
+		}
+		*num = n;
+		return;
+	} while (0);
+	/* the rest would be commonly eliminated by x86* compiler */
+#endif
+	while (l<len) {
+		if (n == 0) {
+			(*block)(ivec, ivec, key);
+		}
+		out[l] = ivec[n] ^= in[l];
+		++l;
+		n = (n+1) % 16;
+	}
+	*num = n;
+    } else {
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (16%sizeof(size_t) == 0) do {	/* always true actually */
+		while (n && len) {
+			unsigned char c;
+			*(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c;
+			--len;
+			n = (n+1) % 16;
+ 		}
+#if defined(STRICT_ALIGNMENT)
+		if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
+			break;
+#endif
+		while (len>=16) {
+			(*block)(ivec, ivec, key);
+			for (n=0; n<16; n+=sizeof(size_t)) {
+				size_t t = *(size_t*)(in+n);
+				*(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t;
+				*(size_t*)(ivec+n) = t;
+			}
+			len -= 16;
+			out += 16;
+			in  += 16;
+		}
+		n = 0;
+		if (len) {
+			(*block)(ivec, ivec, key);
+			while (len--) {
+				unsigned char c;
+				out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c;
+				++n;
+			}
+ 		}
+		*num = n;
+		return;
+	} while (0);
+	/* the rest would be commonly eliminated by x86* compiler */
+#endif
+	while (l<len) {
+		unsigned char c;
+		if (n == 0) {
+			(*block)(ivec, ivec, key);
+		}
+		out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c;
+		++l;
+		n = (n+1) % 16;
+	}
+	*num=n;
+    }
+}
+
+/* This expects a single block of size nbits for both in and out. Note that
+   it corrupts any extra bits in the last byte of out */
+static void cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
+			    int nbits,const void *key,
+			    unsigned char ivec[16],int enc,
+			    block128_f block)
+{
+    int n,rem,num;
+    unsigned char ovec[16*2 + 1];  /* +1 because we dererefence (but don't use) one byte off the end */
+
+    if (nbits<=0 || nbits>128) return;
+
+	/* fill in the first half of the new IV with the current IV */
+	memcpy(ovec,ivec,16);
+	/* construct the new IV */
+	(*block)(ivec,ivec,key);
+	num = (nbits+7)/8;
+	if (enc)	/* encrypt the input */
+	    for(n=0 ; n < num ; ++n)
+		out[n] = (ovec[16+n] = in[n] ^ ivec[n]);
+	else		/* decrypt the input */
+	    for(n=0 ; n < num ; ++n)
+		out[n] = (ovec[16+n] = in[n]) ^ ivec[n];
+	/* shift ovec left... */
+	rem = nbits%8;
+	num = nbits/8;
+	if(rem==0)
+	    memcpy(ivec,ovec+num,16);
+	else
+	    for(n=0 ; n < 16 ; ++n)
+		ivec[n] = ovec[n+num]<<rem | ovec[n+num+1]>>(8-rem);
+
+    /* it is not necessary to cleanse ovec, since the IV is not secret */
+}
+
+/* N.B. This expects the input to be packed, MS bit first */
+void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
+		 	size_t bits, const void *key,
+			unsigned char ivec[16], int *num,
+			int enc, block128_f block)
+{
+    size_t n;
+    unsigned char c[1],d[1];
+
+    assert(in && out && key && ivec && num);
+    assert(*num == 0);
+
+    for(n=0 ; n<bits ; ++n)
+	{
+	c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
+	cfbr_encrypt_block(c,d,1,key,ivec,enc,block);
+	out[n/8]=(out[n/8]&~(1 << (unsigned int)(7-n%8))) |
+		 ((d[0]&0x80) >> (unsigned int)(n%8));
+	}
+}
+
+void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
+			size_t length, const void *key,
+			unsigned char ivec[16], int *num,
+			int enc, block128_f block)
+{
+    size_t n;
+
+    assert(in && out && key && ivec && num);
+    assert(*num == 0);
+
+    for(n=0 ; n<length ; ++n)
+	cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc,block);
+}
+
diff --git a/crypto/modes/ctr128.c b/crypto/modes/ctr128.c
new file mode 100644
index 0000000..bd84f41
--- /dev/null
+++ b/crypto/modes/ctr128.c
@@ -0,0 +1,186 @@
+/* ====================================================================
+ * 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
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include "modes.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+typedef unsigned int u32;
+typedef unsigned char u8;
+
+# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3]))
+# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >>  8); (ct)[3] = (u8)(st); }
+
+#define STRICT_ALIGNMENT
+#if defined(__i386) || defined(__i386__) || \
+    defined(__x86_64) || defined(__x86_64__) || \
+    defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
+    defined(__s390__) || defined(__s390x__)
+#  undef STRICT_ALIGNMENT
+#endif
+
+/* NOTE: the IV/counter CTR mode is big-endian.  The code itself
+ * is endian-neutral. */
+
+/* increment counter (128-bit int) by 1 */
+static void ctr128_inc(unsigned char *counter) {
+	u32 c,n=16;
+
+	do {
+		n -= 4;
+		c = GETU32(counter+n);
+		++c;	c &= 0xFFFFFFFF;
+		PUTU32(counter + n, c);
+		if (c) return;
+	} while (n);
+}
+
+#if !defined(OPENSSL_SMALL_FOORPRINT)
+static void ctr128_inc_aligned(unsigned char *counter) {
+	size_t *data,c,n;
+	const union { long one; char little; } is_endian = {1};
+
+	if (is_endian.little) {
+		ctr128_inc(counter);
+		return;
+	}
+
+	data = (size_t *)counter;
+	n = 16/sizeof(size_t);
+	do {
+		--n;
+		c = data[n];
+		++c;
+		data[n] = c;
+		if (c) return;
+	} while (n);
+}
+#endif
+
+/* The input encrypted as though 128bit counter mode is being
+ * used.  The extra state information to record how much of the
+ * 128bit block we have used is contained in *num, and the
+ * encrypted counter is kept in ecount_buf.  Both *num and
+ * ecount_buf must be initialised with zeros before the first
+ * call to CRYPTO_ctr128_encrypt().
+ *
+ * This algorithm assumes that the counter is in the x lower bits
+ * of the IV (ivec), and that the application has full control over
+ * overflow and the rest of the IV.  This implementation takes NO
+ * responsability for checking that the counter doesn't overflow
+ * into the rest of the IV when incremented.
+ */
+void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], unsigned char ecount_buf[16],
+			unsigned int *num, block128_f block)
+{
+	unsigned int n;
+	size_t l=0;
+
+	assert(in && out && key && ecount_buf && num);
+	assert(*num < 16);
+
+	n = *num;
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (16%sizeof(size_t) == 0) do { /* always true actually */
+		while (n && len) {
+			*(out++) = *(in++) ^ ecount_buf[n];
+			--len;
+			n = (n+1) % 16;
+		}
+
+#if defined(STRICT_ALIGNMENT)
+		if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
+			break;
+#endif
+		while (len>=16) {
+			(*block)(ivec, ecount_buf, key);
+			ctr128_inc_aligned(ivec);
+			for (n=0; n<16; n+=sizeof(size_t))
+				*(size_t *)(out+n) =
+				*(size_t *)(in+n) ^ *(size_t *)(ecount_buf+n);
+			len -= 16;
+			out += 16;
+			in  += 16;
+		}
+		n = 0;
+		if (len) {
+			(*block)(ivec, ecount_buf, key);
+ 			ctr128_inc_aligned(ivec);
+			while (len--) {
+				out[n] = in[n] ^ ecount_buf[n];
+				++n;
+			}
+		}
+		*num = n;
+		return;
+	} while(0);
+	/* the rest would be commonly eliminated by x86* compiler */
+#endif
+	while (l<len) {
+		if (n==0) {
+			(*block)(ivec, ecount_buf, key);
+ 			ctr128_inc(ivec);
+		}
+		out[l] = in[l] ^ ecount_buf[n];
+		++l;
+		n = (n+1) % 16;
+	}
+
+	*num=n;
+}
diff --git a/crypto/modes/ofb128.c b/crypto/modes/ofb128.c
new file mode 100644
index 0000000..09b3430
--- /dev/null
+++ b/crypto/modes/ofb128.c
@@ -0,0 +1,128 @@
+/* ====================================================================
+ * 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
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include "modes.h"
+#include <string.h>
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+#define STRICT_ALIGNMENT
+#if defined(__i386) || defined(__i386__) || \
+    defined(__x86_64) || defined(__x86_64__) || \
+    defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
+    defined(__s390__) || defined(__s390x__)
+#  undef STRICT_ALIGNMENT
+#endif
+
+/* The input and output encrypted as though 128bit ofb mode is being
+ * used.  The extra state information to record how much of the
+ * 128bit block we have used is contained in *num;
+ */
+void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], int *num,
+			block128_f block)
+{
+	unsigned int n;
+	size_t l=0;
+
+	assert(in && out && key && ivec && num);
+
+	n = *num;
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (16%sizeof(size_t) == 0) do { /* always true actually */
+		while (n && len) {
+			*(out++) = *(in++) ^ ivec[n];
+			--len;
+			n = (n+1) % 16;
+		}
+#if defined(STRICT_ALIGNMENT)
+		if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
+			break;
+#endif
+		while (len>=16) {
+			(*block)(ivec, ivec, key);
+			for (n=0; n<16; n+=sizeof(size_t))
+				*(size_t*)(out+n) =
+				*(size_t*)(in+n) ^ *(size_t*)(ivec+n);
+			len -= 16;
+			out += 16;
+			in  += 16;
+		}
+		n = 0;
+		if (len) {
+			(*block)(ivec, ivec, key);
+			while (len--) {
+				out[n] = in[n] ^ ivec[n];
+				++n;
+			}
+		}
+		*num = n;
+		return;
+	} while(0);
+	/* the rest would be commonly eliminated by x86* compiler */
+#endif
+	while (l<len) {
+		if (n==0) {
+			(*block)(ivec, ivec, key);
+		}
+		out[l] = in[l] ^ ivec[n];
+		++l;
+		n = (n+1) % 16;
+	}
+
+	*num=n;
+}
diff --git a/crypto/o_init.c b/crypto/o_init.c
deleted file mode 100644
index 2a5f5aa..0000000
--- a/crypto/o_init.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* o_init.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project.
- */
-/* ====================================================================
- * Copyright (c) 2007 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#include <e_os.h>
-#include <openssl/err.h>
-/* Internal only functions: only ever used here */
-extern	void int_ERR_lib_init(void);
-extern	void int_EVP_MD_init_engine_callbacks(void );
-extern	void int_EVP_CIPHER_init_engine_callbacks(void );
-extern	void int_RAND_init_engine_callbacks(void );
-
-/* 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
-#ifndef OPENSSL_NO_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/o_time.c b/crypto/o_time.c
index e29091d..eecbdd1 100644
--- a/crypto/o_time.c
+++ b/crypto/o_time.c
@@ -2,6 +2,9 @@
 /* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
  * project 2001.
  */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2008.
+ */
 /* ====================================================================
  * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
  *
@@ -73,7 +76,7 @@
 	{
 	struct tm *ts = NULL;
 
-#if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_OS2) && !defined(__CYGWIN32__) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_MACOSX) && !defined(OPENSSL_SYS_SUNOS)
+#if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_OS2) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_MACOSX) && !defined(OPENSSL_SYS_SUNOS)
 	/* should return &data, but doesn't on some systems,
 	   so we don't even look at the return value */
 	gmtime_r(timer,result);
@@ -214,4 +217,150 @@
 		}
 #endif
 	return ts;
-	}	
+	}
+
+/* Take a tm structure and add an offset to it. This avoids any OS issues
+ * with restricted date types and overflows which cause the year 2038
+ * problem.
+ */
+
+#define SECS_PER_DAY (24 * 60 * 60)
+
+static long date_to_julian(int y, int m, int d);
+static void julian_to_date(long jd, int *y, int *m, int *d);
+
+int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec)
+	{
+	int offset_hms, offset_day;
+	long time_jd;
+	int time_year, time_month, time_day;
+	/* split offset into days and day seconds */
+	offset_day = offset_sec / SECS_PER_DAY;
+	/* Avoid sign issues with % operator */
+	offset_hms  = offset_sec - (offset_day * SECS_PER_DAY);
+	offset_day += off_day;
+	/* Add current time seconds to offset */
+	offset_hms += tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec;
+	/* Adjust day seconds if overflow */
+	if (offset_hms >= SECS_PER_DAY)
+		{
+		offset_day++;
+		offset_hms -= SECS_PER_DAY;
+		}
+	else if (offset_hms < 0)
+		{
+		offset_day--;
+		offset_hms += SECS_PER_DAY;
+		}
+
+	/* Convert date of time structure into a Julian day number.
+	 */
+
+	time_year = tm->tm_year + 1900;
+	time_month = tm->tm_mon + 1;
+	time_day = tm->tm_mday;
+
+	time_jd = date_to_julian(time_year, time_month, time_day);
+
+	/* Work out Julian day of new date */
+	time_jd += offset_day;
+
+	if (time_jd < 0)
+		return 0;
+
+	/* Convert Julian day back to date */
+
+	julian_to_date(time_jd, &time_year, &time_month, &time_day);
+
+	if (time_year < 1900 || time_year > 9999)
+		return 0;
+
+	/* Update tm structure */
+
+	tm->tm_year = time_year - 1900;
+	tm->tm_mon = time_month - 1;
+	tm->tm_mday = time_day;
+
+	tm->tm_hour = offset_hms / 3600;
+	tm->tm_min = (offset_hms / 60) % 60;
+	tm->tm_sec = offset_hms % 60;
+
+	return 1;
+		
+}
+
+/* Convert date to and from julian day
+ * Uses Fliegel & Van Flandern algorithm
+ */
+static long date_to_julian(int y, int m, int d)
+{
+	return (1461 * (y + 4800 + (m - 14) / 12)) / 4 +
+		(367 * (m - 2 - 12 * ((m - 14) / 12))) / 12 -
+		(3 * ((y + 4900 + (m - 14) / 12) / 100)) / 4 +
+		d - 32075;
+}
+
+static void julian_to_date(long jd, int *y, int *m, int *d)
+	{
+	long  L = jd + 68569;
+	long  n = (4 * L) / 146097;
+	long  i, j;
+
+	L = L - (146097 * n + 3) / 4;
+	i = (4000 * (L + 1)) / 1461001;
+	L = L - (1461 * i) / 4 + 31;
+	j = (80 * L) / 2447;
+	*d = L - (2447 * j) / 80;
+	L = j / 11;
+	*m = j + 2 - (12 * L);
+	*y = 100 * (n - 49) + i + L;
+	}
+
+#ifdef OPENSSL_TIME_TEST
+
+#include <stdio.h>
+
+/* Time checking test code. Check times are identical for a wide range of
+ * offsets. This should be run on a machine with 64 bit time_t or it will
+ * trigger the very errors the routines fix.
+ */
+
+int main(int argc, char **argv)
+	{
+	long offset;
+	for (offset = 0; offset < 1000000; offset++)
+		{
+		check_time(offset);
+		check_time(-offset);
+		check_time(offset * 1000);
+		check_time(-offset * 1000);
+		}
+	}
+
+int check_time(long offset)
+	{
+	struct tm tm1, tm2;
+	time_t t1, t2;
+	time(&t1);
+	t2 = t1 + offset;
+	OPENSSL_gmtime(&t2, &tm2);
+	OPENSSL_gmtime(&t1, &tm1);
+	OPENSSL_gmtime_adj(&tm1, 0, offset);
+	if ((tm1.tm_year == tm2.tm_year) &&
+	    (tm1.tm_mon == tm2.tm_mon) &&
+	    (tm1.tm_mday == tm2.tm_mday) &&
+	    (tm1.tm_hour == tm2.tm_hour) &&
+	    (tm1.tm_min == tm2.tm_min) &&
+	    (tm1.tm_sec == tm2.tm_sec))
+		return 1;
+	fprintf(stderr, "TIME ERROR!!\n");
+	fprintf(stderr, "Time1: %d/%d/%d, %d:%02d:%02d\n",
+			tm2.tm_mday, tm2.tm_mon + 1, tm2.tm_year + 1900,
+			tm2.tm_hour, tm2.tm_min, tm2.tm_sec);
+	fprintf(stderr, "Time2: %d/%d/%d, %d:%02d:%02d\n",
+			tm1.tm_mday, tm1.tm_mon + 1, tm1.tm_year + 1900,
+			tm1.tm_hour, tm1.tm_min, tm1.tm_sec);
+	return 0;
+	}
+
+#endif
diff --git a/crypto/o_time.h b/crypto/o_time.h
index e660446..e391da7 100644
--- a/crypto/o_time.h
+++ b/crypto/o_time.h
@@ -62,5 +62,6 @@
 #include <time.h>
 
 struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result);
+int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec);
 
 #endif
diff --git a/crypto/objects/Makefile b/crypto/objects/Makefile
deleted file mode 100644
index 25e8b23..0000000
--- a/crypto/objects/Makefile
+++ /dev/null
@@ -1,119 +0,0 @@
-#
-# OpenSSL/crypto/objects/Makefile
-#
-
-DIR=	objects
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-PERL=		perl
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile README
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=	o_names.c obj_dat.c obj_lib.c obj_err.c
-LIBOBJ= o_names.o obj_dat.o obj_lib.o obj_err.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= objects.h obj_mac.h
-HEADER=	$(EXHEADER) obj_dat.h
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	obj_dat.h lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-obj_dat.h: obj_dat.pl obj_mac.h
-	$(PERL) obj_dat.pl obj_mac.h obj_dat.h
-
-# objects.pl both reads and writes obj_mac.num
-obj_mac.h: objects.pl objects.txt obj_mac.num
-	$(PERL) objects.pl objects.txt obj_mac.num obj_mac.h
-	@sleep 1; touch obj_mac.h; sleep 1
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-o_names.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-o_names.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-o_names.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-o_names.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-o_names.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-o_names.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-o_names.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-o_names.o: o_names.c
-obj_dat.o: ../../e_os.h ../../include/openssl/asn1.h
-obj_dat.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-obj_dat.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-obj_dat.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-obj_dat.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-obj_dat.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-obj_dat.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-obj_dat.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-obj_dat.o: ../../include/openssl/symhacks.h ../cryptlib.h obj_dat.c obj_dat.h
-obj_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-obj_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-obj_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-obj_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-obj_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-obj_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-obj_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-obj_err.o: obj_err.c
-obj_lib.o: ../../e_os.h ../../include/openssl/asn1.h
-obj_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-obj_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-obj_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-obj_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-obj_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-obj_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-obj_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-obj_lib.o: ../cryptlib.h obj_lib.c
diff --git a/crypto/objects/o_names.c b/crypto/objects/o_names.c
index adb5731..84380a9 100644
--- a/crypto/objects/o_names.c
+++ b/crypto/objects/o_names.c
@@ -22,7 +22,8 @@
 /* I use the ex_data stuff to manage the identifiers for the obj_name_types
  * that applications may define.  I only really use the free function field.
  */
-static LHASH *names_lh=NULL;
+DECLARE_LHASH_OF(OBJ_NAME);
+static LHASH_OF(OBJ_NAME) *names_lh=NULL;
 static int names_type_num=OBJ_NAME_TYPE_NUM;
 
 typedef struct name_funcs_st
@@ -46,11 +47,14 @@
 /* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */
 static int obj_name_cmp(const void *a_void,const void *b_void);
 
+static IMPLEMENT_LHASH_HASH_FN(obj_name, OBJ_NAME)
+static IMPLEMENT_LHASH_COMP_FN(obj_name, OBJ_NAME)
+
 int OBJ_NAME_init(void)
 	{
 	if (names_lh != NULL) return(1);
 	MemCheck_off();
-	names_lh=lh_new(obj_name_hash, obj_name_cmp);
+	names_lh=lh_OBJ_NAME_new();
 	MemCheck_on();
 	return(names_lh != NULL);
 	}
@@ -164,7 +168,7 @@
 
 	for (;;)
 	{
-		ret=(OBJ_NAME *)lh_retrieve(names_lh,&on);
+		ret=lh_OBJ_NAME_retrieve(names_lh,&on);
 		if (ret == NULL) return(NULL);
 		if ((ret->alias) && !alias)
 			{
@@ -200,7 +204,7 @@
 	onp->type=type;
 	onp->data=data;
 
-	ret=(OBJ_NAME *)lh_insert(names_lh,onp);
+	ret=lh_OBJ_NAME_insert(names_lh,onp);
 	if (ret != NULL)
 		{
 		/* free things */
@@ -217,7 +221,7 @@
 		}
 	else
 		{
-		if (lh_error(names_lh))
+		if (lh_OBJ_NAME_error(names_lh))
 			{
 			/* ERROR */
 			return(0);
@@ -235,7 +239,7 @@
 	type&= ~OBJ_NAME_ALIAS;
 	on.name=name;
 	on.type=type;
-	ret=(OBJ_NAME *)lh_delete(names_lh,&on);
+	ret=lh_OBJ_NAME_delete(names_lh,&on);
 	if (ret != NULL)
 		{
 		/* free things */
@@ -262,13 +266,13 @@
 	void *arg;
 	};
 
-static void do_all_fn(const OBJ_NAME *name,struct doall *d)
+static void do_all_fn_doall_arg(const OBJ_NAME *name,struct doall *d)
 	{
 	if(name->type == d->type)
 		d->fn(name,d->arg);
 	}
 
-static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME *, struct doall *)
+static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME, struct doall)
 
 void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),void *arg)
 	{
@@ -278,7 +282,8 @@
 	d.fn=fn;
 	d.arg=arg;
 
-	lh_doall_arg(names_lh,LHASH_DOALL_ARG_FN(do_all_fn),&d);
+	lh_OBJ_NAME_doall_arg(names_lh, LHASH_DOALL_ARG_FN(do_all_fn),
+			      struct doall, &d);
 	}
 
 struct doall_sorted
@@ -313,7 +318,7 @@
 	int n;
 
 	d.type=type;
-	d.names=OPENSSL_malloc(lh_num_items(names_lh)*sizeof *d.names);
+	d.names=OPENSSL_malloc(lh_OBJ_NAME_num_items(names_lh)*sizeof *d.names);
 	d.n=0;
 	OBJ_NAME_do_all(type,do_all_sorted_fn,&d);
 
@@ -327,18 +332,16 @@
 
 static int free_type;
 
-static void names_lh_free(OBJ_NAME *onp)
-{
-	if(onp == NULL)
+static void names_lh_free_doall(OBJ_NAME *onp)
+	{
+	if (onp == NULL)
 		return;
 
-	if ((free_type < 0) || (free_type == onp->type))
-		{
+	if (free_type < 0 || free_type == onp->type)
 		OBJ_NAME_remove(onp->name,onp->type);
-		}
 	}
 
-static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME *)
+static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME)
 
 static void name_funcs_free(NAME_FUNCS *ptr)
 	{
@@ -352,18 +355,18 @@
 	if (names_lh == NULL) return;
 
 	free_type=type;
-	down_load=names_lh->down_load;
-	names_lh->down_load=0;
+	down_load=lh_OBJ_NAME_down_load(names_lh);
+	lh_OBJ_NAME_down_load(names_lh)=0;
 
-	lh_doall(names_lh,LHASH_DOALL_FN(names_lh_free));
+	lh_OBJ_NAME_doall(names_lh,LHASH_DOALL_FN(names_lh_free));
 	if (type < 0)
 		{
-		lh_free(names_lh);
+		lh_OBJ_NAME_free(names_lh);
 		sk_NAME_FUNCS_pop_free(name_funcs_stack,name_funcs_free);
 		names_lh=NULL;
 		name_funcs_stack = NULL;
 		}
 	else
-		names_lh->down_load=down_load;
+		lh_OBJ_NAME_down_load(names_lh)=down_load;
 	}
 
diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c
index 760af16..8a342ba 100644
--- a/crypto/objects/obj_dat.c
+++ b/crypto/objects/obj_dat.c
@@ -74,16 +74,17 @@
 #define NUM_SN 0
 #define NUM_LN 0
 #define NUM_OBJ 0
-static unsigned char lvalues[1];
-static ASN1_OBJECT nid_objs[1];
-static ASN1_OBJECT *sn_objs[1];
-static ASN1_OBJECT *ln_objs[1];
-static ASN1_OBJECT *obj_objs[1];
+static const unsigned char lvalues[1];
+static const ASN1_OBJECT nid_objs[1];
+static const unsigned int sn_objs[1];
+static const unsigned int ln_objs[1];
+static const unsigned int obj_objs[1];
 #endif
 
-static int sn_cmp(const void *a, const void *b);
-static int ln_cmp(const void *a, const void *b);
-static int obj_cmp(const void *a, const void *b);
+DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
+DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
+DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
+
 #define ADDED_DATA	0
 #define ADDED_SNAME	1
 #define ADDED_LNAME	2
@@ -94,30 +95,27 @@
 	int type;
 	ASN1_OBJECT *obj;
 	} ADDED_OBJ;
+DECLARE_LHASH_OF(ADDED_OBJ);
 
 static int new_nid=NUM_NID;
-static LHASH *added=NULL;
+static LHASH_OF(ADDED_OBJ) *added=NULL;
 
-static int sn_cmp(const void *a, const void *b)
-	{
-	const ASN1_OBJECT * const *ap = a, * const *bp = b;
-	return(strcmp((*ap)->sn,(*bp)->sn));
-	}
+static int sn_cmp(const ASN1_OBJECT * const *a, const unsigned int *b)
+	{ return(strcmp((*a)->sn,nid_objs[*b].sn)); }
 
-static int ln_cmp(const void *a, const void *b)
-	{ 
-	const ASN1_OBJECT * const *ap = a, * const *bp = b;
-	return(strcmp((*ap)->ln,(*bp)->ln));
-	}
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
 
-/* static unsigned long add_hash(ADDED_OBJ *ca) */
-static unsigned long add_hash(const void *ca_void)
+static int ln_cmp(const ASN1_OBJECT * const *a, const unsigned int *b)
+	{ return(strcmp((*a)->ln,nid_objs[*b].ln)); }
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
+
+static unsigned long added_obj_hash(const ADDED_OBJ *ca)
 	{
 	const ASN1_OBJECT *a;
 	int i;
 	unsigned long ret=0;
 	unsigned char *p;
-	const ADDED_OBJ *ca = (const ADDED_OBJ *)ca_void;
 
 	a=ca->obj;
 	switch (ca->type)
@@ -145,14 +143,12 @@
 	ret|=ca->type<<30L;
 	return(ret);
 	}
+static IMPLEMENT_LHASH_HASH_FN(added_obj, ADDED_OBJ)
 
-/* static int add_cmp(ADDED_OBJ *ca, ADDED_OBJ *cb) */
-static int add_cmp(const void *ca_void, const void *cb_void)
+static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb)
 	{
 	ASN1_OBJECT *a,*b;
 	int i;
-	const ADDED_OBJ *ca = (const ADDED_OBJ *)ca_void;
-	const ADDED_OBJ *cb = (const ADDED_OBJ *)cb_void;
 
 	i=ca->type-cb->type;
 	if (i) return(i);
@@ -179,15 +175,16 @@
 		return 0;
 		}
 	}
+static IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ)
 
 static int init_added(void)
 	{
 	if (added != NULL) return(1);
-	added=lh_new(add_hash,add_cmp);
+	added=lh_ADDED_OBJ_new();
 	return(added != NULL);
 	}
 
-static void cleanup1(ADDED_OBJ *a)
+static void cleanup1_doall(ADDED_OBJ *a)
 	{
 	a->obj->nid=0;
 	a->obj->flags|=ASN1_OBJECT_FLAG_DYNAMIC|
@@ -195,28 +192,46 @@
 			ASN1_OBJECT_FLAG_DYNAMIC_DATA;
 	}
 
-static void cleanup2(ADDED_OBJ *a)
+static void cleanup2_doall(ADDED_OBJ *a)
 	{ a->obj->nid++; }
 
-static void cleanup3(ADDED_OBJ *a)
+static void cleanup3_doall(ADDED_OBJ *a)
 	{
 	if (--a->obj->nid == 0)
 		ASN1_OBJECT_free(a->obj);
 	OPENSSL_free(a);
 	}
 
-static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ *)
-static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ *)
-static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ *)
+static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ)
+static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ)
+static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ)
+
+/* The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting
+ * to use freed up OIDs. If neccessary the actual freeing up of OIDs is
+ * delayed.
+ */
+
+int obj_cleanup_defer = 0;
+
+void check_defer(int nid)
+	{
+	if (!obj_cleanup_defer && nid >= NUM_NID)
+			obj_cleanup_defer = 1;
+	}
 
 void OBJ_cleanup(void)
 	{
+	if (obj_cleanup_defer)
+		{
+		obj_cleanup_defer = 2;
+		return ;
+		}
 	if (added == NULL) return;
-	added->down_load=0;
-	lh_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */
-	lh_doall(added,LHASH_DOALL_FN(cleanup2)); /* set counters */
-	lh_doall(added,LHASH_DOALL_FN(cleanup3)); /* free objects */
-	lh_free(added);
+	lh_ADDED_OBJ_down_load(added) = 0;
+	lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */
+	lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup2)); /* set counters */
+	lh_ADDED_OBJ_doall(added,LHASH_DOALL_FN(cleanup3)); /* free objects */
+	lh_ADDED_OBJ_free(added);
 	added=NULL;
 	}
 
@@ -252,7 +267,7 @@
 			{
 			ao[i]->type=i;
 			ao[i]->obj=o;
-			aop=(ADDED_OBJ *)lh_insert(added,ao[i]);
+			aop=lh_ADDED_OBJ_insert(added,ao[i]);
 			/* memory leak, buit should not normally matter */
 			if (aop != NULL)
 				OPENSSL_free(aop);
@@ -292,7 +307,7 @@
 		ad.type=ADDED_NID;
 		ad.obj= &ob;
 		ob.nid=n;
-		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
+		adp=lh_ADDED_OBJ_retrieve(added,&ad);
 		if (adp != NULL)
 			return(adp->obj);
 		else
@@ -324,7 +339,7 @@
 		ad.type=ADDED_NID;
 		ad.obj= &ob;
 		ob.nid=n;
-		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
+		adp=lh_ADDED_OBJ_retrieve(added,&ad);
 		if (adp != NULL)
 			return(adp->obj->sn);
 		else
@@ -356,7 +371,7 @@
 		ad.type=ADDED_NID;
 		ad.obj= &ob;
 		ob.nid=n;
-		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
+		adp=lh_ADDED_OBJ_retrieve(added,&ad);
 		if (adp != NULL)
 			return(adp->obj->ln);
 		else
@@ -367,9 +382,22 @@
 		}
 	}
 
+static int obj_cmp(const ASN1_OBJECT * const *ap, const unsigned int *bp)
+	{
+	int j;
+	const ASN1_OBJECT *a= *ap;
+	const ASN1_OBJECT *b= &nid_objs[*bp];
+
+	j=(a->length - b->length);
+        if (j) return(j);
+	return(memcmp(a->data,b->data,a->length));
+	}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
+
 int OBJ_obj2nid(const ASN1_OBJECT *a)
 	{
-	ASN1_OBJECT **op;
+	const unsigned int *op;
 	ADDED_OBJ ad,*adp;
 
 	if (a == NULL)
@@ -381,14 +409,13 @@
 		{
 		ad.type=ADDED_DATA;
 		ad.obj=(ASN1_OBJECT *)a; /* XXX: ugly but harmless */
-		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
+		adp=lh_ADDED_OBJ_retrieve(added,&ad);
 		if (adp != NULL) return (adp->obj->nid);
 		}
-	op=(ASN1_OBJECT **)OBJ_bsearch((const char *)&a,(const char *)obj_objs,
-		NUM_OBJ, sizeof(ASN1_OBJECT *),obj_cmp);
+	op=OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ);
 	if (op == NULL)
 		return(NID_undef);
-	return((*op)->nid);
+	return(nid_objs[*op].nid);
 	}
 
 /* Convert an object name into an ASN1_OBJECT
@@ -441,7 +468,7 @@
 	int i,n=0,len,nid, first, use_bn;
 	BIGNUM *bl;
 	unsigned long l;
-	unsigned char *p;
+	const unsigned char *p;
 	char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2];
 
 	if ((a == NULL) || (a->data == NULL)) {
@@ -610,62 +637,56 @@
 
 int OBJ_ln2nid(const char *s)
 	{
-	ASN1_OBJECT o,*oo= &o,**op;
+	ASN1_OBJECT o;
+	const ASN1_OBJECT *oo= &o;
 	ADDED_OBJ ad,*adp;
+	const unsigned int *op;
 
 	o.ln=s;
 	if (added != NULL)
 		{
 		ad.type=ADDED_LNAME;
 		ad.obj= &o;
-		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
+		adp=lh_ADDED_OBJ_retrieve(added,&ad);
 		if (adp != NULL) return (adp->obj->nid);
 		}
-	op=(ASN1_OBJECT **)OBJ_bsearch((char *)&oo,(char *)ln_objs, NUM_LN,
-		sizeof(ASN1_OBJECT *),ln_cmp);
+	op=OBJ_bsearch_ln(&oo, ln_objs, NUM_LN);
 	if (op == NULL) return(NID_undef);
-	return((*op)->nid);
+	return(nid_objs[*op].nid);
 	}
 
 int OBJ_sn2nid(const char *s)
 	{
-	ASN1_OBJECT o,*oo= &o,**op;
+	ASN1_OBJECT o;
+	const ASN1_OBJECT *oo= &o;
 	ADDED_OBJ ad,*adp;
+	const unsigned int *op;
 
 	o.sn=s;
 	if (added != NULL)
 		{
 		ad.type=ADDED_SNAME;
 		ad.obj= &o;
-		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
+		adp=lh_ADDED_OBJ_retrieve(added,&ad);
 		if (adp != NULL) return (adp->obj->nid);
 		}
-	op=(ASN1_OBJECT **)OBJ_bsearch((char *)&oo,(char *)sn_objs,NUM_SN,
-		sizeof(ASN1_OBJECT *),sn_cmp);
+	op=OBJ_bsearch_sn(&oo, sn_objs, NUM_SN);
 	if (op == NULL) return(NID_undef);
-	return((*op)->nid);
+	return(nid_objs[*op].nid);
 	}
 
-static int obj_cmp(const void *ap, const void *bp)
+const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
+			 int (*cmp)(const void *, const void *))
 	{
-	int j;
-	const ASN1_OBJECT *a= *(ASN1_OBJECT * const *)ap;
-	const ASN1_OBJECT *b= *(ASN1_OBJECT * const *)bp;
-
-	j=(a->length - b->length);
-        if (j) return(j);
-	return(memcmp(a->data,b->data,a->length));
-        }
-
-const char *OBJ_bsearch(const char *key, const char *base, int num, int size,
-	int (*cmp)(const void *, const void *))
-	{
-	return OBJ_bsearch_ex(key, base, num, size, cmp, 0);
+	return OBJ_bsearch_ex_(key, base, num, size, cmp, 0);
 	}
 
-const char *OBJ_bsearch_ex(const char *key, const char *base, int num,
-	int size, int (*cmp)(const void *, const void *), int flags)
+const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num,
+			    int size,
+			    int (*cmp)(const void *, const void *),
+			    int flags)
 	{
+	const char *base=base_;
 	int l,h,i=0,c=0;
 	const char *p = NULL;
 
diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h
index 23bdb46..6449be6 100644
--- a/crypto/objects/obj_dat.h
+++ b/crypto/objects/obj_dat.h
@@ -67,7 +67,7 @@
 #define NUM_LN 886
 #define NUM_OBJ 840
 
-static unsigned char lvalues[5824]={
+static const unsigned char lvalues[5824]={
 0x00,                                        /* [  0] OBJ_undef */
 0x2A,0x86,0x48,0x86,0xF7,0x0D,               /* [  1] OBJ_rsadsi */
 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,          /* [  7] OBJ_pkcs */
@@ -910,7 +910,7 @@
 0x55,0x04,0x36,                              /* [5820] OBJ_dmdName */
 };
 
-static ASN1_OBJECT nid_objs[NUM_NID]={
+static const ASN1_OBJECT nid_objs[NUM_NID]={
 {"UNDEF","undefined",NID_undef,1,&(lvalues[0]),0},
 {"rsadsi","RSA Data Security, Inc.",NID_rsadsi,6,&(lvalues[1]),0},
 {"pkcs","RSA Data Security, Inc. PKCS",NID_pkcs,7,&(lvalues[7]),0},
@@ -2353,2624 +2353,2624 @@
 {"dmdName","dmdName",NID_dmdName,3,&(lvalues[5820]),0},
 };
 
-static ASN1_OBJECT *sn_objs[NUM_SN]={
-&(nid_objs[364]),/* "AD_DVCS" */
-&(nid_objs[419]),/* "AES-128-CBC" */
-&(nid_objs[421]),/* "AES-128-CFB" */
-&(nid_objs[650]),/* "AES-128-CFB1" */
-&(nid_objs[653]),/* "AES-128-CFB8" */
-&(nid_objs[418]),/* "AES-128-ECB" */
-&(nid_objs[420]),/* "AES-128-OFB" */
-&(nid_objs[423]),/* "AES-192-CBC" */
-&(nid_objs[425]),/* "AES-192-CFB" */
-&(nid_objs[651]),/* "AES-192-CFB1" */
-&(nid_objs[654]),/* "AES-192-CFB8" */
-&(nid_objs[422]),/* "AES-192-ECB" */
-&(nid_objs[424]),/* "AES-192-OFB" */
-&(nid_objs[427]),/* "AES-256-CBC" */
-&(nid_objs[429]),/* "AES-256-CFB" */
-&(nid_objs[652]),/* "AES-256-CFB1" */
-&(nid_objs[655]),/* "AES-256-CFB8" */
-&(nid_objs[426]),/* "AES-256-ECB" */
-&(nid_objs[428]),/* "AES-256-OFB" */
-&(nid_objs[91]),/* "BF-CBC" */
-&(nid_objs[93]),/* "BF-CFB" */
-&(nid_objs[92]),/* "BF-ECB" */
-&(nid_objs[94]),/* "BF-OFB" */
-&(nid_objs[14]),/* "C" */
-&(nid_objs[751]),/* "CAMELLIA-128-CBC" */
-&(nid_objs[757]),/* "CAMELLIA-128-CFB" */
-&(nid_objs[760]),/* "CAMELLIA-128-CFB1" */
-&(nid_objs[763]),/* "CAMELLIA-128-CFB8" */
-&(nid_objs[754]),/* "CAMELLIA-128-ECB" */
-&(nid_objs[766]),/* "CAMELLIA-128-OFB" */
-&(nid_objs[752]),/* "CAMELLIA-192-CBC" */
-&(nid_objs[758]),/* "CAMELLIA-192-CFB" */
-&(nid_objs[761]),/* "CAMELLIA-192-CFB1" */
-&(nid_objs[764]),/* "CAMELLIA-192-CFB8" */
-&(nid_objs[755]),/* "CAMELLIA-192-ECB" */
-&(nid_objs[767]),/* "CAMELLIA-192-OFB" */
-&(nid_objs[753]),/* "CAMELLIA-256-CBC" */
-&(nid_objs[759]),/* "CAMELLIA-256-CFB" */
-&(nid_objs[762]),/* "CAMELLIA-256-CFB1" */
-&(nid_objs[765]),/* "CAMELLIA-256-CFB8" */
-&(nid_objs[756]),/* "CAMELLIA-256-ECB" */
-&(nid_objs[768]),/* "CAMELLIA-256-OFB" */
-&(nid_objs[108]),/* "CAST5-CBC" */
-&(nid_objs[110]),/* "CAST5-CFB" */
-&(nid_objs[109]),/* "CAST5-ECB" */
-&(nid_objs[111]),/* "CAST5-OFB" */
-&(nid_objs[13]),/* "CN" */
-&(nid_objs[141]),/* "CRLReason" */
-&(nid_objs[417]),/* "CSPName" */
-&(nid_objs[367]),/* "CrlID" */
-&(nid_objs[391]),/* "DC" */
-&(nid_objs[31]),/* "DES-CBC" */
-&(nid_objs[643]),/* "DES-CDMF" */
-&(nid_objs[30]),/* "DES-CFB" */
-&(nid_objs[656]),/* "DES-CFB1" */
-&(nid_objs[657]),/* "DES-CFB8" */
-&(nid_objs[29]),/* "DES-ECB" */
-&(nid_objs[32]),/* "DES-EDE" */
-&(nid_objs[43]),/* "DES-EDE-CBC" */
-&(nid_objs[60]),/* "DES-EDE-CFB" */
-&(nid_objs[62]),/* "DES-EDE-OFB" */
-&(nid_objs[33]),/* "DES-EDE3" */
-&(nid_objs[44]),/* "DES-EDE3-CBC" */
-&(nid_objs[61]),/* "DES-EDE3-CFB" */
-&(nid_objs[658]),/* "DES-EDE3-CFB1" */
-&(nid_objs[659]),/* "DES-EDE3-CFB8" */
-&(nid_objs[63]),/* "DES-EDE3-OFB" */
-&(nid_objs[45]),/* "DES-OFB" */
-&(nid_objs[80]),/* "DESX-CBC" */
-&(nid_objs[380]),/* "DOD" */
-&(nid_objs[116]),/* "DSA" */
-&(nid_objs[66]),/* "DSA-SHA" */
-&(nid_objs[113]),/* "DSA-SHA1" */
-&(nid_objs[70]),/* "DSA-SHA1-old" */
-&(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" */
-&(nid_objs[34]),/* "IDEA-CBC" */
-&(nid_objs[35]),/* "IDEA-CFB" */
-&(nid_objs[36]),/* "IDEA-ECB" */
-&(nid_objs[46]),/* "IDEA-OFB" */
-&(nid_objs[181]),/* "ISO" */
-&(nid_objs[183]),/* "ISO-US" */
-&(nid_objs[645]),/* "ITU-T" */
-&(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" */
-&(nid_objs[114]),/* "MD5-SHA1" */
-&(nid_objs[95]),/* "MDC2" */
-&(nid_objs[388]),/* "Mail" */
-&(nid_objs[393]),/* "NULL" */
-&(nid_objs[404]),/* "NULL" */
-&(nid_objs[57]),/* "Netscape" */
-&(nid_objs[366]),/* "Nonce" */
-&(nid_objs[17]),/* "O" */
-&(nid_objs[178]),/* "OCSP" */
-&(nid_objs[180]),/* "OCSPSigning" */
-&(nid_objs[379]),/* "ORG" */
-&(nid_objs[18]),/* "OU" */
-&(nid_objs[749]),/* "Oakley-EC2N-3" */
-&(nid_objs[750]),/* "Oakley-EC2N-4" */
-&(nid_objs[ 9]),/* "PBE-MD2-DES" */
-&(nid_objs[168]),/* "PBE-MD2-RC2-64" */
-&(nid_objs[10]),/* "PBE-MD5-DES" */
-&(nid_objs[169]),/* "PBE-MD5-RC2-64" */
-&(nid_objs[147]),/* "PBE-SHA1-2DES" */
-&(nid_objs[146]),/* "PBE-SHA1-3DES" */
-&(nid_objs[170]),/* "PBE-SHA1-DES" */
-&(nid_objs[148]),/* "PBE-SHA1-RC2-128" */
-&(nid_objs[149]),/* "PBE-SHA1-RC2-40" */
-&(nid_objs[68]),/* "PBE-SHA1-RC2-64" */
-&(nid_objs[144]),/* "PBE-SHA1-RC4-128" */
-&(nid_objs[145]),/* "PBE-SHA1-RC4-40" */
-&(nid_objs[161]),/* "PBES2" */
-&(nid_objs[69]),/* "PBKDF2" */
-&(nid_objs[162]),/* "PBMAC1" */
-&(nid_objs[127]),/* "PKIX" */
-&(nid_objs[98]),/* "RC2-40-CBC" */
-&(nid_objs[166]),/* "RC2-64-CBC" */
-&(nid_objs[37]),/* "RC2-CBC" */
-&(nid_objs[39]),/* "RC2-CFB" */
-&(nid_objs[38]),/* "RC2-ECB" */
-&(nid_objs[40]),/* "RC2-OFB" */
-&(nid_objs[ 5]),/* "RC4" */
-&(nid_objs[97]),/* "RC4-40" */
-&(nid_objs[120]),/* "RC5-CBC" */
-&(nid_objs[122]),/* "RC5-CFB" */
-&(nid_objs[121]),/* "RC5-ECB" */
-&(nid_objs[123]),/* "RC5-OFB" */
-&(nid_objs[117]),/* "RIPEMD160" */
-&(nid_objs[124]),/* "RLE" */
-&(nid_objs[19]),/* "RSA" */
-&(nid_objs[ 7]),/* "RSA-MD2" */
-&(nid_objs[396]),/* "RSA-MD4" */
-&(nid_objs[ 8]),/* "RSA-MD5" */
-&(nid_objs[96]),/* "RSA-MDC2" */
-&(nid_objs[104]),/* "RSA-NP-MD5" */
-&(nid_objs[119]),/* "RSA-RIPEMD160" */
-&(nid_objs[42]),/* "RSA-SHA" */
-&(nid_objs[65]),/* "RSA-SHA1" */
-&(nid_objs[115]),/* "RSA-SHA1-2" */
-&(nid_objs[671]),/* "RSA-SHA224" */
-&(nid_objs[668]),/* "RSA-SHA256" */
-&(nid_objs[669]),/* "RSA-SHA384" */
-&(nid_objs[670]),/* "RSA-SHA512" */
-&(nid_objs[777]),/* "SEED-CBC" */
-&(nid_objs[779]),/* "SEED-CFB" */
-&(nid_objs[776]),/* "SEED-ECB" */
-&(nid_objs[778]),/* "SEED-OFB" */
-&(nid_objs[41]),/* "SHA" */
-&(nid_objs[64]),/* "SHA1" */
-&(nid_objs[675]),/* "SHA224" */
-&(nid_objs[672]),/* "SHA256" */
-&(nid_objs[673]),/* "SHA384" */
-&(nid_objs[674]),/* "SHA512" */
-&(nid_objs[188]),/* "SMIME" */
-&(nid_objs[167]),/* "SMIME-CAPS" */
-&(nid_objs[100]),/* "SN" */
-&(nid_objs[16]),/* "ST" */
-&(nid_objs[143]),/* "SXNetID" */
-&(nid_objs[458]),/* "UID" */
-&(nid_objs[ 0]),/* "UNDEF" */
-&(nid_objs[11]),/* "X500" */
-&(nid_objs[378]),/* "X500algorithms" */
-&(nid_objs[12]),/* "X509" */
-&(nid_objs[184]),/* "X9-57" */
-&(nid_objs[185]),/* "X9cm" */
-&(nid_objs[125]),/* "ZLIB" */
-&(nid_objs[478]),/* "aRecord" */
-&(nid_objs[289]),/* "aaControls" */
-&(nid_objs[287]),/* "ac-auditEntity" */
-&(nid_objs[397]),/* "ac-proxying" */
-&(nid_objs[288]),/* "ac-targeting" */
-&(nid_objs[368]),/* "acceptableResponses" */
-&(nid_objs[446]),/* "account" */
-&(nid_objs[363]),/* "ad_timestamping" */
-&(nid_objs[376]),/* "algorithm" */
-&(nid_objs[405]),/* "ansi-X9-62" */
-&(nid_objs[746]),/* "anyPolicy" */
-&(nid_objs[370]),/* "archiveCutoff" */
-&(nid_objs[484]),/* "associatedDomain" */
-&(nid_objs[485]),/* "associatedName" */
-&(nid_objs[501]),/* "audio" */
-&(nid_objs[177]),/* "authorityInfoAccess" */
-&(nid_objs[90]),/* "authorityKeyIdentifier" */
-&(nid_objs[882]),/* "authorityRevocationList" */
-&(nid_objs[87]),/* "basicConstraints" */
-&(nid_objs[365]),/* "basicOCSPResponse" */
-&(nid_objs[285]),/* "biometricInfo" */
-&(nid_objs[494]),/* "buildingName" */
-&(nid_objs[860]),/* "businessCategory" */
-&(nid_objs[691]),/* "c2onb191v4" */
-&(nid_objs[692]),/* "c2onb191v5" */
-&(nid_objs[697]),/* "c2onb239v4" */
-&(nid_objs[698]),/* "c2onb239v5" */
-&(nid_objs[684]),/* "c2pnb163v1" */
-&(nid_objs[685]),/* "c2pnb163v2" */
-&(nid_objs[686]),/* "c2pnb163v3" */
-&(nid_objs[687]),/* "c2pnb176v1" */
-&(nid_objs[693]),/* "c2pnb208w1" */
-&(nid_objs[699]),/* "c2pnb272w1" */
-&(nid_objs[700]),/* "c2pnb304w1" */
-&(nid_objs[702]),/* "c2pnb368w1" */
-&(nid_objs[688]),/* "c2tnb191v1" */
-&(nid_objs[689]),/* "c2tnb191v2" */
-&(nid_objs[690]),/* "c2tnb191v3" */
-&(nid_objs[694]),/* "c2tnb239v1" */
-&(nid_objs[695]),/* "c2tnb239v2" */
-&(nid_objs[696]),/* "c2tnb239v3" */
-&(nid_objs[701]),/* "c2tnb359v1" */
-&(nid_objs[703]),/* "c2tnb431r1" */
-&(nid_objs[881]),/* "cACertificate" */
-&(nid_objs[483]),/* "cNAMERecord" */
-&(nid_objs[179]),/* "caIssuers" */
-&(nid_objs[785]),/* "caRepository" */
-&(nid_objs[443]),/* "caseIgnoreIA5StringSyntax" */
-&(nid_objs[152]),/* "certBag" */
-&(nid_objs[677]),/* "certicom-arc" */
-&(nid_objs[771]),/* "certificateIssuer" */
-&(nid_objs[89]),/* "certificatePolicies" */
-&(nid_objs[883]),/* "certificateRevocationList" */
-&(nid_objs[54]),/* "challengePassword" */
-&(nid_objs[407]),/* "characteristic-two-field" */
-&(nid_objs[395]),/* "clearance" */
-&(nid_objs[130]),/* "clientAuth" */
-&(nid_objs[131]),/* "codeSigning" */
-&(nid_objs[50]),/* "contentType" */
-&(nid_objs[53]),/* "countersignature" */
-&(nid_objs[153]),/* "crlBag" */
-&(nid_objs[103]),/* "crlDistributionPoints" */
-&(nid_objs[88]),/* "crlNumber" */
-&(nid_objs[884]),/* "crossCertificatePair" */
-&(nid_objs[806]),/* "cryptocom" */
-&(nid_objs[805]),/* "cryptopro" */
-&(nid_objs[500]),/* "dITRedirect" */
-&(nid_objs[451]),/* "dNSDomain" */
-&(nid_objs[495]),/* "dSAQuality" */
-&(nid_objs[434]),/* "data" */
-&(nid_objs[390]),/* "dcobject" */
-&(nid_objs[140]),/* "deltaCRL" */
-&(nid_objs[891]),/* "deltaRevocationList" */
-&(nid_objs[107]),/* "description" */
-&(nid_objs[871]),/* "destinationIndicator" */
-&(nid_objs[28]),/* "dhKeyAgreement" */
-&(nid_objs[382]),/* "directory" */
-&(nid_objs[887]),/* "distinguishedName" */
-&(nid_objs[892]),/* "dmdName" */
-&(nid_objs[174]),/* "dnQualifier" */
-&(nid_objs[447]),/* "document" */
-&(nid_objs[471]),/* "documentAuthor" */
-&(nid_objs[468]),/* "documentIdentifier" */
-&(nid_objs[472]),/* "documentLocation" */
-&(nid_objs[502]),/* "documentPublisher" */
-&(nid_objs[449]),/* "documentSeries" */
-&(nid_objs[469]),/* "documentTitle" */
-&(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[885]),/* "enhancedSearchGuide" */
-&(nid_objs[389]),/* "enterprises" */
-&(nid_objs[384]),/* "experimental" */
-&(nid_objs[172]),/* "extReq" */
-&(nid_objs[56]),/* "extendedCertificateAttributes" */
-&(nid_objs[126]),/* "extendedKeyUsage" */
-&(nid_objs[372]),/* "extendedStatus" */
-&(nid_objs[867]),/* "facsimileTelephoneNumber" */
-&(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" */
-&(nid_objs[433]),/* "holdInstructionReject" */
-&(nid_objs[486]),/* "homePostalAddress" */
-&(nid_objs[473]),/* "homeTelephoneNumber" */
-&(nid_objs[466]),/* "host" */
-&(nid_objs[889]),/* "houseIdentifier" */
-&(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" */
-&(nid_objs[354]),/* "id-aca-authenticationInfo" */
-&(nid_objs[356]),/* "id-aca-chargingIdentity" */
-&(nid_objs[399]),/* "id-aca-encAttrs" */
-&(nid_objs[357]),/* "id-aca-group" */
-&(nid_objs[358]),/* "id-aca-role" */
-&(nid_objs[176]),/* "id-ad" */
-&(nid_objs[788]),/* "id-aes128-wrap" */
-&(nid_objs[789]),/* "id-aes192-wrap" */
-&(nid_objs[790]),/* "id-aes256-wrap" */
-&(nid_objs[262]),/* "id-alg" */
-&(nid_objs[323]),/* "id-alg-des40" */
-&(nid_objs[326]),/* "id-alg-dh-pop" */
-&(nid_objs[325]),/* "id-alg-dh-sig-hmac-sha1" */
-&(nid_objs[324]),/* "id-alg-noSignature" */
-&(nid_objs[268]),/* "id-cct" */
-&(nid_objs[361]),/* "id-cct-PKIData" */
-&(nid_objs[362]),/* "id-cct-PKIResponse" */
-&(nid_objs[360]),/* "id-cct-crs" */
-&(nid_objs[81]),/* "id-ce" */
-&(nid_objs[680]),/* "id-characteristic-two-basis" */
-&(nid_objs[263]),/* "id-cmc" */
-&(nid_objs[334]),/* "id-cmc-addExtensions" */
-&(nid_objs[346]),/* "id-cmc-confirmCertAcceptance" */
-&(nid_objs[330]),/* "id-cmc-dataReturn" */
-&(nid_objs[336]),/* "id-cmc-decryptedPOP" */
-&(nid_objs[335]),/* "id-cmc-encryptedPOP" */
-&(nid_objs[339]),/* "id-cmc-getCRL" */
-&(nid_objs[338]),/* "id-cmc-getCert" */
-&(nid_objs[328]),/* "id-cmc-identification" */
-&(nid_objs[329]),/* "id-cmc-identityProof" */
-&(nid_objs[337]),/* "id-cmc-lraPOPWitness" */
-&(nid_objs[344]),/* "id-cmc-popLinkRandom" */
-&(nid_objs[345]),/* "id-cmc-popLinkWitness" */
-&(nid_objs[343]),/* "id-cmc-queryPending" */
-&(nid_objs[333]),/* "id-cmc-recipientNonce" */
-&(nid_objs[341]),/* "id-cmc-regInfo" */
-&(nid_objs[342]),/* "id-cmc-responseInfo" */
-&(nid_objs[340]),/* "id-cmc-revokeRequest" */
-&(nid_objs[332]),/* "id-cmc-senderNonce" */
-&(nid_objs[327]),/* "id-cmc-statusInfo" */
-&(nid_objs[331]),/* "id-cmc-transactionId" */
-&(nid_objs[787]),/* "id-ct-asciiTextWithCRLF" */
-&(nid_objs[408]),/* "id-ecPublicKey" */
-&(nid_objs[508]),/* "id-hex-multipart-message" */
-&(nid_objs[507]),/* "id-hex-partial-message" */
-&(nid_objs[260]),/* "id-it" */
-&(nid_objs[302]),/* "id-it-caKeyUpdateInfo" */
-&(nid_objs[298]),/* "id-it-caProtEncCert" */
-&(nid_objs[311]),/* "id-it-confirmWaitTime" */
-&(nid_objs[303]),/* "id-it-currentCRL" */
-&(nid_objs[300]),/* "id-it-encKeyPairTypes" */
-&(nid_objs[310]),/* "id-it-implicitConfirm" */
-&(nid_objs[308]),/* "id-it-keyPairParamRep" */
-&(nid_objs[307]),/* "id-it-keyPairParamReq" */
-&(nid_objs[312]),/* "id-it-origPKIMessage" */
-&(nid_objs[301]),/* "id-it-preferredSymmAlg" */
-&(nid_objs[309]),/* "id-it-revPassphrase" */
-&(nid_objs[299]),/* "id-it-signKeyPairTypes" */
-&(nid_objs[305]),/* "id-it-subscriptionRequest" */
-&(nid_objs[306]),/* "id-it-subscriptionResponse" */
-&(nid_objs[784]),/* "id-it-suppLangTags" */
-&(nid_objs[304]),/* "id-it-unsupportedOIDs" */
-&(nid_objs[128]),/* "id-kp" */
-&(nid_objs[280]),/* "id-mod-attribute-cert" */
-&(nid_objs[274]),/* "id-mod-cmc" */
-&(nid_objs[277]),/* "id-mod-cmp" */
-&(nid_objs[284]),/* "id-mod-cmp2000" */
-&(nid_objs[273]),/* "id-mod-crmf" */
-&(nid_objs[283]),/* "id-mod-dvcs" */
-&(nid_objs[275]),/* "id-mod-kea-profile-88" */
-&(nid_objs[276]),/* "id-mod-kea-profile-93" */
-&(nid_objs[282]),/* "id-mod-ocsp" */
-&(nid_objs[278]),/* "id-mod-qualified-cert-88" */
-&(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" */
-&(nid_objs[353]),/* "id-pda-countryOfResidence" */
-&(nid_objs[348]),/* "id-pda-dateOfBirth" */
-&(nid_objs[351]),/* "id-pda-gender" */
-&(nid_objs[349]),/* "id-pda-placeOfBirth" */
-&(nid_objs[175]),/* "id-pe" */
-&(nid_objs[261]),/* "id-pkip" */
-&(nid_objs[258]),/* "id-pkix-mod" */
-&(nid_objs[269]),/* "id-pkix1-explicit-88" */
-&(nid_objs[271]),/* "id-pkix1-explicit-93" */
-&(nid_objs[270]),/* "id-pkix1-implicit-88" */
-&(nid_objs[272]),/* "id-pkix1-implicit-93" */
-&(nid_objs[662]),/* "id-ppl" */
-&(nid_objs[664]),/* "id-ppl-anyLanguage" */
-&(nid_objs[667]),/* "id-ppl-independent" */
-&(nid_objs[665]),/* "id-ppl-inheritAll" */
-&(nid_objs[267]),/* "id-qcs" */
-&(nid_objs[359]),/* "id-qcs-pkixQCSyntax-v1" */
-&(nid_objs[259]),/* "id-qt" */
-&(nid_objs[164]),/* "id-qt-cps" */
-&(nid_objs[165]),/* "id-qt-unotice" */
-&(nid_objs[313]),/* "id-regCtrl" */
-&(nid_objs[316]),/* "id-regCtrl-authenticator" */
-&(nid_objs[319]),/* "id-regCtrl-oldCertID" */
-&(nid_objs[318]),/* "id-regCtrl-pkiArchiveOptions" */
-&(nid_objs[317]),/* "id-regCtrl-pkiPublicationInfo" */
-&(nid_objs[320]),/* "id-regCtrl-protocolEncrKey" */
-&(nid_objs[315]),/* "id-regCtrl-regToken" */
-&(nid_objs[314]),/* "id-regInfo" */
-&(nid_objs[322]),/* "id-regInfo-certReq" */
-&(nid_objs[321]),/* "id-regInfo-utf8Pairs" */
-&(nid_objs[512]),/* "id-set" */
-&(nid_objs[191]),/* "id-smime-aa" */
-&(nid_objs[215]),/* "id-smime-aa-contentHint" */
-&(nid_objs[218]),/* "id-smime-aa-contentIdentifier" */
-&(nid_objs[221]),/* "id-smime-aa-contentReference" */
-&(nid_objs[240]),/* "id-smime-aa-dvcs-dvc" */
-&(nid_objs[217]),/* "id-smime-aa-encapContentType" */
-&(nid_objs[222]),/* "id-smime-aa-encrypKeyPref" */
-&(nid_objs[220]),/* "id-smime-aa-equivalentLabels" */
-&(nid_objs[232]),/* "id-smime-aa-ets-CertificateRefs" */
-&(nid_objs[233]),/* "id-smime-aa-ets-RevocationRefs" */
-&(nid_objs[238]),/* "id-smime-aa-ets-archiveTimeStamp" */
-&(nid_objs[237]),/* "id-smime-aa-ets-certCRLTimestamp" */
-&(nid_objs[234]),/* "id-smime-aa-ets-certValues" */
-&(nid_objs[227]),/* "id-smime-aa-ets-commitmentType" */
-&(nid_objs[231]),/* "id-smime-aa-ets-contentTimestamp" */
-&(nid_objs[236]),/* "id-smime-aa-ets-escTimeStamp" */
-&(nid_objs[230]),/* "id-smime-aa-ets-otherSigCert" */
-&(nid_objs[235]),/* "id-smime-aa-ets-revocationValues" */
-&(nid_objs[226]),/* "id-smime-aa-ets-sigPolicyId" */
-&(nid_objs[229]),/* "id-smime-aa-ets-signerAttr" */
-&(nid_objs[228]),/* "id-smime-aa-ets-signerLocation" */
-&(nid_objs[219]),/* "id-smime-aa-macValue" */
-&(nid_objs[214]),/* "id-smime-aa-mlExpandHistory" */
-&(nid_objs[216]),/* "id-smime-aa-msgSigDigest" */
-&(nid_objs[212]),/* "id-smime-aa-receiptRequest" */
-&(nid_objs[213]),/* "id-smime-aa-securityLabel" */
-&(nid_objs[239]),/* "id-smime-aa-signatureType" */
-&(nid_objs[223]),/* "id-smime-aa-signingCertificate" */
-&(nid_objs[224]),/* "id-smime-aa-smimeEncryptCerts" */
-&(nid_objs[225]),/* "id-smime-aa-timeStampToken" */
-&(nid_objs[192]),/* "id-smime-alg" */
-&(nid_objs[243]),/* "id-smime-alg-3DESwrap" */
-&(nid_objs[246]),/* "id-smime-alg-CMS3DESwrap" */
-&(nid_objs[247]),/* "id-smime-alg-CMSRC2wrap" */
-&(nid_objs[245]),/* "id-smime-alg-ESDH" */
-&(nid_objs[241]),/* "id-smime-alg-ESDHwith3DES" */
-&(nid_objs[242]),/* "id-smime-alg-ESDHwithRC2" */
-&(nid_objs[244]),/* "id-smime-alg-RC2wrap" */
-&(nid_objs[193]),/* "id-smime-cd" */
-&(nid_objs[248]),/* "id-smime-cd-ldap" */
-&(nid_objs[190]),/* "id-smime-ct" */
-&(nid_objs[210]),/* "id-smime-ct-DVCSRequestData" */
-&(nid_objs[211]),/* "id-smime-ct-DVCSResponseData" */
-&(nid_objs[208]),/* "id-smime-ct-TDTInfo" */
-&(nid_objs[207]),/* "id-smime-ct-TSTInfo" */
-&(nid_objs[205]),/* "id-smime-ct-authData" */
-&(nid_objs[786]),/* "id-smime-ct-compressedData" */
-&(nid_objs[209]),/* "id-smime-ct-contentInfo" */
-&(nid_objs[206]),/* "id-smime-ct-publishCert" */
-&(nid_objs[204]),/* "id-smime-ct-receipt" */
-&(nid_objs[195]),/* "id-smime-cti" */
-&(nid_objs[255]),/* "id-smime-cti-ets-proofOfApproval" */
-&(nid_objs[256]),/* "id-smime-cti-ets-proofOfCreation" */
-&(nid_objs[253]),/* "id-smime-cti-ets-proofOfDelivery" */
-&(nid_objs[251]),/* "id-smime-cti-ets-proofOfOrigin" */
-&(nid_objs[252]),/* "id-smime-cti-ets-proofOfReceipt" */
-&(nid_objs[254]),/* "id-smime-cti-ets-proofOfSender" */
-&(nid_objs[189]),/* "id-smime-mod" */
-&(nid_objs[196]),/* "id-smime-mod-cms" */
-&(nid_objs[197]),/* "id-smime-mod-ess" */
-&(nid_objs[202]),/* "id-smime-mod-ets-eSigPolicy-88" */
-&(nid_objs[203]),/* "id-smime-mod-ets-eSigPolicy-97" */
-&(nid_objs[200]),/* "id-smime-mod-ets-eSignature-88" */
-&(nid_objs[201]),/* "id-smime-mod-ets-eSignature-97" */
-&(nid_objs[199]),/* "id-smime-mod-msg-v3" */
-&(nid_objs[198]),/* "id-smime-mod-oid" */
-&(nid_objs[194]),/* "id-smime-spq" */
-&(nid_objs[250]),/* "id-smime-spq-ets-sqt-unotice" */
-&(nid_objs[249]),/* "id-smime-spq-ets-sqt-uri" */
-&(nid_objs[676]),/* "identified-organization" */
-&(nid_objs[461]),/* "info" */
-&(nid_objs[748]),/* "inhibitAnyPolicy" */
-&(nid_objs[101]),/* "initials" */
-&(nid_objs[647]),/* "international-organizations" */
-&(nid_objs[869]),/* "internationaliSDNNumber" */
-&(nid_objs[142]),/* "invalidityDate" */
-&(nid_objs[294]),/* "ipsecEndSystem" */
-&(nid_objs[295]),/* "ipsecTunnel" */
-&(nid_objs[296]),/* "ipsecUser" */
-&(nid_objs[86]),/* "issuerAltName" */
-&(nid_objs[770]),/* "issuingDistributionPoint" */
-&(nid_objs[492]),/* "janetMailbox" */
-&(nid_objs[150]),/* "keyBag" */
-&(nid_objs[83]),/* "keyUsage" */
-&(nid_objs[477]),/* "lastModifiedBy" */
-&(nid_objs[476]),/* "lastModifiedTime" */
-&(nid_objs[157]),/* "localKeyID" */
-&(nid_objs[480]),/* "mXRecord" */
-&(nid_objs[460]),/* "mail" */
-&(nid_objs[493]),/* "mailPreferenceOption" */
-&(nid_objs[467]),/* "manager" */
-&(nid_objs[809]),/* "md_gost94" */
-&(nid_objs[875]),/* "member" */
-&(nid_objs[182]),/* "member-body" */
-&(nid_objs[51]),/* "messageDigest" */
-&(nid_objs[383]),/* "mgmt" */
-&(nid_objs[504]),/* "mime-mhs" */
-&(nid_objs[506]),/* "mime-mhs-bodies" */
-&(nid_objs[505]),/* "mime-mhs-headings" */
-&(nid_objs[488]),/* "mobileTelephoneNumber" */
-&(nid_objs[136]),/* "msCTLSign" */
-&(nid_objs[135]),/* "msCodeCom" */
-&(nid_objs[134]),/* "msCodeInd" */
-&(nid_objs[138]),/* "msEFS" */
-&(nid_objs[171]),/* "msExtReq" */
-&(nid_objs[137]),/* "msSGC" */
-&(nid_objs[648]),/* "msSmartcardLogin" */
-&(nid_objs[649]),/* "msUPN" */
-&(nid_objs[481]),/* "nSRecord" */
-&(nid_objs[173]),/* "name" */
-&(nid_objs[666]),/* "nameConstraints" */
-&(nid_objs[369]),/* "noCheck" */
-&(nid_objs[403]),/* "noRevAvail" */
-&(nid_objs[72]),/* "nsBaseUrl" */
-&(nid_objs[76]),/* "nsCaPolicyUrl" */
-&(nid_objs[74]),/* "nsCaRevocationUrl" */
-&(nid_objs[58]),/* "nsCertExt" */
-&(nid_objs[79]),/* "nsCertSequence" */
-&(nid_objs[71]),/* "nsCertType" */
-&(nid_objs[78]),/* "nsComment" */
-&(nid_objs[59]),/* "nsDataType" */
-&(nid_objs[75]),/* "nsRenewalUrl" */
-&(nid_objs[73]),/* "nsRevocationUrl" */
-&(nid_objs[139]),/* "nsSGC" */
-&(nid_objs[77]),/* "nsSslServerName" */
-&(nid_objs[681]),/* "onBasis" */
-&(nid_objs[491]),/* "organizationalStatus" */
-&(nid_objs[475]),/* "otherMailbox" */
-&(nid_objs[876]),/* "owner" */
-&(nid_objs[489]),/* "pagerTelephoneNumber" */
-&(nid_objs[374]),/* "path" */
-&(nid_objs[112]),/* "pbeWithMD5AndCast5CBC" */
-&(nid_objs[499]),/* "personalSignature" */
-&(nid_objs[487]),/* "personalTitle" */
-&(nid_objs[464]),/* "photo" */
-&(nid_objs[863]),/* "physicalDeliveryOfficeName" */
-&(nid_objs[437]),/* "pilot" */
-&(nid_objs[439]),/* "pilotAttributeSyntax" */
-&(nid_objs[438]),/* "pilotAttributeType" */
-&(nid_objs[479]),/* "pilotAttributeType27" */
-&(nid_objs[456]),/* "pilotDSA" */
-&(nid_objs[441]),/* "pilotGroups" */
-&(nid_objs[444]),/* "pilotObject" */
-&(nid_objs[440]),/* "pilotObjectClass" */
-&(nid_objs[455]),/* "pilotOrganization" */
-&(nid_objs[445]),/* "pilotPerson" */
-&(nid_objs[ 2]),/* "pkcs" */
-&(nid_objs[186]),/* "pkcs1" */
-&(nid_objs[27]),/* "pkcs3" */
-&(nid_objs[187]),/* "pkcs5" */
-&(nid_objs[20]),/* "pkcs7" */
-&(nid_objs[21]),/* "pkcs7-data" */
-&(nid_objs[25]),/* "pkcs7-digestData" */
-&(nid_objs[26]),/* "pkcs7-encryptedData" */
-&(nid_objs[23]),/* "pkcs7-envelopedData" */
-&(nid_objs[24]),/* "pkcs7-signedAndEnvelopedData" */
-&(nid_objs[22]),/* "pkcs7-signedData" */
-&(nid_objs[151]),/* "pkcs8ShroudedKeyBag" */
-&(nid_objs[47]),/* "pkcs9" */
-&(nid_objs[401]),/* "policyConstraints" */
-&(nid_objs[747]),/* "policyMappings" */
-&(nid_objs[862]),/* "postOfficeBox" */
-&(nid_objs[861]),/* "postalAddress" */
-&(nid_objs[661]),/* "postalCode" */
-&(nid_objs[683]),/* "ppBasis" */
-&(nid_objs[872]),/* "preferredDeliveryMethod" */
-&(nid_objs[873]),/* "presentationAddress" */
-&(nid_objs[816]),/* "prf-gostr3411-94" */
-&(nid_objs[406]),/* "prime-field" */
-&(nid_objs[409]),/* "prime192v1" */
-&(nid_objs[410]),/* "prime192v2" */
-&(nid_objs[411]),/* "prime192v3" */
-&(nid_objs[412]),/* "prime239v1" */
-&(nid_objs[413]),/* "prime239v2" */
-&(nid_objs[414]),/* "prime239v3" */
-&(nid_objs[415]),/* "prime256v1" */
-&(nid_objs[385]),/* "private" */
-&(nid_objs[84]),/* "privateKeyUsagePeriod" */
-&(nid_objs[886]),/* "protocolInformation" */
-&(nid_objs[663]),/* "proxyCertInfo" */
-&(nid_objs[510]),/* "pseudonym" */
-&(nid_objs[435]),/* "pss" */
-&(nid_objs[286]),/* "qcStatements" */
-&(nid_objs[457]),/* "qualityLabelledData" */
-&(nid_objs[450]),/* "rFC822localPart" */
-&(nid_objs[870]),/* "registeredAddress" */
-&(nid_objs[400]),/* "role" */
-&(nid_objs[877]),/* "roleOccupant" */
-&(nid_objs[448]),/* "room" */
-&(nid_objs[463]),/* "roomNumber" */
-&(nid_objs[ 6]),/* "rsaEncryption" */
-&(nid_objs[644]),/* "rsaOAEPEncryptionSET" */
-&(nid_objs[377]),/* "rsaSignature" */
-&(nid_objs[ 1]),/* "rsadsi" */
-&(nid_objs[482]),/* "sOARecord" */
-&(nid_objs[155]),/* "safeContentsBag" */
-&(nid_objs[291]),/* "sbgp-autonomousSysNum" */
-&(nid_objs[290]),/* "sbgp-ipAddrBlock" */
-&(nid_objs[292]),/* "sbgp-routerIdentifier" */
-&(nid_objs[159]),/* "sdsiCertificate" */
-&(nid_objs[859]),/* "searchGuide" */
-&(nid_objs[704]),/* "secp112r1" */
-&(nid_objs[705]),/* "secp112r2" */
-&(nid_objs[706]),/* "secp128r1" */
-&(nid_objs[707]),/* "secp128r2" */
-&(nid_objs[708]),/* "secp160k1" */
-&(nid_objs[709]),/* "secp160r1" */
-&(nid_objs[710]),/* "secp160r2" */
-&(nid_objs[711]),/* "secp192k1" */
-&(nid_objs[712]),/* "secp224k1" */
-&(nid_objs[713]),/* "secp224r1" */
-&(nid_objs[714]),/* "secp256k1" */
-&(nid_objs[715]),/* "secp384r1" */
-&(nid_objs[716]),/* "secp521r1" */
-&(nid_objs[154]),/* "secretBag" */
-&(nid_objs[474]),/* "secretary" */
-&(nid_objs[717]),/* "sect113r1" */
-&(nid_objs[718]),/* "sect113r2" */
-&(nid_objs[719]),/* "sect131r1" */
-&(nid_objs[720]),/* "sect131r2" */
-&(nid_objs[721]),/* "sect163k1" */
-&(nid_objs[722]),/* "sect163r1" */
-&(nid_objs[723]),/* "sect163r2" */
-&(nid_objs[724]),/* "sect193r1" */
-&(nid_objs[725]),/* "sect193r2" */
-&(nid_objs[726]),/* "sect233k1" */
-&(nid_objs[727]),/* "sect233r1" */
-&(nid_objs[728]),/* "sect239k1" */
-&(nid_objs[729]),/* "sect283k1" */
-&(nid_objs[730]),/* "sect283r1" */
-&(nid_objs[731]),/* "sect409k1" */
-&(nid_objs[732]),/* "sect409r1" */
-&(nid_objs[733]),/* "sect571k1" */
-&(nid_objs[734]),/* "sect571r1" */
-&(nid_objs[386]),/* "security" */
-&(nid_objs[878]),/* "seeAlso" */
-&(nid_objs[394]),/* "selected-attribute-types" */
-&(nid_objs[105]),/* "serialNumber" */
-&(nid_objs[129]),/* "serverAuth" */
-&(nid_objs[371]),/* "serviceLocator" */
-&(nid_objs[625]),/* "set-addPolicy" */
-&(nid_objs[515]),/* "set-attr" */
-&(nid_objs[518]),/* "set-brand" */
-&(nid_objs[638]),/* "set-brand-AmericanExpress" */
-&(nid_objs[637]),/* "set-brand-Diners" */
-&(nid_objs[636]),/* "set-brand-IATA-ATA" */
-&(nid_objs[639]),/* "set-brand-JCB" */
-&(nid_objs[641]),/* "set-brand-MasterCard" */
-&(nid_objs[642]),/* "set-brand-Novus" */
-&(nid_objs[640]),/* "set-brand-Visa" */
-&(nid_objs[517]),/* "set-certExt" */
-&(nid_objs[513]),/* "set-ctype" */
-&(nid_objs[514]),/* "set-msgExt" */
-&(nid_objs[516]),/* "set-policy" */
-&(nid_objs[607]),/* "set-policy-root" */
-&(nid_objs[624]),/* "set-rootKeyThumb" */
-&(nid_objs[620]),/* "setAttr-Cert" */
-&(nid_objs[631]),/* "setAttr-GenCryptgrm" */
-&(nid_objs[623]),/* "setAttr-IssCap" */
-&(nid_objs[628]),/* "setAttr-IssCap-CVM" */
-&(nid_objs[630]),/* "setAttr-IssCap-Sig" */
-&(nid_objs[629]),/* "setAttr-IssCap-T2" */
-&(nid_objs[621]),/* "setAttr-PGWYcap" */
-&(nid_objs[635]),/* "setAttr-SecDevSig" */
-&(nid_objs[632]),/* "setAttr-T2Enc" */
-&(nid_objs[633]),/* "setAttr-T2cleartxt" */
-&(nid_objs[634]),/* "setAttr-TokICCsig" */
-&(nid_objs[627]),/* "setAttr-Token-B0Prime" */
-&(nid_objs[626]),/* "setAttr-Token-EMV" */
-&(nid_objs[622]),/* "setAttr-TokenType" */
-&(nid_objs[619]),/* "setCext-IssuerCapabilities" */
-&(nid_objs[615]),/* "setCext-PGWYcapabilities" */
-&(nid_objs[616]),/* "setCext-TokenIdentifier" */
-&(nid_objs[618]),/* "setCext-TokenType" */
-&(nid_objs[617]),/* "setCext-Track2Data" */
-&(nid_objs[611]),/* "setCext-cCertRequired" */
-&(nid_objs[609]),/* "setCext-certType" */
-&(nid_objs[608]),/* "setCext-hashedRoot" */
-&(nid_objs[610]),/* "setCext-merchData" */
-&(nid_objs[613]),/* "setCext-setExt" */
-&(nid_objs[614]),/* "setCext-setQualf" */
-&(nid_objs[612]),/* "setCext-tunneling" */
-&(nid_objs[540]),/* "setct-AcqCardCodeMsg" */
-&(nid_objs[576]),/* "setct-AcqCardCodeMsgTBE" */
-&(nid_objs[570]),/* "setct-AuthReqTBE" */
-&(nid_objs[534]),/* "setct-AuthReqTBS" */
-&(nid_objs[527]),/* "setct-AuthResBaggage" */
-&(nid_objs[571]),/* "setct-AuthResTBE" */
-&(nid_objs[572]),/* "setct-AuthResTBEX" */
-&(nid_objs[535]),/* "setct-AuthResTBS" */
-&(nid_objs[536]),/* "setct-AuthResTBSX" */
-&(nid_objs[528]),/* "setct-AuthRevReqBaggage" */
-&(nid_objs[577]),/* "setct-AuthRevReqTBE" */
-&(nid_objs[541]),/* "setct-AuthRevReqTBS" */
-&(nid_objs[529]),/* "setct-AuthRevResBaggage" */
-&(nid_objs[542]),/* "setct-AuthRevResData" */
-&(nid_objs[578]),/* "setct-AuthRevResTBE" */
-&(nid_objs[579]),/* "setct-AuthRevResTBEB" */
-&(nid_objs[543]),/* "setct-AuthRevResTBS" */
-&(nid_objs[573]),/* "setct-AuthTokenTBE" */
-&(nid_objs[537]),/* "setct-AuthTokenTBS" */
-&(nid_objs[600]),/* "setct-BCIDistributionTBS" */
-&(nid_objs[558]),/* "setct-BatchAdminReqData" */
-&(nid_objs[592]),/* "setct-BatchAdminReqTBE" */
-&(nid_objs[559]),/* "setct-BatchAdminResData" */
-&(nid_objs[593]),/* "setct-BatchAdminResTBE" */
-&(nid_objs[599]),/* "setct-CRLNotificationResTBS" */
-&(nid_objs[598]),/* "setct-CRLNotificationTBS" */
-&(nid_objs[580]),/* "setct-CapReqTBE" */
-&(nid_objs[581]),/* "setct-CapReqTBEX" */
-&(nid_objs[544]),/* "setct-CapReqTBS" */
-&(nid_objs[545]),/* "setct-CapReqTBSX" */
-&(nid_objs[546]),/* "setct-CapResData" */
-&(nid_objs[582]),/* "setct-CapResTBE" */
-&(nid_objs[583]),/* "setct-CapRevReqTBE" */
-&(nid_objs[584]),/* "setct-CapRevReqTBEX" */
-&(nid_objs[547]),/* "setct-CapRevReqTBS" */
-&(nid_objs[548]),/* "setct-CapRevReqTBSX" */
-&(nid_objs[549]),/* "setct-CapRevResData" */
-&(nid_objs[585]),/* "setct-CapRevResTBE" */
-&(nid_objs[538]),/* "setct-CapTokenData" */
-&(nid_objs[530]),/* "setct-CapTokenSeq" */
-&(nid_objs[574]),/* "setct-CapTokenTBE" */
-&(nid_objs[575]),/* "setct-CapTokenTBEX" */
-&(nid_objs[539]),/* "setct-CapTokenTBS" */
-&(nid_objs[560]),/* "setct-CardCInitResTBS" */
-&(nid_objs[566]),/* "setct-CertInqReqTBS" */
-&(nid_objs[563]),/* "setct-CertReqData" */
-&(nid_objs[595]),/* "setct-CertReqTBE" */
-&(nid_objs[596]),/* "setct-CertReqTBEX" */
-&(nid_objs[564]),/* "setct-CertReqTBS" */
-&(nid_objs[565]),/* "setct-CertResData" */
-&(nid_objs[597]),/* "setct-CertResTBE" */
-&(nid_objs[586]),/* "setct-CredReqTBE" */
-&(nid_objs[587]),/* "setct-CredReqTBEX" */
-&(nid_objs[550]),/* "setct-CredReqTBS" */
-&(nid_objs[551]),/* "setct-CredReqTBSX" */
-&(nid_objs[552]),/* "setct-CredResData" */
-&(nid_objs[588]),/* "setct-CredResTBE" */
-&(nid_objs[589]),/* "setct-CredRevReqTBE" */
-&(nid_objs[590]),/* "setct-CredRevReqTBEX" */
-&(nid_objs[553]),/* "setct-CredRevReqTBS" */
-&(nid_objs[554]),/* "setct-CredRevReqTBSX" */
-&(nid_objs[555]),/* "setct-CredRevResData" */
-&(nid_objs[591]),/* "setct-CredRevResTBE" */
-&(nid_objs[567]),/* "setct-ErrorTBS" */
-&(nid_objs[526]),/* "setct-HODInput" */
-&(nid_objs[561]),/* "setct-MeAqCInitResTBS" */
-&(nid_objs[522]),/* "setct-OIData" */
-&(nid_objs[519]),/* "setct-PANData" */
-&(nid_objs[521]),/* "setct-PANOnly" */
-&(nid_objs[520]),/* "setct-PANToken" */
-&(nid_objs[556]),/* "setct-PCertReqData" */
-&(nid_objs[557]),/* "setct-PCertResTBS" */
-&(nid_objs[523]),/* "setct-PI" */
-&(nid_objs[532]),/* "setct-PI-TBS" */
-&(nid_objs[524]),/* "setct-PIData" */
-&(nid_objs[525]),/* "setct-PIDataUnsigned" */
-&(nid_objs[568]),/* "setct-PIDualSignedTBE" */
-&(nid_objs[569]),/* "setct-PIUnsignedTBE" */
-&(nid_objs[531]),/* "setct-PInitResData" */
-&(nid_objs[533]),/* "setct-PResData" */
-&(nid_objs[594]),/* "setct-RegFormReqTBE" */
-&(nid_objs[562]),/* "setct-RegFormResTBS" */
-&(nid_objs[606]),/* "setext-cv" */
-&(nid_objs[601]),/* "setext-genCrypt" */
-&(nid_objs[602]),/* "setext-miAuth" */
-&(nid_objs[604]),/* "setext-pinAny" */
-&(nid_objs[603]),/* "setext-pinSecure" */
-&(nid_objs[605]),/* "setext-track2" */
-&(nid_objs[52]),/* "signingTime" */
-&(nid_objs[454]),/* "simpleSecurityObject" */
-&(nid_objs[496]),/* "singleLevelQuality" */
-&(nid_objs[387]),/* "snmpv2" */
-&(nid_objs[660]),/* "street" */
-&(nid_objs[85]),/* "subjectAltName" */
-&(nid_objs[769]),/* "subjectDirectoryAttributes" */
-&(nid_objs[398]),/* "subjectInfoAccess" */
-&(nid_objs[82]),/* "subjectKeyIdentifier" */
-&(nid_objs[498]),/* "subtreeMaximumQuality" */
-&(nid_objs[497]),/* "subtreeMinimumQuality" */
-&(nid_objs[890]),/* "supportedAlgorithms" */
-&(nid_objs[874]),/* "supportedApplicationContext" */
-&(nid_objs[402]),/* "targetInformation" */
-&(nid_objs[864]),/* "telephoneNumber" */
-&(nid_objs[866]),/* "teletexTerminalIdentifier" */
-&(nid_objs[865]),/* "telexNumber" */
-&(nid_objs[459]),/* "textEncodedORAddress" */
-&(nid_objs[293]),/* "textNotice" */
-&(nid_objs[133]),/* "timeStamping" */
-&(nid_objs[106]),/* "title" */
-&(nid_objs[682]),/* "tpBasis" */
-&(nid_objs[375]),/* "trustRoot" */
-&(nid_objs[436]),/* "ucl" */
-&(nid_objs[888]),/* "uniqueMember" */
-&(nid_objs[55]),/* "unstructuredAddress" */
-&(nid_objs[49]),/* "unstructuredName" */
-&(nid_objs[880]),/* "userCertificate" */
-&(nid_objs[465]),/* "userClass" */
-&(nid_objs[879]),/* "userPassword" */
-&(nid_objs[373]),/* "valid" */
-&(nid_objs[678]),/* "wap" */
-&(nid_objs[679]),/* "wap-wsg" */
-&(nid_objs[735]),/* "wap-wsg-idm-ecid-wtls1" */
-&(nid_objs[743]),/* "wap-wsg-idm-ecid-wtls10" */
-&(nid_objs[744]),/* "wap-wsg-idm-ecid-wtls11" */
-&(nid_objs[745]),/* "wap-wsg-idm-ecid-wtls12" */
-&(nid_objs[736]),/* "wap-wsg-idm-ecid-wtls3" */
-&(nid_objs[737]),/* "wap-wsg-idm-ecid-wtls4" */
-&(nid_objs[738]),/* "wap-wsg-idm-ecid-wtls5" */
-&(nid_objs[739]),/* "wap-wsg-idm-ecid-wtls6" */
-&(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[868]),/* "x121Address" */
-&(nid_objs[503]),/* "x500UniqueIdentifier" */
-&(nid_objs[158]),/* "x509Certificate" */
-&(nid_objs[160]),/* "x509Crl" */
+static const unsigned int sn_objs[NUM_SN]={
+364,	/* "AD_DVCS" */
+419,	/* "AES-128-CBC" */
+421,	/* "AES-128-CFB" */
+650,	/* "AES-128-CFB1" */
+653,	/* "AES-128-CFB8" */
+418,	/* "AES-128-ECB" */
+420,	/* "AES-128-OFB" */
+423,	/* "AES-192-CBC" */
+425,	/* "AES-192-CFB" */
+651,	/* "AES-192-CFB1" */
+654,	/* "AES-192-CFB8" */
+422,	/* "AES-192-ECB" */
+424,	/* "AES-192-OFB" */
+427,	/* "AES-256-CBC" */
+429,	/* "AES-256-CFB" */
+652,	/* "AES-256-CFB1" */
+655,	/* "AES-256-CFB8" */
+426,	/* "AES-256-ECB" */
+428,	/* "AES-256-OFB" */
+91,	/* "BF-CBC" */
+93,	/* "BF-CFB" */
+92,	/* "BF-ECB" */
+94,	/* "BF-OFB" */
+14,	/* "C" */
+751,	/* "CAMELLIA-128-CBC" */
+757,	/* "CAMELLIA-128-CFB" */
+760,	/* "CAMELLIA-128-CFB1" */
+763,	/* "CAMELLIA-128-CFB8" */
+754,	/* "CAMELLIA-128-ECB" */
+766,	/* "CAMELLIA-128-OFB" */
+752,	/* "CAMELLIA-192-CBC" */
+758,	/* "CAMELLIA-192-CFB" */
+761,	/* "CAMELLIA-192-CFB1" */
+764,	/* "CAMELLIA-192-CFB8" */
+755,	/* "CAMELLIA-192-ECB" */
+767,	/* "CAMELLIA-192-OFB" */
+753,	/* "CAMELLIA-256-CBC" */
+759,	/* "CAMELLIA-256-CFB" */
+762,	/* "CAMELLIA-256-CFB1" */
+765,	/* "CAMELLIA-256-CFB8" */
+756,	/* "CAMELLIA-256-ECB" */
+768,	/* "CAMELLIA-256-OFB" */
+108,	/* "CAST5-CBC" */
+110,	/* "CAST5-CFB" */
+109,	/* "CAST5-ECB" */
+111,	/* "CAST5-OFB" */
+13,	/* "CN" */
+141,	/* "CRLReason" */
+417,	/* "CSPName" */
+367,	/* "CrlID" */
+391,	/* "DC" */
+31,	/* "DES-CBC" */
+643,	/* "DES-CDMF" */
+30,	/* "DES-CFB" */
+656,	/* "DES-CFB1" */
+657,	/* "DES-CFB8" */
+29,	/* "DES-ECB" */
+32,	/* "DES-EDE" */
+43,	/* "DES-EDE-CBC" */
+60,	/* "DES-EDE-CFB" */
+62,	/* "DES-EDE-OFB" */
+33,	/* "DES-EDE3" */
+44,	/* "DES-EDE3-CBC" */
+61,	/* "DES-EDE3-CFB" */
+658,	/* "DES-EDE3-CFB1" */
+659,	/* "DES-EDE3-CFB8" */
+63,	/* "DES-EDE3-OFB" */
+45,	/* "DES-OFB" */
+80,	/* "DESX-CBC" */
+380,	/* "DOD" */
+116,	/* "DSA" */
+66,	/* "DSA-SHA" */
+113,	/* "DSA-SHA1" */
+70,	/* "DSA-SHA1-old" */
+67,	/* "DSA-old" */
+297,	/* "DVCS" */
+99,	/* "GN" */
+855,	/* "HMAC" */
+780,	/* "HMAC-MD5" */
+781,	/* "HMAC-SHA1" */
+381,	/* "IANA" */
+34,	/* "IDEA-CBC" */
+35,	/* "IDEA-CFB" */
+36,	/* "IDEA-ECB" */
+46,	/* "IDEA-OFB" */
+181,	/* "ISO" */
+183,	/* "ISO-US" */
+645,	/* "ITU-T" */
+646,	/* "JOINT-ISO-ITU-T" */
+773,	/* "KISA" */
+15,	/* "L" */
+856,	/* "LocalKeySet" */
+ 3,	/* "MD2" */
+257,	/* "MD4" */
+ 4,	/* "MD5" */
+114,	/* "MD5-SHA1" */
+95,	/* "MDC2" */
+388,	/* "Mail" */
+393,	/* "NULL" */
+404,	/* "NULL" */
+57,	/* "Netscape" */
+366,	/* "Nonce" */
+17,	/* "O" */
+178,	/* "OCSP" */
+180,	/* "OCSPSigning" */
+379,	/* "ORG" */
+18,	/* "OU" */
+749,	/* "Oakley-EC2N-3" */
+750,	/* "Oakley-EC2N-4" */
+ 9,	/* "PBE-MD2-DES" */
+168,	/* "PBE-MD2-RC2-64" */
+10,	/* "PBE-MD5-DES" */
+169,	/* "PBE-MD5-RC2-64" */
+147,	/* "PBE-SHA1-2DES" */
+146,	/* "PBE-SHA1-3DES" */
+170,	/* "PBE-SHA1-DES" */
+148,	/* "PBE-SHA1-RC2-128" */
+149,	/* "PBE-SHA1-RC2-40" */
+68,	/* "PBE-SHA1-RC2-64" */
+144,	/* "PBE-SHA1-RC4-128" */
+145,	/* "PBE-SHA1-RC4-40" */
+161,	/* "PBES2" */
+69,	/* "PBKDF2" */
+162,	/* "PBMAC1" */
+127,	/* "PKIX" */
+98,	/* "RC2-40-CBC" */
+166,	/* "RC2-64-CBC" */
+37,	/* "RC2-CBC" */
+39,	/* "RC2-CFB" */
+38,	/* "RC2-ECB" */
+40,	/* "RC2-OFB" */
+ 5,	/* "RC4" */
+97,	/* "RC4-40" */
+120,	/* "RC5-CBC" */
+122,	/* "RC5-CFB" */
+121,	/* "RC5-ECB" */
+123,	/* "RC5-OFB" */
+117,	/* "RIPEMD160" */
+124,	/* "RLE" */
+19,	/* "RSA" */
+ 7,	/* "RSA-MD2" */
+396,	/* "RSA-MD4" */
+ 8,	/* "RSA-MD5" */
+96,	/* "RSA-MDC2" */
+104,	/* "RSA-NP-MD5" */
+119,	/* "RSA-RIPEMD160" */
+42,	/* "RSA-SHA" */
+65,	/* "RSA-SHA1" */
+115,	/* "RSA-SHA1-2" */
+671,	/* "RSA-SHA224" */
+668,	/* "RSA-SHA256" */
+669,	/* "RSA-SHA384" */
+670,	/* "RSA-SHA512" */
+777,	/* "SEED-CBC" */
+779,	/* "SEED-CFB" */
+776,	/* "SEED-ECB" */
+778,	/* "SEED-OFB" */
+41,	/* "SHA" */
+64,	/* "SHA1" */
+675,	/* "SHA224" */
+672,	/* "SHA256" */
+673,	/* "SHA384" */
+674,	/* "SHA512" */
+188,	/* "SMIME" */
+167,	/* "SMIME-CAPS" */
+100,	/* "SN" */
+16,	/* "ST" */
+143,	/* "SXNetID" */
+458,	/* "UID" */
+ 0,	/* "UNDEF" */
+11,	/* "X500" */
+378,	/* "X500algorithms" */
+12,	/* "X509" */
+184,	/* "X9-57" */
+185,	/* "X9cm" */
+125,	/* "ZLIB" */
+478,	/* "aRecord" */
+289,	/* "aaControls" */
+287,	/* "ac-auditEntity" */
+397,	/* "ac-proxying" */
+288,	/* "ac-targeting" */
+368,	/* "acceptableResponses" */
+446,	/* "account" */
+363,	/* "ad_timestamping" */
+376,	/* "algorithm" */
+405,	/* "ansi-X9-62" */
+746,	/* "anyPolicy" */
+370,	/* "archiveCutoff" */
+484,	/* "associatedDomain" */
+485,	/* "associatedName" */
+501,	/* "audio" */
+177,	/* "authorityInfoAccess" */
+90,	/* "authorityKeyIdentifier" */
+882,	/* "authorityRevocationList" */
+87,	/* "basicConstraints" */
+365,	/* "basicOCSPResponse" */
+285,	/* "biometricInfo" */
+494,	/* "buildingName" */
+860,	/* "businessCategory" */
+691,	/* "c2onb191v4" */
+692,	/* "c2onb191v5" */
+697,	/* "c2onb239v4" */
+698,	/* "c2onb239v5" */
+684,	/* "c2pnb163v1" */
+685,	/* "c2pnb163v2" */
+686,	/* "c2pnb163v3" */
+687,	/* "c2pnb176v1" */
+693,	/* "c2pnb208w1" */
+699,	/* "c2pnb272w1" */
+700,	/* "c2pnb304w1" */
+702,	/* "c2pnb368w1" */
+688,	/* "c2tnb191v1" */
+689,	/* "c2tnb191v2" */
+690,	/* "c2tnb191v3" */
+694,	/* "c2tnb239v1" */
+695,	/* "c2tnb239v2" */
+696,	/* "c2tnb239v3" */
+701,	/* "c2tnb359v1" */
+703,	/* "c2tnb431r1" */
+881,	/* "cACertificate" */
+483,	/* "cNAMERecord" */
+179,	/* "caIssuers" */
+785,	/* "caRepository" */
+443,	/* "caseIgnoreIA5StringSyntax" */
+152,	/* "certBag" */
+677,	/* "certicom-arc" */
+771,	/* "certificateIssuer" */
+89,	/* "certificatePolicies" */
+883,	/* "certificateRevocationList" */
+54,	/* "challengePassword" */
+407,	/* "characteristic-two-field" */
+395,	/* "clearance" */
+130,	/* "clientAuth" */
+131,	/* "codeSigning" */
+50,	/* "contentType" */
+53,	/* "countersignature" */
+153,	/* "crlBag" */
+103,	/* "crlDistributionPoints" */
+88,	/* "crlNumber" */
+884,	/* "crossCertificatePair" */
+806,	/* "cryptocom" */
+805,	/* "cryptopro" */
+500,	/* "dITRedirect" */
+451,	/* "dNSDomain" */
+495,	/* "dSAQuality" */
+434,	/* "data" */
+390,	/* "dcobject" */
+140,	/* "deltaCRL" */
+891,	/* "deltaRevocationList" */
+107,	/* "description" */
+871,	/* "destinationIndicator" */
+28,	/* "dhKeyAgreement" */
+382,	/* "directory" */
+887,	/* "distinguishedName" */
+892,	/* "dmdName" */
+174,	/* "dnQualifier" */
+447,	/* "document" */
+471,	/* "documentAuthor" */
+468,	/* "documentIdentifier" */
+472,	/* "documentLocation" */
+502,	/* "documentPublisher" */
+449,	/* "documentSeries" */
+469,	/* "documentTitle" */
+470,	/* "documentVersion" */
+392,	/* "domain" */
+452,	/* "domainRelatedObject" */
+802,	/* "dsa_with_SHA224" */
+803,	/* "dsa_with_SHA256" */
+791,	/* "ecdsa-with-Recommended" */
+416,	/* "ecdsa-with-SHA1" */
+793,	/* "ecdsa-with-SHA224" */
+794,	/* "ecdsa-with-SHA256" */
+795,	/* "ecdsa-with-SHA384" */
+796,	/* "ecdsa-with-SHA512" */
+792,	/* "ecdsa-with-Specified" */
+48,	/* "emailAddress" */
+132,	/* "emailProtection" */
+885,	/* "enhancedSearchGuide" */
+389,	/* "enterprises" */
+384,	/* "experimental" */
+172,	/* "extReq" */
+56,	/* "extendedCertificateAttributes" */
+126,	/* "extendedKeyUsage" */
+372,	/* "extendedStatus" */
+867,	/* "facsimileTelephoneNumber" */
+462,	/* "favouriteDrink" */
+857,	/* "freshestCRL" */
+453,	/* "friendlyCountry" */
+490,	/* "friendlyCountryName" */
+156,	/* "friendlyName" */
+509,	/* "generationQualifier" */
+815,	/* "gost-mac" */
+811,	/* "gost2001" */
+851,	/* "gost2001cc" */
+813,	/* "gost89" */
+814,	/* "gost89-cnt" */
+812,	/* "gost94" */
+850,	/* "gost94cc" */
+797,	/* "hmacWithMD5" */
+163,	/* "hmacWithSHA1" */
+798,	/* "hmacWithSHA224" */
+799,	/* "hmacWithSHA256" */
+800,	/* "hmacWithSHA384" */
+801,	/* "hmacWithSHA512" */
+432,	/* "holdInstructionCallIssuer" */
+430,	/* "holdInstructionCode" */
+431,	/* "holdInstructionNone" */
+433,	/* "holdInstructionReject" */
+486,	/* "homePostalAddress" */
+473,	/* "homeTelephoneNumber" */
+466,	/* "host" */
+889,	/* "houseIdentifier" */
+442,	/* "iA5StringSyntax" */
+783,	/* "id-DHBasedMac" */
+824,	/* "id-Gost28147-89-CryptoPro-A-ParamSet" */
+825,	/* "id-Gost28147-89-CryptoPro-B-ParamSet" */
+826,	/* "id-Gost28147-89-CryptoPro-C-ParamSet" */
+827,	/* "id-Gost28147-89-CryptoPro-D-ParamSet" */
+819,	/* "id-Gost28147-89-CryptoPro-KeyMeshing" */
+829,	/* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */
+828,	/* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */
+830,	/* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */
+820,	/* "id-Gost28147-89-None-KeyMeshing" */
+823,	/* "id-Gost28147-89-TestParamSet" */
+849,	/* "id-Gost28147-89-cc" */
+840,	/* "id-GostR3410-2001-CryptoPro-A-ParamSet" */
+841,	/* "id-GostR3410-2001-CryptoPro-B-ParamSet" */
+842,	/* "id-GostR3410-2001-CryptoPro-C-ParamSet" */
+843,	/* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */
+844,	/* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */
+854,	/* "id-GostR3410-2001-ParamSet-cc" */
+839,	/* "id-GostR3410-2001-TestParamSet" */
+817,	/* "id-GostR3410-2001DH" */
+832,	/* "id-GostR3410-94-CryptoPro-A-ParamSet" */
+833,	/* "id-GostR3410-94-CryptoPro-B-ParamSet" */
+834,	/* "id-GostR3410-94-CryptoPro-C-ParamSet" */
+835,	/* "id-GostR3410-94-CryptoPro-D-ParamSet" */
+836,	/* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */
+837,	/* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */
+838,	/* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */
+831,	/* "id-GostR3410-94-TestParamSet" */
+845,	/* "id-GostR3410-94-a" */
+846,	/* "id-GostR3410-94-aBis" */
+847,	/* "id-GostR3410-94-b" */
+848,	/* "id-GostR3410-94-bBis" */
+818,	/* "id-GostR3410-94DH" */
+822,	/* "id-GostR3411-94-CryptoProParamSet" */
+821,	/* "id-GostR3411-94-TestParamSet" */
+807,	/* "id-GostR3411-94-with-GostR3410-2001" */
+853,	/* "id-GostR3411-94-with-GostR3410-2001-cc" */
+808,	/* "id-GostR3411-94-with-GostR3410-94" */
+852,	/* "id-GostR3411-94-with-GostR3410-94-cc" */
+810,	/* "id-HMACGostR3411-94" */
+782,	/* "id-PasswordBasedMAC" */
+266,	/* "id-aca" */
+355,	/* "id-aca-accessIdentity" */
+354,	/* "id-aca-authenticationInfo" */
+356,	/* "id-aca-chargingIdentity" */
+399,	/* "id-aca-encAttrs" */
+357,	/* "id-aca-group" */
+358,	/* "id-aca-role" */
+176,	/* "id-ad" */
+788,	/* "id-aes128-wrap" */
+789,	/* "id-aes192-wrap" */
+790,	/* "id-aes256-wrap" */
+262,	/* "id-alg" */
+323,	/* "id-alg-des40" */
+326,	/* "id-alg-dh-pop" */
+325,	/* "id-alg-dh-sig-hmac-sha1" */
+324,	/* "id-alg-noSignature" */
+268,	/* "id-cct" */
+361,	/* "id-cct-PKIData" */
+362,	/* "id-cct-PKIResponse" */
+360,	/* "id-cct-crs" */
+81,	/* "id-ce" */
+680,	/* "id-characteristic-two-basis" */
+263,	/* "id-cmc" */
+334,	/* "id-cmc-addExtensions" */
+346,	/* "id-cmc-confirmCertAcceptance" */
+330,	/* "id-cmc-dataReturn" */
+336,	/* "id-cmc-decryptedPOP" */
+335,	/* "id-cmc-encryptedPOP" */
+339,	/* "id-cmc-getCRL" */
+338,	/* "id-cmc-getCert" */
+328,	/* "id-cmc-identification" */
+329,	/* "id-cmc-identityProof" */
+337,	/* "id-cmc-lraPOPWitness" */
+344,	/* "id-cmc-popLinkRandom" */
+345,	/* "id-cmc-popLinkWitness" */
+343,	/* "id-cmc-queryPending" */
+333,	/* "id-cmc-recipientNonce" */
+341,	/* "id-cmc-regInfo" */
+342,	/* "id-cmc-responseInfo" */
+340,	/* "id-cmc-revokeRequest" */
+332,	/* "id-cmc-senderNonce" */
+327,	/* "id-cmc-statusInfo" */
+331,	/* "id-cmc-transactionId" */
+787,	/* "id-ct-asciiTextWithCRLF" */
+408,	/* "id-ecPublicKey" */
+508,	/* "id-hex-multipart-message" */
+507,	/* "id-hex-partial-message" */
+260,	/* "id-it" */
+302,	/* "id-it-caKeyUpdateInfo" */
+298,	/* "id-it-caProtEncCert" */
+311,	/* "id-it-confirmWaitTime" */
+303,	/* "id-it-currentCRL" */
+300,	/* "id-it-encKeyPairTypes" */
+310,	/* "id-it-implicitConfirm" */
+308,	/* "id-it-keyPairParamRep" */
+307,	/* "id-it-keyPairParamReq" */
+312,	/* "id-it-origPKIMessage" */
+301,	/* "id-it-preferredSymmAlg" */
+309,	/* "id-it-revPassphrase" */
+299,	/* "id-it-signKeyPairTypes" */
+305,	/* "id-it-subscriptionRequest" */
+306,	/* "id-it-subscriptionResponse" */
+784,	/* "id-it-suppLangTags" */
+304,	/* "id-it-unsupportedOIDs" */
+128,	/* "id-kp" */
+280,	/* "id-mod-attribute-cert" */
+274,	/* "id-mod-cmc" */
+277,	/* "id-mod-cmp" */
+284,	/* "id-mod-cmp2000" */
+273,	/* "id-mod-crmf" */
+283,	/* "id-mod-dvcs" */
+275,	/* "id-mod-kea-profile-88" */
+276,	/* "id-mod-kea-profile-93" */
+282,	/* "id-mod-ocsp" */
+278,	/* "id-mod-qualified-cert-88" */
+279,	/* "id-mod-qualified-cert-93" */
+281,	/* "id-mod-timestamp-protocol" */
+264,	/* "id-on" */
+858,	/* "id-on-permanentIdentifier" */
+347,	/* "id-on-personalData" */
+265,	/* "id-pda" */
+352,	/* "id-pda-countryOfCitizenship" */
+353,	/* "id-pda-countryOfResidence" */
+348,	/* "id-pda-dateOfBirth" */
+351,	/* "id-pda-gender" */
+349,	/* "id-pda-placeOfBirth" */
+175,	/* "id-pe" */
+261,	/* "id-pkip" */
+258,	/* "id-pkix-mod" */
+269,	/* "id-pkix1-explicit-88" */
+271,	/* "id-pkix1-explicit-93" */
+270,	/* "id-pkix1-implicit-88" */
+272,	/* "id-pkix1-implicit-93" */
+662,	/* "id-ppl" */
+664,	/* "id-ppl-anyLanguage" */
+667,	/* "id-ppl-independent" */
+665,	/* "id-ppl-inheritAll" */
+267,	/* "id-qcs" */
+359,	/* "id-qcs-pkixQCSyntax-v1" */
+259,	/* "id-qt" */
+164,	/* "id-qt-cps" */
+165,	/* "id-qt-unotice" */
+313,	/* "id-regCtrl" */
+316,	/* "id-regCtrl-authenticator" */
+319,	/* "id-regCtrl-oldCertID" */
+318,	/* "id-regCtrl-pkiArchiveOptions" */
+317,	/* "id-regCtrl-pkiPublicationInfo" */
+320,	/* "id-regCtrl-protocolEncrKey" */
+315,	/* "id-regCtrl-regToken" */
+314,	/* "id-regInfo" */
+322,	/* "id-regInfo-certReq" */
+321,	/* "id-regInfo-utf8Pairs" */
+512,	/* "id-set" */
+191,	/* "id-smime-aa" */
+215,	/* "id-smime-aa-contentHint" */
+218,	/* "id-smime-aa-contentIdentifier" */
+221,	/* "id-smime-aa-contentReference" */
+240,	/* "id-smime-aa-dvcs-dvc" */
+217,	/* "id-smime-aa-encapContentType" */
+222,	/* "id-smime-aa-encrypKeyPref" */
+220,	/* "id-smime-aa-equivalentLabels" */
+232,	/* "id-smime-aa-ets-CertificateRefs" */
+233,	/* "id-smime-aa-ets-RevocationRefs" */
+238,	/* "id-smime-aa-ets-archiveTimeStamp" */
+237,	/* "id-smime-aa-ets-certCRLTimestamp" */
+234,	/* "id-smime-aa-ets-certValues" */
+227,	/* "id-smime-aa-ets-commitmentType" */
+231,	/* "id-smime-aa-ets-contentTimestamp" */
+236,	/* "id-smime-aa-ets-escTimeStamp" */
+230,	/* "id-smime-aa-ets-otherSigCert" */
+235,	/* "id-smime-aa-ets-revocationValues" */
+226,	/* "id-smime-aa-ets-sigPolicyId" */
+229,	/* "id-smime-aa-ets-signerAttr" */
+228,	/* "id-smime-aa-ets-signerLocation" */
+219,	/* "id-smime-aa-macValue" */
+214,	/* "id-smime-aa-mlExpandHistory" */
+216,	/* "id-smime-aa-msgSigDigest" */
+212,	/* "id-smime-aa-receiptRequest" */
+213,	/* "id-smime-aa-securityLabel" */
+239,	/* "id-smime-aa-signatureType" */
+223,	/* "id-smime-aa-signingCertificate" */
+224,	/* "id-smime-aa-smimeEncryptCerts" */
+225,	/* "id-smime-aa-timeStampToken" */
+192,	/* "id-smime-alg" */
+243,	/* "id-smime-alg-3DESwrap" */
+246,	/* "id-smime-alg-CMS3DESwrap" */
+247,	/* "id-smime-alg-CMSRC2wrap" */
+245,	/* "id-smime-alg-ESDH" */
+241,	/* "id-smime-alg-ESDHwith3DES" */
+242,	/* "id-smime-alg-ESDHwithRC2" */
+244,	/* "id-smime-alg-RC2wrap" */
+193,	/* "id-smime-cd" */
+248,	/* "id-smime-cd-ldap" */
+190,	/* "id-smime-ct" */
+210,	/* "id-smime-ct-DVCSRequestData" */
+211,	/* "id-smime-ct-DVCSResponseData" */
+208,	/* "id-smime-ct-TDTInfo" */
+207,	/* "id-smime-ct-TSTInfo" */
+205,	/* "id-smime-ct-authData" */
+786,	/* "id-smime-ct-compressedData" */
+209,	/* "id-smime-ct-contentInfo" */
+206,	/* "id-smime-ct-publishCert" */
+204,	/* "id-smime-ct-receipt" */
+195,	/* "id-smime-cti" */
+255,	/* "id-smime-cti-ets-proofOfApproval" */
+256,	/* "id-smime-cti-ets-proofOfCreation" */
+253,	/* "id-smime-cti-ets-proofOfDelivery" */
+251,	/* "id-smime-cti-ets-proofOfOrigin" */
+252,	/* "id-smime-cti-ets-proofOfReceipt" */
+254,	/* "id-smime-cti-ets-proofOfSender" */
+189,	/* "id-smime-mod" */
+196,	/* "id-smime-mod-cms" */
+197,	/* "id-smime-mod-ess" */
+202,	/* "id-smime-mod-ets-eSigPolicy-88" */
+203,	/* "id-smime-mod-ets-eSigPolicy-97" */
+200,	/* "id-smime-mod-ets-eSignature-88" */
+201,	/* "id-smime-mod-ets-eSignature-97" */
+199,	/* "id-smime-mod-msg-v3" */
+198,	/* "id-smime-mod-oid" */
+194,	/* "id-smime-spq" */
+250,	/* "id-smime-spq-ets-sqt-unotice" */
+249,	/* "id-smime-spq-ets-sqt-uri" */
+676,	/* "identified-organization" */
+461,	/* "info" */
+748,	/* "inhibitAnyPolicy" */
+101,	/* "initials" */
+647,	/* "international-organizations" */
+869,	/* "internationaliSDNNumber" */
+142,	/* "invalidityDate" */
+294,	/* "ipsecEndSystem" */
+295,	/* "ipsecTunnel" */
+296,	/* "ipsecUser" */
+86,	/* "issuerAltName" */
+770,	/* "issuingDistributionPoint" */
+492,	/* "janetMailbox" */
+150,	/* "keyBag" */
+83,	/* "keyUsage" */
+477,	/* "lastModifiedBy" */
+476,	/* "lastModifiedTime" */
+157,	/* "localKeyID" */
+480,	/* "mXRecord" */
+460,	/* "mail" */
+493,	/* "mailPreferenceOption" */
+467,	/* "manager" */
+809,	/* "md_gost94" */
+875,	/* "member" */
+182,	/* "member-body" */
+51,	/* "messageDigest" */
+383,	/* "mgmt" */
+504,	/* "mime-mhs" */
+506,	/* "mime-mhs-bodies" */
+505,	/* "mime-mhs-headings" */
+488,	/* "mobileTelephoneNumber" */
+136,	/* "msCTLSign" */
+135,	/* "msCodeCom" */
+134,	/* "msCodeInd" */
+138,	/* "msEFS" */
+171,	/* "msExtReq" */
+137,	/* "msSGC" */
+648,	/* "msSmartcardLogin" */
+649,	/* "msUPN" */
+481,	/* "nSRecord" */
+173,	/* "name" */
+666,	/* "nameConstraints" */
+369,	/* "noCheck" */
+403,	/* "noRevAvail" */
+72,	/* "nsBaseUrl" */
+76,	/* "nsCaPolicyUrl" */
+74,	/* "nsCaRevocationUrl" */
+58,	/* "nsCertExt" */
+79,	/* "nsCertSequence" */
+71,	/* "nsCertType" */
+78,	/* "nsComment" */
+59,	/* "nsDataType" */
+75,	/* "nsRenewalUrl" */
+73,	/* "nsRevocationUrl" */
+139,	/* "nsSGC" */
+77,	/* "nsSslServerName" */
+681,	/* "onBasis" */
+491,	/* "organizationalStatus" */
+475,	/* "otherMailbox" */
+876,	/* "owner" */
+489,	/* "pagerTelephoneNumber" */
+374,	/* "path" */
+112,	/* "pbeWithMD5AndCast5CBC" */
+499,	/* "personalSignature" */
+487,	/* "personalTitle" */
+464,	/* "photo" */
+863,	/* "physicalDeliveryOfficeName" */
+437,	/* "pilot" */
+439,	/* "pilotAttributeSyntax" */
+438,	/* "pilotAttributeType" */
+479,	/* "pilotAttributeType27" */
+456,	/* "pilotDSA" */
+441,	/* "pilotGroups" */
+444,	/* "pilotObject" */
+440,	/* "pilotObjectClass" */
+455,	/* "pilotOrganization" */
+445,	/* "pilotPerson" */
+ 2,	/* "pkcs" */
+186,	/* "pkcs1" */
+27,	/* "pkcs3" */
+187,	/* "pkcs5" */
+20,	/* "pkcs7" */
+21,	/* "pkcs7-data" */
+25,	/* "pkcs7-digestData" */
+26,	/* "pkcs7-encryptedData" */
+23,	/* "pkcs7-envelopedData" */
+24,	/* "pkcs7-signedAndEnvelopedData" */
+22,	/* "pkcs7-signedData" */
+151,	/* "pkcs8ShroudedKeyBag" */
+47,	/* "pkcs9" */
+401,	/* "policyConstraints" */
+747,	/* "policyMappings" */
+862,	/* "postOfficeBox" */
+861,	/* "postalAddress" */
+661,	/* "postalCode" */
+683,	/* "ppBasis" */
+872,	/* "preferredDeliveryMethod" */
+873,	/* "presentationAddress" */
+816,	/* "prf-gostr3411-94" */
+406,	/* "prime-field" */
+409,	/* "prime192v1" */
+410,	/* "prime192v2" */
+411,	/* "prime192v3" */
+412,	/* "prime239v1" */
+413,	/* "prime239v2" */
+414,	/* "prime239v3" */
+415,	/* "prime256v1" */
+385,	/* "private" */
+84,	/* "privateKeyUsagePeriod" */
+886,	/* "protocolInformation" */
+663,	/* "proxyCertInfo" */
+510,	/* "pseudonym" */
+435,	/* "pss" */
+286,	/* "qcStatements" */
+457,	/* "qualityLabelledData" */
+450,	/* "rFC822localPart" */
+870,	/* "registeredAddress" */
+400,	/* "role" */
+877,	/* "roleOccupant" */
+448,	/* "room" */
+463,	/* "roomNumber" */
+ 6,	/* "rsaEncryption" */
+644,	/* "rsaOAEPEncryptionSET" */
+377,	/* "rsaSignature" */
+ 1,	/* "rsadsi" */
+482,	/* "sOARecord" */
+155,	/* "safeContentsBag" */
+291,	/* "sbgp-autonomousSysNum" */
+290,	/* "sbgp-ipAddrBlock" */
+292,	/* "sbgp-routerIdentifier" */
+159,	/* "sdsiCertificate" */
+859,	/* "searchGuide" */
+704,	/* "secp112r1" */
+705,	/* "secp112r2" */
+706,	/* "secp128r1" */
+707,	/* "secp128r2" */
+708,	/* "secp160k1" */
+709,	/* "secp160r1" */
+710,	/* "secp160r2" */
+711,	/* "secp192k1" */
+712,	/* "secp224k1" */
+713,	/* "secp224r1" */
+714,	/* "secp256k1" */
+715,	/* "secp384r1" */
+716,	/* "secp521r1" */
+154,	/* "secretBag" */
+474,	/* "secretary" */
+717,	/* "sect113r1" */
+718,	/* "sect113r2" */
+719,	/* "sect131r1" */
+720,	/* "sect131r2" */
+721,	/* "sect163k1" */
+722,	/* "sect163r1" */
+723,	/* "sect163r2" */
+724,	/* "sect193r1" */
+725,	/* "sect193r2" */
+726,	/* "sect233k1" */
+727,	/* "sect233r1" */
+728,	/* "sect239k1" */
+729,	/* "sect283k1" */
+730,	/* "sect283r1" */
+731,	/* "sect409k1" */
+732,	/* "sect409r1" */
+733,	/* "sect571k1" */
+734,	/* "sect571r1" */
+386,	/* "security" */
+878,	/* "seeAlso" */
+394,	/* "selected-attribute-types" */
+105,	/* "serialNumber" */
+129,	/* "serverAuth" */
+371,	/* "serviceLocator" */
+625,	/* "set-addPolicy" */
+515,	/* "set-attr" */
+518,	/* "set-brand" */
+638,	/* "set-brand-AmericanExpress" */
+637,	/* "set-brand-Diners" */
+636,	/* "set-brand-IATA-ATA" */
+639,	/* "set-brand-JCB" */
+641,	/* "set-brand-MasterCard" */
+642,	/* "set-brand-Novus" */
+640,	/* "set-brand-Visa" */
+517,	/* "set-certExt" */
+513,	/* "set-ctype" */
+514,	/* "set-msgExt" */
+516,	/* "set-policy" */
+607,	/* "set-policy-root" */
+624,	/* "set-rootKeyThumb" */
+620,	/* "setAttr-Cert" */
+631,	/* "setAttr-GenCryptgrm" */
+623,	/* "setAttr-IssCap" */
+628,	/* "setAttr-IssCap-CVM" */
+630,	/* "setAttr-IssCap-Sig" */
+629,	/* "setAttr-IssCap-T2" */
+621,	/* "setAttr-PGWYcap" */
+635,	/* "setAttr-SecDevSig" */
+632,	/* "setAttr-T2Enc" */
+633,	/* "setAttr-T2cleartxt" */
+634,	/* "setAttr-TokICCsig" */
+627,	/* "setAttr-Token-B0Prime" */
+626,	/* "setAttr-Token-EMV" */
+622,	/* "setAttr-TokenType" */
+619,	/* "setCext-IssuerCapabilities" */
+615,	/* "setCext-PGWYcapabilities" */
+616,	/* "setCext-TokenIdentifier" */
+618,	/* "setCext-TokenType" */
+617,	/* "setCext-Track2Data" */
+611,	/* "setCext-cCertRequired" */
+609,	/* "setCext-certType" */
+608,	/* "setCext-hashedRoot" */
+610,	/* "setCext-merchData" */
+613,	/* "setCext-setExt" */
+614,	/* "setCext-setQualf" */
+612,	/* "setCext-tunneling" */
+540,	/* "setct-AcqCardCodeMsg" */
+576,	/* "setct-AcqCardCodeMsgTBE" */
+570,	/* "setct-AuthReqTBE" */
+534,	/* "setct-AuthReqTBS" */
+527,	/* "setct-AuthResBaggage" */
+571,	/* "setct-AuthResTBE" */
+572,	/* "setct-AuthResTBEX" */
+535,	/* "setct-AuthResTBS" */
+536,	/* "setct-AuthResTBSX" */
+528,	/* "setct-AuthRevReqBaggage" */
+577,	/* "setct-AuthRevReqTBE" */
+541,	/* "setct-AuthRevReqTBS" */
+529,	/* "setct-AuthRevResBaggage" */
+542,	/* "setct-AuthRevResData" */
+578,	/* "setct-AuthRevResTBE" */
+579,	/* "setct-AuthRevResTBEB" */
+543,	/* "setct-AuthRevResTBS" */
+573,	/* "setct-AuthTokenTBE" */
+537,	/* "setct-AuthTokenTBS" */
+600,	/* "setct-BCIDistributionTBS" */
+558,	/* "setct-BatchAdminReqData" */
+592,	/* "setct-BatchAdminReqTBE" */
+559,	/* "setct-BatchAdminResData" */
+593,	/* "setct-BatchAdminResTBE" */
+599,	/* "setct-CRLNotificationResTBS" */
+598,	/* "setct-CRLNotificationTBS" */
+580,	/* "setct-CapReqTBE" */
+581,	/* "setct-CapReqTBEX" */
+544,	/* "setct-CapReqTBS" */
+545,	/* "setct-CapReqTBSX" */
+546,	/* "setct-CapResData" */
+582,	/* "setct-CapResTBE" */
+583,	/* "setct-CapRevReqTBE" */
+584,	/* "setct-CapRevReqTBEX" */
+547,	/* "setct-CapRevReqTBS" */
+548,	/* "setct-CapRevReqTBSX" */
+549,	/* "setct-CapRevResData" */
+585,	/* "setct-CapRevResTBE" */
+538,	/* "setct-CapTokenData" */
+530,	/* "setct-CapTokenSeq" */
+574,	/* "setct-CapTokenTBE" */
+575,	/* "setct-CapTokenTBEX" */
+539,	/* "setct-CapTokenTBS" */
+560,	/* "setct-CardCInitResTBS" */
+566,	/* "setct-CertInqReqTBS" */
+563,	/* "setct-CertReqData" */
+595,	/* "setct-CertReqTBE" */
+596,	/* "setct-CertReqTBEX" */
+564,	/* "setct-CertReqTBS" */
+565,	/* "setct-CertResData" */
+597,	/* "setct-CertResTBE" */
+586,	/* "setct-CredReqTBE" */
+587,	/* "setct-CredReqTBEX" */
+550,	/* "setct-CredReqTBS" */
+551,	/* "setct-CredReqTBSX" */
+552,	/* "setct-CredResData" */
+588,	/* "setct-CredResTBE" */
+589,	/* "setct-CredRevReqTBE" */
+590,	/* "setct-CredRevReqTBEX" */
+553,	/* "setct-CredRevReqTBS" */
+554,	/* "setct-CredRevReqTBSX" */
+555,	/* "setct-CredRevResData" */
+591,	/* "setct-CredRevResTBE" */
+567,	/* "setct-ErrorTBS" */
+526,	/* "setct-HODInput" */
+561,	/* "setct-MeAqCInitResTBS" */
+522,	/* "setct-OIData" */
+519,	/* "setct-PANData" */
+521,	/* "setct-PANOnly" */
+520,	/* "setct-PANToken" */
+556,	/* "setct-PCertReqData" */
+557,	/* "setct-PCertResTBS" */
+523,	/* "setct-PI" */
+532,	/* "setct-PI-TBS" */
+524,	/* "setct-PIData" */
+525,	/* "setct-PIDataUnsigned" */
+568,	/* "setct-PIDualSignedTBE" */
+569,	/* "setct-PIUnsignedTBE" */
+531,	/* "setct-PInitResData" */
+533,	/* "setct-PResData" */
+594,	/* "setct-RegFormReqTBE" */
+562,	/* "setct-RegFormResTBS" */
+606,	/* "setext-cv" */
+601,	/* "setext-genCrypt" */
+602,	/* "setext-miAuth" */
+604,	/* "setext-pinAny" */
+603,	/* "setext-pinSecure" */
+605,	/* "setext-track2" */
+52,	/* "signingTime" */
+454,	/* "simpleSecurityObject" */
+496,	/* "singleLevelQuality" */
+387,	/* "snmpv2" */
+660,	/* "street" */
+85,	/* "subjectAltName" */
+769,	/* "subjectDirectoryAttributes" */
+398,	/* "subjectInfoAccess" */
+82,	/* "subjectKeyIdentifier" */
+498,	/* "subtreeMaximumQuality" */
+497,	/* "subtreeMinimumQuality" */
+890,	/* "supportedAlgorithms" */
+874,	/* "supportedApplicationContext" */
+402,	/* "targetInformation" */
+864,	/* "telephoneNumber" */
+866,	/* "teletexTerminalIdentifier" */
+865,	/* "telexNumber" */
+459,	/* "textEncodedORAddress" */
+293,	/* "textNotice" */
+133,	/* "timeStamping" */
+106,	/* "title" */
+682,	/* "tpBasis" */
+375,	/* "trustRoot" */
+436,	/* "ucl" */
+888,	/* "uniqueMember" */
+55,	/* "unstructuredAddress" */
+49,	/* "unstructuredName" */
+880,	/* "userCertificate" */
+465,	/* "userClass" */
+879,	/* "userPassword" */
+373,	/* "valid" */
+678,	/* "wap" */
+679,	/* "wap-wsg" */
+735,	/* "wap-wsg-idm-ecid-wtls1" */
+743,	/* "wap-wsg-idm-ecid-wtls10" */
+744,	/* "wap-wsg-idm-ecid-wtls11" */
+745,	/* "wap-wsg-idm-ecid-wtls12" */
+736,	/* "wap-wsg-idm-ecid-wtls3" */
+737,	/* "wap-wsg-idm-ecid-wtls4" */
+738,	/* "wap-wsg-idm-ecid-wtls5" */
+739,	/* "wap-wsg-idm-ecid-wtls6" */
+740,	/* "wap-wsg-idm-ecid-wtls7" */
+741,	/* "wap-wsg-idm-ecid-wtls8" */
+742,	/* "wap-wsg-idm-ecid-wtls9" */
+804,	/* "whirlpool" */
+868,	/* "x121Address" */
+503,	/* "x500UniqueIdentifier" */
+158,	/* "x509Certificate" */
+160,	/* "x509Crl" */
 };
 
-static ASN1_OBJECT *ln_objs[NUM_LN]={
-&(nid_objs[363]),/* "AD Time Stamping" */
-&(nid_objs[405]),/* "ANSI X9.62" */
-&(nid_objs[368]),/* "Acceptable OCSP Responses" */
-&(nid_objs[664]),/* "Any language" */
-&(nid_objs[177]),/* "Authority Information Access" */
-&(nid_objs[365]),/* "Basic OCSP Response" */
-&(nid_objs[285]),/* "Biometric Info" */
-&(nid_objs[179]),/* "CA Issuers" */
-&(nid_objs[785]),/* "CA Repository" */
-&(nid_objs[131]),/* "Code Signing" */
-&(nid_objs[783]),/* "Diffie-Hellman based MAC" */
-&(nid_objs[382]),/* "Directory" */
-&(nid_objs[392]),/* "Domain" */
-&(nid_objs[132]),/* "E-mail Protection" */
-&(nid_objs[389]),/* "Enterprises" */
-&(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" */
-&(nid_objs[433]),/* "Hold Instruction Reject" */
-&(nid_objs[634]),/* "ICC or token signature" */
-&(nid_objs[294]),/* "IPSec End System" */
-&(nid_objs[295]),/* "IPSec Tunnel" */
-&(nid_objs[296]),/* "IPSec User" */
-&(nid_objs[182]),/* "ISO Member Body" */
-&(nid_objs[183]),/* "ISO US Member Body" */
-&(nid_objs[667]),/* "Independent" */
-&(nid_objs[665]),/* "Inherit all" */
-&(nid_objs[647]),/* "International Organizations" */
-&(nid_objs[142]),/* "Invalidity Date" */
-&(nid_objs[504]),/* "MIME MHS" */
-&(nid_objs[388]),/* "Mail" */
-&(nid_objs[383]),/* "Management" */
-&(nid_objs[417]),/* "Microsoft CSP Name" */
-&(nid_objs[135]),/* "Microsoft Commercial Code Signing" */
-&(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" */
-&(nid_objs[649]),/* "Microsoft Universal Principal Name" */
-&(nid_objs[393]),/* "NULL" */
-&(nid_objs[404]),/* "NULL" */
-&(nid_objs[72]),/* "Netscape Base Url" */
-&(nid_objs[76]),/* "Netscape CA Policy Url" */
-&(nid_objs[74]),/* "Netscape CA Revocation Url" */
-&(nid_objs[71]),/* "Netscape Cert Type" */
-&(nid_objs[58]),/* "Netscape Certificate Extension" */
-&(nid_objs[79]),/* "Netscape Certificate Sequence" */
-&(nid_objs[78]),/* "Netscape Comment" */
-&(nid_objs[57]),/* "Netscape Communications Corp." */
-&(nid_objs[59]),/* "Netscape Data Type" */
-&(nid_objs[75]),/* "Netscape Renewal Url" */
-&(nid_objs[73]),/* "Netscape Revocation Url" */
-&(nid_objs[77]),/* "Netscape SSL Server Name" */
-&(nid_objs[139]),/* "Netscape Server Gated Crypto" */
-&(nid_objs[178]),/* "OCSP" */
-&(nid_objs[370]),/* "OCSP Archive Cutoff" */
-&(nid_objs[367]),/* "OCSP CRL ID" */
-&(nid_objs[369]),/* "OCSP No Check" */
-&(nid_objs[366]),/* "OCSP Nonce" */
-&(nid_objs[371]),/* "OCSP Service Locator" */
-&(nid_objs[180]),/* "OCSP Signing" */
-&(nid_objs[161]),/* "PBES2" */
-&(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" */
-&(nid_objs[663]),/* "Proxy Certificate Information" */
-&(nid_objs[ 1]),/* "RSA Data Security, Inc." */
-&(nid_objs[ 2]),/* "RSA Data Security, Inc. PKCS" */
-&(nid_objs[188]),/* "S/MIME" */
-&(nid_objs[167]),/* "S/MIME Capabilities" */
-&(nid_objs[387]),/* "SNMPv2" */
-&(nid_objs[512]),/* "Secure Electronic Transactions" */
-&(nid_objs[386]),/* "Security" */
-&(nid_objs[394]),/* "Selected Attribute Types" */
-&(nid_objs[143]),/* "Strong Extranet ID" */
-&(nid_objs[398]),/* "Subject Information Access" */
-&(nid_objs[130]),/* "TLS Web Client Authentication" */
-&(nid_objs[129]),/* "TLS Web Server Authentication" */
-&(nid_objs[133]),/* "Time Stamping" */
-&(nid_objs[375]),/* "Trust Root" */
-&(nid_objs[12]),/* "X509" */
-&(nid_objs[402]),/* "X509v3 AC Targeting" */
-&(nid_objs[746]),/* "X509v3 Any Policy" */
-&(nid_objs[90]),/* "X509v3 Authority Key Identifier" */
-&(nid_objs[87]),/* "X509v3 Basic Constraints" */
-&(nid_objs[103]),/* "X509v3 CRL Distribution Points" */
-&(nid_objs[88]),/* "X509v3 CRL Number" */
-&(nid_objs[141]),/* "X509v3 CRL Reason Code" */
-&(nid_objs[771]),/* "X509v3 Certificate Issuer" */
-&(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" */
-&(nid_objs[83]),/* "X509v3 Key Usage" */
-&(nid_objs[666]),/* "X509v3 Name Constraints" */
-&(nid_objs[403]),/* "X509v3 No Revocation Available" */
-&(nid_objs[401]),/* "X509v3 Policy Constraints" */
-&(nid_objs[747]),/* "X509v3 Policy Mappings" */
-&(nid_objs[84]),/* "X509v3 Private Key Usage Period" */
-&(nid_objs[85]),/* "X509v3 Subject Alternative Name" */
-&(nid_objs[769]),/* "X509v3 Subject Directory Attributes" */
-&(nid_objs[82]),/* "X509v3 Subject Key Identifier" */
-&(nid_objs[184]),/* "X9.57" */
-&(nid_objs[185]),/* "X9.57 CM ?" */
-&(nid_objs[478]),/* "aRecord" */
-&(nid_objs[289]),/* "aaControls" */
-&(nid_objs[287]),/* "ac-auditEntity" */
-&(nid_objs[397]),/* "ac-proxying" */
-&(nid_objs[288]),/* "ac-targeting" */
-&(nid_objs[446]),/* "account" */
-&(nid_objs[364]),/* "ad dvcs" */
-&(nid_objs[606]),/* "additional verification" */
-&(nid_objs[419]),/* "aes-128-cbc" */
-&(nid_objs[421]),/* "aes-128-cfb" */
-&(nid_objs[650]),/* "aes-128-cfb1" */
-&(nid_objs[653]),/* "aes-128-cfb8" */
-&(nid_objs[418]),/* "aes-128-ecb" */
-&(nid_objs[420]),/* "aes-128-ofb" */
-&(nid_objs[423]),/* "aes-192-cbc" */
-&(nid_objs[425]),/* "aes-192-cfb" */
-&(nid_objs[651]),/* "aes-192-cfb1" */
-&(nid_objs[654]),/* "aes-192-cfb8" */
-&(nid_objs[422]),/* "aes-192-ecb" */
-&(nid_objs[424]),/* "aes-192-ofb" */
-&(nid_objs[427]),/* "aes-256-cbc" */
-&(nid_objs[429]),/* "aes-256-cfb" */
-&(nid_objs[652]),/* "aes-256-cfb1" */
-&(nid_objs[655]),/* "aes-256-cfb8" */
-&(nid_objs[426]),/* "aes-256-ecb" */
-&(nid_objs[428]),/* "aes-256-ofb" */
-&(nid_objs[376]),/* "algorithm" */
-&(nid_objs[484]),/* "associatedDomain" */
-&(nid_objs[485]),/* "associatedName" */
-&(nid_objs[501]),/* "audio" */
-&(nid_objs[882]),/* "authorityRevocationList" */
-&(nid_objs[91]),/* "bf-cbc" */
-&(nid_objs[93]),/* "bf-cfb" */
-&(nid_objs[92]),/* "bf-ecb" */
-&(nid_objs[94]),/* "bf-ofb" */
-&(nid_objs[494]),/* "buildingName" */
-&(nid_objs[860]),/* "businessCategory" */
-&(nid_objs[691]),/* "c2onb191v4" */
-&(nid_objs[692]),/* "c2onb191v5" */
-&(nid_objs[697]),/* "c2onb239v4" */
-&(nid_objs[698]),/* "c2onb239v5" */
-&(nid_objs[684]),/* "c2pnb163v1" */
-&(nid_objs[685]),/* "c2pnb163v2" */
-&(nid_objs[686]),/* "c2pnb163v3" */
-&(nid_objs[687]),/* "c2pnb176v1" */
-&(nid_objs[693]),/* "c2pnb208w1" */
-&(nid_objs[699]),/* "c2pnb272w1" */
-&(nid_objs[700]),/* "c2pnb304w1" */
-&(nid_objs[702]),/* "c2pnb368w1" */
-&(nid_objs[688]),/* "c2tnb191v1" */
-&(nid_objs[689]),/* "c2tnb191v2" */
-&(nid_objs[690]),/* "c2tnb191v3" */
-&(nid_objs[694]),/* "c2tnb239v1" */
-&(nid_objs[695]),/* "c2tnb239v2" */
-&(nid_objs[696]),/* "c2tnb239v3" */
-&(nid_objs[701]),/* "c2tnb359v1" */
-&(nid_objs[703]),/* "c2tnb431r1" */
-&(nid_objs[881]),/* "cACertificate" */
-&(nid_objs[483]),/* "cNAMERecord" */
-&(nid_objs[751]),/* "camellia-128-cbc" */
-&(nid_objs[757]),/* "camellia-128-cfb" */
-&(nid_objs[760]),/* "camellia-128-cfb1" */
-&(nid_objs[763]),/* "camellia-128-cfb8" */
-&(nid_objs[754]),/* "camellia-128-ecb" */
-&(nid_objs[766]),/* "camellia-128-ofb" */
-&(nid_objs[752]),/* "camellia-192-cbc" */
-&(nid_objs[758]),/* "camellia-192-cfb" */
-&(nid_objs[761]),/* "camellia-192-cfb1" */
-&(nid_objs[764]),/* "camellia-192-cfb8" */
-&(nid_objs[755]),/* "camellia-192-ecb" */
-&(nid_objs[767]),/* "camellia-192-ofb" */
-&(nid_objs[753]),/* "camellia-256-cbc" */
-&(nid_objs[759]),/* "camellia-256-cfb" */
-&(nid_objs[762]),/* "camellia-256-cfb1" */
-&(nid_objs[765]),/* "camellia-256-cfb8" */
-&(nid_objs[756]),/* "camellia-256-ecb" */
-&(nid_objs[768]),/* "camellia-256-ofb" */
-&(nid_objs[443]),/* "caseIgnoreIA5StringSyntax" */
-&(nid_objs[108]),/* "cast5-cbc" */
-&(nid_objs[110]),/* "cast5-cfb" */
-&(nid_objs[109]),/* "cast5-ecb" */
-&(nid_objs[111]),/* "cast5-ofb" */
-&(nid_objs[152]),/* "certBag" */
-&(nid_objs[677]),/* "certicom-arc" */
-&(nid_objs[517]),/* "certificate extensions" */
-&(nid_objs[883]),/* "certificateRevocationList" */
-&(nid_objs[54]),/* "challengePassword" */
-&(nid_objs[407]),/* "characteristic-two-field" */
-&(nid_objs[395]),/* "clearance" */
-&(nid_objs[633]),/* "cleartext track 2" */
-&(nid_objs[13]),/* "commonName" */
-&(nid_objs[513]),/* "content types" */
-&(nid_objs[50]),/* "contentType" */
-&(nid_objs[53]),/* "countersignature" */
-&(nid_objs[14]),/* "countryName" */
-&(nid_objs[153]),/* "crlBag" */
-&(nid_objs[884]),/* "crossCertificatePair" */
-&(nid_objs[806]),/* "cryptocom" */
-&(nid_objs[805]),/* "cryptopro" */
-&(nid_objs[500]),/* "dITRedirect" */
-&(nid_objs[451]),/* "dNSDomain" */
-&(nid_objs[495]),/* "dSAQuality" */
-&(nid_objs[434]),/* "data" */
-&(nid_objs[390]),/* "dcObject" */
-&(nid_objs[891]),/* "deltaRevocationList" */
-&(nid_objs[31]),/* "des-cbc" */
-&(nid_objs[643]),/* "des-cdmf" */
-&(nid_objs[30]),/* "des-cfb" */
-&(nid_objs[656]),/* "des-cfb1" */
-&(nid_objs[657]),/* "des-cfb8" */
-&(nid_objs[29]),/* "des-ecb" */
-&(nid_objs[32]),/* "des-ede" */
-&(nid_objs[43]),/* "des-ede-cbc" */
-&(nid_objs[60]),/* "des-ede-cfb" */
-&(nid_objs[62]),/* "des-ede-ofb" */
-&(nid_objs[33]),/* "des-ede3" */
-&(nid_objs[44]),/* "des-ede3-cbc" */
-&(nid_objs[61]),/* "des-ede3-cfb" */
-&(nid_objs[658]),/* "des-ede3-cfb1" */
-&(nid_objs[659]),/* "des-ede3-cfb8" */
-&(nid_objs[63]),/* "des-ede3-ofb" */
-&(nid_objs[45]),/* "des-ofb" */
-&(nid_objs[107]),/* "description" */
-&(nid_objs[871]),/* "destinationIndicator" */
-&(nid_objs[80]),/* "desx-cbc" */
-&(nid_objs[28]),/* "dhKeyAgreement" */
-&(nid_objs[11]),/* "directory services (X.500)" */
-&(nid_objs[378]),/* "directory services - algorithms" */
-&(nid_objs[887]),/* "distinguishedName" */
-&(nid_objs[892]),/* "dmdName" */
-&(nid_objs[174]),/* "dnQualifier" */
-&(nid_objs[447]),/* "document" */
-&(nid_objs[471]),/* "documentAuthor" */
-&(nid_objs[468]),/* "documentIdentifier" */
-&(nid_objs[472]),/* "documentLocation" */
-&(nid_objs[502]),/* "documentPublisher" */
-&(nid_objs[449]),/* "documentSeries" */
-&(nid_objs[469]),/* "documentTitle" */
-&(nid_objs[470]),/* "documentVersion" */
-&(nid_objs[380]),/* "dod" */
-&(nid_objs[391]),/* "domainComponent" */
-&(nid_objs[452]),/* "domainRelatedObject" */
-&(nid_objs[116]),/* "dsaEncryption" */
-&(nid_objs[67]),/* "dsaEncryption-old" */
-&(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[885]),/* "enhancedSearchGuide" */
-&(nid_objs[56]),/* "extendedCertificateAttributes" */
-&(nid_objs[867]),/* "facsimileTelephoneNumber" */
-&(nid_objs[462]),/* "favouriteDrink" */
-&(nid_objs[453]),/* "friendlyCountry" */
-&(nid_objs[490]),/* "friendlyCountryName" */
-&(nid_objs[156]),/* "friendlyName" */
-&(nid_objs[631]),/* "generate cryptogram" */
-&(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[889]),/* "houseIdentifier" */
-&(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" */
-&(nid_objs[356]),/* "id-aca-chargingIdentity" */
-&(nid_objs[399]),/* "id-aca-encAttrs" */
-&(nid_objs[357]),/* "id-aca-group" */
-&(nid_objs[358]),/* "id-aca-role" */
-&(nid_objs[176]),/* "id-ad" */
-&(nid_objs[788]),/* "id-aes128-wrap" */
-&(nid_objs[789]),/* "id-aes192-wrap" */
-&(nid_objs[790]),/* "id-aes256-wrap" */
-&(nid_objs[262]),/* "id-alg" */
-&(nid_objs[323]),/* "id-alg-des40" */
-&(nid_objs[326]),/* "id-alg-dh-pop" */
-&(nid_objs[325]),/* "id-alg-dh-sig-hmac-sha1" */
-&(nid_objs[324]),/* "id-alg-noSignature" */
-&(nid_objs[268]),/* "id-cct" */
-&(nid_objs[361]),/* "id-cct-PKIData" */
-&(nid_objs[362]),/* "id-cct-PKIResponse" */
-&(nid_objs[360]),/* "id-cct-crs" */
-&(nid_objs[81]),/* "id-ce" */
-&(nid_objs[680]),/* "id-characteristic-two-basis" */
-&(nid_objs[263]),/* "id-cmc" */
-&(nid_objs[334]),/* "id-cmc-addExtensions" */
-&(nid_objs[346]),/* "id-cmc-confirmCertAcceptance" */
-&(nid_objs[330]),/* "id-cmc-dataReturn" */
-&(nid_objs[336]),/* "id-cmc-decryptedPOP" */
-&(nid_objs[335]),/* "id-cmc-encryptedPOP" */
-&(nid_objs[339]),/* "id-cmc-getCRL" */
-&(nid_objs[338]),/* "id-cmc-getCert" */
-&(nid_objs[328]),/* "id-cmc-identification" */
-&(nid_objs[329]),/* "id-cmc-identityProof" */
-&(nid_objs[337]),/* "id-cmc-lraPOPWitness" */
-&(nid_objs[344]),/* "id-cmc-popLinkRandom" */
-&(nid_objs[345]),/* "id-cmc-popLinkWitness" */
-&(nid_objs[343]),/* "id-cmc-queryPending" */
-&(nid_objs[333]),/* "id-cmc-recipientNonce" */
-&(nid_objs[341]),/* "id-cmc-regInfo" */
-&(nid_objs[342]),/* "id-cmc-responseInfo" */
-&(nid_objs[340]),/* "id-cmc-revokeRequest" */
-&(nid_objs[332]),/* "id-cmc-senderNonce" */
-&(nid_objs[327]),/* "id-cmc-statusInfo" */
-&(nid_objs[331]),/* "id-cmc-transactionId" */
-&(nid_objs[787]),/* "id-ct-asciiTextWithCRLF" */
-&(nid_objs[408]),/* "id-ecPublicKey" */
-&(nid_objs[508]),/* "id-hex-multipart-message" */
-&(nid_objs[507]),/* "id-hex-partial-message" */
-&(nid_objs[260]),/* "id-it" */
-&(nid_objs[302]),/* "id-it-caKeyUpdateInfo" */
-&(nid_objs[298]),/* "id-it-caProtEncCert" */
-&(nid_objs[311]),/* "id-it-confirmWaitTime" */
-&(nid_objs[303]),/* "id-it-currentCRL" */
-&(nid_objs[300]),/* "id-it-encKeyPairTypes" */
-&(nid_objs[310]),/* "id-it-implicitConfirm" */
-&(nid_objs[308]),/* "id-it-keyPairParamRep" */
-&(nid_objs[307]),/* "id-it-keyPairParamReq" */
-&(nid_objs[312]),/* "id-it-origPKIMessage" */
-&(nid_objs[301]),/* "id-it-preferredSymmAlg" */
-&(nid_objs[309]),/* "id-it-revPassphrase" */
-&(nid_objs[299]),/* "id-it-signKeyPairTypes" */
-&(nid_objs[305]),/* "id-it-subscriptionRequest" */
-&(nid_objs[306]),/* "id-it-subscriptionResponse" */
-&(nid_objs[784]),/* "id-it-suppLangTags" */
-&(nid_objs[304]),/* "id-it-unsupportedOIDs" */
-&(nid_objs[128]),/* "id-kp" */
-&(nid_objs[280]),/* "id-mod-attribute-cert" */
-&(nid_objs[274]),/* "id-mod-cmc" */
-&(nid_objs[277]),/* "id-mod-cmp" */
-&(nid_objs[284]),/* "id-mod-cmp2000" */
-&(nid_objs[273]),/* "id-mod-crmf" */
-&(nid_objs[283]),/* "id-mod-dvcs" */
-&(nid_objs[275]),/* "id-mod-kea-profile-88" */
-&(nid_objs[276]),/* "id-mod-kea-profile-93" */
-&(nid_objs[282]),/* "id-mod-ocsp" */
-&(nid_objs[278]),/* "id-mod-qualified-cert-88" */
-&(nid_objs[279]),/* "id-mod-qualified-cert-93" */
-&(nid_objs[281]),/* "id-mod-timestamp-protocol" */
-&(nid_objs[264]),/* "id-on" */
-&(nid_objs[347]),/* "id-on-personalData" */
-&(nid_objs[265]),/* "id-pda" */
-&(nid_objs[352]),/* "id-pda-countryOfCitizenship" */
-&(nid_objs[353]),/* "id-pda-countryOfResidence" */
-&(nid_objs[348]),/* "id-pda-dateOfBirth" */
-&(nid_objs[351]),/* "id-pda-gender" */
-&(nid_objs[349]),/* "id-pda-placeOfBirth" */
-&(nid_objs[175]),/* "id-pe" */
-&(nid_objs[261]),/* "id-pkip" */
-&(nid_objs[258]),/* "id-pkix-mod" */
-&(nid_objs[269]),/* "id-pkix1-explicit-88" */
-&(nid_objs[271]),/* "id-pkix1-explicit-93" */
-&(nid_objs[270]),/* "id-pkix1-implicit-88" */
-&(nid_objs[272]),/* "id-pkix1-implicit-93" */
-&(nid_objs[662]),/* "id-ppl" */
-&(nid_objs[267]),/* "id-qcs" */
-&(nid_objs[359]),/* "id-qcs-pkixQCSyntax-v1" */
-&(nid_objs[259]),/* "id-qt" */
-&(nid_objs[313]),/* "id-regCtrl" */
-&(nid_objs[316]),/* "id-regCtrl-authenticator" */
-&(nid_objs[319]),/* "id-regCtrl-oldCertID" */
-&(nid_objs[318]),/* "id-regCtrl-pkiArchiveOptions" */
-&(nid_objs[317]),/* "id-regCtrl-pkiPublicationInfo" */
-&(nid_objs[320]),/* "id-regCtrl-protocolEncrKey" */
-&(nid_objs[315]),/* "id-regCtrl-regToken" */
-&(nid_objs[314]),/* "id-regInfo" */
-&(nid_objs[322]),/* "id-regInfo-certReq" */
-&(nid_objs[321]),/* "id-regInfo-utf8Pairs" */
-&(nid_objs[191]),/* "id-smime-aa" */
-&(nid_objs[215]),/* "id-smime-aa-contentHint" */
-&(nid_objs[218]),/* "id-smime-aa-contentIdentifier" */
-&(nid_objs[221]),/* "id-smime-aa-contentReference" */
-&(nid_objs[240]),/* "id-smime-aa-dvcs-dvc" */
-&(nid_objs[217]),/* "id-smime-aa-encapContentType" */
-&(nid_objs[222]),/* "id-smime-aa-encrypKeyPref" */
-&(nid_objs[220]),/* "id-smime-aa-equivalentLabels" */
-&(nid_objs[232]),/* "id-smime-aa-ets-CertificateRefs" */
-&(nid_objs[233]),/* "id-smime-aa-ets-RevocationRefs" */
-&(nid_objs[238]),/* "id-smime-aa-ets-archiveTimeStamp" */
-&(nid_objs[237]),/* "id-smime-aa-ets-certCRLTimestamp" */
-&(nid_objs[234]),/* "id-smime-aa-ets-certValues" */
-&(nid_objs[227]),/* "id-smime-aa-ets-commitmentType" */
-&(nid_objs[231]),/* "id-smime-aa-ets-contentTimestamp" */
-&(nid_objs[236]),/* "id-smime-aa-ets-escTimeStamp" */
-&(nid_objs[230]),/* "id-smime-aa-ets-otherSigCert" */
-&(nid_objs[235]),/* "id-smime-aa-ets-revocationValues" */
-&(nid_objs[226]),/* "id-smime-aa-ets-sigPolicyId" */
-&(nid_objs[229]),/* "id-smime-aa-ets-signerAttr" */
-&(nid_objs[228]),/* "id-smime-aa-ets-signerLocation" */
-&(nid_objs[219]),/* "id-smime-aa-macValue" */
-&(nid_objs[214]),/* "id-smime-aa-mlExpandHistory" */
-&(nid_objs[216]),/* "id-smime-aa-msgSigDigest" */
-&(nid_objs[212]),/* "id-smime-aa-receiptRequest" */
-&(nid_objs[213]),/* "id-smime-aa-securityLabel" */
-&(nid_objs[239]),/* "id-smime-aa-signatureType" */
-&(nid_objs[223]),/* "id-smime-aa-signingCertificate" */
-&(nid_objs[224]),/* "id-smime-aa-smimeEncryptCerts" */
-&(nid_objs[225]),/* "id-smime-aa-timeStampToken" */
-&(nid_objs[192]),/* "id-smime-alg" */
-&(nid_objs[243]),/* "id-smime-alg-3DESwrap" */
-&(nid_objs[246]),/* "id-smime-alg-CMS3DESwrap" */
-&(nid_objs[247]),/* "id-smime-alg-CMSRC2wrap" */
-&(nid_objs[245]),/* "id-smime-alg-ESDH" */
-&(nid_objs[241]),/* "id-smime-alg-ESDHwith3DES" */
-&(nid_objs[242]),/* "id-smime-alg-ESDHwithRC2" */
-&(nid_objs[244]),/* "id-smime-alg-RC2wrap" */
-&(nid_objs[193]),/* "id-smime-cd" */
-&(nid_objs[248]),/* "id-smime-cd-ldap" */
-&(nid_objs[190]),/* "id-smime-ct" */
-&(nid_objs[210]),/* "id-smime-ct-DVCSRequestData" */
-&(nid_objs[211]),/* "id-smime-ct-DVCSResponseData" */
-&(nid_objs[208]),/* "id-smime-ct-TDTInfo" */
-&(nid_objs[207]),/* "id-smime-ct-TSTInfo" */
-&(nid_objs[205]),/* "id-smime-ct-authData" */
-&(nid_objs[786]),/* "id-smime-ct-compressedData" */
-&(nid_objs[209]),/* "id-smime-ct-contentInfo" */
-&(nid_objs[206]),/* "id-smime-ct-publishCert" */
-&(nid_objs[204]),/* "id-smime-ct-receipt" */
-&(nid_objs[195]),/* "id-smime-cti" */
-&(nid_objs[255]),/* "id-smime-cti-ets-proofOfApproval" */
-&(nid_objs[256]),/* "id-smime-cti-ets-proofOfCreation" */
-&(nid_objs[253]),/* "id-smime-cti-ets-proofOfDelivery" */
-&(nid_objs[251]),/* "id-smime-cti-ets-proofOfOrigin" */
-&(nid_objs[252]),/* "id-smime-cti-ets-proofOfReceipt" */
-&(nid_objs[254]),/* "id-smime-cti-ets-proofOfSender" */
-&(nid_objs[189]),/* "id-smime-mod" */
-&(nid_objs[196]),/* "id-smime-mod-cms" */
-&(nid_objs[197]),/* "id-smime-mod-ess" */
-&(nid_objs[202]),/* "id-smime-mod-ets-eSigPolicy-88" */
-&(nid_objs[203]),/* "id-smime-mod-ets-eSigPolicy-97" */
-&(nid_objs[200]),/* "id-smime-mod-ets-eSignature-88" */
-&(nid_objs[201]),/* "id-smime-mod-ets-eSignature-97" */
-&(nid_objs[199]),/* "id-smime-mod-msg-v3" */
-&(nid_objs[198]),/* "id-smime-mod-oid" */
-&(nid_objs[194]),/* "id-smime-spq" */
-&(nid_objs[250]),/* "id-smime-spq-ets-sqt-unotice" */
-&(nid_objs[249]),/* "id-smime-spq-ets-sqt-uri" */
-&(nid_objs[34]),/* "idea-cbc" */
-&(nid_objs[35]),/* "idea-cfb" */
-&(nid_objs[36]),/* "idea-ecb" */
-&(nid_objs[46]),/* "idea-ofb" */
-&(nid_objs[676]),/* "identified-organization" */
-&(nid_objs[461]),/* "info" */
-&(nid_objs[101]),/* "initials" */
-&(nid_objs[869]),/* "internationaliSDNNumber" */
-&(nid_objs[749]),/* "ipsec3" */
-&(nid_objs[750]),/* "ipsec4" */
-&(nid_objs[181]),/* "iso" */
-&(nid_objs[623]),/* "issuer capabilities" */
-&(nid_objs[645]),/* "itu-t" */
-&(nid_objs[492]),/* "janetMailbox" */
-&(nid_objs[646]),/* "joint-iso-itu-t" */
-&(nid_objs[150]),/* "keyBag" */
-&(nid_objs[773]),/* "kisa" */
-&(nid_objs[477]),/* "lastModifiedBy" */
-&(nid_objs[476]),/* "lastModifiedTime" */
-&(nid_objs[157]),/* "localKeyID" */
-&(nid_objs[15]),/* "localityName" */
-&(nid_objs[480]),/* "mXRecord" */
-&(nid_objs[493]),/* "mailPreferenceOption" */
-&(nid_objs[467]),/* "manager" */
-&(nid_objs[ 3]),/* "md2" */
-&(nid_objs[ 7]),/* "md2WithRSAEncryption" */
-&(nid_objs[257]),/* "md4" */
-&(nid_objs[396]),/* "md4WithRSAEncryption" */
-&(nid_objs[ 4]),/* "md5" */
-&(nid_objs[114]),/* "md5-sha1" */
-&(nid_objs[104]),/* "md5WithRSA" */
-&(nid_objs[ 8]),/* "md5WithRSAEncryption" */
-&(nid_objs[95]),/* "mdc2" */
-&(nid_objs[96]),/* "mdc2WithRSA" */
-&(nid_objs[875]),/* "member" */
-&(nid_objs[602]),/* "merchant initiated auth" */
-&(nid_objs[514]),/* "message extensions" */
-&(nid_objs[51]),/* "messageDigest" */
-&(nid_objs[506]),/* "mime-mhs-bodies" */
-&(nid_objs[505]),/* "mime-mhs-headings" */
-&(nid_objs[488]),/* "mobileTelephoneNumber" */
-&(nid_objs[481]),/* "nSRecord" */
-&(nid_objs[173]),/* "name" */
-&(nid_objs[681]),/* "onBasis" */
-&(nid_objs[379]),/* "org" */
-&(nid_objs[17]),/* "organizationName" */
-&(nid_objs[491]),/* "organizationalStatus" */
-&(nid_objs[18]),/* "organizationalUnitName" */
-&(nid_objs[475]),/* "otherMailbox" */
-&(nid_objs[876]),/* "owner" */
-&(nid_objs[489]),/* "pagerTelephoneNumber" */
-&(nid_objs[782]),/* "password based MAC" */
-&(nid_objs[374]),/* "path" */
-&(nid_objs[621]),/* "payment gateway capabilities" */
-&(nid_objs[ 9]),/* "pbeWithMD2AndDES-CBC" */
-&(nid_objs[168]),/* "pbeWithMD2AndRC2-CBC" */
-&(nid_objs[112]),/* "pbeWithMD5AndCast5CBC" */
-&(nid_objs[10]),/* "pbeWithMD5AndDES-CBC" */
-&(nid_objs[169]),/* "pbeWithMD5AndRC2-CBC" */
-&(nid_objs[148]),/* "pbeWithSHA1And128BitRC2-CBC" */
-&(nid_objs[144]),/* "pbeWithSHA1And128BitRC4" */
-&(nid_objs[147]),/* "pbeWithSHA1And2-KeyTripleDES-CBC" */
-&(nid_objs[146]),/* "pbeWithSHA1And3-KeyTripleDES-CBC" */
-&(nid_objs[149]),/* "pbeWithSHA1And40BitRC2-CBC" */
-&(nid_objs[145]),/* "pbeWithSHA1And40BitRC4" */
-&(nid_objs[170]),/* "pbeWithSHA1AndDES-CBC" */
-&(nid_objs[68]),/* "pbeWithSHA1AndRC2-CBC" */
-&(nid_objs[499]),/* "personalSignature" */
-&(nid_objs[487]),/* "personalTitle" */
-&(nid_objs[464]),/* "photo" */
-&(nid_objs[863]),/* "physicalDeliveryOfficeName" */
-&(nid_objs[437]),/* "pilot" */
-&(nid_objs[439]),/* "pilotAttributeSyntax" */
-&(nid_objs[438]),/* "pilotAttributeType" */
-&(nid_objs[479]),/* "pilotAttributeType27" */
-&(nid_objs[456]),/* "pilotDSA" */
-&(nid_objs[441]),/* "pilotGroups" */
-&(nid_objs[444]),/* "pilotObject" */
-&(nid_objs[440]),/* "pilotObjectClass" */
-&(nid_objs[455]),/* "pilotOrganization" */
-&(nid_objs[445]),/* "pilotPerson" */
-&(nid_objs[186]),/* "pkcs1" */
-&(nid_objs[27]),/* "pkcs3" */
-&(nid_objs[187]),/* "pkcs5" */
-&(nid_objs[20]),/* "pkcs7" */
-&(nid_objs[21]),/* "pkcs7-data" */
-&(nid_objs[25]),/* "pkcs7-digestData" */
-&(nid_objs[26]),/* "pkcs7-encryptedData" */
-&(nid_objs[23]),/* "pkcs7-envelopedData" */
-&(nid_objs[24]),/* "pkcs7-signedAndEnvelopedData" */
-&(nid_objs[22]),/* "pkcs7-signedData" */
-&(nid_objs[151]),/* "pkcs8ShroudedKeyBag" */
-&(nid_objs[47]),/* "pkcs9" */
-&(nid_objs[862]),/* "postOfficeBox" */
-&(nid_objs[861]),/* "postalAddress" */
-&(nid_objs[661]),/* "postalCode" */
-&(nid_objs[683]),/* "ppBasis" */
-&(nid_objs[872]),/* "preferredDeliveryMethod" */
-&(nid_objs[873]),/* "presentationAddress" */
-&(nid_objs[406]),/* "prime-field" */
-&(nid_objs[409]),/* "prime192v1" */
-&(nid_objs[410]),/* "prime192v2" */
-&(nid_objs[411]),/* "prime192v3" */
-&(nid_objs[412]),/* "prime239v1" */
-&(nid_objs[413]),/* "prime239v2" */
-&(nid_objs[414]),/* "prime239v3" */
-&(nid_objs[415]),/* "prime256v1" */
-&(nid_objs[886]),/* "protocolInformation" */
-&(nid_objs[510]),/* "pseudonym" */
-&(nid_objs[435]),/* "pss" */
-&(nid_objs[286]),/* "qcStatements" */
-&(nid_objs[457]),/* "qualityLabelledData" */
-&(nid_objs[450]),/* "rFC822localPart" */
-&(nid_objs[98]),/* "rc2-40-cbc" */
-&(nid_objs[166]),/* "rc2-64-cbc" */
-&(nid_objs[37]),/* "rc2-cbc" */
-&(nid_objs[39]),/* "rc2-cfb" */
-&(nid_objs[38]),/* "rc2-ecb" */
-&(nid_objs[40]),/* "rc2-ofb" */
-&(nid_objs[ 5]),/* "rc4" */
-&(nid_objs[97]),/* "rc4-40" */
-&(nid_objs[120]),/* "rc5-cbc" */
-&(nid_objs[122]),/* "rc5-cfb" */
-&(nid_objs[121]),/* "rc5-ecb" */
-&(nid_objs[123]),/* "rc5-ofb" */
-&(nid_objs[870]),/* "registeredAddress" */
-&(nid_objs[460]),/* "rfc822Mailbox" */
-&(nid_objs[117]),/* "ripemd160" */
-&(nid_objs[119]),/* "ripemd160WithRSA" */
-&(nid_objs[400]),/* "role" */
-&(nid_objs[877]),/* "roleOccupant" */
-&(nid_objs[448]),/* "room" */
-&(nid_objs[463]),/* "roomNumber" */
-&(nid_objs[19]),/* "rsa" */
-&(nid_objs[ 6]),/* "rsaEncryption" */
-&(nid_objs[644]),/* "rsaOAEPEncryptionSET" */
-&(nid_objs[377]),/* "rsaSignature" */
-&(nid_objs[124]),/* "run length compression" */
-&(nid_objs[482]),/* "sOARecord" */
-&(nid_objs[155]),/* "safeContentsBag" */
-&(nid_objs[291]),/* "sbgp-autonomousSysNum" */
-&(nid_objs[290]),/* "sbgp-ipAddrBlock" */
-&(nid_objs[292]),/* "sbgp-routerIdentifier" */
-&(nid_objs[159]),/* "sdsiCertificate" */
-&(nid_objs[859]),/* "searchGuide" */
-&(nid_objs[704]),/* "secp112r1" */
-&(nid_objs[705]),/* "secp112r2" */
-&(nid_objs[706]),/* "secp128r1" */
-&(nid_objs[707]),/* "secp128r2" */
-&(nid_objs[708]),/* "secp160k1" */
-&(nid_objs[709]),/* "secp160r1" */
-&(nid_objs[710]),/* "secp160r2" */
-&(nid_objs[711]),/* "secp192k1" */
-&(nid_objs[712]),/* "secp224k1" */
-&(nid_objs[713]),/* "secp224r1" */
-&(nid_objs[714]),/* "secp256k1" */
-&(nid_objs[715]),/* "secp384r1" */
-&(nid_objs[716]),/* "secp521r1" */
-&(nid_objs[154]),/* "secretBag" */
-&(nid_objs[474]),/* "secretary" */
-&(nid_objs[717]),/* "sect113r1" */
-&(nid_objs[718]),/* "sect113r2" */
-&(nid_objs[719]),/* "sect131r1" */
-&(nid_objs[720]),/* "sect131r2" */
-&(nid_objs[721]),/* "sect163k1" */
-&(nid_objs[722]),/* "sect163r1" */
-&(nid_objs[723]),/* "sect163r2" */
-&(nid_objs[724]),/* "sect193r1" */
-&(nid_objs[725]),/* "sect193r2" */
-&(nid_objs[726]),/* "sect233k1" */
-&(nid_objs[727]),/* "sect233r1" */
-&(nid_objs[728]),/* "sect239k1" */
-&(nid_objs[729]),/* "sect283k1" */
-&(nid_objs[730]),/* "sect283r1" */
-&(nid_objs[731]),/* "sect409k1" */
-&(nid_objs[732]),/* "sect409r1" */
-&(nid_objs[733]),/* "sect571k1" */
-&(nid_objs[734]),/* "sect571r1" */
-&(nid_objs[635]),/* "secure device signature" */
-&(nid_objs[878]),/* "seeAlso" */
-&(nid_objs[777]),/* "seed-cbc" */
-&(nid_objs[779]),/* "seed-cfb" */
-&(nid_objs[776]),/* "seed-ecb" */
-&(nid_objs[778]),/* "seed-ofb" */
-&(nid_objs[105]),/* "serialNumber" */
-&(nid_objs[625]),/* "set-addPolicy" */
-&(nid_objs[515]),/* "set-attr" */
-&(nid_objs[518]),/* "set-brand" */
-&(nid_objs[638]),/* "set-brand-AmericanExpress" */
-&(nid_objs[637]),/* "set-brand-Diners" */
-&(nid_objs[636]),/* "set-brand-IATA-ATA" */
-&(nid_objs[639]),/* "set-brand-JCB" */
-&(nid_objs[641]),/* "set-brand-MasterCard" */
-&(nid_objs[642]),/* "set-brand-Novus" */
-&(nid_objs[640]),/* "set-brand-Visa" */
-&(nid_objs[516]),/* "set-policy" */
-&(nid_objs[607]),/* "set-policy-root" */
-&(nid_objs[624]),/* "set-rootKeyThumb" */
-&(nid_objs[620]),/* "setAttr-Cert" */
-&(nid_objs[628]),/* "setAttr-IssCap-CVM" */
-&(nid_objs[630]),/* "setAttr-IssCap-Sig" */
-&(nid_objs[629]),/* "setAttr-IssCap-T2" */
-&(nid_objs[627]),/* "setAttr-Token-B0Prime" */
-&(nid_objs[626]),/* "setAttr-Token-EMV" */
-&(nid_objs[622]),/* "setAttr-TokenType" */
-&(nid_objs[619]),/* "setCext-IssuerCapabilities" */
-&(nid_objs[615]),/* "setCext-PGWYcapabilities" */
-&(nid_objs[616]),/* "setCext-TokenIdentifier" */
-&(nid_objs[618]),/* "setCext-TokenType" */
-&(nid_objs[617]),/* "setCext-Track2Data" */
-&(nid_objs[611]),/* "setCext-cCertRequired" */
-&(nid_objs[609]),/* "setCext-certType" */
-&(nid_objs[608]),/* "setCext-hashedRoot" */
-&(nid_objs[610]),/* "setCext-merchData" */
-&(nid_objs[613]),/* "setCext-setExt" */
-&(nid_objs[614]),/* "setCext-setQualf" */
-&(nid_objs[612]),/* "setCext-tunneling" */
-&(nid_objs[540]),/* "setct-AcqCardCodeMsg" */
-&(nid_objs[576]),/* "setct-AcqCardCodeMsgTBE" */
-&(nid_objs[570]),/* "setct-AuthReqTBE" */
-&(nid_objs[534]),/* "setct-AuthReqTBS" */
-&(nid_objs[527]),/* "setct-AuthResBaggage" */
-&(nid_objs[571]),/* "setct-AuthResTBE" */
-&(nid_objs[572]),/* "setct-AuthResTBEX" */
-&(nid_objs[535]),/* "setct-AuthResTBS" */
-&(nid_objs[536]),/* "setct-AuthResTBSX" */
-&(nid_objs[528]),/* "setct-AuthRevReqBaggage" */
-&(nid_objs[577]),/* "setct-AuthRevReqTBE" */
-&(nid_objs[541]),/* "setct-AuthRevReqTBS" */
-&(nid_objs[529]),/* "setct-AuthRevResBaggage" */
-&(nid_objs[542]),/* "setct-AuthRevResData" */
-&(nid_objs[578]),/* "setct-AuthRevResTBE" */
-&(nid_objs[579]),/* "setct-AuthRevResTBEB" */
-&(nid_objs[543]),/* "setct-AuthRevResTBS" */
-&(nid_objs[573]),/* "setct-AuthTokenTBE" */
-&(nid_objs[537]),/* "setct-AuthTokenTBS" */
-&(nid_objs[600]),/* "setct-BCIDistributionTBS" */
-&(nid_objs[558]),/* "setct-BatchAdminReqData" */
-&(nid_objs[592]),/* "setct-BatchAdminReqTBE" */
-&(nid_objs[559]),/* "setct-BatchAdminResData" */
-&(nid_objs[593]),/* "setct-BatchAdminResTBE" */
-&(nid_objs[599]),/* "setct-CRLNotificationResTBS" */
-&(nid_objs[598]),/* "setct-CRLNotificationTBS" */
-&(nid_objs[580]),/* "setct-CapReqTBE" */
-&(nid_objs[581]),/* "setct-CapReqTBEX" */
-&(nid_objs[544]),/* "setct-CapReqTBS" */
-&(nid_objs[545]),/* "setct-CapReqTBSX" */
-&(nid_objs[546]),/* "setct-CapResData" */
-&(nid_objs[582]),/* "setct-CapResTBE" */
-&(nid_objs[583]),/* "setct-CapRevReqTBE" */
-&(nid_objs[584]),/* "setct-CapRevReqTBEX" */
-&(nid_objs[547]),/* "setct-CapRevReqTBS" */
-&(nid_objs[548]),/* "setct-CapRevReqTBSX" */
-&(nid_objs[549]),/* "setct-CapRevResData" */
-&(nid_objs[585]),/* "setct-CapRevResTBE" */
-&(nid_objs[538]),/* "setct-CapTokenData" */
-&(nid_objs[530]),/* "setct-CapTokenSeq" */
-&(nid_objs[574]),/* "setct-CapTokenTBE" */
-&(nid_objs[575]),/* "setct-CapTokenTBEX" */
-&(nid_objs[539]),/* "setct-CapTokenTBS" */
-&(nid_objs[560]),/* "setct-CardCInitResTBS" */
-&(nid_objs[566]),/* "setct-CertInqReqTBS" */
-&(nid_objs[563]),/* "setct-CertReqData" */
-&(nid_objs[595]),/* "setct-CertReqTBE" */
-&(nid_objs[596]),/* "setct-CertReqTBEX" */
-&(nid_objs[564]),/* "setct-CertReqTBS" */
-&(nid_objs[565]),/* "setct-CertResData" */
-&(nid_objs[597]),/* "setct-CertResTBE" */
-&(nid_objs[586]),/* "setct-CredReqTBE" */
-&(nid_objs[587]),/* "setct-CredReqTBEX" */
-&(nid_objs[550]),/* "setct-CredReqTBS" */
-&(nid_objs[551]),/* "setct-CredReqTBSX" */
-&(nid_objs[552]),/* "setct-CredResData" */
-&(nid_objs[588]),/* "setct-CredResTBE" */
-&(nid_objs[589]),/* "setct-CredRevReqTBE" */
-&(nid_objs[590]),/* "setct-CredRevReqTBEX" */
-&(nid_objs[553]),/* "setct-CredRevReqTBS" */
-&(nid_objs[554]),/* "setct-CredRevReqTBSX" */
-&(nid_objs[555]),/* "setct-CredRevResData" */
-&(nid_objs[591]),/* "setct-CredRevResTBE" */
-&(nid_objs[567]),/* "setct-ErrorTBS" */
-&(nid_objs[526]),/* "setct-HODInput" */
-&(nid_objs[561]),/* "setct-MeAqCInitResTBS" */
-&(nid_objs[522]),/* "setct-OIData" */
-&(nid_objs[519]),/* "setct-PANData" */
-&(nid_objs[521]),/* "setct-PANOnly" */
-&(nid_objs[520]),/* "setct-PANToken" */
-&(nid_objs[556]),/* "setct-PCertReqData" */
-&(nid_objs[557]),/* "setct-PCertResTBS" */
-&(nid_objs[523]),/* "setct-PI" */
-&(nid_objs[532]),/* "setct-PI-TBS" */
-&(nid_objs[524]),/* "setct-PIData" */
-&(nid_objs[525]),/* "setct-PIDataUnsigned" */
-&(nid_objs[568]),/* "setct-PIDualSignedTBE" */
-&(nid_objs[569]),/* "setct-PIUnsignedTBE" */
-&(nid_objs[531]),/* "setct-PInitResData" */
-&(nid_objs[533]),/* "setct-PResData" */
-&(nid_objs[594]),/* "setct-RegFormReqTBE" */
-&(nid_objs[562]),/* "setct-RegFormResTBS" */
-&(nid_objs[604]),/* "setext-pinAny" */
-&(nid_objs[603]),/* "setext-pinSecure" */
-&(nid_objs[605]),/* "setext-track2" */
-&(nid_objs[41]),/* "sha" */
-&(nid_objs[64]),/* "sha1" */
-&(nid_objs[115]),/* "sha1WithRSA" */
-&(nid_objs[65]),/* "sha1WithRSAEncryption" */
-&(nid_objs[675]),/* "sha224" */
-&(nid_objs[671]),/* "sha224WithRSAEncryption" */
-&(nid_objs[672]),/* "sha256" */
-&(nid_objs[668]),/* "sha256WithRSAEncryption" */
-&(nid_objs[673]),/* "sha384" */
-&(nid_objs[669]),/* "sha384WithRSAEncryption" */
-&(nid_objs[674]),/* "sha512" */
-&(nid_objs[670]),/* "sha512WithRSAEncryption" */
-&(nid_objs[42]),/* "shaWithRSAEncryption" */
-&(nid_objs[52]),/* "signingTime" */
-&(nid_objs[454]),/* "simpleSecurityObject" */
-&(nid_objs[496]),/* "singleLevelQuality" */
-&(nid_objs[16]),/* "stateOrProvinceName" */
-&(nid_objs[660]),/* "streetAddress" */
-&(nid_objs[498]),/* "subtreeMaximumQuality" */
-&(nid_objs[497]),/* "subtreeMinimumQuality" */
-&(nid_objs[890]),/* "supportedAlgorithms" */
-&(nid_objs[874]),/* "supportedApplicationContext" */
-&(nid_objs[100]),/* "surname" */
-&(nid_objs[864]),/* "telephoneNumber" */
-&(nid_objs[866]),/* "teletexTerminalIdentifier" */
-&(nid_objs[865]),/* "telexNumber" */
-&(nid_objs[459]),/* "textEncodedORAddress" */
-&(nid_objs[293]),/* "textNotice" */
-&(nid_objs[106]),/* "title" */
-&(nid_objs[682]),/* "tpBasis" */
-&(nid_objs[436]),/* "ucl" */
-&(nid_objs[ 0]),/* "undefined" */
-&(nid_objs[888]),/* "uniqueMember" */
-&(nid_objs[55]),/* "unstructuredAddress" */
-&(nid_objs[49]),/* "unstructuredName" */
-&(nid_objs[880]),/* "userCertificate" */
-&(nid_objs[465]),/* "userClass" */
-&(nid_objs[458]),/* "userId" */
-&(nid_objs[879]),/* "userPassword" */
-&(nid_objs[373]),/* "valid" */
-&(nid_objs[678]),/* "wap" */
-&(nid_objs[679]),/* "wap-wsg" */
-&(nid_objs[735]),/* "wap-wsg-idm-ecid-wtls1" */
-&(nid_objs[743]),/* "wap-wsg-idm-ecid-wtls10" */
-&(nid_objs[744]),/* "wap-wsg-idm-ecid-wtls11" */
-&(nid_objs[745]),/* "wap-wsg-idm-ecid-wtls12" */
-&(nid_objs[736]),/* "wap-wsg-idm-ecid-wtls3" */
-&(nid_objs[737]),/* "wap-wsg-idm-ecid-wtls4" */
-&(nid_objs[738]),/* "wap-wsg-idm-ecid-wtls5" */
-&(nid_objs[739]),/* "wap-wsg-idm-ecid-wtls6" */
-&(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[868]),/* "x121Address" */
-&(nid_objs[503]),/* "x500UniqueIdentifier" */
-&(nid_objs[158]),/* "x509Certificate" */
-&(nid_objs[160]),/* "x509Crl" */
-&(nid_objs[125]),/* "zlib compression" */
+static const unsigned int ln_objs[NUM_LN]={
+363,	/* "AD Time Stamping" */
+405,	/* "ANSI X9.62" */
+368,	/* "Acceptable OCSP Responses" */
+664,	/* "Any language" */
+177,	/* "Authority Information Access" */
+365,	/* "Basic OCSP Response" */
+285,	/* "Biometric Info" */
+179,	/* "CA Issuers" */
+785,	/* "CA Repository" */
+131,	/* "Code Signing" */
+783,	/* "Diffie-Hellman based MAC" */
+382,	/* "Directory" */
+392,	/* "Domain" */
+132,	/* "E-mail Protection" */
+389,	/* "Enterprises" */
+384,	/* "Experimental" */
+372,	/* "Extended OCSP Status" */
+172,	/* "Extension Request" */
+813,	/* "GOST 28147-89" */
+849,	/* "GOST 28147-89 Cryptocom ParamSet" */
+815,	/* "GOST 28147-89 MAC" */
+851,	/* "GOST 34.10-2001 Cryptocom" */
+850,	/* "GOST 34.10-94 Cryptocom" */
+811,	/* "GOST R 34.10-2001" */
+817,	/* "GOST R 34.10-2001 DH" */
+812,	/* "GOST R 34.10-94" */
+818,	/* "GOST R 34.10-94 DH" */
+809,	/* "GOST R 34.11-94" */
+816,	/* "GOST R 34.11-94 PRF" */
+807,	/* "GOST R 34.11-94 with GOST R 34.10-2001" */
+853,	/* "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" */
+808,	/* "GOST R 34.11-94 with GOST R 34.10-94" */
+852,	/* "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" */
+854,	/* "GOST R 3410-2001 Parameter Set Cryptocom" */
+810,	/* "HMAC GOST 34.11-94" */
+432,	/* "Hold Instruction Call Issuer" */
+430,	/* "Hold Instruction Code" */
+431,	/* "Hold Instruction None" */
+433,	/* "Hold Instruction Reject" */
+634,	/* "ICC or token signature" */
+294,	/* "IPSec End System" */
+295,	/* "IPSec Tunnel" */
+296,	/* "IPSec User" */
+182,	/* "ISO Member Body" */
+183,	/* "ISO US Member Body" */
+667,	/* "Independent" */
+665,	/* "Inherit all" */
+647,	/* "International Organizations" */
+142,	/* "Invalidity Date" */
+504,	/* "MIME MHS" */
+388,	/* "Mail" */
+383,	/* "Management" */
+417,	/* "Microsoft CSP Name" */
+135,	/* "Microsoft Commercial Code Signing" */
+138,	/* "Microsoft Encrypted File System" */
+171,	/* "Microsoft Extension Request" */
+134,	/* "Microsoft Individual Code Signing" */
+856,	/* "Microsoft Local Key set" */
+137,	/* "Microsoft Server Gated Crypto" */
+648,	/* "Microsoft Smartcardlogin" */
+136,	/* "Microsoft Trust List Signing" */
+649,	/* "Microsoft Universal Principal Name" */
+393,	/* "NULL" */
+404,	/* "NULL" */
+72,	/* "Netscape Base Url" */
+76,	/* "Netscape CA Policy Url" */
+74,	/* "Netscape CA Revocation Url" */
+71,	/* "Netscape Cert Type" */
+58,	/* "Netscape Certificate Extension" */
+79,	/* "Netscape Certificate Sequence" */
+78,	/* "Netscape Comment" */
+57,	/* "Netscape Communications Corp." */
+59,	/* "Netscape Data Type" */
+75,	/* "Netscape Renewal Url" */
+73,	/* "Netscape Revocation Url" */
+77,	/* "Netscape SSL Server Name" */
+139,	/* "Netscape Server Gated Crypto" */
+178,	/* "OCSP" */
+370,	/* "OCSP Archive Cutoff" */
+367,	/* "OCSP CRL ID" */
+369,	/* "OCSP No Check" */
+366,	/* "OCSP Nonce" */
+371,	/* "OCSP Service Locator" */
+180,	/* "OCSP Signing" */
+161,	/* "PBES2" */
+69,	/* "PBKDF2" */
+162,	/* "PBMAC1" */
+127,	/* "PKIX" */
+858,	/* "Permanent Identifier" */
+164,	/* "Policy Qualifier CPS" */
+165,	/* "Policy Qualifier User Notice" */
+385,	/* "Private" */
+663,	/* "Proxy Certificate Information" */
+ 1,	/* "RSA Data Security, Inc." */
+ 2,	/* "RSA Data Security, Inc. PKCS" */
+188,	/* "S/MIME" */
+167,	/* "S/MIME Capabilities" */
+387,	/* "SNMPv2" */
+512,	/* "Secure Electronic Transactions" */
+386,	/* "Security" */
+394,	/* "Selected Attribute Types" */
+143,	/* "Strong Extranet ID" */
+398,	/* "Subject Information Access" */
+130,	/* "TLS Web Client Authentication" */
+129,	/* "TLS Web Server Authentication" */
+133,	/* "Time Stamping" */
+375,	/* "Trust Root" */
+12,	/* "X509" */
+402,	/* "X509v3 AC Targeting" */
+746,	/* "X509v3 Any Policy" */
+90,	/* "X509v3 Authority Key Identifier" */
+87,	/* "X509v3 Basic Constraints" */
+103,	/* "X509v3 CRL Distribution Points" */
+88,	/* "X509v3 CRL Number" */
+141,	/* "X509v3 CRL Reason Code" */
+771,	/* "X509v3 Certificate Issuer" */
+89,	/* "X509v3 Certificate Policies" */
+140,	/* "X509v3 Delta CRL Indicator" */
+126,	/* "X509v3 Extended Key Usage" */
+857,	/* "X509v3 Freshest CRL" */
+748,	/* "X509v3 Inhibit Any Policy" */
+86,	/* "X509v3 Issuer Alternative Name" */
+770,	/* "X509v3 Issuing Distrubution Point" */
+83,	/* "X509v3 Key Usage" */
+666,	/* "X509v3 Name Constraints" */
+403,	/* "X509v3 No Revocation Available" */
+401,	/* "X509v3 Policy Constraints" */
+747,	/* "X509v3 Policy Mappings" */
+84,	/* "X509v3 Private Key Usage Period" */
+85,	/* "X509v3 Subject Alternative Name" */
+769,	/* "X509v3 Subject Directory Attributes" */
+82,	/* "X509v3 Subject Key Identifier" */
+184,	/* "X9.57" */
+185,	/* "X9.57 CM ?" */
+478,	/* "aRecord" */
+289,	/* "aaControls" */
+287,	/* "ac-auditEntity" */
+397,	/* "ac-proxying" */
+288,	/* "ac-targeting" */
+446,	/* "account" */
+364,	/* "ad dvcs" */
+606,	/* "additional verification" */
+419,	/* "aes-128-cbc" */
+421,	/* "aes-128-cfb" */
+650,	/* "aes-128-cfb1" */
+653,	/* "aes-128-cfb8" */
+418,	/* "aes-128-ecb" */
+420,	/* "aes-128-ofb" */
+423,	/* "aes-192-cbc" */
+425,	/* "aes-192-cfb" */
+651,	/* "aes-192-cfb1" */
+654,	/* "aes-192-cfb8" */
+422,	/* "aes-192-ecb" */
+424,	/* "aes-192-ofb" */
+427,	/* "aes-256-cbc" */
+429,	/* "aes-256-cfb" */
+652,	/* "aes-256-cfb1" */
+655,	/* "aes-256-cfb8" */
+426,	/* "aes-256-ecb" */
+428,	/* "aes-256-ofb" */
+376,	/* "algorithm" */
+484,	/* "associatedDomain" */
+485,	/* "associatedName" */
+501,	/* "audio" */
+882,	/* "authorityRevocationList" */
+91,	/* "bf-cbc" */
+93,	/* "bf-cfb" */
+92,	/* "bf-ecb" */
+94,	/* "bf-ofb" */
+494,	/* "buildingName" */
+860,	/* "businessCategory" */
+691,	/* "c2onb191v4" */
+692,	/* "c2onb191v5" */
+697,	/* "c2onb239v4" */
+698,	/* "c2onb239v5" */
+684,	/* "c2pnb163v1" */
+685,	/* "c2pnb163v2" */
+686,	/* "c2pnb163v3" */
+687,	/* "c2pnb176v1" */
+693,	/* "c2pnb208w1" */
+699,	/* "c2pnb272w1" */
+700,	/* "c2pnb304w1" */
+702,	/* "c2pnb368w1" */
+688,	/* "c2tnb191v1" */
+689,	/* "c2tnb191v2" */
+690,	/* "c2tnb191v3" */
+694,	/* "c2tnb239v1" */
+695,	/* "c2tnb239v2" */
+696,	/* "c2tnb239v3" */
+701,	/* "c2tnb359v1" */
+703,	/* "c2tnb431r1" */
+881,	/* "cACertificate" */
+483,	/* "cNAMERecord" */
+751,	/* "camellia-128-cbc" */
+757,	/* "camellia-128-cfb" */
+760,	/* "camellia-128-cfb1" */
+763,	/* "camellia-128-cfb8" */
+754,	/* "camellia-128-ecb" */
+766,	/* "camellia-128-ofb" */
+752,	/* "camellia-192-cbc" */
+758,	/* "camellia-192-cfb" */
+761,	/* "camellia-192-cfb1" */
+764,	/* "camellia-192-cfb8" */
+755,	/* "camellia-192-ecb" */
+767,	/* "camellia-192-ofb" */
+753,	/* "camellia-256-cbc" */
+759,	/* "camellia-256-cfb" */
+762,	/* "camellia-256-cfb1" */
+765,	/* "camellia-256-cfb8" */
+756,	/* "camellia-256-ecb" */
+768,	/* "camellia-256-ofb" */
+443,	/* "caseIgnoreIA5StringSyntax" */
+108,	/* "cast5-cbc" */
+110,	/* "cast5-cfb" */
+109,	/* "cast5-ecb" */
+111,	/* "cast5-ofb" */
+152,	/* "certBag" */
+677,	/* "certicom-arc" */
+517,	/* "certificate extensions" */
+883,	/* "certificateRevocationList" */
+54,	/* "challengePassword" */
+407,	/* "characteristic-two-field" */
+395,	/* "clearance" */
+633,	/* "cleartext track 2" */
+13,	/* "commonName" */
+513,	/* "content types" */
+50,	/* "contentType" */
+53,	/* "countersignature" */
+14,	/* "countryName" */
+153,	/* "crlBag" */
+884,	/* "crossCertificatePair" */
+806,	/* "cryptocom" */
+805,	/* "cryptopro" */
+500,	/* "dITRedirect" */
+451,	/* "dNSDomain" */
+495,	/* "dSAQuality" */
+434,	/* "data" */
+390,	/* "dcObject" */
+891,	/* "deltaRevocationList" */
+31,	/* "des-cbc" */
+643,	/* "des-cdmf" */
+30,	/* "des-cfb" */
+656,	/* "des-cfb1" */
+657,	/* "des-cfb8" */
+29,	/* "des-ecb" */
+32,	/* "des-ede" */
+43,	/* "des-ede-cbc" */
+60,	/* "des-ede-cfb" */
+62,	/* "des-ede-ofb" */
+33,	/* "des-ede3" */
+44,	/* "des-ede3-cbc" */
+61,	/* "des-ede3-cfb" */
+658,	/* "des-ede3-cfb1" */
+659,	/* "des-ede3-cfb8" */
+63,	/* "des-ede3-ofb" */
+45,	/* "des-ofb" */
+107,	/* "description" */
+871,	/* "destinationIndicator" */
+80,	/* "desx-cbc" */
+28,	/* "dhKeyAgreement" */
+11,	/* "directory services (X.500)" */
+378,	/* "directory services - algorithms" */
+887,	/* "distinguishedName" */
+892,	/* "dmdName" */
+174,	/* "dnQualifier" */
+447,	/* "document" */
+471,	/* "documentAuthor" */
+468,	/* "documentIdentifier" */
+472,	/* "documentLocation" */
+502,	/* "documentPublisher" */
+449,	/* "documentSeries" */
+469,	/* "documentTitle" */
+470,	/* "documentVersion" */
+380,	/* "dod" */
+391,	/* "domainComponent" */
+452,	/* "domainRelatedObject" */
+116,	/* "dsaEncryption" */
+67,	/* "dsaEncryption-old" */
+66,	/* "dsaWithSHA" */
+113,	/* "dsaWithSHA1" */
+70,	/* "dsaWithSHA1-old" */
+802,	/* "dsa_with_SHA224" */
+803,	/* "dsa_with_SHA256" */
+297,	/* "dvcs" */
+791,	/* "ecdsa-with-Recommended" */
+416,	/* "ecdsa-with-SHA1" */
+793,	/* "ecdsa-with-SHA224" */
+794,	/* "ecdsa-with-SHA256" */
+795,	/* "ecdsa-with-SHA384" */
+796,	/* "ecdsa-with-SHA512" */
+792,	/* "ecdsa-with-Specified" */
+48,	/* "emailAddress" */
+632,	/* "encrypted track 2" */
+885,	/* "enhancedSearchGuide" */
+56,	/* "extendedCertificateAttributes" */
+867,	/* "facsimileTelephoneNumber" */
+462,	/* "favouriteDrink" */
+453,	/* "friendlyCountry" */
+490,	/* "friendlyCountryName" */
+156,	/* "friendlyName" */
+631,	/* "generate cryptogram" */
+509,	/* "generationQualifier" */
+601,	/* "generic cryptogram" */
+99,	/* "givenName" */
+814,	/* "gost89-cnt" */
+855,	/* "hmac" */
+780,	/* "hmac-md5" */
+781,	/* "hmac-sha1" */
+797,	/* "hmacWithMD5" */
+163,	/* "hmacWithSHA1" */
+798,	/* "hmacWithSHA224" */
+799,	/* "hmacWithSHA256" */
+800,	/* "hmacWithSHA384" */
+801,	/* "hmacWithSHA512" */
+486,	/* "homePostalAddress" */
+473,	/* "homeTelephoneNumber" */
+466,	/* "host" */
+889,	/* "houseIdentifier" */
+442,	/* "iA5StringSyntax" */
+381,	/* "iana" */
+824,	/* "id-Gost28147-89-CryptoPro-A-ParamSet" */
+825,	/* "id-Gost28147-89-CryptoPro-B-ParamSet" */
+826,	/* "id-Gost28147-89-CryptoPro-C-ParamSet" */
+827,	/* "id-Gost28147-89-CryptoPro-D-ParamSet" */
+819,	/* "id-Gost28147-89-CryptoPro-KeyMeshing" */
+829,	/* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */
+828,	/* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */
+830,	/* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */
+820,	/* "id-Gost28147-89-None-KeyMeshing" */
+823,	/* "id-Gost28147-89-TestParamSet" */
+840,	/* "id-GostR3410-2001-CryptoPro-A-ParamSet" */
+841,	/* "id-GostR3410-2001-CryptoPro-B-ParamSet" */
+842,	/* "id-GostR3410-2001-CryptoPro-C-ParamSet" */
+843,	/* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */
+844,	/* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */
+839,	/* "id-GostR3410-2001-TestParamSet" */
+832,	/* "id-GostR3410-94-CryptoPro-A-ParamSet" */
+833,	/* "id-GostR3410-94-CryptoPro-B-ParamSet" */
+834,	/* "id-GostR3410-94-CryptoPro-C-ParamSet" */
+835,	/* "id-GostR3410-94-CryptoPro-D-ParamSet" */
+836,	/* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */
+837,	/* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */
+838,	/* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */
+831,	/* "id-GostR3410-94-TestParamSet" */
+845,	/* "id-GostR3410-94-a" */
+846,	/* "id-GostR3410-94-aBis" */
+847,	/* "id-GostR3410-94-b" */
+848,	/* "id-GostR3410-94-bBis" */
+822,	/* "id-GostR3411-94-CryptoProParamSet" */
+821,	/* "id-GostR3411-94-TestParamSet" */
+266,	/* "id-aca" */
+355,	/* "id-aca-accessIdentity" */
+354,	/* "id-aca-authenticationInfo" */
+356,	/* "id-aca-chargingIdentity" */
+399,	/* "id-aca-encAttrs" */
+357,	/* "id-aca-group" */
+358,	/* "id-aca-role" */
+176,	/* "id-ad" */
+788,	/* "id-aes128-wrap" */
+789,	/* "id-aes192-wrap" */
+790,	/* "id-aes256-wrap" */
+262,	/* "id-alg" */
+323,	/* "id-alg-des40" */
+326,	/* "id-alg-dh-pop" */
+325,	/* "id-alg-dh-sig-hmac-sha1" */
+324,	/* "id-alg-noSignature" */
+268,	/* "id-cct" */
+361,	/* "id-cct-PKIData" */
+362,	/* "id-cct-PKIResponse" */
+360,	/* "id-cct-crs" */
+81,	/* "id-ce" */
+680,	/* "id-characteristic-two-basis" */
+263,	/* "id-cmc" */
+334,	/* "id-cmc-addExtensions" */
+346,	/* "id-cmc-confirmCertAcceptance" */
+330,	/* "id-cmc-dataReturn" */
+336,	/* "id-cmc-decryptedPOP" */
+335,	/* "id-cmc-encryptedPOP" */
+339,	/* "id-cmc-getCRL" */
+338,	/* "id-cmc-getCert" */
+328,	/* "id-cmc-identification" */
+329,	/* "id-cmc-identityProof" */
+337,	/* "id-cmc-lraPOPWitness" */
+344,	/* "id-cmc-popLinkRandom" */
+345,	/* "id-cmc-popLinkWitness" */
+343,	/* "id-cmc-queryPending" */
+333,	/* "id-cmc-recipientNonce" */
+341,	/* "id-cmc-regInfo" */
+342,	/* "id-cmc-responseInfo" */
+340,	/* "id-cmc-revokeRequest" */
+332,	/* "id-cmc-senderNonce" */
+327,	/* "id-cmc-statusInfo" */
+331,	/* "id-cmc-transactionId" */
+787,	/* "id-ct-asciiTextWithCRLF" */
+408,	/* "id-ecPublicKey" */
+508,	/* "id-hex-multipart-message" */
+507,	/* "id-hex-partial-message" */
+260,	/* "id-it" */
+302,	/* "id-it-caKeyUpdateInfo" */
+298,	/* "id-it-caProtEncCert" */
+311,	/* "id-it-confirmWaitTime" */
+303,	/* "id-it-currentCRL" */
+300,	/* "id-it-encKeyPairTypes" */
+310,	/* "id-it-implicitConfirm" */
+308,	/* "id-it-keyPairParamRep" */
+307,	/* "id-it-keyPairParamReq" */
+312,	/* "id-it-origPKIMessage" */
+301,	/* "id-it-preferredSymmAlg" */
+309,	/* "id-it-revPassphrase" */
+299,	/* "id-it-signKeyPairTypes" */
+305,	/* "id-it-subscriptionRequest" */
+306,	/* "id-it-subscriptionResponse" */
+784,	/* "id-it-suppLangTags" */
+304,	/* "id-it-unsupportedOIDs" */
+128,	/* "id-kp" */
+280,	/* "id-mod-attribute-cert" */
+274,	/* "id-mod-cmc" */
+277,	/* "id-mod-cmp" */
+284,	/* "id-mod-cmp2000" */
+273,	/* "id-mod-crmf" */
+283,	/* "id-mod-dvcs" */
+275,	/* "id-mod-kea-profile-88" */
+276,	/* "id-mod-kea-profile-93" */
+282,	/* "id-mod-ocsp" */
+278,	/* "id-mod-qualified-cert-88" */
+279,	/* "id-mod-qualified-cert-93" */
+281,	/* "id-mod-timestamp-protocol" */
+264,	/* "id-on" */
+347,	/* "id-on-personalData" */
+265,	/* "id-pda" */
+352,	/* "id-pda-countryOfCitizenship" */
+353,	/* "id-pda-countryOfResidence" */
+348,	/* "id-pda-dateOfBirth" */
+351,	/* "id-pda-gender" */
+349,	/* "id-pda-placeOfBirth" */
+175,	/* "id-pe" */
+261,	/* "id-pkip" */
+258,	/* "id-pkix-mod" */
+269,	/* "id-pkix1-explicit-88" */
+271,	/* "id-pkix1-explicit-93" */
+270,	/* "id-pkix1-implicit-88" */
+272,	/* "id-pkix1-implicit-93" */
+662,	/* "id-ppl" */
+267,	/* "id-qcs" */
+359,	/* "id-qcs-pkixQCSyntax-v1" */
+259,	/* "id-qt" */
+313,	/* "id-regCtrl" */
+316,	/* "id-regCtrl-authenticator" */
+319,	/* "id-regCtrl-oldCertID" */
+318,	/* "id-regCtrl-pkiArchiveOptions" */
+317,	/* "id-regCtrl-pkiPublicationInfo" */
+320,	/* "id-regCtrl-protocolEncrKey" */
+315,	/* "id-regCtrl-regToken" */
+314,	/* "id-regInfo" */
+322,	/* "id-regInfo-certReq" */
+321,	/* "id-regInfo-utf8Pairs" */
+191,	/* "id-smime-aa" */
+215,	/* "id-smime-aa-contentHint" */
+218,	/* "id-smime-aa-contentIdentifier" */
+221,	/* "id-smime-aa-contentReference" */
+240,	/* "id-smime-aa-dvcs-dvc" */
+217,	/* "id-smime-aa-encapContentType" */
+222,	/* "id-smime-aa-encrypKeyPref" */
+220,	/* "id-smime-aa-equivalentLabels" */
+232,	/* "id-smime-aa-ets-CertificateRefs" */
+233,	/* "id-smime-aa-ets-RevocationRefs" */
+238,	/* "id-smime-aa-ets-archiveTimeStamp" */
+237,	/* "id-smime-aa-ets-certCRLTimestamp" */
+234,	/* "id-smime-aa-ets-certValues" */
+227,	/* "id-smime-aa-ets-commitmentType" */
+231,	/* "id-smime-aa-ets-contentTimestamp" */
+236,	/* "id-smime-aa-ets-escTimeStamp" */
+230,	/* "id-smime-aa-ets-otherSigCert" */
+235,	/* "id-smime-aa-ets-revocationValues" */
+226,	/* "id-smime-aa-ets-sigPolicyId" */
+229,	/* "id-smime-aa-ets-signerAttr" */
+228,	/* "id-smime-aa-ets-signerLocation" */
+219,	/* "id-smime-aa-macValue" */
+214,	/* "id-smime-aa-mlExpandHistory" */
+216,	/* "id-smime-aa-msgSigDigest" */
+212,	/* "id-smime-aa-receiptRequest" */
+213,	/* "id-smime-aa-securityLabel" */
+239,	/* "id-smime-aa-signatureType" */
+223,	/* "id-smime-aa-signingCertificate" */
+224,	/* "id-smime-aa-smimeEncryptCerts" */
+225,	/* "id-smime-aa-timeStampToken" */
+192,	/* "id-smime-alg" */
+243,	/* "id-smime-alg-3DESwrap" */
+246,	/* "id-smime-alg-CMS3DESwrap" */
+247,	/* "id-smime-alg-CMSRC2wrap" */
+245,	/* "id-smime-alg-ESDH" */
+241,	/* "id-smime-alg-ESDHwith3DES" */
+242,	/* "id-smime-alg-ESDHwithRC2" */
+244,	/* "id-smime-alg-RC2wrap" */
+193,	/* "id-smime-cd" */
+248,	/* "id-smime-cd-ldap" */
+190,	/* "id-smime-ct" */
+210,	/* "id-smime-ct-DVCSRequestData" */
+211,	/* "id-smime-ct-DVCSResponseData" */
+208,	/* "id-smime-ct-TDTInfo" */
+207,	/* "id-smime-ct-TSTInfo" */
+205,	/* "id-smime-ct-authData" */
+786,	/* "id-smime-ct-compressedData" */
+209,	/* "id-smime-ct-contentInfo" */
+206,	/* "id-smime-ct-publishCert" */
+204,	/* "id-smime-ct-receipt" */
+195,	/* "id-smime-cti" */
+255,	/* "id-smime-cti-ets-proofOfApproval" */
+256,	/* "id-smime-cti-ets-proofOfCreation" */
+253,	/* "id-smime-cti-ets-proofOfDelivery" */
+251,	/* "id-smime-cti-ets-proofOfOrigin" */
+252,	/* "id-smime-cti-ets-proofOfReceipt" */
+254,	/* "id-smime-cti-ets-proofOfSender" */
+189,	/* "id-smime-mod" */
+196,	/* "id-smime-mod-cms" */
+197,	/* "id-smime-mod-ess" */
+202,	/* "id-smime-mod-ets-eSigPolicy-88" */
+203,	/* "id-smime-mod-ets-eSigPolicy-97" */
+200,	/* "id-smime-mod-ets-eSignature-88" */
+201,	/* "id-smime-mod-ets-eSignature-97" */
+199,	/* "id-smime-mod-msg-v3" */
+198,	/* "id-smime-mod-oid" */
+194,	/* "id-smime-spq" */
+250,	/* "id-smime-spq-ets-sqt-unotice" */
+249,	/* "id-smime-spq-ets-sqt-uri" */
+34,	/* "idea-cbc" */
+35,	/* "idea-cfb" */
+36,	/* "idea-ecb" */
+46,	/* "idea-ofb" */
+676,	/* "identified-organization" */
+461,	/* "info" */
+101,	/* "initials" */
+869,	/* "internationaliSDNNumber" */
+749,	/* "ipsec3" */
+750,	/* "ipsec4" */
+181,	/* "iso" */
+623,	/* "issuer capabilities" */
+645,	/* "itu-t" */
+492,	/* "janetMailbox" */
+646,	/* "joint-iso-itu-t" */
+150,	/* "keyBag" */
+773,	/* "kisa" */
+477,	/* "lastModifiedBy" */
+476,	/* "lastModifiedTime" */
+157,	/* "localKeyID" */
+15,	/* "localityName" */
+480,	/* "mXRecord" */
+493,	/* "mailPreferenceOption" */
+467,	/* "manager" */
+ 3,	/* "md2" */
+ 7,	/* "md2WithRSAEncryption" */
+257,	/* "md4" */
+396,	/* "md4WithRSAEncryption" */
+ 4,	/* "md5" */
+114,	/* "md5-sha1" */
+104,	/* "md5WithRSA" */
+ 8,	/* "md5WithRSAEncryption" */
+95,	/* "mdc2" */
+96,	/* "mdc2WithRSA" */
+875,	/* "member" */
+602,	/* "merchant initiated auth" */
+514,	/* "message extensions" */
+51,	/* "messageDigest" */
+506,	/* "mime-mhs-bodies" */
+505,	/* "mime-mhs-headings" */
+488,	/* "mobileTelephoneNumber" */
+481,	/* "nSRecord" */
+173,	/* "name" */
+681,	/* "onBasis" */
+379,	/* "org" */
+17,	/* "organizationName" */
+491,	/* "organizationalStatus" */
+18,	/* "organizationalUnitName" */
+475,	/* "otherMailbox" */
+876,	/* "owner" */
+489,	/* "pagerTelephoneNumber" */
+782,	/* "password based MAC" */
+374,	/* "path" */
+621,	/* "payment gateway capabilities" */
+ 9,	/* "pbeWithMD2AndDES-CBC" */
+168,	/* "pbeWithMD2AndRC2-CBC" */
+112,	/* "pbeWithMD5AndCast5CBC" */
+10,	/* "pbeWithMD5AndDES-CBC" */
+169,	/* "pbeWithMD5AndRC2-CBC" */
+148,	/* "pbeWithSHA1And128BitRC2-CBC" */
+144,	/* "pbeWithSHA1And128BitRC4" */
+147,	/* "pbeWithSHA1And2-KeyTripleDES-CBC" */
+146,	/* "pbeWithSHA1And3-KeyTripleDES-CBC" */
+149,	/* "pbeWithSHA1And40BitRC2-CBC" */
+145,	/* "pbeWithSHA1And40BitRC4" */
+170,	/* "pbeWithSHA1AndDES-CBC" */
+68,	/* "pbeWithSHA1AndRC2-CBC" */
+499,	/* "personalSignature" */
+487,	/* "personalTitle" */
+464,	/* "photo" */
+863,	/* "physicalDeliveryOfficeName" */
+437,	/* "pilot" */
+439,	/* "pilotAttributeSyntax" */
+438,	/* "pilotAttributeType" */
+479,	/* "pilotAttributeType27" */
+456,	/* "pilotDSA" */
+441,	/* "pilotGroups" */
+444,	/* "pilotObject" */
+440,	/* "pilotObjectClass" */
+455,	/* "pilotOrganization" */
+445,	/* "pilotPerson" */
+186,	/* "pkcs1" */
+27,	/* "pkcs3" */
+187,	/* "pkcs5" */
+20,	/* "pkcs7" */
+21,	/* "pkcs7-data" */
+25,	/* "pkcs7-digestData" */
+26,	/* "pkcs7-encryptedData" */
+23,	/* "pkcs7-envelopedData" */
+24,	/* "pkcs7-signedAndEnvelopedData" */
+22,	/* "pkcs7-signedData" */
+151,	/* "pkcs8ShroudedKeyBag" */
+47,	/* "pkcs9" */
+862,	/* "postOfficeBox" */
+861,	/* "postalAddress" */
+661,	/* "postalCode" */
+683,	/* "ppBasis" */
+872,	/* "preferredDeliveryMethod" */
+873,	/* "presentationAddress" */
+406,	/* "prime-field" */
+409,	/* "prime192v1" */
+410,	/* "prime192v2" */
+411,	/* "prime192v3" */
+412,	/* "prime239v1" */
+413,	/* "prime239v2" */
+414,	/* "prime239v3" */
+415,	/* "prime256v1" */
+886,	/* "protocolInformation" */
+510,	/* "pseudonym" */
+435,	/* "pss" */
+286,	/* "qcStatements" */
+457,	/* "qualityLabelledData" */
+450,	/* "rFC822localPart" */
+98,	/* "rc2-40-cbc" */
+166,	/* "rc2-64-cbc" */
+37,	/* "rc2-cbc" */
+39,	/* "rc2-cfb" */
+38,	/* "rc2-ecb" */
+40,	/* "rc2-ofb" */
+ 5,	/* "rc4" */
+97,	/* "rc4-40" */
+120,	/* "rc5-cbc" */
+122,	/* "rc5-cfb" */
+121,	/* "rc5-ecb" */
+123,	/* "rc5-ofb" */
+870,	/* "registeredAddress" */
+460,	/* "rfc822Mailbox" */
+117,	/* "ripemd160" */
+119,	/* "ripemd160WithRSA" */
+400,	/* "role" */
+877,	/* "roleOccupant" */
+448,	/* "room" */
+463,	/* "roomNumber" */
+19,	/* "rsa" */
+ 6,	/* "rsaEncryption" */
+644,	/* "rsaOAEPEncryptionSET" */
+377,	/* "rsaSignature" */
+124,	/* "run length compression" */
+482,	/* "sOARecord" */
+155,	/* "safeContentsBag" */
+291,	/* "sbgp-autonomousSysNum" */
+290,	/* "sbgp-ipAddrBlock" */
+292,	/* "sbgp-routerIdentifier" */
+159,	/* "sdsiCertificate" */
+859,	/* "searchGuide" */
+704,	/* "secp112r1" */
+705,	/* "secp112r2" */
+706,	/* "secp128r1" */
+707,	/* "secp128r2" */
+708,	/* "secp160k1" */
+709,	/* "secp160r1" */
+710,	/* "secp160r2" */
+711,	/* "secp192k1" */
+712,	/* "secp224k1" */
+713,	/* "secp224r1" */
+714,	/* "secp256k1" */
+715,	/* "secp384r1" */
+716,	/* "secp521r1" */
+154,	/* "secretBag" */
+474,	/* "secretary" */
+717,	/* "sect113r1" */
+718,	/* "sect113r2" */
+719,	/* "sect131r1" */
+720,	/* "sect131r2" */
+721,	/* "sect163k1" */
+722,	/* "sect163r1" */
+723,	/* "sect163r2" */
+724,	/* "sect193r1" */
+725,	/* "sect193r2" */
+726,	/* "sect233k1" */
+727,	/* "sect233r1" */
+728,	/* "sect239k1" */
+729,	/* "sect283k1" */
+730,	/* "sect283r1" */
+731,	/* "sect409k1" */
+732,	/* "sect409r1" */
+733,	/* "sect571k1" */
+734,	/* "sect571r1" */
+635,	/* "secure device signature" */
+878,	/* "seeAlso" */
+777,	/* "seed-cbc" */
+779,	/* "seed-cfb" */
+776,	/* "seed-ecb" */
+778,	/* "seed-ofb" */
+105,	/* "serialNumber" */
+625,	/* "set-addPolicy" */
+515,	/* "set-attr" */
+518,	/* "set-brand" */
+638,	/* "set-brand-AmericanExpress" */
+637,	/* "set-brand-Diners" */
+636,	/* "set-brand-IATA-ATA" */
+639,	/* "set-brand-JCB" */
+641,	/* "set-brand-MasterCard" */
+642,	/* "set-brand-Novus" */
+640,	/* "set-brand-Visa" */
+516,	/* "set-policy" */
+607,	/* "set-policy-root" */
+624,	/* "set-rootKeyThumb" */
+620,	/* "setAttr-Cert" */
+628,	/* "setAttr-IssCap-CVM" */
+630,	/* "setAttr-IssCap-Sig" */
+629,	/* "setAttr-IssCap-T2" */
+627,	/* "setAttr-Token-B0Prime" */
+626,	/* "setAttr-Token-EMV" */
+622,	/* "setAttr-TokenType" */
+619,	/* "setCext-IssuerCapabilities" */
+615,	/* "setCext-PGWYcapabilities" */
+616,	/* "setCext-TokenIdentifier" */
+618,	/* "setCext-TokenType" */
+617,	/* "setCext-Track2Data" */
+611,	/* "setCext-cCertRequired" */
+609,	/* "setCext-certType" */
+608,	/* "setCext-hashedRoot" */
+610,	/* "setCext-merchData" */
+613,	/* "setCext-setExt" */
+614,	/* "setCext-setQualf" */
+612,	/* "setCext-tunneling" */
+540,	/* "setct-AcqCardCodeMsg" */
+576,	/* "setct-AcqCardCodeMsgTBE" */
+570,	/* "setct-AuthReqTBE" */
+534,	/* "setct-AuthReqTBS" */
+527,	/* "setct-AuthResBaggage" */
+571,	/* "setct-AuthResTBE" */
+572,	/* "setct-AuthResTBEX" */
+535,	/* "setct-AuthResTBS" */
+536,	/* "setct-AuthResTBSX" */
+528,	/* "setct-AuthRevReqBaggage" */
+577,	/* "setct-AuthRevReqTBE" */
+541,	/* "setct-AuthRevReqTBS" */
+529,	/* "setct-AuthRevResBaggage" */
+542,	/* "setct-AuthRevResData" */
+578,	/* "setct-AuthRevResTBE" */
+579,	/* "setct-AuthRevResTBEB" */
+543,	/* "setct-AuthRevResTBS" */
+573,	/* "setct-AuthTokenTBE" */
+537,	/* "setct-AuthTokenTBS" */
+600,	/* "setct-BCIDistributionTBS" */
+558,	/* "setct-BatchAdminReqData" */
+592,	/* "setct-BatchAdminReqTBE" */
+559,	/* "setct-BatchAdminResData" */
+593,	/* "setct-BatchAdminResTBE" */
+599,	/* "setct-CRLNotificationResTBS" */
+598,	/* "setct-CRLNotificationTBS" */
+580,	/* "setct-CapReqTBE" */
+581,	/* "setct-CapReqTBEX" */
+544,	/* "setct-CapReqTBS" */
+545,	/* "setct-CapReqTBSX" */
+546,	/* "setct-CapResData" */
+582,	/* "setct-CapResTBE" */
+583,	/* "setct-CapRevReqTBE" */
+584,	/* "setct-CapRevReqTBEX" */
+547,	/* "setct-CapRevReqTBS" */
+548,	/* "setct-CapRevReqTBSX" */
+549,	/* "setct-CapRevResData" */
+585,	/* "setct-CapRevResTBE" */
+538,	/* "setct-CapTokenData" */
+530,	/* "setct-CapTokenSeq" */
+574,	/* "setct-CapTokenTBE" */
+575,	/* "setct-CapTokenTBEX" */
+539,	/* "setct-CapTokenTBS" */
+560,	/* "setct-CardCInitResTBS" */
+566,	/* "setct-CertInqReqTBS" */
+563,	/* "setct-CertReqData" */
+595,	/* "setct-CertReqTBE" */
+596,	/* "setct-CertReqTBEX" */
+564,	/* "setct-CertReqTBS" */
+565,	/* "setct-CertResData" */
+597,	/* "setct-CertResTBE" */
+586,	/* "setct-CredReqTBE" */
+587,	/* "setct-CredReqTBEX" */
+550,	/* "setct-CredReqTBS" */
+551,	/* "setct-CredReqTBSX" */
+552,	/* "setct-CredResData" */
+588,	/* "setct-CredResTBE" */
+589,	/* "setct-CredRevReqTBE" */
+590,	/* "setct-CredRevReqTBEX" */
+553,	/* "setct-CredRevReqTBS" */
+554,	/* "setct-CredRevReqTBSX" */
+555,	/* "setct-CredRevResData" */
+591,	/* "setct-CredRevResTBE" */
+567,	/* "setct-ErrorTBS" */
+526,	/* "setct-HODInput" */
+561,	/* "setct-MeAqCInitResTBS" */
+522,	/* "setct-OIData" */
+519,	/* "setct-PANData" */
+521,	/* "setct-PANOnly" */
+520,	/* "setct-PANToken" */
+556,	/* "setct-PCertReqData" */
+557,	/* "setct-PCertResTBS" */
+523,	/* "setct-PI" */
+532,	/* "setct-PI-TBS" */
+524,	/* "setct-PIData" */
+525,	/* "setct-PIDataUnsigned" */
+568,	/* "setct-PIDualSignedTBE" */
+569,	/* "setct-PIUnsignedTBE" */
+531,	/* "setct-PInitResData" */
+533,	/* "setct-PResData" */
+594,	/* "setct-RegFormReqTBE" */
+562,	/* "setct-RegFormResTBS" */
+604,	/* "setext-pinAny" */
+603,	/* "setext-pinSecure" */
+605,	/* "setext-track2" */
+41,	/* "sha" */
+64,	/* "sha1" */
+115,	/* "sha1WithRSA" */
+65,	/* "sha1WithRSAEncryption" */
+675,	/* "sha224" */
+671,	/* "sha224WithRSAEncryption" */
+672,	/* "sha256" */
+668,	/* "sha256WithRSAEncryption" */
+673,	/* "sha384" */
+669,	/* "sha384WithRSAEncryption" */
+674,	/* "sha512" */
+670,	/* "sha512WithRSAEncryption" */
+42,	/* "shaWithRSAEncryption" */
+52,	/* "signingTime" */
+454,	/* "simpleSecurityObject" */
+496,	/* "singleLevelQuality" */
+16,	/* "stateOrProvinceName" */
+660,	/* "streetAddress" */
+498,	/* "subtreeMaximumQuality" */
+497,	/* "subtreeMinimumQuality" */
+890,	/* "supportedAlgorithms" */
+874,	/* "supportedApplicationContext" */
+100,	/* "surname" */
+864,	/* "telephoneNumber" */
+866,	/* "teletexTerminalIdentifier" */
+865,	/* "telexNumber" */
+459,	/* "textEncodedORAddress" */
+293,	/* "textNotice" */
+106,	/* "title" */
+682,	/* "tpBasis" */
+436,	/* "ucl" */
+ 0,	/* "undefined" */
+888,	/* "uniqueMember" */
+55,	/* "unstructuredAddress" */
+49,	/* "unstructuredName" */
+880,	/* "userCertificate" */
+465,	/* "userClass" */
+458,	/* "userId" */
+879,	/* "userPassword" */
+373,	/* "valid" */
+678,	/* "wap" */
+679,	/* "wap-wsg" */
+735,	/* "wap-wsg-idm-ecid-wtls1" */
+743,	/* "wap-wsg-idm-ecid-wtls10" */
+744,	/* "wap-wsg-idm-ecid-wtls11" */
+745,	/* "wap-wsg-idm-ecid-wtls12" */
+736,	/* "wap-wsg-idm-ecid-wtls3" */
+737,	/* "wap-wsg-idm-ecid-wtls4" */
+738,	/* "wap-wsg-idm-ecid-wtls5" */
+739,	/* "wap-wsg-idm-ecid-wtls6" */
+740,	/* "wap-wsg-idm-ecid-wtls7" */
+741,	/* "wap-wsg-idm-ecid-wtls8" */
+742,	/* "wap-wsg-idm-ecid-wtls9" */
+804,	/* "whirlpool" */
+868,	/* "x121Address" */
+503,	/* "x500UniqueIdentifier" */
+158,	/* "x509Certificate" */
+160,	/* "x509Crl" */
+125,	/* "zlib compression" */
 };
 
-static ASN1_OBJECT *obj_objs[NUM_OBJ]={
-&(nid_objs[ 0]),/* OBJ_undef                        0 */
-&(nid_objs[393]),/* OBJ_joint_iso_ccitt              OBJ_joint_iso_itu_t */
-&(nid_objs[404]),/* OBJ_ccitt                        OBJ_itu_t */
-&(nid_objs[645]),/* OBJ_itu_t                        0 */
-&(nid_objs[434]),/* OBJ_data                         0 9 */
-&(nid_objs[181]),/* OBJ_iso                          1 */
-&(nid_objs[182]),/* OBJ_member_body                  1 2 */
-&(nid_objs[379]),/* OBJ_org                          1 3 */
-&(nid_objs[676]),/* OBJ_identified_organization      1 3 */
-&(nid_objs[646]),/* OBJ_joint_iso_itu_t              2 */
-&(nid_objs[11]),/* OBJ_X500                         2 5 */
-&(nid_objs[647]),/* OBJ_international_organizations  2 23 */
-&(nid_objs[380]),/* OBJ_dod                          1 3 6 */
-&(nid_objs[12]),/* OBJ_X509                         2 5 4 */
-&(nid_objs[378]),/* OBJ_X500algorithms               2 5 8 */
-&(nid_objs[81]),/* OBJ_id_ce                        2 5 29 */
-&(nid_objs[512]),/* OBJ_id_set                       2 23 42 */
-&(nid_objs[678]),/* OBJ_wap                          2 23 43 */
-&(nid_objs[435]),/* OBJ_pss                          0 9 2342 */
-&(nid_objs[183]),/* OBJ_ISO_US                       1 2 840 */
-&(nid_objs[381]),/* OBJ_iana                         1 3 6 1 */
-&(nid_objs[677]),/* OBJ_certicom_arc                 1 3 132 */
-&(nid_objs[394]),/* OBJ_selected_attribute_types     2 5 1 5 */
-&(nid_objs[13]),/* OBJ_commonName                   2 5 4 3 */
-&(nid_objs[100]),/* OBJ_surname                      2 5 4 4 */
-&(nid_objs[105]),/* OBJ_serialNumber                 2 5 4 5 */
-&(nid_objs[14]),/* OBJ_countryName                  2 5 4 6 */
-&(nid_objs[15]),/* OBJ_localityName                 2 5 4 7 */
-&(nid_objs[16]),/* OBJ_stateOrProvinceName          2 5 4 8 */
-&(nid_objs[660]),/* OBJ_streetAddress                2 5 4 9 */
-&(nid_objs[17]),/* OBJ_organizationName             2 5 4 10 */
-&(nid_objs[18]),/* OBJ_organizationalUnitName       2 5 4 11 */
-&(nid_objs[106]),/* OBJ_title                        2 5 4 12 */
-&(nid_objs[107]),/* OBJ_description                  2 5 4 13 */
-&(nid_objs[859]),/* OBJ_searchGuide                  2 5 4 14 */
-&(nid_objs[860]),/* OBJ_businessCategory             2 5 4 15 */
-&(nid_objs[861]),/* OBJ_postalAddress                2 5 4 16 */
-&(nid_objs[661]),/* OBJ_postalCode                   2 5 4 17 */
-&(nid_objs[862]),/* OBJ_postOfficeBox                2 5 4 18 */
-&(nid_objs[863]),/* OBJ_physicalDeliveryOfficeName   2 5 4 19 */
-&(nid_objs[864]),/* OBJ_telephoneNumber              2 5 4 20 */
-&(nid_objs[865]),/* OBJ_telexNumber                  2 5 4 21 */
-&(nid_objs[866]),/* OBJ_teletexTerminalIdentifier    2 5 4 22 */
-&(nid_objs[867]),/* OBJ_facsimileTelephoneNumber     2 5 4 23 */
-&(nid_objs[868]),/* OBJ_x121Address                  2 5 4 24 */
-&(nid_objs[869]),/* OBJ_internationaliSDNNumber      2 5 4 25 */
-&(nid_objs[870]),/* OBJ_registeredAddress            2 5 4 26 */
-&(nid_objs[871]),/* OBJ_destinationIndicator         2 5 4 27 */
-&(nid_objs[872]),/* OBJ_preferredDeliveryMethod      2 5 4 28 */
-&(nid_objs[873]),/* OBJ_presentationAddress          2 5 4 29 */
-&(nid_objs[874]),/* OBJ_supportedApplicationContext  2 5 4 30 */
-&(nid_objs[875]),/* OBJ_member                       2 5 4 31 */
-&(nid_objs[876]),/* OBJ_owner                        2 5 4 32 */
-&(nid_objs[877]),/* OBJ_roleOccupant                 2 5 4 33 */
-&(nid_objs[878]),/* OBJ_seeAlso                      2 5 4 34 */
-&(nid_objs[879]),/* OBJ_userPassword                 2 5 4 35 */
-&(nid_objs[880]),/* OBJ_userCertificate              2 5 4 36 */
-&(nid_objs[881]),/* OBJ_cACertificate                2 5 4 37 */
-&(nid_objs[882]),/* OBJ_authorityRevocationList      2 5 4 38 */
-&(nid_objs[883]),/* OBJ_certificateRevocationList    2 5 4 39 */
-&(nid_objs[884]),/* OBJ_crossCertificatePair         2 5 4 40 */
-&(nid_objs[173]),/* OBJ_name                         2 5 4 41 */
-&(nid_objs[99]),/* OBJ_givenName                    2 5 4 42 */
-&(nid_objs[101]),/* OBJ_initials                     2 5 4 43 */
-&(nid_objs[509]),/* OBJ_generationQualifier          2 5 4 44 */
-&(nid_objs[503]),/* OBJ_x500UniqueIdentifier         2 5 4 45 */
-&(nid_objs[174]),/* OBJ_dnQualifier                  2 5 4 46 */
-&(nid_objs[885]),/* OBJ_enhancedSearchGuide          2 5 4 47 */
-&(nid_objs[886]),/* OBJ_protocolInformation          2 5 4 48 */
-&(nid_objs[887]),/* OBJ_distinguishedName            2 5 4 49 */
-&(nid_objs[888]),/* OBJ_uniqueMember                 2 5 4 50 */
-&(nid_objs[889]),/* OBJ_houseIdentifier              2 5 4 51 */
-&(nid_objs[890]),/* OBJ_supportedAlgorithms          2 5 4 52 */
-&(nid_objs[891]),/* OBJ_deltaRevocationList          2 5 4 53 */
-&(nid_objs[892]),/* OBJ_dmdName                      2 5 4 54 */
-&(nid_objs[510]),/* OBJ_pseudonym                    2 5 4 65 */
-&(nid_objs[400]),/* OBJ_role                         2 5 4 72 */
-&(nid_objs[769]),/* OBJ_subject_directory_attributes 2 5 29 9 */
-&(nid_objs[82]),/* OBJ_subject_key_identifier       2 5 29 14 */
-&(nid_objs[83]),/* OBJ_key_usage                    2 5 29 15 */
-&(nid_objs[84]),/* OBJ_private_key_usage_period     2 5 29 16 */
-&(nid_objs[85]),/* OBJ_subject_alt_name             2 5 29 17 */
-&(nid_objs[86]),/* OBJ_issuer_alt_name              2 5 29 18 */
-&(nid_objs[87]),/* OBJ_basic_constraints            2 5 29 19 */
-&(nid_objs[88]),/* OBJ_crl_number                   2 5 29 20 */
-&(nid_objs[141]),/* OBJ_crl_reason                   2 5 29 21 */
-&(nid_objs[430]),/* OBJ_hold_instruction_code        2 5 29 23 */
-&(nid_objs[142]),/* OBJ_invalidity_date              2 5 29 24 */
-&(nid_objs[140]),/* OBJ_delta_crl                    2 5 29 27 */
-&(nid_objs[770]),/* OBJ_issuing_distribution_point   2 5 29 28 */
-&(nid_objs[771]),/* OBJ_certificate_issuer           2 5 29 29 */
-&(nid_objs[666]),/* OBJ_name_constraints             2 5 29 30 */
-&(nid_objs[103]),/* OBJ_crl_distribution_points      2 5 29 31 */
-&(nid_objs[89]),/* OBJ_certificate_policies         2 5 29 32 */
-&(nid_objs[747]),/* OBJ_policy_mappings              2 5 29 33 */
-&(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 */
-&(nid_objs[513]),/* OBJ_set_ctype                    2 23 42 0 */
-&(nid_objs[514]),/* OBJ_set_msgExt                   2 23 42 1 */
-&(nid_objs[515]),/* OBJ_set_attr                     2 23 42 3 */
-&(nid_objs[516]),/* OBJ_set_policy                   2 23 42 5 */
-&(nid_objs[517]),/* OBJ_set_certExt                  2 23 42 7 */
-&(nid_objs[518]),/* OBJ_set_brand                    2 23 42 8 */
-&(nid_objs[679]),/* OBJ_wap_wsg                      2 23 43 1 */
-&(nid_objs[382]),/* OBJ_Directory                    1 3 6 1 1 */
-&(nid_objs[383]),/* OBJ_Management                   1 3 6 1 2 */
-&(nid_objs[384]),/* OBJ_Experimental                 1 3 6 1 3 */
-&(nid_objs[385]),/* OBJ_Private                      1 3 6 1 4 */
-&(nid_objs[386]),/* OBJ_Security                     1 3 6 1 5 */
-&(nid_objs[387]),/* OBJ_SNMPv2                       1 3 6 1 6 */
-&(nid_objs[388]),/* OBJ_Mail                         1 3 6 1 7 */
-&(nid_objs[376]),/* OBJ_algorithm                    1 3 14 3 2 */
-&(nid_objs[395]),/* OBJ_clearance                    2 5 1 5 55 */
-&(nid_objs[19]),/* OBJ_rsa                          2 5 8 1 1 */
-&(nid_objs[96]),/* OBJ_mdc2WithRSA                  2 5 8 3 100 */
-&(nid_objs[95]),/* OBJ_mdc2                         2 5 8 3 101 */
-&(nid_objs[746]),/* OBJ_any_policy                   2 5 29 32 0 */
-&(nid_objs[519]),/* OBJ_setct_PANData                2 23 42 0 0 */
-&(nid_objs[520]),/* OBJ_setct_PANToken               2 23 42 0 1 */
-&(nid_objs[521]),/* OBJ_setct_PANOnly                2 23 42 0 2 */
-&(nid_objs[522]),/* OBJ_setct_OIData                 2 23 42 0 3 */
-&(nid_objs[523]),/* OBJ_setct_PI                     2 23 42 0 4 */
-&(nid_objs[524]),/* OBJ_setct_PIData                 2 23 42 0 5 */
-&(nid_objs[525]),/* OBJ_setct_PIDataUnsigned         2 23 42 0 6 */
-&(nid_objs[526]),/* OBJ_setct_HODInput               2 23 42 0 7 */
-&(nid_objs[527]),/* OBJ_setct_AuthResBaggage         2 23 42 0 8 */
-&(nid_objs[528]),/* OBJ_setct_AuthRevReqBaggage      2 23 42 0 9 */
-&(nid_objs[529]),/* OBJ_setct_AuthRevResBaggage      2 23 42 0 10 */
-&(nid_objs[530]),/* OBJ_setct_CapTokenSeq            2 23 42 0 11 */
-&(nid_objs[531]),/* OBJ_setct_PInitResData           2 23 42 0 12 */
-&(nid_objs[532]),/* OBJ_setct_PI_TBS                 2 23 42 0 13 */
-&(nid_objs[533]),/* OBJ_setct_PResData               2 23 42 0 14 */
-&(nid_objs[534]),/* OBJ_setct_AuthReqTBS             2 23 42 0 16 */
-&(nid_objs[535]),/* OBJ_setct_AuthResTBS             2 23 42 0 17 */
-&(nid_objs[536]),/* OBJ_setct_AuthResTBSX            2 23 42 0 18 */
-&(nid_objs[537]),/* OBJ_setct_AuthTokenTBS           2 23 42 0 19 */
-&(nid_objs[538]),/* OBJ_setct_CapTokenData           2 23 42 0 20 */
-&(nid_objs[539]),/* OBJ_setct_CapTokenTBS            2 23 42 0 21 */
-&(nid_objs[540]),/* OBJ_setct_AcqCardCodeMsg         2 23 42 0 22 */
-&(nid_objs[541]),/* OBJ_setct_AuthRevReqTBS          2 23 42 0 23 */
-&(nid_objs[542]),/* OBJ_setct_AuthRevResData         2 23 42 0 24 */
-&(nid_objs[543]),/* OBJ_setct_AuthRevResTBS          2 23 42 0 25 */
-&(nid_objs[544]),/* OBJ_setct_CapReqTBS              2 23 42 0 26 */
-&(nid_objs[545]),/* OBJ_setct_CapReqTBSX             2 23 42 0 27 */
-&(nid_objs[546]),/* OBJ_setct_CapResData             2 23 42 0 28 */
-&(nid_objs[547]),/* OBJ_setct_CapRevReqTBS           2 23 42 0 29 */
-&(nid_objs[548]),/* OBJ_setct_CapRevReqTBSX          2 23 42 0 30 */
-&(nid_objs[549]),/* OBJ_setct_CapRevResData          2 23 42 0 31 */
-&(nid_objs[550]),/* OBJ_setct_CredReqTBS             2 23 42 0 32 */
-&(nid_objs[551]),/* OBJ_setct_CredReqTBSX            2 23 42 0 33 */
-&(nid_objs[552]),/* OBJ_setct_CredResData            2 23 42 0 34 */
-&(nid_objs[553]),/* OBJ_setct_CredRevReqTBS          2 23 42 0 35 */
-&(nid_objs[554]),/* OBJ_setct_CredRevReqTBSX         2 23 42 0 36 */
-&(nid_objs[555]),/* OBJ_setct_CredRevResData         2 23 42 0 37 */
-&(nid_objs[556]),/* OBJ_setct_PCertReqData           2 23 42 0 38 */
-&(nid_objs[557]),/* OBJ_setct_PCertResTBS            2 23 42 0 39 */
-&(nid_objs[558]),/* OBJ_setct_BatchAdminReqData      2 23 42 0 40 */
-&(nid_objs[559]),/* OBJ_setct_BatchAdminResData      2 23 42 0 41 */
-&(nid_objs[560]),/* OBJ_setct_CardCInitResTBS        2 23 42 0 42 */
-&(nid_objs[561]),/* OBJ_setct_MeAqCInitResTBS        2 23 42 0 43 */
-&(nid_objs[562]),/* OBJ_setct_RegFormResTBS          2 23 42 0 44 */
-&(nid_objs[563]),/* OBJ_setct_CertReqData            2 23 42 0 45 */
-&(nid_objs[564]),/* OBJ_setct_CertReqTBS             2 23 42 0 46 */
-&(nid_objs[565]),/* OBJ_setct_CertResData            2 23 42 0 47 */
-&(nid_objs[566]),/* OBJ_setct_CertInqReqTBS          2 23 42 0 48 */
-&(nid_objs[567]),/* OBJ_setct_ErrorTBS               2 23 42 0 49 */
-&(nid_objs[568]),/* OBJ_setct_PIDualSignedTBE        2 23 42 0 50 */
-&(nid_objs[569]),/* OBJ_setct_PIUnsignedTBE          2 23 42 0 51 */
-&(nid_objs[570]),/* OBJ_setct_AuthReqTBE             2 23 42 0 52 */
-&(nid_objs[571]),/* OBJ_setct_AuthResTBE             2 23 42 0 53 */
-&(nid_objs[572]),/* OBJ_setct_AuthResTBEX            2 23 42 0 54 */
-&(nid_objs[573]),/* OBJ_setct_AuthTokenTBE           2 23 42 0 55 */
-&(nid_objs[574]),/* OBJ_setct_CapTokenTBE            2 23 42 0 56 */
-&(nid_objs[575]),/* OBJ_setct_CapTokenTBEX           2 23 42 0 57 */
-&(nid_objs[576]),/* OBJ_setct_AcqCardCodeMsgTBE      2 23 42 0 58 */
-&(nid_objs[577]),/* OBJ_setct_AuthRevReqTBE          2 23 42 0 59 */
-&(nid_objs[578]),/* OBJ_setct_AuthRevResTBE          2 23 42 0 60 */
-&(nid_objs[579]),/* OBJ_setct_AuthRevResTBEB         2 23 42 0 61 */
-&(nid_objs[580]),/* OBJ_setct_CapReqTBE              2 23 42 0 62 */
-&(nid_objs[581]),/* OBJ_setct_CapReqTBEX             2 23 42 0 63 */
-&(nid_objs[582]),/* OBJ_setct_CapResTBE              2 23 42 0 64 */
-&(nid_objs[583]),/* OBJ_setct_CapRevReqTBE           2 23 42 0 65 */
-&(nid_objs[584]),/* OBJ_setct_CapRevReqTBEX          2 23 42 0 66 */
-&(nid_objs[585]),/* OBJ_setct_CapRevResTBE           2 23 42 0 67 */
-&(nid_objs[586]),/* OBJ_setct_CredReqTBE             2 23 42 0 68 */
-&(nid_objs[587]),/* OBJ_setct_CredReqTBEX            2 23 42 0 69 */
-&(nid_objs[588]),/* OBJ_setct_CredResTBE             2 23 42 0 70 */
-&(nid_objs[589]),/* OBJ_setct_CredRevReqTBE          2 23 42 0 71 */
-&(nid_objs[590]),/* OBJ_setct_CredRevReqTBEX         2 23 42 0 72 */
-&(nid_objs[591]),/* OBJ_setct_CredRevResTBE          2 23 42 0 73 */
-&(nid_objs[592]),/* OBJ_setct_BatchAdminReqTBE       2 23 42 0 74 */
-&(nid_objs[593]),/* OBJ_setct_BatchAdminResTBE       2 23 42 0 75 */
-&(nid_objs[594]),/* OBJ_setct_RegFormReqTBE          2 23 42 0 76 */
-&(nid_objs[595]),/* OBJ_setct_CertReqTBE             2 23 42 0 77 */
-&(nid_objs[596]),/* OBJ_setct_CertReqTBEX            2 23 42 0 78 */
-&(nid_objs[597]),/* OBJ_setct_CertResTBE             2 23 42 0 79 */
-&(nid_objs[598]),/* OBJ_setct_CRLNotificationTBS     2 23 42 0 80 */
-&(nid_objs[599]),/* OBJ_setct_CRLNotificationResTBS  2 23 42 0 81 */
-&(nid_objs[600]),/* OBJ_setct_BCIDistributionTBS     2 23 42 0 82 */
-&(nid_objs[601]),/* OBJ_setext_genCrypt              2 23 42 1 1 */
-&(nid_objs[602]),/* OBJ_setext_miAuth                2 23 42 1 3 */
-&(nid_objs[603]),/* OBJ_setext_pinSecure             2 23 42 1 4 */
-&(nid_objs[604]),/* OBJ_setext_pinAny                2 23 42 1 5 */
-&(nid_objs[605]),/* OBJ_setext_track2                2 23 42 1 7 */
-&(nid_objs[606]),/* OBJ_setext_cv                    2 23 42 1 8 */
-&(nid_objs[620]),/* OBJ_setAttr_Cert                 2 23 42 3 0 */
-&(nid_objs[621]),/* OBJ_setAttr_PGWYcap              2 23 42 3 1 */
-&(nid_objs[622]),/* OBJ_setAttr_TokenType            2 23 42 3 2 */
-&(nid_objs[623]),/* OBJ_setAttr_IssCap               2 23 42 3 3 */
-&(nid_objs[607]),/* OBJ_set_policy_root              2 23 42 5 0 */
-&(nid_objs[608]),/* OBJ_setCext_hashedRoot           2 23 42 7 0 */
-&(nid_objs[609]),/* OBJ_setCext_certType             2 23 42 7 1 */
-&(nid_objs[610]),/* OBJ_setCext_merchData            2 23 42 7 2 */
-&(nid_objs[611]),/* OBJ_setCext_cCertRequired        2 23 42 7 3 */
-&(nid_objs[612]),/* OBJ_setCext_tunneling            2 23 42 7 4 */
-&(nid_objs[613]),/* OBJ_setCext_setExt               2 23 42 7 5 */
-&(nid_objs[614]),/* OBJ_setCext_setQualf             2 23 42 7 6 */
-&(nid_objs[615]),/* OBJ_setCext_PGWYcapabilities     2 23 42 7 7 */
-&(nid_objs[616]),/* OBJ_setCext_TokenIdentifier      2 23 42 7 8 */
-&(nid_objs[617]),/* OBJ_setCext_Track2Data           2 23 42 7 9 */
-&(nid_objs[618]),/* OBJ_setCext_TokenType            2 23 42 7 10 */
-&(nid_objs[619]),/* OBJ_setCext_IssuerCapabilities   2 23 42 7 11 */
-&(nid_objs[636]),/* OBJ_set_brand_IATA_ATA           2 23 42 8 1 */
-&(nid_objs[640]),/* OBJ_set_brand_Visa               2 23 42 8 4 */
-&(nid_objs[641]),/* OBJ_set_brand_MasterCard         2 23 42 8 5 */
-&(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 */
-&(nid_objs[504]),/* OBJ_mime_mhs                     1 3 6 1 7 1 */
-&(nid_objs[104]),/* OBJ_md5WithRSA                   1 3 14 3 2 3 */
-&(nid_objs[29]),/* OBJ_des_ecb                      1 3 14 3 2 6 */
-&(nid_objs[31]),/* OBJ_des_cbc                      1 3 14 3 2 7 */
-&(nid_objs[45]),/* OBJ_des_ofb64                    1 3 14 3 2 8 */
-&(nid_objs[30]),/* OBJ_des_cfb64                    1 3 14 3 2 9 */
-&(nid_objs[377]),/* OBJ_rsaSignature                 1 3 14 3 2 11 */
-&(nid_objs[67]),/* OBJ_dsa_2                        1 3 14 3 2 12 */
-&(nid_objs[66]),/* OBJ_dsaWithSHA                   1 3 14 3 2 13 */
-&(nid_objs[42]),/* OBJ_shaWithRSAEncryption         1 3 14 3 2 15 */
-&(nid_objs[32]),/* OBJ_des_ede_ecb                  1 3 14 3 2 17 */
-&(nid_objs[41]),/* OBJ_sha                          1 3 14 3 2 18 */
-&(nid_objs[64]),/* OBJ_sha1                         1 3 14 3 2 26 */
-&(nid_objs[70]),/* OBJ_dsaWithSHA1_2                1 3 14 3 2 27 */
-&(nid_objs[115]),/* OBJ_sha1WithRSA                  1 3 14 3 2 29 */
-&(nid_objs[117]),/* OBJ_ripemd160                    1 3 36 3 2 1 */
-&(nid_objs[143]),/* OBJ_sxnet                        1 3 101 1 4 1 */
-&(nid_objs[721]),/* OBJ_sect163k1                    1 3 132 0 1 */
-&(nid_objs[722]),/* OBJ_sect163r1                    1 3 132 0 2 */
-&(nid_objs[728]),/* OBJ_sect239k1                    1 3 132 0 3 */
-&(nid_objs[717]),/* OBJ_sect113r1                    1 3 132 0 4 */
-&(nid_objs[718]),/* OBJ_sect113r2                    1 3 132 0 5 */
-&(nid_objs[704]),/* OBJ_secp112r1                    1 3 132 0 6 */
-&(nid_objs[705]),/* OBJ_secp112r2                    1 3 132 0 7 */
-&(nid_objs[709]),/* OBJ_secp160r1                    1 3 132 0 8 */
-&(nid_objs[708]),/* OBJ_secp160k1                    1 3 132 0 9 */
-&(nid_objs[714]),/* OBJ_secp256k1                    1 3 132 0 10 */
-&(nid_objs[723]),/* OBJ_sect163r2                    1 3 132 0 15 */
-&(nid_objs[729]),/* OBJ_sect283k1                    1 3 132 0 16 */
-&(nid_objs[730]),/* OBJ_sect283r1                    1 3 132 0 17 */
-&(nid_objs[719]),/* OBJ_sect131r1                    1 3 132 0 22 */
-&(nid_objs[720]),/* OBJ_sect131r2                    1 3 132 0 23 */
-&(nid_objs[724]),/* OBJ_sect193r1                    1 3 132 0 24 */
-&(nid_objs[725]),/* OBJ_sect193r2                    1 3 132 0 25 */
-&(nid_objs[726]),/* OBJ_sect233k1                    1 3 132 0 26 */
-&(nid_objs[727]),/* OBJ_sect233r1                    1 3 132 0 27 */
-&(nid_objs[706]),/* OBJ_secp128r1                    1 3 132 0 28 */
-&(nid_objs[707]),/* OBJ_secp128r2                    1 3 132 0 29 */
-&(nid_objs[710]),/* OBJ_secp160r2                    1 3 132 0 30 */
-&(nid_objs[711]),/* OBJ_secp192k1                    1 3 132 0 31 */
-&(nid_objs[712]),/* OBJ_secp224k1                    1 3 132 0 32 */
-&(nid_objs[713]),/* OBJ_secp224r1                    1 3 132 0 33 */
-&(nid_objs[715]),/* OBJ_secp384r1                    1 3 132 0 34 */
-&(nid_objs[716]),/* OBJ_secp521r1                    1 3 132 0 35 */
-&(nid_objs[731]),/* OBJ_sect409k1                    1 3 132 0 36 */
-&(nid_objs[732]),/* OBJ_sect409r1                    1 3 132 0 37 */
-&(nid_objs[733]),/* OBJ_sect571k1                    1 3 132 0 38 */
-&(nid_objs[734]),/* OBJ_sect571r1                    1 3 132 0 39 */
-&(nid_objs[624]),/* OBJ_set_rootKeyThumb             2 23 42 3 0 0 */
-&(nid_objs[625]),/* OBJ_set_addPolicy                2 23 42 3 0 1 */
-&(nid_objs[626]),/* OBJ_setAttr_Token_EMV            2 23 42 3 2 1 */
-&(nid_objs[627]),/* OBJ_setAttr_Token_B0Prime        2 23 42 3 2 2 */
-&(nid_objs[628]),/* OBJ_setAttr_IssCap_CVM           2 23 42 3 3 3 */
-&(nid_objs[629]),/* OBJ_setAttr_IssCap_T2            2 23 42 3 3 4 */
-&(nid_objs[630]),/* OBJ_setAttr_IssCap_Sig           2 23 42 3 3 5 */
-&(nid_objs[642]),/* OBJ_set_brand_Novus              2 23 42 8 6011 */
-&(nid_objs[735]),/* OBJ_wap_wsg_idm_ecid_wtls1       2 23 43 1 4 1 */
-&(nid_objs[736]),/* OBJ_wap_wsg_idm_ecid_wtls3       2 23 43 1 4 3 */
-&(nid_objs[737]),/* OBJ_wap_wsg_idm_ecid_wtls4       2 23 43 1 4 4 */
-&(nid_objs[738]),/* OBJ_wap_wsg_idm_ecid_wtls5       2 23 43 1 4 5 */
-&(nid_objs[739]),/* OBJ_wap_wsg_idm_ecid_wtls6       2 23 43 1 4 6 */
-&(nid_objs[740]),/* OBJ_wap_wsg_idm_ecid_wtls7       2 23 43 1 4 7 */
-&(nid_objs[741]),/* OBJ_wap_wsg_idm_ecid_wtls8       2 23 43 1 4 8 */
-&(nid_objs[742]),/* OBJ_wap_wsg_idm_ecid_wtls9       2 23 43 1 4 9 */
-&(nid_objs[743]),/* OBJ_wap_wsg_idm_ecid_wtls10      2 23 43 1 4 10 */
-&(nid_objs[744]),/* OBJ_wap_wsg_idm_ecid_wtls11      2 23 43 1 4 11 */
-&(nid_objs[745]),/* OBJ_wap_wsg_idm_ecid_wtls12      2 23 43 1 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 */
-&(nid_objs[505]),/* OBJ_mime_mhs_headings            1 3 6 1 7 1 1 */
-&(nid_objs[506]),/* OBJ_mime_mhs_bodies              1 3 6 1 7 1 2 */
-&(nid_objs[119]),/* OBJ_ripemd160WithRSA             1 3 36 3 3 1 2 */
-&(nid_objs[631]),/* OBJ_setAttr_GenCryptgrm          2 23 42 3 3 3 1 */
-&(nid_objs[632]),/* OBJ_setAttr_T2Enc                2 23 42 3 3 4 1 */
-&(nid_objs[633]),/* OBJ_setAttr_T2cleartxt           2 23 42 3 3 4 2 */
-&(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 */
-&(nid_objs[433]),/* OBJ_hold_instruction_reject      1 2 840 10040 2 3 */
-&(nid_objs[116]),/* OBJ_dsa                          1 2 840 10040 4 1 */
-&(nid_objs[113]),/* OBJ_dsaWithSHA1                  1 2 840 10040 4 3 */
-&(nid_objs[406]),/* OBJ_X9_62_prime_field            1 2 840 10045 1 1 */
-&(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 */
-&(nid_objs[128]),/* OBJ_id_kp                        1 3 6 1 5 5 7 3 */
-&(nid_objs[260]),/* OBJ_id_it                        1 3 6 1 5 5 7 4 */
-&(nid_objs[261]),/* OBJ_id_pkip                      1 3 6 1 5 5 7 5 */
-&(nid_objs[262]),/* OBJ_id_alg                       1 3 6 1 5 5 7 6 */
-&(nid_objs[263]),/* OBJ_id_cmc                       1 3 6 1 5 5 7 7 */
-&(nid_objs[264]),/* OBJ_id_on                        1 3 6 1 5 5 7 8 */
-&(nid_objs[265]),/* OBJ_id_pda                       1 3 6 1 5 5 7 9 */
-&(nid_objs[266]),/* OBJ_id_aca                       1 3 6 1 5 5 7 10 */
-&(nid_objs[267]),/* OBJ_id_qcs                       1 3 6 1 5 5 7 11 */
-&(nid_objs[268]),/* OBJ_id_cct                       1 3 6 1 5 5 7 12 */
-&(nid_objs[662]),/* OBJ_id_ppl                       1 3 6 1 5 5 7 21 */
-&(nid_objs[176]),/* OBJ_id_ad                        1 3 6 1 5 5 7 48 */
-&(nid_objs[507]),/* OBJ_id_hex_partial_message       1 3 6 1 7 1 1 1 */
-&(nid_objs[508]),/* OBJ_id_hex_multipart_message     1 3 6 1 7 1 1 2 */
-&(nid_objs[57]),/* OBJ_netscape                     2 16 840 1 113730 */
-&(nid_objs[754]),/* OBJ_camellia_128_ecb             0 3 4401 5 3 1 9 1 */
-&(nid_objs[766]),/* OBJ_camellia_128_ofb128          0 3 4401 5 3 1 9 3 */
-&(nid_objs[757]),/* OBJ_camellia_128_cfb128          0 3 4401 5 3 1 9 4 */
-&(nid_objs[755]),/* OBJ_camellia_192_ecb             0 3 4401 5 3 1 9 21 */
-&(nid_objs[767]),/* OBJ_camellia_192_ofb128          0 3 4401 5 3 1 9 23 */
-&(nid_objs[758]),/* OBJ_camellia_192_cfb128          0 3 4401 5 3 1 9 24 */
-&(nid_objs[756]),/* OBJ_camellia_256_ecb             0 3 4401 5 3 1 9 41 */
-&(nid_objs[768]),/* OBJ_camellia_256_ofb128          0 3 4401 5 3 1 9 43 */
-&(nid_objs[759]),/* OBJ_camellia_256_cfb128          0 3 4401 5 3 1 9 44 */
-&(nid_objs[437]),/* OBJ_pilot                        0 9 2342 19200300 100 */
-&(nid_objs[776]),/* OBJ_seed_ecb                     1 2 410 200004 1 3 */
-&(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 */
-&(nid_objs[20]),/* OBJ_pkcs7                        1 2 840 113549 1 7 */
-&(nid_objs[47]),/* OBJ_pkcs9                        1 2 840 113549 1 9 */
-&(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 */
-&(nid_objs[120]),/* OBJ_rc5_cbc                      1 2 840 113549 3 8 */
-&(nid_objs[643]),/* OBJ_des_cdmf                     1 2 840 113549 3 10 */
-&(nid_objs[680]),/* OBJ_X9_62_id_characteristic_two_basis 1 2 840 10045 1 2 3 */
-&(nid_objs[684]),/* OBJ_X9_62_c2pnb163v1             1 2 840 10045 3 0 1 */
-&(nid_objs[685]),/* OBJ_X9_62_c2pnb163v2             1 2 840 10045 3 0 2 */
-&(nid_objs[686]),/* OBJ_X9_62_c2pnb163v3             1 2 840 10045 3 0 3 */
-&(nid_objs[687]),/* OBJ_X9_62_c2pnb176v1             1 2 840 10045 3 0 4 */
-&(nid_objs[688]),/* OBJ_X9_62_c2tnb191v1             1 2 840 10045 3 0 5 */
-&(nid_objs[689]),/* OBJ_X9_62_c2tnb191v2             1 2 840 10045 3 0 6 */
-&(nid_objs[690]),/* OBJ_X9_62_c2tnb191v3             1 2 840 10045 3 0 7 */
-&(nid_objs[691]),/* OBJ_X9_62_c2onb191v4             1 2 840 10045 3 0 8 */
-&(nid_objs[692]),/* OBJ_X9_62_c2onb191v5             1 2 840 10045 3 0 9 */
-&(nid_objs[693]),/* OBJ_X9_62_c2pnb208w1             1 2 840 10045 3 0 10 */
-&(nid_objs[694]),/* OBJ_X9_62_c2tnb239v1             1 2 840 10045 3 0 11 */
-&(nid_objs[695]),/* OBJ_X9_62_c2tnb239v2             1 2 840 10045 3 0 12 */
-&(nid_objs[696]),/* OBJ_X9_62_c2tnb239v3             1 2 840 10045 3 0 13 */
-&(nid_objs[697]),/* OBJ_X9_62_c2onb239v4             1 2 840 10045 3 0 14 */
-&(nid_objs[698]),/* OBJ_X9_62_c2onb239v5             1 2 840 10045 3 0 15 */
-&(nid_objs[699]),/* OBJ_X9_62_c2pnb272w1             1 2 840 10045 3 0 16 */
-&(nid_objs[700]),/* OBJ_X9_62_c2pnb304w1             1 2 840 10045 3 0 17 */
-&(nid_objs[701]),/* OBJ_X9_62_c2tnb359v1             1 2 840 10045 3 0 18 */
-&(nid_objs[702]),/* OBJ_X9_62_c2pnb368w1             1 2 840 10045 3 0 19 */
-&(nid_objs[703]),/* OBJ_X9_62_c2tnb431r1             1 2 840 10045 3 0 20 */
-&(nid_objs[409]),/* OBJ_X9_62_prime192v1             1 2 840 10045 3 1 1 */
-&(nid_objs[410]),/* OBJ_X9_62_prime192v2             1 2 840 10045 3 1 2 */
-&(nid_objs[411]),/* OBJ_X9_62_prime192v3             1 2 840 10045 3 1 3 */
-&(nid_objs[412]),/* OBJ_X9_62_prime239v1             1 2 840 10045 3 1 4 */
-&(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 */
-&(nid_objs[272]),/* OBJ_id_pkix1_implicit_93         1 3 6 1 5 5 7 0 4 */
-&(nid_objs[273]),/* OBJ_id_mod_crmf                  1 3 6 1 5 5 7 0 5 */
-&(nid_objs[274]),/* OBJ_id_mod_cmc                   1 3 6 1 5 5 7 0 6 */
-&(nid_objs[275]),/* OBJ_id_mod_kea_profile_88        1 3 6 1 5 5 7 0 7 */
-&(nid_objs[276]),/* OBJ_id_mod_kea_profile_93        1 3 6 1 5 5 7 0 8 */
-&(nid_objs[277]),/* OBJ_id_mod_cmp                   1 3 6 1 5 5 7 0 9 */
-&(nid_objs[278]),/* OBJ_id_mod_qualified_cert_88     1 3 6 1 5 5 7 0 10 */
-&(nid_objs[279]),/* OBJ_id_mod_qualified_cert_93     1 3 6 1 5 5 7 0 11 */
-&(nid_objs[280]),/* OBJ_id_mod_attribute_cert        1 3 6 1 5 5 7 0 12 */
-&(nid_objs[281]),/* OBJ_id_mod_timestamp_protocol    1 3 6 1 5 5 7 0 13 */
-&(nid_objs[282]),/* OBJ_id_mod_ocsp                  1 3 6 1 5 5 7 0 14 */
-&(nid_objs[283]),/* OBJ_id_mod_dvcs                  1 3 6 1 5 5 7 0 15 */
-&(nid_objs[284]),/* OBJ_id_mod_cmp2000               1 3 6 1 5 5 7 0 16 */
-&(nid_objs[177]),/* OBJ_info_access                  1 3 6 1 5 5 7 1 1 */
-&(nid_objs[285]),/* OBJ_biometricInfo                1 3 6 1 5 5 7 1 2 */
-&(nid_objs[286]),/* OBJ_qcStatements                 1 3 6 1 5 5 7 1 3 */
-&(nid_objs[287]),/* OBJ_ac_auditEntity               1 3 6 1 5 5 7 1 4 */
-&(nid_objs[288]),/* OBJ_ac_targeting                 1 3 6 1 5 5 7 1 5 */
-&(nid_objs[289]),/* OBJ_aaControls                   1 3 6 1 5 5 7 1 6 */
-&(nid_objs[290]),/* OBJ_sbgp_ipAddrBlock             1 3 6 1 5 5 7 1 7 */
-&(nid_objs[291]),/* OBJ_sbgp_autonomousSysNum        1 3 6 1 5 5 7 1 8 */
-&(nid_objs[292]),/* OBJ_sbgp_routerIdentifier        1 3 6 1 5 5 7 1 9 */
-&(nid_objs[397]),/* OBJ_ac_proxying                  1 3 6 1 5 5 7 1 10 */
-&(nid_objs[398]),/* OBJ_sinfo_access                 1 3 6 1 5 5 7 1 11 */
-&(nid_objs[663]),/* OBJ_proxyCertInfo                1 3 6 1 5 5 7 1 14 */
-&(nid_objs[164]),/* OBJ_id_qt_cps                    1 3 6 1 5 5 7 2 1 */
-&(nid_objs[165]),/* OBJ_id_qt_unotice                1 3 6 1 5 5 7 2 2 */
-&(nid_objs[293]),/* OBJ_textNotice                   1 3 6 1 5 5 7 2 3 */
-&(nid_objs[129]),/* OBJ_server_auth                  1 3 6 1 5 5 7 3 1 */
-&(nid_objs[130]),/* OBJ_client_auth                  1 3 6 1 5 5 7 3 2 */
-&(nid_objs[131]),/* OBJ_code_sign                    1 3 6 1 5 5 7 3 3 */
-&(nid_objs[132]),/* OBJ_email_protect                1 3 6 1 5 5 7 3 4 */
-&(nid_objs[294]),/* OBJ_ipsecEndSystem               1 3 6 1 5 5 7 3 5 */
-&(nid_objs[295]),/* OBJ_ipsecTunnel                  1 3 6 1 5 5 7 3 6 */
-&(nid_objs[296]),/* OBJ_ipsecUser                    1 3 6 1 5 5 7 3 7 */
-&(nid_objs[133]),/* OBJ_time_stamp                   1 3 6 1 5 5 7 3 8 */
-&(nid_objs[180]),/* OBJ_OCSP_sign                    1 3 6 1 5 5 7 3 9 */
-&(nid_objs[297]),/* OBJ_dvcs                         1 3 6 1 5 5 7 3 10 */
-&(nid_objs[298]),/* OBJ_id_it_caProtEncCert          1 3 6 1 5 5 7 4 1 */
-&(nid_objs[299]),/* OBJ_id_it_signKeyPairTypes       1 3 6 1 5 5 7 4 2 */
-&(nid_objs[300]),/* OBJ_id_it_encKeyPairTypes        1 3 6 1 5 5 7 4 3 */
-&(nid_objs[301]),/* OBJ_id_it_preferredSymmAlg       1 3 6 1 5 5 7 4 4 */
-&(nid_objs[302]),/* OBJ_id_it_caKeyUpdateInfo        1 3 6 1 5 5 7 4 5 */
-&(nid_objs[303]),/* OBJ_id_it_currentCRL             1 3 6 1 5 5 7 4 6 */
-&(nid_objs[304]),/* OBJ_id_it_unsupportedOIDs        1 3 6 1 5 5 7 4 7 */
-&(nid_objs[305]),/* OBJ_id_it_subscriptionRequest    1 3 6 1 5 5 7 4 8 */
-&(nid_objs[306]),/* OBJ_id_it_subscriptionResponse   1 3 6 1 5 5 7 4 9 */
-&(nid_objs[307]),/* OBJ_id_it_keyPairParamReq        1 3 6 1 5 5 7 4 10 */
-&(nid_objs[308]),/* OBJ_id_it_keyPairParamRep        1 3 6 1 5 5 7 4 11 */
-&(nid_objs[309]),/* OBJ_id_it_revPassphrase          1 3 6 1 5 5 7 4 12 */
-&(nid_objs[310]),/* OBJ_id_it_implicitConfirm        1 3 6 1 5 5 7 4 13 */
-&(nid_objs[311]),/* OBJ_id_it_confirmWaitTime        1 3 6 1 5 5 7 4 14 */
-&(nid_objs[312]),/* OBJ_id_it_origPKIMessage         1 3 6 1 5 5 7 4 15 */
-&(nid_objs[784]),/* OBJ_id_it_suppLangTags           1 3 6 1 5 5 7 4 16 */
-&(nid_objs[313]),/* OBJ_id_regCtrl                   1 3 6 1 5 5 7 5 1 */
-&(nid_objs[314]),/* OBJ_id_regInfo                   1 3 6 1 5 5 7 5 2 */
-&(nid_objs[323]),/* OBJ_id_alg_des40                 1 3 6 1 5 5 7 6 1 */
-&(nid_objs[324]),/* OBJ_id_alg_noSignature           1 3 6 1 5 5 7 6 2 */
-&(nid_objs[325]),/* OBJ_id_alg_dh_sig_hmac_sha1      1 3 6 1 5 5 7 6 3 */
-&(nid_objs[326]),/* OBJ_id_alg_dh_pop                1 3 6 1 5 5 7 6 4 */
-&(nid_objs[327]),/* OBJ_id_cmc_statusInfo            1 3 6 1 5 5 7 7 1 */
-&(nid_objs[328]),/* OBJ_id_cmc_identification        1 3 6 1 5 5 7 7 2 */
-&(nid_objs[329]),/* OBJ_id_cmc_identityProof         1 3 6 1 5 5 7 7 3 */
-&(nid_objs[330]),/* OBJ_id_cmc_dataReturn            1 3 6 1 5 5 7 7 4 */
-&(nid_objs[331]),/* OBJ_id_cmc_transactionId         1 3 6 1 5 5 7 7 5 */
-&(nid_objs[332]),/* OBJ_id_cmc_senderNonce           1 3 6 1 5 5 7 7 6 */
-&(nid_objs[333]),/* OBJ_id_cmc_recipientNonce        1 3 6 1 5 5 7 7 7 */
-&(nid_objs[334]),/* OBJ_id_cmc_addExtensions         1 3 6 1 5 5 7 7 8 */
-&(nid_objs[335]),/* OBJ_id_cmc_encryptedPOP          1 3 6 1 5 5 7 7 9 */
-&(nid_objs[336]),/* OBJ_id_cmc_decryptedPOP          1 3 6 1 5 5 7 7 10 */
-&(nid_objs[337]),/* OBJ_id_cmc_lraPOPWitness         1 3 6 1 5 5 7 7 11 */
-&(nid_objs[338]),/* OBJ_id_cmc_getCert               1 3 6 1 5 5 7 7 15 */
-&(nid_objs[339]),/* OBJ_id_cmc_getCRL                1 3 6 1 5 5 7 7 16 */
-&(nid_objs[340]),/* OBJ_id_cmc_revokeRequest         1 3 6 1 5 5 7 7 17 */
-&(nid_objs[341]),/* OBJ_id_cmc_regInfo               1 3 6 1 5 5 7 7 18 */
-&(nid_objs[342]),/* OBJ_id_cmc_responseInfo          1 3 6 1 5 5 7 7 19 */
-&(nid_objs[343]),/* OBJ_id_cmc_queryPending          1 3 6 1 5 5 7 7 21 */
-&(nid_objs[344]),/* OBJ_id_cmc_popLinkRandom         1 3 6 1 5 5 7 7 22 */
-&(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 */
-&(nid_objs[352]),/* OBJ_id_pda_countryOfCitizenship  1 3 6 1 5 5 7 9 4 */
-&(nid_objs[353]),/* OBJ_id_pda_countryOfResidence    1 3 6 1 5 5 7 9 5 */
-&(nid_objs[354]),/* OBJ_id_aca_authenticationInfo    1 3 6 1 5 5 7 10 1 */
-&(nid_objs[355]),/* OBJ_id_aca_accessIdentity        1 3 6 1 5 5 7 10 2 */
-&(nid_objs[356]),/* OBJ_id_aca_chargingIdentity      1 3 6 1 5 5 7 10 3 */
-&(nid_objs[357]),/* OBJ_id_aca_group                 1 3 6 1 5 5 7 10 4 */
-&(nid_objs[358]),/* OBJ_id_aca_role                  1 3 6 1 5 5 7 10 5 */
-&(nid_objs[399]),/* OBJ_id_aca_encAttrs              1 3 6 1 5 5 7 10 6 */
-&(nid_objs[359]),/* OBJ_id_qcs_pkixQCSyntax_v1       1 3 6 1 5 5 7 11 1 */
-&(nid_objs[360]),/* OBJ_id_cct_crs                   1 3 6 1 5 5 7 12 1 */
-&(nid_objs[361]),/* OBJ_id_cct_PKIData               1 3 6 1 5 5 7 12 2 */
-&(nid_objs[362]),/* OBJ_id_cct_PKIResponse           1 3 6 1 5 5 7 12 3 */
-&(nid_objs[664]),/* OBJ_id_ppl_anyLanguage           1 3 6 1 5 5 7 21 0 */
-&(nid_objs[665]),/* OBJ_id_ppl_inheritAll            1 3 6 1 5 5 7 21 1 */
-&(nid_objs[667]),/* OBJ_Independent                  1 3 6 1 5 5 7 21 2 */
-&(nid_objs[178]),/* OBJ_ad_OCSP                      1 3 6 1 5 5 7 48 1 */
-&(nid_objs[179]),/* OBJ_ad_ca_issuers                1 3 6 1 5 5 7 48 2 */
-&(nid_objs[363]),/* OBJ_ad_timeStamping              1 3 6 1 5 5 7 48 3 */
-&(nid_objs[364]),/* OBJ_ad_dvcs                      1 3 6 1 5 5 7 48 4 */
-&(nid_objs[785]),/* OBJ_caRepository                 1 3 6 1 5 5 7 48 5 */
-&(nid_objs[780]),/* OBJ_hmac_md5                     1 3 6 1 5 5 8 1 1 */
-&(nid_objs[781]),/* OBJ_hmac_sha1                    1 3 6 1 5 5 8 1 2 */
-&(nid_objs[58]),/* OBJ_netscape_cert_extension      2 16 840 1 113730 1 */
-&(nid_objs[59]),/* OBJ_netscape_data_type           2 16 840 1 113730 2 */
-&(nid_objs[438]),/* OBJ_pilotAttributeType           0 9 2342 19200300 100 1 */
-&(nid_objs[439]),/* OBJ_pilotAttributeSyntax         0 9 2342 19200300 100 3 */
-&(nid_objs[440]),/* OBJ_pilotObjectClass             0 9 2342 19200300 100 4 */
-&(nid_objs[441]),/* OBJ_pilotGroups                  0 9 2342 19200300 100 10 */
-&(nid_objs[108]),/* OBJ_cast5_cbc                    1 2 840 113533 7 66 10 */
-&(nid_objs[112]),/* OBJ_pbeWithMD5AndCast5_CBC       1 2 840 113533 7 66 12 */
-&(nid_objs[782]),/* OBJ_id_PasswordBasedMAC          1 2 840 113533 7 66 13 */
-&(nid_objs[783]),/* OBJ_id_DHBasedMac                1 2 840 113533 7 66 30 */
-&(nid_objs[ 6]),/* OBJ_rsaEncryption                1 2 840 113549 1 1 1 */
-&(nid_objs[ 7]),/* OBJ_md2WithRSAEncryption         1 2 840 113549 1 1 2 */
-&(nid_objs[396]),/* OBJ_md4WithRSAEncryption         1 2 840 113549 1 1 3 */
-&(nid_objs[ 8]),/* OBJ_md5WithRSAEncryption         1 2 840 113549 1 1 4 */
-&(nid_objs[65]),/* OBJ_sha1WithRSAEncryption        1 2 840 113549 1 1 5 */
-&(nid_objs[644]),/* OBJ_rsaOAEPEncryptionSET         1 2 840 113549 1 1 6 */
-&(nid_objs[668]),/* OBJ_sha256WithRSAEncryption      1 2 840 113549 1 1 11 */
-&(nid_objs[669]),/* OBJ_sha384WithRSAEncryption      1 2 840 113549 1 1 12 */
-&(nid_objs[670]),/* OBJ_sha512WithRSAEncryption      1 2 840 113549 1 1 13 */
-&(nid_objs[671]),/* OBJ_sha224WithRSAEncryption      1 2 840 113549 1 1 14 */
-&(nid_objs[28]),/* OBJ_dhKeyAgreement               1 2 840 113549 1 3 1 */
-&(nid_objs[ 9]),/* OBJ_pbeWithMD2AndDES_CBC         1 2 840 113549 1 5 1 */
-&(nid_objs[10]),/* OBJ_pbeWithMD5AndDES_CBC         1 2 840 113549 1 5 3 */
-&(nid_objs[168]),/* OBJ_pbeWithMD2AndRC2_CBC         1 2 840 113549 1 5 4 */
-&(nid_objs[169]),/* OBJ_pbeWithMD5AndRC2_CBC         1 2 840 113549 1 5 6 */
-&(nid_objs[170]),/* OBJ_pbeWithSHA1AndDES_CBC        1 2 840 113549 1 5 10 */
-&(nid_objs[68]),/* OBJ_pbeWithSHA1AndRC2_CBC        1 2 840 113549 1 5 11 */
-&(nid_objs[69]),/* OBJ_id_pbkdf2                    1 2 840 113549 1 5 12 */
-&(nid_objs[161]),/* OBJ_pbes2                        1 2 840 113549 1 5 13 */
-&(nid_objs[162]),/* OBJ_pbmac1                       1 2 840 113549 1 5 14 */
-&(nid_objs[21]),/* OBJ_pkcs7_data                   1 2 840 113549 1 7 1 */
-&(nid_objs[22]),/* OBJ_pkcs7_signed                 1 2 840 113549 1 7 2 */
-&(nid_objs[23]),/* OBJ_pkcs7_enveloped              1 2 840 113549 1 7 3 */
-&(nid_objs[24]),/* OBJ_pkcs7_signedAndEnveloped     1 2 840 113549 1 7 4 */
-&(nid_objs[25]),/* OBJ_pkcs7_digest                 1 2 840 113549 1 7 5 */
-&(nid_objs[26]),/* OBJ_pkcs7_encrypted              1 2 840 113549 1 7 6 */
-&(nid_objs[48]),/* OBJ_pkcs9_emailAddress           1 2 840 113549 1 9 1 */
-&(nid_objs[49]),/* OBJ_pkcs9_unstructuredName       1 2 840 113549 1 9 2 */
-&(nid_objs[50]),/* OBJ_pkcs9_contentType            1 2 840 113549 1 9 3 */
-&(nid_objs[51]),/* OBJ_pkcs9_messageDigest          1 2 840 113549 1 9 4 */
-&(nid_objs[52]),/* OBJ_pkcs9_signingTime            1 2 840 113549 1 9 5 */
-&(nid_objs[53]),/* OBJ_pkcs9_countersignature       1 2 840 113549 1 9 6 */
-&(nid_objs[54]),/* OBJ_pkcs9_challengePassword      1 2 840 113549 1 9 7 */
-&(nid_objs[55]),/* OBJ_pkcs9_unstructuredAddress    1 2 840 113549 1 9 8 */
-&(nid_objs[56]),/* OBJ_pkcs9_extCertAttributes      1 2 840 113549 1 9 9 */
-&(nid_objs[172]),/* OBJ_ext_req                      1 2 840 113549 1 9 14 */
-&(nid_objs[167]),/* OBJ_SMIMECapabilities            1 2 840 113549 1 9 15 */
-&(nid_objs[188]),/* OBJ_SMIME                        1 2 840 113549 1 9 16 */
-&(nid_objs[156]),/* OBJ_friendlyName                 1 2 840 113549 1 9 20 */
-&(nid_objs[157]),/* OBJ_localKeyID                   1 2 840 113549 1 9 21 */
-&(nid_objs[681]),/* OBJ_X9_62_onBasis                1 2 840 10045 1 2 3 1 */
-&(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 */
-&(nid_objs[316]),/* OBJ_id_regCtrl_authenticator     1 3 6 1 5 5 7 5 1 2 */
-&(nid_objs[317]),/* OBJ_id_regCtrl_pkiPublicationInfo 1 3 6 1 5 5 7 5 1 3 */
-&(nid_objs[318]),/* OBJ_id_regCtrl_pkiArchiveOptions 1 3 6 1 5 5 7 5 1 4 */
-&(nid_objs[319]),/* OBJ_id_regCtrl_oldCertID         1 3 6 1 5 5 7 5 1 5 */
-&(nid_objs[320]),/* OBJ_id_regCtrl_protocolEncrKey   1 3 6 1 5 5 7 5 1 6 */
-&(nid_objs[321]),/* OBJ_id_regInfo_utf8Pairs         1 3 6 1 5 5 7 5 2 1 */
-&(nid_objs[322]),/* OBJ_id_regInfo_certReq           1 3 6 1 5 5 7 5 2 2 */
-&(nid_objs[365]),/* OBJ_id_pkix_OCSP_basic           1 3 6 1 5 5 7 48 1 1 */
-&(nid_objs[366]),/* OBJ_id_pkix_OCSP_Nonce           1 3 6 1 5 5 7 48 1 2 */
-&(nid_objs[367]),/* OBJ_id_pkix_OCSP_CrlID           1 3 6 1 5 5 7 48 1 3 */
-&(nid_objs[368]),/* OBJ_id_pkix_OCSP_acceptableResponses 1 3 6 1 5 5 7 48 1 4 */
-&(nid_objs[369]),/* OBJ_id_pkix_OCSP_noCheck         1 3 6 1 5 5 7 48 1 5 */
-&(nid_objs[370]),/* OBJ_id_pkix_OCSP_archiveCutoff   1 3 6 1 5 5 7 48 1 6 */
-&(nid_objs[371]),/* OBJ_id_pkix_OCSP_serviceLocator  1 3 6 1 5 5 7 48 1 7 */
-&(nid_objs[372]),/* OBJ_id_pkix_OCSP_extendedStatus  1 3 6 1 5 5 7 48 1 8 */
-&(nid_objs[373]),/* OBJ_id_pkix_OCSP_valid           1 3 6 1 5 5 7 48 1 9 */
-&(nid_objs[374]),/* OBJ_id_pkix_OCSP_path            1 3 6 1 5 5 7 48 1 10 */
-&(nid_objs[375]),/* OBJ_id_pkix_OCSP_trustRoot       1 3 6 1 5 5 7 48 1 11 */
-&(nid_objs[418]),/* OBJ_aes_128_ecb                  2 16 840 1 101 3 4 1 1 */
-&(nid_objs[419]),/* OBJ_aes_128_cbc                  2 16 840 1 101 3 4 1 2 */
-&(nid_objs[420]),/* OBJ_aes_128_ofb128               2 16 840 1 101 3 4 1 3 */
-&(nid_objs[421]),/* OBJ_aes_128_cfb128               2 16 840 1 101 3 4 1 4 */
-&(nid_objs[788]),/* OBJ_id_aes128_wrap               2 16 840 1 101 3 4 1 5 */
-&(nid_objs[422]),/* OBJ_aes_192_ecb                  2 16 840 1 101 3 4 1 21 */
-&(nid_objs[423]),/* OBJ_aes_192_cbc                  2 16 840 1 101 3 4 1 22 */
-&(nid_objs[424]),/* OBJ_aes_192_ofb128               2 16 840 1 101 3 4 1 23 */
-&(nid_objs[425]),/* OBJ_aes_192_cfb128               2 16 840 1 101 3 4 1 24 */
-&(nid_objs[789]),/* OBJ_id_aes192_wrap               2 16 840 1 101 3 4 1 25 */
-&(nid_objs[426]),/* OBJ_aes_256_ecb                  2 16 840 1 101 3 4 1 41 */
-&(nid_objs[427]),/* OBJ_aes_256_cbc                  2 16 840 1 101 3 4 1 42 */
-&(nid_objs[428]),/* OBJ_aes_256_ofb128               2 16 840 1 101 3 4 1 43 */
-&(nid_objs[429]),/* OBJ_aes_256_cfb128               2 16 840 1 101 3 4 1 44 */
-&(nid_objs[790]),/* OBJ_id_aes256_wrap               2 16 840 1 101 3 4 1 45 */
-&(nid_objs[672]),/* OBJ_sha256                       2 16 840 1 101 3 4 2 1 */
-&(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 */
-&(nid_objs[74]),/* OBJ_netscape_ca_revocation_url   2 16 840 1 113730 1 4 */
-&(nid_objs[75]),/* OBJ_netscape_renewal_url         2 16 840 1 113730 1 7 */
-&(nid_objs[76]),/* OBJ_netscape_ca_policy_url       2 16 840 1 113730 1 8 */
-&(nid_objs[77]),/* OBJ_netscape_ssl_server_name     2 16 840 1 113730 1 12 */
-&(nid_objs[78]),/* OBJ_netscape_comment             2 16 840 1 113730 1 13 */
-&(nid_objs[79]),/* OBJ_netscape_cert_sequence       2 16 840 1 113730 2 5 */
-&(nid_objs[139]),/* OBJ_ns_sgc                       2 16 840 1 113730 4 1 */
-&(nid_objs[458]),/* OBJ_userId                       0 9 2342 19200300 100 1 1 */
-&(nid_objs[459]),/* OBJ_textEncodedORAddress         0 9 2342 19200300 100 1 2 */
-&(nid_objs[460]),/* OBJ_rfc822Mailbox                0 9 2342 19200300 100 1 3 */
-&(nid_objs[461]),/* OBJ_info                         0 9 2342 19200300 100 1 4 */
-&(nid_objs[462]),/* OBJ_favouriteDrink               0 9 2342 19200300 100 1 5 */
-&(nid_objs[463]),/* OBJ_roomNumber                   0 9 2342 19200300 100 1 6 */
-&(nid_objs[464]),/* OBJ_photo                        0 9 2342 19200300 100 1 7 */
-&(nid_objs[465]),/* OBJ_userClass                    0 9 2342 19200300 100 1 8 */
-&(nid_objs[466]),/* OBJ_host                         0 9 2342 19200300 100 1 9 */
-&(nid_objs[467]),/* OBJ_manager                      0 9 2342 19200300 100 1 10 */
-&(nid_objs[468]),/* OBJ_documentIdentifier           0 9 2342 19200300 100 1 11 */
-&(nid_objs[469]),/* OBJ_documentTitle                0 9 2342 19200300 100 1 12 */
-&(nid_objs[470]),/* OBJ_documentVersion              0 9 2342 19200300 100 1 13 */
-&(nid_objs[471]),/* OBJ_documentAuthor               0 9 2342 19200300 100 1 14 */
-&(nid_objs[472]),/* OBJ_documentLocation             0 9 2342 19200300 100 1 15 */
-&(nid_objs[473]),/* OBJ_homeTelephoneNumber          0 9 2342 19200300 100 1 20 */
-&(nid_objs[474]),/* OBJ_secretary                    0 9 2342 19200300 100 1 21 */
-&(nid_objs[475]),/* OBJ_otherMailbox                 0 9 2342 19200300 100 1 22 */
-&(nid_objs[476]),/* OBJ_lastModifiedTime             0 9 2342 19200300 100 1 23 */
-&(nid_objs[477]),/* OBJ_lastModifiedBy               0 9 2342 19200300 100 1 24 */
-&(nid_objs[391]),/* OBJ_domainComponent              0 9 2342 19200300 100 1 25 */
-&(nid_objs[478]),/* OBJ_aRecord                      0 9 2342 19200300 100 1 26 */
-&(nid_objs[479]),/* OBJ_pilotAttributeType27         0 9 2342 19200300 100 1 27 */
-&(nid_objs[480]),/* OBJ_mXRecord                     0 9 2342 19200300 100 1 28 */
-&(nid_objs[481]),/* OBJ_nSRecord                     0 9 2342 19200300 100 1 29 */
-&(nid_objs[482]),/* OBJ_sOARecord                    0 9 2342 19200300 100 1 30 */
-&(nid_objs[483]),/* OBJ_cNAMERecord                  0 9 2342 19200300 100 1 31 */
-&(nid_objs[484]),/* OBJ_associatedDomain             0 9 2342 19200300 100 1 37 */
-&(nid_objs[485]),/* OBJ_associatedName               0 9 2342 19200300 100 1 38 */
-&(nid_objs[486]),/* OBJ_homePostalAddress            0 9 2342 19200300 100 1 39 */
-&(nid_objs[487]),/* OBJ_personalTitle                0 9 2342 19200300 100 1 40 */
-&(nid_objs[488]),/* OBJ_mobileTelephoneNumber        0 9 2342 19200300 100 1 41 */
-&(nid_objs[489]),/* OBJ_pagerTelephoneNumber         0 9 2342 19200300 100 1 42 */
-&(nid_objs[490]),/* OBJ_friendlyCountryName          0 9 2342 19200300 100 1 43 */
-&(nid_objs[491]),/* OBJ_organizationalStatus         0 9 2342 19200300 100 1 45 */
-&(nid_objs[492]),/* OBJ_janetMailbox                 0 9 2342 19200300 100 1 46 */
-&(nid_objs[493]),/* OBJ_mailPreferenceOption         0 9 2342 19200300 100 1 47 */
-&(nid_objs[494]),/* OBJ_buildingName                 0 9 2342 19200300 100 1 48 */
-&(nid_objs[495]),/* OBJ_dSAQuality                   0 9 2342 19200300 100 1 49 */
-&(nid_objs[496]),/* OBJ_singleLevelQuality           0 9 2342 19200300 100 1 50 */
-&(nid_objs[497]),/* OBJ_subtreeMinimumQuality        0 9 2342 19200300 100 1 51 */
-&(nid_objs[498]),/* OBJ_subtreeMaximumQuality        0 9 2342 19200300 100 1 52 */
-&(nid_objs[499]),/* OBJ_personalSignature            0 9 2342 19200300 100 1 53 */
-&(nid_objs[500]),/* OBJ_dITRedirect                  0 9 2342 19200300 100 1 54 */
-&(nid_objs[501]),/* OBJ_audio                        0 9 2342 19200300 100 1 55 */
-&(nid_objs[502]),/* OBJ_documentPublisher            0 9 2342 19200300 100 1 56 */
-&(nid_objs[442]),/* OBJ_iA5StringSyntax              0 9 2342 19200300 100 3 4 */
-&(nid_objs[443]),/* OBJ_caseIgnoreIA5StringSyntax    0 9 2342 19200300 100 3 5 */
-&(nid_objs[444]),/* OBJ_pilotObject                  0 9 2342 19200300 100 4 3 */
-&(nid_objs[445]),/* OBJ_pilotPerson                  0 9 2342 19200300 100 4 4 */
-&(nid_objs[446]),/* OBJ_account                      0 9 2342 19200300 100 4 5 */
-&(nid_objs[447]),/* OBJ_document                     0 9 2342 19200300 100 4 6 */
-&(nid_objs[448]),/* OBJ_room                         0 9 2342 19200300 100 4 7 */
-&(nid_objs[449]),/* OBJ_documentSeries               0 9 2342 19200300 100 4 9 */
-&(nid_objs[392]),/* OBJ_Domain                       0 9 2342 19200300 100 4 13 */
-&(nid_objs[450]),/* OBJ_rFC822localPart              0 9 2342 19200300 100 4 14 */
-&(nid_objs[451]),/* OBJ_dNSDomain                    0 9 2342 19200300 100 4 15 */
-&(nid_objs[452]),/* OBJ_domainRelatedObject          0 9 2342 19200300 100 4 17 */
-&(nid_objs[453]),/* OBJ_friendlyCountry              0 9 2342 19200300 100 4 18 */
-&(nid_objs[454]),/* OBJ_simpleSecurityObject         0 9 2342 19200300 100 4 19 */
-&(nid_objs[455]),/* OBJ_pilotOrganization            0 9 2342 19200300 100 4 20 */
-&(nid_objs[456]),/* OBJ_pilotDSA                     0 9 2342 19200300 100 4 21 */
-&(nid_objs[457]),/* OBJ_qualityLabelledData          0 9 2342 19200300 100 4 22 */
-&(nid_objs[189]),/* OBJ_id_smime_mod                 1 2 840 113549 1 9 16 0 */
-&(nid_objs[190]),/* OBJ_id_smime_ct                  1 2 840 113549 1 9 16 1 */
-&(nid_objs[191]),/* OBJ_id_smime_aa                  1 2 840 113549 1 9 16 2 */
-&(nid_objs[192]),/* OBJ_id_smime_alg                 1 2 840 113549 1 9 16 3 */
-&(nid_objs[193]),/* OBJ_id_smime_cd                  1 2 840 113549 1 9 16 4 */
-&(nid_objs[194]),/* OBJ_id_smime_spq                 1 2 840 113549 1 9 16 5 */
-&(nid_objs[195]),/* OBJ_id_smime_cti                 1 2 840 113549 1 9 16 6 */
-&(nid_objs[158]),/* OBJ_x509Certificate              1 2 840 113549 1 9 22 1 */
-&(nid_objs[159]),/* OBJ_sdsiCertificate              1 2 840 113549 1 9 22 2 */
-&(nid_objs[160]),/* OBJ_x509Crl                      1 2 840 113549 1 9 23 1 */
-&(nid_objs[144]),/* OBJ_pbe_WithSHA1And128BitRC4     1 2 840 113549 1 12 1 1 */
-&(nid_objs[145]),/* OBJ_pbe_WithSHA1And40BitRC4      1 2 840 113549 1 12 1 2 */
-&(nid_objs[146]),/* OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC 1 2 840 113549 1 12 1 3 */
-&(nid_objs[147]),/* OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC 1 2 840 113549 1 12 1 4 */
-&(nid_objs[148]),/* OBJ_pbe_WithSHA1And128BitRC2_CBC 1 2 840 113549 1 12 1 5 */
-&(nid_objs[149]),/* OBJ_pbe_WithSHA1And40BitRC2_CBC  1 2 840 113549 1 12 1 6 */
-&(nid_objs[171]),/* OBJ_ms_ext_req                   1 3 6 1 4 1 311 2 1 14 */
-&(nid_objs[134]),/* OBJ_ms_code_ind                  1 3 6 1 4 1 311 2 1 21 */
-&(nid_objs[135]),/* OBJ_ms_code_com                  1 3 6 1 4 1 311 2 1 22 */
-&(nid_objs[136]),/* OBJ_ms_ctl_sign                  1 3 6 1 4 1 311 10 3 1 */
-&(nid_objs[137]),/* OBJ_ms_sgc                       1 3 6 1 4 1 311 10 3 3 */
-&(nid_objs[138]),/* OBJ_ms_efs                       1 3 6 1 4 1 311 10 3 4 */
-&(nid_objs[648]),/* OBJ_ms_smartcard_login           1 3 6 1 4 1 311 20 2 2 */
-&(nid_objs[649]),/* OBJ_ms_upn                       1 3 6 1 4 1 311 20 2 3 */
-&(nid_objs[751]),/* OBJ_camellia_128_cbc             1 2 392 200011 61 1 1 1 2 */
-&(nid_objs[752]),/* OBJ_camellia_192_cbc             1 2 392 200011 61 1 1 1 3 */
-&(nid_objs[753]),/* OBJ_camellia_256_cbc             1 2 392 200011 61 1 1 1 4 */
-&(nid_objs[196]),/* OBJ_id_smime_mod_cms             1 2 840 113549 1 9 16 0 1 */
-&(nid_objs[197]),/* OBJ_id_smime_mod_ess             1 2 840 113549 1 9 16 0 2 */
-&(nid_objs[198]),/* OBJ_id_smime_mod_oid             1 2 840 113549 1 9 16 0 3 */
-&(nid_objs[199]),/* OBJ_id_smime_mod_msg_v3          1 2 840 113549 1 9 16 0 4 */
-&(nid_objs[200]),/* OBJ_id_smime_mod_ets_eSignature_88 1 2 840 113549 1 9 16 0 5 */
-&(nid_objs[201]),/* OBJ_id_smime_mod_ets_eSignature_97 1 2 840 113549 1 9 16 0 6 */
-&(nid_objs[202]),/* OBJ_id_smime_mod_ets_eSigPolicy_88 1 2 840 113549 1 9 16 0 7 */
-&(nid_objs[203]),/* OBJ_id_smime_mod_ets_eSigPolicy_97 1 2 840 113549 1 9 16 0 8 */
-&(nid_objs[204]),/* OBJ_id_smime_ct_receipt          1 2 840 113549 1 9 16 1 1 */
-&(nid_objs[205]),/* OBJ_id_smime_ct_authData         1 2 840 113549 1 9 16 1 2 */
-&(nid_objs[206]),/* OBJ_id_smime_ct_publishCert      1 2 840 113549 1 9 16 1 3 */
-&(nid_objs[207]),/* OBJ_id_smime_ct_TSTInfo          1 2 840 113549 1 9 16 1 4 */
-&(nid_objs[208]),/* OBJ_id_smime_ct_TDTInfo          1 2 840 113549 1 9 16 1 5 */
-&(nid_objs[209]),/* OBJ_id_smime_ct_contentInfo      1 2 840 113549 1 9 16 1 6 */
-&(nid_objs[210]),/* OBJ_id_smime_ct_DVCSRequestData  1 2 840 113549 1 9 16 1 7 */
-&(nid_objs[211]),/* OBJ_id_smime_ct_DVCSResponseData 1 2 840 113549 1 9 16 1 8 */
-&(nid_objs[786]),/* OBJ_id_smime_ct_compressedData   1 2 840 113549 1 9 16 1 9 */
-&(nid_objs[787]),/* OBJ_id_ct_asciiTextWithCRLF      1 2 840 113549 1 9 16 1 27 */
-&(nid_objs[212]),/* OBJ_id_smime_aa_receiptRequest   1 2 840 113549 1 9 16 2 1 */
-&(nid_objs[213]),/* OBJ_id_smime_aa_securityLabel    1 2 840 113549 1 9 16 2 2 */
-&(nid_objs[214]),/* OBJ_id_smime_aa_mlExpandHistory  1 2 840 113549 1 9 16 2 3 */
-&(nid_objs[215]),/* OBJ_id_smime_aa_contentHint      1 2 840 113549 1 9 16 2 4 */
-&(nid_objs[216]),/* OBJ_id_smime_aa_msgSigDigest     1 2 840 113549 1 9 16 2 5 */
-&(nid_objs[217]),/* OBJ_id_smime_aa_encapContentType 1 2 840 113549 1 9 16 2 6 */
-&(nid_objs[218]),/* OBJ_id_smime_aa_contentIdentifier 1 2 840 113549 1 9 16 2 7 */
-&(nid_objs[219]),/* OBJ_id_smime_aa_macValue         1 2 840 113549 1 9 16 2 8 */
-&(nid_objs[220]),/* OBJ_id_smime_aa_equivalentLabels 1 2 840 113549 1 9 16 2 9 */
-&(nid_objs[221]),/* OBJ_id_smime_aa_contentReference 1 2 840 113549 1 9 16 2 10 */
-&(nid_objs[222]),/* OBJ_id_smime_aa_encrypKeyPref    1 2 840 113549 1 9 16 2 11 */
-&(nid_objs[223]),/* OBJ_id_smime_aa_signingCertificate 1 2 840 113549 1 9 16 2 12 */
-&(nid_objs[224]),/* OBJ_id_smime_aa_smimeEncryptCerts 1 2 840 113549 1 9 16 2 13 */
-&(nid_objs[225]),/* OBJ_id_smime_aa_timeStampToken   1 2 840 113549 1 9 16 2 14 */
-&(nid_objs[226]),/* OBJ_id_smime_aa_ets_sigPolicyId  1 2 840 113549 1 9 16 2 15 */
-&(nid_objs[227]),/* OBJ_id_smime_aa_ets_commitmentType 1 2 840 113549 1 9 16 2 16 */
-&(nid_objs[228]),/* OBJ_id_smime_aa_ets_signerLocation 1 2 840 113549 1 9 16 2 17 */
-&(nid_objs[229]),/* OBJ_id_smime_aa_ets_signerAttr   1 2 840 113549 1 9 16 2 18 */
-&(nid_objs[230]),/* OBJ_id_smime_aa_ets_otherSigCert 1 2 840 113549 1 9 16 2 19 */
-&(nid_objs[231]),/* OBJ_id_smime_aa_ets_contentTimestamp 1 2 840 113549 1 9 16 2 20 */
-&(nid_objs[232]),/* OBJ_id_smime_aa_ets_CertificateRefs 1 2 840 113549 1 9 16 2 21 */
-&(nid_objs[233]),/* OBJ_id_smime_aa_ets_RevocationRefs 1 2 840 113549 1 9 16 2 22 */
-&(nid_objs[234]),/* OBJ_id_smime_aa_ets_certValues   1 2 840 113549 1 9 16 2 23 */
-&(nid_objs[235]),/* OBJ_id_smime_aa_ets_revocationValues 1 2 840 113549 1 9 16 2 24 */
-&(nid_objs[236]),/* OBJ_id_smime_aa_ets_escTimeStamp 1 2 840 113549 1 9 16 2 25 */
-&(nid_objs[237]),/* OBJ_id_smime_aa_ets_certCRLTimestamp 1 2 840 113549 1 9 16 2 26 */
-&(nid_objs[238]),/* OBJ_id_smime_aa_ets_archiveTimeStamp 1 2 840 113549 1 9 16 2 27 */
-&(nid_objs[239]),/* OBJ_id_smime_aa_signatureType    1 2 840 113549 1 9 16 2 28 */
-&(nid_objs[240]),/* OBJ_id_smime_aa_dvcs_dvc         1 2 840 113549 1 9 16 2 29 */
-&(nid_objs[241]),/* OBJ_id_smime_alg_ESDHwith3DES    1 2 840 113549 1 9 16 3 1 */
-&(nid_objs[242]),/* OBJ_id_smime_alg_ESDHwithRC2     1 2 840 113549 1 9 16 3 2 */
-&(nid_objs[243]),/* OBJ_id_smime_alg_3DESwrap        1 2 840 113549 1 9 16 3 3 */
-&(nid_objs[244]),/* OBJ_id_smime_alg_RC2wrap         1 2 840 113549 1 9 16 3 4 */
-&(nid_objs[245]),/* OBJ_id_smime_alg_ESDH            1 2 840 113549 1 9 16 3 5 */
-&(nid_objs[246]),/* OBJ_id_smime_alg_CMS3DESwrap     1 2 840 113549 1 9 16 3 6 */
-&(nid_objs[247]),/* OBJ_id_smime_alg_CMSRC2wrap      1 2 840 113549 1 9 16 3 7 */
-&(nid_objs[125]),/* OBJ_zlib_compression             1 2 840 113549 1 9 16 3 8 */
-&(nid_objs[248]),/* OBJ_id_smime_cd_ldap             1 2 840 113549 1 9 16 4 1 */
-&(nid_objs[249]),/* OBJ_id_smime_spq_ets_sqt_uri     1 2 840 113549 1 9 16 5 1 */
-&(nid_objs[250]),/* OBJ_id_smime_spq_ets_sqt_unotice 1 2 840 113549 1 9 16 5 2 */
-&(nid_objs[251]),/* OBJ_id_smime_cti_ets_proofOfOrigin 1 2 840 113549 1 9 16 6 1 */
-&(nid_objs[252]),/* OBJ_id_smime_cti_ets_proofOfReceipt 1 2 840 113549 1 9 16 6 2 */
-&(nid_objs[253]),/* OBJ_id_smime_cti_ets_proofOfDelivery 1 2 840 113549 1 9 16 6 3 */
-&(nid_objs[254]),/* OBJ_id_smime_cti_ets_proofOfSender 1 2 840 113549 1 9 16 6 4 */
-&(nid_objs[255]),/* OBJ_id_smime_cti_ets_proofOfApproval 1 2 840 113549 1 9 16 6 5 */
-&(nid_objs[256]),/* OBJ_id_smime_cti_ets_proofOfCreation 1 2 840 113549 1 9 16 6 6 */
-&(nid_objs[150]),/* OBJ_keyBag                       1 2 840 113549 1 12 10 1 1 */
-&(nid_objs[151]),/* OBJ_pkcs8ShroudedKeyBag          1 2 840 113549 1 12 10 1 2 */
-&(nid_objs[152]),/* OBJ_certBag                      1 2 840 113549 1 12 10 1 3 */
-&(nid_objs[153]),/* OBJ_crlBag                       1 2 840 113549 1 12 10 1 4 */
-&(nid_objs[154]),/* OBJ_secretBag                    1 2 840 113549 1 12 10 1 5 */
-&(nid_objs[155]),/* OBJ_safeContentsBag              1 2 840 113549 1 12 10 1 6 */
-&(nid_objs[34]),/* OBJ_idea_cbc                     1 3 6 1 4 1 188 7 1 1 2 */
+static const unsigned int obj_objs[NUM_OBJ]={
+ 0,	/* OBJ_undef                        0 */
+393,	/* OBJ_joint_iso_ccitt              OBJ_joint_iso_itu_t */
+404,	/* OBJ_ccitt                        OBJ_itu_t */
+645,	/* OBJ_itu_t                        0 */
+434,	/* OBJ_data                         0 9 */
+181,	/* OBJ_iso                          1 */
+182,	/* OBJ_member_body                  1 2 */
+379,	/* OBJ_org                          1 3 */
+676,	/* OBJ_identified_organization      1 3 */
+646,	/* OBJ_joint_iso_itu_t              2 */
+11,	/* OBJ_X500                         2 5 */
+647,	/* OBJ_international_organizations  2 23 */
+380,	/* OBJ_dod                          1 3 6 */
+12,	/* OBJ_X509                         2 5 4 */
+378,	/* OBJ_X500algorithms               2 5 8 */
+81,	/* OBJ_id_ce                        2 5 29 */
+512,	/* OBJ_id_set                       2 23 42 */
+678,	/* OBJ_wap                          2 23 43 */
+435,	/* OBJ_pss                          0 9 2342 */
+183,	/* OBJ_ISO_US                       1 2 840 */
+381,	/* OBJ_iana                         1 3 6 1 */
+677,	/* OBJ_certicom_arc                 1 3 132 */
+394,	/* OBJ_selected_attribute_types     2 5 1 5 */
+13,	/* OBJ_commonName                   2 5 4 3 */
+100,	/* OBJ_surname                      2 5 4 4 */
+105,	/* OBJ_serialNumber                 2 5 4 5 */
+14,	/* OBJ_countryName                  2 5 4 6 */
+15,	/* OBJ_localityName                 2 5 4 7 */
+16,	/* OBJ_stateOrProvinceName          2 5 4 8 */
+660,	/* OBJ_streetAddress                2 5 4 9 */
+17,	/* OBJ_organizationName             2 5 4 10 */
+18,	/* OBJ_organizationalUnitName       2 5 4 11 */
+106,	/* OBJ_title                        2 5 4 12 */
+107,	/* OBJ_description                  2 5 4 13 */
+859,	/* OBJ_searchGuide                  2 5 4 14 */
+860,	/* OBJ_businessCategory             2 5 4 15 */
+861,	/* OBJ_postalAddress                2 5 4 16 */
+661,	/* OBJ_postalCode                   2 5 4 17 */
+862,	/* OBJ_postOfficeBox                2 5 4 18 */
+863,	/* OBJ_physicalDeliveryOfficeName   2 5 4 19 */
+864,	/* OBJ_telephoneNumber              2 5 4 20 */
+865,	/* OBJ_telexNumber                  2 5 4 21 */
+866,	/* OBJ_teletexTerminalIdentifier    2 5 4 22 */
+867,	/* OBJ_facsimileTelephoneNumber     2 5 4 23 */
+868,	/* OBJ_x121Address                  2 5 4 24 */
+869,	/* OBJ_internationaliSDNNumber      2 5 4 25 */
+870,	/* OBJ_registeredAddress            2 5 4 26 */
+871,	/* OBJ_destinationIndicator         2 5 4 27 */
+872,	/* OBJ_preferredDeliveryMethod      2 5 4 28 */
+873,	/* OBJ_presentationAddress          2 5 4 29 */
+874,	/* OBJ_supportedApplicationContext  2 5 4 30 */
+875,	/* OBJ_member                       2 5 4 31 */
+876,	/* OBJ_owner                        2 5 4 32 */
+877,	/* OBJ_roleOccupant                 2 5 4 33 */
+878,	/* OBJ_seeAlso                      2 5 4 34 */
+879,	/* OBJ_userPassword                 2 5 4 35 */
+880,	/* OBJ_userCertificate              2 5 4 36 */
+881,	/* OBJ_cACertificate                2 5 4 37 */
+882,	/* OBJ_authorityRevocationList      2 5 4 38 */
+883,	/* OBJ_certificateRevocationList    2 5 4 39 */
+884,	/* OBJ_crossCertificatePair         2 5 4 40 */
+173,	/* OBJ_name                         2 5 4 41 */
+99,	/* OBJ_givenName                    2 5 4 42 */
+101,	/* OBJ_initials                     2 5 4 43 */
+509,	/* OBJ_generationQualifier          2 5 4 44 */
+503,	/* OBJ_x500UniqueIdentifier         2 5 4 45 */
+174,	/* OBJ_dnQualifier                  2 5 4 46 */
+885,	/* OBJ_enhancedSearchGuide          2 5 4 47 */
+886,	/* OBJ_protocolInformation          2 5 4 48 */
+887,	/* OBJ_distinguishedName            2 5 4 49 */
+888,	/* OBJ_uniqueMember                 2 5 4 50 */
+889,	/* OBJ_houseIdentifier              2 5 4 51 */
+890,	/* OBJ_supportedAlgorithms          2 5 4 52 */
+891,	/* OBJ_deltaRevocationList          2 5 4 53 */
+892,	/* OBJ_dmdName                      2 5 4 54 */
+510,	/* OBJ_pseudonym                    2 5 4 65 */
+400,	/* OBJ_role                         2 5 4 72 */
+769,	/* OBJ_subject_directory_attributes 2 5 29 9 */
+82,	/* OBJ_subject_key_identifier       2 5 29 14 */
+83,	/* OBJ_key_usage                    2 5 29 15 */
+84,	/* OBJ_private_key_usage_period     2 5 29 16 */
+85,	/* OBJ_subject_alt_name             2 5 29 17 */
+86,	/* OBJ_issuer_alt_name              2 5 29 18 */
+87,	/* OBJ_basic_constraints            2 5 29 19 */
+88,	/* OBJ_crl_number                   2 5 29 20 */
+141,	/* OBJ_crl_reason                   2 5 29 21 */
+430,	/* OBJ_hold_instruction_code        2 5 29 23 */
+142,	/* OBJ_invalidity_date              2 5 29 24 */
+140,	/* OBJ_delta_crl                    2 5 29 27 */
+770,	/* OBJ_issuing_distribution_point   2 5 29 28 */
+771,	/* OBJ_certificate_issuer           2 5 29 29 */
+666,	/* OBJ_name_constraints             2 5 29 30 */
+103,	/* OBJ_crl_distribution_points      2 5 29 31 */
+89,	/* OBJ_certificate_policies         2 5 29 32 */
+747,	/* OBJ_policy_mappings              2 5 29 33 */
+90,	/* OBJ_authority_key_identifier     2 5 29 35 */
+401,	/* OBJ_policy_constraints           2 5 29 36 */
+126,	/* OBJ_ext_key_usage                2 5 29 37 */
+857,	/* OBJ_freshest_crl                 2 5 29 46 */
+748,	/* OBJ_inhibit_any_policy           2 5 29 54 */
+402,	/* OBJ_target_information           2 5 29 55 */
+403,	/* OBJ_no_rev_avail                 2 5 29 56 */
+513,	/* OBJ_set_ctype                    2 23 42 0 */
+514,	/* OBJ_set_msgExt                   2 23 42 1 */
+515,	/* OBJ_set_attr                     2 23 42 3 */
+516,	/* OBJ_set_policy                   2 23 42 5 */
+517,	/* OBJ_set_certExt                  2 23 42 7 */
+518,	/* OBJ_set_brand                    2 23 42 8 */
+679,	/* OBJ_wap_wsg                      2 23 43 1 */
+382,	/* OBJ_Directory                    1 3 6 1 1 */
+383,	/* OBJ_Management                   1 3 6 1 2 */
+384,	/* OBJ_Experimental                 1 3 6 1 3 */
+385,	/* OBJ_Private                      1 3 6 1 4 */
+386,	/* OBJ_Security                     1 3 6 1 5 */
+387,	/* OBJ_SNMPv2                       1 3 6 1 6 */
+388,	/* OBJ_Mail                         1 3 6 1 7 */
+376,	/* OBJ_algorithm                    1 3 14 3 2 */
+395,	/* OBJ_clearance                    2 5 1 5 55 */
+19,	/* OBJ_rsa                          2 5 8 1 1 */
+96,	/* OBJ_mdc2WithRSA                  2 5 8 3 100 */
+95,	/* OBJ_mdc2                         2 5 8 3 101 */
+746,	/* OBJ_any_policy                   2 5 29 32 0 */
+519,	/* OBJ_setct_PANData                2 23 42 0 0 */
+520,	/* OBJ_setct_PANToken               2 23 42 0 1 */
+521,	/* OBJ_setct_PANOnly                2 23 42 0 2 */
+522,	/* OBJ_setct_OIData                 2 23 42 0 3 */
+523,	/* OBJ_setct_PI                     2 23 42 0 4 */
+524,	/* OBJ_setct_PIData                 2 23 42 0 5 */
+525,	/* OBJ_setct_PIDataUnsigned         2 23 42 0 6 */
+526,	/* OBJ_setct_HODInput               2 23 42 0 7 */
+527,	/* OBJ_setct_AuthResBaggage         2 23 42 0 8 */
+528,	/* OBJ_setct_AuthRevReqBaggage      2 23 42 0 9 */
+529,	/* OBJ_setct_AuthRevResBaggage      2 23 42 0 10 */
+530,	/* OBJ_setct_CapTokenSeq            2 23 42 0 11 */
+531,	/* OBJ_setct_PInitResData           2 23 42 0 12 */
+532,	/* OBJ_setct_PI_TBS                 2 23 42 0 13 */
+533,	/* OBJ_setct_PResData               2 23 42 0 14 */
+534,	/* OBJ_setct_AuthReqTBS             2 23 42 0 16 */
+535,	/* OBJ_setct_AuthResTBS             2 23 42 0 17 */
+536,	/* OBJ_setct_AuthResTBSX            2 23 42 0 18 */
+537,	/* OBJ_setct_AuthTokenTBS           2 23 42 0 19 */
+538,	/* OBJ_setct_CapTokenData           2 23 42 0 20 */
+539,	/* OBJ_setct_CapTokenTBS            2 23 42 0 21 */
+540,	/* OBJ_setct_AcqCardCodeMsg         2 23 42 0 22 */
+541,	/* OBJ_setct_AuthRevReqTBS          2 23 42 0 23 */
+542,	/* OBJ_setct_AuthRevResData         2 23 42 0 24 */
+543,	/* OBJ_setct_AuthRevResTBS          2 23 42 0 25 */
+544,	/* OBJ_setct_CapReqTBS              2 23 42 0 26 */
+545,	/* OBJ_setct_CapReqTBSX             2 23 42 0 27 */
+546,	/* OBJ_setct_CapResData             2 23 42 0 28 */
+547,	/* OBJ_setct_CapRevReqTBS           2 23 42 0 29 */
+548,	/* OBJ_setct_CapRevReqTBSX          2 23 42 0 30 */
+549,	/* OBJ_setct_CapRevResData          2 23 42 0 31 */
+550,	/* OBJ_setct_CredReqTBS             2 23 42 0 32 */
+551,	/* OBJ_setct_CredReqTBSX            2 23 42 0 33 */
+552,	/* OBJ_setct_CredResData            2 23 42 0 34 */
+553,	/* OBJ_setct_CredRevReqTBS          2 23 42 0 35 */
+554,	/* OBJ_setct_CredRevReqTBSX         2 23 42 0 36 */
+555,	/* OBJ_setct_CredRevResData         2 23 42 0 37 */
+556,	/* OBJ_setct_PCertReqData           2 23 42 0 38 */
+557,	/* OBJ_setct_PCertResTBS            2 23 42 0 39 */
+558,	/* OBJ_setct_BatchAdminReqData      2 23 42 0 40 */
+559,	/* OBJ_setct_BatchAdminResData      2 23 42 0 41 */
+560,	/* OBJ_setct_CardCInitResTBS        2 23 42 0 42 */
+561,	/* OBJ_setct_MeAqCInitResTBS        2 23 42 0 43 */
+562,	/* OBJ_setct_RegFormResTBS          2 23 42 0 44 */
+563,	/* OBJ_setct_CertReqData            2 23 42 0 45 */
+564,	/* OBJ_setct_CertReqTBS             2 23 42 0 46 */
+565,	/* OBJ_setct_CertResData            2 23 42 0 47 */
+566,	/* OBJ_setct_CertInqReqTBS          2 23 42 0 48 */
+567,	/* OBJ_setct_ErrorTBS               2 23 42 0 49 */
+568,	/* OBJ_setct_PIDualSignedTBE        2 23 42 0 50 */
+569,	/* OBJ_setct_PIUnsignedTBE          2 23 42 0 51 */
+570,	/* OBJ_setct_AuthReqTBE             2 23 42 0 52 */
+571,	/* OBJ_setct_AuthResTBE             2 23 42 0 53 */
+572,	/* OBJ_setct_AuthResTBEX            2 23 42 0 54 */
+573,	/* OBJ_setct_AuthTokenTBE           2 23 42 0 55 */
+574,	/* OBJ_setct_CapTokenTBE            2 23 42 0 56 */
+575,	/* OBJ_setct_CapTokenTBEX           2 23 42 0 57 */
+576,	/* OBJ_setct_AcqCardCodeMsgTBE      2 23 42 0 58 */
+577,	/* OBJ_setct_AuthRevReqTBE          2 23 42 0 59 */
+578,	/* OBJ_setct_AuthRevResTBE          2 23 42 0 60 */
+579,	/* OBJ_setct_AuthRevResTBEB         2 23 42 0 61 */
+580,	/* OBJ_setct_CapReqTBE              2 23 42 0 62 */
+581,	/* OBJ_setct_CapReqTBEX             2 23 42 0 63 */
+582,	/* OBJ_setct_CapResTBE              2 23 42 0 64 */
+583,	/* OBJ_setct_CapRevReqTBE           2 23 42 0 65 */
+584,	/* OBJ_setct_CapRevReqTBEX          2 23 42 0 66 */
+585,	/* OBJ_setct_CapRevResTBE           2 23 42 0 67 */
+586,	/* OBJ_setct_CredReqTBE             2 23 42 0 68 */
+587,	/* OBJ_setct_CredReqTBEX            2 23 42 0 69 */
+588,	/* OBJ_setct_CredResTBE             2 23 42 0 70 */
+589,	/* OBJ_setct_CredRevReqTBE          2 23 42 0 71 */
+590,	/* OBJ_setct_CredRevReqTBEX         2 23 42 0 72 */
+591,	/* OBJ_setct_CredRevResTBE          2 23 42 0 73 */
+592,	/* OBJ_setct_BatchAdminReqTBE       2 23 42 0 74 */
+593,	/* OBJ_setct_BatchAdminResTBE       2 23 42 0 75 */
+594,	/* OBJ_setct_RegFormReqTBE          2 23 42 0 76 */
+595,	/* OBJ_setct_CertReqTBE             2 23 42 0 77 */
+596,	/* OBJ_setct_CertReqTBEX            2 23 42 0 78 */
+597,	/* OBJ_setct_CertResTBE             2 23 42 0 79 */
+598,	/* OBJ_setct_CRLNotificationTBS     2 23 42 0 80 */
+599,	/* OBJ_setct_CRLNotificationResTBS  2 23 42 0 81 */
+600,	/* OBJ_setct_BCIDistributionTBS     2 23 42 0 82 */
+601,	/* OBJ_setext_genCrypt              2 23 42 1 1 */
+602,	/* OBJ_setext_miAuth                2 23 42 1 3 */
+603,	/* OBJ_setext_pinSecure             2 23 42 1 4 */
+604,	/* OBJ_setext_pinAny                2 23 42 1 5 */
+605,	/* OBJ_setext_track2                2 23 42 1 7 */
+606,	/* OBJ_setext_cv                    2 23 42 1 8 */
+620,	/* OBJ_setAttr_Cert                 2 23 42 3 0 */
+621,	/* OBJ_setAttr_PGWYcap              2 23 42 3 1 */
+622,	/* OBJ_setAttr_TokenType            2 23 42 3 2 */
+623,	/* OBJ_setAttr_IssCap               2 23 42 3 3 */
+607,	/* OBJ_set_policy_root              2 23 42 5 0 */
+608,	/* OBJ_setCext_hashedRoot           2 23 42 7 0 */
+609,	/* OBJ_setCext_certType             2 23 42 7 1 */
+610,	/* OBJ_setCext_merchData            2 23 42 7 2 */
+611,	/* OBJ_setCext_cCertRequired        2 23 42 7 3 */
+612,	/* OBJ_setCext_tunneling            2 23 42 7 4 */
+613,	/* OBJ_setCext_setExt               2 23 42 7 5 */
+614,	/* OBJ_setCext_setQualf             2 23 42 7 6 */
+615,	/* OBJ_setCext_PGWYcapabilities     2 23 42 7 7 */
+616,	/* OBJ_setCext_TokenIdentifier      2 23 42 7 8 */
+617,	/* OBJ_setCext_Track2Data           2 23 42 7 9 */
+618,	/* OBJ_setCext_TokenType            2 23 42 7 10 */
+619,	/* OBJ_setCext_IssuerCapabilities   2 23 42 7 11 */
+636,	/* OBJ_set_brand_IATA_ATA           2 23 42 8 1 */
+640,	/* OBJ_set_brand_Visa               2 23 42 8 4 */
+641,	/* OBJ_set_brand_MasterCard         2 23 42 8 5 */
+637,	/* OBJ_set_brand_Diners             2 23 42 8 30 */
+638,	/* OBJ_set_brand_AmericanExpress    2 23 42 8 34 */
+639,	/* OBJ_set_brand_JCB                2 23 42 8 35 */
+805,	/* OBJ_cryptopro                    1 2 643 2 2 */
+806,	/* OBJ_cryptocom                    1 2 643 2 9 */
+184,	/* OBJ_X9_57                        1 2 840 10040 */
+405,	/* OBJ_ansi_X9_62                   1 2 840 10045 */
+389,	/* OBJ_Enterprises                  1 3 6 1 4 1 */
+504,	/* OBJ_mime_mhs                     1 3 6 1 7 1 */
+104,	/* OBJ_md5WithRSA                   1 3 14 3 2 3 */
+29,	/* OBJ_des_ecb                      1 3 14 3 2 6 */
+31,	/* OBJ_des_cbc                      1 3 14 3 2 7 */
+45,	/* OBJ_des_ofb64                    1 3 14 3 2 8 */
+30,	/* OBJ_des_cfb64                    1 3 14 3 2 9 */
+377,	/* OBJ_rsaSignature                 1 3 14 3 2 11 */
+67,	/* OBJ_dsa_2                        1 3 14 3 2 12 */
+66,	/* OBJ_dsaWithSHA                   1 3 14 3 2 13 */
+42,	/* OBJ_shaWithRSAEncryption         1 3 14 3 2 15 */
+32,	/* OBJ_des_ede_ecb                  1 3 14 3 2 17 */
+41,	/* OBJ_sha                          1 3 14 3 2 18 */
+64,	/* OBJ_sha1                         1 3 14 3 2 26 */
+70,	/* OBJ_dsaWithSHA1_2                1 3 14 3 2 27 */
+115,	/* OBJ_sha1WithRSA                  1 3 14 3 2 29 */
+117,	/* OBJ_ripemd160                    1 3 36 3 2 1 */
+143,	/* OBJ_sxnet                        1 3 101 1 4 1 */
+721,	/* OBJ_sect163k1                    1 3 132 0 1 */
+722,	/* OBJ_sect163r1                    1 3 132 0 2 */
+728,	/* OBJ_sect239k1                    1 3 132 0 3 */
+717,	/* OBJ_sect113r1                    1 3 132 0 4 */
+718,	/* OBJ_sect113r2                    1 3 132 0 5 */
+704,	/* OBJ_secp112r1                    1 3 132 0 6 */
+705,	/* OBJ_secp112r2                    1 3 132 0 7 */
+709,	/* OBJ_secp160r1                    1 3 132 0 8 */
+708,	/* OBJ_secp160k1                    1 3 132 0 9 */
+714,	/* OBJ_secp256k1                    1 3 132 0 10 */
+723,	/* OBJ_sect163r2                    1 3 132 0 15 */
+729,	/* OBJ_sect283k1                    1 3 132 0 16 */
+730,	/* OBJ_sect283r1                    1 3 132 0 17 */
+719,	/* OBJ_sect131r1                    1 3 132 0 22 */
+720,	/* OBJ_sect131r2                    1 3 132 0 23 */
+724,	/* OBJ_sect193r1                    1 3 132 0 24 */
+725,	/* OBJ_sect193r2                    1 3 132 0 25 */
+726,	/* OBJ_sect233k1                    1 3 132 0 26 */
+727,	/* OBJ_sect233r1                    1 3 132 0 27 */
+706,	/* OBJ_secp128r1                    1 3 132 0 28 */
+707,	/* OBJ_secp128r2                    1 3 132 0 29 */
+710,	/* OBJ_secp160r2                    1 3 132 0 30 */
+711,	/* OBJ_secp192k1                    1 3 132 0 31 */
+712,	/* OBJ_secp224k1                    1 3 132 0 32 */
+713,	/* OBJ_secp224r1                    1 3 132 0 33 */
+715,	/* OBJ_secp384r1                    1 3 132 0 34 */
+716,	/* OBJ_secp521r1                    1 3 132 0 35 */
+731,	/* OBJ_sect409k1                    1 3 132 0 36 */
+732,	/* OBJ_sect409r1                    1 3 132 0 37 */
+733,	/* OBJ_sect571k1                    1 3 132 0 38 */
+734,	/* OBJ_sect571r1                    1 3 132 0 39 */
+624,	/* OBJ_set_rootKeyThumb             2 23 42 3 0 0 */
+625,	/* OBJ_set_addPolicy                2 23 42 3 0 1 */
+626,	/* OBJ_setAttr_Token_EMV            2 23 42 3 2 1 */
+627,	/* OBJ_setAttr_Token_B0Prime        2 23 42 3 2 2 */
+628,	/* OBJ_setAttr_IssCap_CVM           2 23 42 3 3 3 */
+629,	/* OBJ_setAttr_IssCap_T2            2 23 42 3 3 4 */
+630,	/* OBJ_setAttr_IssCap_Sig           2 23 42 3 3 5 */
+642,	/* OBJ_set_brand_Novus              2 23 42 8 6011 */
+735,	/* OBJ_wap_wsg_idm_ecid_wtls1       2 23 43 1 4 1 */
+736,	/* OBJ_wap_wsg_idm_ecid_wtls3       2 23 43 1 4 3 */
+737,	/* OBJ_wap_wsg_idm_ecid_wtls4       2 23 43 1 4 4 */
+738,	/* OBJ_wap_wsg_idm_ecid_wtls5       2 23 43 1 4 5 */
+739,	/* OBJ_wap_wsg_idm_ecid_wtls6       2 23 43 1 4 6 */
+740,	/* OBJ_wap_wsg_idm_ecid_wtls7       2 23 43 1 4 7 */
+741,	/* OBJ_wap_wsg_idm_ecid_wtls8       2 23 43 1 4 8 */
+742,	/* OBJ_wap_wsg_idm_ecid_wtls9       2 23 43 1 4 9 */
+743,	/* OBJ_wap_wsg_idm_ecid_wtls10      2 23 43 1 4 10 */
+744,	/* OBJ_wap_wsg_idm_ecid_wtls11      2 23 43 1 4 11 */
+745,	/* OBJ_wap_wsg_idm_ecid_wtls12      2 23 43 1 4 12 */
+804,	/* OBJ_whirlpool                    1 0 10118 3 0 55 */
+124,	/* OBJ_rle_compression              1 1 1 1 666 1 */
+773,	/* OBJ_kisa                         1 2 410 200004 */
+807,	/* OBJ_id_GostR3411_94_with_GostR3410_2001 1 2 643 2 2 3 */
+808,	/* OBJ_id_GostR3411_94_with_GostR3410_94 1 2 643 2 2 4 */
+809,	/* OBJ_id_GostR3411_94              1 2 643 2 2 9 */
+810,	/* OBJ_id_HMACGostR3411_94          1 2 643 2 2 10 */
+811,	/* OBJ_id_GostR3410_2001            1 2 643 2 2 19 */
+812,	/* OBJ_id_GostR3410_94              1 2 643 2 2 20 */
+813,	/* OBJ_id_Gost28147_89              1 2 643 2 2 21 */
+815,	/* OBJ_id_Gost28147_89_MAC          1 2 643 2 2 22 */
+816,	/* OBJ_id_GostR3411_94_prf          1 2 643 2 2 23 */
+817,	/* OBJ_id_GostR3410_2001DH          1 2 643 2 2 98 */
+818,	/* OBJ_id_GostR3410_94DH            1 2 643 2 2 99 */
+ 1,	/* OBJ_rsadsi                       1 2 840 113549 */
+185,	/* OBJ_X9cm                         1 2 840 10040 4 */
+127,	/* OBJ_id_pkix                      1 3 6 1 5 5 7 */
+505,	/* OBJ_mime_mhs_headings            1 3 6 1 7 1 1 */
+506,	/* OBJ_mime_mhs_bodies              1 3 6 1 7 1 2 */
+119,	/* OBJ_ripemd160WithRSA             1 3 36 3 3 1 2 */
+631,	/* OBJ_setAttr_GenCryptgrm          2 23 42 3 3 3 1 */
+632,	/* OBJ_setAttr_T2Enc                2 23 42 3 3 4 1 */
+633,	/* OBJ_setAttr_T2cleartxt           2 23 42 3 3 4 2 */
+634,	/* OBJ_setAttr_TokICCsig            2 23 42 3 3 5 1 */
+635,	/* OBJ_setAttr_SecDevSig            2 23 42 3 3 5 2 */
+436,	/* OBJ_ucl                          0 9 2342 19200300 */
+820,	/* OBJ_id_Gost28147_89_None_KeyMeshing 1 2 643 2 2 14 0 */
+819,	/* OBJ_id_Gost28147_89_CryptoPro_KeyMeshing 1 2 643 2 2 14 1 */
+845,	/* OBJ_id_GostR3410_94_a            1 2 643 2 2 20 1 */
+846,	/* OBJ_id_GostR3410_94_aBis         1 2 643 2 2 20 2 */
+847,	/* OBJ_id_GostR3410_94_b            1 2 643 2 2 20 3 */
+848,	/* OBJ_id_GostR3410_94_bBis         1 2 643 2 2 20 4 */
+821,	/* OBJ_id_GostR3411_94_TestParamSet 1 2 643 2 2 30 0 */
+822,	/* OBJ_id_GostR3411_94_CryptoProParamSet 1 2 643 2 2 30 1 */
+823,	/* OBJ_id_Gost28147_89_TestParamSet 1 2 643 2 2 31 0 */
+824,	/* OBJ_id_Gost28147_89_CryptoPro_A_ParamSet 1 2 643 2 2 31 1 */
+825,	/* OBJ_id_Gost28147_89_CryptoPro_B_ParamSet 1 2 643 2 2 31 2 */
+826,	/* OBJ_id_Gost28147_89_CryptoPro_C_ParamSet 1 2 643 2 2 31 3 */
+827,	/* OBJ_id_Gost28147_89_CryptoPro_D_ParamSet 1 2 643 2 2 31 4 */
+828,	/* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 1 2 643 2 2 31 5 */
+829,	/* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 1 2 643 2 2 31 6 */
+830,	/* OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 1 2 643 2 2 31 7 */
+831,	/* OBJ_id_GostR3410_94_TestParamSet 1 2 643 2 2 32 0 */
+832,	/* OBJ_id_GostR3410_94_CryptoPro_A_ParamSet 1 2 643 2 2 32 2 */
+833,	/* OBJ_id_GostR3410_94_CryptoPro_B_ParamSet 1 2 643 2 2 32 3 */
+834,	/* OBJ_id_GostR3410_94_CryptoPro_C_ParamSet 1 2 643 2 2 32 4 */
+835,	/* OBJ_id_GostR3410_94_CryptoPro_D_ParamSet 1 2 643 2 2 32 5 */
+836,	/* OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet 1 2 643 2 2 33 1 */
+837,	/* OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet 1 2 643 2 2 33 2 */
+838,	/* OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet 1 2 643 2 2 33 3 */
+839,	/* OBJ_id_GostR3410_2001_TestParamSet 1 2 643 2 2 35 0 */
+840,	/* OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet 1 2 643 2 2 35 1 */
+841,	/* OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet 1 2 643 2 2 35 2 */
+842,	/* OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet 1 2 643 2 2 35 3 */
+843,	/* OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet 1 2 643 2 2 36 0 */
+844,	/* OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet 1 2 643 2 2 36 1 */
+ 2,	/* OBJ_pkcs                         1 2 840 113549 1 */
+431,	/* OBJ_hold_instruction_none        1 2 840 10040 2 1 */
+432,	/* OBJ_hold_instruction_call_issuer 1 2 840 10040 2 2 */
+433,	/* OBJ_hold_instruction_reject      1 2 840 10040 2 3 */
+116,	/* OBJ_dsa                          1 2 840 10040 4 1 */
+113,	/* OBJ_dsaWithSHA1                  1 2 840 10040 4 3 */
+406,	/* OBJ_X9_62_prime_field            1 2 840 10045 1 1 */
+407,	/* OBJ_X9_62_characteristic_two_field 1 2 840 10045 1 2 */
+408,	/* OBJ_X9_62_id_ecPublicKey         1 2 840 10045 2 1 */
+416,	/* OBJ_ecdsa_with_SHA1              1 2 840 10045 4 1 */
+791,	/* OBJ_ecdsa_with_Recommended       1 2 840 10045 4 2 */
+792,	/* OBJ_ecdsa_with_Specified         1 2 840 10045 4 3 */
+258,	/* OBJ_id_pkix_mod                  1 3 6 1 5 5 7 0 */
+175,	/* OBJ_id_pe                        1 3 6 1 5 5 7 1 */
+259,	/* OBJ_id_qt                        1 3 6 1 5 5 7 2 */
+128,	/* OBJ_id_kp                        1 3 6 1 5 5 7 3 */
+260,	/* OBJ_id_it                        1 3 6 1 5 5 7 4 */
+261,	/* OBJ_id_pkip                      1 3 6 1 5 5 7 5 */
+262,	/* OBJ_id_alg                       1 3 6 1 5 5 7 6 */
+263,	/* OBJ_id_cmc                       1 3 6 1 5 5 7 7 */
+264,	/* OBJ_id_on                        1 3 6 1 5 5 7 8 */
+265,	/* OBJ_id_pda                       1 3 6 1 5 5 7 9 */
+266,	/* OBJ_id_aca                       1 3 6 1 5 5 7 10 */
+267,	/* OBJ_id_qcs                       1 3 6 1 5 5 7 11 */
+268,	/* OBJ_id_cct                       1 3 6 1 5 5 7 12 */
+662,	/* OBJ_id_ppl                       1 3 6 1 5 5 7 21 */
+176,	/* OBJ_id_ad                        1 3 6 1 5 5 7 48 */
+507,	/* OBJ_id_hex_partial_message       1 3 6 1 7 1 1 1 */
+508,	/* OBJ_id_hex_multipart_message     1 3 6 1 7 1 1 2 */
+57,	/* OBJ_netscape                     2 16 840 1 113730 */
+754,	/* OBJ_camellia_128_ecb             0 3 4401 5 3 1 9 1 */
+766,	/* OBJ_camellia_128_ofb128          0 3 4401 5 3 1 9 3 */
+757,	/* OBJ_camellia_128_cfb128          0 3 4401 5 3 1 9 4 */
+755,	/* OBJ_camellia_192_ecb             0 3 4401 5 3 1 9 21 */
+767,	/* OBJ_camellia_192_ofb128          0 3 4401 5 3 1 9 23 */
+758,	/* OBJ_camellia_192_cfb128          0 3 4401 5 3 1 9 24 */
+756,	/* OBJ_camellia_256_ecb             0 3 4401 5 3 1 9 41 */
+768,	/* OBJ_camellia_256_ofb128          0 3 4401 5 3 1 9 43 */
+759,	/* OBJ_camellia_256_cfb128          0 3 4401 5 3 1 9 44 */
+437,	/* OBJ_pilot                        0 9 2342 19200300 100 */
+776,	/* OBJ_seed_ecb                     1 2 410 200004 1 3 */
+777,	/* OBJ_seed_cbc                     1 2 410 200004 1 4 */
+779,	/* OBJ_seed_cfb128                  1 2 410 200004 1 5 */
+778,	/* OBJ_seed_ofb128                  1 2 410 200004 1 6 */
+852,	/* OBJ_id_GostR3411_94_with_GostR3410_94_cc 1 2 643 2 9 1 3 3 */
+853,	/* OBJ_id_GostR3411_94_with_GostR3410_2001_cc 1 2 643 2 9 1 3 4 */
+850,	/* OBJ_id_GostR3410_94_cc           1 2 643 2 9 1 5 3 */
+851,	/* OBJ_id_GostR3410_2001_cc         1 2 643 2 9 1 5 4 */
+849,	/* OBJ_id_Gost28147_89_cc           1 2 643 2 9 1 6 1 */
+854,	/* OBJ_id_GostR3410_2001_ParamSet_cc 1 2 643 2 9 1 8 1 */
+186,	/* OBJ_pkcs1                        1 2 840 113549 1 1 */
+27,	/* OBJ_pkcs3                        1 2 840 113549 1 3 */
+187,	/* OBJ_pkcs5                        1 2 840 113549 1 5 */
+20,	/* OBJ_pkcs7                        1 2 840 113549 1 7 */
+47,	/* OBJ_pkcs9                        1 2 840 113549 1 9 */
+ 3,	/* OBJ_md2                          1 2 840 113549 2 2 */
+257,	/* OBJ_md4                          1 2 840 113549 2 4 */
+ 4,	/* OBJ_md5                          1 2 840 113549 2 5 */
+797,	/* OBJ_hmacWithMD5                  1 2 840 113549 2 6 */
+163,	/* OBJ_hmacWithSHA1                 1 2 840 113549 2 7 */
+798,	/* OBJ_hmacWithSHA224               1 2 840 113549 2 8 */
+799,	/* OBJ_hmacWithSHA256               1 2 840 113549 2 9 */
+800,	/* OBJ_hmacWithSHA384               1 2 840 113549 2 10 */
+801,	/* OBJ_hmacWithSHA512               1 2 840 113549 2 11 */
+37,	/* OBJ_rc2_cbc                      1 2 840 113549 3 2 */
+ 5,	/* OBJ_rc4                          1 2 840 113549 3 4 */
+44,	/* OBJ_des_ede3_cbc                 1 2 840 113549 3 7 */
+120,	/* OBJ_rc5_cbc                      1 2 840 113549 3 8 */
+643,	/* OBJ_des_cdmf                     1 2 840 113549 3 10 */
+680,	/* OBJ_X9_62_id_characteristic_two_basis 1 2 840 10045 1 2 3 */
+684,	/* OBJ_X9_62_c2pnb163v1             1 2 840 10045 3 0 1 */
+685,	/* OBJ_X9_62_c2pnb163v2             1 2 840 10045 3 0 2 */
+686,	/* OBJ_X9_62_c2pnb163v3             1 2 840 10045 3 0 3 */
+687,	/* OBJ_X9_62_c2pnb176v1             1 2 840 10045 3 0 4 */
+688,	/* OBJ_X9_62_c2tnb191v1             1 2 840 10045 3 0 5 */
+689,	/* OBJ_X9_62_c2tnb191v2             1 2 840 10045 3 0 6 */
+690,	/* OBJ_X9_62_c2tnb191v3             1 2 840 10045 3 0 7 */
+691,	/* OBJ_X9_62_c2onb191v4             1 2 840 10045 3 0 8 */
+692,	/* OBJ_X9_62_c2onb191v5             1 2 840 10045 3 0 9 */
+693,	/* OBJ_X9_62_c2pnb208w1             1 2 840 10045 3 0 10 */
+694,	/* OBJ_X9_62_c2tnb239v1             1 2 840 10045 3 0 11 */
+695,	/* OBJ_X9_62_c2tnb239v2             1 2 840 10045 3 0 12 */
+696,	/* OBJ_X9_62_c2tnb239v3             1 2 840 10045 3 0 13 */
+697,	/* OBJ_X9_62_c2onb239v4             1 2 840 10045 3 0 14 */
+698,	/* OBJ_X9_62_c2onb239v5             1 2 840 10045 3 0 15 */
+699,	/* OBJ_X9_62_c2pnb272w1             1 2 840 10045 3 0 16 */
+700,	/* OBJ_X9_62_c2pnb304w1             1 2 840 10045 3 0 17 */
+701,	/* OBJ_X9_62_c2tnb359v1             1 2 840 10045 3 0 18 */
+702,	/* OBJ_X9_62_c2pnb368w1             1 2 840 10045 3 0 19 */
+703,	/* OBJ_X9_62_c2tnb431r1             1 2 840 10045 3 0 20 */
+409,	/* OBJ_X9_62_prime192v1             1 2 840 10045 3 1 1 */
+410,	/* OBJ_X9_62_prime192v2             1 2 840 10045 3 1 2 */
+411,	/* OBJ_X9_62_prime192v3             1 2 840 10045 3 1 3 */
+412,	/* OBJ_X9_62_prime239v1             1 2 840 10045 3 1 4 */
+413,	/* OBJ_X9_62_prime239v2             1 2 840 10045 3 1 5 */
+414,	/* OBJ_X9_62_prime239v3             1 2 840 10045 3 1 6 */
+415,	/* OBJ_X9_62_prime256v1             1 2 840 10045 3 1 7 */
+793,	/* OBJ_ecdsa_with_SHA224            1 2 840 10045 4 3 1 */
+794,	/* OBJ_ecdsa_with_SHA256            1 2 840 10045 4 3 2 */
+795,	/* OBJ_ecdsa_with_SHA384            1 2 840 10045 4 3 3 */
+796,	/* OBJ_ecdsa_with_SHA512            1 2 840 10045 4 3 4 */
+269,	/* OBJ_id_pkix1_explicit_88         1 3 6 1 5 5 7 0 1 */
+270,	/* OBJ_id_pkix1_implicit_88         1 3 6 1 5 5 7 0 2 */
+271,	/* OBJ_id_pkix1_explicit_93         1 3 6 1 5 5 7 0 3 */
+272,	/* OBJ_id_pkix1_implicit_93         1 3 6 1 5 5 7 0 4 */
+273,	/* OBJ_id_mod_crmf                  1 3 6 1 5 5 7 0 5 */
+274,	/* OBJ_id_mod_cmc                   1 3 6 1 5 5 7 0 6 */
+275,	/* OBJ_id_mod_kea_profile_88        1 3 6 1 5 5 7 0 7 */
+276,	/* OBJ_id_mod_kea_profile_93        1 3 6 1 5 5 7 0 8 */
+277,	/* OBJ_id_mod_cmp                   1 3 6 1 5 5 7 0 9 */
+278,	/* OBJ_id_mod_qualified_cert_88     1 3 6 1 5 5 7 0 10 */
+279,	/* OBJ_id_mod_qualified_cert_93     1 3 6 1 5 5 7 0 11 */
+280,	/* OBJ_id_mod_attribute_cert        1 3 6 1 5 5 7 0 12 */
+281,	/* OBJ_id_mod_timestamp_protocol    1 3 6 1 5 5 7 0 13 */
+282,	/* OBJ_id_mod_ocsp                  1 3 6 1 5 5 7 0 14 */
+283,	/* OBJ_id_mod_dvcs                  1 3 6 1 5 5 7 0 15 */
+284,	/* OBJ_id_mod_cmp2000               1 3 6 1 5 5 7 0 16 */
+177,	/* OBJ_info_access                  1 3 6 1 5 5 7 1 1 */
+285,	/* OBJ_biometricInfo                1 3 6 1 5 5 7 1 2 */
+286,	/* OBJ_qcStatements                 1 3 6 1 5 5 7 1 3 */
+287,	/* OBJ_ac_auditEntity               1 3 6 1 5 5 7 1 4 */
+288,	/* OBJ_ac_targeting                 1 3 6 1 5 5 7 1 5 */
+289,	/* OBJ_aaControls                   1 3 6 1 5 5 7 1 6 */
+290,	/* OBJ_sbgp_ipAddrBlock             1 3 6 1 5 5 7 1 7 */
+291,	/* OBJ_sbgp_autonomousSysNum        1 3 6 1 5 5 7 1 8 */
+292,	/* OBJ_sbgp_routerIdentifier        1 3 6 1 5 5 7 1 9 */
+397,	/* OBJ_ac_proxying                  1 3 6 1 5 5 7 1 10 */
+398,	/* OBJ_sinfo_access                 1 3 6 1 5 5 7 1 11 */
+663,	/* OBJ_proxyCertInfo                1 3 6 1 5 5 7 1 14 */
+164,	/* OBJ_id_qt_cps                    1 3 6 1 5 5 7 2 1 */
+165,	/* OBJ_id_qt_unotice                1 3 6 1 5 5 7 2 2 */
+293,	/* OBJ_textNotice                   1 3 6 1 5 5 7 2 3 */
+129,	/* OBJ_server_auth                  1 3 6 1 5 5 7 3 1 */
+130,	/* OBJ_client_auth                  1 3 6 1 5 5 7 3 2 */
+131,	/* OBJ_code_sign                    1 3 6 1 5 5 7 3 3 */
+132,	/* OBJ_email_protect                1 3 6 1 5 5 7 3 4 */
+294,	/* OBJ_ipsecEndSystem               1 3 6 1 5 5 7 3 5 */
+295,	/* OBJ_ipsecTunnel                  1 3 6 1 5 5 7 3 6 */
+296,	/* OBJ_ipsecUser                    1 3 6 1 5 5 7 3 7 */
+133,	/* OBJ_time_stamp                   1 3 6 1 5 5 7 3 8 */
+180,	/* OBJ_OCSP_sign                    1 3 6 1 5 5 7 3 9 */
+297,	/* OBJ_dvcs                         1 3 6 1 5 5 7 3 10 */
+298,	/* OBJ_id_it_caProtEncCert          1 3 6 1 5 5 7 4 1 */
+299,	/* OBJ_id_it_signKeyPairTypes       1 3 6 1 5 5 7 4 2 */
+300,	/* OBJ_id_it_encKeyPairTypes        1 3 6 1 5 5 7 4 3 */
+301,	/* OBJ_id_it_preferredSymmAlg       1 3 6 1 5 5 7 4 4 */
+302,	/* OBJ_id_it_caKeyUpdateInfo        1 3 6 1 5 5 7 4 5 */
+303,	/* OBJ_id_it_currentCRL             1 3 6 1 5 5 7 4 6 */
+304,	/* OBJ_id_it_unsupportedOIDs        1 3 6 1 5 5 7 4 7 */
+305,	/* OBJ_id_it_subscriptionRequest    1 3 6 1 5 5 7 4 8 */
+306,	/* OBJ_id_it_subscriptionResponse   1 3 6 1 5 5 7 4 9 */
+307,	/* OBJ_id_it_keyPairParamReq        1 3 6 1 5 5 7 4 10 */
+308,	/* OBJ_id_it_keyPairParamRep        1 3 6 1 5 5 7 4 11 */
+309,	/* OBJ_id_it_revPassphrase          1 3 6 1 5 5 7 4 12 */
+310,	/* OBJ_id_it_implicitConfirm        1 3 6 1 5 5 7 4 13 */
+311,	/* OBJ_id_it_confirmWaitTime        1 3 6 1 5 5 7 4 14 */
+312,	/* OBJ_id_it_origPKIMessage         1 3 6 1 5 5 7 4 15 */
+784,	/* OBJ_id_it_suppLangTags           1 3 6 1 5 5 7 4 16 */
+313,	/* OBJ_id_regCtrl                   1 3 6 1 5 5 7 5 1 */
+314,	/* OBJ_id_regInfo                   1 3 6 1 5 5 7 5 2 */
+323,	/* OBJ_id_alg_des40                 1 3 6 1 5 5 7 6 1 */
+324,	/* OBJ_id_alg_noSignature           1 3 6 1 5 5 7 6 2 */
+325,	/* OBJ_id_alg_dh_sig_hmac_sha1      1 3 6 1 5 5 7 6 3 */
+326,	/* OBJ_id_alg_dh_pop                1 3 6 1 5 5 7 6 4 */
+327,	/* OBJ_id_cmc_statusInfo            1 3 6 1 5 5 7 7 1 */
+328,	/* OBJ_id_cmc_identification        1 3 6 1 5 5 7 7 2 */
+329,	/* OBJ_id_cmc_identityProof         1 3 6 1 5 5 7 7 3 */
+330,	/* OBJ_id_cmc_dataReturn            1 3 6 1 5 5 7 7 4 */
+331,	/* OBJ_id_cmc_transactionId         1 3 6 1 5 5 7 7 5 */
+332,	/* OBJ_id_cmc_senderNonce           1 3 6 1 5 5 7 7 6 */
+333,	/* OBJ_id_cmc_recipientNonce        1 3 6 1 5 5 7 7 7 */
+334,	/* OBJ_id_cmc_addExtensions         1 3 6 1 5 5 7 7 8 */
+335,	/* OBJ_id_cmc_encryptedPOP          1 3 6 1 5 5 7 7 9 */
+336,	/* OBJ_id_cmc_decryptedPOP          1 3 6 1 5 5 7 7 10 */
+337,	/* OBJ_id_cmc_lraPOPWitness         1 3 6 1 5 5 7 7 11 */
+338,	/* OBJ_id_cmc_getCert               1 3 6 1 5 5 7 7 15 */
+339,	/* OBJ_id_cmc_getCRL                1 3 6 1 5 5 7 7 16 */
+340,	/* OBJ_id_cmc_revokeRequest         1 3 6 1 5 5 7 7 17 */
+341,	/* OBJ_id_cmc_regInfo               1 3 6 1 5 5 7 7 18 */
+342,	/* OBJ_id_cmc_responseInfo          1 3 6 1 5 5 7 7 19 */
+343,	/* OBJ_id_cmc_queryPending          1 3 6 1 5 5 7 7 21 */
+344,	/* OBJ_id_cmc_popLinkRandom         1 3 6 1 5 5 7 7 22 */
+345,	/* OBJ_id_cmc_popLinkWitness        1 3 6 1 5 5 7 7 23 */
+346,	/* OBJ_id_cmc_confirmCertAcceptance 1 3 6 1 5 5 7 7 24 */
+347,	/* OBJ_id_on_personalData           1 3 6 1 5 5 7 8 1 */
+858,	/* OBJ_id_on_permanentIdentifier    1 3 6 1 5 5 7 8 3 */
+348,	/* OBJ_id_pda_dateOfBirth           1 3 6 1 5 5 7 9 1 */
+349,	/* OBJ_id_pda_placeOfBirth          1 3 6 1 5 5 7 9 2 */
+351,	/* OBJ_id_pda_gender                1 3 6 1 5 5 7 9 3 */
+352,	/* OBJ_id_pda_countryOfCitizenship  1 3 6 1 5 5 7 9 4 */
+353,	/* OBJ_id_pda_countryOfResidence    1 3 6 1 5 5 7 9 5 */
+354,	/* OBJ_id_aca_authenticationInfo    1 3 6 1 5 5 7 10 1 */
+355,	/* OBJ_id_aca_accessIdentity        1 3 6 1 5 5 7 10 2 */
+356,	/* OBJ_id_aca_chargingIdentity      1 3 6 1 5 5 7 10 3 */
+357,	/* OBJ_id_aca_group                 1 3 6 1 5 5 7 10 4 */
+358,	/* OBJ_id_aca_role                  1 3 6 1 5 5 7 10 5 */
+399,	/* OBJ_id_aca_encAttrs              1 3 6 1 5 5 7 10 6 */
+359,	/* OBJ_id_qcs_pkixQCSyntax_v1       1 3 6 1 5 5 7 11 1 */
+360,	/* OBJ_id_cct_crs                   1 3 6 1 5 5 7 12 1 */
+361,	/* OBJ_id_cct_PKIData               1 3 6 1 5 5 7 12 2 */
+362,	/* OBJ_id_cct_PKIResponse           1 3 6 1 5 5 7 12 3 */
+664,	/* OBJ_id_ppl_anyLanguage           1 3 6 1 5 5 7 21 0 */
+665,	/* OBJ_id_ppl_inheritAll            1 3 6 1 5 5 7 21 1 */
+667,	/* OBJ_Independent                  1 3 6 1 5 5 7 21 2 */
+178,	/* OBJ_ad_OCSP                      1 3 6 1 5 5 7 48 1 */
+179,	/* OBJ_ad_ca_issuers                1 3 6 1 5 5 7 48 2 */
+363,	/* OBJ_ad_timeStamping              1 3 6 1 5 5 7 48 3 */
+364,	/* OBJ_ad_dvcs                      1 3 6 1 5 5 7 48 4 */
+785,	/* OBJ_caRepository                 1 3 6 1 5 5 7 48 5 */
+780,	/* OBJ_hmac_md5                     1 3 6 1 5 5 8 1 1 */
+781,	/* OBJ_hmac_sha1                    1 3 6 1 5 5 8 1 2 */
+58,	/* OBJ_netscape_cert_extension      2 16 840 1 113730 1 */
+59,	/* OBJ_netscape_data_type           2 16 840 1 113730 2 */
+438,	/* OBJ_pilotAttributeType           0 9 2342 19200300 100 1 */
+439,	/* OBJ_pilotAttributeSyntax         0 9 2342 19200300 100 3 */
+440,	/* OBJ_pilotObjectClass             0 9 2342 19200300 100 4 */
+441,	/* OBJ_pilotGroups                  0 9 2342 19200300 100 10 */
+108,	/* OBJ_cast5_cbc                    1 2 840 113533 7 66 10 */
+112,	/* OBJ_pbeWithMD5AndCast5_CBC       1 2 840 113533 7 66 12 */
+782,	/* OBJ_id_PasswordBasedMAC          1 2 840 113533 7 66 13 */
+783,	/* OBJ_id_DHBasedMac                1 2 840 113533 7 66 30 */
+ 6,	/* OBJ_rsaEncryption                1 2 840 113549 1 1 1 */
+ 7,	/* OBJ_md2WithRSAEncryption         1 2 840 113549 1 1 2 */
+396,	/* OBJ_md4WithRSAEncryption         1 2 840 113549 1 1 3 */
+ 8,	/* OBJ_md5WithRSAEncryption         1 2 840 113549 1 1 4 */
+65,	/* OBJ_sha1WithRSAEncryption        1 2 840 113549 1 1 5 */
+644,	/* OBJ_rsaOAEPEncryptionSET         1 2 840 113549 1 1 6 */
+668,	/* OBJ_sha256WithRSAEncryption      1 2 840 113549 1 1 11 */
+669,	/* OBJ_sha384WithRSAEncryption      1 2 840 113549 1 1 12 */
+670,	/* OBJ_sha512WithRSAEncryption      1 2 840 113549 1 1 13 */
+671,	/* OBJ_sha224WithRSAEncryption      1 2 840 113549 1 1 14 */
+28,	/* OBJ_dhKeyAgreement               1 2 840 113549 1 3 1 */
+ 9,	/* OBJ_pbeWithMD2AndDES_CBC         1 2 840 113549 1 5 1 */
+10,	/* OBJ_pbeWithMD5AndDES_CBC         1 2 840 113549 1 5 3 */
+168,	/* OBJ_pbeWithMD2AndRC2_CBC         1 2 840 113549 1 5 4 */
+169,	/* OBJ_pbeWithMD5AndRC2_CBC         1 2 840 113549 1 5 6 */
+170,	/* OBJ_pbeWithSHA1AndDES_CBC        1 2 840 113549 1 5 10 */
+68,	/* OBJ_pbeWithSHA1AndRC2_CBC        1 2 840 113549 1 5 11 */
+69,	/* OBJ_id_pbkdf2                    1 2 840 113549 1 5 12 */
+161,	/* OBJ_pbes2                        1 2 840 113549 1 5 13 */
+162,	/* OBJ_pbmac1                       1 2 840 113549 1 5 14 */
+21,	/* OBJ_pkcs7_data                   1 2 840 113549 1 7 1 */
+22,	/* OBJ_pkcs7_signed                 1 2 840 113549 1 7 2 */
+23,	/* OBJ_pkcs7_enveloped              1 2 840 113549 1 7 3 */
+24,	/* OBJ_pkcs7_signedAndEnveloped     1 2 840 113549 1 7 4 */
+25,	/* OBJ_pkcs7_digest                 1 2 840 113549 1 7 5 */
+26,	/* OBJ_pkcs7_encrypted              1 2 840 113549 1 7 6 */
+48,	/* OBJ_pkcs9_emailAddress           1 2 840 113549 1 9 1 */
+49,	/* OBJ_pkcs9_unstructuredName       1 2 840 113549 1 9 2 */
+50,	/* OBJ_pkcs9_contentType            1 2 840 113549 1 9 3 */
+51,	/* OBJ_pkcs9_messageDigest          1 2 840 113549 1 9 4 */
+52,	/* OBJ_pkcs9_signingTime            1 2 840 113549 1 9 5 */
+53,	/* OBJ_pkcs9_countersignature       1 2 840 113549 1 9 6 */
+54,	/* OBJ_pkcs9_challengePassword      1 2 840 113549 1 9 7 */
+55,	/* OBJ_pkcs9_unstructuredAddress    1 2 840 113549 1 9 8 */
+56,	/* OBJ_pkcs9_extCertAttributes      1 2 840 113549 1 9 9 */
+172,	/* OBJ_ext_req                      1 2 840 113549 1 9 14 */
+167,	/* OBJ_SMIMECapabilities            1 2 840 113549 1 9 15 */
+188,	/* OBJ_SMIME                        1 2 840 113549 1 9 16 */
+156,	/* OBJ_friendlyName                 1 2 840 113549 1 9 20 */
+157,	/* OBJ_localKeyID                   1 2 840 113549 1 9 21 */
+681,	/* OBJ_X9_62_onBasis                1 2 840 10045 1 2 3 1 */
+682,	/* OBJ_X9_62_tpBasis                1 2 840 10045 1 2 3 2 */
+683,	/* OBJ_X9_62_ppBasis                1 2 840 10045 1 2 3 3 */
+417,	/* OBJ_ms_csp_name                  1 3 6 1 4 1 311 17 1 */
+856,	/* OBJ_LocalKeySet                  1 3 6 1 4 1 311 17 2 */
+390,	/* OBJ_dcObject                     1 3 6 1 4 1 1466 344 */
+91,	/* OBJ_bf_cbc                       1 3 6 1 4 1 3029 1 2 */
+315,	/* OBJ_id_regCtrl_regToken          1 3 6 1 5 5 7 5 1 1 */
+316,	/* OBJ_id_regCtrl_authenticator     1 3 6 1 5 5 7 5 1 2 */
+317,	/* OBJ_id_regCtrl_pkiPublicationInfo 1 3 6 1 5 5 7 5 1 3 */
+318,	/* OBJ_id_regCtrl_pkiArchiveOptions 1 3 6 1 5 5 7 5 1 4 */
+319,	/* OBJ_id_regCtrl_oldCertID         1 3 6 1 5 5 7 5 1 5 */
+320,	/* OBJ_id_regCtrl_protocolEncrKey   1 3 6 1 5 5 7 5 1 6 */
+321,	/* OBJ_id_regInfo_utf8Pairs         1 3 6 1 5 5 7 5 2 1 */
+322,	/* OBJ_id_regInfo_certReq           1 3 6 1 5 5 7 5 2 2 */
+365,	/* OBJ_id_pkix_OCSP_basic           1 3 6 1 5 5 7 48 1 1 */
+366,	/* OBJ_id_pkix_OCSP_Nonce           1 3 6 1 5 5 7 48 1 2 */
+367,	/* OBJ_id_pkix_OCSP_CrlID           1 3 6 1 5 5 7 48 1 3 */
+368,	/* OBJ_id_pkix_OCSP_acceptableResponses 1 3 6 1 5 5 7 48 1 4 */
+369,	/* OBJ_id_pkix_OCSP_noCheck         1 3 6 1 5 5 7 48 1 5 */
+370,	/* OBJ_id_pkix_OCSP_archiveCutoff   1 3 6 1 5 5 7 48 1 6 */
+371,	/* OBJ_id_pkix_OCSP_serviceLocator  1 3 6 1 5 5 7 48 1 7 */
+372,	/* OBJ_id_pkix_OCSP_extendedStatus  1 3 6 1 5 5 7 48 1 8 */
+373,	/* OBJ_id_pkix_OCSP_valid           1 3 6 1 5 5 7 48 1 9 */
+374,	/* OBJ_id_pkix_OCSP_path            1 3 6 1 5 5 7 48 1 10 */
+375,	/* OBJ_id_pkix_OCSP_trustRoot       1 3 6 1 5 5 7 48 1 11 */
+418,	/* OBJ_aes_128_ecb                  2 16 840 1 101 3 4 1 1 */
+419,	/* OBJ_aes_128_cbc                  2 16 840 1 101 3 4 1 2 */
+420,	/* OBJ_aes_128_ofb128               2 16 840 1 101 3 4 1 3 */
+421,	/* OBJ_aes_128_cfb128               2 16 840 1 101 3 4 1 4 */
+788,	/* OBJ_id_aes128_wrap               2 16 840 1 101 3 4 1 5 */
+422,	/* OBJ_aes_192_ecb                  2 16 840 1 101 3 4 1 21 */
+423,	/* OBJ_aes_192_cbc                  2 16 840 1 101 3 4 1 22 */
+424,	/* OBJ_aes_192_ofb128               2 16 840 1 101 3 4 1 23 */
+425,	/* OBJ_aes_192_cfb128               2 16 840 1 101 3 4 1 24 */
+789,	/* OBJ_id_aes192_wrap               2 16 840 1 101 3 4 1 25 */
+426,	/* OBJ_aes_256_ecb                  2 16 840 1 101 3 4 1 41 */
+427,	/* OBJ_aes_256_cbc                  2 16 840 1 101 3 4 1 42 */
+428,	/* OBJ_aes_256_ofb128               2 16 840 1 101 3 4 1 43 */
+429,	/* OBJ_aes_256_cfb128               2 16 840 1 101 3 4 1 44 */
+790,	/* OBJ_id_aes256_wrap               2 16 840 1 101 3 4 1 45 */
+672,	/* OBJ_sha256                       2 16 840 1 101 3 4 2 1 */
+673,	/* OBJ_sha384                       2 16 840 1 101 3 4 2 2 */
+674,	/* OBJ_sha512                       2 16 840 1 101 3 4 2 3 */
+675,	/* OBJ_sha224                       2 16 840 1 101 3 4 2 4 */
+802,	/* OBJ_dsa_with_SHA224              2 16 840 1 101 3 4 3 1 */
+803,	/* OBJ_dsa_with_SHA256              2 16 840 1 101 3 4 3 2 */
+71,	/* OBJ_netscape_cert_type           2 16 840 1 113730 1 1 */
+72,	/* OBJ_netscape_base_url            2 16 840 1 113730 1 2 */
+73,	/* OBJ_netscape_revocation_url      2 16 840 1 113730 1 3 */
+74,	/* OBJ_netscape_ca_revocation_url   2 16 840 1 113730 1 4 */
+75,	/* OBJ_netscape_renewal_url         2 16 840 1 113730 1 7 */
+76,	/* OBJ_netscape_ca_policy_url       2 16 840 1 113730 1 8 */
+77,	/* OBJ_netscape_ssl_server_name     2 16 840 1 113730 1 12 */
+78,	/* OBJ_netscape_comment             2 16 840 1 113730 1 13 */
+79,	/* OBJ_netscape_cert_sequence       2 16 840 1 113730 2 5 */
+139,	/* OBJ_ns_sgc                       2 16 840 1 113730 4 1 */
+458,	/* OBJ_userId                       0 9 2342 19200300 100 1 1 */
+459,	/* OBJ_textEncodedORAddress         0 9 2342 19200300 100 1 2 */
+460,	/* OBJ_rfc822Mailbox                0 9 2342 19200300 100 1 3 */
+461,	/* OBJ_info                         0 9 2342 19200300 100 1 4 */
+462,	/* OBJ_favouriteDrink               0 9 2342 19200300 100 1 5 */
+463,	/* OBJ_roomNumber                   0 9 2342 19200300 100 1 6 */
+464,	/* OBJ_photo                        0 9 2342 19200300 100 1 7 */
+465,	/* OBJ_userClass                    0 9 2342 19200300 100 1 8 */
+466,	/* OBJ_host                         0 9 2342 19200300 100 1 9 */
+467,	/* OBJ_manager                      0 9 2342 19200300 100 1 10 */
+468,	/* OBJ_documentIdentifier           0 9 2342 19200300 100 1 11 */
+469,	/* OBJ_documentTitle                0 9 2342 19200300 100 1 12 */
+470,	/* OBJ_documentVersion              0 9 2342 19200300 100 1 13 */
+471,	/* OBJ_documentAuthor               0 9 2342 19200300 100 1 14 */
+472,	/* OBJ_documentLocation             0 9 2342 19200300 100 1 15 */
+473,	/* OBJ_homeTelephoneNumber          0 9 2342 19200300 100 1 20 */
+474,	/* OBJ_secretary                    0 9 2342 19200300 100 1 21 */
+475,	/* OBJ_otherMailbox                 0 9 2342 19200300 100 1 22 */
+476,	/* OBJ_lastModifiedTime             0 9 2342 19200300 100 1 23 */
+477,	/* OBJ_lastModifiedBy               0 9 2342 19200300 100 1 24 */
+391,	/* OBJ_domainComponent              0 9 2342 19200300 100 1 25 */
+478,	/* OBJ_aRecord                      0 9 2342 19200300 100 1 26 */
+479,	/* OBJ_pilotAttributeType27         0 9 2342 19200300 100 1 27 */
+480,	/* OBJ_mXRecord                     0 9 2342 19200300 100 1 28 */
+481,	/* OBJ_nSRecord                     0 9 2342 19200300 100 1 29 */
+482,	/* OBJ_sOARecord                    0 9 2342 19200300 100 1 30 */
+483,	/* OBJ_cNAMERecord                  0 9 2342 19200300 100 1 31 */
+484,	/* OBJ_associatedDomain             0 9 2342 19200300 100 1 37 */
+485,	/* OBJ_associatedName               0 9 2342 19200300 100 1 38 */
+486,	/* OBJ_homePostalAddress            0 9 2342 19200300 100 1 39 */
+487,	/* OBJ_personalTitle                0 9 2342 19200300 100 1 40 */
+488,	/* OBJ_mobileTelephoneNumber        0 9 2342 19200300 100 1 41 */
+489,	/* OBJ_pagerTelephoneNumber         0 9 2342 19200300 100 1 42 */
+490,	/* OBJ_friendlyCountryName          0 9 2342 19200300 100 1 43 */
+491,	/* OBJ_organizationalStatus         0 9 2342 19200300 100 1 45 */
+492,	/* OBJ_janetMailbox                 0 9 2342 19200300 100 1 46 */
+493,	/* OBJ_mailPreferenceOption         0 9 2342 19200300 100 1 47 */
+494,	/* OBJ_buildingName                 0 9 2342 19200300 100 1 48 */
+495,	/* OBJ_dSAQuality                   0 9 2342 19200300 100 1 49 */
+496,	/* OBJ_singleLevelQuality           0 9 2342 19200300 100 1 50 */
+497,	/* OBJ_subtreeMinimumQuality        0 9 2342 19200300 100 1 51 */
+498,	/* OBJ_subtreeMaximumQuality        0 9 2342 19200300 100 1 52 */
+499,	/* OBJ_personalSignature            0 9 2342 19200300 100 1 53 */
+500,	/* OBJ_dITRedirect                  0 9 2342 19200300 100 1 54 */
+501,	/* OBJ_audio                        0 9 2342 19200300 100 1 55 */
+502,	/* OBJ_documentPublisher            0 9 2342 19200300 100 1 56 */
+442,	/* OBJ_iA5StringSyntax              0 9 2342 19200300 100 3 4 */
+443,	/* OBJ_caseIgnoreIA5StringSyntax    0 9 2342 19200300 100 3 5 */
+444,	/* OBJ_pilotObject                  0 9 2342 19200300 100 4 3 */
+445,	/* OBJ_pilotPerson                  0 9 2342 19200300 100 4 4 */
+446,	/* OBJ_account                      0 9 2342 19200300 100 4 5 */
+447,	/* OBJ_document                     0 9 2342 19200300 100 4 6 */
+448,	/* OBJ_room                         0 9 2342 19200300 100 4 7 */
+449,	/* OBJ_documentSeries               0 9 2342 19200300 100 4 9 */
+392,	/* OBJ_Domain                       0 9 2342 19200300 100 4 13 */
+450,	/* OBJ_rFC822localPart              0 9 2342 19200300 100 4 14 */
+451,	/* OBJ_dNSDomain                    0 9 2342 19200300 100 4 15 */
+452,	/* OBJ_domainRelatedObject          0 9 2342 19200300 100 4 17 */
+453,	/* OBJ_friendlyCountry              0 9 2342 19200300 100 4 18 */
+454,	/* OBJ_simpleSecurityObject         0 9 2342 19200300 100 4 19 */
+455,	/* OBJ_pilotOrganization            0 9 2342 19200300 100 4 20 */
+456,	/* OBJ_pilotDSA                     0 9 2342 19200300 100 4 21 */
+457,	/* OBJ_qualityLabelledData          0 9 2342 19200300 100 4 22 */
+189,	/* OBJ_id_smime_mod                 1 2 840 113549 1 9 16 0 */
+190,	/* OBJ_id_smime_ct                  1 2 840 113549 1 9 16 1 */
+191,	/* OBJ_id_smime_aa                  1 2 840 113549 1 9 16 2 */
+192,	/* OBJ_id_smime_alg                 1 2 840 113549 1 9 16 3 */
+193,	/* OBJ_id_smime_cd                  1 2 840 113549 1 9 16 4 */
+194,	/* OBJ_id_smime_spq                 1 2 840 113549 1 9 16 5 */
+195,	/* OBJ_id_smime_cti                 1 2 840 113549 1 9 16 6 */
+158,	/* OBJ_x509Certificate              1 2 840 113549 1 9 22 1 */
+159,	/* OBJ_sdsiCertificate              1 2 840 113549 1 9 22 2 */
+160,	/* OBJ_x509Crl                      1 2 840 113549 1 9 23 1 */
+144,	/* OBJ_pbe_WithSHA1And128BitRC4     1 2 840 113549 1 12 1 1 */
+145,	/* OBJ_pbe_WithSHA1And40BitRC4      1 2 840 113549 1 12 1 2 */
+146,	/* OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC 1 2 840 113549 1 12 1 3 */
+147,	/* OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC 1 2 840 113549 1 12 1 4 */
+148,	/* OBJ_pbe_WithSHA1And128BitRC2_CBC 1 2 840 113549 1 12 1 5 */
+149,	/* OBJ_pbe_WithSHA1And40BitRC2_CBC  1 2 840 113549 1 12 1 6 */
+171,	/* OBJ_ms_ext_req                   1 3 6 1 4 1 311 2 1 14 */
+134,	/* OBJ_ms_code_ind                  1 3 6 1 4 1 311 2 1 21 */
+135,	/* OBJ_ms_code_com                  1 3 6 1 4 1 311 2 1 22 */
+136,	/* OBJ_ms_ctl_sign                  1 3 6 1 4 1 311 10 3 1 */
+137,	/* OBJ_ms_sgc                       1 3 6 1 4 1 311 10 3 3 */
+138,	/* OBJ_ms_efs                       1 3 6 1 4 1 311 10 3 4 */
+648,	/* OBJ_ms_smartcard_login           1 3 6 1 4 1 311 20 2 2 */
+649,	/* OBJ_ms_upn                       1 3 6 1 4 1 311 20 2 3 */
+751,	/* OBJ_camellia_128_cbc             1 2 392 200011 61 1 1 1 2 */
+752,	/* OBJ_camellia_192_cbc             1 2 392 200011 61 1 1 1 3 */
+753,	/* OBJ_camellia_256_cbc             1 2 392 200011 61 1 1 1 4 */
+196,	/* OBJ_id_smime_mod_cms             1 2 840 113549 1 9 16 0 1 */
+197,	/* OBJ_id_smime_mod_ess             1 2 840 113549 1 9 16 0 2 */
+198,	/* OBJ_id_smime_mod_oid             1 2 840 113549 1 9 16 0 3 */
+199,	/* OBJ_id_smime_mod_msg_v3          1 2 840 113549 1 9 16 0 4 */
+200,	/* OBJ_id_smime_mod_ets_eSignature_88 1 2 840 113549 1 9 16 0 5 */
+201,	/* OBJ_id_smime_mod_ets_eSignature_97 1 2 840 113549 1 9 16 0 6 */
+202,	/* OBJ_id_smime_mod_ets_eSigPolicy_88 1 2 840 113549 1 9 16 0 7 */
+203,	/* OBJ_id_smime_mod_ets_eSigPolicy_97 1 2 840 113549 1 9 16 0 8 */
+204,	/* OBJ_id_smime_ct_receipt          1 2 840 113549 1 9 16 1 1 */
+205,	/* OBJ_id_smime_ct_authData         1 2 840 113549 1 9 16 1 2 */
+206,	/* OBJ_id_smime_ct_publishCert      1 2 840 113549 1 9 16 1 3 */
+207,	/* OBJ_id_smime_ct_TSTInfo          1 2 840 113549 1 9 16 1 4 */
+208,	/* OBJ_id_smime_ct_TDTInfo          1 2 840 113549 1 9 16 1 5 */
+209,	/* OBJ_id_smime_ct_contentInfo      1 2 840 113549 1 9 16 1 6 */
+210,	/* OBJ_id_smime_ct_DVCSRequestData  1 2 840 113549 1 9 16 1 7 */
+211,	/* OBJ_id_smime_ct_DVCSResponseData 1 2 840 113549 1 9 16 1 8 */
+786,	/* OBJ_id_smime_ct_compressedData   1 2 840 113549 1 9 16 1 9 */
+787,	/* OBJ_id_ct_asciiTextWithCRLF      1 2 840 113549 1 9 16 1 27 */
+212,	/* OBJ_id_smime_aa_receiptRequest   1 2 840 113549 1 9 16 2 1 */
+213,	/* OBJ_id_smime_aa_securityLabel    1 2 840 113549 1 9 16 2 2 */
+214,	/* OBJ_id_smime_aa_mlExpandHistory  1 2 840 113549 1 9 16 2 3 */
+215,	/* OBJ_id_smime_aa_contentHint      1 2 840 113549 1 9 16 2 4 */
+216,	/* OBJ_id_smime_aa_msgSigDigest     1 2 840 113549 1 9 16 2 5 */
+217,	/* OBJ_id_smime_aa_encapContentType 1 2 840 113549 1 9 16 2 6 */
+218,	/* OBJ_id_smime_aa_contentIdentifier 1 2 840 113549 1 9 16 2 7 */
+219,	/* OBJ_id_smime_aa_macValue         1 2 840 113549 1 9 16 2 8 */
+220,	/* OBJ_id_smime_aa_equivalentLabels 1 2 840 113549 1 9 16 2 9 */
+221,	/* OBJ_id_smime_aa_contentReference 1 2 840 113549 1 9 16 2 10 */
+222,	/* OBJ_id_smime_aa_encrypKeyPref    1 2 840 113549 1 9 16 2 11 */
+223,	/* OBJ_id_smime_aa_signingCertificate 1 2 840 113549 1 9 16 2 12 */
+224,	/* OBJ_id_smime_aa_smimeEncryptCerts 1 2 840 113549 1 9 16 2 13 */
+225,	/* OBJ_id_smime_aa_timeStampToken   1 2 840 113549 1 9 16 2 14 */
+226,	/* OBJ_id_smime_aa_ets_sigPolicyId  1 2 840 113549 1 9 16 2 15 */
+227,	/* OBJ_id_smime_aa_ets_commitmentType 1 2 840 113549 1 9 16 2 16 */
+228,	/* OBJ_id_smime_aa_ets_signerLocation 1 2 840 113549 1 9 16 2 17 */
+229,	/* OBJ_id_smime_aa_ets_signerAttr   1 2 840 113549 1 9 16 2 18 */
+230,	/* OBJ_id_smime_aa_ets_otherSigCert 1 2 840 113549 1 9 16 2 19 */
+231,	/* OBJ_id_smime_aa_ets_contentTimestamp 1 2 840 113549 1 9 16 2 20 */
+232,	/* OBJ_id_smime_aa_ets_CertificateRefs 1 2 840 113549 1 9 16 2 21 */
+233,	/* OBJ_id_smime_aa_ets_RevocationRefs 1 2 840 113549 1 9 16 2 22 */
+234,	/* OBJ_id_smime_aa_ets_certValues   1 2 840 113549 1 9 16 2 23 */
+235,	/* OBJ_id_smime_aa_ets_revocationValues 1 2 840 113549 1 9 16 2 24 */
+236,	/* OBJ_id_smime_aa_ets_escTimeStamp 1 2 840 113549 1 9 16 2 25 */
+237,	/* OBJ_id_smime_aa_ets_certCRLTimestamp 1 2 840 113549 1 9 16 2 26 */
+238,	/* OBJ_id_smime_aa_ets_archiveTimeStamp 1 2 840 113549 1 9 16 2 27 */
+239,	/* OBJ_id_smime_aa_signatureType    1 2 840 113549 1 9 16 2 28 */
+240,	/* OBJ_id_smime_aa_dvcs_dvc         1 2 840 113549 1 9 16 2 29 */
+241,	/* OBJ_id_smime_alg_ESDHwith3DES    1 2 840 113549 1 9 16 3 1 */
+242,	/* OBJ_id_smime_alg_ESDHwithRC2     1 2 840 113549 1 9 16 3 2 */
+243,	/* OBJ_id_smime_alg_3DESwrap        1 2 840 113549 1 9 16 3 3 */
+244,	/* OBJ_id_smime_alg_RC2wrap         1 2 840 113549 1 9 16 3 4 */
+245,	/* OBJ_id_smime_alg_ESDH            1 2 840 113549 1 9 16 3 5 */
+246,	/* OBJ_id_smime_alg_CMS3DESwrap     1 2 840 113549 1 9 16 3 6 */
+247,	/* OBJ_id_smime_alg_CMSRC2wrap      1 2 840 113549 1 9 16 3 7 */
+125,	/* OBJ_zlib_compression             1 2 840 113549 1 9 16 3 8 */
+248,	/* OBJ_id_smime_cd_ldap             1 2 840 113549 1 9 16 4 1 */
+249,	/* OBJ_id_smime_spq_ets_sqt_uri     1 2 840 113549 1 9 16 5 1 */
+250,	/* OBJ_id_smime_spq_ets_sqt_unotice 1 2 840 113549 1 9 16 5 2 */
+251,	/* OBJ_id_smime_cti_ets_proofOfOrigin 1 2 840 113549 1 9 16 6 1 */
+252,	/* OBJ_id_smime_cti_ets_proofOfReceipt 1 2 840 113549 1 9 16 6 2 */
+253,	/* OBJ_id_smime_cti_ets_proofOfDelivery 1 2 840 113549 1 9 16 6 3 */
+254,	/* OBJ_id_smime_cti_ets_proofOfSender 1 2 840 113549 1 9 16 6 4 */
+255,	/* OBJ_id_smime_cti_ets_proofOfApproval 1 2 840 113549 1 9 16 6 5 */
+256,	/* OBJ_id_smime_cti_ets_proofOfCreation 1 2 840 113549 1 9 16 6 6 */
+150,	/* OBJ_keyBag                       1 2 840 113549 1 12 10 1 1 */
+151,	/* OBJ_pkcs8ShroudedKeyBag          1 2 840 113549 1 12 10 1 2 */
+152,	/* OBJ_certBag                      1 2 840 113549 1 12 10 1 3 */
+153,	/* OBJ_crlBag                       1 2 840 113549 1 12 10 1 4 */
+154,	/* OBJ_secretBag                    1 2 840 113549 1 12 10 1 5 */
+155,	/* OBJ_safeContentsBag              1 2 840 113549 1 12 10 1 6 */
+34,	/* OBJ_idea_cbc                     1 3 6 1 4 1 188 7 1 1 2 */
 };
 
diff --git a/crypto/objects/obj_dat.pl b/crypto/objects/obj_dat.pl
index 7de2f77..c67f71c 100644
--- a/crypto/objects/obj_dat.pl
+++ b/crypto/objects/obj_dat.pl
@@ -2,9 +2,7 @@
 
 # fixes bug in floating point emulation on sparc64 when
 # this script produces off-by-one output on sparc64
-eval 'use integer;';
-
-print STDERR "Warning: perl module integer not found.\n" if ($@);
+use integer;
 
 sub obj_cmp
 	{
@@ -150,13 +148,13 @@
 @a=grep(defined($sn{$nid{$_}}),0 .. $n);
 foreach (sort { $sn{$nid{$a}} cmp $sn{$nid{$b}} } @a)
 	{
-	push(@sn,sprintf("&(nid_objs[%2d]),/* \"$sn{$nid{$_}}\" */\n",$_));
+	push(@sn,sprintf("%2d,\t/* \"$sn{$nid{$_}}\" */\n",$_));
 	}
 
 @a=grep(defined($ln{$nid{$_}}),0 .. $n);
 foreach (sort { $ln{$nid{$a}} cmp $ln{$nid{$b}} } @a)
 	{
-	push(@ln,sprintf("&(nid_objs[%2d]),/* \"$ln{$nid{$_}}\" */\n",$_));
+	push(@ln,sprintf("%2d,\t/* \"$ln{$nid{$_}}\" */\n",$_));
 	}
 
 @a=grep(defined($obj{$nid{$_}}),0 .. $n);
@@ -166,7 +164,7 @@
 	$v=$objd{$m};
 	$v =~ s/L//g;
 	$v =~ s/,/ /g;
-	push(@ob,sprintf("&(nid_objs[%2d]),/* %-32s %s */\n",$_,$m,$v));
+	push(@ob,sprintf("%2d,\t/* %-32s %s */\n",$_,$m,$v));
 	}
 
 print OUT <<'EOF';
@@ -241,11 +239,11 @@
 printf OUT "#define NUM_LN %d\n",$#ln+1;
 printf OUT "#define NUM_OBJ %d\n\n",$#ob+1;
 
-printf OUT "static unsigned char lvalues[%d]={\n",$lvalues+1;
+printf OUT "static const unsigned char lvalues[%d]={\n",$lvalues+1;
 print OUT @lvalues;
 print OUT "};\n\n";
 
-printf OUT "static ASN1_OBJECT nid_objs[NUM_NID]={\n";
+printf OUT "static const ASN1_OBJECT nid_objs[NUM_NID]={\n";
 foreach (@out)
 	{
 	if (length($_) > 75)
@@ -269,15 +267,15 @@
 	}
 print  OUT "};\n\n";
 
-printf OUT "static ASN1_OBJECT *sn_objs[NUM_SN]={\n";
+printf OUT "static const unsigned int sn_objs[NUM_SN]={\n";
 print  OUT @sn;
 print  OUT "};\n\n";
 
-printf OUT "static ASN1_OBJECT *ln_objs[NUM_LN]={\n";
+printf OUT "static const unsigned int ln_objs[NUM_LN]={\n";
 print  OUT @ln;
 print  OUT "};\n\n";
 
-printf OUT "static ASN1_OBJECT *obj_objs[NUM_OBJ]={\n";
+printf OUT "static const unsigned int obj_objs[NUM_OBJ]={\n";
 print  OUT @ob;
 print  OUT "};\n\n";
 
diff --git a/crypto/objects/obj_err.c b/crypto/objects/obj_err.c
index 12b4885..2e7a034 100644
--- a/crypto/objects/obj_err.c
+++ b/crypto/objects/obj_err.c
@@ -1,6 +1,6 @@
 /* crypto/objects/obj_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
diff --git a/crypto/objects/obj_lib.c b/crypto/objects/obj_lib.c
index 706fa0b..23e9d48 100644
--- a/crypto/objects/obj_lib.c
+++ b/crypto/objects/obj_lib.c
@@ -66,7 +66,8 @@
 	{
 	ASN1_OBJECT *r;
 	int i;
-	char *ln=NULL;
+	char *ln=NULL,*sn=NULL;
+	unsigned char *data=NULL;
 
 	if (o == NULL) return(NULL);
 	if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC))
@@ -79,42 +80,42 @@
 		OBJerr(OBJ_F_OBJ_DUP,ERR_R_ASN1_LIB);
 		return(NULL);
 		}
-	r->data=OPENSSL_malloc(o->length);
-	if (r->data == NULL)
+	data=OPENSSL_malloc(o->length);
+	if (data == NULL)
 		goto err;
 	if (o->data != NULL)
-		memcpy(r->data,o->data,o->length);
+		memcpy(data,o->data,o->length);
+	/* once data attached to object it remains const */
+	r->data = data;
 	r->length=o->length;
 	r->nid=o->nid;
 	r->ln=r->sn=NULL;
 	if (o->ln != NULL)
 		{
 		i=strlen(o->ln)+1;
-		r->ln=ln=OPENSSL_malloc(i);
-		if (r->ln == NULL) goto err;
+		ln=OPENSSL_malloc(i);
+		if (ln == NULL) goto err;
 		memcpy(ln,o->ln,i);
+		r->ln=ln;
 		}
 
 	if (o->sn != NULL)
 		{
-		char *s;
-
 		i=strlen(o->sn)+1;
-		r->sn=s=OPENSSL_malloc(i);
-		if (r->sn == NULL) goto err;
-		memcpy(s,o->sn,i);
+		sn=OPENSSL_malloc(i);
+		if (sn == NULL) goto err;
+		memcpy(sn,o->sn,i);
+		r->sn=sn;
 		}
 	r->flags=o->flags|(ASN1_OBJECT_FLAG_DYNAMIC|
 		ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|ASN1_OBJECT_FLAG_DYNAMIC_DATA);
 	return(r);
 err:
 	OBJerr(OBJ_F_OBJ_DUP,ERR_R_MALLOC_FAILURE);
-	if (r != NULL)
-		{
-		if (ln != NULL) OPENSSL_free(ln);
-		if (r->data != NULL) OPENSSL_free(r->data);
-		OPENSSL_free(r);
-		}
+	if (ln != NULL)		OPENSSL_free(ln);
+	if (sn != NULL)		OPENSSL_free(sn);
+	if (data != NULL)	OPENSSL_free(data);
+	if (r != NULL)		OPENSSL_free(r);
 	return(NULL);
 	}
 
diff --git a/crypto/objects/obj_xref.c b/crypto/objects/obj_xref.c
new file mode 100644
index 0000000..152eca5
--- /dev/null
+++ b/crypto/objects/obj_xref.c
@@ -0,0 +1,231 @@
+/* crypto/objects/obj_xref.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/objects.h>
+#include "obj_xref.h"
+
+DECLARE_STACK_OF(nid_triple)
+STACK_OF(nid_triple) *sig_app, *sigx_app;
+
+static int sig_cmp(const nid_triple *a, const nid_triple *b)
+	{
+	return a->sign_id - b->sign_id;
+	}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig);
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig);
+
+static int sig_sk_cmp(const nid_triple * const *a, const nid_triple * const *b)
+	{
+	return (*a)->sign_id - (*b)->sign_id;
+	}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx);
+
+static int sigx_cmp(const nid_triple * const *a, const nid_triple * const *b)
+	{
+	int ret;
+	ret = (*a)->hash_id - (*b)->hash_id;
+	if (ret)
+		return ret;
+	return (*a)->pkey_id - (*b)->pkey_id;
+	}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx);
+
+int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid)
+	{
+	nid_triple tmp;
+	const nid_triple *rv = NULL;
+	tmp.sign_id = signid;
+
+	if (sig_app)
+		{
+		int idx = sk_nid_triple_find(sig_app, &tmp);
+		if (idx >= 0)
+			rv = sk_nid_triple_value(sig_app, idx);
+		}
+
+#ifndef OBJ_XREF_TEST2
+	if (rv == NULL)
+		{
+		rv = OBJ_bsearch_sig(&tmp, sigoid_srt,
+				 sizeof(sigoid_srt) / sizeof(nid_triple));
+		}
+#endif
+	if (rv == NULL)
+		return 0;
+	*pdig_nid = rv->hash_id;
+	*ppkey_nid = rv->pkey_id;
+	return 1;
+	}
+
+int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid)
+	{
+	nid_triple tmp;
+	const nid_triple *t=&tmp;
+	const nid_triple **rv = NULL;
+
+	tmp.hash_id = dig_nid;
+	tmp.pkey_id = pkey_nid;
+
+	if (sigx_app)
+		{
+		int idx = sk_nid_triple_find(sigx_app, &tmp);
+		if (idx >= 0)
+			{
+			t = sk_nid_triple_value(sigx_app, idx);
+			rv = &t;
+			}
+		}
+
+#ifndef OBJ_XREF_TEST2
+	if (rv == NULL)
+		{
+		rv = OBJ_bsearch_sigx(&t, sigoid_srt_xref,
+				 sizeof(sigoid_srt_xref) / sizeof(nid_triple *)
+				 );
+		}
+#endif
+	if (rv == NULL)
+		return 0;
+	*psignid = (*rv)->sign_id;
+	return 1;
+	}
+
+int OBJ_add_sigid(int signid, int dig_id, int pkey_id)
+	{
+	nid_triple *ntr;
+	if (!sig_app)
+		sig_app = sk_nid_triple_new(sig_sk_cmp);
+	if (!sig_app)
+		return 0;
+	if (!sigx_app)
+		sigx_app = sk_nid_triple_new(sigx_cmp);
+	if (!sigx_app)
+		return 0;
+	ntr = OPENSSL_malloc(sizeof(int) * 3);
+	if (!ntr)
+		return 0;
+	ntr->sign_id = signid;
+	ntr->hash_id = dig_id;
+	ntr->pkey_id = pkey_id;
+
+	if (!sk_nid_triple_push(sig_app, ntr))
+		{
+		OPENSSL_free(ntr);
+		return 0;
+		}
+
+	if (!sk_nid_triple_push(sigx_app, ntr))
+		return 0;
+
+	sk_nid_triple_sort(sig_app);
+	sk_nid_triple_sort(sigx_app);
+
+	return 1;
+	}
+
+static void sid_free(nid_triple *tt)
+	{
+	OPENSSL_free(tt);
+	}
+
+void OBJ_sigid_free(void)
+	{
+	if (sig_app)
+		{
+		sk_nid_triple_pop_free(sig_app, sid_free);
+		sig_app = NULL;
+		}
+	if (sigx_app)
+		{
+		sk_nid_triple_free(sigx_app);
+		sigx_app = NULL;
+		}
+	}
+		
+#ifdef OBJ_XREF_TEST
+
+main()
+	{
+	int n1, n2, n3;
+
+	int i, rv;
+#ifdef OBJ_XREF_TEST2
+	for (i = 0; i <	sizeof(sigoid_srt) / sizeof(nid_triple); i++)
+		{
+		OBJ_add_sigid(sigoid_srt[i][0], sigoid_srt[i][1],
+				sigoid_srt[i][2]);
+		}
+#endif
+
+	for (i = 0; i <	sizeof(sigoid_srt) / sizeof(nid_triple); i++)
+		{
+		n1 = sigoid_srt[i][0];
+		rv = OBJ_find_sigid_algs(n1, &n2, &n3);
+		printf("Forward: %d, %s %s %s\n", rv,
+			OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3));
+		n1=0;
+		rv = OBJ_find_sigid_by_algs(&n1, n2, n3);
+		printf("Reverse: %d, %s %s %s\n", rv,
+			OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3));
+		}
+	}
+	
+#endif
diff --git a/crypto/objects/obj_xref.h b/crypto/objects/obj_xref.h
new file mode 100644
index 0000000..d5b9b8e
--- /dev/null
+++ b/crypto/objects/obj_xref.h
@@ -0,0 +1,75 @@
+/* AUTOGENERATED BY objxref.pl, DO NOT EDIT */
+
+typedef struct
+	{
+	int sign_id;
+	int hash_id;
+	int pkey_id;
+	} nid_triple;
+
+static const nid_triple sigoid_srt[] =
+	{
+	{NID_md2WithRSAEncryption, NID_md2, NID_rsaEncryption},
+	{NID_md5WithRSAEncryption, NID_md5, NID_rsaEncryption},
+	{NID_shaWithRSAEncryption, NID_sha, NID_rsaEncryption},
+	{NID_sha1WithRSAEncryption, NID_sha1, NID_rsaEncryption},
+	{NID_dsaWithSHA, NID_sha, NID_dsa},
+	{NID_dsaWithSHA1_2, NID_sha1, NID_dsa_2},
+	{NID_mdc2WithRSA, NID_mdc2, NID_rsaEncryption},
+	{NID_md5WithRSA, NID_md5, NID_rsa},
+	{NID_dsaWithSHA1, NID_sha1, NID_dsa},
+	{NID_sha1WithRSA, NID_sha1, NID_rsa},
+	{NID_ripemd160WithRSA, NID_ripemd160, NID_rsaEncryption},
+	{NID_md4WithRSAEncryption, NID_md4, NID_rsaEncryption},
+	{NID_ecdsa_with_SHA1, NID_sha1, NID_X9_62_id_ecPublicKey},
+	{NID_sha256WithRSAEncryption, NID_sha256, NID_rsaEncryption},
+	{NID_sha384WithRSAEncryption, NID_sha384, NID_rsaEncryption},
+	{NID_sha512WithRSAEncryption, NID_sha512, NID_rsaEncryption},
+	{NID_sha224WithRSAEncryption, NID_sha224, NID_rsaEncryption},
+	{NID_ecdsa_with_Recommended, NID_undef, NID_X9_62_id_ecPublicKey},
+	{NID_ecdsa_with_Specified, NID_undef, NID_X9_62_id_ecPublicKey},
+	{NID_ecdsa_with_SHA224, NID_sha224, NID_X9_62_id_ecPublicKey},
+	{NID_ecdsa_with_SHA256, NID_sha256, NID_X9_62_id_ecPublicKey},
+	{NID_ecdsa_with_SHA384, NID_sha384, NID_X9_62_id_ecPublicKey},
+	{NID_ecdsa_with_SHA512, NID_sha512, NID_X9_62_id_ecPublicKey},
+	{NID_dsa_with_SHA224, NID_sha224, NID_dsa},
+	{NID_dsa_with_SHA256, NID_sha256, NID_dsa},
+	{NID_id_GostR3411_94_with_GostR3410_2001, NID_id_GostR3411_94, NID_id_GostR3410_2001},
+	{NID_id_GostR3411_94_with_GostR3410_94, NID_id_GostR3411_94, NID_id_GostR3410_94},
+	{NID_id_GostR3411_94_with_GostR3410_94_cc, NID_id_GostR3411_94, NID_id_GostR3410_94_cc},
+	{NID_id_GostR3411_94_with_GostR3410_2001_cc, NID_id_GostR3411_94, NID_id_GostR3410_2001_cc},
+	};
+
+static const nid_triple * const sigoid_srt_xref[] =
+	{
+	&sigoid_srt[17],
+	&sigoid_srt[18],
+	&sigoid_srt[0],
+	&sigoid_srt[1],
+	&sigoid_srt[7],
+	&sigoid_srt[2],
+	&sigoid_srt[4],
+	&sigoid_srt[3],
+	&sigoid_srt[9],
+	&sigoid_srt[5],
+	&sigoid_srt[8],
+	&sigoid_srt[12],
+	&sigoid_srt[6],
+	&sigoid_srt[10],
+	&sigoid_srt[11],
+	&sigoid_srt[13],
+	&sigoid_srt[24],
+	&sigoid_srt[20],
+	&sigoid_srt[14],
+	&sigoid_srt[21],
+	&sigoid_srt[15],
+	&sigoid_srt[22],
+	&sigoid_srt[16],
+	&sigoid_srt[23],
+	&sigoid_srt[19],
+	&sigoid_srt[25],
+	&sigoid_srt[26],
+	&sigoid_srt[27],
+	&sigoid_srt[28],
+	};
+
diff --git a/crypto/objects/obj_xref.txt b/crypto/objects/obj_xref.txt
new file mode 100644
index 0000000..e45b3d3
--- /dev/null
+++ b/crypto/objects/obj_xref.txt
@@ -0,0 +1,42 @@
+# OID cross reference table.
+# Links signatures OIDs to their corresponding public key algorithms
+# and digests.
+
+md2WithRSAEncryption	md2	rsaEncryption
+md5WithRSAEncryption	md5	rsaEncryption
+shaWithRSAEncryption	sha	rsaEncryption
+sha1WithRSAEncryption	sha1	rsaEncryption
+md4WithRSAEncryption	md4	rsaEncryption
+sha256WithRSAEncryption sha256	rsaEncryption
+sha384WithRSAEncryption	sha384	rsaEncryption
+sha512WithRSAEncryption	sha512	rsaEncryption
+sha224WithRSAEncryption	sha224	rsaEncryption
+mdc2WithRSA		mdc2	rsaEncryption
+ripemd160WithRSA	ripemd160 rsaEncryption
+
+# Alternative deprecated OIDs. By using the older "rsa" OID this
+# type will be recognized by not normally used.
+
+md5WithRSA		md5	rsa
+sha1WithRSA		sha1	rsa
+
+dsaWithSHA		sha	dsa
+dsaWithSHA1		sha1	dsa
+
+dsaWithSHA1_2		sha1	dsa_2
+
+ecdsa_with_SHA1		sha1	X9_62_id_ecPublicKey
+ecdsa_with_SHA224	sha224	X9_62_id_ecPublicKey
+ecdsa_with_SHA256	sha256	X9_62_id_ecPublicKey
+ecdsa_with_SHA384	sha384	X9_62_id_ecPublicKey
+ecdsa_with_SHA512	sha512	X9_62_id_ecPublicKey
+ecdsa_with_Recommended	undef	X9_62_id_ecPublicKey
+ecdsa_with_Specified	undef	X9_62_id_ecPublicKey
+
+dsa_with_SHA224		sha224	dsa
+dsa_with_SHA256		sha256	dsa
+
+id_GostR3411_94_with_GostR3410_2001	id_GostR3411_94 id_GostR3410_2001
+id_GostR3411_94_with_GostR3410_94	id_GostR3411_94 id_GostR3410_94
+id_GostR3411_94_with_GostR3410_94_cc	id_GostR3411_94 id_GostR3410_94_cc
+id_GostR3411_94_with_GostR3410_2001_cc	id_GostR3411_94 id_GostR3410_2001_cc
diff --git a/crypto/objects/objects.h b/crypto/objects/objects.h
index 7242f76..bd0ee52 100644
--- a/crypto/objects/objects.h
+++ b/crypto/objects/objects.h
@@ -1011,10 +1011,91 @@
 int		OBJ_ln2nid(const char *s);
 int		OBJ_sn2nid(const char *s);
 int		OBJ_cmp(const ASN1_OBJECT *a,const ASN1_OBJECT *b);
-const char *	OBJ_bsearch(const char *key,const char *base,int num,int size,
-	int (*cmp)(const void *, const void *));
-const char *	OBJ_bsearch_ex(const char *key,const char *base,int num,
-	int size, int (*cmp)(const void *, const void *), int flags);
+const void *	OBJ_bsearch_(const void *key,const void *base,int num,int size,
+			     int (*cmp)(const void *, const void *));
+const void *	OBJ_bsearch_ex_(const void *key,const void *base,int num,
+				int size,
+				int (*cmp)(const void *, const void *),
+				int flags);
+
+#define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm)	\
+  static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \
+  static int nm##_cmp(type1 const *, type2 const *); \
+  scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num)
+
+#define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp)	\
+  _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp)
+#define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm)	\
+  type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num)
+
+/*
+ * Unsolved problem: if a type is actually a pointer type, like
+ * nid_triple is, then its impossible to get a const where you need
+ * it. Consider:
+ *
+ * typedef int nid_triple[3];
+ * const void *a_;
+ * const nid_triple const *a = a_;
+ *
+ * The assignement discards a const because what you really want is:
+ *
+ * const int const * const *a = a_;
+ *
+ * But if you do that, you lose the fact that a is an array of 3 ints,
+ * which breaks comparison functions.
+ *
+ * Thus we end up having to cast, sadly, or unpack the
+ * declarations. Or, as I finally did in this case, delcare nid_triple
+ * to be a struct, which it should have been in the first place.
+ *
+ * Ben, August 2008.
+ *
+ * Also, strictly speaking not all types need be const, but handling
+ * the non-constness means a lot of complication, and in practice
+ * comparison routines do always not touch their arguments.
+ */
+
+#define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm)	\
+  static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)	\
+      { \
+      type1 const *a = a_; \
+      type2 const *b = b_; \
+      return nm##_cmp(a,b); \
+      } \
+  static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \
+      { \
+      return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \
+					nm##_cmp_BSEARCH_CMP_FN); \
+      } \
+      extern void dummy_prototype(void)
+
+#define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm)	\
+  static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)	\
+      { \
+      type1 const *a = a_; \
+      type2 const *b = b_; \
+      return nm##_cmp(a,b); \
+      } \
+  type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \
+      { \
+      return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \
+					nm##_cmp_BSEARCH_CMP_FN); \
+      } \
+      extern void dummy_prototype(void)
+
+#define OBJ_bsearch(type1,key,type2,base,num,cmp)			       \
+  ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \
+			 num,sizeof(type2),				\
+			 ((void)CHECKED_PTR_OF(type1,cmp##_type_1),	\
+			  (void)CHECKED_PTR_OF(type2,cmp##_type_2),	\
+			  cmp##_BSEARCH_CMP_FN)))
+
+#define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags)			\
+  ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \
+			 num,sizeof(type2),				\
+			 ((void)CHECKED_PTR_OF(type1,cmp##_type_1),	\
+			  (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \
+			  cmp##_BSEARCH_CMP_FN)),flags)
 
 int		OBJ_new_nid(int num);
 int		OBJ_add_object(const ASN1_OBJECT *obj);
@@ -1022,6 +1103,14 @@
 void		OBJ_cleanup(void );
 int		OBJ_create_objects(BIO *in);
 
+int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid);
+int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid);
+int OBJ_add_sigid(int signid, int dig_id, int pkey_id);
+void OBJ_sigid_free(void);
+
+extern int obj_cleanup_defer;
+void check_defer(int nid);
+
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
  * made after this point may be overwritten when the script is next run.
diff --git a/crypto/objects/objects.pl b/crypto/objects/objects.pl
index 76c06cc..15c00bb 100644
--- a/crypto/objects/objects.pl
+++ b/crypto/objects/objects.pl
@@ -14,6 +14,8 @@
 	$Cname =~ s/^X//;
 	if (defined($nidn{$mynum}))
 		{ die "$ARGV[1]:$o:There's already an object with NID ",$mynum," on line ",$order{$mynum},"\n"; }
+	if (defined($nid{$Cname}))
+		{ die "$ARGV[1]:$o:There's already an object with name ",$Cname," on line ",$order{$nid{$Cname}},"\n"; }
 	$nid{$Cname} = $mynum;
 	$nidn{$mynum} = $Cname;
 	$order{$mynum} = $o;
@@ -102,6 +104,7 @@
 		$max_nid++;
 		$nid{$Cname} = $max_nid;
 		$nidn{$max_nid} = $Cname;
+print STDERR "Added OID $Cname\n";
 		}
 	$Cname="";
 	}
diff --git a/crypto/objects/objxref.pl b/crypto/objects/objxref.pl
new file mode 100644
index 0000000..731d3ae
--- /dev/null
+++ b/crypto/objects/objxref.pl
@@ -0,0 +1,107 @@
+#!/usr/local/bin/perl
+
+use strict;
+
+my %xref_tbl;
+my %oid_tbl;
+
+my ($mac_file, $xref_file) = @ARGV;
+
+open(IN, $mac_file) || die "Can't open $mac_file";
+
+# Read in OID nid values for a lookup table.
+
+while (<IN>)
+	{
+	chomp;
+	my ($name, $num) = /^(\S+)\s+(\S+)$/;
+	$oid_tbl{$name} = $num;
+	}
+close IN;
+
+open(IN, $xref_file) || die "Can't open $xref_file";
+
+my $ln = 1;
+
+while (<IN>)
+	{
+	chomp;
+	s/#.*$//;
+	next if (/^\S*$/);
+	my ($xr, $p1, $p2) = /^(\S+)\s+(\S+)\s+(\S+)/;
+	check_oid($xr);
+	check_oid($p1);
+	check_oid($p2);
+	$xref_tbl{$xr} = [$p1, $p2, $ln];
+	}
+
+my @xrkeys = keys %xref_tbl;
+
+my @srt1 = sort { $oid_tbl{$a} <=> $oid_tbl{$b}} @xrkeys;
+
+for(my $i = 0; $i <= $#srt1; $i++)
+	{
+	$xref_tbl{$srt1[$i]}[2] = $i;
+	}
+
+my @srt2 = sort
+	{
+	my$ap1 = $oid_tbl{$xref_tbl{$a}[0]};
+	my$bp1 = $oid_tbl{$xref_tbl{$b}[0]};
+	return $ap1 - $bp1 if ($ap1 != $bp1);
+	my$ap2 = $oid_tbl{$xref_tbl{$a}[1]};
+	my$bp2 = $oid_tbl{$xref_tbl{$b}[1]};
+
+	return $ap2 - $bp2;
+	} @xrkeys;
+
+my $pname = $0;
+
+$pname =~ s|^.[^/]/||;
+
+print <<EOF;
+/* AUTOGENERATED BY $pname, DO NOT EDIT */
+
+typedef struct
+	{
+	int sign_id;
+	int hash_id;
+	int pkey_id;
+	} nid_triple;
+
+static const nid_triple sigoid_srt[] =
+	{
+EOF
+
+foreach (@srt1)
+	{
+	my $xr = $_;
+	my ($p1, $p2) = @{$xref_tbl{$_}};
+	print "\t{NID_$xr, NID_$p1, NID_$p2},\n";
+	}
+
+print "\t};";
+print <<EOF;
+
+
+static const nid_triple * const sigoid_srt_xref[] =
+	{
+EOF
+
+foreach (@srt2)
+	{
+	my $x = $xref_tbl{$_}[2];
+	print "\t\&sigoid_srt\[$x\],\n";
+	}
+
+print "\t};\n\n";
+
+sub check_oid
+	{
+	my ($chk) = @_;
+	if (!exists $oid_tbl{$chk})
+		{
+		die "Not Found \"$chk\"\n";
+		}
+	}
+
diff --git a/crypto/ocsp/Makefile b/crypto/ocsp/Makefile
deleted file mode 100644
index 30a00b3..0000000
--- a/crypto/ocsp/Makefile
+++ /dev/null
@@ -1,218 +0,0 @@
-#
-# OpenSSL/ocsp/Makefile
-#
-
-DIR=	ocsp
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile README
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC= ocsp_asn.c ocsp_ext.c ocsp_ht.c ocsp_lib.c ocsp_cl.c \
-	ocsp_srv.c ocsp_prn.c ocsp_vfy.c ocsp_err.c
-
-LIBOBJ= ocsp_asn.o ocsp_ext.o ocsp_ht.o ocsp_lib.o ocsp_cl.o \
-	ocsp_srv.o ocsp_prn.o ocsp_vfy.o ocsp_err.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= ocsp.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-depend:
-	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
-	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(LIBSRC)
-
-dclean:
-	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
-	mv -f Makefile.new $(MAKEFILE)
-
-clean:
-	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-ocsp_asn.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
-ocsp_asn.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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
-ocsp_asn.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-ocsp_asn.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-ocsp_asn.o: ocsp_asn.c
-ocsp_cl.o: ../../e_os.h ../../include/openssl/asn1.h
-ocsp_cl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-ocsp_cl.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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/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
-ocsp_err.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-ocsp_err.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-ocsp_err.o: ocsp_err.c
-ocsp_ext.o: ../../e_os.h ../../include/openssl/asn1.h
-ocsp_ext.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-ocsp_ext.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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: ../../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
-ocsp_ht.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-ocsp_ht.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-ocsp_ht.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-ocsp_ht.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-ocsp_ht.o: ocsp_ht.c
-ocsp_lib.o: ../../e_os.h ../../include/openssl/asn1.h
-ocsp_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-ocsp_lib.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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
-ocsp_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-ocsp_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-ocsp_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-ocsp_lib.o: ../../include/openssl/x509v3.h ../cryptlib.h ocsp_lib.c
-ocsp_prn.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ocsp_prn.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
-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/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
-ocsp_prn.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-ocsp_prn.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-ocsp_prn.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-ocsp_prn.o: ocsp_prn.c
-ocsp_srv.o: ../../e_os.h ../../include/openssl/asn1.h
-ocsp_srv.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-ocsp_srv.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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
-ocsp_srv.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-ocsp_srv.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-ocsp_srv.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-ocsp_srv.o: ../../include/openssl/x509v3.h ../cryptlib.h ocsp_srv.c
-ocsp_vfy.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ocsp_vfy.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
-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/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
-ocsp_vfy.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-ocsp_vfy.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-ocsp_vfy.o: ocsp_vfy.c
diff --git a/crypto/ocsp/ocsp.h b/crypto/ocsp/ocsp.h
index a0577a7..31e4574 100644
--- a/crypto/ocsp/ocsp.h
+++ b/crypto/ocsp/ocsp.h
@@ -64,6 +64,7 @@
 #ifndef HEADER_OCSP_H
 #define HEADER_OCSP_H
 
+#include <openssl/ossl_typ.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 #include <openssl/safestack.h>
@@ -394,17 +395,20 @@
 #define ASN1_BIT_STRING_digest(data,type,md,len) \
 	ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len)
 
-#define OCSP_CERTID_dup(cid) ASN1_dup_of(OCSP_CERTID,i2d_OCSP_CERTID,d2i_OCSP_CERTID,cid)
-
 #define OCSP_CERTSTATUS_dup(cs)\
                 (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\
 		(char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs))
 
+OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id);
+
 OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, char *path, OCSP_REQUEST *req);
 OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req,
 								int maxline);
 int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx);
 void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx);
+int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req);
+int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx,
+		const char *name, const char *value);
 
 OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer);
 
@@ -474,11 +478,6 @@
 			X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
 			STACK_OF(X509) *certs, unsigned long flags);
 
-ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d,
-				void *data, STACK_OF(ASN1_OBJECT) *sk);
-#define ASN1_STRING_encode_of(type,s,i2d,data,sk) \
-	ASN1_STRING_encode(s, CHECKED_I2D_OF(type, i2d), data, sk)
-
 X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim);
 
 X509_EXTENSION *OCSP_accept_responses_new(char **oids);
@@ -547,9 +546,9 @@
 DECLARE_ASN1_FUNCTIONS(OCSP_CRLID)
 DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC)
 
-char *OCSP_response_status_str(long s);
-char *OCSP_cert_status_str(long s);
-char *OCSP_crl_reason_str(long s);
+const char *OCSP_response_status_str(long s);
+const char *OCSP_cert_status_str(long s);
+const char *OCSP_crl_reason_str(long s);
 
 int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* a, unsigned long flags);
 int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags);
@@ -582,7 +581,8 @@
 #define OCSP_F_OCSP_REQUEST_VERIFY			 116
 #define OCSP_F_OCSP_RESPONSE_GET1_BASIC			 111
 #define OCSP_F_OCSP_SENDREQ_BIO				 112
-#define OCSP_F_PARSE_HTTP_LINE1				 117
+#define OCSP_F_OCSP_SENDREQ_NBIO			 117
+#define OCSP_F_PARSE_HTTP_LINE1				 118
 #define OCSP_F_REQUEST_VERIFY				 113
 
 /* Reason codes. */
diff --git a/crypto/ocsp/ocsp_cl.c b/crypto/ocsp/ocsp_cl.c
index 17bab5f..9c14d9d 100644
--- a/crypto/ocsp/ocsp_cl.c
+++ b/crypto/ocsp/ocsp_cl.c
@@ -155,7 +155,6 @@
 			goto err;
 
 	if (!(req->optionalSignature = sig = OCSP_SIGNATURE_new())) goto err;
-	if (!dgst) dgst = EVP_sha1();
 	if (key)
 		{
 		if (!X509_check_private_key(signer, key))
diff --git a/crypto/ocsp/ocsp_err.c b/crypto/ocsp/ocsp_err.c
index d2f2e79..0cedcea 100644
--- a/crypto/ocsp/ocsp_err.c
+++ b/crypto/ocsp/ocsp_err.c
@@ -1,6 +1,6 @@
 /* crypto/ocsp/ocsp_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
@@ -86,6 +86,7 @@
 {ERR_FUNC(OCSP_F_OCSP_REQUEST_VERIFY),	"OCSP_request_verify"},
 {ERR_FUNC(OCSP_F_OCSP_RESPONSE_GET1_BASIC),	"OCSP_response_get1_basic"},
 {ERR_FUNC(OCSP_F_OCSP_SENDREQ_BIO),	"OCSP_sendreq_bio"},
+{ERR_FUNC(OCSP_F_OCSP_SENDREQ_NBIO),	"OCSP_sendreq_nbio"},
 {ERR_FUNC(OCSP_F_PARSE_HTTP_LINE1),	"PARSE_HTTP_LINE1"},
 {ERR_FUNC(OCSP_F_REQUEST_VERIFY),	"REQUEST_VERIFY"},
 {0,NULL}
diff --git a/crypto/ocsp/ocsp_ext.c b/crypto/ocsp/ocsp_ext.c
index 815cc29..ec884cb 100644
--- a/crypto/ocsp/ocsp_ext.c
+++ b/crypto/ocsp/ocsp_ext.c
@@ -264,7 +264,7 @@
 	}
 
 /* also CRL Entry Extensions */
-
+#if 0
 ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d,
 				void *data, STACK_OF(ASN1_OBJECT) *sk)
         {
@@ -305,6 +305,7 @@
 	if (b) OPENSSL_free(b);
 	return NULL;
 	}
+#endif
 
 /* Nonce handling functions */
 
@@ -442,17 +443,10 @@
 		if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) 
 		        goto err;
 		}
-	if (!(x = X509_EXTENSION_new())) goto err;
-	if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_CrlID))) goto err;
-	if (!(ASN1_STRING_encode_of(OCSP_CRLID,x->value,i2d_OCSP_CRLID,cid,
-				    NULL)))
-	        goto err;
-	OCSP_CRLID_free(cid);
-	return x;
+	x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid);
 err:
-	if (x) X509_EXTENSION_free(x);
 	if (cid) OCSP_CRLID_free(cid);
-	return NULL;
+	return x;
 	}
 
 /*   AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */
@@ -470,18 +464,10 @@
 		        sk_ASN1_OBJECT_push(sk, o);
 		oids++;
 		}
-	if (!(x = X509_EXTENSION_new())) goto err;
-	if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_acceptableResponses)))
-		goto err;
-	if (!(ASN1_STRING_encode_of(ASN1_OBJECT,x->value,i2d_ASN1_OBJECT,NULL,
-				    sk)))
-	        goto err;
-	sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free);
-	return x;
+	x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk);
 err:
-	if (x) X509_EXTENSION_free(x);
 	if (sk) sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free);
-	return NULL;
+	return x;
         }
 
 /*  ArchiveCutoff ::= GeneralizedTime */
@@ -492,16 +478,10 @@
 
 	if (!(gt = ASN1_GENERALIZEDTIME_new())) goto err;
 	if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) goto err;
-	if (!(x = X509_EXTENSION_new())) goto err;
-	if (!(x->object=OBJ_nid2obj(NID_id_pkix_OCSP_archiveCutoff)))goto err;
-	if (!(ASN1_STRING_encode_of(ASN1_GENERALIZEDTIME,x->value,
-				    i2d_ASN1_GENERALIZEDTIME,gt,NULL))) goto err;
-	ASN1_GENERALIZEDTIME_free(gt);
-	return x;
+	x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt);
 err:
 	if (gt) ASN1_GENERALIZEDTIME_free(gt);
-	if (x) X509_EXTENSION_free(x);
-	return NULL;
+	return x;
 	}
 
 /* per ACCESS_DESCRIPTION parameter are oids, of which there are currently
@@ -530,16 +510,9 @@
 		if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) goto err;
 		urls++;
 		}
-	if (!(x = X509_EXTENSION_new())) goto err;
-	if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_serviceLocator))) 
-	        goto err;
-	if (!(ASN1_STRING_encode_of(OCSP_SERVICELOC,x->value,
-				    i2d_OCSP_SERVICELOC,sloc,NULL))) goto err;
-	OCSP_SERVICELOC_free(sloc);
-	return x;
+	x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc);
 err:
-	if (x) X509_EXTENSION_free(x);
 	if (sloc) OCSP_SERVICELOC_free(sloc);
-	return NULL;
+	return x;
 	}
 
diff --git a/crypto/ocsp/ocsp_ht.c b/crypto/ocsp/ocsp_ht.c
index 6abb30b..12bbfcf 100644
--- a/crypto/ocsp/ocsp_ht.c
+++ b/crypto/ocsp/ocsp_ht.c
@@ -118,39 +118,65 @@
 	OPENSSL_free(rctx);
 	}
 
+int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req)
+	{
+	static const char req_hdr[] =
+	"Content-Type: application/ocsp-request\r\n"
+	"Content-Length: %d\r\n\r\n";
+        if (BIO_printf(rctx->mem, req_hdr, i2d_OCSP_REQUEST(req, NULL)) <= 0)
+		return 0;
+        if (i2d_OCSP_REQUEST_bio(rctx->mem, req) <= 0)
+		return 0;
+	rctx->state = OHS_ASN1_WRITE;
+	rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL);
+	return 1;
+	}
+
+int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx,
+		const char *name, const char *value)
+	{
+	if (!name)
+		return 0;
+	if (BIO_puts(rctx->mem, name) <= 0)
+		return 0;
+	if (value)
+		{
+		if (BIO_write(rctx->mem, ": ", 2) != 2)
+			return 0;
+		if (BIO_puts(rctx->mem, value) <= 0)
+			return 0;
+		}
+	if (BIO_write(rctx->mem, "\r\n", 2) != 2)
+		return 0;
+	return 1;
+	}
+
 OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req,
 								int maxline)
 	{
-	static char post_hdr[] = "POST %s HTTP/1.0\r\n"
-	"Content-Type: application/ocsp-request\r\n"
-	"Content-Length: %d\r\n\r\n";
+	static const char post_hdr[] = "POST %s HTTP/1.0\r\n";
 
 	OCSP_REQ_CTX *rctx;
 	rctx = OPENSSL_malloc(sizeof(OCSP_REQ_CTX));
-	rctx->state = OHS_FIRSTLINE;
+	rctx->state = OHS_ERROR;
 	rctx->mem = BIO_new(BIO_s_mem());
 	rctx->io = io;
+	rctx->asn1_len = 0;
 	if (maxline > 0)
 		rctx->iobuflen = maxline;
 	else
 		rctx->iobuflen = OCSP_MAX_LINE_LEN;
 	rctx->iobuf = OPENSSL_malloc(rctx->iobuflen);
+	if (!rctx->iobuf)
+		return 0;
 	if (!path)
 		path = "/";
 
-        if (BIO_printf(rctx->mem, post_hdr, path,
-				i2d_OCSP_REQUEST(req, NULL)) <= 0)
-		{
-		rctx->state = OHS_ERROR;
+        if (BIO_printf(rctx->mem, post_hdr, path) <= 0)
 		return 0;
-		}
-        if (i2d_OCSP_REQUEST_bio(rctx->mem, req) <= 0)
-		{
-		rctx->state = OHS_ERROR;
+
+	if (req && !OCSP_REQ_CTX_set1_req(rctx, req))
 		return 0;
-		}
-	rctx->state = OHS_ASN1_WRITE;
-	rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL);
 
 	return rctx;
 	}
diff --git a/crypto/ocsp/ocsp_lib.c b/crypto/ocsp/ocsp_lib.c
index 2745081..36905d7 100644
--- a/crypto/ocsp/ocsp_lib.c
+++ b/crypto/ocsp/ocsp_lib.c
@@ -69,6 +69,7 @@
 #include <openssl/pem.h>
 #include <openssl/x509v3.h>
 #include <openssl/ocsp.h>
+#include <openssl/asn1t.h>
 
 /* Convert a certificate and its issuer to an OCSP_CERTID */
 
@@ -260,3 +261,5 @@
 	return 0;
 
 	}
+
+IMPLEMENT_ASN1_DUP_FUNCTION(OCSP_CERTID)
diff --git a/crypto/ocsp/ocsp_prn.c b/crypto/ocsp/ocsp_prn.c
index 01f81e7..1695c9c 100644
--- a/crypto/ocsp/ocsp_prn.c
+++ b/crypto/ocsp/ocsp_prn.c
@@ -85,21 +85,21 @@
 typedef struct
 	{
 	long t;
-	char *m;
+	const char *m;
 	} OCSP_TBLSTR;
 
-static char *table2string(long s, OCSP_TBLSTR *ts, int len)
+static const char *table2string(long s, const OCSP_TBLSTR *ts, int len)
 {
-	OCSP_TBLSTR *p;
+	const OCSP_TBLSTR *p;
 	for (p=ts; p < ts + len; p++)
 	        if (p->t == s)
 		         return p->m;
 	return "(UNKNOWN)";
 }
 
-char *OCSP_response_status_str(long s)
+const char *OCSP_response_status_str(long s)
         {
-	static OCSP_TBLSTR rstat_tbl[] = {
+	static const OCSP_TBLSTR rstat_tbl[] = {
 	        { OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful" },
 	        { OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest" },
 	        { OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror" },
@@ -109,18 +109,18 @@
 	return table2string(s, rstat_tbl, 6);
 	} 
 
-char *OCSP_cert_status_str(long s)
+const char *OCSP_cert_status_str(long s)
         {
-	static OCSP_TBLSTR cstat_tbl[] = {
+	static const OCSP_TBLSTR cstat_tbl[] = {
 	        { V_OCSP_CERTSTATUS_GOOD, "good" },
 	        { V_OCSP_CERTSTATUS_REVOKED, "revoked" },
 	        { V_OCSP_CERTSTATUS_UNKNOWN, "unknown" } };
 	return table2string(s, cstat_tbl, 3);
 	} 
 
-char *OCSP_crl_reason_str(long s)
+const char *OCSP_crl_reason_str(long s)
         {
-	OCSP_TBLSTR reason_tbl[] = {
+	static const OCSP_TBLSTR reason_tbl[] = {
 	  { OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified" },
           { OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise" },
           { OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise" },
@@ -275,6 +275,7 @@
 		}
 	if (!X509V3_extensions_print(bp, "Response Extensions",
 					rd->responseExtensions, flags, 4))
+							goto err;
 	if(X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= 0)
 							goto err;
 
diff --git a/crypto/ocsp/ocsp_vfy.c b/crypto/ocsp/ocsp_vfy.c
index 4a0c387..415d67e 100644
--- a/crypto/ocsp/ocsp_vfy.c
+++ b/crypto/ocsp/ocsp_vfy.c
@@ -308,6 +308,8 @@
 			}
 
 		mdlen = EVP_MD_size(dgst);
+		if (mdlen < 0)
+		    return -1;
 		if ((cid->issuerNameHash->length != mdlen) ||
 		   (cid->issuerKeyHash->length != mdlen))
 			return 0;
@@ -316,7 +318,7 @@
 			return -1;
 		if (memcmp(md, cid->issuerNameHash->data, mdlen))
 			return 0;
-		X509_pubkey_digest(cert, EVP_sha1(), md, NULL);
+		X509_pubkey_digest(cert, dgst, md, NULL);
 		if (memcmp(md, cid->issuerKeyHash->data, mdlen))
 			return 0;
 
diff --git a/crypto/opensslconf.h b/crypto/opensslconf.h
index 4aa0330..394d1d4 100644
--- a/crypto/opensslconf.h
+++ b/crypto/opensslconf.h
@@ -8,18 +8,9 @@
 #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
-#ifndef OPENSSL_NO_CMS
-# define OPENSSL_NO_CMS
-#endif
 #ifndef OPENSSL_NO_GMP
 # define OPENSSL_NO_GMP
 #endif
@@ -35,9 +26,6 @@
 #ifndef OPENSSL_NO_MD2
 # define OPENSSL_NO_MD2
 #endif
-#ifndef OPENSSL_NO_MDC2
-# define OPENSSL_NO_MDC2
-#endif
 #ifndef OPENSSL_NO_RC5
 # define OPENSSL_NO_RC5
 #endif
@@ -47,6 +35,12 @@
 #ifndef OPENSSL_NO_SEED
 # define OPENSSL_NO_SEED
 #endif
+#ifndef OPENSSL_NO_STORE
+# define OPENSSL_NO_STORE
+#endif
+#ifndef OPENSSL_NO_WHRLPOOL
+# define OPENSSL_NO_WHRLPOOL
+#endif
 
 #endif /* OPENSSL_DOING_MAKEDEPEND */
 
@@ -65,18 +59,9 @@
 # if defined(OPENSSL_NO_BF) && !defined(NO_BF)
 #  define NO_BF
 # endif
-# if defined(OPENSSL_NO_CAMELLIA) && !defined(NO_CAMELLIA)
-#  define NO_CAMELLIA
-# endif
-# if defined(OPENSSL_NO_CAPIENG) && !defined(NO_CAPIENG)
-#  define NO_CAPIENG
-# endif
 # if defined(OPENSSL_NO_CAST) && !defined(NO_CAST)
 #  define NO_CAST
 # endif
-# if defined(OPENSSL_NO_CMS) && !defined(NO_CMS)
-#  define NO_CMS
-# endif
 # if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
 #  define NO_GMP
 # endif
@@ -92,9 +77,6 @@
 # if defined(OPENSSL_NO_MD2) && !defined(NO_MD2)
 #  define NO_MD2
 # endif
-# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
-#  define NO_MDC2
-# endif
 # if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
 #  define NO_RC5
 # endif
@@ -104,25 +86,16 @@
 # if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
 #  define NO_SEED
 # endif
+# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE)
+#  define NO_STORE
+# endif
+# if defined(OPENSSL_NO_WHRLPOOL) && !defined(NO_WHRLPOOL)
+#  define NO_WHRLPOOL
+# 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
 
@@ -186,14 +159,9 @@
 /* Should we define BN_DIV2W here? */
 
 /* Only one for the following should be defined */
-/* The prime number generation stuff may not work when
- * EIGHT_BIT but I don't care since I've only used this mode
- * for debuging the bignum libraries */
 #undef SIXTY_FOUR_BIT_LONG
 #undef SIXTY_FOUR_BIT
 #define THIRTY_TWO_BIT
-#undef SIXTEEN_BIT
-#undef EIGHT_BIT
 #endif
 
 #if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
diff --git a/crypto/opensslconf.h.in b/crypto/opensslconf.h.in
index 1c77f03..97e3745 100644
--- a/crypto/opensslconf.h.in
+++ b/crypto/opensslconf.h.in
@@ -1,20 +1,5 @@
 /* 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
 
@@ -78,14 +63,9 @@
 /* Should we define BN_DIV2W here? */
 
 /* Only one for the following should be defined */
-/* The prime number generation stuff may not work when
- * EIGHT_BIT but I don't care since I've only used this mode
- * for debuging the bignum libraries */
 #undef SIXTY_FOUR_BIT_LONG
 #undef SIXTY_FOUR_BIT
 #define THIRTY_TWO_BIT
-#undef SIXTEEN_BIT
-#undef EIGHT_BIT
 #endif
 
 #if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
diff --git a/crypto/opensslv.h b/crypto/opensslv.h
index 3d794d9..cbe5264 100644
--- a/crypto/opensslv.h
+++ b/crypto/opensslv.h
@@ -12,7 +12,7 @@
  * 0.9.3-beta2    0x00903002 (same as ...beta2-dev)
  * 0.9.3	  0x0090300f
  * 0.9.3a	  0x0090301f
- * 0.9.4	  0x0090400f
+ * 0.9.4 	  0x0090400f
  * 1.2.3z	  0x102031af
  *
  * For continuity reasons (because 0.9.5 is already out, and is coded
@@ -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	0x009080dfL
+#define OPENSSL_VERSION_NUMBER	0x1000000fL
 #ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.8m-fips 25 Feb 2010"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.0-fips 29 Mar 2010"
 #else
-#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.8m 25 Feb 2010"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.0 29 Mar 2010"
 #endif
 #define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
 
@@ -83,7 +83,7 @@
  * should only keep the versions that are binary compatible with the current.
  */
 #define SHLIB_VERSION_HISTORY ""
-#define SHLIB_VERSION_NUMBER "0.9.8"
+#define SHLIB_VERSION_NUMBER "1.0.0"
 
 
 #endif /* HEADER_OPENSSLV_H */
diff --git a/crypto/ossl_typ.h b/crypto/ossl_typ.h
index 0e7a380..12bd701 100644
--- a/crypto/ossl_typ.h
+++ b/crypto/ossl_typ.h
@@ -95,6 +95,8 @@
 typedef int ASN1_NULL;
 #endif
 
+typedef struct asn1_pctx_st ASN1_PCTX;
+
 #ifdef OPENSSL_SYS_WIN32
 #undef X509_NAME
 #undef X509_EXTENSIONS
@@ -122,6 +124,11 @@
 typedef struct env_md_ctx_st EVP_MD_CTX;
 typedef struct evp_pkey_st EVP_PKEY;
 
+typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;
+
+typedef struct evp_pkey_method_st EVP_PKEY_METHOD;
+typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
+
 typedef struct dh_st DH;
 typedef struct dh_method DH_METHOD;
 
@@ -139,11 +146,14 @@
 typedef struct x509_st X509;
 typedef struct X509_algor_st X509_ALGOR;
 typedef struct X509_crl_st X509_CRL;
+typedef struct x509_crl_method_st X509_CRL_METHOD;
+typedef struct x509_revoked_st X509_REVOKED;
 typedef struct X509_name_st X509_NAME;
+typedef struct X509_pubkey_st X509_PUBKEY;
 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 pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;
 
 typedef struct v3_ext_ctx X509V3_CTX;
 typedef struct conf_st CONF;
@@ -157,12 +167,19 @@
 typedef struct st_ERR_FNS ERR_FNS;
 
 typedef struct engine_st ENGINE;
+typedef struct ssl_st SSL;
+typedef struct ssl_ctx_st SSL_CTX;
 
 typedef struct X509_POLICY_NODE_st X509_POLICY_NODE;
 typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL;
 typedef struct X509_POLICY_TREE_st X509_POLICY_TREE;
 typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE;
 
+typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID;
+typedef struct DIST_POINT_st DIST_POINT;
+typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT;
+typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS;
+
   /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */
 #define DECLARE_PKCS12_STACK_OF(type) /* Nothing */
 #define IMPLEMENT_PKCS12_STACK_OF(type) /* Nothing */
diff --git a/crypto/pem/Makefile b/crypto/pem/Makefile
deleted file mode 100644
index 669f366..0000000
--- a/crypto/pem/Makefile
+++ /dev/null
@@ -1,245 +0,0 @@
-#
-# OpenSSL/crypto/pem/Makefile
-#
-
-DIR=	pem
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC= pem_sign.c pem_seal.c pem_info.c pem_lib.c pem_all.c pem_err.c \
-	pem_x509.c pem_xaux.c pem_oth.c pem_pk8.c pem_pkey.c
-
-LIBOBJ=	pem_sign.o pem_seal.o pem_info.o pem_lib.o pem_all.o pem_err.o \
-	pem_x509.o pem_xaux.o pem_oth.o pem_pk8.o pem_pkey.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= pem.h pem2.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links: $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-depend:
-	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
-	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(LIBSRC)
-
-dclean:
-	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
-	mv -f Makefile.new $(MAKEFILE)
-
-clean:
-	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-pem_all.o: ../../e_os.h ../../include/openssl/asn1.h
-pem_all.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-pem_all.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
-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/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/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/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
-pem_info.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-pem_info.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-pem_info.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-pem_info.o: ../cryptlib.h pem_info.c
-pem_lib.o: ../../e_os.h ../../include/openssl/asn1.h
-pem_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-pem_lib.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
-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/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/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/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/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
-pem_pkey.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-pem_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-pem_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-pem_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pem_pkey.c
-pem_seal.o: ../../e_os.h ../../include/openssl/asn1.h
-pem_seal.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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
-pem_seal.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-pem_seal.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-pem_seal.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-pem_seal.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pem_seal.c
-pem_sign.o: ../../e_os.h ../../include/openssl/asn1.h
-pem_sign.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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
-pem_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-pem_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-pem_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-pem_sign.o: ../cryptlib.h pem_sign.c
-pem_x509.o: ../../e_os.h ../../include/openssl/asn1.h
-pem_x509.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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
-pem_x509.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-pem_x509.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-pem_x509.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pem_x509.c
-pem_xaux.o: ../../e_os.h ../../include/openssl/asn1.h
-pem_xaux.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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
-pem_xaux.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-pem_xaux.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-pem_xaux.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pem_xaux.c
diff --git a/crypto/pem/pem.h b/crypto/pem/pem.h
index 6c193f1..22231c2 100644
--- a/crypto/pem/pem.h
+++ b/crypto/pem/pem.h
@@ -134,6 +134,7 @@
 #define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
 #define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
 #define PEM_STRING_ECPRIVATEKEY	"EC PRIVATE KEY"
+#define PEM_STRING_PARAMETERS	"PARAMETERS"
 #define PEM_STRING_CMS		"CMS"
 
   /* Note that this structure is initialised by PEM_SealInit and cleaned up
@@ -183,11 +184,8 @@
 	int num_recipient;
 	PEM_USER **recipient;
 
-#ifndef OPENSSL_NO_STACK
-	STACK *x509_chain;	/* certificate chain */
-#else
-	char *x509_chain;	/* certificate chain */
-#endif
+	/* XXX(ben): don#t think this is used! 
+		STACK *x509_chain;	/ * certificate chain */
 	EVP_MD *md;		/* signature type */
 
 	int md_enc;		/* is the md encrypted or not? */
@@ -224,28 +222,19 @@
 #define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \
 type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\
 { \
-    return (type*)PEM_ASN1_read(CHECKED_D2I_OF(type, d2i_##asn1), \
-				str, fp, \
-				CHECKED_PPTR_OF(type, x), \
-				cb, u); \
+return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \
 } 
 
 #define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \
 int PEM_write_##name(FILE *fp, type *x) \
 { \
-    return PEM_ASN1_write(CHECKED_I2D_OF(type, i2d_##asn1), \
-			  str, fp, \
-			  CHECKED_PTR_OF(type, x), \
-			  NULL, NULL, 0, NULL, NULL); \
+return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \
 }
 
 #define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \
 int PEM_write_##name(FILE *fp, const type *x) \
 { \
-    return PEM_ASN1_write(CHECKED_I2D_OF(const type, i2d_##asn1), \
-			  str, fp, \
-			  CHECKED_PTR_OF(const type, x), \
-			  NULL, NULL, 0, NULL, NULL); \
+return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \
 }
 
 #define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \
@@ -253,10 +242,7 @@
 	     unsigned char *kstr, int klen, pem_password_cb *cb, \
 		  void *u) \
 	{ \
-	    return PEM_ASN1_write(CHECKED_I2D_OF(type, i2d_##asn1), \
-				  str, fp, \
-				  CHECKED_PTR_OF(type, x), \
-				  enc, kstr, klen, cb, u); \
+	return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
 	}
 
 #define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \
@@ -264,10 +250,7 @@
 	     unsigned char *kstr, int klen, pem_password_cb *cb, \
 		  void *u) \
 	{ \
-	    return PEM_ASN1_write(CHECKED_I2D_OF(const type, i2d_##asn1), \
-				  str, fp, \
-				  CHECKED_PTR_OF(const type, x), \
-				  enc, kstr, klen, cb, u); \
+	return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
 	}
 
 #endif
@@ -275,48 +258,33 @@
 #define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
 type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\
 { \
-    return (type*)PEM_ASN1_read_bio(CHECKED_D2I_OF(type, d2i_##asn1), \
-				    str, bp, \
-				    CHECKED_PPTR_OF(type, x), \
-				    cb, u); \
+return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \
 }
 
 #define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
 int PEM_write_bio_##name(BIO *bp, type *x) \
 { \
-    return PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d_##asn1), \
-			      str, bp, \
-			      CHECKED_PTR_OF(type, x), \
-			      NULL, NULL, 0, NULL, NULL); \
+return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \
 }
 
 #define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
 int PEM_write_bio_##name(BIO *bp, const type *x) \
 { \
-    return PEM_ASN1_write_bio(CHECKED_I2D_OF(const type, i2d_##asn1), \
-			      str, bp, \
-			      CHECKED_PTR_OF(const type, x), \
-			      NULL, NULL, 0, NULL, NULL); \
+return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \
 }
 
 #define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
 int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
 	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
 	{ \
-	    return PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d_##asn1), \
-				      str, bp, \
-				      CHECKED_PTR_OF(type, x), \
-				      enc, kstr, klen, cb, u); \
+	return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \
 	}
 
 #define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
 int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
 	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
 	{ \
-	    return PEM_ASN1_write_bio(CHECKED_I2D_OF(const type, i2d_##asn1), \
-				      str, bp, \
-				      CHECKED_PTR_OF(const type, x), \
-				      enc, kstr, klen, cb, u); \
+	return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \
 	}
 
 #define IMPLEMENT_PEM_write(name, type, str, asn1) \
@@ -353,11 +321,10 @@
 
 /* These are the same except they are for the declarations */
 
-#if defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_NO_FP_API)
+#if defined(OPENSSL_NO_FP_API)
 
 #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
@@ -428,138 +395,6 @@
 	DECLARE_PEM_read(name, type) \
 	DECLARE_PEM_write_cb(name, type)
 
-#ifdef SSLEAY_MACROS
-
-#define PEM_write_SSL_SESSION(fp,x) \
-		PEM_ASN1_write((int (*)())i2d_SSL_SESSION, \
-			PEM_STRING_SSL_SESSION,fp, (char *)x, NULL,NULL,0,NULL,NULL)
-#define PEM_write_X509(fp,x) \
-		PEM_ASN1_write((int (*)())i2d_X509,PEM_STRING_X509,fp, \
-			(char *)x, NULL,NULL,0,NULL,NULL)
-#define PEM_write_X509_REQ(fp,x) PEM_ASN1_write( \
-		(int (*)())i2d_X509_REQ,PEM_STRING_X509_REQ,fp,(char *)x, \
-			NULL,NULL,0,NULL,NULL)
-#define PEM_write_X509_CRL(fp,x) \
-		PEM_ASN1_write((int (*)())i2d_X509_CRL,PEM_STRING_X509_CRL, \
-			fp,(char *)x, NULL,NULL,0,NULL,NULL)
-#define	PEM_write_RSAPrivateKey(fp,x,enc,kstr,klen,cb,u) \
-		PEM_ASN1_write((int (*)())i2d_RSAPrivateKey,PEM_STRING_RSA,fp,\
-			(char *)x,enc,kstr,klen,cb,u)
-#define	PEM_write_RSAPublicKey(fp,x) \
-		PEM_ASN1_write((int (*)())i2d_RSAPublicKey,\
-			PEM_STRING_RSA_PUBLIC,fp,(char *)x,NULL,NULL,0,NULL,NULL)
-#define	PEM_write_DSAPrivateKey(fp,x,enc,kstr,klen,cb,u) \
-		PEM_ASN1_write((int (*)())i2d_DSAPrivateKey,PEM_STRING_DSA,fp,\
-			(char *)x,enc,kstr,klen,cb,u)
-#define	PEM_write_PrivateKey(bp,x,enc,kstr,klen,cb,u) \
-		PEM_ASN1_write((int (*)())i2d_PrivateKey,\
-		(((x)->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA),\
-			bp,(char *)x,enc,kstr,klen,cb,u)
-#define PEM_write_PKCS7(fp,x) \
-		PEM_ASN1_write((int (*)())i2d_PKCS7,PEM_STRING_PKCS7,fp, \
-			(char *)x, NULL,NULL,0,NULL,NULL)
-#define PEM_write_DHparams(fp,x) \
-		PEM_ASN1_write((int (*)())i2d_DHparams,PEM_STRING_DHPARAMS,fp,\
-			(char *)x,NULL,NULL,0,NULL,NULL)
-
-#define PEM_write_NETSCAPE_CERT_SEQUENCE(fp,x) \
-                PEM_ASN1_write((int (*)())i2d_NETSCAPE_CERT_SEQUENCE, \
-			PEM_STRING_X509,fp, \
-                        (char *)x, NULL,NULL,0,NULL,NULL)
-
-#define	PEM_read_SSL_SESSION(fp,x,cb,u) (SSL_SESSION *)PEM_ASN1_read( \
-	(char *(*)())d2i_SSL_SESSION,PEM_STRING_SSL_SESSION,fp,(char **)x,cb,u)
-#define	PEM_read_X509(fp,x,cb,u) (X509 *)PEM_ASN1_read( \
-	(char *(*)())d2i_X509,PEM_STRING_X509,fp,(char **)x,cb,u)
-#define	PEM_read_X509_REQ(fp,x,cb,u) (X509_REQ *)PEM_ASN1_read( \
-	(char *(*)())d2i_X509_REQ,PEM_STRING_X509_REQ,fp,(char **)x,cb,u)
-#define	PEM_read_X509_CRL(fp,x,cb,u) (X509_CRL *)PEM_ASN1_read( \
-	(char *(*)())d2i_X509_CRL,PEM_STRING_X509_CRL,fp,(char **)x,cb,u)
-#define	PEM_read_RSAPrivateKey(fp,x,cb,u) (RSA *)PEM_ASN1_read( \
-	(char *(*)())d2i_RSAPrivateKey,PEM_STRING_RSA,fp,(char **)x,cb,u)
-#define	PEM_read_RSAPublicKey(fp,x,cb,u) (RSA *)PEM_ASN1_read( \
-	(char *(*)())d2i_RSAPublicKey,PEM_STRING_RSA_PUBLIC,fp,(char **)x,cb,u)
-#define	PEM_read_DSAPrivateKey(fp,x,cb,u) (DSA *)PEM_ASN1_read( \
-	(char *(*)())d2i_DSAPrivateKey,PEM_STRING_DSA,fp,(char **)x,cb,u)
-#define	PEM_read_PrivateKey(fp,x,cb,u) (EVP_PKEY *)PEM_ASN1_read( \
-	(char *(*)())d2i_PrivateKey,PEM_STRING_EVP_PKEY,fp,(char **)x,cb,u)
-#define	PEM_read_PKCS7(fp,x,cb,u) (PKCS7 *)PEM_ASN1_read( \
-	(char *(*)())d2i_PKCS7,PEM_STRING_PKCS7,fp,(char **)x,cb,u)
-#define	PEM_read_DHparams(fp,x,cb,u) (DH *)PEM_ASN1_read( \
-	(char *(*)())d2i_DHparams,PEM_STRING_DHPARAMS,fp,(char **)x,cb,u)
-
-#define PEM_read_NETSCAPE_CERT_SEQUENCE(fp,x,cb,u) \
-		(NETSCAPE_CERT_SEQUENCE *)PEM_ASN1_read( \
-        (char *(*)())d2i_NETSCAPE_CERT_SEQUENCE,PEM_STRING_X509,fp,\
-							(char **)x,cb,u)
-
-#define PEM_write_bio_X509(bp,x) \
-		PEM_ASN1_write_bio((int (*)())i2d_X509,PEM_STRING_X509,bp, \
-			(char *)x, NULL,NULL,0,NULL,NULL)
-#define PEM_write_bio_X509_REQ(bp,x) PEM_ASN1_write_bio( \
-		(int (*)())i2d_X509_REQ,PEM_STRING_X509_REQ,bp,(char *)x, \
-			NULL,NULL,0,NULL,NULL)
-#define PEM_write_bio_X509_CRL(bp,x) \
-		PEM_ASN1_write_bio((int (*)())i2d_X509_CRL,PEM_STRING_X509_CRL,\
-			bp,(char *)x, NULL,NULL,0,NULL,NULL)
-#define	PEM_write_bio_RSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
-		PEM_ASN1_write_bio((int (*)())i2d_RSAPrivateKey,PEM_STRING_RSA,\
-			bp,(char *)x,enc,kstr,klen,cb,u)
-#define	PEM_write_bio_RSAPublicKey(bp,x) \
-		PEM_ASN1_write_bio((int (*)())i2d_RSAPublicKey, \
-			PEM_STRING_RSA_PUBLIC,\
-			bp,(char *)x,NULL,NULL,0,NULL,NULL)
-#define	PEM_write_bio_DSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
-		PEM_ASN1_write_bio((int (*)())i2d_DSAPrivateKey,PEM_STRING_DSA,\
-			bp,(char *)x,enc,kstr,klen,cb,u)
-#define	PEM_write_bio_PrivateKey(bp,x,enc,kstr,klen,cb,u) \
-		PEM_ASN1_write_bio((int (*)())i2d_PrivateKey,\
-		(((x)->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA),\
-			bp,(char *)x,enc,kstr,klen,cb,u)
-#define PEM_write_bio_PKCS7(bp,x) \
-		PEM_ASN1_write_bio((int (*)())i2d_PKCS7,PEM_STRING_PKCS7,bp, \
-			(char *)x, NULL,NULL,0,NULL,NULL)
-#define PEM_write_bio_DHparams(bp,x) \
-		PEM_ASN1_write_bio((int (*)())i2d_DHparams,PEM_STRING_DHPARAMS,\
-			bp,(char *)x,NULL,NULL,0,NULL,NULL)
-#define PEM_write_bio_DSAparams(bp,x) \
-		PEM_ASN1_write_bio((int (*)())i2d_DSAparams, \
-			PEM_STRING_DSAPARAMS,bp,(char *)x,NULL,NULL,0,NULL,NULL)
-
-#define PEM_write_bio_NETSCAPE_CERT_SEQUENCE(bp,x) \
-                PEM_ASN1_write_bio((int (*)())i2d_NETSCAPE_CERT_SEQUENCE, \
-			PEM_STRING_X509,bp, \
-                        (char *)x, NULL,NULL,0,NULL,NULL)
-
-#define	PEM_read_bio_X509(bp,x,cb,u) (X509 *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_X509,PEM_STRING_X509,bp,(char **)x,cb,u)
-#define	PEM_read_bio_X509_REQ(bp,x,cb,u) (X509_REQ *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_X509_REQ,PEM_STRING_X509_REQ,bp,(char **)x,cb,u)
-#define	PEM_read_bio_X509_CRL(bp,x,cb,u) (X509_CRL *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_X509_CRL,PEM_STRING_X509_CRL,bp,(char **)x,cb,u)
-#define	PEM_read_bio_RSAPrivateKey(bp,x,cb,u) (RSA *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_RSAPrivateKey,PEM_STRING_RSA,bp,(char **)x,cb,u)
-#define	PEM_read_bio_RSAPublicKey(bp,x,cb,u) (RSA *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_RSAPublicKey,PEM_STRING_RSA_PUBLIC,bp,(char **)x,cb,u)
-#define	PEM_read_bio_DSAPrivateKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_DSAPrivateKey,PEM_STRING_DSA,bp,(char **)x,cb,u)
-#define	PEM_read_bio_PrivateKey(bp,x,cb,u) (EVP_PKEY *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_PrivateKey,PEM_STRING_EVP_PKEY,bp,(char **)x,cb,u)
-
-#define	PEM_read_bio_PKCS7(bp,x,cb,u) (PKCS7 *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_PKCS7,PEM_STRING_PKCS7,bp,(char **)x,cb,u)
-#define	PEM_read_bio_DHparams(bp,x,cb,u) (DH *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_DHparams,PEM_STRING_DHPARAMS,bp,(char **)x,cb,u)
-#define	PEM_read_bio_DSAparams(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_DSAparams,PEM_STRING_DSAPARAMS,bp,(char **)x,cb,u)
-
-#define PEM_read_bio_NETSCAPE_CERT_SEQUENCE(bp,x,cb,u) \
-		(NETSCAPE_CERT_SEQUENCE *)PEM_ASN1_read_bio( \
-        (char *(*)())d2i_NETSCAPE_CERT_SEQUENCE,PEM_STRING_X509,bp,\
-							(char **)x,cb,u)
-
-#endif
-
 #if 1
 /* "userdata": new with OpenSSL 0.9.4 */
 typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata);
@@ -581,40 +416,25 @@
 	     pem_password_cb *cb, void *u);
 void *	PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp,
 			  void **x, pem_password_cb *cb, void *u);
-
-#define PEM_ASN1_read_bio_of(type,d2i,name,bp,x,cb,u) \
-    ((type*)PEM_ASN1_read_bio(CHECKED_D2I_OF(type, d2i), \
-			      name, bp,			\
-			      CHECKED_PPTR_OF(type, x), \
-			      cb, u))
-
-int	PEM_ASN1_write_bio(i2d_of_void *i2d,const char *name,BIO *bp,char *x,
+int	PEM_ASN1_write_bio(i2d_of_void *i2d,const char *name,BIO *bp, void *x,
 			   const EVP_CIPHER *enc,unsigned char *kstr,int klen,
 			   pem_password_cb *cb, void *u);
 
-#define PEM_ASN1_write_bio_of(type,i2d,name,bp,x,enc,kstr,klen,cb,u) \
-    (PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d), \
-			name, bp,		   \
-			CHECKED_PTR_OF(type, x), \
-			enc, kstr, klen, cb, u))
-
 STACK_OF(X509_INFO) *	PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u);
 int	PEM_X509_INFO_write_bio(BIO *bp,X509_INFO *xi, EVP_CIPHER *enc,
 		unsigned char *kstr, int klen, pem_password_cb *cd, void *u);
 #endif
 
-#ifndef OPENSSL_SYS_WIN16
 int	PEM_read(FILE *fp, char **name, char **header,
 		unsigned char **data,long *len);
 int	PEM_write(FILE *fp,char *name,char *hdr,unsigned char *data,long len);
 void *  PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
 		      pem_password_cb *cb, void *u);
 int	PEM_ASN1_write(i2d_of_void *i2d,const char *name,FILE *fp,
-		       char *x,const EVP_CIPHER *enc,unsigned char *kstr,
+		       void *x,const EVP_CIPHER *enc,unsigned char *kstr,
 		       int klen,pem_password_cb *callback, void *u);
 STACK_OF(X509_INFO) *	PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
 	pem_password_cb *cb, void *u);
-#endif
 
 int	PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type,
 		EVP_MD *md_type, unsigned char **ek, int *ekl,
@@ -633,7 +453,6 @@
 void	PEM_proc_type(char *buf, int type);
 void	PEM_dek_info(char *buf, const char *type, int len, char *str);
 
-#ifndef SSLEAY_MACROS
 
 #include <openssl/symhacks.h>
 
@@ -719,7 +538,20 @@
 int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc,
 			      char *kstr,int klen, pem_password_cb *cd, void *u);
 
-#endif /* SSLEAY_MACROS */
+EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x);
+int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x);
+
+
+EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length);
+EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length);
+EVP_PKEY *b2i_PrivateKey_bio(BIO *in);
+EVP_PKEY *b2i_PublicKey_bio(BIO *in);
+int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk);
+int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk);
+
+EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u);
+int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
+		pem_password_cb *cb, void *u);
 
 
 /* BEGIN ERROR CODES */
@@ -731,10 +563,22 @@
 /* Error codes for the PEM functions. */
 
 /* Function codes. */
+#define PEM_F_B2I_DSS					 127
+#define PEM_F_B2I_PVK_BIO				 128
+#define PEM_F_B2I_RSA					 129
+#define PEM_F_CHECK_BITLEN_DSA				 130
+#define PEM_F_CHECK_BITLEN_RSA				 131
 #define PEM_F_D2I_PKCS8PRIVATEKEY_BIO			 120
 #define PEM_F_D2I_PKCS8PRIVATEKEY_FP			 121
+#define PEM_F_DO_B2I					 132
+#define PEM_F_DO_B2I_BIO				 133
+#define PEM_F_DO_BLOB_HEADER				 134
 #define PEM_F_DO_PK8PKEY				 126
 #define PEM_F_DO_PK8PKEY_FP				 125
+#define PEM_F_DO_PVK_BODY				 135
+#define PEM_F_DO_PVK_HEADER				 136
+#define PEM_F_I2B_PVK					 137
+#define PEM_F_I2B_PVK_BIO				 138
 #define PEM_F_LOAD_IV					 101
 #define PEM_F_PEM_ASN1_READ				 102
 #define PEM_F_PEM_ASN1_READ_BIO				 103
@@ -747,6 +591,7 @@
 #define PEM_F_PEM_PK8PKEY				 119
 #define PEM_F_PEM_READ					 108
 #define PEM_F_PEM_READ_BIO				 109
+#define PEM_F_PEM_READ_BIO_PARAMETERS			 140
 #define PEM_F_PEM_READ_BIO_PRIVATEKEY			 123
 #define PEM_F_PEM_READ_PRIVATEKEY			 124
 #define PEM_F_PEM_SEALFINAL				 110
@@ -754,6 +599,7 @@
 #define PEM_F_PEM_SIGNFINAL				 112
 #define PEM_F_PEM_WRITE					 113
 #define PEM_F_PEM_WRITE_BIO				 114
+#define PEM_F_PEM_WRITE_PRIVATEKEY			 139
 #define PEM_F_PEM_X509_INFO_READ			 115
 #define PEM_F_PEM_X509_INFO_READ_BIO			 116
 #define PEM_F_PEM_X509_INFO_WRITE_BIO			 117
@@ -763,18 +609,30 @@
 #define PEM_R_BAD_DECRYPT				 101
 #define PEM_R_BAD_END_LINE				 102
 #define PEM_R_BAD_IV_CHARS				 103
+#define PEM_R_BAD_MAGIC_NUMBER				 116
 #define PEM_R_BAD_PASSWORD_READ				 104
+#define PEM_R_BAD_VERSION_NUMBER			 117
+#define PEM_R_BIO_WRITE_FAILURE				 118
+#define PEM_R_CIPHER_IS_NULL				 127
 #define PEM_R_ERROR_CONVERTING_PRIVATE_KEY		 115
+#define PEM_R_EXPECTING_PRIVATE_KEY_BLOB		 119
+#define PEM_R_EXPECTING_PUBLIC_KEY_BLOB			 120
+#define PEM_R_INCONSISTENT_HEADER			 121
+#define PEM_R_KEYBLOB_HEADER_PARSE_ERROR		 122
+#define PEM_R_KEYBLOB_TOO_SHORT				 123
 #define PEM_R_NOT_DEK_INFO				 105
 #define PEM_R_NOT_ENCRYPTED				 106
 #define PEM_R_NOT_PROC_TYPE				 107
 #define PEM_R_NO_START_LINE				 108
 #define PEM_R_PROBLEMS_GETTING_PASSWORD			 109
 #define PEM_R_PUBLIC_KEY_NO_RSA				 110
+#define PEM_R_PVK_DATA_TOO_SHORT			 124
+#define PEM_R_PVK_TOO_SHORT				 125
 #define PEM_R_READ_KEY					 111
 #define PEM_R_SHORT_HEADER				 112
 #define PEM_R_UNSUPPORTED_CIPHER			 113
 #define PEM_R_UNSUPPORTED_ENCRYPTION			 114
+#define PEM_R_UNSUPPORTED_KEY_COMPONENTS		 126
 
 #ifdef  __cplusplus
 }
diff --git a/crypto/pem/pem_all.c b/crypto/pem/pem_all.c
index 69dd19b..3e7a609 100644
--- a/crypto/pem/pem_all.c
+++ b/crypto/pem/pem_all.c
@@ -110,7 +110,6 @@
  */
 
 #include <stdio.h>
-#undef SSLEAY_MACROS
 #include "cryptlib.h"
 #include <openssl/bio.h>
 #include <openssl/evp.h>
@@ -194,49 +193,7 @@
 
 #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)
 
@@ -263,50 +220,10 @@
 {
 	EVP_PKEY *pktmp;
 	pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
-	return pkey_get_dsa(pktmp, dsa);
+	return pkey_get_dsa(pktmp, dsa);	/* will free pktmp */
 }
 
-#ifdef OPENSSL_FIPS
-
-int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc,
-                                               unsigned char *kstr, int klen,
-                                               pem_password_cb *cb, void *u)
-{
-	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
@@ -316,7 +233,7 @@
 {
 	EVP_PKEY *pktmp;
 	pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
-	return pkey_get_dsa(pktmp, dsa);
+	return pkey_get_dsa(pktmp, dsa);	/* will free pktmp */
 }
 
 #endif
@@ -347,54 +264,13 @@
 {
 	EVP_PKEY *pktmp;
 	pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
-	return pkey_get_eckey(pktmp, key);
+	return pkey_get_eckey(pktmp, key);	/* will free pktmp */
 }
 
 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
@@ -404,7 +280,7 @@
 {
 	EVP_PKEY *pktmp;
 	pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
-	return pkey_get_eckey(pktmp, eckey);
+	return pkey_get_eckey(pktmp, eckey);	/* will free pktmp */
 }
 
 #endif
@@ -417,66 +293,4 @@
 
 #endif
 
-
-/* The PrivateKey case is not that straightforward.
- *   IMPLEMENT_PEM_rw_cb(PrivateKey, EVP_PKEY, PEM_STRING_EVP_PKEY, PrivateKey)
- * does not work, RSA and DSA keys have specific strings.
- * (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_err.c b/crypto/pem/pem_err.c
index 3133563..d644aee 100644
--- a/crypto/pem/pem_err.c
+++ b/crypto/pem/pem_err.c
@@ -1,6 +1,6 @@
 /* crypto/pem/pem_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,10 +70,22 @@
 
 static ERR_STRING_DATA PEM_str_functs[]=
 	{
+{ERR_FUNC(PEM_F_B2I_DSS),	"B2I_DSS"},
+{ERR_FUNC(PEM_F_B2I_PVK_BIO),	"b2i_PVK_bio"},
+{ERR_FUNC(PEM_F_B2I_RSA),	"B2I_RSA"},
+{ERR_FUNC(PEM_F_CHECK_BITLEN_DSA),	"CHECK_BITLEN_DSA"},
+{ERR_FUNC(PEM_F_CHECK_BITLEN_RSA),	"CHECK_BITLEN_RSA"},
 {ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_BIO),	"d2i_PKCS8PrivateKey_bio"},
 {ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_FP),	"d2i_PKCS8PrivateKey_fp"},
+{ERR_FUNC(PEM_F_DO_B2I),	"DO_B2I"},
+{ERR_FUNC(PEM_F_DO_B2I_BIO),	"DO_B2I_BIO"},
+{ERR_FUNC(PEM_F_DO_BLOB_HEADER),	"DO_BLOB_HEADER"},
 {ERR_FUNC(PEM_F_DO_PK8PKEY),	"DO_PK8PKEY"},
 {ERR_FUNC(PEM_F_DO_PK8PKEY_FP),	"DO_PK8PKEY_FP"},
+{ERR_FUNC(PEM_F_DO_PVK_BODY),	"DO_PVK_BODY"},
+{ERR_FUNC(PEM_F_DO_PVK_HEADER),	"DO_PVK_HEADER"},
+{ERR_FUNC(PEM_F_I2B_PVK),	"I2B_PVK"},
+{ERR_FUNC(PEM_F_I2B_PVK_BIO),	"i2b_PVK_bio"},
 {ERR_FUNC(PEM_F_LOAD_IV),	"LOAD_IV"},
 {ERR_FUNC(PEM_F_PEM_ASN1_READ),	"PEM_ASN1_read"},
 {ERR_FUNC(PEM_F_PEM_ASN1_READ_BIO),	"PEM_ASN1_read_bio"},
@@ -86,6 +98,7 @@
 {ERR_FUNC(PEM_F_PEM_PK8PKEY),	"PEM_PK8PKEY"},
 {ERR_FUNC(PEM_F_PEM_READ),	"PEM_read"},
 {ERR_FUNC(PEM_F_PEM_READ_BIO),	"PEM_read_bio"},
+{ERR_FUNC(PEM_F_PEM_READ_BIO_PARAMETERS),	"PEM_read_bio_Parameters"},
 {ERR_FUNC(PEM_F_PEM_READ_BIO_PRIVATEKEY),	"PEM_READ_BIO_PRIVATEKEY"},
 {ERR_FUNC(PEM_F_PEM_READ_PRIVATEKEY),	"PEM_READ_PRIVATEKEY"},
 {ERR_FUNC(PEM_F_PEM_SEALFINAL),	"PEM_SealFinal"},
@@ -93,6 +106,7 @@
 {ERR_FUNC(PEM_F_PEM_SIGNFINAL),	"PEM_SignFinal"},
 {ERR_FUNC(PEM_F_PEM_WRITE),	"PEM_write"},
 {ERR_FUNC(PEM_F_PEM_WRITE_BIO),	"PEM_write_bio"},
+{ERR_FUNC(PEM_F_PEM_WRITE_PRIVATEKEY),	"PEM_WRITE_PRIVATEKEY"},
 {ERR_FUNC(PEM_F_PEM_X509_INFO_READ),	"PEM_X509_INFO_read"},
 {ERR_FUNC(PEM_F_PEM_X509_INFO_READ_BIO),	"PEM_X509_INFO_read_bio"},
 {ERR_FUNC(PEM_F_PEM_X509_INFO_WRITE_BIO),	"PEM_X509_INFO_write_bio"},
@@ -105,18 +119,30 @@
 {ERR_REASON(PEM_R_BAD_DECRYPT)           ,"bad decrypt"},
 {ERR_REASON(PEM_R_BAD_END_LINE)          ,"bad end line"},
 {ERR_REASON(PEM_R_BAD_IV_CHARS)          ,"bad iv chars"},
+{ERR_REASON(PEM_R_BAD_MAGIC_NUMBER)      ,"bad magic number"},
 {ERR_REASON(PEM_R_BAD_PASSWORD_READ)     ,"bad password read"},
+{ERR_REASON(PEM_R_BAD_VERSION_NUMBER)    ,"bad version number"},
+{ERR_REASON(PEM_R_BIO_WRITE_FAILURE)     ,"bio write failure"},
+{ERR_REASON(PEM_R_CIPHER_IS_NULL)        ,"cipher is null"},
 {ERR_REASON(PEM_R_ERROR_CONVERTING_PRIVATE_KEY),"error converting private key"},
+{ERR_REASON(PEM_R_EXPECTING_PRIVATE_KEY_BLOB),"expecting private key blob"},
+{ERR_REASON(PEM_R_EXPECTING_PUBLIC_KEY_BLOB),"expecting public key blob"},
+{ERR_REASON(PEM_R_INCONSISTENT_HEADER)   ,"inconsistent header"},
+{ERR_REASON(PEM_R_KEYBLOB_HEADER_PARSE_ERROR),"keyblob header parse error"},
+{ERR_REASON(PEM_R_KEYBLOB_TOO_SHORT)     ,"keyblob too short"},
 {ERR_REASON(PEM_R_NOT_DEK_INFO)          ,"not dek info"},
 {ERR_REASON(PEM_R_NOT_ENCRYPTED)         ,"not encrypted"},
 {ERR_REASON(PEM_R_NOT_PROC_TYPE)         ,"not proc type"},
 {ERR_REASON(PEM_R_NO_START_LINE)         ,"no start line"},
 {ERR_REASON(PEM_R_PROBLEMS_GETTING_PASSWORD),"problems getting password"},
 {ERR_REASON(PEM_R_PUBLIC_KEY_NO_RSA)     ,"public key no rsa"},
+{ERR_REASON(PEM_R_PVK_DATA_TOO_SHORT)    ,"pvk data too short"},
+{ERR_REASON(PEM_R_PVK_TOO_SHORT)         ,"pvk too short"},
 {ERR_REASON(PEM_R_READ_KEY)              ,"read key"},
 {ERR_REASON(PEM_R_SHORT_HEADER)          ,"short header"},
 {ERR_REASON(PEM_R_UNSUPPORTED_CIPHER)    ,"unsupported cipher"},
 {ERR_REASON(PEM_R_UNSUPPORTED_ENCRYPTION),"unsupported encryption"},
+{ERR_REASON(PEM_R_UNSUPPORTED_KEY_COMPONENTS),"unsupported key components"},
 {0,NULL}
 	};
 
diff --git a/crypto/pem/pem_info.c b/crypto/pem/pem_info.c
index 3a273f6..1b2be52 100644
--- a/crypto/pem/pem_info.c
+++ b/crypto/pem/pem_info.c
@@ -98,8 +98,8 @@
 	long len,error=0;
 	int ok=0;
 	STACK_OF(X509_INFO) *ret=NULL;
-	unsigned int i,raw;
-	d2i_of_void *d2i;
+	unsigned int i,raw,ptype;
+	d2i_of_void *d2i = 0;
 
 	if (sk == NULL)
 		{
@@ -116,6 +116,7 @@
 	for (;;)
 		{
 		raw=0;
+		ptype = 0;
 		i=PEM_read_bio(bp,&name,&header,&data,&len);
 		if (i == 0)
 			{
@@ -166,7 +167,6 @@
 #ifndef OPENSSL_NO_RSA
 			if (strcmp(name,PEM_STRING_RSA) == 0)
 			{
-			d2i=(D2I_OF(void))d2i_RSAPrivateKey;
 			if (xi->x_pkey != NULL) 
 				{
 				if (!sk_X509_INFO_push(ret,xi)) goto err;
@@ -178,10 +178,8 @@
 			xi->enc_len=0;
 
 			xi->x_pkey=X509_PKEY_new();
-			if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL)
-				goto err;
-			xi->x_pkey->dec_pkey->type=EVP_PKEY_RSA;
-			pp=&(xi->x_pkey->dec_pkey->pkey.rsa);
+			ptype=EVP_PKEY_RSA;
+			pp=&xi->x_pkey->dec_pkey;
 			if ((int)strlen(header) > 10) /* assume encrypted */
 				raw=1;
 			}
@@ -202,10 +200,8 @@
 			xi->enc_len=0;
 
 			xi->x_pkey=X509_PKEY_new();
-			if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL)
-				goto err;
-			xi->x_pkey->dec_pkey->type=EVP_PKEY_DSA;
-			pp=&xi->x_pkey->dec_pkey->pkey.dsa;
+			ptype = EVP_PKEY_DSA;
+			pp=&xi->x_pkey->dec_pkey;
 			if ((int)strlen(header) > 10) /* assume encrypted */
 				raw=1;
 			}
@@ -226,10 +222,8 @@
  			xi->enc_len=0;
  
  			xi->x_pkey=X509_PKEY_new();
- 			if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL)
- 				goto err;
- 			xi->x_pkey->dec_pkey->type=EVP_PKEY_EC;
- 			pp=&(xi->x_pkey->dec_pkey->pkey.ec);
+			ptype = EVP_PKEY_EC;
+ 			pp=&xi->x_pkey->dec_pkey;
  			if ((int)strlen(header) > 10) /* assume encrypted */
  				raw=1;
 			}
@@ -251,7 +245,15 @@
 				if (!PEM_do_header(&cipher,data,&len,cb,u))
 					goto err;
 				p=data;
-				if (d2i(pp,&p,len) == NULL)
+				if (ptype)
+					{
+					if (!d2i_PrivateKey(ptype, pp, &p, len))
+						{
+						PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_ASN1_LIB);
+						goto err;
+						}
+					}
+				else if (d2i(pp,&p,len) == NULL)
 					{
 					PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_ASN1_LIB);
 					goto err;
@@ -337,6 +339,12 @@
 		{
 		if ( (xi->enc_data!=NULL) && (xi->enc_len>0) )
 			{
+			if (enc == NULL)
+				{
+				PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,PEM_R_CIPHER_IS_NULL);
+				goto err;
+				}
+
 			/* copy from weirdo names into more normal things */
 			iv=xi->enc_cipher.iv;
 			data=(unsigned char *)xi->enc_data;
diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c
index cbafefe..42e4861 100644
--- a/crypto/pem/pem_lib.c
+++ b/crypto/pem/pem_lib.c
@@ -57,6 +57,7 @@
  */
 
 #include <stdio.h>
+#include <ctype.h>
 #include "cryptlib.h"
 #include <openssl/buffer.h>
 #include <openssl/objects.h>
@@ -65,9 +66,13 @@
 #include <openssl/x509.h>
 #include <openssl/pem.h>
 #include <openssl/pkcs12.h>
+#include "asn1_locl.h"
 #ifndef OPENSSL_NO_DES
 #include <openssl/des.h>
 #endif
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
 
 const char PEM_version[]="PEM" OPENSSL_VERSION_PTEXT;
 
@@ -75,6 +80,7 @@
 
 static int load_iv(char **fromp,unsigned char *to, int num);
 static int check_pem(const char *nm, const char *name);
+int pem_check_suffix(const char *pem_str, const char *suffix);
 
 int PEM_def_callback(char *buf, int num, int w, void *key)
 	{
@@ -99,7 +105,7 @@
 
 	for (;;)
 		{
-		i=EVP_read_pw_string(buf,num,prompt,w);
+		i=EVP_read_pw_string_min(buf,MIN_LENGTH,num,prompt,w);
 		if (i != 0)
 			{
 			PEMerr(PEM_F_PEM_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD);
@@ -183,20 +189,54 @@
 
 	/* Make PEM_STRING_EVP_PKEY match any private key */
 
-	if(!strcmp(nm,PEM_STRING_PKCS8) &&
-		!strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
+	if(!strcmp(name,PEM_STRING_EVP_PKEY))
+		{
+		int slen;
+		const EVP_PKEY_ASN1_METHOD *ameth;
+		if(!strcmp(nm,PEM_STRING_PKCS8))
+			return 1;
+		if(!strcmp(nm,PEM_STRING_PKCS8INF))
+			return 1;
+		slen = pem_check_suffix(nm, "PRIVATE KEY"); 
+		if (slen > 0)
+			{
+			/* NB: ENGINE implementations wont contain
+			 * a deprecated old private key decode function
+			 * so don't look for them.
+			 */
+			ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
+			if (ameth && ameth->old_priv_decode)
+				return 1;
+			}
+		return 0;
+		}
 
-	if(!strcmp(nm,PEM_STRING_PKCS8INF) &&
-		 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
+	if(!strcmp(name,PEM_STRING_PARAMETERS))
+		{
+		int slen;
+		const EVP_PKEY_ASN1_METHOD *ameth;
+		slen = pem_check_suffix(nm, "PARAMETERS"); 
+		if (slen > 0)
+			{
+			ENGINE *e;
+			ameth = EVP_PKEY_asn1_find_str(&e, nm, slen);
+			if (ameth)
+				{
+				int r;
+				if (ameth->param_decode)
+					r = 1;
+				else
+					r = 0;
+#ifndef OPENSSL_NO_ENGINE
+				if (e)
+					ENGINE_finish(e);
+#endif
+				return r;
+				}
+			}
+		return 0;
+		}
 
-	if(!strcmp(nm,PEM_STRING_RSA) &&
-		!strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
-
-	if(!strcmp(nm,PEM_STRING_DSA) &&
-		 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
-
- 	if(!strcmp(nm,PEM_STRING_ECPRIVATEKEY) &&
- 		 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
 	/* Permit older strings */
 
 	if(!strcmp(nm,PEM_STRING_X509_OLD) &&
@@ -219,6 +259,14 @@
 	if(!strcmp(nm, PEM_STRING_PKCS7_SIGNED) &&
 		!strcmp(name, PEM_STRING_PKCS7)) return 1;
 
+#ifndef OPENSSL_NO_CMS
+	if(!strcmp(nm, PEM_STRING_X509) &&
+		!strcmp(name, PEM_STRING_CMS)) return 1;
+	/* Allow CMS to be read from PKCS#7 headers */
+	if(!strcmp(nm, PEM_STRING_PKCS7) &&
+		!strcmp(name, PEM_STRING_CMS)) return 1;
+#endif
+
 	return 0;
 }
 
@@ -264,7 +312,7 @@
 
 #ifndef OPENSSL_NO_FP_API
 int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
-		   char *x, const EVP_CIPHER *enc, unsigned char *kstr,
+		   void *x, const EVP_CIPHER *enc, unsigned char *kstr,
 		   int klen, pem_password_cb *callback, void *u)
         {
         BIO *b;
@@ -283,7 +331,7 @@
 #endif
 
 int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
-		       char *x, const EVP_CIPHER *enc, unsigned char *kstr,
+		       void *x, const EVP_CIPHER *enc, unsigned char *kstr,
 		       int klen, pem_password_cb *callback, void *u)
 	{
 	EVP_CIPHER_CTX ctx;
@@ -782,3 +830,25 @@
 	BUF_MEM_free(dataB);
 	return(0);
 	}
+
+/* Check pem string and return prefix length.
+ * If for example the pem_str == "RSA PRIVATE KEY" and suffix = "PRIVATE KEY"
+ * the return value is 3 for the string "RSA".
+ */
+
+int pem_check_suffix(const char *pem_str, const char *suffix)
+	{
+	int pem_len = strlen(pem_str);
+	int suffix_len = strlen(suffix);
+	const char *p;
+	if (suffix_len + 1 >= pem_len)
+		return 0;
+	p = pem_str + pem_len - suffix_len;
+	if (strcmp(p, suffix))
+		return 0;
+	p--;
+	if (*p != ' ')
+		return 0;
+	return p - pem_str;
+	}
+
diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c
index 4da4c31..8ecf249 100644
--- a/crypto/pem/pem_pkey.c
+++ b/crypto/pem/pem_pkey.c
@@ -65,7 +65,12 @@
 #include <openssl/x509.h>
 #include <openssl/pkcs12.h>
 #include <openssl/pem.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include "asn1_locl.h"
 
+int pem_check_suffix(const char *pem_str, const char *suffix);
 
 EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
 	{
@@ -73,19 +78,14 @@
 	const unsigned char *p=NULL;
 	unsigned char *data=NULL;
 	long len;
+	int slen;
 	EVP_PKEY *ret=NULL;
 
 	if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u))
 		return NULL;
 	p = data;
 
-	if (strcmp(nm,PEM_STRING_RSA) == 0)
-		ret=d2i_PrivateKey(EVP_PKEY_RSA,x,&p,len);
-	else if (strcmp(nm,PEM_STRING_DSA) == 0)
-		ret=d2i_PrivateKey(EVP_PKEY_DSA,x,&p,len);
-	else if (strcmp(nm,PEM_STRING_ECPRIVATEKEY) == 0)
-		ret=d2i_PrivateKey(EVP_PKEY_EC,x,&p,len);
-	else if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) {
+	if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) {
 		PKCS8_PRIV_KEY_INFO *p8inf;
 		p8inf=d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
 		if(!p8inf) goto p8err;
@@ -119,7 +119,14 @@
 			*x = ret;
 		}
 		PKCS8_PRIV_KEY_INFO_free(p8inf);
-	}
+	} else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0)
+		{
+		const EVP_PKEY_ASN1_METHOD *ameth;
+		ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
+		if (!ameth || !ameth->old_priv_decode)
+			goto p8err;
+		ret=d2i_PrivateKey(ameth->pkey_id,x,&p,len);
+		}
 p8err:
 	if (ret == NULL)
 		PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY,ERR_R_ASN1_LIB);
@@ -130,6 +137,74 @@
 	return(ret);
 	}
 
+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)
+	{
+	char pem_str[80];
+	if (!x->ameth || x->ameth->priv_encode)
+		return PEM_write_bio_PKCS8PrivateKey(bp, x, enc,
+							(char *)kstr, klen,
+							cb, u);
+
+	BIO_snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str);
+	return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey,
+				pem_str,bp,x,enc,kstr,klen,cb,u);
+	}
+
+EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x)
+	{
+	char *nm=NULL;
+	const unsigned char *p=NULL;
+	unsigned char *data=NULL;
+	long len;
+	int slen;
+	EVP_PKEY *ret=NULL;
+
+	if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS,
+								bp, 0, NULL))
+		return NULL;
+	p = data;
+
+	if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0)
+		{
+		ret = EVP_PKEY_new();
+		if (!ret)
+			goto err;
+		if (!EVP_PKEY_set_type_str(ret, nm, slen)
+			|| !ret->ameth->param_decode
+			|| !ret->ameth->param_decode(ret, &p, len))
+			{
+			EVP_PKEY_free(ret);
+			ret = NULL;
+			goto err;
+			}
+		if(x)
+			{
+			if(*x) EVP_PKEY_free((EVP_PKEY *)*x);
+			*x = ret;
+			}
+		}
+err:
+	if (ret == NULL)
+		PEMerr(PEM_F_PEM_READ_BIO_PARAMETERS,ERR_R_ASN1_LIB);
+	OPENSSL_free(nm);
+	OPENSSL_free(data);
+	return(ret);
+	}
+
+int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x)
+	{
+	char pem_str[80];
+	if (!x->ameth || !x->ameth->param_encode)
+		return 0;
+
+	BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str);
+	return PEM_ASN1_write_bio(
+		(i2d_of_void *)x->ameth->param_encode,
+				pem_str,bp,x,NULL,NULL,0,0,NULL);
+	}
+
 #ifndef OPENSSL_NO_FP_API
 EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u)
 	{
@@ -146,4 +221,22 @@
         BIO_free(b);
         return(ret);
 	}
+
+int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+	{
+        BIO *b;
+        int ret;
+
+        if ((b=BIO_new_fp(fp, BIO_NOCLOSE)) == NULL)
+		{
+		PEMerr(PEM_F_PEM_WRITE_PRIVATEKEY,ERR_R_BUF_LIB);
+                return 0;
+		}
+        ret=PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u);
+        BIO_free(b);
+        return ret;
+	}
+
 #endif
diff --git a/crypto/pem/pem_x509.c b/crypto/pem/pem_x509.c
index 3f709f1..b531057 100644
--- a/crypto/pem/pem_x509.c
+++ b/crypto/pem/pem_x509.c
@@ -57,7 +57,6 @@
  */
 
 #include <stdio.h>
-#undef SSLEAY_MACROS
 #include "cryptlib.h"
 #include <openssl/bio.h>
 #include <openssl/evp.h>
diff --git a/crypto/pem/pem_xaux.c b/crypto/pem/pem_xaux.c
index 7cc7491..328f796 100644
--- a/crypto/pem/pem_xaux.c
+++ b/crypto/pem/pem_xaux.c
@@ -57,7 +57,6 @@
  */
 
 #include <stdio.h>
-#undef SSLEAY_MACROS
 #include "cryptlib.h"
 #include <openssl/bio.h>
 #include <openssl/evp.h>
diff --git a/crypto/pem/pvkfmt.c b/crypto/pem/pvkfmt.c
new file mode 100644
index 0000000..11e1f10
--- /dev/null
+++ b/crypto/pem/pvkfmt.c
@@ -0,0 +1,937 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Support for PVK format keys and related structures (such a PUBLICKEYBLOB
+ * and PRIVATEKEYBLOB).
+ */
+
+#include "cryptlib.h"
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
+#include <openssl/dsa.h>
+#include <openssl/rsa.h>
+
+/* Utility function: read a DWORD (4 byte unsigned integer) in little endian
+ * format
+ */
+
+static unsigned int read_ledword(const unsigned char **in)
+	{
+	const unsigned char *p = *in;
+	unsigned int ret;
+	ret = *p++;
+	ret |= (*p++ << 8);
+	ret |= (*p++ << 16);
+	ret |= (*p++ << 24);
+	*in = p;
+	return ret;
+	}
+
+/* Read a BIGNUM in little endian format. The docs say that this should take up 
+ * bitlen/8 bytes.
+ */
+
+static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r)
+	{
+	const unsigned char *p;
+	unsigned char *tmpbuf, *q;
+	unsigned int i;
+	p = *in + nbyte - 1;
+	tmpbuf = OPENSSL_malloc(nbyte);
+	if (!tmpbuf)
+		return 0;
+	q = tmpbuf;
+	for (i = 0; i < nbyte; i++)
+		*q++ = *p--;
+	*r = BN_bin2bn(tmpbuf, nbyte, NULL);
+	OPENSSL_free(tmpbuf);
+	if (*r)
+		{
+		*in += nbyte;
+		return 1;
+		}
+	else
+		return 0;
+	}
+
+
+/* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */
+
+#define MS_PUBLICKEYBLOB	0x6
+#define MS_PRIVATEKEYBLOB	0x7
+#define MS_RSA1MAGIC		0x31415352L
+#define MS_RSA2MAGIC		0x32415352L
+#define MS_DSS1MAGIC		0x31535344L
+#define MS_DSS2MAGIC		0x32535344L
+
+#define MS_KEYALG_RSA_KEYX	0xa400
+#define MS_KEYALG_DSS_SIGN	0x2200
+
+#define MS_KEYTYPE_KEYX		0x1
+#define MS_KEYTYPE_SIGN		0x2
+
+/* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */
+#define MS_PVKMAGIC		0xb0b5f11eL
+/* Salt length for PVK files */
+#define PVK_SALTLEN		0x10
+
+static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length,
+						unsigned int bitlen, int ispub);
+static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length,
+						unsigned int bitlen, int ispub);
+
+static int do_blob_header(const unsigned char **in, unsigned int length,
+				unsigned int *pmagic, unsigned int *pbitlen,
+				int *pisdss, int *pispub)
+	{
+	const unsigned char *p = *in;
+	if (length < 16)
+		return 0;
+	/* bType */
+	if (*p == MS_PUBLICKEYBLOB)
+		{
+		if (*pispub == 0)
+			{
+			PEMerr(PEM_F_DO_BLOB_HEADER,
+					PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
+			return 0;
+			}
+		*pispub = 1;
+		}
+	else if (*p == MS_PRIVATEKEYBLOB)
+		{
+		if (*pispub == 1)
+			{
+			PEMerr(PEM_F_DO_BLOB_HEADER,
+					PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
+			return 0;
+			}
+		*pispub = 0;
+		}
+	else
+		return 0;
+	p++;
+	/* Version */
+	if (*p++ != 0x2)
+		{
+		PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_VERSION_NUMBER);
+		return 0;
+		}
+	/* Ignore reserved, aiKeyAlg */
+	p+= 6;
+	*pmagic = read_ledword(&p);
+	*pbitlen = read_ledword(&p);
+	*pisdss = 0;
+	switch (*pmagic)
+		{
+
+		case MS_DSS1MAGIC:
+		*pisdss = 1;
+		case MS_RSA1MAGIC:
+		if (*pispub == 0)
+			{
+			PEMerr(PEM_F_DO_BLOB_HEADER,
+					PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
+			return 0;
+			}
+		break;
+
+		case MS_DSS2MAGIC:
+		*pisdss = 1;
+		case MS_RSA2MAGIC:
+		if (*pispub == 1)
+			{
+			PEMerr(PEM_F_DO_BLOB_HEADER,
+					PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
+			return 0;
+			}
+		break;
+
+		default:
+		PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_MAGIC_NUMBER);
+		return -1;
+		}
+	*in = p;
+	return 1;
+	}
+
+static unsigned int blob_length(unsigned bitlen, int isdss, int ispub)
+	{
+	unsigned int nbyte, hnbyte;
+	nbyte = (bitlen + 7) >> 3;
+	hnbyte = (bitlen + 15) >> 4;
+	if (isdss)
+		{
+
+		/* Expected length: 20 for q + 3 components bitlen each + 24
+		 * for seed structure.
+		 */
+		if (ispub)
+			return  44 + 3 * nbyte;
+		/* Expected length: 20 for q, priv, 2 bitlen components + 24
+		 * for seed structure.
+		 */
+		else
+			return 64 + 2 * nbyte;
+		}
+	else
+		{
+		/* Expected length: 4 for 'e' + 'n' */
+		if (ispub)
+			return 4 + nbyte;
+		else
+		/* Expected length: 4 for 'e' and 7 other components.
+		 * 2 components are bitlen size, 5 are bitlen/2
+		 */
+			return 4 + 2*nbyte + 5*hnbyte;
+		}
+
+	}
+
+static EVP_PKEY *do_b2i(const unsigned char **in, unsigned int length,
+								int ispub)
+	{
+	const unsigned char *p = *in;
+	unsigned int bitlen, magic;
+	int isdss;
+	if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0)
+		{
+		PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_HEADER_PARSE_ERROR);
+		return NULL;
+		}
+	length -= 16;
+	if (length < blob_length(bitlen, isdss, ispub))
+		{
+		PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_TOO_SHORT);
+		return NULL;
+		}
+	if (isdss)
+		return b2i_dss(&p, length, bitlen, ispub);
+	else
+		return b2i_rsa(&p, length, bitlen, ispub);
+	}
+
+static EVP_PKEY *do_b2i_bio(BIO *in, int ispub)
+	{
+	const unsigned char *p;
+	unsigned char hdr_buf[16], *buf = NULL;
+	unsigned int bitlen, magic, length;
+	int isdss;
+	EVP_PKEY *ret = NULL;
+	if (BIO_read(in, hdr_buf, 16) != 16)
+		{
+		PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
+		return NULL;
+		}
+	p = hdr_buf;
+	if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0)
+		return NULL;
+
+	length = blob_length(bitlen, isdss, ispub);
+	buf = OPENSSL_malloc(length);
+	if (!buf)
+		{
+		PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+	p = buf;
+	if (BIO_read(in, buf, length) != (int)length)
+		{
+		PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
+		goto err;
+		}
+
+	if (isdss)
+		ret = b2i_dss(&p, length, bitlen, ispub);
+	else
+		ret = b2i_rsa(&p, length, bitlen, ispub);
+
+	err:
+	if (buf)
+		OPENSSL_free(buf);
+	return ret;
+	}
+
+static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length,
+						unsigned int bitlen, int ispub)
+	{
+	const unsigned char *p = *in;
+	EVP_PKEY *ret = NULL;
+	DSA *dsa = NULL;
+	BN_CTX *ctx = NULL;
+	unsigned int nbyte;
+	nbyte = (bitlen + 7) >> 3;
+
+	dsa = DSA_new();
+	ret = EVP_PKEY_new();
+	if (!dsa || !ret)
+		goto memerr;
+	if (!read_lebn(&p, nbyte, &dsa->p))
+		goto memerr;
+	if (!read_lebn(&p, 20, &dsa->q))
+		goto memerr;
+	if (!read_lebn(&p, nbyte, &dsa->g))
+		goto memerr;
+	if (ispub)
+		{
+		if (!read_lebn(&p, nbyte, &dsa->pub_key))
+			goto memerr;
+		}
+	else
+		{
+		if (!read_lebn(&p, 20, &dsa->priv_key))
+			goto memerr;
+		/* Calculate public key */
+		if (!(dsa->pub_key = BN_new()))
+			goto memerr;
+		if (!(ctx = BN_CTX_new()))
+			goto memerr;
+			
+		if (!BN_mod_exp(dsa->pub_key, dsa->g,
+						 dsa->priv_key, dsa->p, ctx))
+			
+			goto memerr;
+		BN_CTX_free(ctx);
+		}
+
+	EVP_PKEY_set1_DSA(ret, dsa);
+	DSA_free(dsa);
+	*in = p;
+	return ret;
+
+	memerr:
+	PEMerr(PEM_F_B2I_DSS, ERR_R_MALLOC_FAILURE);
+	if (dsa)
+		DSA_free(dsa);
+	if (ret)
+		EVP_PKEY_free(ret);
+	if (ctx)
+		BN_CTX_free(ctx);
+	return NULL;
+	}
+
+static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length,
+						unsigned int bitlen, int ispub)
+		
+	{
+	const unsigned char *p = *in;
+	EVP_PKEY *ret = NULL;
+	RSA *rsa = NULL;
+	unsigned int nbyte, hnbyte;
+	nbyte = (bitlen + 7) >> 3;
+	hnbyte = (bitlen + 15) >> 4;
+	rsa = RSA_new();
+	ret = EVP_PKEY_new();
+	if (!rsa || !ret)
+		goto memerr;
+	rsa->e = BN_new();
+	if (!rsa->e)
+		goto memerr;
+	if (!BN_set_word(rsa->e, read_ledword(&p)))
+		goto memerr;
+	if (!read_lebn(&p, nbyte, &rsa->n))
+		goto memerr;
+	if (!ispub)
+		{
+		if (!read_lebn(&p, hnbyte, &rsa->p))
+			goto memerr;
+		if (!read_lebn(&p, hnbyte, &rsa->q))
+			goto memerr;
+		if (!read_lebn(&p, hnbyte, &rsa->dmp1))
+			goto memerr;
+		if (!read_lebn(&p, hnbyte, &rsa->dmq1))
+			goto memerr;
+		if (!read_lebn(&p, hnbyte, &rsa->iqmp))
+			goto memerr;
+		if (!read_lebn(&p, nbyte, &rsa->d))
+			goto memerr;
+		}
+
+	EVP_PKEY_set1_RSA(ret, rsa);
+	RSA_free(rsa);
+	*in = p;
+	return ret;
+	memerr:
+	PEMerr(PEM_F_B2I_RSA, ERR_R_MALLOC_FAILURE);
+	if (rsa)
+		RSA_free(rsa);
+	if (ret)
+		EVP_PKEY_free(ret);
+	return NULL;
+	}
+
+EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length)
+	{
+	return do_b2i(in, length, 0);
+	}
+
+EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length)
+	{
+	return do_b2i(in, length, 1);
+	}
+
+
+EVP_PKEY *b2i_PrivateKey_bio(BIO *in)
+	{
+	return do_b2i_bio(in, 0);
+	}
+
+EVP_PKEY *b2i_PublicKey_bio(BIO *in)
+	{
+	return do_b2i_bio(in, 1);
+	}
+
+static void write_ledword(unsigned char **out, unsigned int dw)
+	{
+	unsigned char *p = *out;
+	*p++ = dw & 0xff;
+	*p++ = (dw>>8) & 0xff;
+	*p++ = (dw>>16) & 0xff;
+	*p++ = (dw>>24) & 0xff;
+	*out = p;
+	}
+
+static void write_lebn(unsigned char **out, const BIGNUM *bn, int len)
+	{
+	int nb, i;
+	unsigned char *p = *out, *q, c;
+	nb = BN_num_bytes(bn);
+	BN_bn2bin(bn, p);
+	q = p + nb - 1;
+	/* In place byte order reversal */
+	for (i = 0; i < nb/2; i++)
+		{
+		c = *p;
+		*p++ = *q;
+		*q-- = c;
+		}
+	*out += nb;
+	/* Pad with zeroes if we have to */
+	if (len > 0)
+		{
+		len -= nb;
+		if (len > 0)
+			{
+			memset(*out, 0, len);
+			*out += len;
+			}
+		}
+	}
+
+
+static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *magic);
+static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic);
+
+static void write_rsa(unsigned char **out, RSA *rsa, int ispub);
+static void write_dsa(unsigned char **out, DSA *dsa, int ispub);
+	
+static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub)
+	{
+	unsigned char *p;
+	unsigned int bitlen, magic = 0, keyalg;
+	int outlen, noinc = 0;
+	if (pk->type == EVP_PKEY_DSA)
+		{
+		bitlen = check_bitlen_dsa(pk->pkey.dsa, ispub, &magic);
+		keyalg = MS_KEYALG_DSS_SIGN;
+		}
+	else if (pk->type == EVP_PKEY_RSA)
+		{
+		bitlen = check_bitlen_rsa(pk->pkey.rsa, ispub, &magic);
+		keyalg = MS_KEYALG_RSA_KEYX;
+		}
+	else
+		return -1;
+	if (bitlen == 0)
+		return -1;
+	outlen = 16 + blob_length(bitlen,
+			keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub);
+	if (out == NULL)
+		return outlen;
+	if (*out)
+		p = *out;
+	else
+		{
+		p = OPENSSL_malloc(outlen);
+		if (!p)
+			return -1;
+		*out = p;
+		noinc = 1;
+		}
+	if (ispub)
+		*p++ = MS_PUBLICKEYBLOB;
+	else
+		*p++ = MS_PRIVATEKEYBLOB;
+	*p++ = 0x2;
+	*p++ = 0;
+	*p++ = 0;
+	write_ledword(&p, keyalg);
+	write_ledword(&p, magic);
+	write_ledword(&p, bitlen);
+	if (keyalg == MS_KEYALG_DSS_SIGN)
+		write_dsa(&p, pk->pkey.dsa, ispub);
+	else
+		write_rsa(&p, pk->pkey.rsa, ispub);
+	if (!noinc)
+		*out += outlen;
+	return outlen;
+	}
+
+static int do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub)
+	{
+	unsigned char *tmp = NULL;
+	int outlen, wrlen;
+	outlen = do_i2b(&tmp, pk, ispub);
+	if (outlen < 0)
+		return -1;
+	wrlen = BIO_write(out, tmp, outlen);
+	OPENSSL_free(tmp);
+	if (wrlen == outlen)
+		return outlen;
+	return -1;
+	}
+
+static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic)
+	{
+	int bitlen;
+	bitlen = BN_num_bits(dsa->p);
+	if ((bitlen & 7) || (BN_num_bits(dsa->q) != 160)
+		|| (BN_num_bits(dsa->g) > bitlen))
+		goto badkey;
+	if (ispub)
+		{
+		if (BN_num_bits(dsa->pub_key) > bitlen)
+			goto badkey;
+		*pmagic = MS_DSS1MAGIC;
+		}
+	else
+		{
+		if (BN_num_bits(dsa->priv_key) > 160)
+			goto badkey;
+		*pmagic = MS_DSS2MAGIC;
+		}
+	
+	return bitlen;
+	badkey:
+	PEMerr(PEM_F_CHECK_BITLEN_DSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
+	return 0;
+	}
+
+static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic)
+	{
+	int nbyte, hnbyte, bitlen;
+	if (BN_num_bits(rsa->e) > 32)
+		goto badkey;
+	bitlen = BN_num_bits(rsa->n);
+	nbyte = BN_num_bytes(rsa->n);
+	hnbyte = (BN_num_bits(rsa->n) + 15) >> 4;
+	if (ispub)
+		{
+		*pmagic = MS_RSA1MAGIC;
+		return bitlen;
+		}
+	else
+	{
+		*pmagic = MS_RSA2MAGIC;
+		/* For private key each component must fit within nbyte or
+		 * hnbyte.
+		 */
+		if (BN_num_bytes(rsa->d) > nbyte)
+			goto badkey;
+		if ((BN_num_bytes(rsa->iqmp) > hnbyte)
+			|| (BN_num_bytes(rsa->p) > hnbyte)
+			|| (BN_num_bytes(rsa->q) > hnbyte)
+			|| (BN_num_bytes(rsa->dmp1) > hnbyte)
+			|| (BN_num_bytes(rsa->dmq1) > hnbyte))
+			goto badkey;
+	}
+	return bitlen;
+	badkey:
+	PEMerr(PEM_F_CHECK_BITLEN_RSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
+	return 0;
+	}
+
+
+static void write_rsa(unsigned char **out, RSA *rsa, int ispub)
+	{
+	int nbyte, hnbyte;
+	nbyte = BN_num_bytes(rsa->n);
+	hnbyte = (BN_num_bits(rsa->n) + 15) >> 4;
+	write_lebn(out, rsa->e, 4);
+	write_lebn(out, rsa->n, -1);
+	if (ispub)
+		return;
+	write_lebn(out, rsa->p, hnbyte);
+	write_lebn(out, rsa->q, hnbyte);
+	write_lebn(out, rsa->dmp1, hnbyte);
+	write_lebn(out, rsa->dmq1, hnbyte);
+	write_lebn(out, rsa->iqmp, hnbyte);
+	write_lebn(out, rsa->d, nbyte);
+	}
+
+	
+static void write_dsa(unsigned char **out, DSA *dsa, int ispub)
+	{
+	int nbyte;
+	nbyte = BN_num_bytes(dsa->p);
+	write_lebn(out, dsa->p, nbyte);
+	write_lebn(out, dsa->q, 20);
+	write_lebn(out, dsa->g, nbyte);
+	if (ispub)
+		write_lebn(out, dsa->pub_key, nbyte);
+	else
+		write_lebn(out, dsa->priv_key, 20);
+	/* Set "invalid" for seed structure values */
+	memset(*out, 0xff, 24);
+	*out += 24;
+	return;
+	}
+	
+
+int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk)
+	{
+	return do_i2b_bio(out, pk, 0);
+	}
+
+int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk)
+	{
+	return do_i2b_bio(out, pk, 1);
+	}
+
+static int do_PVK_header(const unsigned char **in, unsigned int length,
+		int skip_magic,
+	       	unsigned int *psaltlen, unsigned int *pkeylen)
+		
+	{
+	const unsigned char *p = *in;
+	unsigned int pvk_magic, keytype, is_encrypted;
+	if (skip_magic)
+		{
+		if (length < 20)
+			{
+			PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
+			return 0;
+			}
+		length -= 20;
+		}
+	else
+		{
+		if (length < 24)
+			{
+			PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
+			return 0;
+			}
+		length -= 24;
+		pvk_magic = read_ledword(&p);
+		if (pvk_magic != MS_PVKMAGIC)
+			{
+			PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_BAD_MAGIC_NUMBER);
+			return 0;
+			}
+		}
+	/* Skip reserved */
+	p += 4;
+	keytype = read_ledword(&p);
+	is_encrypted = read_ledword(&p);
+	*psaltlen = read_ledword(&p);
+	*pkeylen = read_ledword(&p);
+
+	if (is_encrypted && !*psaltlen)
+		{
+		PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER);
+		return 0;
+		}
+
+	*in = p;
+	return 1;
+	}
+
+static int derive_pvk_key(unsigned char *key, 
+			const unsigned char *salt, unsigned int saltlen,
+			const unsigned char *pass, int passlen)
+	{
+	EVP_MD_CTX mctx;
+	EVP_MD_CTX_init(&mctx);
+	EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL);
+	EVP_DigestUpdate(&mctx, salt, saltlen);
+	EVP_DigestUpdate(&mctx, pass, passlen);
+	EVP_DigestFinal_ex(&mctx, key, NULL);
+	EVP_MD_CTX_cleanup(&mctx);
+	return 1;
+	}
+	
+
+static EVP_PKEY *do_PVK_body(const unsigned char **in,
+		unsigned int saltlen, unsigned int keylen,
+		pem_password_cb *cb, void *u)
+	{
+	EVP_PKEY *ret = NULL;
+	const unsigned char *p = *in;
+	unsigned int magic;
+	unsigned char *enctmp = NULL, *q;
+	if (saltlen)
+		{
+		char psbuf[PEM_BUFSIZE];
+		unsigned char keybuf[20];
+		EVP_CIPHER_CTX cctx;
+		int enctmplen, inlen;
+		if (cb)
+			inlen=cb(psbuf,PEM_BUFSIZE,0,u);
+		else
+			inlen=PEM_def_callback(psbuf,PEM_BUFSIZE,0,u);
+		if (inlen <= 0)
+			{
+			PEMerr(PEM_F_DO_PVK_BODY,PEM_R_BAD_PASSWORD_READ);
+			return NULL;
+			}
+		enctmp = OPENSSL_malloc(keylen + 8);
+		if (!enctmp)
+			{
+			PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE);
+			return NULL;
+			}
+		if (!derive_pvk_key(keybuf, p, saltlen,
+			    (unsigned char *)psbuf, inlen))
+			return NULL;
+		p += saltlen;
+		/* Copy BLOBHEADER across, decrypt rest */
+		memcpy(enctmp, p, 8);
+		p += 8;
+		inlen = keylen - 8;
+		q = enctmp + 8;
+		EVP_CIPHER_CTX_init(&cctx);
+		EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL);
+		EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen);
+		EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen);
+		magic = read_ledword((const unsigned char **)&q);
+		if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC)
+			{
+			q = enctmp + 8;
+			memset(keybuf + 5, 0, 11);
+			EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf,
+								NULL);
+			OPENSSL_cleanse(keybuf, 20);
+			EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen);
+			EVP_DecryptFinal_ex(&cctx, q + enctmplen,
+								&enctmplen);
+			magic = read_ledword((const unsigned char **)&q);
+			if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC)
+				{
+				EVP_CIPHER_CTX_cleanup(&cctx);
+				PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT);
+				goto err;
+				}
+			}
+		else
+			OPENSSL_cleanse(keybuf, 20);
+		EVP_CIPHER_CTX_cleanup(&cctx);
+		p = enctmp;
+		}
+
+	ret = b2i_PrivateKey(&p, keylen);
+	err:
+	if (enctmp && saltlen)
+		OPENSSL_free(enctmp);
+	return ret;
+	}
+
+
+EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
+	{
+	unsigned char pvk_hdr[24], *buf = NULL;
+	const unsigned char *p;
+	int buflen;
+	EVP_PKEY *ret = NULL;
+	unsigned int saltlen, keylen;
+	if (BIO_read(in, pvk_hdr, 24) != 24)
+		{
+		PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT);
+		return NULL;
+		}
+	p = pvk_hdr;
+
+	if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen))
+		return 0;
+	buflen = (int) keylen + saltlen;
+	buf = OPENSSL_malloc(buflen);
+	if (!buf)
+		{
+		PEMerr(PEM_F_B2I_PVK_BIO, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	p = buf;
+	if (BIO_read(in, buf, buflen) != buflen)
+		{
+		PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT);
+		goto err;
+		}
+	ret = do_PVK_body(&p, saltlen, keylen, cb, u);
+
+	err:
+	if (buf)
+		{
+		OPENSSL_cleanse(buf, buflen);
+		OPENSSL_free(buf);
+		}
+	return ret;
+	}
+
+	
+	
+static int i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel,
+		pem_password_cb *cb, void *u)
+	{
+	int outlen = 24, noinc, pklen;
+	unsigned char *p, *salt = NULL;
+	if (enclevel)
+		outlen += PVK_SALTLEN;
+	pklen = do_i2b(NULL, pk, 0);
+	if (pklen < 0)
+		return -1;
+	outlen += pklen;
+	if (!out)
+		return outlen;
+	if (*out)
+		{
+		p = *out;
+		noinc = 0;
+		}
+	else
+		{
+		p = OPENSSL_malloc(outlen);
+		if (!p)
+			{
+			PEMerr(PEM_F_I2B_PVK,ERR_R_MALLOC_FAILURE);
+			return -1;
+			}
+		*out = p;
+		noinc = 1;
+		}
+
+	write_ledword(&p, MS_PVKMAGIC);
+	write_ledword(&p, 0);
+	if (pk->type == EVP_PKEY_DSA)
+		write_ledword(&p, MS_KEYTYPE_SIGN);
+	else
+		write_ledword(&p, MS_KEYTYPE_KEYX);
+	write_ledword(&p, enclevel ? 1 : 0);
+	write_ledword(&p, enclevel ? PVK_SALTLEN: 0);
+	write_ledword(&p, pklen);
+	if (enclevel)
+		{
+		if (RAND_bytes(p, PVK_SALTLEN) <= 0)
+			goto error;
+		salt = p;
+		p += PVK_SALTLEN;
+		}
+	do_i2b(&p, pk, 0);
+	if (enclevel == 0)
+		return outlen;
+	else
+		{
+		char psbuf[PEM_BUFSIZE];
+		unsigned char keybuf[20];
+		EVP_CIPHER_CTX cctx;
+		int enctmplen, inlen;
+		if (cb)
+			inlen=cb(psbuf,PEM_BUFSIZE,1,u);
+		else
+			inlen=PEM_def_callback(psbuf,PEM_BUFSIZE,1,u);
+		if (inlen <= 0)
+			{
+			PEMerr(PEM_F_I2B_PVK,PEM_R_BAD_PASSWORD_READ);
+			goto error;
+			}
+		if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN,
+			    (unsigned char *)psbuf, inlen))
+			goto error;
+		if (enclevel == 1)
+			memset(keybuf + 5, 0, 11);
+		p = salt + PVK_SALTLEN + 8;
+		EVP_CIPHER_CTX_init(&cctx);
+		EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL);
+		OPENSSL_cleanse(keybuf, 20);
+		EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8);
+		EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen);
+		EVP_CIPHER_CTX_cleanup(&cctx);
+		}
+	return outlen;
+
+	error:
+	return -1;
+	}
+
+int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
+		pem_password_cb *cb, void *u)
+	{
+	unsigned char *tmp = NULL;
+	int outlen, wrlen;
+	outlen = i2b_PVK(&tmp, pk, enclevel, cb, u);
+	if (outlen < 0)
+		return -1;
+	wrlen = BIO_write(out, tmp, outlen);
+	OPENSSL_free(tmp);
+	if (wrlen == outlen)
+		{
+		PEMerr(PEM_F_I2B_PVK_BIO, PEM_R_BIO_WRITE_FAILURE);
+		return outlen;
+		}
+	return -1;
+	}
+#endif
diff --git a/crypto/perlasm/ppc-xlate.pl b/crypto/perlasm/ppc-xlate.pl
new file mode 100755
index 0000000..4579671
--- /dev/null
+++ b/crypto/perlasm/ppc-xlate.pl
@@ -0,0 +1,152 @@
+#!/usr/bin/env perl
+
+# PowerPC assembler distiller by <appro>.
+
+my $flavour = shift;
+my $output = shift;
+open STDOUT,">$output" || die "can't open $output: $!";
+
+my %GLOBALS;
+my $dotinlocallabels=($flavour=~/linux/)?1:0;
+
+################################################################
+# directives which need special treatment on different platforms
+################################################################
+my $globl = sub {
+    my $junk = shift;
+    my $name = shift;
+    my $global = \$GLOBALS{$name};
+    my $ret;
+
+    $name =~ s|^[\.\_]||;
+ 
+    SWITCH: for ($flavour) {
+	/aix/		&& do { $name = ".$name";
+				last;
+			      };
+	/osx/		&& do { $name = "_$name";
+				last;
+			      };
+	/linux.*32/	&& do {	$ret .= ".globl	$name\n";
+				$ret .= ".type	$name,\@function";
+				last;
+			      };
+	/linux.*64/	&& do {	$ret .= ".globl	.$name\n";
+				$ret .= ".type	.$name,\@function\n";
+				$ret .= ".section	\".opd\",\"aw\"\n";
+				$ret .= ".globl	$name\n";
+				$ret .= ".align	3\n";
+				$ret .= "$name:\n";
+				$ret .= ".quad	.$name,.TOC.\@tocbase,0\n";
+				$ret .= ".size	$name,24\n";
+				$ret .= ".previous\n";
+
+				$name = ".$name";
+				last;
+			      };
+    }
+
+    $ret = ".globl	$name" if (!$ret);
+    $$global = $name;
+    $ret;
+};
+my $text = sub {
+    ($flavour =~ /aix/) ? ".csect" : ".text";
+};
+my $machine = sub {
+    my $junk = shift;
+    my $arch = shift;
+    if ($flavour =~ /osx/)
+    {	$arch =~ s/\"//g;
+	$arch = ($flavour=~/64/) ? "ppc970-64" : "ppc970" if ($arch eq "any");
+    }
+    ".machine	$arch";
+};
+my $asciz = sub {
+    shift;
+    my $line = join(",",@_);
+    if ($line =~ /^"(.*)"$/)
+    {	".byte	" . join(",",unpack("C*",$1),0) . "\n.align	2";	}
+    else
+    {	"";	}
+};
+
+################################################################
+# simplified mnemonics not handled by at least one assembler
+################################################################
+my $cmplw = sub {
+    my $f = shift;
+    my $cr = 0; $cr = shift if ($#_>1);
+    # Some out-of-date 32-bit GNU assembler just can't handle cmplw...
+    ($flavour =~ /linux.*32/) ?
+	"	.long	".sprintf "0x%x",31<<26|$cr<<23|$_[0]<<16|$_[1]<<11|64 :
+	"	cmplw	".join(',',$cr,@_);
+};
+my $bdnz = sub {
+    my $f = shift;
+    my $bo = $f=~/[\+\-]/ ? 16+9 : 16;	# optional "to be taken" hint
+    "	bc	$bo,0,".shift;
+} if ($flavour!~/linux/);
+my $bltlr = sub {
+    my $f = shift;
+    my $bo = $f=~/\-/ ? 12+2 : 12;	# optional "not to be taken" hint
+    ($flavour =~ /linux/) ?		# GNU as doesn't allow most recent hints
+	"	.long	".sprintf "0x%x",19<<26|$bo<<21|16<<1 :
+	"	bclr	$bo,0";
+};
+my $bnelr = sub {
+    my $f = shift;
+    my $bo = $f=~/\-/ ? 4+2 : 4;	# optional "not to be taken" hint
+    ($flavour =~ /linux/) ?		# GNU as doesn't allow most recent hints
+	"	.long	".sprintf "0x%x",19<<26|$bo<<21|2<<16|16<<1 :
+	"	bclr	$bo,2";
+};
+my $beqlr = sub {
+    my $f = shift;
+    my $bo = $f=~/-/ ? 12+2 : 12;	# optional "not to be taken" hint
+    ($flavour =~ /linux/) ?		# GNU as doesn't allow most recent hints
+	"	.long	".sprintf "0x%X",19<<26|$bo<<21|2<<16|16<<1 :
+	"	bclr	$bo,2";
+};
+# GNU assembler can't handle extrdi rA,rS,16,48, or when sum of last two
+# arguments is 64, with "operand out of range" error.
+my $extrdi = sub {
+    my ($f,$ra,$rs,$n,$b) = @_;
+    $b = ($b+$n)&63; $n = 64-$n;
+    "	rldicl	$ra,$rs,$b,$n";
+};
+
+while($line=<>) {
+
+    $line =~ s|[#!;].*$||;	# get rid of asm-style comments...
+    $line =~ s|/\*.*\*/||;	# ... and C-style comments...
+    $line =~ s|^\s+||;		# ... and skip white spaces in beginning...
+    $line =~ s|\s+$||;		# ... and at the end
+
+    {
+	$line =~ s|\b\.L(\w+)|L$1|g;	# common denominator for Locallabel
+	$line =~ s|\bL(\w+)|\.L$1|g	if ($dotinlocallabels);
+    }
+
+    {
+	$line =~ s|(^[\.\w]+)\:\s*||;
+	my $label = $1;
+	printf "%s:",($GLOBALS{$label} or $label) if ($label);
+    }
+
+    {
+	$line =~ s|^\s*(\.?)(\w+)([\.\+\-]?)\s*||;
+	my $c = $1; $c = "\t" if ($c eq "");
+	my $mnemonic = $2;
+	my $f = $3;
+	my $opcode = eval("\$$mnemonic");
+	$line =~ s|\bc?[rf]([0-9]+)\b|$1|g if ($c ne "." and $flavour !~ /osx/);
+	if (ref($opcode) eq 'CODE') { $line = &$opcode($f,split(',',$line)); }
+	elsif ($mnemonic)           { $line = $c.$mnemonic.$f."\t".$line; }
+    }
+
+    print $line if ($line);
+    print "\n";
+}
+
+close STDOUT;
diff --git a/crypto/perlasm/x86_64-xlate.pl b/crypto/perlasm/x86_64-xlate.pl
index fe348b9..d89765d 100755
--- a/crypto/perlasm/x86_64-xlate.pl
+++ b/crypto/perlasm/x86_64-xlate.pl
@@ -1,6 +1,6 @@
 #!/usr/bin/env perl
 
-# Ascetic x86_64 AT&T to MASM assembler translator by <appro>.
+# Ascetic x86_64 AT&T to MASM/NASM assembler translator by <appro>.
 #
 # Why AT&T to MASM and not vice versa? Several reasons. Because AT&T
 # format is way easier to parse. Because it's simpler to "gear" from
@@ -20,12 +20,11 @@
 # Currently recognized limitations:
 #
 # - can't use multiple ops per line;
-# - indirect calls and jumps are not supported;
 #
 # Dual-ABI styling rules.
 #
-# 1. Adhere to Unix register and stack layout [see the end for
-#    explanation].
+# 1. Adhere to Unix register and stack layout [see cross-reference
+#    ABI "card" at the end for explanation].
 # 2. Forget about "red zone," stick to more traditional blended
 #    stack frame allocation. If volatile storage is actually required
 #    that is. If not, just leave the stack as is.
@@ -42,21 +41,24 @@
 # 6. Don't use [or hand-code with .byte] "rep ret." "ret" mnemonic is
 #    required to identify the spots, where to inject Win64 epilogue!
 #    But on the pros, it's then prefixed with rep automatically:-)
-# 7. Due to MASM limitations [and certain general counter-intuitivity
-#    of ip-relative addressing] generation of position-independent
-#    code is assisted by synthetic directive, .picmeup, which puts
-#    address of the *next* instruction into target register.
+# 7. Stick to explicit ip-relative addressing. If you have to use
+#    GOTPCREL addressing, stick to mov symbol@GOTPCREL(%rip),%r??.
+#    Both are recognized and translated to proper Win64 addressing
+#    modes. To support legacy code a synthetic directive, .picmeup,
+#    is implemented. It puts address of the *next* instruction into
+#    target register, e.g.:
 #
-#    Example 1:
 #		.picmeup	%rax
 #		lea		.Label-.(%rax),%rax
-#    Example 2:
-#		.picmeup	%rcx
-#	.Lpic_point:
-#		...
-#		lea		.Label-.Lpic_point(%rcx),%rbp
-
-my $output = shift;
+#
+# 8. In order to provide for structured exception handling unified
+#    Win64 prologue copies %rsp value to %rax. For further details
+#    see SEH paragraph at the end.
+# 9. .init segment is allowed to contain calls to functions only.
+
+my $flavour = shift;
+my $output  = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
 
 { my ($stddev,$stdino,@junk)=stat(STDOUT);
   my ($outdev,$outino,@junk)=stat($output);
@@ -65,13 +67,37 @@
 	if ($stddev!=$outdev || $stdino!=$outino);
 }
 
+my $gas=1;	$gas=0 if ($output =~ /\.asm$/);
+my $elf=1;	$elf=0 if (!$gas);
+my $win64=0;
+my $prefix="";
+my $decor=".L";
+
 my $masmref=8 + 50727*2**-32;	# 8.00.50727 shipped with VS2005
-my $masm=$masmref if ($output =~ /\.asm/);
-if ($masm && `ml64 2>&1` =~ m/Version ([0-9]+)\.([0-9]+)(\.([0-9]+))?/)
-{   $masm=$1 + $2*2**-16 + $4*2**-32;   }
+my $masm=0;
+my $PTR=" PTR";
+
+my $nasmref=2.03;
+my $nasm=0;
+
+if    ($flavour eq "mingw64")	{ $gas=1; $elf=0; $win64=1; $prefix="_"; }
+elsif ($flavour eq "macosx")	{ $gas=1; $elf=0; $prefix="_"; $decor="L\$"; }
+elsif ($flavour eq "masm")	{ $gas=0; $elf=0; $masm=$masmref; $win64=1; $decor="\$L\$"; }
+elsif ($flavour eq "nasm")	{ $gas=0; $elf=0; $nasm=$nasmref; $win64=1; $decor="\$L\$"; $PTR=""; }
+elsif (!$gas)
+{   if ($ENV{ASM} =~ m/nasm/ && `nasm -v` =~ m/version ([0-9]+)\.([0-9]+)/i)
+    {	$nasm = $1 + $2*0.01; $PTR="";  }
+    elsif (`ml64 2>&1` =~ m/Version ([0-9]+)\.([0-9]+)(\.([0-9]+))?/)
+    {	$masm = $1 + $2*2**-16 + $4*2**-32;   }
+    die "no assembler found on %PATH" if (!($nasm || $masm));
+    $win64=1;
+    $elf=0;
+    $decor="\$L\$";
+}
 
 my $current_segment;
 my $current_function;
+my %globals;
 
 { package opcode;	# pick up opcodes
     sub re {
@@ -88,7 +114,7 @@
 	    if ($self->{op} =~ /^(movz)b.*/) {	# movz is pain...
 		$self->{op} = $1;
 		$self->{sz} = "b";
-	    } elsif ($self->{op} =~ /call/) {
+	    } elsif ($self->{op} =~ /call|jmp/) {
 		$self->{sz} = ""
 	    } elsif ($self->{op} =~ /([a-z]{3,})([qlwb])$/) {
 		$self->{op} = $1;
@@ -105,13 +131,20 @@
     }
     sub out {
 	my $self = shift;
-	if (!$masm) {
+	if ($gas) {
 	    if ($self->{op} eq "movz") {	# movz is pain...
 		sprintf "%s%s%s",$self->{op},$self->{sz},shift;
 	    } elsif ($self->{op} =~ /^set/) { 
 		"$self->{op}";
 	    } elsif ($self->{op} eq "ret") {
-	    	".byte	0xf3,0xc3";
+		my $epilogue = "";
+		if ($win64 && $current_function->{abi} eq "svr4") {
+		    $epilogue = "movq	8(%rsp),%rdi\n\t" .
+				"movq	16(%rsp),%rsi\n\t";
+		}
+	    	$epilogue . ".byte	0xf3,0xc3";
+	    } elsif ($self->{op} eq "call" && !$elf && $current_segment eq ".init") {
+		".p2align\t3\n\t.quad";
 	    } else {
 		"$self->{op}$self->{sz}";
 	    }
@@ -119,15 +152,25 @@
 	    $self->{op} =~ s/^movz/movzx/;
 	    if ($self->{op} eq "ret") {
 		$self->{op} = "";
-		if ($current_function->{abi} eq "svr4") {
-		    $self->{op} = "mov	rdi,QWORD PTR 8[rsp]\t;WIN64 epilogue\n\t".
-				  "mov	rsi,QWORD PTR 16[rsp]\n\t";
+		if ($win64 && $current_function->{abi} eq "svr4") {
+		    $self->{op} = "mov	rdi,QWORD${PTR}[8+rsp]\t;WIN64 epilogue\n\t".
+				  "mov	rsi,QWORD${PTR}[16+rsp]\n\t";
 	    	}
 		$self->{op} .= "DB\t0F3h,0C3h\t\t;repret";
-	    }
+	    } elsif ($self->{op} =~ /^(pop|push)f/) {
+		$self->{op} .= $self->{sz};
+	    } elsif ($self->{op} eq "call" && $current_segment eq ".CRT\$XCU") {
+		$self->{op} = "ALIGN\t8\n\tDQ";
+	    } 
 	    $self->{op};
 	}
     }
+    sub mnemonic {
+	my $self=shift;
+	my $op=shift;
+	$self->{op}=$op if (defined($op));
+	$self->{op};
+    }
 }
 { package const;	# pick up constants, which start with $
     sub re {
@@ -145,14 +188,15 @@
     sub out {
     	my $self = shift;
 
-	if (!$masm) {
+	if ($gas) {
 	    # Solaris /usr/ccs/bin/as can't handle multiplications
 	    # in $self->{value}
 	    $self->{value} =~ s/(?<![0-9a-f])(0[x0-9a-f]+)/oct($1)/egi;
 	    $self->{value} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg;
 	    sprintf "\$%s",$self->{value};
 	} else {
-	    $self->{value} =~ s/0x([0-9a-f]+)/0$1h/ig;
+	    $self->{value} =~ s/(0b[0-1]+)/oct($1)/eig;
+	    $self->{value} =~ s/0x([0-9a-f]+)/0$1h/ig if ($masm);
 	    sprintf "%s",$self->{value};
 	}
     }
@@ -163,13 +207,19 @@
 	local	*line = shift;
 	undef	$ret;
 
-	if ($line =~ /^([^\(,]*)\(([%\w,]+)\)/) {
-	    $self->{label} = $1;
-	    ($self->{base},$self->{index},$self->{scale})=split(/,/,$2);
+	# optional * ---vvv--- appears in indirect jmp/call
+	if ($line =~ /^(\*?)([^\(,]*)\(([%\w,]+)\)/) {
+	    $self->{asterisk} = $1;
+	    $self->{label} = $2;
+	    ($self->{base},$self->{index},$self->{scale})=split(/,/,$3);
 	    $self->{scale} = 1 if (!defined($self->{scale}));
 	    $ret = $self;
 	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
 
+	    if ($win64 && $self->{label} =~ s/\@GOTPCREL//) {
+		die if (opcode->mnemonic() ne "mov");
+		opcode->mnemonic("lea");
+	    }
 	    $self->{base}  =~ s/^%//;
 	    $self->{index} =~ s/^%// if (defined($self->{index}));
 	}
@@ -180,44 +230,50 @@
     	my $self = shift;
 	my $sz = shift;
 
+	$self->{label} =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
+	$self->{label} =~ s/\.L/$decor/g;
+
 	# Silently convert all EAs to 64-bit. This is required for
 	# elder GNU assembler and results in more compact code,
 	# *but* most importantly AES module depends on this feature!
 	$self->{index} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/;
 	$self->{base}  =~ s/^[er](.?[0-9xpi])[d]?$/r\1/;
 
-	if (!$masm) {
+	if ($gas) {
 	    # Solaris /usr/ccs/bin/as can't handle multiplications
-	    # in $self->{label}
+	    # in $self->{label}, new gas requires sign extension...
 	    use integer;
 	    $self->{label} =~ s/(?<![0-9a-f])(0[x0-9a-f]+)/oct($1)/egi;
 	    $self->{label} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg;
 	    $self->{label} =~ s/([0-9]+)/$1<<32>>32/eg;
+	    $self->{label} =~ s/^___imp_/__imp__/   if ($flavour eq "mingw64");
 
 	    if (defined($self->{index})) {
-		sprintf "%s(%%%s,%%%s,%d)",
+		sprintf "%s%s(%%%s,%%%s,%d)",$self->{asterisk},
 					$self->{label},$self->{base},
 					$self->{index},$self->{scale};
 	    } else {
-		sprintf "%s(%%%s)",	$self->{label},$self->{base};
+		sprintf "%s%s(%%%s)",	$self->{asterisk},$self->{label},$self->{base};
 	    }
 	} else {
-	    %szmap = ( b=>"BYTE", w=>"WORD", l=>"DWORD", q=>"QWORD" );
+	    %szmap = ( b=>"BYTE$PTR", w=>"WORD$PTR", l=>"DWORD$PTR", q=>"QWORD$PTR" );
 
 	    $self->{label} =~ s/\./\$/g;
 	    $self->{label} =~ s/0x([0-9a-f]+)/0$1h/ig;
 	    $self->{label} = "($self->{label})" if ($self->{label} =~ /[\*\+\-\/]/);
+	    $sz="q" if ($self->{asterisk});
 
 	    if (defined($self->{index})) {
-		sprintf "%s PTR %s[%s*%d+%s]",$szmap{$sz},
-					$self->{label},
+		sprintf "%s[%s%s*%d+%s]",$szmap{$sz},
+					$self->{label}?"$self->{label}+":"",
 					$self->{index},$self->{scale},
 					$self->{base};
 	    } elsif ($self->{base} eq "rip") {
-		sprintf "%s PTR %s",$szmap{$sz},$self->{label};
+		sprintf "%s[%s]",$szmap{$sz},$self->{label};
 	    } else {
-		sprintf "%s PTR %s[%s]",$szmap{$sz},
-					$self->{label},$self->{base};
+		sprintf "%s[%s%s]",$szmap{$sz},
+					$self->{label}?"$self->{label}+":"",
+					$self->{base};
 	    }
 	}
     }
@@ -229,9 +285,11 @@
 	local	*line = shift;
 	undef	$ret;
 
-	if ($line =~ /^%(\w+)/) {
+	# optional * ---vvv--- appears in indirect jmp/call
+	if ($line =~ /^(\*?)%(\w+)/) {
 	    bless $self,$class;
-	    $self->{value} = $1;
+	    $self->{asterisk} = $1;
+	    $self->{value} = $2;
 	    $ret = $self;
 	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
 	}
@@ -254,7 +312,8 @@
     }
     sub out {
     	my $self = shift;
-	sprintf $masm?"%s":"%%%s",$self->{value};
+	if ($gas)	{ sprintf "%s%%%s",$self->{asterisk},$self->{value}; }
+	else		{ $self->{value}; }
     }
 }
 { package label;	# pick up labels, which end with :
@@ -263,37 +322,63 @@
 	local	*line = shift;
 	undef	$ret;
 
-	if ($line =~ /(^[\.\w]+\:)/) {
+	if ($line =~ /(^[\.\w]+)\:/) {
 	    $self->{value} = $1;
 	    $ret = $self;
 	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
 
-	    $self->{value} =~ s/\.L/\$L/ if ($masm);
+	    $self->{value} =~ s/^\.L/$decor/;
 	}
 	$ret;
     }
     sub out {
 	my $self = shift;
 
-	if (!$masm) {
-	    $self->{value};
-	} elsif ($self->{value} ne "$current_function->{name}:") {
-	    $self->{value};
-	} elsif ($current_function->{abi} eq "svr4") {
-	    my $func =	"$current_function->{name}	PROC\n".
-			"	mov	QWORD PTR 8[rsp],rdi\t;WIN64 prologue\n".
-			"	mov	QWORD PTR 16[rsp],rsi\n";
+	if ($gas) {
+	    my $func = ($globals{$self->{value}} or $self->{value}) . ":";
+	    if ($win64	&&
+			$current_function->{name} eq $self->{value} &&
+			$current_function->{abi} eq "svr4") {
+		$func .= "\n";
+		$func .= "	movq	%rdi,8(%rsp)\n";
+		$func .= "	movq	%rsi,16(%rsp)\n";
+		$func .= "	movq	%rsp,%rax\n";
+		$func .= "${decor}SEH_begin_$current_function->{name}:\n";
+		my $narg = $current_function->{narg};
+		$narg=6 if (!defined($narg));
+		$func .= "	movq	%rcx,%rdi\n" if ($narg>0);
+		$func .= "	movq	%rdx,%rsi\n" if ($narg>1);
+		$func .= "	movq	%r8,%rdx\n"  if ($narg>2);
+		$func .= "	movq	%r9,%rcx\n"  if ($narg>3);
+		$func .= "	movq	40(%rsp),%r8\n" if ($narg>4);
+		$func .= "	movq	48(%rsp),%r9\n" if ($narg>5);
+	    }
+	    $func;
+	} elsif ($self->{value} ne "$current_function->{name}") {
+	    $self->{value} .= ":" if ($masm && $ret!~m/^\$/);
+	    $self->{value} . ":";
+	} elsif ($win64 && $current_function->{abi} eq "svr4") {
+	    my $func =	"$current_function->{name}" .
+			($nasm ? ":" : "\tPROC $current_function->{scope}") .
+			"\n";
+	    $func .= "	mov	QWORD${PTR}[8+rsp],rdi\t;WIN64 prologue\n";
+	    $func .= "	mov	QWORD${PTR}[16+rsp],rsi\n";
+	    $func .= "	mov	rax,rsp\n";
+	    $func .= "${decor}SEH_begin_$current_function->{name}:";
+	    $func .= ":" if ($masm);
+	    $func .= "\n";
 	    my $narg = $current_function->{narg};
 	    $narg=6 if (!defined($narg));
 	    $func .= "	mov	rdi,rcx\n" if ($narg>0);
 	    $func .= "	mov	rsi,rdx\n" if ($narg>1);
 	    $func .= "	mov	rdx,r8\n"  if ($narg>2);
 	    $func .= "	mov	rcx,r9\n"  if ($narg>3);
-	    $func .= "	mov	r8,QWORD PTR 40[rsp]\n" if ($narg>4);
-	    $func .= "	mov	r9,QWORD PTR 48[rsp]\n" if ($narg>5);
+	    $func .= "	mov	r8,QWORD${PTR}[40+rsp]\n" if ($narg>4);
+	    $func .= "	mov	r9,QWORD${PTR}[48+rsp]\n" if ($narg>5);
 	    $func .= "\n";
 	} else {
-	   "$current_function->{name}	PROC";
+	   "$current_function->{name}".
+			($nasm ? ":" : "\tPROC $current_function->{scope}");
 	}
     }
 }
@@ -308,13 +393,19 @@
 	    $ret = $self;
 	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
 
-	    $self->{value} =~ s/\.L/\$L/g if ($masm);
+	    $self->{value} =~ s/\@PLT// if (!$elf);
+	    $self->{value} =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
+	    $self->{value} =~ s/\.L/$decor/g;
 	}
 	$ret;
     }
     sub out {
 	my $self = shift;
-	$self->{value};
+	if ($nasm && opcode->mnemonic()=~m/^j/) {
+	    "NEAR ".$self->{value};
+	} else {
+	    $self->{value};
+	}
     }
 }
 { package directive;	# pick up directives, which start with .
@@ -334,89 +425,181 @@
 			"%r14"=>0x01358d4c,	"%r15"=>0x013d8d4c	);
 
 	if ($line =~ /^\s*(\.\w+)/) {
-	    if (!$masm) {
-		$self->{value} = $1;
-		$line =~ s/\@abi\-omnipotent/\@function/;
-		$line =~ s/\@function.*/\@function/;
-		if ($line =~ /\.picmeup\s+(%r[\w]+)/i) {
-		    $self->{value} = sprintf "\t.long\t0x%x,0x90000000",$opcode{$1};
-		} elsif ($line =~ /\.asciz\s+"(.*)"$/) {
-		    $self->{value} = ".byte\t".join(",",unpack("C*",$1),0);
-		} elsif ($line =~ /\.extern/) {
-		    $self->{value} = ""; # swallow extern
-		} else {
-		    $self->{value} = $line;
-		}
-		$line = "";
-		return $self;
-	    }
-
 	    $dir = $1;
 	    $ret = $self;
 	    undef $self->{value};
 	    $line = substr($line,@+[0]); $line =~ s/^\s+//;
+
 	    SWITCH: for ($dir) {
-		/\.(text)/
-			    && do { my $v=undef;
-				    $v="$current_segment\tENDS\n" if ($current_segment);
-				    $current_segment = "_$1\$";
-				    $current_segment =~ tr/[a-z]/[A-Z]/;
-				    $v.="$current_segment\tSEGMENT ";
-				    $v.=$masm>=$masmref ? "ALIGN(64)" : "PAGE";
-				    $v.=" 'CODE'";
-				    $self->{value} = $v;
+		/\.picmeup/ && do { if ($line =~ /(%r[\w]+)/i) {
+			    		$dir="\t.long";
+					$line=sprintf "0x%x,0x90000000",$opcode{$1};
+				    }
 				    last;
 				  };
-		/\.extern/  && do { $self->{value} = "EXTRN\t".$line.":BYTE"; last;  };
-		/\.globl/   && do { $self->{value} = "PUBLIC\t".$line; last; };
+		/\.global|\.globl|\.extern/
+			    && do { $globals{$line} = $prefix . $line;
+				    $line = $globals{$line} if ($prefix);
+				    last;
+				  };
 		/\.type/    && do { ($sym,$type,$narg) = split(',',$line);
 				    if ($type eq "\@function") {
 					undef $current_function;
 					$current_function->{name} = $sym;
 					$current_function->{abi}  = "svr4";
 					$current_function->{narg} = $narg;
+					$current_function->{scope} = defined($globals{$sym})?"PUBLIC":"PRIVATE";
 				    } elsif ($type eq "\@abi-omnipotent") {
 					undef $current_function;
 					$current_function->{name} = $sym;
+					$current_function->{scope} = defined($globals{$sym})?"PUBLIC":"PRIVATE";
+				    }
+				    $line =~ s/\@abi\-omnipotent/\@function/;
+				    $line =~ s/\@function.*/\@function/;
+				    last;
+				  };
+		/\.asciz/   && do { if ($line =~ /^"(.*)"$/) {
+					$dir  = ".byte";
+					$line = join(",",unpack("C*",$1),0);
 				    }
 				    last;
 				  };
+		/\.rva|\.long|\.quad/
+			    && do { $line =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
+				    $line =~ s/\.L/$decor/g;
+				    last;
+				  };
+	    }
+
+	    if ($gas) {
+		$self->{value} = $dir . "\t" . $line;
+
+		if ($dir =~ /\.extern/) {
+		    $self->{value} = ""; # swallow extern
+		} elsif (!$elf && $dir =~ /\.type/) {
+		    $self->{value} = "";
+		    $self->{value} = ".def\t" . ($globals{$1} or $1) . ";\t" .
+				(defined($globals{$1})?".scl 2;":".scl 3;") .
+				"\t.type 32;\t.endef"
+				if ($win64 && $line =~ /([^,]+),\@function/);
+		} elsif (!$elf && $dir =~ /\.size/) {
+		    $self->{value} = "";
+		    if (defined($current_function)) {
+			$self->{value} .= "${decor}SEH_end_$current_function->{name}:"
+				if ($win64 && $current_function->{abi} eq "svr4");
+			undef $current_function;
+		    }
+		} elsif (!$elf && $dir =~ /\.align/) {
+		    $self->{value} = ".p2align\t" . (log($line)/log(2));
+		} elsif ($dir eq ".section") {
+		    $current_segment=$line;
+		    if (!$elf && $current_segment eq ".init") {
+			if	($flavour eq "macosx")	{ $self->{value} = ".mod_init_func"; }
+			elsif	($flavour eq "mingw64")	{ $self->{value} = ".section\t.ctors"; }
+		    }
+		} elsif ($dir =~ /\.(text|data)/) {
+		    $current_segment=".$1";
+		}
+		$line = "";
+		return $self;
+	    }
+
+	    # non-gas case or nasm/masm
+	    SWITCH: for ($dir) {
+		/\.text/    && do { my $v=undef;
+				    if ($nasm) {
+					$v="section	.text code align=64\n";
+				    } else {
+					$v="$current_segment\tENDS\n" if ($current_segment);
+					$current_segment = ".text\$";
+					$v.="$current_segment\tSEGMENT ";
+					$v.=$masm>=$masmref ? "ALIGN(64)" : "PAGE";
+					$v.=" 'CODE'";
+				    }
+				    $self->{value} = $v;
+				    last;
+				  };
+		/\.data/    && do { my $v=undef;
+				    if ($nasm) {
+					$v="section	.data data align=8\n";
+				    } else {
+					$v="$current_segment\tENDS\n" if ($current_segment);
+					$current_segment = "_DATA";
+					$v.="$current_segment\tSEGMENT";
+				    }
+				    $self->{value} = $v;
+				    last;
+				  };
+		/\.section/ && do { my $v=undef;
+				    $line =~ s/([^,]*).*/$1/;
+				    $line = ".CRT\$XCU" if ($line eq ".init");
+				    if ($nasm) {
+					$v="section	$line";
+					if ($line=~/\.([px])data/) {
+					    $v.=" rdata align=";
+					    $v.=$1 eq "p"? 4 : 8;
+					}
+				    } else {
+					$v="$current_segment\tENDS\n" if ($current_segment);
+					$v.="$line\tSEGMENT";
+					if ($line=~/\.([px])data/) {
+					    $v.=" READONLY";
+					    $v.=" ALIGN(".($1 eq "p" ? 4 : 8).")" if ($masm>=$masmref);
+					}
+				    }
+				    $current_segment = $line;
+				    $self->{value} = $v;
+				    last;
+				  };
+		/\.extern/  && do { $self->{value}  = "EXTERN\t".$line;
+				    $self->{value} .= ":NEAR" if ($masm);
+				    last;
+				  };
+		/\.globl|.global/
+			    && do { $self->{value}  = $masm?"PUBLIC":"global";
+				    $self->{value} .= "\t".$line;
+				    last;
+				  };
 		/\.size/    && do { if (defined($current_function)) {
-					$self->{value}="$current_function->{name}\tENDP";
+					undef $self->{value};
+					if ($current_function->{abi} eq "svr4") {
+					    $self->{value}="${decor}SEH_end_$current_function->{name}:";
+					    $self->{value}.=":\n" if($masm);
+					}
+					$self->{value}.="$current_function->{name}\tENDP" if($masm);
 					undef $current_function;
 				    }
 				    last;
 				  };
 		/\.align/   && do { $self->{value} = "ALIGN\t".$line; last; };
-		/\.(byte|value|long|quad)/
-			    && do { my @arr = split(',',$line);
-				    my $sz  = substr($1,0,1);
+		/\.(value|long|rva|quad)/
+			    && do { my $sz  = substr($1,0,1);
+				    my @arr = split(',',$line);
 				    my $last = pop(@arr);
 				    my $conv = sub  {	my $var=shift;
-							if ($var=~s/0x([0-9a-f]+)/0$1h/i) { $var; }
-							else { sprintf"0%Xh",$var; }
+							$var=~s/^(0b[0-1]+)/oct($1)/eig;
+							$var=~s/0x([0-9a-f]+)/0$1h/ig if ($masm);
+							if ($sz eq "D" && ($current_segment=~/.[px]data/ || $dir eq ".rva"))
+							{ $var=~s/([_a-z\$\@][_a-z0-9\$\@]*)/$nasm?"$1 wrt ..imagebase":"imagerel $1"/egi; }
+							$var;
 						    };  
 
-				    $sz =~ tr/bvlq/BWDQ/;
+				    $sz =~ tr/bvlrq/BWDDQ/;
 				    $self->{value} = "\tD$sz\t";
 				    for (@arr) { $self->{value} .= &$conv($_).","; }
 				    $self->{value} .= &$conv($last);
 				    last;
 				  };
-		/\.picmeup/ && do { $self->{value} = sprintf"\tDD\t 0%Xh,090000000h",$opcode{$line};
-				    last;
-				  };
-		/\.asciz/   && do { if ($line =~ /^"(.*)"$/) {
-					my @str=unpack("C*",$1);
-					push @str,0;
-					while ($#str>15) {
-					    $self->{value}.="DB\t"
-						.join(",",@str[0..15])."\n";
-					    foreach (0..15) { shift @str; }
-					}
+		/\.byte/    && do { my @str=split(",",$line);
+				    map(s/(0b[0-1]+)/oct($1)/eig,@str);
+				    map(s/0x([0-9a-f]+)/0$1h/ig,@str) if ($masm);	
+				    while ($#str>15) {
 					$self->{value}.="DB\t"
-						.join(",",@str) if (@str);
+						.join(",",@str[0..15])."\n";
+					foreach (0..15) { shift @str; }
 				    }
+				    $self->{value}.="DB\t"
+						.join(",",@str) if (@str);
 				    last;
 				  };
 	    }
@@ -431,6 +614,15 @@
     }
 }
 
+if ($nasm) {
+    print <<___;
+default	rel
+___
+} elsif ($masm) {
+    print <<___;
+OPTION	DOTNAME
+___
+}
 while($line=<>) {
 
     chomp($line);
@@ -441,43 +633,42 @@
 
     undef $label;
     undef $opcode;
-    undef $dst;
-    undef $src;
     undef $sz;
+    undef @args;
 
     if ($label=label->re(\$line))	{ print $label->out(); }
 
     if (directive->re(\$line)) {
 	printf "%s",directive->out();
-    } elsif ($opcode=opcode->re(\$line)) { ARGUMENT: {
+    } elsif ($opcode=opcode->re(\$line)) { ARGUMENT: while (1) {
+	my $arg;
 
-	if ($src=register->re(\$line))	{ opcode->size($src->size()); }
-	elsif ($src=const->re(\$line))	{ }
-	elsif ($src=ea->re(\$line))	{ }
-	elsif ($src=expr->re(\$line))	{ }
+	if ($arg=register->re(\$line))	{ opcode->size($arg->size()); }
+	elsif ($arg=const->re(\$line))	{ }
+	elsif ($arg=ea->re(\$line))	{ }
+	elsif ($arg=expr->re(\$line))	{ }
+	else				{ last ARGUMENT; }
+
+	push @args,$arg;
 
 	last ARGUMENT if ($line !~ /^,/);
 
-	$line = substr($line,1); $line =~ s/^\s+//;
-
-	if ($dst=register->re(\$line))	{ opcode->size($dst->size()); }
-	elsif ($dst=const->re(\$line))	{ }
-	elsif ($dst=ea->re(\$line))	{ }
-
+	$line =~ s/^,\s*//;
 	} # ARGUMENT:
 
 	$sz=opcode->size();
 
-	if (defined($dst)) {
-	    if (!$masm) {
-		printf "\t%s\t%s,%s",	$opcode->out($dst->size()),
-					$src->out($sz),$dst->out($sz);
+	if ($#args>=0) {
+	    my $insn;
+	    if ($gas) {
+		$insn = $opcode->out($#args>=1?$args[$#args]->size():$sz);
 	    } else {
-		printf "\t%s\t%s,%s",	$opcode->out(),
-					$dst->out($sz),$src->out($sz);
+		$insn = $opcode->out();
+		$insn .= $sz if (map($_->out() =~ /xmm|mmx/,@args));
+		@args = reverse(@args);
+		undef $sz if ($nasm && $opcode->mnemonic() eq "lea");
 	    }
-	} elsif (defined($src)) {
-	    printf "\t%s\t%s",$opcode->out(),$src->out($sz);
+	    printf "\t%s\t%s",$insn,join(",",map($_->out($sz),@args));
 	} else {
 	    printf "\t%s",$opcode->out();
 	}
@@ -486,11 +677,12 @@
     print $line,"\n";
 }
 
-print "\n$current_segment\tENDS\nEND\n" if ($masm);
+print "\n$current_segment\tENDS\n"	if ($current_segment && $masm);
+print "END\n"				if ($masm);
 
 close STDOUT;
 
-#################################################
+#################################################
 # Cross-reference x86_64 ABI "card"
 #
 # 		Unix		Win64
@@ -554,3 +746,161 @@
 #	movq	16(%rsp),%rsi
 # endif
 #	ret
+#
+#################################################
+# Win64 SEH, Structured Exception Handling.
+#
+# Unlike on Unix systems(*) lack of Win64 stack unwinding information
+# has undesired side-effect at run-time: if an exception is raised in
+# assembler subroutine such as those in question (basically we're
+# referring to segmentation violations caused by malformed input
+# parameters), the application is briskly terminated without invoking
+# any exception handlers, most notably without generating memory dump
+# or any user notification whatsoever. This poses a problem. It's
+# possible to address it by registering custom language-specific
+# handler that would restore processor context to the state at
+# subroutine entry point and return "exception is not handled, keep
+# unwinding" code. Writing such handler can be a challenge... But it's
+# doable, though requires certain coding convention. Consider following
+# snippet:
+#
+# .type	function,@function
+# function:
+#	movq	%rsp,%rax	# copy rsp to volatile register
+#	pushq	%r15		# save non-volatile registers
+#	pushq	%rbx
+#	pushq	%rbp
+#	movq	%rsp,%r11
+#	subq	%rdi,%r11	# prepare [variable] stack frame
+#	andq	$-64,%r11
+#	movq	%rax,0(%r11)	# check for exceptions
+#	movq	%r11,%rsp	# allocate [variable] stack frame
+#	movq	%rax,0(%rsp)	# save original rsp value
+# magic_point:
+#	...
+#	movq	0(%rsp),%rcx	# pull original rsp value
+#	movq	-24(%rcx),%rbp	# restore non-volatile registers
+#	movq	-16(%rcx),%rbx
+#	movq	-8(%rcx),%r15
+#	movq	%rcx,%rsp	# restore original rsp
+#	ret
+# .size function,.-function
+#
+# The key is that up to magic_point copy of original rsp value remains
+# in chosen volatile register and no non-volatile register, except for
+# rsp, is modified. While past magic_point rsp remains constant till
+# the very end of the function. In this case custom language-specific
+# exception handler would look like this:
+#
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
+# {	ULONG64 *rsp = (ULONG64 *)context->Rax;
+#	if (context->Rip >= magic_point)
+#	{   rsp = ((ULONG64 **)context->Rsp)[0];
+#	    context->Rbp = rsp[-3];
+#	    context->Rbx = rsp[-2];
+#	    context->R15 = rsp[-1];
+#	}
+#	context->Rsp = (ULONG64)rsp;
+#	context->Rdi = rsp[1];
+#	context->Rsi = rsp[2];
+#
+#	memcpy (disp->ContextRecord,context,sizeof(CONTEXT));
+#	RtlVirtualUnwind(UNW_FLAG_NHANDLER,disp->ImageBase,
+#		dips->ControlPc,disp->FunctionEntry,disp->ContextRecord,
+#		&disp->HandlerData,&disp->EstablisherFrame,NULL);
+#	return ExceptionContinueSearch;
+# }
+#
+# It's appropriate to implement this handler in assembler, directly in
+# function's module. In order to do that one has to know members'
+# offsets in CONTEXT and DISPATCHER_CONTEXT structures and some constant
+# values. Here they are:
+#
+#	CONTEXT.Rax				120
+#	CONTEXT.Rcx				128
+#	CONTEXT.Rdx				136
+#	CONTEXT.Rbx				144
+#	CONTEXT.Rsp				152
+#	CONTEXT.Rbp				160
+#	CONTEXT.Rsi				168
+#	CONTEXT.Rdi				176
+#	CONTEXT.R8				184
+#	CONTEXT.R9				192
+#	CONTEXT.R10				200
+#	CONTEXT.R11				208
+#	CONTEXT.R12				216
+#	CONTEXT.R13				224
+#	CONTEXT.R14				232
+#	CONTEXT.R15				240
+#	CONTEXT.Rip				248
+#	CONTEXT.Xmm6				512
+#	sizeof(CONTEXT)				1232
+#	DISPATCHER_CONTEXT.ControlPc		0
+#	DISPATCHER_CONTEXT.ImageBase		8
+#	DISPATCHER_CONTEXT.FunctionEntry	16
+#	DISPATCHER_CONTEXT.EstablisherFrame	24
+#	DISPATCHER_CONTEXT.TargetIp		32
+#	DISPATCHER_CONTEXT.ContextRecord	40
+#	DISPATCHER_CONTEXT.LanguageHandler	48
+#	DISPATCHER_CONTEXT.HandlerData		56
+#	UNW_FLAG_NHANDLER			0
+#	ExceptionContinueSearch			1
+#
+# In order to tie the handler to the function one has to compose
+# couple of structures: one for .xdata segment and one for .pdata.
+#
+# UNWIND_INFO structure for .xdata segment would be
+#
+# function_unwind_info:
+#	.byte	9,0,0,0
+#	.rva	handler
+#
+# This structure designates exception handler for a function with
+# zero-length prologue, no stack frame or frame register.
+#
+# To facilitate composing of .pdata structures, auto-generated "gear"
+# prologue copies rsp value to rax and denotes next instruction with
+# .LSEH_begin_{function_name} label. This essentially defines the SEH
+# styling rule mentioned in the beginning. Position of this label is
+# chosen in such manner that possible exceptions raised in the "gear"
+# prologue would be accounted to caller and unwound from latter's frame.
+# End of function is marked with respective .LSEH_end_{function_name}
+# label. To summarize, .pdata segment would contain
+#
+#	.rva	.LSEH_begin_function
+#	.rva	.LSEH_end_function
+#	.rva	function_unwind_info
+#
+# Reference to functon_unwind_info from .xdata segment is the anchor.
+# In case you wonder why references are 32-bit .rvas and not 64-bit
+# .quads. References put into these two segments are required to be
+# *relative* to the base address of the current binary module, a.k.a.
+# image base. No Win64 module, be it .exe or .dll, can be larger than
+# 2GB and thus such relative references can be and are accommodated in
+# 32 bits.
+#
+# Having reviewed the example function code, one can argue that "movq
+# %rsp,%rax" above is redundant. It is not! Keep in mind that on Unix
+# rax would contain an undefined value. If this "offends" you, use
+# another register and refrain from modifying rax till magic_point is
+# reached, i.e. as if it was a non-volatile register. If more registers
+# are required prior [variable] frame setup is completed, note that
+# nobody says that you can have only one "magic point." You can
+# "liberate" non-volatile registers by denoting last stack off-load
+# instruction and reflecting it in finer grade unwind logic in handler.
+# After all, isn't it why it's called *language-specific* handler...
+#
+# Attentive reader can notice that exceptions would be mishandled in
+# auto-generated "gear" epilogue. Well, exception effectively can't
+# occur there, because if memory area used by it was subject to
+# segmentation violation, then it would be raised upon call to the
+# function (and as already mentioned be accounted to caller, which is
+# not a problem). If you're still not comfortable, then define tail
+# "magic point" just prior ret instruction and have handler treat it...
+#
+# (*)	Note that we're talking about run-time, not debug-time. Lack of
+#	unwind information makes debugging hard on both Windows and
+#	Unix. "Unlike" referes to the fact that on Unix signal handler
+#	will always be invoked, core dumped and appropriate exit code
+#	returned to parent (for user notification).
diff --git a/crypto/perlasm/x86asm.pl b/crypto/perlasm/x86asm.pl
index 5979122..28080ca 100644
--- a/crypto/perlasm/x86asm.pl
+++ b/crypto/perlasm/x86asm.pl
@@ -1,130 +1,207 @@
-#!/usr/local/bin/perl
+#!/usr/bin/env perl
 
 # require 'x86asm.pl';
-# &asm_init("cpp","des-586.pl");
-# XXX
-# XXX
-# main'asm_finish
+# &asm_init(<flavor>,"des-586.pl"[,$i386only]);
+# &function_begin("foo");
+# ...
+# &function_end("foo");
+# &asm_finish
 
-sub main'asm_finish
-	{
-	&file_end();
-	&asm_finish_cpp() if $cpp;
-	print &asm_get_output();
-	}
+$out=();
+$i386=0;
 
-sub main'asm_init
-	{
-	($type,$fn,$i386)=@_;
-	$filename=$fn;
+# AUTOLOAD is this context has quite unpleasant side effect, namely
+# that typos in function calls effectively go to assembler output,
+# but on the pros side we don't have to implement one subroutine per
+# each opcode...
+sub ::AUTOLOAD
+{ my $opcode = $AUTOLOAD;
 
-	$elf=$cpp=$coff=$aout=$win32=$netware=$mwerks=0;
-	if (	($type eq "elf"))
-		{ $elf=1; require "x86unix.pl"; }
-	elsif (	($type eq "a.out"))
-		{ $aout=1; require "x86unix.pl"; }
-	elsif (	($type eq "coff" or $type eq "gaswin"))
-		{ $coff=1; require "x86unix.pl"; }
-	elsif (	($type eq "cpp"))
-		{ $cpp=1; require "x86unix.pl"; }
-	elsif (	($type eq "win32"))
-		{ $win32=1; require "x86ms.pl"; }
-	elsif (	($type eq "win32n"))
-		{ $win32=1; require "x86nasm.pl"; }
-	elsif (	($type eq "nw-nasm"))
-		{ $netware=1; require "x86nasm.pl"; }
-	elsif (	($type eq "nw-mwasm"))
-		{ $netware=1; $mwerks=1; require "x86nasm.pl"; }
-	else
-		{
-		print STDERR <<"EOF";
+    die "more than 4 arguments passed to $opcode" if ($#_>3);
+
+    $opcode =~ s/.*:://;
+    if    ($opcode =~ /^push/) { $stack+=4; }
+    elsif ($opcode =~ /^pop/)  { $stack-=4; }
+
+    &generic($opcode,@_) or die "undefined subroutine \&$AUTOLOAD";
+}
+
+sub ::emit
+{ my $opcode=shift;
+
+    if ($#_==-1)    { push(@out,"\t$opcode\n");				}
+    else            { push(@out,"\t$opcode\t".join(',',@_)."\n");	}
+}
+
+sub ::LB
+{   $_[0] =~ m/^e?([a-d])x$/o or die "$_[0] does not have a 'low byte'";
+  $1."l";
+}
+sub ::HB
+{   $_[0] =~ m/^e?([a-d])x$/o or die "$_[0] does not have a 'high byte'";
+  $1."h";
+}
+sub ::stack_push{ my $num=$_[0]*4; $stack+=$num; &sub("esp",$num);	}
+sub ::stack_pop	{ my $num=$_[0]*4; $stack-=$num; &add("esp",$num);	}
+sub ::blindpop	{ &pop($_[0]); $stack+=4;				}
+sub ::wparam	{ &DWP($stack+4*$_[0],"esp");				}
+sub ::swtmp	{ &DWP(4*$_[0],"esp");					}
+
+sub ::bswap
+{   if ($i386)	# emulate bswap for i386
+    {	&comment("bswap @_");
+	&xchg(&HB(@_),&LB(@_));
+	&ror (@_,16);
+	&xchg(&HB(@_),&LB(@_));
+    }
+    else
+    {	&generic("bswap",@_);	}
+}
+# These are made-up opcodes introduced over the years essentially
+# by ignorance, just alias them to real ones...
+sub ::movb	{ &mov(@_);	}
+sub ::xorb	{ &xor(@_);	}
+sub ::rotl	{ &rol(@_);	}
+sub ::rotr	{ &ror(@_);	}
+sub ::exch	{ &xchg(@_);	}
+sub ::halt	{ &hlt;		}
+sub ::movz	{ &movzx(@_);	}
+sub ::pushf	{ &pushfd;	}
+sub ::popf	{ &popfd;	}
+
+# 3 argument instructions
+sub ::movq
+{ my($p1,$p2,$optimize)=@_;
+
+    if ($optimize && $p1=~/^mm[0-7]$/ && $p2=~/^mm[0-7]$/)
+    # movq between mmx registers can sink Intel CPUs
+    {	&::pshufw($p1,$p2,0xe4);		}
+    else
+    {	&::generic("movq",@_);			}
+}
+
+# label management
+$lbdecor="L";		# local label decoration, set by package
+$label="000";
+
+sub ::islabel		# see is argument is a known label
+{ my $i;
+    foreach $i (values %label) { return $i if ($i eq $_[0]); }
+  $label{$_[0]};	# can be undef
+}
+
+sub ::label		# instantiate a function-scope label
+{   if (!defined($label{$_[0]}))
+    {	$label{$_[0]}="${lbdecor}${label}${_[0]}"; $label++;   }
+  $label{$_[0]};
+}
+
+sub ::LABEL		# instantiate a file-scope label
+{   $label{$_[0]}=$_[1] if (!defined($label{$_[0]}));
+  $label{$_[0]};
+}
+
+sub ::static_label	{ &::LABEL($_[0],$lbdecor.$_[0]); }
+
+sub ::set_label_B	{ push(@out,"@_:\n"); }
+sub ::set_label
+{ my $label=&::label($_[0]);
+    &::align($_[1]) if ($_[1]>1);
+    &::set_label_B($label);
+  $label;
+}
+
+sub ::wipe_labels	# wipes function-scope labels
+{   foreach $i (keys %label)
+    {	delete $label{$i} if ($label{$i} =~ /^\Q${lbdecor}\E[0-9]{3}/);	}
+}
+
+# subroutine management
+sub ::function_begin
+{   &function_begin_B(@_);
+    $stack=4;
+    &push("ebp");
+    &push("ebx");
+    &push("esi");
+    &push("edi");
+}
+
+sub ::function_end
+{   &pop("edi");
+    &pop("esi");
+    &pop("ebx");
+    &pop("ebp");
+    &ret();
+    &function_end_B(@_);
+    $stack=0;
+    &wipe_labels();
+}
+
+sub ::function_end_A
+{   &pop("edi");
+    &pop("esi");
+    &pop("ebx");
+    &pop("ebp");
+    &ret();
+    $stack+=16;	# readjust esp as if we didn't pop anything
+}
+
+sub ::asciz
+{ my @str=unpack("C*",shift);
+    push @str,0;
+    while ($#str>15) {
+	&data_byte(@str[0..15]);
+	foreach (0..15) { shift @str; }
+    }
+    &data_byte(@str) if (@str);
+}
+
+sub ::asm_finish
+{   &file_end();
+    print @out;
+}
+
+sub ::asm_init
+{ my ($type,$fn,$cpu)=@_;
+
+    $filename=$fn;
+    $i386=$cpu;
+
+    $elf=$cpp=$coff=$aout=$macosx=$win32=$netware=$mwerks=0;
+    if    (($type eq "elf"))
+    {	$elf=1;			require "x86gas.pl";	}
+    elsif (($type eq "a\.out"))
+    {	$aout=1;		require "x86gas.pl";	}
+    elsif (($type eq "coff" or $type eq "gaswin"))
+    {	$coff=1;		require "x86gas.pl";	}
+    elsif (($type eq "win32n"))
+    {	$win32=1;		require "x86nasm.pl";	}
+    elsif (($type eq "nw-nasm"))
+    {	$netware=1;		require "x86nasm.pl";	}
+    #elsif (($type eq "nw-mwasm"))
+    #{	$netware=1; $mwerks=1;	require "x86nasm.pl";	}
+    elsif (($type eq "win32"))
+    {	$win32=1;		require "x86masm.pl";	}
+    elsif (($type eq "macosx"))
+    {	$aout=1; $macosx=1;	require "x86gas.pl";	}
+    else
+    {	print STDERR <<"EOF";
 Pick one target type from
 	elf	- Linux, FreeBSD, Solaris x86, etc.
-	a.out	- OpenBSD, DJGPP, etc.
+	a.out	- DJGPP, elder OpenBSD, etc.
 	coff	- GAS/COFF such as Win32 targets
-	win32	- Windows 95/Windows NT
 	win32n	- Windows 95/Windows NT NASM format
 	nw-nasm - NetWare NASM format
-	nw-mwasm- NetWare Metrowerks Assembler
+	macosx	- Mac OS X
 EOF
-		exit(1);
-		}
+	exit(1);
+    }
 
-	$pic=0;
-	for (@ARGV) {	$pic=1 if (/\-[fK]PIC/i);	}
+    $pic=0;
+    for (@ARGV) { $pic=1 if (/\-[fK]PIC/i); }
 
-	&asm_init_output();
-
-&comment("Don't even think of reading this code");
-&comment("It was automatically generated by $filename");
-&comment("Which is a perl program used to generate the x86 assember for");
-&comment("any of ELF, a.out, COFF, Win32, ...");
-&comment("eric <eay\@cryptsoft.com>");
-&comment("");
-
-	$filename =~ s/\.pl$//;
-	&file($filename);
-	}
-
-sub asm_finish_cpp
-	{
-	return unless $cpp;
-
-	local($tmp,$i);
-	foreach $i (&get_labels())
-		{
-		$tmp.="#define $i _$i\n";
-		}
-	print <<"EOF";
-/* Run the C pre-processor over this file with one of the following defined
- * ELF - elf object files,
- * OUT - a.out object files,
- * BSDI - BSDI style a.out object files
- * SOL - Solaris style elf
- */
-
-#define TYPE(a,b)       .type   a,b
-#define SIZE(a,b)       .size   a,b
-
-#if defined(OUT) || (defined(BSDI) && !defined(ELF))
-$tmp
-#endif
-
-#ifdef OUT
-#define OK	1
-#define ALIGN	4
-#if defined(__CYGWIN__) || defined(__DJGPP__) || (__MINGW32__)
-#undef SIZE
-#undef TYPE
-#define SIZE(a,b)
-#define TYPE(a,b)	.def a; .scl 2; .type 32; .endef
-#endif /* __CYGWIN || __DJGPP */
-#endif
-
-#if defined(BSDI) && !defined(ELF)
-#define OK              1
-#define ALIGN           4
-#undef SIZE
-#undef TYPE
-#define SIZE(a,b)
-#define TYPE(a,b)
-#endif
-
-#if defined(ELF) || defined(SOL)
-#define OK              1
-#define ALIGN           16
-#endif
-
-#ifndef OK
-You need to define one of
-ELF - elf systems - linux-elf, NetBSD and DG-UX
-OUT - a.out systems - linux-a.out and FreeBSD
-SOL - solaris systems, which are elf with strange comment lines
-BSDI - a.out with a very primative version of as.
-#endif
-
-/* Let the Assembler begin :-) */
-EOF
-	}
+    $filename =~ s/\.pl$//;
+    &file($filename);
+}
 
 1;
diff --git a/crypto/perlasm/x86gas.pl b/crypto/perlasm/x86gas.pl
new file mode 100644
index 0000000..6eab727
--- /dev/null
+++ b/crypto/perlasm/x86gas.pl
@@ -0,0 +1,247 @@
+#!/usr/bin/env perl
+
+package x86gas;
+
+*out=\@::out;
+
+$::lbdecor=$::aout?"L":".L";		# local label decoration
+$nmdecor=($::aout or $::coff)?"_":"";	# external name decoration
+
+$initseg="";
+
+$align=16;
+$align=log($align)/log(2) if ($::aout);
+$com_start="#" if ($::aout or $::coff);
+
+sub opsize()
+{ my $reg=shift;
+    if    ($reg =~ m/^%e/o)		{ "l"; }
+    elsif ($reg =~ m/^%[a-d][hl]$/o)	{ "b"; }
+    elsif ($reg =~ m/^%[xm]/o)		{ undef; }
+    else				{ "w"; }
+}
+
+# swap arguments;
+# expand opcode with size suffix;
+# prefix numeric constants with $;
+sub ::generic
+{ my($opcode,@arg)=@_;
+  my($suffix,$dst,$src);
+
+    @arg=reverse(@arg);
+
+    for (@arg)
+    {	s/^(\*?)(e?[a-dsixphl]{2})$/$1%$2/o;	# gp registers
+	s/^([xy]?mm[0-7])$/%$1/o;		# xmm/mmx registers
+	s/^(\-?[0-9]+)$/\$$1/o;			# constants
+	s/^(\-?0x[0-9a-f]+)$/\$$1/o;		# constants
+    }
+
+    $dst = $arg[$#arg]		if ($#arg>=0);
+    $src = $arg[$#arg-1]	if ($#arg>=1);
+    if    ($dst =~ m/^%/o)	{ $suffix=&opsize($dst); }
+    elsif ($src =~ m/^%/o)	{ $suffix=&opsize($src); }
+    else			{ $suffix="l";           }
+    undef $suffix if ($dst =~ m/^%[xm]/o || $src =~ m/^%[xm]/o);
+
+    if ($#_==0)				{ &::emit($opcode);		}
+    elsif ($opcode =~ m/^j/o && $#_==1)	{ &::emit($opcode,@arg);	}
+    elsif ($opcode eq "call" && $#_==1)	{ &::emit($opcode,@arg);	}
+    elsif ($opcode =~ m/^set/&& $#_==1)	{ &::emit($opcode,@arg);	}
+    else				{ &::emit($opcode.$suffix,@arg);}
+
+  1;
+}
+#
+# opcodes not covered by ::generic above, mostly inconsistent namings...
+#
+sub ::movzx	{ &::movzb(@_);			}
+sub ::pushfd	{ &::pushfl;			}
+sub ::popfd	{ &::popfl;			}
+sub ::cpuid	{ &::emit(".byte\t0x0f,0xa2");	}
+sub ::rdtsc	{ &::emit(".byte\t0x0f,0x31");	}
+
+sub ::call	{ &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); }
+sub ::call_ptr	{ &::generic("call","*$_[0]");	}
+sub ::jmp_ptr	{ &::generic("jmp","*$_[0]");	}
+
+*::bswap = sub	{ &::emit("bswap","%$_[0]");	} if (!$::i386);
+
+sub ::DWP
+{ my($addr,$reg1,$reg2,$idx)=@_;
+  my $ret="";
+
+    $addr =~ s/^\s+//;
+    # prepend global references with optional underscore
+    $addr =~ s/^([^\+\-0-9][^\+\-]*)/&::islabel($1) or "$nmdecor$1"/ige;
+
+    $reg1 = "%$reg1" if ($reg1);
+    $reg2 = "%$reg2" if ($reg2);
+
+    $ret .= $addr if (($addr ne "") && ($addr ne 0));
+
+    if ($reg2)
+    {	$idx!= 0 or $idx=1;
+	$ret .= "($reg1,$reg2,$idx)";
+    }
+    elsif ($reg1)
+    {	$ret .= "($reg1)";	}
+
+  $ret;
+}
+sub ::QWP	{ &::DWP(@_);	}
+sub ::BP	{ &::DWP(@_);	}
+sub ::BC	{ @_;		}
+sub ::DWC	{ @_;		}
+
+sub ::file
+{   push(@out,".file\t\"$_[0].s\"\n.text\n");	}
+
+sub ::function_begin_B
+{ my $func=shift;
+  my $global=($func !~ /^_/);
+  my $begin="${::lbdecor}_${func}_begin";
+
+    &::LABEL($func,$global?"$begin":"$nmdecor$func");
+    $func=$nmdecor.$func;
+
+    push(@out,".globl\t$func\n")	if ($global);
+    if ($::coff)
+    {	push(@out,".def\t$func;\t.scl\t".(3-$global).";\t.type\t32;\t.endef\n"); }
+    elsif (($::aout and !$::pic) or $::macosx)
+    { }
+    else
+    {	push(@out,".type	$func,\@function\n"); }
+    push(@out,".align\t$align\n");
+    push(@out,"$func:\n");
+    push(@out,"$begin:\n")		if ($global);
+    $::stack=4;
+}
+
+sub ::function_end_B
+{ my $func=shift;
+    push(@out,".size\t$nmdecor$func,.-".&::LABEL($func)."\n") if ($::elf);
+    $::stack=0;
+    &::wipe_labels();
+}
+
+sub ::comment
+	{
+	if (!defined($com_start) or $::elf)
+		{	# Regarding $::elf above...
+			# GNU and SVR4 as'es use different comment delimiters,
+		push(@out,"\n");	# so we just skip ELF comments...
+		return;
+		}
+	foreach (@_)
+		{
+		if (/^\s*$/)
+			{ push(@out,"\n"); }
+		else
+			{ push(@out,"\t$com_start $_ $com_end\n"); }
+		}
+	}
+
+sub ::external_label
+{   foreach(@_) { &::LABEL($_,$nmdecor.$_); }   }
+
+sub ::public_label
+{   push(@out,".globl\t".&::LABEL($_[0],$nmdecor.$_[0])."\n");   }
+
+sub ::file_end
+{   if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out) {
+	my $tmp=".comm\t${nmdecor}OPENSSL_ia32cap_P,4";
+	if ($::elf)	{ push (@out,"$tmp,4\n"); }
+	else		{ push (@out,"$tmp\n"); }
+    }
+    if ($::macosx)
+    {	if (%non_lazy_ptr)
+    	{   push(@out,".section __IMPORT,__pointers,non_lazy_symbol_pointers\n");
+	    foreach $i (keys %non_lazy_ptr)
+	    {	push(@out,"$non_lazy_ptr{$i}:\n.indirect_symbol\t$i\n.long\t0\n");   }
+	}
+    }
+    push(@out,$initseg) if ($initseg);
+}
+
+sub ::data_byte	{   push(@out,".byte\t".join(',',@_)."\n");   }
+sub ::data_word {   push(@out,".long\t".join(',',@_)."\n");   }
+
+sub ::align
+{ my $val=$_[0],$p2,$i;
+    if ($::aout)
+    {	for ($p2=0;$val!=0;$val>>=1) { $p2++; }
+	$val=$p2-1;
+	$val.=",0x90";
+    }
+    push(@out,".align\t$val\n");
+}
+
+sub ::picmeup
+{ my($dst,$sym,$base,$reflabel)=@_;
+
+    if ($::pic && ($::elf || $::aout))
+    {	if (!defined($base))
+	{   &::call(&::label("PIC_me_up"));
+	    &::set_label("PIC_me_up");
+	    &::blindpop($dst);
+	    $base=$dst;
+	    $reflabel=&::label("PIC_me_up");
+	}
+	if ($::macosx)
+	{   my $indirect=&::static_label("$nmdecor$sym\$non_lazy_ptr");
+	    &::mov($dst,&::DWP("$indirect-$reflabel",$base));
+	    $non_lazy_ptr{"$nmdecor$sym"}=$indirect;
+	}
+	else
+	{   &::lea($dst,&::DWP("_GLOBAL_OFFSET_TABLE_+[.-$reflabel]",
+			    $base));
+	    &::mov($dst,&::DWP("$sym\@GOT",$dst));
+	}
+    }
+    else
+    {	&::lea($dst,&::DWP($sym));	}
+}
+
+sub ::initseg
+{ my $f=$nmdecor.shift;
+
+    if ($::elf)
+    {	$initseg.=<<___;
+.section	.init
+	call	$f
+	jmp	.Linitalign
+.align	$align
+.Linitalign:
+___
+    }
+    elsif ($::coff)
+    {   $initseg.=<<___;	# applies to both Cygwin and Mingw
+.section	.ctors
+.long	$f
+___
+    }
+    elsif ($::macosx)
+    {	$initseg.=<<___;
+.mod_init_func
+.align 2
+.long   $f
+___
+    }
+    elsif ($::aout)
+    {	my $ctor="${nmdecor}_GLOBAL_\$I\$$f";
+	$initseg.=".text\n";
+	$initseg.=".type	$ctor,\@function\n" if ($::pic);
+	$initseg.=<<___;	# OpenBSD way...
+.globl	$ctor
+.align	2
+$ctor:
+	jmp	$f
+___
+    }
+}
+
+sub ::dataseg
+{   push(@out,".data\n");   }
+
+1;
diff --git a/crypto/perlasm/x86masm.pl b/crypto/perlasm/x86masm.pl
new file mode 100644
index 0000000..3d50e4a
--- /dev/null
+++ b/crypto/perlasm/x86masm.pl
@@ -0,0 +1,184 @@
+#!/usr/bin/env perl
+
+package x86masm;
+
+*out=\@::out;
+
+$::lbdecor="\$L";	# local label decoration
+$nmdecor="_";		# external name decoration
+
+$initseg="";
+$segment="";
+
+sub ::generic
+{ my ($opcode,@arg)=@_;
+
+    # fix hexadecimal constants
+    for (@arg) { s/0x([0-9a-f]+)/0$1h/oi; }
+
+    if ($opcode !~ /movq/)
+    {	# fix xmm references
+	$arg[0] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[1]=~/\bxmm[0-7]\b/i);
+	$arg[1] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[0]=~/\bxmm[0-7]\b/i);
+    }
+
+    &::emit($opcode,@arg);
+  1;
+}
+#
+# opcodes not covered by ::generic above, mostly inconsistent namings...
+#
+sub ::call	{ &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); }
+sub ::call_ptr	{ &::emit("call",@_);	}
+sub ::jmp_ptr	{ &::emit("jmp",@_);	}
+
+sub get_mem
+{ my($size,$addr,$reg1,$reg2,$idx)=@_;
+  my($post,$ret);
+
+    $ret .= "$size PTR " if ($size ne "");
+
+    $addr =~ s/^\s+//;
+    # prepend global references with optional underscore
+    $addr =~ s/^([^\+\-0-9][^\+\-]*)/&::islabel($1) or "$nmdecor$1"/ige;
+    # put address arithmetic expression in parenthesis
+    $addr="($addr)" if ($addr =~ /^.+[\-\+].+$/);
+
+    if (($addr ne "") && ($addr ne 0))
+    {	if ($addr !~ /^-/)	{ $ret .= "$addr";  }
+	else			{ $post=$addr;      }
+    }
+    $ret .= "[";
+
+    if ($reg2 ne "")
+    {	$idx!=0 or $idx=1;
+	$ret .= "$reg2*$idx";
+	$ret .= "+$reg1" if ($reg1 ne "");
+    }
+    else
+    {	$ret .= "$reg1";   }
+
+    $ret .= "$post]";
+    $ret =~ s/\+\]/]/; # in case $addr was the only argument
+    $ret =~ s/\[\s*\]//;
+
+  $ret;
+}
+sub ::BP	{ &get_mem("BYTE",@_);  }
+sub ::DWP	{ &get_mem("DWORD",@_); }
+sub ::QWP	{ &get_mem("QWORD",@_); }
+sub ::BC	{ "@_";  }
+sub ::DWC	{ "@_"; }
+
+sub ::file
+{ my $tmp=<<___;
+TITLE	$_[0].asm
+IF \@Version LT 800
+ECHO MASM version 8.00 or later is strongly recommended.
+ENDIF
+.486
+.MODEL	FLAT
+OPTION	DOTNAME
+IF \@Version LT 800
+.text\$	SEGMENT PAGE 'CODE'
+ELSE
+.text\$	SEGMENT ALIGN(64) 'CODE'
+ENDIF
+___
+    push(@out,$tmp);
+    $segment = ".text\$";
+}
+
+sub ::function_begin_B
+{ my $func=shift;
+  my $global=($func !~ /^_/);
+  my $begin="${::lbdecor}_${func}_begin";
+
+    &::LABEL($func,$global?"$begin":"$nmdecor$func");
+    $func="ALIGN\t16\n".$nmdecor.$func."\tPROC";
+
+    if ($global)    { $func.=" PUBLIC\n${begin}::\n"; }
+    else	    { $func.=" PRIVATE\n";            }
+    push(@out,$func);
+    $::stack=4;
+}
+sub ::function_end_B
+{ my $func=shift;
+
+    push(@out,"$nmdecor$func ENDP\n");
+    $::stack=0;
+    &::wipe_labels();
+}
+
+sub ::file_end
+{ my $xmmheader=<<___;
+.686
+.XMM
+IF \@Version LT 800
+XMMWORD STRUCT 16
+DQ	2 dup (?)
+XMMWORD	ENDS
+ENDIF
+___
+    if (grep {/\b[x]?mm[0-7]\b/i} @out) {
+	grep {s/\.[3-7]86/$xmmheader/} @out;
+    }
+
+    push(@out,"$segment	ENDS\n");
+
+    if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out)
+    {	my $comm=<<___;
+.bss	SEGMENT 'BSS'
+COMM	${nmdecor}OPENSSL_ia32cap_P:DWORD
+.bss	ENDS
+___
+	# comment out OPENSSL_ia32cap_P declarations
+	grep {s/(^EXTERN\s+${nmdecor}OPENSSL_ia32cap_P)/\;$1/} @out;
+	push (@out,$comm);
+    }
+    push (@out,$initseg) if ($initseg);
+    push (@out,"END\n");
+}
+
+sub ::comment {   foreach (@_) { push(@out,"\t; $_\n"); }   }
+
+*::set_label_B = sub
+{ my $l=shift; push(@out,$l.($l=~/^\Q${::lbdecor}\E[0-9]{3}/?":\n":"::\n")); };
+
+sub ::external_label
+{   foreach(@_)
+    {	push(@out, "EXTERN\t".&::LABEL($_,$nmdecor.$_).":NEAR\n");   }
+}
+
+sub ::public_label
+{   push(@out,"PUBLIC\t".&::LABEL($_[0],$nmdecor.$_[0])."\n");   }
+
+sub ::data_byte
+{   push(@out,("DB\t").join(',',@_)."\n");	}
+
+sub ::data_word
+{   push(@out,("DD\t").join(',',@_)."\n");	}
+
+sub ::align
+{   push(@out,"ALIGN\t$_[0]\n");	}
+
+sub ::picmeup
+{ my($dst,$sym)=@_;
+    &::lea($dst,&::DWP($sym));
+}
+
+sub ::initseg
+{ my $f=$nmdecor.shift;
+
+    $initseg.=<<___;
+.CRT\$XCU	SEGMENT DWORD PUBLIC 'DATA'
+EXTERN	$f:NEAR
+DD	$f
+.CRT\$XCU	ENDS
+___
+}
+
+sub ::dataseg
+{   push(@out,"$segment\tENDS\n_DATA\tSEGMENT\n"); $segment="_DATA";   }
+
+1;
diff --git a/crypto/perlasm/x86ms.pl b/crypto/perlasm/x86ms.pl
deleted file mode 100644
index a0be293..0000000
--- a/crypto/perlasm/x86ms.pl
+++ /dev/null
@@ -1,472 +0,0 @@
-#!/usr/local/bin/perl
-
-package x86ms;
-
-$label="L000";
-
-%lb=(	'eax',	'al',
-	'ebx',	'bl',
-	'ecx',	'cl',
-	'edx',	'dl',
-	'ax',	'al',
-	'bx',	'bl',
-	'cx',	'cl',
-	'dx',	'dl',
-	);
-
-%hb=(	'eax',	'ah',
-	'ebx',	'bh',
-	'ecx',	'ch',
-	'edx',	'dh',
-	'ax',	'ah',
-	'bx',	'bh',
-	'cx',	'ch',
-	'dx',	'dh',
-	);
-
-sub main'asm_init_output { @out=(); }
-sub main'asm_get_output { return(@out); }
-sub main'get_labels { return(@labels); }
-sub main'external_label
-{
-	push(@labels,@_);
-	foreach (@_) {
-		push(@out, "EXTRN\t_$_:DWORD\n");
-	}
-}
-
-sub main'LB
-	{
-	(defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
-	return($lb{$_[0]});
-	}
-
-sub main'HB
-	{
-	(defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
-	return($hb{$_[0]});
-	}
-
-sub main'BP
-	{
-	&get_mem("BYTE",@_);
-	}
-
-sub main'DWP
-	{
-	&get_mem("DWORD",@_);
-	}
-
-sub main'QWP
-	{
-	&get_mem("QWORD",@_);
-	}
-
-sub main'BC
-	{
-	return @_;
-	}
-
-sub main'DWC
-	{
-	return @_;
-	}
-
-sub main'stack_push
-	{
-	local($num)=@_;
-	$stack+=$num*4;
-	&main'sub("esp",$num*4);
-	}
-
-sub main'stack_pop
-	{
-	local($num)=@_;
-	$stack-=$num*4;
-	&main'add("esp",$num*4);
-	}
-
-sub get_mem
-	{
-	local($size,$addr,$reg1,$reg2,$idx)=@_;
-	local($t,$post);
-	local($ret)="$size PTR ";
-
-	$addr =~ s/^\s+//;
-	if ($addr =~ /^(.+)\+(.+)$/)
-		{
-		$reg2=&conv($1);
-		$addr="_$2";
-		}
-	elsif ($addr =~ /^[_a-z][_a-z0-9]*$/i)
-		{
-		$addr="_$addr";
-		}
-
-	if ($addr =~ /^.+\-.+$/) { $addr="($addr)"; }
-
-	$reg1="$regs{$reg1}" if defined($regs{$reg1});
-	$reg2="$regs{$reg2}" if defined($regs{$reg2});
-	if (($addr ne "") && ($addr ne 0))
-		{
-		if ($addr !~ /^-/)
-			{ $ret.=$addr; }
-		else	{ $post=$addr; }
-		}
-	if ($reg2 ne "")
-		{
-		$t="";
-		$t="*$idx" if ($idx != 0);
-		$reg1="+".$reg1 if ("$reg1$post" ne "");
-		$ret.="[$reg2$t$reg1$post]";
-		}
-	else
-		{
-		$ret.="[$reg1$post]"
-		}
-	$ret =~ s/\[\]//;	# in case $addr was the only argument
-	return($ret);
-	}
-
-sub main'mov	{ &out2("mov",@_); }
-sub main'movb	{ &out2("mov",@_); }
-sub main'and	{ &out2("and",@_); }
-sub main'or	{ &out2("or",@_); }
-sub main'shl	{ &out2("shl",@_); }
-sub main'shr	{ &out2("shr",@_); }
-sub main'xor	{ &out2("xor",@_); }
-sub main'xorb	{ &out2("xor",@_); }
-sub main'add	{ &out2("add",@_); }
-sub main'adc	{ &out2("adc",@_); }
-sub main'sub	{ &out2("sub",@_); }
-sub main'sbb	{ &out2("sbb",@_); }
-sub main'rotl	{ &out2("rol",@_); }
-sub main'rotr	{ &out2("ror",@_); }
-sub main'exch	{ &out2("xchg",@_); }
-sub main'cmp	{ &out2("cmp",@_); }
-sub main'lea	{ &out2("lea",@_); }
-sub main'mul	{ &out1("mul",@_); }
-sub main'imul	{ &out2("imul",@_); }
-sub main'div	{ &out1("div",@_); }
-sub main'dec	{ &out1("dec",@_); }
-sub main'inc	{ &out1("inc",@_); }
-sub main'jmp	{ &out1("jmp",@_); }
-sub main'jmp_ptr { &out1p("jmp",@_); }
-sub main'je	{ &out1("je",@_); }
-sub main'jle	{ &out1("jle",@_); }
-sub main'jz	{ &out1("jz",@_); }
-sub main'jge	{ &out1("jge",@_); }
-sub main'jl	{ &out1("jl",@_); }
-sub main'ja	{ &out1("ja",@_); }
-sub main'jae	{ &out1("jae",@_); }
-sub main'jb	{ &out1("jb",@_); }
-sub main'jbe	{ &out1("jbe",@_); }
-sub main'jc	{ &out1("jc",@_); }
-sub main'jnc	{ &out1("jnc",@_); }
-sub main'jnz	{ &out1("jnz",@_); }
-sub main'jne	{ &out1("jne",@_); }
-sub main'jno	{ &out1("jno",@_); }
-sub main'push	{ &out1("push",@_); $stack+=4; }
-sub main'pop	{ &out1("pop",@_); $stack-=4; }
-sub main'pushf	{ &out0("pushfd"); $stack+=4; }
-sub main'popf	{ &out0("popfd"); $stack-=4; }
-sub main'bswap	{ &out1("bswap",@_); &using486(); }
-sub main'not	{ &out1("not",@_); }
-sub main'call	{ &out1("call",($_[0]=~/^\$L/?'':'_').$_[0]); }
-sub main'call_ptr { &out1p("call",@_); }
-sub main'ret	{ &out0("ret"); }
-sub main'nop	{ &out0("nop"); }
-sub main'test	{ &out2("test",@_); }
-sub main'bt	{ &out2("bt",@_); }
-sub main'leave	{ &out0("leave"); }
-sub main'cpuid  { &out0("DW\t0A20Fh"); }
-sub main'rdtsc  { &out0("DW\t0310Fh"); }
-sub main'halt	{ &out0("hlt"); }
-sub main'movz	{ &out2("movzx",@_); }
-sub main'neg	{ &out1("neg",@_); }
-sub main'cld	{ &out0("cld"); }
-
-# SSE2
-sub main'emms	{ &out0("emms"); }
-sub main'movd	{ &out2("movd",@_); }
-sub main'movq	{ &out2("movq",@_); }
-sub main'movdqu	{ &out2("movdqu",@_); }
-sub main'movdqa	{ &out2("movdqa",@_); }
-sub main'movdq2q{ &out2("movdq2q",@_); }
-sub main'movq2dq{ &out2("movq2dq",@_); }
-sub main'paddq	{ &out2("paddq",@_); }
-sub main'pmuludq{ &out2("pmuludq",@_); }
-sub main'psrlq	{ &out2("psrlq",@_); }
-sub main'psllq	{ &out2("psllq",@_); }
-sub main'pxor	{ &out2("pxor",@_); }
-sub main'por	{ &out2("por",@_); }
-sub main'pand	{ &out2("pand",@_); }
-
-sub out2
-	{
-	local($name,$p1,$p2)=@_;
-	local($l,$t,$line);
-
-	$line="\t$name\t";
-	$t=&conv($p1).",";
-	$l=length($t);
-	$line.="$t";
-	$l=4-($l+9)/8;
-	$line.="\t" x $l;
-	$line.=&conv($p2);
-	if ($line=~/\bxmm[0-7]\b/i) { $line=~s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i; }
-	push(@out,$line."\n");
-	}
-
-sub out0
-	{
-	local($name)=@_;
-
-	push(@out,"\t$name\n");
-	}
-
-sub out1
-	{
-	local($name,$p1)=@_;
-	local($l,$t);
-
-	push(@out,"\t$name\t".&conv($p1)."\n");
-	}
-
-sub conv
-	{
-	local($p)=@_;
-
-	$p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
-	return $p;
-	}
-
-sub using486
-	{
-	return if $using486;
-	$using486++;
-	grep(s/\.386/\.486/,@out);
-	}
-
-sub main'file
-	{
-	local($file)=@_;
-
-	local($tmp)=<<"EOF";
-	TITLE	$file.asm
-        .386
-.model	FLAT
-_TEXT\$	SEGMENT PAGE 'CODE'
-
-EOF
-	push(@out,$tmp);
-	}
-
-sub main'function_begin
-	{
-	local($func,$extra)=@_;
-
-	push(@labels,$func);
-
-	local($tmp)=<<"EOF";
-PUBLIC	_$func
-$extra
-_$func PROC NEAR
-	push	ebp
-	push	ebx
-	push	esi
-	push	edi
-EOF
-	push(@out,$tmp);
-	$stack=20;
-	}
-
-sub main'function_begin_B
-	{
-	local($func,$extra)=@_;
-
-	local($tmp)=<<"EOF";
-PUBLIC	_$func
-$extra
-_$func PROC NEAR
-EOF
-	push(@out,$tmp);
-	$stack=4;
-	}
-
-sub main'function_end
-	{
-	local($func)=@_;
-
-	local($tmp)=<<"EOF";
-	pop	edi
-	pop	esi
-	pop	ebx
-	pop	ebp
-	ret
-_$func ENDP
-EOF
-	push(@out,$tmp);
-	$stack=0;
-	%label=();
-	}
-
-sub main'function_end_B
-	{
-	local($func)=@_;
-
-	local($tmp)=<<"EOF";
-_$func ENDP
-EOF
-	push(@out,$tmp);
-	$stack=0;
-	%label=();
-	}
-
-sub main'function_end_A
-	{
-	local($func)=@_;
-
-	local($tmp)=<<"EOF";
-	pop	edi
-	pop	esi
-	pop	ebx
-	pop	ebp
-	ret
-EOF
-	push(@out,$tmp);
-	}
-
-sub main'file_end
-	{
-	# try to detect if SSE2 or MMX extensions were used...
-	my $xmmheader=<<___;
-.686
-.XMM
-IF \@Version LT 800
-XMMWORD STRUCT 16
-	DQ  2 dup (?)
-XMMWORD ENDS
-ENDIF
-___
-	if (grep {/\b[x]?mm[0-7]\b/i} @out) {
-		grep {s/\.[3-7]86/$xmmheader/} @out;
-		}
-	push(@out,"_TEXT\$	ENDS\n");
-	push(@out,"END\n");
-	}
-
-sub main'wparam
-	{
-	local($num)=@_;
-
-	return(&main'DWP($stack+$num*4,"esp","",0));
-	}
-
-sub main'swtmp
-	{
-	return(&main'DWP($_[0]*4,"esp","",0));
-	}
-
-# Should use swtmp, which is above esp.  Linix can trash the stack above esp
-#sub main'wtmp
-#	{
-#	local($num)=@_;
-#
-#	return(&main'DWP(-(($num+1)*4),"esp","",0));
-#	}
-
-sub main'comment
-	{
-	foreach (@_)
-		{
-		push(@out,"\t; $_\n");
-		}
-	}
-
-sub main'public_label
-	{
-	$label{$_[0]}="_$_[0]"	if (!defined($label{$_[0]}));
-	push(@out,"PUBLIC\t$label{$_[0]}\n");
-	}
-
-sub main'label
-	{
-	if (!defined($label{$_[0]}))
-		{
-		$label{$_[0]}="\$${label}${_[0]}";
-		$label++;
-		}
-	return($label{$_[0]});
-	}
-
-sub main'set_label
-	{
-	if (!defined($label{$_[0]}))
-		{
-		$label{$_[0]}="\$${label}${_[0]}";
-		$label++;
-		}
-	if ($_[1]!=0 && $_[1]>1)
-		{
-		main'align($_[1]);
-		}
-	if((defined $_[2]) && ($_[2] == 1))
-		{
-		push(@out,"$label{$_[0]}::\n");
-		}
-	elsif ($label{$_[0]} !~ /^\$/)
-		{
-		push(@out,"$label{$_[0]}\tLABEL PTR\n");
-		}
-	else
-		{
-		push(@out,"$label{$_[0]}:\n");
-		}
-	}
-
-sub main'data_byte
-	{
-	push(@out,"\tDB\t".join(',',@_)."\n");
-	}
-
-sub main'data_word
-	{
-	push(@out,"\tDD\t".join(',',@_)."\n");
-	}
-
-sub main'align
-	{
-	push(@out,"\tALIGN\t$_[0]\n");
-	}
-
-sub out1p
-	{
-	local($name,$p1)=@_;
-	local($l,$t);
-
-	push(@out,"\t$name\t".&conv($p1)."\n");
-	}
-
-sub main'picmeup
-	{
-	local($dst,$sym)=@_;
-	&main'lea($dst,&main'DWP($sym));
-	}
-
-sub main'blindpop { &out1("pop",@_); }
-
-sub main'initseg 
-	{
-	local($f)=@_;
-	local($tmp)=<<___;
-OPTION	DOTNAME
-.CRT\$XCU	SEGMENT DWORD PUBLIC 'DATA'
-EXTRN	_$f:NEAR
-DD	_$f
-.CRT\$XCU	ENDS
-___
-	push(@out,$tmp);
-	}
-
-1;
diff --git a/crypto/perlasm/x86nasm.pl b/crypto/perlasm/x86nasm.pl
index fa38f89..ce2bed9 100644
--- a/crypto/perlasm/x86nasm.pl
+++ b/crypto/perlasm/x86nasm.pl
@@ -1,455 +1,166 @@
-#!/usr/local/bin/perl
+#!/usr/bin/env perl
 
 package x86nasm;
 
-$label="L000";
-$under=($main'netware)?'':'_';
+*out=\@::out;
 
-%lb=(	'eax',	'al',
-	'ebx',	'bl',
-	'ecx',	'cl',
-	'edx',	'dl',
-	'ax',	'al',
-	'bx',	'bl',
-	'cx',	'cl',
-	'dx',	'dl',
-	);
+$::lbdecor="L\$";		# local label decoration
+$nmdecor=$::netware?"":"_";	# external name decoration
+$drdecor=$::mwerks?".":"";	# directive decoration
 
-%hb=(	'eax',	'ah',
-	'ebx',	'bh',
-	'ecx',	'ch',
-	'edx',	'dh',
-	'ax',	'ah',
-	'bx',	'bh',
-	'cx',	'ch',
-	'dx',	'dh',
-	);
+$initseg="";
 
-sub main'asm_init_output { @out=(); }
-sub main'asm_get_output { return(@out); }
-sub main'get_labels { return(@labels); }
+sub ::generic
+{ my $opcode=shift;
+  my $tmp;
 
-sub main'external_label
-{
-	push(@labels,@_);
-	foreach (@_) {
-		push(@out,".") if ($main'mwerks);
-		push(@out, "extern\t${under}$_\n");
-	}
+    if (!$::mwerks)
+    {   if    ($opcode =~ m/^j/o && $#_==0) # optimize jumps
+	{   $_[0] = "NEAR $_[0]";   	}
+	elsif ($opcode eq "lea" && $#_==1)  # wipe storage qualifier from lea
+	{   $_[1] =~ s/^[^\[]*\[/\[/o;	}
+    }
+    &::emit($opcode,@_);
+  1;
 }
-
-sub main'LB
-	{
-	(defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
-	return($lb{$_[0]});
-	}
-
-sub main'HB
-	{
-	(defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
-	return($hb{$_[0]});
-	}
-
-sub main'BP
-	{
-	&get_mem("BYTE",@_);
-	}
-
-sub main'DWP
-	{
-	&get_mem("DWORD",@_);
-	}
-
-sub main'QWP
-	{
-	&get_mem("",@_);
-	}
-
-sub main'BC
-	{
-	return (($main'mwerks)?"":"BYTE ")."@_";
-	}
-
-sub main'DWC
-	{
-	return (($main'mwerks)?"":"DWORD ")."@_";
-	}
-
-sub main'stack_push
-	{
-	my($num)=@_;
-	$stack+=$num*4;
-	&main'sub("esp",$num*4);
-	}
-
-sub main'stack_pop
-	{
-	my($num)=@_;
-	$stack-=$num*4;
-	&main'add("esp",$num*4);
-	}
+#
+# opcodes not covered by ::generic above, mostly inconsistent namings...
+#
+sub ::call	{ &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); }
+sub ::call_ptr	{ &::emit("call",@_);	}
+sub ::jmp_ptr	{ &::emit("jmp",@_);	}
 
 sub get_mem
-	{
-	my($size,$addr,$reg1,$reg2,$idx)=@_;
-	my($t,$post);
-	my($ret)=$size;
-	if ($ret ne "")
-		{
-		$ret .= " PTR" if ($main'mwerks);
-		$ret .= " ";
-		}
-	$ret .= "[";
-	$addr =~ s/^\s+//;
-	if ($addr =~ /^(.+)\+(.+)$/)
-		{
-		$reg2=&conv($1);
-		$addr="$under$2";
-		}
-	elsif ($addr =~ /^[_a-z][_a-z0-9]*$/i)
-		{
-		$addr="$under$addr";
-		}
+{ my($size,$addr,$reg1,$reg2,$idx)=@_;
+  my($post,$ret);
 
-	if ($addr =~ /^.+\-.+$/) { $addr="($addr)"; }
+    if ($size ne "")
+    {	$ret .= "$size";
+	$ret .= " PTR" if ($::mwerks);
+	$ret .= " ";
+    }
+    $ret .= "[";
 
-	$reg1="$regs{$reg1}" if defined($regs{$reg1});
-	$reg2="$regs{$reg2}" if defined($regs{$reg2});
-	if (($addr ne "") && ($addr ne 0))
-		{
-		if ($addr !~ /^-/)
-			{ $ret.="${addr}+"; }
-		else	{ $post=$addr; }
-		}
-	if ($reg2 ne "")
-		{
-		$t="";
-		$t="*$idx" if ($idx != 0);
-		$reg1="+".$reg1 if ("$reg1$post" ne "");
-		$ret.="$reg2$t$reg1$post]";
-		}
-	else
-		{
-		$ret.="$reg1$post]"
-		}
-	$ret =~ s/\+\]/]/; # in case $addr was the only argument
-	return($ret);
-	}
+    $addr =~ s/^\s+//;
+    # prepend global references with optional underscore
+    $addr =~ s/^([^\+\-0-9][^\+\-]*)/::islabel($1) or "$nmdecor$1"/ige;
+    # put address arithmetic expression in parenthesis
+    $addr="($addr)" if ($addr =~ /^.+[\-\+].+$/);
 
-sub main'mov	{ &out2("mov",@_); }
-sub main'movb	{ &out2("mov",@_); }
-sub main'and	{ &out2("and",@_); }
-sub main'or	{ &out2("or",@_); }
-sub main'shl	{ &out2("shl",@_); }
-sub main'shr	{ &out2("shr",@_); }
-sub main'xor	{ &out2("xor",@_); }
-sub main'xorb	{ &out2("xor",@_); }
-sub main'add	{ &out2("add",@_); }
-sub main'adc	{ &out2("adc",@_); }
-sub main'sub	{ &out2("sub",@_); }
-sub main'sbb	{ &out2("sbb",@_); }
-sub main'rotl	{ &out2("rol",@_); }
-sub main'rotr	{ &out2("ror",@_); }
-sub main'exch	{ &out2("xchg",@_); }
-sub main'cmp	{ &out2("cmp",@_); }
-sub main'lea	{ &out2("lea",@_); }
-sub main'mul	{ &out1("mul",@_); }
-sub main'imul	{ &out2("imul",@_); }
-sub main'div	{ &out1("div",@_); }
-sub main'dec	{ &out1("dec",@_); }
-sub main'inc	{ &out1("inc",@_); }
-sub main'jmp	{ &out1("jmp",@_); }
-sub main'jmp_ptr { &out1p("jmp",@_); }
+    if (($addr ne "") && ($addr ne 0))
+    {	if ($addr !~ /^-/)	{ $ret .= "$addr+"; }
+	else			{ $post=$addr;      }
+    }
 
-# This is a bit of a kludge: declare all branches as NEAR.
-$near=($main'mwerks)?'':'NEAR';
-sub main'je	{ &out1("je $near",@_); }
-sub main'jle	{ &out1("jle $near",@_); }
-sub main'jz	{ &out1("jz $near",@_); }
-sub main'jge	{ &out1("jge $near",@_); }
-sub main'jl	{ &out1("jl $near",@_); }
-sub main'ja	{ &out1("ja $near",@_); }
-sub main'jae	{ &out1("jae $near",@_); }
-sub main'jb	{ &out1("jb $near",@_); }
-sub main'jbe	{ &out1("jbe $near",@_); }
-sub main'jc	{ &out1("jc $near",@_); }
-sub main'jnc	{ &out1("jnc $near",@_); }
-sub main'jnz	{ &out1("jnz $near",@_); }
-sub main'jne	{ &out1("jne $near",@_); }
-sub main'jno	{ &out1("jno $near",@_); }
+    if ($reg2 ne "")
+    {	$idx!=0 or $idx=1;
+	$ret .= "$reg2*$idx";
+	$ret .= "+$reg1" if ($reg1 ne "");
+    }
+    else
+    {	$ret .= "$reg1";   }
 
-sub main'push	{ &out1("push",@_); $stack+=4; }
-sub main'pop	{ &out1("pop",@_); $stack-=4; }
-sub main'pushf	{ &out0("pushfd"); $stack+=4; }
-sub main'popf	{ &out0("popfd"); $stack-=4; }
-sub main'bswap	{ &out1("bswap",@_); &using486(); }
-sub main'not	{ &out1("not",@_); }
-sub main'call	{ &out1("call",($_[0]=~/^\@L/?'':$under).$_[0]); }
-sub main'call_ptr { &out1p("call",@_); }
-sub main'ret	{ &out0("ret"); }
-sub main'nop	{ &out0("nop"); }
-sub main'test	{ &out2("test",@_); }
-sub main'bt	{ &out2("bt",@_); }
-sub main'leave	{ &out0("leave"); }
-sub main'cpuid	{ &out0("cpuid"); }
-sub main'rdtsc	{ &out0("rdtsc"); }
-sub main'halt	{ &out0("hlt"); }
-sub main'movz	{ &out2("movzx",@_); }
-sub main'neg	{ &out1("neg",@_); }
-sub main'cld	{ &out0("cld"); }
+    $ret .= "$post]";
+    $ret =~ s/\+\]/]/; # in case $addr was the only argument
 
-# SSE2
-sub main'emms	{ &out0("emms"); }
-sub main'movd	{ &out2("movd",@_); }
-sub main'movq	{ &out2("movq",@_); }
-sub main'movdqu	{ &out2("movdqu",@_); }
-sub main'movdqa	{ &out2("movdqa",@_); }
-sub main'movdq2q{ &out2("movdq2q",@_); }
-sub main'movq2dq{ &out2("movq2dq",@_); }
-sub main'paddq	{ &out2("paddq",@_); }
-sub main'pmuludq{ &out2("pmuludq",@_); }
-sub main'psrlq	{ &out2("psrlq",@_); }
-sub main'psllq	{ &out2("psllq",@_); }
-sub main'pxor	{ &out2("pxor",@_); }
-sub main'por	{ &out2("por",@_); }
-sub main'pand	{ &out2("pand",@_); }
+  $ret;
+}
+sub ::BP	{ &get_mem("BYTE",@_);  }
+sub ::DWP	{ &get_mem("DWORD",@_); }
+sub ::QWP	{ &get_mem("",@_);      }
+sub ::BC	{ (($::mwerks)?"":"BYTE ")."@_";  }
+sub ::DWC	{ (($::mwerks)?"":"DWORD ")."@_"; }
 
-sub out2
-	{
-	my($name,$p1,$p2)=@_;
-	my($l,$t);
-
-	push(@out,"\t$name\t");
-	if (!$main'mwerks and $name eq "lea")
-		{
-		$p1 =~ s/^[^\[]*\[/\[/;
-		$p2 =~ s/^[^\[]*\[/\[/;
-		}
-	$t=&conv($p1).",";
-	$l=length($t);
-	push(@out,$t);
-	$l=4-($l+9)/8;
-	push(@out,"\t" x $l);
-	push(@out,&conv($p2));
-	push(@out,"\n");
-	}
-
-sub out0
-	{
-	my($name)=@_;
-
-	push(@out,"\t$name\n");
-	}
-
-sub out1
-	{
-	my($name,$p1)=@_;
-	my($l,$t);
-	push(@out,"\t$name\t".&conv($p1)."\n");
-	}
-
-sub conv
-	{
-	my($p)=@_;
-	$p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
-	return $p;
-	}
-
-sub using486
-	{
-	return if $using486;
-	$using486++;
-	grep(s/\.386/\.486/,@out);
-	}
-
-sub main'file
-	{
-	if ($main'mwerks)	{ push(@out,".section\t.text\n"); }
-	else	{
-		local $tmp=<<___;
-%ifdef __omf__
-section	code	use32 class=code
+sub ::file
+{   if ($::mwerks)	{ push(@out,".section\t.text,64\n"); }
+    else
+    { my $tmp=<<___;
+%ifidn __OUTPUT_FORMAT__,obj
+section	code	use32 class=code align=64
+%elifidn __OUTPUT_FORMAT__,win32
+\$\@feat.00 equ 1
+section	.text	code align=64
 %else
-section	.text
+section	.text	code
 %endif
 ___
-		push(@out,$tmp);
-		}
-	}
-
-sub main'function_begin
-	{
-	my($func,$extra)=@_;
-
-	push(@labels,$func);
-	push(@out,".") if ($main'mwerks);
-	my($tmp)=<<"EOF";
-global	$under$func
-$under$func:
-	push	ebp
-	push	ebx
-	push	esi
-	push	edi
-EOF
 	push(@out,$tmp);
-	$stack=20;
-	}
+    }
+}
 
-sub main'function_begin_B
-	{
-	my($func,$extra)=@_;
-	push(@out,".") if ($main'mwerks);
-	my($tmp)=<<"EOF";
-global	$under$func
-$under$func:
-EOF
-	push(@out,$tmp);
-	$stack=4;
-	}
+sub ::function_begin_B
+{ my $func=shift;
+  my $global=($func !~ /^_/);
+  my $begin="${::lbdecor}_${func}_begin";
 
-sub main'function_end
-	{
-	my($func)=@_;
+    $begin =~ s/^\@/./ if ($::mwerks);	# the torture never stops
 
-	my($tmp)=<<"EOF";
-	pop	edi
-	pop	esi
-	pop	ebx
-	pop	ebp
-	ret
-EOF
-	push(@out,$tmp);
-	$stack=0;
-	%label=();
-	}
+    &::LABEL($func,$global?"$begin":"$nmdecor$func");
+    $func=$nmdecor.$func;
 
-sub main'function_end_B
-	{
-	$stack=0;
-	%label=();
-	}
+    push(@out,"${drdecor}global	$func\n")	if ($global);
+    push(@out,"${drdecor}align	16\n");
+    push(@out,"$func:\n");
+    push(@out,"$begin:\n")			if ($global);
+    $::stack=4;
+}
 
-sub main'function_end_A
-	{
-	my($func)=@_;
+sub ::function_end_B
+{   $::stack=0;
+    &::wipe_labels();
+}
 
-	my($tmp)=<<"EOF";
-	pop	edi
-	pop	esi
-	pop	ebx
-	pop	ebp
-	ret
-EOF
-	push(@out,$tmp);
-	}
-
-sub main'file_end
-	{
-	}
-
-sub main'wparam
-	{
-	my($num)=@_;
-
-	return(&main'DWP($stack+$num*4,"esp","",0));
-	}
-
-sub main'swtmp
-	{
-	return(&main'DWP($_[0]*4,"esp","",0));
-	}
-
-# Should use swtmp, which is above esp.  Linix can trash the stack above esp
-#sub main'wtmp
-#	{
-#	my($num)=@_;
-#
-#	return(&main'DWP(-(($num+1)*4),"esp","",0));
-#	}
-
-sub main'comment
-	{
-	foreach (@_)
-		{
-		push(@out,"\t; $_\n");
-		}
-	}
-
-sub main'public_label
-	{
-	$label{$_[0]}="${under}${_[0]}"	if (!defined($label{$_[0]}));
-	push(@out,".") if ($main'mwerks);
-	push(@out,"global\t$label{$_[0]}\n");
-	}
-
-sub main'label
-	{
-	if (!defined($label{$_[0]}))
-		{
-		$label{$_[0]}="\@${label}${_[0]}";
-		$label++;
-		}
-	return($label{$_[0]});
-	}
-
-sub main'set_label
-	{
-	if (!defined($label{$_[0]}))
-		{
-		$label{$_[0]}="\@${label}${_[0]}";
-		$label++;
-		}
-	if ($_[1]!=0 && $_[1]>1)
-		{
-		main'align($_[1]);
-		}
-	push(@out,"$label{$_[0]}:\n");
-	}
-
-sub main'data_byte
-	{
-	push(@out,(($main'mwerks)?".byte\t":"DB\t").join(',',@_)."\n");
-	}
-
-sub main'data_word
-	{
-	push(@out,(($main'mwerks)?".long\t":"DD\t").join(',',@_)."\n");
-	}
-
-sub main'align
-	{
-	push(@out,".") if ($main'mwerks);
-	push(@out,"align\t$_[0]\n");
-	}
-
-sub out1p
-	{
-	my($name,$p1)=@_;
-	my($l,$t);
-
-	push(@out,"\t$name\t".&conv($p1)."\n");
-	}
-
-sub main'picmeup
-	{
-	local($dst,$sym)=@_;
-	&main'lea($dst,&main'DWP($sym));
-	}
-
-sub main'blindpop { &out1("pop",@_); }
-
-sub main'initseg
-	{
-	local($f)=@_;
-	if ($main'win32)
-		{
-		local($tmp)=<<___;
-segment	.CRT\$XCU data
-extern	$under$f
-DD	$under$f
+sub ::file_end
+{   if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out)
+    {	my $comm=<<___;
+${drdecor}segment	.bss
+${drdecor}common	${nmdecor}OPENSSL_ia32cap_P 4
 ___
-		push(@out,$tmp);
-		}
-	}
+	# comment out OPENSSL_ia32cap_P declarations
+	grep {s/(^extern\s+${nmdecor}OPENSSL_ia32cap_P)/\;$1/} @out;
+	push (@out,$comm)
+    }
+    push (@out,$initseg) if ($initseg);		
+}
+
+sub ::comment {   foreach (@_) { push(@out,"\t; $_\n"); }   }
+
+sub ::external_label
+{   foreach(@_)
+    {	push(@out,"${drdecor}extern\t".&::LABEL($_,$nmdecor.$_)."\n");   }
+}
+
+sub ::public_label
+{   push(@out,"${drdecor}global\t".&::LABEL($_[0],$nmdecor.$_[0])."\n");  }
+
+sub ::data_byte
+{   push(@out,(($::mwerks)?".byte\t":"db\t").join(',',@_)."\n");	}
+
+sub ::data_word
+{   push(@out,(($::mwerks)?".long\t":"dd\t").join(',',@_)."\n");	}
+
+sub ::align
+{   push(@out,"${drdecor}align\t$_[0]\n");	}
+
+sub ::picmeup
+{ my($dst,$sym)=@_;
+    &::lea($dst,&::DWP($sym));
+}
+
+sub ::initseg
+{ my $f=$nmdecor.shift;
+    if ($::win32)
+    {	$initseg=<<___;
+segment	.CRT\$XCU data align=4
+extern	$f
+dd	$f
+___
+    }
+}
+
+sub ::dataseg
+{   if ($mwerks)	{ push(@out,".section\t.data,4\n");   }
+    else		{ push(@out,"section\t.data align=4\n"); }
+}
 
 1;
diff --git a/crypto/perlasm/x86unix.pl b/crypto/perlasm/x86unix.pl
deleted file mode 100644
index a4c9471..0000000
--- a/crypto/perlasm/x86unix.pl
+++ /dev/null
@@ -1,725 +0,0 @@
-#!/usr/local/bin/perl
-
-package x86unix;	# GAS actually...
-
-$label="L000";
-$const="";
-$constl=0;
-
-$align=($main'aout)?"4":"16";
-$under=($main'aout or $main'coff)?"_":"";
-$dot=($main'aout)?"":".";
-$com_start="#" if ($main'aout or $main'coff);
-
-sub main'asm_init_output { @out=(); }
-sub main'asm_get_output { return(@out); }
-sub main'get_labels { return(@labels); }
-sub main'external_label { push(@labels,@_); }
-
-if ($main'cpp)
-	{
-	$align="ALIGN";
-	$under="";
-	$com_start='/*';
-	$com_end='*/';
-	}
-
-%lb=(	'eax',	'%al',
-	'ebx',	'%bl',
-	'ecx',	'%cl',
-	'edx',	'%dl',
-	'ax',	'%al',
-	'bx',	'%bl',
-	'cx',	'%cl',
-	'dx',	'%dl',
-	);
-
-%hb=(	'eax',	'%ah',
-	'ebx',	'%bh',
-	'ecx',	'%ch',
-	'edx',	'%dh',
-	'ax',	'%ah',
-	'bx',	'%bh',
-	'cx',	'%ch',
-	'dx',	'%dh',
-	);
-
-%regs=(	'eax',	'%eax',
-	'ebx',	'%ebx',
-	'ecx',	'%ecx',
-	'edx',	'%edx',
-	'esi',	'%esi',
-	'edi',	'%edi',
-	'ebp',	'%ebp',
-	'esp',	'%esp',
-
-	'mm0',	'%mm0',
-	'mm1',	'%mm1',
-	'mm2',	'%mm2',
-	'mm3',	'%mm3',
-	'mm4',	'%mm4',
-	'mm5',	'%mm5',
-	'mm6',	'%mm6',
-	'mm7',	'%mm7',
-
-	'xmm0',	'%xmm0',
-	'xmm1',	'%xmm1',
-	'xmm2',	'%xmm2',
-	'xmm3',	'%xmm3',
-	'xmm4',	'%xmm4',
-	'xmm5',	'%xmm5',
-	'xmm6',	'%xmm6',
-	'xmm7',	'%xmm7',
-	);
-
-%reg_val=(
-	'eax',	0x00,
-	'ebx',	0x03,
-	'ecx',	0x01,
-	'edx',	0x02,
-	'esi',	0x06,
-	'edi',	0x07,
-	'ebp',	0x05,
-	'esp',	0x04,
-	);
-
-sub main'LB
-	{
-	(defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
-	return($lb{$_[0]});
-	}
-
-sub main'HB
-	{
-	(defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
-	return($hb{$_[0]});
-	}
-
-sub main'DWP
-	{
-	local($addr,$reg1,$reg2,$idx)=@_;
-
-	$ret="";
-	$addr =~ s/(^|[+ \t])([A-Za-z_]+[A-Za-z0-9_]+)($|[+ \t])/$1$under$2$3/;
-	$reg1="$regs{$reg1}" if defined($regs{$reg1});
-	$reg2="$regs{$reg2}" if defined($regs{$reg2});
-	$ret.=$addr if ($addr ne "") && ($addr ne 0);
-	if ($reg2 ne "")
-		{
-		if($idx ne "" && $idx != 0)
-		    { $ret.="($reg1,$reg2,$idx)"; }
-		else
-		    { $ret.="($reg1,$reg2)"; }
-	        }
-	elsif ($reg1 ne "")
-		{ $ret.="($reg1)" }
-	return($ret);
-	}
-
-sub main'QWP
-	{
-	return(&main'DWP(@_));
-	}
-
-sub main'BP
-	{
-	return(&main'DWP(@_));
-	}
-
-sub main'BC
-	{
-	return @_;
-	}
-
-sub main'DWC
-	{
-	return @_;
-	}
-
-#sub main'BP
-#	{
-#	local($addr,$reg1,$reg2,$idx)=@_;
-#
-#	$ret="";
-#
-#	$addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/;
-#	$reg1="$regs{$reg1}" if defined($regs{$reg1});
-#	$reg2="$regs{$reg2}" if defined($regs{$reg2});
-#	$ret.=$addr if ($addr ne "") && ($addr ne 0);
-#	if ($reg2 ne "")
-#		{ $ret.="($reg1,$reg2,$idx)"; }
-#	else
-#		{ $ret.="($reg1)" }
-#	return($ret);
-#	}
-
-sub main'mov	{ &out2("movl",@_); }
-sub main'movb	{ &out2("movb",@_); }
-sub main'and	{ &out2("andl",@_); }
-sub main'or	{ &out2("orl",@_); }
-sub main'shl	{ &out2("sall",@_); }
-sub main'shr	{ &out2("shrl",@_); }
-sub main'xor	{ &out2("xorl",@_); }
-sub main'xorb	{ &out2("xorb",@_); }
-sub main'add	{ &out2($_[0]=~/%[a-d][lh]/?"addb":"addl",@_); }
-sub main'adc	{ &out2("adcl",@_); }
-sub main'sub	{ &out2("subl",@_); }
-sub main'sbb	{ &out2("sbbl",@_); }
-sub main'rotl	{ &out2("roll",@_); }
-sub main'rotr	{ &out2("rorl",@_); }
-sub main'exch	{ &out2($_[0]=~/%[a-d][lh]/?"xchgb":"xchgl",@_); }
-sub main'cmp	{ &out2("cmpl",@_); }
-sub main'lea	{ &out2("leal",@_); }
-sub main'mul	{ &out1("mull",@_); }
-sub main'imul	{ &out2("imull",@_); }
-sub main'div	{ &out1("divl",@_); }
-sub main'jmp	{ &out1("jmp",@_); }
-sub main'jmp_ptr { &out1p("jmp",@_); }
-sub main'je	{ &out1("je",@_); }
-sub main'jle	{ &out1("jle",@_); }
-sub main'jne	{ &out1("jne",@_); }
-sub main'jnz	{ &out1("jnz",@_); }
-sub main'jz	{ &out1("jz",@_); }
-sub main'jge	{ &out1("jge",@_); }
-sub main'jl	{ &out1("jl",@_); }
-sub main'ja	{ &out1("ja",@_); }
-sub main'jae	{ &out1("jae",@_); }
-sub main'jb	{ &out1("jb",@_); }
-sub main'jbe	{ &out1("jbe",@_); }
-sub main'jc	{ &out1("jc",@_); }
-sub main'jnc	{ &out1("jnc",@_); }
-sub main'jno	{ &out1("jno",@_); }
-sub main'dec	{ &out1("decl",@_); }
-sub main'inc	{ &out1($_[0]=~/%[a-d][hl]/?"incb":"incl",@_); }
-sub main'push	{ &out1("pushl",@_); $stack+=4; }
-sub main'pop	{ &out1("popl",@_); $stack-=4; }
-sub main'pushf	{ &out0("pushfl"); $stack+=4; }
-sub main'popf	{ &out0("popfl"); $stack-=4; }
-sub main'not	{ &out1("notl",@_); }
-sub main'call	{	my $pre=$under;
-			foreach $i (%label)
-			{ if ($label{$i} eq $_[0]) { $pre=''; last; } }
-			&out1("call",$pre.$_[0]);
-		}
-sub main'call_ptr { &out1p("call",@_); }
-sub main'ret	{ &out0("ret"); }
-sub main'nop	{ &out0("nop"); }
-sub main'test	{ &out2("testl",@_); }
-sub main'bt	{ &out2("btl",@_); }
-sub main'leave	{ &out0("leave"); }
-sub main'cpuid	{ &out0(".byte\t0x0f,0xa2"); }
-sub main'rdtsc	{ &out0(".byte\t0x0f,0x31"); }
-sub main'halt	{ &out0("hlt"); }
-sub main'movz	{ &out2("movzbl",@_); }
-sub main'neg	{ &out1("negl",@_); }
-sub main'cld	{ &out0("cld"); }
-
-# SSE2
-sub main'emms	{ &out0("emms"); }
-sub main'movd	{ &out2("movd",@_); }
-sub main'movdqu	{ &out2("movdqu",@_); }
-sub main'movdqa	{ &out2("movdqa",@_); }
-sub main'movdq2q{ &out2("movdq2q",@_); }
-sub main'movq2dq{ &out2("movq2dq",@_); }
-sub main'paddq	{ &out2("paddq",@_); }
-sub main'pmuludq{ &out2("pmuludq",@_); }
-sub main'psrlq	{ &out2("psrlq",@_); }
-sub main'psllq	{ &out2("psllq",@_); }
-sub main'pxor	{ &out2("pxor",@_); }
-sub main'por	{ &out2("por",@_); }
-sub main'pand	{ &out2("pand",@_); }
-sub main'movq	{
-	local($p1,$p2,$optimize)=@_;
-	if ($optimize && $p1=~/^mm[0-7]$/ && $p2=~/^mm[0-7]$/)
-		# movq between mmx registers can sink Intel CPUs
-		{	push(@out,"\tpshufw\t\$0xe4,%$p2,%$p1\n");	}
-	else	{	&out2("movq",@_);				}
-	}
-
-# The bswapl instruction is new for the 486. Emulate if i386.
-sub main'bswap
-	{
-	if ($main'i386)
-		{
-		&main'comment("bswapl @_");
-		&main'exch(main'HB(@_),main'LB(@_));
-		&main'rotr(@_,16);
-		&main'exch(main'HB(@_),main'LB(@_));
-		}
-	else
-		{
-		&out1("bswapl",@_);
-		}
-	}
-
-sub out2
-	{
-	local($name,$p1,$p2)=@_;
-	local($l,$ll,$t);
-	local(%special)=(	"roll",0xD1C0,"rorl",0xD1C8,
-				"rcll",0xD1D0,"rcrl",0xD1D8,
-				"shll",0xD1E0,"shrl",0xD1E8,
-				"sarl",0xD1F8);
-	
-	if ((defined($special{$name})) && defined($regs{$p1}) && ($p2 == 1))
-		{
-		$op=$special{$name}|$reg_val{$p1};
-		$tmp1=sprintf(".byte %d\n",($op>>8)&0xff);
-		$tmp2=sprintf(".byte %d\t",$op     &0xff);
-		push(@out,$tmp1);
-		push(@out,$tmp2);
-
-		$p2=&conv($p2);
-		$p1=&conv($p1);
-		&main'comment("$name $p2 $p1");
-		return;
-		}
-
-	push(@out,"\t$name\t");
-	$t=&conv($p2).",";
-	$l=length($t);
-	push(@out,$t);
-	$ll=4-($l+9)/8;
-	$tmp1=sprintf("\t" x $ll);
-	push(@out,$tmp1);
-	push(@out,&conv($p1)."\n");
-	}
-
-sub out1
-	{
-	local($name,$p1)=@_;
-	local($l,$t);
-	local(%special)=("bswapl",0x0FC8);
-
-	if ((defined($special{$name})) && defined($regs{$p1}))
-		{
-		$op=$special{$name}|$reg_val{$p1};
-		$tmp1=sprintf(".byte %d\n",($op>>8)&0xff);
-		$tmp2=sprintf(".byte %d\t",$op     &0xff);
-		push(@out,$tmp1);
-		push(@out,$tmp2);
-
-		$p2=&conv($p2);
-		$p1=&conv($p1);
-		&main'comment("$name $p2 $p1");
-		return;
-		}
-
-	push(@out,"\t$name\t".&conv($p1)."\n");
-	}
-
-sub out1p
-	{
-	local($name,$p1)=@_;
-	local($l,$t);
-
-	push(@out,"\t$name\t*".&conv($p1)."\n");
-	}
-
-sub out0
-	{
-	push(@out,"\t$_[0]\n");
-	}
-
-sub conv
-	{
-	local($p)=@_;
-
-#	$p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
-
-	$p=$regs{$p} if (defined($regs{$p}));
-
-	$p =~ s/^(-{0,1}[0-9A-Fa-f]+)$/\$$1/;
-	$p =~ s/^(0x[0-9A-Fa-f]+)$/\$$1/;
-	return $p;
-	}
-
-sub main'file
-	{
-	local($file)=@_;
-
-	local($tmp)=<<"EOF";
-	.file	"$file.s"
-EOF
-	push(@out,$tmp);
-	}
-
-sub main'function_begin
-	{
-	local($func)=@_;
-
-	&main'external_label($func);
-	$func=$under.$func;
-
-	local($tmp)=<<"EOF";
-.text
-.globl	$func
-EOF
-	push(@out,$tmp);
-	if ($main'cpp)
-		{ $tmp=push(@out,"TYPE($func,\@function)\n"); }
-	elsif ($main'coff)
-		{ $tmp=push(@out,".def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); }
-	elsif ($main'aout and !$main'pic)
-		{ }
-	else	{ $tmp=push(@out,".type\t$func,\@function\n"); }
-	push(@out,".align\t$align\n");
-	push(@out,"$func:\n");
-	$tmp=<<"EOF";
-	pushl	%ebp
-	pushl	%ebx
-	pushl	%esi
-	pushl	%edi
-
-EOF
-	push(@out,$tmp);
-	$stack=20;
-	}
-
-sub main'function_begin_B
-	{
-	local($func,$extra)=@_;
-
-	&main'external_label($func);
-	$func=$under.$func;
-
-	local($tmp)=<<"EOF";
-.text
-.globl	$func
-EOF
-	push(@out,$tmp);
-	if ($main'cpp)
-		{ push(@out,"TYPE($func,\@function)\n"); }
-	elsif ($main'coff)
-		{ $tmp=push(@out,".def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); }
-	elsif ($main'aout and !$main'pic)
-		{ }
-	else	{ push(@out,".type	$func,\@function\n"); }
-	push(@out,".align\t$align\n");
-	push(@out,"$func:\n");
-	$stack=4;
-	}
-
-sub main'function_end
-	{
-	local($func)=@_;
-
-	$func=$under.$func;
-
-	local($tmp)=<<"EOF";
-	popl	%edi
-	popl	%esi
-	popl	%ebx
-	popl	%ebp
-	ret
-${dot}L_${func}_end:
-EOF
-	push(@out,$tmp);
-
-	if ($main'cpp)
-		{ push(@out,"SIZE($func,${dot}L_${func}_end-$func)\n"); }
-	elsif ($main'coff or $main'aout)
-                { }
-	else	{ push(@out,".size\t$func,${dot}L_${func}_end-$func\n"); }
-	push(@out,".ident	\"$func\"\n");
-	$stack=0;
-	%label=();
-	}
-
-sub main'function_end_A
-	{
-	local($func)=@_;
-
-	local($tmp)=<<"EOF";
-	popl	%edi
-	popl	%esi
-	popl	%ebx
-	popl	%ebp
-	ret
-EOF
-	push(@out,$tmp);
-	}
-
-sub main'function_end_B
-	{
-	local($func)=@_;
-
-	$func=$under.$func;
-
-	push(@out,"${dot}L_${func}_end:\n");
-	if ($main'cpp)
-		{ push(@out,"SIZE($func,${dot}L_${func}_end-$func)\n"); }
-        elsif ($main'coff or $main'aout)
-                { }
-	else	{ push(@out,".size\t$func,${dot}L_${func}_end-$func\n"); }
-	push(@out,".ident	\"$func\"\n");
-	$stack=0;
-	%label=();
-	}
-
-sub main'wparam
-	{
-	local($num)=@_;
-
-	return(&main'DWP($stack+$num*4,"esp","",0));
-	}
-
-sub main'stack_push
-	{
-	local($num)=@_;
-	$stack+=$num*4;
-	&main'sub("esp",$num*4);
-	}
-
-sub main'stack_pop
-	{
-	local($num)=@_;
-	$stack-=$num*4;
-	&main'add("esp",$num*4);
-	}
-
-sub main'swtmp
-	{
-	return(&main'DWP($_[0]*4,"esp","",0));
-	}
-
-# Should use swtmp, which is above esp.  Linix can trash the stack above esp
-#sub main'wtmp
-#	{
-#	local($num)=@_;
-#
-#	return(&main'DWP(-($num+1)*4,"esp","",0));
-#	}
-
-sub main'comment
-	{
-	if (!defined($com_start) or $main'elf)
-		{	# Regarding $main'elf above...
-			# GNU and SVR4 as'es use different comment delimiters,
-		push(@out,"\n");	# so we just skip ELF comments...
-		return;
-		}
-	foreach (@_)
-		{
-		if (/^\s*$/)
-			{ push(@out,"\n"); }
-		else
-			{ push(@out,"\t$com_start $_ $com_end\n"); }
-		}
-	}
-
-sub main'public_label
-	{
-	$label{$_[0]}="${under}${_[0]}"	if (!defined($label{$_[0]}));
-	push(@out,".globl\t$label{$_[0]}\n");
-	}
-
-sub main'label
-	{
-	if (!defined($label{$_[0]}))
-		{
-		$label{$_[0]}="${dot}${label}${_[0]}";
-		$label++;
-		}
-	return($label{$_[0]});
-	}
-
-sub main'set_label
-	{
-	if (!defined($label{$_[0]}))
-		{
-		$label{$_[0]}="${dot}${label}${_[0]}";
-		$label++;
-		}
-	if ($_[1]!=0)
-		{
-		if ($_[1]>1)	{ main'align($_[1]);		}
-		else		{ push(@out,".align $align\n");	}
-		}
-	push(@out,"$label{$_[0]}:\n");
-	}
-
-sub main'file_end
-	{
-	# try to detect if SSE2 or MMX extensions were used on ELF platform...
-	if ($main'elf && grep {/\b%[x]*mm[0-7]\b|OPENSSL_ia32cap_P\b/i} @out) {
-		local($tmp);
-
-		push (@out,"\n.section\t.bss\n");
-		push (@out,".comm\t${under}OPENSSL_ia32cap_P,4,4\n");
-
-		return;
-	}
-
-	if ($const ne "")
-		{
-		push(@out,".section .rodata\n");
-		push(@out,$const);
-		$const="";
-		}
-	}
-
-sub main'data_byte
-	{
-	push(@out,"\t.byte\t".join(',',@_)."\n");
-	}
-
-sub main'data_word
-	{
-	push(@out,"\t.long\t".join(',',@_)."\n");
-	}
-
-sub main'align
-	{
-	my $val=$_[0],$p2,$i;
-	if ($main'aout) {
-		for ($p2=0;$val!=0;$val>>=1) { $p2++; }
-		$val=$p2-1;
-		$val.=",0x90";
-	}
-	push(@out,".align\t$val\n");
-	}
-
-# debug output functions: puts, putx, printf
-
-sub main'puts
-	{
-	&pushvars();
-	&main'push('$Lstring' . ++$constl);
-	&main'call('puts');
-	$stack-=4;
-	&main'add("esp",4);
-	&popvars();
-
-	$const .= "Lstring$constl:\n\t.string \"@_[0]\"\n";
-	}
-
-sub main'putx
-	{
-	&pushvars();
-	&main'push($_[0]);
-	&main'push('$Lstring' . ++$constl);
-	&main'call('printf');
-	&main'add("esp",8);
-	$stack-=8;
-	&popvars();
-
-	$const .= "Lstring$constl:\n\t.string \"\%X\"\n";
-	}
-
-sub main'printf
-	{
-	$ostack = $stack;
-	&pushvars();
-	for ($i = @_ - 1; $i >= 0; $i--)
-		{
-		if ($i == 0) # change this to support %s format strings
-			{
-			&main'push('$Lstring' . ++$constl);
-			$const .= "Lstring$constl:\n\t.string \"@_[$i]\"\n";
-			}
-		else
-			{
-			if ($_[$i] =~ /([0-9]*)\(%esp\)/)
-				{
-				&main'push(($1 + $stack - $ostack) . '(%esp)');
-				}
-			else
-				{
-				&main'push($_[$i]);
-				}
-			}
-		}
-	&main'call('printf');
-	$stack-=4*@_;
-	&main'add("esp",4*@_);
-	&popvars();
-	}
-
-sub pushvars
-	{
-	&main'pushf();
-	&main'push("edx");
-	&main'push("ecx");
-	&main'push("eax");
-	}
-
-sub popvars
-	{
-	&main'pop("eax");
-	&main'pop("ecx");
-	&main'pop("edx");
-	&main'popf();
-	}
-
-sub main'picmeup
-	{
-	local($dst,$sym)=@_;
-	if ($main'cpp)
-		{
-		local($tmp)=<<___;
-#if (defined(ELF) || defined(SOL)) && defined(PIC)
-	call	1f
-1:	popl	$regs{$dst}
-	addl	\$_GLOBAL_OFFSET_TABLE_+[.-1b],$regs{$dst}
-	movl	$sym\@GOT($regs{$dst}),$regs{$dst}
-#else
-	leal	$sym,$regs{$dst}
-#endif
-___
-		push(@out,$tmp);
-		}
-	elsif ($main'pic && ($main'elf || $main'aout))
-		{
-		&main'call(&main'label("PIC_me_up"));
-		&main'set_label("PIC_me_up");
-		&main'blindpop($dst);
-		&main'add($dst,"\$${under}_GLOBAL_OFFSET_TABLE_+[.-".
-				&main'label("PIC_me_up") . "]");
-		&main'mov($dst,&main'DWP($under.$sym."\@GOT",$dst));
-		}
-	else
-		{
-		&main'lea($dst,&main'DWP($sym));
-		}
-	}
-
-sub main'blindpop { &out1("popl",@_); }
-
-sub main'initseg
-	{
-	local($f)=@_;
-	local($tmp);
-	if ($main'elf)
-		{
-		$tmp=<<___;
-.section	.init
-	call	$under$f
-	jmp	.Linitalign
-.align	$align
-.Linitalign:
-___
-		}
-	elsif ($main'coff)
-		{
-		$tmp=<<___;	# applies to both Cygwin and Mingw
-.section	.ctors
-.long	$under$f
-___
-		}
-	elsif ($main'aout)
-		{
-		local($ctor)="${under}_GLOBAL_\$I\$$f";
-		$tmp=".text\n";
-		$tmp.=".type	$ctor,\@function\n" if ($main'pic);
-		$tmp.=<<___;	# OpenBSD way...
-.globl	$ctor
-.align	2
-$ctor:
-	jmp	$under$f
-___
-		}
-	push(@out,$tmp) if ($tmp);
-	}
-
-1;
diff --git a/crypto/pkcs12/Makefile b/crypto/pkcs12/Makefile
deleted file mode 100644
index eed226b..0000000
--- a/crypto/pkcs12/Makefile
+++ /dev/null
@@ -1,293 +0,0 @@
-#
-# OpenSSL/crypto/pkcs12/Makefile
-#
-
-DIR=	pkcs12
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC= p12_add.c p12_asn.c p12_attr.c p12_crpt.c p12_crt.c p12_decr.c \
-	p12_init.c p12_key.c p12_kiss.c p12_mutl.c\
-	p12_utl.c p12_npas.c pk12err.c p12_p8d.c p12_p8e.c
-LIBOBJ= p12_add.o p12_asn.o p12_attr.o p12_crpt.o p12_crt.o p12_decr.o \
-	p12_init.o p12_key.o p12_kiss.o p12_mutl.o\
-	p12_utl.o p12_npas.o pk12err.o p12_p8d.o p12_p8e.o
-
-SRC= $(LIBSRC)
-
-EXHEADER=  pkcs12.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-test:
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-p12_add.o: ../../e_os.h ../../include/openssl/asn1.h
-p12_add.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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/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/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
-p12_attr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-p12_attr.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-p12_attr.o: ../cryptlib.h p12_attr.c
-p12_crpt.o: ../../e_os.h ../../include/openssl/asn1.h
-p12_crpt.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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
-p12_crpt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-p12_crpt.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-p12_crpt.o: ../cryptlib.h p12_crpt.c
-p12_crt.o: ../../e_os.h ../../include/openssl/asn1.h
-p12_crt.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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/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
-p12_decr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-p12_decr.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-p12_decr.o: ../cryptlib.h p12_decr.c
-p12_init.o: ../../e_os.h ../../include/openssl/asn1.h
-p12_init.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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
-p12_init.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-p12_init.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-p12_init.o: ../cryptlib.h p12_init.c
-p12_key.o: ../../e_os.h ../../include/openssl/asn1.h
-p12_key.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-p12_key.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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/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
-p12_kiss.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-p12_kiss.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-p12_kiss.o: ../cryptlib.h p12_kiss.c
-p12_mutl.o: ../../e_os.h ../../include/openssl/asn1.h
-p12_mutl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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
-p12_mutl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-p12_mutl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-p12_mutl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_mutl.c
-p12_npas.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-p12_npas.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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
-p12_npas.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-p12_npas.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-p12_npas.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-p12_npas.o: p12_npas.c
-p12_p8d.o: ../../e_os.h ../../include/openssl/asn1.h
-p12_p8d.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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/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/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/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 1f3e378..27ac5fa 100644
--- a/crypto/pkcs12/p12_add.c
+++ b/crypto/pkcs12/p12_add.c
@@ -106,6 +106,7 @@
 	     PKCS8_PRIV_KEY_INFO *p8)
 {
 	PKCS12_SAFEBAG *bag;
+	const EVP_CIPHER *pbe_ciph;
 
 	/* Set up the safe bag */
 	if (!(bag = PKCS12_SAFEBAG_new())) {
@@ -114,8 +115,14 @@
 	}
 
 	bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag);
+
+	pbe_ciph = EVP_get_cipherbynid(pbe_nid);
+
+	if (pbe_ciph)
+		pbe_nid = -1;
+
 	if (!(bag->value.shkeybag = 
-	  PKCS8_encrypt(pbe_nid, NULL, pass, passlen, salt, saltlen, iter,
+	  PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter,
 									 p8))) {
 		PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
 		return NULL;
@@ -164,6 +171,7 @@
 {
 	PKCS7 *p7;
 	X509_ALGOR *pbe;
+	const EVP_CIPHER *pbe_ciph;
 	if (!(p7 = PKCS7_new())) {
 		PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
 		return NULL;
@@ -173,7 +181,15 @@
 				PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE);
 		return NULL;
 	}
-	if (!(pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen))) {
+
+	pbe_ciph = EVP_get_cipherbynid(pbe_nid);
+
+	if (pbe_ciph)
+		pbe = PKCS5_pbe2_set(pbe_ciph, iter, salt, saltlen);
+	else
+		pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
+
+	if (!pbe) {
 		PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
 		return NULL;
 	}
diff --git a/crypto/pkcs12/p12_attr.c b/crypto/pkcs12/p12_attr.c
index 856933d..e4d9c25 100644
--- a/crypto/pkcs12/p12_attr.c
+++ b/crypto/pkcs12/p12_attr.c
@@ -60,12 +60,6 @@
 #include "cryptlib.h"
 #include <openssl/pkcs12.h>
 
-#ifdef OPENSSL_SYS_NETWARE
-/* Rename these functions to avoid name clashes on NetWare OS */
-#define uni2asc OPENSSL_uni2asc
-#define asc2uni OPENSSL_asc2uni
-#endif
-
 /* Add a local keyid to a safebag */
 
 int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name,
@@ -145,7 +139,7 @@
 	ASN1_TYPE *atype;
 	if (!(atype = PKCS12_get_attr(bag, NID_friendlyName))) return NULL;
 	if (atype->type != V_ASN1_BMPSTRING) return NULL;
-	return uni2asc(atype->value.bmpstring->data,
+	return OPENSSL_uni2asc(atype->value.bmpstring->data,
 				 atype->value.bmpstring->length);
 }
 
diff --git a/crypto/pkcs12/p12_crpt.c b/crypto/pkcs12/p12_crpt.c
index f8b952e..b71d07b 100644
--- a/crypto/pkcs12/p12_crpt.c
+++ b/crypto/pkcs12/p12_crpt.c
@@ -60,28 +60,10 @@
 #include "cryptlib.h"
 #include <openssl/pkcs12.h>
 
-/* PKCS#12 specific PBE functions */
+/* PKCS#12 PBE algorithms now in static table */
 
 void PKCS12_PBE_add(void)
 {
-#ifndef OPENSSL_NO_RC4
-EVP_PBE_alg_add(NID_pbe_WithSHA1And128BitRC4, EVP_rc4(), EVP_sha1(),
-							 PKCS12_PBE_keyivgen);
-EVP_PBE_alg_add(NID_pbe_WithSHA1And40BitRC4, EVP_rc4_40(), EVP_sha1(),
-							 PKCS12_PBE_keyivgen);
-#endif
-#ifndef OPENSSL_NO_DES
-EVP_PBE_alg_add(NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
-		 	EVP_des_ede3_cbc(), EVP_sha1(), PKCS12_PBE_keyivgen);
-EVP_PBE_alg_add(NID_pbe_WithSHA1And2_Key_TripleDES_CBC, 
-			EVP_des_ede_cbc(), EVP_sha1(), PKCS12_PBE_keyivgen);
-#endif
-#ifndef OPENSSL_NO_RC2
-EVP_PBE_alg_add(NID_pbe_WithSHA1And128BitRC2_CBC, EVP_rc2_cbc(),
-					EVP_sha1(), PKCS12_PBE_keyivgen);
-EVP_PBE_alg_add(NID_pbe_WithSHA1And40BitRC2_CBC, EVP_rc2_40_cbc(),
-					EVP_sha1(), PKCS12_PBE_keyivgen);
-#endif
 }
 
 int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
diff --git a/crypto/pkcs12/p12_crt.c b/crypto/pkcs12/p12_crt.c
index 9522342..96b131d 100644
--- a/crypto/pkcs12/p12_crt.c
+++ b/crypto/pkcs12/p12_crt.c
@@ -59,10 +59,6 @@
 #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);
@@ -94,14 +90,7 @@
 
 	/* Set defaults */
 	if (!nid_cert)
-		{
-#ifdef OPENSSL_FIPS
-		if (FIPS_mode())
-			nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
-		else
-#endif
 		nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
-		}
 	if (!nid_key)
 		nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
 	if (!iter)
diff --git a/crypto/pkcs12/p12_key.c b/crypto/pkcs12/p12_key.c
index 5cfe727..a29794b 100644
--- a/crypto/pkcs12/p12_key.c
+++ b/crypto/pkcs12/p12_key.c
@@ -69,12 +69,6 @@
 void h__dump (unsigned char *p, int len);
 #endif
 
-#ifdef OPENSSL_SYS_NETWARE
-/* Rename these functions to avoid name clashes on NetWare OS */
-#define uni2asc OPENSSL_uni2asc
-#define asc2uni OPENSSL_asc2uni
-#endif
-
 /* PKCS12 compatible key/IV generation */
 #ifndef min
 #define min(a,b) ((a) < (b) ? (a) : (b))
@@ -87,15 +81,18 @@
 	int ret;
 	unsigned char *unipass;
 	int uniplen;
+
 	if(!pass) {
 		unipass = NULL;
 		uniplen = 0;
-	} else if (!asc2uni(pass, passlen, &unipass, &uniplen)) {
+	} else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) {
 		PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC,ERR_R_MALLOC_FAILURE);
 		return 0;
 	}
 	ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen,
 						 id, iter, n, out, md_type);
+	if (ret <= 0)
+	    return 0;
 	if(unipass) {
 		OPENSSL_cleanse(unipass, uniplen);	/* Clear password from memory */
 		OPENSSL_free(unipass);
@@ -135,6 +132,8 @@
 #endif
 	v = EVP_MD_block_size (md_type);
 	u = EVP_MD_size (md_type);
+	if (u < 0)
+	    return 0;
 	D = OPENSSL_malloc (v);
 	Ai = OPENSSL_malloc (u);
 	B = OPENSSL_malloc (v + 1);
diff --git a/crypto/pkcs12/p12_kiss.c b/crypto/pkcs12/p12_kiss.c
index 5c4c6ec..292cc3e 100644
--- a/crypto/pkcs12/p12_kiss.c
+++ b/crypto/pkcs12/p12_kiss.c
@@ -63,16 +63,13 @@
 /* Simplified PKCS#12 routines */
 
 static int parse_pk12( PKCS12 *p12, const char *pass, int passlen,
-		EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca);
+		EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
 
 static int parse_bags( STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
-		       int passlen, EVP_PKEY **pkey, X509 **cert,
-		       STACK_OF(X509) **ca, ASN1_OCTET_STRING **keyid,
-		       char *keymatch);
+		       int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
 
 static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen,
-			EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca,
-			ASN1_OCTET_STRING **keyid, char *keymatch);
+			EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
 
 /* Parse and decrypt a PKCS#12 structure returning user key, user cert
  * and other (CA) certs. Note either ca should be NULL, *ca should be NULL,
@@ -83,24 +80,20 @@
 int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
 	     STACK_OF(X509) **ca)
 {
-
+	STACK_OF(X509) *ocerts = NULL;
+	X509 *x = NULL;
 	/* Check for NULL PKCS12 structure */
 
-	if(!p12) {
+	if(!p12)
+		{
 		PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER);
 		return 0;
-	}
-
-	/* Allocate stack for ca certificates if needed */
-	if ((ca != NULL) && (*ca == NULL)) {
-		if (!(*ca = sk_X509_new_null())) {
-			PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE);
-			return 0;
 		}
-	}
 
-	if(pkey) *pkey = NULL;
-	if(cert) *cert = NULL;
+	if(pkey)
+		*pkey = NULL;
+	if(cert)
+		*cert = NULL;
 
 	/* Check the mac */
 
@@ -122,19 +115,61 @@
 		goto err;
 	}
 
-	if (!parse_pk12 (p12, pass, -1, pkey, cert, ca))
+	/* Allocate stack for other certificates */
+	ocerts = sk_X509_new_null();
+
+	if (!ocerts)
+		{
+		PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+
+	if (!parse_pk12 (p12, pass, -1, pkey, ocerts))
 		{
 		PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_PARSE_ERROR);
 		goto err;
 		}
 
+	while ((x = sk_X509_pop(ocerts)))
+		{
+		if (pkey && *pkey && cert && !*cert)
+			{
+			if (X509_check_private_key(x, *pkey))
+				{
+				*cert = x;
+				x = NULL;
+				}
+			}
+
+		if (ca && x)
+			{
+			if (!*ca)
+				*ca = sk_X509_new_null();
+			if (!*ca)
+				goto err;
+			if (!sk_X509_push(*ca, x))
+				goto err;
+			x = NULL;
+			}
+		if (x)
+			X509_free(x);
+		}
+
+	if (ocerts)
+		sk_X509_pop_free(ocerts, X509_free);
+
 	return 1;
 
  err:
 
-	if (pkey && *pkey) EVP_PKEY_free(*pkey);
-	if (cert && *cert) X509_free(*cert);
-	if (ca) sk_X509_pop_free(*ca, X509_free);
+	if (pkey && *pkey)
+		EVP_PKEY_free(*pkey);
+	if (cert && *cert)
+		X509_free(*cert);
+	if (x)
+		X509_free(*cert);
+	if (ocerts)
+		sk_X509_pop_free(ocerts, X509_free);
 	return 0;
 
 }
@@ -142,15 +177,13 @@
 /* Parse the outer PKCS#12 structure */
 
 static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
-	     EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
+	     EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
 {
 	STACK_OF(PKCS7) *asafes;
 	STACK_OF(PKCS12_SAFEBAG) *bags;
 	int i, bagnid;
 	PKCS7 *p7;
-	ASN1_OCTET_STRING *keyid = NULL;
 
-	char keymatch = 0;
 	if (!(asafes = PKCS12_unpack_authsafes (p12))) return 0;
 	for (i = 0; i < sk_PKCS7_num (asafes); i++) {
 		p7 = sk_PKCS7_value (asafes, i);
@@ -164,8 +197,7 @@
 			sk_PKCS7_pop_free(asafes, PKCS7_free);
 			return 0;
 		}
-	    	if (!parse_bags(bags, pass, passlen, pkey, cert, ca,
-							 &keyid, &keymatch)) {
+	    	if (!parse_bags(bags, pass, passlen, pkey, ocerts)) {
 			sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
 			sk_PKCS7_pop_free(asafes, PKCS7_free);
 			return 0;
@@ -173,89 +205,65 @@
 		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
 	}
 	sk_PKCS7_pop_free(asafes, PKCS7_free);
-	if (keyid) M_ASN1_OCTET_STRING_free(keyid);
 	return 1;
 }
 
 
 static int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
-		      int passlen, EVP_PKEY **pkey, X509 **cert,
-		      STACK_OF(X509) **ca, ASN1_OCTET_STRING **keyid,
-		      char *keymatch)
+		      int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
 {
 	int i;
 	for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
 		if (!parse_bag(sk_PKCS12_SAFEBAG_value (bags, i),
-			 pass, passlen, pkey, cert, ca, keyid,
-							 keymatch)) return 0;
+				 pass, passlen, pkey, ocerts))
+			return 0;
 	}
 	return 1;
 }
 
-#define MATCH_KEY  0x1
-#define MATCH_CERT 0x2
-#define MATCH_ALL  0x3
-
 static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
-		     EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca,
-		     ASN1_OCTET_STRING **keyid,
-		     char *keymatch)
+		     EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
 {
 	PKCS8_PRIV_KEY_INFO *p8;
 	X509 *x509;
-	ASN1_OCTET_STRING *lkey = NULL, *ckid = NULL;
 	ASN1_TYPE *attrib;
 	ASN1_BMPSTRING *fname = NULL;
+	ASN1_OCTET_STRING *lkid = NULL;
 
 	if ((attrib = PKCS12_get_attr (bag, NID_friendlyName)))
 		fname = attrib->value.bmpstring;
 
-	if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) {
-		lkey = attrib->value.octet_string;
-		ckid = lkey;
-	}
+	if ((attrib = PKCS12_get_attr (bag, NID_localKeyID)))
+		lkid = attrib->value.octet_string;
 
-	/* Check for any local key id matching (if needed) */
-	if (lkey && ((*keymatch & MATCH_ALL) != MATCH_ALL)) {
-		if (*keyid) {
-			if (M_ASN1_OCTET_STRING_cmp(*keyid, lkey)) lkey = NULL;
-		} else {
-			if (!(*keyid = M_ASN1_OCTET_STRING_dup(lkey))) {
-				PKCS12err(PKCS12_F_PARSE_BAG,ERR_R_MALLOC_FAILURE);
-				return 0;
-		    }
-		}
-	}
-	
 	switch (M_PKCS12_bag_type(bag))
 	{
 	case NID_keyBag:
-		if (!lkey || !pkey) return 1;	
-		if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag))) return 0;
-		*keymatch |= MATCH_KEY;
+		if (!pkey || *pkey)
+			return 1;	
+		if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag)))
+			return 0;
 	break;
 
 	case NID_pkcs8ShroudedKeyBag:
-		if (!lkey || !pkey) return 1;	
+		if (!pkey || *pkey)
+			return 1;	
 		if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
 				return 0;
 		*pkey = EVP_PKCS82PKEY(p8);
 		PKCS8_PRIV_KEY_INFO_free(p8);
 		if (!(*pkey)) return 0;
-		*keymatch |= MATCH_KEY;
 	break;
 
 	case NID_certBag:
 		if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate )
-								 return 1;
-		if (!(x509 = PKCS12_certbag2x509(bag))) return 0;
-		if(ckid)
+			return 1;
+		if (!(x509 = PKCS12_certbag2x509(bag)))
+			return 0;
+		if(lkid && !X509_keyid_set1(x509, lkid->data, lkid->length))
 			{
-			if (!X509_keyid_set1(x509, ckid->data, ckid->length))
-				{
-				X509_free(x509);
-				return 0;
-				}
+			X509_free(x509);
+			return 0;
 			}
 		if(fname) {
 			int len, r;
@@ -272,20 +280,17 @@
 			}
 		}
 
+		if(!sk_X509_push(ocerts, x509))
+			{
+			X509_free(x509);
+			return 0;
+			}
 
-		if (lkey) {
-			*keymatch |= MATCH_CERT;
-			if (cert) *cert = x509;
-			else X509_free(x509);
-		} else {
-			if(ca) sk_X509_push (*ca, x509);
-			else X509_free(x509);
-		}
 	break;
 
 	case NID_safeContentsBag:
 		return parse_bags(bag->value.safes, pass, passlen,
-			 		pkey, cert, ca, keyid, keymatch);
+			 		pkey, ocerts);
 	break;
 
 	default:
diff --git a/crypto/pkcs12/p12_mutl.c b/crypto/pkcs12/p12_mutl.c
index 70bfef6..9ab740d 100644
--- a/crypto/pkcs12/p12_mutl.c
+++ b/crypto/pkcs12/p12_mutl.c
@@ -71,6 +71,7 @@
 	HMAC_CTX hmac;
 	unsigned char key[EVP_MAX_MD_SIZE], *salt;
 	int saltlen, iter;
+	int md_size;
 
 	if (!PKCS7_type_is_data(p12->authsafes))
 		{
@@ -87,13 +88,16 @@
 		PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_UNKNOWN_DIGEST_ALGORITHM);
 		return 0;
 	}
+	md_size = EVP_MD_size(md_type);
+	if (md_size < 0)
+	    return 0;
 	if(!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter,
-				 EVP_MD_size(md_type), key, md_type)) {
+				 md_size, key, md_type)) {
 		PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_KEY_GEN_ERROR);
 		return 0;
 	}
 	HMAC_CTX_init(&hmac);
-	HMAC_Init_ex(&hmac, key, EVP_MD_size(md_type), md_type, NULL);
+	HMAC_Init_ex(&hmac, key, md_size, md_type, NULL);
     	HMAC_Update(&hmac, p12->authsafes->d.data->data,
 					 p12->authsafes->d.data->length);
     	HMAC_Final(&hmac, mac, maclen);
diff --git a/crypto/pkcs12/p12_npas.c b/crypto/pkcs12/p12_npas.c
index 47e5e9c..2f71355 100644
--- a/crypto/pkcs12/p12_npas.c
+++ b/crypto/pkcs12/p12_npas.c
@@ -120,8 +120,13 @@
 			bags = PKCS12_unpack_p7data(p7);
 		} else if (bagnid == NID_pkcs7_encrypted) {
 			bags = PKCS12_unpack_p7encdata(p7, oldpass, -1);
-			alg_get(p7->d.encrypted->enc_data->algorithm,
-				&pbe_nid, &pbe_iter, &pbe_saltlen);
+			if (!alg_get(p7->d.encrypted->enc_data->algorithm,
+				&pbe_nid, &pbe_iter, &pbe_saltlen))
+				{
+				sk_PKCS12_SAFEBAG_pop_free(bags,
+						PKCS12_SAFEBAG_free);
+				bags = NULL;
+				}
 		} else continue;
 		if (!bags) {
 			sk_PKCS7_pop_free(asafes, PKCS7_free);
@@ -193,7 +198,9 @@
 	if(M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag) return 1;
 
 	if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1))) return 0;
-	alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter, &p8_saltlen);
+	if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter,
+							&p8_saltlen))
+		return 0;
 	if(!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen,
 						     p8_iter, p8))) return 0;
 	X509_SIG_free(bag->value.shkeybag);
@@ -208,9 +215,11 @@
 
         p = alg->parameter->value.sequence->data;
         pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length);
+	if (!pbe)
+		return 0;
         *pnid = OBJ_obj2nid(alg->algorithm);
 	*piter = ASN1_INTEGER_get(pbe->iter);
 	*psaltlen = pbe->salt->length;
         PBEPARAM_free(pbe);
-        return 0;
+        return 1;
 }
diff --git a/crypto/pkcs12/p12_utl.c b/crypto/pkcs12/p12_utl.c
index 2edbf90..59c6f45 100644
--- a/crypto/pkcs12/p12_utl.c
+++ b/crypto/pkcs12/p12_utl.c
@@ -60,15 +60,9 @@
 #include "cryptlib.h"
 #include <openssl/pkcs12.h>
 
-#ifdef OPENSSL_SYS_NETWARE
-/* Rename these functions to avoid name clashes on NetWare OS */
-#define uni2asc OPENSSL_uni2asc
-#define asc2uni OPENSSL_asc2uni
-#endif
-
 /* Cheap and nasty Unicode stuff */
 
-unsigned char *asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen)
+unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen)
 {
 	int ulen, i;
 	unsigned char *unitmp;
@@ -87,7 +81,7 @@
 	return unitmp;
 }
 
-char *uni2asc(unsigned char *uni, int unilen)
+char *OPENSSL_uni2asc(unsigned char *uni, int unilen)
 {
 	int asclen, i;
 	char *asctmp;
diff --git a/crypto/pkcs12/pk12err.c b/crypto/pkcs12/pk12err.c
index 07a1fb6..f6ddf2d 100644
--- a/crypto/pkcs12/pk12err.c
+++ b/crypto/pkcs12/pk12err.c
@@ -1,6 +1,6 @@
 /* crypto/pkcs12/pk12err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
diff --git a/crypto/pkcs12/pkcs12.h b/crypto/pkcs12/pkcs12.h
index 78317fb..b17eb9f 100644
--- a/crypto/pkcs12/pkcs12.h
+++ b/crypto/pkcs12/pkcs12.h
@@ -108,8 +108,6 @@
 PKCS7 *authsafes;
 } PKCS12;
 
-PREDECLARE_STACK_OF(PKCS12_SAFEBAG)
-
 typedef struct {
 ASN1_OBJECT *type;
 union {
@@ -232,14 +230,9 @@
 		   const EVP_MD *md_type);
 int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt,
 					 int saltlen, const EVP_MD *md_type);
-#if defined(NETWARE) || defined(OPENSSL_SYS_NETWARE)
-/* Rename these functions to avoid name clashes on NetWare OS */
 unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen);
 char *OPENSSL_uni2asc(unsigned char *uni, int unilen);
-#else
-unsigned char *asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen);
-char *uni2asc(unsigned char *uni, int unilen);
-#endif
+
 DECLARE_ASN1_FUNCTIONS(PKCS12)
 DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA)
 DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG)
diff --git a/crypto/pkcs7/Makefile b/crypto/pkcs7/Makefile
deleted file mode 100644
index 790d8ed..0000000
--- a/crypto/pkcs7/Makefile
+++ /dev/null
@@ -1,190 +0,0 @@
-#
-# OpenSSL/crypto/pkcs7/Makefile
-#
-
-DIR=	pkcs7
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-PEX_LIBS=
-EX_LIBS=
- 
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile README
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=	pk7_asn1.c pk7_lib.c pkcs7err.c pk7_doit.c pk7_smime.c pk7_attr.c \
-	pk7_mime.c
-LIBOBJ= pk7_asn1.o pk7_lib.o pkcs7err.o pk7_doit.o pk7_smime.o pk7_attr.o \
-	pk7_mime.o
-
-SRC= $(LIBSRC)
-
-EXHEADER=  pkcs7.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-test:
-
-all:	lib
-
-testapps: enc dec sign verify
-
-enc: enc.o lib
-	$(CC) $(CFLAGS) -o enc enc.o $(PEX_LIBS) $(LIB) $(EX_LIBS)
-
-dec: dec.o lib
-	$(CC) $(CFLAGS) -o dec dec.o $(PEX_LIBS) $(LIB) $(EX_LIBS)
-
-sign: sign.o lib
-	$(CC) $(CFLAGS) -o sign sign.o $(PEX_LIBS) $(LIB) $(EX_LIBS)
-
-verify: verify.o example.o lib
-	$(CC) $(CFLAGS) -o verify verify.o $(PEX_LIBS) example.o $(LIB) $(EX_LIBS)
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff enc dec sign verify
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-pk7_asn1.o: ../../e_os.h ../../include/openssl/asn1.h
-pk7_asn1.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-pk7_asn1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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
-pk7_asn1.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-pk7_asn1.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pk7_asn1.c
-pk7_attr.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-pk7_attr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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
-pk7_attr.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-pk7_attr.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-pk7_attr.o: ../../include/openssl/x509_vfy.h pk7_attr.c
-pk7_doit.o: ../../e_os.h ../../include/openssl/asn1.h
-pk7_doit.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-pk7_doit.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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
-pk7_doit.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-pk7_doit.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-pk7_doit.o: ../../include/openssl/x509v3.h ../cryptlib.h pk7_doit.c
-pk7_lib.o: ../../e_os.h ../../include/openssl/asn1.h
-pk7_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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/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
-pk7_mime.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-pk7_mime.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-pk7_mime.o: ../cryptlib.h pk7_mime.c
-pk7_smime.o: ../../e_os.h ../../include/openssl/asn1.h
-pk7_smime.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-pk7_smime.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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
-pk7_smime.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-pk7_smime.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-pk7_smime.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-pk7_smime.o: ../cryptlib.h pk7_smime.c
-pkcs7err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-pkcs7err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-pkcs7err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-pkcs7err.o: ../../include/openssl/opensslconf.h
-pkcs7err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-pkcs7err.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-pkcs7err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-pkcs7err.o: pkcs7err.c
diff --git a/crypto/pkcs7/pk7_asn1.c b/crypto/pkcs7/pk7_asn1.c
index 1f70d31..b7ec288 100644
--- a/crypto/pkcs7/pk7_asn1.c
+++ b/crypto/pkcs7/pk7_asn1.c
@@ -77,10 +77,39 @@
 	ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0))
 } ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL);
 
-ASN1_NDEF_SEQUENCE(PKCS7) = {
+/* PKCS#7 streaming support */
+static int pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+							void *exarg)
+{
+	ASN1_STREAM_ARG *sarg = exarg;
+	PKCS7 **pp7 = (PKCS7 **)pval;
+
+	switch(operation)
+		{
+
+		case ASN1_OP_STREAM_PRE:
+		if (PKCS7_stream(&sarg->boundary, *pp7) <= 0)
+			return 0;
+		case ASN1_OP_DETACHED_PRE:
+		sarg->ndef_bio = PKCS7_dataInit(*pp7, sarg->out);
+		if (!sarg->ndef_bio)
+			return 0;
+		break;
+
+		case ASN1_OP_STREAM_POST:
+		case ASN1_OP_DETACHED_POST:
+		if (PKCS7_dataFinal(*pp7, sarg->ndef_bio) <= 0)
+			return 0;
+		break;
+
+		}
+	return 1;
+}
+
+ASN1_NDEF_SEQUENCE_cb(PKCS7, pk7_cb) = {
 	ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT),
 	ASN1_ADB_OBJECT(PKCS7)
-}ASN1_NDEF_SEQUENCE_END(PKCS7)
+}ASN1_NDEF_SEQUENCE_END_cb(PKCS7, PKCS7)
 
 IMPLEMENT_ASN1_FUNCTIONS(PKCS7)
 IMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7)
@@ -98,7 +127,8 @@
 IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED)
 
 /* Minor tweak to operation: free up EVP_PKEY */
-static int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+							void *exarg)
 {
 	if(operation == ASN1_OP_FREE_POST) {
 		PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval;
@@ -140,7 +170,8 @@
 IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
 
 /* Minor tweak to operation: free up X509 */
-static int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+								void *exarg)
 {
 	if(operation == ASN1_OP_FREE_POST) {
 		PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval;
@@ -161,7 +192,7 @@
 ASN1_NDEF_SEQUENCE(PKCS7_ENC_CONTENT) = {
 	ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT),
 	ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR),
-	ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING, 0)
+	ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING_NDEF, 0)
 } ASN1_NDEF_SEQUENCE_END(PKCS7_ENC_CONTENT)
 
 IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
@@ -212,3 +243,5 @@
 	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
 				V_ASN1_SET, PKCS7_ATTRIBUTES, X509_ATTRIBUTE)
 ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_VERIFY)
+
+IMPLEMENT_ASN1_PRINT_FUNCTION(PKCS7)
diff --git a/crypto/pkcs7/pk7_attr.c b/crypto/pkcs7/pk7_attr.c
index d549717..a97db51 100644
--- a/crypto/pkcs7/pk7_attr.c
+++ b/crypto/pkcs7/pk7_attr.c
@@ -60,6 +60,7 @@
 #include <stdlib.h>
 #include <openssl/bio.h>
 #include <openssl/asn1.h>
+#include <openssl/asn1t.h>
 #include <openssl/pem.h>
 #include <openssl/pkcs7.h>
 #include <openssl/x509.h>
@@ -68,27 +69,12 @@
 int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK_OF(X509_ALGOR) *cap)
 {
 	ASN1_STRING *seq;
-	unsigned char *p, *pp;
-	int len;
-	len=i2d_ASN1_SET_OF_X509_ALGOR(cap,NULL,i2d_X509_ALGOR,
-				       V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL,
-				       IS_SEQUENCE);
-	if(!(pp=(unsigned char *)OPENSSL_malloc(len))) {
-		PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
-		return 0;
-	}
-	p=pp;
-	i2d_ASN1_SET_OF_X509_ALGOR(cap,&p,i2d_X509_ALGOR, V_ASN1_SEQUENCE,
-				   V_ASN1_UNIVERSAL, IS_SEQUENCE);
 	if(!(seq = ASN1_STRING_new())) {
 		PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
 		return 0;
 	}
-	if(!ASN1_STRING_set (seq, pp, len)) {
-		PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
-		return 0;
-	}
-	OPENSSL_free (pp);
+	seq->length = ASN1_item_i2d((ASN1_VALUE *)cap,&seq->data,
+				ASN1_ITEM_rptr(X509_ALGORS));
         return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,
 							V_ASN1_SEQUENCE, seq);
 }
@@ -102,10 +88,9 @@
 	if (!cap || (cap->type != V_ASN1_SEQUENCE))
 		return NULL;
 	p = cap->value.sequence->data;
-	return d2i_ASN1_SET_OF_X509_ALGOR(NULL, &p,
-					  cap->value.sequence->length,
-					  d2i_X509_ALGOR, X509_ALGOR_free,
-					  V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
+	return (STACK_OF(X509_ALGOR) *)
+		ASN1_item_d2i(NULL, &p, cap->value.sequence->length,
+				ASN1_ITEM_rptr(X509_ALGORS));
 	}
 
 /* Basic smime-capabilities OID and optional integer arg */
@@ -139,3 +124,42 @@
 	sk_X509_ALGOR_push (sk, alg);
 	return 1;
 }
+
+int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid)
+	{
+	if (PKCS7_get_signed_attribute(si, NID_pkcs9_contentType))
+		return 0;
+	if (!coid)
+		coid = OBJ_nid2obj(NID_pkcs7_data);
+	return PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
+				V_ASN1_OBJECT, coid);
+	}
+
+int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t)
+	{
+	if (!t && !(t=X509_gmtime_adj(NULL,0)))
+		{
+		PKCS7err(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME,
+				ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime,
+						V_ASN1_UTCTIME, t);
+	}
+
+int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
+				const unsigned char *md, int mdlen)
+	{
+	ASN1_OCTET_STRING *os;
+	os = ASN1_OCTET_STRING_new();
+	if (!os)
+		return 0;
+	if (!ASN1_STRING_set(os, md, mdlen)
+		|| !PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest,
+						V_ASN1_OCTET_STRING, os))
+		{
+		ASN1_OCTET_STRING_free(os);
+		return 0;
+		}
+	return 1;
+	}
diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c
index a03d7eb..451de84 100644
--- a/crypto/pkcs7/pk7_doit.c
+++ b/crypto/pkcs7/pk7_doit.c
@@ -138,6 +138,121 @@
 
 	}
 
+static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
+					unsigned char *key, int keylen)
+	{
+	EVP_PKEY_CTX *pctx = NULL;
+	EVP_PKEY *pkey = NULL;
+	unsigned char *ek = NULL;
+	int ret = 0;
+	size_t eklen;
+
+	pkey = X509_get_pubkey(ri->cert);
+
+	if (!pkey)
+		return 0;
+
+	pctx = EVP_PKEY_CTX_new(pkey, NULL);
+	if (!pctx)
+		return 0;
+
+	if (EVP_PKEY_encrypt_init(pctx) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
+				EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0)
+		{
+		PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR);
+		goto err;
+		}
+
+	if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0)
+		goto err;
+
+	ek = OPENSSL_malloc(eklen);
+
+	if (ek == NULL)
+		{
+		PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0)
+		goto err;
+
+	ASN1_STRING_set0(ri->enc_key, ek, eklen);
+	ek = NULL;
+
+	ret = 1;
+
+	err:
+	if (pkey)
+		EVP_PKEY_free(pkey);
+	if (pctx)
+		EVP_PKEY_CTX_free(pctx);
+	if (ek)
+		OPENSSL_free(ek);
+	return ret;
+
+	}
+
+
+static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
+			       PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey)
+	{
+	EVP_PKEY_CTX *pctx = NULL;
+	unsigned char *ek = NULL;
+	size_t eklen;
+
+	int ret = 0;
+
+	pctx = EVP_PKEY_CTX_new(pkey, NULL);
+	if (!pctx)
+		return 0;
+
+	if (EVP_PKEY_decrypt_init(pctx) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
+				EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0)
+		{
+		PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR);
+		goto err;
+		}
+
+	if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
+				ri->enc_key->data, ri->enc_key->length) <= 0)
+		goto err;
+
+	ek = OPENSSL_malloc(eklen);
+
+	if (ek == NULL)
+		{
+		PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (EVP_PKEY_decrypt(pctx, ek, &eklen,
+				ri->enc_key->data, ri->enc_key->length) <= 0)
+		{
+		PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
+		goto err;
+		}
+
+	ret = 1;
+
+	*pek = ek;
+	*peklen = eklen;
+
+	err:
+	if (pctx)
+		EVP_PKEY_CTX_free(pctx);
+	if (!ret && ek)
+		OPENSSL_free(ek);
+
+	return ret;
+	}
+
 BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
 	{
 	int i;
@@ -148,7 +263,6 @@
 	STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
 	X509_ALGOR *xalg=NULL;
 	PKCS7_RECIP_INFO *ri=NULL;
-	EVP_PKEY *pkey;
 	ASN1_OCTET_STRING *os=NULL;
 
 	i=OBJ_obj2nid(p7->type);
@@ -187,6 +301,8 @@
 		xa = p7->d.digest->md;
 		os = PKCS7_get_octet_string(p7->d.digest->contents);
 		break;
+	case NID_pkcs7_data:
+		break;
 	default:
 		PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
 	        goto err;
@@ -204,8 +320,6 @@
 		unsigned char key[EVP_MAX_KEY_LENGTH];
 		unsigned char iv[EVP_MAX_IV_LENGTH];
 		int keylen,ivlen;
-		int jj,max;
-		unsigned char *tmp;
 		EVP_CIPHER_CTX *ctx;
 
 		if ((btmp=BIO_new(BIO_f_cipher())) == NULL)
@@ -234,52 +348,16 @@
 					goto err;
 			}
 			if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
-			       goto err;
+				goto err;
 		}
 
 		/* Lets do the pub key stuff :-) */
-		max=0;
 		for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
 			{
 			ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
-			if (ri->cert == NULL)
-				{
-				PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO);
+			if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
 				goto err;
-				}
-			if ((pkey=X509_get_pubkey(ri->cert)) == NULL)
-				goto err;
-			jj=EVP_PKEY_size(pkey);
-			EVP_PKEY_free(pkey);
-			if (max < jj) max=jj;
 			}
-		if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL)
-			{
-			PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE);
-			goto err;
-			}
-		for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
-			{
-			ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
-			if ((pkey=X509_get_pubkey(ri->cert)) == NULL)
-				goto err;
-			jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey);
-			EVP_PKEY_free(pkey);
-			if (jj <= 0)
-				{
-				PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB);
-				OPENSSL_free(tmp);
-				goto err;
-				}
-			if (!M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj))
-				{
-				PKCS7err(PKCS7_F_PKCS7_DATAINIT,
-					ERR_R_MALLOC_FAILURE);
-				OPENSSL_free(tmp);
-				goto err;
-				}
-			}
-		OPENSSL_free(tmp);
 		OPENSSL_cleanse(key, keylen);
 
 		if (out == NULL)
@@ -303,7 +381,10 @@
 			BIO_set_mem_eof_return(bio,0);
 			}
 		}
-	BIO_push(out,bio);
+	if (out)
+		BIO_push(out,bio);
+	else
+		out = bio;
 	bio=NULL;
 	if (0)
 		{
@@ -333,7 +414,6 @@
 	{
 	int i,j;
 	BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL;
-	unsigned char *tmp=NULL;
 	X509_ALGOR *xa;
 	ASN1_OCTET_STRING *data_body=NULL;
 	const EVP_MD *evp_md;
@@ -423,7 +503,8 @@
 		int max;
 		X509_OBJECT ret;
 #endif
-		int jj;
+		unsigned char *ek = NULL;
+		int eklen;
 
 		if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
 			{
@@ -438,26 +519,21 @@
 		 * (if any)
 		 */
 
-		if (pcert) {
-			for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
+		if (pcert)
+			{
+			for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
+				{
 				ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
 				if (!pkcs7_cmp_ri(ri, pcert))
 					break;
 				ri=NULL;
-			}
-			if (ri == NULL) {
+				}
+			if (ri == NULL)
+				{
 				PKCS7err(PKCS7_F_PKCS7_DATADECODE,
 				      PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
 				goto err;
-			}
-		}
-
-		jj=EVP_PKEY_size(pkey);
-		tmp=(unsigned char *)OPENSSL_malloc(jj+10);
-		if (tmp == NULL)
-			{
-			PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE);
-			goto err;
+				}
 			}
 
 		/* If we haven't got a certificate try each ri in turn */
@@ -467,11 +543,8 @@
 			for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
 				{
 				ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
-				jj=EVP_PKEY_decrypt(tmp,
-					M_ASN1_STRING_data(ri->enc_key),
-					M_ASN1_STRING_length(ri->enc_key),
-						pkey);
-				if (jj > 0)
+				if (pkcs7_decrypt_rinfo(&ek, &eklen,
+							ri, pkey) > 0)
 					break;
 				ERR_clear_error();
 				ri = NULL;
@@ -485,15 +558,8 @@
 			}
 		else
 			{
-			jj=EVP_PKEY_decrypt(tmp,
-				M_ASN1_STRING_data(ri->enc_key),
-				M_ASN1_STRING_length(ri->enc_key), pkey);
-			if (jj <= 0)
-				{
-				PKCS7err(PKCS7_F_PKCS7_DATADECODE,
-								ERR_R_EVP_LIB);
+			if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) <= 0)
 				goto err;
-				}
 			}
 
 		evp_ctx=NULL;
@@ -503,22 +569,26 @@
 		if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
 			goto err;
 
-		if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
+		if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) {
 			/* Some S/MIME clients don't use the same key
 			 * and effective key length. The key length is
 			 * determined by the size of the decrypted RSA key.
 			 */
-			if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj))
+			if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen))
 				{
 				PKCS7err(PKCS7_F_PKCS7_DATADECODE,
 					PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
 				goto err;
 				}
 		} 
-		if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0)
+		if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,ek,NULL,0) <= 0)
 			goto err;
 
-		OPENSSL_cleanse(tmp,jj);
+		if (ek)
+			{
+			OPENSSL_cleanse(ek,eklen);
+			OPENSSL_free(ek);
+			}
 
 		if (out == NULL)
 			out=etmp;
@@ -566,8 +636,6 @@
 		if (bio != NULL) BIO_free_all(bio);
 		out=NULL;
 		}
-	if (tmp != NULL)
-		OPENSSL_free(tmp);
 	return(out);
 	}
 
@@ -594,13 +662,43 @@
 	return NULL;
 	}
 
+static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx)
+	{
+	unsigned char md_data[EVP_MAX_MD_SIZE];
+	unsigned int md_len;
+
+	/* Add signing time if not already present */
+	if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime))
+		{
+		if (!PKCS7_add0_attrib_signing_time(si, NULL))
+			{
+			PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB,
+					ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		}
+
+	/* Add digest */
+	EVP_DigestFinal_ex(mctx, md_data,&md_len);
+	if (!PKCS7_add1_attrib_digest(si, md_data, md_len))
+		{
+		PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+
+	/* Now sign the attributes */
+	if (!PKCS7_SIGNER_INFO_sign(si))
+			return 0;
+
+	return 1;
+	}
+	
+				
 int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
 	{
 	int ret=0;
 	int i,j;
 	BIO *btmp;
-	BUF_MEM *buf_mem=NULL;
-	BUF_MEM *buf=NULL;
 	PKCS7_SIGNER_INFO *si;
 	EVP_MD_CTX *mdc,ctx_tmp;
 	STACK_OF(X509_ATTRIBUTE) *sk;
@@ -613,24 +711,37 @@
 
 	switch (i)
 		{
+	case NID_pkcs7_data:
+		os = p7->d.data;
+		break;
 	case NID_pkcs7_signedAndEnveloped:
 		/* XXXXXXXXXXXXXXXX */
 		si_sk=p7->d.signed_and_enveloped->signer_info;
-		if (!(os=M_ASN1_OCTET_STRING_new()))
+		os = p7->d.signed_and_enveloped->enc_data->enc_data;
+		if (!os)
 			{
-			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
-			goto err;
+			os=M_ASN1_OCTET_STRING_new();
+			if (!os)
+				{
+				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			p7->d.signed_and_enveloped->enc_data->enc_data=os;
 			}
-		p7->d.signed_and_enveloped->enc_data->enc_data=os;
 		break;
 	case NID_pkcs7_enveloped:
 		/* XXXXXXXXXXXXXXXX */
-		if (!(os=M_ASN1_OCTET_STRING_new()))
+		os = p7->d.enveloped->enc_data->enc_data;
+		if (!os)
 			{
-			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
-			goto err;
+			os=M_ASN1_OCTET_STRING_new();
+			if (!os)
+				{
+				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			p7->d.enveloped->enc_data->enc_data=os;
 			}
-		p7->d.enveloped->enc_data->enc_data=os;
 		break;
 	case NID_pkcs7_signed:
 		si_sk=p7->d.sign->signer_info;
@@ -652,21 +763,20 @@
 			}
 		break;
 
+	default:
+		PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+	        goto err;
 		}
 
 	if (si_sk != NULL)
 		{
-		if ((buf=BUF_MEM_new()) == NULL)
-			{
-			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB);
-			goto err;
-			}
 		for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
 			{
 			si=sk_PKCS7_SIGNER_INFO_value(si_sk,i);
-			if (si->pkey == NULL) continue;
+			if (si->pkey == NULL)
+				continue;
 
-			j=OBJ_obj2nid(si->digest_alg->algorithm);
+			j = OBJ_obj2nid(si->digest_alg->algorithm);
 
 			btmp=bio;
 
@@ -678,97 +788,33 @@
 			/* We now have the EVP_MD_CTX, lets do the
 			 * signing. */
 			EVP_MD_CTX_copy_ex(&ctx_tmp,mdc);
-			if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey)))
-				{
-				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB);
-				goto err;
-				}
 
 			sk=si->auth_attr;
 
 			/* If there are attributes, we add the digest
 			 * attribute and only sign the attributes */
-			if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
+			if (sk_X509_ATTRIBUTE_num(sk) > 0)
 				{
-				unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL;
-				unsigned int md_len, alen;
-				ASN1_OCTET_STRING *digest;
-				ASN1_UTCTIME *sign_time;
-				const EVP_MD *md_tmp;
+				if (!do_pkcs7_signed_attrib(si, &ctx_tmp))
+					goto err;
+				}
+			else
+				{
+				unsigned char *abuf = NULL;
+				unsigned int abuflen;
+				abuflen = EVP_PKEY_size(si->pkey);
+				abuf = OPENSSL_malloc(abuflen);
+				if (!abuf)
+					goto err;
 
-				/* Add signing time if not already present */
-				if (!PKCS7_get_signed_attribute(si,
-							NID_pkcs9_signingTime))
-					{
-					if (!(sign_time=X509_gmtime_adj(NULL,0)))
-						{
-						PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
-							ERR_R_MALLOC_FAILURE);
-						goto err;
-						}
-					if (!PKCS7_add_signed_attribute(si,
-						NID_pkcs9_signingTime,
-						V_ASN1_UTCTIME,sign_time))
-						{
-						M_ASN1_UTCTIME_free(sign_time);
-						goto err;
-						}
-					}
-
-				/* Add digest */
-				md_tmp=EVP_MD_CTX_md(&ctx_tmp);
-				EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len);
-				if (!(digest=M_ASN1_OCTET_STRING_new()))
+				if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen,
+							si->pkey))
 					{
 					PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
-						ERR_R_MALLOC_FAILURE);
+							ERR_R_EVP_LIB);
 					goto err;
 					}
-				if (!M_ASN1_OCTET_STRING_set(digest,md_data,
-								md_len))
-					{
-					PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
-						ERR_R_MALLOC_FAILURE);
-					M_ASN1_OCTET_STRING_free(digest);
-					goto err;
-					}
-				if (!PKCS7_add_signed_attribute(si,
-					NID_pkcs9_messageDigest,
-					V_ASN1_OCTET_STRING,digest))
-					{
-					M_ASN1_OCTET_STRING_free(digest);
-					goto err;
-					}
-
-				/* Now sign the attributes */
-				EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL);
-				alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf,
-							ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
-				if(!abuf) goto err;
-				EVP_SignUpdate(&ctx_tmp,abuf,alen);
-				OPENSSL_free(abuf);
-				}
-
-#ifndef OPENSSL_NO_DSA
-			if (si->pkey->type == EVP_PKEY_DSA)
-				ctx_tmp.digest=EVP_dss1();
-#endif
-#ifndef OPENSSL_NO_ECDSA
- 			if (si->pkey->type == EVP_PKEY_EC)
- 				ctx_tmp.digest=EVP_ecdsa();
-#endif
-
-			if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data,
-				(unsigned int *)&buf->length,si->pkey))
-				{
-				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_EVP_LIB);
-				goto err;
-				}
-			if (!ASN1_STRING_set(si->enc_digest,
-				(unsigned char *)buf->data,buf->length))
-				{
-				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_ASN1_LIB);
-				goto err;
+				ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
 				}
 			}
 		}
@@ -783,34 +829,90 @@
 		M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
 		}
 
-	if (!PKCS7_is_detached(p7))
+	if (!PKCS7_is_detached(p7) && !(os->flags & ASN1_STRING_FLAG_NDEF))
 		{
+		char *cont;
+		long contlen;
 		btmp=BIO_find_type(bio,BIO_TYPE_MEM);
 		if (btmp == NULL)
 			{
 			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
 			goto err;
 			}
-		BIO_get_mem_ptr(btmp,&buf_mem);
+		contlen = BIO_get_mem_data(btmp, &cont);
 		/* Mark the BIO read only then we can use its copy of the data
 		 * instead of making an extra copy.
 		 */
 		BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
 		BIO_set_mem_eof_return(btmp, 0);
-		os->data = (unsigned char *)buf_mem->data;
-		os->length = buf_mem->length;
-#if 0
-		M_ASN1_OCTET_STRING_set(os,
-			(unsigned char *)buf_mem->data,buf_mem->length);
-#endif
+		ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
 		}
 	ret=1;
 err:
 	EVP_MD_CTX_cleanup(&ctx_tmp);
-	if (buf != NULL) BUF_MEM_free(buf);
 	return(ret);
 	}
 
+int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
+	{
+	EVP_MD_CTX mctx;
+	EVP_PKEY_CTX *pctx;
+	unsigned char *abuf = NULL;
+	int alen;
+	size_t siglen;
+	const EVP_MD *md = NULL;
+
+	md = EVP_get_digestbyobj(si->digest_alg->algorithm);
+	if (md == NULL)
+		return 0;
+
+	EVP_MD_CTX_init(&mctx);
+	if (EVP_DigestSignInit(&mctx, &pctx, md,NULL, si->pkey) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
+				EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0)
+		{
+		PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
+		goto err;
+		}
+
+	alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr,&abuf,
+				ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
+	if(!abuf)
+		goto err;
+	if (EVP_DigestSignUpdate(&mctx,abuf,alen) <= 0)
+		goto err;
+	OPENSSL_free(abuf);
+	if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
+		goto err;
+	abuf = OPENSSL_malloc(siglen);
+	if(!abuf)
+		goto err;
+	if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
+				EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0)
+		{
+		PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
+		goto err;
+		}
+
+	EVP_MD_CTX_cleanup(&mctx);
+
+	ASN1_STRING_set0(si->enc_digest, abuf, siglen);
+
+	return 1;
+
+	err:
+	if (abuf)
+		OPENSSL_free(abuf);
+	EVP_MD_CTX_cleanup(&mctx);
+	return 0;
+
+	}
+
 int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
 	     PKCS7 *p7, PKCS7_SIGNER_INFO *si)
 	{
@@ -922,7 +1024,8 @@
 	if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
 		{
 		unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
-                unsigned int md_len, alen;
+                unsigned int md_len;
+		int alen;
 		ASN1_OCTET_STRING *message_digest;
 
 		EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len);
@@ -954,6 +1057,12 @@
 
 		alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
 						ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
+		if (alen <= 0) 
+			{
+			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,ERR_R_ASN1_LIB);
+			ret = -1;
+			goto err;
+			}
 		EVP_VerifyUpdate(&mdc_tmp, abuf, alen);
 
 		OPENSSL_free(abuf);
@@ -966,12 +1075,6 @@
 		ret = -1;
 		goto err;
 		}
-#ifndef OPENSSL_NO_DSA
-	if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1();
-#endif
-#ifndef OPENSSL_NO_ECDSA
-	if (pkey->type == EVP_PKEY_EC) mdc_tmp.digest=EVP_ecdsa();
-#endif
 
 	i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey);
 	EVP_PKEY_free(pkey);
@@ -1107,8 +1210,9 @@
 
 	if (*sk == NULL)
 		{
-		if (!(*sk = sk_X509_ATTRIBUTE_new_null()))
-			return 0;
+		*sk = sk_X509_ATTRIBUTE_new_null();
+		if (*sk == NULL)
+			return 0;	
 new_attrib:
 		if (!(attr=X509_ATTRIBUTE_create(nid,atrtype,value)))
 			return 0;
diff --git a/crypto/pkcs7/pk7_lib.c b/crypto/pkcs7/pk7_lib.c
index f249094..3ca0952 100644
--- a/crypto/pkcs7/pk7_lib.c
+++ b/crypto/pkcs7/pk7_lib.c
@@ -60,6 +60,7 @@
 #include "cryptlib.h"
 #include <openssl/objects.h>
 #include <openssl/x509.h>
+#include "asn1_locl.h"
 
 long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
 	{
@@ -314,7 +315,7 @@
 		*sk=sk_X509_new_null();
 	if (*sk == NULL)
 		{
-		PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE,ERR_R_MALLOC_FAILURE);
+		PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE);
 		return 0;
 		}
 	CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
@@ -365,13 +366,8 @@
 int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
 	     const EVP_MD *dgst)
 	{
-	int nid;
-	char is_dsa;
+	int ret;
 
-	if (pkey->type == EVP_PKEY_DSA || pkey->type == EVP_PKEY_EC)
-		is_dsa = 1;
-	else
-		is_dsa = 0;
 	/* We now need to add another PKCS7_SIGNER_INFO entry */
 	if (!ASN1_INTEGER_set(p7i->version,1))
 		goto err;
@@ -391,65 +387,55 @@
 	p7i->pkey=pkey;
 
 	/* Set the algorithms */
-	if (is_dsa) p7i->digest_alg->algorithm=OBJ_nid2obj(NID_sha1);
-	else	
-		p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst));
 
-	if (p7i->digest_alg->parameter != NULL)
-		ASN1_TYPE_free(p7i->digest_alg->parameter);
-	if ((p7i->digest_alg->parameter=ASN1_TYPE_new()) == NULL)
-		goto err;
-	p7i->digest_alg->parameter->type=V_ASN1_NULL;
+	X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)),
+				V_ASN1_NULL, NULL);
 
-	if (p7i->digest_enc_alg->parameter != NULL)
-		ASN1_TYPE_free(p7i->digest_enc_alg->parameter);
-	nid = EVP_PKEY_type(pkey->type);
-	if (nid == EVP_PKEY_RSA)
+	if (pkey->ameth && pkey->ameth->pkey_ctrl)
 		{
-		p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_rsaEncryption);
-		if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new()))
-			goto err;
-		p7i->digest_enc_alg->parameter->type=V_ASN1_NULL;
+		ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN,
+						0, p7i);
+		if (ret > 0)
+			return 1;
+		if (ret != -2)
+			{
+			PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
+					PKCS7_R_SIGNING_CTRL_FAILURE);
+			return 0;
+			}
 		}
-	else if (nid == EVP_PKEY_DSA)
-		{
-#if 1
-		/* use 'dsaEncryption' OID for compatibility with other software
-		 * (PKCS #7 v1.5 does specify how to handle DSA) ... */
-		p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsa);
-#else
-		/* ... although the 'dsaWithSHA1' OID (as required by RFC 2630 for CMS)
-		 * would make more sense. */
-		p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsaWithSHA1);
-#endif
-		p7i->digest_enc_alg->parameter = NULL; /* special case for DSA: omit 'parameter'! */
-		}
-	else if (nid == EVP_PKEY_EC)
-		{
-		p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_ecdsa_with_SHA1);
-		if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new()))
-			goto err;
-		p7i->digest_enc_alg->parameter->type=V_ASN1_NULL;
-		}
-	else
-		return(0);
-
-	return(1);
+	PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
+			PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
 err:
-	return(0);
+	return 0;
 	}
 
 PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
 	     const EVP_MD *dgst)
 	{
-	PKCS7_SIGNER_INFO *si;
+	PKCS7_SIGNER_INFO *si = NULL;
+
+	if (dgst == NULL)
+		{
+		int def_nid;
+		if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
+			goto err;
+		dgst = EVP_get_digestbynid(def_nid);
+		if (dgst == NULL)
+			{
+			PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE,
+						PKCS7_R_NO_DEFAULT_DIGEST);
+			goto err;
+			}
+		}
 
 	if ((si=PKCS7_SIGNER_INFO_new()) == NULL) goto err;
 	if (!PKCS7_SIGNER_INFO_set(si,x509,pkey,dgst)) goto err;
 	if (!PKCS7_add_signer(p7,si)) goto err;
 	return(si);
 err:
-	PKCS7_SIGNER_INFO_free(si);
+	if (si)
+		PKCS7_SIGNER_INFO_free(si);
 	return(NULL);
 	}
 
@@ -485,6 +471,23 @@
 		return(NULL);
 	}
 
+void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
+					X509_ALGOR **pdig, X509_ALGOR **psig)
+	{
+	if (pk)
+		*pk = si->pkey;
+	if (pdig)
+		*pdig = si->digest_alg;
+	if (psig)
+		*psig = si->digest_enc_alg;
+	}
+
+void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
+	{
+	if (penc)
+		*penc = ri->key_enc_algor;
+	}
+
 PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
 	{
 	PKCS7_RECIP_INFO *ri;
@@ -492,10 +495,11 @@
 	if ((ri=PKCS7_RECIP_INFO_new()) == NULL) goto err;
 	if (!PKCS7_RECIP_INFO_set(ri,x509)) goto err;
 	if (!PKCS7_add_recipient_info(p7,ri)) goto err;
-	return(ri);
+	return ri;
 err:
-	PKCS7_RECIP_INFO_free(ri);
-	return(NULL);
+	if (ri)
+		PKCS7_RECIP_INFO_free(ri);
+	return NULL;
 	}
 
 int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
@@ -524,6 +528,8 @@
 
 int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
 	{
+	int ret;
+	EVP_PKEY *pkey = NULL;
 	if (!ASN1_INTEGER_set(p7i->version,0))
 		return 0;
 	if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
@@ -535,14 +541,41 @@
 		M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
 		return 0;
 
-	X509_ALGOR_free(p7i->key_enc_algor);
-	if (!(p7i->key_enc_algor= X509_ALGOR_dup(x509->cert_info->key->algor)))
-		return 0;
+	pkey = X509_get_pubkey(x509);
+
+	if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl)
+		{
+		PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
+			PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+		goto err;
+		}
+
+	ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT,
+						0, p7i);
+	if (ret == -2)
+		{
+		PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
+			PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+		goto err;
+		}
+	if (ret <= 0)
+		{
+		PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
+				PKCS7_R_ENCRYPTION_CTRL_FAILURE);
+		goto err;
+		}
+
+	EVP_PKEY_free(pkey);
 
 	CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
 	p7i->cert=x509;
 
-	return(1);
+	return 1;
+
+	err:
+	if (pkey)
+		EVP_PKEY_free(pkey);
+	return 0;
 	}
 
 X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
@@ -587,3 +620,48 @@
 	return 1;
 	}
 
+int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
+	{
+	ASN1_OCTET_STRING *os = NULL;
+
+	switch (OBJ_obj2nid(p7->type))
+		{
+		case NID_pkcs7_data:
+		os = p7->d.data;
+		break;
+
+		case NID_pkcs7_signedAndEnveloped:
+		os = p7->d.signed_and_enveloped->enc_data->enc_data;
+		if (os == NULL)
+			{
+			os=M_ASN1_OCTET_STRING_new();
+			p7->d.signed_and_enveloped->enc_data->enc_data=os;
+			}
+		break;
+
+		case NID_pkcs7_enveloped:
+		os = p7->d.enveloped->enc_data->enc_data;
+		if (os == NULL)
+			{
+			os=M_ASN1_OCTET_STRING_new();
+			p7->d.enveloped->enc_data->enc_data=os;
+			}
+		break;
+
+		case NID_pkcs7_signed:
+		os=p7->d.sign->contents->d.data;
+		break;
+
+		default:
+		os = NULL;
+		break;
+		}
+	
+	if (os == NULL)
+		return 0;
+
+	os->flags |= ASN1_STRING_FLAG_NDEF;
+	*boundary = &os->data;
+
+	return 1;
+	}
diff --git a/crypto/pkcs7/pk7_mime.c b/crypto/pkcs7/pk7_mime.c
index 7762d64..938f79a 100644
--- a/crypto/pkcs7/pk7_mime.c
+++ b/crypto/pkcs7/pk7_mime.c
@@ -59,57 +59,19 @@
 #include <openssl/x509.h>
 #include <openssl/asn1.h>
 
-/* PKCS#7 wrappers round generalised MIME routines */
+/* PKCS#7 wrappers round generalised stream and MIME routines */
 
-PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont)
+int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
 	{
-	return (PKCS7 *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(PKCS7));
+	return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)p7, in, flags,
+					ASN1_ITEM_rptr(PKCS7));
 	}
 
-/* Callback for int_smime_write_ASN1 */
-
-static int pk7_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
-					const ASN1_ITEM *it)
+int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
 	{
-	PKCS7 *p7 = (PKCS7 *)val;
-	BIO *tmpbio, *p7bio;
-	int r = 0;
-
-	if (!(flags & SMIME_DETACHED))
-		{
-		SMIME_crlf_copy(data, out, flags);
-		return 1;
-		}
-
-	/* Let PKCS7 code prepend any needed BIOs */
-
-	p7bio = PKCS7_dataInit(p7, out);
-
-	if (!p7bio)
-		return 0;
-
-	/* Copy data across, passing through filter BIOs for processing */
-	SMIME_crlf_copy(data, p7bio, flags);
-
-	/* Finalize structure */
-	if (PKCS7_dataFinal(p7, p7bio) <= 0)
-		goto err;
-
-	r = 1;
-
-	err:
-
-	/* Now remove any digests prepended to the BIO */
-
-	while (p7bio != out)
-		{
-		tmpbio = BIO_pop(p7bio);
-		BIO_free(p7bio);
-		p7bio = tmpbio;
-		}
-
-	return 1;
-
+	return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *) p7, in, flags,
+						"PKCS7",
+						ASN1_ITEM_rptr(PKCS7));
 	}
 
 int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
@@ -121,8 +83,15 @@
 	else
 		mdalgs = NULL;
 
-	return int_smime_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags,
+	flags ^= SMIME_OLDMIME;
+
+
+	return SMIME_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags,
 					ctype_nid, NID_undef, mdalgs,
-					pk7_output_data,
 					ASN1_ITEM_rptr(PKCS7));	
 	}
+
+PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont)
+	{
+	return (PKCS7 *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(PKCS7));
+	}
diff --git a/crypto/pkcs7/pk7_smime.c b/crypto/pkcs7/pk7_smime.c
index fd18ec3..86742d0 100644
--- a/crypto/pkcs7/pk7_smime.c
+++ b/crypto/pkcs7/pk7_smime.c
@@ -63,24 +63,19 @@
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
+static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
+
 PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
 		  BIO *data, int flags)
 {
-	PKCS7 *p7 = NULL;
-	PKCS7_SIGNER_INFO *si;
-	BIO *p7bio = NULL;
-	STACK_OF(X509_ALGOR) *smcap = NULL;
+	PKCS7 *p7;
 	int i;
 
-	if(!X509_check_private_key(signcert, pkey)) {
-		PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
-                return NULL;
-	}
-
-	if(!(p7 = PKCS7_new())) {
+	if(!(p7 = PKCS7_new()))
+		{
 		PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
 		return NULL;
-	}
+		}
 
 	if (!PKCS7_set_type(p7, NID_pkcs7_signed))
 		goto err;
@@ -88,83 +83,186 @@
 	if (!PKCS7_content_new(p7, NID_pkcs7_data))
 		goto err;
 
-	if (!(si = PKCS7_add_signature(p7,signcert,pkey,EVP_sha1()))) {
-		PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);
+    	if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags))
+		{
+		PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNER_ERROR);
 		goto err;
-	}
+		}
 
-	if(!(flags & PKCS7_NOCERTS)) {
-		if (!PKCS7_add_certificate(p7, signcert))
-			goto err;
-		if(certs) for(i = 0; i < sk_X509_num(certs); i++)
+	if(!(flags & PKCS7_NOCERTS))
+		{
+		for(i = 0; i < sk_X509_num(certs); i++)
+			{
 			if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i)))
 				goto err;
-	}
-
-	if(!(flags & PKCS7_NOATTR)) {
-		if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
-				V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data)))
-			goto err;
-		/* Add SMIMECapabilities */
-		if(!(flags & PKCS7_NOSMIMECAP))
-		{
-		if(!(smcap = sk_X509_ALGOR_new_null())) {
-			PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
-			goto err;
+			}
 		}
-#ifndef OPENSSL_NO_DES
-		if (!PKCS7_simple_smimecap (smcap, NID_des_ede3_cbc, -1))
-			goto err;
-#endif
-#ifndef OPENSSL_NO_RC2
-		if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 128))
-			goto err;
-		if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 64))
-			goto err;
-#endif
-#ifndef OPENSSL_NO_DES
-		if (!PKCS7_simple_smimecap (smcap, NID_des_cbc, -1))
-			goto err;
-#endif
-#ifndef OPENSSL_NO_RC2
-		if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 40))
-			goto err;
-#endif
-		if (!PKCS7_add_attrib_smimecap (si, smcap))
-			goto err;
-		sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
-		smcap = NULL;
-		}
-	}
 
-	if(flags & PKCS7_DETACHED)PKCS7_set_detached(p7, 1);
+	if(flags & PKCS7_DETACHED)
+		PKCS7_set_detached(p7, 1);
 
-	if (flags & PKCS7_STREAM)
+	if (flags & (PKCS7_STREAM|PKCS7_PARTIAL))
 		return p7;
 
+	if (PKCS7_final(p7, data, flags))
+		return p7;
 
-	if (!(p7bio = PKCS7_dataInit(p7, NULL))) {
-		PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
-		goto err;
-	}
-
-	SMIME_crlf_copy(data, p7bio, flags);
-
-
-	if (!PKCS7_dataFinal(p7,p7bio)) {
-		PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_DATASIGN);
-		goto err;
-	}
-
-	BIO_free_all(p7bio);
-	return p7;
-err:
-	sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
-	BIO_free_all(p7bio);
+	err:
 	PKCS7_free(p7);
 	return NULL;
 }
 
+int PKCS7_final(PKCS7 *p7, BIO *data, int flags)
+	{
+	BIO *p7bio;
+	int ret = 0;
+	if (!(p7bio = PKCS7_dataInit(p7, NULL)))
+		{
+		PKCS7err(PKCS7_F_PKCS7_FINAL,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+
+	SMIME_crlf_copy(data, p7bio, flags);
+
+	(void)BIO_flush(p7bio);
+
+
+        if (!PKCS7_dataFinal(p7,p7bio))
+		{
+		PKCS7err(PKCS7_F_PKCS7_FINAL,PKCS7_R_PKCS7_DATASIGN);
+		goto err;
+		}
+
+	ret = 1;
+
+	err:
+	BIO_free_all(p7bio);
+
+	return ret;
+
+	}
+
+/* Check to see if a cipher exists and if so add S/MIME capabilities */
+
+static int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
+	{
+	if (EVP_get_cipherbynid(nid))
+		return PKCS7_simple_smimecap(sk, nid, arg);
+	return 1;
+	}
+
+static int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
+	{
+	if (EVP_get_digestbynid(nid))
+		return PKCS7_simple_smimecap(sk, nid, arg);
+	return 1;
+	}
+
+PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert,
+					EVP_PKEY *pkey, const EVP_MD *md,
+					int flags)
+	{
+	PKCS7_SIGNER_INFO *si = NULL;
+	STACK_OF(X509_ALGOR) *smcap = NULL;
+	if(!X509_check_private_key(signcert, pkey))
+		{
+		PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
+			PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+                return NULL;
+		}
+
+    	if (!(si = PKCS7_add_signature(p7,signcert,pkey, md)))
+		{
+		PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
+				PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);
+		return NULL;
+		}
+
+	if(!(flags & PKCS7_NOCERTS))
+		{
+		if (!PKCS7_add_certificate(p7, signcert))
+			goto err;
+		}
+
+	if(!(flags & PKCS7_NOATTR))
+		{
+		if (!PKCS7_add_attrib_content_type(si, NULL))
+			goto err;
+		/* Add SMIMECapabilities */
+		if(!(flags & PKCS7_NOSMIMECAP))
+			{
+			if(!(smcap = sk_X509_ALGOR_new_null()))
+				{
+				PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
+					ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+			if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
+			|| !add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
+			|| !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
+				|| !add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
+				|| !add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
+			|| !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
+				|| !add_cipher_smcap(smcap, NID_rc2_cbc, 128)
+				|| !add_cipher_smcap(smcap, NID_rc2_cbc, 64)
+				|| !add_cipher_smcap(smcap, NID_des_cbc, -1)
+				|| !add_cipher_smcap(smcap, NID_rc2_cbc, 40)
+				|| !PKCS7_add_attrib_smimecap (si, smcap))
+				goto err;
+			sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
+			smcap = NULL;
+			}
+		if (flags & PKCS7_REUSE_DIGEST)
+			{
+			if (!pkcs7_copy_existing_digest(p7, si))
+				goto err;
+			if (!(flags & PKCS7_PARTIAL) &&
+					!PKCS7_SIGNER_INFO_sign(si))
+				goto err;
+			}
+		}
+	return si;
+	err:
+	if (smcap)
+		sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
+	return NULL;
+	}
+
+/* Search for a digest matching SignerInfo digest type and if found
+ * copy across.
+ */
+
+static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
+	{
+	int i;
+	STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
+	PKCS7_SIGNER_INFO *sitmp;
+	ASN1_OCTET_STRING *osdig = NULL;
+	sinfos = PKCS7_get_signer_info(p7);
+	for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
+		{
+		sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
+		if (si == sitmp)
+			break;
+		if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0)
+			continue;
+		if (!OBJ_cmp(si->digest_alg->algorithm,
+				sitmp->digest_alg->algorithm))
+			{
+			osdig = PKCS7_digest_from_attributes(sitmp->auth_attr);
+			break;
+			}
+
+		}
+
+	if (osdig)
+		return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length);
+
+	PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST,
+			PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND);
+	return 0;
+	}
+
 int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
 					BIO *indata, BIO *out, int flags)
 {
@@ -354,7 +452,7 @@
 
 	if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
 		PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS);
-		return NULL;
+		return 0;
 	}
 
 	if(!(signers = sk_X509_new_null())) {
@@ -377,12 +475,12 @@
 	    if (!signer) {
 			PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND);
 			sk_X509_free(signers);
-			return NULL;
+			return 0;
 	    }
 
 	    if (!sk_X509_push(signers, signer)) {
-			sk_X509_free(signers);
-			return NULL;
+		sk_X509_free(signers);
+		return NULL;
 	    }
 	}
 	return signers;
@@ -405,7 +503,7 @@
 
 	if (!PKCS7_set_type(p7, NID_pkcs7_enveloped))
 		goto err;
-	if(!PKCS7_set_cipher(p7, cipher)) {
+	if (!PKCS7_set_cipher(p7, cipher)) {
 		PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER);
 		goto err;
 	}
@@ -419,22 +517,11 @@
 		}
 	}
 
-	if(!(p7bio = PKCS7_dataInit(p7, NULL))) {
-		PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE);
-		goto err;
-	}
+	if (flags & PKCS7_STREAM)
+		return p7;
 
-	SMIME_crlf_copy(in, p7bio, flags);
-
-	(void)BIO_flush(p7bio);
-
-        if (!PKCS7_dataFinal(p7,p7bio)) {
-		PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_PKCS7_DATAFINAL_ERROR);
-		goto err;
-	}
-        BIO_free_all(p7bio);
-
-	return p7;
+	if (PKCS7_final(p7, in, flags))
+		return p7;
 
 	err:
 
diff --git a/crypto/pkcs7/pkcs7.h b/crypto/pkcs7/pkcs7.h
index cc092d2..e4d4431 100644
--- a/crypto/pkcs7/pkcs7.h
+++ b/crypto/pkcs7/pkcs7.h
@@ -232,6 +232,9 @@
 #define PKCS7_type_is_signedAndEnveloped(a) \
 		(OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
 #define PKCS7_type_is_data(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
+#define PKCS7_type_is_digest(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
+#define PKCS7_type_is_encrypted(a) \
+		(OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
 
 #define PKCS7_type_is_digest(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
 
@@ -242,14 +245,6 @@
 
 #define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7))
 
-#ifdef SSLEAY_MACROS
-#ifndef PKCS7_ISSUER_AND_SERIAL_digest
-#define PKCS7_ISSUER_AND_SERIAL_digest(data,type,md,len) \
-        ASN1_digest((int (*)())i2d_PKCS7_ISSUER_AND_SERIAL,type,\
-	                (char *)data,md,len)
-#endif
-#endif
-
 /* S/MIME related flags */
 
 #define PKCS7_TEXT		0x1
@@ -266,6 +261,8 @@
 #define PKCS7_CRLFEOL		0x800
 #define PKCS7_STREAM		0x1000
 #define PKCS7_NOCRL		0x2000
+#define PKCS7_PARTIAL		0x4000
+#define PKCS7_REUSE_DIGEST	0x8000
 
 /* Flags: for compatibility with older code */
 
@@ -281,7 +278,6 @@
 
 DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
 
-#ifndef SSLEAY_MACROS
 int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,const EVP_MD *type,
 	unsigned char *md,unsigned int *len);
 #ifndef OPENSSL_NO_FP_API
@@ -291,7 +287,8 @@
 PKCS7 *PKCS7_dup(PKCS7 *p7);
 PKCS7 *d2i_PKCS7_bio(BIO *bp,PKCS7 **p7);
 int i2d_PKCS7_bio(BIO *bp,PKCS7 *p7);
-#endif
+int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
+int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
 
 DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
 DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
@@ -307,6 +304,7 @@
 DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY)
 
 DECLARE_ASN1_NDEF_FUNCTION(PKCS7)
+DECLARE_ASN1_PRINT_FUNCTION(PKCS7)
 
 long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg);
 
@@ -315,6 +313,7 @@
 int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data);
 int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
 	const EVP_MD *dgst);
+int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si);
 int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
 int PKCS7_add_certificate(PKCS7 *p7, X509 *x509);
 int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
@@ -336,9 +335,13 @@
 STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7);
 
 PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
+void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
+					X509_ALGOR **pdig, X509_ALGOR **psig);
+void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc);
 int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri);
 int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509);
 int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher);
+int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7);
 
 PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx);
 ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk);
@@ -355,6 +358,12 @@
 
 PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
 							BIO *data, int flags);
+
+PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7,
+			X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md,
+			int flags);
+
+int PKCS7_final(PKCS7 *p7, BIO *data, int flags);
 int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
 					BIO *indata, BIO *out, int flags);
 STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags);
@@ -367,10 +376,16 @@
 STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si);
 int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg);
 
+int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid);
+int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t);
+int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
+				const unsigned char *md, int mdlen);
+
 int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags);
 PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont);
-int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
-int SMIME_text(BIO *in, BIO *out);
+
+BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7);
+
 
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -383,12 +398,17 @@
 /* Function codes. */
 #define PKCS7_F_B64_READ_PKCS7				 120
 #define PKCS7_F_B64_WRITE_PKCS7				 121
+#define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB			 136
+#define PKCS7_F_I2D_PKCS7_BIO_STREAM			 140
+#define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME		 135
 #define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP		 118
 #define PKCS7_F_PKCS7_ADD_CERTIFICATE			 100
 #define PKCS7_F_PKCS7_ADD_CRL				 101
 #define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO		 102
+#define PKCS7_F_PKCS7_ADD_SIGNATURE			 131
 #define PKCS7_F_PKCS7_ADD_SIGNER			 103
 #define PKCS7_F_PKCS7_BIO_ADD_DIGEST			 125
+#define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST		 138
 #define PKCS7_F_PKCS7_CTRL				 104
 #define PKCS7_F_PKCS7_DATADECODE			 112
 #define PKCS7_F_PKCS7_DATAFINAL				 128
@@ -396,15 +416,22 @@
 #define PKCS7_F_PKCS7_DATASIGN				 106
 #define PKCS7_F_PKCS7_DATAVERIFY			 107
 #define PKCS7_F_PKCS7_DECRYPT				 114
+#define PKCS7_F_PKCS7_DECRYPT_RINFO			 133
+#define PKCS7_F_PKCS7_ENCODE_RINFO			 132
 #define PKCS7_F_PKCS7_ENCRYPT				 115
+#define PKCS7_F_PKCS7_FINAL				 134
 #define PKCS7_F_PKCS7_FIND_DIGEST			 127
 #define PKCS7_F_PKCS7_GET0_SIGNERS			 124
+#define PKCS7_F_PKCS7_RECIP_INFO_SET			 130
 #define PKCS7_F_PKCS7_SET_CIPHER			 108
 #define PKCS7_F_PKCS7_SET_CONTENT			 109
 #define PKCS7_F_PKCS7_SET_DIGEST			 126
 #define PKCS7_F_PKCS7_SET_TYPE				 110
 #define PKCS7_F_PKCS7_SIGN				 116
 #define PKCS7_F_PKCS7_SIGNATUREVERIFY			 113
+#define PKCS7_F_PKCS7_SIGNER_INFO_SET			 129
+#define PKCS7_F_PKCS7_SIGNER_INFO_SIGN			 139
+#define PKCS7_F_PKCS7_SIGN_ADD_SIGNER			 137
 #define PKCS7_F_PKCS7_SIMPLE_SMIMECAP			 119
 #define PKCS7_F_PKCS7_VERIFY				 117
 #define PKCS7_F_SMIME_READ_PKCS7			 122
@@ -415,10 +442,13 @@
 #define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER		 144
 #define PKCS7_R_CIPHER_NOT_INITIALIZED			 116
 #define PKCS7_R_CONTENT_AND_DATA_PRESENT		 118
+#define PKCS7_R_CTRL_ERROR				 152
 #define PKCS7_R_DECODE_ERROR				 130
 #define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH		 100
 #define PKCS7_R_DECRYPT_ERROR				 119
 #define PKCS7_R_DIGEST_FAILURE				 101
+#define PKCS7_R_ENCRYPTION_CTRL_FAILURE			 149
+#define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150
 #define PKCS7_R_ERROR_ADDING_RECIPIENT			 120
 #define PKCS7_R_ERROR_SETTING_CIPHER			 121
 #define PKCS7_R_INVALID_MIME_TYPE			 131
@@ -429,6 +459,8 @@
 #define PKCS7_R_MISSING_CERIPEND_INFO			 103
 #define PKCS7_R_NO_CONTENT				 122
 #define PKCS7_R_NO_CONTENT_TYPE				 135
+#define PKCS7_R_NO_DEFAULT_DIGEST			 151
+#define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND		 154
 #define PKCS7_R_NO_MULTIPART_BODY_FAILURE		 136
 #define PKCS7_R_NO_MULTIPART_BOUNDARY			 137
 #define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE	 115
@@ -438,6 +470,7 @@
 #define PKCS7_R_NO_SIG_CONTENT_TYPE			 138
 #define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE	 104
 #define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR		 124
+#define PKCS7_R_PKCS7_ADD_SIGNER_ERROR			 153
 #define PKCS7_R_PKCS7_DATAFINAL				 126
 #define PKCS7_R_PKCS7_DATAFINAL_ERROR			 125
 #define PKCS7_R_PKCS7_DATASIGN				 145
@@ -446,6 +479,8 @@
 #define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 127
 #define PKCS7_R_SIGNATURE_FAILURE			 105
 #define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND		 128
+#define PKCS7_R_SIGNING_CTRL_FAILURE			 147
+#define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE	 148
 #define PKCS7_R_SIG_INVALID_MIME_TYPE			 141
 #define PKCS7_R_SMIME_TEXT_ERROR			 129
 #define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE		 106
diff --git a/crypto/pkcs7/pkcs7err.c b/crypto/pkcs7/pkcs7err.c
index c0e3d4c..d0af32a 100644
--- a/crypto/pkcs7/pkcs7err.c
+++ b/crypto/pkcs7/pkcs7err.c
@@ -1,6 +1,6 @@
 /* crypto/pkcs7/pkcs7err.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
@@ -72,12 +72,17 @@
 	{
 {ERR_FUNC(PKCS7_F_B64_READ_PKCS7),	"B64_READ_PKCS7"},
 {ERR_FUNC(PKCS7_F_B64_WRITE_PKCS7),	"B64_WRITE_PKCS7"},
+{ERR_FUNC(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB),	"DO_PKCS7_SIGNED_ATTRIB"},
+{ERR_FUNC(PKCS7_F_I2D_PKCS7_BIO_STREAM),	"i2d_PKCS7_bio_stream"},
+{ERR_FUNC(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME),	"PKCS7_add0_attrib_signing_time"},
 {ERR_FUNC(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP),	"PKCS7_add_attrib_smimecap"},
 {ERR_FUNC(PKCS7_F_PKCS7_ADD_CERTIFICATE),	"PKCS7_add_certificate"},
 {ERR_FUNC(PKCS7_F_PKCS7_ADD_CRL),	"PKCS7_add_crl"},
 {ERR_FUNC(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO),	"PKCS7_add_recipient_info"},
+{ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNATURE),	"PKCS7_add_signature"},
 {ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER),	"PKCS7_add_signer"},
 {ERR_FUNC(PKCS7_F_PKCS7_BIO_ADD_DIGEST),	"PKCS7_BIO_ADD_DIGEST"},
+{ERR_FUNC(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST),	"PKCS7_COPY_EXISTING_DIGEST"},
 {ERR_FUNC(PKCS7_F_PKCS7_CTRL),	"PKCS7_ctrl"},
 {ERR_FUNC(PKCS7_F_PKCS7_DATADECODE),	"PKCS7_dataDecode"},
 {ERR_FUNC(PKCS7_F_PKCS7_DATAFINAL),	"PKCS7_dataFinal"},
@@ -85,15 +90,22 @@
 {ERR_FUNC(PKCS7_F_PKCS7_DATASIGN),	"PKCS7_DATASIGN"},
 {ERR_FUNC(PKCS7_F_PKCS7_DATAVERIFY),	"PKCS7_dataVerify"},
 {ERR_FUNC(PKCS7_F_PKCS7_DECRYPT),	"PKCS7_decrypt"},
+{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT_RINFO),	"PKCS7_DECRYPT_RINFO"},
+{ERR_FUNC(PKCS7_F_PKCS7_ENCODE_RINFO),	"PKCS7_ENCODE_RINFO"},
 {ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT),	"PKCS7_encrypt"},
+{ERR_FUNC(PKCS7_F_PKCS7_FINAL),	"PKCS7_final"},
 {ERR_FUNC(PKCS7_F_PKCS7_FIND_DIGEST),	"PKCS7_FIND_DIGEST"},
 {ERR_FUNC(PKCS7_F_PKCS7_GET0_SIGNERS),	"PKCS7_get0_signers"},
+{ERR_FUNC(PKCS7_F_PKCS7_RECIP_INFO_SET),	"PKCS7_RECIP_INFO_set"},
 {ERR_FUNC(PKCS7_F_PKCS7_SET_CIPHER),	"PKCS7_set_cipher"},
 {ERR_FUNC(PKCS7_F_PKCS7_SET_CONTENT),	"PKCS7_set_content"},
 {ERR_FUNC(PKCS7_F_PKCS7_SET_DIGEST),	"PKCS7_set_digest"},
 {ERR_FUNC(PKCS7_F_PKCS7_SET_TYPE),	"PKCS7_set_type"},
 {ERR_FUNC(PKCS7_F_PKCS7_SIGN),	"PKCS7_sign"},
 {ERR_FUNC(PKCS7_F_PKCS7_SIGNATUREVERIFY),	"PKCS7_signatureVerify"},
+{ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SET),	"PKCS7_SIGNER_INFO_set"},
+{ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SIGN),	"PKCS7_SIGNER_INFO_sign"},
+{ERR_FUNC(PKCS7_F_PKCS7_SIGN_ADD_SIGNER),	"PKCS7_sign_add_signer"},
 {ERR_FUNC(PKCS7_F_PKCS7_SIMPLE_SMIMECAP),	"PKCS7_simple_smimecap"},
 {ERR_FUNC(PKCS7_F_PKCS7_VERIFY),	"PKCS7_verify"},
 {ERR_FUNC(PKCS7_F_SMIME_READ_PKCS7),	"SMIME_read_PKCS7"},
@@ -107,10 +119,13 @@
 {ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"},
 {ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED),"cipher not initialized"},
 {ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT),"content and data present"},
+{ERR_REASON(PKCS7_R_CTRL_ERROR)          ,"ctrl error"},
 {ERR_REASON(PKCS7_R_DECODE_ERROR)        ,"decode error"},
 {ERR_REASON(PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH),"decrypted key is wrong length"},
 {ERR_REASON(PKCS7_R_DECRYPT_ERROR)       ,"decrypt error"},
 {ERR_REASON(PKCS7_R_DIGEST_FAILURE)      ,"digest failure"},
+{ERR_REASON(PKCS7_R_ENCRYPTION_CTRL_FAILURE),"encryption ctrl failure"},
+{ERR_REASON(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"encryption not supported for this key type"},
 {ERR_REASON(PKCS7_R_ERROR_ADDING_RECIPIENT),"error adding recipient"},
 {ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER),"error setting cipher"},
 {ERR_REASON(PKCS7_R_INVALID_MIME_TYPE)   ,"invalid mime type"},
@@ -121,6 +136,8 @@
 {ERR_REASON(PKCS7_R_MISSING_CERIPEND_INFO),"missing ceripend info"},
 {ERR_REASON(PKCS7_R_NO_CONTENT)          ,"no content"},
 {ERR_REASON(PKCS7_R_NO_CONTENT_TYPE)     ,"no content type"},
+{ERR_REASON(PKCS7_R_NO_DEFAULT_DIGEST)   ,"no default digest"},
+{ERR_REASON(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND),"no matching digest type found"},
 {ERR_REASON(PKCS7_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"},
 {ERR_REASON(PKCS7_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"},
 {ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE),"no recipient matches certificate"},
@@ -130,6 +147,7 @@
 {ERR_REASON(PKCS7_R_NO_SIG_CONTENT_TYPE) ,"no sig content type"},
 {ERR_REASON(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE),"operation not supported on this type"},
 {ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR),"pkcs7 add signature error"},
+{ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNER_ERROR),"pkcs7 add signer error"},
 {ERR_REASON(PKCS7_R_PKCS7_DATAFINAL)     ,"pkcs7 datafinal"},
 {ERR_REASON(PKCS7_R_PKCS7_DATAFINAL_ERROR),"pkcs7 datafinal error"},
 {ERR_REASON(PKCS7_R_PKCS7_DATASIGN)      ,"pkcs7 datasign"},
@@ -138,6 +156,8 @@
 {ERR_REASON(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
 {ERR_REASON(PKCS7_R_SIGNATURE_FAILURE)   ,"signature failure"},
 {ERR_REASON(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"},
+{ERR_REASON(PKCS7_R_SIGNING_CTRL_FAILURE),"signing ctrl failure"},
+{ERR_REASON(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"signing not supported for this key type"},
 {ERR_REASON(PKCS7_R_SIG_INVALID_MIME_TYPE),"sig invalid mime type"},
 {ERR_REASON(PKCS7_R_SMIME_TEXT_ERROR)    ,"smime text error"},
 {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE),"unable to find certificate"},
diff --git a/crypto/ppccpuid.pl b/crypto/ppccpuid.pl
new file mode 100755
index 0000000..369e1d0
--- /dev/null
+++ b/crypto/ppccpuid.pl
@@ -0,0 +1,96 @@
+#!/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
+	$CMPLI	r4,0
+	beqlr-
+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
deleted file mode 100644
index 36bfc34..0000000
--- a/crypto/pqueue/Makefile
+++ /dev/null
@@ -1,84 +0,0 @@
-#
-# OpenSSL/crypto/pqueue/Makefile
-#
-
-DIR=	pqueue
-TOP=	../..
-CC=	cc
-INCLUDES=
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=pqueue.c
-LIBOBJ=pqueue.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= pqueue.h pq_compat.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-pqueue.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-pqueue.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-pqueue.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-pqueue.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-pqueue.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-pqueue.o: ../../include/openssl/pq_compat.h ../../include/openssl/safestack.h
-pqueue.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-pqueue.o: ../cryptlib.h pqueue.c pqueue.h
diff --git a/crypto/pqueue/pq_compat.h b/crypto/pqueue/pq_compat.h
deleted file mode 100644
index 7b2c327..0000000
--- a/crypto/pqueue/pq_compat.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/* crypto/pqueue/pqueue_compat.h */
-/* 
- * DTLS implementation written by Nagendra Modadugu
- * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
- */
-/* ====================================================================
- * Copyright (c) 1999-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
- *    openssl-core@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#ifndef HEADER_PQ_COMPAT_H
-#define HEADER_PQ_COMPAT_H
-
-#include <openssl/opensslconf.h>
-#include <openssl/bn.h>
-
-/* 
- * The purpose of this header file is for supporting 64-bit integer
- * manipulation on 32-bit (and lower) machines.  Currently the only
- * such environment is VMS, Utrix and those with smaller default integer
- * sizes than 32 bits.  For all such environment, we fall back to using
- * BIGNUM.  We may need to fine tune the conditions for systems that
- * are incorrectly configured.
- *
- * The only clients of this code are (1) pqueue for priority, and
- * (2) DTLS, for sequence number manipulation.
- */
-
-#if (defined(THIRTY_TWO_BIT) && !defined(BN_LLONG)) || defined(SIXTEEN_BIT) || defined(EIGHT_BIT)
-
-#define PQ_64BIT_IS_INTEGER 0
-#define PQ_64BIT_IS_BIGNUM 1
-
-#define PQ_64BIT     BIGNUM
-#define PQ_64BIT_CTX BN_CTX
-
-#define pq_64bit_init(x)           BN_init(x)
-#define pq_64bit_free(x)           BN_free(x)
-
-#define pq_64bit_ctx_new(ctx)      BN_CTX_new()
-#define pq_64bit_ctx_free(x)       BN_CTX_free(x)
-
-#define pq_64bit_assign(x, y)      BN_copy(x, y)
-#define pq_64bit_assign_word(x, y) BN_set_word(x, y)
-#define pq_64bit_gt(x, y)          BN_ucmp(x, y) >= 1 ? 1 : 0
-#define pq_64bit_eq(x, y)          BN_ucmp(x, y) == 0 ? 1 : 0
-#define pq_64bit_add_word(x, w)    BN_add_word(x, w)
-#define pq_64bit_sub(r, x, y)      BN_sub(r, x, y)
-#define pq_64bit_sub_word(x, w)    BN_sub_word(x, w)
-#define pq_64bit_mod(r, x, n, ctx) BN_mod(r, x, n, ctx)
-
-#define pq_64bit_bin2num(bn, bytes, len)   BN_bin2bn(bytes, len, bn)
-#define pq_64bit_num2bin(bn, bytes)        BN_bn2bin(bn, bytes)
-#define pq_64bit_get_word(x)               BN_get_word(x)
-#define pq_64bit_is_bit_set(x, offset)     BN_is_bit_set(x, offset)
-#define pq_64bit_lshift(r, x, shift)       BN_lshift(r, x, shift)
-#define pq_64bit_set_bit(x, num)           BN_set_bit(x, num)
-#define pq_64bit_get_length(x)             BN_num_bits((x))
-
-#else
-
-#define PQ_64BIT_IS_INTEGER 1
-#define PQ_64BIT_IS_BIGNUM 0
-
-#if defined(SIXTY_FOUR_BIT)
-#define PQ_64BIT BN_ULONG
-#define PQ_64BIT_PRINT "%lld"
-#elif defined(SIXTY_FOUR_BIT_LONG)
-#define PQ_64BIT BN_ULONG
-#define PQ_64BIT_PRINT "%ld"
-#elif defined(THIRTY_TWO_BIT)
-#define PQ_64BIT BN_ULLONG
-#define PQ_64BIT_PRINT "%lld"
-#endif
-
-#define PQ_64BIT_CTX      void
-
-#define pq_64bit_init(x)
-#define pq_64bit_free(x)
-#define pq_64bit_ctx_new(ctx)        (ctx)
-#define pq_64bit_ctx_free(x)
-
-#define pq_64bit_assign(x, y)        (*(x) = *(y))
-#define pq_64bit_assign_word(x, y)   (*(x) = y)
-#define pq_64bit_gt(x, y)	         (*(x) > *(y))
-#define pq_64bit_eq(x, y)            (*(x) == *(y))
-#define pq_64bit_add_word(x, w)      (*(x) = (*(x) + (w)))
-#define pq_64bit_sub(r, x, y)        (*(r) = (*(x) - *(y)))
-#define pq_64bit_sub_word(x, w)      (*(x) = (*(x) - (w)))
-#define pq_64bit_mod(r, x, n, ctx)
-
-#define pq_64bit_bin2num(num, bytes, len) bytes_to_long_long(bytes, num)
-#define pq_64bit_num2bin(num, bytes)      long_long_to_bytes(num, bytes)
-#define pq_64bit_get_word(x)              *(x)
-#define pq_64bit_lshift(r, x, shift)      (*(r) = (*(x) << (shift)))
-#define pq_64bit_set_bit(x, num)          do { \
-                                              PQ_64BIT mask = 1; \
-                                              mask = mask << (num); \
-                                              *(x) |= mask; \
-                                          } while(0)
-#endif /* OPENSSL_SYS_VMS */
-
-#endif
diff --git a/crypto/pqueue/pqueue.c b/crypto/pqueue/pqueue.c
index 6c89f06..99a6fb8 100644
--- a/crypto/pqueue/pqueue.c
+++ b/crypto/pqueue/pqueue.c
@@ -68,13 +68,12 @@
 	} pqueue_s;
 
 pitem *
-pitem_new(PQ_64BIT priority, void *data)
+pitem_new(unsigned char *prio64be, void *data)
 	{
 	pitem *item = (pitem *) OPENSSL_malloc(sizeof(pitem));
 	if (item == NULL) return NULL;
 
-	pq_64bit_init(&(item->priority));
-	pq_64bit_assign(&item->priority, &priority);
+	memcpy(item->priority,prio64be,sizeof(item->priority));
 
 	item->data = data;
 	item->next = NULL;
@@ -87,7 +86,6 @@
 	{
 	if (item == NULL) return;
 
-	pq_64bit_free(&(item->priority));
 	OPENSSL_free(item);
 	}
 
@@ -124,7 +122,10 @@
 		next != NULL;
 		curr = next, next = next->next)
 		{
-		if (pq_64bit_gt(&(next->priority), &(item->priority)))
+		/* we can compare 64-bit value in big-endian encoding
+		 * with memcmp:-) */
+		int cmp = memcmp(next->priority, item->priority,8);
+		if (cmp > 0)		/* next > item */
 			{
 			item->next = next;
 
@@ -135,8 +136,8 @@
 
 			return item;
 			}
-		/* duplicates not allowed */
-		if (pq_64bit_eq(&(item->priority), &(next->priority)))
+		
+		else if (cmp == 0)	/* duplicates not allowed */
 			return NULL;
 		}
 
@@ -164,7 +165,7 @@
 	}
 
 pitem *
-pqueue_find(pqueue_s *pq, PQ_64BIT priority)
+pqueue_find(pqueue_s *pq, unsigned char *prio64be)
 	{
 	pitem *next, *prev = NULL;
 	pitem *found = NULL;
@@ -175,7 +176,7 @@
 	for ( next = pq->items; next->next != NULL; 
 		  prev = next, next = next->next)
 		{
-		if ( pq_64bit_eq(&(next->priority), &priority))
+		if ( memcmp(next->priority, prio64be,8) == 0)
 			{
 			found = next;
 			break;
@@ -183,7 +184,7 @@
 		}
 	
 	/* check the one last node */
-	if ( pq_64bit_eq(&(next->priority), &priority))
+	if ( memcmp(next->priority, prio64be,8) ==0)
 		found = next;
 
 	if ( ! found)
@@ -199,7 +200,6 @@
 	return found;
 	}
 
-#if PQ_64BIT_IS_INTEGER
 void
 pqueue_print(pqueue_s *pq)
 	{
@@ -207,11 +207,14 @@
 
 	while(item != NULL)
 		{
-		printf("item\t" PQ_64BIT_PRINT "\n", item->priority);
+		printf("item\t%02x%02x%02x%02x%02x%02x%02x%02x\n",
+			item->priority[0],item->priority[1],
+			item->priority[2],item->priority[3],
+			item->priority[4],item->priority[5],
+			item->priority[6],item->priority[7]);
 		item = item->next;
 		}
 	}
-#endif
 
 pitem *
 pqueue_iterator(pqueue_s *pq)
diff --git a/crypto/pqueue/pqueue.h b/crypto/pqueue/pqueue.h
index 16c4072..87fc903 100644
--- a/crypto/pqueue/pqueue.h
+++ b/crypto/pqueue/pqueue.h
@@ -64,20 +64,18 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <openssl/pq_compat.h>
-
 typedef struct _pqueue *pqueue;
 
 typedef struct _pitem
 	{
-	PQ_64BIT priority;
+	unsigned char priority[8]; /* 64-bit value in big-endian encoding */
 	void *data;
 	struct _pitem *next;
 	} pitem;
 
 typedef struct _pitem *piterator;
 
-pitem *pitem_new(PQ_64BIT priority, void *data);
+pitem *pitem_new(unsigned char *prio64be, void *data);
 void   pitem_free(pitem *item);
 
 pqueue pqueue_new(void);
@@ -86,7 +84,7 @@
 pitem *pqueue_insert(pqueue pq, pitem *item);
 pitem *pqueue_peek(pqueue pq);
 pitem *pqueue_pop(pqueue pq);
-pitem *pqueue_find(pqueue pq, PQ_64BIT priority);
+pitem *pqueue_find(pqueue pq, unsigned char *prio64be);
 pitem *pqueue_iterator(pqueue pq);
 pitem *pqueue_next(piterator *iter);
 
diff --git a/crypto/rand/Makefile b/crypto/rand/Makefile
deleted file mode 100644
index 3079430..0000000
--- a/crypto/rand/Makefile
+++ /dev/null
@@ -1,187 +0,0 @@
-#
-# OpenSSL/crypto/rand/Makefile
-#
-
-DIR=	rand
-TOP=	../..
-CC=	cc
-INCLUDES=
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST= randtest.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-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_eng.o rand_err.o rand_egd.o \
-	rand_win.o rand_unix.o rand_os2.o rand_nw.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= rand.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-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/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
-rand_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-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/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/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: ../../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/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/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
-rand_os2.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h
-rand_os2.o: rand_os2.c
-rand_unix.o: ../../e_os.h ../../include/openssl/asn1.h
-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/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
-rand_unix.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-rand_unix.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h
-rand_unix.o: rand_unix.c
-rand_win.o: ../../e_os.h ../../include/openssl/asn1.h
-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/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
-rand_win.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h
-rand_win.o: rand_win.c
-randfile.o: ../../e_os.h ../../include/openssl/buffer.h
-randfile.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-randfile.o: ../../include/openssl/opensslconf.h
-randfile.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-randfile.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-randfile.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-randfile.o: randfile.c
diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c
index 0f8dd3e..88088ce 100644
--- a/crypto/rand/md_rand.c
+++ b/crypto/rand/md_rand.c
@@ -126,10 +126,6 @@
 
 #include <openssl/crypto.h>
 #include <openssl/err.h>
-#ifdef OPENSSL_FIPS
-#include <openssl/fips.h>
-#endif
-
 
 #ifdef BN_DEBUG
 # define PREDICT
@@ -149,7 +145,7 @@
                                            * holds CRYPTO_LOCK_RAND
                                            * (to prevent double locking) */
 /* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
-static unsigned long locking_thread = 0; /* valid iff crypto_lock_rand is set */
+static CRYPTO_THREADID locking_threadid; /* valid iff crypto_lock_rand is set */
 
 
 #ifdef PREDICT
@@ -217,8 +213,10 @@
 	/* check if we already have the lock */
 	if (crypto_lock_rand)
 		{
+		CRYPTO_THREADID cur;
+		CRYPTO_THREADID_current(&cur);
 		CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
-		do_not_lock = (locking_thread == CRYPTO_thread_id());
+		do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
 		CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
 		}
 	else
@@ -274,8 +272,16 @@
 			}
 		else
 			MD_Update(&m,&(state[st_idx]),j);
-			
+
+		/* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
 		MD_Update(&m,buf,j);
+		/* We know that line may cause programs such as
+		   purify and valgrind to complain about use of
+		   uninitialized data.  The problem is not, it's
+		   with the caller.  Removing that line will make
+		   sure you get really bad randomness and thereby
+		   other problems such as very insecure keys. */
+
 		MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
 		MD_Final(&m,local_md);
 		md_c[1]++;
@@ -336,14 +342,6 @@
 #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)
 		{
@@ -384,7 +382,7 @@
 
 	/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
 	CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
-	locking_thread = CRYPTO_thread_id();
+	CRYPTO_THREADID_current(&locking_threadid);
 	CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
 	crypto_lock_rand = 1;
 
@@ -476,9 +474,15 @@
 #endif
 		MD_Update(&m,local_md,MD_DIGEST_LENGTH);
 		MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
-#ifndef PURIFY
-		MD_Update(&m,buf,j); /* purify complains */
+
+#ifndef PURIFY /* purify complains */
+		/* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
+		MD_Update(&m,buf,j);
+		/* We know that line may cause programs such as
+		   purify and valgrind to complain about use of
+		   uninitialized data.  */
 #endif
+
 		k=(st_idx+MD_DIGEST_LENGTH/2)-st_num;
 		if (k > 0)
 			{
@@ -539,15 +543,17 @@
 
 static int ssleay_rand_status(void)
 	{
+	CRYPTO_THREADID cur;
 	int ret;
 	int do_not_lock;
 
+	CRYPTO_THREADID_current(&cur);
 	/* check if we already have the lock
 	 * (could happen if a RAND_poll() implementation calls RAND_status()) */
 	if (crypto_lock_rand)
 		{
 		CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
-		do_not_lock = (locking_thread == CRYPTO_thread_id());
+		do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
 		CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
 		}
 	else
@@ -559,7 +565,7 @@
 		
 		/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
 		CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
-		locking_thread = CRYPTO_thread_id();
+		CRYPTO_THREADID_cpy(&locking_threadid, &cur);
 		CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
 		crypto_lock_rand = 1;
 		}
diff --git a/crypto/rand/rand.h b/crypto/rand/rand.h
index ea89153..ac6c021 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 int
+#define FIPS_RAND_SIZE_T size_t
 #endif
 
 /* Already defined in ossl_typ.h */
@@ -111,15 +111,6 @@
 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)
 
@@ -137,29 +128,11 @@
 /* Error codes for the RAND functions. */
 
 /* Function codes. */
-#define RAND_F_ENG_RAND_GET_RAND_METHOD			 108
-#define RAND_F_FIPS_RAND				 103
-#define RAND_F_FIPS_RAND_BYTES				 102
-#define RAND_F_FIPS_RAND_GET_RAND_METHOD		 109
-#define RAND_F_FIPS_RAND_SET_DT				 106
-#define RAND_F_FIPS_SET_DT				 104
-#define RAND_F_FIPS_SET_PRNG_SEED			 107
-#define RAND_F_FIPS_SET_TEST_MODE			 105
 #define RAND_F_RAND_GET_RAND_METHOD			 101
 #define RAND_F_SSLEAY_RAND_BYTES			 100
 
 /* Reason codes. */
-#define RAND_R_NON_FIPS_METHOD				 105
-#define RAND_R_NOT_IN_TEST_MODE				 106
-#define RAND_R_NO_KEY_SET				 107
-#define RAND_R_PRNG_ASKING_FOR_TOO_MUCH			 101
-#define RAND_R_PRNG_ERROR				 108
-#define RAND_R_PRNG_KEYED				 109
-#define RAND_R_PRNG_NOT_REKEYED				 102
-#define RAND_R_PRNG_NOT_RESEEDED			 103
 #define RAND_R_PRNG_NOT_SEEDED				 100
-#define RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY		 110
-#define RAND_R_PRNG_STUCK				 104
 
 #ifdef  __cplusplus
 }
diff --git a/crypto/rand/rand_egd.c b/crypto/rand/rand_egd.c
index 50bce6c..d53b916 100644
--- a/crypto/rand/rand_egd.c
+++ b/crypto/rand/rand_egd.c
@@ -95,7 +95,7 @@
  *   RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255.
  */
 
-#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS)
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_BEOS)
 int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
 	{
 	return(-1);
diff --git a/crypto/rand/rand_eng.c b/crypto/rand/rand_eng.c
deleted file mode 100644
index 1669cef..0000000
--- a/crypto/rand/rand_eng.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/* crypto/rand/rand_lib.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#include <stdio.h>
-#include <time.h>
-#include "cryptlib.h"
-#include "rand_lcl.h"
-#include <openssl/rand.h>
-#ifdef OPENSSL_FIPS
-#include <openssl/fips.h>
-#include <openssl/fips_rand.h>
-#endif
-
-#ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
-#endif
-
-#if defined(OPENSSL_FIPS) && !defined(OPENSSL_NO_ENGINE)
-
-/* non-NULL if default_RAND_meth is ENGINE-provided */
-static ENGINE *funct_ref =NULL;
-
-int eng_RAND_set_rand_method(const RAND_METHOD *meth, const RAND_METHOD **pmeth)
-	{
-	if(funct_ref)
-		{
-		ENGINE_finish(funct_ref);
-		funct_ref = NULL;
-		}
-	*pmeth = meth;
-	return 1;
-	}
-
-const RAND_METHOD *eng_RAND_get_rand_method(const RAND_METHOD **pmeth)
-	{
-	if (!*pmeth)
-		{
-		ENGINE *e = ENGINE_get_default_RAND();
-		if(e)
-			{
-			*pmeth = ENGINE_get_RAND(e);
-			if(!*pmeth)
-				{
-				ENGINE_finish(e);
-				e = NULL;
-				}
-			}
-		if(e)
-			funct_ref = e;
-		else
-			if(FIPS_mode())
-				*pmeth=FIPS_rand_method();
-			else
-			*pmeth = RAND_SSLeay();
-		}
-
-	if(FIPS_mode()
-		&& *pmeth != FIPS_rand_check())
-	    {
-	    RANDerr(RAND_F_ENG_RAND_GET_RAND_METHOD,RAND_R_NON_FIPS_METHOD);
-	    return 0;
-	    }
-
-	return *pmeth;
-	}
-
-int RAND_set_rand_engine(ENGINE *engine)
-	{
-	const RAND_METHOD *tmp_meth = NULL;
-	if(engine)
-		{
-		if(!ENGINE_init(engine))
-			return 0;
-		tmp_meth = ENGINE_get_RAND(engine);
-		if(!tmp_meth)
-			{
-			ENGINE_finish(engine);
-			return 0;
-			}
-		}
-	/* This function releases any prior ENGINE so call it first */
-	RAND_set_rand_method(tmp_meth);
-	funct_ref = engine;
-	return 1;
-	}
-
-void int_RAND_init_engine_callbacks(void)
-	{
-	static int done = 0;
-	if (done)
-		return;
-	int_RAND_set_callbacks(eng_RAND_set_rand_method,
-				 eng_RAND_get_rand_method);
-	done = 1;
-	}
-
-#endif
diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c
index 829fb44..03cda4d 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-2007 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
@@ -70,14 +70,6 @@
 
 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}
@@ -85,17 +77,7 @@
 
 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 18cc9b1..618a8ec 100644
--- a/crypto/rand/rand_lcl.h
+++ b/crypto/rand/rand_lcl.h
@@ -154,16 +154,5 @@
 #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 da6b4e0..513e338 100644
--- a/crypto/rand/rand_lib.c
+++ b/crypto/rand/rand_lib.c
@@ -60,82 +60,15 @@
 #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)
 	{
@@ -196,8 +129,6 @@
 	}
 #endif
 
-#endif
-
 void RAND_cleanup(void)
 	{
 	const RAND_METHOD *meth = RAND_get_rand_method();
diff --git a/crypto/rand/rand_os2.c b/crypto/rand/rand_os2.c
index c3e36d4..fc1e78b 100644
--- a/crypto/rand/rand_os2.c
+++ b/crypto/rand/rand_os2.c
@@ -78,8 +78,10 @@
     ULONG ulIntrHigh;           /* High 32 bits of interrupt time */
 } CPUUTIL;
 
+#ifndef __KLIBC__
 APIRET APIENTRY(*DosPerfSysCall) (ULONG ulCommand, ULONG ulParm1, ULONG ulParm2, ULONG ulParm3) = NULL;
 APIRET APIENTRY(*DosQuerySysState) (ULONG func, ULONG arg1, ULONG pid, ULONG _res_, PVOID buf, ULONG bufsz) = NULL;
+#endif
 HMODULE hDoscalls = 0;
 
 int RAND_poll(void)
@@ -91,6 +93,7 @@
     if (hDoscalls == 0) {
         ULONG rc = DosLoadModule(failed_module, sizeof(failed_module), "DOSCALLS", &hDoscalls);
 
+#ifndef __KLIBC__
         if (rc == 0) {
             rc = DosQueryProcAddr(hDoscalls, 976, NULL, (PFN *)&DosPerfSysCall);
 
@@ -102,6 +105,7 @@
             if (rc)
                 DosQuerySysState = NULL;
         }
+#endif
     }
 
     /* Sample the hi-res timer, runs at around 1.1 MHz */
@@ -122,7 +126,9 @@
             RAND_add(&util, sizeof(util), 10);
         }
         else {
+#ifndef __KLIBC__
             DosPerfSysCall = NULL;
+#endif
         }
     }
 
diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c
index 71b98ec..e9ead3a 100644
--- a/crypto/rand/rand_unix.c
+++ b/crypto/rand/rand_unix.c
@@ -133,7 +133,50 @@
 # define FD_SETSIZE (8*sizeof(fd_set))
 #endif
 
-#ifdef __OpenBSD__
+#ifdef __VOS__
+int RAND_poll(void)
+{
+	unsigned char buf[ENTROPY_NEEDED];
+	pid_t curr_pid;
+	uid_t curr_uid;
+	static int first=1;
+	int i;
+	long rnd = 0;
+	struct timespec ts;
+	unsigned seed;
+
+/* The VOS random() function starts from a static seed so its
+   initial value is predictable.  If random() returns the
+   initial value, reseed it with dynamic data.  The VOS
+   real-time clock has a granularity of 1 nsec so it should be
+   reasonably difficult to predict its exact value.  Do not
+   gratuitously reseed the PRNG because other code in this
+   process or thread may be using it.  */
+
+	if (first) {
+		first = 0;
+		rnd = random ();
+		if (rnd == 1804289383) {
+			clock_gettime (CLOCK_REALTIME, &ts);
+			curr_pid = getpid();
+			curr_uid = getuid();
+			seed = ts.tv_sec ^ ts.tv_nsec ^ curr_pid ^ curr_uid;
+			srandom (seed);
+		}
+	}
+
+	for (i = 0; i < sizeof(buf); i++) {
+		if (i % 4 == 0)
+			rnd = random();
+		buf[i] = rnd;
+		rnd >>= 8;
+	}
+	RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
+	memset(buf, 0, sizeof(buf));
+
+	return 1;
+}
+#elif defined __OpenBSD__
 int RAND_poll(void)
 {
 	u_int32_t rnd = 0, i;
@@ -163,7 +206,7 @@
 	static const char *randomfiles[] = { DEVRANDOM };
 	struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])];
 	int fd;
-	size_t i;
+	unsigned int i;
 #endif
 #ifdef DEVRANDOM_EGD
 	static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
@@ -176,7 +219,8 @@
 	 * have this. Use /dev/urandom if you can as /dev/random may block
 	 * if it runs out of random entries.  */
 
-	for (i=0; i<sizeof(randomfiles)/sizeof(randomfiles[0]) && n < ENTROPY_NEEDED; i++)
+	for (i = 0; (i < sizeof(randomfiles)/sizeof(randomfiles[0])) &&
+			(n < ENTROPY_NEEDED); i++)
 		{
 		if ((fd = open(randomfiles[i], O_RDONLY
 #ifdef O_NONBLOCK
@@ -193,7 +237,7 @@
 			{
 			int usec = 10*1000; /* spend 10ms on each file */
 			int r;
-			size_t j;
+			unsigned int j;
 			struct stat *st=&randomstats[i];
 
 			/* Avoid using same input... Used to be O_NOFOLLOW
@@ -211,7 +255,12 @@
 				{
 				int try_read = 0;
 
-#if defined(OPENSSL_SYS_LINUX)
+#if defined(OPENSSL_SYS_BEOS_R5)
+				/* select() is broken in BeOS R5, so we simply
+				 *  try to read something and snooze if we couldn't */
+				try_read = 1;
+
+#elif defined(OPENSSL_SYS_LINUX)
 				/* use poll() */
 				struct pollfd pset;
 				
@@ -258,6 +307,10 @@
 					r = read(fd,(unsigned char *)tmpbuf+n, ENTROPY_NEEDED-n);
 					if (r > 0)
 						n += r;
+#if defined(OPENSSL_SYS_BEOS_R5)
+					if (r == 0)
+						snooze(t.tv_usec);
+#endif
 					}
 				else
 					r = -1;
@@ -311,6 +364,14 @@
 	l=time(NULL);
 	RAND_add(&l,sizeof(l),0.0);
 
+#if defined(OPENSSL_SYS_BEOS)
+	{
+	system_info sysInfo;
+	get_system_info(&sysInfo);
+	RAND_add(&sysInfo,sizeof(sysInfo),0);
+	}
+#endif
+
 #if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
 	return 1;
 #else
diff --git a/crypto/rand/rand_win.c b/crypto/rand/rand_win.c
index 5198351..5d134e1 100644
--- a/crypto/rand/rand_win.c
+++ b/crypto/rand/rand_win.c
@@ -750,7 +750,7 @@
   int		y;		/* y-coordinate of screen lines to grab */
   int		n = 16;		/* number of screen lines to grab at a time */
 
-  if (GetVersion() >= 0x80000000 || !OPENSSL_isservice())
+  if (GetVersion() < 0x80000000 && OPENSSL_isservice()>0)
     return;
 
   /* Create a screen DC and a memory DC compatible to screen DC */
diff --git a/crypto/rand/randfile.c b/crypto/rand/randfile.c
index 84276d7..4ed40b7 100644
--- a/crypto/rand/randfile.c
+++ b/crypto/rand/randfile.c
@@ -75,9 +75,7 @@
 #ifndef NO_SYS_TYPES_H
 # include <sys/types.h>
 #endif
-#ifdef MAC_OS_pre_X
-# include <stat.h>
-#else
+#ifndef OPENSSL_NO_POSIX_IO
 # include <sys/stat.h>
 #endif
 
@@ -111,12 +109,15 @@
 	 * if bytes == -1, read complete file. */
 
 	MS_STATIC unsigned char buf[BUFSIZE];
+#ifndef OPENSSL_NO_POSIX_IO
 	struct stat sb;
+#endif
 	int i,ret=0,n;
 	FILE *in;
 
 	if (file == NULL) return(0);
 
+#ifndef OPENSSL_NO_POSIX_IO
 #ifdef PURIFY
 	/* struct stat can have padding and unused fields that may not be
 	 * initialized in the call to stat(). We need to clear the entire
@@ -125,9 +126,9 @@
 	 */
 	memset(&sb, 0, sizeof(sb));
 #endif
-
 	if (stat(file,&sb) < 0) return(0);
 	RAND_add(&sb,sizeof(sb),0.0);
+#endif
 	if (bytes == 0) return(ret);
 
 #ifdef OPENSSL_SYS_VMS
@@ -136,8 +137,8 @@
 	in=fopen(file,"rb");
 #endif
 	if (in == NULL) goto err;
-#if defined(S_ISBLK) && defined(S_ISCHR)
-	if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
+#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPNESSL_NO_POSIX_IO)
+	if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
 	  /* this file is a device. we don't want read an infinite number
 	   * of bytes from a random device, nor do we want to use buffered
 	   * I/O because we will waste system entropy. 
@@ -179,6 +180,7 @@
 	int i,ret=0,rand_err=0;
 	FILE *out = NULL;
 	int n;
+#ifndef OPENSSL_NO_POSIX_IO
 	struct stat sb;
 	
 	i=stat(file,&sb);
@@ -194,14 +196,16 @@
 	  }
 #endif
 	}
+#endif
 
-#if defined(O_CREAT) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_VMS)
+#if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && !defined(OPENSSL_SYS_VMS)
 	{
-	/* For some reason Win32 can't write to files created this way */
-	
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
 	/* chmod(..., 0600) is too late to protect the file,
 	 * permissions should be restrictive from the start */
-	int fd = open(file, O_CREAT, 0600);
+	int fd = open(file, O_WRONLY|O_CREAT|O_BINARY, 0600);
 	if (fd != -1)
 		out = fdopen(fd, "wb");
 	}
diff --git a/crypto/rc2/Makefile b/crypto/rc2/Makefile
deleted file mode 100644
index 4b6292b..0000000
--- a/crypto/rc2/Makefile
+++ /dev/null
@@ -1,90 +0,0 @@
-#
-# OpenSSL/crypto/rc2/Makefile
-#
-
-DIR=	rc2
-TOP=	../..
-CC=	cc
-INCLUDES=
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=rc2test.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=rc2_ecb.c rc2_skey.c rc2_cbc.c rc2cfb64.c rc2ofb64.c
-LIBOBJ=rc2_ecb.o rc2_skey.o rc2_cbc.o rc2cfb64.o rc2ofb64.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= rc2.h
-HEADER=	rc2_locl.h $(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-rc2_cbc.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc2.h
-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/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
-rc2ofb64.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc2.h
-rc2ofb64.o: rc2_locl.h rc2ofb64.c
diff --git a/crypto/rc2/rc2.h b/crypto/rc2/rc2.h
index e542ec9..34c8362 100644
--- a/crypto/rc2/rc2.h
+++ b/crypto/rc2/rc2.h
@@ -79,9 +79,7 @@
 	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 4e000e5..0150b0e 100644
--- a/crypto/rc2/rc2_skey.c
+++ b/crypto/rc2/rc2_skey.c
@@ -57,14 +57,9 @@
  */
 
 #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]={
+static const unsigned char key_table[256]={
 	0xd9,0x78,0xf9,0xc4,0x19,0xdd,0xb5,0xed,0x28,0xe9,0xfd,0x79,
 	0x4a,0xa0,0xd8,0x9d,0xc6,0x7e,0x37,0x83,0x2b,0x76,0x53,0x8e,
 	0x62,0x4c,0x64,0x88,0x44,0x8b,0xfb,0xa2,0x17,0x9a,0x59,0xf5,
@@ -99,20 +94,8 @@
  * 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
deleted file mode 100644
index f0bd767..0000000
--- a/crypto/rc4/Makefile
+++ /dev/null
@@ -1,125 +0,0 @@
-#
-# OpenSSL/crypto/rc4/Makefile
-#
-
-DIR=	rc4
-TOP=	../..
-CC=	cc
-CPP=    $(CC) -E
-INCLUDES=
-CFLAG=-g
-AR=		ar r
-
-RC4_ENC=rc4_enc.o rc4_skey.o
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-ASFLAGS= $(INCLUDES) $(ASFLAG)
-AFLAGS= $(ASFLAGS)
-
-GENERAL=Makefile
-TEST=rc4test.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=rc4_skey.c rc4_enc.c rc4_fblk.c
-LIBOBJ=$(RC4_ENC) rc4_fblk.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= rc4.h
-HEADER=	$(EXHEADER) rc4_locl.h
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-# ELF
-rx86-elf.s: asm/rc4-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) rc4-586.pl elf $(CFLAGS) > ../$@)
-# COFF
-rx86-cof.s: asm/rc4-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) rc4-586.pl coff $(CFLAGS) > ../$@)
-# a.out
-rx86-out.s: asm/rc4-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) rc4-586.pl a.out $(CFLAGS) > ../$@)
-
-rc4-x86_64.s: asm/rc4-x86_64.pl;	$(PERL) asm/rc4-x86_64.pl $@
-
-rc4-ia64.s: asm/rc4-ia64.S
-	@case `awk '/^#define RC4_INT/{print$$NF}' $(TOP)/include/openssl/opensslconf.h` in \
-	int)	set -x; $(CC) $(CFLAGS) -DSZ=4 -E asm/rc4-ia64.S > $@ ;; \
-	char)	set -x; $(CC) $(CFLAGS) -DSZ=1 -E asm/rc4-ia64.S > $@ ;; \
-	*)	exit 1 ;; \
-	esac
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-rc4_enc.o: ../../e_os.h ../../include/openssl/bio.h
-rc4_enc.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rc4_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rc4_enc.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-rc4_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-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/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
-rc4_skey.o: ../cryptlib.h rc4_locl.h rc4_skey.c
diff --git a/crypto/rc4/asm/rc4-586.pl b/crypto/rc4/asm/rc4-586.pl
index ef7eee7..38a44a7 100644
--- a/crypto/rc4/asm/rc4-586.pl
+++ b/crypto/rc4/asm/rc4-586.pl
@@ -1,14 +1,21 @@
-#!/usr/local/bin/perl
+#!/usr/bin/env perl
+
+# ====================================================================
+# [Re]written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
 
 # At some point it became apparent that the original SSLeay RC4
-# assembler implementation performs suboptimaly on latest IA-32
+# assembler implementation performs suboptimally on latest IA-32
 # microarchitectures. After re-tuning performance has changed as
 # following:
 #
-# Pentium	+0%
-# Pentium III	+17%
-# AMD		+52%(*)
-# P4		+180%(**)
+# Pentium	-10%
+# Pentium III	+12%
+# AMD		+50%(*)
+# P4		+250%(**)
 #
 # (*)	This number is actually a trade-off:-) It's possible to
 #	achieve	+72%, but at the cost of -48% off PIII performance.
@@ -17,214 +24,247 @@
 #	For reference! This code delivers ~80% of rc4-amd64.pl
 #	performance on the same Opteron machine.
 # (**)	This number requires compressed key schedule set up by
-#	RC4_set_key and therefore doesn't apply to 0.9.7 [option for
-#	compressed key schedule is implemented in 0.9.8 and later,
-#	see commentary section in rc4_skey.c for further details].
+#	RC4_set_key [see commentary below for further details].
 #
 #					<appro@fy.chalmers.se>
 
-push(@INC,"perlasm","../../perlasm");
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
 require "x86asm.pl";
 
 &asm_init($ARGV[0],"rc4-586.pl");
 
-$x="eax";
-$y="ebx";
+$xx="eax";
+$yy="ebx";
 $tx="ecx";
 $ty="edx";
-$in="esi";
-$out="edi";
-$d="ebp";
+$inp="esi";
+$out="ebp";
+$dat="edi";
 
-&RC4("RC4");
+sub RC4_loop {
+  my $i=shift;
+  my $func = ($i==0)?*mov:*or;
+
+	&add	(&LB($yy),&LB($tx));
+	&mov	($ty,&DWP(0,$dat,$yy,4));
+	&mov	(&DWP(0,$dat,$yy,4),$tx);
+	&mov	(&DWP(0,$dat,$xx,4),$ty);
+	&add	($ty,$tx);
+	&inc	(&LB($xx));
+	&and	($ty,0xff);
+	&ror	($out,8)	if ($i!=0);
+	if ($i<3) {
+	  &mov	($tx,&DWP(0,$dat,$xx,4));
+	} else {
+	  &mov	($tx,&wparam(3));	# reload [re-biased] out
+	}
+	&$func	($out,&DWP(0,$dat,$ty,4));
+}
+
+# void RC4(RC4_KEY *key,size_t len,const unsigned char *inp,unsigned char *out);
+&function_begin("RC4");
+	&mov	($dat,&wparam(0));	# load key schedule pointer
+	&mov	($ty, &wparam(1));	# load len
+	&mov	($inp,&wparam(2));	# load inp
+	&mov	($out,&wparam(3));	# load out
+
+	&xor	($xx,$xx);		# avoid partial register stalls
+	&xor	($yy,$yy);
+
+	&cmp	($ty,0);		# safety net
+	&je	(&label("abort"));
+
+	&mov	(&LB($xx),&BP(0,$dat));	# load key->x
+	&mov	(&LB($yy),&BP(4,$dat));	# load key->y
+	&add	($dat,8);
+
+	&lea	($tx,&DWP(0,$inp,$ty));
+	&sub	($out,$inp);		# re-bias out
+	&mov	(&wparam(1),$tx);	# save input+len
+
+	&inc	(&LB($xx));
+
+	# detect compressed key schedule...
+	&cmp	(&DWP(256,$dat),-1);
+	&je	(&label("RC4_CHAR"));
+
+	&mov	($tx,&DWP(0,$dat,$xx,4));
+
+	&and	($ty,-4);		# how many 4-byte chunks?
+	&jz	(&label("loop1"));
+
+	&lea	($ty,&DWP(-4,$inp,$ty));
+	&mov	(&wparam(2),$ty);	# save input+(len/4)*4-4
+	&mov	(&wparam(3),$out);	# $out as accumulator in this loop
+
+	&set_label("loop4",16);
+		for ($i=0;$i<4;$i++) { RC4_loop($i); }
+		&ror	($out,8);
+		&xor	($out,&DWP(0,$inp));
+		&cmp	($inp,&wparam(2));	# compare to input+(len/4)*4-4
+		&mov	(&DWP(0,$tx,$inp),$out);# $tx holds re-biased out here
+		&lea	($inp,&DWP(4,$inp));
+		&mov	($tx,&DWP(0,$dat,$xx,4));
+	&jb	(&label("loop4"));
+
+	&cmp	($inp,&wparam(1));	# compare to input+len
+	&je	(&label("done"));
+	&mov	($out,&wparam(3));	# restore $out
+
+	&set_label("loop1",16);
+		&add	(&LB($yy),&LB($tx));
+		&mov	($ty,&DWP(0,$dat,$yy,4));
+		&mov	(&DWP(0,$dat,$yy,4),$tx);
+		&mov	(&DWP(0,$dat,$xx,4),$ty);
+		&add	($ty,$tx);
+		&inc	(&LB($xx));
+		&and	($ty,0xff);
+		&mov	($ty,&DWP(0,$dat,$ty,4));
+		&xor	(&LB($ty),&BP(0,$inp));
+		&lea	($inp,&DWP(1,$inp));
+		&mov	($tx,&DWP(0,$dat,$xx,4));
+		&cmp	($inp,&wparam(1));	# compare to input+len
+		&mov	(&BP(-1,$out,$inp),&LB($ty));
+	&jb	(&label("loop1"));
+
+	&jmp	(&label("done"));
+
+# this is essentially Intel P4 specific codepath...
+&set_label("RC4_CHAR",16);
+	&movz	($tx,&BP(0,$dat,$xx));
+	# strangely enough unrolled loop performs over 20% slower...
+	&set_label("cloop1");
+		&add	(&LB($yy),&LB($tx));
+		&movz	($ty,&BP(0,$dat,$yy));
+		&mov	(&BP(0,$dat,$yy),&LB($tx));
+		&mov	(&BP(0,$dat,$xx),&LB($ty));
+		&add	(&LB($ty),&LB($tx));
+		&movz	($ty,&BP(0,$dat,$ty));
+		&add	(&LB($xx),1);
+		&xor	(&LB($ty),&BP(0,$inp));
+		&lea	($inp,&DWP(1,$inp));
+		&movz	($tx,&BP(0,$dat,$xx));
+		&cmp	($inp,&wparam(1));
+		&mov	(&BP(-1,$out,$inp),&LB($ty));
+	&jb	(&label("cloop1"));
+
+&set_label("done");
+	&dec	(&LB($xx));
+	&mov	(&BP(-4,$dat),&LB($yy));	# save key->y
+	&mov	(&BP(-8,$dat),&LB($xx));	# save key->x
+&set_label("abort");
+&function_end("RC4");
+
+########################################################################
+
+$inp="esi";
+$out="edi";
+$idi="ebp";
+$ido="ecx";
+$idx="edx";
+
+&external_label("OPENSSL_ia32cap_P");
+
+# void RC4_set_key(RC4_KEY *key,int len,const unsigned char *data);
+&function_begin("RC4_set_key");
+	&mov	($out,&wparam(0));		# load key
+	&mov	($idi,&wparam(1));		# load len
+	&mov	($inp,&wparam(2));		# load data
+	&picmeup($idx,"OPENSSL_ia32cap_P");
+
+	&lea	($out,&DWP(2*4,$out));		# &key->data
+	&lea	($inp,&DWP(0,$inp,$idi));	# $inp to point at the end
+	&neg	($idi);
+	&xor	("eax","eax");
+	&mov	(&DWP(-4,$out),$idi);		# borrow key->y
+
+	&bt	(&DWP(0,$idx),20);		# check for bit#20
+	&jc	(&label("c1stloop"));
+
+&set_label("w1stloop",16);
+	&mov	(&DWP(0,$out,"eax",4),"eax");	# key->data[i]=i;
+	&add	(&LB("eax"),1);			# i++;
+	&jnc	(&label("w1stloop"));
+
+	&xor	($ido,$ido);
+	&xor	($idx,$idx);
+
+&set_label("w2ndloop",16);
+	&mov	("eax",&DWP(0,$out,$ido,4));
+	&add	(&LB($idx),&BP(0,$inp,$idi));
+	&add	(&LB($idx),&LB("eax"));
+	&add	($idi,1);
+	&mov	("ebx",&DWP(0,$out,$idx,4));
+	&jnz	(&label("wnowrap"));
+	  &mov	($idi,&DWP(-4,$out));
+	&set_label("wnowrap");
+	&mov	(&DWP(0,$out,$idx,4),"eax");
+	&mov	(&DWP(0,$out,$ido,4),"ebx");
+	&add	(&LB($ido),1);
+	&jnc	(&label("w2ndloop"));
+&jmp	(&label("exit"));
+
+# Unlike all other x86 [and x86_64] implementations, Intel P4 core
+# [including EM64T] was found to perform poorly with above "32-bit" key
+# schedule, a.k.a. RC4_INT. Performance improvement for IA-32 hand-coded
+# assembler turned out to be 3.5x if re-coded for compressed 8-bit one,
+# a.k.a. RC4_CHAR! It's however inappropriate to just switch to 8-bit
+# schedule for x86[_64], because non-P4 implementations suffer from
+# significant performance losses then, e.g. PIII exhibits >2x
+# deterioration, and so does Opteron. In order to assure optimal
+# all-round performance, we detect P4 at run-time and set up compressed
+# key schedule, which is recognized by RC4 procedure.
+
+&set_label("c1stloop",16);
+	&mov	(&BP(0,$out,"eax"),&LB("eax"));	# key->data[i]=i;
+	&add	(&LB("eax"),1);			# i++;
+	&jnc	(&label("c1stloop"));
+
+	&xor	($ido,$ido);
+	&xor	($idx,$idx);
+	&xor	("ebx","ebx");
+
+&set_label("c2ndloop",16);
+	&mov	(&LB("eax"),&BP(0,$out,$ido));
+	&add	(&LB($idx),&BP(0,$inp,$idi));
+	&add	(&LB($idx),&LB("eax"));
+	&add	($idi,1);
+	&mov	(&LB("ebx"),&BP(0,$out,$idx));
+	&jnz	(&label("cnowrap"));
+	  &mov	($idi,&DWP(-4,$out));
+	&set_label("cnowrap");
+	&mov	(&BP(0,$out,$idx),&LB("eax"));
+	&mov	(&BP(0,$out,$ido),&LB("ebx"));
+	&add	(&LB($ido),1);
+	&jnc	(&label("c2ndloop"));
+
+	&mov	(&DWP(256,$out),-1);		# mark schedule as compressed
+
+&set_label("exit");
+	&xor	("eax","eax");
+	&mov	(&DWP(-8,$out),"eax");		# key->x=0;
+	&mov	(&DWP(-4,$out),"eax");		# key->y=0;
+&function_end("RC4_set_key");
+
+# const char *RC4_options(void);
+&function_begin_B("RC4_options");
+	&call	(&label("pic_point"));
+&set_label("pic_point");
+	&blindpop("eax");
+	&lea	("eax",&DWP(&label("opts")."-".&label("pic_point"),"eax"));
+	&picmeup("edx","OPENSSL_ia32cap_P");
+	&bt	(&DWP(0,"edx"),20);
+	&jnc	(&label("skip"));
+	  &add	("eax",12);
+	&set_label("skip");
+	&ret	();
+&set_label("opts",64);
+&asciz	("rc4(4x,int)");
+&asciz	("rc4(1x,char)");
+&asciz	("RC4 for x86, CRYPTOGAMS by <appro\@openssl.org>");
+&align	(64);
+&function_end_B("RC4_options");
 
 &asm_finish();
 
-sub RC4_loop
-	{
-	local($n,$p,$char)=@_;
-
-	&comment("Round $n");
-
-	if ($char)
-		{
-		if ($p >= 0)
-			{
-			 &mov($ty,	&swtmp(2));
-			&cmp($ty,	$in);
-			 &jbe(&label("finished"));
-			&inc($in);
-			}
-		else
-			{
-			&add($ty,	8);
-			 &inc($in);
-			&cmp($ty,	$in);
-			 &jb(&label("finished"));
-			&mov(&swtmp(2),	$ty);
-			}
-		}
-	# Moved out
-	# &mov(	$tx,		&DWP(0,$d,$x,4)) if $p < 0;
-
-	&add(	&LB($y),	&LB($tx));
-	&mov(	$ty,		&DWP(0,$d,$y,4));
-	 # XXX
-	&mov(	&DWP(0,$d,$x,4),$ty);
-	 &add(	$ty,		$tx);
-	&mov(	&DWP(0,$d,$y,4),$tx);
-	 &and(	$ty,		0xff);
-	 &inc(	&LB($x));			# NEXT ROUND
-	&mov(	$tx,		&DWP(0,$d,$x,4)) if $p < 1; # NEXT ROUND
-	 &mov(	$ty,		&DWP(0,$d,$ty,4));
-
-	if (!$char)
-		{
-		#moved up into last round
-		if ($p >= 1)
-			{
-			&add(	$out,	8)
-			}
-		&movb(	&BP($n,"esp","",0),	&LB($ty));
-		}
-	else
-		{
-		# Note in+=8 has occured
-		&movb(	&HB($ty),	&BP(-1,$in,"",0));
-		 # XXX
-		&xorb(&LB($ty),		&HB($ty));
-		 # XXX
-		&movb(&BP($n,$out,"",0),&LB($ty));
-		}
-	}
-
-
-sub RC4
-	{
-	local($name)=@_;
-
-	&function_begin_B($name,"");
-
-	&mov($ty,&wparam(1));		# len
-	&cmp($ty,0);
-	&jne(&label("proceed"));
-	&ret();
-	&set_label("proceed");
-
-	&comment("");
-
-	&push("ebp");
-	 &push("ebx");
-	&push("esi");
-	 &xor(	$x,	$x);		# avoid partial register stalls
-	&push("edi");
-	 &xor(	$y,	$y);		# avoid partial register stalls
-	&mov(	$d,	&wparam(0));	# key
-	 &mov(	$in,	&wparam(2));
-
-	&movb(	&LB($x),	&BP(0,$d,"",1));
-	 &movb(	&LB($y),	&BP(4,$d,"",1));
-
-	&mov(	$out,	&wparam(3));
-	 &inc(	&LB($x));
-
-	&stack_push(3);	# 3 temp variables
-	 &add(	$d,	8);
-
-	# detect compressed schedule, see commentary section in rc4_skey.c...
-	# in 0.9.7 context ~50 bytes below RC4_CHAR label remain redundant,
-	# as compressed key schedule is set up in 0.9.8 and later.
-	&cmp(&DWP(256,$d),-1);
-	&je(&label("RC4_CHAR"));
-
-	 &lea(	$ty,	&DWP(-8,$ty,$in));
-
-	# check for 0 length input
-
-	 &mov(	&swtmp(2),	$ty);	# this is now address to exit at
-	&mov(	$tx,	&DWP(0,$d,$x,4));
-
-	 &cmp(	$ty,	$in);
-	&jb(	&label("end")); # less than 8 bytes
-
-	&set_label("start");
-
-	# filling DELAY SLOT
-	&add(	$in,	8);
-
-	&RC4_loop(0,-1,0);
-	&RC4_loop(1,0,0);
-	&RC4_loop(2,0,0);
-	&RC4_loop(3,0,0);
-	&RC4_loop(4,0,0);
-	&RC4_loop(5,0,0);
-	&RC4_loop(6,0,0);
-	&RC4_loop(7,1,0);
-	
-	&comment("apply the cipher text");
-	# xor the cipher data with input
-
-	#&add(	$out,	8); #moved up into last round
-
-	&mov(	$tx,	&swtmp(0));
-	 &mov(	$ty,	&DWP(-8,$in,"",0));
-	&xor(	$tx,	$ty);
-	 &mov(	$ty,	&DWP(-4,$in,"",0)); 
-	&mov(	&DWP(-8,$out,"",0),	$tx);
-	 &mov(	$tx,	&swtmp(1));
-	&xor(	$tx,	$ty);
-	 &mov(	$ty,	&swtmp(2));	# load end ptr;
-	&mov(	&DWP(-4,$out,"",0),	$tx);
-	 &mov(	$tx,		&DWP(0,$d,$x,4));
-	&cmp($in,	$ty);
-	 &jbe(&label("start"));
-
-	&set_label("end");
-
-	# There is quite a bit of extra crap in RC4_loop() for this
-	# first round
-	&RC4_loop(0,-1,1);
-	&RC4_loop(1,0,1);
-	&RC4_loop(2,0,1);
-	&RC4_loop(3,0,1);
-	&RC4_loop(4,0,1);
-	&RC4_loop(5,0,1);
-	&RC4_loop(6,1,1);
-
-	&jmp(&label("finished"));
-
-	&align(16);
-	# this is essentially Intel P4 specific codepath, see rc4_skey.c,
-	# and is engaged in 0.9.8 and later context...
-	&set_label("RC4_CHAR");
-
-	&lea	($ty,&DWP(0,$in,$ty));
-	&mov	(&swtmp(2),$ty);
-	&movz	($tx,&BP(0,$d,$x));
-
-	# strangely enough unrolled loop performs over 20% slower...
-	&set_label("RC4_CHAR_loop");
-		&add	(&LB($y),&LB($tx));
-		&movz	($ty,&BP(0,$d,$y));
-		&movb	(&BP(0,$d,$y),&LB($tx));
-		&movb	(&BP(0,$d,$x),&LB($ty));
-		&add	(&LB($ty),&LB($tx));
-		&movz	($ty,&BP(0,$d,$ty));
-		&add	(&LB($x),1);
-		&xorb	(&LB($ty),&BP(0,$in));
-		&lea	($in,&DWP(1,$in));
-		&movz	($tx,&BP(0,$d,$x));
-		&cmp	($in,&swtmp(2));
-		&movb	(&BP(0,$out),&LB($ty));
-		&lea	($out,&DWP(1,$out));
-	&jb	(&label("RC4_CHAR_loop"));
-
-	&set_label("finished");
-	&dec(	$x);
-	 &stack_pop(3);
-	&movb(	&BP(-4,$d,"",0),&LB($y));
-	 &movb(	&BP(-8,$d,"",0),&LB($x));
-
-	&function_end($name);
-	}
-
diff --git a/crypto/rc4/asm/rc4-ia64.S b/crypto/rc4/asm/rc4-ia64.S
deleted file mode 100644
index 8210c47..0000000
--- a/crypto/rc4/asm/rc4-ia64.S
+++ /dev/null
@@ -1,159 +0,0 @@
-// ====================================================================
-// Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-// project.
-//
-// Rights for redistribution and usage in source and binary forms are
-// granted according to the OpenSSL license. Warranty of any kind is
-// disclaimed.
-// ====================================================================
-
-.ident  "rc4-ia64.S, Version 2.0"
-.ident  "IA-64 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
-
-// What's wrong with compiler generated code? Because of the nature of
-// C language, compiler doesn't [dare to] reorder load and stores. But
-// being memory-bound, RC4 should benefit from reorder [on in-order-
-// execution core such as IA-64]. But what can we reorder? At the very
-// least we can safely reorder references to key schedule in respect
-// to input and output streams. Secondly, from the first [close] glance
-// it appeared that it's possible to pull up some references to
-// elements of the key schedule itself. Original rationale ["prior
-// loads are not safe only for "degenerated" key schedule, when some
-// elements equal to the same value"] was kind of sloppy. I should have
-// formulated as it really was: if we assume that pulling up reference
-// to key[x+1] is not safe, then it would mean that key schedule would
-// "degenerate," which is never the case. The problem is that this
-// holds true in respect to references to key[x], but not to key[y].
-// Legitimate "collisions" do occur within every 256^2 bytes window.
-// Fortunately there're enough free instruction slots to keep prior
-// reference to key[x+1], detect "collision" and compensate for it.
-// All this without sacrificing a single clock cycle:-) Throughput is
-// ~210MBps on 900MHz CPU, which is is >3x faster than gcc generated
-// code and +30% - if compared to HP-UX C. Unrolling loop below should
-// give >30% on top of that...
-
-.text
-.explicit
-
-#if defined(_HPUX_SOURCE) && !defined(_LP64)
-# define ADDP	addp4
-#else
-# define ADDP	add
-#endif
-
-#ifndef SZ
-#define SZ	4	// this is set to sizeof(RC4_INT)
-#endif
-// SZ==4 seems to be optimal. At least SZ==8 is not any faster, not for
-// assembler implementation, while SZ==1 code is ~30% slower.
-#if SZ==1	// RC4_INT is unsigned char
-# define	LDKEY	ld1
-# define	STKEY	st1
-# define	OFF	0
-#elif SZ==4	// RC4_INT is unsigned int
-# define	LDKEY	ld4
-# define	STKEY	st4
-# define	OFF	2
-#elif SZ==8	// RC4_INT is unsigned long
-# define	LDKEY	ld8
-# define	STKEY	st8
-# define	OFF	3
-#endif
-
-out=r8;		// [expanded] output pointer
-inp=r9;		// [expanded] output pointer
-prsave=r10;
-key=r28;	// [expanded] pointer to RC4_KEY
-ksch=r29;	// (key->data+255)[&~(sizeof(key->data)-1)]
-xx=r30;
-yy=r31;
-
-// void RC4(RC4_KEY *key,size_t len,const void *inp,void *out);
-.global	RC4#
-.proc	RC4#
-.align	32
-.skip	16
-RC4:
-	.prologue
-	.save   ar.pfs,r2
-{ .mii;	alloc	r2=ar.pfs,4,12,0,16
-	.save	pr,prsave
-	mov	prsave=pr
-	ADDP	key=0,in0		};;
-{ .mib;	cmp.eq	p6,p0=0,in1			// len==0?
-	.save	ar.lc,r3
-	mov	r3=ar.lc
-(p6)	br.ret.spnt.many	b0	};;	// emergency exit
-
-	.body
-	.rotr	dat[4],key_x[4],tx[2],rnd[2],key_y[2],ty[1];
-
-{ .mib;	LDKEY	xx=[key],SZ			// load key->x
-	add	in1=-1,in1			// adjust len for loop counter
-	nop.b	0			}
-{ .mib;	ADDP	inp=0,in2
-	ADDP	out=0,in3
-	brp.loop.imp	.Ltop,.Lexit-16	};;
-{ .mmi;	LDKEY	yy=[key]			// load key->y
-	add	ksch=SZ,key
-	mov	ar.lc=in1		}
-{ .mmi;	mov	key_y[1]=r0			// guarantee inequality
-						// in first iteration
-	add	xx=1,xx
-	mov	pr.rot=1<<16		};;
-{ .mii;	nop.m	0
-	dep	key_x[1]=xx,r0,OFF,8
-	mov	ar.ec=3			};;	// note that epilogue counter
-						// is off by 1. I compensate
-						// for this at exit...
-.Ltop:
-// The loop is scheduled for 4*(n+2) spin-rate on Itanium 2, which
-// theoretically gives asymptotic performance of clock frequency
-// divided by 4 bytes per seconds, or 400MBps on 1.6GHz CPU. This is
-// for sizeof(RC4_INT)==4. For smaller RC4_INT STKEY inadvertently
-// splits the last bundle and you end up with 5*n spin-rate:-(
-// Originally the loop was scheduled for 3*n and relied on key
-// schedule to be aligned at 256*sizeof(RC4_INT) boundary. But
-// *(out++)=dat, which maps to st1, had same effect [inadvertent
-// bundle split] and holded the loop back. Rescheduling for 4*n
-// made it possible to eliminate dependence on specific alignment
-// and allow OpenSSH keep "abusing" our API. Reaching for 3*n would
-// require unrolling, sticking to variable shift instruction for
-// collecting output [to avoid starvation for integer shifter] and
-// copying of key schedule to controlled place in stack [so that
-// deposit instruction can serve as substitute for whole
-// key->data+((x&255)<<log2(sizeof(key->data[0])))]...
-{ .mmi;	(p19)	st1	[out]=dat[3],1			// *(out++)=dat
-	(p16)	add	xx=1,xx				// x++
-	(p18)	dep	rnd[1]=rnd[1],r0,OFF,8	}	// ((tx+ty)&255)<<OFF
-{ .mmi;	(p16)	add	key_x[1]=ksch,key_x[1]		// &key[xx&255]
-	(p17)	add	key_y[1]=ksch,key_y[1]	};;	// &key[yy&255]	
-{ .mmi;	(p16)	LDKEY	tx[0]=[key_x[1]]		// tx=key[xx]
-	(p17)	LDKEY	ty[0]=[key_y[1]]		// ty=key[yy]	
-	(p16)	dep	key_x[0]=xx,r0,OFF,8	}	// (xx&255)<<OFF
-{ .mmi;	(p18)	add	rnd[1]=ksch,rnd[1]		// &key[(tx+ty)&255]
-	(p16)	cmp.ne.unc p20,p21=key_x[1],key_y[1] };;
-{ .mmi;	(p18)	LDKEY	rnd[1]=[rnd[1]]			// rnd=key[(tx+ty)&255]
-	(p16)	ld1	dat[0]=[inp],1		}	// dat=*(inp++)
-.pred.rel	"mutex",p20,p21
-{ .mmi;	(p21)	add	yy=yy,tx[1]			// (p16)
-	(p20)	add	yy=yy,tx[0]			// (p16) y+=tx
-	(p21)	mov	tx[0]=tx[1]		};;	// (p16)
-{ .mmi;	(p17)	STKEY	[key_y[1]]=tx[1]		// key[yy]=tx
-	(p17)	STKEY	[key_x[2]]=ty[0]		// key[xx]=ty
-	(p16)	dep	key_y[0]=yy,r0,OFF,8	}	// &key[yy&255]
-{ .mmb;	(p17)	add	rnd[0]=tx[1],ty[0]		// tx+=ty
-	(p18)	xor	dat[2]=dat[2],rnd[1]		// dat^=rnd
-	br.ctop.sptk	.Ltop			};;
-.Lexit:
-{ .mib;	STKEY	[key]=yy,-SZ			// save key->y
-	mov	pr=prsave,0x1ffff
-	nop.b	0			}
-{ .mib;	st1	[out]=dat[3],1			// compensate for truncated
-						// epilogue counter
-	add	xx=-1,xx
-	nop.b	0			};;
-{ .mib;	STKEY	[key]=xx			// save key->x
-	mov	ar.lc=r3
-	br.ret.sptk.many	b0	};;
-.endp	RC4#
diff --git a/crypto/rc4/asm/rc4-ia64.pl b/crypto/rc4/asm/rc4-ia64.pl
new file mode 100644
index 0000000..49cd5b5
--- /dev/null
+++ b/crypto/rc4/asm/rc4-ia64.pl
@@ -0,0 +1,755 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by David Mosberger <David.Mosberger@acm.org> based on the
+# Itanium optimized Crypto code which was released by HP Labs at
+# http://www.hpl.hp.com/research/linux/crypto/.
+#
+# Copyright (c) 2005 Hewlett-Packard Development Company, L.P.
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+
+
+# This is a little helper program which generates a software-pipelined
+# for RC4 encryption.  The basic algorithm looks like this:
+#
+#   for (counter = 0; counter < len; ++counter)
+#     {
+#       in = inp[counter];
+#       SI = S[I];
+#       J = (SI + J) & 0xff;
+#       SJ = S[J];
+#       T = (SI + SJ) & 0xff;
+#       S[I] = SJ, S[J] = SI;
+#       ST = S[T];
+#       outp[counter] = in ^ ST;
+#       I = (I + 1) & 0xff;
+#     }
+#
+# Pipelining this loop isn't easy, because the stores to the S[] array
+# need to be observed in the right order.  The loop generated by the
+# code below has the following pipeline diagram:
+#
+#      cycle
+#     | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 |12 |13 |14 |15 |16 |17 |
+# iter
+#   1: xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx
+#   2:             xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx
+#   3:                         xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx
+#
+#   where:
+# 	LDI = load of S[I]
+# 	LDJ = load of S[J]
+# 	SWP = swap of S[I] and S[J]
+# 	LDT = load of S[T]
+#
+# Note that in the above diagram, the major trouble-spot is that LDI
+# of the 2nd iteration is performed BEFORE the SWP of the first
+# iteration.  Fortunately, this is easy to detect (I of the 1st
+# iteration will be equal to J of the 2nd iteration) and when this
+# happens, we simply forward the proper value from the 1st iteration
+# to the 2nd one.  The proper value in this case is simply the value
+# of S[I] from the first iteration (thanks to the fact that SWP
+# simply swaps the contents of S[I] and S[J]).
+#
+# Another potential trouble-spot is in cycle 7, where SWP of the 1st
+# iteration issues at the same time as the LDI of the 3rd iteration.
+# However, thanks to IA-64 execution semantics, this can be taken
+# care of simply by placing LDI later in the instruction-group than
+# SWP.  IA-64 CPUs will automatically forward the value if they
+# detect that the SWP and LDI are accessing the same memory-location.
+
+# The core-loop that can be pipelined then looks like this (annotated
+# with McKinley/Madison issue port & latency numbers, assuming L1
+# cache hits for the most part):
+
+# operation:	    instruction:		    issue-ports:  latency
+# ------------------  -----------------------------   ------------- -------
+
+# Data = *inp++       ld1 data = [inp], 1             M0-M1         1 cyc     c0
+#                     shladd Iptr = I, KeyTable, 3    M0-M3, I0, I1 1 cyc
+# I = (I + 1) & 0xff  padd1 nextI = I, one            M0-M3, I0, I1 3 cyc
+#                     ;;
+# SI = S[I]           ld8 SI = [Iptr]                 M0-M1         1 cyc     c1 * after SWAP!
+#                     ;;
+#                     cmp.eq.unc pBypass = I, J                                  * after J is valid!
+# J = SI + J          add J = J, SI                   M0-M3, I0, I1 1 cyc     c2
+#                     (pBypass) br.cond.spnt Bypass
+#                     ;;
+# ---------------------------------------------------------------------------------------
+# J = J & 0xff        zxt1 J = J                      I0, I1, 1 cyc           c3
+#                     ;;
+#                     shladd Jptr = J, KeyTable, 3    M0-M3, I0, I1 1 cyc     c4
+#                     ;;
+# SJ = S[J]           ld8 SJ = [Jptr]                 M0-M1         1 cyc     c5
+#                     ;;
+# ---------------------------------------------------------------------------------------
+# T = (SI + SJ)       add T = SI, SJ                  M0-M3, I0, I1 1 cyc     c6
+#                     ;;
+# T = T & 0xff        zxt1 T = T                      I0, I1        1 cyc
+# S[I] = SJ           st8 [Iptr] = SJ                 M2-M3                   c7
+# S[J] = SI           st8 [Jptr] = SI                 M2-M3
+#                     ;;
+#                     shladd Tptr = T, KeyTable, 3    M0-M3, I0, I1 1 cyc     c8
+#                     ;;
+# ---------------------------------------------------------------------------------------
+# T = S[T]            ld8 T = [Tptr]                  M0-M1         1 cyc     c9
+#                     ;;
+# data ^= T           xor data = data, T              M0-M3, I0, I1 1 cyc     c10
+#                     ;;
+# *out++ = Data ^ T   dep word = word, data, 8, POS   I0, I1        1 cyc     c11
+#                     ;;
+# ---------------------------------------------------------------------------------------
+
+# There are several points worth making here:
+
+#   - Note that due to the bypass/forwarding-path, the first two
+#     phases of the loop are strangly mingled together.  In
+#     particular, note that the first stage of the pipeline is
+#     using the value of "J", as calculated by the second stage.
+#   - Each bundle-pair will have exactly 6 instructions.
+#   - Pipelined, the loop can execute in 3 cycles/iteration and
+#     4 stages.  However, McKinley/Madison can issue "st1" to
+#     the same bank at a rate of at most one per 4 cycles.  Thus,
+#     instead of storing each byte, we accumulate them in a word
+#     and then write them back at once with a single "st8" (this
+#     implies that the setup code needs to ensure that the output
+#     buffer is properly aligned, if need be, by encoding the
+#     first few bytes separately).
+#   - There is no space for a "br.ctop" instruction.  For this
+#     reason we can't use module-loop support in IA-64 and have
+#     to do a traditional, purely software-pipelined loop.
+#   - We can't replace any of the remaining "add/zxt1" pairs with
+#     "padd1" because the latency for that instruction is too high
+#     and would push the loop to the point where more bypasses
+#     would be needed, which we don't have space for.
+#   - The above loop runs at around 3.26 cycles/byte, or roughly
+#     440 MByte/sec on a 1.5GHz Madison.  This is well below the
+#     system bus bandwidth and hence with judicious use of
+#     "lfetch" this loop can run at (almost) peak speed even when
+#     the input and output data reside in memory.  The
+#     max. latency that can be tolerated is (PREFETCH_DISTANCE *
+#     L2_LINE_SIZE * 3 cyc), or about 384 cycles assuming (at
+#     least) 1-ahead prefetching of 128 byte cache-lines.  Note
+#     that we do NOT prefetch into L1, since that would only
+#     interfere with the S[] table values stored there.  This is
+#     acceptable because there is a 10 cycle latency between
+#     load and first use of the input data.
+#   - We use a branch to out-of-line bypass-code of cycle-pressure:
+#     we calculate the next J, check for the need to activate the
+#     bypass path, and activate the bypass path ALL IN THE SAME
+#     CYCLE.  If we didn't have these constraints, we could do
+#     the bypass with a simple conditional move instruction.
+#     Fortunately, the bypass paths get activated relatively
+#     infrequently, so the extra branches don't cost all that much
+#     (about 0.04 cycles/byte, measured on a 16396 byte file with
+#     random input data).
+#
+
+$phases = 4;		# number of stages/phases in the pipelined-loop
+$unroll_count = 6;	# number of times we unrolled it
+$pComI = (1 << 0);
+$pComJ = (1 << 1);
+$pComT = (1 << 2);
+$pOut  = (1 << 3);
+
+$NData = 4;
+$NIP = 3;
+$NJP = 2;
+$NI = 2;
+$NSI = 3;
+$NSJ = 2;
+$NT = 2;
+$NOutWord = 2;
+
+#
+# $threshold is the minimum length before we attempt to use the
+# big software-pipelined loop.  It MUST be greater-or-equal
+# to:
+#  		PHASES * (UNROLL_COUNT + 1) + 7
+#
+# The "+ 7" comes from the fact we may have to encode up to
+#   7 bytes separately before the output pointer is aligned.
+#
+$threshold = (3 * ($phases * ($unroll_count + 1)) + 7);
+
+sub I {
+    local *code = shift;
+    local $format = shift;
+    $code .= sprintf ("\t\t".$format."\n", @_);
+}
+
+sub P {
+    local *code = shift;
+    local $format = shift;
+    $code .= sprintf ($format."\n", @_);
+}
+
+sub STOP {
+    local *code = shift;
+    $code .=<<___;
+		;;
+___
+}
+
+sub emit_body {
+    local *c = shift;
+    local *bypass = shift;
+    local ($iteration, $p) = @_;
+
+    local $i0 = $iteration;
+    local $i1 = $iteration - 1;
+    local $i2 = $iteration - 2;
+    local $i3 = $iteration - 3;
+    local $iw0 = ($iteration - 3) / 8;
+    local $iw1 = ($iteration > 3) ? ($iteration - 4) / 8 : 1;
+    local $byte_num = ($iteration - 3) % 8;
+    local $label = $iteration + 1;
+    local $pAny = ($p & 0xf) == 0xf;
+    local $pByp = (($p & $pComI) && ($iteration > 0));
+
+    $c.=<<___;
+//////////////////////////////////////////////////
+___
+
+    if (($p & 0xf) == 0) {
+	$c.="#ifdef HOST_IS_BIG_ENDIAN\n";
+	&I(\$c,"shr.u	OutWord[%u] = OutWord[%u], 32;;",
+				$iw1 % $NOutWord, $iw1 % $NOutWord);
+	$c.="#endif\n";
+	&I(\$c, "st4 [OutPtr] = OutWord[%u], 4", $iw1 % $NOutWord);
+	return;
+    }
+
+    # Cycle 0
+    &I(\$c, "{ .mmi")					      if ($pAny);
+    &I(\$c, "ld1    Data[%u] = [InPtr], 1", $i0 % $NData)     if ($p & $pComI);
+    &I(\$c, "padd1  I[%u] = One, I[%u]", $i0 % $NI, $i1 % $NI)if ($p & $pComI);
+    &I(\$c, "zxt1   J = J")				      if ($p & $pComJ);
+    &I(\$c, "}")					      if ($pAny);
+    &I(\$c, "{ .mmi")					      if ($pAny);
+    &I(\$c, "LKEY   T[%u] = [T[%u]]", $i1 % $NT, $i1 % $NT)   if ($p & $pOut);
+    &I(\$c, "add    T[%u] = SI[%u], SJ[%u]",
+       $i0 % $NT, $i2 % $NSI, $i1 % $NSJ)		      if ($p & $pComT);
+    &I(\$c, "KEYADDR(IPr[%u], I[%u])", $i0 % $NIP, $i1 % $NI) if ($p & $pComI);
+    &I(\$c, "}")					      if ($pAny);
+    &STOP(\$c);
+
+    # Cycle 1
+    &I(\$c, "{ .mmi")					      if ($pAny);
+    &I(\$c, "SKEY   [IPr[%u]] = SJ[%u]", $i2 % $NIP, $i1%$NSJ)if ($p & $pComT);
+    &I(\$c, "SKEY   [JP[%u]] = SI[%u]", $i1 % $NJP, $i2%$NSI) if ($p & $pComT);
+    &I(\$c, "zxt1   T[%u] = T[%u]", $i0 % $NT, $i0 % $NT)     if ($p & $pComT);
+    &I(\$c, "}")					      if ($pAny);
+    &I(\$c, "{ .mmi")					      if ($pAny);
+    &I(\$c, "LKEY   SI[%u] = [IPr[%u]]", $i0 % $NSI, $i0%$NIP)if ($p & $pComI);
+    &I(\$c, "KEYADDR(JP[%u], J)", $i0 % $NJP)		      if ($p & $pComJ);
+    &I(\$c, "xor    Data[%u] = Data[%u], T[%u]",
+       $i3 % $NData, $i3 % $NData, $i1 % $NT)		      if ($p & $pOut);
+    &I(\$c, "}")					      if ($pAny);
+    &STOP(\$c);
+
+    # Cycle 2
+    &I(\$c, "{ .mmi")					      if ($pAny);
+    &I(\$c, "LKEY   SJ[%u] = [JP[%u]]", $i0 % $NSJ, $i0%$NJP) if ($p & $pComJ);
+    &I(\$c, "cmp.eq pBypass, p0 = I[%u], J", $i1 % $NI)	      if ($pByp);
+    &I(\$c, "dep OutWord[%u] = Data[%u], OutWord[%u], BYTE_POS(%u), 8",
+       $iw0%$NOutWord, $i3%$NData, $iw1%$NOutWord, $byte_num) if ($p & $pOut);
+    &I(\$c, "}")					      if ($pAny);
+    &I(\$c, "{ .mmb")					      if ($pAny);
+    &I(\$c, "add    J = J, SI[%u]", $i0 % $NSI)		      if ($p & $pComI);
+    &I(\$c, "KEYADDR(T[%u], T[%u])", $i0 % $NT, $i0 % $NT)    if ($p & $pComT);
+    &P(\$c, "(pBypass)\tbr.cond.spnt.many .rc4Bypass%u",$label)if ($pByp);
+    &I(\$c, "}") if ($pAny);
+    &STOP(\$c);
+
+    &P(\$c, ".rc4Resume%u:", $label)			      if ($pByp);
+    if ($byte_num == 0 && $iteration >= $phases) {
+	&I(\$c, "st8 [OutPtr] = OutWord[%u], 8",
+	   $iw1 % $NOutWord)				      if ($p & $pOut);
+	if ($iteration == (1 + $unroll_count) * $phases - 1) {
+	    if ($unroll_count == 6) {
+		&I(\$c, "mov OutWord[%u] = OutWord[%u]",
+		   $iw1 % $NOutWord, $iw0 % $NOutWord);
+	    }
+	    &I(\$c, "lfetch.nt1 [InPrefetch], %u",
+	       $unroll_count * $phases);
+	    &I(\$c, "lfetch.excl.nt1 [OutPrefetch], %u",
+	       $unroll_count * $phases);
+	    &I(\$c, "br.cloop.sptk.few .rc4Loop");
+	}
+    }
+
+    if ($pByp) {
+	&P(\$bypass, ".rc4Bypass%u:", $label);
+	&I(\$bypass, "sub J = J, SI[%u]", $i0 % $NSI);
+	&I(\$bypass, "nop 0");
+	&I(\$bypass, "nop 0");
+	&I(\$bypass, ";;");
+	&I(\$bypass, "add J = J, SI[%u]", $i1 % $NSI);
+	&I(\$bypass, "mov SI[%u] = SI[%u]", $i0 % $NSI, $i1 % $NSI);
+	&I(\$bypass, "br.sptk.many .rc4Resume%u\n", $label);
+	&I(\$bypass, ";;");
+    }
+}
+
+$code=<<___;
+.ident \"rc4-ia64.s, version 3.0\"
+.ident \"Copyright (c) 2005 Hewlett-Packard Development Company, L.P.\"
+
+#define LCSave		r8
+#define PRSave		r9
+
+/* Inputs become invalid once rotation begins!  */
+
+#define StateTable	in0
+#define DataLen		in1
+#define InputBuffer	in2
+#define OutputBuffer	in3
+
+#define KTable		r14
+#define J		r15
+#define InPtr		r16
+#define OutPtr		r17
+#define InPrefetch	r18
+#define OutPrefetch	r19
+#define One		r20
+#define LoopCount	r21
+#define Remainder	r22
+#define IFinal		r23
+#define EndPtr		r24
+
+#define tmp0		r25
+#define tmp1		r26
+
+#define pBypass		p6
+#define pDone		p7
+#define pSmall		p8
+#define pAligned	p9
+#define pUnaligned	p10
+
+#define pComputeI	pPhase[0]
+#define pComputeJ	pPhase[1]
+#define pComputeT	pPhase[2]
+#define pOutput		pPhase[3]
+
+#define RetVal		r8
+#define L_OK		p7
+#define L_NOK		p8
+
+#define	_NINPUTS	4
+#define	_NOUTPUT	0
+
+#define	_NROTATE	24
+#define	_NLOCALS	(_NROTATE - _NINPUTS - _NOUTPUT)
+
+#ifndef SZ
+# define SZ	4	// this must be set to sizeof(RC4_INT)
+#endif
+
+#if SZ == 1
+# define LKEY			ld1
+# define SKEY			st1
+# define KEYADDR(dst, i)	add dst = i, KTable
+#elif SZ == 2
+# define LKEY			ld2
+# define SKEY			st2
+# define KEYADDR(dst, i)	shladd dst = i, 1, KTable
+#elif SZ == 4
+# define LKEY			ld4
+# define SKEY			st4
+# define KEYADDR(dst, i)	shladd dst = i, 2, KTable
+#else
+# define LKEY			ld8
+# define SKEY			st8
+# define KEYADDR(dst, i)	shladd dst = i, 3, KTable
+#endif
+
+#if defined(_HPUX_SOURCE) && !defined(_LP64)
+# define ADDP	addp4
+#else
+# define ADDP	add
+#endif
+
+/* Define a macro for the bit number of the n-th byte: */
+
+#if defined(_HPUX_SOURCE) || defined(B_ENDIAN)
+# define HOST_IS_BIG_ENDIAN
+# define BYTE_POS(n)	(56 - (8 * (n)))
+#else
+# define BYTE_POS(n)	(8 * (n))
+#endif
+
+/*
+   We must perform the first phase of the pipeline explicitly since
+   we will always load from the stable the first time. The br.cexit
+   will never be taken since regardless of the number of bytes because
+   the epilogue count is 4.
+*/
+/* MODSCHED_RC4 macro was split to _PROLOGUE and _LOOP, because HP-UX
+   assembler failed on original macro with syntax error. <appro> */
+#define MODSCHED_RC4_PROLOGUE						   \\
+	{								   \\
+				ld1		Data[0] = [InPtr], 1;	   \\
+				add		IFinal = 1, I[1];	   \\
+				KEYADDR(IPr[0], I[1]);			   \\
+	} ;;								   \\
+	{								   \\
+				LKEY		SI[0] = [IPr[0]];	   \\
+				mov		pr.rot = 0x10000;	   \\
+				mov		ar.ec = 4;		   \\
+	} ;;								   \\
+	{								   \\
+				add		J = J, SI[0];		   \\
+				zxt1		I[0] = IFinal;		   \\
+				br.cexit.spnt.few .+16; /* never taken */  \\
+	} ;;
+#define MODSCHED_RC4_LOOP(label)					   \\
+label:									   \\
+	{	.mmi;							   \\
+		(pComputeI)	ld1		Data[0] = [InPtr], 1;	   \\
+		(pComputeI)	add		IFinal = 1, I[1];	   \\
+		(pComputeJ)	zxt1		J = J;			   \\
+	}{	.mmi;							   \\
+		(pOutput)	LKEY		T[1] = [T[1]];		   \\
+		(pComputeT)	add		T[0] = SI[2], SJ[1];	   \\
+		(pComputeI)	KEYADDR(IPr[0], I[1]);			   \\
+	} ;;								   \\
+	{	.mmi;							   \\
+		(pComputeT)	SKEY		[IPr[2]] = SJ[1];	   \\
+		(pComputeT)	SKEY		[JP[1]] = SI[2];	   \\
+		(pComputeT)	zxt1		T[0] = T[0];		   \\
+	}{	.mmi;							   \\
+		(pComputeI)	LKEY		SI[0] = [IPr[0]];	   \\
+		(pComputeJ)	KEYADDR(JP[0], J);			   \\
+		(pComputeI)	cmp.eq.unc	pBypass, p0 = I[1], J;	   \\
+	} ;;								   \\
+	{	.mmi;							   \\
+		(pComputeJ)	LKEY		SJ[0] = [JP[0]];	   \\
+		(pOutput)	xor		Data[3] = Data[3], T[1];   \\
+				nop		0x0;			   \\
+	}{	.mmi;							   \\
+		(pComputeT)	KEYADDR(T[0], T[0]);			   \\
+		(pBypass)	mov		SI[0] = SI[1];		   \\
+		(pComputeI)	zxt1		I[0] = IFinal;		   \\
+	} ;;								   \\
+	{	.mmb;							   \\
+		(pOutput)	st1		[OutPtr] = Data[3], 1;	   \\
+		(pComputeI)	add		J = J, SI[0];		   \\
+				br.ctop.sptk.few label;			   \\
+	} ;;
+
+	.text
+
+	.align	32
+
+	.type	RC4, \@function
+	.global	RC4
+
+	.proc	RC4
+	.prologue
+
+RC4:
+	{
+	  	.mmi
+		alloc	r2 = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE
+
+		.rotr Data[4], I[2], IPr[3], SI[3], JP[2], SJ[2], T[2], \\
+		      OutWord[2]
+		.rotp pPhase[4]
+
+		ADDP		InPrefetch = 0, InputBuffer
+		ADDP		KTable = 0, StateTable
+	}
+	{
+		.mmi
+		ADDP		InPtr = 0, InputBuffer
+		ADDP		OutPtr = 0, OutputBuffer
+		mov		RetVal = r0
+	}
+	;;
+	{
+		.mmi
+		lfetch.nt1	[InPrefetch], 0x80
+		ADDP		OutPrefetch = 0, OutputBuffer
+	}
+	{               // Return 0 if the input length is nonsensical
+        	.mib
+		ADDP		StateTable = 0, StateTable
+        	cmp.ge.unc  	L_NOK, L_OK = r0, DataLen
+	(L_NOK) br.ret.sptk.few rp
+	}
+	;;
+	{
+        	.mib
+        	cmp.eq.or  	L_NOK, L_OK = r0, InPtr
+        	cmp.eq.or  	L_NOK, L_OK = r0, OutPtr
+		nop		0x0
+	}
+	{
+		.mib
+        	cmp.eq.or  	L_NOK, L_OK = r0, StateTable
+		nop		0x0
+	(L_NOK) br.ret.sptk.few rp
+	}
+	;;
+		LKEY		I[1] = [KTable], SZ
+/* Prefetch the state-table. It contains 256 elements of size SZ */
+
+#if SZ == 1
+		ADDP		tmp0 = 1*128, StateTable
+#elif SZ == 2
+		ADDP		tmp0 = 3*128, StateTable
+		ADDP		tmp1 = 2*128, StateTable
+#elif SZ == 4
+		ADDP		tmp0 = 7*128, StateTable
+		ADDP		tmp1 = 6*128, StateTable
+#elif SZ == 8
+		ADDP		tmp0 = 15*128, StateTable
+		ADDP		tmp1 = 14*128, StateTable
+#endif
+		;;
+#if SZ >= 8
+		lfetch.fault.nt1		[tmp0], -256	// 15
+		lfetch.fault.nt1		[tmp1], -256;;
+		lfetch.fault.nt1		[tmp0], -256	// 13
+		lfetch.fault.nt1		[tmp1], -256;;
+		lfetch.fault.nt1		[tmp0], -256	// 11
+		lfetch.fault.nt1		[tmp1], -256;;
+		lfetch.fault.nt1		[tmp0], -256	//  9
+		lfetch.fault.nt1		[tmp1], -256;;
+#endif
+#if SZ >= 4
+		lfetch.fault.nt1		[tmp0], -256	//  7
+		lfetch.fault.nt1		[tmp1], -256;;
+		lfetch.fault.nt1		[tmp0], -256	//  5
+		lfetch.fault.nt1		[tmp1], -256;;
+#endif
+#if SZ >= 2
+		lfetch.fault.nt1		[tmp0], -256	//  3
+		lfetch.fault.nt1		[tmp1], -256;;
+#endif
+	{
+		.mii
+		lfetch.fault.nt1		[tmp0]		//  1
+		add		I[1]=1,I[1];;
+		zxt1		I[1]=I[1]
+	}
+	{
+		.mmi
+		lfetch.nt1	[InPrefetch], 0x80
+		lfetch.excl.nt1	[OutPrefetch], 0x80
+		.save		pr, PRSave
+		mov		PRSave = pr
+	} ;;
+	{
+		.mmi
+		lfetch.excl.nt1	[OutPrefetch], 0x80
+		LKEY		J = [KTable], SZ
+		ADDP		EndPtr = DataLen, InPtr
+	}  ;;
+	{
+		.mmi
+		ADDP		EndPtr = -1, EndPtr	// Make it point to
+							// last data byte.
+		mov		One = 1
+		.save		ar.lc, LCSave
+		mov		LCSave = ar.lc
+		.body
+	} ;;
+	{
+		.mmb
+		sub		Remainder = 0, OutPtr
+		cmp.gtu		pSmall, p0 = $threshold, DataLen
+(pSmall)	br.cond.dpnt	.rc4Remainder		// Data too small for
+							// big loop.
+	} ;;
+	{
+		.mmi
+		and		Remainder = 0x7, Remainder
+		;;
+		cmp.eq		pAligned, pUnaligned = Remainder, r0
+		nop		0x0
+	} ;;
+	{
+		.mmb
+.pred.rel	"mutex",pUnaligned,pAligned
+(pUnaligned)	add		Remainder = -1, Remainder
+(pAligned)	sub		Remainder = EndPtr, InPtr
+(pAligned)	br.cond.dptk.many .rc4Aligned
+	} ;;
+	{
+		.mmi
+		nop		0x0
+		nop		0x0
+		mov.i		ar.lc = Remainder
+	}
+
+/* Do the initial few bytes via the compact, modulo-scheduled loop
+   until the output pointer is 8-byte-aligned.  */
+
+		MODSCHED_RC4_PROLOGUE
+		MODSCHED_RC4_LOOP(.RC4AlignLoop)
+
+	{
+		.mib
+		sub		Remainder = EndPtr, InPtr
+		zxt1		IFinal = IFinal
+		clrrrb				// Clear CFM.rrb.pr so
+		;;				// next "mov pr.rot = N"
+						// does the right thing.
+	}
+	{
+		.mmi
+		mov		I[1] = IFinal
+		nop		0x0
+		nop		0x0
+	} ;;
+
+
+.rc4Aligned:
+
+/*
+   Unrolled loop count = (Remainder - ($unroll_count+1)*$phases)/($unroll_count*$phases)
+ */
+
+	{
+		.mlx
+		add	LoopCount = 1 - ($unroll_count + 1)*$phases, Remainder
+		movl		Remainder = 0xaaaaaaaaaaaaaaab
+	} ;;
+	{
+		.mmi
+		setf.sig	f6 = LoopCount		// M2, M3	6 cyc
+		setf.sig	f7 = Remainder		// M2, M3	6 cyc
+		nop		0x0
+	} ;;
+	{
+		.mfb
+		nop		0x0
+		xmpy.hu		f6 = f6, f7
+		nop		0x0
+	} ;;
+	{
+		.mmi
+		getf.sig	LoopCount = f6;;	// M2		5 cyc
+		nop		0x0
+		shr.u		LoopCount = LoopCount, 4
+	} ;;
+	{
+		.mmi
+		nop		0x0
+		nop		0x0
+		mov.i		ar.lc = LoopCount
+	} ;;
+
+/* Now comes the unrolled loop: */
+
+.rc4Prologue:
+___
+
+$iteration = 0;
+
+# Generate the prologue:
+$predicates = 1;
+for ($i = 0; $i < $phases; ++$i) {
+    &emit_body (\$code, \$bypass, $iteration++, $predicates);
+    $predicates = ($predicates << 1) | 1;
+}
+
+$code.=<<___;
+.rc4Loop:
+___
+
+# Generate the body:
+for ($i = 0; $i < $unroll_count*$phases; ++$i) {
+    &emit_body (\$code, \$bypass, $iteration++, $predicates);
+}
+
+$code.=<<___;
+.rc4Epilogue:
+___
+
+# Generate the epilogue:
+for ($i = 0; $i < $phases; ++$i) {
+    $predicates <<= 1;
+    &emit_body (\$code, \$bypass, $iteration++, $predicates);
+}
+
+$code.=<<___;
+	{
+		.mmi
+		lfetch.nt1	[EndPtr]	// fetch line with last byte
+		mov		IFinal = I[1]
+		nop		0x0
+	}
+
+.rc4Remainder:
+	{
+		.mmi
+		sub		Remainder = EndPtr, InPtr	// Calculate
+								// # of bytes
+								// left - 1
+		nop		0x0
+		nop		0x0
+	} ;;
+	{
+		.mib
+		cmp.eq		pDone, p0 = -1, Remainder // done already?
+		mov.i		ar.lc = Remainder
+(pDone)		br.cond.dptk.few .rc4Complete
+	}
+
+/* Do the remaining bytes via the compact, modulo-scheduled loop */
+
+		MODSCHED_RC4_PROLOGUE
+		MODSCHED_RC4_LOOP(.RC4RestLoop)
+
+.rc4Complete:
+	{
+		.mmi
+		add		KTable = -SZ, KTable
+		add		IFinal = -1, IFinal
+		mov		ar.lc = LCSave
+	} ;;
+	{
+		.mii
+		SKEY		[KTable] = J,-SZ
+		zxt1		IFinal = IFinal
+		mov		pr = PRSave, 0x1FFFF
+	} ;;
+	{
+		.mib
+		SKEY		[KTable] = IFinal
+		add		RetVal = 1, r0
+		br.ret.sptk.few	rp
+	} ;;
+___
+
+# Last but not least, emit the code for the bypass-code of the unrolled loop:
+
+$code.=$bypass;
+
+$code.=<<___;
+	.endp RC4
+___
+
+print $code;
diff --git a/crypto/rc4/asm/rc4-s390x.pl b/crypto/rc4/asm/rc4-s390x.pl
new file mode 100644
index 0000000..96681fa
--- /dev/null
+++ b/crypto/rc4/asm/rc4-s390x.pl
@@ -0,0 +1,205 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# February 2009
+#
+# Performance is 2x of gcc 3.4.6 on z10. Coding "secret" is to
+# "cluster" Address Generation Interlocks, so that one pipeline stall
+# resolves several dependencies.
+
+$rp="%r14";
+$sp="%r15";
+$code=<<___;
+.text
+
+___
+
+# void RC4(RC4_KEY *key,size_t len,const void *inp,void *out)
+{
+$acc="%r0";
+$cnt="%r1";
+$key="%r2";
+$len="%r3";
+$inp="%r4";
+$out="%r5";
+
+@XX=("%r6","%r7");
+@TX=("%r8","%r9");
+$YY="%r10";
+$TY="%r11";
+
+$code.=<<___;
+.globl	RC4
+.type	RC4,\@function
+.align	64
+RC4:
+	stmg	%r6,%r11,48($sp)
+	llgc	$XX[0],0($key)
+	llgc	$YY,1($key)
+	la	$XX[0],1($XX[0])
+	nill	$XX[0],0xff
+	srlg	$cnt,$len,3
+	ltgr	$cnt,$cnt
+	llgc	$TX[0],2($XX[0],$key)
+	jz	.Lshort
+	j	.Loop8
+
+.align	64
+.Loop8:
+___
+for ($i=0;$i<8;$i++) {
+$code.=<<___;
+	la	$YY,0($YY,$TX[0])	# $i
+	nill	$YY,255
+	la	$XX[1],1($XX[0])
+	nill	$XX[1],255
+___
+$code.=<<___ if ($i==1);
+	llgc	$acc,2($TY,$key)
+___
+$code.=<<___ if ($i>1);
+	sllg	$acc,$acc,8
+	ic	$acc,2($TY,$key)
+___
+$code.=<<___;
+	llgc	$TY,2($YY,$key)
+	stc	$TX[0],2($YY,$key)
+	llgc	$TX[1],2($XX[1],$key)
+	stc	$TY,2($XX[0],$key)
+	cr	$XX[1],$YY
+	jne	.Lcmov$i
+	la	$TX[1],0($TX[0])
+.Lcmov$i:
+	la	$TY,0($TY,$TX[0])
+	nill	$TY,255
+___
+push(@TX,shift(@TX)); push(@XX,shift(@XX));     # "rotate" registers
+}
+
+$code.=<<___;
+	lg	$TX[1],0($inp)
+	sllg	$acc,$acc,8
+	la	$inp,8($inp)
+	ic	$acc,2($TY,$key)
+	xgr	$acc,$TX[1]
+	stg	$acc,0($out)
+	la	$out,8($out)
+	brct	$cnt,.Loop8
+
+.Lshort:
+	lghi	$acc,7
+	ngr	$len,$acc
+	jz	.Lexit
+	j	.Loop1
+
+.align	16
+.Loop1:
+	la	$YY,0($YY,$TX[0])
+	nill	$YY,255
+	llgc	$TY,2($YY,$key)
+	stc	$TX[0],2($YY,$key)
+	stc	$TY,2($XX[0],$key)
+	ar	$TY,$TX[0]
+	ahi	$XX[0],1
+	nill	$TY,255
+	nill	$XX[0],255
+	llgc	$acc,0($inp)
+	la	$inp,1($inp)
+	llgc	$TY,2($TY,$key)
+	llgc	$TX[0],2($XX[0],$key)
+	xr	$acc,$TY
+	stc	$acc,0($out)
+	la	$out,1($out)
+	brct	$len,.Loop1
+
+.Lexit:
+	ahi	$XX[0],-1
+	stc	$XX[0],0($key)
+	stc	$YY,1($key)
+	lmg	%r6,%r11,48($sp)
+	br	$rp
+.size	RC4,.-RC4
+.string	"RC4 for s390x, CRYPTOGAMS by <appro\@openssl.org>"
+
+___
+}
+
+# void RC4_set_key(RC4_KEY *key,unsigned int len,const void *inp)
+{
+$cnt="%r0";
+$idx="%r1";
+$key="%r2";
+$len="%r3";
+$inp="%r4";
+$acc="%r5";
+$dat="%r6";
+$ikey="%r7";
+$iinp="%r8";
+
+$code.=<<___;
+.globl	RC4_set_key
+.type	RC4_set_key,\@function
+.align	64
+RC4_set_key:
+	stmg	%r6,%r8,48($sp)
+	lhi	$cnt,256
+	la	$idx,0(%r0)
+	sth	$idx,0($key)
+.align	4
+.L1stloop:
+	stc	$idx,2($idx,$key)
+	la	$idx,1($idx)
+	brct	$cnt,.L1stloop
+
+	lghi	$ikey,-256
+	lr	$cnt,$len
+	la	$iinp,0(%r0)
+	la	$idx,0(%r0)
+.align	16
+.L2ndloop:
+	llgc	$acc,2+256($ikey,$key)
+	llgc	$dat,0($iinp,$inp)
+	la	$idx,0($idx,$acc)
+	la	$ikey,1($ikey)
+	la	$idx,0($idx,$dat)
+	nill	$idx,255
+	la	$iinp,1($iinp)
+	tml	$ikey,255
+	llgc	$dat,2($idx,$key)
+	stc	$dat,2+256-1($ikey,$key)
+	stc	$acc,2($idx,$key)
+	jz	.Ldone
+	brct	$cnt,.L2ndloop
+	lr	$cnt,$len
+	la	$iinp,0(%r0)
+	j	.L2ndloop
+.Ldone:
+	lmg	%r6,%r8,48($sp)
+	br	$rp
+.size	RC4_set_key,.-RC4_set_key
+
+___
+}
+
+# const char *RC4_options()
+$code.=<<___;
+.globl	RC4_options
+.type	RC4_options,\@function
+.align	16
+RC4_options:
+	larl	%r2,.Loptions
+	br	%r14
+.size	RC4_options,.-RC4_options
+.section	.rodata
+.Loptions:
+.align	8
+.string	"rc4(8x,char)"
+___
+
+print $code;
diff --git a/crypto/rc4/asm/rc4-x86_64.pl b/crypto/rc4/asm/rc4-x86_64.pl
index 00c6fa2..677be5f 100755
--- a/crypto/rc4/asm/rc4-x86_64.pl
+++ b/crypto/rc4/asm/rc4-x86_64.pl
@@ -58,14 +58,18 @@
 # fit for Core2 and therefore the code was modified to skip cloop8 on
 # this CPU.
 
-$output=shift;
+$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 $output";
+open STDOUT,"| $^X $xlate $flavour $output";
 
 $dat="%rdi";	    # arg1
 $len="%rsi";	    # arg2
@@ -87,8 +91,10 @@
 	jne	.Lentry
 	ret
 .Lentry:
+	push	%rbx
 	push	%r12
 	push	%r13
+.Lprologue:
 
 	add	\$8,$dat
 	movl	-8($dat),$XX[0]#d
@@ -133,16 +139,8 @@
 	jnz	.Lloop8
 	cmp	\$0,$len
 	jne	.Lloop1
-___
-$code.=<<___;
-.Lexit:
-	sub	\$1,$XX[0]#b
-	movl	$XX[0]#d,-8($dat)
-	movl	$YY#d,-4($dat)
+	jmp	.Lexit
 
-	pop	%r13
-	pop	%r12
-	ret
 .align	16
 .Lloop1:
 	add	$TX[0]#b,$YY#b
@@ -167,9 +165,8 @@
 	movzb	($dat,$XX[0]),$TX[0]#d
 	test	\$-8,$len
 	jz	.Lcloop1
-	cmp	\$0,260($dat)
+	cmpl	\$0,260($dat)
 	jnz	.Lcloop1
-	push	%rbx
 	jmp	.Lcloop8
 .align	16
 .Lcloop8:
@@ -224,7 +221,6 @@
 
 	test	\$-8,$len
 	jnz	.Lcloop8
-	pop	%rbx
 	cmp	\$0,$len
 	jne	.Lcloop1
 	jmp	.Lexit
@@ -249,6 +245,19 @@
 	sub	\$1,$len
 	jnz	.Lcloop1
 	jmp	.Lexit
+
+.align	16
+.Lexit:
+	sub	\$1,$XX[0]#b
+	movl	$XX[0]#d,-8($dat)
+	movl	$YY#d,-4($dat)
+
+	mov	(%rsp),%r13
+	mov	8(%rsp),%r12
+	mov	16(%rsp),%rbx
+	add	\$24,%rsp
+.Lepilogue:
+	ret
 .size	RC4,.-RC4
 ___
 
@@ -333,11 +342,10 @@
 .size	RC4_set_key,.-RC4_set_key
 
 .globl	RC4_options
-.type	RC4_options,\@function,0
+.type	RC4_options,\@abi-omnipotent
 .align	16
 RC4_options:
-	.picmeup %rax
-	lea	.Lopts-.(%rax),%rax
+	lea	.Lopts(%rip),%rax
 	mov	OPENSSL_ia32cap_P(%rip),%edx
 	bt	\$20,%edx
 	jnc	.Ldone
@@ -357,9 +365,139 @@
 .size	RC4_options,.-RC4_options
 ___
 
-$code =~ s/#([bwd])/$1/gm;
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
 
-$code =~ s/RC4_set_key/private_RC4_set_key/g if ($ENV{FIPSCANLIB} ne "");
+$code.=<<___;
+.extern	__imp_RtlVirtualUnwind
+.type	stream_se_handler,\@abi-omnipotent
+.align	16
+stream_se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	lea	.Lprologue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<prologue label
+	jb	.Lin_prologue
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	lea	.Lepilogue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip>=epilogue label
+	jae	.Lin_prologue
+
+	lea	24(%rax),%rax
+
+	mov	-8(%rax),%rbx
+	mov	-16(%rax),%r12
+	mov	-24(%rax),%r13
+	mov	%rbx,144($context)	# restore context->Rbx
+	mov	%r12,216($context)	# restore context->R12
+	mov	%r13,224($context)	# restore context->R13
+
+.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	stream_se_handler,.-stream_se_handler
+
+.type	key_se_handler,\@abi-omnipotent
+.align	16
+key_se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%rsp
+
+	mov	152($context),%rax	# pull context->Rsp
+	mov	8(%rax),%rdi
+	mov	16(%rax),%rsi
+	mov	%rsi,168($context)	# restore context->Rsi
+	mov	%rdi,176($context)	# restore context->Rdi
+
+.Lcommon_seh_exit:
+
+	mov	40($disp),%rdi		# disp->ContextRecord
+	mov	$context,%rsi		# context
+	mov	\$154,%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
+	add	\$64,%rsp
+	popfq
+	pop	%r15
+	pop	%r14
+	pop	%r13
+	pop	%r12
+	pop	%rbp
+	pop	%rbx
+	pop	%rdi
+	pop	%rsi
+	ret
+.size	key_se_handler,.-key_se_handler
+
+.section	.pdata
+.align	4
+	.rva	.LSEH_begin_RC4
+	.rva	.LSEH_end_RC4
+	.rva	.LSEH_info_RC4
+
+	.rva	.LSEH_begin_RC4_set_key
+	.rva	.LSEH_end_RC4_set_key
+	.rva	.LSEH_info_RC4_set_key
+
+.section	.xdata
+.align	8
+.LSEH_info_RC4:
+	.byte	9,0,0,0
+	.rva	stream_se_handler
+.LSEH_info_RC4_set_key:
+	.byte	9,0,0,0
+	.rva	key_se_handler
+___
+}
+
+$code =~ s/#([bwd])/$1/gm;
 
 print $code;
 
diff --git a/crypto/rc4/rc4.h b/crypto/rc4/rc4.h
index 2d8620d..29d1acc 100644
--- a/crypto/rc4/rc4.h
+++ b/crypto/rc4/rc4.h
@@ -64,6 +64,8 @@
 #error RC4 is disabled.
 #endif
 
+#include <stddef.h>
+
 #ifdef  __cplusplus
 extern "C" {
 #endif
@@ -76,11 +78,8 @@
 
  
 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,
+void RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
 		unsigned char *outdata);
 
 #ifdef  __cplusplus
diff --git a/crypto/rc4/rc4_enc.c b/crypto/rc4/rc4_enc.c
index 0660ea6..8c4fc6c 100644
--- a/crypto/rc4/rc4_enc.c
+++ b/crypto/rc4/rc4_enc.c
@@ -67,12 +67,12 @@
  * Date: Wed, 14 Sep 1994 06:35:31 GMT
  */
 
-void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
+void RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
 	     unsigned char *outdata)
 	{
         register RC4_INT *d;
         register RC4_INT x,y,tx,ty;
-	int i;
+	size_t i;
         
         x=key->x;     
         y=key->y;     
@@ -120,8 +120,8 @@
 			(RC4_CHUNK)d[(tx+ty)&0xff]\
 			)
 
-	if ( ( ((unsigned long)indata  & (sizeof(RC4_CHUNK)-1)) | 
-	       ((unsigned long)outdata & (sizeof(RC4_CHUNK)-1)) ) == 0 )
+	if ( ( ((size_t)indata  & (sizeof(RC4_CHUNK)-1)) | 
+	       ((size_t)outdata & (sizeof(RC4_CHUNK)-1)) ) == 0 )
 		{
 		RC4_CHUNK ichunk,otp;
 		const union { long one; char little; } is_endian = {1};
@@ -157,7 +157,7 @@
 		if (!is_endian.little)
 			{	/* BIG-ENDIAN CASE */
 # define BESHFT(c)	(((sizeof(RC4_CHUNK)-(c)-1)*8)&(sizeof(RC4_CHUNK)*8-1))
-			for (;len&~(sizeof(RC4_CHUNK)-1);len-=sizeof(RC4_CHUNK))
+			for (;len&(0-sizeof(RC4_CHUNK));len-=sizeof(RC4_CHUNK))
 				{
 				ichunk  = *(RC4_CHUNK *)indata;
 				otp  = RC4_STEP<<BESHFT(0);
@@ -210,7 +210,7 @@
 		else
 			{	/* LITTLE-ENDIAN CASE */
 # define LESHFT(c)	(((c)*8)&(sizeof(RC4_CHUNK)*8-1))
-			for (;len&~(sizeof(RC4_CHUNK)-1);len-=sizeof(RC4_CHUNK))
+			for (;len&(0-sizeof(RC4_CHUNK));len-=sizeof(RC4_CHUNK))
 				{
 				ichunk  = *(RC4_CHUNK *)indata;
 				otp  = RC4_STEP;
@@ -276,7 +276,7 @@
 #define RC4_LOOP(a,b,i)	LOOP(a[i],b[i])
 #endif
 
-	i=(int)(len>>3L);
+	i=len>>3;
 	if (i)
 		{
 		for (;;)
@@ -296,7 +296,7 @@
 			if (--i == 0) break;
 			}
 		}
-	i=(int)len&0x07;
+	i=len&0x07;
 	if (i)
 		{
 		for (;;)
diff --git a/crypto/rc4/rc4_skey.c b/crypto/rc4/rc4_skey.c
index 4478d1a..b22c40b 100644
--- a/crypto/rc4/rc4_skey.c
+++ b/crypto/rc4/rc4_skey.c
@@ -59,11 +59,6 @@
 #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;
 
@@ -90,11 +85,7 @@
  * 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;
@@ -128,20 +119,14 @@
 		 * implementations suffer from significant performance
 		 * losses then, e.g. PIII exhibits >2x deterioration,
 		 * and so does Opteron. In order to assure optimal
-		 * all-round performance, we detect P4 at run-time by
-		 * checking upon reserved bit 20 in CPU capability
+		 * all-round performance, let us [try to] detect P4 at
+		 * run-time by checking upon HTT bit in CPU capability
 		 * vector and set up compressed key schedule, which is
 		 * recognized by correspondingly updated assembler
-		 * module... Bit 20 is set up by OPENSSL_ia32_cpuid.
-		 *
+		 * module...
 		 *				<appro@fy.chalmers.se>
 		 */
-#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/rc4/rc4test.c b/crypto/rc4/rc4test.c
index 54b597f..633a79e 100644
--- a/crypto/rc4/rc4test.c
+++ b/crypto/rc4/rc4test.c
@@ -114,8 +114,8 @@
 
 int main(int argc, char *argv[])
 	{
-	int err=0;
-	unsigned int i, j;
+	int i,err=0;
+	int j;
 	unsigned char *p;
 	RC4_KEY key;
 	unsigned char obuf[512];
@@ -129,12 +129,12 @@
 			{
 			printf("error calculating RC4\n");
 			printf("output:");
-			for (j=0; j<data_len[i]+1U; j++)
+			for (j=0; j<data_len[i]+1; j++)
 				printf(" %02x",obuf[j]);
 			printf("\n");
 			printf("expect:");
 			p= &(output[i][0]);
-			for (j=0; j<data_len[i]+1U; j++)
+			for (j=0; j<data_len[i]+1; j++)
 				printf(" %02x",*(p++));
 			printf("\n");
 			err++;
@@ -180,12 +180,12 @@
 			{
 			printf("error in RC4 multi-call processing\n");
 			printf("output:");
-			for (j=0; j<data_len[3]+1U; j++)
+			for (j=0; j<data_len[3]+1; j++)
 				printf(" %02x",obuf[j]);
 			printf("\n");
 			printf("expect:");
 			p= &(output[3][0]);
-			for (j=0; j<data_len[3]+1U; j++)
+			for (j=0; j<data_len[3]+1; j++)
 				printf(" %02x",*(p++));
 			err++;
 			}
@@ -216,11 +216,11 @@
 		if (memcmp(md,expected,sizeof(md))) {
 			printf("error in RC4 bulk test\n");
 			printf("output:");
-			for (j=0; j<sizeof(md); j++)
+			for (j=0; j<(int)sizeof(md); j++)
 				printf(" %02x",md[j]);
 			printf("\n");
 			printf("expect:");
-			for (j=0; j<sizeof(md); j++)
+			for (j=0; j<(int)sizeof(md); j++)
 				printf(" %02x",expected[j]);
 			printf("\n");
 			err++;
diff --git a/crypto/ripemd/Makefile b/crypto/ripemd/Makefile
deleted file mode 100644
index 6145f13..0000000
--- a/crypto/ripemd/Makefile
+++ /dev/null
@@ -1,104 +0,0 @@
-#
-# OpenSSL/crypto/ripemd/Makefile
-#
-
-DIR=    ripemd
-TOP=    ../..
-CC=     cc
-CPP=    $(CC) -E
-INCLUDES=
-CFLAG=-g
-MAKEFILE=       Makefile
-AR=             ar r
-
-RIP_ASM_OBJ=
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-ASFLAGS= $(INCLUDES) $(ASFLAG)
-AFLAGS= $(ASFLAGS)
-
-GENERAL=Makefile
-TEST=rmdtest.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=rmd_dgst.c rmd_one.c
-LIBOBJ=rmd_dgst.o rmd_one.o $(RMD160_ASM_OBJ)
-
-SRC= $(LIBSRC)
-
-EXHEADER= ripemd.h
-HEADER= rmd_locl.h rmdconst.h $(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:    lib
-
-lib:    $(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-# ELF
-rm86-elf.s: asm/rmd-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) rmd-586.pl elf $(CFLAGS) > ../$@)
-# COFF
-rm86-cof.s: asm/rmd-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) rmd-586.pl coff $(CFLAGS) > ../$@)
-# a.out
-rm86-out.s: asm/rmd-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) rmd-586.pl a.out $(CFLAGS) > ../$@)
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-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
-rmd_one.o: ../../include/openssl/ossl_typ.h ../../include/openssl/ripemd.h
-rmd_one.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-rmd_one.o: ../../include/openssl/symhacks.h rmd_one.c
diff --git a/crypto/ripemd/asm/rmd-586.pl b/crypto/ripemd/asm/rmd-586.pl
index 4f3c4c9..e8b2bc2 100644
--- a/crypto/ripemd/asm/rmd-586.pl
+++ b/crypto/ripemd/asm/rmd-586.pl
@@ -5,7 +5,8 @@
 
 $normal=0;
 
-push(@INC,"perlasm","../../perlasm");
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
 require "x86asm.pl";
 
 &asm_init($ARGV[0],$0);
diff --git a/crypto/ripemd/ripemd.h b/crypto/ripemd/ripemd.h
index 3b6d043..5942eb6 100644
--- a/crypto/ripemd/ripemd.h
+++ b/crypto/ripemd/ripemd.h
@@ -70,7 +70,7 @@
 #error RIPEMD is disabled.
 #endif
 
-#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#if defined(__LP32__)
 #define RIPEMD160_LONG unsigned long
 #elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
 #define RIPEMD160_LONG unsigned long
@@ -90,9 +90,7 @@
 	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 ead11d0..59b017f 100644
--- a/crypto/ripemd/rmd_dgst.c
+++ b/crypto/ripemd/rmd_dgst.c
@@ -59,11 +59,6 @@
 #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;
 
@@ -74,16 +69,14 @@
      void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p,size_t num);
 #  endif
 
-FIPS_NON_FIPS_MD_Init(RIPEMD160)
+int RIPEMD160_Init(RIPEMD160_CTX *c)
 	{
+	memset (c,0,sizeof(*c));
 	c->A=RIPEMD160_A;
 	c->B=RIPEMD160_B;
 	c->C=RIPEMD160_C;
 	c->D=RIPEMD160_D;
 	c->E=RIPEMD160_E;
-	c->Nl=0;
-	c->Nh=0;
-	c->num=0;
 	return 1;
 	}
 
diff --git a/crypto/ripemd/rmd_locl.h b/crypto/ripemd/rmd_locl.h
index ce12a80..f14b346 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_host_order ripemd160_block_asm_data_order
+#  define ripemd160_block_data_order ripemd160_block_asm_data_order
 # endif
 #endif
 
diff --git a/crypto/rsa/Makefile b/crypto/rsa/Makefile
deleted file mode 100644
index 7b1fd64..0000000
--- a/crypto/rsa/Makefile
+++ /dev/null
@@ -1,270 +0,0 @@
-#
-# OpenSSL/crypto/rsa/Makefile
-#
-
-DIR=	rsa
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=rsa_test.c
-APPS=
-
-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_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_x931g.o rsa_asn1.o rsa_depr.o rsa_eng.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= rsa.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-rsa_asn1.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_asn1.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-rsa_asn1.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-rsa_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-rsa_asn1.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-rsa_asn1.o: ../../include/openssl/opensslconf.h
-rsa_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_asn1.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-rsa_asn1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_asn1.o: ../cryptlib.h rsa_asn1.c
-rsa_chk.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-rsa_chk.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-rsa_chk.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_chk.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-rsa_chk.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_chk.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-rsa_chk.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_chk.o: rsa_chk.c
-rsa_depr.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_depr.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_depr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_depr.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_depr.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-rsa_depr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_depr.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-rsa_depr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_depr.o: ../cryptlib.h rsa_depr.c
-rsa_eay.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_eay.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_eay.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_eay.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_eay.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-rsa_eay.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-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
-rsa_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-rsa_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
-rsa_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-rsa_err.o: ../../include/openssl/symhacks.h rsa_err.c
-rsa_gen.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_gen.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_gen.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_gen.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_gen.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-rsa_gen.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_gen.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-rsa_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_gen.o: ../cryptlib.h rsa_gen.c
-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/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/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
-rsa_none.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_none.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-rsa_none.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_none.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
-rsa_none.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-rsa_none.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_none.c
-rsa_null.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_null.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_null.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_null.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-rsa_null.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_null.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
-rsa_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-rsa_null.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_null.c
-rsa_oaep.o: ../../e_os.h ../../include/openssl/asn1.h
-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/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
-rsa_oaep.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_oaep.o: ../cryptlib.h rsa_oaep.c
-rsa_pk1.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_pk1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_pk1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_pk1.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_pk1.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-rsa_pk1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_pk1.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
-rsa_pk1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-rsa_pk1.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_pk1.c
-rsa_pss.o: ../../e_os.h ../../include/openssl/asn1.h
-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/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/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
-rsa_saos.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_saos.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-rsa_saos.o: ../cryptlib.h rsa_saos.c
-rsa_sign.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_sign.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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
-rsa_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-rsa_sign.o: ../cryptlib.h rsa_sign.c
-rsa_ssl.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_ssl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_ssl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_ssl.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_ssl.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-rsa_ssl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_ssl.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
-rsa_ssl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-rsa_ssl.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_ssl.c
-rsa_x931.o: ../../e_os.h ../../include/openssl/asn1.h
-rsa_x931.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_x931.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_x931.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_x931.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-rsa_x931.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-rsa_x931.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-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 5bb932a..cf74343 100644
--- a/crypto/rsa/rsa.h
+++ b/crypto/rsa/rsa.h
@@ -74,25 +74,6 @@
 #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
@@ -136,7 +117,8 @@
 		unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
 	int (*rsa_verify)(int dtype,
 		const unsigned char *m, unsigned int m_length,
-		unsigned char *sigbuf, unsigned int siglen, const RSA *rsa);
+		const unsigned char *sigbuf, unsigned int siglen,
+								const RSA *rsa);
 /* If this callback is NULL, the builtin software RSA key-gen will be used. This
  * is for behavioural compatibility whilst the code gets rewired, but one day
  * it would be nice to assume there are no such things as "builtin software"
@@ -182,8 +164,6 @@
 # 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
@@ -238,11 +218,37 @@
 #endif
 
 
+#define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \
+				pad, NULL)
+
+#define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
+				(EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \
+				EVP_PKEY_CTRL_RSA_PSS_SALTLEN, \
+				len, NULL)
+
+#define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
+				EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL)
+
+#define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
+				EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp)
+
+#define EVP_PKEY_CTRL_RSA_PADDING	(EVP_PKEY_ALG_CTRL + 1)
+#define EVP_PKEY_CTRL_RSA_PSS_SALTLEN	(EVP_PKEY_ALG_CTRL + 2)
+
+#define EVP_PKEY_CTRL_RSA_KEYGEN_BITS	(EVP_PKEY_ALG_CTRL + 3)
+#define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP	(EVP_PKEY_ALG_CTRL + 4)
+
 #define RSA_PKCS1_PADDING	1
 #define RSA_SSLV23_PADDING	2
 #define RSA_NO_PADDING		3
 #define RSA_PKCS1_OAEP_PADDING	4
 #define RSA_X931_PADDING	5
+/* EVP_PKEY_ only */
+#define RSA_PKCS1_PSS_PADDING	6
 
 #define RSA_PKCS1_PADDING_SIZE	11
 
@@ -261,11 +267,6 @@
 
 /* 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 */
@@ -283,11 +284,6 @@
 
 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);
@@ -333,7 +329,7 @@
 int RSA_sign(int type, const unsigned char *m, unsigned int m_length,
 	unsigned char *sigret, unsigned int *siglen, RSA *rsa);
 int RSA_verify(int type, const unsigned char *m, unsigned int m_length,
-	unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
+	const unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
 
 /* The following 2 function sign and verify a ASN1_OCTET_STRING
  * object inside PKCS#1 padded RSA encryption */
@@ -401,9 +397,15 @@
 /* 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_CHECK_PADDING_MD				 140
+#define RSA_F_DO_RSA_PRINT				 146
+#define RSA_F_INT_RSA_VERIFY				 145
 #define RSA_F_MEMORY_LOCK				 100
+#define RSA_F_OLD_RSA_PRIV_DECODE			 147
+#define RSA_F_PKEY_RSA_CTRL				 143
+#define RSA_F_PKEY_RSA_CTRL_STR				 144
+#define RSA_F_PKEY_RSA_SIGN				 142
+#define RSA_F_PKEY_RSA_VERIFYRECOVER			 141
 #define RSA_F_RSA_BUILTIN_KEYGEN			 129
 #define RSA_F_RSA_CHECK_KEY				 123
 #define RSA_F_RSA_EAY_PRIVATE_DECRYPT			 101
@@ -434,11 +436,10 @@
 #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_PRIV_DECODE				 137
+#define RSA_F_RSA_PRIV_ENCODE				 138
+#define RSA_F_RSA_PUB_DECODE				 139
 #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
@@ -464,20 +465,25 @@
 #define RSA_R_DMQ1_NOT_CONGRUENT_TO_D			 125
 #define RSA_R_D_E_NOT_CONGRUENT_TO_1			 123
 #define RSA_R_FIRST_OCTET_INVALID			 133
+#define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE	 144
+#define RSA_R_INVALID_DIGEST_LENGTH			 143
 #define RSA_R_INVALID_HEADER				 137
+#define RSA_R_INVALID_KEYBITS				 145
 #define RSA_R_INVALID_MESSAGE_LENGTH			 131
 #define RSA_R_INVALID_PADDING				 138
+#define RSA_R_INVALID_PADDING_MODE			 141
+#define RSA_R_INVALID_PSS_SALTLEN			 146
 #define RSA_R_INVALID_TRAILER				 139
+#define RSA_R_INVALID_X931_DIGEST			 142
 #define RSA_R_IQMP_NOT_INVERSE_OF_Q			 126
 #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_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE	 148
 #define RSA_R_PADDING_CHECK_FAILED			 114
 #define RSA_R_P_NOT_PRIME				 128
 #define RSA_R_Q_NOT_PRIME				 129
@@ -488,6 +494,7 @@
 #define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116
 #define RSA_R_UNKNOWN_ALGORITHM_TYPE			 117
 #define RSA_R_UNKNOWN_PADDING_TYPE			 118
+#define RSA_R_VALUE_MISSING				 147
 #define RSA_R_WRONG_SIGNATURE_LENGTH			 119
 
 #ifdef  __cplusplus
diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c
new file mode 100644
index 0000000..8c32098
--- /dev/null
+++ b/crypto/rsa/rsa_ameth.c
@@ -0,0 +1,349 @@
+/* crypto/rsa/rsa_ameth.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rsa.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_CMS
+#include <openssl/cms.h>
+#endif
+#include "asn1_locl.h"
+
+static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
+	{
+	unsigned char *penc = NULL;
+	int penclen;
+	penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc);
+	if (penclen <= 0)
+		return 0;
+	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA),
+				V_ASN1_NULL, NULL, penc, penclen))
+		return 1;
+
+	OPENSSL_free(penc);
+	return 0;
+	}
+
+static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+	{
+	const unsigned char *p;
+	int pklen;
+	RSA *rsa = NULL;
+	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey))
+		return 0;
+	if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen)))
+		{
+		RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB);
+		return 0;
+		}
+	EVP_PKEY_assign_RSA (pkey, rsa);
+	return 1;
+	}
+
+static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+	{
+	if (BN_cmp(b->pkey.rsa->n,a->pkey.rsa->n) != 0
+		|| BN_cmp(b->pkey.rsa->e,a->pkey.rsa->e) != 0)
+			return 0;
+	return 1;
+	}
+
+static int old_rsa_priv_decode(EVP_PKEY *pkey,
+					const unsigned char **pder, int derlen)
+	{
+	RSA *rsa;
+	if (!(rsa = d2i_RSAPrivateKey (NULL, pder, derlen)))
+		{
+		RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB);
+		return 0;
+		}
+	EVP_PKEY_assign_RSA(pkey, rsa);
+	return 1;
+	}
+
+static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
+	{
+	return i2d_RSAPrivateKey(pkey->pkey.rsa, pder);
+	}
+
+static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+	{
+	unsigned char *rk = NULL;
+	int rklen;
+	rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk);
+
+	if (rklen <= 0)
+		{
+		RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+
+	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_rsaEncryption), 0,
+				V_ASN1_NULL, NULL, rk, rklen))
+		{
+		RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+
+	return 1;
+	}
+
+static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
+	{
+	const unsigned char *p;
+	int pklen;
+	if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8))
+		return 0;
+	return old_rsa_priv_decode(pkey, &p, pklen);
+	}
+
+static int int_rsa_size(const EVP_PKEY *pkey)
+	{
+	return RSA_size(pkey->pkey.rsa);
+	}
+
+static int rsa_bits(const EVP_PKEY *pkey)
+	{
+	return BN_num_bits(pkey->pkey.rsa->n);
+	}
+
+static void int_rsa_free(EVP_PKEY *pkey)
+	{
+	RSA_free(pkey->pkey.rsa);
+	}
+
+
+static void update_buflen(const BIGNUM *b, size_t *pbuflen)
+	{
+	size_t i;
+	if (!b)
+		return;
+	if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
+			*pbuflen = i;
+	}
+
+static int do_rsa_print(BIO *bp, const RSA *x, int off, int priv)
+	{
+	char *str;
+	const char *s;
+	unsigned char *m=NULL;
+	int ret=0, mod_len = 0;
+	size_t buf_len=0;
+
+	update_buflen(x->n, &buf_len);
+	update_buflen(x->e, &buf_len);
+
+	if (priv)
+		{
+		update_buflen(x->d, &buf_len);
+		update_buflen(x->p, &buf_len);
+		update_buflen(x->q, &buf_len);
+		update_buflen(x->dmp1, &buf_len);
+		update_buflen(x->dmq1, &buf_len);
+		update_buflen(x->iqmp, &buf_len);
+		}
+
+	m=(unsigned char *)OPENSSL_malloc(buf_len+10);
+	if (m == NULL)
+		{
+		RSAerr(RSA_F_DO_RSA_PRINT,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (x->n != NULL)
+		mod_len = BN_num_bits(x->n);
+
+	if(!BIO_indent(bp,off,128))
+		goto err;
+
+	if (priv && x->d)
+		{
+		if (BIO_printf(bp,"Private-Key: (%d bit)\n", mod_len)
+			<= 0) goto err;
+		str = "modulus:";
+		s = "publicExponent:";
+		}
+	else
+		{
+		if (BIO_printf(bp,"Public-Key: (%d bit)\n", mod_len)
+			<= 0) goto err;
+		str = "Modulus:";
+		s= "Exponent:";
+		}
+	if (!ASN1_bn_print(bp,str,x->n,m,off)) goto err;
+	if (!ASN1_bn_print(bp,s,x->e,m,off))
+		goto err;
+	if (priv)
+		{
+		if (!ASN1_bn_print(bp,"privateExponent:",x->d,m,off))
+			goto err;
+		if (!ASN1_bn_print(bp,"prime1:",x->p,m,off))
+			goto err;
+		if (!ASN1_bn_print(bp,"prime2:",x->q,m,off))
+			goto err;
+		if (!ASN1_bn_print(bp,"exponent1:",x->dmp1,m,off))
+			goto err;
+		if (!ASN1_bn_print(bp,"exponent2:",x->dmq1,m,off))
+			goto err;
+		if (!ASN1_bn_print(bp,"coefficient:",x->iqmp,m,off))
+			goto err;
+		}
+	ret=1;
+err:
+	if (m != NULL) OPENSSL_free(m);
+	return(ret);
+	}
+
+static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
+	}
+
+
+static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *ctx)
+	{
+	return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
+	}
+
+
+static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+	{
+	X509_ALGOR *alg = NULL;
+	switch (op)
+		{
+
+		case ASN1_PKEY_CTRL_PKCS7_SIGN:
+		if (arg1 == 0)
+			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg);
+		break;
+
+		case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
+		if (arg1 == 0)
+			PKCS7_RECIP_INFO_get0_alg(arg2, &alg);
+		break;
+#ifndef OPENSSL_NO_CMS
+		case ASN1_PKEY_CTRL_CMS_SIGN:
+		if (arg1 == 0)
+			CMS_SignerInfo_get0_algs(arg2, NULL, NULL, NULL, &alg);
+		break;
+
+		case ASN1_PKEY_CTRL_CMS_ENVELOPE:
+		if (arg1 == 0)
+			CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg);
+		break;
+#endif
+
+		case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+		*(int *)arg2 = NID_sha1;
+		return 1;
+
+		default:
+		return -2;
+
+		}
+
+	if (alg)
+		X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption),
+							V_ASN1_NULL, 0);
+
+	return 1;
+
+	}
+
+
+const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = 
+	{
+		{
+		EVP_PKEY_RSA,
+		EVP_PKEY_RSA,
+		ASN1_PKEY_SIGPARAM_NULL,
+
+		"RSA",
+		"OpenSSL RSA method",
+
+		rsa_pub_decode,
+		rsa_pub_encode,
+		rsa_pub_cmp,
+		rsa_pub_print,
+
+		rsa_priv_decode,
+		rsa_priv_encode,
+		rsa_priv_print,
+
+		int_rsa_size,
+		rsa_bits,
+
+		0,0,0,0,0,0,
+
+		int_rsa_free,
+		rsa_pkey_ctrl,
+		old_rsa_priv_decode,
+		old_rsa_priv_encode
+		},
+
+		{
+		EVP_PKEY_RSA2,
+		EVP_PKEY_RSA,
+		ASN1_PKEY_ALIAS
+		}
+	};
diff --git a/crypto/rsa/rsa_asn1.c b/crypto/rsa/rsa_asn1.c
index 6e8a803..4efca8c 100644
--- a/crypto/rsa/rsa_asn1.c
+++ b/crypto/rsa/rsa_asn1.c
@@ -3,7 +3,7 @@
  * project 2000.
  */
 /* ====================================================================
- * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 2000-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
@@ -62,19 +62,9 @@
 #include <openssl/rsa.h>
 #include <openssl/asn1t.h>
 
-static ASN1_METHOD method={
-        (I2D_OF(void))     i2d_RSAPrivateKey,
-        (D2I_OF(void))     d2i_RSAPrivateKey,
-        (void *(*)(void))  RSA_new,
-        (void (*)(void *)) RSA_free};
-
-ASN1_METHOD *RSAPrivateKey_asn1_meth(void)
-	{
-	return(&method);
-	}
-
 /* Override the default free and new methods */
-static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+								void *exarg)
 {
 	if(operation == ASN1_OP_NEW_PRE) {
 		*pval = (ASN1_VALUE *)RSA_new();
diff --git a/crypto/rsa/rsa_eay.c b/crypto/rsa/rsa_eay.c
index 0ac6418..c5eaeea 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>
 
-#if !defined(RSA_NULL) && !defined(OPENSSL_FIPS)
+#ifndef RSA_NULL
 
 static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
 		unsigned char *to, RSA *rsa,int padding);
@@ -256,6 +256,7 @@
 {
 	BN_BLINDING *ret;
 	int got_write_lock = 0;
+	CRYPTO_THREADID cur;
 
 	CRYPTO_r_lock(CRYPTO_LOCK_RSA);
 
@@ -273,7 +274,8 @@
 	if (ret == NULL)
 		goto err;
 
-	if (BN_BLINDING_get_thread_id(ret) == CRYPTO_thread_id())
+	CRYPTO_THREADID_current(&cur);
+	if (!CRYPTO_THREADID_cmp(&cur, BN_BLINDING_thread_id(ret)))
 		{
 		/* rsa->blinding is ours! */
 
diff --git a/crypto/rsa/rsa_eng.c b/crypto/rsa/rsa_eng.c
deleted file mode 100644
index 2f21ddb..0000000
--- a/crypto/rsa/rsa_eng.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/* crypto/rsa/rsa_lib.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#include <stdio.h>
-#include <openssl/crypto.h>
-#include "cryptlib.h"
-#include <openssl/lhash.h>
-#include <openssl/bn.h>
-#include <openssl/rsa.h>
-#include <openssl/rand.h>
-#ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
-#endif
-
-const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT;
-
-static const RSA_METHOD *default_RSA_meth=NULL;
-
-RSA *RSA_new(void)
-	{
-	RSA *r=RSA_new_method(NULL);
-
-	return r;
-	}
-
-void RSA_set_default_method(const RSA_METHOD *meth)
-	{
-#ifdef OPENSSL_FIPS
-	if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD))
-		{
-		RSAerr(RSA_F_RSA_SET_DEFAULT_METHOD, RSA_R_NON_FIPS_METHOD);
-		return;
-		}
-#endif
-	default_RSA_meth = meth;
-	}
-
-const RSA_METHOD *RSA_get_default_method(void)
-	{
-	if (default_RSA_meth == NULL)
-		{
-#ifdef RSA_NULL
-		default_RSA_meth=RSA_null_method();
-#else
-#if 0 /* was: #ifdef RSAref */
-		default_RSA_meth=RSA_PKCS1_RSAref();
-#else
-		default_RSA_meth=RSA_PKCS1_SSLeay();
-#endif
-#endif
-		}
-
-	return default_RSA_meth;
-	}
-
-const RSA_METHOD *RSA_get_method(const RSA *rsa)
-	{
-	return rsa->meth;
-	}
-
-int RSA_set_method(RSA *rsa, const RSA_METHOD *meth)
-	{
-	/* NB: The caller is specifically setting a method, so it's not up to us
-	 * to deal with which ENGINE it comes from. */
-	const RSA_METHOD *mtmp;
-#ifdef OPENSSL_FIPS
-	if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD))
-		{
-		RSAerr(RSA_F_RSA_SET_METHOD, RSA_R_NON_FIPS_METHOD);
-		return 0;
-		}
-#endif
-	mtmp = rsa->meth;
-	if (mtmp->finish) mtmp->finish(rsa);
-#ifndef OPENSSL_NO_ENGINE
-	if (rsa->engine)
-		{
-		ENGINE_finish(rsa->engine);
-		rsa->engine = NULL;
-		}
-#endif
-	rsa->meth = meth;
-	if (meth->init) meth->init(rsa);
-	return 1;
-	}
-
-RSA *RSA_new_method(ENGINE *engine)
-	{
-	RSA *ret;
-
-	ret=(RSA *)OPENSSL_malloc(sizeof(RSA));
-	if (ret == NULL)
-		{
-		RSAerr(RSA_F_RSA_NEW_METHOD,ERR_R_MALLOC_FAILURE);
-		return NULL;
-		}
-
-	ret->meth = RSA_get_default_method();
-#ifndef OPENSSL_NO_ENGINE
-	if (engine)
-		{
-		if (!ENGINE_init(engine))
-			{
-			RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB);
-			OPENSSL_free(ret);
-			return NULL;
-			}
-		ret->engine = engine;
-		}
-	else
-		ret->engine = ENGINE_get_default_RSA();
-	if(ret->engine)
-		{
-		ret->meth = ENGINE_get_RSA(ret->engine);
-		if(!ret->meth)
-			{
-			RSAerr(RSA_F_RSA_NEW_METHOD,
-				ERR_R_ENGINE_LIB);
-			ENGINE_finish(ret->engine);
-			OPENSSL_free(ret);
-			return NULL;
-			}
-		}
-#endif
-#ifdef OPENSSL_FIPS
-	if (FIPS_mode() && !(ret->meth->flags & RSA_FLAG_FIPS_METHOD))
-		{
-		RSAerr(RSA_F_RSA_NEW_METHOD, RSA_R_NON_FIPS_METHOD);
-#ifndef OPENSSL_NO_ENGINE
-		if (ret->engine)
-			ENGINE_finish(ret->engine);
-#endif
-		OPENSSL_free(ret);
-		return NULL;
-		}
-#endif
-
-	ret->pad=0;
-	ret->version=0;
-	ret->n=NULL;
-	ret->e=NULL;
-	ret->d=NULL;
-	ret->p=NULL;
-	ret->q=NULL;
-	ret->dmp1=NULL;
-	ret->dmq1=NULL;
-	ret->iqmp=NULL;
-	ret->references=1;
-	ret->_method_mod_n=NULL;
-	ret->_method_mod_p=NULL;
-	ret->_method_mod_q=NULL;
-	ret->blinding=NULL;
-	ret->mt_blinding=NULL;
-	ret->bignum_data=NULL;
-	ret->flags=ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW;
-	if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data))
-		{
-#ifndef OPENSSL_NO_ENGINE
-	if (ret->engine)
-		ENGINE_finish(ret->engine);
-#endif
-		OPENSSL_free(ret);
-		return(NULL);
-		}
-
-	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 501f5ea..cf9f110 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-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
@@ -70,9 +70,15 @@
 
 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_CHECK_PADDING_MD),	"CHECK_PADDING_MD"},
+{ERR_FUNC(RSA_F_DO_RSA_PRINT),	"DO_RSA_PRINT"},
+{ERR_FUNC(RSA_F_INT_RSA_VERIFY),	"INT_RSA_VERIFY"},
 {ERR_FUNC(RSA_F_MEMORY_LOCK),	"MEMORY_LOCK"},
+{ERR_FUNC(RSA_F_OLD_RSA_PRIV_DECODE),	"OLD_RSA_PRIV_DECODE"},
+{ERR_FUNC(RSA_F_PKEY_RSA_CTRL),	"PKEY_RSA_CTRL"},
+{ERR_FUNC(RSA_F_PKEY_RSA_CTRL_STR),	"PKEY_RSA_CTRL_STR"},
+{ERR_FUNC(RSA_F_PKEY_RSA_SIGN),	"PKEY_RSA_SIGN"},
+{ERR_FUNC(RSA_F_PKEY_RSA_VERIFYRECOVER),	"PKEY_RSA_VERIFYRECOVER"},
 {ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN),	"RSA_BUILTIN_KEYGEN"},
 {ERR_FUNC(RSA_F_RSA_CHECK_KEY),	"RSA_check_key"},
 {ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_DECRYPT),	"RSA_EAY_PRIVATE_DECRYPT"},
@@ -103,11 +109,10 @@
 {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_PRIV_DECODE),	"RSA_PRIV_DECODE"},
+{ERR_FUNC(RSA_F_RSA_PRIV_ENCODE),	"RSA_PRIV_ENCODE"},
+{ERR_FUNC(RSA_F_RSA_PUB_DECODE),	"RSA_PUB_DECODE"},
 {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"},
@@ -136,20 +141,25 @@
 {ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D),"dmq1 not congruent to d"},
 {ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1),"d e not congruent to 1"},
 {ERR_REASON(RSA_R_FIRST_OCTET_INVALID)   ,"first octet invalid"},
+{ERR_REASON(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE),"illegal or unsupported padding mode"},
+{ERR_REASON(RSA_R_INVALID_DIGEST_LENGTH) ,"invalid digest length"},
 {ERR_REASON(RSA_R_INVALID_HEADER)        ,"invalid header"},
+{ERR_REASON(RSA_R_INVALID_KEYBITS)       ,"invalid keybits"},
 {ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH),"invalid message length"},
 {ERR_REASON(RSA_R_INVALID_PADDING)       ,"invalid padding"},
+{ERR_REASON(RSA_R_INVALID_PADDING_MODE)  ,"invalid padding mode"},
+{ERR_REASON(RSA_R_INVALID_PSS_SALTLEN)   ,"invalid pss saltlen"},
 {ERR_REASON(RSA_R_INVALID_TRAILER)       ,"invalid trailer"},
+{ERR_REASON(RSA_R_INVALID_X931_DIGEST)   ,"invalid x931 digest"},
 {ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q) ,"iqmp not inverse of q"},
 {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_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),"operation not supported for this keytype"},
 {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"},
@@ -160,6 +170,7 @@
 {ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),"the asn1 object identifier is not known for this md"},
 {ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE),"unknown algorithm type"},
 {ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE)  ,"unknown padding type"},
+{ERR_REASON(RSA_R_VALUE_MISSING)         ,"value missing"},
 {ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH),"wrong signature length"},
 {0,NULL}
 	};
diff --git a/crypto/rsa/rsa_gen.c b/crypto/rsa/rsa_gen.c
index 41278f8..767f7ab 100644
--- a/crypto/rsa/rsa_gen.c
+++ b/crypto/rsa/rsa_gen.c
@@ -68,8 +68,6 @@
 #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
@@ -219,4 +217,3 @@
 	return ok;
 	}
 
-#endif
diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c
index 5714841..de45088 100644
--- a/crypto/rsa/rsa_lib.c
+++ b/crypto/rsa/rsa_lib.c
@@ -67,6 +67,224 @@
 #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;
+	if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data))
+		{
+#ifndef OPENSSL_NO_ENGINE
+	if (ret->engine)
+		ENGINE_finish(ret->engine);
+#endif
+		OPENSSL_free(ret);
+		return(NULL);
+		}
+
+	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)
 	{
@@ -76,13 +294,6 @@
 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));
 	}
 
@@ -95,19 +306,12 @@
 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_size(const RSA *r)
+int RSA_flags(const RSA *r)
 	{
-	return(BN_num_bytes(r->n));
+	return((r == NULL)?0:r->meth->flags);
 	}
 
 void RSA_blinding_off(RSA *rsa)
@@ -222,7 +426,7 @@
 		RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB);
 		goto err;
 		}
-	BN_BLINDING_set_thread_id(ret, CRYPTO_thread_id());
+	CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret));
 err:
 	BN_CTX_end(ctx);
 	if (in_ctx == NULL)
@@ -232,3 +436,48 @@
 
 	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_locl.h b/crypto/rsa/rsa_locl.h
new file mode 100644
index 0000000..f5d2d56
--- /dev/null
+++ b/crypto/rsa/rsa_locl.h
@@ -0,0 +1,4 @@
+extern int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
+		unsigned char *rm, size_t *prm_len,
+		const unsigned char *sigbuf, size_t siglen,
+		RSA *rsa);
diff --git a/crypto/rsa/rsa_oaep.c b/crypto/rsa/rsa_oaep.c
index 546ae5f..e238d10 100644
--- a/crypto/rsa/rsa_oaep.c
+++ b/crypto/rsa/rsa_oaep.c
@@ -28,7 +28,7 @@
 #include <openssl/rand.h>
 #include <openssl/sha.h>
 
-int MGF1(unsigned char *mask, long len,
+static int MGF1(unsigned char *mask, long len,
 	const unsigned char *seed, long seedlen);
 
 int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
@@ -76,11 +76,13 @@
 		return 0;
 		}
 
-	MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH);
+	if (MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH) < 0)
+		return 0;
 	for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++)
 		db[i] ^= dbmask[i];
 
-	MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH);
+	if (MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH) < 0)
+		return 0;
 	for (i = 0; i < SHA_DIGEST_LENGTH; i++)
 		seed[i] ^= seedmask[i];
 
@@ -133,11 +135,13 @@
 
 	maskeddb = padded_from + SHA_DIGEST_LENGTH;
 
-	MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen);
+	if (MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen))
+		return -1;
 	for (i = 0; i < SHA_DIGEST_LENGTH; i++)
 		seed[i] ^= padded_from[i];
   
-	MGF1(db, dblen, seed, SHA_DIGEST_LENGTH);
+	if (MGF1(db, dblen, seed, SHA_DIGEST_LENGTH))
+		return -1;
 	for (i = 0; i < dblen; i++)
 		db[i] ^= maskeddb[i];
 
@@ -187,7 +191,9 @@
 	int mdlen;
 
 	EVP_MD_CTX_init(&c);
-	mdlen = M_EVP_MD_size(dgst);
+	mdlen = EVP_MD_size(dgst);
+	if (mdlen < 0)
+		return -1;
 	for (i = 0; outlen < len; i++)
 		{
 		cnt[0] = (unsigned char)((i >> 24) & 255);
@@ -213,7 +219,8 @@
 	return 0;
 	}
 
-int MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen)
+static int MGF1(unsigned char *mask, long len, const unsigned char *seed,
+		 long seedlen)
 	{
 	return PKCS1_MGF1(mask, len, seed, seedlen, EVP_sha1());
 	}
diff --git a/crypto/rsa/rsa_pmeth.c b/crypto/rsa/rsa_pmeth.c
new file mode 100644
index 0000000..297e17c
--- /dev/null
+++ b/crypto/rsa/rsa_pmeth.c
@@ -0,0 +1,585 @@
+/* crypto/rsa/rsa_pmeth.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rsa.h>
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include "evp_locl.h"
+#include "rsa_locl.h"
+
+/* RSA pkey context structure */
+
+typedef struct
+	{
+	/* Key gen parameters */
+	int nbits;
+	BIGNUM *pub_exp;
+	/* Keygen callback info */
+	int gentmp[2];
+	/* RSA padding mode */
+	int pad_mode;
+	/* message digest */
+	const EVP_MD *md;
+	/* PSS/OAEP salt length */
+	int saltlen;
+	/* Temp buffer */
+	unsigned char *tbuf;
+	} RSA_PKEY_CTX;
+
+static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
+	{
+	RSA_PKEY_CTX *rctx;
+	rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX));
+	if (!rctx)
+		return 0;
+	rctx->nbits = 1024;
+	rctx->pub_exp = NULL;
+	rctx->pad_mode = RSA_PKCS1_PADDING;
+	rctx->md = NULL;
+	rctx->tbuf = NULL;
+
+	rctx->saltlen = -2;
+
+	ctx->data = rctx;
+	ctx->keygen_info = rctx->gentmp;
+	ctx->keygen_info_count = 2;
+	
+	return 1;
+	}
+
+static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+	{
+	RSA_PKEY_CTX *dctx, *sctx;
+	if (!pkey_rsa_init(dst))
+		return 0;
+       	sctx = src->data;
+	dctx = dst->data;
+	dctx->nbits = sctx->nbits;
+	if (sctx->pub_exp)
+		{
+		dctx->pub_exp = BN_dup(sctx->pub_exp);
+		if (!dctx->pub_exp)
+			return 0;
+		}
+	dctx->pad_mode = sctx->pad_mode;
+	dctx->md = sctx->md;
+	return 1;
+	}
+
+static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
+	{
+	if (ctx->tbuf)
+		return 1;
+	ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey));
+	if (!ctx->tbuf)
+		return 0;
+	return 1;
+	}
+
+static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx)
+	{
+	RSA_PKEY_CTX *rctx = ctx->data;
+	if (rctx)
+		{
+		if (rctx->pub_exp)
+			BN_free(rctx->pub_exp);
+		if (rctx->tbuf)
+			OPENSSL_free(rctx->tbuf);
+		OPENSSL_free(rctx);
+		}
+	}
+
+static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					const unsigned char *tbs, size_t tbslen)
+	{
+	int ret;
+	RSA_PKEY_CTX *rctx = ctx->data;
+	RSA *rsa = ctx->pkey->pkey.rsa;
+
+	if (rctx->md)
+		{
+		if (tbslen != (size_t)EVP_MD_size(rctx->md))
+			{
+			RSAerr(RSA_F_PKEY_RSA_SIGN,
+					RSA_R_INVALID_DIGEST_LENGTH);
+			return -1;
+			}
+		if (rctx->pad_mode == RSA_X931_PADDING)
+			{
+			if (!setup_tbuf(rctx, ctx))
+				return -1;
+			memcpy(rctx->tbuf, tbs, tbslen);
+			rctx->tbuf[tbslen] =
+				RSA_X931_hash_id(EVP_MD_type(rctx->md));
+			ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
+						sig, rsa, RSA_X931_PADDING);
+			}
+		else if (rctx->pad_mode == RSA_PKCS1_PADDING)
+			{
+			unsigned int sltmp;
+			ret = RSA_sign(EVP_MD_type(rctx->md),
+						tbs, tbslen, sig, &sltmp, rsa);
+			if (ret <= 0)
+				return ret;
+			ret = sltmp;
+			}
+		else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
+			{
+			if (!setup_tbuf(rctx, ctx))
+				return -1;
+			if (!RSA_padding_add_PKCS1_PSS(rsa, rctx->tbuf, tbs,
+						rctx->md, rctx->saltlen))
+				return -1;
+			ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf,
+						sig, rsa, RSA_NO_PADDING);
+			}
+		else
+			return -1;
+		}
+	else
+		ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
+							rctx->pad_mode);
+	if (ret < 0)
+		return ret;
+	*siglen = ret;
+	return 1;
+	}
+
+
+static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
+					unsigned char *rout, size_t *routlen,
+					const unsigned char *sig, size_t siglen)
+	{
+	int ret;
+	RSA_PKEY_CTX *rctx = ctx->data;
+
+	if (rctx->md)
+		{
+		if (rctx->pad_mode == RSA_X931_PADDING)
+			{
+			if (!setup_tbuf(rctx, ctx))
+				return -1;
+			ret = RSA_public_decrypt(siglen, sig,
+						rctx->tbuf, ctx->pkey->pkey.rsa,
+						RSA_X931_PADDING);
+			if (ret < 1)
+				return 0;
+			ret--;
+			if (rctx->tbuf[ret] !=
+				RSA_X931_hash_id(EVP_MD_type(rctx->md)))
+				{
+				RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
+						RSA_R_ALGORITHM_MISMATCH);
+				return 0;
+				}
+			if (ret != EVP_MD_size(rctx->md))
+				{
+				RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
+					RSA_R_INVALID_DIGEST_LENGTH);
+				return 0;
+				}
+			if (rout)
+				memcpy(rout, rctx->tbuf, ret);
+			}
+		else if (rctx->pad_mode == RSA_PKCS1_PADDING)
+			{
+			size_t sltmp;
+			ret = int_rsa_verify(EVP_MD_type(rctx->md),
+						NULL, 0, rout, &sltmp,
+					sig, siglen, ctx->pkey->pkey.rsa);
+			ret = sltmp;
+			}
+		else
+			return -1;
+		}
+	else
+		ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa,
+							rctx->pad_mode);
+	if (ret < 0)
+		return ret;
+	*routlen = ret;
+	return 1;
+	}
+
+static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
+					const unsigned char *sig, size_t siglen,
+					const unsigned char *tbs, size_t tbslen)
+	{
+	RSA_PKEY_CTX *rctx = ctx->data;
+	RSA *rsa = ctx->pkey->pkey.rsa;
+	size_t rslen;
+	if (rctx->md)
+		{
+		if (rctx->pad_mode == RSA_PKCS1_PADDING)
+			return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
+					sig, siglen, rsa);
+		if (rctx->pad_mode == RSA_X931_PADDING)
+			{
+			if (pkey_rsa_verifyrecover(ctx, NULL, &rslen,
+					sig, siglen) <= 0)
+				return 0;
+			}
+		else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
+			{
+			int ret;
+			if (!setup_tbuf(rctx, ctx))
+				return -1;
+			ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
+							rsa, RSA_NO_PADDING);
+			if (ret <= 0)
+				return 0;
+			ret = RSA_verify_PKCS1_PSS(rsa, tbs, rctx->md,
+						rctx->tbuf, rctx->saltlen);
+			if (ret <= 0)
+				return 0;
+			return 1;
+			}
+		else
+			return -1;
+		}
+	else
+		{
+		if (!setup_tbuf(rctx, ctx))
+			return -1;
+		rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf,
+						rsa, rctx->pad_mode);
+		if (rslen == 0)
+			return 0;
+		}
+
+	if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen))
+		return 0;
+
+	return 1;
+			
+	}
+	
+
+static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx,
+					unsigned char *out, size_t *outlen,
+					const unsigned char *in, size_t inlen)
+	{
+	int ret;
+	RSA_PKEY_CTX *rctx = ctx->data;
+	ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
+							rctx->pad_mode);
+	if (ret < 0)
+		return ret;
+	*outlen = ret;
+	return 1;
+	}
+
+static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx,
+					unsigned char *out, size_t *outlen,
+					const unsigned char *in, size_t inlen)
+	{
+	int ret;
+	RSA_PKEY_CTX *rctx = ctx->data;
+	ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
+							rctx->pad_mode);
+	if (ret < 0)
+		return ret;
+	*outlen = ret;
+	return 1;
+	}
+
+static int check_padding_md(const EVP_MD *md, int padding)
+	{
+	if (!md)
+		return 1;
+
+	if (padding == RSA_NO_PADDING)
+		{
+		RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE);
+		return 0;
+		}
+
+	if (padding == RSA_X931_PADDING)
+		{
+		if (RSA_X931_hash_id(EVP_MD_type(md)) == -1)
+			{
+			RSAerr(RSA_F_CHECK_PADDING_MD,
+						RSA_R_INVALID_X931_DIGEST);
+			return 0;
+			}
+		return 1;
+		}
+
+	return 1;
+	}
+			
+
+static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+	{
+	RSA_PKEY_CTX *rctx = ctx->data;
+	switch (type)
+		{
+		case EVP_PKEY_CTRL_RSA_PADDING:
+		if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING))
+			{
+			if (!check_padding_md(rctx->md, p1))
+				return 0;
+			if (p1 == RSA_PKCS1_PSS_PADDING) 
+				{
+				if (!(ctx->operation &
+				     (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY)))
+					goto bad_pad;
+				if (!rctx->md)
+					rctx->md = EVP_sha1();
+				}
+			if (p1 == RSA_PKCS1_OAEP_PADDING) 
+				{
+				if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))
+					goto bad_pad;
+				if (!rctx->md)
+					rctx->md = EVP_sha1();
+				}
+			rctx->pad_mode = p1;
+			return 1;
+			}
+		bad_pad:
+		RSAerr(RSA_F_PKEY_RSA_CTRL,
+				RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
+		return -2;
+
+		case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
+		if (p1 < -2)
+			return -2;
+		if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING)
+			{
+			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN);
+			return -2;
+			}
+		rctx->saltlen = p1;
+		return 1;
+
+		case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
+		if (p1 < 256)
+			{
+			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS);
+			return -2;
+			}
+		rctx->nbits = p1;
+		return 1;
+
+		case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
+		if (!p2)
+			return -2;
+		rctx->pub_exp = p2;
+		return 1;
+
+		case EVP_PKEY_CTRL_MD:
+		if (!check_padding_md(p2, rctx->pad_mode))
+			return 0;
+		rctx->md = p2;
+		return 1;
+
+		case EVP_PKEY_CTRL_DIGESTINIT:
+		case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
+		case EVP_PKEY_CTRL_PKCS7_DECRYPT:
+		case EVP_PKEY_CTRL_PKCS7_SIGN:
+#ifndef OPENSSL_NO_CMS
+		case EVP_PKEY_CTRL_CMS_ENCRYPT:
+		case EVP_PKEY_CTRL_CMS_DECRYPT:
+		case EVP_PKEY_CTRL_CMS_SIGN:
+#endif
+		return 1;
+		case EVP_PKEY_CTRL_PEER_KEY:
+			RSAerr(RSA_F_PKEY_RSA_CTRL,
+			RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+			return -2;	
+
+		default:
+		return -2;
+
+		}
+	}
+			
+static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
+			const char *type, const char *value)
+	{
+	if (!value)
+		{
+		RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING);
+		return 0;
+		}
+	if (!strcmp(type, "rsa_padding_mode"))
+		{
+		int pm;
+		if (!strcmp(value, "pkcs1"))
+			pm = RSA_PKCS1_PADDING;
+		else if (!strcmp(value, "sslv23"))
+			pm = RSA_SSLV23_PADDING;
+		else if (!strcmp(value, "none"))
+			pm = RSA_NO_PADDING;
+		else if (!strcmp(value, "oeap"))
+			pm = RSA_PKCS1_OAEP_PADDING;
+		else if (!strcmp(value, "x931"))
+			pm = RSA_X931_PADDING;
+		else if (!strcmp(value, "pss"))
+			pm = RSA_PKCS1_PSS_PADDING;
+		else
+			{
+			RSAerr(RSA_F_PKEY_RSA_CTRL_STR,
+						RSA_R_UNKNOWN_PADDING_TYPE);
+			return -2;
+			}
+		return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
+		}
+
+	if (!strcmp(type, "rsa_pss_saltlen"))
+		{
+		int saltlen;
+		saltlen = atoi(value);
+		return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen);
+		}
+
+	if (!strcmp(type, "rsa_keygen_bits"))
+		{
+		int nbits;
+		nbits = atoi(value);
+		return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits);
+		}
+
+	if (!strcmp(type, "rsa_keygen_pubexp"))
+		{
+		int ret;
+		BIGNUM *pubexp = NULL;
+		if (!BN_asc2bn(&pubexp, value))
+			return 0;
+		ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp);
+		if (ret <= 0)
+			BN_free(pubexp);
+		return ret;
+		}
+
+	return -2;
+	}
+
+static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+	{
+	RSA *rsa = NULL;
+	RSA_PKEY_CTX *rctx = ctx->data;
+	BN_GENCB *pcb, cb;
+	int ret;
+	if (!rctx->pub_exp)
+		{
+		rctx->pub_exp = BN_new();
+		if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4))
+			return 0;
+		}
+	rsa = RSA_new();
+	if (!rsa)
+		return 0;
+	if (ctx->pkey_gencb)
+		{
+		pcb = &cb;
+		evp_pkey_set_cb_translate(pcb, ctx);
+		}
+	else
+		pcb = NULL;
+	ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb);
+	if (ret > 0)
+		EVP_PKEY_assign_RSA(pkey, rsa);
+	else
+		RSA_free(rsa);
+	return ret;
+	}
+
+const EVP_PKEY_METHOD rsa_pkey_meth = 
+	{
+	EVP_PKEY_RSA,
+	EVP_PKEY_FLAG_AUTOARGLEN,
+	pkey_rsa_init,
+	pkey_rsa_copy,
+	pkey_rsa_cleanup,
+
+	0,0,
+
+	0,
+	pkey_rsa_keygen,
+
+	0,
+	pkey_rsa_sign,
+
+	0,
+	pkey_rsa_verify,
+
+	0,
+	pkey_rsa_verifyrecover,
+
+
+	0,0,0,0,
+
+	0,
+	pkey_rsa_encrypt,
+
+	0,
+	pkey_rsa_decrypt,
+
+	0,0,
+
+	pkey_rsa_ctrl,
+	pkey_rsa_ctrl_str
+
+
+	};
diff --git a/crypto/rc4/rc4_fblk.c b/crypto/rsa/rsa_prn.c
similarity index 72%
copy from crypto/rc4/rc4_fblk.c
copy to crypto/rsa/rsa_prn.c
index 1b2a429..224db0f 100644
--- a/crypto/rc4/rc4_fblk.c
+++ b/crypto/rsa/rsa_prn.c
@@ -1,9 +1,9 @@
-/* crypto/rc4/rc4_fblk.c */
+/* crypto/rsa/rsa_prn.c */
 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project.
+ * project 2006.
  */
 /* ====================================================================
- * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ * 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
@@ -49,27 +49,45 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
  */
 
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
 
-#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)
+#ifndef OPENSSL_NO_FP_API
+int RSA_print_fp(FILE *fp, const RSA *x, int off)
 	{
-	if (FIPS_mode())
-		FIPS_BAD_ABORT(RC4)
-	private_RC4_set_key(key, len, data);
+	BIO *b;
+	int ret;
+
+	if ((b=BIO_new(BIO_s_file())) == NULL)
+		{
+		RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB);
+		return(0);
+		}
+	BIO_set_fp(b,fp,BIO_NOCLOSE);
+	ret=RSA_print(b,x,off);
+	BIO_free(b);
+	return(ret);
 	}
 #endif
 
+int RSA_print(BIO *bp, const RSA *x, int off)
+	{
+	EVP_PKEY *pk;
+	int ret;
+	pk = EVP_PKEY_new();
+	if (!pk || !EVP_PKEY_set1_RSA(pk, (RSA *)x))
+		return 0;
+	ret = EVP_PKEY_print_private(bp, pk, off, NULL);
+	EVP_PKEY_free(pk);
+	return ret;
+	}
+
diff --git a/crypto/rsa/rsa_pss.c b/crypto/rsa/rsa_pss.c
index 2bda491..ac211e2 100644
--- a/crypto/rsa/rsa_pss.c
+++ b/crypto/rsa/rsa_pss.c
@@ -81,7 +81,9 @@
 	EVP_MD_CTX ctx;
 	unsigned char H_[EVP_MAX_MD_SIZE];
 
-	hLen = M_EVP_MD_size(Hash);
+	hLen = EVP_MD_size(Hash);
+	if (hLen < 0)
+		goto err;
 	/*
 	 * Negative sLen has special meanings:
 	 *	-1	sLen == hLen
@@ -126,7 +128,8 @@
 		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, ERR_R_MALLOC_FAILURE);
 		goto err;
 		}
-	PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash);
+	if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash) < 0)
+		goto err;
 	for (i = 0; i < maskedDBLen; i++)
 		DB[i] ^= EM[i];
 	if (MSBits)
@@ -176,7 +179,9 @@
 	unsigned char *H, *salt = NULL, *p;
 	EVP_MD_CTX ctx;
 
-	hLen = M_EVP_MD_size(Hash);
+	hLen = EVP_MD_size(Hash);
+	if (hLen < 0)
+		goto err;
 	/*
 	 * Negative sLen has special meanings:
 	 *	-1	sLen == hLen
@@ -232,7 +237,8 @@
 	EVP_MD_CTX_cleanup(&ctx);
 
 	/* Generate dbMask in place then perform XOR on it */
-	PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash);
+	if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash))
+		goto err;
 
 	p = EM;
 
diff --git a/crypto/rsa/rsa_sign.c b/crypto/rsa/rsa_sign.c
index 743dfd7..0be4ec7 100644
--- a/crypto/rsa/rsa_sign.c
+++ b/crypto/rsa/rsa_sign.c
@@ -62,6 +62,7 @@
 #include <openssl/rsa.h>
 #include <openssl/objects.h>
 #include <openssl/x509.h>
+#include "rsa_locl.h"
 
 /* Size of an SSL signature: MD5+SHA1 */
 #define SSL_SIG_LENGTH	36
@@ -90,14 +91,6 @@
 		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)
@@ -137,12 +130,7 @@
 		i2d_X509_SIG(&sig,&p);
 		s=tmps;
 	}
-#ifdef OPENSSL_FIPS
-	/* Bypass algorithm blocking: this is allowed if we get this far */
-	i=rsa->meth->rsa_priv_enc(i,s,sigret,rsa,RSA_PKCS1_PADDING);
-#else
 	i=RSA_private_encrypt(i,s,sigret,rsa,RSA_PKCS1_PADDING);
-#endif
 	if (i <= 0)
 		ret=0;
 	else
@@ -155,8 +143,11 @@
 	return(ret);
 	}
 
-int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
-	     unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
+int int_rsa_verify(int dtype, const unsigned char *m,
+			  unsigned int m_len,
+			  unsigned char *rm, size_t *prm_len,
+			  const unsigned char *sigbuf, size_t siglen,
+			  RSA *rsa)
 	{
 	int i,ret=0,sigtype;
 	unsigned char *s;
@@ -164,49 +155,38 @@
 
 	if (siglen != (unsigned int)RSA_size(rsa))
 		{
-		RSAerr(RSA_F_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH);
+		RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH);
 		return(0);
 		}
 
-	if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify)
+	if((dtype == NID_md5_sha1) && rm)
 		{
-		return rsa->meth->rsa_verify(dtype, m, m_len,
-			sigbuf, siglen, rsa);
+		i = RSA_public_decrypt((int)siglen,
+					sigbuf,rm,rsa,RSA_PKCS1_PADDING);
+		if (i <= 0)
+			return 0;
+		*prm_len = i;
+		return 1;
 		}
 
 	s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen);
 	if (s == NULL)
 		{
-		RSAerr(RSA_F_RSA_VERIFY,ERR_R_MALLOC_FAILURE);
+		RSAerr(RSA_F_INT_RSA_VERIFY,ERR_R_MALLOC_FAILURE);
 		goto err;
 		}
-	if(dtype == NID_md5_sha1)
-		{
-		if (m_len != SSL_SIG_LENGTH)
-			{
-			RSAerr(RSA_F_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH);
+	if((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH) ) {
+			RSAerr(RSA_F_INT_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;
-		}
-	/* Bypass algorithm blocking: this is allowed */
-	i=rsa->meth->rsa_pub_dec((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);
-#else
+	}
 	i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);
-#endif
 
 	if (i <= 0) goto err;
 
 	/* Special case: SSL signature */
 	if(dtype == NID_md5_sha1) {
 		if((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH))
-				RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+				RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
 		else ret = 1;
 	} else {
 		const unsigned char *p=s;
@@ -217,7 +197,7 @@
 		/* Excess data can be used to create forgeries */
 		if(p != s+i)
 			{
-			RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+			RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
 			goto err;
 			}
 
@@ -226,7 +206,7 @@
 		if(sig->algor->parameter
 		   && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL)
 			{
-			RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+			RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
 			goto err;
 			}
 
@@ -252,15 +232,30 @@
 				}
 			else
 				{
-				RSAerr(RSA_F_RSA_VERIFY,
+				RSAerr(RSA_F_INT_RSA_VERIFY,
 						RSA_R_ALGORITHM_MISMATCH);
 				goto err;
 				}
 			}
-		if (	((unsigned int)sig->digest->length != m_len) ||
+		if (rm)
+			{
+			const EVP_MD *md;
+			md = EVP_get_digestbynid(dtype);
+			if (md && (EVP_MD_size(md) != sig->digest->length))
+				RSAerr(RSA_F_INT_RSA_VERIFY,
+						RSA_R_INVALID_DIGEST_LENGTH);
+			else
+				{
+				memcpy(rm, sig->digest->data,
+							sig->digest->length);
+				*prm_len = sig->digest->length;
+				ret = 1;
+				}
+			}
+		else if (((unsigned int)sig->digest->length != m_len) ||
 			(memcmp(m,sig->digest->data,m_len) != 0))
 			{
-			RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+			RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
 			}
 		else
 			ret=1;
@@ -275,3 +270,16 @@
 	return(ret);
 	}
 
+int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
+		const unsigned char *sigbuf, unsigned int siglen,
+		RSA *rsa)
+	{
+
+	if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify)
+		{
+		return rsa->meth->rsa_verify(dtype, m, m_len,
+			sigbuf, siglen, rsa);
+		}
+
+	return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa);
+	}
diff --git a/crypto/rsa/rsa_test.c b/crypto/rsa/rsa_test.c
index 4080de8..c8705a0 100644
--- a/crypto/rsa/rsa_test.c
+++ b/crypto/rsa/rsa_test.c
@@ -328,7 +328,7 @@
 	}
 
     CRYPTO_cleanup_all_ex_data();
-    ERR_remove_state(0);
+    ERR_remove_thread_state(NULL);
 
     CRYPTO_mem_leaks_fp(stderr);
 
diff --git a/crypto/rsa/rsa_x931g.c b/crypto/rsa/rsa_x931g.c
deleted file mode 100644
index bf94f8b..0000000
--- a/crypto/rsa/rsa_x931g.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/* crypto/rsa/rsa_gen.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <openssl/err.h>
-#include <openssl/bn.h>
-#include <openssl/rsa.h>
-
-#ifndef OPENSSL_FIPS
-
-/* X9.31 RSA key derivation and generation */
-
-int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2,
-			const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp,
-			const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq,
-			const BIGNUM *e, BN_GENCB *cb)
-	{
-	BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL;
-	BN_CTX *ctx=NULL,*ctx2=NULL;
-
-	if (!rsa) 
-		goto err;
-
-	ctx = BN_CTX_new();
-	if (!ctx) 
-		goto err;
-	BN_CTX_start(ctx);
-
-	r0 = BN_CTX_get(ctx);
-	r1 = BN_CTX_get(ctx);
-	r2 = BN_CTX_get(ctx);
-	r3 = BN_CTX_get(ctx);
-
-	if (r3 == NULL)
-		goto err;
-	if (!rsa->e)
-		{
-		rsa->e = BN_dup(e);
-		if (!rsa->e)
-			goto err;
-		}
-	else
-		e = rsa->e;
-
-	/* If not all parameters present only calculate what we can.
-	 * This allows test programs to output selective parameters.
-	 */
-
-	if (Xp && !rsa->p)
-		{
-		rsa->p = BN_new();
-		if (!rsa->p)
-			goto err;
-
-		if (!BN_X931_derive_prime_ex(rsa->p, p1, p2,
-					Xp, Xp1, Xp2, e, ctx, cb))
-			goto err;
-		}
-
-	if (Xq && !rsa->q)
-		{
-		rsa->q = BN_new();
-		if (!rsa->q)
-			goto err;
-		if (!BN_X931_derive_prime_ex(rsa->q, q1, q2,
-					Xq, Xq1, Xq2, e, ctx, cb))
-			goto err;
-		}
-
-	if (!rsa->p || !rsa->q)
-		{
-		BN_CTX_end(ctx);
-		BN_CTX_free(ctx);
-		return 2;
-		}
-
-	/* Since both primes are set we can now calculate all remaining 
-	 * components.
-	 */
-
-	/* calculate n */
-	rsa->n=BN_new();
-	if (rsa->n == NULL)
-		goto err;
-	if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx))
-		goto err;
-
-	/* calculate d */
-	if (!BN_sub(r1,rsa->p,BN_value_one()))
-		goto err;	/* p-1 */
-	if (!BN_sub(r2,rsa->q,BN_value_one()))
-		goto err;	/* q-1 */
-	if (!BN_mul(r0,r1,r2,ctx))
-		goto err;	/* (p-1)(q-1) */
-
-	if (!BN_gcd(r3, r1, r2, ctx))
-		goto err;
-
-	if (!BN_div(r0, NULL, r0, r3, ctx))
-		goto err;	/* LCM((p-1)(q-1)) */
-
-	ctx2 = BN_CTX_new();
-	if (!ctx2)
-		goto err;
-
-	rsa->d=BN_mod_inverse(NULL,rsa->e,r0,ctx2);	/* d */
-	if (rsa->d == NULL)
-		goto err;
-
-	/* calculate d mod (p-1) */
-	rsa->dmp1=BN_new();
-	if (rsa->dmp1 == NULL)
-		goto err;
-	if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx))
-		goto err;
-
-	/* calculate d mod (q-1) */
-	rsa->dmq1=BN_new();
-	if (rsa->dmq1 == NULL)
-		goto err;
-	if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx))
-		goto err;
-
-	/* calculate inverse of q mod p */
-	rsa->iqmp=BN_mod_inverse(NULL,rsa->q,rsa->p,ctx2);
-
-	err:
-	if (ctx)
-		{
-		BN_CTX_end(ctx);
-		BN_CTX_free(ctx);
-		}
-	if (ctx2)
-		BN_CTX_free(ctx2);
-	/* If this is set all calls successful */
-	if (rsa && rsa->iqmp != NULL)
-		return 1;
-
-	return 0;
-
-	}
-
-int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb)
-	{
-	int ok = 0;
-	BIGNUM *Xp = NULL, *Xq = NULL;
-	BN_CTX *ctx = NULL;
-	
-	ctx = BN_CTX_new();
-	if (!ctx)
-		goto error;
-
-	BN_CTX_start(ctx);
-	Xp = BN_CTX_get(ctx);
-	Xq = BN_CTX_get(ctx);
-	if (!BN_X931_generate_Xpq(Xp, Xq, bits, ctx))
-		goto error;
-
-	rsa->p = BN_new();
-	rsa->q = BN_new();
-	if (!rsa->p || !rsa->q)
-		goto error;
-
-	/* Generate two primes from Xp, Xq */
-
-	if (!BN_X931_generate_prime_ex(rsa->p, NULL, NULL, NULL, NULL, Xp,
-					e, ctx, cb))
-		goto error;
-
-	if (!BN_X931_generate_prime_ex(rsa->q, NULL, NULL, NULL, NULL, Xq,
-					e, ctx, cb))
-		goto error;
-
-	/* Since rsa->p and rsa->q are valid this call will just derive
-	 * remaining RSA components.
-	 */
-
-	if (!RSA_X931_derive_ex(rsa, NULL, NULL, NULL, NULL,
-				NULL, NULL, NULL, NULL, NULL, NULL, e, cb))
-		goto error;
-
-	ok = 1;
-
-	error:
-	if (ctx)
-		{
-		BN_CTX_end(ctx);
-		BN_CTX_free(ctx);
-		}
-
-	if (ok)
-		return 1;
-
-	return 0;
-
-	}
-
-#endif
diff --git a/crypto/s390xcap.c b/crypto/s390xcap.c
new file mode 100644
index 0000000..ffbe023
--- /dev/null
+++ b/crypto/s390xcap.c
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <setjmp.h>
+#include <signal.h>
+
+extern unsigned long OPENSSL_s390xcap_P;
+
+static sigjmp_buf ill_jmp;
+static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
+
+unsigned long OPENSSL_s390x_facilities(void);
+
+void OPENSSL_cpuid_setup(void)
+	{
+	sigset_t oset;
+	struct sigaction ill_act,oact;
+
+	if (OPENSSL_s390xcap_P) return;
+
+	memset(&ill_act,0,sizeof(ill_act));
+	ill_act.sa_handler = ill_handler;
+	sigfillset(&ill_act.sa_mask);
+	sigdelset(&ill_act.sa_mask,SIGILL);
+	sigdelset(&ill_act.sa_mask,SIGTRAP);
+	sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset);
+	sigaction (SIGILL,&ill_act,&oact);
+
+	/* protection against missing store-facility-list-extended */
+	if (sigsetjmp(ill_jmp,0) == 0)
+		OPENSSL_s390xcap_P = OPENSSL_s390x_facilities();
+	else
+		OPENSSL_s390xcap_P = 1UL<<63;
+
+	sigaction (SIGILL,&oact,NULL);
+	sigprocmask(SIG_SETMASK,&oset,NULL);
+	}
diff --git a/crypto/s390xcpuid.S b/crypto/s390xcpuid.S
new file mode 100644
index 0000000..b053c6a
--- /dev/null
+++ b/crypto/s390xcpuid.S
@@ -0,0 +1,92 @@
+.text
+
+.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)
+	larl	%r1,OPENSSL_s390xcap_P
+	stg	%r2,0(%r1)
+	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
+	clgr	%r3,%r0
+	bcr	8,%r14
+.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
+
+.section	.init
+	brasl	%r14,OPENSSL_cpuid_setup
+
+.comm	OPENSSL_s390xcap_P,8,8
diff --git a/crypto/sha/Makefile b/crypto/sha/Makefile
deleted file mode 100644
index f4741b9..0000000
--- a/crypto/sha/Makefile
+++ /dev/null
@@ -1,146 +0,0 @@
-#
-# OpenSSL/crypto/sha/Makefile
-#
-
-DIR=    sha
-TOP=    ../..
-CC=     cc
-CPP=    $(CC) -E
-INCLUDES=
-CFLAG=-g
-MAKEFILE=       Makefile
-AR=             ar r
-
-SHA1_ASM_OBJ=
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-ASFLAGS= $(INCLUDES) $(ASFLAG)
-AFLAGS= $(ASFLAGS)
-
-GENERAL=Makefile
-TEST=shatest.c sha1test.c sha256t.c sha512t.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=sha_dgst.c sha1dgst.c sha_one.c sha1_one.c sha256.c sha512.c
-LIBOBJ=sha_dgst.o sha1dgst.o sha_one.o sha1_one.o sha256.o sha512.o $(SHA1_ASM_OBJ)
-
-SRC= $(LIBSRC)
-
-EXHEADER= sha.h
-HEADER= sha_locl.h $(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:    lib
-
-lib:    $(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-# ELF
-sx86-elf.s: asm/sha1-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) sha1-586.pl elf $(CFLAGS) $(PROCESSOR) > ../$@)
-s512sse2-elf.s:	asm/sha512-sse2.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) sha512-sse2.pl elf $(CFLAGS) $(PROCESSOR) > ../$@)
-# COFF
-sx86-cof.s: asm/sha1-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) sha1-586.pl coff $(CFLAGS) $(PROCESSOR) > ../$@)
-s512sse2-cof.s:     asm/sha512-sse2.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) sha512-sse2.pl coff $(CFLAGS) $(PROCESSOR) > ../$@)
-# a.out
-sx86-out.s: asm/sha1-586.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) sha1-586.pl a.out $(CFLAGS) $(PROCESSOR) > ../$@)
-s512sse2-out.s:     asm/sha512-sse2.pl ../perlasm/x86asm.pl
-	(cd asm; $(PERL) sha512-sse2.pl a.out $(CFLAGS) $(PROCESSOR) > ../$@)
-
-sha1-ia64.s:   asm/sha1-ia64.pl
-	(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
-	(cd asm; $(PERL) sha512-ia64.pl ../$@ $(CFLAGS))
-
-# Solaris make has to be explicitly told
-sha1-x86_64.s:	asm/sha1-x86_64.pl;	$(PERL) asm/sha1-x86_64.pl $@
-sha256-x86_64.s:asm/sha512-x86_64.pl;	$(PERL) asm/sha512-x86_64.pl $@
-sha512-x86_64.s:asm/sha512-x86_64.pl;	$(PERL) asm/sha512-x86_64.pl $@
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-sha1_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-sha1_one.o: ../../include/openssl/opensslconf.h
-sha1_one.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-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/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/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/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
-sha_one.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-sha_one.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-sha_one.o: ../../include/openssl/symhacks.h sha_one.c
diff --git a/crypto/sha/asm/sha1-586.pl b/crypto/sha/asm/sha1-586.pl
index a787dd3..a1f8762 100644
--- a/crypto/sha/asm/sha1-586.pl
+++ b/crypto/sha/asm/sha1-586.pl
@@ -215,5 +215,6 @@
 
 	&stack_pop(16);
 &function_end("sha1_block_data_order");
+&asciz("SHA1 block transform for x86, CRYPTOGAMS by <appro\@openssl.org>");
 
 &asm_finish();
diff --git a/crypto/0.9.9-dev/sha/sha1-armv4-large.pl b/crypto/sha/asm/sha1-armv4-large.pl
similarity index 93%
rename from crypto/0.9.9-dev/sha/sha1-armv4-large.pl
rename to crypto/sha/asm/sha1-armv4-large.pl
index d468be3..88861af 100644
--- a/crypto/0.9.9-dev/sha/sha1-armv4-large.pl
+++ b/crypto/sha/asm/sha1-armv4-large.pl
@@ -18,8 +18,8 @@
 # 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%
+# armv4-large	1420/+92%	1307/+19%	1370/+34%[***]
+# full unroll	~5100/+260%	~1260/+4%	~1300/+5%
 # ====================================================================
 # thumb		= same as 'small' but in Thumb instructions[**] and
 #		  with recurring code in two private functions;
@@ -37,6 +37,7 @@
 #	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.
+# [***]	which is also ~35% better than compiler generated code.
 
 $output=shift;
 open STDOUT,">$output";
@@ -50,9 +51,10 @@
 $d="r6";
 $e="r7";
 $K="r8";
-$t0="r10";
-$t1="r11";
-$t2="r12";
+$t0="r9";
+$t1="r10";
+$t2="r11";
+$t3="r12";
 $Xi="r14";
 @V=($a,$b,$c,$d,$e);
 
@@ -64,14 +66,14 @@
 	ldrb	$t0,[$inp],#4
 	ldrb	$t1,[$inp,#-3]
 	ldrb	$t2,[$inp,#-2]
+	ldrb	$t3,[$inp,#-1]
 	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]
+	orr	$t0,$t2,$t0,lsl#8
 	eor	$t1,$c,$d			@ F_xx_xx
+	orr	$t0,$t3,$t0,lsl#8
+	add	$e,$e,$t0			@ E+=X[i]
 	str	$t0,[$Xi,#-4]!
 ___
 }
@@ -81,12 +83,12 @@
 	ldr	$t0,[$Xi,#15*4]
 	ldr	$t1,[$Xi,#13*4]
 	ldr	$t2,[$Xi,#7*4]
+	ldr	$t3,[$Xi,#2*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
+	eor	$t0,$t0,$t3
+	add	$e,$e,$a,ror#27			@ E+=ROR(A,27)
 ___
 $code.=<<___ if (!defined($flag));
 	eor	$t1,$c,$d			@ F_xx_xx, but not in 40_59
@@ -203,12 +205,12 @@
 	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}
+	ldmia	$ctx,{$K,$t0,$t1,$t2,$t3}
 	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
+	add	$e,$t3,$e,ror#2
 	stmia	$ctx,{$a,$b,$c,$d,$e}
 	teq	$inp,$len
 	bne	.Lloop			@ [+18], total 1307
@@ -224,6 +226,7 @@
 .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>"
+.align	2
 ___
 
 $code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
diff --git a/crypto/sha/asm/sha1-armv4-large.s b/crypto/sha/asm/sha1-armv4-large.s
new file mode 100644
index 0000000..7fc90c5
--- /dev/null
+++ b/crypto/sha/asm/sha1-armv4-large.s
@@ -0,0 +1,377 @@
+.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	r9,[r1],#4
+	ldrb	r10,[r1,#-3]
+	ldrb	r11,[r1,#-2]
+	ldrb	r12,[r1,#-1]
+	add	r7,r8,r7,ror#2			@ E+=K_00_19
+	orr	r9,r10,r9,lsl#8
+	add	r7,r7,r3,ror#27			@ E+=ROR(A,27)
+	orr	r9,r11,r9,lsl#8
+	eor	r10,r5,r6			@ F_xx_xx
+	orr	r9,r12,r9,lsl#8
+	add	r7,r7,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	and	r10,r4,r10,ror#2
+	eor	r10,r10,r6,ror#2		@ F_00_19(B,C,D)
+	add	r7,r7,r10			@ E+=F_00_19(B,C,D)
+	ldrb	r9,[r1],#4
+	ldrb	r10,[r1,#-3]
+	ldrb	r11,[r1,#-2]
+	ldrb	r12,[r1,#-1]
+	add	r6,r8,r6,ror#2			@ E+=K_00_19
+	orr	r9,r10,r9,lsl#8
+	add	r6,r6,r7,ror#27			@ E+=ROR(A,27)
+	orr	r9,r11,r9,lsl#8
+	eor	r10,r4,r5			@ F_xx_xx
+	orr	r9,r12,r9,lsl#8
+	add	r6,r6,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	and	r10,r3,r10,ror#2
+	eor	r10,r10,r5,ror#2		@ F_00_19(B,C,D)
+	add	r6,r6,r10			@ E+=F_00_19(B,C,D)
+	ldrb	r9,[r1],#4
+	ldrb	r10,[r1,#-3]
+	ldrb	r11,[r1,#-2]
+	ldrb	r12,[r1,#-1]
+	add	r5,r8,r5,ror#2			@ E+=K_00_19
+	orr	r9,r10,r9,lsl#8
+	add	r5,r5,r6,ror#27			@ E+=ROR(A,27)
+	orr	r9,r11,r9,lsl#8
+	eor	r10,r3,r4			@ F_xx_xx
+	orr	r9,r12,r9,lsl#8
+	add	r5,r5,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	and	r10,r7,r10,ror#2
+	eor	r10,r10,r4,ror#2		@ F_00_19(B,C,D)
+	add	r5,r5,r10			@ E+=F_00_19(B,C,D)
+	ldrb	r9,[r1],#4
+	ldrb	r10,[r1,#-3]
+	ldrb	r11,[r1,#-2]
+	ldrb	r12,[r1,#-1]
+	add	r4,r8,r4,ror#2			@ E+=K_00_19
+	orr	r9,r10,r9,lsl#8
+	add	r4,r4,r5,ror#27			@ E+=ROR(A,27)
+	orr	r9,r11,r9,lsl#8
+	eor	r10,r7,r3			@ F_xx_xx
+	orr	r9,r12,r9,lsl#8
+	add	r4,r4,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	and	r10,r6,r10,ror#2
+	eor	r10,r10,r3,ror#2		@ F_00_19(B,C,D)
+	add	r4,r4,r10			@ E+=F_00_19(B,C,D)
+	ldrb	r9,[r1],#4
+	ldrb	r10,[r1,#-3]
+	ldrb	r11,[r1,#-2]
+	ldrb	r12,[r1,#-1]
+	add	r3,r8,r3,ror#2			@ E+=K_00_19
+	orr	r9,r10,r9,lsl#8
+	add	r3,r3,r4,ror#27			@ E+=ROR(A,27)
+	orr	r9,r11,r9,lsl#8
+	eor	r10,r6,r7			@ F_xx_xx
+	orr	r9,r12,r9,lsl#8
+	add	r3,r3,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	and	r10,r5,r10,ror#2
+	eor	r10,r10,r7,ror#2		@ F_00_19(B,C,D)
+	add	r3,r3,r10			@ E+=F_00_19(B,C,D)
+	teq	r14,sp
+	bne	.L_00_15		@ [((11+4)*5+2)*3]
+	ldrb	r9,[r1],#4
+	ldrb	r10,[r1,#-3]
+	ldrb	r11,[r1,#-2]
+	ldrb	r12,[r1,#-1]
+	add	r7,r8,r7,ror#2			@ E+=K_00_19
+	orr	r9,r10,r9,lsl#8
+	add	r7,r7,r3,ror#27			@ E+=ROR(A,27)
+	orr	r9,r11,r9,lsl#8
+	eor	r10,r5,r6			@ F_xx_xx
+	orr	r9,r12,r9,lsl#8
+	add	r7,r7,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	and	r10,r4,r10,ror#2
+	eor	r10,r10,r6,ror#2		@ F_00_19(B,C,D)
+	add	r7,r7,r10			@ E+=F_00_19(B,C,D)
+	ldr	r9,[r14,#15*4]
+	ldr	r10,[r14,#13*4]
+	ldr	r11,[r14,#7*4]
+	ldr	r12,[r14,#2*4]
+	add	r6,r8,r6,ror#2			@ E+=K_xx_xx
+	eor	r9,r9,r10
+	eor	r9,r9,r11
+	eor	r9,r9,r12
+	add	r6,r6,r7,ror#27			@ E+=ROR(A,27)
+	eor	r10,r4,r5			@ F_xx_xx, but not in 40_59
+	mov	r9,r9,ror#31
+	add	r6,r6,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	and	r10,r3,r10,ror#2
+	eor	r10,r10,r5,ror#2		@ F_00_19(B,C,D)
+	add	r6,r6,r10			@ E+=F_00_19(B,C,D)
+	ldr	r9,[r14,#15*4]
+	ldr	r10,[r14,#13*4]
+	ldr	r11,[r14,#7*4]
+	ldr	r12,[r14,#2*4]
+	add	r5,r8,r5,ror#2			@ E+=K_xx_xx
+	eor	r9,r9,r10
+	eor	r9,r9,r11
+	eor	r9,r9,r12
+	add	r5,r5,r6,ror#27			@ E+=ROR(A,27)
+	eor	r10,r3,r4			@ F_xx_xx, but not in 40_59
+	mov	r9,r9,ror#31
+	add	r5,r5,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	and	r10,r7,r10,ror#2
+	eor	r10,r10,r4,ror#2		@ F_00_19(B,C,D)
+	add	r5,r5,r10			@ E+=F_00_19(B,C,D)
+	ldr	r9,[r14,#15*4]
+	ldr	r10,[r14,#13*4]
+	ldr	r11,[r14,#7*4]
+	ldr	r12,[r14,#2*4]
+	add	r4,r8,r4,ror#2			@ E+=K_xx_xx
+	eor	r9,r9,r10
+	eor	r9,r9,r11
+	eor	r9,r9,r12
+	add	r4,r4,r5,ror#27			@ E+=ROR(A,27)
+	eor	r10,r7,r3			@ F_xx_xx, but not in 40_59
+	mov	r9,r9,ror#31
+	add	r4,r4,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	and	r10,r6,r10,ror#2
+	eor	r10,r10,r3,ror#2		@ F_00_19(B,C,D)
+	add	r4,r4,r10			@ E+=F_00_19(B,C,D)
+	ldr	r9,[r14,#15*4]
+	ldr	r10,[r14,#13*4]
+	ldr	r11,[r14,#7*4]
+	ldr	r12,[r14,#2*4]
+	add	r3,r8,r3,ror#2			@ E+=K_xx_xx
+	eor	r9,r9,r10
+	eor	r9,r9,r11
+	eor	r9,r9,r12
+	add	r3,r3,r4,ror#27			@ E+=ROR(A,27)
+	eor	r10,r6,r7			@ F_xx_xx, but not in 40_59
+	mov	r9,r9,ror#31
+	add	r3,r3,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	and	r10,r5,r10,ror#2
+	eor	r10,r10,r7,ror#2		@ F_00_19(B,C,D)
+	add	r3,r3,r10			@ 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	r9,[r14,#15*4]
+	ldr	r10,[r14,#13*4]
+	ldr	r11,[r14,#7*4]
+	ldr	r12,[r14,#2*4]
+	add	r7,r8,r7,ror#2			@ E+=K_xx_xx
+	eor	r9,r9,r10
+	eor	r9,r9,r11
+	eor	r9,r9,r12
+	add	r7,r7,r3,ror#27			@ E+=ROR(A,27)
+	eor	r10,r5,r6			@ F_xx_xx, but not in 40_59
+	mov	r9,r9,ror#31
+	add	r7,r7,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	eor	r10,r4,r10,ror#2		@ F_20_39(B,C,D)
+	add	r7,r7,r10			@ E+=F_20_39(B,C,D)
+	ldr	r9,[r14,#15*4]
+	ldr	r10,[r14,#13*4]
+	ldr	r11,[r14,#7*4]
+	ldr	r12,[r14,#2*4]
+	add	r6,r8,r6,ror#2			@ E+=K_xx_xx
+	eor	r9,r9,r10
+	eor	r9,r9,r11
+	eor	r9,r9,r12
+	add	r6,r6,r7,ror#27			@ E+=ROR(A,27)
+	eor	r10,r4,r5			@ F_xx_xx, but not in 40_59
+	mov	r9,r9,ror#31
+	add	r6,r6,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	eor	r10,r3,r10,ror#2		@ F_20_39(B,C,D)
+	add	r6,r6,r10			@ E+=F_20_39(B,C,D)
+	ldr	r9,[r14,#15*4]
+	ldr	r10,[r14,#13*4]
+	ldr	r11,[r14,#7*4]
+	ldr	r12,[r14,#2*4]
+	add	r5,r8,r5,ror#2			@ E+=K_xx_xx
+	eor	r9,r9,r10
+	eor	r9,r9,r11
+	eor	r9,r9,r12
+	add	r5,r5,r6,ror#27			@ E+=ROR(A,27)
+	eor	r10,r3,r4			@ F_xx_xx, but not in 40_59
+	mov	r9,r9,ror#31
+	add	r5,r5,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	eor	r10,r7,r10,ror#2		@ F_20_39(B,C,D)
+	add	r5,r5,r10			@ E+=F_20_39(B,C,D)
+	ldr	r9,[r14,#15*4]
+	ldr	r10,[r14,#13*4]
+	ldr	r11,[r14,#7*4]
+	ldr	r12,[r14,#2*4]
+	add	r4,r8,r4,ror#2			@ E+=K_xx_xx
+	eor	r9,r9,r10
+	eor	r9,r9,r11
+	eor	r9,r9,r12
+	add	r4,r4,r5,ror#27			@ E+=ROR(A,27)
+	eor	r10,r7,r3			@ F_xx_xx, but not in 40_59
+	mov	r9,r9,ror#31
+	add	r4,r4,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	eor	r10,r6,r10,ror#2		@ F_20_39(B,C,D)
+	add	r4,r4,r10			@ E+=F_20_39(B,C,D)
+	ldr	r9,[r14,#15*4]
+	ldr	r10,[r14,#13*4]
+	ldr	r11,[r14,#7*4]
+	ldr	r12,[r14,#2*4]
+	add	r3,r8,r3,ror#2			@ E+=K_xx_xx
+	eor	r9,r9,r10
+	eor	r9,r9,r11
+	eor	r9,r9,r12
+	add	r3,r3,r4,ror#27			@ E+=ROR(A,27)
+	eor	r10,r6,r7			@ F_xx_xx, but not in 40_59
+	mov	r9,r9,ror#31
+	add	r3,r3,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	eor	r10,r5,r10,ror#2		@ F_20_39(B,C,D)
+	add	r3,r3,r10			@ 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	r9,[r14,#15*4]
+	ldr	r10,[r14,#13*4]
+	ldr	r11,[r14,#7*4]
+	ldr	r12,[r14,#2*4]
+	add	r7,r8,r7,ror#2			@ E+=K_xx_xx
+	eor	r9,r9,r10
+	eor	r9,r9,r11
+	eor	r9,r9,r12
+	add	r7,r7,r3,ror#27			@ E+=ROR(A,27)
+	mov	r9,r9,ror#31
+	add	r7,r7,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	and	r10,r4,r5,ror#2
+	orr	r11,r4,r5,ror#2
+	and	r11,r11,r6,ror#2
+	orr	r10,r10,r11			@ F_40_59(B,C,D)
+	add	r7,r7,r10			@ E+=F_40_59(B,C,D)
+	ldr	r9,[r14,#15*4]
+	ldr	r10,[r14,#13*4]
+	ldr	r11,[r14,#7*4]
+	ldr	r12,[r14,#2*4]
+	add	r6,r8,r6,ror#2			@ E+=K_xx_xx
+	eor	r9,r9,r10
+	eor	r9,r9,r11
+	eor	r9,r9,r12
+	add	r6,r6,r7,ror#27			@ E+=ROR(A,27)
+	mov	r9,r9,ror#31
+	add	r6,r6,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	and	r10,r3,r4,ror#2
+	orr	r11,r3,r4,ror#2
+	and	r11,r11,r5,ror#2
+	orr	r10,r10,r11			@ F_40_59(B,C,D)
+	add	r6,r6,r10			@ E+=F_40_59(B,C,D)
+	ldr	r9,[r14,#15*4]
+	ldr	r10,[r14,#13*4]
+	ldr	r11,[r14,#7*4]
+	ldr	r12,[r14,#2*4]
+	add	r5,r8,r5,ror#2			@ E+=K_xx_xx
+	eor	r9,r9,r10
+	eor	r9,r9,r11
+	eor	r9,r9,r12
+	add	r5,r5,r6,ror#27			@ E+=ROR(A,27)
+	mov	r9,r9,ror#31
+	add	r5,r5,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	and	r10,r7,r3,ror#2
+	orr	r11,r7,r3,ror#2
+	and	r11,r11,r4,ror#2
+	orr	r10,r10,r11			@ F_40_59(B,C,D)
+	add	r5,r5,r10			@ E+=F_40_59(B,C,D)
+	ldr	r9,[r14,#15*4]
+	ldr	r10,[r14,#13*4]
+	ldr	r11,[r14,#7*4]
+	ldr	r12,[r14,#2*4]
+	add	r4,r8,r4,ror#2			@ E+=K_xx_xx
+	eor	r9,r9,r10
+	eor	r9,r9,r11
+	eor	r9,r9,r12
+	add	r4,r4,r5,ror#27			@ E+=ROR(A,27)
+	mov	r9,r9,ror#31
+	add	r4,r4,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	and	r10,r6,r7,ror#2
+	orr	r11,r6,r7,ror#2
+	and	r11,r11,r3,ror#2
+	orr	r10,r10,r11			@ F_40_59(B,C,D)
+	add	r4,r4,r10			@ E+=F_40_59(B,C,D)
+	ldr	r9,[r14,#15*4]
+	ldr	r10,[r14,#13*4]
+	ldr	r11,[r14,#7*4]
+	ldr	r12,[r14,#2*4]
+	add	r3,r8,r3,ror#2			@ E+=K_xx_xx
+	eor	r9,r9,r10
+	eor	r9,r9,r11
+	eor	r9,r9,r12
+	add	r3,r3,r4,ror#27			@ E+=ROR(A,27)
+	mov	r9,r9,ror#31
+	add	r3,r3,r9			@ E+=X[i]
+	str	r9,[r14,#-4]!
+	and	r10,r5,r6,ror#2
+	orr	r11,r5,r6,ror#2
+	and	r11,r11,r7,ror#2
+	orr	r10,r10,r11			@ F_40_59(B,C,D)
+	add	r3,r3,r10			@ 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,r9,r10,r11,r12}
+	add	r3,r8,r3
+	add	r4,r9,r4
+	add	r5,r10,r5,ror#2
+	add	r6,r11,r6,ror#2
+	add	r7,r12,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 <appro@openssl.org>"
+.align	2
diff --git a/crypto/sha/asm/sha1-ppc.pl b/crypto/sha/asm/sha1-ppc.pl
new file mode 100755
index 0000000..dcd0fcd
--- /dev/null
+++ b/crypto/sha/asm/sha1-ppc.pl
@@ -0,0 +1,319 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# I let hardware handle unaligned input(*), except on page boundaries
+# (see below for details). Otherwise straightforward implementation
+# with X vector in register bank. The module is big-endian [which is
+# not big deal as there're no little-endian targets left around].
+#
+# (*) this means that this module is inappropriate for PPC403? Does
+#     anybody know if pre-POWER3 can sustain unaligned load?
+
+# 			-m64	-m32
+# ----------------------------------
+# PPC970,gcc-4.0.0	+76%	+59%
+# Power6,xlc-7		+68%	+33%
+
+$flavour = shift;
+
+if ($flavour =~ /64/) {
+	$SIZE_T	=8;
+	$UCMP	="cmpld";
+	$STU	="stdu";
+	$POP	="ld";
+	$PUSH	="std";
+} elsif ($flavour =~ /32/) {
+	$SIZE_T	=4;
+	$UCMP	="cmplw";
+	$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=24*$SIZE_T;
+
+$K  ="r0";
+$sp ="r1";
+$toc="r2";
+$ctx="r3";
+$inp="r4";
+$num="r5";
+$t0 ="r15";
+$t1 ="r6";
+
+$A  ="r7";
+$B  ="r8";
+$C  ="r9";
+$D  ="r10";
+$E  ="r11";
+$T  ="r12";
+
+@V=($A,$B,$C,$D,$E,$T);
+@X=("r16","r17","r18","r19","r20","r21","r22","r23",
+    "r24","r25","r26","r27","r28","r29","r30","r31");
+
+sub BODY_00_19 {
+my ($i,$a,$b,$c,$d,$e,$f)=@_;
+my $j=$i+1;
+$code.=<<___ if ($i==0);
+	lwz	@X[$i],`$i*4`($inp)
+___
+$code.=<<___ if ($i<15);
+	lwz	@X[$j],`$j*4`($inp)
+	add	$f,$K,$e
+	rotlwi	$e,$a,5
+	add	$f,$f,@X[$i]
+	and	$t0,$c,$b
+	add	$f,$f,$e
+	andc	$t1,$d,$b
+	rotlwi	$b,$b,30
+	or	$t0,$t0,$t1
+	add	$f,$f,$t0
+___
+$code.=<<___ if ($i>=15);
+	add	$f,$K,$e
+	rotlwi	$e,$a,5
+	xor	@X[$j%16],@X[$j%16],@X[($j+2)%16]
+	add	$f,$f,@X[$i%16]
+	and	$t0,$c,$b
+	xor	@X[$j%16],@X[$j%16],@X[($j+8)%16]
+	add	$f,$f,$e
+	andc	$t1,$d,$b
+	rotlwi	$b,$b,30
+	or	$t0,$t0,$t1
+	xor	@X[$j%16],@X[$j%16],@X[($j+13)%16]
+	add	$f,$f,$t0
+	rotlwi	@X[$j%16],@X[$j%16],1
+___
+}
+
+sub BODY_20_39 {
+my ($i,$a,$b,$c,$d,$e,$f)=@_;
+my $j=$i+1;
+$code.=<<___ if ($i<79);
+	add	$f,$K,$e
+	rotlwi	$e,$a,5
+	xor	@X[$j%16],@X[$j%16],@X[($j+2)%16]
+	add	$f,$f,@X[$i%16]
+	xor	$t0,$b,$c
+	xor	@X[$j%16],@X[$j%16],@X[($j+8)%16]
+	add	$f,$f,$e
+	rotlwi	$b,$b,30
+	xor	$t0,$t0,$d
+	xor	@X[$j%16],@X[$j%16],@X[($j+13)%16]
+	add	$f,$f,$t0
+	rotlwi	@X[$j%16],@X[$j%16],1
+___
+$code.=<<___ if ($i==79);
+	add	$f,$K,$e
+	rotlwi	$e,$a,5
+	lwz	r16,0($ctx)
+	add	$f,$f,@X[$i%16]
+	xor	$t0,$b,$c
+	lwz	r17,4($ctx)
+	add	$f,$f,$e
+	rotlwi	$b,$b,30
+	lwz	r18,8($ctx)
+	xor	$t0,$t0,$d
+	lwz	r19,12($ctx)
+	add	$f,$f,$t0
+	lwz	r20,16($ctx)
+___
+}
+
+sub BODY_40_59 {
+my ($i,$a,$b,$c,$d,$e,$f)=@_;
+my $j=$i+1;
+$code.=<<___;
+	add	$f,$K,$e
+	rotlwi	$e,$a,5
+	xor	@X[$j%16],@X[$j%16],@X[($j+2)%16]
+	add	$f,$f,@X[$i%16]
+	and	$t0,$b,$c
+	xor	@X[$j%16],@X[$j%16],@X[($j+8)%16]
+	add	$f,$f,$e
+	or	$t1,$b,$c
+	rotlwi	$b,$b,30
+	xor	@X[$j%16],@X[$j%16],@X[($j+13)%16]
+	and	$t1,$t1,$d
+	or	$t0,$t0,$t1
+	rotlwi	@X[$j%16],@X[$j%16],1
+	add	$f,$f,$t0
+___
+}
+
+$code=<<___;
+.machine	"any"
+.text
+
+.globl	.sha1_block_data_order
+.align	4
+.sha1_block_data_order:
+	mflr	r0
+	$STU	$sp,`-($FRAME+64)`($sp)
+	$PUSH	r0,`$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	$A,0($ctx)
+	lwz	$B,4($ctx)
+	lwz	$C,8($ctx)
+	lwz	$D,12($ctx)
+	lwz	$E,16($ctx)
+	andi.	r0,$inp,3
+	bne	Lunaligned
+Laligned:
+	mtctr	$num
+	bl	Lsha1_block_private
+Ldone:
+	$POP	r0,`$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+64`
+	blr
+___
+
+# PowerPC specification allows an implementation to be ill-behaved
+# upon unaligned access which crosses page boundary. "Better safe
+# than sorry" principle makes me treat it specially. But I don't
+# look for particular offending word, but rather for 64-byte input
+# block which crosses the boundary. Once found that block is aligned
+# and hashed separately...
+$code.=<<___;
+.align	4
+Lunaligned:
+	subfic	$t1,$inp,4096
+	andi.	$t1,$t1,4095	; distance to closest page boundary
+	srwi.	$t1,$t1,6	; t1/=64
+	beq	Lcross_page
+	$UCMP	$num,$t1
+	ble-	Laligned	; didn't cross the page boundary
+	mtctr	$t1
+	subfc	$num,$t1,$num
+	bl	Lsha1_block_private
+Lcross_page:
+	li	$t1,16
+	mtctr	$t1
+	addi	r20,$sp,$FRAME	; spot below the frame
+Lmemcpy:
+	lbz	r16,0($inp)
+	lbz	r17,1($inp)
+	lbz	r18,2($inp)
+	lbz	r19,3($inp)
+	addi	$inp,$inp,4
+	stb	r16,0(r20)
+	stb	r17,1(r20)
+	stb	r18,2(r20)
+	stb	r19,3(r20)
+	addi	r20,r20,4
+	bdnz	Lmemcpy
+
+	$PUSH	$inp,`$FRAME-$SIZE_T*19`($sp)
+	li	$t1,1
+	addi	$inp,$sp,$FRAME
+	mtctr	$t1
+	bl	Lsha1_block_private
+	$POP	$inp,`$FRAME-$SIZE_T*19`($sp)
+	addic.	$num,$num,-1
+	bne-	Lunaligned
+	b	Ldone
+___
+
+# This is private block function, which uses tailored calling
+# interface, namely upon entry SHA_CTX is pre-loaded to given
+# registers and counter register contains amount of chunks to
+# digest...
+$code.=<<___;
+.align	4
+Lsha1_block_private:
+___
+$code.=<<___;	# load K_00_19
+	lis	$K,0x5a82
+	ori	$K,$K,0x7999
+___
+for($i=0;$i<20;$i++)	{ &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;	# load K_20_39
+	lis	$K,0x6ed9
+	ori	$K,$K,0xeba1
+___
+for(;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;	# load K_40_59
+	lis	$K,0x8f1b
+	ori	$K,$K,0xbcdc
+___
+for(;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;	# load K_60_79
+	lis	$K,0xca62
+	ori	$K,$K,0xc1d6
+___
+for(;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+	add	r16,r16,$E
+	add	r17,r17,$T
+	add	r18,r18,$A
+	add	r19,r19,$B
+	add	r20,r20,$C
+	stw	r16,0($ctx)
+	mr	$A,r16
+	stw	r17,4($ctx)
+	mr	$B,r17
+	stw	r18,8($ctx)
+	mr	$C,r18
+	stw	r19,12($ctx)
+	mr	$D,r19
+	stw	r20,16($ctx)
+	mr	$E,r20
+	addi	$inp,$inp,`16*4`
+	bdnz-	Lsha1_block_private
+	blr
+___
+$code.=<<___;
+.asciz	"SHA1 block transform for PPC, CRYPTOGAMS by <appro\@fy.chalmers.se>"
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/crypto/sha/asm/sha1-s390x.pl b/crypto/sha/asm/sha1-s390x.pl
new file mode 100644
index 0000000..4b17848
--- /dev/null
+++ b/crypto/sha/asm/sha1-s390x.pl
@@ -0,0 +1,226 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# SHA1 block procedure for s390x.
+
+# April 2007.
+#
+# Performance is >30% better than gcc 3.3 generated code. But the real
+# twist is that SHA1 hardware support is detected and utilized. In
+# which case performance can reach further >4.5x for larger chunks.
+
+# January 2009.
+#
+# Optimize Xupdate for amount of memory references and reschedule
+# instructions to favour dual-issue z10 pipeline. On z10 hardware is
+# "only" ~2.3x faster than software.
+
+$kimdfunc=1;	# magic function code for kimd instruction
+
+$output=shift;
+open STDOUT,">$output";
+
+$K_00_39="%r0"; $K=$K_00_39;
+$K_40_79="%r1";
+$ctx="%r2";	$prefetch="%r2";
+$inp="%r3";
+$len="%r4";
+
+$A="%r5";
+$B="%r6";
+$C="%r7";
+$D="%r8";
+$E="%r9";	@V=($A,$B,$C,$D,$E);
+$t0="%r10";
+$t1="%r11";
+@X=("%r12","%r13","%r14");
+$sp="%r15";
+
+$frame=160+16*4;
+
+sub Xupdate {
+my $i=shift;
+
+$code.=<<___ if ($i==15);
+	lg	$prefetch,160($sp)	### Xupdate(16) warm-up
+	lr	$X[0],$X[2]
+___
+return if ($i&1);	# Xupdate is vectorized and executed every 2nd cycle
+$code.=<<___ if ($i<16);
+	lg	$X[0],`$i*4`($inp)	### Xload($i)
+	rllg	$X[1],$X[0],32
+___
+$code.=<<___ if ($i>=16);
+	xgr	$X[0],$prefetch		### Xupdate($i)
+	lg	$prefetch,`160+4*(($i+2)%16)`($sp)
+	xg	$X[0],`160+4*(($i+8)%16)`($sp)
+	xgr	$X[0],$prefetch
+	rll	$X[0],$X[0],1
+	rllg	$X[1],$X[0],32
+	rll	$X[1],$X[1],1
+	rllg	$X[0],$X[1],32
+	lr	$X[2],$X[1]		# feedback
+___
+$code.=<<___ if ($i<=70);
+	stg	$X[0],`160+4*($i%16)`($sp)
+___
+unshift(@X,pop(@X));
+}
+
+sub BODY_00_19 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $xi=$X[1];
+
+	&Xupdate($i);
+$code.=<<___;
+	alr	$e,$K		### $i
+	rll	$t1,$a,5
+	lr	$t0,$d
+	xr	$t0,$c
+	alr	$e,$t1
+	nr	$t0,$b
+	alr	$e,$xi
+	xr	$t0,$d
+	rll	$b,$b,30
+	alr	$e,$t0
+___
+}
+
+sub BODY_20_39 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $xi=$X[1];
+
+	&Xupdate($i);
+$code.=<<___;
+	alr	$e,$K		### $i
+	rll	$t1,$a,5
+	lr	$t0,$b
+	alr	$e,$t1
+	xr	$t0,$c
+	alr	$e,$xi
+	xr	$t0,$d
+	rll	$b,$b,30
+	alr	$e,$t0
+___
+}
+
+sub BODY_40_59 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $xi=$X[1];
+
+	&Xupdate($i);
+$code.=<<___;
+	alr	$e,$K		### $i
+	rll	$t1,$a,5
+	lr	$t0,$b
+	alr	$e,$t1
+	or	$t0,$c
+	lr	$t1,$b
+	nr	$t0,$d
+	nr	$t1,$c
+	alr	$e,$xi
+	or	$t0,$t1
+	rll	$b,$b,30
+	alr	$e,$t0
+___
+}
+
+$code.=<<___;
+.text
+.align	64
+.type	Ktable,\@object
+Ktable: .long	0x5a827999,0x6ed9eba1,0x8f1bbcdc,0xca62c1d6
+	.skip	48	#.long	0,0,0,0,0,0,0,0,0,0,0,0
+.size	Ktable,.-Ktable
+.globl	sha1_block_data_order
+.type	sha1_block_data_order,\@function
+sha1_block_data_order:
+___
+$code.=<<___ if ($kimdfunc);
+	larl	%r1,OPENSSL_s390xcap_P
+	lg	%r0,0(%r1)
+	tmhl	%r0,0x4000	# check for message-security assist
+	jz	.Lsoftware
+	lghi	%r0,0
+	la	%r1,16($sp)
+	.long	0xb93e0002	# kimd %r0,%r2
+	lg	%r0,16($sp)
+	tmhh	%r0,`0x8000>>$kimdfunc`
+	jz	.Lsoftware
+	lghi	%r0,$kimdfunc
+	lgr	%r1,$ctx
+	lgr	%r2,$inp
+	sllg	%r3,$len,6
+	.long	0xb93e0002	# kimd %r0,%r2
+	brc	1,.-4		# pay attention to "partial completion"
+	br	%r14
+.align	16
+.Lsoftware:
+___
+$code.=<<___;
+	lghi	%r1,-$frame
+	stg	$ctx,16($sp)
+	stmg	%r6,%r15,48($sp)
+	lgr	%r0,$sp
+	la	$sp,0(%r1,$sp)
+	stg	%r0,0($sp)
+
+	larl	$t0,Ktable
+	llgf	$A,0($ctx)
+	llgf	$B,4($ctx)
+	llgf	$C,8($ctx)
+	llgf	$D,12($ctx)
+	llgf	$E,16($ctx)
+
+	lg	$K_00_39,0($t0)
+	lg	$K_40_79,8($t0)
+
+.Lloop:
+	rllg	$K_00_39,$K_00_39,32
+___
+for ($i=0;$i<20;$i++)	{ &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+	rllg	$K_00_39,$K_00_39,32
+___
+for (;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;	$K=$K_40_79;
+	rllg	$K_40_79,$K_40_79,32
+___
+for (;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+	rllg	$K_40_79,$K_40_79,32
+___
+for (;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+
+	lg	$ctx,`$frame+16`($sp)
+	la	$inp,64($inp)
+	al	$A,0($ctx)
+	al	$B,4($ctx)
+	al	$C,8($ctx)
+	al	$D,12($ctx)
+	al	$E,16($ctx)
+	st	$A,0($ctx)
+	st	$B,4($ctx)
+	st	$C,8($ctx)
+	st	$D,12($ctx)
+	st	$E,16($ctx)
+	brct	$len,.Lloop
+
+	lmg	%r6,%r15,`$frame+48`($sp)
+	br	%r14
+.size	sha1_block_data_order,.-sha1_block_data_order
+.string	"SHA1 block transform for s390x, CRYPTOGAMS by <appro\@openssl.org>"
+.comm	OPENSSL_s390xcap_P,8,8
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+
+print $code;
+close STDOUT;
diff --git a/crypto/sha/asm/sha1-sparcv9.pl b/crypto/sha/asm/sha1-sparcv9.pl
new file mode 100644
index 0000000..8306fc8
--- /dev/null
+++ b/crypto/sha/asm/sha1-sparcv9.pl
@@ -0,0 +1,283 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# Performance improvement is not really impressive on pre-T1 CPU: +8%
+# over Sun C and +25% over gcc [3.3]. While on T1, a.k.a. Niagara, it
+# turned to be 40% faster than 64-bit code generated by Sun C 5.8 and
+# >2x than 64-bit code generated by gcc 3.4. And there is a gimmick.
+# X[16] vector is packed to 8 64-bit registers and as result nothing
+# is spilled on stack. In addition input data is loaded in compact
+# instruction sequence, thus minimizing the window when the code is
+# subject to [inter-thread] cache-thrashing hazard. The goal is to
+# ensure scalability on UltraSPARC T1, or rather to avoid decay when
+# amount of active threads exceeds the number of physical cores.
+
+$bits=32;
+for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
+if ($bits==64)	{ $bias=2047; $frame=192; }
+else		{ $bias=0;    $frame=112; }
+
+$output=shift;
+open STDOUT,">$output";
+
+@X=("%o0","%o1","%o2","%o3","%o4","%o5","%g1","%o7");
+$rot1m="%g2";
+$tmp64="%g3";
+$Xi="%g4";
+$A="%l0";
+$B="%l1";
+$C="%l2";
+$D="%l3";
+$E="%l4";
+@V=($A,$B,$C,$D,$E);
+$K_00_19="%l5";
+$K_20_39="%l6";
+$K_40_59="%l7";
+$K_60_79="%g5";
+@K=($K_00_19,$K_20_39,$K_40_59,$K_60_79);
+
+$ctx="%i0";
+$inp="%i1";
+$len="%i2";
+$tmp0="%i3";
+$tmp1="%i4";
+$tmp2="%i5";
+
+sub BODY_00_15 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $xi=($i&1)?@X[($i/2)%8]:$Xi;
+
+$code.=<<___;
+	sll	$a,5,$tmp0		!! $i
+	add	@K[$i/20],$e,$e
+	srl	$a,27,$tmp1
+	add	$tmp0,$e,$e
+	and	$c,$b,$tmp0
+	add	$tmp1,$e,$e
+	sll	$b,30,$tmp2
+	andn	$d,$b,$tmp1
+	srl	$b,2,$b
+	or	$tmp1,$tmp0,$tmp1
+	or	$tmp2,$b,$b
+	add	$xi,$e,$e
+___
+if ($i&1 && $i<15) {
+	$code.=
+	"	srlx	@X[(($i+1)/2)%8],32,$Xi\n";
+}
+$code.=<<___;
+	add	$tmp1,$e,$e
+___
+}
+
+sub Xupdate {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i/2;
+
+if ($i&1) {
+$code.=<<___;
+	sll	$a,5,$tmp0		!! $i
+	add	@K[$i/20],$e,$e
+	srl	$a,27,$tmp1
+___
+} else {
+$code.=<<___;
+	sllx	@X[($j+6)%8],32,$Xi	! Xupdate($i)
+	xor	@X[($j+1)%8],@X[$j%8],@X[$j%8]
+	srlx	@X[($j+7)%8],32,$tmp1
+	xor	@X[($j+4)%8],@X[$j%8],@X[$j%8]
+	sll	$a,5,$tmp0		!! $i
+	or	$tmp1,$Xi,$Xi
+	add	@K[$i/20],$e,$e		!!
+	xor	$Xi,@X[$j%8],@X[$j%8]
+	srlx	@X[$j%8],31,$Xi
+	add	@X[$j%8],@X[$j%8],@X[$j%8]
+	and	$Xi,$rot1m,$Xi
+	andn	@X[$j%8],$rot1m,@X[$j%8]
+	srl	$a,27,$tmp1		!!
+	or	$Xi,@X[$j%8],@X[$j%8]
+___
+}
+}
+
+sub BODY_16_19 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+
+	&Xupdate(@_);
+    if ($i&1) {
+	$xi=@X[($i/2)%8];
+    } else {
+	$xi=$Xi;
+	$code.="\tsrlx	@X[($i/2)%8],32,$xi\n";
+    }
+$code.=<<___;
+	add	$tmp0,$e,$e		!!
+	and	$c,$b,$tmp0
+	add	$tmp1,$e,$e
+	sll	$b,30,$tmp2
+	add	$xi,$e,$e
+	andn	$d,$b,$tmp1
+	srl	$b,2,$b
+	or	$tmp1,$tmp0,$tmp1
+	or	$tmp2,$b,$b
+	add	$tmp1,$e,$e
+___
+}
+
+sub BODY_20_39 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $xi;
+	&Xupdate(@_);
+    if ($i&1) {
+	$xi=@X[($i/2)%8];
+    } else {
+	$xi=$Xi;
+	$code.="\tsrlx	@X[($i/2)%8],32,$xi\n";
+    }
+$code.=<<___;
+	add	$tmp0,$e,$e		!!
+	xor	$c,$b,$tmp0
+	add	$tmp1,$e,$e
+	sll	$b,30,$tmp2
+	xor	$d,$tmp0,$tmp1
+	srl	$b,2,$b
+	add	$tmp1,$e,$e
+	or	$tmp2,$b,$b
+	add	$xi,$e,$e
+___
+}
+
+sub BODY_40_59 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $xi;
+	&Xupdate(@_);
+    if ($i&1) {
+	$xi=@X[($i/2)%8];
+    } else {
+	$xi=$Xi;
+	$code.="\tsrlx	@X[($i/2)%8],32,$xi\n";
+    }
+$code.=<<___;
+	add	$tmp0,$e,$e		!!
+	and	$c,$b,$tmp0
+	add	$tmp1,$e,$e
+	sll	$b,30,$tmp2
+	or	$c,$b,$tmp1
+	srl	$b,2,$b
+	and	$d,$tmp1,$tmp1
+	add	$xi,$e,$e
+	or	$tmp1,$tmp0,$tmp1
+	or	$tmp2,$b,$b
+	add	$tmp1,$e,$e
+___
+}
+
+$code.=<<___ if ($bits==64);
+.register	%g2,#scratch
+.register	%g3,#scratch
+___
+$code.=<<___;
+.section	".text",#alloc,#execinstr
+
+.align	32
+.globl	sha1_block_data_order
+sha1_block_data_order:
+	save	%sp,-$frame,%sp
+	sllx	$len,6,$len
+	add	$inp,$len,$len
+
+	or	%g0,1,$rot1m
+	sllx	$rot1m,32,$rot1m
+	or	$rot1m,1,$rot1m
+
+	ld	[$ctx+0],$A
+	ld	[$ctx+4],$B
+	ld	[$ctx+8],$C
+	ld	[$ctx+12],$D
+	ld	[$ctx+16],$E
+	andn	$inp,7,$tmp0
+
+	sethi	%hi(0x5a827999),$K_00_19
+	or	$K_00_19,%lo(0x5a827999),$K_00_19
+	sethi	%hi(0x6ed9eba1),$K_20_39
+	or	$K_20_39,%lo(0x6ed9eba1),$K_20_39
+	sethi	%hi(0x8f1bbcdc),$K_40_59
+	or	$K_40_59,%lo(0x8f1bbcdc),$K_40_59
+	sethi	%hi(0xca62c1d6),$K_60_79
+	or	$K_60_79,%lo(0xca62c1d6),$K_60_79
+
+.Lloop:
+	ldx	[$tmp0+0],@X[0]
+	ldx	[$tmp0+16],@X[2]
+	ldx	[$tmp0+32],@X[4]
+	ldx	[$tmp0+48],@X[6]
+	and	$inp,7,$tmp1
+	ldx	[$tmp0+8],@X[1]
+	sll	$tmp1,3,$tmp1
+	ldx	[$tmp0+24],@X[3]
+	subcc	%g0,$tmp1,$tmp2	! should be 64-$tmp1, but -$tmp1 works too
+	ldx	[$tmp0+40],@X[5]
+	bz,pt	%icc,.Laligned
+	ldx	[$tmp0+56],@X[7]
+
+	sllx	@X[0],$tmp1,@X[0]
+	ldx	[$tmp0+64],$tmp64
+___
+for($i=0;$i<7;$i++)
+{   $code.=<<___;
+	srlx	@X[$i+1],$tmp2,$Xi
+	sllx	@X[$i+1],$tmp1,@X[$i+1]
+	or	$Xi,@X[$i],@X[$i]
+___
+}
+$code.=<<___;
+	srlx	$tmp64,$tmp2,$tmp64
+	or	$tmp64,@X[7],@X[7]
+.Laligned:
+	srlx	@X[0],32,$Xi
+___
+for ($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
+for (;$i<20;$i++)	{ &BODY_16_19($i,@V); unshift(@V,pop(@V)); }
+for (;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+for (;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
+for (;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+
+	ld	[$ctx+0],@X[0]
+	ld	[$ctx+4],@X[1]
+	ld	[$ctx+8],@X[2]
+	ld	[$ctx+12],@X[3]
+	add	$inp,64,$inp
+	ld	[$ctx+16],@X[4]
+	cmp	$inp,$len
+
+	add	$A,@X[0],$A
+	st	$A,[$ctx+0]
+	add	$B,@X[1],$B
+	st	$B,[$ctx+4]
+	add	$C,@X[2],$C
+	st	$C,[$ctx+8]
+	add	$D,@X[3],$D
+	st	$D,[$ctx+12]
+	add	$E,@X[4],$E
+	st	$E,[$ctx+16]
+
+	bne	`$bits==64?"%xcc":"%icc"`,.Lloop
+	andn	$inp,7,$tmp0
+
+	ret
+	restore
+.type	sha1_block_data_order,#function
+.size	sha1_block_data_order,(.-sha1_block_data_order)
+.asciz	"SHA1 block transform for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/crypto/sha/asm/sha1-sparcv9a.pl b/crypto/sha/asm/sha1-sparcv9a.pl
new file mode 100644
index 0000000..15eb854
--- /dev/null
+++ b/crypto/sha/asm/sha1-sparcv9a.pl
@@ -0,0 +1,600 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# January 2009
+#
+# Provided that UltraSPARC VIS instructions are pipe-lined(*) and
+# pairable(*) with IALU ones, offloading of Xupdate to the UltraSPARC
+# Graphic Unit would make it possible to achieve higher instruction-
+# level parallelism, ILP, and thus higher performance. It should be
+# explicitly noted that ILP is the keyword, and it means that this
+# code would be unsuitable for cores like UltraSPARC-Tx. The idea is
+# not really novel, Sun had VIS-powered implementation for a while.
+# Unlike Sun's implementation this one can process multiple unaligned
+# input blocks, and as such works as drop-in replacement for OpenSSL
+# sha1_block_data_order. Performance improvement was measured to be
+# 40% over pure IALU sha1-sparcv9.pl on UltraSPARC-IIi, but 12% on
+# UltraSPARC-III. See below for discussion...
+#
+# The module does not present direct interest for OpenSSL, because
+# it doesn't provide better performance on contemporary SPARCv9 CPUs,
+# UltraSPARC-Tx and SPARC64-V[II] to be specific. Those who feel they
+# absolutely must score on UltraSPARC-I-IV can simply replace
+# crypto/sha/asm/sha1-sparcv9.pl with this module.
+#
+# (*)	"Pipe-lined" means that even if it takes several cycles to
+#	complete, next instruction using same functional unit [but not
+#	depending on the result of the current instruction] can start
+#	execution without having to wait for the unit. "Pairable"
+#	means that two [or more] independent instructions can be
+#	issued at the very same time.
+
+$bits=32;
+for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
+if ($bits==64)	{ $bias=2047; $frame=192; }
+else		{ $bias=0;    $frame=112; }
+
+$output=shift;
+open STDOUT,">$output";
+
+$ctx="%i0";
+$inp="%i1";
+$len="%i2";
+$tmp0="%i3";
+$tmp1="%i4";
+$tmp2="%i5";
+$tmp3="%g5";
+
+$base="%g1";
+$align="%g4";
+$Xfer="%o5";
+$nXfer=$tmp3;
+$Xi="%o7";
+
+$A="%l0";
+$B="%l1";
+$C="%l2";
+$D="%l3";
+$E="%l4";
+@V=($A,$B,$C,$D,$E);
+
+$Actx="%o0";
+$Bctx="%o1";
+$Cctx="%o2";
+$Dctx="%o3";
+$Ectx="%o4";
+
+$fmul="%f32";
+$VK_00_19="%f34";
+$VK_20_39="%f36";
+$VK_40_59="%f38";
+$VK_60_79="%f40";
+@VK=($VK_00_19,$VK_20_39,$VK_40_59,$VK_60_79);
+@X=("%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
+    "%f8", "%f9","%f10","%f11","%f12","%f13","%f14","%f15","%f16");
+
+# This is reference 2x-parallelized VIS-powered Xupdate procedure. It
+# covers even K_NN_MM addition...
+sub Xupdate {
+my ($i)=@_;
+my $K=@VK[($i+16)/20];
+my $j=($i+16)%16;
+
+#	[ provided that GSR.alignaddr_offset is 5, $mul contains
+#	  0x100ULL<<32|0x100 value and K_NN_MM are pre-loaded to
+#	  chosen registers... ]
+$code.=<<___;
+	fxors		@X[($j+13)%16],@X[$j],@X[$j]	!-1/-1/-1:X[0]^=X[13]
+	fxors		@X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
+	fxor		@X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
+	fxor		%f18,@X[$j],@X[$j]		! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
+	faligndata	@X[$j],@X[$j],%f18		! 3/ 7/ 5:Tmp=X[0,1]>>>24
+	fpadd32		@X[$j],@X[$j],@X[$j]		! 4/ 8/ 6:X[0,1]<<=1
+	fmul8ulx16	%f18,$fmul,%f18			! 5/10/ 7:Tmp>>=7, Tmp&=1
+	![fxors		%f15,%f2,%f2]
+	for		%f18,@X[$j],@X[$j]		! 8/14/10:X[0,1]|=Tmp
+	![fxors		%f0,%f3,%f3]			!10/17/12:X[0] dependency
+	fpadd32		$K,@X[$j],%f20
+	std		%f20,[$Xfer+`4*$j`]
+___
+# The numbers delimited with slash are the earliest possible dispatch
+# cycles for given instruction assuming 1 cycle latency for simple VIS
+# instructions, such as on UltraSPARC-I&II, 3 cycles latency, such as
+# on UltraSPARC-III&IV, and 2 cycles latency(*), respectively. Being
+# 2x-parallelized the procedure is "worth" 5, 8.5 or 6 ticks per SHA1
+# round. As [long as] FPU/VIS instructions are perfectly pairable with
+# IALU ones, the round timing is defined by the maximum between VIS
+# and IALU timings. The latter varies from round to round and averages
+# out at 6.25 ticks. This means that USI&II should operate at IALU
+# rate, while USIII&IV - at VIS rate. This explains why performance
+# improvement varies among processors. Well, given that pure IALU
+# sha1-sparcv9.pl module exhibits virtually uniform performance of
+# ~9.3 cycles per SHA1 round. Timings mentioned above are theoretical
+# lower limits. Real-life performance was measured to be 6.6 cycles
+# per SHA1 round on USIIi and 8.3 on USIII. The latter is lower than
+# half-round VIS timing, because there are 16 Xupdate-free rounds,
+# which "push down" average theoretical timing to 8 cycles...
+
+# (*)	SPARC64-V[II] was originally believed to have 2 cycles VIS
+#	latency. Well, it might have, but it doesn't have dedicated
+#	VIS-unit. Instead, VIS instructions are executed by other
+#	functional units, ones used here - by IALU. This doesn't
+#	improve effective ILP...
+}
+
+# The reference Xupdate procedure is then "strained" over *pairs* of
+# BODY_NN_MM and kind of modulo-scheduled in respect to X[n]^=X[n+13]
+# and K_NN_MM addition. It's "running" 15 rounds ahead, which leaves
+# plenty of room to amortize for read-after-write hazard, as well as
+# to fetch and align input for the next spin. The VIS instructions are
+# scheduled for latency of 2 cycles, because there are not enough IALU
+# instructions to schedule for latency of 3, while scheduling for 1
+# would give no gain on USI&II anyway.
+
+sub BODY_00_19 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i&~1;
+my $k=($j+16+2)%16;	# ahead reference
+my $l=($j+16-2)%16;	# behind reference
+my $K=@VK[($j+16-2)/20];
+
+$j=($j+16)%16;
+
+$code.=<<___ if (!($i&1));
+	sll		$a,5,$tmp0			!! $i
+	and		$c,$b,$tmp3
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	 fxors		@X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	 fxor		@X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
+	sll		$b,30,$tmp2
+	add		$tmp1,$e,$e
+	andn		$d,$b,$tmp1
+	add		$Xi,$e,$e
+	 fxor		%f18,@X[$j],@X[$j]		! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
+	srl		$b,2,$b
+	or		$tmp1,$tmp3,$tmp1
+	or		$tmp2,$b,$b
+	add		$tmp1,$e,$e
+	 faligndata	@X[$j],@X[$j],%f18		! 3/ 7/ 5:Tmp=X[0,1]>>>24
+___
+$code.=<<___ if ($i&1);
+	sll		$a,5,$tmp0			!! $i
+	and		$c,$b,$tmp3
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	 fpadd32	@X[$j],@X[$j],@X[$j]		! 4/ 8/ 6:X[0,1]<<=1
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	 fmul8ulx16	%f18,$fmul,%f18			! 5/10/ 7:Tmp>>=7, Tmp&=1
+	sll		$b,30,$tmp2
+	add		$tmp1,$e,$e
+	 fpadd32	$K,@X[$l],%f20			!
+	andn		$d,$b,$tmp1
+	add		$Xi,$e,$e
+	 fxors		@X[($k+13)%16],@X[$k],@X[$k]	!-1/-1/-1:X[0]^=X[13]
+	srl		$b,2,$b
+	or		$tmp1,$tmp3,$tmp1
+	 fxor		%f18,@X[$j],@X[$j]		! 8/14/10:X[0,1]|=Tmp
+	or		$tmp2,$b,$b
+	add		$tmp1,$e,$e
+___
+$code.=<<___ if ($i&1 && $i>=2);
+	 std		%f20,[$Xfer+`4*$l`]		!
+___
+}
+
+sub BODY_20_39 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i&~1;
+my $k=($j+16+2)%16;	# ahead reference
+my $l=($j+16-2)%16;	# behind reference
+my $K=@VK[($j+16-2)/20];
+
+$j=($j+16)%16;
+
+$code.=<<___ if (!($i&1) && $i<64);
+	sll		$a,5,$tmp0			!! $i
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	 fxors		@X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	 fxor		@X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
+	xor		$c,$b,$tmp0
+	add		$tmp1,$e,$e
+	sll		$b,30,$tmp2
+	xor		$d,$tmp0,$tmp1
+	 fxor		%f18,@X[$j],@X[$j]		! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
+	srl		$b,2,$b
+	add		$tmp1,$e,$e
+	or		$tmp2,$b,$b
+	add		$Xi,$e,$e
+	 faligndata	@X[$j],@X[$j],%f18		! 3/ 7/ 5:Tmp=X[0,1]>>>24
+___
+$code.=<<___ if ($i&1 && $i<64);
+	sll		$a,5,$tmp0			!! $i
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	 fpadd32	@X[$j],@X[$j],@X[$j]		! 4/ 8/ 6:X[0,1]<<=1
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	 fmul8ulx16	%f18,$fmul,%f18			! 5/10/ 7:Tmp>>=7, Tmp&=1
+	xor		$c,$b,$tmp0
+	add		$tmp1,$e,$e
+	 fpadd32	$K,@X[$l],%f20			!
+	sll		$b,30,$tmp2
+	xor		$d,$tmp0,$tmp1
+	 fxors		@X[($k+13)%16],@X[$k],@X[$k]	!-1/-1/-1:X[0]^=X[13]
+	srl		$b,2,$b
+	add		$tmp1,$e,$e
+	 fxor		%f18,@X[$j],@X[$j]		! 8/14/10:X[0,1]|=Tmp
+	or		$tmp2,$b,$b
+	add		$Xi,$e,$e
+	 std		%f20,[$Xfer+`4*$l`]		!
+___
+$code.=<<___ if ($i==64);
+	sll		$a,5,$tmp0			!! $i
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	 fpadd32	$K,@X[$l],%f20
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	xor		$c,$b,$tmp0
+	add		$tmp1,$e,$e
+	sll		$b,30,$tmp2
+	xor		$d,$tmp0,$tmp1
+	 std		%f20,[$Xfer+`4*$l`]
+	srl		$b,2,$b
+	add		$tmp1,$e,$e
+	or		$tmp2,$b,$b
+	add		$Xi,$e,$e
+___
+$code.=<<___ if ($i>64);
+	sll		$a,5,$tmp0			!! $i
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	xor		$c,$b,$tmp0
+	add		$tmp1,$e,$e
+	sll		$b,30,$tmp2
+	xor		$d,$tmp0,$tmp1
+	srl		$b,2,$b
+	add		$tmp1,$e,$e
+	or		$tmp2,$b,$b
+	add		$Xi,$e,$e
+___
+}
+
+sub BODY_40_59 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i&~1;
+my $k=($j+16+2)%16;	# ahead reference
+my $l=($j+16-2)%16;	# behind reference
+my $K=@VK[($j+16-2)/20];
+
+$j=($j+16)%16;
+
+$code.=<<___ if (!($i&1));
+	sll		$a,5,$tmp0			!! $i
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	 fxors		@X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	 fxor		@X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
+	and		$c,$b,$tmp0
+	add		$tmp1,$e,$e
+	sll		$b,30,$tmp2
+	or		$c,$b,$tmp1
+	 fxor		%f18,@X[$j],@X[$j]		! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
+	srl		$b,2,$b
+	and		$d,$tmp1,$tmp1
+	add		$Xi,$e,$e
+	or		$tmp1,$tmp0,$tmp1
+	 faligndata	@X[$j],@X[$j],%f18		! 3/ 7/ 5:Tmp=X[0,1]>>>24
+	or		$tmp2,$b,$b
+	add		$tmp1,$e,$e
+	 fpadd32	@X[$j],@X[$j],@X[$j]		! 4/ 8/ 6:X[0,1]<<=1
+___
+$code.=<<___ if ($i&1);
+	sll		$a,5,$tmp0			!! $i
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	 fmul8ulx16	%f18,$fmul,%f18			! 5/10/ 7:Tmp>>=7, Tmp&=1
+	and		$c,$b,$tmp0
+	add		$tmp1,$e,$e
+	 fpadd32	$K,@X[$l],%f20			!
+	sll		$b,30,$tmp2
+	or		$c,$b,$tmp1
+	 fxors		@X[($k+13)%16],@X[$k],@X[$k]	!-1/-1/-1:X[0]^=X[13]
+	srl		$b,2,$b
+	and		$d,$tmp1,$tmp1
+	 fxor		%f18,@X[$j],@X[$j]		! 8/14/10:X[0,1]|=Tmp
+	add		$Xi,$e,$e
+	or		$tmp1,$tmp0,$tmp1
+	or		$tmp2,$b,$b
+	add		$tmp1,$e,$e
+	 std		%f20,[$Xfer+`4*$l`]		!
+___
+}
+
+# If there is more data to process, then we pre-fetch the data for
+# next iteration in last ten rounds...
+sub BODY_70_79 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i&~1;
+my $m=($i%8)*2;
+
+$j=($j+16)%16;
+
+$code.=<<___ if ($i==70);
+	sll		$a,5,$tmp0			!! $i
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	 ldd		[$inp+64],@X[0]
+	xor		$c,$b,$tmp0
+	add		$tmp1,$e,$e
+	sll		$b,30,$tmp2
+	xor		$d,$tmp0,$tmp1
+	srl		$b,2,$b
+	add		$tmp1,$e,$e
+	or		$tmp2,$b,$b
+	add		$Xi,$e,$e
+
+	and		$inp,-64,$nXfer
+	inc		64,$inp
+	and		$nXfer,255,$nXfer
+	alignaddr	%g0,$align,%g0
+	add		$base,$nXfer,$nXfer
+___
+$code.=<<___ if ($i==71);
+	sll		$a,5,$tmp0			!! $i
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	xor		$c,$b,$tmp0
+	add		$tmp1,$e,$e
+	sll		$b,30,$tmp2
+	xor		$d,$tmp0,$tmp1
+	srl		$b,2,$b
+	add		$tmp1,$e,$e
+	or		$tmp2,$b,$b
+	add		$Xi,$e,$e
+___
+$code.=<<___ if ($i>=72);
+	 faligndata	@X[$m],@X[$m+2],@X[$m]
+	sll		$a,5,$tmp0			!! $i
+	ld		[$Xfer+`4*($i%16)`],$Xi
+	srl		$a,27,$tmp1
+	add		$tmp0,$e,$e
+	xor		$c,$b,$tmp0
+	add		$tmp1,$e,$e
+	 fpadd32	$VK_00_19,@X[$m],%f20
+	sll		$b,30,$tmp2
+	xor		$d,$tmp0,$tmp1
+	srl		$b,2,$b
+	add		$tmp1,$e,$e
+	or		$tmp2,$b,$b
+	add		$Xi,$e,$e
+___
+$code.=<<___ if ($i<77);
+	 ldd		[$inp+`8*($i+1-70)`],@X[2*($i+1-70)]
+___
+$code.=<<___ if ($i==77);	# redundant if $inp was aligned
+	 add		$align,63,$tmp0
+	 and		$tmp0,-8,$tmp0
+	 ldd		[$inp+$tmp0],@X[16]
+___
+$code.=<<___ if ($i>=72);
+	 std		%f20,[$nXfer+`4*$m`]
+___
+}
+
+$code.=<<___;
+.section	".text",#alloc,#execinstr
+
+.align	64
+vis_const:
+.long	0x5a827999,0x5a827999	! K_00_19
+.long	0x6ed9eba1,0x6ed9eba1	! K_20_39
+.long	0x8f1bbcdc,0x8f1bbcdc	! K_40_59
+.long	0xca62c1d6,0xca62c1d6	! K_60_79
+.long	0x00000100,0x00000100
+.align	64
+.type	vis_const,#object
+.size	vis_const,(.-vis_const)
+
+.globl	sha1_block_data_order
+sha1_block_data_order:
+	save	%sp,-$frame,%sp
+	add	%fp,$bias-256,$base
+
+1:	call	.+8
+	add	%o7,vis_const-1b,$tmp0
+
+	ldd	[$tmp0+0],$VK_00_19
+	ldd	[$tmp0+8],$VK_20_39
+	ldd	[$tmp0+16],$VK_40_59
+	ldd	[$tmp0+24],$VK_60_79
+	ldd	[$tmp0+32],$fmul
+
+	ld	[$ctx+0],$Actx
+	and	$base,-256,$base
+	ld	[$ctx+4],$Bctx
+	sub	$base,$bias+$frame,%sp
+	ld	[$ctx+8],$Cctx
+	and	$inp,7,$align
+	ld	[$ctx+12],$Dctx
+	and	$inp,-8,$inp
+	ld	[$ctx+16],$Ectx
+
+	! X[16] is maintained in FP register bank
+	alignaddr	%g0,$align,%g0
+	ldd		[$inp+0],@X[0]
+	sub		$inp,-64,$Xfer
+	ldd		[$inp+8],@X[2]
+	and		$Xfer,-64,$Xfer
+	ldd		[$inp+16],@X[4]
+	and		$Xfer,255,$Xfer
+	ldd		[$inp+24],@X[6]
+	add		$base,$Xfer,$Xfer
+	ldd		[$inp+32],@X[8]
+	ldd		[$inp+40],@X[10]
+	ldd		[$inp+48],@X[12]
+	brz,pt		$align,.Laligned
+	ldd		[$inp+56],@X[14]
+
+	ldd		[$inp+64],@X[16]
+	faligndata	@X[0],@X[2],@X[0]
+	faligndata	@X[2],@X[4],@X[2]
+	faligndata	@X[4],@X[6],@X[4]
+	faligndata	@X[6],@X[8],@X[6]
+	faligndata	@X[8],@X[10],@X[8]
+	faligndata	@X[10],@X[12],@X[10]
+	faligndata	@X[12],@X[14],@X[12]
+	faligndata	@X[14],@X[16],@X[14]
+
+.Laligned:
+	mov		5,$tmp0
+	dec		1,$len
+	alignaddr	%g0,$tmp0,%g0
+	fpadd32		$VK_00_19,@X[0],%f16
+	fpadd32		$VK_00_19,@X[2],%f18
+	fpadd32		$VK_00_19,@X[4],%f20
+	fpadd32		$VK_00_19,@X[6],%f22
+	fpadd32		$VK_00_19,@X[8],%f24
+	fpadd32		$VK_00_19,@X[10],%f26
+	fpadd32		$VK_00_19,@X[12],%f28
+	fpadd32		$VK_00_19,@X[14],%f30
+	std		%f16,[$Xfer+0]
+	mov		$Actx,$A
+	std		%f18,[$Xfer+8]
+	mov		$Bctx,$B
+	std		%f20,[$Xfer+16]
+	mov		$Cctx,$C
+	std		%f22,[$Xfer+24]
+	mov		$Dctx,$D
+	std		%f24,[$Xfer+32]
+	mov		$Ectx,$E
+	std		%f26,[$Xfer+40]
+	fxors		@X[13],@X[0],@X[0]
+	std		%f28,[$Xfer+48]
+	ba		.Loop
+	std		%f30,[$Xfer+56]
+.align	32
+.Loop:
+___
+for ($i=0;$i<20;$i++)	{ &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
+for (;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+for (;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
+for (;$i<70;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+	tst		$len
+	bz,pn		`$bits==32?"%icc":"%xcc"`,.Ltail
+	nop
+___
+for (;$i<80;$i++)	{ &BODY_70_79($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+	add		$A,$Actx,$Actx
+	add		$B,$Bctx,$Bctx
+	add		$C,$Cctx,$Cctx
+	add		$D,$Dctx,$Dctx
+	add		$E,$Ectx,$Ectx
+	mov		5,$tmp0
+	fxors		@X[13],@X[0],@X[0]
+	mov		$Actx,$A
+	mov		$Bctx,$B
+	mov		$Cctx,$C
+	mov		$Dctx,$D
+	mov		$Ectx,$E
+	alignaddr	%g0,$tmp0,%g0	
+	dec		1,$len
+	ba		.Loop
+	mov		$nXfer,$Xfer
+
+.align	32
+.Ltail:
+___
+for($i=70;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+	add	$A,$Actx,$Actx
+	add	$B,$Bctx,$Bctx
+	add	$C,$Cctx,$Cctx
+	add	$D,$Dctx,$Dctx
+	add	$E,$Ectx,$Ectx
+
+	st	$Actx,[$ctx+0]
+	st	$Bctx,[$ctx+4]
+	st	$Cctx,[$ctx+8]
+	st	$Dctx,[$ctx+12]
+	st	$Ectx,[$ctx+16]
+
+	ret
+	restore
+.type	sha1_block_data_order,#function
+.size	sha1_block_data_order,(.-sha1_block_data_order)
+.asciz	"SHA1 block transform for SPARCv9a, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+# Purpose of these subroutines is to explicitly encode VIS instructions,
+# so that one can compile the module without having to specify VIS
+# extentions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
+# Idea is to reserve for option to produce "universal" binary and let
+# programmer detect if current CPU is VIS capable at run-time.
+sub unvis {
+my ($mnemonic,$rs1,$rs2,$rd)=@_;
+my $ref,$opf;
+my %visopf = (	"fmul8ulx16"	=> 0x037,
+		"faligndata"	=> 0x048,
+		"fpadd32"	=> 0x052,
+		"fxor"		=> 0x06c,
+		"fxors"		=> 0x06d	);
+
+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
+
+    if ($opf=$visopf{$mnemonic}) {
+	foreach ($rs1,$rs2,$rd) {
+	    return $ref if (!/%f([0-9]{1,2})/);
+	    $_=$1;
+	    if ($1>=32) {
+		return $ref if ($1&1);
+		# re-encode for upper double register addressing
+		$_=($1|$1>>5)&31;
+	    }
+	}
+
+	return	sprintf ".word\t0x%08x !%s",
+			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
+			$ref;
+    } else {
+	return $ref;
+    }
+}
+sub unalignaddr {
+my ($mnemonic,$rs1,$rs2,$rd)=@_;
+my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
+my $ref="$mnemonic\t$rs1,$rs2,$rd";
+
+    foreach ($rs1,$rs2,$rd) {
+	if (/%([goli])([0-7])/)	{ $_=$bias{$1}+$2; }
+	else			{ return $ref; }
+    }
+    return  sprintf ".word\t0x%08x !%s",
+		    0x81b00300|$rd<<25|$rs1<<14|$rs2,
+		    $ref;
+}
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+$code =~ s/\b(f[^\s]*)\s+(%f[0-9]{1,2}),(%f[0-9]{1,2}),(%f[0-9]{1,2})/
+		&unvis($1,$2,$3,$4)
+	  /gem;
+$code =~ s/\b(alignaddr)\s+(%[goli][0-7]),(%[goli][0-7]),(%[goli][0-7])/
+		&unalignaddr($1,$2,$3,$4)
+	  /gem;
+print $code;
+close STDOUT;
diff --git a/crypto/sha/asm/sha1-thumb.pl b/crypto/sha/asm/sha1-thumb.pl
new file mode 100644
index 0000000..7c9ea9b
--- /dev/null
+++ b/crypto/sha/asm/sha1-thumb.pl
@@ -0,0 +1,259 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# sha1_block for Thumb.
+#
+# January 2007.
+#
+# The code does not present direct interest to OpenSSL, because of low
+# performance. Its purpose is to establish _size_ benchmark. Pretty
+# useless one I must say, because 30% or 88 bytes larger ARMv4 code
+# [avialable on demand] is almost _twice_ as fast. It should also be
+# noted that in-lining of .Lcommon and .Lrotate improves performance
+# by over 40%, while code increases by only 10% or 32 bytes. But once
+# again, the goal was to establish _size_ benchmark, not performance.
+
+$output=shift;
+open STDOUT,">$output";
+
+$inline=0;
+#$cheat_on_binutils=1;
+
+$t0="r0";
+$t1="r1";
+$t2="r2";
+$a="r3";
+$b="r4";
+$c="r5";
+$d="r6";
+$e="r7";
+$K="r8";	# "upper" registers can be used in add/sub and mov insns
+$ctx="r9";
+$inp="r10";
+$len="r11";
+$Xi="r12";
+
+sub common {
+<<___;
+	sub	$t0,#4
+	ldr	$t1,[$t0]
+	add	$e,$K			@ E+=K_xx_xx
+	lsl	$t2,$a,#5
+	add	$t2,$e
+	lsr	$e,$a,#27
+	add	$t2,$e			@ E+=ROR(A,27)
+	add	$t2,$t1			@ E+=X[i]
+___
+}
+sub rotate {
+<<___;
+	mov	$e,$d			@ E=D
+	mov	$d,$c			@ D=C
+	lsl	$c,$b,#30
+	lsr	$b,$b,#2
+	orr	$c,$b			@ C=ROR(B,2)
+	mov	$b,$a			@ B=A
+	add	$a,$t2,$t1		@ A=E+F_xx_xx(B,C,D)
+___
+}
+
+sub BODY_00_19 {
+$code.=$inline?&common():"\tbl	.Lcommon\n";
+$code.=<<___;
+	mov	$t1,$c
+	eor	$t1,$d
+	and	$t1,$b
+	eor	$t1,$d			@ F_00_19(B,C,D)
+___
+$code.=$inline?&rotate():"\tbl	.Lrotate\n";
+}
+
+sub BODY_20_39 {
+$code.=$inline?&common():"\tbl	.Lcommon\n";
+$code.=<<___;
+	mov	$t1,$b
+	eor	$t1,$c
+	eor	$t1,$d			@ F_20_39(B,C,D)
+___
+$code.=$inline?&rotate():"\tbl	.Lrotate\n";
+}
+
+sub BODY_40_59 {
+$code.=$inline?&common():"\tbl	.Lcommon\n";
+$code.=<<___;
+	mov	$t1,$b
+	and	$t1,$c
+	mov	$e,$b
+	orr	$e,$c
+	and	$e,$d
+	orr	$t1,$e			@ F_40_59(B,C,D)
+___
+$code.=$inline?&rotate():"\tbl	.Lrotate\n";
+}
+
+$code=<<___;
+.text
+.code	16
+
+.global	sha1_block_data_order
+.type	sha1_block_data_order,%function
+
+.align	2
+sha1_block_data_order:
+___
+if ($cheat_on_binutils) {
+$code.=<<___;
+.code	32
+	add	r3,pc,#1
+	bx	r3			@ switch to Thumb ISA
+.code	16
+___
+}
+$code.=<<___;
+	push	{r4-r7}
+	mov	r3,r8
+	mov	r4,r9
+	mov	r5,r10
+	mov	r6,r11
+	mov	r7,r12
+	push	{r3-r7,lr}
+	lsl	r2,#6
+	mov	$ctx,r0			@ save context
+	mov	$inp,r1			@ save inp
+	mov	$len,r2			@ save len
+	add	$len,$inp		@ $len to point at inp end
+
+.Lloop:
+	mov	$Xi,sp
+	mov	$t2,sp
+	sub	$t2,#16*4		@ [3]
+.LXload:
+	ldrb	$a,[$t1,#0]		@ $t1 is r1 and holds inp
+	ldrb	$b,[$t1,#1]
+	ldrb	$c,[$t1,#2]
+	ldrb	$d,[$t1,#3]
+	lsl	$a,#24
+	lsl	$b,#16
+	lsl	$c,#8
+	orr	$a,$b
+	orr	$a,$c
+	orr	$a,$d
+	add	$t1,#4
+	push	{$a}
+	cmp	sp,$t2
+	bne	.LXload			@ [+14*16]
+
+	mov	$inp,$t1		@ update $inp
+	sub	$t2,#32*4
+	sub	$t2,#32*4
+	mov	$e,#31			@ [+4]
+.LXupdate:
+	ldr	$a,[sp,#15*4]
+	ldr	$b,[sp,#13*4]
+	ldr	$c,[sp,#7*4]
+	ldr	$d,[sp,#2*4]
+	eor	$a,$b
+	eor	$a,$c
+	eor	$a,$d
+	ror	$a,$e
+	push	{$a}
+	cmp	sp,$t2
+	bne	.LXupdate		@ [+(11+1)*64]
+
+	ldmia	$t0!,{$a,$b,$c,$d,$e}	@ $t0 is r0 and holds ctx
+	mov	$t0,$Xi
+
+	ldr	$t2,.LK_00_19
+	mov	$t1,$t0
+	sub	$t1,#20*4
+	mov	$Xi,$t1
+	mov	$K,$t2			@ [+7+4]
+.L_00_19:
+___
+	&BODY_00_19();
+$code.=<<___;
+	cmp	$Xi,$t0
+	bne	.L_00_19		@ [+(2+9+4+2+8+2)*20]
+
+	ldr	$t2,.LK_20_39
+	mov	$t1,$t0
+	sub	$t1,#20*4
+	mov	$Xi,$t1
+	mov	$K,$t2			@ [+5]
+.L_20_39_or_60_79:
+___
+	&BODY_20_39();
+$code.=<<___;
+	cmp	$Xi,$t0
+	bne	.L_20_39_or_60_79	@ [+(2+9+3+2+8+2)*20*2]
+	cmp	sp,$t0
+	beq	.Ldone			@ [+2]
+
+	ldr	$t2,.LK_40_59
+	mov	$t1,$t0
+	sub	$t1,#20*4
+	mov	$Xi,$t1
+	mov	$K,$t2			@ [+5]
+.L_40_59:
+___
+	&BODY_40_59();
+$code.=<<___;
+	cmp	$Xi,$t0
+	bne	.L_40_59		@ [+(2+9+6+2+8+2)*20]
+
+	ldr	$t2,.LK_60_79
+	mov	$Xi,sp
+	mov	$K,$t2
+	b	.L_20_39_or_60_79	@ [+4]
+.Ldone:
+	mov	$t0,$ctx
+	ldr	$t1,[$t0,#0]
+	ldr	$t2,[$t0,#4]
+	add	$a,$t1
+	ldr	$t1,[$t0,#8]
+	add	$b,$t2
+	ldr	$t2,[$t0,#12]
+	add	$c,$t1
+	ldr	$t1,[$t0,#16]
+	add	$d,$t2
+	add	$e,$t1
+	stmia	$t0!,{$a,$b,$c,$d,$e}	@ [+20]
+
+	add	sp,#80*4		@ deallocate stack frame
+	mov	$t0,$ctx		@ restore ctx
+	mov	$t1,$inp		@ restore inp
+	cmp	$t1,$len
+	beq	.Lexit
+	b	.Lloop			@ [+6] total 3212 cycles
+.Lexit:
+	pop	{r2-r7}
+	mov	r8,r2
+	mov	r9,r3
+	mov	r10,r4
+	mov	r11,r5
+	mov	r12,r6
+	mov	lr,r7
+	pop	{r4-r7}
+	bx	lr
+.align	2
+___
+$code.=".Lcommon:\n".&common()."\tmov	pc,lr\n" if (!$inline);
+$code.=".Lrotate:\n".&rotate()."\tmov	pc,lr\n" if (!$inline);
+$code.=<<___;
+.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 Thumb, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+print $code;
+close STDOUT; # enforce flush
diff --git a/crypto/sha/asm/sha1-x86_64.pl b/crypto/sha/asm/sha1-x86_64.pl
index f7ed67a..4edc5ea 100755
--- a/crypto/sha/asm/sha1-x86_64.pl
+++ b/crypto/sha/asm/sha1-x86_64.pl
@@ -29,14 +29,18 @@
 # Xeon P4	+65%		+0%		9.9
 # Core2		+60%		+10%		7.0
 
-$output=shift;
+$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 $output";
+open STDOUT,"| $^X $xlate $flavour $output";
 
 $ctx="%rdi";	# 1st arg
 $inp="%rsi";	# 2nd arg
@@ -69,13 +73,14 @@
 	push	%rbx
 	push	%rbp
 	push	%r12
-	mov	%rsp,%rax
+	mov	%rsp,%r11
 	mov	%rdi,$ctx	# reassigned argument
 	sub	\$`8+16*4`,%rsp
 	mov	%rsi,$inp	# reassigned argument
 	and	\$-64,%rsp
 	mov	%rdx,$num	# reassigned argument
-	mov	%rax,`16*4`(%rsp)
+	mov	%r11,`16*4`(%rsp)
+.Lprologue:
 
 	mov	0($ctx),$A
 	mov	4($ctx),$B
@@ -88,10 +93,12 @@
 sub EPILOGUE {
 my $func=shift;
 $code.=<<___;
-	mov	`16*4`(%rsp),%rsp
-	pop	%r12
-	pop	%rbp
-	pop	%rbx
+	mov	`16*4`(%rsp),%rsi
+	mov	(%rsi),%r12
+	mov	8(%rsi),%rbp
+	mov	16(%rsi),%rbx
+	lea	24(%rsi),%rsp
+.Lepilogue:
 	ret
 .size	$func,.-$func
 ___
@@ -233,8 +240,110 @@
 &EPILOGUE("sha1_block_data_order");
 $code.=<<___;
 .asciz	"SHA1 block transform for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
+.align	16
 ___
 
+# 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	se_handler,\@abi-omnipotent
+.align	16
+se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	lea	.Lprologue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lprologue
+	jb	.Lin_prologue
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	lea	.Lepilogue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
+	jae	.Lin_prologue
+
+	mov	`16*4`(%rax),%rax	# pull saved stack pointer
+	lea	24(%rax),%rax
+
+	mov	-8(%rax),%rbx
+	mov	-16(%rax),%rbp
+	mov	-24(%rax),%r12
+	mov	%rbx,144($context)	# restore context->Rbx
+	mov	%rbp,160($context)	# restore context->Rbp
+	mov	%r12,216($context)	# restore context->R12
+
+.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
+
+	mov	40($disp),%rdi		# disp->ContextRecord
+	mov	$context,%rsi		# context
+	mov	\$154,%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
+	add	\$64,%rsp
+	popfq
+	pop	%r15
+	pop	%r14
+	pop	%r13
+	pop	%r12
+	pop	%rbp
+	pop	%rbx
+	pop	%rdi
+	pop	%rsi
+	ret
+.size	se_handler,.-se_handler
+
+.section	.pdata
+.align	4
+	.rva	.LSEH_begin_sha1_block_data_order
+	.rva	.LSEH_end_sha1_block_data_order
+	.rva	.LSEH_info_sha1_block_data_order
+
+.section	.xdata
+.align	8
+.LSEH_info_sha1_block_data_order:
+	.byte	9,0,0,0
+	.rva	se_handler
+___
+}
+
 ####################################################################
 
 $code =~ s/\`([^\`]*)\`/eval $1/gem;
diff --git a/crypto/sha/asm/sha256-586.pl b/crypto/sha/asm/sha256-586.pl
new file mode 100644
index 0000000..ecc8b69
--- /dev/null
+++ b/crypto/sha/asm/sha256-586.pl
@@ -0,0 +1,251 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# SHA256 block transform for x86. September 2007.
+#
+# Performance in clock cycles per processed byte (less is better):
+#
+#		Pentium	PIII	P4	AMD K8	Core2
+# gcc		46	36	41	27	26
+# icc		57	33	38	25	23	
+# x86 asm	40	30	35	20	20
+# x86_64 asm(*)	-	-	21	15.8	16.5
+#
+# (*) x86_64 assembler performance is presented for reference
+#     purposes.
+#
+# Performance improvement over compiler generated code varies from
+# 10% to 40% [see above]. Not very impressive on some µ-archs, but
+# it's 5 times smaller and optimizies amount of writes.
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"sha512-586.pl",$ARGV[$#ARGV] eq "386");
+
+$A="eax";
+$E="edx";
+$T="ebx";
+$Aoff=&DWP(0,"esp");
+$Boff=&DWP(4,"esp");
+$Coff=&DWP(8,"esp");
+$Doff=&DWP(12,"esp");
+$Eoff=&DWP(16,"esp");
+$Foff=&DWP(20,"esp");
+$Goff=&DWP(24,"esp");
+$Hoff=&DWP(28,"esp");
+$Xoff=&DWP(32,"esp");
+$K256="ebp";
+
+sub BODY_00_15() {
+    my $in_16_63=shift;
+
+	&mov	("ecx",$E);
+	 &add	($T,&DWP(4*(8+15+16-9),"esp"))	if ($in_16_63);	# T += X[-7]
+	&ror	("ecx",6);
+	&mov	("edi",$E);
+	&ror	("edi",11);
+	 &mov	("esi",$Foff);
+	&xor	("ecx","edi");
+	&ror	("edi",25-11);
+	 &mov	(&DWP(4*(8+15),"esp"),$T)	if ($in_16_63);	# save X[0]
+	&xor	("ecx","edi");	# Sigma1(e)
+	 &mov	("edi",$Goff);
+	&add	($T,"ecx");	# T += Sigma1(e)
+	 &mov	($Eoff,$E);	# modulo-scheduled
+
+	&xor	("esi","edi");
+	 &mov	("ecx",$A);
+	&and	("esi",$E);
+	 &mov	($E,$Doff);	# e becomes d, which is e in next iteration
+	&xor	("esi","edi");	# Ch(e,f,g)
+	 &mov	("edi",$A);
+	&add	($T,"esi");	# T += Ch(e,f,g)
+
+	&ror	("ecx",2);
+	 &add	($T,$Hoff);	# T += h
+	&ror	("edi",13);
+	 &mov	("esi",$Boff);
+	&xor	("ecx","edi");
+	&ror	("edi",22-13);
+	 &add	($E,$T);	# d += T
+	&xor	("ecx","edi");	# Sigma0(a)
+	 &mov	("edi",$Coff);
+
+	&add	($T,"ecx");	# T += Sigma0(a)
+	 &mov	($Aoff,$A);	# modulo-scheduled
+
+	&mov	("ecx",$A);
+	 &sub	("esp",4);
+	&or	($A,"esi");	# a becomes h, which is a in next iteration
+	&and	("ecx","esi");
+	&and	($A,"edi");
+	 &mov	("esi",&DWP(0,$K256));
+	&or	($A,"ecx");	# h=Maj(a,b,c)
+
+	&add	($K256,4);
+	&add	($A,$T);	# h += T
+	 &mov	($T,&DWP(4*(8+15+16-1),"esp"))	if ($in_16_63);	# preload T
+	&add	($E,"esi");	# d += K256[i]
+	&add	($A,"esi");	# h += K256[i]
+}
+
+&function_begin("sha256_block_data_order");
+	&mov	("esi",wparam(0));	# ctx
+	&mov	("edi",wparam(1));	# inp
+	&mov	("eax",wparam(2));	# num
+	&mov	("ebx","esp");		# saved sp
+
+	&call	(&label("pic_point"));	# make it PIC!
+&set_label("pic_point");
+	&blindpop($K256);
+	&lea	($K256,&DWP(&label("K256")."-".&label("pic_point"),$K256));
+
+	&sub	("esp",16);
+	&and	("esp",-64);
+
+	&shl	("eax",6);
+	&add	("eax","edi");
+	&mov	(&DWP(0,"esp"),"esi");	# ctx
+	&mov	(&DWP(4,"esp"),"edi");	# inp
+	&mov	(&DWP(8,"esp"),"eax");	# inp+num*128
+	&mov	(&DWP(12,"esp"),"ebx");	# saved sp
+
+&set_label("loop",16);
+    # copy input block to stack reversing byte and dword order
+    for($i=0;$i<4;$i++) {
+	&mov	("eax",&DWP($i*16+0,"edi"));
+	&mov	("ebx",&DWP($i*16+4,"edi"));
+	&mov	("ecx",&DWP($i*16+8,"edi"));
+	&mov	("edx",&DWP($i*16+12,"edi"));
+	&bswap	("eax");
+	&bswap	("ebx");
+	&bswap	("ecx");
+	&bswap	("edx");
+	&push	("eax");
+	&push	("ebx");
+	&push	("ecx");
+	&push	("edx");
+    }
+	&add	("edi",64);
+	&sub	("esp",4*8);		# place for A,B,C,D,E,F,G,H
+	&mov	(&DWP(4*(8+16)+4,"esp"),"edi");
+
+	# copy ctx->h[0-7] to A,B,C,D,E,F,G,H on stack
+	&mov	($A,&DWP(0,"esi"));
+	&mov	("ebx",&DWP(4,"esi"));
+	&mov	("ecx",&DWP(8,"esi"));
+	&mov	("edi",&DWP(12,"esi"));
+	# &mov	($Aoff,$A);
+	&mov	($Boff,"ebx");
+	&mov	($Coff,"ecx");
+	&mov	($Doff,"edi");
+	&mov	($E,&DWP(16,"esi"));	
+	&mov	("ebx",&DWP(20,"esi"));
+	&mov	("ecx",&DWP(24,"esi"));
+	&mov	("edi",&DWP(28,"esi"));
+	# &mov	($Eoff,$E);
+	&mov	($Foff,"ebx");
+	&mov	($Goff,"ecx");
+	&mov	($Hoff,"edi");
+
+&set_label("00_15",16);
+	&mov	($T,&DWP(4*(8+15),"esp"));
+
+	&BODY_00_15();
+
+	&cmp	("esi",0xc19bf174);
+	&jne	(&label("00_15"));
+
+	&mov	($T,&DWP(4*(8+15+16-1),"esp"));	# preloaded in BODY_00_15(1)
+&set_label("16_63",16);
+	&mov	("esi",$T);
+	 &mov	("ecx",&DWP(4*(8+15+16-14),"esp"));
+	&shr	($T,3);
+	&ror	("esi",7);
+	&xor	($T,"esi");
+	&ror	("esi",18-7);
+	 &mov	("edi","ecx");
+	&xor	($T,"esi");			# T = sigma0(X[-15])
+
+	&shr	("ecx",10);
+	 &mov	("esi",&DWP(4*(8+15+16),"esp"));
+	&ror	("edi",17);
+	&xor	("ecx","edi");
+	&ror	("edi",19-17);
+	 &add	($T,"esi");			# T += X[-16]
+	&xor	("edi","ecx")			# sigma1(X[-2])
+
+	&add	($T,"edi");			# T += sigma1(X[-2])
+	# &add	($T,&DWP(4*(8+15+16-9),"esp"));	# T += X[-7], moved to BODY_00_15(1)
+	# &mov	(&DWP(4*(8+15),"esp"),$T);	# save X[0]
+
+	&BODY_00_15(1);
+
+	&cmp	("esi",0xc67178f2);
+	&jne	(&label("16_63"));
+
+	&mov	("esi",&DWP(4*(8+16+64)+0,"esp"));#ctx
+	# &mov	($A,$Aoff);
+	&mov	("ebx",$Boff);
+	&mov	("ecx",$Coff);
+	&mov	("edi",$Doff);
+	&add	($A,&DWP(0,"esi"));
+	&add	("ebx",&DWP(4,"esi"));
+	&add	("ecx",&DWP(8,"esi"));
+	&add	("edi",&DWP(12,"esi"));
+	&mov	(&DWP(0,"esi"),$A);
+	&mov	(&DWP(4,"esi"),"ebx");
+	&mov	(&DWP(8,"esi"),"ecx");
+	&mov	(&DWP(12,"esi"),"edi");
+	# &mov	($E,$Eoff);
+	&mov	("eax",$Foff);
+	&mov	("ebx",$Goff);
+	&mov	("ecx",$Hoff);
+	&mov	("edi",&DWP(4*(8+16+64)+4,"esp"));#inp
+	&add	($E,&DWP(16,"esi"));
+	&add	("eax",&DWP(20,"esi"));
+	&add	("ebx",&DWP(24,"esi"));
+	&add	("ecx",&DWP(28,"esi"));
+	&mov	(&DWP(16,"esi"),$E);
+	&mov	(&DWP(20,"esi"),"eax");
+	&mov	(&DWP(24,"esi"),"ebx");
+	&mov	(&DWP(28,"esi"),"ecx");
+
+	&add	("esp",4*(8+16+64));		# destroy frame
+	&sub	($K256,4*64);			# rewind K
+
+	&cmp	("edi",&DWP(8,"esp"));		# are we done yet?
+	&jb	(&label("loop"));
+
+	&mov	("esp",&DWP(12,"esp"));		# restore sp
+&function_end_A();
+
+&set_label("K256",64);	# Yes! I keep it in the code segment!
+	&data_word(0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5);
+	&data_word(0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5);
+	&data_word(0xd807aa98,0x12835b01,0x243185be,0x550c7dc3);
+	&data_word(0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174);
+	&data_word(0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc);
+	&data_word(0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da);
+	&data_word(0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7);
+	&data_word(0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967);
+	&data_word(0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13);
+	&data_word(0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85);
+	&data_word(0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3);
+	&data_word(0xd192e819,0xd6990624,0xf40e3585,0x106aa070);
+	&data_word(0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5);
+	&data_word(0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3);
+	&data_word(0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208);
+	&data_word(0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2);
+&function_end_B("sha256_block_data_order");
+&asciz("SHA256 block transform for x86, CRYPTOGAMS by <appro\@openssl.org>");
+
+&asm_finish();
diff --git a/crypto/0.9.9-dev/sha/sha256-armv4.pl b/crypto/sha/asm/sha256-armv4.pl
similarity index 99%
rename from crypto/0.9.9-dev/sha/sha256-armv4.pl
rename to crypto/sha/asm/sha256-armv4.pl
index 853ca31..48d846d 100644
--- a/crypto/0.9.9-dev/sha/sha256-armv4.pl
+++ b/crypto/sha/asm/sha256-armv4.pl
@@ -172,6 +172,7 @@
 	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>"
+.align	2
 ___
 
 $code =~ s/\`([^\`]*)\`/eval $1/gem;
diff --git a/crypto/0.9.9-dev/sha/sha256-armv4.s b/crypto/sha/asm/sha256-armv4.s
similarity index 99%
rename from crypto/0.9.9-dev/sha/sha256-armv4.s
rename to crypto/sha/asm/sha256-armv4.s
index c7fe720..8f9cce9 100644
--- a/crypto/0.9.9-dev/sha/sha256-armv4.s
+++ b/crypto/sha/asm/sha256-armv4.s
@@ -1108,3 +1108,4 @@
 	.word	0xe12fff1e			@ interoperable with Thumb ISA:-)
 .size   sha256_block_data_order,.-sha256_block_data_order
 .asciz  "SHA256 block transform for ARMv4, CRYPTOGAMS by <appro@openssl.org>"
+.align	2
diff --git a/crypto/sha/asm/sha512-586.pl b/crypto/sha/asm/sha512-586.pl
new file mode 100644
index 0000000..5b9f333
--- /dev/null
+++ b/crypto/sha/asm/sha512-586.pl
@@ -0,0 +1,644 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# SHA512 block transform for x86. September 2007.
+#
+# Performance in clock cycles per processed byte (less is better):
+#
+#		Pentium	PIII	P4	AMD K8	Core2
+# gcc		100	75	116	54	66
+# icc		97	77	95	55	57
+# x86 asm	61	56	82	36	40
+# SSE2 asm	-	-	38	24	20
+# x86_64 asm(*)	-	-	30	10.0	10.5
+#
+# (*) x86_64 assembler performance is presented for reference
+#     purposes.
+#
+# IALU code-path is optimized for elder Pentiums. On vanilla Pentium
+# performance improvement over compiler generated code reaches ~60%,
+# while on PIII - ~35%. On newer µ-archs improvement varies from 15%
+# to 50%, but it's less important as they are expected to execute SSE2
+# code-path, which is commonly ~2-3x faster [than compiler generated
+# code]. SSE2 code-path is as fast as original sha512-sse2.pl, even
+# though it does not use 128-bit operations. The latter means that
+# SSE2-aware kernel is no longer required to execute the code. Another
+# difference is that new code optimizes amount of writes, but at the
+# cost of increased data cache "footprint" by 1/2KB.
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"sha512-586.pl",$ARGV[$#ARGV] eq "386");
+
+$sse2=0;
+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
+
+&external_label("OPENSSL_ia32cap_P") if ($sse2);
+
+$Tlo=&DWP(0,"esp");	$Thi=&DWP(4,"esp");
+$Alo=&DWP(8,"esp");	$Ahi=&DWP(8+4,"esp");
+$Blo=&DWP(16,"esp");	$Bhi=&DWP(16+4,"esp");
+$Clo=&DWP(24,"esp");	$Chi=&DWP(24+4,"esp");
+$Dlo=&DWP(32,"esp");	$Dhi=&DWP(32+4,"esp");
+$Elo=&DWP(40,"esp");	$Ehi=&DWP(40+4,"esp");
+$Flo=&DWP(48,"esp");	$Fhi=&DWP(48+4,"esp");
+$Glo=&DWP(56,"esp");	$Ghi=&DWP(56+4,"esp");
+$Hlo=&DWP(64,"esp");	$Hhi=&DWP(64+4,"esp");
+$K512="ebp";
+
+$Asse2=&QWP(0,"esp");
+$Bsse2=&QWP(8,"esp");
+$Csse2=&QWP(16,"esp");
+$Dsse2=&QWP(24,"esp");
+$Esse2=&QWP(32,"esp");
+$Fsse2=&QWP(40,"esp");
+$Gsse2=&QWP(48,"esp");
+$Hsse2=&QWP(56,"esp");
+
+$A="mm0";	# B-D and
+$E="mm4";	# F-H are commonly loaded to respectively mm1-mm3 and
+		# mm5-mm7, but it's done on on-demand basis...
+
+sub BODY_00_15_sse2 {
+    my $prefetch=shift;
+
+	&movq	("mm5",$Fsse2);			# load f
+	&movq	("mm6",$Gsse2);			# load g
+	&movq	("mm7",$Hsse2);			# load h
+
+	&movq	("mm1",$E);			# %mm1 is sliding right
+	&movq	("mm2",$E);			# %mm2 is sliding left
+	&psrlq	("mm1",14);
+	&movq	($Esse2,$E);			# modulo-scheduled save e
+	&psllq	("mm2",23);
+	&movq	("mm3","mm1");			# %mm3 is T1
+	&psrlq	("mm1",4);
+	&pxor	("mm3","mm2");
+	&psllq	("mm2",23);
+	&pxor	("mm3","mm1");
+	&psrlq	("mm1",23);
+	&pxor	("mm3","mm2");
+	&psllq	("mm2",4);
+	&pxor	("mm3","mm1");
+	&paddq	("mm7",QWP(0,$K512));		# h+=K512[i]
+	&pxor	("mm3","mm2");			# T1=Sigma1_512(e)
+
+	&pxor	("mm5","mm6");			# f^=g
+	&movq	("mm1",$Bsse2);			# load b
+	&pand	("mm5",$E);			# f&=e
+	&movq	("mm2",$Csse2);			# load c
+	&pxor	("mm5","mm6");			# f^=g
+	&movq	($E,$Dsse2);			# e = load d
+	&paddq	("mm3","mm5");			# T1+=Ch(e,f,g)
+	&movq	(&QWP(0,"esp"),$A);		# modulo-scheduled save a
+	&paddq	("mm3","mm7");			# T1+=h
+
+	&movq	("mm5",$A);			# %mm5 is sliding right
+	&movq	("mm6",$A);			# %mm6 is sliding left
+	&paddq	("mm3",&QWP(8*9,"esp"));	# T1+=X[0]
+	&psrlq	("mm5",28);
+	&paddq	($E,"mm3");			# e += T1
+	&psllq	("mm6",25);
+	&movq	("mm7","mm5");			# %mm7 is T2
+	&psrlq	("mm5",6);
+	&pxor	("mm7","mm6");
+	&psllq	("mm6",5);
+	&pxor	("mm7","mm5");
+	&psrlq	("mm5",5);
+	&pxor	("mm7","mm6");
+	&psllq	("mm6",6);
+	&pxor	("mm7","mm5");
+	&sub	("esp",8);
+	&pxor	("mm7","mm6");			# T2=Sigma0_512(a)
+
+	&movq	("mm5",$A);			# %mm5=a
+	&por	($A,"mm2");			# a=a|c
+	&movq	("mm6",&QWP(8*(9+16-14),"esp"))	if ($prefetch);
+	&pand	("mm5","mm2");			# %mm5=a&c
+	&pand	($A,"mm1");			# a=(a|c)&b
+	&movq	("mm2",&QWP(8*(9+16-1),"esp"))	if ($prefetch);
+	&por	("mm5",$A);			# %mm5=(a&c)|((a|c)&b)
+	&paddq	("mm7","mm5");			# T2+=Maj(a,b,c)
+	&movq	($A,"mm3");			# a=T1
+
+	&mov	(&LB("edx"),&BP(0,$K512));
+	&paddq	($A,"mm7");			# a+=T2
+	&add	($K512,8);
+}
+
+sub BODY_00_15_x86 {
+	#define 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	("ecx",$Elo);
+	&mov	("edx",$Ehi);
+	&mov	("esi","ecx");
+
+	&shr	("ecx",9)	# lo>>9
+	&mov	("edi","edx");
+	&shr	("edx",9)	# hi>>9
+	&mov	("ebx","ecx");
+	&shl	("esi",14);	# lo<<14
+	&mov	("eax","edx");
+	&shl	("edi",14);	# hi<<14
+	&xor	("ebx","esi");
+
+	&shr	("ecx",14-9);	# lo>>14
+	&xor	("eax","edi");
+	&shr	("edx",14-9);	# hi>>14
+	&xor	("eax","ecx");
+	&shl	("esi",18-14);	# lo<<18
+	&xor	("ebx","edx");
+	&shl	("edi",18-14);	# hi<<18
+	&xor	("ebx","esi");
+
+	&shr	("ecx",18-14);	# lo>>18
+	&xor	("eax","edi");
+	&shr	("edx",18-14);	# hi>>18
+	&xor	("eax","ecx");
+	&shl	("esi",23-18);	# lo<<23
+	&xor	("ebx","edx");
+	&shl	("edi",23-18);	# hi<<23
+	&xor	("eax","esi");
+	&xor	("ebx","edi");			# T1 = Sigma1(e)
+
+	&mov	("ecx",$Flo);
+	&mov	("edx",$Fhi);
+	&mov	("esi",$Glo);
+	&mov	("edi",$Ghi);
+	 &add	("eax",$Hlo);
+	 &adc	("ebx",$Hhi);			# T1 += h
+	&xor	("ecx","esi");
+	&xor	("edx","edi");
+	&and	("ecx",$Elo);
+	&and	("edx",$Ehi);
+	 &add	("eax",&DWP(8*(9+15)+0,"esp"));
+	 &adc	("ebx",&DWP(8*(9+15)+4,"esp"));	# T1 += X[0]
+	&xor	("ecx","esi");
+	&xor	("edx","edi");			# Ch(e,f,g) = (f^g)&e)^g
+
+	&mov	("esi",&DWP(0,$K512));
+	&mov	("edi",&DWP(4,$K512));		# K[i]
+	&add	("eax","ecx");
+	&adc	("ebx","edx");			# T1 += Ch(e,f,g)
+	&mov	("ecx",$Dlo);
+	&mov	("edx",$Dhi);
+	&add	("eax","esi");
+	&adc	("ebx","edi");			# T1 += K[i]
+	&mov	($Tlo,"eax");
+	&mov	($Thi,"ebx");			# put T1 away
+	&add	("eax","ecx");
+	&adc	("ebx","edx");			# d += T1
+
+	#define 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	("ecx",$Alo);
+	&mov	("edx",$Ahi);
+	&mov	($Dlo,"eax");
+	&mov	($Dhi,"ebx");
+	&mov	("esi","ecx");
+
+	&shr	("ecx",2)	# lo>>2
+	&mov	("edi","edx");
+	&shr	("edx",2)	# hi>>2
+	&mov	("ebx","ecx");
+	&shl	("esi",4);	# lo<<4
+	&mov	("eax","edx");
+	&shl	("edi",4);	# hi<<4
+	&xor	("ebx","esi");
+
+	&shr	("ecx",7-2);	# lo>>7
+	&xor	("eax","edi");
+	&shr	("edx",7-2);	# hi>>7
+	&xor	("ebx","ecx");
+	&shl	("esi",25-4);	# lo<<25
+	&xor	("eax","edx");
+	&shl	("edi",25-4);	# hi<<25
+	&xor	("eax","esi");
+
+	&shr	("ecx",28-7);	# lo>>28
+	&xor	("ebx","edi");
+	&shr	("edx",28-7);	# hi>>28
+	&xor	("eax","ecx");
+	&shl	("esi",30-25);	# lo<<30
+	&xor	("ebx","edx");
+	&shl	("edi",30-25);	# hi<<30
+	&xor	("eax","esi");
+	&xor	("ebx","edi");			# Sigma0(a)
+
+	&mov	("ecx",$Alo);
+	&mov	("edx",$Ahi);
+	&mov	("esi",$Blo);
+	&mov	("edi",$Bhi);
+	&add	("eax",$Tlo);
+	&adc	("ebx",$Thi);			# T1 = Sigma0(a)+T1
+	&or	("ecx","esi");
+	&or	("edx","edi");
+	&and	("ecx",$Clo);
+	&and	("edx",$Chi);
+	&and	("esi",$Alo);
+	&and	("edi",$Ahi);
+	&or	("ecx","esi");
+	&or	("edx","edi");			# Maj(a,b,c) = ((a|b)&c)|(a&b)
+
+	&add	("eax","ecx");
+	&adc	("ebx","edx");			# T1 += Maj(a,b,c)
+	&mov	($Tlo,"eax");
+	&mov	($Thi,"ebx");
+
+	&mov	(&LB("edx"),&BP(0,$K512));	# pre-fetch LSB of *K
+	&sub	("esp",8);
+	&lea	($K512,&DWP(8,$K512));		# K++
+}
+
+
+&function_begin("sha512_block_data_order");
+	&mov	("esi",wparam(0));	# ctx
+	&mov	("edi",wparam(1));	# inp
+	&mov	("eax",wparam(2));	# num
+	&mov	("ebx","esp");		# saved sp
+
+	&call	(&label("pic_point"));	# make it PIC!
+&set_label("pic_point");
+	&blindpop($K512);
+	&lea	($K512,&DWP(&label("K512")."-".&label("pic_point"),$K512));
+
+	&sub	("esp",16);
+	&and	("esp",-64);
+
+	&shl	("eax",7);
+	&add	("eax","edi");
+	&mov	(&DWP(0,"esp"),"esi");	# ctx
+	&mov	(&DWP(4,"esp"),"edi");	# inp
+	&mov	(&DWP(8,"esp"),"eax");	# inp+num*128
+	&mov	(&DWP(12,"esp"),"ebx");	# saved sp
+
+if ($sse2) {
+	&picmeup("edx","OPENSSL_ia32cap_P",$K512,&label("K512"));
+	&bt	(&DWP(0,"edx"),26);
+	&jnc	(&label("loop_x86"));
+
+	# load ctx->h[0-7]
+	&movq	($A,&QWP(0,"esi"));
+	&movq	("mm1",&QWP(8,"esi"));
+	&movq	("mm2",&QWP(16,"esi"));
+	&movq	("mm3",&QWP(24,"esi"));
+	&movq	($E,&QWP(32,"esi"));
+	&movq	("mm5",&QWP(40,"esi"));
+	&movq	("mm6",&QWP(48,"esi"));
+	&movq	("mm7",&QWP(56,"esi"));
+	&sub	("esp",8*10);
+
+&set_label("loop_sse2",16);
+	# &movq	($Asse2,$A);
+	&movq	($Bsse2,"mm1");
+	&movq	($Csse2,"mm2");
+	&movq	($Dsse2,"mm3");
+	# &movq	($Esse2,$E);
+	&movq	($Fsse2,"mm5");
+	&movq	($Gsse2,"mm6");
+	&movq	($Hsse2,"mm7");
+
+	&mov	("ecx",&DWP(0,"edi"));
+	&mov	("edx",&DWP(4,"edi"));
+	&add	("edi",8);
+	&bswap	("ecx");
+	&bswap	("edx");
+	&mov	(&DWP(8*9+4,"esp"),"ecx");
+	&mov	(&DWP(8*9+0,"esp"),"edx");
+
+&set_label("00_14_sse2",16);
+	&mov	("eax",&DWP(0,"edi"));
+	&mov	("ebx",&DWP(4,"edi"));
+	&add	("edi",8);
+	&bswap	("eax");
+	&bswap	("ebx");
+	&mov	(&DWP(8*8+4,"esp"),"eax");
+	&mov	(&DWP(8*8+0,"esp"),"ebx");
+
+	&BODY_00_15_sse2();
+
+	&cmp	(&LB("edx"),0x35);
+	&jne	(&label("00_14_sse2"));
+
+	&BODY_00_15_sse2(1);
+
+&set_label("16_79_sse2",16);
+	#&movq	("mm2",&QWP(8*(9+16-1),"esp"));	#prefetched in BODY_00_15 
+	#&movq	("mm6",&QWP(8*(9+16-14),"esp"));
+	&movq	("mm1","mm2");
+
+	&psrlq	("mm2",1);
+	&movq	("mm7","mm6");
+	&psrlq	("mm6",6);
+	&movq	("mm3","mm2");
+
+	&psrlq	("mm2",7-1);
+	&movq	("mm5","mm6");
+	&psrlq	("mm6",19-6);
+	&pxor	("mm3","mm2");
+
+	&psrlq	("mm2",8-7);
+	&pxor	("mm5","mm6");
+	&psrlq	("mm6",61-19);
+	&pxor	("mm3","mm2");
+
+	&movq	("mm2",&QWP(8*(9+16),"esp"));
+
+	&psllq	("mm1",56);
+	&pxor	("mm5","mm6");
+	&psllq	("mm7",3);
+	&pxor	("mm3","mm1");
+
+	&paddq	("mm2",&QWP(8*(9+16-9),"esp"));
+
+	&psllq	("mm1",63-56);
+	&pxor	("mm5","mm7");
+	&psllq	("mm7",45-3);
+	&pxor	("mm3","mm1");
+	&pxor	("mm5","mm7");
+
+	&paddq	("mm3","mm5");
+	&paddq	("mm3","mm2");
+	&movq	(&QWP(8*9,"esp"),"mm3");
+
+	&BODY_00_15_sse2(1);
+
+	&cmp	(&LB("edx"),0x17);
+	&jne	(&label("16_79_sse2"));
+
+	# &movq	($A,$Asse2);
+	&movq	("mm1",$Bsse2);
+	&movq	("mm2",$Csse2);
+	&movq	("mm3",$Dsse2);
+	# &movq	($E,$Esse2);
+	&movq	("mm5",$Fsse2);
+	&movq	("mm6",$Gsse2);
+	&movq	("mm7",$Hsse2);
+
+	&paddq	($A,&QWP(0,"esi"));
+	&paddq	("mm1",&QWP(8,"esi"));
+	&paddq	("mm2",&QWP(16,"esi"));
+	&paddq	("mm3",&QWP(24,"esi"));
+	&paddq	($E,&QWP(32,"esi"));
+	&paddq	("mm5",&QWP(40,"esi"));
+	&paddq	("mm6",&QWP(48,"esi"));
+	&paddq	("mm7",&QWP(56,"esi"));
+
+	&movq	(&QWP(0,"esi"),$A);
+	&movq	(&QWP(8,"esi"),"mm1");
+	&movq	(&QWP(16,"esi"),"mm2");
+	&movq	(&QWP(24,"esi"),"mm3");
+	&movq	(&QWP(32,"esi"),$E);
+	&movq	(&QWP(40,"esi"),"mm5");
+	&movq	(&QWP(48,"esi"),"mm6");
+	&movq	(&QWP(56,"esi"),"mm7");
+
+	&add	("esp",8*80);			# destroy frame
+	&sub	($K512,8*80);			# rewind K
+
+	&cmp	("edi",&DWP(8*10+8,"esp"));	# are we done yet?
+	&jb	(&label("loop_sse2"));
+
+	&emms	();
+	&mov	("esp",&DWP(8*10+12,"esp"));	# restore sp
+&function_end_A();
+}
+&set_label("loop_x86",16);
+    # copy input block to stack reversing byte and qword order
+    for ($i=0;$i<8;$i++) {
+	&mov	("eax",&DWP($i*16+0,"edi"));
+	&mov	("ebx",&DWP($i*16+4,"edi"));
+	&mov	("ecx",&DWP($i*16+8,"edi"));
+	&mov	("edx",&DWP($i*16+12,"edi"));
+	&bswap	("eax");
+	&bswap	("ebx");
+	&bswap	("ecx");
+	&bswap	("edx");
+	&push	("eax");
+	&push	("ebx");
+	&push	("ecx");
+	&push	("edx");
+    }
+	&add	("edi",128);
+	&sub	("esp",9*8);		# place for T,A,B,C,D,E,F,G,H
+	&mov	(&DWP(8*(9+16)+4,"esp"),"edi");
+
+	# copy ctx->h[0-7] to A,B,C,D,E,F,G,H on stack
+	&lea	("edi",&DWP(8,"esp"));
+	&mov	("ecx",16);
+	&data_word(0xA5F3F689);		# rep movsd
+
+&set_label("00_15_x86",16);
+	&BODY_00_15_x86();
+
+	&cmp	(&LB("edx"),0x94);
+	&jne	(&label("00_15_x86"));
+
+&set_label("16_79_x86",16);
+	#define 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	("ecx",&DWP(8*(9+15+16-1)+0,"esp"));
+	&mov	("edx",&DWP(8*(9+15+16-1)+4,"esp"));
+	&mov	("esi","ecx");
+
+	&shr	("ecx",1)	# lo>>1
+	&mov	("edi","edx");
+	&shr	("edx",1)	# hi>>1
+	&mov	("eax","ecx");
+	&shl	("esi",24);	# lo<<24
+	&mov	("ebx","edx");
+	&shl	("edi",24);	# hi<<24
+	&xor	("ebx","esi");
+
+	&shr	("ecx",7-1);	# lo>>7
+	&xor	("eax","edi");
+	&shr	("edx",7-1);	# hi>>7
+	&xor	("eax","ecx");
+	&shl	("esi",31-24);	# lo<<31
+	&xor	("ebx","edx");
+	&shl	("edi",25-24);	# hi<<25
+	&xor	("ebx","esi");
+
+	&shr	("ecx",8-7);	# lo>>8
+	&xor	("eax","edi");
+	&shr	("edx",8-7);	# hi>>8
+	&xor	("eax","ecx");
+	&shl	("edi",31-25);	# hi<<31
+	&xor	("ebx","edx");
+	&xor	("eax","edi");			# T1 = sigma0(X[-15])
+
+	&mov	(&DWP(0,"esp"),"eax");
+	&mov	(&DWP(4,"esp"),"ebx");		# put T1 away
+
+	#define 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	("ecx",&DWP(8*(9+15+16-14)+0,"esp"));
+	&mov	("edx",&DWP(8*(9+15+16-14)+4,"esp"));
+	&mov	("esi","ecx");
+
+	&shr	("ecx",6)	# lo>>6
+	&mov	("edi","edx");
+	&shr	("edx",6)	# hi>>6
+	&mov	("eax","ecx");
+	&shl	("esi",3);	# lo<<3
+	&mov	("ebx","edx");
+	&shl	("edi",3);	# hi<<3
+	&xor	("eax","esi");
+
+	&shr	("ecx",19-6);	# lo>>19
+	&xor	("ebx","edi");
+	&shr	("edx",19-6);	# hi>>19
+	&xor	("eax","ecx");
+	&shl	("esi",13-3);	# lo<<13
+	&xor	("ebx","edx");
+	&shl	("edi",13-3);	# hi<<13
+	&xor	("ebx","esi");
+
+	&shr	("ecx",29-19);	# lo>>29
+	&xor	("eax","edi");
+	&shr	("edx",29-19);	# hi>>29
+	&xor	("ebx","ecx");
+	&shl	("edi",26-13);	# hi<<26
+	&xor	("eax","edx");
+	&xor	("eax","edi");			# sigma1(X[-2])
+
+	&mov	("ecx",&DWP(8*(9+15+16)+0,"esp"));
+	&mov	("edx",&DWP(8*(9+15+16)+4,"esp"));
+	&add	("eax",&DWP(0,"esp"));
+	&adc	("ebx",&DWP(4,"esp"));		# T1 = sigma1(X[-2])+T1
+	&mov	("esi",&DWP(8*(9+15+16-9)+0,"esp"));
+	&mov	("edi",&DWP(8*(9+15+16-9)+4,"esp"));
+	&add	("eax","ecx");
+	&adc	("ebx","edx");			# T1 += X[-16]
+	&add	("eax","esi");
+	&adc	("ebx","edi");			# T1 += X[-7]
+	&mov	(&DWP(8*(9+15)+0,"esp"),"eax");
+	&mov	(&DWP(8*(9+15)+4,"esp"),"ebx");	# save X[0]
+
+	&BODY_00_15_x86();
+
+	&cmp	(&LB("edx"),0x17);
+	&jne	(&label("16_79_x86"));
+
+	&mov	("esi",&DWP(8*(9+16+80)+0,"esp"));# ctx
+	&mov	("edi",&DWP(8*(9+16+80)+4,"esp"));# inp
+    for($i=0;$i<4;$i++) {
+	&mov	("eax",&DWP($i*16+0,"esi"));
+	&mov	("ebx",&DWP($i*16+4,"esi"));
+	&mov	("ecx",&DWP($i*16+8,"esi"));
+	&mov	("edx",&DWP($i*16+12,"esi"));
+	&add	("eax",&DWP(8+($i*16)+0,"esp"));
+	&adc	("ebx",&DWP(8+($i*16)+4,"esp"));
+	&mov	(&DWP($i*16+0,"esi"),"eax");
+	&mov	(&DWP($i*16+4,"esi"),"ebx");
+	&add	("ecx",&DWP(8+($i*16)+8,"esp"));
+	&adc	("edx",&DWP(8+($i*16)+12,"esp"));
+	&mov	(&DWP($i*16+8,"esi"),"ecx");
+	&mov	(&DWP($i*16+12,"esi"),"edx");
+    }
+	&add	("esp",8*(9+16+80));		# destroy frame
+	&sub	($K512,8*80);			# rewind K
+
+	&cmp	("edi",&DWP(8,"esp"));		# are we done yet?
+	&jb	(&label("loop_x86"));
+
+	&mov	("esp",&DWP(12,"esp"));		# restore sp
+&function_end_A();
+
+&set_label("K512",64);	# Yes! I keep it in the code segment!
+	&data_word(0xd728ae22,0x428a2f98);	# u64
+	&data_word(0x23ef65cd,0x71374491);	# u64
+	&data_word(0xec4d3b2f,0xb5c0fbcf);	# u64
+	&data_word(0x8189dbbc,0xe9b5dba5);	# u64
+	&data_word(0xf348b538,0x3956c25b);	# u64
+	&data_word(0xb605d019,0x59f111f1);	# u64
+	&data_word(0xaf194f9b,0x923f82a4);	# u64
+	&data_word(0xda6d8118,0xab1c5ed5);	# u64
+	&data_word(0xa3030242,0xd807aa98);	# u64
+	&data_word(0x45706fbe,0x12835b01);	# u64
+	&data_word(0x4ee4b28c,0x243185be);	# u64
+	&data_word(0xd5ffb4e2,0x550c7dc3);	# u64
+	&data_word(0xf27b896f,0x72be5d74);	# u64
+	&data_word(0x3b1696b1,0x80deb1fe);	# u64
+	&data_word(0x25c71235,0x9bdc06a7);	# u64
+	&data_word(0xcf692694,0xc19bf174);	# u64
+	&data_word(0x9ef14ad2,0xe49b69c1);	# u64
+	&data_word(0x384f25e3,0xefbe4786);	# u64
+	&data_word(0x8b8cd5b5,0x0fc19dc6);	# u64
+	&data_word(0x77ac9c65,0x240ca1cc);	# u64
+	&data_word(0x592b0275,0x2de92c6f);	# u64
+	&data_word(0x6ea6e483,0x4a7484aa);	# u64
+	&data_word(0xbd41fbd4,0x5cb0a9dc);	# u64
+	&data_word(0x831153b5,0x76f988da);	# u64
+	&data_word(0xee66dfab,0x983e5152);	# u64
+	&data_word(0x2db43210,0xa831c66d);	# u64
+	&data_word(0x98fb213f,0xb00327c8);	# u64
+	&data_word(0xbeef0ee4,0xbf597fc7);	# u64
+	&data_word(0x3da88fc2,0xc6e00bf3);	# u64
+	&data_word(0x930aa725,0xd5a79147);	# u64
+	&data_word(0xe003826f,0x06ca6351);	# u64
+	&data_word(0x0a0e6e70,0x14292967);	# u64
+	&data_word(0x46d22ffc,0x27b70a85);	# u64
+	&data_word(0x5c26c926,0x2e1b2138);	# u64
+	&data_word(0x5ac42aed,0x4d2c6dfc);	# u64
+	&data_word(0x9d95b3df,0x53380d13);	# u64
+	&data_word(0x8baf63de,0x650a7354);	# u64
+	&data_word(0x3c77b2a8,0x766a0abb);	# u64
+	&data_word(0x47edaee6,0x81c2c92e);	# u64
+	&data_word(0x1482353b,0x92722c85);	# u64
+	&data_word(0x4cf10364,0xa2bfe8a1);	# u64
+	&data_word(0xbc423001,0xa81a664b);	# u64
+	&data_word(0xd0f89791,0xc24b8b70);	# u64
+	&data_word(0x0654be30,0xc76c51a3);	# u64
+	&data_word(0xd6ef5218,0xd192e819);	# u64
+	&data_word(0x5565a910,0xd6990624);	# u64
+	&data_word(0x5771202a,0xf40e3585);	# u64
+	&data_word(0x32bbd1b8,0x106aa070);	# u64
+	&data_word(0xb8d2d0c8,0x19a4c116);	# u64
+	&data_word(0x5141ab53,0x1e376c08);	# u64
+	&data_word(0xdf8eeb99,0x2748774c);	# u64
+	&data_word(0xe19b48a8,0x34b0bcb5);	# u64
+	&data_word(0xc5c95a63,0x391c0cb3);	# u64
+	&data_word(0xe3418acb,0x4ed8aa4a);	# u64
+	&data_word(0x7763e373,0x5b9cca4f);	# u64
+	&data_word(0xd6b2b8a3,0x682e6ff3);	# u64
+	&data_word(0x5defb2fc,0x748f82ee);	# u64
+	&data_word(0x43172f60,0x78a5636f);	# u64
+	&data_word(0xa1f0ab72,0x84c87814);	# u64
+	&data_word(0x1a6439ec,0x8cc70208);	# u64
+	&data_word(0x23631e28,0x90befffa);	# u64
+	&data_word(0xde82bde9,0xa4506ceb);	# u64
+	&data_word(0xb2c67915,0xbef9a3f7);	# u64
+	&data_word(0xe372532b,0xc67178f2);	# u64
+	&data_word(0xea26619c,0xca273ece);	# u64
+	&data_word(0x21c0c207,0xd186b8c7);	# u64
+	&data_word(0xcde0eb1e,0xeada7dd6);	# u64
+	&data_word(0xee6ed178,0xf57d4f7f);	# u64
+	&data_word(0x72176fba,0x06f067aa);	# u64
+	&data_word(0xa2c898a6,0x0a637dc5);	# u64
+	&data_word(0xbef90dae,0x113f9804);	# u64
+	&data_word(0x131c471b,0x1b710b35);	# u64
+	&data_word(0x23047d84,0x28db77f5);	# u64
+	&data_word(0x40c72493,0x32caab7b);	# u64
+	&data_word(0x15c9bebc,0x3c9ebe0a);	# u64
+	&data_word(0x9c100d4c,0x431d67c4);	# u64
+	&data_word(0xcb3e42b6,0x4cc5d4be);	# u64
+	&data_word(0xfc657e2a,0x597f299c);	# u64
+	&data_word(0x3ad6faec,0x5fcb6fab);	# u64
+	&data_word(0x4a475817,0x6c44198c);	# u64
+&function_end_B("sha512_block_data_order");
+&asciz("SHA512 block transform for x86, CRYPTOGAMS by <appro\@openssl.org>");
+
+&asm_finish();
diff --git a/crypto/0.9.9-dev/sha/sha512-armv4.pl b/crypto/sha/asm/sha512-armv4.pl
similarity index 99%
rename from crypto/0.9.9-dev/sha/sha512-armv4.pl
rename to crypto/sha/asm/sha512-armv4.pl
index f27e9cd..4fbb94a 100644
--- a/crypto/0.9.9-dev/sha/sha512-armv4.pl
+++ b/crypto/sha/asm/sha512-armv4.pl
@@ -390,6 +390,7 @@
 	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>"
+.align	2
 ___
 
 $code =~ s/\`([^\`]*)\`/eval $1/gem;
diff --git a/crypto/0.9.9-dev/sha/sha512-armv4.s b/crypto/sha/asm/sha512-armv4.s
similarity index 99%
rename from crypto/0.9.9-dev/sha/sha512-armv4.s
rename to crypto/sha/asm/sha512-armv4.s
index 9ec2ff1..b0bf9b6 100644
--- a/crypto/0.9.9-dev/sha/sha512-armv4.s
+++ b/crypto/sha/asm/sha512-armv4.s
@@ -413,3 +413,4 @@
 	.word	0xe12fff1e			@ interoperable with Thumb ISA:-)
 .size   sha512_block_data_order,.-sha512_block_data_order
 .asciz  "SHA512 block transform for ARMv4, CRYPTOGAMS by <appro@openssl.org>"
+.align	2
diff --git a/crypto/sha/asm/sha512-ppc.pl b/crypto/sha/asm/sha512-ppc.pl
new file mode 100755
index 0000000..768a6a6
--- /dev/null
+++ b/crypto/sha/asm/sha512-ppc.pl
@@ -0,0 +1,462 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# I let hardware handle unaligned input, except on page boundaries
+# (see below for details). Otherwise straightforward implementation
+# with X vector in register bank. The module is big-endian [which is
+# not big deal as there're no little-endian targets left around].
+
+#			sha256		|	sha512
+# 			-m64	-m32	|	-m64	-m32
+# --------------------------------------+-----------------------
+# PPC970,gcc-4.0.0	+50%	+38%	|	+40%	+410%(*)
+# Power6,xlc-7		+150%	+90%	|	+100%	+430%(*)
+#
+# (*)	64-bit code in 32-bit application context, which actually is
+#	on TODO list. It should be noted that for safe deployment in
+#	32-bit *mutli-threaded* context asyncronous signals should be
+#	blocked upon entry to SHA512 block routine. This is because
+#	32-bit signaling procedure invalidates upper halves of GPRs.
+#	Context switch procedure preserves them, but not signaling:-(
+
+# Second version is true multi-thread safe. Trouble with the original
+# version was that it was using thread local storage pointer register.
+# Well, it scrupulously preserved it, but the problem would arise the
+# moment asynchronous signal was delivered and signal handler would
+# dereference the TLS pointer. While it's never the case in openssl
+# application or test suite, we have to respect this scenario and not
+# use TLS pointer register. Alternative would be to require caller to
+# block signals prior calling this routine. For the record, in 32-bit
+# context R2 serves as TLS pointer, while in 64-bit context - R13.
+
+$flavour=shift;
+$output =shift;
+
+if ($flavour =~ /64/) {
+	$SIZE_T=8;
+	$STU="stdu";
+	$UCMP="cmpld";
+	$SHL="sldi";
+	$POP="ld";
+	$PUSH="std";
+} elsif ($flavour =~ /32/) {
+	$SIZE_T=4;
+	$STU="stwu";
+	$UCMP="cmplw";
+	$SHL="slwi";
+	$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 $output" || die "can't call $xlate: $!";
+
+if ($output =~ /512/) {
+	$func="sha512_block_data_order";
+	$SZ=8;
+	@Sigma0=(28,34,39);
+	@Sigma1=(14,18,41);
+	@sigma0=(1,  8, 7);
+	@sigma1=(19,61, 6);
+	$rounds=80;
+	$LD="ld";
+	$ST="std";
+	$ROR="rotrdi";
+	$SHR="srdi";
+} else {
+	$func="sha256_block_data_order";
+	$SZ=4;
+	@Sigma0=( 2,13,22);
+	@Sigma1=( 6,11,25);
+	@sigma0=( 7,18, 3);
+	@sigma1=(17,19,10);
+	$rounds=64;
+	$LD="lwz";
+	$ST="stw";
+	$ROR="rotrwi";
+	$SHR="srwi";
+}
+
+$FRAME=32*$SIZE_T;
+
+$sp ="r1";
+$toc="r2";
+$ctx="r3";	# zapped by $a0
+$inp="r4";	# zapped by $a1
+$num="r5";	# zapped by $t0
+
+$T  ="r0";
+$a0 ="r3";
+$a1 ="r4";
+$t0 ="r5";
+$t1 ="r6";
+$Tbl="r7";
+
+$A  ="r8";
+$B  ="r9";
+$C  ="r10";
+$D  ="r11";
+$E  ="r12";
+$F  ="r13";	$F="r2" if ($SIZE_T==8);# reassigned to exempt TLS pointer
+$G  ="r14";
+$H  ="r15";
+
+@V=($A,$B,$C,$D,$E,$F,$G,$H);
+@X=("r16","r17","r18","r19","r20","r21","r22","r23",
+    "r24","r25","r26","r27","r28","r29","r30","r31");
+
+$inp="r31";	# reassigned $inp! aliases with @X[15]
+
+sub ROUND_00_15 {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
+$code.=<<___;
+	$LD	$T,`$i*$SZ`($Tbl)
+	$ROR	$a0,$e,$Sigma1[0]
+	$ROR	$a1,$e,$Sigma1[1]
+	and	$t0,$f,$e
+	andc	$t1,$g,$e
+	add	$T,$T,$h
+	xor	$a0,$a0,$a1
+	$ROR	$a1,$a1,`$Sigma1[2]-$Sigma1[1]`
+	or	$t0,$t0,$t1		; Ch(e,f,g)
+	add	$T,$T,@X[$i]
+	xor	$a0,$a0,$a1		; Sigma1(e)
+	add	$T,$T,$t0
+	add	$T,$T,$a0
+
+	$ROR	$a0,$a,$Sigma0[0]
+	$ROR	$a1,$a,$Sigma0[1]
+	and	$t0,$a,$b
+	and	$t1,$a,$c
+	xor	$a0,$a0,$a1
+	$ROR	$a1,$a1,`$Sigma0[2]-$Sigma0[1]`
+	xor	$t0,$t0,$t1
+	and	$t1,$b,$c
+	xor	$a0,$a0,$a1		; Sigma0(a)
+	add	$d,$d,$T
+	xor	$t0,$t0,$t1		; Maj(a,b,c)
+	add	$h,$T,$a0
+	add	$h,$h,$t0
+
+___
+}
+
+sub ROUND_16_xx {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
+$i-=16;
+$code.=<<___;
+	$ROR	$a0,@X[($i+1)%16],$sigma0[0]
+	$ROR	$a1,@X[($i+1)%16],$sigma0[1]
+	$ROR	$t0,@X[($i+14)%16],$sigma1[0]
+	$ROR	$t1,@X[($i+14)%16],$sigma1[1]
+	xor	$a0,$a0,$a1
+	$SHR	$a1,@X[($i+1)%16],$sigma0[2]
+	xor	$t0,$t0,$t1
+	$SHR	$t1,@X[($i+14)%16],$sigma1[2]
+	add	@X[$i],@X[$i],@X[($i+9)%16]
+	xor	$a0,$a0,$a1		; sigma0(X[(i+1)&0x0f])
+	xor	$t0,$t0,$t1		; sigma1(X[(i+14)&0x0f])
+	add	@X[$i],@X[$i],$a0
+	add	@X[$i],@X[$i],$t0
+___
+&ROUND_00_15($i,$a,$b,$c,$d,$e,$f,$g,$h);
+}
+
+$code=<<___;
+.machine	"any"
+.text
+
+.globl	$func
+.align	6
+$func:
+	mflr	r0
+	$STU	$sp,`-($FRAME+16*$SZ)`($sp)
+	$SHL	$num,$num,`log(16*$SZ)/log(2)`
+
+	$PUSH	$ctx,`$FRAME-$SIZE_T*22`($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)
+
+	$LD	$A,`0*$SZ`($ctx)
+	mr	$inp,r4				; incarnate $inp
+	$LD	$B,`1*$SZ`($ctx)
+	$LD	$C,`2*$SZ`($ctx)
+	$LD	$D,`3*$SZ`($ctx)
+	$LD	$E,`4*$SZ`($ctx)
+	$LD	$F,`5*$SZ`($ctx)
+	$LD	$G,`6*$SZ`($ctx)
+	$LD	$H,`7*$SZ`($ctx)
+
+	b	LPICmeup
+LPICedup:
+	andi.	r0,$inp,3
+	bne	Lunaligned
+Laligned:
+	add	$num,$inp,$num
+	$PUSH	$num,`$FRAME-$SIZE_T*24`($sp)	; end pointer
+	$PUSH	$inp,`$FRAME-$SIZE_T*23`($sp)	; inp pointer
+	bl	Lsha2_block_private
+Ldone:
+	$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+16*$SZ`
+	blr
+___
+
+# PowerPC specification allows an implementation to be ill-behaved
+# upon unaligned access which crosses page boundary. "Better safe
+# than sorry" principle makes me treat it specially. But I don't
+# look for particular offending word, but rather for the input
+# block which crosses the boundary. Once found that block is aligned
+# and hashed separately...
+$code.=<<___;
+.align	4
+Lunaligned:
+	subfic	$t1,$inp,4096
+	andi.	$t1,$t1,`4096-16*$SZ`	; distance to closest page boundary
+	beq	Lcross_page
+	$UCMP	$num,$t1
+	ble-	Laligned		; didn't cross the page boundary
+	subfc	$num,$t1,$num
+	add	$t1,$inp,$t1
+	$PUSH	$num,`$FRAME-$SIZE_T*25`($sp)	; save real remaining num
+	$PUSH	$t1,`$FRAME-$SIZE_T*24`($sp)	; intermediate end pointer
+	$PUSH	$inp,`$FRAME-$SIZE_T*23`($sp)	; inp pointer
+	bl	Lsha2_block_private
+	; $inp equals to the intermediate end pointer here
+	$POP	$num,`$FRAME-$SIZE_T*25`($sp)	; restore real remaining num
+Lcross_page:
+	li	$t1,`16*$SZ/4`
+	mtctr	$t1
+	addi	r20,$sp,$FRAME			; aligned spot below the frame
+Lmemcpy:
+	lbz	r16,0($inp)
+	lbz	r17,1($inp)
+	lbz	r18,2($inp)
+	lbz	r19,3($inp)
+	addi	$inp,$inp,4
+	stb	r16,0(r20)
+	stb	r17,1(r20)
+	stb	r18,2(r20)
+	stb	r19,3(r20)
+	addi	r20,r20,4
+	bdnz	Lmemcpy
+
+	$PUSH	$inp,`$FRAME-$SIZE_T*26`($sp)	; save real inp
+	addi	$t1,$sp,`$FRAME+16*$SZ`		; fictitious end pointer
+	addi	$inp,$sp,$FRAME			; fictitious inp pointer
+	$PUSH	$num,`$FRAME-$SIZE_T*25`($sp)	; save real num
+	$PUSH	$t1,`$FRAME-$SIZE_T*24`($sp)	; end pointer
+	$PUSH	$inp,`$FRAME-$SIZE_T*23`($sp)	; inp pointer
+	bl	Lsha2_block_private
+	$POP	$inp,`$FRAME-$SIZE_T*26`($sp)	; restore real inp
+	$POP	$num,`$FRAME-$SIZE_T*25`($sp)	; restore real num
+	addic.	$num,$num,`-16*$SZ`		; num--
+	bne-	Lunaligned
+	b	Ldone
+___
+
+$code.=<<___;
+.align	4
+Lsha2_block_private:
+___
+for($i=0;$i<16;$i++) {
+$code.=<<___ if ($SZ==4);
+	lwz	@X[$i],`$i*$SZ`($inp)
+___
+# 64-bit loads are split to 2x32-bit ones, as CPU can't handle
+# unaligned 64-bit loads, only 32-bit ones...
+$code.=<<___ if ($SZ==8);
+	lwz	$t0,`$i*$SZ`($inp)
+	lwz	@X[$i],`$i*$SZ+4`($inp)
+	insrdi	@X[$i],$t0,32,0
+___
+	&ROUND_00_15($i,@V);
+	unshift(@V,pop(@V));
+}
+$code.=<<___;
+	li	$T,`$rounds/16-1`
+	mtctr	$T
+.align	4
+Lrounds:
+	addi	$Tbl,$Tbl,`16*$SZ`
+___
+for(;$i<32;$i++) {
+	&ROUND_16_xx($i,@V);
+	unshift(@V,pop(@V));
+}
+$code.=<<___;
+	bdnz-	Lrounds
+
+	$POP	$ctx,`$FRAME-$SIZE_T*22`($sp)
+	$POP	$inp,`$FRAME-$SIZE_T*23`($sp)	; inp pointer
+	$POP	$num,`$FRAME-$SIZE_T*24`($sp)	; end pointer
+	subi	$Tbl,$Tbl,`($rounds-16)*$SZ`	; rewind Tbl
+
+	$LD	r16,`0*$SZ`($ctx)
+	$LD	r17,`1*$SZ`($ctx)
+	$LD	r18,`2*$SZ`($ctx)
+	$LD	r19,`3*$SZ`($ctx)
+	$LD	r20,`4*$SZ`($ctx)
+	$LD	r21,`5*$SZ`($ctx)
+	$LD	r22,`6*$SZ`($ctx)
+	addi	$inp,$inp,`16*$SZ`		; advance inp
+	$LD	r23,`7*$SZ`($ctx)
+	add	$A,$A,r16
+	add	$B,$B,r17
+	$PUSH	$inp,`$FRAME-$SIZE_T*23`($sp)
+	add	$C,$C,r18
+	$ST	$A,`0*$SZ`($ctx)
+	add	$D,$D,r19
+	$ST	$B,`1*$SZ`($ctx)
+	add	$E,$E,r20
+	$ST	$C,`2*$SZ`($ctx)
+	add	$F,$F,r21
+	$ST	$D,`3*$SZ`($ctx)
+	add	$G,$G,r22
+	$ST	$E,`4*$SZ`($ctx)
+	add	$H,$H,r23
+	$ST	$F,`5*$SZ`($ctx)
+	$ST	$G,`6*$SZ`($ctx)
+	$UCMP	$inp,$num
+	$ST	$H,`7*$SZ`($ctx)
+	bne	Lsha2_block_private
+	blr
+___
+
+# Ugly hack here, because PPC assembler syntax seem to vary too
+# much from platforms to platform...
+$code.=<<___;
+.align	6
+LPICmeup:
+	bl	LPIC
+	addi	$Tbl,$Tbl,`64-4`	; "distance" between . and last nop
+	b	LPICedup
+	nop
+	nop
+	nop
+	nop
+	nop
+LPIC:	mflr	$Tbl
+	blr
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+___
+$code.=<<___ if ($SZ==8);
+	.long	0x428a2f98,0xd728ae22,0x71374491,0x23ef65cd
+	.long	0xb5c0fbcf,0xec4d3b2f,0xe9b5dba5,0x8189dbbc
+	.long	0x3956c25b,0xf348b538,0x59f111f1,0xb605d019
+	.long	0x923f82a4,0xaf194f9b,0xab1c5ed5,0xda6d8118
+	.long	0xd807aa98,0xa3030242,0x12835b01,0x45706fbe
+	.long	0x243185be,0x4ee4b28c,0x550c7dc3,0xd5ffb4e2
+	.long	0x72be5d74,0xf27b896f,0x80deb1fe,0x3b1696b1
+	.long	0x9bdc06a7,0x25c71235,0xc19bf174,0xcf692694
+	.long	0xe49b69c1,0x9ef14ad2,0xefbe4786,0x384f25e3
+	.long	0x0fc19dc6,0x8b8cd5b5,0x240ca1cc,0x77ac9c65
+	.long	0x2de92c6f,0x592b0275,0x4a7484aa,0x6ea6e483
+	.long	0x5cb0a9dc,0xbd41fbd4,0x76f988da,0x831153b5
+	.long	0x983e5152,0xee66dfab,0xa831c66d,0x2db43210
+	.long	0xb00327c8,0x98fb213f,0xbf597fc7,0xbeef0ee4
+	.long	0xc6e00bf3,0x3da88fc2,0xd5a79147,0x930aa725
+	.long	0x06ca6351,0xe003826f,0x14292967,0x0a0e6e70
+	.long	0x27b70a85,0x46d22ffc,0x2e1b2138,0x5c26c926
+	.long	0x4d2c6dfc,0x5ac42aed,0x53380d13,0x9d95b3df
+	.long	0x650a7354,0x8baf63de,0x766a0abb,0x3c77b2a8
+	.long	0x81c2c92e,0x47edaee6,0x92722c85,0x1482353b
+	.long	0xa2bfe8a1,0x4cf10364,0xa81a664b,0xbc423001
+	.long	0xc24b8b70,0xd0f89791,0xc76c51a3,0x0654be30
+	.long	0xd192e819,0xd6ef5218,0xd6990624,0x5565a910
+	.long	0xf40e3585,0x5771202a,0x106aa070,0x32bbd1b8
+	.long	0x19a4c116,0xb8d2d0c8,0x1e376c08,0x5141ab53
+	.long	0x2748774c,0xdf8eeb99,0x34b0bcb5,0xe19b48a8
+	.long	0x391c0cb3,0xc5c95a63,0x4ed8aa4a,0xe3418acb
+	.long	0x5b9cca4f,0x7763e373,0x682e6ff3,0xd6b2b8a3
+	.long	0x748f82ee,0x5defb2fc,0x78a5636f,0x43172f60
+	.long	0x84c87814,0xa1f0ab72,0x8cc70208,0x1a6439ec
+	.long	0x90befffa,0x23631e28,0xa4506ceb,0xde82bde9
+	.long	0xbef9a3f7,0xb2c67915,0xc67178f2,0xe372532b
+	.long	0xca273ece,0xea26619c,0xd186b8c7,0x21c0c207
+	.long	0xeada7dd6,0xcde0eb1e,0xf57d4f7f,0xee6ed178
+	.long	0x06f067aa,0x72176fba,0x0a637dc5,0xa2c898a6
+	.long	0x113f9804,0xbef90dae,0x1b710b35,0x131c471b
+	.long	0x28db77f5,0x23047d84,0x32caab7b,0x40c72493
+	.long	0x3c9ebe0a,0x15c9bebc,0x431d67c4,0x9c100d4c
+	.long	0x4cc5d4be,0xcb3e42b6,0x597f299c,0xfc657e2a
+	.long	0x5fcb6fab,0x3ad6faec,0x6c44198c,0x4a475817
+___
+$code.=<<___ if ($SZ==4);
+	.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+	.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+	.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+	.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+	.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+	.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+	.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+	.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+	.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+	.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+	.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+	.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+	.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+	.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+	.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+	.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/crypto/sha/asm/sha512-s390x.pl b/crypto/sha/asm/sha512-s390x.pl
new file mode 100644
index 0000000..e7ef2d5
--- /dev/null
+++ b/crypto/sha/asm/sha512-s390x.pl
@@ -0,0 +1,301 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# SHA256/512 block procedures for s390x.
+
+# April 2007.
+#
+# sha256_block_data_order is reportedly >3 times faster than gcc 3.3
+# generated code (must be a bug in compiler, as improvement is
+# "pathologically" high, in particular in comparison to other SHA
+# modules). But the real twist is that it detects if hardware support
+# for SHA256 is available and in such case utilizes it. Then the
+# performance can reach >6.5x of assembler one for larger chunks.
+#
+# sha512_block_data_order is ~70% faster than gcc 3.3 generated code.
+
+# January 2009.
+#
+# Add support for hardware SHA512 and reschedule instructions to
+# favour dual-issue z10 pipeline. Hardware SHA256/512 is ~4.7x faster
+# than software.
+
+$t0="%r0";
+$t1="%r1";
+$ctx="%r2";	$t2="%r2";
+$inp="%r3";
+$len="%r4";	# used as index in inner loop
+
+$A="%r5";
+$B="%r6";
+$C="%r7";
+$D="%r8";
+$E="%r9";
+$F="%r10";
+$G="%r11";
+$H="%r12";	@V=($A,$B,$C,$D,$E,$F,$G,$H);
+$tbl="%r13";
+$T1="%r14";
+$sp="%r15";
+
+$output=shift;
+open STDOUT,">$output";
+
+if ($output =~ /512/) {
+	$label="512";
+	$SZ=8;
+	$LD="lg";	# load from memory
+	$ST="stg";	# store to memory
+	$ADD="alg";	# add with memory operand
+	$ROT="rllg";	# rotate left
+	$SHR="srlg";	# logical right shift [see even at the end]
+	@Sigma0=(25,30,36);
+	@Sigma1=(23,46,50);
+	@sigma0=(56,63, 7);
+	@sigma1=( 3,45, 6);
+	$rounds=80;
+	$kimdfunc=3;	# 0 means unknown/unsupported/unimplemented/disabled
+} else {
+	$label="256";
+	$SZ=4;
+	$LD="llgf";	# load from memory
+	$ST="st";	# store to memory
+	$ADD="al";	# add with memory operand
+	$ROT="rll";	# rotate left
+	$SHR="srl";	# logical right shift
+	@Sigma0=(10,19,30);
+	@Sigma1=( 7,21,26);
+	@sigma0=(14,25, 3);
+	@sigma1=(13,15,10);
+	$rounds=64;
+	$kimdfunc=2;	# magic function code for kimd instruction
+}
+$Func="sha${label}_block_data_order";
+$Table="K${label}";
+$frame=160+16*$SZ;
+
+sub BODY_00_15 {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
+
+$code.=<<___ if ($i<16);
+	$LD	$T1,`$i*$SZ`($inp)	### $i
+___
+$code.=<<___;
+	$ROT	$t0,$e,$Sigma1[0]
+	$ROT	$t1,$e,$Sigma1[1]
+	 lgr	$t2,$f
+	xgr	$t0,$t1
+	$ROT	$t1,$t1,`$Sigma1[2]-$Sigma1[1]`
+	 xgr	$t2,$g
+	$ST	$T1,`160+$SZ*($i%16)`($sp)
+	xgr	$t0,$t1			# Sigma1(e)
+	la	$T1,0($T1,$h)		# T1+=h
+	 ngr	$t2,$e
+	 lgr	$t1,$a
+	algr	$T1,$t0			# T1+=Sigma1(e)
+	$ROT	$h,$a,$Sigma0[0]
+	 xgr	$t2,$g			# Ch(e,f,g)
+	$ADD	$T1,`$i*$SZ`($len,$tbl)	# T1+=K[i]
+	$ROT	$t0,$a,$Sigma0[1]
+	algr	$T1,$t2			# T1+=Ch(e,f,g)
+	 ogr	$t1,$b
+	xgr	$h,$t0
+	 lgr	$t2,$a
+	 ngr	$t1,$c
+	$ROT	$t0,$t0,`$Sigma0[2]-$Sigma0[1]`
+	xgr	$h,$t0			# h=Sigma0(a)
+	 ngr	$t2,$b
+	algr	$h,$T1			# h+=T1
+	 ogr	$t2,$t1			# Maj(a,b,c)
+	la	$d,0($d,$T1)		# d+=T1
+	algr	$h,$t2			# h+=Maj(a,b,c)
+___
+}
+
+sub BODY_16_XX {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
+
+$code.=<<___;
+	$LD	$T1,`160+$SZ*(($i+1)%16)`($sp)	### $i
+	$LD	$t1,`160+$SZ*(($i+14)%16)`($sp)
+	$ROT	$t0,$T1,$sigma0[0]
+	$SHR	$T1,$sigma0[2]
+	$ROT	$t2,$t0,`$sigma0[1]-$sigma0[0]`
+	xgr	$T1,$t0
+	$ROT	$t0,$t1,$sigma1[0]
+	xgr	$T1,$t2				# sigma0(X[i+1])
+	$SHR	$t1,$sigma1[2]
+	$ADD	$T1,`160+$SZ*($i%16)`($sp)	# +=X[i]
+	xgr	$t1,$t0
+	$ROT	$t0,$t0,`$sigma1[1]-$sigma1[0]`
+	$ADD	$T1,`160+$SZ*(($i+9)%16)`($sp)	# +=X[i+9]
+	xgr	$t1,$t0				# sigma1(X[i+14])
+	algr	$T1,$t1				# +=sigma1(X[i+14])
+___
+	&BODY_00_15(@_);
+}
+
+$code.=<<___;
+.text
+.align	64
+.type	$Table,\@object
+$Table:
+___
+$code.=<<___ if ($SZ==4);
+	.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+	.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+	.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+	.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+	.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+	.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+	.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+	.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+	.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+	.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+	.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+	.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+	.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+	.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+	.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+	.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+___
+$code.=<<___ if ($SZ==8);
+	.quad	0x428a2f98d728ae22,0x7137449123ef65cd
+	.quad	0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
+	.quad	0x3956c25bf348b538,0x59f111f1b605d019
+	.quad	0x923f82a4af194f9b,0xab1c5ed5da6d8118
+	.quad	0xd807aa98a3030242,0x12835b0145706fbe
+	.quad	0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
+	.quad	0x72be5d74f27b896f,0x80deb1fe3b1696b1
+	.quad	0x9bdc06a725c71235,0xc19bf174cf692694
+	.quad	0xe49b69c19ef14ad2,0xefbe4786384f25e3
+	.quad	0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
+	.quad	0x2de92c6f592b0275,0x4a7484aa6ea6e483
+	.quad	0x5cb0a9dcbd41fbd4,0x76f988da831153b5
+	.quad	0x983e5152ee66dfab,0xa831c66d2db43210
+	.quad	0xb00327c898fb213f,0xbf597fc7beef0ee4
+	.quad	0xc6e00bf33da88fc2,0xd5a79147930aa725
+	.quad	0x06ca6351e003826f,0x142929670a0e6e70
+	.quad	0x27b70a8546d22ffc,0x2e1b21385c26c926
+	.quad	0x4d2c6dfc5ac42aed,0x53380d139d95b3df
+	.quad	0x650a73548baf63de,0x766a0abb3c77b2a8
+	.quad	0x81c2c92e47edaee6,0x92722c851482353b
+	.quad	0xa2bfe8a14cf10364,0xa81a664bbc423001
+	.quad	0xc24b8b70d0f89791,0xc76c51a30654be30
+	.quad	0xd192e819d6ef5218,0xd69906245565a910
+	.quad	0xf40e35855771202a,0x106aa07032bbd1b8
+	.quad	0x19a4c116b8d2d0c8,0x1e376c085141ab53
+	.quad	0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
+	.quad	0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
+	.quad	0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
+	.quad	0x748f82ee5defb2fc,0x78a5636f43172f60
+	.quad	0x84c87814a1f0ab72,0x8cc702081a6439ec
+	.quad	0x90befffa23631e28,0xa4506cebde82bde9
+	.quad	0xbef9a3f7b2c67915,0xc67178f2e372532b
+	.quad	0xca273eceea26619c,0xd186b8c721c0c207
+	.quad	0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
+	.quad	0x06f067aa72176fba,0x0a637dc5a2c898a6
+	.quad	0x113f9804bef90dae,0x1b710b35131c471b
+	.quad	0x28db77f523047d84,0x32caab7b40c72493
+	.quad	0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
+	.quad	0x4cc5d4becb3e42b6,0x597f299cfc657e2a
+	.quad	0x5fcb6fab3ad6faec,0x6c44198c4a475817
+___
+$code.=<<___;
+.size	$Table,.-$Table
+.globl	$Func
+.type	$Func,\@function
+$Func:
+___
+$code.=<<___ if ($kimdfunc);
+	larl	%r1,OPENSSL_s390xcap_P
+	lg	%r0,0(%r1)
+	tmhl	%r0,0x4000	# check for message-security assist
+	jz	.Lsoftware
+	lghi	%r0,0
+	la	%r1,16($sp)
+	.long	0xb93e0002	# kimd %r0,%r2
+	lg	%r0,16($sp)
+	tmhh	%r0,`0x8000>>$kimdfunc`
+	jz	.Lsoftware
+	lghi	%r0,$kimdfunc
+	lgr	%r1,$ctx
+	lgr	%r2,$inp
+	sllg	%r3,$len,`log(16*$SZ)/log(2)`
+	.long	0xb93e0002	# kimd %r0,%r2
+	brc	1,.-4		# pay attention to "partial completion"
+	br	%r14
+.align	16
+.Lsoftware:
+___
+$code.=<<___;
+	sllg	$len,$len,`log(16*$SZ)/log(2)`
+	lghi	%r1,-$frame
+	agr	$len,$inp
+	stmg	$ctx,%r15,16($sp)
+	lgr	%r0,$sp
+	la	$sp,0(%r1,$sp)
+	stg	%r0,0($sp)
+
+	larl	$tbl,$Table
+	$LD	$A,`0*$SZ`($ctx)
+	$LD	$B,`1*$SZ`($ctx)
+	$LD	$C,`2*$SZ`($ctx)
+	$LD	$D,`3*$SZ`($ctx)
+	$LD	$E,`4*$SZ`($ctx)
+	$LD	$F,`5*$SZ`($ctx)
+	$LD	$G,`6*$SZ`($ctx)
+	$LD	$H,`7*$SZ`($ctx)
+
+.Lloop:
+	lghi	$len,0
+___
+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.=<<___;
+	aghi	$len,`16*$SZ`
+	lghi	$t0,`($rounds-16)*$SZ`
+	clgr	$len,$t0
+	jne	.Lrounds_16_xx
+
+	lg	$ctx,`$frame+16`($sp)
+	la	$inp,`16*$SZ`($inp)
+	$ADD	$A,`0*$SZ`($ctx)
+	$ADD	$B,`1*$SZ`($ctx)
+	$ADD	$C,`2*$SZ`($ctx)
+	$ADD	$D,`3*$SZ`($ctx)
+	$ADD	$E,`4*$SZ`($ctx)
+	$ADD	$F,`5*$SZ`($ctx)
+	$ADD	$G,`6*$SZ`($ctx)
+	$ADD	$H,`7*$SZ`($ctx)
+	$ST	$A,`0*$SZ`($ctx)
+	$ST	$B,`1*$SZ`($ctx)
+	$ST	$C,`2*$SZ`($ctx)
+	$ST	$D,`3*$SZ`($ctx)
+	$ST	$E,`4*$SZ`($ctx)
+	$ST	$F,`5*$SZ`($ctx)
+	$ST	$G,`6*$SZ`($ctx)
+	$ST	$H,`7*$SZ`($ctx)
+	clg	$inp,`$frame+32`($sp)
+	jne	.Lloop
+
+	lmg	%r6,%r15,`$frame+48`($sp)	
+	br	%r14
+.size	$Func,.-$Func
+.string	"SHA${label} block transform for s390x, CRYPTOGAMS by <appro\@openssl.org>"
+.comm	OPENSSL_s390xcap_P,8,8
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+# unlike 32-bit shift 64-bit one takes three arguments
+$code =~ s/(srlg\s+)(%r[0-9]+),/$1$2,$2,/gm;
+
+print $code;
+close STDOUT;
diff --git a/crypto/sha/asm/sha512-sparcv9.pl b/crypto/sha/asm/sha512-sparcv9.pl
new file mode 100644
index 0000000..54241aa
--- /dev/null
+++ b/crypto/sha/asm/sha512-sparcv9.pl
@@ -0,0 +1,593 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# SHA256 performance improvement over compiler generated code varies
+# from 40% for Sun C [32-bit build] to 70% for gcc [3.3, 64-bit
+# build]. Just like in SHA1 module I aim to ensure scalability on
+# UltraSPARC T1 by packing X[16] to 8 64-bit registers.
+
+# SHA512 on pre-T1 UltraSPARC.
+#
+# Performance is >75% better than 64-bit code generated by Sun C and
+# over 2x than 32-bit code. X[16] resides on stack, but access to it
+# is scheduled for L2 latency and staged through 32 least significant
+# bits of %l0-%l7. The latter is done to achieve 32-/64-bit ABI
+# duality. Nevetheless it's ~40% faster than SHA256, which is pretty
+# good [optimal coefficient is 50%].
+#
+# SHA512 on UltraSPARC T1.
+#
+# It's not any faster than 64-bit code generated by Sun C 5.8. This is
+# because 64-bit code generator has the advantage of using 64-bit
+# loads(*) to access X[16], which I consciously traded for 32-/64-bit
+# ABI duality [as per above]. But it surpasses 32-bit Sun C generated
+# code by 60%, not to mention that it doesn't suffer from severe decay
+# when running 4 times physical cores threads and that it leaves gcc
+# [3.4] behind by over 4x factor! If compared to SHA256, single thread
+# performance is only 10% better, but overall throughput for maximum
+# amount of threads for given CPU exceeds corresponding one of SHA256
+# by 30% [again, optimal coefficient is 50%].
+#
+# (*)	Unlike pre-T1 UltraSPARC loads on T1 are executed strictly
+#	in-order, i.e. load instruction has to complete prior next
+#	instruction in given thread is executed, even if the latter is
+#	not dependent on load result! This means that on T1 two 32-bit
+#	loads are always slower than one 64-bit load. Once again this
+#	is unlike pre-T1 UltraSPARC, where, if scheduled appropriately,
+#	2x32-bit loads can be as fast as 1x64-bit ones.
+
+$bits=32;
+for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
+if ($bits==64)	{ $bias=2047; $frame=192; }
+else		{ $bias=0;    $frame=112; }
+
+$output=shift;
+open STDOUT,">$output";
+
+if ($output =~ /512/) {
+	$label="512";
+	$SZ=8;
+	$LD="ldx";		# load from memory
+	$ST="stx";		# store to memory
+	$SLL="sllx";		# shift left logical
+	$SRL="srlx";		# shift right logical
+	@Sigma0=(28,34,39);
+	@Sigma1=(14,18,41);
+	@sigma0=( 7, 1, 8);	# right shift first
+	@sigma1=( 6,19,61);	# right shift first
+	$lastK=0x817;
+	$rounds=80;
+	$align=4;
+
+	$locals=16*$SZ;		# X[16]
+
+	$A="%o0";
+	$B="%o1";
+	$C="%o2";
+	$D="%o3";
+	$E="%o4";
+	$F="%o5";
+	$G="%g1";
+	$H="%o7";
+	@V=($A,$B,$C,$D,$E,$F,$G,$H);
+} else {
+	$label="256";
+	$SZ=4;
+	$LD="ld";		# load from memory
+	$ST="st";		# store to memory
+	$SLL="sll";		# shift left logical
+	$SRL="srl";		# shift right logical
+	@Sigma0=( 2,13,22);
+	@Sigma1=( 6,11,25);
+	@sigma0=( 3, 7,18);	# right shift first
+	@sigma1=(10,17,19);	# right shift first
+	$lastK=0x8f2;
+	$rounds=64;
+	$align=8;
+
+	$locals=0;		# X[16] is register resident
+	@X=("%o0","%o1","%o2","%o3","%o4","%o5","%g1","%o7");
+	
+	$A="%l0";
+	$B="%l1";
+	$C="%l2";
+	$D="%l3";
+	$E="%l4";
+	$F="%l5";
+	$G="%l6";
+	$H="%l7";
+	@V=($A,$B,$C,$D,$E,$F,$G,$H);
+}
+$T1="%g2";
+$tmp0="%g3";
+$tmp1="%g4";
+$tmp2="%g5";
+
+$ctx="%i0";
+$inp="%i1";
+$len="%i2";
+$Ktbl="%i3";
+$tmp31="%i4";
+$tmp32="%i5";
+
+########### SHA256
+$Xload = sub {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
+
+    if ($i==0) {
+$code.=<<___;
+	ldx	[$inp+0],@X[0]
+	ldx	[$inp+16],@X[2]
+	ldx	[$inp+32],@X[4]
+	ldx	[$inp+48],@X[6]
+	ldx	[$inp+8],@X[1]
+	ldx	[$inp+24],@X[3]
+	subcc	%g0,$tmp31,$tmp32 ! should be 64-$tmp31, but -$tmp31 works too
+	ldx	[$inp+40],@X[5]
+	bz,pt	%icc,.Laligned
+	ldx	[$inp+56],@X[7]
+
+	sllx	@X[0],$tmp31,@X[0]
+	ldx	[$inp+64],$T1
+___
+for($j=0;$j<7;$j++)
+{   $code.=<<___;
+	srlx	@X[$j+1],$tmp32,$tmp1
+	sllx	@X[$j+1],$tmp31,@X[$j+1]
+	or	$tmp1,@X[$j],@X[$j]
+___
+}
+$code.=<<___;
+	srlx	$T1,$tmp32,$T1
+	or	$T1,@X[7],@X[7]
+.Laligned:
+___
+    }
+
+    if ($i&1) {
+	$code.="\tadd	@X[$i/2],$h,$T1\n";
+    } else {
+	$code.="\tsrlx	@X[$i/2],32,$T1\n\tadd	$h,$T1,$T1\n";
+    }
+} if ($SZ==4);
+
+########### SHA512
+$Xload = sub {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
+my @pair=("%l".eval(($i*2)%8),"%l".eval(($i*2)%8+1),"%l".eval((($i+1)*2)%8));
+
+$code.=<<___ if ($i==0);
+	ld	[$inp+0],%l0
+	ld	[$inp+4],%l1
+	ld	[$inp+8],%l2
+	ld	[$inp+12],%l3
+	ld	[$inp+16],%l4
+	ld	[$inp+20],%l5
+	ld	[$inp+24],%l6
+	ld	[$inp+28],%l7
+___
+$code.=<<___ if ($i<15);
+	sllx	@pair[1],$tmp31,$tmp2	! Xload($i)
+	add	$tmp31,32,$tmp0
+	sllx	@pair[0],$tmp0,$tmp1
+	`"ld	[$inp+".eval(32+0+$i*8)."],@pair[0]"	if ($i<12)`
+	srlx	@pair[2],$tmp32,@pair[1]
+	or	$tmp1,$tmp2,$tmp2
+	or	@pair[1],$tmp2,$tmp2
+	`"ld	[$inp+".eval(32+4+$i*8)."],@pair[1]"	if ($i<12)`
+	add	$h,$tmp2,$T1
+	$ST	$tmp2,[%sp+`$bias+$frame+$i*$SZ`]
+___
+$code.=<<___ if ($i==12);
+	brnz,a	$tmp31,.+8
+	ld	[$inp+128],%l0
+___
+$code.=<<___ if ($i==15);
+	ld	[%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+0`],%l2
+	sllx	@pair[1],$tmp31,$tmp2	! Xload($i)
+	add	$tmp31,32,$tmp0
+	ld	[%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+4`],%l3
+	sllx	@pair[0],$tmp0,$tmp1
+	ld	[%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+0`],%l4
+	srlx	@pair[2],$tmp32,@pair[1]
+	or	$tmp1,$tmp2,$tmp2
+	ld	[%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+4`],%l5
+	or	@pair[1],$tmp2,$tmp2
+	ld	[%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+0`],%l6
+	add	$h,$tmp2,$T1
+	$ST	$tmp2,[%sp+`$bias+$frame+$i*$SZ`]
+	ld	[%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+4`],%l7
+	ld	[%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+0`],%l0
+	ld	[%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+4`],%l1
+___
+} if ($SZ==8);
+
+########### common
+sub BODY_00_15 {
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
+
+    if ($i<16) {
+	&$Xload(@_);
+    } else {
+	$code.="\tadd	$h,$T1,$T1\n";
+    }
+
+$code.=<<___;
+	$SRL	$e,@Sigma1[0],$h	!! $i
+	xor	$f,$g,$tmp2
+	$SLL	$e,`$SZ*8-@Sigma1[2]`,$tmp1
+	and	$e,$tmp2,$tmp2
+	$SRL	$e,@Sigma1[1],$tmp0
+	xor	$tmp1,$h,$h
+	$SLL	$e,`$SZ*8-@Sigma1[1]`,$tmp1
+	xor	$tmp0,$h,$h
+	$SRL	$e,@Sigma1[2],$tmp0
+	xor	$tmp1,$h,$h
+	$SLL	$e,`$SZ*8-@Sigma1[0]`,$tmp1
+	xor	$tmp0,$h,$h
+	xor	$g,$tmp2,$tmp2		! Ch(e,f,g)
+	xor	$tmp1,$h,$tmp0		! Sigma1(e)
+
+	$SRL	$a,@Sigma0[0],$h
+	add	$tmp2,$T1,$T1
+	$LD	[$Ktbl+`$i*$SZ`],$tmp2	! K[$i]
+	$SLL	$a,`$SZ*8-@Sigma0[2]`,$tmp1
+	add	$tmp0,$T1,$T1
+	$SRL	$a,@Sigma0[1],$tmp0
+	xor	$tmp1,$h,$h
+	$SLL	$a,`$SZ*8-@Sigma0[1]`,$tmp1
+	xor	$tmp0,$h,$h
+	$SRL	$a,@Sigma0[2],$tmp0
+	xor	$tmp1,$h,$h	
+	$SLL	$a,`$SZ*8-@Sigma0[0]`,$tmp1
+	xor	$tmp0,$h,$h
+	xor	$tmp1,$h,$h		! Sigma0(a)
+
+	or	$a,$b,$tmp0
+	and	$a,$b,$tmp1
+	and	$c,$tmp0,$tmp0
+	or	$tmp0,$tmp1,$tmp1	! Maj(a,b,c)
+	add	$tmp2,$T1,$T1		! +=K[$i]
+	add	$tmp1,$h,$h
+
+	add	$T1,$d,$d
+	add	$T1,$h,$h
+___
+}
+
+########### SHA256
+$BODY_16_XX = sub {
+my $i=@_[0];
+my $xi;
+
+    if ($i&1) {
+	$xi=$tmp32;
+	$code.="\tsrlx	@X[(($i+1)/2)%8],32,$xi\n";
+    } else {
+	$xi=@X[(($i+1)/2)%8];
+    }
+$code.=<<___;
+	srl	$xi,@sigma0[0],$T1		!! Xupdate($i)
+	sll	$xi,`32-@sigma0[2]`,$tmp1
+	srl	$xi,@sigma0[1],$tmp0
+	xor	$tmp1,$T1,$T1
+	sll	$tmp1,`@sigma0[2]-@sigma0[1]`,$tmp1
+	xor	$tmp0,$T1,$T1
+	srl	$xi,@sigma0[2],$tmp0
+	xor	$tmp1,$T1,$T1
+___
+    if ($i&1) {
+	$xi=@X[(($i+14)/2)%8];
+    } else {
+	$xi=$tmp32;
+	$code.="\tsrlx	@X[(($i+14)/2)%8],32,$xi\n";
+    }
+$code.=<<___;
+	srl	$xi,@sigma1[0],$tmp2
+	xor	$tmp0,$T1,$T1			! T1=sigma0(X[i+1])
+	sll	$xi,`32-@sigma1[2]`,$tmp1
+	srl	$xi,@sigma1[1],$tmp0
+	xor	$tmp1,$tmp2,$tmp2
+	sll	$tmp1,`@sigma1[2]-@sigma1[1]`,$tmp1
+	xor	$tmp0,$tmp2,$tmp2
+	srl	$xi,@sigma1[2],$tmp0
+	xor	$tmp1,$tmp2,$tmp2
+___
+    if ($i&1) {
+	$xi=@X[($i/2)%8];
+$code.=<<___;
+	srlx	@X[(($i+9)/2)%8],32,$tmp1	! X[i+9]
+	xor	$tmp0,$tmp2,$tmp2		! sigma1(X[i+14])
+	srl	@X[($i/2)%8],0,$tmp0
+	add	$xi,$T1,$T1			! +=X[i]
+	xor	$tmp0,@X[($i/2)%8],@X[($i/2)%8]
+	add	$tmp2,$T1,$T1
+	add	$tmp1,$T1,$T1
+
+	srl	$T1,0,$T1
+	or	$T1,@X[($i/2)%8],@X[($i/2)%8]
+___
+    } else {
+	$xi=@X[(($i+9)/2)%8];
+$code.=<<___;
+	srlx	@X[($i/2)%8],32,$tmp1		! X[i]
+	xor	$tmp0,$tmp2,$tmp2		! sigma1(X[i+14])
+	srl	@X[($i/2)%8],0,@X[($i/2)%8]
+	add	$xi,$T1,$T1			! +=X[i+9]
+	add	$tmp2,$T1,$T1
+	add	$tmp1,$T1,$T1
+
+	sllx	$T1,32,$tmp0
+	or	$tmp0,@X[($i/2)%8],@X[($i/2)%8]
+___
+    }
+    &BODY_00_15(@_);
+} if ($SZ==4);
+
+########### SHA512
+$BODY_16_XX = sub {
+my $i=@_[0];
+my @pair=("%l".eval(($i*2)%8),"%l".eval(($i*2)%8+1));
+
+$code.=<<___;
+	sllx	%l2,32,$tmp0		!! Xupdate($i)
+	or	%l3,$tmp0,$tmp0
+
+	srlx	$tmp0,@sigma0[0],$T1
+	ld	[%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+0`],%l2
+	sllx	$tmp0,`64-@sigma0[2]`,$tmp1
+	ld	[%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+4`],%l3
+	srlx	$tmp0,@sigma0[1],$tmp0
+	xor	$tmp1,$T1,$T1
+	sllx	$tmp1,`@sigma0[2]-@sigma0[1]`,$tmp1
+	xor	$tmp0,$T1,$T1
+	srlx	$tmp0,`@sigma0[2]-@sigma0[1]`,$tmp0
+	xor	$tmp1,$T1,$T1
+	sllx	%l6,32,$tmp2
+	xor	$tmp0,$T1,$T1		! sigma0(X[$i+1])
+	or	%l7,$tmp2,$tmp2
+
+	srlx	$tmp2,@sigma1[0],$tmp1
+	ld	[%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+0`],%l6
+	sllx	$tmp2,`64-@sigma1[2]`,$tmp0
+	ld	[%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+4`],%l7
+	srlx	$tmp2,@sigma1[1],$tmp2
+	xor	$tmp0,$tmp1,$tmp1
+	sllx	$tmp0,`@sigma1[2]-@sigma1[1]`,$tmp0
+	xor	$tmp2,$tmp1,$tmp1
+	srlx	$tmp2,`@sigma1[2]-@sigma1[1]`,$tmp2
+	xor	$tmp0,$tmp1,$tmp1
+	sllx	%l4,32,$tmp0
+	xor	$tmp2,$tmp1,$tmp1	! sigma1(X[$i+14])
+	ld	[%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+0`],%l4
+	or	%l5,$tmp0,$tmp0
+	ld	[%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+4`],%l5
+
+	sllx	%l0,32,$tmp2
+	add	$tmp1,$T1,$T1
+	ld	[%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+0`],%l0
+	or	%l1,$tmp2,$tmp2
+	add	$tmp0,$T1,$T1		! +=X[$i+9]
+	ld	[%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+4`],%l1
+	add	$tmp2,$T1,$T1		! +=X[$i]
+	$ST	$T1,[%sp+`$bias+$frame+($i%16)*$SZ`]
+___
+    &BODY_00_15(@_);
+} if ($SZ==8);
+
+$code.=<<___ if ($bits==64);
+.register	%g2,#scratch
+.register	%g3,#scratch
+___
+$code.=<<___;
+.section	".text",#alloc,#execinstr
+
+.align	64
+K${label}:
+.type	K${label},#object
+___
+if ($SZ==4) {
+$code.=<<___;
+	.long	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
+	.long	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
+	.long	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
+	.long	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
+	.long	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
+	.long	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
+	.long	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
+	.long	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
+	.long	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
+	.long	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
+	.long	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
+	.long	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
+	.long	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
+	.long	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
+	.long	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
+	.long	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+___
+} else {
+$code.=<<___;
+	.long	0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd
+	.long	0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc
+	.long	0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019
+	.long	0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118
+	.long	0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe
+	.long	0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2
+	.long	0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1
+	.long	0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694
+	.long	0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3
+	.long	0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65
+	.long	0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483
+	.long	0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5
+	.long	0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210
+	.long	0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4
+	.long	0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725
+	.long	0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70
+	.long	0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926
+	.long	0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df
+	.long	0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8
+	.long	0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b
+	.long	0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001
+	.long	0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30
+	.long	0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910
+	.long	0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8
+	.long	0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53
+	.long	0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8
+	.long	0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb
+	.long	0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3
+	.long	0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60
+	.long	0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec
+	.long	0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9
+	.long	0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b
+	.long	0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207
+	.long	0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178
+	.long	0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6
+	.long	0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b
+	.long	0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493
+	.long	0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c
+	.long	0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a
+	.long	0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817
+___
+}
+$code.=<<___;
+.size	K${label},.-K${label}
+.globl	sha${label}_block_data_order
+sha${label}_block_data_order:
+	save	%sp,`-$frame-$locals`,%sp
+	and	$inp,`$align-1`,$tmp31
+	sllx	$len,`log(16*$SZ)/log(2)`,$len
+	andn	$inp,`$align-1`,$inp
+	sll	$tmp31,3,$tmp31
+	add	$inp,$len,$len
+___
+$code.=<<___ if ($SZ==8); # SHA512
+	mov	32,$tmp32
+	sub	$tmp32,$tmp31,$tmp32
+___
+$code.=<<___;
+.Lpic:	call	.+8
+	add	%o7,K${label}-.Lpic,$Ktbl
+
+	$LD	[$ctx+`0*$SZ`],$A
+	$LD	[$ctx+`1*$SZ`],$B
+	$LD	[$ctx+`2*$SZ`],$C
+	$LD	[$ctx+`3*$SZ`],$D
+	$LD	[$ctx+`4*$SZ`],$E
+	$LD	[$ctx+`5*$SZ`],$F
+	$LD	[$ctx+`6*$SZ`],$G
+	$LD	[$ctx+`7*$SZ`],$H
+
+.Lloop:
+___
+for ($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
+$code.=".L16_xx:\n";
+for (;$i<32;$i++)	{ &$BODY_16_XX($i,@V); unshift(@V,pop(@V)); }
+$code.=<<___;
+	and	$tmp2,0xfff,$tmp2
+	cmp	$tmp2,$lastK
+	bne	.L16_xx
+	add	$Ktbl,`16*$SZ`,$Ktbl	! Ktbl+=16
+
+___
+$code.=<<___ if ($SZ==4); # SHA256
+	$LD	[$ctx+`0*$SZ`],@X[0]
+	$LD	[$ctx+`1*$SZ`],@X[1]
+	$LD	[$ctx+`2*$SZ`],@X[2]
+	$LD	[$ctx+`3*$SZ`],@X[3]
+	$LD	[$ctx+`4*$SZ`],@X[4]
+	$LD	[$ctx+`5*$SZ`],@X[5]
+	$LD	[$ctx+`6*$SZ`],@X[6]
+	$LD	[$ctx+`7*$SZ`],@X[7]
+
+	add	$A,@X[0],$A
+	$ST	$A,[$ctx+`0*$SZ`]
+	add	$B,@X[1],$B
+	$ST	$B,[$ctx+`1*$SZ`]
+	add	$C,@X[2],$C
+	$ST	$C,[$ctx+`2*$SZ`]
+	add	$D,@X[3],$D
+	$ST	$D,[$ctx+`3*$SZ`]
+	add	$E,@X[4],$E
+	$ST	$E,[$ctx+`4*$SZ`]
+	add	$F,@X[5],$F
+	$ST	$F,[$ctx+`5*$SZ`]
+	add	$G,@X[6],$G
+	$ST	$G,[$ctx+`6*$SZ`]
+	add	$H,@X[7],$H
+	$ST	$H,[$ctx+`7*$SZ`]
+___
+$code.=<<___ if ($SZ==8); # SHA512
+	ld	[$ctx+`0*$SZ+0`],%l0
+	ld	[$ctx+`0*$SZ+4`],%l1
+	ld	[$ctx+`1*$SZ+0`],%l2
+	ld	[$ctx+`1*$SZ+4`],%l3
+	ld	[$ctx+`2*$SZ+0`],%l4
+	ld	[$ctx+`2*$SZ+4`],%l5
+	ld	[$ctx+`3*$SZ+0`],%l6
+
+	sllx	%l0,32,$tmp0
+	ld	[$ctx+`3*$SZ+4`],%l7
+	sllx	%l2,32,$tmp1
+	or	%l1,$tmp0,$tmp0
+	or	%l3,$tmp1,$tmp1
+	add	$tmp0,$A,$A
+	add	$tmp1,$B,$B
+	$ST	$A,[$ctx+`0*$SZ`]
+	sllx	%l4,32,$tmp2
+	$ST	$B,[$ctx+`1*$SZ`]
+	sllx	%l6,32,$T1
+	or	%l5,$tmp2,$tmp2
+	or	%l7,$T1,$T1
+	add	$tmp2,$C,$C
+	$ST	$C,[$ctx+`2*$SZ`]
+	add	$T1,$D,$D
+	$ST	$D,[$ctx+`3*$SZ`]
+
+	ld	[$ctx+`4*$SZ+0`],%l0
+	ld	[$ctx+`4*$SZ+4`],%l1
+	ld	[$ctx+`5*$SZ+0`],%l2
+	ld	[$ctx+`5*$SZ+4`],%l3
+	ld	[$ctx+`6*$SZ+0`],%l4
+	ld	[$ctx+`6*$SZ+4`],%l5
+	ld	[$ctx+`7*$SZ+0`],%l6
+
+	sllx	%l0,32,$tmp0
+	ld	[$ctx+`7*$SZ+4`],%l7
+	sllx	%l2,32,$tmp1
+	or	%l1,$tmp0,$tmp0
+	or	%l3,$tmp1,$tmp1
+	add	$tmp0,$E,$E
+	add	$tmp1,$F,$F
+	$ST	$E,[$ctx+`4*$SZ`]
+	sllx	%l4,32,$tmp2
+	$ST	$F,[$ctx+`5*$SZ`]
+	sllx	%l6,32,$T1
+	or	%l5,$tmp2,$tmp2
+	or	%l7,$T1,$T1
+	add	$tmp2,$G,$G
+	$ST	$G,[$ctx+`6*$SZ`]
+	add	$T1,$H,$H
+	$ST	$H,[$ctx+`7*$SZ`]
+___
+$code.=<<___;
+	add	$inp,`16*$SZ`,$inp		! advance inp
+	cmp	$inp,$len
+	bne	`$bits==64?"%xcc":"%icc"`,.Lloop
+	sub	$Ktbl,`($rounds-16)*$SZ`,$Ktbl	! rewind Ktbl
+
+	ret
+	restore
+.type	sha${label}_block_data_order,#function
+.size	sha${label}_block_data_order,(.-sha${label}_block_data_order)
+.asciz	"SHA${label} block transform for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/crypto/sha/asm/sha512-sse2.pl b/crypto/sha/asm/sha512-sse2.pl
deleted file mode 100644
index 10902bf..0000000
--- a/crypto/sha/asm/sha512-sse2.pl
+++ /dev/null
@@ -1,404 +0,0 @@
-#!/usr/bin/env perl
-#
-# ====================================================================
-# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. Rights for redistribution and usage in source and binary
-# forms are granted according to the OpenSSL license.
-# ====================================================================
-#
-# SHA512_Transform_SSE2.
-#
-# As the name suggests, this is an IA-32 SSE2 implementation of
-# SHA512_Transform. Motivating factor for the undertaken effort was that
-# SHA512 was observed to *consistently* perform *significantly* poorer
-# than SHA256 [2x and slower is common] on 32-bit platforms. On 64-bit
-# platforms on the other hand SHA512 tend to outperform SHA256 [~50%
-# seem to be common improvement factor]. All this is perfectly natural,
-# as SHA512 is a 64-bit algorithm. But isn't IA-32 SSE2 essentially
-# a 64-bit instruction set? Is it rich enough to implement SHA512?
-# If answer was "no," then you wouldn't have been reading this...
-#
-# Throughput performance in MBps (larger is better):
-#
-#		2.4GHz P4	1.4GHz AMD32	1.4GHz AMD64(*)
-# SHA256/gcc(*)	54		43		59
-# SHA512/gcc	17		23		92
-# SHA512/sse2	61(**)		57(**)
-# SHA512/icc	26		28
-# SHA256/icc(*)	65		54
-#
-# (*)	AMD64 and SHA256 numbers are presented mostly for amusement or
-#	reference purposes.
-# (**)	I.e. it gives ~2-3x speed-up if compared with compiler generated
-#	code. One can argue that hand-coded *non*-SSE2 implementation
-#	would perform better than compiler generated one as well, and
-#	that comparison is therefore not exactly fair. Well, as SHA512
-#	puts enormous pressure on IA-32 GP register bank, I reckon that
-#	hand-coded version wouldn't perform significantly better than
-#	one compiled with icc, ~20% perhaps... So that this code would
-#	still outperform it with distinguishing marginal. But feel free
-#	to prove me wrong:-)
-#						<appro@fy.chalmers.se>
-push(@INC,"perlasm","../../perlasm");
-require "x86asm.pl";
-
-&asm_init($ARGV[0],"sha512-sse2.pl",$ARGV[$#ARGV] eq "386");
-
-$K512="esi";	# K512[80] table, found at the end...
-#$W512="esp";	# $W512 is not just W512[16]: it comprises *two* copies
-		# of W512[16] and a copy of A-H variables...
-$W512_SZ=8*(16+16+8);	# see above...
-#$Kidx="ebx";	# index in K512 table, advances from 0 to 80...
-$Widx="edx";	# index in W512, wraps around at 16...
-$data="edi";	# 16 qwords of input data...
-$A="mm0";	# B-D and
-$E="mm1";	# F-H are allocated dynamically...
-$Aoff=256+0;	# A-H offsets relative to $W512...
-$Boff=256+8;
-$Coff=256+16;
-$Doff=256+24;
-$Eoff=256+32;
-$Foff=256+40;
-$Goff=256+48;
-$Hoff=256+56;
-
-sub SHA2_ROUND()
-{ local ($kidx,$widx)=@_;
-
-	# One can argue that one could reorder instructions for better
-	# performance. Well, I tried and it doesn't seem to make any
-	# noticeable difference. Modern out-of-order execution cores
-	# reorder instructions to their liking in either case and they
-	# apparently do decent job. So we can keep the code more
-	# readable/regular/comprehensible:-)
-
-	# I adhere to 64-bit %mmX registers in order to avoid/not care
-	# about #GP exceptions on misaligned 128-bit access, most
-	# notably in paddq with memory operand. Not to mention that
-	# SSE2 intructions operating on %mmX can be scheduled every
-	# cycle [and not every second one if operating on %xmmN].
-
-	&movq	("mm4",&QWP($Foff,$W512));	# load f
-	&movq	("mm5",&QWP($Goff,$W512));	# load g
-	&movq	("mm6",&QWP($Hoff,$W512));	# load h
-
-	&movq	("mm2",$E);			# %mm2 is sliding right
-	&movq	("mm3",$E);			# %mm3 is sliding left
-	&psrlq	("mm2",14);
-	&psllq	("mm3",23);
-	&movq	("mm7","mm2");			# %mm7 is T1
-	&pxor	("mm7","mm3");
-	&psrlq	("mm2",4);
-	&psllq	("mm3",23);
-	&pxor	("mm7","mm2");
-	&pxor	("mm7","mm3");
-	&psrlq	("mm2",23);
-	&psllq	("mm3",4);
-	&pxor	("mm7","mm2");
-	&pxor	("mm7","mm3");			# T1=Sigma1_512(e)
-
-	&movq	(&QWP($Foff,$W512),$E);		# f = e
-	&movq	(&QWP($Goff,$W512),"mm4");	# g = f
-	&movq	(&QWP($Hoff,$W512),"mm5");	# h = g
-
-	&pxor	("mm4","mm5");			# f^=g
-	&pand	("mm4",$E);			# f&=e
-	&pxor	("mm4","mm5");			# f^=g
-	&paddq	("mm7","mm4");			# T1+=Ch(e,f,g)
-
-	&movq	("mm2",&QWP($Boff,$W512));	# load b
-	&movq	("mm3",&QWP($Coff,$W512));	# load c
-	&movq	($E,&QWP($Doff,$W512));		# e = d
-
-	&paddq	("mm7","mm6");			# T1+=h
-	&paddq	("mm7",&QWP(0,$K512,$kidx,8));	# T1+=K512[i]
-	&paddq	("mm7",&QWP(0,$W512,$widx,8));	# T1+=W512[i]
-	&paddq	($E,"mm7");			# e += T1
-
-	&movq	("mm4",$A);			# %mm4 is sliding right
-	&movq	("mm5",$A);			# %mm5 is sliding left
-	&psrlq	("mm4",28);
-	&psllq	("mm5",25);
-	&movq	("mm6","mm4");			# %mm6 is T2
-	&pxor	("mm6","mm5");
-	&psrlq	("mm4",6);
-	&psllq	("mm5",5);
-	&pxor	("mm6","mm4");
-	&pxor	("mm6","mm5");
-	&psrlq	("mm4",5);
-	&psllq	("mm5",6);
-	&pxor	("mm6","mm4");
-	&pxor	("mm6","mm5");			# T2=Sigma0_512(a)
-
-	&movq	(&QWP($Boff,$W512),$A);		# b = a
-	&movq	(&QWP($Coff,$W512),"mm2");	# c = b
-	&movq	(&QWP($Doff,$W512),"mm3");	# d = c
-
-	&movq	("mm4",$A);			# %mm4=a
-	&por	($A,"mm3");			# a=a|c
-	&pand	("mm4","mm3");			# %mm4=a&c
-	&pand	($A,"mm2");			# a=(a|c)&b
-	&por	("mm4",$A);			# %mm4=(a&c)|((a|c)&b)
-	&paddq	("mm6","mm4");			# T2+=Maj(a,b,c)
-
-	&movq	($A,"mm7");			# a=T1
-	&paddq	($A,"mm6");			# a+=T2
-}
-
-$func="sha512_block_sse2";
-
-&function_begin_B($func);
-	if (0) {# Caller is expected to check if it's appropriate to
-		# call this routine. Below 3 lines are retained for
-		# debugging purposes...
-		&picmeup("eax","OPENSSL_ia32cap");
-		&bt	(&DWP(0,"eax"),26);
-		&jnc	("SHA512_Transform");
-	}
-
-	&push	("ebp");
-	&mov	("ebp","esp");
-	&push	("ebx");
-	&push	("esi");
-	&push	("edi");
-
-	&mov	($Widx,&DWP(8,"ebp"));		# A-H state, 1st arg
-	&mov	($data,&DWP(12,"ebp"));		# input data, 2nd arg
-	&call	(&label("pic_point"));		# make it PIC!
-&set_label("pic_point");
-	&blindpop($K512);
-	&lea	($K512,&DWP(&label("K512")."-".&label("pic_point"),$K512));
-
-	$W512 = "esp";			# start using %esp as W512
-	&sub	($W512,$W512_SZ);
-	&and	($W512,-16);		# ensure 128-bit alignment
-
-	# make private copy of A-H
-	#     v assume the worst and stick to unaligned load
-	&movdqu	("xmm0",&QWP(0,$Widx));
-	&movdqu	("xmm1",&QWP(16,$Widx));
-	&movdqu	("xmm2",&QWP(32,$Widx));
-	&movdqu	("xmm3",&QWP(48,$Widx));
-
-&align(8);
-&set_label("_chunk_loop");
-
-	&movdqa	(&QWP($Aoff,$W512),"xmm0");	# a,b
-	&movdqa	(&QWP($Coff,$W512),"xmm1");	# c,d
-	&movdqa	(&QWP($Eoff,$W512),"xmm2");	# e,f
-	&movdqa	(&QWP($Goff,$W512),"xmm3");	# g,h
-
-	&xor	($Widx,$Widx);
-
-	&movdq2q($A,"xmm0");			# load a
-	&movdq2q($E,"xmm2");			# load e
-
-	# Why aren't loops unrolled? It makes sense to unroll if
-	# execution time for loop body is comparable with branch
-	# penalties and/or if whole data-set resides in register bank.
-	# Neither is case here... Well, it would be possible to
-	# eliminate few store operations, but it would hardly affect
-	# so to say stop-watch performance, as there is a lot of
-	# available memory slots to fill. It will only relieve some
-	# pressure off memory bus...
-
-	# flip input stream byte order...
-	&mov	("eax",&DWP(0,$data,$Widx,8));
-	&mov	("ebx",&DWP(4,$data,$Widx,8));
-	&bswap	("eax");
-	&bswap	("ebx");
-	&mov	(&DWP(0,$W512,$Widx,8),"ebx");		# W512[i]
-	&mov	(&DWP(4,$W512,$Widx,8),"eax");
-	&mov	(&DWP(128+0,$W512,$Widx,8),"ebx");	# copy of W512[i]
-	&mov	(&DWP(128+4,$W512,$Widx,8),"eax");
-
-&align(8);
-&set_label("_1st_loop");		# 0-15
-	# flip input stream byte order...
-	&mov	("eax",&DWP(0+8,$data,$Widx,8));
-	&mov	("ebx",&DWP(4+8,$data,$Widx,8));
-	&bswap	("eax");
-	&bswap	("ebx");
-	&mov	(&DWP(0+8,$W512,$Widx,8),"ebx");	# W512[i]
-	&mov	(&DWP(4+8,$W512,$Widx,8),"eax");
-	&mov	(&DWP(128+0+8,$W512,$Widx,8),"ebx");	# copy of W512[i]
-	&mov	(&DWP(128+4+8,$W512,$Widx,8),"eax");
-&set_label("_1st_looplet");
-	&SHA2_ROUND($Widx,$Widx); &inc($Widx);
-
-&cmp	($Widx,15)
-&jl	(&label("_1st_loop"));
-&je	(&label("_1st_looplet"));	# playing similar trick on 2nd loop
-					# does not improve performance...
-
-	$Kidx = "ebx";			# start using %ebx as Kidx
-	&mov	($Kidx,$Widx);
-
-&align(8);
-&set_label("_2nd_loop");		# 16-79
-	&and($Widx,0xf);
-
-	# 128-bit fragment! I update W512[i] and W512[i+1] in
-	# parallel:-) Note that I refer to W512[(i&0xf)+N] and not to
-	# W512[(i+N)&0xf]! This is exactly what I maintain the second
-	# copy of W512[16] for...
-	&movdqu	("xmm0",&QWP(8*1,$W512,$Widx,8));	# s0=W512[i+1]
-	&movdqa	("xmm2","xmm0");		# %xmm2 is sliding right
-	&movdqa	("xmm3","xmm0");		# %xmm3 is sliding left
-	&psrlq	("xmm2",1);
-	&psllq	("xmm3",56);
-	&movdqa	("xmm0","xmm2");
-	&pxor	("xmm0","xmm3");
-	&psrlq	("xmm2",6);
-	&psllq	("xmm3",7);
-	&pxor	("xmm0","xmm2");
-	&pxor	("xmm0","xmm3");
-	&psrlq	("xmm2",1);
-	&pxor	("xmm0","xmm2");		# s0 = sigma0_512(s0);
-
-	&movdqa	("xmm1",&QWP(8*14,$W512,$Widx,8));	# s1=W512[i+14]
-	&movdqa	("xmm4","xmm1");		# %xmm4 is sliding right
-	&movdqa	("xmm5","xmm1");		# %xmm5 is sliding left
-	&psrlq	("xmm4",6);
-	&psllq	("xmm5",3);
-	&movdqa	("xmm1","xmm4");
-	&pxor	("xmm1","xmm5");
-	&psrlq	("xmm4",13);
-	&psllq	("xmm5",42);
-	&pxor	("xmm1","xmm4");
-	&pxor	("xmm1","xmm5");
-	&psrlq	("xmm4",42);
-	&pxor	("xmm1","xmm4");		# s1 = sigma1_512(s1);
-
-	#     + have to explictly load W512[i+9] as it's not 128-bit
-	#     v	aligned and paddq would throw an exception...
-	&movdqu	("xmm6",&QWP(8*9,$W512,$Widx,8));
-	&paddq	("xmm0","xmm1");		# s0 += s1
-	&paddq	("xmm0","xmm6");		# s0 += W512[i+9]
-	&paddq	("xmm0",&QWP(0,$W512,$Widx,8));	# s0 += W512[i]
-
-	&movdqa	(&QWP(0,$W512,$Widx,8),"xmm0");		# W512[i] = s0
-	&movdqa	(&QWP(16*8,$W512,$Widx,8),"xmm0");	# copy of W512[i]
-
-	# as the above fragment was 128-bit, we "owe" 2 rounds...
-	&SHA2_ROUND($Kidx,$Widx); &inc($Kidx); &inc($Widx);
-	&SHA2_ROUND($Kidx,$Widx); &inc($Kidx); &inc($Widx);
-
-&cmp	($Kidx,80);
-&jl	(&label("_2nd_loop"));
-
-	# update A-H state
-	&mov	($Widx,&DWP(8,"ebp"));		# A-H state, 1st arg
-	&movq	(&QWP($Aoff,$W512),$A);		# write out a
-	&movq	(&QWP($Eoff,$W512),$E);		# write out e
-	&movdqu	("xmm0",&QWP(0,$Widx));
-	&movdqu	("xmm1",&QWP(16,$Widx));
-	&movdqu	("xmm2",&QWP(32,$Widx));
-	&movdqu	("xmm3",&QWP(48,$Widx));
-	&paddq	("xmm0",&QWP($Aoff,$W512));	# 128-bit additions...
-	&paddq	("xmm1",&QWP($Coff,$W512));
-	&paddq	("xmm2",&QWP($Eoff,$W512));
-	&paddq	("xmm3",&QWP($Goff,$W512));
-	&movdqu	(&QWP(0,$Widx),"xmm0");
-	&movdqu	(&QWP(16,$Widx),"xmm1");
-	&movdqu	(&QWP(32,$Widx),"xmm2");
-	&movdqu	(&QWP(48,$Widx),"xmm3");
-
-&add	($data,16*8);				# advance input data pointer
-&dec	(&DWP(16,"ebp"));			# decrement 3rd arg
-&jnz	(&label("_chunk_loop"));
-
-	# epilogue
-	&emms	();	# required for at least ELF and Win32 ABIs
-	&mov	("edi",&DWP(-12,"ebp"));
-	&mov	("esi",&DWP(-8,"ebp"));
-	&mov	("ebx",&DWP(-4,"ebp"));
-	&leave	();
-&ret	();
-
-&align(64);
-&set_label("K512");	# Yes! I keep it in the code segment!
-	&data_word(0xd728ae22,0x428a2f98);	# u64
-	&data_word(0x23ef65cd,0x71374491);	# u64
-	&data_word(0xec4d3b2f,0xb5c0fbcf);	# u64
-	&data_word(0x8189dbbc,0xe9b5dba5);	# u64
-	&data_word(0xf348b538,0x3956c25b);	# u64
-	&data_word(0xb605d019,0x59f111f1);	# u64
-	&data_word(0xaf194f9b,0x923f82a4);	# u64
-	&data_word(0xda6d8118,0xab1c5ed5);	# u64
-	&data_word(0xa3030242,0xd807aa98);	# u64
-	&data_word(0x45706fbe,0x12835b01);	# u64
-	&data_word(0x4ee4b28c,0x243185be);	# u64
-	&data_word(0xd5ffb4e2,0x550c7dc3);	# u64
-	&data_word(0xf27b896f,0x72be5d74);	# u64
-	&data_word(0x3b1696b1,0x80deb1fe);	# u64
-	&data_word(0x25c71235,0x9bdc06a7);	# u64
-	&data_word(0xcf692694,0xc19bf174);	# u64
-	&data_word(0x9ef14ad2,0xe49b69c1);	# u64
-	&data_word(0x384f25e3,0xefbe4786);	# u64
-	&data_word(0x8b8cd5b5,0x0fc19dc6);	# u64
-	&data_word(0x77ac9c65,0x240ca1cc);	# u64
-	&data_word(0x592b0275,0x2de92c6f);	# u64
-	&data_word(0x6ea6e483,0x4a7484aa);	# u64
-	&data_word(0xbd41fbd4,0x5cb0a9dc);	# u64
-	&data_word(0x831153b5,0x76f988da);	# u64
-	&data_word(0xee66dfab,0x983e5152);	# u64
-	&data_word(0x2db43210,0xa831c66d);	# u64
-	&data_word(0x98fb213f,0xb00327c8);	# u64
-	&data_word(0xbeef0ee4,0xbf597fc7);	# u64
-	&data_word(0x3da88fc2,0xc6e00bf3);	# u64
-	&data_word(0x930aa725,0xd5a79147);	# u64
-	&data_word(0xe003826f,0x06ca6351);	# u64
-	&data_word(0x0a0e6e70,0x14292967);	# u64
-	&data_word(0x46d22ffc,0x27b70a85);	# u64
-	&data_word(0x5c26c926,0x2e1b2138);	# u64
-	&data_word(0x5ac42aed,0x4d2c6dfc);	# u64
-	&data_word(0x9d95b3df,0x53380d13);	# u64
-	&data_word(0x8baf63de,0x650a7354);	# u64
-	&data_word(0x3c77b2a8,0x766a0abb);	# u64
-	&data_word(0x47edaee6,0x81c2c92e);	# u64
-	&data_word(0x1482353b,0x92722c85);	# u64
-	&data_word(0x4cf10364,0xa2bfe8a1);	# u64
-	&data_word(0xbc423001,0xa81a664b);	# u64
-	&data_word(0xd0f89791,0xc24b8b70);	# u64
-	&data_word(0x0654be30,0xc76c51a3);	# u64
-	&data_word(0xd6ef5218,0xd192e819);	# u64
-	&data_word(0x5565a910,0xd6990624);	# u64
-	&data_word(0x5771202a,0xf40e3585);	# u64
-	&data_word(0x32bbd1b8,0x106aa070);	# u64
-	&data_word(0xb8d2d0c8,0x19a4c116);	# u64
-	&data_word(0x5141ab53,0x1e376c08);	# u64
-	&data_word(0xdf8eeb99,0x2748774c);	# u64
-	&data_word(0xe19b48a8,0x34b0bcb5);	# u64
-	&data_word(0xc5c95a63,0x391c0cb3);	# u64
-	&data_word(0xe3418acb,0x4ed8aa4a);	# u64
-	&data_word(0x7763e373,0x5b9cca4f);	# u64
-	&data_word(0xd6b2b8a3,0x682e6ff3);	# u64
-	&data_word(0x5defb2fc,0x748f82ee);	# u64
-	&data_word(0x43172f60,0x78a5636f);	# u64
-	&data_word(0xa1f0ab72,0x84c87814);	# u64
-	&data_word(0x1a6439ec,0x8cc70208);	# u64
-	&data_word(0x23631e28,0x90befffa);	# u64
-	&data_word(0xde82bde9,0xa4506ceb);	# u64
-	&data_word(0xb2c67915,0xbef9a3f7);	# u64
-	&data_word(0xe372532b,0xc67178f2);	# u64
-	&data_word(0xea26619c,0xca273ece);	# u64
-	&data_word(0x21c0c207,0xd186b8c7);	# u64
-	&data_word(0xcde0eb1e,0xeada7dd6);	# u64
-	&data_word(0xee6ed178,0xf57d4f7f);	# u64
-	&data_word(0x72176fba,0x06f067aa);	# u64
-	&data_word(0xa2c898a6,0x0a637dc5);	# u64
-	&data_word(0xbef90dae,0x113f9804);	# u64
-	&data_word(0x131c471b,0x1b710b35);	# u64
-	&data_word(0x23047d84,0x28db77f5);	# u64
-	&data_word(0x40c72493,0x32caab7b);	# u64
-	&data_word(0x15c9bebc,0x3c9ebe0a);	# u64
-	&data_word(0x9c100d4c,0x431d67c4);	# u64
-	&data_word(0xcb3e42b6,0x4cc5d4be);	# u64
-	&data_word(0xfc657e2a,0x597f299c);	# u64
-	&data_word(0x3ad6faec,0x5fcb6fab);	# u64
-	&data_word(0x4a475817,0x6c44198c);	# u64
-
-&function_end_B($func);
-
-&asm_finish();
diff --git a/crypto/sha/asm/sha512-x86_64.pl b/crypto/sha/asm/sha512-x86_64.pl
index b6252d3..e6643f8 100755
--- a/crypto/sha/asm/sha512-x86_64.pl
+++ b/crypto/sha/asm/sha512-x86_64.pl
@@ -40,14 +40,18 @@
 # sha256_block:-( This is presumably because 64-bit shifts/rotates
 # apparently are not atomic instructions, but implemented in microcode.
 
-$output=shift;
+$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 $output";
+open STDOUT,"| $^X $xlate $flavour $output";
 
 if ($output =~ /512/) {
 	$func="sha512_block_data_order";
@@ -186,7 +190,7 @@
 	push	%r13
 	push	%r14
 	push	%r15
-	mov	%rsp,%rbp		# copy %rsp
+	mov	%rsp,%r11		# copy %rsp
 	shl	\$4,%rdx		# num*16
 	sub	\$$framesz,%rsp
 	lea	($inp,%rdx,$SZ),%rdx	# inp+num*16*$SZ
@@ -194,10 +198,10 @@
 	mov	$ctx,$_ctx		# save ctx, 1st arg
 	mov	$inp,$_inp		# save inp, 2nd arh
 	mov	%rdx,$_end		# save end pointer, "3rd" arg
-	mov	%rbp,$_rsp		# save copy of %rsp
+	mov	%r11,$_rsp		# save copy of %rsp
+.Lprologue:
 
-	.picmeup $Tbl
-	lea	$TABLE-.($Tbl),$Tbl
+	lea	$TABLE(%rip),$Tbl
 
 	mov	$SZ*0($ctx),$A
 	mov	$SZ*1($ctx),$B
@@ -257,14 +261,15 @@
 	mov	$H,$SZ*7($ctx)
 	jb	.Lloop
 
-	mov	$_rsp,%rsp
-	pop	%r15
-	pop	%r14
-	pop	%r13
-	pop	%r12
-	pop	%rbp
-	pop	%rbx
-
+	mov	$_rsp,%rsi
+	mov	(%rsi),%r15
+	mov	8(%rsi),%r14
+	mov	16(%rsi),%r13
+	mov	24(%rsi),%r12
+	mov	32(%rsi),%rbp
+	mov	40(%rsi),%rbx
+	lea	48(%rsi),%rsp
+.Lepilogue:
 	ret
 .size	$func,.-$func
 ___
@@ -339,6 +344,113 @@
 ___
 }
 
+# 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	se_handler,\@abi-omnipotent
+.align	16
+se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	sub	\$64,%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	lea	.Lprologue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lprologue
+	jb	.Lin_prologue
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	lea	.Lepilogue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
+	jae	.Lin_prologue
+
+	mov	16*$SZ+3*8(%rax),%rax	# pull $_rsp
+	lea	48(%rax),%rax
+
+	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_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
+
+	mov	40($disp),%rdi		# disp->ContextRecord
+	mov	$context,%rsi		# context
+	mov	\$154,%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
+	add	\$64,%rsp
+	popfq
+	pop	%r15
+	pop	%r14
+	pop	%r13
+	pop	%r12
+	pop	%rbp
+	pop	%rbx
+	pop	%rdi
+	pop	%rsi
+	ret
+.size	se_handler,.-se_handler
+
+.section	.pdata
+.align	4
+	.rva	.LSEH_begin_$func
+	.rva	.LSEH_end_$func
+	.rva	.LSEH_info_$func
+
+.section	.xdata
+.align	8
+.LSEH_info_$func:
+	.byte	9,0,0,0
+	.rva	se_handler
+___
+}
+
 $code =~ s/\`([^\`]*)\`/eval $1/gem;
 print $code;
 close STDOUT;
diff --git a/crypto/sha/sha.h b/crypto/sha/sha.h
index 47a2c29..16cacf9 100644
--- a/crypto/sha/sha.h
+++ b/crypto/sha/sha.h
@@ -81,7 +81,7 @@
  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  */
 
-#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#if defined(__LP32__)
 #define SHA_LONG unsigned long
 #elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
 #define SHA_LONG unsigned long
@@ -106,9 +106,6 @@
 	} 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 4831174..7c65b60 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>
 
-#if !defined(OPENSSL_NO_SHA1)
+#ifndef 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 d31f078..50d1925 100644
--- a/crypto/sha/sha1dgst.c
+++ b/crypto/sha/sha1dgst.c
@@ -63,10 +63,6 @@
 #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/sha1s.cpp b/crypto/sha/sha1s.cpp
deleted file mode 100644
index af23d1e..0000000
--- a/crypto/sha/sha1s.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-//
-// gettsc.inl
-//
-// gives access to the Pentium's (secret) cycle counter
-//
-// This software was written by Leonard Janke (janke@unixg.ubc.ca)
-// in 1996-7 and is entered, by him, into the public domain.
-
-#if defined(__WATCOMC__)
-void GetTSC(unsigned long&);
-#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax];
-#elif defined(__GNUC__)
-inline
-void GetTSC(unsigned long& tsc)
-{
-  asm volatile(".byte 15, 49\n\t"
-	       : "=eax" (tsc)
-	       :
-	       : "%edx", "%eax");
-}
-#elif defined(_MSC_VER)
-inline
-void GetTSC(unsigned long& tsc)
-{
-  unsigned long a;
-  __asm _emit 0fh
-  __asm _emit 31h
-  __asm mov a, eax;
-  tsc=a;
-}
-#endif      
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <openssl/sha.h>
-
-#define sha1_block_x86 sha1_block_asm_data_order
-extern "C" {
-void sha1_block_x86(SHA_CTX *ctx, unsigned char *buffer,int num);
-}
-
-void main(int argc,char *argv[])
-	{
-	unsigned char buffer[64*256];
-	SHA_CTX ctx;
-	unsigned long s1,s2,e1,e2;
-	unsigned char k[16];
-	unsigned long data[2];
-	unsigned char iv[8];
-	int i,num=0,numm;
-	int j=0;
-
-	if (argc >= 2)
-		num=atoi(argv[1]);
-
-	if (num == 0) num=16;
-	if (num > 250) num=16;
-	numm=num+2;
-#if 0
-	num*=64;
-	numm*=64;
-#endif
-
-	for (j=0; j<6; j++)
-		{
-		for (i=0; i<10; i++) /**/
-			{
-			sha1_block_x86(&ctx,buffer,numm);
-			GetTSC(s1);
-			sha1_block_x86(&ctx,buffer,numm);
-			GetTSC(e1);
-			GetTSC(s2);
-			sha1_block_x86(&ctx,buffer,num);
-			GetTSC(e2);
-			sha1_block_x86(&ctx,buffer,num);
-			}
-
-		printf("sha1 (%d bytes) %d %d (%.2f)\n",num*64,
-			e1-s1,e2-s2,(double)((e1-s1)-(e2-s2))/2);
-		}
-	}
-
diff --git a/crypto/sha/sha256.c b/crypto/sha/sha256.c
index 3256a83..8952d87 100644
--- a/crypto/sha/sha256.c
+++ b/crypto/sha/sha256.c
@@ -12,39 +12,29 @@
 
 #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
+	memset (c,0,sizeof(*c));
 	c->h[0]=0xc1059ed8UL;	c->h[1]=0x367cd507UL;
 	c->h[2]=0x3070dd17UL;	c->h[3]=0xf70e5939UL;
 	c->h[4]=0xffc00b31UL;	c->h[5]=0x68581511UL;
 	c->h[6]=0x64f98fa7UL;	c->h[7]=0xbefa4fa4UL;
-	c->Nl=0;	c->Nh=0;
-	c->num=0;	c->md_len=SHA224_DIGEST_LENGTH;
+	c->md_len=SHA224_DIGEST_LENGTH;
 	return 1;
 	}
 
 int SHA256_Init (SHA256_CTX *c)
 	{
-#ifdef OPENSSL_FIPS
-	FIPS_selftest_check();
-#endif
+	memset (c,0,sizeof(*c));
 	c->h[0]=0x6a09e667UL;	c->h[1]=0xbb67ae85UL;
 	c->h[2]=0x3c6ef372UL;	c->h[3]=0xa54ff53aUL;
 	c->h[4]=0x510e527fUL;	c->h[5]=0x9b05688cUL;
 	c->h[6]=0x1f83d9abUL;	c->h[7]=0x5be0cd19UL;
-	c->Nl=0;	c->Nh=0;
-	c->num=0;	c->md_len=SHA256_DIGEST_LENGTH;
+	c->md_len=SHA256_DIGEST_LENGTH;
 	return 1;
 	}
 
@@ -94,21 +84,21 @@
  */
 #define	HASH_MAKE_STRING(c,s)	do {	\
 	unsigned long ll;		\
-	unsigned int  xn;		\
+	unsigned int  nn;		\
 	switch ((c)->md_len)		\
 	{   case SHA224_DIGEST_LENGTH:	\
-		for (xn=0;xn<SHA224_DIGEST_LENGTH/4;xn++)	\
-		{   ll=(c)->h[xn]; HOST_l2c(ll,(s));   }	\
+		for (nn=0;nn<SHA224_DIGEST_LENGTH/4;nn++)	\
+		{   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }	\
 		break;			\
 	    case SHA256_DIGEST_LENGTH:	\
-		for (xn=0;xn<SHA256_DIGEST_LENGTH/4;xn++)	\
-		{   ll=(c)->h[xn]; HOST_l2c(ll,(s));   }	\
+		for (nn=0;nn<SHA256_DIGEST_LENGTH/4;nn++)	\
+		{   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }	\
 		break;			\
 	    default:			\
 		if ((c)->md_len > SHA256_DIGEST_LENGTH)	\
 		    return 0;				\
-		for (xn=0;xn<(c)->md_len/4;xn++)		\
-		{   ll=(c)->h[xn]; HOST_l2c(ll,(s));   }	\
+		for (nn=0;nn<(c)->md_len/4;nn++)		\
+		{   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }	\
 		break;			\
 	}				\
 	} while (0)
diff --git a/crypto/sha/sha512.c b/crypto/sha/sha512.c
index 9e91bca..cbc0e58 100644
--- a/crypto/sha/sha512.c
+++ b/crypto/sha/sha512.c
@@ -5,10 +5,6 @@
  * ====================================================================
  */
 #include <openssl/opensslconf.h>
-#ifdef OPENSSL_FIPS
-#include <openssl/fips.h>
-#endif
-
 #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512)
 /*
  * IMPLEMENTATION NOTES.
@@ -65,9 +61,19 @@
 
 int SHA384_Init (SHA512_CTX *c)
 	{
-#ifdef OPENSSL_FIPS
-	FIPS_selftest_check();
-#endif
+#if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm))
+	/* maintain dword order required by assembler module */
+	unsigned int *h = (unsigned int *)c->h;
+
+	h[0]  = 0xcbbb9d5d; h[1]  = 0xc1059ed8;
+	h[2]  = 0x629a292a; h[3]  = 0x367cd507;
+	h[4]  = 0x9159015a; h[5]  = 0x3070dd17;
+	h[6]  = 0x152fecd8; h[7]  = 0xf70e5939;
+	h[8]  = 0x67332667; h[9]  = 0xffc00b31;
+	h[10] = 0x8eb44a87; h[11] = 0x68581511;
+	h[12] = 0xdb0c2e0d; h[13] = 0x64f98fa7;
+	h[14] = 0x47b5481d; h[15] = 0xbefa4fa4;
+#else
 	c->h[0]=U64(0xcbbb9d5dc1059ed8);
 	c->h[1]=U64(0x629a292a367cd507);
 	c->h[2]=U64(0x9159015a3070dd17);
@@ -76,6 +82,7 @@
 	c->h[5]=U64(0x8eb44a8768581511);
 	c->h[6]=U64(0xdb0c2e0d64f98fa7);
 	c->h[7]=U64(0x47b5481dbefa4fa4);
+#endif
         c->Nl=0;        c->Nh=0;
         c->num=0;       c->md_len=SHA384_DIGEST_LENGTH;
         return 1;
@@ -83,9 +90,19 @@
 
 int SHA512_Init (SHA512_CTX *c)
 	{
-#ifdef OPENSSL_FIPS
-	FIPS_selftest_check();
-#endif
+#if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm))
+	/* maintain dword order required by assembler module */
+	unsigned int *h = (unsigned int *)c->h;
+
+	h[0]  = 0x6a09e667; h[1]  = 0xf3bcc908;
+	h[2]  = 0xbb67ae85; h[3]  = 0x84caa73b;
+	h[4]  = 0x3c6ef372; h[5]  = 0xfe94f82b;
+	h[6]  = 0xa54ff53a; h[7]  = 0x5f1d36f1;
+	h[8]  = 0x510e527f; h[9]  = 0xade682d1;
+	h[10] = 0x9b05688c; h[11] = 0x2b3e6c1f;
+	h[12] = 0x1f83d9ab; h[13] = 0xfb41bd6b;
+	h[14] = 0x5be0cd19; h[15] = 0x137e2179;
+#else
 	c->h[0]=U64(0x6a09e667f3bcc908);
 	c->h[1]=U64(0xbb67ae8584caa73b);
 	c->h[2]=U64(0x3c6ef372fe94f82b);
@@ -94,6 +111,7 @@
 	c->h[5]=U64(0x9b05688c2b3e6c1f);
 	c->h[6]=U64(0x1f83d9abfb41bd6b);
 	c->h[7]=U64(0x5be0cd19137e2179);
+#endif
         c->Nl=0;        c->Nh=0;
         c->num=0;       c->md_len=SHA512_DIGEST_LENGTH;
         return 1;
@@ -142,6 +160,24 @@
 
 	if (md==0) return 0;
 
+#if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm))
+	/* recall assembler dword order... */
+	n = c->md_len;
+	if (n == SHA384_DIGEST_LENGTH || n == SHA512_DIGEST_LENGTH)
+		{
+		unsigned int *h = (unsigned int *)c->h, t;
+
+		for (n/=4;n;n--)
+			{
+			t = *(h++);
+			*(md++) = (unsigned char)(t>>24);
+			*(md++) = (unsigned char)(t>>16);
+			*(md++) = (unsigned char)(t>>8);
+			*(md++) = (unsigned char)(t);
+			}
+		}
+	else	return 0;
+#else
 	switch (c->md_len)
 		{
 		/* Let compiler decide if it's appropriate to unroll... */
@@ -178,7 +214,7 @@
 		/* ... as well as make sure md_len is not abused. */
 		default:	return 0;
 		}
-
+#endif
 	return 1;
 	}
 
@@ -204,7 +240,7 @@
 
 		if (len < n)
 			{
-			memcpy (p+c->num,data,len), c->num += len;
+			memcpy (p+c->num,data,len), c->num += (unsigned int)len;
 			return 1;
 			}
 		else	{
@@ -314,7 +350,7 @@
 #ifndef PEDANTIC
 # if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
 #  if defined(__x86_64) || defined(__x86_64__)
-#   define ROTR(a,n)	({ unsigned long ret;		\
+#   define ROTR(a,n)	({ SHA_LONG64 ret;		\
 				asm ("rorq %1,%0"	\
 				: "=r"(ret)		\
 				: "J"(n),"0"(a)		\
@@ -337,20 +373,21 @@
 				((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));		\
 				((SHA_LONG64)hi)<<32|lo;	})
 #   endif
 #  elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64)
-#   define ROTR(a,n)	({ unsigned long ret;		\
+#   define ROTR(a,n)	({ SHA_LONG64 ret;		\
 				asm ("rotrdi %0,%1,%2"	\
 				: "=r"(ret)		\
 				: "r"(a),"K"(n)); ret;	})
 #  endif
 # elif defined(_MSC_VER)
 #  if defined(_WIN64)	/* applies to both IA-64 and AMD64 */
+#   pragma intrinsic(_rotr64)
 #   define ROTR(a,n)	_rotr64((a),n)
 #  endif
 #  if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
@@ -398,15 +435,66 @@
 #define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
 #define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
 
-#if defined(OPENSSL_IA32_SSE2) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
-#define	GO_FOR_SSE2(ctx,in,num)		do {		\
-	void	sha512_block_sse2(void *,const void *,size_t);	\
-	if (!(OPENSSL_ia32cap_P & (1<<26))) break;	\
-	sha512_block_sse2(ctx->h,in,num); return;	\
-					} while (0)
-#endif
 
-#ifdef OPENSSL_SMALL_FOOTPRINT
+#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
+/*
+ * This code should give better results on 32-bit CPU with less than
+ * ~24 registers, both size and performance wise...
+ */
+static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num)
+	{
+	const SHA_LONG64 *W=in;
+	SHA_LONG64	A,E,T;
+	SHA_LONG64	X[9+80],*F;
+	int i;
+
+			while (num--) {
+
+	F    = X+80;
+	A    = ctx->h[0];	F[1] = ctx->h[1];
+	F[2] = ctx->h[2];	F[3] = ctx->h[3];
+	E    = ctx->h[4];	F[5] = ctx->h[5];
+	F[6] = ctx->h[6];	F[7] = ctx->h[7];
+
+	for (i=0;i<16;i++,F--)
+		{
+#ifdef B_ENDIAN
+		T = W[i];
+#else
+		T = PULL64(W[i]);
+#endif
+		F[0] = A;
+		F[4] = E;
+		F[8] = T;
+		T   += F[7] + Sigma1(E) + Ch(E,F[5],F[6]) + K512[i];
+		E    = F[3] + T;
+		A    = T + Sigma0(A) + Maj(A,F[1],F[2]);
+		}
+
+	for (;i<80;i++,F--)
+		{
+		T    = sigma0(F[8+16-1]);
+		T   += sigma1(F[8+16-14]);
+		T   += F[8+16] + F[8+16-9];
+
+		F[0] = A;
+		F[4] = E;
+		F[8] = T;
+		T   += F[7] + Sigma1(E) + Ch(E,F[5],F[6]) + K512[i];
+		E    = F[3] + T;
+		A    = T + Sigma0(A) + Maj(A,F[1],F[2]);
+		}
+
+	ctx->h[0] += A;		ctx->h[1] += F[1];
+	ctx->h[2] += F[2];	ctx->h[3] += F[3];
+	ctx->h[4] += E;		ctx->h[5] += F[5];
+	ctx->h[6] += F[6];	ctx->h[7] += F[7];
+
+			W+=SHA_LBLOCK;
+			}
+	}
+
+#elif defined(OPENSSL_SMALL_FOOTPRINT)
 
 static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num)
 	{
@@ -415,10 +503,6 @@
 	SHA_LONG64	X[16];
 	int i;
 
-#ifdef GO_FOR_SSE2
-	GO_FOR_SSE2(ctx,in,num);
-#endif
-
 			while (num--) {
 
 	a = ctx->h[0];	b = ctx->h[1];	c = ctx->h[2];	d = ctx->h[3];
@@ -463,11 +547,11 @@
 	h = Sigma0(a) + Maj(a,b,c);			\
 	d += T1;	h += T1;		} while (0)
 
-#define	ROUND_16_80(i,a,b,c,d,e,f,g,h,X)	do {	\
-	s0 = X[(i+1)&0x0f];	s0 = sigma0(s0);	\
-	s1 = X[(i+14)&0x0f];	s1 = sigma1(s1);	\
-	T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f];	\
-	ROUND_00_15(i,a,b,c,d,e,f,g,h);		} while (0)
+#define	ROUND_16_80(i,j,a,b,c,d,e,f,g,h,X)	do {	\
+	s0 = X[(j+1)&0x0f];	s0 = sigma0(s0);	\
+	s1 = X[(j+14)&0x0f];	s1 = sigma1(s1);	\
+	T1 = X[(j)&0x0f] += s0 + s1 + X[(j+9)&0x0f];	\
+	ROUND_00_15(i+j,a,b,c,d,e,f,g,h);		} while (0)
 
 static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num)
 	{
@@ -476,10 +560,6 @@
 	SHA_LONG64	X[16];
 	int i;
 
-#ifdef GO_FOR_SSE2
-	GO_FOR_SSE2(ctx,in,num);
-#endif
-
 			while (num--) {
 
 	a = ctx->h[0];	b = ctx->h[1];	c = ctx->h[2];	d = ctx->h[3];
@@ -521,16 +601,24 @@
 	T1 = X[15] = PULL64(W[15]);	ROUND_00_15(15,b,c,d,e,f,g,h,a);
 #endif
 
-	for (i=16;i<80;i+=8)
+	for (i=16;i<80;i+=16)
 		{
-		ROUND_16_80(i+0,a,b,c,d,e,f,g,h,X);
-		ROUND_16_80(i+1,h,a,b,c,d,e,f,g,X);
-		ROUND_16_80(i+2,g,h,a,b,c,d,e,f,X);
-		ROUND_16_80(i+3,f,g,h,a,b,c,d,e,X);
-		ROUND_16_80(i+4,e,f,g,h,a,b,c,d,X);
-		ROUND_16_80(i+5,d,e,f,g,h,a,b,c,X);
-		ROUND_16_80(i+6,c,d,e,f,g,h,a,b,X);
-		ROUND_16_80(i+7,b,c,d,e,f,g,h,a,X);
+		ROUND_16_80(i, 0,a,b,c,d,e,f,g,h,X);
+		ROUND_16_80(i, 1,h,a,b,c,d,e,f,g,X);
+		ROUND_16_80(i, 2,g,h,a,b,c,d,e,f,X);
+		ROUND_16_80(i, 3,f,g,h,a,b,c,d,e,X);
+		ROUND_16_80(i, 4,e,f,g,h,a,b,c,d,X);
+		ROUND_16_80(i, 5,d,e,f,g,h,a,b,c,X);
+		ROUND_16_80(i, 6,c,d,e,f,g,h,a,b,X);
+		ROUND_16_80(i, 7,b,c,d,e,f,g,h,a,X);
+		ROUND_16_80(i, 8,a,b,c,d,e,f,g,h,X);
+		ROUND_16_80(i, 9,h,a,b,c,d,e,f,g,X);
+		ROUND_16_80(i,10,g,h,a,b,c,d,e,f,X);
+		ROUND_16_80(i,11,f,g,h,a,b,c,d,e,X);
+		ROUND_16_80(i,12,e,f,g,h,a,b,c,d,X);
+		ROUND_16_80(i,13,d,e,f,g,h,a,b,c,X);
+		ROUND_16_80(i,14,c,d,e,f,g,h,a,b,X);
+		ROUND_16_80(i,15,b,c,d,e,f,g,h,a,X);
 		}
 
 	ctx->h[0] += a;	ctx->h[1] += b;	ctx->h[2] += c;	ctx->h[3] += d;
@@ -544,13 +632,10 @@
 
 #endif /* SHA512_ASM */
 
-#else /* OPENSSL_NO_SHA512 */
+#else /* !OPENSSL_NO_SHA512 */
 
-/* Sensitive compilers ("Compaq C V6.4-005 on OpenVMS VAX V7.3", for
- * example) dislike a statement-free file, complaining:
- * "%CC-W-EMPTYFILE, Source file does not contain any declarations."
- */
+#if defined(PEDANTIC) || defined(__DECC) || defined(OPENSSL_SYS_MACOSX)
+static void *dummy=&dummy;
+#endif
 
-int sha512_dummy();
-
-#endif /* OPENSSL_NO_SHA512 */
+#endif /* !OPENSSL_NO_SHA512 */
diff --git a/crypto/sha/sha_dgst.c b/crypto/sha/sha_dgst.c
index 598f4d7..70eb560 100644
--- a/crypto/sha/sha_dgst.c
+++ b/crypto/sha/sha_dgst.c
@@ -57,12 +57,6 @@
  */
 
 #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 da46ddf..672c26e 100644
--- a/crypto/sha/sha_locl.h
+++ b/crypto/sha/sha_locl.h
@@ -122,23 +122,14 @@
 #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
+	memset (c,0,sizeof(*c));
 	c->h0=INIT_DATA_h0;
 	c->h1=INIT_DATA_h1;
 	c->h2=INIT_DATA_h2;
 	c->h3=INIT_DATA_h3;
 	c->h4=INIT_DATA_h4;
-	c->Nl=0;
-	c->Nh=0;
-	c->num=0;
 	return 1;
 	}
 
diff --git a/crypto/sha/shatest.c b/crypto/sha/shatest.c
index ed0fe06..2761464 100644
--- a/crypto/sha/shatest.c
+++ b/crypto/sha/shatest.c
@@ -123,9 +123,9 @@
 	i=1;
 	while (*P != NULL)
 		{
-		EVP_Digest(*P,strlen((char *)*P),md,NULL,EVP_sha(), NULL);
+		EVP_Digest(*P,strlen(*P),md,NULL,EVP_sha(), NULL);
 		p=pt(md);
-		if (strcmp(p,(char *)*R) != 0)
+		if (strcmp(p,*R) != 0)
 			{
 			printf("error calculating SHA on '%s'\n",*P);
 			printf("got %s instead of %s\n",p,*R);
diff --git a/crypto/sparccpuid.S b/crypto/sparccpuid.S
index c17350f..bcf46f2 100644
--- a/crypto/sparccpuid.S
+++ b/crypto/sparccpuid.S
@@ -34,7 +34,8 @@
 	nop
 	call	.PIC.zero.up
 	mov	.zero-(.-4),%o0
-	ldd	[%o0],%f0
+	ld	[%o0],%f0
+	ld	[%o0],%f1
 
 	subcc	%g0,1,%o0
 	! Following is V9 "rd %ccr,%o0" instruction. However! V8
@@ -166,6 +167,7 @@
 
 .global	OPENSSL_atomic_add
 .type	OPENSSL_atomic_add,#function
+.align	32
 OPENSSL_atomic_add:
 #ifndef ABI64
 	subcc	%g0,1,%o2
@@ -213,27 +215,106 @@
 	sra	%o0,%g0,%o0	! we return signed int, remember?
 .size	OPENSSL_atomic_add,.-OPENSSL_atomic_add
 
-.global	OPENSSL_rdtsc
+.global	_sparcv9_rdtick
+.align	32
+_sparcv9_rdtick:
 	subcc	%g0,1,%o0
 	.word	0x91408000	!rd	%ccr,%o0
 	cmp	%o0,0x99
-	bne	.notsc
+	bne	.notick
 	xor	%o0,%o0,%o0
-	save	%sp,FRAME-16,%sp
-	mov	513,%o0		!SI_PLATFORM
-	add	%sp,BIAS+16,%o1
-	call	sysinfo
-	mov	256,%o2
+	.word	0x91410000	!rd	%tick,%o0
+	retl
+	.word	0x93323020	!srlx	%o2,32,%o1
+.notick:
+	retl
+	xor	%o1,%o1,%o1
+.type	_sparcv9_rdtick,#function
+.size	_sparcv9_rdtick,.-_sparcv9_rdtick
 
-	add	%sp,BIAS-16,%o1
-	ld	[%o1],%l0
-	ld	[%o1+4],%l1
-	ld	[%o1+8],%l2
-	mov	%lo('SUNW'),%l3
-	ret
-	restore
-.notsc:
+.global	OPENSSL_cleanse
+.align	32
+OPENSSL_cleanse:
+	cmp	%o1,14
+	nop
+#ifdef ABI64
+	bgu	%xcc,.Lot
+#else
+	bgu	.Lot
+#endif
+	cmp	%o1,0
+	bne	.Little
+	nop
 	retl
 	nop
-.type	OPENSSL_rdtsc,#function
-.size	OPENSSL_rdtsc,.-OPENSSL_atomic_add
+
+.Little:
+	stb	%g0,[%o0]
+	subcc	%o1,1,%o1
+	bnz	.Little
+	add	%o0,1,%o0
+	retl
+	nop
+.align	32
+.Lot:
+#ifndef ABI64
+	subcc	%g0,1,%g1
+	! see above for explanation
+	.word	0x83408000	!rd	%ccr,%g1
+	cmp	%g1,0x99
+	bne	.v8lot
+	nop
+#endif
+
+.v9lot:	andcc	%o0,7,%g0
+	bz	.v9aligned
+	nop
+	stb	%g0,[%o0]
+	sub	%o1,1,%o1
+	ba	.v9lot
+	add	%o0,1,%o0
+.align	16,0x01000000
+.v9aligned:
+	.word	0xc0720000	!stx	%g0,[%o0]
+	sub	%o1,8,%o1
+	andcc	%o1,-8,%g0
+#ifdef ABI64
+	.word	0x126ffffd	!bnz	%xcc,.v9aligned
+#else
+	.word	0x124ffffd	!bnz	%icc,.v9aligned
+#endif
+	add	%o0,8,%o0
+
+	cmp	%o1,0
+	bne	.Little
+	nop
+	retl
+	nop
+#ifndef ABI64
+.v8lot:	andcc	%o0,3,%g0
+	bz	.v8aligned
+	nop
+	stb	%g0,[%o0]
+	sub	%o1,1,%o1
+	ba	.v8lot
+	add	%o0,1,%o0
+	nop
+.v8aligned:
+	st	%g0,[%o0]
+	sub	%o1,4,%o1
+	andcc	%o1,-4,%g0
+	bnz	.v8aligned
+	add	%o0,4,%o0
+
+	cmp	%o1,0
+	bne	.Little
+	nop
+	retl
+	nop
+#endif
+.type	OPENSSL_cleanse,#function
+.size	OPENSSL_cleanse,.-OPENSSL_cleanse
+
+.section	".init",#alloc,#execinstr
+	call	OPENSSL_cpuid_setup
+	nop
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
deleted file mode 100644
index 489a77b..0000000
--- a/crypto/stack/Makefile
+++ /dev/null
@@ -1,84 +0,0 @@
-#
-# OpenSSL/crypto/stack/Makefile
-#
-
-DIR=	stack
-TOP=	../..
-CC=	cc
-INCLUDES=
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=stack.c
-LIBOBJ=stack.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= stack.h safestack.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-stack.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-stack.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-stack.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-stack.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-stack.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-stack.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-stack.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-stack.o: ../../include/openssl/symhacks.h ../cryptlib.h stack.c
diff --git a/crypto/stack/safestack.h b/crypto/stack/safestack.h
index 78cc485..d616b4a 100644
--- a/crypto/stack/safestack.h
+++ b/crypto/stack/safestack.h
@@ -57,18 +57,27 @@
 
 #include <openssl/stack.h>
 
-#ifdef DEBUG_SAFESTACK
-
 #ifndef CHECKED_PTR_OF
 #define CHECKED_PTR_OF(type, p) \
     ((void*) (1 ? p : (type*)0))
 #endif
 
+/* In C++ we get problems because an explicit cast is needed from (void *)
+ * we use CHECKED_STACK_OF to ensure the correct type is passed in the macros
+ * below. 
+ */
+
+#define CHECKED_STACK_OF(type, p) \
+    ((_STACK*) (1 ? p : (STACK_OF(type)*)0))
+
 #define CHECKED_SK_FREE_FUNC(type, p) \
     ((void (*)(void *)) ((1 ? p : (void (*)(type *))0)))
 
+#define CHECKED_SK_FREE_FUNC2(type, p) \
+    ((void (*)(void *)) ((1 ? p : (void (*)(type))0)))
+
 #define CHECKED_SK_CMP_FUNC(type, p) \
-    ((int (*)(const char * const *, const char * const *)) \
+    ((int (*)(const void *, const void *)) \
 	((1 ? p : (int (*)(const type * const *, const type * const *))0)))
 
 #define STACK_OF(type) struct stack_st_##type
@@ -77,11 +86,51 @@
 #define DECLARE_STACK_OF(type) \
 STACK_OF(type) \
     { \
-    STACK stack; \
+    _STACK stack; \
+    };
+#define DECLARE_SPECIAL_STACK_OF(type, type2) \
+STACK_OF(type) \
+    { \
+    _STACK stack; \
     };
 
 #define IMPLEMENT_STACK_OF(type) /* nada (obsolete in new safestack approach)*/
 
+
+/* Strings are special: normally an lhash entry will point to a single
+ * (somewhat) mutable object. In the case of strings:
+ *
+ * a) Instead of a single char, there is an array of chars, NUL-terminated.
+ * b) The string may have be immutable.
+ *
+ * So, they need their own declarations. Especially important for
+ * type-checking tools, such as Deputy.
+ *
+o * In practice, however, it appears to be hard to have a const
+ * string. For now, I'm settling for dealing with the fact it is a
+ * string at all.
+ */
+typedef char *OPENSSL_STRING;
+
+typedef const char *OPENSSL_CSTRING;
+
+/* Confusingly, LHASH_OF(STRING) deals with char ** throughout, but
+ * STACK_OF(STRING) is really more like STACK_OF(char), only, as
+ * mentioned above, instead of a single char each entry is a
+ * NUL-terminated array of chars. So, we have to implement STRING
+ * specially for STACK_OF. This is dealt with in the autogenerated
+ * macros below.
+ */
+
+DECLARE_SPECIAL_STACK_OF(OPENSSL_STRING, char)
+
+/* Similarly, we sometimes use a block of characters, NOT
+ * nul-terminated. These should also be distinguished from "normal"
+ * stacks. */
+
+typedef void *OPENSSL_BLOCK;
+DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)
+
 /* SKM_sk_... stack macros are internal to safestack.h:
  * never use them directly, use sk_<type>_... instead */
 #define SKM_sk_new(type, cmp) \
@@ -89,52 +138,55 @@
 #define SKM_sk_new_null(type) \
 	((STACK_OF(type) *)sk_new_null())
 #define SKM_sk_free(type, st) \
-	sk_free(CHECKED_PTR_OF(STACK_OF(type), st))
+	sk_free(CHECKED_STACK_OF(type, st))
 #define SKM_sk_num(type, st) \
-	sk_num(CHECKED_PTR_OF(STACK_OF(type), st))
+	sk_num(CHECKED_STACK_OF(type, st))
 #define SKM_sk_value(type, st,i) \
-	((type *)sk_value(CHECKED_PTR_OF(STACK_OF(type), st), i))
+	((type *)sk_value(CHECKED_STACK_OF(type, st), i))
 #define SKM_sk_set(type, st,i,val) \
-	sk_set(CHECKED_PTR_OF(STACK_OF(type), st), i, CHECKED_PTR_OF(type, val))
+	sk_set(CHECKED_STACK_OF(type, st), i, CHECKED_PTR_OF(type, val))
 #define SKM_sk_zero(type, st) \
-	sk_zero(CHECKED_PTR_OF(STACK_OF(type), st))
-#define SKM_sk_push(type, st,val) \
-	sk_push(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val))
-#define SKM_sk_unshift(type, st,val) \
-	sk_unshift(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val))
-#define SKM_sk_find(type, st,val) \
-	sk_find(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val))
-#define SKM_sk_delete(type, st,i) \
-	(type *)sk_delete(CHECKED_PTR_OF(STACK_OF(type), st), i)
-#define SKM_sk_delete_ptr(type, st,ptr) \
-	(type *)sk_delete_ptr(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, ptr))
-#define SKM_sk_insert(type, st,val,i) \
-	sk_insert(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val), i)
-#define SKM_sk_set_cmp_func(type, st,cmp) \
+	sk_zero(CHECKED_STACK_OF(type, st))
+#define SKM_sk_push(type, st, val) \
+	sk_push(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
+#define SKM_sk_unshift(type, st, val) \
+	sk_unshift(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
+#define SKM_sk_find(type, st, val) \
+	sk_find(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
+#define SKM_sk_find_ex(type, st, val) \
+	sk_find_ex(CHECKED_STACK_OF(type, st), \
+		   CHECKED_PTR_OF(type, val))
+#define SKM_sk_delete(type, st, i) \
+	(type *)sk_delete(CHECKED_STACK_OF(type, st), i)
+#define SKM_sk_delete_ptr(type, st, ptr) \
+	(type *)sk_delete_ptr(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, ptr))
+#define SKM_sk_insert(type, st,val, i) \
+	sk_insert(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val), i)
+#define SKM_sk_set_cmp_func(type, st, cmp) \
 	((int (*)(const type * const *,const type * const *)) \
-	sk_set_cmp_func(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_SK_CMP_FUNC(type, cmp)))
+	sk_set_cmp_func(CHECKED_STACK_OF(type, st), CHECKED_SK_CMP_FUNC(type, cmp)))
 #define SKM_sk_dup(type, st) \
-	(STACK_OF(type) *)sk_dup(CHECKED_PTR_OF(STACK_OF(type), st))
-#define SKM_sk_pop_free(type, st,free_func) \
-	sk_pop_free(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_SK_FREE_FUNC(type, free_func))
+	(STACK_OF(type) *)sk_dup(CHECKED_STACK_OF(type, st))
+#define SKM_sk_pop_free(type, st, free_func) \
+	sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func))
 #define SKM_sk_shift(type, st) \
-	(type *)sk_shift(CHECKED_PTR_OF(STACK_OF(type), st))
+	(type *)sk_shift(CHECKED_STACK_OF(type, st))
 #define SKM_sk_pop(type, st) \
-	(type *)sk_pop(CHECKED_PTR_OF(STACK_OF(type), st))
+	(type *)sk_pop(CHECKED_STACK_OF(type, st))
 #define SKM_sk_sort(type, st) \
-	sk_sort(CHECKED_PTR_OF(STACK_OF(type), st))
+	sk_sort(CHECKED_STACK_OF(type, st))
 #define SKM_sk_is_sorted(type, st) \
-	sk_is_sorted(CHECKED_PTR_OF(STACK_OF(type), st))
+	sk_is_sorted(CHECKED_STACK_OF(type, st))
 
 #define	SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
-	(STACK_OF(type) *)d2i_ASN1_SET(CHECKED_PTR_OF(STACK_OF(type), st), \
+	(STACK_OF(type) *)d2i_ASN1_SET(CHECKED_STACK_OF(type, st), \
 				pp, length, \
 				CHECKED_D2I_OF(type, d2i_func), \
 				CHECKED_SK_FREE_FUNC(type, free_func), \
 				ex_tag, ex_class)
 
 #define	SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \
-	i2d_ASN1_SET(CHECKED_PTR_OF(STACK_OF(type), st), pp, \
+  i2d_ASN1_SET((STACK_OF(OPENSSL_BLOCK) *)CHECKED_STACK_OF(type, st), pp, \
 				CHECKED_I2D_OF(type, i2d_func), \
 				ex_tag, ex_class, is_set)
 
@@ -151,72 +203,8 @@
 				CHECKED_SK_FREE_FUNC(type, free_func), \
 				pass, passlen, oct, seq)
 
-#else
-
-#define STACK_OF(type) STACK
-#define PREDECLARE_STACK_OF(type) /* nada */
-#define DECLARE_STACK_OF(type)    /* nada */
-#define IMPLEMENT_STACK_OF(type)  /* nada */
-
-#define SKM_sk_new(type, cmp) \
-	sk_new((int (*)(const char * const *, const char * const *))(cmp))
-#define SKM_sk_new_null(type) \
-	sk_new_null()
-#define SKM_sk_free(type, st) \
-	sk_free(st)
-#define SKM_sk_num(type, st) \
-	sk_num(st)
-#define SKM_sk_value(type, st,i) \
-	((type *)sk_value(st, i))
-#define SKM_sk_set(type, st,i,val) \
-	((type *)sk_set(st, i,(char *)val))
-#define SKM_sk_zero(type, st) \
-	sk_zero(st)
-#define SKM_sk_push(type, st,val) \
-	sk_push(st, (char *)val)
-#define SKM_sk_unshift(type, st,val) \
-	sk_unshift(st, (char *)val)
-#define SKM_sk_find(type, st,val) \
-	sk_find(st, (char *)val)
-#define SKM_sk_delete(type, st,i) \
-	((type *)sk_delete(st, i))
-#define SKM_sk_delete_ptr(type, st,ptr) \
-	((type *)sk_delete_ptr(st,(char *)ptr))
-#define SKM_sk_insert(type, st,val,i) \
-	sk_insert(st, (char *)val, i)
-#define SKM_sk_set_cmp_func(type, st,cmp) \
-	((int (*)(const type * const *,const type * const *)) \
-	sk_set_cmp_func(st, (int (*)(const char * const *, const char * const *))(cmp)))
-#define SKM_sk_dup(type, st) \
-	sk_dup(st)
-#define SKM_sk_pop_free(type, st,free_func) \
-	sk_pop_free(st, (void (*)(void *))free_func)
-#define SKM_sk_shift(type, st) \
-	((type *)sk_shift(st))
-#define SKM_sk_pop(type, st) \
-	((type *)sk_pop(st))
-#define SKM_sk_sort(type, st) \
-	sk_sort(st)
-#define SKM_sk_is_sorted(type, st) \
-	sk_is_sorted(st)
-
-#define	SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
-	d2i_ASN1_SET(st,pp,length, (void *(*)(void ** ,const unsigned char ** ,long))d2i_func, (void (*)(void *))free_func, ex_tag,ex_class)
-#define	SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \
-	i2d_ASN1_SET(st,pp,(int (*)(void *, unsigned char **))i2d_func,ex_tag,ex_class,is_set)
-
-#define	SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \
-	ASN1_seq_pack(st, (int (*)(void *, unsigned char **))i2d_func, buf, len)
-#define	SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \
-	ASN1_seq_unpack(buf,len,(void *(*)(void **,const unsigned char **,long))d2i_func, (void(*)(void *))free_func)
-
-#define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \
-	((STACK *)PKCS12_decrypt_d2i(algor,(char *(*)())d2i_func, (void(*)(void *))free_func,pass,passlen,oct,seq))
-
-#endif
-
 /* This block of defines is updated by util/mkstack.pl, please do not touch! */
-#define sk_ACCESS_DESCRIPTION_new(st) SKM_sk_new(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_new(cmp) SKM_sk_new(ACCESS_DESCRIPTION, (cmp))
 #define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION)
 #define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st))
 #define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st))
@@ -238,7 +226,7 @@
 #define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st))
 #define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st))
 
-#define sk_ASIdOrRange_new(st) SKM_sk_new(ASIdOrRange, (st))
+#define sk_ASIdOrRange_new(cmp) SKM_sk_new(ASIdOrRange, (cmp))
 #define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange)
 #define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st))
 #define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st))
@@ -260,7 +248,7 @@
 #define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st))
 #define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st))
 
-#define sk_ASN1_GENERALSTRING_new(st) SKM_sk_new(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_new(cmp) SKM_sk_new(ASN1_GENERALSTRING, (cmp))
 #define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING)
 #define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st))
 #define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st))
@@ -282,7 +270,7 @@
 #define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st))
 #define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st))
 
-#define sk_ASN1_INTEGER_new(st) SKM_sk_new(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_new(cmp) SKM_sk_new(ASN1_INTEGER, (cmp))
 #define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER)
 #define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st))
 #define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st))
@@ -304,7 +292,7 @@
 #define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st))
 #define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st))
 
-#define sk_ASN1_OBJECT_new(st) SKM_sk_new(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_new(cmp) SKM_sk_new(ASN1_OBJECT, (cmp))
 #define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT)
 #define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st))
 #define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st))
@@ -326,7 +314,7 @@
 #define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st))
 #define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st))
 
-#define sk_ASN1_STRING_TABLE_new(st) SKM_sk_new(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_new(cmp) SKM_sk_new(ASN1_STRING_TABLE, (cmp))
 #define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE)
 #define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st))
 #define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st))
@@ -348,7 +336,7 @@
 #define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st))
 #define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st))
 
-#define sk_ASN1_TYPE_new(st) SKM_sk_new(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_new(cmp) SKM_sk_new(ASN1_TYPE, (cmp))
 #define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE)
 #define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st))
 #define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st))
@@ -370,7 +358,29 @@
 #define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st))
 #define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st))
 
-#define sk_ASN1_VALUE_new(st) SKM_sk_new(ASN1_VALUE, (st))
+#define sk_ASN1_UTF8STRING_new(cmp) SKM_sk_new(ASN1_UTF8STRING, (cmp))
+#define sk_ASN1_UTF8STRING_new_null() SKM_sk_new_null(ASN1_UTF8STRING)
+#define sk_ASN1_UTF8STRING_free(st) SKM_sk_free(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_num(st) SKM_sk_num(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_value(st, i) SKM_sk_value(ASN1_UTF8STRING, (st), (i))
+#define sk_ASN1_UTF8STRING_set(st, i, val) SKM_sk_set(ASN1_UTF8STRING, (st), (i), (val))
+#define sk_ASN1_UTF8STRING_zero(st) SKM_sk_zero(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_push(st, val) SKM_sk_push(ASN1_UTF8STRING, (st), (val))
+#define sk_ASN1_UTF8STRING_unshift(st, val) SKM_sk_unshift(ASN1_UTF8STRING, (st), (val))
+#define sk_ASN1_UTF8STRING_find(st, val) SKM_sk_find(ASN1_UTF8STRING, (st), (val))
+#define sk_ASN1_UTF8STRING_find_ex(st, val) SKM_sk_find_ex(ASN1_UTF8STRING, (st), (val))
+#define sk_ASN1_UTF8STRING_delete(st, i) SKM_sk_delete(ASN1_UTF8STRING, (st), (i))
+#define sk_ASN1_UTF8STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_UTF8STRING, (st), (ptr))
+#define sk_ASN1_UTF8STRING_insert(st, val, i) SKM_sk_insert(ASN1_UTF8STRING, (st), (val), (i))
+#define sk_ASN1_UTF8STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_UTF8STRING, (st), (cmp))
+#define sk_ASN1_UTF8STRING_dup(st) SKM_sk_dup(ASN1_UTF8STRING, st)
+#define sk_ASN1_UTF8STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_UTF8STRING, (st), (free_func))
+#define sk_ASN1_UTF8STRING_shift(st) SKM_sk_shift(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_pop(st) SKM_sk_pop(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_sort(st) SKM_sk_sort(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_is_sorted(st) SKM_sk_is_sorted(ASN1_UTF8STRING, (st))
+
+#define sk_ASN1_VALUE_new(cmp) SKM_sk_new(ASN1_VALUE, (cmp))
 #define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE)
 #define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st))
 #define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st))
@@ -392,7 +402,7 @@
 #define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st))
 #define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st))
 
-#define sk_BIO_new(st) SKM_sk_new(BIO, (st))
+#define sk_BIO_new(cmp) SKM_sk_new(BIO, (cmp))
 #define sk_BIO_new_null() SKM_sk_new_null(BIO)
 #define sk_BIO_free(st) SKM_sk_free(BIO, (st))
 #define sk_BIO_num(st) SKM_sk_num(BIO, (st))
@@ -414,7 +424,51 @@
 #define sk_BIO_sort(st) SKM_sk_sort(BIO, (st))
 #define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st))
 
-#define sk_CMS_CertificateChoices_new(st) SKM_sk_new(CMS_CertificateChoices, (st))
+#define sk_BY_DIR_ENTRY_new(cmp) SKM_sk_new(BY_DIR_ENTRY, (cmp))
+#define sk_BY_DIR_ENTRY_new_null() SKM_sk_new_null(BY_DIR_ENTRY)
+#define sk_BY_DIR_ENTRY_free(st) SKM_sk_free(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_num(st) SKM_sk_num(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_value(st, i) SKM_sk_value(BY_DIR_ENTRY, (st), (i))
+#define sk_BY_DIR_ENTRY_set(st, i, val) SKM_sk_set(BY_DIR_ENTRY, (st), (i), (val))
+#define sk_BY_DIR_ENTRY_zero(st) SKM_sk_zero(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_push(st, val) SKM_sk_push(BY_DIR_ENTRY, (st), (val))
+#define sk_BY_DIR_ENTRY_unshift(st, val) SKM_sk_unshift(BY_DIR_ENTRY, (st), (val))
+#define sk_BY_DIR_ENTRY_find(st, val) SKM_sk_find(BY_DIR_ENTRY, (st), (val))
+#define sk_BY_DIR_ENTRY_find_ex(st, val) SKM_sk_find_ex(BY_DIR_ENTRY, (st), (val))
+#define sk_BY_DIR_ENTRY_delete(st, i) SKM_sk_delete(BY_DIR_ENTRY, (st), (i))
+#define sk_BY_DIR_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_ENTRY, (st), (ptr))
+#define sk_BY_DIR_ENTRY_insert(st, val, i) SKM_sk_insert(BY_DIR_ENTRY, (st), (val), (i))
+#define sk_BY_DIR_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_ENTRY, (st), (cmp))
+#define sk_BY_DIR_ENTRY_dup(st) SKM_sk_dup(BY_DIR_ENTRY, st)
+#define sk_BY_DIR_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_ENTRY, (st), (free_func))
+#define sk_BY_DIR_ENTRY_shift(st) SKM_sk_shift(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_pop(st) SKM_sk_pop(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_sort(st) SKM_sk_sort(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_is_sorted(st) SKM_sk_is_sorted(BY_DIR_ENTRY, (st))
+
+#define sk_BY_DIR_HASH_new(cmp) SKM_sk_new(BY_DIR_HASH, (cmp))
+#define sk_BY_DIR_HASH_new_null() SKM_sk_new_null(BY_DIR_HASH)
+#define sk_BY_DIR_HASH_free(st) SKM_sk_free(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_num(st) SKM_sk_num(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_value(st, i) SKM_sk_value(BY_DIR_HASH, (st), (i))
+#define sk_BY_DIR_HASH_set(st, i, val) SKM_sk_set(BY_DIR_HASH, (st), (i), (val))
+#define sk_BY_DIR_HASH_zero(st) SKM_sk_zero(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_push(st, val) SKM_sk_push(BY_DIR_HASH, (st), (val))
+#define sk_BY_DIR_HASH_unshift(st, val) SKM_sk_unshift(BY_DIR_HASH, (st), (val))
+#define sk_BY_DIR_HASH_find(st, val) SKM_sk_find(BY_DIR_HASH, (st), (val))
+#define sk_BY_DIR_HASH_find_ex(st, val) SKM_sk_find_ex(BY_DIR_HASH, (st), (val))
+#define sk_BY_DIR_HASH_delete(st, i) SKM_sk_delete(BY_DIR_HASH, (st), (i))
+#define sk_BY_DIR_HASH_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_HASH, (st), (ptr))
+#define sk_BY_DIR_HASH_insert(st, val, i) SKM_sk_insert(BY_DIR_HASH, (st), (val), (i))
+#define sk_BY_DIR_HASH_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_HASH, (st), (cmp))
+#define sk_BY_DIR_HASH_dup(st) SKM_sk_dup(BY_DIR_HASH, st)
+#define sk_BY_DIR_HASH_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_HASH, (st), (free_func))
+#define sk_BY_DIR_HASH_shift(st) SKM_sk_shift(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_pop(st) SKM_sk_pop(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_sort(st) SKM_sk_sort(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_is_sorted(st) SKM_sk_is_sorted(BY_DIR_HASH, (st))
+
+#define sk_CMS_CertificateChoices_new(cmp) SKM_sk_new(CMS_CertificateChoices, (cmp))
 #define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices)
 #define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st))
 #define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st))
@@ -436,7 +490,7 @@
 #define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st))
 #define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st))
 
-#define sk_CMS_RecipientInfo_new(st) SKM_sk_new(CMS_RecipientInfo, (st))
+#define sk_CMS_RecipientInfo_new(cmp) SKM_sk_new(CMS_RecipientInfo, (cmp))
 #define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo)
 #define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st))
 #define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st))
@@ -458,7 +512,7 @@
 #define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st))
 #define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st))
 
-#define sk_CMS_RevocationInfoChoice_new(st) SKM_sk_new(CMS_RevocationInfoChoice, (st))
+#define sk_CMS_RevocationInfoChoice_new(cmp) SKM_sk_new(CMS_RevocationInfoChoice, (cmp))
 #define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice)
 #define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st))
 #define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st))
@@ -480,7 +534,7 @@
 #define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st))
 #define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st))
 
-#define sk_CMS_SignerInfo_new(st) SKM_sk_new(CMS_SignerInfo, (st))
+#define sk_CMS_SignerInfo_new(cmp) SKM_sk_new(CMS_SignerInfo, (cmp))
 #define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo)
 #define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st))
 #define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st))
@@ -502,7 +556,7 @@
 #define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st))
 #define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st))
 
-#define sk_CONF_IMODULE_new(st) SKM_sk_new(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_new(cmp) SKM_sk_new(CONF_IMODULE, (cmp))
 #define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE)
 #define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st))
 #define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st))
@@ -524,7 +578,7 @@
 #define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st))
 #define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st))
 
-#define sk_CONF_MODULE_new(st) SKM_sk_new(CONF_MODULE, (st))
+#define sk_CONF_MODULE_new(cmp) SKM_sk_new(CONF_MODULE, (cmp))
 #define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE)
 #define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st))
 #define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st))
@@ -546,7 +600,7 @@
 #define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st))
 #define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st))
 
-#define sk_CONF_VALUE_new(st) SKM_sk_new(CONF_VALUE, (st))
+#define sk_CONF_VALUE_new(cmp) SKM_sk_new(CONF_VALUE, (cmp))
 #define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE)
 #define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st))
 #define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st))
@@ -568,7 +622,7 @@
 #define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st))
 #define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st))
 
-#define sk_CRYPTO_EX_DATA_FUNCS_new(st) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_new(cmp) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (cmp))
 #define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS)
 #define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st))
 #define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st))
@@ -590,7 +644,7 @@
 #define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st))
 #define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st))
 
-#define sk_CRYPTO_dynlock_new(st) SKM_sk_new(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_new(cmp) SKM_sk_new(CRYPTO_dynlock, (cmp))
 #define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock)
 #define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st))
 #define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st))
@@ -612,7 +666,7 @@
 #define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st))
 #define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st))
 
-#define sk_DIST_POINT_new(st) SKM_sk_new(DIST_POINT, (st))
+#define sk_DIST_POINT_new(cmp) SKM_sk_new(DIST_POINT, (cmp))
 #define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT)
 #define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st))
 #define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st))
@@ -634,7 +688,7 @@
 #define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st))
 #define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st))
 
-#define sk_ENGINE_new(st) SKM_sk_new(ENGINE, (st))
+#define sk_ENGINE_new(cmp) SKM_sk_new(ENGINE, (cmp))
 #define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE)
 #define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st))
 #define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st))
@@ -656,7 +710,7 @@
 #define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st))
 #define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st))
 
-#define sk_ENGINE_CLEANUP_ITEM_new(st) SKM_sk_new(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_new(cmp) SKM_sk_new(ENGINE_CLEANUP_ITEM, (cmp))
 #define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM)
 #define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st))
 #define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st))
@@ -678,7 +732,117 @@
 #define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st))
 #define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st))
 
-#define sk_GENERAL_NAME_new(st) SKM_sk_new(GENERAL_NAME, (st))
+#define sk_ESS_CERT_ID_new(cmp) SKM_sk_new(ESS_CERT_ID, (cmp))
+#define sk_ESS_CERT_ID_new_null() SKM_sk_new_null(ESS_CERT_ID)
+#define sk_ESS_CERT_ID_free(st) SKM_sk_free(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_num(st) SKM_sk_num(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_value(st, i) SKM_sk_value(ESS_CERT_ID, (st), (i))
+#define sk_ESS_CERT_ID_set(st, i, val) SKM_sk_set(ESS_CERT_ID, (st), (i), (val))
+#define sk_ESS_CERT_ID_zero(st) SKM_sk_zero(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_push(st, val) SKM_sk_push(ESS_CERT_ID, (st), (val))
+#define sk_ESS_CERT_ID_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID, (st), (val))
+#define sk_ESS_CERT_ID_find(st, val) SKM_sk_find(ESS_CERT_ID, (st), (val))
+#define sk_ESS_CERT_ID_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID, (st), (val))
+#define sk_ESS_CERT_ID_delete(st, i) SKM_sk_delete(ESS_CERT_ID, (st), (i))
+#define sk_ESS_CERT_ID_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID, (st), (ptr))
+#define sk_ESS_CERT_ID_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID, (st), (val), (i))
+#define sk_ESS_CERT_ID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID, (st), (cmp))
+#define sk_ESS_CERT_ID_dup(st) SKM_sk_dup(ESS_CERT_ID, st)
+#define sk_ESS_CERT_ID_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID, (st), (free_func))
+#define sk_ESS_CERT_ID_shift(st) SKM_sk_shift(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_pop(st) SKM_sk_pop(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_sort(st) SKM_sk_sort(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID, (st))
+
+#define sk_EVP_MD_new(cmp) SKM_sk_new(EVP_MD, (cmp))
+#define sk_EVP_MD_new_null() SKM_sk_new_null(EVP_MD)
+#define sk_EVP_MD_free(st) SKM_sk_free(EVP_MD, (st))
+#define sk_EVP_MD_num(st) SKM_sk_num(EVP_MD, (st))
+#define sk_EVP_MD_value(st, i) SKM_sk_value(EVP_MD, (st), (i))
+#define sk_EVP_MD_set(st, i, val) SKM_sk_set(EVP_MD, (st), (i), (val))
+#define sk_EVP_MD_zero(st) SKM_sk_zero(EVP_MD, (st))
+#define sk_EVP_MD_push(st, val) SKM_sk_push(EVP_MD, (st), (val))
+#define sk_EVP_MD_unshift(st, val) SKM_sk_unshift(EVP_MD, (st), (val))
+#define sk_EVP_MD_find(st, val) SKM_sk_find(EVP_MD, (st), (val))
+#define sk_EVP_MD_find_ex(st, val) SKM_sk_find_ex(EVP_MD, (st), (val))
+#define sk_EVP_MD_delete(st, i) SKM_sk_delete(EVP_MD, (st), (i))
+#define sk_EVP_MD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_MD, (st), (ptr))
+#define sk_EVP_MD_insert(st, val, i) SKM_sk_insert(EVP_MD, (st), (val), (i))
+#define sk_EVP_MD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_MD, (st), (cmp))
+#define sk_EVP_MD_dup(st) SKM_sk_dup(EVP_MD, st)
+#define sk_EVP_MD_pop_free(st, free_func) SKM_sk_pop_free(EVP_MD, (st), (free_func))
+#define sk_EVP_MD_shift(st) SKM_sk_shift(EVP_MD, (st))
+#define sk_EVP_MD_pop(st) SKM_sk_pop(EVP_MD, (st))
+#define sk_EVP_MD_sort(st) SKM_sk_sort(EVP_MD, (st))
+#define sk_EVP_MD_is_sorted(st) SKM_sk_is_sorted(EVP_MD, (st))
+
+#define sk_EVP_PBE_CTL_new(cmp) SKM_sk_new(EVP_PBE_CTL, (cmp))
+#define sk_EVP_PBE_CTL_new_null() SKM_sk_new_null(EVP_PBE_CTL)
+#define sk_EVP_PBE_CTL_free(st) SKM_sk_free(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_num(st) SKM_sk_num(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_value(st, i) SKM_sk_value(EVP_PBE_CTL, (st), (i))
+#define sk_EVP_PBE_CTL_set(st, i, val) SKM_sk_set(EVP_PBE_CTL, (st), (i), (val))
+#define sk_EVP_PBE_CTL_zero(st) SKM_sk_zero(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_push(st, val) SKM_sk_push(EVP_PBE_CTL, (st), (val))
+#define sk_EVP_PBE_CTL_unshift(st, val) SKM_sk_unshift(EVP_PBE_CTL, (st), (val))
+#define sk_EVP_PBE_CTL_find(st, val) SKM_sk_find(EVP_PBE_CTL, (st), (val))
+#define sk_EVP_PBE_CTL_find_ex(st, val) SKM_sk_find_ex(EVP_PBE_CTL, (st), (val))
+#define sk_EVP_PBE_CTL_delete(st, i) SKM_sk_delete(EVP_PBE_CTL, (st), (i))
+#define sk_EVP_PBE_CTL_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PBE_CTL, (st), (ptr))
+#define sk_EVP_PBE_CTL_insert(st, val, i) SKM_sk_insert(EVP_PBE_CTL, (st), (val), (i))
+#define sk_EVP_PBE_CTL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PBE_CTL, (st), (cmp))
+#define sk_EVP_PBE_CTL_dup(st) SKM_sk_dup(EVP_PBE_CTL, st)
+#define sk_EVP_PBE_CTL_pop_free(st, free_func) SKM_sk_pop_free(EVP_PBE_CTL, (st), (free_func))
+#define sk_EVP_PBE_CTL_shift(st) SKM_sk_shift(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_pop(st) SKM_sk_pop(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_sort(st) SKM_sk_sort(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_is_sorted(st) SKM_sk_is_sorted(EVP_PBE_CTL, (st))
+
+#define sk_EVP_PKEY_ASN1_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_ASN1_METHOD, (cmp))
+#define sk_EVP_PKEY_ASN1_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_ASN1_METHOD)
+#define sk_EVP_PKEY_ASN1_METHOD_free(st) SKM_sk_free(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_num(st) SKM_sk_num(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_ASN1_METHOD, (st), (i))
+#define sk_EVP_PKEY_ASN1_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_ASN1_METHOD, (st), (i), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_ASN1_METHOD, (st), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_ASN1_METHOD, (st), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_ASN1_METHOD, (st), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_ASN1_METHOD, (st), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_ASN1_METHOD, (st), (i))
+#define sk_EVP_PKEY_ASN1_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_ASN1_METHOD, (st), (ptr))
+#define sk_EVP_PKEY_ASN1_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_ASN1_METHOD, (st), (val), (i))
+#define sk_EVP_PKEY_ASN1_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_ASN1_METHOD, (st), (cmp))
+#define sk_EVP_PKEY_ASN1_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_ASN1_METHOD, st)
+#define sk_EVP_PKEY_ASN1_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_ASN1_METHOD, (st), (free_func))
+#define sk_EVP_PKEY_ASN1_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_ASN1_METHOD, (st))
+
+#define sk_EVP_PKEY_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_METHOD, (cmp))
+#define sk_EVP_PKEY_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_METHOD)
+#define sk_EVP_PKEY_METHOD_free(st) SKM_sk_free(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_num(st) SKM_sk_num(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_METHOD, (st), (i))
+#define sk_EVP_PKEY_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_METHOD, (st), (i), (val))
+#define sk_EVP_PKEY_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_METHOD, (st), (val))
+#define sk_EVP_PKEY_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_METHOD, (st), (val))
+#define sk_EVP_PKEY_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_METHOD, (st), (val))
+#define sk_EVP_PKEY_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_METHOD, (st), (val))
+#define sk_EVP_PKEY_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_METHOD, (st), (i))
+#define sk_EVP_PKEY_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_METHOD, (st), (ptr))
+#define sk_EVP_PKEY_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_METHOD, (st), (val), (i))
+#define sk_EVP_PKEY_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_METHOD, (st), (cmp))
+#define sk_EVP_PKEY_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_METHOD, st)
+#define sk_EVP_PKEY_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_METHOD, (st), (free_func))
+#define sk_EVP_PKEY_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_METHOD, (st))
+
+#define sk_GENERAL_NAME_new(cmp) SKM_sk_new(GENERAL_NAME, (cmp))
 #define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME)
 #define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st))
 #define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st))
@@ -700,7 +864,7 @@
 #define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st))
 #define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st))
 
-#define sk_GENERAL_NAMES_new(st) SKM_sk_new(GENERAL_NAMES, (st))
+#define sk_GENERAL_NAMES_new(cmp) SKM_sk_new(GENERAL_NAMES, (cmp))
 #define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES)
 #define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st))
 #define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st))
@@ -722,7 +886,7 @@
 #define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st))
 #define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st))
 
-#define sk_GENERAL_SUBTREE_new(st) SKM_sk_new(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_new(cmp) SKM_sk_new(GENERAL_SUBTREE, (cmp))
 #define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE)
 #define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st))
 #define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st))
@@ -744,7 +908,7 @@
 #define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st))
 #define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st))
 
-#define sk_IPAddressFamily_new(st) SKM_sk_new(IPAddressFamily, (st))
+#define sk_IPAddressFamily_new(cmp) SKM_sk_new(IPAddressFamily, (cmp))
 #define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily)
 #define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st))
 #define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st))
@@ -766,7 +930,7 @@
 #define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st))
 #define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st))
 
-#define sk_IPAddressOrRange_new(st) SKM_sk_new(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_new(cmp) SKM_sk_new(IPAddressOrRange, (cmp))
 #define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange)
 #define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st))
 #define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st))
@@ -788,7 +952,7 @@
 #define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st))
 #define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st))
 
-#define sk_KRB5_APREQBODY_new(st) SKM_sk_new(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_new(cmp) SKM_sk_new(KRB5_APREQBODY, (cmp))
 #define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY)
 #define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st))
 #define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st))
@@ -810,7 +974,7 @@
 #define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st))
 #define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st))
 
-#define sk_KRB5_AUTHDATA_new(st) SKM_sk_new(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_new(cmp) SKM_sk_new(KRB5_AUTHDATA, (cmp))
 #define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA)
 #define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st))
 #define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st))
@@ -832,7 +996,7 @@
 #define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st))
 #define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st))
 
-#define sk_KRB5_AUTHENTBODY_new(st) SKM_sk_new(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_new(cmp) SKM_sk_new(KRB5_AUTHENTBODY, (cmp))
 #define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY)
 #define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st))
 #define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st))
@@ -854,7 +1018,7 @@
 #define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st))
 #define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st))
 
-#define sk_KRB5_CHECKSUM_new(st) SKM_sk_new(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_new(cmp) SKM_sk_new(KRB5_CHECKSUM, (cmp))
 #define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM)
 #define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st))
 #define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st))
@@ -876,7 +1040,7 @@
 #define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st))
 #define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st))
 
-#define sk_KRB5_ENCDATA_new(st) SKM_sk_new(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_new(cmp) SKM_sk_new(KRB5_ENCDATA, (cmp))
 #define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA)
 #define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st))
 #define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st))
@@ -898,7 +1062,7 @@
 #define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st))
 #define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st))
 
-#define sk_KRB5_ENCKEY_new(st) SKM_sk_new(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_new(cmp) SKM_sk_new(KRB5_ENCKEY, (cmp))
 #define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY)
 #define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st))
 #define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st))
@@ -920,7 +1084,7 @@
 #define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st))
 #define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st))
 
-#define sk_KRB5_PRINCNAME_new(st) SKM_sk_new(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_new(cmp) SKM_sk_new(KRB5_PRINCNAME, (cmp))
 #define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME)
 #define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st))
 #define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st))
@@ -942,7 +1106,7 @@
 #define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st))
 #define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st))
 
-#define sk_KRB5_TKTBODY_new(st) SKM_sk_new(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_new(cmp) SKM_sk_new(KRB5_TKTBODY, (cmp))
 #define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY)
 #define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st))
 #define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st))
@@ -964,7 +1128,29 @@
 #define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st))
 #define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st))
 
-#define sk_MIME_HEADER_new(st) SKM_sk_new(MIME_HEADER, (st))
+#define sk_MEM_OBJECT_DATA_new(cmp) SKM_sk_new(MEM_OBJECT_DATA, (cmp))
+#define sk_MEM_OBJECT_DATA_new_null() SKM_sk_new_null(MEM_OBJECT_DATA)
+#define sk_MEM_OBJECT_DATA_free(st) SKM_sk_free(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_num(st) SKM_sk_num(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_value(st, i) SKM_sk_value(MEM_OBJECT_DATA, (st), (i))
+#define sk_MEM_OBJECT_DATA_set(st, i, val) SKM_sk_set(MEM_OBJECT_DATA, (st), (i), (val))
+#define sk_MEM_OBJECT_DATA_zero(st) SKM_sk_zero(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_push(st, val) SKM_sk_push(MEM_OBJECT_DATA, (st), (val))
+#define sk_MEM_OBJECT_DATA_unshift(st, val) SKM_sk_unshift(MEM_OBJECT_DATA, (st), (val))
+#define sk_MEM_OBJECT_DATA_find(st, val) SKM_sk_find(MEM_OBJECT_DATA, (st), (val))
+#define sk_MEM_OBJECT_DATA_find_ex(st, val) SKM_sk_find_ex(MEM_OBJECT_DATA, (st), (val))
+#define sk_MEM_OBJECT_DATA_delete(st, i) SKM_sk_delete(MEM_OBJECT_DATA, (st), (i))
+#define sk_MEM_OBJECT_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEM_OBJECT_DATA, (st), (ptr))
+#define sk_MEM_OBJECT_DATA_insert(st, val, i) SKM_sk_insert(MEM_OBJECT_DATA, (st), (val), (i))
+#define sk_MEM_OBJECT_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEM_OBJECT_DATA, (st), (cmp))
+#define sk_MEM_OBJECT_DATA_dup(st) SKM_sk_dup(MEM_OBJECT_DATA, st)
+#define sk_MEM_OBJECT_DATA_pop_free(st, free_func) SKM_sk_pop_free(MEM_OBJECT_DATA, (st), (free_func))
+#define sk_MEM_OBJECT_DATA_shift(st) SKM_sk_shift(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_pop(st) SKM_sk_pop(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_sort(st) SKM_sk_sort(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_is_sorted(st) SKM_sk_is_sorted(MEM_OBJECT_DATA, (st))
+
+#define sk_MIME_HEADER_new(cmp) SKM_sk_new(MIME_HEADER, (cmp))
 #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))
@@ -986,7 +1172,7 @@
 #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(cmp) SKM_sk_new(MIME_PARAM, (cmp))
 #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))
@@ -1008,7 +1194,7 @@
 #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_NAME_FUNCS_new(st) SKM_sk_new(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_new(cmp) SKM_sk_new(NAME_FUNCS, (cmp))
 #define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS)
 #define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st))
 #define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st))
@@ -1030,7 +1216,7 @@
 #define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st))
 #define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st))
 
-#define sk_OCSP_CERTID_new(st) SKM_sk_new(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_new(cmp) SKM_sk_new(OCSP_CERTID, (cmp))
 #define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID)
 #define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st))
 #define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st))
@@ -1052,7 +1238,7 @@
 #define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st))
 #define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st))
 
-#define sk_OCSP_ONEREQ_new(st) SKM_sk_new(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_new(cmp) SKM_sk_new(OCSP_ONEREQ, (cmp))
 #define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ)
 #define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st))
 #define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st))
@@ -1074,7 +1260,7 @@
 #define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st))
 #define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st))
 
-#define sk_OCSP_RESPID_new(st) SKM_sk_new(OCSP_RESPID, (st))
+#define sk_OCSP_RESPID_new(cmp) SKM_sk_new(OCSP_RESPID, (cmp))
 #define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID)
 #define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st))
 #define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st))
@@ -1096,7 +1282,7 @@
 #define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st))
 #define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st))
 
-#define sk_OCSP_SINGLERESP_new(st) SKM_sk_new(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_new(cmp) SKM_sk_new(OCSP_SINGLERESP, (cmp))
 #define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP)
 #define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st))
 #define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st))
@@ -1118,7 +1304,7 @@
 #define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st))
 #define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st))
 
-#define sk_PKCS12_SAFEBAG_new(st) SKM_sk_new(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_new(cmp) SKM_sk_new(PKCS12_SAFEBAG, (cmp))
 #define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG)
 #define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st))
 #define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st))
@@ -1140,7 +1326,7 @@
 #define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st))
 #define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st))
 
-#define sk_PKCS7_new(st) SKM_sk_new(PKCS7, (st))
+#define sk_PKCS7_new(cmp) SKM_sk_new(PKCS7, (cmp))
 #define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7)
 #define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st))
 #define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st))
@@ -1162,7 +1348,7 @@
 #define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st))
 #define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st))
 
-#define sk_PKCS7_RECIP_INFO_new(st) SKM_sk_new(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_new(cmp) SKM_sk_new(PKCS7_RECIP_INFO, (cmp))
 #define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO)
 #define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st))
 #define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st))
@@ -1184,7 +1370,7 @@
 #define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st))
 #define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st))
 
-#define sk_PKCS7_SIGNER_INFO_new(st) SKM_sk_new(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_new(cmp) SKM_sk_new(PKCS7_SIGNER_INFO, (cmp))
 #define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO)
 #define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st))
 #define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st))
@@ -1206,7 +1392,7 @@
 #define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st))
 #define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st))
 
-#define sk_POLICYINFO_new(st) SKM_sk_new(POLICYINFO, (st))
+#define sk_POLICYINFO_new(cmp) SKM_sk_new(POLICYINFO, (cmp))
 #define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO)
 #define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st))
 #define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st))
@@ -1228,7 +1414,7 @@
 #define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st))
 #define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st))
 
-#define sk_POLICYQUALINFO_new(st) SKM_sk_new(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_new(cmp) SKM_sk_new(POLICYQUALINFO, (cmp))
 #define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO)
 #define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st))
 #define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st))
@@ -1250,7 +1436,7 @@
 #define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st))
 #define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st))
 
-#define sk_POLICY_MAPPING_new(st) SKM_sk_new(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_new(cmp) SKM_sk_new(POLICY_MAPPING, (cmp))
 #define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING)
 #define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st))
 #define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st))
@@ -1272,7 +1458,7 @@
 #define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st))
 #define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st))
 
-#define sk_SSL_CIPHER_new(st) SKM_sk_new(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp))
 #define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER)
 #define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st))
 #define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st))
@@ -1294,7 +1480,7 @@
 #define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st))
 #define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st))
 
-#define sk_SSL_COMP_new(st) SKM_sk_new(SSL_COMP, (st))
+#define sk_SSL_COMP_new(cmp) SKM_sk_new(SSL_COMP, (cmp))
 #define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP)
 #define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st))
 #define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st))
@@ -1316,7 +1502,51 @@
 #define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st))
 #define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st))
 
-#define sk_STORE_OBJECT_new(st) SKM_sk_new(STORE_OBJECT, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_new(cmp) SKM_sk_new(STACK_OF_X509_NAME_ENTRY, (cmp))
+#define sk_STACK_OF_X509_NAME_ENTRY_new_null() SKM_sk_new_null(STACK_OF_X509_NAME_ENTRY)
+#define sk_STACK_OF_X509_NAME_ENTRY_free(st) SKM_sk_free(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_num(st) SKM_sk_num(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_value(st, i) SKM_sk_value(STACK_OF_X509_NAME_ENTRY, (st), (i))
+#define sk_STACK_OF_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(STACK_OF_X509_NAME_ENTRY, (st), (i), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_zero(st) SKM_sk_zero(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_push(st, val) SKM_sk_push(STACK_OF_X509_NAME_ENTRY, (st), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(STACK_OF_X509_NAME_ENTRY, (st), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_find(st, val) SKM_sk_find(STACK_OF_X509_NAME_ENTRY, (st), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(STACK_OF_X509_NAME_ENTRY, (st), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(STACK_OF_X509_NAME_ENTRY, (st), (i))
+#define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(STACK_OF_X509_NAME_ENTRY, (st), (ptr))
+#define sk_STACK_OF_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(STACK_OF_X509_NAME_ENTRY, (st), (val), (i))
+#define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STACK_OF_X509_NAME_ENTRY, (st), (cmp))
+#define sk_STACK_OF_X509_NAME_ENTRY_dup(st) SKM_sk_dup(STACK_OF_X509_NAME_ENTRY, st)
+#define sk_STACK_OF_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(STACK_OF_X509_NAME_ENTRY, (st), (free_func))
+#define sk_STACK_OF_X509_NAME_ENTRY_shift(st) SKM_sk_shift(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_pop(st) SKM_sk_pop(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_sort(st) SKM_sk_sort(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(STACK_OF_X509_NAME_ENTRY, (st))
+
+#define sk_STORE_ATTR_INFO_new(cmp) SKM_sk_new(STORE_ATTR_INFO, (cmp))
+#define sk_STORE_ATTR_INFO_new_null() SKM_sk_new_null(STORE_ATTR_INFO)
+#define sk_STORE_ATTR_INFO_free(st) SKM_sk_free(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_num(st) SKM_sk_num(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_value(st, i) SKM_sk_value(STORE_ATTR_INFO, (st), (i))
+#define sk_STORE_ATTR_INFO_set(st, i, val) SKM_sk_set(STORE_ATTR_INFO, (st), (i), (val))
+#define sk_STORE_ATTR_INFO_zero(st) SKM_sk_zero(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_push(st, val) SKM_sk_push(STORE_ATTR_INFO, (st), (val))
+#define sk_STORE_ATTR_INFO_unshift(st, val) SKM_sk_unshift(STORE_ATTR_INFO, (st), (val))
+#define sk_STORE_ATTR_INFO_find(st, val) SKM_sk_find(STORE_ATTR_INFO, (st), (val))
+#define sk_STORE_ATTR_INFO_find_ex(st, val) SKM_sk_find_ex(STORE_ATTR_INFO, (st), (val))
+#define sk_STORE_ATTR_INFO_delete(st, i) SKM_sk_delete(STORE_ATTR_INFO, (st), (i))
+#define sk_STORE_ATTR_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_ATTR_INFO, (st), (ptr))
+#define sk_STORE_ATTR_INFO_insert(st, val, i) SKM_sk_insert(STORE_ATTR_INFO, (st), (val), (i))
+#define sk_STORE_ATTR_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_ATTR_INFO, (st), (cmp))
+#define sk_STORE_ATTR_INFO_dup(st) SKM_sk_dup(STORE_ATTR_INFO, st)
+#define sk_STORE_ATTR_INFO_pop_free(st, free_func) SKM_sk_pop_free(STORE_ATTR_INFO, (st), (free_func))
+#define sk_STORE_ATTR_INFO_shift(st) SKM_sk_shift(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_pop(st) SKM_sk_pop(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_sort(st) SKM_sk_sort(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_is_sorted(st) SKM_sk_is_sorted(STORE_ATTR_INFO, (st))
+
+#define sk_STORE_OBJECT_new(cmp) SKM_sk_new(STORE_OBJECT, (cmp))
 #define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT)
 #define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st))
 #define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st))
@@ -1338,7 +1568,7 @@
 #define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st))
 #define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st))
 
-#define sk_SXNETID_new(st) SKM_sk_new(SXNETID, (st))
+#define sk_SXNETID_new(cmp) SKM_sk_new(SXNETID, (cmp))
 #define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID)
 #define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st))
 #define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st))
@@ -1360,7 +1590,7 @@
 #define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st))
 #define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st))
 
-#define sk_UI_STRING_new(st) SKM_sk_new(UI_STRING, (st))
+#define sk_UI_STRING_new(cmp) SKM_sk_new(UI_STRING, (cmp))
 #define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING)
 #define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st))
 #define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st))
@@ -1382,7 +1612,7 @@
 #define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st))
 #define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st))
 
-#define sk_X509_new(st) SKM_sk_new(X509, (st))
+#define sk_X509_new(cmp) SKM_sk_new(X509, (cmp))
 #define sk_X509_new_null() SKM_sk_new_null(X509)
 #define sk_X509_free(st) SKM_sk_free(X509, (st))
 #define sk_X509_num(st) SKM_sk_num(X509, (st))
@@ -1404,7 +1634,7 @@
 #define sk_X509_sort(st) SKM_sk_sort(X509, (st))
 #define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st))
 
-#define sk_X509V3_EXT_METHOD_new(st) SKM_sk_new(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_new(cmp) SKM_sk_new(X509V3_EXT_METHOD, (cmp))
 #define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD)
 #define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st))
 #define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st))
@@ -1426,7 +1656,7 @@
 #define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st))
 #define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st))
 
-#define sk_X509_ALGOR_new(st) SKM_sk_new(X509_ALGOR, (st))
+#define sk_X509_ALGOR_new(cmp) SKM_sk_new(X509_ALGOR, (cmp))
 #define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR)
 #define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st))
 #define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st))
@@ -1448,7 +1678,7 @@
 #define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st))
 #define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st))
 
-#define sk_X509_ATTRIBUTE_new(st) SKM_sk_new(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_new(cmp) SKM_sk_new(X509_ATTRIBUTE, (cmp))
 #define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE)
 #define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st))
 #define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st))
@@ -1470,7 +1700,7 @@
 #define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st))
 #define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st))
 
-#define sk_X509_CRL_new(st) SKM_sk_new(X509_CRL, (st))
+#define sk_X509_CRL_new(cmp) SKM_sk_new(X509_CRL, (cmp))
 #define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL)
 #define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st))
 #define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st))
@@ -1492,7 +1722,7 @@
 #define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st))
 #define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st))
 
-#define sk_X509_EXTENSION_new(st) SKM_sk_new(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_new(cmp) SKM_sk_new(X509_EXTENSION, (cmp))
 #define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION)
 #define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st))
 #define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st))
@@ -1514,7 +1744,7 @@
 #define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st))
 #define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st))
 
-#define sk_X509_INFO_new(st) SKM_sk_new(X509_INFO, (st))
+#define sk_X509_INFO_new(cmp) SKM_sk_new(X509_INFO, (cmp))
 #define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO)
 #define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st))
 #define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st))
@@ -1536,7 +1766,7 @@
 #define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st))
 #define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st))
 
-#define sk_X509_LOOKUP_new(st) SKM_sk_new(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_new(cmp) SKM_sk_new(X509_LOOKUP, (cmp))
 #define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP)
 #define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st))
 #define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st))
@@ -1558,7 +1788,7 @@
 #define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st))
 #define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st))
 
-#define sk_X509_NAME_new(st) SKM_sk_new(X509_NAME, (st))
+#define sk_X509_NAME_new(cmp) SKM_sk_new(X509_NAME, (cmp))
 #define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME)
 #define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st))
 #define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st))
@@ -1580,7 +1810,7 @@
 #define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st))
 #define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st))
 
-#define sk_X509_NAME_ENTRY_new(st) SKM_sk_new(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_new(cmp) SKM_sk_new(X509_NAME_ENTRY, (cmp))
 #define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY)
 #define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st))
 #define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st))
@@ -1602,7 +1832,7 @@
 #define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st))
 #define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st))
 
-#define sk_X509_OBJECT_new(st) SKM_sk_new(X509_OBJECT, (st))
+#define sk_X509_OBJECT_new(cmp) SKM_sk_new(X509_OBJECT, (cmp))
 #define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT)
 #define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st))
 #define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st))
@@ -1624,7 +1854,7 @@
 #define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st))
 #define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st))
 
-#define sk_X509_POLICY_DATA_new(st) SKM_sk_new(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_new(cmp) SKM_sk_new(X509_POLICY_DATA, (cmp))
 #define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA)
 #define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st))
 #define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st))
@@ -1646,7 +1876,7 @@
 #define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st))
 #define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st))
 
-#define sk_X509_POLICY_NODE_new(st) SKM_sk_new(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp))
 #define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE)
 #define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st))
 #define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st))
@@ -1668,29 +1898,7 @@
 #define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st))
 #define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st))
 
-#define sk_X509_POLICY_REF_new(st) SKM_sk_new(X509_POLICY_REF, (st))
-#define sk_X509_POLICY_REF_new_null() SKM_sk_new_null(X509_POLICY_REF)
-#define sk_X509_POLICY_REF_free(st) SKM_sk_free(X509_POLICY_REF, (st))
-#define sk_X509_POLICY_REF_num(st) SKM_sk_num(X509_POLICY_REF, (st))
-#define sk_X509_POLICY_REF_value(st, i) SKM_sk_value(X509_POLICY_REF, (st), (i))
-#define sk_X509_POLICY_REF_set(st, i, val) SKM_sk_set(X509_POLICY_REF, (st), (i), (val))
-#define sk_X509_POLICY_REF_zero(st) SKM_sk_zero(X509_POLICY_REF, (st))
-#define sk_X509_POLICY_REF_push(st, val) SKM_sk_push(X509_POLICY_REF, (st), (val))
-#define sk_X509_POLICY_REF_unshift(st, val) SKM_sk_unshift(X509_POLICY_REF, (st), (val))
-#define sk_X509_POLICY_REF_find(st, val) SKM_sk_find(X509_POLICY_REF, (st), (val))
-#define sk_X509_POLICY_REF_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_REF, (st), (val))
-#define sk_X509_POLICY_REF_delete(st, i) SKM_sk_delete(X509_POLICY_REF, (st), (i))
-#define sk_X509_POLICY_REF_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_REF, (st), (ptr))
-#define sk_X509_POLICY_REF_insert(st, val, i) SKM_sk_insert(X509_POLICY_REF, (st), (val), (i))
-#define sk_X509_POLICY_REF_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_REF, (st), (cmp))
-#define sk_X509_POLICY_REF_dup(st) SKM_sk_dup(X509_POLICY_REF, st)
-#define sk_X509_POLICY_REF_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_REF, (st), (free_func))
-#define sk_X509_POLICY_REF_shift(st) SKM_sk_shift(X509_POLICY_REF, (st))
-#define sk_X509_POLICY_REF_pop(st) SKM_sk_pop(X509_POLICY_REF, (st))
-#define sk_X509_POLICY_REF_sort(st) SKM_sk_sort(X509_POLICY_REF, (st))
-#define sk_X509_POLICY_REF_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_REF, (st))
-
-#define sk_X509_PURPOSE_new(st) SKM_sk_new(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_new(cmp) SKM_sk_new(X509_PURPOSE, (cmp))
 #define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE)
 #define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st))
 #define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st))
@@ -1712,7 +1920,7 @@
 #define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st))
 #define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st))
 
-#define sk_X509_REVOKED_new(st) SKM_sk_new(X509_REVOKED, (st))
+#define sk_X509_REVOKED_new(cmp) SKM_sk_new(X509_REVOKED, (cmp))
 #define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED)
 #define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st))
 #define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st))
@@ -1734,7 +1942,7 @@
 #define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st))
 #define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st))
 
-#define sk_X509_TRUST_new(st) SKM_sk_new(X509_TRUST, (st))
+#define sk_X509_TRUST_new(cmp) SKM_sk_new(X509_TRUST, (cmp))
 #define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST)
 #define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st))
 #define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st))
@@ -1756,7 +1964,7 @@
 #define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st))
 #define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st))
 
-#define sk_X509_VERIFY_PARAM_new(st) SKM_sk_new(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_new(cmp) SKM_sk_new(X509_VERIFY_PARAM, (cmp))
 #define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM)
 #define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st))
 #define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st))
@@ -1778,6 +1986,125 @@
 #define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st))
 #define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st))
 
+#define sk_nid_triple_new(cmp) SKM_sk_new(nid_triple, (cmp))
+#define sk_nid_triple_new_null() SKM_sk_new_null(nid_triple)
+#define sk_nid_triple_free(st) SKM_sk_free(nid_triple, (st))
+#define sk_nid_triple_num(st) SKM_sk_num(nid_triple, (st))
+#define sk_nid_triple_value(st, i) SKM_sk_value(nid_triple, (st), (i))
+#define sk_nid_triple_set(st, i, val) SKM_sk_set(nid_triple, (st), (i), (val))
+#define sk_nid_triple_zero(st) SKM_sk_zero(nid_triple, (st))
+#define sk_nid_triple_push(st, val) SKM_sk_push(nid_triple, (st), (val))
+#define sk_nid_triple_unshift(st, val) SKM_sk_unshift(nid_triple, (st), (val))
+#define sk_nid_triple_find(st, val) SKM_sk_find(nid_triple, (st), (val))
+#define sk_nid_triple_find_ex(st, val) SKM_sk_find_ex(nid_triple, (st), (val))
+#define sk_nid_triple_delete(st, i) SKM_sk_delete(nid_triple, (st), (i))
+#define sk_nid_triple_delete_ptr(st, ptr) SKM_sk_delete_ptr(nid_triple, (st), (ptr))
+#define sk_nid_triple_insert(st, val, i) SKM_sk_insert(nid_triple, (st), (val), (i))
+#define sk_nid_triple_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(nid_triple, (st), (cmp))
+#define sk_nid_triple_dup(st) SKM_sk_dup(nid_triple, st)
+#define sk_nid_triple_pop_free(st, free_func) SKM_sk_pop_free(nid_triple, (st), (free_func))
+#define sk_nid_triple_shift(st) SKM_sk_shift(nid_triple, (st))
+#define sk_nid_triple_pop(st) SKM_sk_pop(nid_triple, (st))
+#define sk_nid_triple_sort(st) SKM_sk_sort(nid_triple, (st))
+#define sk_nid_triple_is_sorted(st) SKM_sk_is_sorted(nid_triple, (st))
+
+#define sk_void_new(cmp) SKM_sk_new(void, (cmp))
+#define sk_void_new_null() SKM_sk_new_null(void)
+#define sk_void_free(st) SKM_sk_free(void, (st))
+#define sk_void_num(st) SKM_sk_num(void, (st))
+#define sk_void_value(st, i) SKM_sk_value(void, (st), (i))
+#define sk_void_set(st, i, val) SKM_sk_set(void, (st), (i), (val))
+#define sk_void_zero(st) SKM_sk_zero(void, (st))
+#define sk_void_push(st, val) SKM_sk_push(void, (st), (val))
+#define sk_void_unshift(st, val) SKM_sk_unshift(void, (st), (val))
+#define sk_void_find(st, val) SKM_sk_find(void, (st), (val))
+#define sk_void_find_ex(st, val) SKM_sk_find_ex(void, (st), (val))
+#define sk_void_delete(st, i) SKM_sk_delete(void, (st), (i))
+#define sk_void_delete_ptr(st, ptr) SKM_sk_delete_ptr(void, (st), (ptr))
+#define sk_void_insert(st, val, i) SKM_sk_insert(void, (st), (val), (i))
+#define sk_void_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(void, (st), (cmp))
+#define sk_void_dup(st) SKM_sk_dup(void, st)
+#define sk_void_pop_free(st, free_func) SKM_sk_pop_free(void, (st), (free_func))
+#define sk_void_shift(st) SKM_sk_shift(void, (st))
+#define sk_void_pop(st) SKM_sk_pop(void, (st))
+#define sk_void_sort(st) SKM_sk_sort(void, (st))
+#define sk_void_is_sorted(st) SKM_sk_is_sorted(void, (st))
+
+#define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_SK_CMP_FUNC(void, cmp)))
+#define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null())
+#define sk_OPENSSL_BLOCK_push(st, val) sk_push(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_find(st, val) sk_find(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_value(st, i) ((OPENSSL_BLOCK)sk_value(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), i))
+#define sk_OPENSSL_BLOCK_num(st) SKM_sk_num(OPENSSL_BLOCK, st)
+#define sk_OPENSSL_BLOCK_pop_free(st, free_func) sk_pop_free(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_SK_FREE_FUNC2(OPENSSL_BLOCK, free_func))
+#define sk_OPENSSL_BLOCK_insert(st, val, i) sk_insert(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, val), i)
+#define sk_OPENSSL_BLOCK_free(st) SKM_sk_free(OPENSSL_BLOCK, st)
+#define sk_OPENSSL_BLOCK_set(st, i, val) sk_set((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), i, CHECKED_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_zero(st) SKM_sk_zero(OPENSSL_BLOCK, (st))
+#define sk_OPENSSL_BLOCK_unshift(st, val) sk_unshift((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_CONST_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_delete(st, i) SKM_sk_delete(OPENSSL_BLOCK, (st), (i))
+#define sk_OPENSSL_BLOCK_delete_ptr(st, ptr) (OPENSSL_BLOCK *)sk_delete_ptr((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, ptr))
+#define sk_OPENSSL_BLOCK_set_cmp_func(st, cmp)  \
+	((int (*)(const void * const *,const void * const *)) \
+	sk_set_cmp_func((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_SK_CMP_FUNC(void, cmp)))
+#define sk_OPENSSL_BLOCK_dup(st) SKM_sk_dup(OPENSSL_BLOCK, st)
+#define sk_OPENSSL_BLOCK_shift(st) SKM_sk_shift(OPENSSL_BLOCK, (st))
+#define sk_OPENSSL_BLOCK_pop(st) (void *)sk_pop((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st))
+#define sk_OPENSSL_BLOCK_sort(st) SKM_sk_sort(OPENSSL_BLOCK, (st))
+#define sk_OPENSSL_BLOCK_is_sorted(st) SKM_sk_is_sorted(OPENSSL_BLOCK, (st))
+
+
+#define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
+#define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null())
+#define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), i))
+#define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st)
+#define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_SK_FREE_FUNC2(OPENSSL_PSTRING, free_func))
+#define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, val), i)
+#define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st)
+#define sk_OPENSSL_PSTRING_set(st, i, val) sk_set((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), i, CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st))
+#define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i))
+#define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, ptr))
+#define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp)  \
+	((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \
+	sk_set_cmp_func((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
+#define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st)
+#define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st))
+#define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st))
+#define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st))
+#define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st))
+
+
+#define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)sk_new(CHECKED_SK_CMP_FUNC(char, cmp)))
+#define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)sk_new_null())
+#define sk_OPENSSL_STRING_push(st, val) sk_push(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), i))
+#define sk_OPENSSL_STRING_num(st) SKM_sk_num(OPENSSL_STRING, st)
+#define sk_OPENSSL_STRING_pop_free(st, free_func) sk_pop_free(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_SK_FREE_FUNC2(OPENSSL_STRING, free_func))
+#define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, val), i)
+#define sk_OPENSSL_STRING_free(st) SKM_sk_free(OPENSSL_STRING, st)
+#define sk_OPENSSL_STRING_set(st, i, val) sk_set((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), i, CHECKED_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_zero(st) SKM_sk_zero(OPENSSL_STRING, (st))
+#define sk_OPENSSL_STRING_unshift(st, val) sk_unshift((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_CONST_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_delete(st, i) SKM_sk_delete(OPENSSL_STRING, (st), (i))
+#define sk_OPENSSL_STRING_delete_ptr(st, ptr) (OPENSSL_STRING *)sk_delete_ptr((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, ptr))
+#define sk_OPENSSL_STRING_set_cmp_func(st, cmp)  \
+	((int (*)(const char * const *,const char * const *)) \
+	sk_set_cmp_func((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_SK_CMP_FUNC(char, cmp)))
+#define sk_OPENSSL_STRING_dup(st) SKM_sk_dup(OPENSSL_STRING, st)
+#define sk_OPENSSL_STRING_shift(st) SKM_sk_shift(OPENSSL_STRING, (st))
+#define sk_OPENSSL_STRING_pop(st) (char *)sk_pop((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st))
+#define sk_OPENSSL_STRING_sort(st) SKM_sk_sort(OPENSSL_STRING, (st))
+#define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st))
+
+
 #define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
 	SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
 #define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
@@ -1814,6 +2141,15 @@
 #define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \
 	SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func))
 
+#define d2i_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(ASN1_UTF8STRING, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(ASN1_UTF8STRING, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ASN1_UTF8STRING(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(ASN1_UTF8STRING, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ASN1_UTF8STRING(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(ASN1_UTF8STRING, (buf), (len), (d2i_func), (free_func))
+
 #define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
 	SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
 #define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
@@ -1823,6 +2159,24 @@
 #define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \
 	SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func))
 
+#define d2i_ASN1_SET_OF_ESS_CERT_ID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(ESS_CERT_ID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_ESS_CERT_ID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(ESS_CERT_ID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ESS_CERT_ID(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(ESS_CERT_ID, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ESS_CERT_ID(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(ESS_CERT_ID, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_EVP_MD(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(EVP_MD, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_EVP_MD(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(EVP_MD, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_EVP_MD(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(EVP_MD, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_EVP_MD(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(EVP_MD, (buf), (len), (d2i_func), (free_func))
+
 #define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
 	SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
 #define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \
@@ -1981,6 +2335,240 @@
 
 #define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \
 	SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
+
+#define lh_ADDED_OBJ_new() LHM_lh_new(ADDED_OBJ,added_obj)
+#define lh_ADDED_OBJ_insert(lh,inst) LHM_lh_insert(ADDED_OBJ,lh,inst)
+#define lh_ADDED_OBJ_retrieve(lh,inst) LHM_lh_retrieve(ADDED_OBJ,lh,inst)
+#define lh_ADDED_OBJ_delete(lh,inst) LHM_lh_delete(ADDED_OBJ,lh,inst)
+#define lh_ADDED_OBJ_doall(lh,fn) LHM_lh_doall(ADDED_OBJ,lh,fn)
+#define lh_ADDED_OBJ_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(ADDED_OBJ,lh,fn,arg_type,arg)
+#define lh_ADDED_OBJ_error(lh) LHM_lh_error(ADDED_OBJ,lh)
+#define lh_ADDED_OBJ_num_items(lh) LHM_lh_num_items(ADDED_OBJ,lh)
+#define lh_ADDED_OBJ_down_load(lh) LHM_lh_down_load(ADDED_OBJ,lh)
+#define lh_ADDED_OBJ_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(ADDED_OBJ,lh,out)
+#define lh_ADDED_OBJ_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(ADDED_OBJ,lh,out)
+#define lh_ADDED_OBJ_stats_bio(lh,out) \
+  LHM_lh_stats_bio(ADDED_OBJ,lh,out)
+#define lh_ADDED_OBJ_free(lh) LHM_lh_free(ADDED_OBJ,lh)
+
+#define lh_APP_INFO_new() LHM_lh_new(APP_INFO,app_info)
+#define lh_APP_INFO_insert(lh,inst) LHM_lh_insert(APP_INFO,lh,inst)
+#define lh_APP_INFO_retrieve(lh,inst) LHM_lh_retrieve(APP_INFO,lh,inst)
+#define lh_APP_INFO_delete(lh,inst) LHM_lh_delete(APP_INFO,lh,inst)
+#define lh_APP_INFO_doall(lh,fn) LHM_lh_doall(APP_INFO,lh,fn)
+#define lh_APP_INFO_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(APP_INFO,lh,fn,arg_type,arg)
+#define lh_APP_INFO_error(lh) LHM_lh_error(APP_INFO,lh)
+#define lh_APP_INFO_num_items(lh) LHM_lh_num_items(APP_INFO,lh)
+#define lh_APP_INFO_down_load(lh) LHM_lh_down_load(APP_INFO,lh)
+#define lh_APP_INFO_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(APP_INFO,lh,out)
+#define lh_APP_INFO_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(APP_INFO,lh,out)
+#define lh_APP_INFO_stats_bio(lh,out) \
+  LHM_lh_stats_bio(APP_INFO,lh,out)
+#define lh_APP_INFO_free(lh) LHM_lh_free(APP_INFO,lh)
+
+#define lh_CONF_VALUE_new() LHM_lh_new(CONF_VALUE,conf_value)
+#define lh_CONF_VALUE_insert(lh,inst) LHM_lh_insert(CONF_VALUE,lh,inst)
+#define lh_CONF_VALUE_retrieve(lh,inst) LHM_lh_retrieve(CONF_VALUE,lh,inst)
+#define lh_CONF_VALUE_delete(lh,inst) LHM_lh_delete(CONF_VALUE,lh,inst)
+#define lh_CONF_VALUE_doall(lh,fn) LHM_lh_doall(CONF_VALUE,lh,fn)
+#define lh_CONF_VALUE_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(CONF_VALUE,lh,fn,arg_type,arg)
+#define lh_CONF_VALUE_error(lh) LHM_lh_error(CONF_VALUE,lh)
+#define lh_CONF_VALUE_num_items(lh) LHM_lh_num_items(CONF_VALUE,lh)
+#define lh_CONF_VALUE_down_load(lh) LHM_lh_down_load(CONF_VALUE,lh)
+#define lh_CONF_VALUE_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(CONF_VALUE,lh,out)
+#define lh_CONF_VALUE_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(CONF_VALUE,lh,out)
+#define lh_CONF_VALUE_stats_bio(lh,out) \
+  LHM_lh_stats_bio(CONF_VALUE,lh,out)
+#define lh_CONF_VALUE_free(lh) LHM_lh_free(CONF_VALUE,lh)
+
+#define lh_ENGINE_PILE_new() LHM_lh_new(ENGINE_PILE,engine_pile)
+#define lh_ENGINE_PILE_insert(lh,inst) LHM_lh_insert(ENGINE_PILE,lh,inst)
+#define lh_ENGINE_PILE_retrieve(lh,inst) LHM_lh_retrieve(ENGINE_PILE,lh,inst)
+#define lh_ENGINE_PILE_delete(lh,inst) LHM_lh_delete(ENGINE_PILE,lh,inst)
+#define lh_ENGINE_PILE_doall(lh,fn) LHM_lh_doall(ENGINE_PILE,lh,fn)
+#define lh_ENGINE_PILE_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(ENGINE_PILE,lh,fn,arg_type,arg)
+#define lh_ENGINE_PILE_error(lh) LHM_lh_error(ENGINE_PILE,lh)
+#define lh_ENGINE_PILE_num_items(lh) LHM_lh_num_items(ENGINE_PILE,lh)
+#define lh_ENGINE_PILE_down_load(lh) LHM_lh_down_load(ENGINE_PILE,lh)
+#define lh_ENGINE_PILE_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(ENGINE_PILE,lh,out)
+#define lh_ENGINE_PILE_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(ENGINE_PILE,lh,out)
+#define lh_ENGINE_PILE_stats_bio(lh,out) \
+  LHM_lh_stats_bio(ENGINE_PILE,lh,out)
+#define lh_ENGINE_PILE_free(lh) LHM_lh_free(ENGINE_PILE,lh)
+
+#define lh_ERR_STATE_new() LHM_lh_new(ERR_STATE,err_state)
+#define lh_ERR_STATE_insert(lh,inst) LHM_lh_insert(ERR_STATE,lh,inst)
+#define lh_ERR_STATE_retrieve(lh,inst) LHM_lh_retrieve(ERR_STATE,lh,inst)
+#define lh_ERR_STATE_delete(lh,inst) LHM_lh_delete(ERR_STATE,lh,inst)
+#define lh_ERR_STATE_doall(lh,fn) LHM_lh_doall(ERR_STATE,lh,fn)
+#define lh_ERR_STATE_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(ERR_STATE,lh,fn,arg_type,arg)
+#define lh_ERR_STATE_error(lh) LHM_lh_error(ERR_STATE,lh)
+#define lh_ERR_STATE_num_items(lh) LHM_lh_num_items(ERR_STATE,lh)
+#define lh_ERR_STATE_down_load(lh) LHM_lh_down_load(ERR_STATE,lh)
+#define lh_ERR_STATE_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(ERR_STATE,lh,out)
+#define lh_ERR_STATE_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(ERR_STATE,lh,out)
+#define lh_ERR_STATE_stats_bio(lh,out) \
+  LHM_lh_stats_bio(ERR_STATE,lh,out)
+#define lh_ERR_STATE_free(lh) LHM_lh_free(ERR_STATE,lh)
+
+#define lh_ERR_STRING_DATA_new() LHM_lh_new(ERR_STRING_DATA,err_string_data)
+#define lh_ERR_STRING_DATA_insert(lh,inst) LHM_lh_insert(ERR_STRING_DATA,lh,inst)
+#define lh_ERR_STRING_DATA_retrieve(lh,inst) LHM_lh_retrieve(ERR_STRING_DATA,lh,inst)
+#define lh_ERR_STRING_DATA_delete(lh,inst) LHM_lh_delete(ERR_STRING_DATA,lh,inst)
+#define lh_ERR_STRING_DATA_doall(lh,fn) LHM_lh_doall(ERR_STRING_DATA,lh,fn)
+#define lh_ERR_STRING_DATA_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(ERR_STRING_DATA,lh,fn,arg_type,arg)
+#define lh_ERR_STRING_DATA_error(lh) LHM_lh_error(ERR_STRING_DATA,lh)
+#define lh_ERR_STRING_DATA_num_items(lh) LHM_lh_num_items(ERR_STRING_DATA,lh)
+#define lh_ERR_STRING_DATA_down_load(lh) LHM_lh_down_load(ERR_STRING_DATA,lh)
+#define lh_ERR_STRING_DATA_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(ERR_STRING_DATA,lh,out)
+#define lh_ERR_STRING_DATA_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(ERR_STRING_DATA,lh,out)
+#define lh_ERR_STRING_DATA_stats_bio(lh,out) \
+  LHM_lh_stats_bio(ERR_STRING_DATA,lh,out)
+#define lh_ERR_STRING_DATA_free(lh) LHM_lh_free(ERR_STRING_DATA,lh)
+
+#define lh_EX_CLASS_ITEM_new() LHM_lh_new(EX_CLASS_ITEM,ex_class_item)
+#define lh_EX_CLASS_ITEM_insert(lh,inst) LHM_lh_insert(EX_CLASS_ITEM,lh,inst)
+#define lh_EX_CLASS_ITEM_retrieve(lh,inst) LHM_lh_retrieve(EX_CLASS_ITEM,lh,inst)
+#define lh_EX_CLASS_ITEM_delete(lh,inst) LHM_lh_delete(EX_CLASS_ITEM,lh,inst)
+#define lh_EX_CLASS_ITEM_doall(lh,fn) LHM_lh_doall(EX_CLASS_ITEM,lh,fn)
+#define lh_EX_CLASS_ITEM_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(EX_CLASS_ITEM,lh,fn,arg_type,arg)
+#define lh_EX_CLASS_ITEM_error(lh) LHM_lh_error(EX_CLASS_ITEM,lh)
+#define lh_EX_CLASS_ITEM_num_items(lh) LHM_lh_num_items(EX_CLASS_ITEM,lh)
+#define lh_EX_CLASS_ITEM_down_load(lh) LHM_lh_down_load(EX_CLASS_ITEM,lh)
+#define lh_EX_CLASS_ITEM_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(EX_CLASS_ITEM,lh,out)
+#define lh_EX_CLASS_ITEM_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(EX_CLASS_ITEM,lh,out)
+#define lh_EX_CLASS_ITEM_stats_bio(lh,out) \
+  LHM_lh_stats_bio(EX_CLASS_ITEM,lh,out)
+#define lh_EX_CLASS_ITEM_free(lh) LHM_lh_free(EX_CLASS_ITEM,lh)
+
+#define lh_FUNCTION_new() LHM_lh_new(FUNCTION,function)
+#define lh_FUNCTION_insert(lh,inst) LHM_lh_insert(FUNCTION,lh,inst)
+#define lh_FUNCTION_retrieve(lh,inst) LHM_lh_retrieve(FUNCTION,lh,inst)
+#define lh_FUNCTION_delete(lh,inst) LHM_lh_delete(FUNCTION,lh,inst)
+#define lh_FUNCTION_doall(lh,fn) LHM_lh_doall(FUNCTION,lh,fn)
+#define lh_FUNCTION_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(FUNCTION,lh,fn,arg_type,arg)
+#define lh_FUNCTION_error(lh) LHM_lh_error(FUNCTION,lh)
+#define lh_FUNCTION_num_items(lh) LHM_lh_num_items(FUNCTION,lh)
+#define lh_FUNCTION_down_load(lh) LHM_lh_down_load(FUNCTION,lh)
+#define lh_FUNCTION_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(FUNCTION,lh,out)
+#define lh_FUNCTION_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(FUNCTION,lh,out)
+#define lh_FUNCTION_stats_bio(lh,out) \
+  LHM_lh_stats_bio(FUNCTION,lh,out)
+#define lh_FUNCTION_free(lh) LHM_lh_free(FUNCTION,lh)
+
+#define lh_MEM_new() LHM_lh_new(MEM,mem)
+#define lh_MEM_insert(lh,inst) LHM_lh_insert(MEM,lh,inst)
+#define lh_MEM_retrieve(lh,inst) LHM_lh_retrieve(MEM,lh,inst)
+#define lh_MEM_delete(lh,inst) LHM_lh_delete(MEM,lh,inst)
+#define lh_MEM_doall(lh,fn) LHM_lh_doall(MEM,lh,fn)
+#define lh_MEM_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(MEM,lh,fn,arg_type,arg)
+#define lh_MEM_error(lh) LHM_lh_error(MEM,lh)
+#define lh_MEM_num_items(lh) LHM_lh_num_items(MEM,lh)
+#define lh_MEM_down_load(lh) LHM_lh_down_load(MEM,lh)
+#define lh_MEM_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(MEM,lh,out)
+#define lh_MEM_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(MEM,lh,out)
+#define lh_MEM_stats_bio(lh,out) \
+  LHM_lh_stats_bio(MEM,lh,out)
+#define lh_MEM_free(lh) LHM_lh_free(MEM,lh)
+
+#define lh_OBJ_NAME_new() LHM_lh_new(OBJ_NAME,obj_name)
+#define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst)
+#define lh_OBJ_NAME_retrieve(lh,inst) LHM_lh_retrieve(OBJ_NAME,lh,inst)
+#define lh_OBJ_NAME_delete(lh,inst) LHM_lh_delete(OBJ_NAME,lh,inst)
+#define lh_OBJ_NAME_doall(lh,fn) LHM_lh_doall(OBJ_NAME,lh,fn)
+#define lh_OBJ_NAME_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(OBJ_NAME,lh,fn,arg_type,arg)
+#define lh_OBJ_NAME_error(lh) LHM_lh_error(OBJ_NAME,lh)
+#define lh_OBJ_NAME_num_items(lh) LHM_lh_num_items(OBJ_NAME,lh)
+#define lh_OBJ_NAME_down_load(lh) LHM_lh_down_load(OBJ_NAME,lh)
+#define lh_OBJ_NAME_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(OBJ_NAME,lh,out)
+#define lh_OBJ_NAME_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(OBJ_NAME,lh,out)
+#define lh_OBJ_NAME_stats_bio(lh,out) \
+  LHM_lh_stats_bio(OBJ_NAME,lh,out)
+#define lh_OBJ_NAME_free(lh) LHM_lh_free(OBJ_NAME,lh)
+
+#define lh_OPENSSL_CSTRING_new() LHM_lh_new(OPENSSL_CSTRING,openssl_cstring)
+#define lh_OPENSSL_CSTRING_insert(lh,inst) LHM_lh_insert(OPENSSL_CSTRING,lh,inst)
+#define lh_OPENSSL_CSTRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_CSTRING,lh,inst)
+#define lh_OPENSSL_CSTRING_delete(lh,inst) LHM_lh_delete(OPENSSL_CSTRING,lh,inst)
+#define lh_OPENSSL_CSTRING_doall(lh,fn) LHM_lh_doall(OPENSSL_CSTRING,lh,fn)
+#define lh_OPENSSL_CSTRING_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(OPENSSL_CSTRING,lh,fn,arg_type,arg)
+#define lh_OPENSSL_CSTRING_error(lh) LHM_lh_error(OPENSSL_CSTRING,lh)
+#define lh_OPENSSL_CSTRING_num_items(lh) LHM_lh_num_items(OPENSSL_CSTRING,lh)
+#define lh_OPENSSL_CSTRING_down_load(lh) LHM_lh_down_load(OPENSSL_CSTRING,lh)
+#define lh_OPENSSL_CSTRING_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(OPENSSL_CSTRING,lh,out)
+#define lh_OPENSSL_CSTRING_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(OPENSSL_CSTRING,lh,out)
+#define lh_OPENSSL_CSTRING_stats_bio(lh,out) \
+  LHM_lh_stats_bio(OPENSSL_CSTRING,lh,out)
+#define lh_OPENSSL_CSTRING_free(lh) LHM_lh_free(OPENSSL_CSTRING,lh)
+
+#define lh_OPENSSL_STRING_new() LHM_lh_new(OPENSSL_STRING,openssl_string)
+#define lh_OPENSSL_STRING_insert(lh,inst) LHM_lh_insert(OPENSSL_STRING,lh,inst)
+#define lh_OPENSSL_STRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_STRING,lh,inst)
+#define lh_OPENSSL_STRING_delete(lh,inst) LHM_lh_delete(OPENSSL_STRING,lh,inst)
+#define lh_OPENSSL_STRING_doall(lh,fn) LHM_lh_doall(OPENSSL_STRING,lh,fn)
+#define lh_OPENSSL_STRING_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(OPENSSL_STRING,lh,fn,arg_type,arg)
+#define lh_OPENSSL_STRING_error(lh) LHM_lh_error(OPENSSL_STRING,lh)
+#define lh_OPENSSL_STRING_num_items(lh) LHM_lh_num_items(OPENSSL_STRING,lh)
+#define lh_OPENSSL_STRING_down_load(lh) LHM_lh_down_load(OPENSSL_STRING,lh)
+#define lh_OPENSSL_STRING_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(OPENSSL_STRING,lh,out)
+#define lh_OPENSSL_STRING_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(OPENSSL_STRING,lh,out)
+#define lh_OPENSSL_STRING_stats_bio(lh,out) \
+  LHM_lh_stats_bio(OPENSSL_STRING,lh,out)
+#define lh_OPENSSL_STRING_free(lh) LHM_lh_free(OPENSSL_STRING,lh)
+
+#define lh_SSL_SESSION_new() LHM_lh_new(SSL_SESSION,ssl_session)
+#define lh_SSL_SESSION_insert(lh,inst) LHM_lh_insert(SSL_SESSION,lh,inst)
+#define lh_SSL_SESSION_retrieve(lh,inst) LHM_lh_retrieve(SSL_SESSION,lh,inst)
+#define lh_SSL_SESSION_delete(lh,inst) LHM_lh_delete(SSL_SESSION,lh,inst)
+#define lh_SSL_SESSION_doall(lh,fn) LHM_lh_doall(SSL_SESSION,lh,fn)
+#define lh_SSL_SESSION_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(SSL_SESSION,lh,fn,arg_type,arg)
+#define lh_SSL_SESSION_error(lh) LHM_lh_error(SSL_SESSION,lh)
+#define lh_SSL_SESSION_num_items(lh) LHM_lh_num_items(SSL_SESSION,lh)
+#define lh_SSL_SESSION_down_load(lh) LHM_lh_down_load(SSL_SESSION,lh)
+#define lh_SSL_SESSION_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(SSL_SESSION,lh,out)
+#define lh_SSL_SESSION_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(SSL_SESSION,lh,out)
+#define lh_SSL_SESSION_stats_bio(lh,out) \
+  LHM_lh_stats_bio(SSL_SESSION,lh,out)
+#define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh)
 /* End of util/mkstack.pl block, you may now edit :-) */
 
 #endif /* !defined HEADER_SAFESTACK_H */
diff --git a/crypto/stack/stack.c b/crypto/stack/stack.c
index 378bd7c..76cf1a1 100644
--- a/crypto/stack/stack.c
+++ b/crypto/stack/stack.c
@@ -77,10 +77,10 @@
 
 #include <errno.h>
 
-int (*sk_set_cmp_func(STACK *sk, int (*c)(const char * const *,const char * const *)))
-		(const char * const *, const char * const *)
+int (*sk_set_cmp_func(_STACK *sk, int (*c)(const void *, const void *)))
+		(const void *, const void *)
 	{
-	int (*old)(const char * const *,const char * const *)=sk->comp;
+	int (*old)(const void *,const void *)=sk->comp;
 
 	if (sk->comp != c)
 		sk->sorted=0;
@@ -89,9 +89,9 @@
 	return old;
 	}
 
-STACK *sk_dup(STACK *sk)
+_STACK *sk_dup(_STACK *sk)
 	{
-	STACK *ret;
+	_STACK *ret;
 	char **s;
 
 	if ((ret=sk_new(sk->comp)) == NULL) goto err;
@@ -112,19 +112,19 @@
 	return(NULL);
 	}
 
-STACK *sk_new_null(void)
+_STACK *sk_new_null(void)
 	{
-	return sk_new((int (*)(const char * const *, const char * const *))0);
+	return sk_new((int (*)(const void *, const void *))0);
 	}
 
-STACK *sk_new(int (*c)(const char * const *, const char * const *))
+_STACK *sk_new(int (*c)(const void *, const void *))
 	{
-	STACK *ret;
+	_STACK *ret;
 	int i;
 
-	if ((ret=(STACK *)OPENSSL_malloc(sizeof(STACK))) == NULL)
+	if ((ret=OPENSSL_malloc(sizeof(_STACK))) == NULL)
 		goto err;
-	if ((ret->data=(char **)OPENSSL_malloc(sizeof(char *)*MIN_NODES)) == NULL)
+	if ((ret->data=OPENSSL_malloc(sizeof(char *)*MIN_NODES)) == NULL)
 		goto err;
 	for (i=0; i<MIN_NODES; i++)
 		ret->data[i]=NULL;
@@ -139,14 +139,14 @@
 	return(NULL);
 	}
 
-int sk_insert(STACK *st, char *data, int loc)
+int sk_insert(_STACK *st, void *data, int loc)
 	{
 	char **s;
 
 	if(st == NULL) return 0;
 	if (st->num_alloc <= st->num+1)
 		{
-		s=(char **)OPENSSL_realloc((char *)st->data,
+		s=OPENSSL_realloc((char *)st->data,
 			(unsigned int)sizeof(char *)*st->num_alloc*2);
 		if (s == NULL)
 			return(0);
@@ -160,14 +160,14 @@
 		int i;
 		char **f,**t;
 
-		f=(char **)st->data;
-		t=(char **)&(st->data[1]);
+		f=st->data;
+		t=&(st->data[1]);
 		for (i=st->num; i>=loc; i--)
 			t[i]=f[i];
 			
 #ifdef undef /* no memmove on sunos :-( */
-		memmove( (char *)&(st->data[loc+1]),
-			(char *)&(st->data[loc]),
+		memmove(&(st->data[loc+1]),
+			&(st->data[loc]),
 			sizeof(char *)*(st->num-loc));
 #endif
 		st->data[loc]=data;
@@ -177,7 +177,7 @@
 	return(st->num);
 	}
 
-char *sk_delete_ptr(STACK *st, char *p)
+void *sk_delete_ptr(_STACK *st, void *p)
 	{
 	int i;
 
@@ -187,7 +187,7 @@
 	return(NULL);
 	}
 
-char *sk_delete(STACK *st, int loc)
+void *sk_delete(_STACK *st, int loc)
 	{
 	char *ret;
 	int i,j;
@@ -210,11 +210,11 @@
 	return(ret);
 	}
 
-static int internal_find(STACK *st, char *data, int ret_val_options)
+static int internal_find(_STACK *st, void *data, int ret_val_options)
 	{
-	char **r;
+	const void * const *r;
 	int i;
-	int (*comp_func)(const void *,const void *);
+
 	if(st == NULL) return -1;
 
 	if (st->comp == NULL)
@@ -226,53 +226,46 @@
 		}
 	sk_sort(st);
 	if (data == NULL) return(-1);
-	/* This (and the "qsort" below) are the two places in OpenSSL
-	 * where we need to convert from our standard (type **,type **)
-	 * compare callback type to the (void *,void *) type required by
-	 * bsearch. However, the "data" it is being called(back) with are
-	 * not (type *) pointers, but the *pointers* to (type *) pointers,
-	 * so we get our extra level of pointer dereferencing that way. */
-	comp_func=(int (*)(const void *,const void *))(st->comp);
-	r=(char **)OBJ_bsearch_ex((char *)&data,(char *)st->data,
-		st->num,sizeof(char *),comp_func,ret_val_options);
+	r=OBJ_bsearch_ex_(&data,st->data,st->num,sizeof(void *),st->comp,
+			  ret_val_options);
 	if (r == NULL) return(-1);
-	return((int)(r-st->data));
+	return (int)((char **)r-st->data);
 	}
 
-int sk_find(STACK *st, char *data)
+int sk_find(_STACK *st, void *data)
 	{
 	return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH);
 	}
-int sk_find_ex(STACK *st, char *data)
+int sk_find_ex(_STACK *st, void *data)
 	{
 	return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH);
 	}
 
-int sk_push(STACK *st, char *data)
+int sk_push(_STACK *st, void *data)
 	{
 	return(sk_insert(st,data,st->num));
 	}
 
-int sk_unshift(STACK *st, char *data)
+int sk_unshift(_STACK *st, void *data)
 	{
 	return(sk_insert(st,data,0));
 	}
 
-char *sk_shift(STACK *st)
+void *sk_shift(_STACK *st)
 	{
 	if (st == NULL) return(NULL);
 	if (st->num <= 0) return(NULL);
 	return(sk_delete(st,0));
 	}
 
-char *sk_pop(STACK *st)
+void *sk_pop(_STACK *st)
 	{
 	if (st == NULL) return(NULL);
 	if (st->num <= 0) return(NULL);
 	return(sk_delete(st,st->num-1));
 	}
 
-void sk_zero(STACK *st)
+void sk_zero(_STACK *st)
 	{
 	if (st == NULL) return;
 	if (st->num <= 0) return;
@@ -280,7 +273,7 @@
 	st->num=0;
 	}
 
-void sk_pop_free(STACK *st, void (*func)(void *))
+void sk_pop_free(_STACK *st, void (*func)(void *))
 	{
 	int i;
 
@@ -291,32 +284,32 @@
 	sk_free(st);
 	}
 
-void sk_free(STACK *st)
+void sk_free(_STACK *st)
 	{
 	if (st == NULL) return;
 	if (st->data != NULL) OPENSSL_free(st->data);
 	OPENSSL_free(st);
 	}
 
-int sk_num(const STACK *st)
+int sk_num(const _STACK *st)
 {
 	if(st == NULL) return -1;
 	return st->num;
 }
 
-char *sk_value(const STACK *st, int i)
+void *sk_value(const _STACK *st, int i)
 {
 	if(!st || (i < 0) || (i >= st->num)) return NULL;
 	return st->data[i];
 }
 
-char *sk_set(STACK *st, int i, char *value)
+void *sk_set(_STACK *st, int i, void *value)
 {
 	if(!st || (i < 0) || (i >= st->num)) return NULL;
 	return (st->data[i] = value);
 }
 
-void sk_sort(STACK *st)
+void sk_sort(_STACK *st)
 	{
 	if (st && !st->sorted)
 		{
@@ -333,7 +326,7 @@
 		}
 	}
 
-int sk_is_sorted(const STACK *st)
+int sk_is_sorted(const _STACK *st)
 	{
 	if (!st)
 		return 1;
diff --git a/crypto/stack/stack.h b/crypto/stack/stack.h
index 5cbb116..ce35e55 100644
--- a/crypto/stack/stack.h
+++ b/crypto/stack/stack.h
@@ -70,37 +70,36 @@
 	int sorted;
 
 	int num_alloc;
-	int (*comp)(const char * const *, const char * const *);
-	} STACK;
+	int (*comp)(const void *, const void *);
+	} _STACK;  /* Use STACK_OF(...) instead */
 
 #define M_sk_num(sk)		((sk) ? (sk)->num:-1)
 #define M_sk_value(sk,n)	((sk) ? (sk)->data[n] : NULL)
 
-int sk_num(const STACK *);
-char *sk_value(const STACK *, int);
+int sk_num(const _STACK *);
+void *sk_value(const _STACK *, int);
 
-char *sk_set(STACK *, int, char *);
+void *sk_set(_STACK *, int, void *);
 
-STACK *sk_new(int (*cmp)(const char * const *, const char * const *));
-STACK *sk_new_null(void);
-void sk_free(STACK *);
-void sk_pop_free(STACK *st, void (*func)(void *));
-int sk_insert(STACK *sk,char *data,int where);
-char *sk_delete(STACK *st,int loc);
-char *sk_delete_ptr(STACK *st, char *p);
-int sk_find(STACK *st,char *data);
-int sk_find_ex(STACK *st,char *data);
-int sk_push(STACK *st,char *data);
-int sk_unshift(STACK *st,char *data);
-char *sk_shift(STACK *st);
-char *sk_pop(STACK *st);
-void sk_zero(STACK *st);
-int (*sk_set_cmp_func(STACK *sk, int (*c)(const char * const *,
-			const char * const *)))
-			(const char * const *, const char * const *);
-STACK *sk_dup(STACK *st);
-void sk_sort(STACK *st);
-int sk_is_sorted(const STACK *st);
+_STACK *sk_new(int (*cmp)(const void *, const void *));
+_STACK *sk_new_null(void);
+void sk_free(_STACK *);
+void sk_pop_free(_STACK *st, void (*func)(void *));
+int sk_insert(_STACK *sk, void *data, int where);
+void *sk_delete(_STACK *st, int loc);
+void *sk_delete_ptr(_STACK *st, void *p);
+int sk_find(_STACK *st, void *data);
+int sk_find_ex(_STACK *st, void *data);
+int sk_push(_STACK *st, void *data);
+int sk_unshift(_STACK *st, void *data);
+void *sk_shift(_STACK *st);
+void *sk_pop(_STACK *st);
+void sk_zero(_STACK *st);
+int (*sk_set_cmp_func(_STACK *sk, int (*c)(const void *, const void *)))
+	(const void *, const void *);
+_STACK *sk_dup(_STACK *st);
+void sk_sort(_STACK *st);
+int sk_is_sorted(const _STACK *st);
 
 #ifdef  __cplusplus
 }
diff --git a/crypto/store/Makefile b/crypto/store/Makefile
deleted file mode 100644
index c9f5d00..0000000
--- a/crypto/store/Makefile
+++ /dev/null
@@ -1,112 +0,0 @@
-#
-# OpenSSL/crypto/store/Makefile
-#
-
-DIR=	store
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-#TEST= storetest.c
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC= str_err.c str_lib.c str_meth.c str_mem.c
-LIBOBJ= str_err.o str_lib.o str_meth.o str_mem.o
-
-SRC= $(LIBSRC)
-
-#EXHEADER= store.h str_compat.h
-EXHEADER= store.h
-HEADER=	$(EXHEADER) str_locl.h
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-str_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
-str_err.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-str_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-str_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-str_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-str_err.o: ../../include/openssl/store.h ../../include/openssl/symhacks.h
-str_err.o: str_err.c
-str_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-str_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-str_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-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/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
-str_mem.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-str_mem.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-str_mem.o: ../../include/openssl/store.h ../../include/openssl/symhacks.h
-str_mem.o: str_locl.h str_mem.c
-str_meth.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-str_meth.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-str_meth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-str_meth.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-str_meth.o: ../../include/openssl/store.h ../../include/openssl/symhacks.h
-str_meth.o: str_locl.h str_meth.c
diff --git a/crypto/store/store.h b/crypto/store/store.h
index 6458337..0a28c7d 100644
--- a/crypto/store/store.h
+++ b/crypto/store/store.h
@@ -59,6 +59,12 @@
 #ifndef HEADER_STORE_H
 #define HEADER_STORE_H
 
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_STORE
+#error STORE is disabled.
+#endif
+
 #include <openssl/ossl_typ.h>
 #ifndef OPENSSL_NO_DEPRECATED
 #include <openssl/evp.h>
@@ -408,7 +414,8 @@
 
 /* Compare on basis of a bit pattern formed by the STORE_ATTR_TYPES values
    in each contained attribute. */
-int STORE_ATTR_INFO_compare(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
+int STORE_ATTR_INFO_compare(const STORE_ATTR_INFO * const *a,
+			    const STORE_ATTR_INFO * const *b);
 /* Check if the set of attributes in a is within the range of attributes
    set in b. */
 int STORE_ATTR_INFO_in_range(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
diff --git a/crypto/store/str_err.c b/crypto/store/str_err.c
index 6fee649..924edf0 100644
--- a/crypto/store/str_err.c
+++ b/crypto/store/str_err.c
@@ -1,6 +1,6 @@
 /* crypto/store/str_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
diff --git a/crypto/store/str_lib.c b/crypto/store/str_lib.c
index 32ae5bd..f1dbcbd 100644
--- a/crypto/store/str_lib.c
+++ b/crypto/store/str_lib.c
@@ -1670,7 +1670,7 @@
 	}
 
 static int attr_info_compare_compute_range(
-	unsigned char *abits, unsigned char *bbits,
+	const unsigned char *abits, const unsigned char *bbits,
 	unsigned int *alowp, unsigned int *ahighp,
 	unsigned int *blowp, unsigned int *bhighp)
 	{
@@ -1739,13 +1739,15 @@
 	return res;
 	}
 
-int STORE_ATTR_INFO_compare(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
+int STORE_ATTR_INFO_compare(const STORE_ATTR_INFO * const *a,
+			    const STORE_ATTR_INFO * const *b)
 	{
 	if (a == b) return 0;
 	if (!a) return -1;
 	if (!b) return 1;
-	return attr_info_compare_compute_range(a->set, b->set, 0, 0, 0, 0);
+	return attr_info_compare_compute_range((*a)->set, (*b)->set, 0, 0, 0, 0);
 	}
+
 int STORE_ATTR_INFO_in_range(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
 	{
 	unsigned int alow, ahigh, blow, bhigh;
@@ -1759,6 +1761,7 @@
 		return 1;
 	return 0;
 	}
+
 int STORE_ATTR_INFO_in(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
 	{
 	unsigned char *abits, *bbits;
@@ -1776,6 +1779,7 @@
 		}
 	return 1;
 	}
+
 int STORE_ATTR_INFO_in_ex(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b)
 	{
 	STORE_ATTR_TYPES i;
diff --git a/crypto/store/str_mem.c b/crypto/store/str_mem.c
index 527757a..8ac4f7e 100644
--- a/crypto/store/str_mem.c
+++ b/crypto/store/str_mem.c
@@ -76,30 +76,35 @@
    attribute type code).
 */
 
-struct mem_object_data_st
+typedef struct mem_object_data_st
 	{
 	STORE_OBJECT *object;
 	STORE_ATTR_INFO *attr_info;
 	int references;
-	};
+	} MEM_OBJECT_DATA;
 
+DECLARE_STACK_OF(MEM_OBJECT_DATA)
 struct mem_data_st
 	{
-	STACK *data;		/* A stack of mem_object_data_st,
-				   sorted with STORE_ATTR_INFO_compare(). */
+	STACK_OF(MEM_OBJECT_DATA) *data; /* sorted with
+					  * STORE_ATTR_INFO_compare(). */
 	unsigned int compute_components : 1; /* Currently unused, but can
 						be used to add attributes
 						from parts of the data. */
 	};
 
+DECLARE_STACK_OF(STORE_ATTR_INFO)
 struct mem_ctx_st
 	{
 	int type;		/* The type we're searching for */
-	STACK *search_attributes; /* Sets of attributes to search for.
-				     Each element is a STORE_ATTR_INFO. */
-	int search_index;	/* which of the search attributes we found a match
-				   for, -1 when we still haven't found any */
-	int index;		/* -1 as long as we're searching for the first */
+	STACK_OF(STORE_ATTR_INFO) *search_attributes; /* Sets of
+				     attributes to search for.  Each
+				     element is a STORE_ATTR_INFO. */
+	int search_index;	/* which of the search attributes we
+				   found a match for, -1 when we still
+				   haven't found any */
+	int index;		/* -1 as long as we're searching for
+                                    the first */
 	};
 
 static int mem_init(STORE *s);
@@ -240,7 +245,7 @@
 		if (context->search_attributes == NULL)
 			{
 			context->search_attributes =
-				sk_new((int (*)(const char * const *, const char * const *))STORE_ATTR_INFO_compare);
+				sk_STORE_ATTR_INFO_new(STORE_ATTR_INFO_compare);
 			if (!context->search_attributes)
 				{
 				STOREerr(STORE_F_MEM_LIST_START,
@@ -248,7 +253,7 @@
 				goto err;
 				}
 			}
-		sk_push(context->search_attributes,(char *)attrs);
+		sk_STORE_ATTR_INFO_push(context->search_attributes,attrs);
 		}
 	if (!STORE_parse_attrs_endp(attribute_context))
 		goto err;
@@ -284,11 +289,14 @@
 
 	if (context->search_index == -1)
 		{
-		for (i = 0; i < sk_num(context->search_attributes); i++)
+		for (i = 0;
+		     i < sk_STORE_ATTR_INFO_num(context->search_attributes);
+		     i++)
 			{
-			key.attr_info =
-				(STORE_ATTR_INFO *)sk_value(context->search_attributes, i);
-			srch = sk_find_ex(store->data, (char *)&key);
+			key.attr_info
+			  = sk_STORE_ATTR_INFO_value(context->search_attributes,
+						     i);
+			srch = sk_MEM_OBJECT_DATA_find_ex(store->data, &key);
 
 			if (srch >= 0)
 				{
@@ -301,21 +309,20 @@
 		return NULL;
 	
 	key.attr_info =
-		(STORE_ATTR_INFO *)sk_value(context->search_attributes,
-			context->search_index);
+		sk_STORE_ATTR_INFO_value(context->search_attributes,
+					 context->search_index);
 	for(srch = context->search_index;
-	    srch < sk_num(store->data)
+	    srch < sk_MEM_OBJECT_DATA_num(store->data)
 		    && STORE_ATTR_INFO_in_range(key.attr_info,
-			    (STORE_ATTR_INFO *)sk_value(store->data, srch))
+			    sk_MEM_OBJECT_DATA_value(store->data, srch)->attr_info)
 		    && !(cres = STORE_ATTR_INFO_in_ex(key.attr_info,
-				 (STORE_ATTR_INFO *)sk_value(store->data, srch)));
+				 sk_MEM_OBJECT_DATA_value(store->data, srch)->attr_info));
 	    srch++)
 		;
 
 	context->search_index = srch;
 	if (cres)
-		return ((struct mem_object_data_st *)sk_value(store->data,
-				srch))->object;
+		return (sk_MEM_OBJECT_DATA_value(store->data, srch))->object;
 	return NULL;
 	}
 static int mem_list_end(STORE *s, void *handle)
@@ -328,7 +335,7 @@
 		return 0;
 		}
 	if (context && context->search_attributes)
-		sk_free(context->search_attributes);
+		sk_STORE_ATTR_INFO_free(context->search_attributes);
 	if (context) OPENSSL_free(context);
 	return 1;
 	}
@@ -337,7 +344,8 @@
 	struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
 
 	if (!context
-		|| context->search_index == sk_num(context->search_attributes))
+	    || context->search_index
+	       == sk_STORE_ATTR_INFO_num(context->search_attributes))
 		return 1;
 	return 0;
 	}
diff --git a/crypto/symhacks.h b/crypto/symhacks.h
index 0114093..151b683 100644
--- a/crypto/symhacks.h
+++ b/crypto/symhacks.h
@@ -67,10 +67,6 @@
    incompatibilities. */
 #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
@@ -151,9 +147,9 @@
 #undef CRYPTO_set_dynlock_create_callback
 #define CRYPTO_set_dynlock_create_callback      CRYPTO_set_dynlock_create_cb
 #undef CRYPTO_set_dynlock_lock_callback
-#define CRYPTO_set_dynlock_lock_callback        CRYPTO_set_dynlock_lock_cb
+#define CRYPTO_set_dynlock_lock_callback	CRYPTO_set_dynlock_lock_cb
 #undef CRYPTO_get_dynlock_lock_callback
-#define CRYPTO_get_dynlock_lock_callback        CRYPTO_get_dynlock_lock_cb
+#define CRYPTO_get_dynlock_lock_callback	CRYPTO_get_dynlock_lock_cb
 #undef CRYPTO_get_dynlock_destroy_callback
 #define CRYPTO_get_dynlock_destroy_callback     CRYPTO_get_dynlock_destroy_cb
 #undef CRYPTO_get_dynlock_create_callback
@@ -165,7 +161,7 @@
 
 /* Hack some long SSL names */
 #undef SSL_CTX_set_default_verify_paths
-#define SSL_CTX_set_default_verify_paths        SSL_CTX_set_def_verify_paths
+#define SSL_CTX_set_default_verify_paths	SSL_CTX_set_def_verify_paths
 #undef SSL_get_ex_data_X509_STORE_CTX_idx
 #define SSL_get_ex_data_X509_STORE_CTX_idx      SSL_get_ex_d_X509_STORE_CTX_idx
 #undef SSL_add_file_cert_subjects_to_stack
@@ -175,7 +171,7 @@
 #undef SSL_CTX_use_certificate_chain_file
 #define SSL_CTX_use_certificate_chain_file      SSL_CTX_use_cert_chain_file
 #undef SSL_CTX_set_cert_verify_callback
-#define SSL_CTX_set_cert_verify_callback        SSL_CTX_set_cert_verify_cb
+#define SSL_CTX_set_cert_verify_callback	SSL_CTX_set_cert_verify_cb
 #undef SSL_CTX_set_default_passwd_cb_userdata
 #define SSL_CTX_set_default_passwd_cb_userdata  SSL_CTX_set_def_passwd_cb_ud
 #undef SSL_COMP_get_compression_methods
@@ -196,9 +192,17 @@
 #undef ENGINE_set_default_BN_mod_exp_crt
 #define ENGINE_set_default_BN_mod_exp_crt	ENGINE_set_def_BN_mod_exp_crt
 #undef ENGINE_set_load_privkey_function
-#define ENGINE_set_load_privkey_function        ENGINE_set_load_privkey_fn
+#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
+#define ENGINE_get_load_privkey_function	ENGINE_get_load_privkey_fn
+#undef ENGINE_unregister_pkey_asn1_meths
+#define ENGINE_unregister_pkey_asn1_meths	ENGINE_unreg_pkey_asn1_meths
+#undef ENGINE_register_all_pkey_asn1_meths
+#define ENGINE_register_all_pkey_asn1_meths	ENGINE_reg_all_pkey_asn1_meths
+#undef ENGINE_set_default_pkey_asn1_meths
+#define ENGINE_set_default_pkey_asn1_meths	ENGINE_set_def_pkey_asn1_meths
+#undef ENGINE_get_pkey_asn1_meth_engine
+#define ENGINE_get_pkey_asn1_meth_engine	ENGINE_get_pkey_asn1_meth_eng
 #undef ENGINE_set_load_ssl_client_cert_function
 #define ENGINE_set_load_ssl_client_cert_function \
 						ENGINE_set_ld_ssl_clnt_cert_fn
@@ -207,7 +211,7 @@
 
 /* Hack some long OCSP names */
 #undef OCSP_REQUEST_get_ext_by_critical
-#define OCSP_REQUEST_get_ext_by_critical        OCSP_REQUEST_get_ext_by_crit
+#define OCSP_REQUEST_get_ext_by_critical	OCSP_REQUEST_get_ext_by_crit
 #undef OCSP_BASICRESP_get_ext_by_critical
 #define OCSP_BASICRESP_get_ext_by_critical      OCSP_BASICRESP_get_ext_by_crit
 #undef OCSP_SINGLERESP_get_ext_by_critical
@@ -224,6 +228,8 @@
 #define OPENSSL_add_all_algorithms_noconf	OPENSSL_add_all_algo_noconf
 #undef OPENSSL_add_all_algorithms_conf
 #define OPENSSL_add_all_algorithms_conf		OPENSSL_add_all_algo_conf
+#undef EVP_PKEY_meth_set_verify_recover
+#define EVP_PKEY_meth_set_verify_recover	EVP_PKEY_meth_set_vrfy_recover
 
 /* Hack some long EC names */
 #undef EC_GROUP_set_point_conversion_form
@@ -252,15 +258,15 @@
 #define EC_POINT_set_compressed_coordinates_GF2m \
                                                 EC_POINT_set_compr_coords_GF2m
 #undef ec_GF2m_simple_group_clear_finish
-#define ec_GF2m_simple_group_clear_finish        ec_GF2m_simple_grp_clr_finish
+#define ec_GF2m_simple_group_clear_finish	ec_GF2m_simple_grp_clr_finish
 #undef ec_GF2m_simple_group_check_discriminant
 #define ec_GF2m_simple_group_check_discriminant	ec_GF2m_simple_grp_chk_discrim
 #undef ec_GF2m_simple_point_clear_finish
-#define ec_GF2m_simple_point_clear_finish        ec_GF2m_simple_pt_clr_finish
+#define ec_GF2m_simple_point_clear_finish	ec_GF2m_simple_pt_clr_finish
 #undef ec_GF2m_simple_point_set_to_infinity
-#define ec_GF2m_simple_point_set_to_infinity     ec_GF2m_simple_pt_set_to_inf
+#define ec_GF2m_simple_point_set_to_infinity	ec_GF2m_simple_pt_set_to_inf
 #undef ec_GF2m_simple_points_make_affine
-#define ec_GF2m_simple_points_make_affine        ec_GF2m_simple_pts_make_affine
+#define ec_GF2m_simple_points_make_affine	ec_GF2m_simple_pts_make_affine
 #undef ec_GF2m_simple_point_set_affine_coordinates
 #define ec_GF2m_simple_point_set_affine_coordinates \
                                                 ec_GF2m_smp_pt_set_af_coords
@@ -275,19 +281,19 @@
 #undef ec_GFp_simple_group_get_curve_GFp
 #define ec_GFp_simple_group_get_curve_GFp       ec_GFp_simple_grp_get_curve_GFp
 #undef ec_GFp_simple_group_clear_finish
-#define ec_GFp_simple_group_clear_finish        ec_GFp_simple_grp_clear_finish
+#define ec_GFp_simple_group_clear_finish	ec_GFp_simple_grp_clear_finish
 #undef ec_GFp_simple_group_set_generator
 #define ec_GFp_simple_group_set_generator       ec_GFp_simple_grp_set_generator
 #undef ec_GFp_simple_group_get0_generator
 #define ec_GFp_simple_group_get0_generator      ec_GFp_simple_grp_gt0_generator
 #undef ec_GFp_simple_group_get_cofactor
-#define ec_GFp_simple_group_get_cofactor        ec_GFp_simple_grp_get_cofactor
+#define ec_GFp_simple_group_get_cofactor	ec_GFp_simple_grp_get_cofactor
 #undef ec_GFp_simple_point_clear_finish
-#define ec_GFp_simple_point_clear_finish        ec_GFp_simple_pt_clear_finish
+#define ec_GFp_simple_point_clear_finish	ec_GFp_simple_pt_clear_finish
 #undef ec_GFp_simple_point_set_to_infinity
 #define ec_GFp_simple_point_set_to_infinity     ec_GFp_simple_pt_set_to_inf
 #undef ec_GFp_simple_points_make_affine
-#define ec_GFp_simple_points_make_affine        ec_GFp_simple_pts_make_affine
+#define ec_GFp_simple_points_make_affine	ec_GFp_simple_pts_make_affine
 #undef ec_GFp_simple_group_get_curve_GFp
 #define ec_GFp_simple_group_get_curve_GFp       ec_GFp_simple_grp_get_curve_GFp
 #undef ec_GFp_simple_set_Jprojective_coordinates_GFp
@@ -367,6 +373,14 @@
 #undef STORE_method_get_unlock_store_function
 #define STORE_method_get_unlock_store_function	STORE_meth_get_unlock_store_fn
 
+/* Hack some long TS names */
+#undef TS_RESP_CTX_set_status_info_cond
+#define TS_RESP_CTX_set_status_info_cond	TS_RESP_CTX_set_stat_info_cond
+#undef TS_RESP_CTX_set_clock_precision_digits
+#define TS_RESP_CTX_set_clock_precision_digits	TS_RESP_CTX_set_clk_prec_digits
+#undef TS_CONF_set_clock_precision_digits
+#define TS_CONF_set_clock_precision_digits	TS_CONF_set_clk_prec_digits
+
 /* Hack some long CMS names */
 #undef CMS_RecipientInfo_ktri_get0_algs
 #define CMS_RecipientInfo_ktri_get0_algs	CMS_RecipInfo_ktri_get0_algs
@@ -388,21 +402,21 @@
 #endif /* defined OPENSSL_SYS_VMS */
 
 
-/* Case insensiteve linking causes problems.... */
-#if defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2)
+/* Case insensitive linking causes problems.... */
+#if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2)
 #undef ERR_load_CRYPTO_strings
 #define ERR_load_CRYPTO_strings			ERR_load_CRYPTOlib_strings
 #undef OCSP_crlID_new
-#define OCSP_crlID_new                          OCSP_crlID2_new
+#define OCSP_crlID_new				OCSP_crlID2_new
 
 #undef d2i_ECPARAMETERS
-#define d2i_ECPARAMETERS                        d2i_UC_ECPARAMETERS
+#define d2i_ECPARAMETERS			d2i_UC_ECPARAMETERS
 #undef i2d_ECPARAMETERS
-#define i2d_ECPARAMETERS                        i2d_UC_ECPARAMETERS
+#define i2d_ECPARAMETERS			i2d_UC_ECPARAMETERS
 #undef d2i_ECPKPARAMETERS
-#define d2i_ECPKPARAMETERS                      d2i_UC_ECPKPARAMETERS
+#define d2i_ECPKPARAMETERS			d2i_UC_ECPKPARAMETERS
 #undef i2d_ECPKPARAMETERS
-#define i2d_ECPKPARAMETERS                      i2d_UC_ECPKPARAMETERS
+#define i2d_ECPKPARAMETERS			i2d_UC_ECPKPARAMETERS
 
 /* These functions do not seem to exist!  However, I'm paranoid...
    Original command in x509v3.h:
@@ -411,19 +425,19 @@
    hide them a little, by giving them an extra 'o' at the
    beginning of the name... */
 #undef X509v3_cleanup_extensions
-#define X509v3_cleanup_extensions               oX509v3_cleanup_extensions
+#define X509v3_cleanup_extensions		oX509v3_cleanup_extensions
 #undef X509v3_add_extension
-#define X509v3_add_extension                    oX509v3_add_extension
+#define X509v3_add_extension			oX509v3_add_extension
 #undef X509v3_add_netscape_extensions
-#define X509v3_add_netscape_extensions          oX509v3_add_netscape_extensions
+#define X509v3_add_netscape_extensions		oX509v3_add_netscape_extensions
 #undef X509v3_add_standard_extensions
-#define X509v3_add_standard_extensions          oX509v3_add_standard_extensions
+#define X509v3_add_standard_extensions		oX509v3_add_standard_extensions
 
+/* This one clashes with CMS_data_create */
+#undef cms_Data_create
+#define cms_Data_create				priv_cms_Data_create
 
 #endif
 
 
 #endif /* ! defined HEADER_VMS_IDHACKS_H */
-/* This one clashes with CMS_data_create */
-#undef cms_Data_create
-#define cms_Data_create				priv_cms_Data_create
diff --git a/crypto/threads/mttest.c b/crypto/threads/mttest.c
index f6f3df4..eba7aa8 100644
--- a/crypto/threads/mttest.c
+++ b/crypto/threads/mttest.c
@@ -117,11 +117,13 @@
 void win32_locking_callback(int mode,int type,char *file,int line);
 void pthreads_locking_callback(int mode,int type,char *file,int line);
 void netware_locking_callback(int mode,int type,char *file,int line);
+void beos_locking_callback(int mode,int type,const char *file,int line);
 
 unsigned long irix_thread_id(void );
 unsigned long solaris_thread_id(void );
 unsigned long pthreads_thread_id(void );
 unsigned long netware_thread_id(void );
+unsigned long beos_thread_id(void );
 
 #if defined(OPENSSL_SYS_NETWARE)
 static MPKMutex *lock_cs;
@@ -1209,3 +1211,100 @@
    return(ret);
 }
 #endif /* NETWARE */
+
+#ifdef BEOS_THREADS
+
+#include <Locker.h>
+
+static BLocker** lock_cs;
+static long* lock_count;
+
+void thread_setup(void)
+	{
+	int i;
+
+	lock_cs=(BLocker**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(BLocker*));
+	lock_count=(long*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		{
+		lock_count[i]=0;
+		lock_cs[i] = new BLocker(CRYPTO_get_lock_name(i));
+		}
+
+	CRYPTO_set_id_callback((unsigned long (*)())beos_thread_id);
+	CRYPTO_set_locking_callback(beos_locking_callback);
+	}
+
+void thread_cleanup(void)
+	{
+	int i;
+
+	CRYPTO_set_locking_callback(NULL);
+	fprintf(stderr,"cleanup\n");
+	for (i=0; i<CRYPTO_num_locks(); i++)
+		{
+		delete lock_cs[i];
+		fprintf(stderr,"%8ld:%s\n",lock_count[i],
+			CRYPTO_get_lock_name(i));
+		}
+	OPENSSL_free(lock_cs);
+	OPENSSL_free(lock_count);
+
+	fprintf(stderr,"done cleanup\n");
+	}
+
+void beos_locking_callback(int mode, int type, const char *file, int line)
+    {
+#if 0
+	fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
+		CRYPTO_thread_id(),
+		(mode&CRYPTO_LOCK)?"l":"u",
+		(type&CRYPTO_READ)?"r":"w",file,line);
+#endif
+	if (mode & CRYPTO_LOCK)
+		{
+		lock_cs[type]->Lock();
+		lock_count[type]++;
+		}
+	else
+		{
+		lock_cs[type]->Unlock();
+		}
+	}
+
+void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
+	{
+	SSL_CTX *ssl_ctx[2];
+	thread_id thread_ctx[MAX_THREAD_NUMBER];
+	int i;
+
+	ssl_ctx[0]=s_ctx;
+	ssl_ctx[1]=c_ctx;
+
+	for (i=0; i<thread_number; i++)
+		{
+		thread_ctx[i] = spawn_thread((thread_func)ndoit,
+			NULL, B_NORMAL_PRIORITY, (void *)ssl_ctx);
+		resume_thread(thread_ctx[i]);
+		}
+
+	printf("waiting...\n");
+	for (i=0; i<thread_number; i++)
+		{
+		status_t result;
+		wait_for_thread(thread_ctx[i], &result);
+		}
+
+	printf("beos threads done (%d,%d)\n",
+		s_ctx->references,c_ctx->references);
+	}
+
+unsigned long beos_thread_id(void)
+	{
+	unsigned long ret;
+
+	ret=(unsigned long)find_thread(NULL);
+	return(ret);
+	}
+
+#endif /* BEOS_THREADS */
diff --git a/crypto/tmdiff.c b/crypto/tmdiff.c
deleted file mode 100644
index 1c6e052..0000000
--- a/crypto/tmdiff.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/* crypto/tmdiff.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include "cryptlib.h"
-#include <openssl/tmdiff.h>
-#if !defined(OPENSSL_SYS_MSDOS)
-#include OPENSSL_UNISTD
-#endif
-
-#ifdef TIMEB
-#undef OPENSSL_SYS_WIN32
-#undef TIMES
-#endif
-
-#if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32) && !(defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX_RHAPSODY) && !defined(OPENSSL_SYS_VXWORKS)
-# define TIMES
-#endif
-
-#ifdef OPENSSL_SYS_NETWARE
-#undef TIMES
-#endif
-
-#if !defined(_IRIX) || defined (OPENSSL_SYS_NETWARE)
-#  include <time.h>
-#endif
-#ifdef TIMES
-#  include <sys/types.h>
-#  include <sys/times.h>
-#endif
-
-/* Depending on the VMS version, the tms structure is perhaps defined.
-   The __TMS macro will show if it was.  If it wasn't defined, we should
-   undefine TIMES, since that tells the rest of the program how things
-   should be handled.				-- Richard Levitte */
-#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
-#undef TIMES
-#endif
-
-#if defined(sun) || defined(__ultrix)
-#define _POSIX_SOURCE
-#include <limits.h>
-#include <sys/param.h>
-#endif
-
-#if !defined(TIMES) && !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_NETWARE)
-#include <sys/timeb.h>
-#endif
-
-#ifdef OPENSSL_SYS_WIN32
-#include <windows.h>
-#endif
-
-/* The following if from times(3) man page.  It may need to be changed */
-#ifndef HZ
-# if defined(_SC_CLK_TCK) \
-     && (!defined(OPENSSL_SYS_VMS) || __CTRL_VER >= 70000000)
-/* #  define HZ ((double)sysconf(_SC_CLK_TCK)) */
-#  define HZ sysconf(_SC_CLK_TCK)
-# else
-#  ifndef CLK_TCK
-#   ifndef _BSD_CLK_TCK_ /* FreeBSD hack */
-#    define HZ  100.0
-#   else /* _BSD_CLK_TCK_ */
-#    define HZ ((double)_BSD_CLK_TCK_)
-#   endif
-#  else /* CLK_TCK */
-#   define HZ ((double)CLK_TCK)
-#  endif
-# endif
-#endif
-
-struct ms_tm
-	{
-#ifdef TIMES
-	struct tms ms_tms;
-#else
-#  ifdef OPENSSL_SYS_WIN32
-	HANDLE thread_id;
-	FILETIME ms_win32;
-#  elif defined (OPENSSL_SYS_NETWARE)
-   clock_t ms_clock;
-#  else
-#    ifdef OPENSSL_SYS_VXWORKS
-          unsigned long ticks;
-#    else
-	struct timeb ms_timeb;
-#    endif
-#  endif
-#endif
-	};
-
-MS_TM *ms_time_new(void)
-	{
-	MS_TM *ret;
-
-	ret=(MS_TM *)OPENSSL_malloc(sizeof(MS_TM));
-	if (ret == NULL)
-		return(NULL);
-	memset(ret,0,sizeof(MS_TM));
-#ifdef OPENSSL_SYS_WIN32
-	ret->thread_id=GetCurrentThread();
-#endif
-	return ret;
-	}
-
-void ms_time_free(MS_TM *a)
-	{
-	if (a != NULL)
-		OPENSSL_free(a);
-	}
-
-void ms_time_get(MS_TM *tm)
-	{
-#ifdef OPENSSL_SYS_WIN32
-	FILETIME tmpa,tmpb,tmpc;
-#endif
-
-#ifdef TIMES
-	times(&tm->ms_tms);
-#else
-#  ifdef OPENSSL_SYS_WIN32
-	GetThreadTimes(tm->thread_id,&tmpa,&tmpb,&tmpc,&(tm->ms_win32));
-#  elif defined (OPENSSL_SYS_NETWARE)
-   tm->ms_clock = clock();
-#  else
-#    ifdef OPENSSL_SYS_VXWORKS
-        tm->ticks = tickGet();
-#    else
-	ftime(&tm->ms_timeb);
-#    endif
-#  endif
-#endif
-	}
-
-double ms_time_diff(MS_TM *a, MS_TM *b)
-	{
-	double ret;
-
-#ifdef TIMES
-	ret = HZ;
-	ret = (b->ms_tms.tms_utime-a->ms_tms.tms_utime) / ret;
-#else
-# ifdef OPENSSL_SYS_WIN32
-	{
-#ifdef __GNUC__
-	signed long long la,lb;
-#else
-	signed _int64 la,lb;
-#endif
-	la=a->ms_win32.dwHighDateTime;
-	lb=b->ms_win32.dwHighDateTime;
-	la<<=32;
-	lb<<=32;
-	la+=a->ms_win32.dwLowDateTime;
-	lb+=b->ms_win32.dwLowDateTime;
-	ret=((double)(lb-la))/1e7;
-	}
-# elif defined (OPENSSL_SYS_NETWARE)
-    ret= (double)(b->ms_clock - a->ms_clock);
-# else
-#  ifdef OPENSSL_SYS_VXWORKS
-        ret = (double)(b->ticks - a->ticks) / (double)sysClkRateGet();
-#  else
-	ret=	 (double)(b->ms_timeb.time-a->ms_timeb.time)+
-		(((double)b->ms_timeb.millitm)-
-		((double)a->ms_timeb.millitm))/1000.0;
-#  endif
-# endif
-#endif
-	return((ret < 0.0000001)?0.0000001:ret);
-	}
-
-int ms_time_cmp(const MS_TM *a, const MS_TM *b)
-	{
-	double d;
-	int ret;
-
-#ifdef TIMES
-	d = HZ;
-	d = (b->ms_tms.tms_utime-a->ms_tms.tms_utime) / d;
-#else
-# ifdef OPENSSL_SYS_WIN32
-	d =(b->ms_win32.dwHighDateTime&0x000fffff)*10+b->ms_win32.dwLowDateTime/1e7;
-	d-=(a->ms_win32.dwHighDateTime&0x000fffff)*10+a->ms_win32.dwLowDateTime/1e7;
-# elif defined (OPENSSL_SYS_NETWARE)
-    d= (double)(b->ms_clock - a->ms_clock);
-# else
-#  ifdef OPENSSL_SYS_VXWORKS
-        d = (b->ticks - a->ticks);
-#  else
-	d=	 (double)(b->ms_timeb.time-a->ms_timeb.time)+
-		(((double)b->ms_timeb.millitm)-(double)a->ms_timeb.millitm)/1000.0;
-#  endif
-# endif
-#endif
-	if (d == 0.0)
-		ret=0;
-	else if (d < 0)
-		ret= -1;
-	else
-		ret=1;
-	return(ret);
-	}
-
diff --git a/crypto/tmdiff.h b/crypto/tmdiff.h
deleted file mode 100644
index af5c41c..0000000
--- a/crypto/tmdiff.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* crypto/tmdiff.h */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-/* Header for dynamic hash table routines
- * Author - Eric Young
- */
-/* ... erm yeah, "dynamic hash tables" you say?
- * 
- * And what would dynamic hash tables have to do with any of this code *now*?
- * AFAICS, this code is only referenced by crypto/bn/exp.c which is an unused
- * file that I doubt compiles any more. speed.c is the only thing that could
- * use this (and it has nothing to do with hash tables), yet it instead has its
- * own duplication of all this stuff and looks, if anything, more complete. See
- * the corresponding note in apps/speed.c.
- * The Bemused - Geoff
- */
-
-#ifndef HEADER_TMDIFF_H
-#define HEADER_TMDIFF_H
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-typedef struct ms_tm MS_TM;
-
-MS_TM *ms_time_new(void );
-void ms_time_free(MS_TM *a);
-void ms_time_get(MS_TM *a);
-double ms_time_diff(MS_TM *start, MS_TM *end);
-int ms_time_cmp(const MS_TM *ap, const MS_TM *bp);
-
-#ifdef  __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/crypto/ts/ts_err.c b/crypto/ts/ts_err.c
new file mode 100644
index 0000000..a08b0ff
--- /dev/null
+++ b/crypto/ts/ts_err.c
@@ -0,0 +1,179 @@
+/* crypto/ts/ts_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/ts.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_TS,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_TS,0,reason)
+
+static ERR_STRING_DATA TS_str_functs[]=
+	{
+{ERR_FUNC(TS_F_D2I_TS_RESP),	"d2i_TS_RESP"},
+{ERR_FUNC(TS_F_DEF_SERIAL_CB),	"DEF_SERIAL_CB"},
+{ERR_FUNC(TS_F_DEF_TIME_CB),	"DEF_TIME_CB"},
+{ERR_FUNC(TS_F_ESS_ADD_SIGNING_CERT),	"ESS_ADD_SIGNING_CERT"},
+{ERR_FUNC(TS_F_ESS_CERT_ID_NEW_INIT),	"ESS_CERT_ID_NEW_INIT"},
+{ERR_FUNC(TS_F_ESS_SIGNING_CERT_NEW_INIT),	"ESS_SIGNING_CERT_NEW_INIT"},
+{ERR_FUNC(TS_F_INT_TS_RESP_VERIFY_TOKEN),	"INT_TS_RESP_VERIFY_TOKEN"},
+{ERR_FUNC(TS_F_PKCS7_TO_TS_TST_INFO),	"PKCS7_to_TS_TST_INFO"},
+{ERR_FUNC(TS_F_TS_ACCURACY_SET_MICROS),	"TS_ACCURACY_set_micros"},
+{ERR_FUNC(TS_F_TS_ACCURACY_SET_MILLIS),	"TS_ACCURACY_set_millis"},
+{ERR_FUNC(TS_F_TS_ACCURACY_SET_SECONDS),	"TS_ACCURACY_set_seconds"},
+{ERR_FUNC(TS_F_TS_CHECK_IMPRINTS),	"TS_CHECK_IMPRINTS"},
+{ERR_FUNC(TS_F_TS_CHECK_NONCES),	"TS_CHECK_NONCES"},
+{ERR_FUNC(TS_F_TS_CHECK_POLICY),	"TS_CHECK_POLICY"},
+{ERR_FUNC(TS_F_TS_CHECK_SIGNING_CERTS),	"TS_CHECK_SIGNING_CERTS"},
+{ERR_FUNC(TS_F_TS_CHECK_STATUS_INFO),	"TS_CHECK_STATUS_INFO"},
+{ERR_FUNC(TS_F_TS_COMPUTE_IMPRINT),	"TS_COMPUTE_IMPRINT"},
+{ERR_FUNC(TS_F_TS_CONF_SET_DEFAULT_ENGINE),	"TS_CONF_set_default_engine"},
+{ERR_FUNC(TS_F_TS_GET_STATUS_TEXT),	"TS_GET_STATUS_TEXT"},
+{ERR_FUNC(TS_F_TS_MSG_IMPRINT_SET_ALGO),	"TS_MSG_IMPRINT_set_algo"},
+{ERR_FUNC(TS_F_TS_REQ_SET_MSG_IMPRINT),	"TS_REQ_set_msg_imprint"},
+{ERR_FUNC(TS_F_TS_REQ_SET_NONCE),	"TS_REQ_set_nonce"},
+{ERR_FUNC(TS_F_TS_REQ_SET_POLICY_ID),	"TS_REQ_set_policy_id"},
+{ERR_FUNC(TS_F_TS_RESP_CREATE_RESPONSE),	"TS_RESP_create_response"},
+{ERR_FUNC(TS_F_TS_RESP_CREATE_TST_INFO),	"TS_RESP_CREATE_TST_INFO"},
+{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO),	"TS_RESP_CTX_add_failure_info"},
+{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_MD),	"TS_RESP_CTX_add_md"},
+{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_POLICY),	"TS_RESP_CTX_add_policy"},
+{ERR_FUNC(TS_F_TS_RESP_CTX_NEW),	"TS_RESP_CTX_new"},
+{ERR_FUNC(TS_F_TS_RESP_CTX_SET_ACCURACY),	"TS_RESP_CTX_set_accuracy"},
+{ERR_FUNC(TS_F_TS_RESP_CTX_SET_CERTS),	"TS_RESP_CTX_set_certs"},
+{ERR_FUNC(TS_F_TS_RESP_CTX_SET_DEF_POLICY),	"TS_RESP_CTX_set_def_policy"},
+{ERR_FUNC(TS_F_TS_RESP_CTX_SET_SIGNER_CERT),	"TS_RESP_CTX_set_signer_cert"},
+{ERR_FUNC(TS_F_TS_RESP_CTX_SET_STATUS_INFO),	"TS_RESP_CTX_set_status_info"},
+{ERR_FUNC(TS_F_TS_RESP_GET_POLICY),	"TS_RESP_GET_POLICY"},
+{ERR_FUNC(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION),	"TS_RESP_SET_GENTIME_WITH_PRECISION"},
+{ERR_FUNC(TS_F_TS_RESP_SET_STATUS_INFO),	"TS_RESP_set_status_info"},
+{ERR_FUNC(TS_F_TS_RESP_SET_TST_INFO),	"TS_RESP_set_tst_info"},
+{ERR_FUNC(TS_F_TS_RESP_SIGN),	"TS_RESP_SIGN"},
+{ERR_FUNC(TS_F_TS_RESP_VERIFY_SIGNATURE),	"TS_RESP_verify_signature"},
+{ERR_FUNC(TS_F_TS_RESP_VERIFY_TOKEN),	"TS_RESP_verify_token"},
+{ERR_FUNC(TS_F_TS_TST_INFO_SET_ACCURACY),	"TS_TST_INFO_set_accuracy"},
+{ERR_FUNC(TS_F_TS_TST_INFO_SET_MSG_IMPRINT),	"TS_TST_INFO_set_msg_imprint"},
+{ERR_FUNC(TS_F_TS_TST_INFO_SET_NONCE),	"TS_TST_INFO_set_nonce"},
+{ERR_FUNC(TS_F_TS_TST_INFO_SET_POLICY_ID),	"TS_TST_INFO_set_policy_id"},
+{ERR_FUNC(TS_F_TS_TST_INFO_SET_SERIAL),	"TS_TST_INFO_set_serial"},
+{ERR_FUNC(TS_F_TS_TST_INFO_SET_TIME),	"TS_TST_INFO_set_time"},
+{ERR_FUNC(TS_F_TS_TST_INFO_SET_TSA),	"TS_TST_INFO_set_tsa"},
+{ERR_FUNC(TS_F_TS_VERIFY),	"TS_VERIFY"},
+{ERR_FUNC(TS_F_TS_VERIFY_CERT),	"TS_VERIFY_CERT"},
+{ERR_FUNC(TS_F_TS_VERIFY_CTX_NEW),	"TS_VERIFY_CTX_new"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA TS_str_reasons[]=
+	{
+{ERR_REASON(TS_R_BAD_PKCS7_TYPE)         ,"bad pkcs7 type"},
+{ERR_REASON(TS_R_BAD_TYPE)               ,"bad type"},
+{ERR_REASON(TS_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"},
+{ERR_REASON(TS_R_COULD_NOT_SET_ENGINE)   ,"could not set engine"},
+{ERR_REASON(TS_R_COULD_NOT_SET_TIME)     ,"could not set time"},
+{ERR_REASON(TS_R_D2I_TS_RESP_INT_FAILED) ,"d2i ts resp int failed"},
+{ERR_REASON(TS_R_DETACHED_CONTENT)       ,"detached content"},
+{ERR_REASON(TS_R_ESS_ADD_SIGNING_CERT_ERROR),"ess add signing cert error"},
+{ERR_REASON(TS_R_ESS_SIGNING_CERTIFICATE_ERROR),"ess signing certificate error"},
+{ERR_REASON(TS_R_INVALID_NULL_POINTER)   ,"invalid null pointer"},
+{ERR_REASON(TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE),"invalid signer certificate purpose"},
+{ERR_REASON(TS_R_MESSAGE_IMPRINT_MISMATCH),"message imprint mismatch"},
+{ERR_REASON(TS_R_NONCE_MISMATCH)         ,"nonce mismatch"},
+{ERR_REASON(TS_R_NONCE_NOT_RETURNED)     ,"nonce not returned"},
+{ERR_REASON(TS_R_NO_CONTENT)             ,"no content"},
+{ERR_REASON(TS_R_NO_TIME_STAMP_TOKEN)    ,"no time stamp token"},
+{ERR_REASON(TS_R_PKCS7_ADD_SIGNATURE_ERROR),"pkcs7 add signature error"},
+{ERR_REASON(TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR),"pkcs7 add signed attr error"},
+{ERR_REASON(TS_R_PKCS7_TO_TS_TST_INFO_FAILED),"pkcs7 to ts tst info failed"},
+{ERR_REASON(TS_R_POLICY_MISMATCH)        ,"policy mismatch"},
+{ERR_REASON(TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
+{ERR_REASON(TS_R_RESPONSE_SETUP_ERROR)   ,"response setup error"},
+{ERR_REASON(TS_R_SIGNATURE_FAILURE)      ,"signature failure"},
+{ERR_REASON(TS_R_THERE_MUST_BE_ONE_SIGNER),"there must be one signer"},
+{ERR_REASON(TS_R_TIME_SYSCALL_ERROR)     ,"time syscall error"},
+{ERR_REASON(TS_R_TOKEN_NOT_PRESENT)      ,"token not present"},
+{ERR_REASON(TS_R_TOKEN_PRESENT)          ,"token present"},
+{ERR_REASON(TS_R_TSA_NAME_MISMATCH)      ,"tsa name mismatch"},
+{ERR_REASON(TS_R_TSA_UNTRUSTED)          ,"tsa untrusted"},
+{ERR_REASON(TS_R_TST_INFO_SETUP_ERROR)   ,"tst info setup error"},
+{ERR_REASON(TS_R_TS_DATASIGN)            ,"ts datasign"},
+{ERR_REASON(TS_R_UNACCEPTABLE_POLICY)    ,"unacceptable policy"},
+{ERR_REASON(TS_R_UNSUPPORTED_MD_ALGORITHM),"unsupported md algorithm"},
+{ERR_REASON(TS_R_UNSUPPORTED_VERSION)    ,"unsupported version"},
+{ERR_REASON(TS_R_WRONG_CONTENT_TYPE)     ,"wrong content type"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_TS_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(TS_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,TS_str_functs);
+		ERR_load_strings(0,TS_str_reasons);
+		}
+#endif
+	}
diff --git a/crypto/txt_db/Makefile b/crypto/txt_db/Makefile
deleted file mode 100644
index 87e57b4..0000000
--- a/crypto/txt_db/Makefile
+++ /dev/null
@@ -1,84 +0,0 @@
-#
-# OpenSSL/crypto/txt_db/Makefile
-#
-
-DIR=	txt_db
-TOP=	../..
-CC=	cc
-INCLUDES=
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=txt_db.c
-LIBOBJ=txt_db.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= txt_db.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-depend:
-	@[ -n "$(MAKEDEPEND)" ] # should be set by top 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 *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-txt_db.o: ../../e_os.h ../../include/openssl/bio.h
-txt_db.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-txt_db.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-txt_db.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-txt_db.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-txt_db.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-txt_db.o: ../../include/openssl/symhacks.h ../../include/openssl/txt_db.h
-txt_db.o: ../cryptlib.h txt_db.c
diff --git a/crypto/txt_db/txt_db.c b/crypto/txt_db/txt_db.c
index 3ed5f72..6f2ce3b 100644
--- a/crypto/txt_db/txt_db.c
+++ b/crypto/txt_db/txt_db.c
@@ -77,22 +77,23 @@
 	int i,add,n;
 	int size=BUFSIZE;
 	int offset=0;
-	char *p,**pp,*f;
+	char *p,*f;
+	OPENSSL_STRING *pp;
 	BUF_MEM *buf=NULL;
 
 	if ((buf=BUF_MEM_new()) == NULL) goto err;
 	if (!BUF_MEM_grow(buf,size)) goto err;
 
-	if ((ret=(TXT_DB *)OPENSSL_malloc(sizeof(TXT_DB))) == NULL)
+	if ((ret=OPENSSL_malloc(sizeof(TXT_DB))) == NULL)
 		goto err;
 	ret->num_fields=num;
 	ret->index=NULL;
 	ret->qual=NULL;
-	if ((ret->data=sk_new_null()) == NULL)
+	if ((ret->data=sk_OPENSSL_PSTRING_new_null()) == NULL)
 		goto err;
-	if ((ret->index=(LHASH **)OPENSSL_malloc(sizeof(LHASH *)*num)) == NULL)
+	if ((ret->index=OPENSSL_malloc(sizeof(*ret->index)*num)) == NULL)
 		goto err;
-	if ((ret->qual=(int (**)(char **))OPENSSL_malloc(sizeof(int (**)(char **))*num)) == NULL)
+	if ((ret->qual=OPENSSL_malloc(sizeof(*(ret->qual))*num)) == NULL)
 		goto err;
 	for (i=0; i<num; i++)
 		{
@@ -122,7 +123,7 @@
 		else
 			{
 			buf->data[offset-1]='\0'; /* blat the '\n' */
-			if (!(p=(char *)OPENSSL_malloc(add+offset))) goto err;
+			if (!(p=OPENSSL_malloc(add+offset))) goto err;
 			offset=0;
 			}
 		pp=(char **)p;
@@ -155,16 +156,16 @@
 		*(p++)='\0';
 		if ((n != num) || (*f != '\0'))
 			{
-#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)	/* temporaty fix :-( */
+#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)	/* temporary fix :-( */
 			fprintf(stderr,"wrong number of fields on line %ld (looking for field %d, got %d, '%s' left)\n",ln,num,n,f);
 #endif
 			er=2;
 			goto err;
 			}
 		pp[n]=p;
-		if (!sk_push(ret->data,(char *)pp))
+		if (!sk_OPENSSL_PSTRING_push(ret->data,pp))
 			{
-#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)	/* temporaty fix :-( */
+#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)	/* temporary fix :-( */
 			fprintf(stderr,"failure in sk_push\n");
 #endif
 			er=2;
@@ -181,7 +182,7 @@
 #endif
 		if (ret != NULL)
 			{
-			if (ret->data != NULL) sk_free(ret->data);
+			if (ret->data != NULL) sk_OPENSSL_PSTRING_free(ret->data);
 			if (ret->index != NULL) OPENSSL_free(ret->index);
 			if (ret->qual != NULL) OPENSSL_free(ret->qual);
 			if (ret != NULL) OPENSSL_free(ret);
@@ -192,10 +193,10 @@
 		return(ret);
 	}
 
-char **TXT_DB_get_by_index(TXT_DB *db, int idx, char **value)
+OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, OPENSSL_STRING *value)
 	{
-	char **ret;
-	LHASH *lh;
+	OPENSSL_STRING *ret;
+	LHASH_OF(OPENSSL_STRING) *lh;
 
 	if (idx >= db->num_fields)
 		{
@@ -208,16 +209,16 @@
 		db->error=DB_ERROR_NO_INDEX;
 		return(NULL);
 		}
-	ret=(char **)lh_retrieve(lh,value);
+	ret=lh_OPENSSL_STRING_retrieve(lh,value);
 	db->error=DB_ERROR_OK;
 	return(ret);
 	}
 
-int TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(char **),
-		LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp)
+int TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(OPENSSL_STRING *),
+			LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp)
 	{
-	LHASH *idx;
-	char **r;
+	LHASH_OF(OPENSSL_STRING) *idx;
+	OPENSSL_STRING *r;
 	int i,n;
 
 	if (field >= db->num_fields)
@@ -225,26 +226,27 @@
 		db->error=DB_ERROR_INDEX_OUT_OF_RANGE;
 		return(0);
 		}
-	if ((idx=lh_new(hash,cmp)) == NULL)
+	/* FIXME: we lose type checking at this point */
+	if ((idx=(LHASH_OF(OPENSSL_STRING) *)lh_new(hash,cmp)) == NULL)
 		{
 		db->error=DB_ERROR_MALLOC;
 		return(0);
 		}
-	n=sk_num(db->data);
+	n=sk_OPENSSL_PSTRING_num(db->data);
 	for (i=0; i<n; i++)
 		{
-		r=(char **)sk_value(db->data,i);
+		r=sk_OPENSSL_PSTRING_value(db->data,i);
 		if ((qual != NULL) && (qual(r) == 0)) continue;
-		if ((r=lh_insert(idx,r)) != NULL)
+		if ((r=lh_OPENSSL_STRING_insert(idx,r)) != NULL)
 			{
 			db->error=DB_ERROR_INDEX_CLASH;
-			db->arg1=sk_find(db->data,(char *)r);
+			db->arg1=sk_OPENSSL_PSTRING_find(db->data,r);
 			db->arg2=i;
-			lh_free(idx);
+			lh_OPENSSL_STRING_free(idx);
 			return(0);
 			}
 		}
-	if (db->index[field] != NULL) lh_free(db->index[field]);
+	if (db->index[field] != NULL) lh_OPENSSL_STRING_free(db->index[field]);
 	db->index[field]=idx;
 	db->qual[field]=qual;
 	return(1);
@@ -259,11 +261,11 @@
 
 	if ((buf=BUF_MEM_new()) == NULL)
 		goto err;
-	n=sk_num(db->data);
+	n=sk_OPENSSL_PSTRING_num(db->data);
 	nn=db->num_fields;
 	for (i=0; i<n; i++)
 		{
-		pp=(char **)sk_value(db->data,i);
+		pp=sk_OPENSSL_PSTRING_value(db->data,i);
 
 		l=0;
 		for (j=0; j<nn; j++)
@@ -298,10 +300,10 @@
 	return(ret);
 	}
 
-int TXT_DB_insert(TXT_DB *db, char **row)
+int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *row)
 	{
 	int i;
-	char **r;
+	OPENSSL_STRING *r;
 
 	for (i=0; i<db->num_fields; i++)
 		{
@@ -309,7 +311,7 @@
 			{
 			if ((db->qual[i] != NULL) &&
 				(db->qual[i](row) == 0)) continue;
-			r=(char **)lh_retrieve(db->index[i],row);
+			r=lh_OPENSSL_STRING_retrieve(db->index[i],row);
 			if (r != NULL)
 				{
 				db->error=DB_ERROR_INDEX_CLASH;
@@ -320,7 +322,7 @@
 			}
 		}
 	/* We have passed the index checks, now just append and insert */
-	if (!sk_push(db->data,(char *)row))
+	if (!sk_OPENSSL_PSTRING_push(db->data,row))
 		{
 		db->error=DB_ERROR_MALLOC;
 		goto err;
@@ -332,7 +334,7 @@
 			{
 			if ((db->qual[i] != NULL) &&
 				(db->qual[i](row) == 0)) continue;
-			lh_insert(db->index[i],row);
+			(void)lh_OPENSSL_STRING_insert(db->index[i],row);
 			}
 		}
 	return(1);
@@ -351,18 +353,18 @@
 	if (db->index != NULL)
 		{
 		for (i=db->num_fields-1; i>=0; i--)
-			if (db->index[i] != NULL) lh_free(db->index[i]);
+			if (db->index[i] != NULL) lh_OPENSSL_STRING_free(db->index[i]);
 		OPENSSL_free(db->index);
 		}
 	if (db->qual != NULL)
 		OPENSSL_free(db->qual);
 	if (db->data != NULL)
 		{
-		for (i=sk_num(db->data)-1; i>=0; i--)
+		for (i=sk_OPENSSL_PSTRING_num(db->data)-1; i>=0; i--)
 			{
 			/* check if any 'fields' have been allocated
 			 * from outside of the initial block */
-			p=(char **)sk_value(db->data,i);
+			p=sk_OPENSSL_PSTRING_value(db->data,i);
 			max=p[db->num_fields]; /* last address */
 			if (max == NULL) /* new row */
 				{
@@ -378,9 +380,9 @@
 						OPENSSL_free(p[n]);
 					}
 				}
-			OPENSSL_free(sk_value(db->data,i));
+			OPENSSL_free(sk_OPENSSL_PSTRING_value(db->data,i));
 			}
-		sk_free(db->data);
+		sk_OPENSSL_PSTRING_free(db->data);
 		}
 	OPENSSL_free(db);
 	}
diff --git a/crypto/txt_db/txt_db.h b/crypto/txt_db/txt_db.h
index 307e1ba..6abe435 100644
--- a/crypto/txt_db/txt_db.h
+++ b/crypto/txt_db/txt_db.h
@@ -77,16 +77,19 @@
 extern "C" {
 #endif
 
+typedef OPENSSL_STRING *OPENSSL_PSTRING;
+DECLARE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING)
+
 typedef struct txt_db_st
 	{
 	int num_fields;
-	STACK /* char ** */ *data;
-	LHASH **index;
-	int (**qual)(char **);
+	STACK_OF(OPENSSL_PSTRING) *data;
+	LHASH_OF(OPENSSL_STRING) **index;
+	int (**qual)(OPENSSL_STRING *);
 	long error;
 	long arg1;
 	long arg2;
-	char **arg_row;
+	OPENSSL_STRING *arg_row;
 	} TXT_DB;
 
 #ifndef OPENSSL_NO_BIO
@@ -96,11 +99,11 @@
 TXT_DB *TXT_DB_read(char *in, int num);
 long TXT_DB_write(char *out, TXT_DB *db);
 #endif
-int TXT_DB_create_index(TXT_DB *db,int field,int (*qual)(char **),
-		LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp);
+int TXT_DB_create_index(TXT_DB *db,int field,int (*qual)(OPENSSL_STRING *),
+			LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp);
 void TXT_DB_free(TXT_DB *db);
-char **TXT_DB_get_by_index(TXT_DB *db, int idx, char **value);
-int TXT_DB_insert(TXT_DB *db,char **value);
+OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, OPENSSL_STRING *value);
+int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value);
 
 #ifdef  __cplusplus
 }
diff --git a/crypto/ui/Makefile b/crypto/ui/Makefile
deleted file mode 100644
index 4755e20..0000000
--- a/crypto/ui/Makefile
+++ /dev/null
@@ -1,111 +0,0 @@
-#
-# OpenSSL/crypto/ui/Makefile
-#
-
-DIR=	ui
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-#TEST= uitest.c
-TEST=
-APPS=
-
-COMPATSRC= ui_compat.c
-COMPATOBJ= ui_compat.o
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC= ui_err.c ui_lib.c ui_openssl.c ui_util.c $(COMPATSRC)
-LIBOBJ= ui_err.o ui_lib.o ui_openssl.o ui_util.o $(COMPATOBJ)
-
-SRC= $(LIBSRC)
-
-EXHEADER= ui.h ui_compat.h
-HEADER=	$(EXHEADER) ui_locl.h
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-ui_compat.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-ui_compat.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-ui_compat.o: ../../include/openssl/stack.h ../../include/openssl/ui.h
-ui_compat.o: ../../include/openssl/ui_compat.h ui_compat.c
-ui_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
-ui_err.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-ui_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-ui_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ui_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ui_err.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h ui_err.c
-ui_lib.o: ../../e_os.h ../../include/openssl/bio.h
-ui_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-ui_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-ui_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-ui_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ui_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ui_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
-ui_lib.o: ../cryptlib.h ui_lib.c ui_locl.h
-ui_openssl.o: ../../e_os.h ../../include/openssl/bio.h
-ui_openssl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-ui_openssl.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-ui_openssl.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-ui_openssl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ui_openssl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ui_openssl.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
-ui_openssl.o: ../cryptlib.h ui_locl.h ui_openssl.c
-ui_util.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-ui_util.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-ui_util.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-ui_util.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-ui_util.o: ../../include/openssl/ui.h ui_locl.h ui_util.c
diff --git a/crypto/ui/ui.h b/crypto/ui/ui.h
index 0182964..2b1cfa2 100644
--- a/crypto/ui/ui.h
+++ b/crypto/ui/ui.h
@@ -287,8 +287,8 @@
 /* The UI_STRING type is the data structure that contains all the needed info
    about a string or a prompt, including test data for a verification prompt.
 */
-DECLARE_STACK_OF(UI_STRING)
 typedef struct ui_string_st UI_STRING;
+DECLARE_STACK_OF(UI_STRING)
 
 /* The different types of strings that are currently supported.
    This is only needed by method authors. */
@@ -310,11 +310,13 @@
 int UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui));
 int UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis));
 int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui));
+int UI_method_set_prompt_constructor(UI_METHOD *method, char *(*prompt_constructor)(UI* ui, const char* object_desc, const char* object_name));
 int (*UI_method_get_opener(UI_METHOD *method))(UI*);
 int (*UI_method_get_writer(UI_METHOD *method))(UI*,UI_STRING*);
 int (*UI_method_get_flusher(UI_METHOD *method))(UI*);
 int (*UI_method_get_reader(UI_METHOD *method))(UI*,UI_STRING*);
 int (*UI_method_get_closer(UI_METHOD *method))(UI*);
+char* (*UI_method_get_prompt_constructor(UI_METHOD *method))(UI*, const char*, const char*);
 
 /* The following functions are helpers for method writers to access relevant
    data from a UI_STRING. */
diff --git a/crypto/ui/ui_err.c b/crypto/ui/ui_err.c
index 786bd0d..a6b9629 100644
--- a/crypto/ui/ui_err.c
+++ b/crypto/ui/ui_err.c
@@ -1,6 +1,6 @@
 /* crypto/ui/ui_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
diff --git a/crypto/ui/ui_lib.c b/crypto/ui/ui_lib.c
index ac01008..a8abc27 100644
--- a/crypto/ui/ui_lib.c
+++ b/crypto/ui/ui_lib.c
@@ -693,6 +693,17 @@
 		return -1;
 	}
 
+int UI_method_set_prompt_constructor(UI_METHOD *method, char *(*prompt_constructor)(UI* ui, const char* object_desc, const char* object_name))
+	{
+	if (method)
+		{
+		method->ui_construct_prompt = prompt_constructor;
+		return 0;
+		}
+	else
+		return -1;
+	}
+
 int (*UI_method_get_opener(UI_METHOD *method))(UI*)
 	{
 	if (method)
@@ -733,6 +744,14 @@
 		return NULL;
 	}
 
+char* (*UI_method_get_prompt_constructor(UI_METHOD *method))(UI*, const char*, const char*)
+	{
+	if (method)
+		return method->ui_construct_prompt;
+	else
+		return NULL;
+	}
+
 enum UI_string_types UI_get_string_type(UI_STRING *uis)
 	{
 	if (!uis)
diff --git a/crypto/ui/ui_openssl.c b/crypto/ui/ui_openssl.c
index 06270f0..1bc25f4 100644
--- a/crypto/ui/ui_openssl.c
+++ b/crypto/ui/ui_openssl.c
@@ -122,7 +122,9 @@
  * sigaction and fileno included. -pedantic would be more appropriate for
  * the intended purposes, but we can't prevent users from adding -ansi.
  */
-#define _POSIX_C_SOURCE 1
+#ifndef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 2
+#endif
 #include <signal.h>
 #include <stdio.h>
 #include <string.h>
@@ -476,7 +478,7 @@
 	CRYPTO_w_lock(CRYPTO_LOCK_UI);
 	is_a_tty = 1;
 
-#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)
+#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS)
 	tty_in=stdin;
 	tty_out=stderr;
 #else
diff --git a/crypto/x509/Makefile b/crypto/x509/Makefile
deleted file mode 100644
index 464752b..0000000
--- a/crypto/x509/Makefile
+++ /dev/null
@@ -1,417 +0,0 @@
-#
-# OpenSSL/crypto/x509/Makefile
-#
-
-DIR=	x509
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile README
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=	x509_def.c x509_d2.c x509_r2x.c x509_cmp.c \
-	x509_obj.c x509_req.c x509spki.c x509_vfy.c \
-	x509_set.c x509cset.c x509rset.c x509_err.c \
-	x509name.c x509_v3.c x509_ext.c x509_att.c \
-	x509type.c x509_lu.c x_all.c x509_txt.c \
-	x509_trs.c by_file.c by_dir.c x509_vpm.c
-LIBOBJ= x509_def.o x509_d2.o x509_r2x.o x509_cmp.o \
-	x509_obj.o x509_req.o x509spki.o x509_vfy.o \
-	x509_set.o x509cset.o x509rset.o x509_err.o \
-	x509name.o x509_v3.o x509_ext.o x509_att.o \
-	x509type.o x509_lu.o x_all.o x509_txt.o \
-	x509_trs.o by_file.o by_dir.o x509_vpm.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= x509.h x509_vfy.h
-HEADER=	$(EXHEADER)
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-by_dir.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-by_dir.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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/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/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
-x509_att.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509_att.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-x509_att.o: ../cryptlib.h x509_att.c
-x509_cmp.o: ../../e_os.h ../../include/openssl/asn1.h
-x509_cmp.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-x509_cmp.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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
-x509_cmp.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509_cmp.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-x509_cmp.o: ../cryptlib.h x509_cmp.c
-x509_d2.o: ../../e_os.h ../../include/openssl/asn1.h
-x509_d2.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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/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
-x509_def.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509_def.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_def.c
-x509_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-x509_err.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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
-x509_err.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509_err.o: ../../include/openssl/x509_vfy.h x509_err.c
-x509_ext.o: ../../e_os.h ../../include/openssl/asn1.h
-x509_ext.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-x509_ext.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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
-x509_ext.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509_ext.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-x509_ext.o: ../cryptlib.h x509_ext.c
-x509_lu.o: ../../e_os.h ../../include/openssl/asn1.h
-x509_lu.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-x509_lu.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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/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
-x509_obj.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509_obj.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_obj.c
-x509_r2x.o: ../../e_os.h ../../include/openssl/asn1.h
-x509_r2x.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-x509_r2x.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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
-x509_r2x.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509_r2x.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_r2x.c
-x509_req.o: ../../e_os.h ../../include/openssl/asn1.h
-x509_req.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-x509_req.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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
-x509_req.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-x509_req.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509_req.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_req.c
-x509_set.o: ../../e_os.h ../../include/openssl/asn1.h
-x509_set.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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
-x509_set.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509_set.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_set.c
-x509_trs.o: ../../e_os.h ../../include/openssl/asn1.h
-x509_trs.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-x509_trs.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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
-x509_trs.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509_trs.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-x509_trs.o: ../cryptlib.h x509_trs.c
-x509_txt.o: ../../e_os.h ../../include/openssl/asn1.h
-x509_txt.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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
-x509_txt.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509_txt.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_txt.c
-x509_v3.o: ../../e_os.h ../../include/openssl/asn1.h
-x509_v3.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-x509_v3.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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/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
-x509_vfy.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509_vfy.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-x509_vfy.o: ../cryptlib.h x509_vfy.c
-x509_vpm.o: ../../e_os.h ../../include/openssl/asn1.h
-x509_vpm.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-x509_vpm.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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
-x509_vpm.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509_vpm.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-x509_vpm.o: ../cryptlib.h x509_vpm.c
-x509cset.o: ../../e_os.h ../../include/openssl/asn1.h
-x509cset.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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
-x509cset.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509cset.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509cset.c
-x509name.o: ../../e_os.h ../../include/openssl/asn1.h
-x509name.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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
-x509name.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509name.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509name.c
-x509rset.o: ../../e_os.h ../../include/openssl/asn1.h
-x509rset.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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
-x509rset.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509rset.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509rset.c
-x509spki.o: ../../e_os.h ../../include/openssl/asn1.h
-x509spki.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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
-x509spki.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509spki.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509spki.c
-x509type.o: ../../e_os.h ../../include/openssl/asn1.h
-x509type.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-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/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
-x509type.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509type.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509type.c
-x_all.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-x_all.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-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/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 b3acd80..27ca515 100644
--- a/crypto/x509/by_dir.c
+++ b/crypto/x509/by_dir.c
@@ -65,28 +65,36 @@
 #ifndef NO_SYS_TYPES_H
 # include <sys/types.h>
 #endif
-#ifdef MAC_OS_pre_X
-# include <stat.h>
-#else
+#ifndef OPENSSL_NO_POSIX_IO
 # include <sys/stat.h>
 #endif
 
 #include <openssl/lhash.h>
 #include <openssl/x509.h>
 
-#ifdef _WIN32
-#define stat	_stat
-#endif
+
+typedef struct lookup_dir_hashes_st
+	{
+	unsigned long hash;
+	int suffix;
+	} BY_DIR_HASH;
+
+typedef struct lookup_dir_entry_st
+	{
+	char *dir;
+	int dir_type;
+	STACK_OF(BY_DIR_HASH) *hashes;
+	} BY_DIR_ENTRY;
 
 typedef struct lookup_dir_st
 	{
 	BUF_MEM *buffer;
-	int num_dirs;
-	char **dirs;
-	int *dirs_type;
-	int num_dirs_alloced;
+	STACK_OF(BY_DIR_ENTRY) *dirs;
 	} BY_DIR;
 
+DECLARE_STACK_OF(BY_DIR_HASH)
+DECLARE_STACK_OF(BY_DIR_ENTRY)
+
 static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
 	char **ret);
 static int new_dir(X509_LOOKUP *lu);
@@ -127,7 +135,7 @@
 	case X509_L_ADD_DIR:
 		if (argl == X509_FILETYPE_DEFAULT)
 			{
-			dir=(char *)Getenv(X509_get_default_cert_dir_env());
+			dir=(char *)getenv(X509_get_default_cert_dir_env());
 			if (dir)
 				ret=add_cert_dir(ld,dir,X509_FILETYPE_PEM);
 			else
@@ -156,34 +164,51 @@
 		OPENSSL_free(a);
 		return(0);
 		}
-	a->num_dirs=0;
 	a->dirs=NULL;
-	a->dirs_type=NULL;
-	a->num_dirs_alloced=0;
 	lu->method_data=(char *)a;
 	return(1);
 	}
 
+static void by_dir_hash_free(BY_DIR_HASH *hash)
+	{
+	OPENSSL_free(hash);
+	}
+
+static int by_dir_hash_cmp(const BY_DIR_HASH * const *a,
+			const BY_DIR_HASH * const *b)
+	{
+	if ((*a)->hash > (*b)->hash)
+		return 1;
+	if ((*a)->hash < (*b)->hash)
+		return -1;
+	return 0;
+	}
+
+static void by_dir_entry_free(BY_DIR_ENTRY *ent)
+	{
+	if (ent->dir)
+		OPENSSL_free(ent->dir);
+	if (ent->hashes)
+		sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free);
+	OPENSSL_free(ent);
+	}
+
 static void free_dir(X509_LOOKUP *lu)
 	{
 	BY_DIR *a;
-	int i;
 
 	a=(BY_DIR *)lu->method_data;
-	for (i=0; i<a->num_dirs; i++)
-		if (a->dirs[i] != NULL) OPENSSL_free(a->dirs[i]);
-	if (a->dirs != NULL) OPENSSL_free(a->dirs);
-	if (a->dirs_type != NULL) OPENSSL_free(a->dirs_type);
-	if (a->buffer != NULL) BUF_MEM_free(a->buffer);
+	if (a->dirs != NULL)
+		sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
+	if (a->buffer != NULL)
+		BUF_MEM_free(a->buffer);
 	OPENSSL_free(a);
 	}
 
 static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
 	{
 	int j,len;
-	int *ip;
 	const char *s,*ss,*p;
-	char **pp;
 
 	if (dir == NULL || !*dir)
 	    {
@@ -197,49 +222,52 @@
 		{
 		if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0'))
 			{
+			BY_DIR_ENTRY *ent;
 			ss=s;
 			s=p+1;
 			len=(int)(p-ss);
 			if (len == 0) continue;
-			for (j=0; j<ctx->num_dirs; j++)
-				if (strlen(ctx->dirs[j]) == (size_t)len &&
-				    strncmp(ctx->dirs[j],ss,(unsigned int)len) == 0)
-					break;
-			if (j<ctx->num_dirs)
-				continue;
-			if (ctx->num_dirs_alloced < (ctx->num_dirs+1))
+			for (j=0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++)
 				{
-				ctx->num_dirs_alloced+=10;
-				pp=(char **)OPENSSL_malloc(ctx->num_dirs_alloced*
-					sizeof(char *));
-				ip=(int *)OPENSSL_malloc(ctx->num_dirs_alloced*
-					sizeof(int));
-				if ((pp == NULL) || (ip == NULL))
+				ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j);
+				if (strlen(ent->dir) == (size_t)len &&
+				    strncmp(ent->dir,ss,(unsigned int)len) == 0)
+					break;
+				}
+			if (j < sk_BY_DIR_ENTRY_num(ctx->dirs))
+				continue;
+			if (ctx->dirs == NULL)
+				{
+				ctx->dirs = sk_BY_DIR_ENTRY_new_null();
+				if (!ctx->dirs)
 					{
 					X509err(X509_F_ADD_CERT_DIR,ERR_R_MALLOC_FAILURE);
-					return(0);
+					return 0;
 					}
-				memcpy(pp,ctx->dirs,(ctx->num_dirs_alloced-10)*
-					sizeof(char *));
-				memcpy(ip,ctx->dirs_type,(ctx->num_dirs_alloced-10)*
-					sizeof(int));
-				if (ctx->dirs != NULL)
-					OPENSSL_free(ctx->dirs);
-				if (ctx->dirs_type != NULL)
-					OPENSSL_free(ctx->dirs_type);
-				ctx->dirs=pp;
-				ctx->dirs_type=ip;
 				}
-			ctx->dirs_type[ctx->num_dirs]=type;
-			ctx->dirs[ctx->num_dirs]=(char *)OPENSSL_malloc((unsigned int)len+1);
-			if (ctx->dirs[ctx->num_dirs] == NULL) return(0);
-			strncpy(ctx->dirs[ctx->num_dirs],ss,(unsigned int)len);
-			ctx->dirs[ctx->num_dirs][len]='\0';
-			ctx->num_dirs++;
+			ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY));
+			if (!ent)
+				return 0;
+			ent->dir_type = type;
+			ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp);
+			ent->dir = OPENSSL_malloc((unsigned int)len+1);
+			if (!ent->dir || !ent->hashes)
+				{
+				by_dir_entry_free(ent);
+				return 0;
+				}
+			strncpy(ent->dir,ss,(unsigned int)len);
+			ent->dir[len] = '\0';
+			if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent))
+				{
+				by_dir_entry_free(ent);
+				return 0;
+				}
 			}
-		if (*p == '\0') break;
+		if (*p == '\0')
+			break;
 		}
-	return(1);
+	return 1;
 	}
 
 static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
@@ -260,7 +288,6 @@
 	int i,j,k;
 	unsigned long h;
 	BUF_MEM *b=NULL;
-	struct stat st;
 	X509_OBJECT stmp,*tmp;
 	const char *postfix="";
 
@@ -296,20 +323,45 @@
 	ctx=(BY_DIR *)xl->method_data;
 
 	h=X509_NAME_hash(name);
-	for (i=0; i<ctx->num_dirs; i++)
+	for (i=0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++)
 		{
-		j=strlen(ctx->dirs[i])+1+8+6+1+1;
+		BY_DIR_ENTRY *ent;
+		int idx;
+		BY_DIR_HASH htmp, *hent;
+		ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i);
+		j=strlen(ent->dir)+1+8+6+1+1;
 		if (!BUF_MEM_grow(b,j))
 			{
 			X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_MALLOC_FAILURE);
 			goto finish;
 			}
-		k=0;
+		if (type == X509_LU_CRL && ent->hashes)
+			{
+			htmp.hash = h;
+			CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE);
+			idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
+			if (idx >= 0)
+				{
+				hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
+				k = hent->suffix;
+				}
+			else
+				{
+				hent = NULL;
+				k=0;
+				}
+			CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);
+			}
+		else
+			{
+			k = 0;
+			hent = NULL;
+			}
 		for (;;)
 			{
 			char c = '/';
 #ifdef OPENSSL_SYS_VMS
-			c = ctx->dirs[i][strlen(ctx->dirs[i])-1];
+			c = ent->dir[strlen(ent->dir)-1];
 			if (c != ':' && c != '>' && c != ']')
 				{
 				/* If no separator is present, we assume the
@@ -330,32 +382,40 @@
 				/* This is special.  When c == '\0', no
 				   directory separator should be added. */
 				BIO_snprintf(b->data,b->max,
-					"%s%08lx.%s%d",ctx->dirs[i],h,
+					"%s%08lx.%s%d",ent->dir,h,
 					postfix,k);
 				}
 			else
 				{
 				BIO_snprintf(b->data,b->max,
-					"%s%c%08lx.%s%d",ctx->dirs[i],c,h,
+					"%s%c%08lx.%s%d",ent->dir,c,h,
 					postfix,k);
 				}
-			k++;
+#ifndef OPENSSL_NO_POSIX_IO
+#ifdef _WIN32
+#define stat _stat
+#endif
+			{
+			struct stat st;
 			if (stat(b->data,&st) < 0)
 				break;
+			}
+#endif
 			/* found one. */
 			if (type == X509_LU_X509)
 				{
 				if ((X509_load_cert_file(xl,b->data,
-					ctx->dirs_type[i])) == 0)
+					ent->dir_type)) == 0)
 					break;
 				}
 			else if (type == X509_LU_CRL)
 				{
 				if ((X509_load_crl_file(xl,b->data,
-					ctx->dirs_type[i])) == 0)
+					ent->dir_type)) == 0)
 					break;
 				}
 			/* else case will caught higher up */
+			k++;
 			}
 
 		/* we have added it to the cache so now pull
@@ -366,6 +426,43 @@
 		else tmp = NULL;
 		CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
 
+
+		/* If a CRL, update the last file suffix added for this */
+
+		if (type == X509_LU_CRL)
+			{
+			CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+			/* Look for entry again in case another thread added
+			 * an entry first.
+			 */
+			if (!hent)
+				{
+				htmp.hash = h;
+				idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
+				if (idx >= 0)
+					hent =
+					 sk_BY_DIR_HASH_value(ent->hashes, idx);
+				}
+			if (!hent)
+				{
+				hent = OPENSSL_malloc(sizeof(BY_DIR_HASH));
+				hent->hash = h;
+				hent->suffix = k;
+				if (!sk_BY_DIR_HASH_push(ent->hashes, hent))
+					{
+					CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+					OPENSSL_free(hent);
+					ok = 0;
+					goto finish;
+					}
+				}
+			else if (hent->suffix < k)
+				hent->suffix = k;
+
+			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+
+			}
+
 		if (tmp != NULL)
 			{
 			ok=1;
diff --git a/crypto/x509/by_file.c b/crypto/x509/by_file.c
index a5e0d4a..57b08ee 100644
--- a/crypto/x509/by_file.c
+++ b/crypto/x509/by_file.c
@@ -100,7 +100,7 @@
 	case X509_L_FILE_LOAD:
 		if (argl == X509_FILETYPE_DEFAULT)
 			{
-			file = (char *)Getenv(X509_get_default_cert_file_env());
+			file = (char *)getenv(X509_get_default_cert_file_env());
 			if (file)
 				ok = (X509_load_cert_crl_file(ctx,file,
 					      X509_FILETYPE_PEM) != 0);
diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h
index 8958e34..604f4fb 100644
--- a/crypto/x509/x509.h
+++ b/crypto/x509/x509.h
@@ -157,12 +157,12 @@
 	ASN1_TIME *notAfter;
 	} X509_VAL;
 
-typedef struct X509_pubkey_st
+struct X509_pubkey_st
 	{
 	X509_ALGOR *algor;
 	ASN1_BIT_STRING *public_key;
 	EVP_PKEY *pkey;
-	} X509_PUBKEY;
+	};
 
 typedef struct X509_sig_st
 	{
@@ -191,7 +191,9 @@
 #else
 	char *bytes;
 #endif
-	unsigned long hash; /* Keep the hash around for lookups */
+/*	unsigned long hash; Keep the hash around for lookups */
+	unsigned char *canon_enc;
+	int canon_enclen;
 	} /* X509_NAME */;
 
 DECLARE_STACK_OF(X509_NAME)
@@ -290,8 +292,11 @@
 	unsigned long ex_xkusage;
 	unsigned long ex_nscert;
 	ASN1_OCTET_STRING *skid;
-	struct AUTHORITY_KEYID_st *akid;
+	AUTHORITY_KEYID *akid;
 	X509_POLICY_CACHE *policy_cache;
+	STACK_OF(DIST_POINT) *crldp;
+	STACK_OF(GENERAL_NAME) *altname;
+	NAME_CONSTRAINTS *nc;
 #ifndef OPENSSL_NO_RFC3779
 	STACK_OF(IPAddressFamily) *rfc3779_addr;
 	struct ASIdentifiers_st *rfc3779_asid;
@@ -334,10 +339,11 @@
 #define X509_TRUST_OBJECT_SIGN	5
 #define X509_TRUST_OCSP_SIGN	6
 #define X509_TRUST_OCSP_REQUEST	7
+#define X509_TRUST_TSA		8
 
 /* Keep these up to date! */
 #define X509_TRUST_MIN		1
-#define X509_TRUST_MAX		7
+#define X509_TRUST_MAX		8
 
 
 /* trust_flags values */
@@ -424,13 +430,17 @@
 			XN_FLAG_FN_LN | \
 			XN_FLAG_FN_ALIGN)
 
-typedef struct X509_revoked_st
+struct x509_revoked_st
 	{
 	ASN1_INTEGER *serialNumber;
 	ASN1_TIME *revocationDate;
 	STACK_OF(X509_EXTENSION) /* optional */ *extensions;
+	/* Set up if indirect CRL */
+	STACK_OF(GENERAL_NAME) *issuer;
+	/* Revocation reason */
+	int reason;
 	int sequence; /* load sequence */
-	} X509_REVOKED;
+	};
 
 DECLARE_STACK_OF(X509_REVOKED)
 DECLARE_ASN1_SET_OF(X509_REVOKED)
@@ -454,6 +464,22 @@
 	X509_ALGOR *sig_alg;
 	ASN1_BIT_STRING *signature;
 	int references;
+	int flags;
+	/* Copies of various extensions */
+	AUTHORITY_KEYID *akid;
+	ISSUING_DIST_POINT *idp;
+	/* Convenient breakdown of IDP */
+	int idp_flags;
+	int idp_reasons;
+	/* CRL and base CRL numbers for delta processing */
+	ASN1_INTEGER *crl_number;
+	ASN1_INTEGER *base_crl_number;
+#ifndef OPENSSL_NO_SHA
+	unsigned char sha1_hash[SHA_DIGEST_LENGTH];
+#endif
+	STACK_OF(GENERAL_NAMES) *issuers;
+	const X509_CRL_METHOD *meth;
+	void *meth_data;
 	} /* X509_CRL */;
 
 DECLARE_STACK_OF(X509_CRL)
@@ -552,18 +578,19 @@
 
 /* PKCS#8 private key info structure */
 
-typedef struct pkcs8_priv_key_info_st
+struct pkcs8_priv_key_info_st
         {
         int broken;     /* Flag for various broken formats */
 #define PKCS8_OK		0
 #define PKCS8_NO_OCTET		1
 #define PKCS8_EMBEDDED_PARAM	2
 #define PKCS8_NS_DB		3
+#define PKCS8_NEG_PRIVKEY	4
         ASN1_INTEGER *version;
         X509_ALGOR *pkeyalg;
         ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */
         STACK_OF(X509_ATTRIBUTE) *attributes;
-        } PKCS8_PRIV_KEY_INFO;
+        };
 
 #ifdef  __cplusplus
 }
@@ -576,151 +603,6 @@
 extern "C" {
 #endif
 
-#ifdef SSLEAY_MACROS
-#define X509_verify(a,r) ASN1_verify((int (*)())i2d_X509_CINF,a->sig_alg,\
-	a->signature,(char *)a->cert_info,r)
-#define X509_REQ_verify(a,r) ASN1_verify((int (*)())i2d_X509_REQ_INFO, \
-	a->sig_alg,a->signature,(char *)a->req_info,r)
-#define X509_CRL_verify(a,r) ASN1_verify((int (*)())i2d_X509_CRL_INFO, \
-	a->sig_alg, a->signature,(char *)a->crl,r)
-
-#define X509_sign(x,pkey,md) \
-	ASN1_sign((int (*)())i2d_X509_CINF, x->cert_info->signature, \
-		x->sig_alg, x->signature, (char *)x->cert_info,pkey,md)
-#define X509_REQ_sign(x,pkey,md) \
-	ASN1_sign((int (*)())i2d_X509_REQ_INFO,x->sig_alg, NULL, \
-		x->signature, (char *)x->req_info,pkey,md)
-#define X509_CRL_sign(x,pkey,md) \
-	ASN1_sign((int (*)())i2d_X509_CRL_INFO,x->crl->sig_alg,x->sig_alg, \
-		x->signature, (char *)x->crl,pkey,md)
-#define NETSCAPE_SPKI_sign(x,pkey,md) \
-	ASN1_sign((int (*)())i2d_NETSCAPE_SPKAC, x->sig_algor,NULL, \
-		x->signature, (char *)x->spkac,pkey,md)
-
-#define X509_dup(x509) (X509 *)ASN1_dup((int (*)())i2d_X509, \
-		(char *(*)())d2i_X509,(char *)x509)
-#define X509_ATTRIBUTE_dup(xa) (X509_ATTRIBUTE *)ASN1_dup(\
-		(int (*)())i2d_X509_ATTRIBUTE, \
-		(char *(*)())d2i_X509_ATTRIBUTE,(char *)xa)
-#define X509_EXTENSION_dup(ex) (X509_EXTENSION *)ASN1_dup( \
-		(int (*)())i2d_X509_EXTENSION, \
-		(char *(*)())d2i_X509_EXTENSION,(char *)ex)
-#define d2i_X509_fp(fp,x509) (X509 *)ASN1_d2i_fp((char *(*)())X509_new, \
-		(char *(*)())d2i_X509, (fp),(unsigned char **)(x509))
-#define i2d_X509_fp(fp,x509) ASN1_i2d_fp(i2d_X509,fp,(unsigned char *)x509)
-#define d2i_X509_bio(bp,x509) (X509 *)ASN1_d2i_bio((char *(*)())X509_new, \
-		(char *(*)())d2i_X509, (bp),(unsigned char **)(x509))
-#define i2d_X509_bio(bp,x509) ASN1_i2d_bio(i2d_X509,bp,(unsigned char *)x509)
-
-#define X509_CRL_dup(crl) (X509_CRL *)ASN1_dup((int (*)())i2d_X509_CRL, \
-		(char *(*)())d2i_X509_CRL,(char *)crl)
-#define d2i_X509_CRL_fp(fp,crl) (X509_CRL *)ASN1_d2i_fp((char *(*)()) \
-		X509_CRL_new,(char *(*)())d2i_X509_CRL, (fp),\
-		(unsigned char **)(crl))
-#define i2d_X509_CRL_fp(fp,crl) ASN1_i2d_fp(i2d_X509_CRL,fp,\
-		(unsigned char *)crl)
-#define d2i_X509_CRL_bio(bp,crl) (X509_CRL *)ASN1_d2i_bio((char *(*)()) \
-		X509_CRL_new,(char *(*)())d2i_X509_CRL, (bp),\
-		(unsigned char **)(crl))
-#define i2d_X509_CRL_bio(bp,crl) ASN1_i2d_bio(i2d_X509_CRL,bp,\
-		(unsigned char *)crl)
-
-#define PKCS7_dup(p7) (PKCS7 *)ASN1_dup((int (*)())i2d_PKCS7, \
-		(char *(*)())d2i_PKCS7,(char *)p7)
-#define d2i_PKCS7_fp(fp,p7) (PKCS7 *)ASN1_d2i_fp((char *(*)()) \
-		PKCS7_new,(char *(*)())d2i_PKCS7, (fp),\
-		(unsigned char **)(p7))
-#define i2d_PKCS7_fp(fp,p7) ASN1_i2d_fp(i2d_PKCS7,fp,\
-		(unsigned char *)p7)
-#define d2i_PKCS7_bio(bp,p7) (PKCS7 *)ASN1_d2i_bio((char *(*)()) \
-		PKCS7_new,(char *(*)())d2i_PKCS7, (bp),\
-		(unsigned char **)(p7))
-#define i2d_PKCS7_bio(bp,p7) ASN1_i2d_bio(i2d_PKCS7,bp,\
-		(unsigned char *)p7)
-
-#define X509_REQ_dup(req) (X509_REQ *)ASN1_dup((int (*)())i2d_X509_REQ, \
-		(char *(*)())d2i_X509_REQ,(char *)req)
-#define d2i_X509_REQ_fp(fp,req) (X509_REQ *)ASN1_d2i_fp((char *(*)())\
-		X509_REQ_new, (char *(*)())d2i_X509_REQ, (fp),\
-		(unsigned char **)(req))
-#define i2d_X509_REQ_fp(fp,req) ASN1_i2d_fp(i2d_X509_REQ,fp,\
-		(unsigned char *)req)
-#define d2i_X509_REQ_bio(bp,req) (X509_REQ *)ASN1_d2i_bio((char *(*)())\
-		X509_REQ_new, (char *(*)())d2i_X509_REQ, (bp),\
-		(unsigned char **)(req))
-#define i2d_X509_REQ_bio(bp,req) ASN1_i2d_bio(i2d_X509_REQ,bp,\
-		(unsigned char *)req)
-
-#define RSAPublicKey_dup(rsa) (RSA *)ASN1_dup((int (*)())i2d_RSAPublicKey, \
-		(char *(*)())d2i_RSAPublicKey,(char *)rsa)
-#define RSAPrivateKey_dup(rsa) (RSA *)ASN1_dup((int (*)())i2d_RSAPrivateKey, \
-		(char *(*)())d2i_RSAPrivateKey,(char *)rsa)
-
-#define d2i_RSAPrivateKey_fp(fp,rsa) (RSA *)ASN1_d2i_fp((char *(*)())\
-		RSA_new,(char *(*)())d2i_RSAPrivateKey, (fp), \
-		(unsigned char **)(rsa))
-#define i2d_RSAPrivateKey_fp(fp,rsa) ASN1_i2d_fp(i2d_RSAPrivateKey,fp, \
-		(unsigned char *)rsa)
-#define d2i_RSAPrivateKey_bio(bp,rsa) (RSA *)ASN1_d2i_bio((char *(*)())\
-		RSA_new,(char *(*)())d2i_RSAPrivateKey, (bp), \
-		(unsigned char **)(rsa))
-#define i2d_RSAPrivateKey_bio(bp,rsa) ASN1_i2d_bio(i2d_RSAPrivateKey,bp, \
-		(unsigned char *)rsa)
-
-#define d2i_RSAPublicKey_fp(fp,rsa) (RSA *)ASN1_d2i_fp((char *(*)())\
-		RSA_new,(char *(*)())d2i_RSAPublicKey, (fp), \
-		(unsigned char **)(rsa))
-#define i2d_RSAPublicKey_fp(fp,rsa) ASN1_i2d_fp(i2d_RSAPublicKey,fp, \
-		(unsigned char *)rsa)
-#define d2i_RSAPublicKey_bio(bp,rsa) (RSA *)ASN1_d2i_bio((char *(*)())\
-		RSA_new,(char *(*)())d2i_RSAPublicKey, (bp), \
-		(unsigned char **)(rsa))
-#define i2d_RSAPublicKey_bio(bp,rsa) ASN1_i2d_bio(i2d_RSAPublicKey,bp, \
-		(unsigned char *)rsa)
-
-#define d2i_DSAPrivateKey_fp(fp,dsa) (DSA *)ASN1_d2i_fp((char *(*)())\
-		DSA_new,(char *(*)())d2i_DSAPrivateKey, (fp), \
-		(unsigned char **)(dsa))
-#define i2d_DSAPrivateKey_fp(fp,dsa) ASN1_i2d_fp(i2d_DSAPrivateKey,fp, \
-		(unsigned char *)dsa)
-#define d2i_DSAPrivateKey_bio(bp,dsa) (DSA *)ASN1_d2i_bio((char *(*)())\
-		DSA_new,(char *(*)())d2i_DSAPrivateKey, (bp), \
-		(unsigned char **)(dsa))
-#define i2d_DSAPrivateKey_bio(bp,dsa) ASN1_i2d_bio(i2d_DSAPrivateKey,bp, \
-		(unsigned char *)dsa)
-
-#define d2i_ECPrivateKey_fp(fp,ecdsa) (EC_KEY *)ASN1_d2i_fp((char *(*)())\
-		EC_KEY_new,(char *(*)())d2i_ECPrivateKey, (fp), \
-		(unsigned char **)(ecdsa))
-#define i2d_ECPrivateKey_fp(fp,ecdsa) ASN1_i2d_fp(i2d_ECPrivateKey,fp, \
-		(unsigned char *)ecdsa)
-#define d2i_ECPrivateKey_bio(bp,ecdsa) (EC_KEY *)ASN1_d2i_bio((char *(*)())\
-		EC_KEY_new,(char *(*)())d2i_ECPrivateKey, (bp), \
-		(unsigned char **)(ecdsa))
-#define i2d_ECPrivateKey_bio(bp,ecdsa) ASN1_i2d_bio(i2d_ECPrivateKey,bp, \
-		(unsigned char *)ecdsa)
-
-#define X509_ALGOR_dup(xn) (X509_ALGOR *)ASN1_dup((int (*)())i2d_X509_ALGOR,\
-		(char *(*)())d2i_X509_ALGOR,(char *)xn)
-
-#define X509_NAME_dup(xn) (X509_NAME *)ASN1_dup((int (*)())i2d_X509_NAME, \
-		(char *(*)())d2i_X509_NAME,(char *)xn)
-#define X509_NAME_ENTRY_dup(ne) (X509_NAME_ENTRY *)ASN1_dup( \
-		(int (*)())i2d_X509_NAME_ENTRY, \
-		(char *(*)())d2i_X509_NAME_ENTRY,\
-		(char *)ne)
-
-#define X509_digest(data,type,md,len) \
-	ASN1_digest((int (*)())i2d_X509,type,(char *)data,md,len)
-#define X509_NAME_digest(data,type,md,len) \
-	ASN1_digest((int (*)())i2d_X509_NAME,type,(char *)data,md,len)
-#ifndef PKCS7_ISSUER_AND_SERIAL_digest
-#define PKCS7_ISSUER_AND_SERIAL_digest(data,type,md,len) \
-	ASN1_digest((int (*)())i2d_PKCS7_ISSUER_AND_SERIAL,type,\
-		(char *)data,md,len)
-#endif
-#endif
-
 #define X509_EXT_PACK_UNKNOWN	1
 #define X509_EXT_PACK_STRING	2
 
@@ -741,6 +623,18 @@
 #define		X509_CRL_get_issuer(x) ((x)->crl->issuer)
 #define		X509_CRL_get_REVOKED(x) ((x)->crl->revoked)
 
+void X509_CRL_set_default_method(const X509_CRL_METHOD *meth);
+X509_CRL_METHOD *X509_CRL_METHOD_new(
+	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));
+void X509_CRL_METHOD_free(X509_CRL_METHOD *m);
+
+void X509_CRL_set_meth_data(X509_CRL *crl, void *dat);
+void *X509_CRL_get_meth_data(X509_CRL *crl);
+
 /* This one is only used so that a binary form can output, as in
  * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf) */
 #define 	X509_get_X509_PUBKEY(x) ((x)->cert_info->key)
@@ -748,7 +642,6 @@
 
 const char *X509_verify_cert_error_string(long n);
 
-#ifndef SSLEAY_MACROS
 #ifndef OPENSSL_NO_EVP
 int X509_verify(X509 *a, EVP_PKEY *r);
 
@@ -873,11 +766,11 @@
 X509_NAME *X509_NAME_dup(X509_NAME *xn);
 X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
 
-#endif /* !SSLEAY_MACROS */
-
-int		X509_cmp_time(ASN1_TIME *s, time_t *t);
-int		X509_cmp_current_time(ASN1_TIME *s);
+int		X509_cmp_time(const ASN1_TIME *s, time_t *t);
+int		X509_cmp_current_time(const ASN1_TIME *s);
 ASN1_TIME *	X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
+ASN1_TIME *	X509_time_adj_ex(ASN1_TIME *s,
+				int offset_day, long offset_sec, time_t *t);
 ASN1_TIME *	X509_gmtime_adj(ASN1_TIME *s, long adj);
 
 const char *	X509_get_default_cert_area(void );
@@ -965,6 +858,9 @@
 DECLARE_ASN1_FUNCTIONS(X509_CRL)
 
 int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
+int X509_CRL_get0_by_serial(X509_CRL *crl,
+		X509_REVOKED **ret, ASN1_INTEGER *serial);
+int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x);
 
 X509_PKEY *	X509_PKEY_new(void );
 void		X509_PKEY_free(X509_PKEY *a);
@@ -1008,8 +904,8 @@
 X509_NAME *	X509_get_issuer_name(X509 *a);
 int 		X509_set_subject_name(X509 *x, X509_NAME *name);
 X509_NAME *	X509_get_subject_name(X509 *a);
-int 		X509_set_notBefore(X509 *x, ASN1_TIME *tm);
-int 		X509_set_notAfter(X509 *x, ASN1_TIME *tm);
+int 		X509_set_notBefore(X509 *x, const ASN1_TIME *tm);
+int 		X509_set_notAfter(X509 *x, const ASN1_TIME *tm);
 int 		X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
 EVP_PKEY *	X509_get_pubkey(X509 *x);
 ASN1_BIT_STRING * X509_get0_pubkey_bitstr(const X509 *x);
@@ -1046,8 +942,8 @@
 
 int X509_CRL_set_version(X509_CRL *x, long version);
 int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
-int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm);
-int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm);
+int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
+int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
 int X509_CRL_sort(X509_CRL *crl);
 
 int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
@@ -1066,11 +962,18 @@
 int		X509_subject_name_cmp(const X509 *a, const X509 *b);
 unsigned long	X509_subject_name_hash(X509 *x);
 
+#ifndef OPENSSL_NO_MD5
+unsigned long	X509_issuer_name_hash_old(X509 *a);
+unsigned long	X509_subject_name_hash_old(X509 *x);
+#endif
+
 int		X509_cmp(const X509 *a, const X509 *b);
 int		X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
 unsigned long	X509_NAME_hash(X509_NAME *x);
+unsigned long	X509_NAME_hash_old(X509_NAME *x);
 
 int		X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
+int		X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
 #ifndef OPENSSL_NO_FP_API
 int		X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag);
 int		X509_print_fp(FILE *bp,X509 *x);
@@ -1246,9 +1149,16 @@
 DECLARE_ASN1_FUNCTIONS(PBE2PARAM)
 DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM)
 
-X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, int saltlen);
+int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
+				const unsigned char *salt, int saltlen);
+
+X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
+				const unsigned char *salt, int saltlen);
 X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
 					 unsigned char *salt, int saltlen);
+X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
+				 unsigned char *salt, int saltlen,
+				 unsigned char *aiv, int prf_nid);
 
 /* PKCS#8 utilities */
 
@@ -1259,6 +1169,22 @@
 PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
 PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
 
+int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
+			int version, int ptype, void *pval,
+				unsigned char *penc, int penclen);
+int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
+		const unsigned char **pk, int *ppklen,
+		X509_ALGOR **pa,
+		PKCS8_PRIV_KEY_INFO *p8);
+
+int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
+					int ptype, void *pval,
+					unsigned char *penc, int penclen);
+int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
+		const unsigned char **pk, int *ppklen,
+		X509_ALGOR **pa,
+		X509_PUBKEY *pub);
+
 int X509_check_trust(X509 *x, int id, int flags);
 int X509_TRUST_get_count(void);
 X509_TRUST * X509_TRUST_get0(int idx);
@@ -1338,7 +1264,10 @@
 #define X509_R_KEY_VALUES_MISMATCH			 116
 #define X509_R_LOADING_CERT_DIR				 103
 #define X509_R_LOADING_DEFAULTS				 104
+#define X509_R_METHOD_NOT_SUPPORTED			 124
 #define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY		 105
+#define X509_R_PUBLIC_KEY_DECODE_ERROR			 125
+#define X509_R_PUBLIC_KEY_ENCODE_ERROR			 126
 #define X509_R_SHOULD_RETRY				 106
 #define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN	 107
 #define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY		 108
diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c
index 2faf925..4bc9da0 100644
--- a/crypto/x509/x509_cmp.c
+++ b/crypto/x509/x509_cmp.c
@@ -116,6 +116,13 @@
 	return(X509_NAME_cmp(a->crl->issuer,b->crl->issuer));
 	}
 
+#ifndef OPENSSL_NO_SHA
+int X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
+	{
+	return memcmp(a->sha1_hash, b->sha1_hash, 20);
+	}
+#endif
+
 X509_NAME *X509_get_issuer_name(X509 *a)
 	{
 	return(a->cert_info->issuer);
@@ -126,6 +133,13 @@
 	return(X509_NAME_hash(x->cert_info->issuer));
 	}
 
+#ifndef OPENSSL_NO_MD5
+unsigned long X509_issuer_name_hash_old(X509 *x)
+	{
+	return(X509_NAME_hash_old(x->cert_info->issuer));
+	}
+#endif
+
 X509_NAME *X509_get_subject_name(X509 *a)
 	{
 	return(a->cert_info->subject);
@@ -141,6 +155,13 @@
 	return(X509_NAME_hash(x->cert_info->subject));
 	}
 
+#ifndef OPENSSL_NO_MD5
+unsigned long X509_subject_name_hash_old(X509 *x)
+	{
+	return(X509_NAME_hash_old(x->cert_info->subject));
+	}
+#endif
+
 #ifndef OPENSSL_NO_SHA
 /* Compare two certificates: they must be identical for
  * this to work. NB: Although "cmp" operations are generally
@@ -162,177 +183,63 @@
 #endif
 
 
-/* Case insensitive string comparision */
-static int nocase_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
-{
-	int i;
-
-	if (a->length != b->length)
-		return (a->length - b->length);
-
-	for (i=0; i<a->length; i++)
-	{
-		int ca, cb;
-
-		ca = tolower(a->data[i]);
-		cb = tolower(b->data[i]);
-
-		if (ca != cb)
-			return(ca-cb);
-	}
-	return 0;
-}
-
-/* Case insensitive string comparision with space normalization 
- * Space normalization - ignore leading, trailing spaces, 
- *       multiple spaces between characters are replaced by single space  
- */
-static int nocase_spacenorm_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
-{
-	unsigned char *pa = NULL, *pb = NULL;
-	int la, lb;
-	
-	la = a->length;
-	lb = b->length;
-	pa = a->data;
-	pb = b->data;
-
-	/* skip leading spaces */
-	while (la > 0 && isspace(*pa))
-	{
-		la--;
-		pa++;
-	}
-	while (lb > 0 && isspace(*pb))
-	{
-		lb--;
-		pb++;
-	}
-
-	/* skip trailing spaces */
-	while (la > 0 && isspace(pa[la-1]))
-		la--;
-	while (lb > 0 && isspace(pb[lb-1]))
-		lb--;
-
-	/* compare strings with space normalization */
-	while (la > 0 && lb > 0)
-	{
-		int ca, cb;
-
-		/* compare character */
-		ca = tolower(*pa);
-		cb = tolower(*pb);
-		if (ca != cb)
-			return (ca - cb);
-
-		pa++; pb++;
-		la--; lb--;
-
-		if (la <= 0 || lb <= 0)
-			break;
-
-		/* is white space next character ? */
-		if (isspace(*pa) && isspace(*pb))
-		{
-			/* skip remaining white spaces */
-			while (la > 0 && isspace(*pa))
-			{
-				la--;
-				pa++;
-			}
-			while (lb > 0 && isspace(*pb))
-			{
-				lb--;
-				pb++;
-			}
-		}
-	}
-	if (la > 0 || lb > 0)
-		return la - lb;
-
-	return 0;
-}
-
-static int asn1_string_memcmp(ASN1_STRING *a, ASN1_STRING *b)
-	{
-	int j;
-	j = a->length - b->length;
-	if (j)
-		return j;
-	return memcmp(a->data, b->data, a->length);
-	}
-
-#define STR_TYPE_CMP (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_UTF8STRING)
-
 int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
 	{
-	int i,j;
-	X509_NAME_ENTRY *na,*nb;
+	int ret;
 
-	unsigned long nabit, nbbit;
+	/* Ensure canonical encoding is present and up to date */
 
-	j = sk_X509_NAME_ENTRY_num(a->entries)
-		  - sk_X509_NAME_ENTRY_num(b->entries);
-	if (j)
-		return j;
-	for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
+	if (!a->canon_enc || a->modified)
 		{
-		na=sk_X509_NAME_ENTRY_value(a->entries,i);
-		nb=sk_X509_NAME_ENTRY_value(b->entries,i);
-		j=na->value->type-nb->value->type;
-		if (j)
-			{
-			nabit = ASN1_tag2bit(na->value->type);
-			nbbit = ASN1_tag2bit(nb->value->type);
-			if (!(nabit & STR_TYPE_CMP) ||
-				!(nbbit & STR_TYPE_CMP))
-				return j;
-			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);
-		else if (na->value->type == V_ASN1_IA5STRING
-			&& OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress)
-			j=nocase_cmp(na->value, nb->value);
-		else
-			j = asn1_string_memcmp(na->value, nb->value);
-		if (j) return(j);
-		j=na->set-nb->set;
-		if (j) return(j);
+		ret = i2d_X509_NAME((X509_NAME *)a, NULL);
+		if (ret < 0)
+			return -2;
 		}
 
-	/* We will check the object types after checking the values
-	 * since the values will more often be different than the object
-	 * types. */
-	for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
+	if (!b->canon_enc || b->modified)
 		{
-		na=sk_X509_NAME_ENTRY_value(a->entries,i);
-		nb=sk_X509_NAME_ENTRY_value(b->entries,i);
-		j=OBJ_cmp(na->object,nb->object);
-		if (j) return(j);
+		ret = i2d_X509_NAME((X509_NAME *)b, NULL);
+		if (ret < 0)
+			return -2;
 		}
-	return(0);
+
+	ret = a->canon_enclen - b->canon_enclen;
+
+	if (ret)
+		return ret;
+
+	return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
+
 	}
 
+unsigned long X509_NAME_hash(X509_NAME *x)
+	{
+	unsigned long ret=0;
+	unsigned char md[SHA_DIGEST_LENGTH];
+
+	/* Make sure X509_NAME structure contains valid cached encoding */
+	i2d_X509_NAME(x,NULL);
+	EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), NULL);
+
+	ret=(	((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
+		((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
+		)&0xffffffffL;
+	return(ret);
+	}
+
+
 #ifndef OPENSSL_NO_MD5
 /* I now DER encode the name and hash it.  Since I cache the DER encoding,
  * this is reasonably efficient. */
-unsigned long X509_NAME_hash(X509_NAME *x)
+
+unsigned long X509_NAME_hash_old(X509_NAME *x)
 	{
 	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_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);
+	EVP_Digest(x->bytes->data, x->bytes->length, md, NULL, EVP_md5(), NULL);
 
 	ret=(	((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
 		((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
@@ -393,14 +300,19 @@
 
 int X509_check_private_key(X509 *x, EVP_PKEY *k)
 	{
-	EVP_PKEY *xk=NULL;
-	int ok=0;
+	EVP_PKEY *xk;
+	int ret;
 
 	xk=X509_get_pubkey(x);
-	switch (EVP_PKEY_cmp(xk, k))
+
+	if (xk)
+		ret = EVP_PKEY_cmp(xk, k);
+	else
+		ret = -2;
+
+	switch (ret)
 		{
 	case 1:
-		ok=1;
 		break;
 	case 0:
 		X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH);
@@ -409,24 +321,11 @@
 		X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH);
 		break;
 	case -2:
-#ifndef OPENSSL_NO_EC
-		if (k->type == EVP_PKEY_EC)
-			{
-			X509err(X509_F_X509_CHECK_PRIVATE_KEY, ERR_R_EC_LIB);
-			break;
-			}
-#endif
-#ifndef OPENSSL_NO_DH
-		if (k->type == EVP_PKEY_DH)
-			{
-			/* No idea */
-			X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_CANT_CHECK_DH_KEY);
-			break;
-			}
-#endif
 	        X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE);
 		}
-
-	EVP_PKEY_free(xk);
-	return(ok);
+	if (xk)
+		EVP_PKEY_free(xk);
+	if (ret > 0)
+		return 1;
+	return 0;
 	}
diff --git a/crypto/x509/x509_err.c b/crypto/x509/x509_err.c
index fb37729..a01402f 100644
--- a/crypto/x509/x509_err.c
+++ b/crypto/x509/x509_err.c
@@ -1,6 +1,6 @@
 /* crypto/x509/x509_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
@@ -132,7 +132,10 @@
 {ERR_REASON(X509_R_KEY_VALUES_MISMATCH)  ,"key values mismatch"},
 {ERR_REASON(X509_R_LOADING_CERT_DIR)     ,"loading cert dir"},
 {ERR_REASON(X509_R_LOADING_DEFAULTS)     ,"loading defaults"},
+{ERR_REASON(X509_R_METHOD_NOT_SUPPORTED) ,"method not supported"},
 {ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY),"no cert set for us to verify"},
+{ERR_REASON(X509_R_PUBLIC_KEY_DECODE_ERROR),"public key decode error"},
+{ERR_REASON(X509_R_PUBLIC_KEY_ENCODE_ERROR),"public key encode error"},
 {ERR_REASON(X509_R_SHOULD_RETRY)         ,"should retry"},
 {ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN),"unable to find parameters in chain"},
 {ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY),"unable to get certs public key"},
diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c
index b486171..3a6e04a 100644
--- a/crypto/x509/x509_lu.c
+++ b/crypto/x509/x509_lu.c
@@ -196,6 +196,8 @@
 	ret->get_crl = 0;
 	ret->check_crl = 0;
 	ret->cert_crl = 0;
+	ret->lookup_certs = 0;
+	ret->lookup_crls = 0;
 	ret->cleanup = 0;
 
 	if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data))
@@ -296,7 +298,7 @@
 	tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name);
 	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
 
-	if (tmp == NULL)
+	if (tmp == NULL || type == X509_LU_CRL)
 		{
 		for (i=vs->current_method; i<sk_X509_LOOKUP_num(ctx->get_cert_methods); i++)
 			{
@@ -421,14 +423,15 @@
 		}
 	}
 
-int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
-	     X509_NAME *name)
+static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
+	     X509_NAME *name, int *pnmatch)
 	{
 	X509_OBJECT stmp;
 	X509 x509_s;
 	X509_CINF cinf_s;
 	X509_CRL crl_s;
 	X509_CRL_INFO crl_info_s;
+	int idx;
 
 	stmp.type=type;
 	switch (type)
@@ -448,7 +451,29 @@
 		return -1;
 		}
 
-	return sk_X509_OBJECT_find(h,&stmp);
+	idx = sk_X509_OBJECT_find(h,&stmp);
+	if (idx >= 0 && pnmatch)
+		{
+		int tidx;
+		const X509_OBJECT *tobj, *pstmp;
+		*pnmatch = 1;
+		pstmp = &stmp;
+		for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++)
+			{
+			tobj = sk_X509_OBJECT_value(h, tidx);
+			if (x509_object_cmp(&tobj, &pstmp))
+				break;
+			(*pnmatch)++;
+			}
+		}
+	return idx;
+	}
+
+
+int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
+	     X509_NAME *name)
+	{
+	return x509_object_idx_cnt(h, type, name, NULL);
 	}
 
 X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type,
@@ -460,19 +485,125 @@
 	return sk_X509_OBJECT_value(h, idx);
 	}
 
+STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
+	{
+	int i, idx, cnt;
+	STACK_OF(X509) *sk;
+	X509 *x;
+	X509_OBJECT *obj;
+	sk = sk_X509_new_null();
+	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+	idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
+	if (idx < 0)
+		{
+		/* Nothing found in cache: do lookup to possibly add new
+		 * objects to cache
+		 */
+		X509_OBJECT xobj;
+		CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+		if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj))
+			{
+			sk_X509_free(sk);
+			return NULL;
+			}
+		X509_OBJECT_free_contents(&xobj);
+		CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+		idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_X509,nm, &cnt);
+		if (idx < 0)
+			{
+			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+			sk_X509_free(sk);
+			return NULL;
+			}
+		}
+	for (i = 0; i < cnt; i++, idx++)
+		{
+		obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
+		x = obj->data.x509;
+		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
+		if (!sk_X509_push(sk, x))
+			{
+			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+			X509_free(x);
+			sk_X509_pop_free(sk, X509_free);
+			return NULL;
+			}
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+	return sk;
+
+	}
+
+STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
+	{
+	int i, idx, cnt;
+	STACK_OF(X509_CRL) *sk;
+	X509_CRL *x;
+	X509_OBJECT *obj, xobj;
+	sk = sk_X509_CRL_new_null();
+	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+	/* Check cache first */
+	idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
+
+	/* Always do lookup to possibly add new CRLs to cache
+	 */
+	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+	if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj))
+		{
+		sk_X509_CRL_free(sk);
+		return NULL;
+		}
+	X509_OBJECT_free_contents(&xobj);
+	CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+	idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_CRL, nm, &cnt);
+	if (idx < 0)
+		{
+		CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+		sk_X509_CRL_free(sk);
+		return NULL;
+		}
+
+	for (i = 0; i < cnt; i++, idx++)
+		{
+		obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
+		x = obj->data.crl;
+		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL);
+		if (!sk_X509_CRL_push(sk, x))
+			{
+			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+			X509_CRL_free(x);
+			sk_X509_CRL_pop_free(sk, X509_CRL_free);
+			return NULL;
+			}
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+	return sk;
+	}
+
 X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
 	{
 	int idx, i;
 	X509_OBJECT *obj;
 	idx = sk_X509_OBJECT_find(h, x);
 	if (idx == -1) return NULL;
-	if (x->type != X509_LU_X509) return sk_X509_OBJECT_value(h, idx);
+	if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
+		return sk_X509_OBJECT_value(h, idx);
 	for (i = idx; i < sk_X509_OBJECT_num(h); i++)
 		{
 		obj = sk_X509_OBJECT_value(h, i);
 		if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
 			return NULL;
-		if ((x->type != X509_LU_X509) || !X509_cmp(obj->data.x509, x->data.x509))
+		if (x->type == X509_LU_X509)
+			{
+			if (!X509_cmp(obj->data.x509, x->data.x509))
+				return obj;
+			}
+		else if (x->type == X509_LU_CRL)
+			{
+			if (!X509_CRL_match(obj->data.crl, x->data.crl))
+				return obj;
+			}
+		else
 			return obj;
 		}
 	return NULL;
@@ -575,5 +706,11 @@
 	return X509_VERIFY_PARAM_set1(ctx->param, param);
 	}
 
+void X509_STORE_set_verify_cb(X509_STORE *ctx,
+				  int (*verify_cb)(int, X509_STORE_CTX *))
+	{
+	ctx->verify_cb = verify_cb;
+	}
+
 IMPLEMENT_STACK_OF(X509_LOOKUP)
 IMPLEMENT_STACK_OF(X509_OBJECT)
diff --git a/crypto/x509/x509_obj.c b/crypto/x509/x509_obj.c
index 1e718f7..21fed9f 100644
--- a/crypto/x509/x509_obj.c
+++ b/crypto/x509/x509_obj.c
@@ -72,7 +72,7 @@
 	char *p;
 	unsigned char *q;
 	BUF_MEM *b=NULL;
-	static char hex[17]="0123456789ABCDEF";
+	static const char hex[17]="0123456789ABCDEF";
 	int gs_doit[4];
 	char tmp_buf[80];
 #ifdef CHARSET_EBCDIC
diff --git a/crypto/x509/x509_req.c b/crypto/x509/x509_req.c
index 3872e1f..48183dc 100644
--- a/crypto/x509/x509_req.c
+++ b/crypto/x509/x509_req.c
@@ -61,6 +61,7 @@
 #include <openssl/bn.h>
 #include <openssl/evp.h>
 #include <openssl/asn1.h>
+#include <openssl/asn1t.h>
 #include <openssl/x509.h>
 #include <openssl/objects.h>
 #include <openssl/buffer.h>
@@ -205,10 +206,9 @@
 	if(!ext || (ext->type != V_ASN1_SEQUENCE))
 		return NULL;
 	p = ext->value.sequence->data;
-	return d2i_ASN1_SET_OF_X509_EXTENSION(NULL, &p,
-			ext->value.sequence->length,
-			d2i_X509_EXTENSION, X509_EXTENSION_free,
-			V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
+	return (STACK_OF(X509_EXTENSION) *)
+		ASN1_item_d2i(NULL, &p, ext->value.sequence->length,
+				ASN1_ITEM_rptr(X509_EXTENSIONS));
 }
 
 /* Add a STACK_OF extensions to a certificate request: allow alternative OIDs
@@ -218,8 +218,6 @@
 int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
 				int nid)
 {
-	unsigned char *p = NULL, *q;
-	long len;
 	ASN1_TYPE *at = NULL;
 	X509_ATTRIBUTE *attr = NULL;
 	if(!(at = ASN1_TYPE_new()) ||
@@ -227,15 +225,10 @@
 
 	at->type = V_ASN1_SEQUENCE;
 	/* Generate encoding of extensions */
-	len = i2d_ASN1_SET_OF_X509_EXTENSION(exts, NULL, i2d_X509_EXTENSION,
-			V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, IS_SEQUENCE);
-	if(!(p = OPENSSL_malloc(len))) goto err;
-	q = p;
-	i2d_ASN1_SET_OF_X509_EXTENSION(exts, &q, i2d_X509_EXTENSION,
-			V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, IS_SEQUENCE);
-	at->value.sequence->data = p;
-	p = NULL;
-	at->value.sequence->length = len;
+	at->value.sequence->length = 
+			ASN1_item_i2d((ASN1_VALUE *)exts,
+				&at->value.sequence->data,
+				ASN1_ITEM_rptr(X509_EXTENSIONS));
 	if(!(attr = X509_ATTRIBUTE_new())) goto err;
 	if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err;
 	if(!sk_ASN1_TYPE_push(attr->value.set, at)) goto err;
@@ -250,7 +243,6 @@
 	if(!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) goto err;
 	return 1;
 	err:
-	if(p) OPENSSL_free(p);
 	X509_ATTRIBUTE_free(attr);
 	ASN1_TYPE_free(at);
 	return 0;
diff --git a/crypto/x509/x509_set.c b/crypto/x509/x509_set.c
index aaf61ca..4b94fc5 100644
--- a/crypto/x509/x509_set.c
+++ b/crypto/x509/x509_set.c
@@ -104,7 +104,7 @@
 	return(X509_NAME_set(&x->cert_info->subject,name));
 	}
 
-int X509_set_notBefore(X509 *x, ASN1_TIME *tm)
+int X509_set_notBefore(X509 *x, const ASN1_TIME *tm)
 	{
 	ASN1_TIME *in;
 
@@ -122,7 +122,7 @@
 	return(in != NULL);
 	}
 
-int X509_set_notAfter(X509 *x, ASN1_TIME *tm)
+int X509_set_notAfter(X509 *x, const ASN1_TIME *tm)
 	{
 	ASN1_TIME *in;
 
diff --git a/crypto/x509/x509_trs.c b/crypto/x509/x509_trs.c
index ed18700..a6cb9c8 100644
--- a/crypto/x509/x509_trs.c
+++ b/crypto/x509/x509_trs.c
@@ -84,7 +84,8 @@
 {X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect, NULL},
 {X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign, NULL},
 {X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign, NULL},
-{X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, NULL}
+{X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, NULL},
+{X509_TRUST_TSA, 0, trust_1oidany, "TSA server", NID_time_stamp, NULL}
 };
 
 #define X509_TRUST_COUNT	(sizeof(trstandard)/sizeof(X509_TRUST))
diff --git a/crypto/x509/x509_txt.c b/crypto/x509/x509_txt.c
index 73a8ec7..c44f753 100644
--- a/crypto/x509/x509_txt.c
+++ b/crypto/x509/x509_txt.c
@@ -162,8 +162,28 @@
 		return("invalid or inconsistent certificate policy extension");
 	case X509_V_ERR_NO_EXPLICIT_POLICY:
 		return("no explicit policy");
-	case X509_V_ERR_UNNESTED_RESOURCE:
-		return("RFC 3779 resource not subset of parent's resources");
+	case X509_V_ERR_DIFFERENT_CRL_SCOPE:
+	return("Different CRL scope");
+	case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE:
+	return("Unsupported extension feature");
+ 	case X509_V_ERR_UNNESTED_RESOURCE:
+ 		return("RFC 3779 resource not subset of parent's resources");
+
+	case X509_V_ERR_PERMITTED_VIOLATION:
+		return("permitted subtree violation");
+	case X509_V_ERR_EXCLUDED_VIOLATION:
+		return("excluded subtree violation");
+	case X509_V_ERR_SUBTREE_MINMAX:
+		return("name constraints minimum and maximum not supported");
+	case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:
+		return("unsupported name constraint type");
+	case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX:
+		return("unsupported or invalid name constraint syntax");
+	case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX:
+		return("unsupported or invalid name syntax");
+	case X509_V_ERR_CRL_PATH_VALIDATION_ERROR:
+		return("CRL path validation error");
+
 	default:
 		BIO_snprintf(buf,sizeof buf,"error number %ld",n);
 		return(buf);
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index b85456e..87ebf62 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -70,14 +70,70 @@
 #include <openssl/x509v3.h>
 #include <openssl/objects.h>
 
+/* CRL score values */
+
+/* No unhandled critical extensions */
+
+#define CRL_SCORE_NOCRITICAL	0x100
+
+/* certificate is within CRL scope */
+
+#define CRL_SCORE_SCOPE		0x080
+
+/* CRL times valid */
+
+#define CRL_SCORE_TIME		0x040
+
+/* Issuer name matches certificate */
+
+#define CRL_SCORE_ISSUER_NAME	0x020
+
+/* If this score or above CRL is probably valid */
+
+#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE)
+
+/* CRL issuer is certificate issuer */
+
+#define CRL_SCORE_ISSUER_CERT	0x018
+
+/* CRL issuer is on certificate path */
+
+#define CRL_SCORE_SAME_PATH	0x008
+
+/* CRL issuer matches CRL AKID */
+
+#define CRL_SCORE_AKID		0x004
+
+/* Have a delta CRL with valid times */
+
+#define CRL_SCORE_TIME_DELTA	0x002
+
 static int null_callback(int ok,X509_STORE_CTX *e);
 static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
 static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
 static int check_chain_extensions(X509_STORE_CTX *ctx);
+static int check_name_constraints(X509_STORE_CTX *ctx);
 static int check_trust(X509_STORE_CTX *ctx);
 static int check_revocation(X509_STORE_CTX *ctx);
 static int check_cert(X509_STORE_CTX *ctx);
 static int check_policy(X509_STORE_CTX *ctx);
+
+static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
+			unsigned int *preasons,
+			X509_CRL *crl, X509 *x);
+static int get_crl_delta(X509_STORE_CTX *ctx,
+				X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x);
+static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score,
+			X509_CRL *base, STACK_OF(X509_CRL) *crls);
+static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
+				X509 **pissuer, int *pcrl_score);
+static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
+				unsigned int *preasons);
+static int check_crl_path(X509_STORE_CTX *ctx, X509 *x);
+static int check_crl_chain(X509_STORE_CTX *ctx,
+			STACK_OF(X509) *cert_path,
+			STACK_OF(X509) *crl_path);
+
 static int internal_verify(X509_STORE_CTX *ctx);
 const char X509_version[]="X.509" OPENSSL_VERSION_PTEXT;
 
@@ -289,6 +345,12 @@
 
 	if (!ok) goto end;
 
+	/* Check name constraints */
+
+	ok = check_name_constraints(ctx);
+	
+	if (!ok) goto end;
+
 	/* The chain extensions are OK: check trust */
 
 	if (param->trust > 0) ok = check_trust(ctx);
@@ -398,8 +460,8 @@
 	X509 *x;
 	int (*cb)(int xok,X509_STORE_CTX *xctx);
 	int proxy_path_length = 0;
-	int allow_proxy_certs =
-		!!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
+	int purpose;
+	int allow_proxy_certs;
 	cb=ctx->verify_cb;
 
 	/* must_be_ca can have 1 of 3 values:
@@ -412,10 +474,22 @@
 	*/
 	must_be_ca = -1;
 
-	/* A hack to keep people who don't want to modify their software
-	   happy */
-	if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
-		allow_proxy_certs = 1;
+	/* CRL path validation */
+	if (ctx->parent)
+		{
+		allow_proxy_certs = 0;
+		purpose = X509_PURPOSE_CRL_SIGN;
+		}
+	else
+		{
+		allow_proxy_certs =
+			!!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
+		/* A hack to keep people who don't want to modify their
+		   software happy */
+		if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
+			allow_proxy_certs = 1;
+		purpose = ctx->param->purpose;
+		}
 
 	/* Check all untrusted certificates */
 	for (i = 0; i < ctx->last_untrusted; i++)
@@ -482,8 +556,7 @@
 			}
 		if (ctx->param->purpose > 0)
 			{
-			ret = X509_check_purpose(x, ctx->param->purpose,
-				must_be_ca > 0);
+			ret = X509_check_purpose(x, purpose, must_be_ca > 0);
 			if ((ret == 0)
 				|| ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
 					&& (ret != 1)))
@@ -536,6 +609,42 @@
 #endif
 }
 
+static int check_name_constraints(X509_STORE_CTX *ctx)
+	{
+	X509 *x;
+	int i, j, rv;
+	/* Check name constraints for all certificates */
+	for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--)
+		{
+		x = sk_X509_value(ctx->chain, i);
+		/* Ignore self issued certs unless last in chain */
+		if (i && (x->ex_flags & EXFLAG_SI))
+			continue;
+		/* Check against constraints for all certificates higher in
+		 * chain including trust anchor. Trust anchor not strictly
+		 * speaking needed but if it includes constraints it is to be
+		 * assumed it expects them to be obeyed.
+		 */
+		for (j = sk_X509_num(ctx->chain) - 1; j > i; j--)
+			{
+			NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
+			if (nc)
+				{
+				rv = NAME_CONSTRAINTS_check(x, nc);
+				if (rv != X509_V_OK)
+					{
+					ctx->error = rv;
+					ctx->error_depth = i;
+					ctx->current_cert = x;
+					if (!ctx->verify_cb(0,ctx))
+						return 0;
+					}
+				}
+			}
+		}
+	return 1;
+	}
+
 static int check_trust(X509_STORE_CTX *ctx)
 {
 #ifdef OPENSSL_NO_CHAIN_VERIFY
@@ -570,7 +679,12 @@
 	if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
 		last = sk_X509_num(ctx->chain) - 1;
 	else
+		{
+		/* If checking CRL paths this isn't the EE certificate */
+		if (ctx->parent)
+			return 1;
 		last = 0;
+		}
 	for(i = 0; i <= last; i++)
 		{
 		ctx->error_depth = i;
@@ -582,30 +696,65 @@
 
 static int check_cert(X509_STORE_CTX *ctx)
 	{
-	X509_CRL *crl = NULL;
+	X509_CRL *crl = NULL, *dcrl = NULL;
 	X509 *x;
 	int ok, cnum;
 	cnum = ctx->error_depth;
 	x = sk_X509_value(ctx->chain, cnum);
 	ctx->current_cert = x;
-	/* Try to retrieve relevant CRL */
-	ok = ctx->get_crl(ctx, &crl, x);
-	/* If error looking up CRL, nothing we can do except
-	 * notify callback
-	 */
-	if(!ok)
+	ctx->current_issuer = NULL;
+	ctx->current_reasons = 0;
+	while (ctx->current_reasons != CRLDP_ALL_REASONS)
 		{
-		ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
-		ok = ctx->verify_cb(0, ctx);
-		goto err;
+		/* Try to retrieve relevant CRL */
+		if (ctx->get_crl)
+			ok = ctx->get_crl(ctx, &crl, x);
+		else
+			ok = get_crl_delta(ctx, &crl, &dcrl, x);
+		/* If error looking up CRL, nothing we can do except
+		 * notify callback
+		 */
+		if(!ok)
+			{
+			ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
+			ok = ctx->verify_cb(0, ctx);
+			goto err;
+			}
+		ctx->current_crl = crl;
+		ok = ctx->check_crl(ctx, crl);
+		if (!ok)
+			goto err;
+
+		if (dcrl)
+			{
+			ok = ctx->check_crl(ctx, dcrl);
+			if (!ok)
+				goto err;
+			ok = ctx->cert_crl(ctx, dcrl, x);
+			if (!ok)
+				goto err;
+			}
+		else
+			ok = 1;
+
+		/* Don't look in full CRL if delta reason is removefromCRL */
+		if (ok != 2)
+			{
+			ok = ctx->cert_crl(ctx, crl, x);
+			if (!ok)
+				goto err;
+			}
+
+		X509_CRL_free(crl);
+		X509_CRL_free(dcrl);
+		crl = NULL;
+		dcrl = NULL;
 		}
-	ctx->current_crl = crl;
-	ok = ctx->check_crl(ctx, crl);
-	if (!ok) goto err;
-	ok = ctx->cert_crl(ctx, crl, x);
 	err:
-	ctx->current_crl = NULL;
 	X509_CRL_free(crl);
+	X509_CRL_free(dcrl);
+
+	ctx->current_crl = NULL;
 	return ok;
 
 	}
@@ -616,7 +765,8 @@
 	{
 	time_t *ptime;
 	int i;
-	ctx->current_crl = crl;
+	if (notify)
+		ctx->current_crl = crl;
 	if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
 		ptime = &ctx->param->check_time;
 	else
@@ -625,15 +775,19 @@
 	i=X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
 	if (i == 0)
 		{
+		if (!notify)
+			return 0;
 		ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
-		if (!notify || !ctx->verify_cb(0, ctx))
+		if (!ctx->verify_cb(0, ctx))
 			return 0;
 		}
 
 	if (i > 0)
 		{
+		if (!notify)
+			return 0;
 		ctx->error=X509_V_ERR_CRL_NOT_YET_VALID;
-		if (!notify || !ctx->verify_cb(0, ctx))
+		if (!ctx->verify_cb(0, ctx))
 			return 0;
 		}
 
@@ -643,92 +797,545 @@
 
 		if (i == 0)
 			{
+			if (!notify)
+				return 0;
 			ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
-			if (!notify || !ctx->verify_cb(0, ctx))
+			if (!ctx->verify_cb(0, ctx))
 				return 0;
 			}
-
-		if (i < 0)
+		/* Ignore expiry of base CRL is delta is valid */
+		if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA))
 			{
+			if (!notify)
+				return 0;
 			ctx->error=X509_V_ERR_CRL_HAS_EXPIRED;
-			if (!notify || !ctx->verify_cb(0, ctx))
+			if (!ctx->verify_cb(0, ctx))
 				return 0;
 			}
 		}
 
-	ctx->current_crl = NULL;
+	if (notify)
+		ctx->current_crl = NULL;
 
 	return 1;
 	}
 
-/* Lookup CRLs from the supplied list. Look for matching isser name
- * and validity. If we can't find a valid CRL return the last one
- * with matching name. This gives more meaningful error codes. Otherwise
- * we'd get a CRL not found error if a CRL existed with matching name but
- * was invalid.
- */
-
-static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl,
-			X509_NAME *nm, STACK_OF(X509_CRL) *crls)
+static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
+			X509 **pissuer, int *pscore, unsigned int *preasons,
+			STACK_OF(X509_CRL) *crls)
 	{
-	int i;
+	int i, crl_score, best_score = *pscore;
+	unsigned int reasons, best_reasons = 0;
+	X509 *x = ctx->current_cert;
 	X509_CRL *crl, *best_crl = NULL;
+	X509 *crl_issuer = NULL, *best_crl_issuer = NULL;
+
 	for (i = 0; i < sk_X509_CRL_num(crls); i++)
 		{
 		crl = sk_X509_CRL_value(crls, i);
-		if (X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
-			continue;
-		if (check_crl_time(ctx, crl, 0))
+		reasons = *preasons;
+		crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
+
+		if (crl_score > best_score)
 			{
-			*pcrl = crl;
-			CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509);
-			return 1;
+			best_crl = crl;
+			best_crl_issuer = crl_issuer;
+			best_score = crl_score;
+			best_reasons = reasons;
 			}
-		best_crl = crl;
 		}
+
 	if (best_crl)
 		{
+		if (*pcrl)
+			X509_CRL_free(*pcrl);
 		*pcrl = best_crl;
-		CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509);
+		*pissuer = best_crl_issuer;
+		*pscore = best_score;
+		*preasons = best_reasons;
+		CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL);
+		if (*pdcrl)
+			{
+			X509_CRL_free(*pdcrl);
+			*pdcrl = NULL;
+			}
+		get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
 		}
-		
+
+	if (best_score >= CRL_SCORE_VALID)
+		return 1;
+
 	return 0;
 	}
 
-/* Retrieve CRL corresponding to certificate: currently just a
- * subject lookup: maybe use AKID later...
+/* Compare two CRL extensions for delta checking purposes. They should be
+ * both present or both absent. If both present all fields must be identical.
  */
-static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x)
+
+static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
 	{
-	int ok;
-	X509_CRL *crl = NULL;
-	X509_OBJECT xobj;
-	X509_NAME *nm;
-	nm = X509_get_issuer_name(x);
-	ok = get_crl_sk(ctx, &crl, nm, ctx->crls);
-	if (ok)
+	ASN1_OCTET_STRING *exta, *extb;
+	int i;
+	i = X509_CRL_get_ext_by_NID(a, nid, 0);
+	if (i >= 0)
 		{
-		*pcrl = crl;
+		/* Can't have multiple occurrences */
+		if (X509_CRL_get_ext_by_NID(a, nid, i) != -1)
+			return 0;
+		exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
+		}
+	else
+		exta = NULL;
+
+	i = X509_CRL_get_ext_by_NID(b, nid, 0);
+
+	if (i >= 0)
+		{
+
+		if (X509_CRL_get_ext_by_NID(b, nid, i) != -1)
+			return 0;
+		extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
+		}
+	else
+		extb = NULL;
+
+	if (!exta && !extb)
 		return 1;
+
+	if (!exta || !extb)
+		return 0;
+
+
+	if (ASN1_OCTET_STRING_cmp(exta, extb))
+		return 0;
+
+	return 1;
+	}
+
+/* See if a base and delta are compatible */
+
+static int check_delta_base(X509_CRL *delta, X509_CRL *base)
+	{
+	/* Delta CRL must be a delta */
+	if (!delta->base_crl_number)
+			return 0;
+	/* Base must have a CRL number */
+	if (!base->crl_number)
+			return 0;
+	/* Issuer names must match */
+	if (X509_NAME_cmp(X509_CRL_get_issuer(base),
+				X509_CRL_get_issuer(delta)))
+		return 0;
+	/* AKID and IDP must match */
+	if (!crl_extension_match(delta, base, NID_authority_key_identifier))
+			return 0;
+	if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
+			return 0;
+	/* Delta CRL base number must not exceed Full CRL number. */
+	if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
+			return 0;
+	/* Delta CRL number must exceed full CRL number */
+	if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
+			return 1;
+	return 0;
+	}
+
+/* For a given base CRL find a delta... maybe extend to delta scoring
+ * or retrieve a chain of deltas...
+ */
+
+static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
+			X509_CRL *base, STACK_OF(X509_CRL) *crls)
+	{
+	X509_CRL *delta;
+	int i;
+	if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS))
+		return;
+	if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST))
+		return;
+	for (i = 0; i < sk_X509_CRL_num(crls); i++)
+		{
+		delta = sk_X509_CRL_value(crls, i);
+		if (check_delta_base(delta, base))
+			{
+			if (check_crl_time(ctx, delta, 0))
+				*pscore |= CRL_SCORE_TIME_DELTA;
+			CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL);
+			*dcrl = delta;
+			return;
+			}
+		}
+	*dcrl = NULL;
+	}
+
+/* For a given CRL return how suitable it is for the supplied certificate 'x'.
+ * The return value is a mask of several criteria.
+ * If the issuer is not the certificate issuer this is returned in *pissuer.
+ * The reasons mask is also used to determine if the CRL is suitable: if
+ * no new reasons the CRL is rejected, otherwise reasons is updated.
+ */
+
+static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
+			unsigned int *preasons,
+			X509_CRL *crl, X509 *x)
+	{
+
+	int crl_score = 0;
+	unsigned int tmp_reasons = *preasons, crl_reasons;
+
+	/* First see if we can reject CRL straight away */
+
+	/* Invalid IDP cannot be processed */
+	if (crl->idp_flags & IDP_INVALID)
+		return 0;
+	/* Reason codes or indirect CRLs need extended CRL support */
+	if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
+		{
+		if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
+			return 0;
+		}
+	else if (crl->idp_flags & IDP_REASONS)
+		{
+		/* If no new reasons reject */
+		if (!(crl->idp_reasons & ~tmp_reasons))
+			return 0;
+		}
+	/* Don't process deltas at this stage */
+	else if (crl->base_crl_number)
+		return 0;
+	/* If issuer name doesn't match certificate need indirect CRL */
+	if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl)))
+		{
+		if (!(crl->idp_flags & IDP_INDIRECT))
+			return 0;
+		}
+	else
+		crl_score |= CRL_SCORE_ISSUER_NAME;
+
+	if (!(crl->flags & EXFLAG_CRITICAL))
+		crl_score |= CRL_SCORE_NOCRITICAL;
+
+	/* Check expiry */
+	if (check_crl_time(ctx, crl, 0))
+		crl_score |= CRL_SCORE_TIME;
+
+	/* Check authority key ID and locate certificate issuer */
+	crl_akid_check(ctx, crl, pissuer, &crl_score);
+
+	/* If we can't locate certificate issuer at this point forget it */
+
+	if (!(crl_score & CRL_SCORE_AKID))
+		return 0;
+
+	/* Check cert for matching CRL distribution points */
+
+	if (crl_crldp_check(x, crl, crl_score, &crl_reasons))
+		{
+		/* If no new reasons reject */
+		if (!(crl_reasons & ~tmp_reasons))
+			return 0;
+		tmp_reasons |= crl_reasons;
+		crl_score |= CRL_SCORE_SCOPE;
 		}
 
-	ok = X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj);
+	*preasons = tmp_reasons;
 
-	if (!ok)
+	return crl_score;
+
+	}
+
+static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
+				X509 **pissuer, int *pcrl_score)
+	{
+	X509 *crl_issuer = NULL;
+	X509_NAME *cnm = X509_CRL_get_issuer(crl);
+	int cidx = ctx->error_depth;
+	int i;
+
+	if (cidx != sk_X509_num(ctx->chain) - 1)
+		cidx++;
+
+	crl_issuer = sk_X509_value(ctx->chain, cidx);
+
+	if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
 		{
-		/* If we got a near match from get_crl_sk use that */
-		if (crl)
+		if (*pcrl_score & CRL_SCORE_ISSUER_NAME)
 			{
-			*pcrl = crl;
-			return 1;
+			*pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_ISSUER_CERT;
+			*pissuer = crl_issuer;
+			return;
+			}
+		}
+
+	for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++)
+		{
+		crl_issuer = sk_X509_value(ctx->chain, cidx);
+		if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
+			continue;
+		if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
+			{
+			*pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_SAME_PATH;
+			*pissuer = crl_issuer;
+			return;
+			}
+		}
+
+	/* Anything else needs extended CRL support */
+
+	if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
+		return;
+
+	/* Otherwise the CRL issuer is not on the path. Look for it in the
+	 * set of untrusted certificates.
+	 */
+	for (i = 0; i < sk_X509_num(ctx->untrusted); i++)
+		{
+		crl_issuer = sk_X509_value(ctx->untrusted, i);
+		if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
+			continue;
+		if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
+			{
+			*pissuer = crl_issuer;
+			*pcrl_score |= CRL_SCORE_AKID;
+			return;
+			}
+		}
+	}
+
+/* Check the path of a CRL issuer certificate. This creates a new
+ * X509_STORE_CTX and populates it with most of the parameters from the
+ * parent. This could be optimised somewhat since a lot of path checking
+ * will be duplicated by the parent, but this will rarely be used in 
+ * practice.
+ */
+
+static int check_crl_path(X509_STORE_CTX *ctx, X509 *x)
+	{
+	X509_STORE_CTX crl_ctx;
+	int ret;
+	/* Don't allow recursive CRL path validation */
+	if (ctx->parent)
+		return 0;
+	if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted))
+		return -1;
+
+	crl_ctx.crls = ctx->crls;
+	/* Copy verify params across */
+	X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);
+
+	crl_ctx.parent = ctx;
+	crl_ctx.verify_cb = ctx->verify_cb;
+
+	/* Verify CRL issuer */
+	ret = X509_verify_cert(&crl_ctx);
+
+	if (ret <= 0)
+		goto err;
+
+	/* Check chain is acceptable */
+
+	ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
+	err:
+	X509_STORE_CTX_cleanup(&crl_ctx);
+	return ret;
+	}
+
+/* RFC3280 says nothing about the relationship between CRL path
+ * and certificate path, which could lead to situations where a
+ * certificate could be revoked or validated by a CA not authorised
+ * to do so. RFC5280 is more strict and states that the two paths must
+ * end in the same trust anchor, though some discussions remain...
+ * until this is resolved we use the RFC5280 version
+ */
+
+static int check_crl_chain(X509_STORE_CTX *ctx,
+			STACK_OF(X509) *cert_path,
+			STACK_OF(X509) *crl_path)
+	{
+	X509 *cert_ta, *crl_ta;
+	cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
+	crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
+	if (!X509_cmp(cert_ta, crl_ta))
+		return 1;
+	return 0;
+	}
+
+/* Check for match between two dist point names: three separate cases.
+ * 1. Both are relative names and compare X509_NAME types.
+ * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES.
+ * 3. Both are full names and compare two GENERAL_NAMES.
+ * 4. One is NULL: automatic match.
+ */
+
+
+static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b)
+	{
+	X509_NAME *nm = NULL;
+	GENERAL_NAMES *gens = NULL;
+	GENERAL_NAME *gena, *genb;
+	int i, j;
+	if (!a || !b)
+		return 1;
+	if (a->type == 1)
+		{
+		if (!a->dpname)
+			return 0;
+		/* Case 1: two X509_NAME */
+		if (b->type == 1)
+			{
+			if (!b->dpname)
+				return 0;
+			if (!X509_NAME_cmp(a->dpname, b->dpname))
+				return 1;
+			else
+				return 0;
+			}
+		/* Case 2: set name and GENERAL_NAMES appropriately */
+		nm = a->dpname;
+		gens = b->name.fullname;
+		}
+	else if (b->type == 1)
+		{
+		if (!b->dpname)
+			return 0;
+		/* Case 2: set name and GENERAL_NAMES appropriately */
+		gens = a->name.fullname;
+		nm = b->dpname;
+		}
+
+	/* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
+	if (nm)
+		{
+		for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
+			{
+			gena = sk_GENERAL_NAME_value(gens, i);	
+			if (gena->type != GEN_DIRNAME)
+				continue;
+			if (!X509_NAME_cmp(nm, gena->d.directoryName))
+				return 1;
 			}
 		return 0;
 		}
 
-	*pcrl = xobj.data.crl;
+	/* Else case 3: two GENERAL_NAMES */
+
+	for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++)
+		{
+		gena = sk_GENERAL_NAME_value(a->name.fullname, i);
+		for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++)
+			{
+			genb = sk_GENERAL_NAME_value(b->name.fullname, j);
+			if (!GENERAL_NAME_cmp(gena, genb))
+				return 1;
+			}
+		}
+
+	return 0;
+
+	}
+
+static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score)
+	{
+	int i;
+	X509_NAME *nm = X509_CRL_get_issuer(crl);
+	/* If no CRLissuer return is successful iff don't need a match */
+	if (!dp->CRLissuer)
+		return !!(crl_score & CRL_SCORE_ISSUER_NAME);
+	for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++)
+		{
+		GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
+		if (gen->type != GEN_DIRNAME)
+			continue;
+		if (!X509_NAME_cmp(gen->d.directoryName, nm))
+			return 1;
+		}
+	return 0;
+	}
+
+/* Check CRLDP and IDP */
+
+static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
+				unsigned int *preasons)
+	{
+	int i;
+	if (crl->idp_flags & IDP_ONLYATTR)
+		return 0;
+	if (x->ex_flags & EXFLAG_CA)
+		{
+		if (crl->idp_flags & IDP_ONLYUSER)
+			return 0;
+		}
+	else
+		{
+		if (crl->idp_flags & IDP_ONLYCA)
+			return 0;
+		}
+	*preasons = crl->idp_reasons;
+	for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
+		{
+		DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
+		if (crldp_check_crlissuer(dp, crl, crl_score))
+			{
+			if (!crl->idp ||
+			     idp_check_dp(dp->distpoint, crl->idp->distpoint))
+				{
+				*preasons &= dp->dp_reasons;
+				return 1;
+				}
+			}
+		}
+	if ((!crl->idp || !crl->idp->distpoint) && (crl_score & CRL_SCORE_ISSUER_NAME))
+		return 1;
+	return 0;
+	}
+
+/* Retrieve CRL corresponding to current certificate.
+ * If deltas enabled try to find a delta CRL too
+ */
+	
+static int get_crl_delta(X509_STORE_CTX *ctx,
+				X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x)
+	{
+	int ok;
+	X509 *issuer = NULL;
+	int crl_score = 0;
+	unsigned int reasons;
+	X509_CRL *crl = NULL, *dcrl = NULL;
+	STACK_OF(X509_CRL) *skcrl;
+	X509_NAME *nm = X509_get_issuer_name(x);
+	reasons = ctx->current_reasons;
+	ok = get_crl_sk(ctx, &crl, &dcrl, 
+				&issuer, &crl_score, &reasons, ctx->crls);
+
+	if (ok)
+		goto done;
+
+	/* Lookup CRLs from store */
+
+	skcrl = ctx->lookup_crls(ctx, nm);
+
+	/* If no CRLs found and a near match from get_crl_sk use that */
+	if (!skcrl && crl)
+		goto done;
+
+	get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);
+
+	sk_X509_CRL_pop_free(skcrl, X509_CRL_free);
+
+	done:
+
+	/* If we got any kind of CRL use it and return success */
 	if (crl)
-		X509_CRL_free(crl);
-	return 1;
+		{
+		ctx->current_issuer = issuer;
+		ctx->current_crl_score = crl_score;
+		ctx->current_reasons = reasons;
+		*pcrl = crl;
+		*pdcrl = dcrl;
+		return 1;
+		}
+
+	return 0;
 	}
 
 /* Check CRL validity */
@@ -739,10 +1346,14 @@
 	int ok = 0, chnum, cnum;
 	cnum = ctx->error_depth;
 	chnum = sk_X509_num(ctx->chain) - 1;
-	/* Find CRL issuer: if not last certificate then issuer
+	/* if we have an alternative CRL issuer cert use that */
+	if (ctx->current_issuer)
+		issuer = ctx->current_issuer;
+
+	/* Else find CRL issuer: if not last certificate then issuer
 	 * is next certificate in chain.
 	 */
-	if(cnum < chnum)
+	else if (cnum < chnum)
 		issuer = sk_X509_value(ctx->chain, cnum + 1);
 	else
 		{
@@ -758,13 +1369,52 @@
 
 	if(issuer)
 		{
-		/* Check for cRLSign bit if keyUsage present */
-		if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
-			!(issuer->ex_kusage & KU_CRL_SIGN))
+		/* Skip most tests for deltas because they have already
+		 * been done
+		 */
+		if (!crl->base_crl_number)
 			{
-			ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
-			ok = ctx->verify_cb(0, ctx);
-			if(!ok) goto err;
+			/* Check for cRLSign bit if keyUsage present */
+			if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
+				!(issuer->ex_kusage & KU_CRL_SIGN))
+				{
+				ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
+				ok = ctx->verify_cb(0, ctx);
+				if(!ok) goto err;
+				}
+
+			if (!(ctx->current_crl_score & CRL_SCORE_SCOPE))
+				{
+				ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
+				ok = ctx->verify_cb(0, ctx);
+				if(!ok) goto err;
+				}
+
+			if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH))
+				{
+				if (check_crl_path(ctx, ctx->current_issuer) <= 0)
+					{
+					ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
+					ok = ctx->verify_cb(0, ctx);
+					if(!ok) goto err;
+					}
+				}
+
+			if (crl->idp_flags & IDP_INVALID)
+				{
+				ctx->error = X509_V_ERR_INVALID_EXTENSION;
+				ok = ctx->verify_cb(0, ctx);
+				if(!ok) goto err;
+				}
+
+
+			}
+
+		if (!(ctx->current_crl_score & CRL_SCORE_TIME))
+			{
+			ok = check_crl_time(ctx, crl, 1);
+			if (!ok)
+				goto err;
 			}
 
 		/* Attempt to get issuer certificate public key */
@@ -788,10 +1438,6 @@
 			}
 		}
 
-	ok = check_crl_time(ctx, crl, 1);
-	if (!ok)
-		goto err;
-
 	ok = 1;
 
 	err:
@@ -802,62 +1448,43 @@
 /* Check certificate against CRL */
 static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
 	{
-	int idx, ok;
-	X509_REVOKED rtmp;
-	STACK_OF(X509_EXTENSION) *exts;
-	X509_EXTENSION *ext;
-	/* Look for serial number of certificate in CRL */
-	rtmp.serialNumber = X509_get_serialNumber(x);
-	/* Sort revoked into serial number order if not already sorted.
-	 * Do this under a lock to avoid race condition.
- 	 */
-	if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))
-		{
-		CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
-		sk_X509_REVOKED_sort(crl->crl->revoked);
-		CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
-		}
-	idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);
-	/* If found assume revoked: want something cleverer than
-	 * this to handle entry extensions in V2 CRLs.
+	int ok;
+	X509_REVOKED *rev;
+	/* The rules changed for this... previously if a CRL contained
+	 * unhandled critical extensions it could still be used to indicate
+	 * a certificate was revoked. This has since been changed since 
+	 * critical extension can change the meaning of CRL entries.
 	 */
-	if(idx >= 0)
+	if (crl->flags & EXFLAG_CRITICAL)
 		{
+		if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
+			return 1;
+		ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
+		ok = ctx->verify_cb(0, ctx);
+		if(!ok)
+			return 0;
+		}
+	/* Look for serial number of certificate in CRL
+	 * If found make sure reason is not removeFromCRL.
+	 */
+	if (X509_CRL_get0_by_cert(crl, &rev, x))
+		{
+		if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
+			return 2;
 		ctx->error = X509_V_ERR_CERT_REVOKED;
 		ok = ctx->verify_cb(0, ctx);
-		if (!ok) return 0;
+		if (!ok)
+			return 0;
 		}
 
-	if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
-		return 1;
-
-	/* See if we have any critical CRL extensions: since we
-	 * currently don't handle any CRL extensions the CRL must be
-	 * rejected. 
-	 * This code accesses the X509_CRL structure directly: applications
-	 * shouldn't do this.
-	 */
-
-	exts = crl->crl->extensions;
-
-	for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++)
-		{
-		ext = sk_X509_EXTENSION_value(exts, idx);
-		if (ext->critical > 0)
-			{
-			ctx->error =
-				X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
-			ok = ctx->verify_cb(0, ctx);
-			if(!ok) return 0;
-			break;
-			}
-		}
 	return 1;
 	}
 
 static int check_policy(X509_STORE_CTX *ctx)
 	{
 	int ret;
+	if (ctx->parent)
+		return 1;
 	ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
 				ctx->param->policies, ctx->param->flags);
 	if (ret == 0)
@@ -880,7 +1507,8 @@
 				continue;
 			ctx->current_cert = x;
 			ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
-			ret = ctx->verify_cb(0, ctx);
+			if(!ctx->verify_cb(0, ctx))
+				return 0;
 			}
 		return 1;
 		}
@@ -1039,12 +1667,12 @@
 	return ok;
 	}
 
-int X509_cmp_current_time(ASN1_TIME *ctm)
+int X509_cmp_current_time(const ASN1_TIME *ctm)
 {
 	return X509_cmp_time(ctm, NULL);
 }
 
-int X509_cmp_time(ASN1_TIME *ctm, time_t *cmp_time)
+int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
 	{
 	char *str;
 	ASN1_TIME atm;
@@ -1099,6 +1727,7 @@
 			offset= -offset;
 		}
 	atm.type=ctm->type;
+	atm.flags = 0;
 	atm.length=sizeof(buff2);
 	atm.data=(unsigned char *)buff2;
 
@@ -1127,19 +1756,28 @@
 	return X509_time_adj(s, adj, NULL);
 }
 
-ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *in_tm)
+ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm)
+	{
+	return X509_time_adj_ex(s, 0, offset_sec, in_tm);
+	}
+
+ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
+				int offset_day, long offset_sec, time_t *in_tm)
 	{
 	time_t t;
-	int type = -1;
 
 	if (in_tm) t = *in_tm;
 	else time(&t);
 
-	t+=adj;
-	if (s) type = s->type;
-	if (type == V_ASN1_UTCTIME) return ASN1_UTCTIME_set(s,t);
-	if (type == V_ASN1_GENERALIZEDTIME) return ASN1_GENERALIZEDTIME_set(s, t);
-	return ASN1_TIME_set(s, t);
+	if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING))
+		{
+		if (s->type == V_ASN1_UTCTIME)
+			return ASN1_UTCTIME_adj(s,t, offset_day, offset_sec);
+		if (s->type == V_ASN1_GENERALIZEDTIME)
+			return ASN1_GENERALIZEDTIME_adj(s, t, offset_day,
+								offset_sec);
+		}
+	return ASN1_TIME_adj(s, t, offset_day, offset_sec);
 	}
 
 int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain)
@@ -1242,6 +1880,21 @@
 	return chain;
 	}
 
+X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx)
+	{
+	return ctx->current_issuer;
+	}
+
+X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx)
+	{
+	return ctx->current_crl;
+	}
+
+X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx)
+	{
+	return ctx->parent;
+	}
+
 void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
 	{
 	ctx->cert=x;
@@ -1363,6 +2016,7 @@
 	ctx->current_cert=NULL;
 	ctx->current_issuer=NULL;
 	ctx->tree = NULL;
+	ctx->parent = NULL;
 
 	ctx->param = X509_VERIFY_PARAM_new();
 
@@ -1428,7 +2082,7 @@
 	if (store && store->get_crl)
 		ctx->get_crl = store->get_crl;
 	else
-		ctx->get_crl = get_crl;
+		ctx->get_crl = NULL;
 
 	if (store && store->check_crl)
 		ctx->check_crl = store->check_crl;
@@ -1440,6 +2094,16 @@
 	else
 		ctx->cert_crl = cert_crl;
 
+	if (store && store->lookup_certs)
+		ctx->lookup_certs = store->lookup_certs;
+	else
+		ctx->lookup_certs = X509_STORE_get1_certs;
+
+	if (store && store->lookup_crls)
+		ctx->lookup_crls = store->lookup_crls;
+	else
+		ctx->lookup_crls = X509_STORE_get1_crls;
+
 	ctx->check_policy = check_policy;
 
 
@@ -1472,7 +2136,8 @@
 	if (ctx->cleanup) ctx->cleanup(ctx);
 	if (ctx->param != NULL)
 		{
-		X509_VERIFY_PARAM_free(ctx->param);
+		if (ctx->parent == NULL)
+			X509_VERIFY_PARAM_free(ctx->param);
 		ctx->param=NULL;
 		}
 	if (ctx->tree != NULL)
diff --git a/crypto/x509/x509_vfy.h b/crypto/x509/x509_vfy.h
index 86ae35f..fe09b30 100644
--- a/crypto/x509/x509_vfy.h
+++ b/crypto/x509/x509_vfy.h
@@ -77,6 +77,7 @@
 extern "C" {
 #endif
 
+#if 0
 /* Outer object */
 typedef struct x509_hash_dir_st
 	{
@@ -85,6 +86,7 @@
 	int *dirs_type;
 	int num_dirs_alloced;
 	} X509_HASH_DIR_CTX;
+#endif
 
 typedef struct x509_file_st
 	{
@@ -198,6 +200,8 @@
 	int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */
 	int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
 	int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
+	STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm);
+	STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm);
 	int (*cleanup)(X509_STORE_CTX *ctx);
 
 	CRYPTO_EX_DATA ex_data;
@@ -246,6 +250,8 @@
 	int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
 	int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
 	int (*check_policy)(X509_STORE_CTX *ctx);
+	STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm);
+	STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm);
 	int (*cleanup)(X509_STORE_CTX *ctx);
 
 	/* The following is built up */
@@ -263,6 +269,11 @@
 	X509 *current_issuer;	/* cert currently being tested as valid issuer */
 	X509_CRL *current_crl;	/* current CRL */
 
+	int current_crl_score;  /* score of current CRL */
+	unsigned int current_reasons;  /* Reason mask */
+
+	X509_STORE_CTX *parent; /* For CRL path validation: parent context */
+
 	CRYPTO_EX_DATA ex_data;
 	} /* X509_STORE_CTX */;
 
@@ -330,8 +341,18 @@
 #define		X509_V_ERR_INVALID_EXTENSION			41
 #define		X509_V_ERR_INVALID_POLICY_EXTENSION		42
 #define		X509_V_ERR_NO_EXPLICIT_POLICY			43
+#define		X509_V_ERR_DIFFERENT_CRL_SCOPE			44
+#define		X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE	45
 
-#define		X509_V_ERR_UNNESTED_RESOURCE			44
+#define		X509_V_ERR_UNNESTED_RESOURCE			46
+
+#define		X509_V_ERR_PERMITTED_VIOLATION			47
+#define		X509_V_ERR_EXCLUDED_VIOLATION			48
+#define		X509_V_ERR_SUBTREE_MINMAX			49
+#define		X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE		51
+#define		X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX	52
+#define		X509_V_ERR_UNSUPPORTED_NAME_SYNTAX		53
+#define		X509_V_ERR_CRL_PATH_VALIDATION_ERROR		54
 
 /* The application is not happy */
 #define		X509_V_ERR_APPLICATION_VERIFICATION		50
@@ -362,10 +383,14 @@
 #define X509_V_FLAG_INHIBIT_MAP			0x400
 /* Notify callback that policy is OK */
 #define X509_V_FLAG_NOTIFY_POLICY		0x800
-
+/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */
+#define X509_V_FLAG_EXTENDED_CRL_SUPPORT	0x1000
+/* Delta CRL support */
+#define X509_V_FLAG_USE_DELTAS			0x2000
 /* Check selfsigned CA signature */
 #define X509_V_FLAG_CHECK_SS_SIGNATURE		0x4000
 
+
 #define X509_VP_FLAG_DEFAULT			0x1
 #define X509_VP_FLAG_OVERWRITE			0x2
 #define X509_VP_FLAG_RESET_FLAGS		0x4
@@ -387,11 +412,16 @@
 X509_STORE *X509_STORE_new(void );
 void X509_STORE_free(X509_STORE *v);
 
+STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm);
+STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm);
 int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
 int X509_STORE_set_purpose(X509_STORE *ctx, int purpose);
 int X509_STORE_set_trust(X509_STORE *ctx, int trust);
 int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);
 
+void X509_STORE_set_verify_cb(X509_STORE *ctx,
+				  int (*verify_cb)(int, X509_STORE_CTX *));
+
 X509_STORE_CTX *X509_STORE_CTX_new(void);
 
 int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
@@ -450,6 +480,9 @@
 void	X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s);
 int	X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
 X509 *	X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
+X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx);
+X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx);
+X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx);
 STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
 STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
 void	X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x);
diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c
index 01c5541..dfd89d8 100644
--- a/crypto/x509/x509_vpm.c
+++ b/crypto/x509/x509_vpm.c
@@ -74,6 +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;
@@ -328,7 +329,7 @@
 	NULL		/* policies */
 	},
 	{
-	"pkcs7",			/* S/MIME signing parameters */
+	"pkcs7",			/* S/MIME sign parameters */
 	0,				/* Check time */
 	0,				/* internal flags */
 	0,				/* flags */
@@ -338,7 +339,7 @@
 	NULL				/* policies */
 	},
 	{
-	"smime_sign",			/* S/MIME signing parameters */
+	"smime_sign",			/* S/MIME sign parameters */
 	0,				/* Check time */
 	0,				/* internal flags */
 	0,				/* flags */
@@ -370,12 +371,17 @@
 
 static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL;
 
-static int table_cmp(const void *pa, const void *pb)
+static int table_cmp(const X509_VERIFY_PARAM *a, const X509_VERIFY_PARAM *b)
+
 	{
-	const X509_VERIFY_PARAM *a = pa, *b = pb;
 	return strcmp(a->name, b->name);
 	}
 
+DECLARE_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM,
+			   table);
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM,
+			     table);
+
 static int param_cmp(const X509_VERIFY_PARAM * const *a,
 			const X509_VERIFY_PARAM * const *b)
 	{
@@ -411,6 +417,7 @@
 	{
 	int idx;
 	X509_VERIFY_PARAM pm;
+
 	pm.name = (char *)name;
 	if (param_table)
 		{
@@ -418,11 +425,8 @@
 		if (idx != -1)
 			return sk_X509_VERIFY_PARAM_value(param_table, idx);
 		}
-	return (const X509_VERIFY_PARAM *) OBJ_bsearch((char *)&pm,
-				(char *)&default_table,
-				sizeof(default_table)/sizeof(X509_VERIFY_PARAM),
-				sizeof(X509_VERIFY_PARAM),
-				table_cmp);
+	return OBJ_bsearch_table(&pm, default_table,
+			   sizeof(default_table)/sizeof(X509_VERIFY_PARAM));
 	}
 
 void X509_VERIFY_PARAM_table_cleanup(void)
diff --git a/crypto/x509/x509cset.c b/crypto/x509/x509cset.c
index 7f4004b..3109def 100644
--- a/crypto/x509/x509cset.c
+++ b/crypto/x509/x509cset.c
@@ -81,7 +81,7 @@
 	}
 
 
-int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm)
+int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm)
 	{
 	ASN1_TIME *in;
 
@@ -99,7 +99,7 @@
 	return(in != NULL);
 	}
 
-int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm)
+int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm)
 	{
 	ASN1_TIME *in;
 
diff --git a/crypto/x509/x509name.c b/crypto/x509/x509name.c
index 068abfe..27bc4dc 100644
--- a/crypto/x509/x509name.c
+++ b/crypto/x509/x509name.c
@@ -356,7 +356,7 @@
 		return ASN1_STRING_set_by_NID(&ne->value, bytes,
 						len, type,
 					OBJ_obj2nid(ne->object)) ? 1 : 0;
-	if (len < 0) len=strlen((char *)bytes);
+	if (len < 0) len=strlen((const char *)bytes);
 	i=ASN1_STRING_set(ne->value,bytes,len);
 	if (!i) return(0);
 	if (type != V_ASN1_UNDEF)
diff --git a/crypto/x509/x509type.c b/crypto/x509/x509type.c
index 2cd994c..3385ad3 100644
--- a/crypto/x509/x509type.c
+++ b/crypto/x509/x509type.c
@@ -91,6 +91,10 @@
 		break;
 	case EVP_PKEY_DH:
 		ret=EVP_PK_DH|EVP_PKT_EXCH;
+		break;	
+	case NID_id_GostR3410_94:
+	case NID_id_GostR3410_2001:
+		ret=EVP_PKT_EXCH|EVP_PKT_SIGN;
 		break;
 	default:
 		break;
diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c
index 9039caa..ebae30b 100644
--- a/crypto/x509/x_all.c
+++ b/crypto/x509/x_all.c
@@ -57,7 +57,6 @@
  */
 
 #include <stdio.h>
-#undef SSLEAY_MACROS
 #include <openssl/stack.h>
 #include "cryptlib.h"
 #include <openssl/buffer.h>
@@ -83,12 +82,6 @@
 		a->sig_alg,a->signature,a->req_info,r));
 	}
 
-int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r)
-	{
-	return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
-		a->sig_alg, a->signature,a->crl,r));
-	}
-
 int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r)
 	{
 	return(ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC),
diff --git a/crypto/x509v3/Makefile b/crypto/x509v3/Makefile
deleted file mode 100644
index e71dc42..0000000
--- a/crypto/x509v3/Makefile
+++ /dev/null
@@ -1,610 +0,0 @@
-#
-# OpenSSL/crypto/x509v3/Makefile
-#
-
-DIR=	x509v3
-TOP=	../..
-CC=	cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-MAKEFILE=	Makefile
-AR=		ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile README
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=	v3_bcons.c v3_bitst.c v3_conf.c v3_extku.c v3_ia5.c v3_lib.c \
-v3_prn.c v3_utl.c v3err.c v3_genn.c v3_alt.c v3_skey.c v3_akey.c v3_pku.c \
-v3_int.c v3_enum.c v3_sxnet.c v3_cpols.c v3_crld.c v3_purp.c v3_info.c \
-v3_ocsp.c v3_akeya.c v3_pmaps.c v3_pcons.c v3_ncons.c v3_pcia.c v3_pci.c \
-pcy_cache.c pcy_node.c pcy_data.c pcy_map.c pcy_tree.c pcy_lib.c \
-v3_asid.c v3_addr.c
-LIBOBJ= v3_bcons.o v3_bitst.o v3_conf.o v3_extku.o v3_ia5.o v3_lib.o \
-v3_prn.o v3_utl.o v3err.o v3_genn.o v3_alt.o v3_skey.o v3_akey.o v3_pku.o \
-v3_int.o v3_enum.o v3_sxnet.o v3_cpols.o v3_crld.o v3_purp.o v3_info.o \
-v3_ocsp.o v3_akeya.o v3_pmaps.o v3_pcons.o v3_ncons.o v3_pcia.o v3_pci.o \
-pcy_cache.o pcy_node.o pcy_data.o pcy_map.o pcy_tree.o pcy_lib.o \
-v3_asid.o v3_addr.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= x509v3.h
-HEADER=	$(EXHEADER) pcy_int.h
-
-ALL=    $(GENERAL) $(SRC) $(HEADER)
-
-top:
-	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all:	lib
-
-lib:	$(LIBOBJ)
-	$(ARX) $(LIB) $(LIBOBJ)
-	$(RANLIB) $(LIB) || echo Never mind.
-	@touch lib
-
-files:
-	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
-	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
-	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
-	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-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;
-
-tags:
-	ctags $(SRC)
-
-tests:
-
-lint:
-	lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-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 *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-pcy_cache.o: ../../e_os.h ../../include/openssl/asn1.h
-pcy_cache.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-pcy_cache.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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
-pcy_cache.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-pcy_cache.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-pcy_cache.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-pcy_cache.o: ../cryptlib.h pcy_cache.c pcy_int.h
-pcy_data.o: ../../e_os.h ../../include/openssl/asn1.h
-pcy_data.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-pcy_data.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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
-pcy_data.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-pcy_data.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-pcy_data.o: ../cryptlib.h pcy_data.c pcy_int.h
-pcy_lib.o: ../../e_os.h ../../include/openssl/asn1.h
-pcy_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-pcy_lib.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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/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/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
-pcy_node.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-pcy_node.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-pcy_node.o: pcy_int.h pcy_node.c
-pcy_tree.o: ../../e_os.h ../../include/openssl/asn1.h
-pcy_tree.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-pcy_tree.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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
-pcy_tree.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-pcy_tree.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-pcy_tree.o: ../cryptlib.h pcy_int.h pcy_tree.c
-v3_addr.o: ../../e_os.h ../../include/openssl/asn1.h
-v3_addr.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-v3_addr.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
-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/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/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/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
-v3_akeya.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-v3_akeya.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-v3_akeya.o: ../cryptlib.h v3_akeya.c
-v3_alt.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-v3_alt.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
-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/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
-v3_asid.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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/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
-v3_bcons.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-v3_bcons.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-v3_bcons.o: ../cryptlib.h v3_bcons.c
-v3_bitst.o: ../../e_os.h ../../include/openssl/asn1.h
-v3_bitst.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-v3_bitst.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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
-v3_bitst.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-v3_bitst.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-v3_bitst.o: ../cryptlib.h v3_bitst.c
-v3_conf.o: ../../e_os.h ../../include/openssl/asn1.h
-v3_conf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-v3_conf.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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/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
-v3_cpols.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-v3_cpols.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-v3_cpols.o: ../cryptlib.h pcy_int.h v3_cpols.c
-v3_crld.o: ../../e_os.h ../../include/openssl/asn1.h
-v3_crld.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-v3_crld.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
-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/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/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/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
-v3_extku.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-v3_extku.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-v3_extku.o: ../cryptlib.h v3_extku.c
-v3_genn.o: ../../e_os.h ../../include/openssl/asn1.h
-v3_genn.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-v3_genn.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
-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/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/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/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/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/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/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
-v3_ncons.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-v3_ncons.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-v3_ncons.o: ../cryptlib.h v3_ncons.c
-v3_ocsp.o: ../../e_os.h ../../include/openssl/asn1.h
-v3_ocsp.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-v3_ocsp.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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/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/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/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
-v3_pcons.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-v3_pcons.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-v3_pcons.o: ../cryptlib.h v3_pcons.c
-v3_pku.o: ../../e_os.h ../../include/openssl/asn1.h
-v3_pku.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-v3_pku.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
-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/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/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
-v3_pmaps.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-v3_pmaps.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-v3_pmaps.o: ../cryptlib.h v3_pmaps.c
-v3_prn.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-v3_prn.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
-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/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/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/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/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
-v3_sxnet.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-v3_sxnet.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-v3_sxnet.o: ../cryptlib.h v3_sxnet.c
-v3_utl.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
-v3_utl.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-v3_utl.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-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/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/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 3eaec46..76daee6 100644
--- a/crypto/x509v3/ext_dat.h
+++ b/crypto/x509v3/ext_dat.h
@@ -61,21 +61,19 @@
 extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo;
 extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id;
 extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate;
-extern X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld;
+extern X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl;
 extern X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff;
 extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc;
 extern X509V3_EXT_METHOD v3_crl_hold, v3_pci;
 extern X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints;
-extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp;
-#ifndef OPENSSL_NO_RFC3779
+extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp;
 extern X509V3_EXT_METHOD v3_addr, v3_asid;
-#endif
 
 /* This table will be searched using OBJ_bsearch so it *must* kept in
  * order of the ext_nid values.
  */
 
-static X509V3_EXT_METHOD *standard_exts[] = {
+static const X509V3_EXT_METHOD *standard_exts[] = {
 &v3_nscert,
 &v3_ns_ia5_list[0],
 &v3_ns_ia5_list[1],
@@ -122,7 +120,10 @@
 &v3_pci,
 &v3_name_constraints,
 &v3_policy_mappings,
-&v3_inhibit_anyp
+&v3_inhibit_anyp,
+&v3_idp,
+&v3_alt[2],
+&v3_freshest_crl,
 };
 
 /* Number of standard extensions */
diff --git a/crypto/x509v3/pcy_cache.c b/crypto/x509v3/pcy_cache.c
index 1030931..172b7e7 100644
--- a/crypto/x509v3/pcy_cache.c
+++ b/crypto/x509v3/pcy_cache.c
@@ -139,7 +139,6 @@
 		return 0;
 	cache->anyPolicy = NULL;
 	cache->data = NULL;
-	cache->maps = NULL;
 	cache->any_skip = -1;
 	cache->explicit_skip = -1;
 	cache->map_skip = -1;
diff --git a/crypto/x509v3/pcy_data.c b/crypto/x509v3/pcy_data.c
index fb392b9..3444b03 100644
--- a/crypto/x509v3/pcy_data.c
+++ b/crypto/x509v3/pcy_data.c
@@ -82,17 +82,21 @@
  * another source.
  */
 
-X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id, int crit)
+X509_POLICY_DATA *policy_data_new(POLICYINFO *policy,
+					const ASN1_OBJECT *cid, int crit)
 	{
 	X509_POLICY_DATA *ret;
-	if (!policy && !id)
+	ASN1_OBJECT *id;
+	if (!policy && !cid)
 		return NULL;
-	if (id)
+	if (cid)
 		{
-		id = OBJ_dup(id);
+		id = OBJ_dup(cid);
 		if (!id)
 			return NULL;
 		}
+	else
+		id = NULL;
 	ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA));
 	if (!ret)
 		return NULL;
diff --git a/crypto/x509v3/pcy_int.h b/crypto/x509v3/pcy_int.h
index 3780de4..ccff928 100644
--- a/crypto/x509v3/pcy_int.h
+++ b/crypto/x509v3/pcy_int.h
@@ -56,12 +56,10 @@
  *
  */
 
-DECLARE_STACK_OF(X509_POLICY_DATA)
-DECLARE_STACK_OF(X509_POLICY_REF)
-DECLARE_STACK_OF(X509_POLICY_NODE)
 
 typedef struct X509_POLICY_DATA_st X509_POLICY_DATA;
-typedef struct X509_POLICY_REF_st X509_POLICY_REF;
+
+DECLARE_STACK_OF(X509_POLICY_DATA)
 
 /* Internal structures */
 
@@ -110,16 +108,6 @@
 
 #define POLICY_DATA_FLAG_CRITICAL		0x10
 
-/* This structure is an entry from a table of mapped policies which
- * cross reference the policy it refers to.
- */
-
-struct X509_POLICY_REF_st
-	{
-	ASN1_OBJECT *subjectDomainPolicy;
-	const X509_POLICY_DATA *data;
-	};
-
 /* This structure is cached with a certificate */
 
 struct X509_POLICY_CACHE_st {
@@ -127,8 +115,6 @@
 	X509_POLICY_DATA *anyPolicy;
 	/* other policy data */
 	STACK_OF(X509_POLICY_DATA) *data;
-	/* If policyMappings extension present a table of mapped policies */
-	STACK_OF(X509_POLICY_REF) *maps;
 	/* If InhibitAnyPolicy present this is its value or -1 if absent. */
 	long any_skip;
 	/* If policyConstraints and requireExplicitPolicy present this is its
@@ -193,7 +179,7 @@
 
 /* Internal functions */
 
-X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id,
+X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id,
 								int crit);
 void policy_data_free(X509_POLICY_DATA *data);
 
@@ -209,15 +195,18 @@
 void policy_cache_free(X509_POLICY_CACHE *cache);
 
 X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
+					const X509_POLICY_NODE *parent,	
 					const ASN1_OBJECT *id);
 
 X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
 						const ASN1_OBJECT *id);
 
 X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
-			X509_POLICY_DATA *data,
+			const X509_POLICY_DATA *data,
 			X509_POLICY_NODE *parent,
 			X509_POLICY_TREE *tree);
 void policy_node_free(X509_POLICY_NODE *node);
+int policy_node_match(const X509_POLICY_LEVEL *lvl,
+		      const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
 
 const X509_POLICY_CACHE *policy_cache_set(X509 *x);
diff --git a/crypto/x509v3/pcy_map.c b/crypto/x509v3/pcy_map.c
index f28796e..21163b5 100644
--- a/crypto/x509v3/pcy_map.c
+++ b/crypto/x509v3/pcy_map.c
@@ -62,31 +62,6 @@
 
 #include "pcy_int.h"
 
-static int ref_cmp(const X509_POLICY_REF * const *a,
-			const X509_POLICY_REF * const *b)
-	{
-	return OBJ_cmp((*a)->subjectDomainPolicy, (*b)->subjectDomainPolicy);
-	}
-
-static void policy_map_free(X509_POLICY_REF *map)
-	{
-	if (map->subjectDomainPolicy)
-		ASN1_OBJECT_free(map->subjectDomainPolicy);
-	OPENSSL_free(map);
-	}
-
-static X509_POLICY_REF *policy_map_find(X509_POLICY_CACHE *cache, ASN1_OBJECT *id)
-	{
-	X509_POLICY_REF tmp;
-	int idx;
-	tmp.subjectDomainPolicy = id;
-
-	idx = sk_X509_POLICY_REF_find(cache->maps, &tmp);
-	if (idx == -1)
-		return NULL;
-	return sk_X509_POLICY_REF_value(cache->maps, idx);
-	}
-
 /* Set policy mapping entries in cache.
  * Note: this modifies the passed POLICY_MAPPINGS structure
  */
@@ -94,7 +69,6 @@
 int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
 	{
 	POLICY_MAPPING *map;
-	X509_POLICY_REF *ref = NULL;
 	X509_POLICY_DATA *data;
 	X509_POLICY_CACHE *cache = x->policy_cache;
 	int i;
@@ -104,7 +78,6 @@
 		ret = -1;
 		goto bad_mapping;
 		}
-	cache->maps = sk_X509_POLICY_REF_new(ref_cmp);
 	for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++)
 		{
 		map = sk_POLICY_MAPPING_value(maps, i);
@@ -116,13 +89,6 @@
 			goto bad_mapping;
 			}
 
-		/* If we've already mapped from this OID bad mapping */
-		if (policy_map_find(cache, map->subjectDomainPolicy) != NULL)
-			{
-			ret = -1;
-			goto bad_mapping;
-			}
-
 		/* Attempt to find matching policy data */
 		data = policy_cache_find_data(cache, map->issuerDomainPolicy);
 		/* If we don't have anyPolicy can't map */
@@ -138,7 +104,7 @@
 			if (!data)
 				goto bad_mapping;
 			data->qualifier_set = cache->anyPolicy->qualifier_set;
-			map->issuerDomainPolicy = NULL;
+			/*map->issuerDomainPolicy = NULL;*/
 			data->flags |= POLICY_DATA_FLAG_MAPPED_ANY;
 			data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
 			if (!sk_X509_POLICY_DATA_push(cache->data, data))
@@ -149,23 +115,10 @@
 			}
 		else
 			data->flags |= POLICY_DATA_FLAG_MAPPED;
-
 		if (!sk_ASN1_OBJECT_push(data->expected_policy_set, 
 						map->subjectDomainPolicy))
 			goto bad_mapping;
-		
-		ref = OPENSSL_malloc(sizeof(X509_POLICY_REF));
-		if (!ref)
-			goto bad_mapping;
-
-		ref->subjectDomainPolicy = map->subjectDomainPolicy;
 		map->subjectDomainPolicy = NULL;
-		ref->data = data;
-
-		if (!sk_X509_POLICY_REF_push(cache->maps, ref))
-			goto bad_mapping;
-
-		ref = NULL;
 
 		}
 
@@ -173,13 +126,6 @@
 	bad_mapping:
 	if (ret == -1)
 		x->ex_flags |= EXFLAG_INVALID_POLICY;
-	if (ref)
-		policy_map_free(ref);
-	if (ret <= 0)
-		{
-		sk_X509_POLICY_REF_pop_free(cache->maps, policy_map_free);
-		cache->maps = NULL;
-		}
 	sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free);
 	return ret;
 
diff --git a/crypto/x509v3/pcy_node.c b/crypto/x509v3/pcy_node.c
index 6587cb0..bd1e7f1 100644
--- a/crypto/x509v3/pcy_node.c
+++ b/crypto/x509v3/pcy_node.c
@@ -92,13 +92,25 @@
 	}
 
 X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
+					const X509_POLICY_NODE *parent,	
 					const ASN1_OBJECT *id)
 	{
-	return tree_find_sk(level->nodes, id);
+	X509_POLICY_NODE *node;
+	int i;
+	for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++)
+		{
+		node = sk_X509_POLICY_NODE_value(level->nodes, i);
+		if (node->parent == parent)
+			{
+			if (!OBJ_cmp(node->data->valid_policy, id))
+				return node;
+			}
+		}
+	return NULL;
 	}
 
 X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
-			X509_POLICY_DATA *data,
+			const X509_POLICY_DATA *data,
 			X509_POLICY_NODE *parent,
 			X509_POLICY_TREE *tree)
 	{
@@ -155,4 +167,31 @@
 	OPENSSL_free(node);
 	}
 
+/* See if a policy node matches a policy OID. If mapping enabled look through
+ * expected policy set otherwise just valid policy.
+ */
 
+int policy_node_match(const X509_POLICY_LEVEL *lvl,
+		      const X509_POLICY_NODE *node, const ASN1_OBJECT *oid)
+	{
+	int i;
+	ASN1_OBJECT *policy_oid;
+	const X509_POLICY_DATA *x = node->data;
+
+	if (	    (lvl->flags & X509_V_FLAG_INHIBIT_MAP)
+		|| !(x->flags & POLICY_DATA_FLAG_MAP_MASK))
+		{
+		if (!OBJ_cmp(x->valid_policy, oid))
+			return 1;
+		return 0;
+		}
+
+	for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++)
+		{
+		policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i);
+		if (!OBJ_cmp(policy_oid, oid))
+			return 1;
+		}
+	return 0;
+
+	}
diff --git a/crypto/x509v3/pcy_tree.c b/crypto/x509v3/pcy_tree.c
index 89f84bf..92f6b24 100644
--- a/crypto/x509v3/pcy_tree.c
+++ b/crypto/x509v3/pcy_tree.c
@@ -62,6 +62,75 @@
 
 #include "pcy_int.h"
 
+/* Enable this to print out the complete policy tree at various point during
+ * evaluation.
+ */
+
+/*#define OPENSSL_POLICY_DEBUG*/
+
+#ifdef OPENSSL_POLICY_DEBUG
+
+static void expected_print(BIO *err, X509_POLICY_LEVEL *lev,
+				X509_POLICY_NODE *node, int indent)
+	{
+	if (	    (lev->flags & X509_V_FLAG_INHIBIT_MAP)
+		|| !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
+		BIO_puts(err, "  Not Mapped\n");
+	else
+		{
+		int i;
+		STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
+		ASN1_OBJECT *oid;
+		BIO_puts(err, "  Expected: ");
+		for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++)
+			{
+			oid = sk_ASN1_OBJECT_value(pset, i);
+			if (i)
+				BIO_puts(err, ", ");
+			i2a_ASN1_OBJECT(err, oid);
+			}
+		BIO_puts(err, "\n");
+		}
+	}
+
+static void tree_print(char *str, X509_POLICY_TREE *tree,
+			X509_POLICY_LEVEL *curr)
+	{
+	X509_POLICY_LEVEL *plev;
+	X509_POLICY_NODE *node;
+	int i;
+	BIO *err;
+	err = BIO_new_fp(stderr, BIO_NOCLOSE);
+	if (!curr)
+		curr = tree->levels + tree->nlevel;
+	else
+		curr++;
+	BIO_printf(err, "Level print after %s\n", str);
+	BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
+	for (plev = tree->levels; plev != curr; plev++)
+		{
+		BIO_printf(err, "Level %ld, flags = %x\n",
+				plev - tree->levels, plev->flags);
+		for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++)
+			{
+			node = sk_X509_POLICY_NODE_value(plev->nodes, i);
+			X509_POLICY_NODE_print(err, node, 2);
+			expected_print(err, plev, node, 2);
+			BIO_printf(err, "  Flags: %x\n", node->data->flags);
+			}
+		if (plev->anyPolicy)
+			X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
+		}
+
+	BIO_free(err);
+
+	}
+#else
+
+#define tree_print(a,b,c) /* */
+
+#endif
+
 /* Initialize policy tree. Return values:
  *  0 Some internal error occured.
  * -1 Inconsistent or invalid extensions in certificates.
@@ -87,8 +156,10 @@
 	*ptree = NULL;
 	n = sk_X509_num(certs);
 
+#if 0
 	/* Disable policy mapping for now... */
 	flags |= X509_V_FLAG_INHIBIT_MAP;
+#endif
 
 	if (flags & X509_V_FLAG_EXPLICIT_POLICY)
 		explicit_policy = 0;
@@ -184,7 +255,6 @@
 		level++;
 		x = sk_X509_value(certs, i);
 		cache = policy_cache_set(x);
-
 		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
 		level->cert = x;
 
@@ -213,13 +283,13 @@
 			level->flags |= X509_V_FLAG_INHIBIT_MAP;
 		else
 			{
-			map_skip--;
+			if (!(x->ex_flags & EXFLAG_SI))
+				map_skip--;
 			if ((cache->map_skip >= 0)
 				&& (cache->map_skip < map_skip))
 				map_skip = cache->map_skip;
 			}
 
-
 		}
 
 	*ptree = tree;
@@ -237,7 +307,32 @@
 
 	}
 
-/* This corresponds to RFC3280 XXXX XXXXX:
+static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
+				const X509_POLICY_DATA *data)
+	{
+	X509_POLICY_LEVEL *last = curr - 1;
+	X509_POLICY_NODE *node;
+	int i, matched = 0;
+	/* Iterate through all in nodes linking matches */
+	for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
+		{
+		node = sk_X509_POLICY_NODE_value(last->nodes, i);
+		if (policy_node_match(last, node, data->valid_policy))
+			{
+			if (!level_add_node(curr, data, node, NULL))
+				return 0;
+			matched = 1;
+			}
+		}
+	if (!matched && last->anyPolicy)
+		{
+		if (!level_add_node(curr, data, last->anyPolicy, NULL))
+			return 0;
+		}
+	return 1;
+	}
+
+/* This corresponds to RFC3280 6.1.3(d)(1):
  * link any data from CertificatePolicies onto matching parent
  * or anyPolicy if no match.
  */
@@ -248,7 +343,6 @@
 	int i;
 	X509_POLICY_LEVEL *last;
 	X509_POLICY_DATA *data;
-	X509_POLICY_NODE *parent;
 	last = curr - 1;
 	for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++)
 		{
@@ -261,40 +355,109 @@
 		 * link because then it will have the mapping flags
 		 * right and we can prune it later.
 		 */
+#if 0
 		if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
 			&& !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
 			continue;
-		/* Look for matching node in parent */
-		parent = level_find_node(last, data->valid_policy);
-		/* If no match link to anyPolicy */
-		if (!parent)
-			parent = last->anyPolicy;
-		if (parent && !level_add_node(curr, data, parent, NULL))
+#endif
+		/* Look for matching nodes in previous level */
+		if (!tree_link_matching_nodes(curr, data))
 				return 0;
 		}
 	return 1;
 	}
 
-/* This corresponds to RFC3280 XXXX XXXXX:
+/* This corresponds to RFC3280 6.1.3(d)(2):
  * Create new data for any unmatched policies in the parent and link
  * to anyPolicy.
  */
 
+static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
+			const X509_POLICY_CACHE *cache,
+			const ASN1_OBJECT *id,
+			X509_POLICY_NODE *node,
+			X509_POLICY_TREE *tree)
+	{
+	X509_POLICY_DATA *data;
+	if (id == NULL)
+		id = node->data->valid_policy;
+	/* Create a new node with qualifiers from anyPolicy and
+	 * id from unmatched node.
+	 */
+	data = policy_data_new(NULL, id, node_critical(node));
+
+	if (data == NULL)
+		return 0;
+	/* 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))
+		{
+		policy_data_free(data);
+		return 0;
+		}
+
+	return 1;
+	}
+
+static int tree_link_unmatched(X509_POLICY_LEVEL *curr,
+			const X509_POLICY_CACHE *cache,
+			X509_POLICY_NODE *node,
+			X509_POLICY_TREE *tree)
+	{
+	const X509_POLICY_LEVEL *last = curr - 1;
+	int i;
+
+	if (	    (last->flags & X509_V_FLAG_INHIBIT_MAP)
+		|| !(node->data->flags & POLICY_DATA_FLAG_MAPPED))
+		{
+		/* If no policy mapping: matched if one child present */
+		if (node->nchild)
+			return 1;
+		if (!tree_add_unmatched(curr, cache, NULL, node, tree))
+			return 0;
+		/* Add it */
+		}
+	else
+		{
+		/* If mapping: matched if one child per expected policy set */
+		STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
+		if (node->nchild == sk_ASN1_OBJECT_num(expset))
+			return 1;
+		/* Locate unmatched nodes */
+		for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++)
+			{
+			ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
+			if (level_find_node(curr, node, oid))
+				continue;
+			if (!tree_add_unmatched(curr, cache, oid, node, tree))
+				return 0;
+			}
+
+		}
+
+	return 1;
+
+	}
+
 static int tree_link_any(X509_POLICY_LEVEL *curr,
 			const X509_POLICY_CACHE *cache,
 			X509_POLICY_TREE *tree)
 	{
 	int i;
-	X509_POLICY_DATA *data;
+	/*X509_POLICY_DATA *data;*/
 	X509_POLICY_NODE *node;
-	X509_POLICY_LEVEL *last;
-
-	last = curr - 1;
+	X509_POLICY_LEVEL *last = curr - 1;
 
 	for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
 		{
 		node = sk_X509_POLICY_NODE_value(last->nodes, i);
 
+		if (!tree_link_unmatched(curr, cache, node, tree))
+			return 0;
+
+#if 0
+
 		/* Skip any node with any children: we only want unmathced
 		 * nodes.
 		 *
@@ -303,6 +466,7 @@
 		 */
 		if (node->nchild)
 			continue;
+
 		/* Create a new node with qualifiers from anyPolicy and
 		 * id from unmatched node.
 		 */
@@ -319,6 +483,9 @@
 			policy_data_free(data);
 			return 0;
 			}
+
+#endif
+
 		}
 	/* Finally add link to anyPolicy */
 	if (last->anyPolicy)
@@ -337,30 +504,36 @@
 
 static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
 	{
+	STACK_OF(X509_POLICY_NODE) *nodes;
 	X509_POLICY_NODE *node;
 	int i;
-	for (i = sk_X509_POLICY_NODE_num(curr->nodes) - 1; i >= 0; i--)
+	nodes = curr->nodes;
+	if (curr->flags & X509_V_FLAG_INHIBIT_MAP)
 		{
-		node = sk_X509_POLICY_NODE_value(curr->nodes, i);
-		/* Delete any mapped data: see RFC3280 XXXX */
-		if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK)
+		for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
 			{
-			node->parent->nchild--;
-			OPENSSL_free(node);
-			(void)sk_X509_POLICY_NODE_delete(curr->nodes, i);
+			node = sk_X509_POLICY_NODE_value(nodes, i);
+			/* Delete any mapped data: see RFC3280 XXXX */
+			if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK)
+				{
+				node->parent->nchild--;
+				OPENSSL_free(node);
+				(void)sk_X509_POLICY_NODE_delete(nodes,i);
+				}
 			}
 		}
 
 	for(;;)	{
 		--curr;
-		for (i = sk_X509_POLICY_NODE_num(curr->nodes) - 1; i >= 0; i--)
+		nodes = curr->nodes;
+		for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
 			{
-			node = sk_X509_POLICY_NODE_value(curr->nodes, i);
+			node = sk_X509_POLICY_NODE_value(nodes, i);
 			if (node->nchild == 0)
 				{
 				node->parent->nchild--;
 				OPENSSL_free(node);
-				(void)sk_X509_POLICY_NODE_delete(curr->nodes, i);
+				(void)sk_X509_POLICY_NODE_delete(nodes, i);
 				}
 			}
 		if (curr->anyPolicy && !curr->anyPolicy->nchild)
@@ -536,6 +709,7 @@
 		if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
 			&& !tree_link_any(curr, cache, tree))
 			return 0;
+	tree_print("before tree_prune()", tree, curr);
 		ret = tree_prune(tree, curr);
 		if (ret != 1)
 			return ret;
@@ -604,7 +778,6 @@
 	*pexplicit_policy = 0;
 	ret = tree_init(&tree, certs, flags);
 
-
 	switch (ret)
 		{
 
@@ -613,6 +786,10 @@
 		return 1;
 
 		/* Some internal error */
+		case -1:
+		return -1;
+
+		/* Some internal error */
 		case 0:
 		return 0;
 
@@ -646,6 +823,8 @@
 	if (!tree) goto error;
 	ret = tree_evaluate(tree);
 
+	tree_print("tree_evaluate()", tree, NULL);
+
 	if (ret <= 0)
 		goto error;
 
diff --git a/crypto/x509v3/v3_addr.c b/crypto/x509v3/v3_addr.c
index efdf7c3..9087d66 100644
--- a/crypto/x509v3/v3_addr.c
+++ b/crypto/x509v3/v3_addr.c
@@ -236,7 +236,7 @@
 /*
  * i2r handler for an IPAddrBlocks extension.
  */
-static int i2r_IPAddrBlocks(X509V3_EXT_METHOD *method,
+static int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method,
 			    void *ext,
 			    BIO *out,
 			    int indent)
@@ -315,8 +315,7 @@
 				const int length)
 {
   unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN];
-  int prefixlen_a = 0;
-  int prefixlen_b = 0;
+  int prefixlen_a = 0, prefixlen_b = 0;
   int r;
 
   switch (a->type) {
@@ -596,10 +595,10 @@
     return NULL;
   switch (afi) {
   case IANA_AFI_IPV4:
-    (void)sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
+    sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
     break;
   case IANA_AFI_IPV6:
-    (void)sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);
+    sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);
     break;
   }
   f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges;
@@ -856,7 +855,7 @@
       if (!make_addressRange(&merged, a_min, b_max, length))
 	return 0;
       sk_IPAddressOrRange_set(aors, i, merged);
-      (void)sk_IPAddressOrRange_delete(aors, i + 1);
+      sk_IPAddressOrRange_delete(aors, i + 1);
       IPAddressOrRange_free(a);
       IPAddressOrRange_free(b);
       --i;
@@ -880,7 +879,7 @@
 				    v3_addr_get_afi(f)))
       return 0;
   }
-  (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp);
+  sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp);
   sk_IPAddressFamily_sort(addr);
   OPENSSL_assert(v3_addr_is_canonical(addr));
   return 1;
@@ -889,7 +888,7 @@
 /*
  * v2i handler for the IPAddrBlocks extension.
  */
-static void *v2i_IPAddrBlocks(struct v3_ext_method *method,
+static void *v2i_IPAddrBlocks(const struct v3_ext_method *method,
 			      struct v3_ext_ctx *ctx,
 			      STACK_OF(CONF_VALUE) *values)
 {
@@ -1125,7 +1124,7 @@
     return 1;
   if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b))
     return 0;
-  (void)sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp);
+  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);
@@ -1167,7 +1166,7 @@
 {
   IPAddrBlocks *child = NULL;
   int i, j, ret = 1;
-  X509 *x = NULL;
+  X509 *x;
 
   OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0);
   OPENSSL_assert(ctx != NULL || ext != NULL);
@@ -1180,6 +1179,7 @@
    */
   if (ext != NULL) {
     i = -1;
+    x = NULL;
   } else {
     i = 0;
     x = sk_X509_value(chain, i);
@@ -1189,7 +1189,7 @@
   }
   if (!v3_addr_is_canonical(ext))
     validation_err(X509_V_ERR_INVALID_EXTENSION);
-  (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp);
+  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;
@@ -1215,7 +1215,7 @@
       }
       continue;
     }
-    (void)sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp);
+    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);
@@ -1242,6 +1242,7 @@
   /*
    * Trust anchor can't inherit.
    */
+  OPENSSL_assert(x != NULL);
   if (x->rfc3779_addr != NULL) {
     for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) {
       IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, j);
diff --git a/crypto/x509v3/v3_alt.c b/crypto/x509v3/v3_alt.c
index 69244e4..d29d943 100644
--- a/crypto/x509v3/v3_alt.c
+++ b/crypto/x509v3/v3_alt.c
@@ -82,6 +82,12 @@
 (X509V3_EXT_I2V)i2v_GENERAL_NAMES,
 (X509V3_EXT_V2I)v2i_issuer_alt,
 NULL, NULL, NULL},
+
+{ NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES),
+0,0,0,0,
+0,0,
+(X509V3_EXT_I2V)i2v_GENERAL_NAMES,
+NULL, NULL, NULL, NULL},
 };
 
 STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
@@ -387,8 +393,8 @@
 	
 }
 
-GENERAL_NAMES *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method,
-				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
+				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
 {
 	GENERAL_NAME *gen;
 	GENERAL_NAMES *gens = NULL;
@@ -409,20 +415,118 @@
 	return NULL;
 }
 
-GENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
-							 CONF_VALUE *cnf)
+GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+			       CONF_VALUE *cnf)
 	{
 	return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
 	}
 
-GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
-				X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
-						 CONF_VALUE *cnf, int is_nc)
+GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
+			       const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+			       int gen_type, char *value, int is_nc)
 	{
 	char is_string = 0;
-	int type;
 	GENERAL_NAME *gen = NULL;
 
+	if(!value)
+		{
+		X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_MISSING_VALUE);
+		return NULL;
+		}
+
+	if (out)
+		gen = out;
+	else
+		{
+		gen = GENERAL_NAME_new();
+		if(gen == NULL)
+			{
+			X509V3err(X509V3_F_A2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE);
+			return NULL;
+			}
+		}
+
+	switch (gen_type)
+		{
+		case GEN_URI:
+		case GEN_EMAIL:
+		case GEN_DNS:
+		is_string = 1;
+		break;
+		
+		case GEN_RID:
+		{
+		ASN1_OBJECT *obj;
+		if(!(obj = OBJ_txt2obj(value,0)))
+			{
+			X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_BAD_OBJECT);
+			ERR_add_error_data(2, "value=", value);
+			goto err;
+			}
+		gen->d.rid = obj;
+		}
+		break;
+
+		case GEN_IPADD:
+		if (is_nc)
+			gen->d.ip = a2i_IPADDRESS_NC(value);
+		else
+			gen->d.ip = a2i_IPADDRESS(value);
+		if(gen->d.ip == NULL)
+			{
+			X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_BAD_IP_ADDRESS);
+			ERR_add_error_data(2, "value=", value);
+			goto err;
+			}
+		break;
+
+		case GEN_DIRNAME:
+		if (!do_dirname(gen, value, ctx))
+			{
+			X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_DIRNAME_ERROR);
+			goto err;
+			}
+		break;
+
+		case GEN_OTHERNAME:
+		if (!do_othername(gen, value, ctx))
+			{
+			X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_OTHERNAME_ERROR);
+			goto err;
+			}
+		break;
+		default:
+		X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_UNSUPPORTED_TYPE);
+		goto err;
+		}
+
+	if(is_string)
+		{
+		if(!(gen->d.ia5 = M_ASN1_IA5STRING_new()) ||
+			      !ASN1_STRING_set(gen->d.ia5, (unsigned char*)value,
+					       strlen(value)))
+			{
+			X509V3err(X509V3_F_A2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+
+	gen->type = gen_type;
+
+	return gen;
+
+	err:
+	if (!out)
+		GENERAL_NAME_free(gen);
+	return NULL;
+	}
+
+GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
+				  const X509V3_EXT_METHOD *method,
+				  X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
+	{
+	int type;
+
 	char *name, *value;
 
 	name = cnf->name;
@@ -434,103 +538,29 @@
 		return NULL;
 		}
 
-	if (out)
-		gen = out;
-	else
-		{
-		gen = GENERAL_NAME_new();
-		if(gen == NULL)
-			{
-			X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,ERR_R_MALLOC_FAILURE);
-			return NULL;
-			}
-		}
-
 	if(!name_cmp(name, "email"))
-		{
-		is_string = 1;
 		type = GEN_EMAIL;
-		}
 	else if(!name_cmp(name, "URI"))
-		{
-		is_string = 1;
 		type = GEN_URI;
-		}
 	else if(!name_cmp(name, "DNS"))
-		{
-		is_string = 1;
 		type = GEN_DNS;
-		}
 	else if(!name_cmp(name, "RID"))
-		{
-		ASN1_OBJECT *obj;
-		if(!(obj = OBJ_txt2obj(value,0)))
-			{
-			X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_BAD_OBJECT);
-			ERR_add_error_data(2, "value=", value);
-			goto err;
-			}
-		gen->d.rid = obj;
 		type = GEN_RID;
-		}
 	else if(!name_cmp(name, "IP"))
-		{
-		if (is_nc)
-			gen->d.ip = a2i_IPADDRESS_NC(value);
-		else
-			gen->d.ip = a2i_IPADDRESS(value);
-		if(gen->d.ip == NULL)
-			{
-			X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_BAD_IP_ADDRESS);
-			ERR_add_error_data(2, "value=", value);
-			goto err;
-			}
 		type = GEN_IPADD;
-		}
 	else if(!name_cmp(name, "dirName"))
-		{
 		type = GEN_DIRNAME;
-		if (!do_dirname(gen, value, ctx))
-			{
-			X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_DIRNAME_ERROR);
-			goto err;
-			}
-		}
 	else if(!name_cmp(name, "otherName"))
-		{
-		if (!do_othername(gen, value, ctx))
-			{
-			X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_OTHERNAME_ERROR);
-			goto err;
-			}
 		type = GEN_OTHERNAME;
-		}
 	else
 		{
 		X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_UNSUPPORTED_OPTION);
 		ERR_add_error_data(2, "name=", name);
-		goto err;
+		return NULL;
 		}
 
-	if(is_string)
-		{
-		if(!(gen->d.ia5 = M_ASN1_IA5STRING_new()) ||
-			      !ASN1_STRING_set(gen->d.ia5, (unsigned char*)value,
-					       strlen(value)))
-			{
-			X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,ERR_R_MALLOC_FAILURE);
-			goto err;
-			}
-		}
+	return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
 
-	gen->type = type;
-
-	return gen;
-
-	err:
-	if (!out)
-		GENERAL_NAME_free(gen);
-	return NULL;
 	}
 
 static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
@@ -578,7 +608,6 @@
 	if (!ret)
 		X509_NAME_free(nm);
 	gen->d.dirn = nm;
-
 	X509V3_section_free(ctx, sk);
 		
 	return ret;
diff --git a/crypto/x509v3/v3_asid.c b/crypto/x509v3/v3_asid.c
index abd497e..56702f8 100644
--- a/crypto/x509v3/v3_asid.c
+++ b/crypto/x509v3/v3_asid.c
@@ -152,7 +152,7 @@
 /*
  * i2r method for an ASIdentifier extension.
  */
-static int i2r_ASIdentifiers(X509V3_EXT_METHOD *method,
+static int i2r_ASIdentifiers(const X509V3_EXT_METHOD *method,
 			     void *ext,
 			     BIO *out,
 			     int indent)
@@ -466,7 +466,7 @@
 	break;
       }
       ASIdOrRange_free(b);
-      (void)sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1);
+      sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1);
       i--;
       continue;
     }
@@ -495,7 +495,7 @@
 /*
  * v2i method for an ASIdentifier extension.
  */
-static void *v2i_ASIdentifiers(struct v3_ext_method *method,
+static void *v2i_ASIdentifiers(const struct v3_ext_method *method,
 			       struct v3_ext_ctx *ctx,
 			       STACK_OF(CONF_VALUE) *values)
 {
@@ -707,7 +707,7 @@
 {
   ASIdOrRanges *child_as = NULL, *child_rdi = NULL;
   int i, ret = 1, inherit_as = 0, inherit_rdi = 0;
-  X509 *x = NULL;
+  X509 *x;
 
   assert(chain != NULL && sk_X509_num(chain) > 0);
   assert(ctx != NULL || ext != NULL);
@@ -720,6 +720,7 @@
    */
   if (ext != NULL) {
     i = -1;
+    x = NULL;
   } else {
     i = 0;
     x = sk_X509_value(chain, i);
@@ -799,6 +800,7 @@
   /*
    * Trust anchor can't inherit.
    */
+  assert(x != NULL);
   if (x->rfc3779_asid != NULL) {
     if (x->rfc3779_asid->asnum != NULL &&
 	x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit)
diff --git a/crypto/x509v3/v3_conf.c b/crypto/x509v3/v3_conf.c
index 11eb6b7..6730f9a 100644
--- a/crypto/x509v3/v3_conf.c
+++ b/crypto/x509v3/v3_conf.c
@@ -72,14 +72,14 @@
 static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, int crit, int type, X509V3_CTX *ctx);
 static char *conf_lhash_get_string(void *db, char *section, char *value);
 static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section);
-static X509_EXTENSION *do_ext_i2d(X509V3_EXT_METHOD *method, int ext_nid,
-						 int crit, void *ext_struc);
+static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
+				  int crit, void *ext_struc);
 static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len);
 /* CONF *conf:  Config file    */
 /* char *name:  Name    */
 /* char *value:  Value    */
 X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
-	     char *value)
+				 char *value)
 	{
 	int crit;
 	int ext_type;
@@ -99,7 +99,7 @@
 /* CONF *conf:  Config file    */
 /* char *value:  Value    */
 X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
-	     char *value)
+				     char *value)
 	{
 	int crit;
 	int ext_type;
@@ -113,9 +113,9 @@
 /* CONF *conf:  Config file    */
 /* char *value:  Value    */
 static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
-	     int crit, char *value)
+				    int crit, char *value)
 	{
-	X509V3_EXT_METHOD *method;
+	const X509V3_EXT_METHOD *method;
 	X509_EXTENSION *ext;
 	STACK_OF(CONF_VALUE) *nval;
 	void *ext_struc;
@@ -172,8 +172,8 @@
 
 	}
 
-static X509_EXTENSION *do_ext_i2d(X509V3_EXT_METHOD *method, int ext_nid,
-						 int crit, void *ext_struc)
+static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
+				  int crit, void *ext_struc)
 	{
 	unsigned char *ext_der;
 	int ext_len;
@@ -214,7 +214,7 @@
 
 X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc)
 	{
-	X509V3_EXT_METHOD *method;
+	const X509V3_EXT_METHOD *method;
 	if (!(method = X509V3_EXT_get_nid(ext_nid))) {
 		X509V3err(X509V3_F_X509V3_EXT_I2D,X509V3_R_UNKNOWN_EXTENSION);
 		return NULL;
@@ -258,7 +258,8 @@
 
 /* Create a generic extension: for now just handle DER type */
 static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
-	     int crit, int gen_type, X509V3_CTX *ctx)
+					    int crit, int gen_type,
+					    X509V3_CTX *ctx)
 	{
 	unsigned char *ext_der=NULL;
 	long ext_len;
@@ -322,7 +323,7 @@
 
 
 int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section,
-	     STACK_OF(X509_EXTENSION) **sk)
+			    STACK_OF(X509_EXTENSION) **sk)
 	{
 	X509_EXTENSION *ext;
 	STACK_OF(CONF_VALUE) *nval;
@@ -343,7 +344,7 @@
 /* Convenience functions to add extensions to a certificate, CRL and request */
 
 int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
-	     X509 *cert)
+			 X509 *cert)
 	{
 	STACK_OF(X509_EXTENSION) **sk = NULL;
 	if (cert)
@@ -354,7 +355,7 @@
 /* Same as above but for a CRL */
 
 int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
-	     X509_CRL *crl)
+			     X509_CRL *crl)
 	{
 	STACK_OF(X509_EXTENSION) **sk = NULL;
 	if (crl)
@@ -443,7 +444,7 @@
 	}
 
 void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
-	     X509_CRL *crl, int flags)
+		    X509_CRL *crl, int flags)
 	{
 	ctx->issuer_cert = issuer;
 	ctx->subject_cert = subj;
@@ -454,8 +455,8 @@
 
 /* Old conf compatibility functions */
 
-X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name,
-	     char *value)
+X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+				char *name, char *value)
 	{
 	CONF ctmp;
 	CONF_set_nconf(&ctmp, conf);
@@ -464,8 +465,8 @@
 
 /* LHASH *conf:  Config file    */
 /* char *value:  Value    */
-X509_EXTENSION *X509V3_EXT_conf_nid(LHASH *conf, X509V3_CTX *ctx, int ext_nid,
-	     char *value)
+X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+				    int ext_nid, char *value)
 	{
 	CONF ctmp;
 	CONF_set_nconf(&ctmp, conf);
@@ -489,14 +490,14 @@
 NULL
 };
 
-void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH *lhash)
+void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash)
 	{
 	ctx->db_meth = &conf_lhash_method;
 	ctx->db = lhash;
 	}
 
-int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
-	     X509 *cert)
+int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+			char *section, X509 *cert)
 	{
 	CONF ctmp;
 	CONF_set_nconf(&ctmp, conf);
@@ -505,8 +506,8 @@
 
 /* Same as above but for a CRL */
 
-int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
-	     X509_CRL *crl)
+int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+			    char *section, X509_CRL *crl)
 	{
 	CONF ctmp;
 	CONF_set_nconf(&ctmp, conf);
@@ -515,8 +516,8 @@
 
 /* Add extensions to certificate request */
 
-int X509V3_EXT_REQ_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
-	     X509_REQ *req)
+int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+			    char *section, X509_REQ *req)
 	{
 	CONF ctmp;
 	CONF_set_nconf(&ctmp, conf);
diff --git a/crypto/x509v3/v3_cpols.c b/crypto/x509v3/v3_cpols.c
index ad0506d..1f0798b 100644
--- a/crypto/x509v3/v3_cpols.c
+++ b/crypto/x509v3/v3_cpols.c
@@ -450,5 +450,8 @@
 	else
 		BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
 	}
-	
+
+
 IMPLEMENT_STACK_OF(X509_POLICY_NODE)
+IMPLEMENT_STACK_OF(X509_POLICY_DATA)
+
diff --git a/crypto/x509v3/v3_crld.c b/crypto/x509v3/v3_crld.c
index 181a897..790a6dd 100644
--- a/crypto/x509v3/v3_crld.c
+++ b/crypto/x509v3/v3_crld.c
@@ -3,7 +3,7 @@
  * project 1999.
  */
 /* ====================================================================
- * Copyright (c) 1999 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
@@ -63,45 +63,254 @@
 #include <openssl/asn1t.h>
 #include <openssl/x509v3.h>
 
-static STACK_OF(CONF_VALUE) *i2v_crld(X509V3_EXT_METHOD *method,
-		STACK_OF(DIST_POINT) *crld, STACK_OF(CONF_VALUE) *extlist);
-static STACK_OF(DIST_POINT) *v2i_crld(X509V3_EXT_METHOD *method,
-				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+static void *v2i_crld(const X509V3_EXT_METHOD *method,
+		      X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
+		     int indent);
 
-const X509V3_EXT_METHOD v3_crld = {
-NID_crl_distribution_points, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(CRL_DIST_POINTS),
-0,0,0,0,
-0,0,
-(X509V3_EXT_I2V)i2v_crld,
-(X509V3_EXT_V2I)v2i_crld,
-0,0,
-NULL
+const X509V3_EXT_METHOD v3_crld =
+	{
+	NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
+	0,0,0,0,
+	0,0,
+	0,
+	v2i_crld,
+	i2r_crldp,0,
+	NULL
+	};
+
+const X509V3_EXT_METHOD v3_freshest_crl =
+	{
+	NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
+	0,0,0,0,
+	0,0,
+	0,
+	v2i_crld,
+	i2r_crldp,0,
+	NULL
+	};
+
+static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, char *sect)
+	{
+	STACK_OF(CONF_VALUE) *gnsect;
+	STACK_OF(GENERAL_NAME) *gens;
+	if (*sect == '@')
+		gnsect = X509V3_get_section(ctx, sect + 1);
+	else
+		gnsect = X509V3_parse_list(sect);
+	if (!gnsect)
+		{
+		X509V3err(X509V3_F_GNAMES_FROM_SECTNAME,
+						X509V3_R_SECTION_NOT_FOUND);
+		return NULL;
+		}
+	gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
+	if (*sect == '@')
+		X509V3_section_free(ctx, gnsect);
+	else
+		sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free);
+	return gens;
+	}
+
+static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
+							CONF_VALUE *cnf)
+	{
+	STACK_OF(GENERAL_NAME) *fnm = NULL;
+	STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
+	if (!strncmp(cnf->name, "fullname", 9))
+		{
+		fnm = gnames_from_sectname(ctx, cnf->value);
+		if (!fnm)
+			goto err;
+		}
+	else if (!strcmp(cnf->name, "relativename"))
+		{
+		int ret;
+		STACK_OF(CONF_VALUE) *dnsect;
+		X509_NAME *nm;
+		nm = X509_NAME_new();
+		if (!nm)
+			return -1;
+		dnsect = X509V3_get_section(ctx, cnf->value);
+		if (!dnsect)
+			{
+			X509V3err(X509V3_F_SET_DIST_POINT_NAME,
+						X509V3_R_SECTION_NOT_FOUND);
+			return -1;
+			}
+		ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
+		X509V3_section_free(ctx, dnsect);
+		rnm = nm->entries;
+		nm->entries = NULL;
+		X509_NAME_free(nm);
+		if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0)
+			goto err;
+		/* Since its a name fragment can't have more than one
+		 * RDNSequence
+		 */
+		if (sk_X509_NAME_ENTRY_value(rnm,
+				sk_X509_NAME_ENTRY_num(rnm) - 1)->set)
+			{
+			X509V3err(X509V3_F_SET_DIST_POINT_NAME,
+						X509V3_R_INVALID_MULTIPLE_RDNS);
+			goto err;
+			}
+		}
+	else
+		return 0;
+
+	if (*pdp)
+		{
+		X509V3err(X509V3_F_SET_DIST_POINT_NAME,
+						X509V3_R_DISTPOINT_ALREADY_SET);
+		goto err;
+		}
+
+	*pdp = DIST_POINT_NAME_new();
+	if (!*pdp)
+		goto err;
+	if (fnm)
+		{
+		(*pdp)->type = 0;
+		(*pdp)->name.fullname = fnm;
+		}
+	else
+		{
+		(*pdp)->type = 1;
+		(*pdp)->name.relativename = rnm;
+		}
+
+	return 1;
+		
+	err:
+	if (fnm)
+		sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free);
+	if (rnm)
+		sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free);
+	return -1;
+	}
+
+static const BIT_STRING_BITNAME reason_flags[] = {
+{0, "Unused", "unused"},
+{1, "Key Compromise", "keyCompromise"},
+{2, "CA Compromise", "CACompromise"},
+{3, "Affiliation Changed", "affiliationChanged"},
+{4, "Superseded", "superseded"},
+{5, "Cessation Of Operation", "cessationOfOperation"},
+{6, "Certificate Hold", "certificateHold"},
+{7, "Privilege Withdrawn", "privilegeWithdrawn"},
+{8, "AA Compromise", "AACompromise"},
+{-1, NULL, NULL}
 };
 
-static STACK_OF(CONF_VALUE) *i2v_crld(X509V3_EXT_METHOD *method,
-			STACK_OF(DIST_POINT) *crld, STACK_OF(CONF_VALUE) *exts)
-{
-	DIST_POINT *point;
-	int i;
-	for(i = 0; i < sk_DIST_POINT_num(crld); i++) {
-		point = sk_DIST_POINT_value(crld, i);
-		if(point->distpoint) {
-			if(point->distpoint->type == 0)
-				exts = i2v_GENERAL_NAMES(NULL,
-					 point->distpoint->name.fullname, exts);
-		        else X509V3_add_value("RelativeName","<UNSUPPORTED>", &exts);
+static int set_reasons(ASN1_BIT_STRING **preas, char *value)
+	{
+	STACK_OF(CONF_VALUE) *rsk = NULL;
+	const BIT_STRING_BITNAME *pbn;
+	const char *bnam;
+	int i, ret = 0;
+	rsk = X509V3_parse_list(value);
+	if (!rsk)
+		return 0;
+	if (*preas)
+		return 0;
+	for (i = 0; i < sk_CONF_VALUE_num(rsk); i++)
+		{
+		bnam = sk_CONF_VALUE_value(rsk, i)->name;
+		if (!*preas)
+			{
+			*preas = ASN1_BIT_STRING_new();
+			if (!*preas)
+				goto err;
+			}
+		for (pbn = reason_flags; pbn->lname; pbn++)
+			{
+			if (!strcmp(pbn->sname, bnam))
+				{
+				if (!ASN1_BIT_STRING_set_bit(*preas,
+							pbn->bitnum, 1))
+					goto err;
+				break;
+				}
+			}
+		if (!pbn->lname)
+			goto err;
 		}
-		if(point->reasons) 
-			X509V3_add_value("reasons","<UNSUPPORTED>", &exts);
-		if(point->CRLissuer)
-			X509V3_add_value("CRLissuer","<UNSUPPORTED>", &exts);
-	}
-	return exts;
-}
+	ret = 1;
 
-static STACK_OF(DIST_POINT) *v2i_crld(X509V3_EXT_METHOD *method,
-				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
-{
+	err:
+	sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free);
+	return ret;
+	}
+
+static int print_reasons(BIO *out, const char *rname,
+			ASN1_BIT_STRING *rflags, int indent)
+	{
+	int first = 1;
+	const BIT_STRING_BITNAME *pbn;
+	BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
+	for (pbn = reason_flags; pbn->lname; pbn++)
+		{
+		if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum))
+			{
+			if (first)
+				first = 0;
+			else
+				BIO_puts(out, ", ");
+			BIO_puts(out, pbn->lname);
+			}
+		}
+	if (first)
+		BIO_puts(out, "<EMPTY>\n");
+	else
+		BIO_puts(out, "\n");
+	return 1;
+	}
+
+static DIST_POINT *crldp_from_section(X509V3_CTX *ctx,
+						STACK_OF(CONF_VALUE) *nval)
+	{
+	int i;
+	CONF_VALUE *cnf;
+	DIST_POINT *point = NULL;
+	point = DIST_POINT_new();
+	if (!point)
+		goto err;
+	for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
+		{
+		int ret;
+		cnf = sk_CONF_VALUE_value(nval, i);
+		ret = set_dist_point_name(&point->distpoint, ctx, cnf);
+		if (ret > 0)
+			continue;
+		if (ret < 0)
+			goto err;
+		if (!strcmp(cnf->name, "reasons"))
+			{
+			if (!set_reasons(&point->reasons, cnf->value))
+				goto err;
+			}
+		else if (!strcmp(cnf->name, "CRLissuer"))
+			{
+			point->CRLissuer =
+				gnames_from_sectname(ctx, cnf->value);
+			if (!point->CRLissuer)
+				goto err;
+			}
+		}
+
+	return point;
+			
+
+	err:
+	if (point)
+		DIST_POINT_free(point);
+	return NULL;
+	}
+
+static void *v2i_crld(const X509V3_EXT_METHOD *method,
+		      X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+	{
 	STACK_OF(DIST_POINT) *crld = NULL;
 	GENERAL_NAMES *gens = NULL;
 	GENERAL_NAME *gen = NULL;
@@ -111,19 +320,44 @@
 	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
 		DIST_POINT *point;
 		cnf = sk_CONF_VALUE_value(nval, i);
-		if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) goto err; 
-		if(!(gens = GENERAL_NAMES_new())) goto merr;
-		if(!sk_GENERAL_NAME_push(gens, gen)) goto merr;
-		gen = NULL;
-		if(!(point = DIST_POINT_new())) goto merr;
-		if(!sk_DIST_POINT_push(crld, point)) {
-			DIST_POINT_free(point);
-			goto merr;
-		}
-		if(!(point->distpoint = DIST_POINT_NAME_new())) goto merr;
-		point->distpoint->name.fullname = gens;
-		point->distpoint->type = 0;
-		gens = NULL;
+		if (!cnf->value)
+			{
+			STACK_OF(CONF_VALUE) *dpsect;
+			dpsect = X509V3_get_section(ctx, cnf->name);
+			if (!dpsect)
+				goto err;
+			point = crldp_from_section(ctx, dpsect);
+			X509V3_section_free(ctx, dpsect);
+			if (!point)
+				goto err;
+			if(!sk_DIST_POINT_push(crld, point))
+				{
+				DIST_POINT_free(point);
+				goto merr;
+				}
+			}
+		else
+			{
+			if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
+				goto err; 
+			if(!(gens = GENERAL_NAMES_new()))
+				goto merr;
+			if(!sk_GENERAL_NAME_push(gens, gen))
+				goto merr;
+			gen = NULL;
+			if(!(point = DIST_POINT_new()))
+				goto merr;
+			if(!sk_DIST_POINT_push(crld, point))
+				{
+				DIST_POINT_free(point);
+				goto merr;
+				}
+			if(!(point->distpoint = DIST_POINT_NAME_new()))
+				goto merr;
+			point->distpoint->name.fullname = gens;
+			point->distpoint->type = 0;
+			gens = NULL;
+			}
 	}
 	return crld;
 
@@ -139,11 +373,31 @@
 IMPLEMENT_STACK_OF(DIST_POINT)
 IMPLEMENT_ASN1_SET_OF(DIST_POINT)
 
+static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+								void *exarg)
+	{
+	DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;
 
-ASN1_CHOICE(DIST_POINT_NAME) = {
+	switch(operation)
+		{
+		case ASN1_OP_NEW_POST:
+		dpn->dpname = NULL;
+		break;
+
+		case ASN1_OP_FREE_POST:
+		if (dpn->dpname)
+			X509_NAME_free(dpn->dpname);
+		break;
+		}
+	return 1;
+	}
+
+
+ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = {
 	ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0),
 	ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1)
-} ASN1_CHOICE_END(DIST_POINT_NAME)
+} ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type)
+
 
 IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME)
 
@@ -160,3 +414,203 @@
 ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS)
 
 IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS)
+
+ASN1_SEQUENCE(ISSUING_DIST_POINT) = {
+	ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0),
+	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1),
+	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2),
+	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3),
+	ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4),
+	ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5)
+} ASN1_SEQUENCE_END(ISSUING_DIST_POINT)
+
+IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
+
+static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
+		   int indent);
+static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+		     STACK_OF(CONF_VALUE) *nval);
+
+const X509V3_EXT_METHOD v3_idp =
+	{
+	NID_issuing_distribution_point, X509V3_EXT_MULTILINE,
+	ASN1_ITEM_ref(ISSUING_DIST_POINT),
+	0,0,0,0,
+	0,0,
+	0,
+	v2i_idp,
+	i2r_idp,0,
+	NULL
+	};
+
+static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+		     STACK_OF(CONF_VALUE) *nval)
+	{
+	ISSUING_DIST_POINT *idp = NULL;
+	CONF_VALUE *cnf;
+	char *name, *val;
+	int i, ret;
+	idp = ISSUING_DIST_POINT_new();
+	if (!idp)
+		goto merr;
+	for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
+		{
+		cnf = sk_CONF_VALUE_value(nval, i);
+		name = cnf->name;
+		val = cnf->value;
+		ret = set_dist_point_name(&idp->distpoint, ctx, cnf);
+		if (ret > 0)
+			continue;
+		if (ret < 0)
+			goto err;
+		if (!strcmp(name, "onlyuser"))
+			{
+			if (!X509V3_get_value_bool(cnf, &idp->onlyuser))
+				goto err;
+			}
+		else if (!strcmp(name, "onlyCA"))
+			{
+			if (!X509V3_get_value_bool(cnf, &idp->onlyCA))
+				goto err;
+			}
+		else if (!strcmp(name, "onlyAA"))
+			{
+			if (!X509V3_get_value_bool(cnf, &idp->onlyattr))
+				goto err;
+			}
+		else if (!strcmp(name, "indirectCRL"))
+			{
+			if (!X509V3_get_value_bool(cnf, &idp->indirectCRL))
+				goto err;
+			}
+		else if (!strcmp(name, "onlysomereasons"))
+			{
+			if (!set_reasons(&idp->onlysomereasons, val))
+				goto err;
+			}
+		else
+			{
+                        X509V3err(X509V3_F_V2I_IDP, X509V3_R_INVALID_NAME);
+                        X509V3_conf_err(cnf);
+                        goto err;
+			}
+		}
+	return idp;
+
+	merr:
+	X509V3err(X509V3_F_V2I_IDP,ERR_R_MALLOC_FAILURE);
+	err:
+	ISSUING_DIST_POINT_free(idp);
+	return NULL;
+	}
+
+static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent)
+	{
+	int i;
+	for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
+		{
+		BIO_printf(out, "%*s", indent + 2, "");
+		GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
+		BIO_puts(out, "\n");
+		}
+	return 1;
+	}
+
+static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent)
+	{
+	if (dpn->type == 0)
+		{
+		BIO_printf(out, "%*sFull Name:\n", indent, "");
+		print_gens(out, dpn->name.fullname, indent);
+		}
+	else
+		{
+		X509_NAME ntmp;
+		ntmp.entries = dpn->name.relativename;
+		BIO_printf(out, "%*sRelative Name:\n%*s",
+						indent, "", indent + 2, "");
+		X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE);
+		BIO_puts(out, "\n");
+		}
+	return 1;
+	}
+
+static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
+		   int indent)
+	{
+	ISSUING_DIST_POINT *idp = pidp;
+	if (idp->distpoint)
+		print_distpoint(out, idp->distpoint, indent);
+	if (idp->onlyuser > 0)
+		BIO_printf(out, "%*sOnly User Certificates\n", indent, "");
+	if (idp->onlyCA > 0)
+		BIO_printf(out, "%*sOnly CA Certificates\n", indent, "");
+	if (idp->indirectCRL > 0)
+		BIO_printf(out, "%*sIndirect CRL\n", indent, "");
+	if (idp->onlysomereasons)
+		print_reasons(out, "Only Some Reasons", 
+				idp->onlysomereasons, indent);
+	if (idp->onlyattr > 0)
+		BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, "");
+	if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0)
+		&& (idp->indirectCRL <= 0) && !idp->onlysomereasons
+		&& (idp->onlyattr <= 0))
+		BIO_printf(out, "%*s<EMPTY>\n", indent, "");
+		
+	return 1;
+	}
+
+static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
+		     int indent)
+	{
+	STACK_OF(DIST_POINT) *crld = pcrldp;
+	DIST_POINT *point;
+	int i;
+	for(i = 0; i < sk_DIST_POINT_num(crld); i++)
+		{
+		BIO_puts(out, "\n");
+		point = sk_DIST_POINT_value(crld, i);
+		if(point->distpoint)
+			print_distpoint(out, point->distpoint, indent);
+		if(point->reasons) 
+			print_reasons(out, "Reasons", point->reasons,
+								indent);
+		if(point->CRLissuer)
+			{
+			BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
+			print_gens(out, point->CRLissuer, indent);
+			}
+		}
+	return 1;
+	}
+
+int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname)
+	{
+	int i;
+	STACK_OF(X509_NAME_ENTRY) *frag;
+	X509_NAME_ENTRY *ne;
+	if (!dpn || (dpn->type != 1))
+		return 1;
+	frag = dpn->name.relativename;
+	dpn->dpname = X509_NAME_dup(iname);
+	if (!dpn->dpname)
+		return 0;
+	for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++)
+		{
+		ne = sk_X509_NAME_ENTRY_value(frag, i);
+		if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1))
+			{
+			X509_NAME_free(dpn->dpname);
+			dpn->dpname = NULL;
+			return 0;
+			}
+		}
+	/* generate cached encoding of name */
+	if (i2d_X509_NAME(dpn->dpname, NULL) < 0)
+		{
+		X509_NAME_free(dpn->dpname);
+		dpn->dpname = NULL;
+		return 0;
+		}
+	return 1;
+	}
diff --git a/crypto/x509v3/v3_enum.c b/crypto/x509v3/v3_enum.c
index 36576ea..c0575e3 100644
--- a/crypto/x509v3/v3_enum.c
+++ b/crypto/x509v3/v3_enum.c
@@ -61,14 +61,17 @@
 #include <openssl/x509v3.h>
 
 static ENUMERATED_NAMES crl_reasons[] = {
-{0, "Unspecified", "unspecified"},
-{1, "Key Compromise", "keyCompromise"},
-{2, "CA Compromise", "CACompromise"},
-{3, "Affiliation Changed", "affiliationChanged"},
-{4, "Superseded", "superseded"},
-{5, "Cessation Of Operation", "cessationOfOperation"},
-{6, "Certificate Hold", "certificateHold"},
-{8, "Remove From CRL", "removeFromCRL"},
+{CRL_REASON_UNSPECIFIED, 	 "Unspecified", "unspecified"},
+{CRL_REASON_KEY_COMPROMISE,	 "Key Compromise", "keyCompromise"},
+{CRL_REASON_CA_COMPROMISE,	 "CA Compromise", "CACompromise"},
+{CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", "affiliationChanged"},
+{CRL_REASON_SUPERSEDED, 	 "Superseded", "superseded"},
+{CRL_REASON_CESSATION_OF_OPERATION,
+			"Cessation Of Operation", "cessationOfOperation"},
+{CRL_REASON_CERTIFICATE_HOLD,	 "Certificate Hold", "certificateHold"},
+{CRL_REASON_REMOVE_FROM_CRL,	 "Remove From CRL", "removeFromCRL"},
+{CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", "privilegeWithdrawn"},
+{CRL_REASON_AA_COMPROMISE,	 "AA Compromise", "AACompromise"},
 {-1, NULL, NULL}
 };
 
diff --git a/crypto/x509v3/v3_extku.c b/crypto/x509v3/v3_extku.c
index c0d1450..1c66532 100644
--- a/crypto/x509v3/v3_extku.c
+++ b/crypto/x509v3/v3_extku.c
@@ -63,9 +63,10 @@
 #include <openssl/conf.h>
 #include <openssl/x509v3.h>
 
-static void *v2i_EXTENDED_KEY_USAGE(X509V3_EXT_METHOD *method,
-				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
-static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(X509V3_EXT_METHOD *method,
+static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
+				    X509V3_CTX *ctx,
+				    STACK_OF(CONF_VALUE) *nval);
+static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
 		void *eku, STACK_OF(CONF_VALUE) *extlist);
 
 const X509V3_EXT_METHOD v3_ext_ku = {
@@ -97,8 +98,9 @@
 
 IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
 
-static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(X509V3_EXT_METHOD *method,
-		void *a, STACK_OF(CONF_VALUE) *ext_list)
+static STACK_OF(CONF_VALUE) *
+  i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, void *a,
+			 STACK_OF(CONF_VALUE) *ext_list)
 {
 	EXTENDED_KEY_USAGE *eku = a;
 	int i;
@@ -112,8 +114,8 @@
 	return ext_list;
 }
 
-static void *v2i_EXTENDED_KEY_USAGE(X509V3_EXT_METHOD *method,
-				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
+				    X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
 {
 	EXTENDED_KEY_USAGE *extku;
 	char *extval;
diff --git a/crypto/x509v3/v3_genn.c b/crypto/x509v3/v3_genn.c
index 84b4b1c..b628357 100644
--- a/crypto/x509v3/v3_genn.c
+++ b/crypto/x509v3/v3_genn.c
@@ -3,7 +3,7 @@
  * project 1999.
  */
 /* ====================================================================
- * Copyright (c) 1999 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
@@ -99,3 +99,154 @@
 ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES)
 
 IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES)
+
+GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a)
+	{
+	return (GENERAL_NAME *) ASN1_dup((i2d_of_void *) i2d_GENERAL_NAME,
+					 (d2i_of_void *) d2i_GENERAL_NAME,
+					 (char *) a);
+	}
+
+/* Returns 0 if they are equal, != 0 otherwise. */
+int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
+	{
+	int result = -1;
+
+	if (!a || !b || a->type != b->type) return -1;
+	switch(a->type)
+		{
+	case GEN_X400:
+	case GEN_EDIPARTY:
+		result = ASN1_TYPE_cmp(a->d.other, b->d.other);
+		break;
+
+	case GEN_OTHERNAME:
+		result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
+		break;
+
+	case GEN_EMAIL:
+	case GEN_DNS:
+	case GEN_URI:
+		result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
+		break;
+
+	case GEN_DIRNAME:
+		result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
+		break;
+
+	case GEN_IPADD:
+		result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
+		break;
+	
+	case GEN_RID:
+		result = OBJ_cmp(a->d.rid, b->d.rid);
+		break;
+		}
+	return result;
+	}
+
+/* Returns 0 if they are equal, != 0 otherwise. */
+int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b)
+	{
+	int result = -1;
+
+	if (!a || !b) return -1;
+	/* Check their type first. */
+	if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
+		return result;
+	/* Check the value. */
+	result = ASN1_TYPE_cmp(a->value, b->value);
+	return result;
+	}
+
+void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
+	{
+	switch(type)
+		{
+	case GEN_X400:
+	case GEN_EDIPARTY:
+		a->d.other = value;
+		break;
+
+	case GEN_OTHERNAME:
+		a->d.otherName = value;
+		break;
+
+	case GEN_EMAIL:
+	case GEN_DNS:
+	case GEN_URI:
+		a->d.ia5 = value;
+		break;
+
+	case GEN_DIRNAME:
+		a->d.dirn = value;
+		break;
+
+	case GEN_IPADD:
+		a->d.ip = value;
+		break;
+	
+	case GEN_RID:
+		a->d.rid = value;
+		break;
+		}
+	a->type = type;
+	}
+
+void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype)
+	{
+	if (ptype)
+		*ptype = a->type;
+	switch(a->type)
+		{
+	case GEN_X400:
+	case GEN_EDIPARTY:
+		return a->d.other;
+
+	case GEN_OTHERNAME:
+		return a->d.otherName;
+
+	case GEN_EMAIL:
+	case GEN_DNS:
+	case GEN_URI:
+		return a->d.ia5;
+
+	case GEN_DIRNAME:
+		return a->d.dirn;
+
+	case GEN_IPADD:
+		return a->d.ip;
+	
+	case GEN_RID:
+		return a->d.rid;
+
+	default:
+		return NULL;
+		}
+	}
+
+int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
+				ASN1_OBJECT *oid, ASN1_TYPE *value)
+	{
+	OTHERNAME *oth;
+	oth = OTHERNAME_new();
+	if (!oth)
+		return 0;
+	oth->type_id = oid;
+	oth->value = value;
+	GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
+	return 1;
+	}
+
+int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, 
+				ASN1_OBJECT **poid, ASN1_TYPE **pvalue)
+	{
+	if (gen->type != GEN_OTHERNAME)
+		return 0;
+	if (poid)
+		*poid = gen->d.otherName->type_id;
+	if (pvalue)
+		*pvalue = gen->d.otherName->value;
+	return 1;
+	}
+
diff --git a/crypto/x509v3/v3_lib.c b/crypto/x509v3/v3_lib.c
index df3a48f..0f1e1d4 100644
--- a/crypto/x509v3/v3_lib.c
+++ b/crypto/x509v3/v3_lib.c
@@ -84,20 +84,24 @@
 }
 
 static int ext_cmp(const X509V3_EXT_METHOD * const *a,
-		const X509V3_EXT_METHOD * const *b)
+		   const X509V3_EXT_METHOD * const *b)
 {
 	return ((*a)->ext_nid - (*b)->ext_nid);
 }
 
-X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid)
+DECLARE_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *, const X509V3_EXT_METHOD *,
+			   ext);
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *,
+			     const X509V3_EXT_METHOD *, ext);
+
+const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid)
 {
-	X509V3_EXT_METHOD tmp, *t = &tmp, **ret;
+	X509V3_EXT_METHOD tmp;
+	const X509V3_EXT_METHOD *t = &tmp, * const *ret;
 	int idx;
 	if(nid < 0) return NULL;
 	tmp.ext_nid = nid;
-	ret = (X509V3_EXT_METHOD **) OBJ_bsearch((char *)&t,
-			(char *)standard_exts, STANDARD_EXTENSION_COUNT,
-			sizeof(X509V3_EXT_METHOD *), (int (*)(const void *, const void *))ext_cmp);
+	ret = OBJ_bsearch_ext(&t, standard_exts, STANDARD_EXTENSION_COUNT);
 	if(ret) return *ret;
 	if(!ext_list) return NULL;
 	idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp);
@@ -105,7 +109,7 @@
 	return sk_X509V3_EXT_METHOD_value(ext_list, idx);
 }
 
-X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext)
+const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext)
 {
 	int nid;
 	if((nid = OBJ_obj2nid(ext->object)) == NID_undef) return NULL;
@@ -122,7 +126,9 @@
 
 int X509V3_EXT_add_alias(int nid_to, int nid_from)
 {
-	X509V3_EXT_METHOD *ext, *tmpext;
+	const X509V3_EXT_METHOD *ext;
+	X509V3_EXT_METHOD *tmpext;
+
 	if(!(ext = X509V3_EXT_get_nid(nid_from))) {
 		X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS,X509V3_R_EXTENSION_NOT_FOUND);
 		return 0;
@@ -161,7 +167,7 @@
 
 void *X509V3_EXT_d2i(X509_EXTENSION *ext)
 {
-	X509V3_EXT_METHOD *method;
+	const X509V3_EXT_METHOD *method;
 	const unsigned char *p;
 
 	if(!(method = X509V3_EXT_get(ext))) return NULL;
diff --git a/crypto/x509v3/v3_ncons.c b/crypto/x509v3/v3_ncons.c
index 4e706be..689df46 100644
--- a/crypto/x509v3/v3_ncons.c
+++ b/crypto/x509v3/v3_ncons.c
@@ -63,15 +63,22 @@
 #include <openssl/conf.h>
 #include <openssl/x509v3.h>
 
-static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method,
-				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
-static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, 
+static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
+				  X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, 
 				void *a, BIO *bp, int ind);
-static int do_i2r_name_constraints(X509V3_EXT_METHOD *method,
-				STACK_OF(GENERAL_SUBTREE) *trees,
-					BIO *bp, int ind, char *name);
+static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
+				   STACK_OF(GENERAL_SUBTREE) *trees,
+				   BIO *bp, int ind, char *name);
 static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip);
 
+static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc);
+static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen);
+static int nc_dn(X509_NAME *sub, X509_NAME *nm);
+static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns);
+static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml);
+static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base);
+
 const X509V3_EXT_METHOD v3_name_constraints = {
 	NID_name_constraints, 0,
 	ASN1_ITEM_ref(NAME_CONSTRAINTS),
@@ -99,8 +106,8 @@
 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
 
-static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method,
-				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
+				  X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
 	{
 	int i;
 	CONF_VALUE tval, *val;
@@ -155,8 +162,8 @@
 
 	
 
-static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method,
-				void *a, BIO *bp, int ind)
+static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
+				BIO *bp, int ind)
 	{
 	NAME_CONSTRAINTS *ncons = a;
 	do_i2r_name_constraints(method, ncons->permittedSubtrees,
@@ -166,9 +173,9 @@
 	return 1;
 	}
 
-static int do_i2r_name_constraints(X509V3_EXT_METHOD *method,
-				STACK_OF(GENERAL_SUBTREE) *trees,
-					BIO *bp, int ind, char *name)
+static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
+				   STACK_OF(GENERAL_SUBTREE) *trees,
+				   BIO *bp, int ind, char *name)
 	{
 	GENERAL_SUBTREE *tree;
 	int i;
@@ -218,3 +225,282 @@
 	return 1;
 	}
 
+/* Check a certificate conforms to a specified set of constraints.
+ * Return values:
+ *  X509_V_OK: All constraints obeyed.
+ *  X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation.
+ *  X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation.
+ *  X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type.
+ *  X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:  Unsupported constraint type.
+ *  X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax.
+ *  X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name
+
+ */
+
+int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc)
+	{
+	int r, i;
+	X509_NAME *nm;
+
+	nm = X509_get_subject_name(x);
+
+	if (X509_NAME_entry_count(nm) > 0)
+		{
+		GENERAL_NAME gntmp;
+		gntmp.type = GEN_DIRNAME;
+		gntmp.d.directoryName = nm;
+
+		r = nc_match(&gntmp, nc);
+
+		if (r != X509_V_OK)
+			return r;
+
+		gntmp.type = GEN_EMAIL;
+
+
+		/* Process any email address attributes in subject name */
+
+		for (i = -1;;)
+			{
+			X509_NAME_ENTRY *ne;
+			i = X509_NAME_get_index_by_NID(nm,
+						       NID_pkcs9_emailAddress,
+						       i);
+			if (i == -1)
+				break;
+			ne = X509_NAME_get_entry(nm, i);
+			gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne);
+			if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING)
+				return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+
+			r = nc_match(&gntmp, nc);
+
+			if (r != X509_V_OK)
+				return r;
+			}
+		
+		}
+
+	for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++)
+		{
+		GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i);
+		r = nc_match(gen, nc);
+		if (r != X509_V_OK)
+			return r;
+		}
+
+	return X509_V_OK;
+
+	}
+
+static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
+	{
+	GENERAL_SUBTREE *sub;
+	int i, r, match = 0;
+
+	/* Permitted subtrees: if any subtrees exist of matching the type
+	 * at least one subtree must match.
+	 */
+
+	for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++)
+		{
+		sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
+		if (gen->type != sub->base->type)
+			continue;
+		if (sub->minimum || sub->maximum)
+			return X509_V_ERR_SUBTREE_MINMAX;
+		/* If we already have a match don't bother trying any more */
+		if (match == 2)
+			continue;
+		if (match == 0)
+			match = 1;
+		r = nc_match_single(gen, sub->base);
+		if (r == X509_V_OK)
+			match = 2;
+		else if (r != X509_V_ERR_PERMITTED_VIOLATION)
+			return r;
+		}
+
+	if (match == 1)
+		return X509_V_ERR_PERMITTED_VIOLATION;
+
+	/* Excluded subtrees: must not match any of these */
+
+	for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++)
+		{
+		sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
+		if (gen->type != sub->base->type)
+			continue;
+		if (sub->minimum || sub->maximum)
+			return X509_V_ERR_SUBTREE_MINMAX;
+
+		r = nc_match_single(gen, sub->base);
+		if (r == X509_V_OK)
+			return X509_V_ERR_EXCLUDED_VIOLATION;
+		else if (r != X509_V_ERR_PERMITTED_VIOLATION)
+			return r;
+
+		}
+
+	return X509_V_OK;
+
+	}
+
+static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base)
+	{
+	switch(base->type)
+		{
+		case GEN_DIRNAME:
+		return nc_dn(gen->d.directoryName, base->d.directoryName);
+
+		case GEN_DNS:
+		return nc_dns(gen->d.dNSName, base->d.dNSName);
+
+		case GEN_EMAIL:
+		return nc_email(gen->d.rfc822Name, base->d.rfc822Name);
+
+		case GEN_URI:
+		return nc_uri(gen->d.uniformResourceIdentifier,
+					base->d.uniformResourceIdentifier);
+
+		default:
+		return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
+		}
+
+	}
+
+/* directoryName name constraint matching.
+ * The canonical encoding of X509_NAME makes this comparison easy. It is
+ * matched if the subtree is a subset of the name.
+ */
+
+static int nc_dn(X509_NAME *nm, X509_NAME *base)
+	{
+	/* Ensure canonical encodings are up to date.  */
+	if (nm->modified && i2d_X509_NAME(nm, NULL) < 0)
+		return X509_V_ERR_OUT_OF_MEM;
+	if (base->modified && i2d_X509_NAME(base, NULL) < 0)
+		return X509_V_ERR_OUT_OF_MEM;
+	if (base->canon_enclen > nm->canon_enclen)
+		return X509_V_ERR_PERMITTED_VIOLATION;
+	if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen))
+		return X509_V_ERR_PERMITTED_VIOLATION;
+	return X509_V_OK;
+	}
+
+static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base)
+	{
+	char *baseptr = (char *)base->data;
+	char *dnsptr = (char *)dns->data;
+	/* Empty matches everything */
+	if (!*baseptr)
+		return X509_V_OK;
+	/* Otherwise can add zero or more components on the left so
+	 * compare RHS and if dns is longer and expect '.' as preceding
+	 * character.
+	 */
+	if (dns->length > base->length)
+		{
+		dnsptr += dns->length - base->length;
+		if (dnsptr[-1] != '.')
+			return X509_V_ERR_PERMITTED_VIOLATION;
+		}
+
+	if (strcasecmp(baseptr, dnsptr))
+			return X509_V_ERR_PERMITTED_VIOLATION;
+
+	return X509_V_OK;
+
+	}
+
+static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base)
+	{
+	const char *baseptr = (char *)base->data;
+	const char *emlptr = (char *)eml->data;
+
+	const char *baseat = strchr(baseptr, '@');
+	const char *emlat = strchr(emlptr, '@');
+	if (!emlat)
+		return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+	/* Special case: inital '.' is RHS match */
+	if (!baseat && (*baseptr == '.'))
+		{
+		if (eml->length > base->length)
+			{
+			emlptr += eml->length - base->length;
+			if (!strcasecmp(baseptr, emlptr))
+				return X509_V_OK;
+			}
+		return X509_V_ERR_PERMITTED_VIOLATION;
+		}
+
+	/* If we have anything before '@' match local part */
+
+	if (baseat)
+		{
+		if (baseat != baseptr)
+			{
+			if ((baseat - baseptr) != (emlat - emlptr))
+				return X509_V_ERR_PERMITTED_VIOLATION;
+			/* Case sensitive match of local part */
+			if (strncmp(baseptr, emlptr, emlat - emlptr))
+				return X509_V_ERR_PERMITTED_VIOLATION;
+			}
+		/* Position base after '@' */
+		baseptr = baseat + 1;
+		}
+	emlptr = emlat + 1;
+	/* Just have hostname left to match: case insensitive */
+	if (strcasecmp(baseptr, emlptr))
+		return X509_V_ERR_PERMITTED_VIOLATION;
+
+	return X509_V_OK;
+
+	}
+
+static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base)
+	{
+	const char *baseptr = (char *)base->data;
+	const char *hostptr = (char *)uri->data;
+	const char *p = strchr(hostptr, ':');
+	int hostlen;
+	/* Check for foo:// and skip past it */
+	if (!p || (p[1] != '/') || (p[2] != '/'))
+		return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+	hostptr = p + 3;
+
+	/* Determine length of hostname part of URI */
+
+	/* Look for a port indicator as end of hostname first */
+
+	p = strchr(hostptr, ':');
+	/* Otherwise look for trailing slash */
+	if (!p)
+		p = strchr(hostptr, '/');
+
+	if (!p)
+		hostlen = strlen(hostptr);
+	else
+		hostlen = p - hostptr;
+
+	if (hostlen == 0)
+		return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+
+	/* Special case: inital '.' is RHS match */
+	if (*baseptr == '.')
+		{
+		if (hostlen > base->length)
+			{
+			p = hostptr + hostlen - base->length;
+			if (!strncasecmp(p, baseptr, base->length))
+				return X509_V_OK;
+			}
+		return X509_V_ERR_PERMITTED_VIOLATION;
+		}
+
+	if ((base->length != (int)hostlen) || strncasecmp(hostptr, baseptr, hostlen))
+		return X509_V_ERR_PERMITTED_VIOLATION;
+
+	return X509_V_OK;
+
+	}
diff --git a/crypto/x509v3/v3_ocsp.c b/crypto/x509v3/v3_ocsp.c
index 5c19cf4..0c165af 100644
--- a/crypto/x509v3/v3_ocsp.c
+++ b/crypto/x509v3/v3_ocsp.c
@@ -68,19 +68,26 @@
 /* OCSP extensions and a couple of CRL entry extensions
  */
 
-static int i2r_ocsp_crlid(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent);
-static int i2r_ocsp_acutoff(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent);
-static int i2r_object(X509V3_EXT_METHOD *method, void *obj, BIO *out, int indent);
+static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *nonce,
+			  BIO *out, int indent);
+static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce,
+			    BIO *out, int indent);
+static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out,
+		      int indent);
 
 static void *ocsp_nonce_new(void);
 static int i2d_ocsp_nonce(void *a, unsigned char **pp);
 static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length);
 static void ocsp_nonce_free(void *a);
-static int i2r_ocsp_nonce(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent);
+static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
+			  BIO *out, int indent);
 
-static int i2r_ocsp_nocheck(X509V3_EXT_METHOD *method, void *nocheck, BIO *out, int indent);
-static void *s2i_ocsp_nocheck(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str);
-static int i2r_ocsp_serviceloc(X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind);
+static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method,
+			    void *nocheck, BIO *out, int indent);
+static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+			      const char *str);
+static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
+			       BIO *bp, int ind);
 
 const X509V3_EXT_METHOD v3_ocsp_crlid = {
 	NID_id_pkix_OCSP_CrlID, 0, ASN1_ITEM_ref(OCSP_CRLID),
@@ -148,7 +155,8 @@
 	NULL
 };
 
-static int i2r_ocsp_crlid(X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind)
+static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *in, BIO *bp,
+			  int ind)
 {
 	OCSP_CRLID *a = in;
 	if (a->crlUrl)
@@ -174,7 +182,8 @@
 	return 0;
 }
 
-static int i2r_ocsp_acutoff(X509V3_EXT_METHOD *method, void *cutoff, BIO *bp, int ind)
+static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff,
+			    BIO *bp, int ind)
 {
 	if (BIO_printf(bp, "%*s", ind, "") <= 0) return 0;
 	if(!ASN1_GENERALIZEDTIME_print(bp, cutoff)) return 0;
@@ -182,7 +191,8 @@
 }
 
 
-static int i2r_object(X509V3_EXT_METHOD *method, void *oid, BIO *bp, int ind)
+static int i2r_object(const X509V3_EXT_METHOD *method, void *oid, BIO *bp,
+		      int ind)
 {
 	if (BIO_printf(bp, "%*s", ind, "") <= 0) return 0;
 	if(i2a_ASN1_OBJECT(bp, oid) <= 0) return 0;
@@ -232,7 +242,8 @@
 	M_ASN1_OCTET_STRING_free(a);
 }
 
-static int i2r_ocsp_nonce(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent)
+static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
+			  BIO *out, int indent)
 {
 	if(BIO_printf(out, "%*s", indent, "") <= 0) return 0;
 	if(i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0) return 0;
@@ -241,17 +252,20 @@
 
 /* Nocheck is just a single NULL. Don't print anything and always set it */
 
-static int i2r_ocsp_nocheck(X509V3_EXT_METHOD *method, void *nocheck, BIO *out, int indent)
+static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck,
+			    BIO *out, int indent)
 {
 	return 1;
 }
 
-static void *s2i_ocsp_nocheck(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str)
+static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+			      const char *str)
 {
 	return ASN1_NULL_new();
 }
 
-static int i2r_ocsp_serviceloc(X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind)
+static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
+			       BIO *bp, int ind)
         {
 	int i;
 	OCSP_SERVICELOC *a = in;
diff --git a/crypto/x509v3/v3_pci.c b/crypto/x509v3/v3_pci.c
index 601211f..c254b2f 100644
--- a/crypto/x509v3/v3_pci.c
+++ b/crypto/x509v3/v3_pci.c
@@ -82,7 +82,7 @@
 		{
 		if (*language)
 			{
-			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED);
+			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
 			X509V3_conf_err(val);
 			return 0;
 			}
@@ -97,7 +97,7 @@
 		{
 		if (*pathlen)
 			{
-			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED);
+			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
 			X509V3_conf_err(val);
 			return 0;
 			}
diff --git a/crypto/x509v3/v3_pcons.c b/crypto/x509v3/v3_pcons.c
index 86c0ff7..30ca652 100644
--- a/crypto/x509v3/v3_pcons.c
+++ b/crypto/x509v3/v3_pcons.c
@@ -64,10 +64,12 @@
 #include <openssl/conf.h>
 #include <openssl/x509v3.h>
 
-static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method,
-				void *bcons, STACK_OF(CONF_VALUE) *extlist);
-static void *v2i_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method,
-				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
+static STACK_OF(CONF_VALUE) *
+i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *bcons,
+		       STACK_OF(CONF_VALUE) *extlist);
+static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
+				    X509V3_CTX *ctx,
+				    STACK_OF(CONF_VALUE) *values);
 
 const X509V3_EXT_METHOD v3_policy_constraints = {
 NID_policy_constraints, 0,
@@ -88,8 +90,9 @@
 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
 
 
-static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method,
-	     void *a, STACK_OF(CONF_VALUE) *extlist)
+static STACK_OF(CONF_VALUE) *
+i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
+		       STACK_OF(CONF_VALUE) *extlist)
 {
 	POLICY_CONSTRAINTS *pcons = a;
 	X509V3_add_value_int("Require Explicit Policy",
@@ -99,8 +102,9 @@
 	return extlist;
 }
 
-static void *v2i_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method,
-	     X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values)
+static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
+				    X509V3_CTX *ctx,
+				    STACK_OF(CONF_VALUE) *values)
 {
 	POLICY_CONSTRAINTS *pcons=NULL;
 	CONF_VALUE *val;
diff --git a/crypto/x509v3/v3_pmaps.c b/crypto/x509v3/v3_pmaps.c
index da03bbc..865bcd3 100644
--- a/crypto/x509v3/v3_pmaps.c
+++ b/crypto/x509v3/v3_pmaps.c
@@ -63,10 +63,11 @@
 #include <openssl/conf.h>
 #include <openssl/x509v3.h>
 
-static void *v2i_POLICY_MAPPINGS(X509V3_EXT_METHOD *method,
-				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
-static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method,
-				void *pmps, STACK_OF(CONF_VALUE) *extlist);
+static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
+				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+static STACK_OF(CONF_VALUE) *
+i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *pmps,
+		    STACK_OF(CONF_VALUE) *extlist);
 
 const X509V3_EXT_METHOD v3_policy_mappings = {
 	NID_policy_mappings, 0,
@@ -92,8 +93,9 @@
 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
 
 
-static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method,
-		void *a, STACK_OF(CONF_VALUE) *ext_list)
+static STACK_OF(CONF_VALUE) *
+i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *a,
+		    STACK_OF(CONF_VALUE) *ext_list)
 {
 	POLICY_MAPPINGS *pmaps = a;
 	POLICY_MAPPING *pmap;
@@ -109,8 +111,8 @@
 	return ext_list;
 }
 
-static void *v2i_POLICY_MAPPINGS(X509V3_EXT_METHOD *method,
-				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
+				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
 {
 	POLICY_MAPPINGS *pmaps;
 	POLICY_MAPPING *pmap;
diff --git a/crypto/x509v3/v3_prn.c b/crypto/x509v3/v3_prn.c
index c1bb17f..3146218 100644
--- a/crypto/x509v3/v3_prn.c
+++ b/crypto/x509v3/v3_prn.c
@@ -110,7 +110,7 @@
 	void *ext_str = NULL;
 	char *value = NULL;
 	const unsigned char *p;
-	X509V3_EXT_METHOD *method;	
+	const X509V3_EXT_METHOD *method;	
 	STACK_OF(CONF_VALUE) *nval = NULL;
 	int ok = 1;
 
diff --git a/crypto/x509v3/v3_purp.c b/crypto/x509v3/v3_purp.c
index e18751e..181bd34 100644
--- a/crypto/x509v3/v3_purp.c
+++ b/crypto/x509v3/v3_purp.c
@@ -71,6 +71,7 @@
 static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
 static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca);
 static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
+static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, int ca);
 static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca);
 static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca);
 
@@ -87,6 +88,7 @@
 	{X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, "CRL signing", "crlsign", NULL},
 	{X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any", NULL},
 	{X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, "OCSP helper", "ocsphelper", NULL},
+	{X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, check_purpose_timestamp_sign, "Time Stamp signing", "timestampsign", NULL},
 };
 
 #define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE))
@@ -265,11 +267,14 @@
 	return xp->trust;
 }
 
-static int nid_cmp(int *a, int *b)
+static int nid_cmp(const int *a, const int *b)
 	{
 	return *a - *b;
 	}
 
+DECLARE_OBJ_BSEARCH_CMP_FN(int, int, nid);
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(int, int, nid);
+
 int X509_supported_extension(X509_EXTENSION *ex)
 	{
 	/* This table is a list of the NIDs of supported extensions:
@@ -280,7 +285,7 @@
 	 * searched using bsearch.
 	 */
 
-	static int supported_nids[] = {
+	static const int supported_nids[] = {
 		NID_netscape_cert_type, /* 71 */
         	NID_key_usage,		/* 83 */
 		NID_subject_alt_name,	/* 85 */
@@ -292,24 +297,62 @@
 		NID_sbgp_autonomousSysNum, /* 291 */
 #endif
 		NID_policy_constraints,	/* 401 */
-		NID_proxyCertInfo,	/* 661 */
+		NID_proxyCertInfo,	/* 663 */
+		NID_name_constraints,	/* 666 */
+		NID_policy_mappings,	/* 747 */
 		NID_inhibit_any_policy	/* 748 */
 	};
 
-	int ex_nid;
-
-	ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));
+	int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));
 
 	if (ex_nid == NID_undef) 
 		return 0;
 
-	if (OBJ_bsearch((char *)&ex_nid, (char *)supported_nids,
-		sizeof(supported_nids)/sizeof(int), sizeof(int),
-		(int (*)(const void *, const void *))nid_cmp))
+	if (OBJ_bsearch_nid(&ex_nid, supported_nids,
+			sizeof(supported_nids)/sizeof(int)))
 		return 1;
 	return 0;
 	}
- 
+
+static void setup_dp(X509 *x, DIST_POINT *dp)
+	{
+	X509_NAME *iname = NULL;
+	int i;
+	if (dp->reasons)
+		{
+		if (dp->reasons->length > 0)
+			dp->dp_reasons = dp->reasons->data[0];
+		if (dp->reasons->length > 1)
+			dp->dp_reasons |= (dp->reasons->data[1] << 8);
+		dp->dp_reasons &= CRLDP_ALL_REASONS;
+		}
+	else
+		dp->dp_reasons = CRLDP_ALL_REASONS;
+	if (!dp->distpoint || (dp->distpoint->type != 1))
+		return;
+	for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++)
+		{
+		GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
+		if (gen->type == GEN_DIRNAME)
+			{
+			iname = gen->d.directoryName;
+			break;
+			}
+		}
+	if (!iname)
+		iname = X509_get_issuer_name(x);
+
+	DIST_POINT_set_dpname(dp->distpoint, iname);
+
+	}
+
+static void setup_crldp(X509 *x)
+	{
+	int i;
+	x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
+	for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
+		setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
+	}
 
 static void x509v3_cache_extensions(X509 *x)
 {
@@ -417,16 +460,25 @@
 	}
 	x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
 	x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
+	x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
+	x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL);
+	if (!x->nc && (i != -1))
+		x->ex_flags |= EXFLAG_INVALID;
+	setup_crldp(x);
+
 #ifndef OPENSSL_NO_RFC3779
-	x->rfc3779_addr =X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL);
-	x->rfc3779_asid =X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum,
-					  NULL, NULL);
+ 	x->rfc3779_addr =X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL);
+ 	x->rfc3779_asid =X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum,
+ 					  NULL, NULL);
 #endif
 	for (i = 0; i < X509_get_ext_count(x); i++)
 		{
 		ex = X509_get_ext(x, i);
 		if (!X509_EXTENSION_get_critical(ex))
 			continue;
+		if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
+					== NID_freshest_crl)
+			x->ex_flags |= EXFLAG_FRESHEST;
 		if (!X509_supported_extension(ex))
 			{
 			x->ex_flags |= EXFLAG_CRITICAL;
@@ -594,6 +646,41 @@
 	return 1;
 }
 
+static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
+					int ca)
+{
+	int i_ext;
+
+	/* If ca is true we must return if this is a valid CA certificate. */
+	if (ca) return check_ca(x);
+
+	/* 
+	 * Check the optional key usage field:
+	 * if Key Usage is present, it must be one of digitalSignature 
+	 * and/or nonRepudiation (other values are not consistent and shall
+	 * be rejected).
+	 */
+	if ((x->ex_flags & EXFLAG_KUSAGE)
+	    && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) ||
+		!(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE))))
+		return 0;
+
+	/* Only time stamp key usage is permitted and it's required. */
+	if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP)
+		return 0;
+
+	/* Extended Key Usage MUST be critical */
+	i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, 0);
+	if (i_ext >= 0)
+		{
+		X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext);
+		if (!X509_EXTENSION_get_critical(ext))
+			return 0;
+		}
+
+	return 1;
+}
+
 static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca)
 {
 	return 1;
@@ -618,39 +705,14 @@
 				return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
 	x509v3_cache_extensions(issuer);
 	x509v3_cache_extensions(subject);
-	if(subject->akid) {
-		/* Check key ids (if present) */
-		if(subject->akid->keyid && issuer->skid &&
-		 ASN1_OCTET_STRING_cmp(subject->akid->keyid, issuer->skid) )
-				return X509_V_ERR_AKID_SKID_MISMATCH;
-		/* Check serial number */
-		if(subject->akid->serial &&
-			ASN1_INTEGER_cmp(X509_get_serialNumber(issuer),
-						subject->akid->serial))
-				return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
-		/* Check issuer name */
-		if(subject->akid->issuer) {
-			/* Ugh, for some peculiar reason AKID includes
-			 * SEQUENCE OF GeneralName. So look for a DirName.
-			 * There may be more than one but we only take any
-			 * notice of the first.
-			 */
-			GENERAL_NAMES *gens;
-			GENERAL_NAME *gen;
-			X509_NAME *nm = NULL;
-			int i;
-			gens = subject->akid->issuer;
-			for(i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
-				gen = sk_GENERAL_NAME_value(gens, i);
-				if(gen->type == GEN_DIRNAME) {
-					nm = gen->d.dirn;
-					break;
-				}
-			}
-			if(nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))
-				return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
+
+	if(subject->akid)
+		{
+		int ret = X509_check_akid(issuer, subject->akid);
+		if (ret != X509_V_OK)
+			return ret;
 		}
-	}
+
 	if(subject->ex_flags & EXFLAG_PROXY)
 		{
 		if(ku_reject(issuer, KU_DIGITAL_SIGNATURE))
@@ -661,3 +723,45 @@
 	return X509_V_OK;
 }
 
+int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid)
+	{
+
+	if(!akid)
+		return X509_V_OK;
+
+	/* Check key ids (if present) */
+	if(akid->keyid && issuer->skid &&
+		 ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid) )
+				return X509_V_ERR_AKID_SKID_MISMATCH;
+	/* Check serial number */
+	if(akid->serial &&
+		ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial))
+				return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
+	/* Check issuer name */
+	if(akid->issuer)
+		{
+		/* Ugh, for some peculiar reason AKID includes
+		 * SEQUENCE OF GeneralName. So look for a DirName.
+		 * There may be more than one but we only take any
+		 * notice of the first.
+		 */
+		GENERAL_NAMES *gens;
+		GENERAL_NAME *gen;
+		X509_NAME *nm = NULL;
+		int i;
+		gens = akid->issuer;
+		for(i = 0; i < sk_GENERAL_NAME_num(gens); i++)
+			{
+			gen = sk_GENERAL_NAME_value(gens, i);
+			if(gen->type == GEN_DIRNAME)
+				{
+				nm = gen->d.dirn;
+				break;
+				}
+			}
+		if(nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))
+			return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
+		}
+	return X509_V_OK;
+	}
+
diff --git a/crypto/x509v3/v3_utl.c b/crypto/x509v3/v3_utl.c
index 7a45216..e030234 100644
--- a/crypto/x509v3/v3_utl.c
+++ b/crypto/x509v3/v3_utl.c
@@ -67,9 +67,9 @@
 
 static char *strip_spaces(char *name);
 static int sk_strcmp(const char * const *a, const char * const *b);
-static STACK *get_email(X509_NAME *name, GENERAL_NAMES *gens);
-static void str_free(void *str);
-static int append_ia5(STACK **sk, ASN1_IA5STRING *email);
+static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, GENERAL_NAMES *gens);
+static void str_free(OPENSSL_STRING str);
+static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email);
 
 static int ipv4_from_asc(unsigned char *v4, const char *in);
 static int ipv6_from_asc(unsigned char *v6, const char *in);
@@ -360,10 +360,10 @@
  * @@@ (Contents of buffer are always kept in ASCII, also on EBCDIC machines)
  */
 
-char *hex_to_string(unsigned char *buffer, long len)
+char *hex_to_string(const unsigned char *buffer, long len)
 {
 	char *tmp, *q;
-	unsigned char *p;
+	const unsigned char *p;
 	int i;
 	const static char hexdig[] = "0123456789ABCDEF";
 	if(!buffer || !len) return NULL;
@@ -389,7 +389,7 @@
  * a buffer
  */
 
-unsigned char *string_to_hex(char *str, long *len)
+unsigned char *string_to_hex(const char *str, long *len)
 {
 	unsigned char *hexbuf, *q;
 	unsigned char ch, cl, *p;
@@ -463,21 +463,23 @@
 	return strcmp(*a, *b);
 }
 
-STACK *X509_get1_email(X509 *x)
+STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x)
 {
 	GENERAL_NAMES *gens;
-	STACK *ret;
+	STACK_OF(OPENSSL_STRING) *ret;
+
 	gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
 	ret = get_email(X509_get_subject_name(x), gens);
 	sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
 	return ret;
 }
 
-STACK *X509_get1_ocsp(X509 *x)
+STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x)
 {
 	AUTHORITY_INFO_ACCESS *info;
-	STACK *ret = NULL;
+	STACK_OF(OPENSSL_STRING) *ret = NULL;
 	int i;
+
 	info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL);
 	if (!info)
 		return NULL;
@@ -497,11 +499,12 @@
 	return ret;
 }
 
-STACK *X509_REQ_get1_email(X509_REQ *x)
+STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x)
 {
 	GENERAL_NAMES *gens;
 	STACK_OF(X509_EXTENSION) *exts;
-	STACK *ret;
+	STACK_OF(OPENSSL_STRING) *ret;
+
 	exts = X509_REQ_get_extensions(x);
 	gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
 	ret = get_email(X509_REQ_get_subject_name(x), gens);
@@ -511,9 +514,9 @@
 }
 
 
-static STACK *get_email(X509_NAME *name, GENERAL_NAMES *gens)
+static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, GENERAL_NAMES *gens)
 {
-	STACK *ret = NULL;
+	STACK_OF(OPENSSL_STRING) *ret = NULL;
 	X509_NAME_ENTRY *ne;
 	ASN1_IA5STRING *email;
 	GENERAL_NAME *gen;
@@ -536,23 +539,23 @@
 	return ret;
 }
 
-static void str_free(void *str)
+static void str_free(OPENSSL_STRING str)
 {
 	OPENSSL_free(str);
 }
 
-static int append_ia5(STACK **sk, ASN1_IA5STRING *email)
+static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email)
 {
 	char *emtmp;
 	/* First some sanity checks */
 	if(email->type != V_ASN1_IA5STRING) return 1;
 	if(!email->data || !email->length) return 1;
-	if(!*sk) *sk = sk_new(sk_strcmp);
+	if(!*sk) *sk = sk_OPENSSL_STRING_new(sk_strcmp);
 	if(!*sk) return 0;
 	/* Don't add duplicates */
-	if(sk_find(*sk, (char *)email->data) != -1) return 1;
+	if(sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1) return 1;
 	emtmp = BUF_strdup((char *)email->data);
-	if(!emtmp || !sk_push(*sk, emtmp)) {
+	if(!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) {
 		X509_email_free(*sk);
 		*sk = NULL;
 		return 0;
@@ -560,9 +563,9 @@
 	return 1;
 }
 
-void X509_email_free(STACK *sk)
+void X509_email_free(STACK_OF(OPENSSL_STRING) *sk)
 {
-	sk_pop_free(sk, str_free);
+	sk_OPENSSL_STRING_pop_free(sk, str_free);
 }
 
 /* Convert IP addresses both IPv4 and IPv6 into an 
diff --git a/crypto/x509v3/v3err.c b/crypto/x509v3/v3err.c
index d538ad8..f9f6f1f 100644
--- a/crypto/x509v3/v3err.c
+++ b/crypto/x509v3/v3err.c
@@ -1,6 +1,6 @@
 /* crypto/x509v3/v3err.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,7 @@
 
 static ERR_STRING_DATA X509V3_str_functs[]=
 	{
+{ERR_FUNC(X509V3_F_A2I_GENERAL_NAME),	"A2I_GENERAL_NAME"},
 {ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE),	"ASIDENTIFIERCHOICE_CANONIZE"},
 {ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL),	"ASIDENTIFIERCHOICE_IS_CANONICAL"},
 {ERR_FUNC(X509V3_F_COPY_EMAIL),	"COPY_EMAIL"},
@@ -79,6 +80,7 @@
 {ERR_FUNC(X509V3_F_DO_EXT_I2D),	"DO_EXT_I2D"},
 {ERR_FUNC(X509V3_F_DO_EXT_NCONF),	"DO_EXT_NCONF"},
 {ERR_FUNC(X509V3_F_DO_I2V_NAME_CONSTRAINTS),	"DO_I2V_NAME_CONSTRAINTS"},
+{ERR_FUNC(X509V3_F_GNAMES_FROM_SECTNAME),	"GNAMES_FROM_SECTNAME"},
 {ERR_FUNC(X509V3_F_HEX_TO_STRING),	"hex_to_string"},
 {ERR_FUNC(X509V3_F_I2S_ASN1_ENUMERATED),	"i2s_ASN1_ENUMERATED"},
 {ERR_FUNC(X509V3_F_I2S_ASN1_IA5STRING),	"I2S_ASN1_IA5STRING"},
@@ -95,6 +97,7 @@
 {ERR_FUNC(X509V3_F_S2I_ASN1_OCTET_STRING),	"s2i_ASN1_OCTET_STRING"},
 {ERR_FUNC(X509V3_F_S2I_ASN1_SKEY_ID),	"S2I_ASN1_SKEY_ID"},
 {ERR_FUNC(X509V3_F_S2I_SKEY_ID),	"S2I_SKEY_ID"},
+{ERR_FUNC(X509V3_F_SET_DIST_POINT_NAME),	"SET_DIST_POINT_NAME"},
 {ERR_FUNC(X509V3_F_STRING_TO_HEX),	"string_to_hex"},
 {ERR_FUNC(X509V3_F_SXNET_ADD_ID_ASC),	"SXNET_add_id_asc"},
 {ERR_FUNC(X509V3_F_SXNET_ADD_ID_INTEGER),	"SXNET_add_id_INTEGER"},
@@ -110,6 +113,7 @@
 {ERR_FUNC(X509V3_F_V2I_EXTENDED_KEY_USAGE),	"V2I_EXTENDED_KEY_USAGE"},
 {ERR_FUNC(X509V3_F_V2I_GENERAL_NAMES),	"v2i_GENERAL_NAMES"},
 {ERR_FUNC(X509V3_F_V2I_GENERAL_NAME_EX),	"v2i_GENERAL_NAME_ex"},
+{ERR_FUNC(X509V3_F_V2I_IDP),	"V2I_IDP"},
 {ERR_FUNC(X509V3_F_V2I_IPADDRBLOCKS),	"V2I_IPADDRBLOCKS"},
 {ERR_FUNC(X509V3_F_V2I_ISSUER_ALT),	"V2I_ISSUER_ALT"},
 {ERR_FUNC(X509V3_F_V2I_NAME_CONSTRAINTS),	"V2I_NAME_CONSTRAINTS"},
@@ -141,6 +145,7 @@
 {ERR_REASON(X509V3_R_BN_DEC2BN_ERROR)    ,"bn dec2bn error"},
 {ERR_REASON(X509V3_R_BN_TO_ASN1_INTEGER_ERROR),"bn to asn1 integer error"},
 {ERR_REASON(X509V3_R_DIRNAME_ERROR)      ,"dirname error"},
+{ERR_REASON(X509V3_R_DISTPOINT_ALREADY_SET),"distpoint already set"},
 {ERR_REASON(X509V3_R_DUPLICATE_ZONE_ID)  ,"duplicate zone id"},
 {ERR_REASON(X509V3_R_ERROR_CONVERTING_ZONE),"error converting zone"},
 {ERR_REASON(X509V3_R_ERROR_CREATING_EXTENSION),"error creating extension"},
@@ -154,6 +159,7 @@
 {ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION),"illegal empty extension"},
 {ERR_REASON(X509V3_R_ILLEGAL_HEX_DIGIT)  ,"illegal hex digit"},
 {ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG),"incorrect policy syntax tag"},
+{ERR_REASON(X509V3_R_INVALID_MULTIPLE_RDNS),"invalid multiple rdns"},
 {ERR_REASON(X509V3_R_INVALID_ASNUMBER)   ,"invalid asnumber"},
 {ERR_REASON(X509V3_R_INVALID_ASRANGE)    ,"invalid asrange"},
 {ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING),"invalid boolean string"},
@@ -187,9 +193,9 @@
 {ERR_REASON(X509V3_R_ODD_NUMBER_OF_DIGITS),"odd number of digits"},
 {ERR_REASON(X509V3_R_OPERATION_NOT_DEFINED),"operation not defined"},
 {ERR_REASON(X509V3_R_OTHERNAME_ERROR)    ,"othername error"},
-{ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED),"policy language alreadty defined"},
+{ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED),"policy language already defined"},
 {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH) ,"policy path length"},
-{ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED),"policy path length alreadty defined"},
+{ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED),"policy path length already defined"},
 {ERR_REASON(X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED),"policy syntax not currently supported"},
 {ERR_REASON(X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY),"policy when proxy language requires no policy"},
 {ERR_REASON(X509V3_R_SECTION_NOT_FOUND)  ,"section not found"},
@@ -200,6 +206,7 @@
 {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION_NAME),"unknown extension name"},
 {ERR_REASON(X509V3_R_UNKNOWN_OPTION)     ,"unknown option"},
 {ERR_REASON(X509V3_R_UNSUPPORTED_OPTION) ,"unsupported option"},
+{ERR_REASON(X509V3_R_UNSUPPORTED_TYPE)   ,"unsupported type"},
 {ERR_REASON(X509V3_R_USER_TOO_LONG)      ,"user too long"},
 {0,NULL}
 	};
diff --git a/crypto/x509v3/x509v3.h b/crypto/x509v3/x509v3.h
index 9ef83da..b308abe 100644
--- a/crypto/x509v3/x509v3.h
+++ b/crypto/x509v3/x509v3.h
@@ -76,12 +76,19 @@
 typedef void (*X509V3_EXT_FREE)(void *);
 typedef void * (*X509V3_EXT_D2I)(void *, const unsigned char ** , long);
 typedef int (*X509V3_EXT_I2D)(void *, unsigned char **);
-typedef STACK_OF(CONF_VALUE) * (*X509V3_EXT_I2V)(struct v3_ext_method *method, void *ext, STACK_OF(CONF_VALUE) *extlist);
-typedef void * (*X509V3_EXT_V2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, STACK_OF(CONF_VALUE) *values);
-typedef char * (*X509V3_EXT_I2S)(struct v3_ext_method *method, void *ext);
-typedef void * (*X509V3_EXT_S2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, const char *str);
-typedef int (*X509V3_EXT_I2R)(struct v3_ext_method *method, void *ext, BIO *out, int indent);
-typedef void * (*X509V3_EXT_R2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, const char *str);
+typedef STACK_OF(CONF_VALUE) *
+  (*X509V3_EXT_I2V)(const struct v3_ext_method *method, void *ext,
+		    STACK_OF(CONF_VALUE) *extlist);
+typedef void * (*X509V3_EXT_V2I)(const struct v3_ext_method *method,
+				 struct v3_ext_ctx *ctx,
+				 STACK_OF(CONF_VALUE) *values);
+typedef char * (*X509V3_EXT_I2S)(const struct v3_ext_method *method, void *ext);
+typedef void * (*X509V3_EXT_S2I)(const struct v3_ext_method *method,
+				 struct v3_ext_ctx *ctx, const char *str);
+typedef int (*X509V3_EXT_I2R)(const struct v3_ext_method *method, void *ext,
+			      BIO *out, int indent);
+typedef void * (*X509V3_EXT_R2I)(const struct v3_ext_method *method,
+				 struct v3_ext_ctx *ctx, const char *str);
 
 /* V3 extension structure */
 
@@ -220,24 +227,41 @@
 	GENERAL_NAMES *fullname;
 	STACK_OF(X509_NAME_ENTRY) *relativename;
 } name;
+/* If relativename then this contains the full distribution point name */
+X509_NAME *dpname;
 } DIST_POINT_NAME;
+/* All existing reasons */
+#define CRLDP_ALL_REASONS	0x807f
 
-typedef struct DIST_POINT_st {
+#define CRL_REASON_NONE				-1
+#define CRL_REASON_UNSPECIFIED			0
+#define CRL_REASON_KEY_COMPROMISE		1
+#define CRL_REASON_CA_COMPROMISE		2
+#define CRL_REASON_AFFILIATION_CHANGED		3
+#define CRL_REASON_SUPERSEDED			4
+#define CRL_REASON_CESSATION_OF_OPERATION	5
+#define CRL_REASON_CERTIFICATE_HOLD		6
+#define CRL_REASON_REMOVE_FROM_CRL		8
+#define CRL_REASON_PRIVILEGE_WITHDRAWN		9
+#define CRL_REASON_AA_COMPROMISE		10
+
+struct DIST_POINT_st {
 DIST_POINT_NAME	*distpoint;
 ASN1_BIT_STRING *reasons;
 GENERAL_NAMES *CRLissuer;
-} DIST_POINT;
+int dp_reasons;
+};
 
 typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS;
 
 DECLARE_STACK_OF(DIST_POINT)
 DECLARE_ASN1_SET_OF(DIST_POINT)
 
-typedef struct AUTHORITY_KEYID_st {
+struct AUTHORITY_KEYID_st {
 ASN1_OCTET_STRING *keyid;
 GENERAL_NAMES *issuer;
 ASN1_INTEGER *serial;
-} AUTHORITY_KEYID;
+};
 
 /* Strong extranet structures */
 
@@ -303,10 +327,10 @@
 
 DECLARE_STACK_OF(GENERAL_SUBTREE)
 
-typedef struct NAME_CONSTRAINTS_st {
+struct NAME_CONSTRAINTS_st {
 	STACK_OF(GENERAL_SUBTREE) *permittedSubtrees;
 	STACK_OF(GENERAL_SUBTREE) *excludedSubtrees;
-} NAME_CONSTRAINTS;
+};
 
 typedef struct POLICY_CONSTRAINTS_st {
 	ASN1_INTEGER *requireExplicitPolicy;
@@ -329,6 +353,31 @@
 DECLARE_ASN1_FUNCTIONS(PROXY_POLICY)
 DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
 
+struct ISSUING_DIST_POINT_st
+	{
+	DIST_POINT_NAME *distpoint;
+	int onlyuser;
+	int onlyCA;
+	ASN1_BIT_STRING *onlysomereasons;
+	int indirectCRL;
+	int onlyattr;
+	};
+
+/* Values in idp_flags field */
+/* IDP present */
+#define	IDP_PRESENT	0x1
+/* IDP values inconsistent */
+#define IDP_INVALID	0x2
+/* onlyuser true */
+#define	IDP_ONLYUSER	0x4
+/* onlyCA true */
+#define	IDP_ONLYCA	0x8
+/* onlyattr true */
+#define IDP_ONLYATTR	0x10
+/* indirectCRL true */
+#define IDP_INDIRECT	0x20
+/* onlysomereasons present */
+#define IDP_REASONS	0x40
 
 #define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \
 ",name:", val->name, ",value:", val->value);
@@ -373,6 +422,7 @@
 #define EXFLAG_PROXY		0x400
 
 #define EXFLAG_INVALID_POLICY	0x800
+#define EXFLAG_FRESHEST		0x1000
 
 #define KU_DIGITAL_SIGNATURE	0x0080
 #define KU_NON_REPUDIATION	0x0040
@@ -424,9 +474,10 @@
 #define X509_PURPOSE_CRL_SIGN		6
 #define X509_PURPOSE_ANY		7
 #define X509_PURPOSE_OCSP_HELPER	8
+#define X509_PURPOSE_TIMESTAMP_SIGN	9
 
 #define X509_PURPOSE_MIN		1
-#define X509_PURPOSE_MAX		8
+#define X509_PURPOSE_MAX		9
 
 /* Flags for X509V3_EXT_print() */
 
@@ -471,6 +522,9 @@
 DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
 
 DECLARE_ASN1_FUNCTIONS(GENERAL_NAME)
+GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a);
+int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b);
+
 
 
 ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
@@ -486,11 +540,18 @@
 
 STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
 		GENERAL_NAMES *gen, STACK_OF(CONF_VALUE) *extlist);
-GENERAL_NAMES *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method,
-				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
+				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
 
 DECLARE_ASN1_FUNCTIONS(OTHERNAME)
 DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME)
+int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b);
+void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value);
+void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype);
+int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
+				ASN1_OBJECT *oid, ASN1_TYPE *value);
+int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, 
+				ASN1_OBJECT **poid, ASN1_TYPE **pvalue);
 
 char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *ia5);
 ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
@@ -507,6 +568,11 @@
 DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS)
 DECLARE_ASN1_FUNCTIONS(DIST_POINT)
 DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME)
+DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
+
+int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname);
+
+int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc);
 
 DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
 DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
@@ -524,11 +590,16 @@
 DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
 DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS)
 
+GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
+			       const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+			       int gen_type, char *value, int is_nc);
+
 #ifdef HEADER_CONF_H
-GENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
-							CONF_VALUE *cnf);
-GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, X509V3_EXT_METHOD *method,
-				X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc);
+GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+			       CONF_VALUE *cnf);
+GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
+				  const X509V3_EXT_METHOD *method,
+				  X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc);
 void X509V3_conf_free(CONF_VALUE *val);
 
 X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, char *value);
@@ -538,18 +609,23 @@
 int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_REQ *req);
 int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl);
 
-X509_EXTENSION *X509V3_EXT_conf_nid(LHASH *conf, X509V3_CTX *ctx, int ext_nid, char *value);
-X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name, char *value);
-int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509 *cert);
-int X509V3_EXT_REQ_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509_REQ *req);
-int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl);
+X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+				    int ext_nid, char *value);
+X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+				char *name, char *value);
+int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+			char *section, X509 *cert);
+int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+			    char *section, X509_REQ *req);
+int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+			    char *section, X509_CRL *crl);
 
 int X509V3_add_value_bool_nf(char *name, int asn1_bool,
-						STACK_OF(CONF_VALUE) **extlist);
+			     STACK_OF(CONF_VALUE) **extlist);
 int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool);
 int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint);
 void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf);
-void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH *lhash);
+void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash);
 #endif
 
 char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section);
@@ -576,8 +652,8 @@
 int X509V3_EXT_add_alias(int nid_to, int nid_from);
 void X509V3_EXT_cleanup(void);
 
-X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext);
-X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid);
+const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext);
+const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid);
 int X509V3_add_standard_extensions(void);
 STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line);
 void *X509V3_EXT_d2i(X509_EXTENSION *ext);
@@ -587,8 +663,8 @@
 X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
 int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags);
 
-char *hex_to_string(unsigned char *buffer, long len);
-unsigned char *string_to_hex(char *str, long *len);
+char *hex_to_string(const unsigned char *buffer, long len);
+unsigned char *string_to_hex(const char *str, long *len);
 int name_cmp(const char *name, const char *cmp);
 
 void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
@@ -603,6 +679,7 @@
 int X509_supported_extension(X509_EXTENSION *ex);
 int X509_PURPOSE_set(int *p, int purpose);
 int X509_check_issued(X509 *issuer, X509 *subject);
+int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid);
 int X509_PURPOSE_get_count(void);
 X509_PURPOSE * X509_PURPOSE_get0(int idx);
 int X509_PURPOSE_get_by_sname(char *sname);
@@ -616,10 +693,10 @@
 void X509_PURPOSE_cleanup(void);
 int X509_PURPOSE_get_id(X509_PURPOSE *);
 
-STACK *X509_get1_email(X509 *x);
-STACK *X509_REQ_get1_email(X509_REQ *x);
-void X509_email_free(STACK *sk);
-STACK *X509_get1_ocsp(X509 *x);
+STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x);
+STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x);
+void X509_email_free(STACK_OF(OPENSSL_STRING) *sk);
+STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x);
 
 ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc);
 ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc);
@@ -628,6 +705,7 @@
 						unsigned long chtype);
 
 void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent);
+DECLARE_STACK_OF(X509_POLICY_NODE)
 
 #ifndef OPENSSL_NO_RFC3779
 
@@ -787,8 +865,9 @@
 /* Error codes for the X509V3 functions. */
 
 /* Function codes. */
-#define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE		 156
-#define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL	 157
+#define X509V3_F_A2I_GENERAL_NAME			 164
+#define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE		 161
+#define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL	 162
 #define X509V3_F_COPY_EMAIL				 122
 #define X509V3_F_COPY_ISSUER				 123
 #define X509V3_F_DO_DIRNAME				 144
@@ -796,6 +875,7 @@
 #define X509V3_F_DO_EXT_I2D				 135
 #define X509V3_F_DO_EXT_NCONF				 151
 #define X509V3_F_DO_I2V_NAME_CONSTRAINTS		 148
+#define X509V3_F_GNAMES_FROM_SECTNAME			 156
 #define X509V3_F_HEX_TO_STRING				 111
 #define X509V3_F_I2S_ASN1_ENUMERATED			 121
 #define X509V3_F_I2S_ASN1_IA5STRING			 149
@@ -812,13 +892,14 @@
 #define X509V3_F_S2I_ASN1_OCTET_STRING			 112
 #define X509V3_F_S2I_ASN1_SKEY_ID			 114
 #define X509V3_F_S2I_SKEY_ID				 115
+#define X509V3_F_SET_DIST_POINT_NAME			 158
 #define X509V3_F_STRING_TO_HEX				 113
 #define X509V3_F_SXNET_ADD_ID_ASC			 125
 #define X509V3_F_SXNET_ADD_ID_INTEGER			 126
 #define X509V3_F_SXNET_ADD_ID_ULONG			 127
 #define X509V3_F_SXNET_GET_ID_ASC			 128
 #define X509V3_F_SXNET_GET_ID_ULONG			 129
-#define X509V3_F_V2I_ASIDENTIFIERS			 158
+#define X509V3_F_V2I_ASIDENTIFIERS			 163
 #define X509V3_F_V2I_ASN1_BIT_STRING			 101
 #define X509V3_F_V2I_AUTHORITY_INFO_ACCESS		 139
 #define X509V3_F_V2I_AUTHORITY_KEYID			 119
@@ -827,6 +908,7 @@
 #define X509V3_F_V2I_EXTENDED_KEY_USAGE			 103
 #define X509V3_F_V2I_GENERAL_NAMES			 118
 #define X509V3_F_V2I_GENERAL_NAME_EX			 117
+#define X509V3_F_V2I_IDP				 157
 #define X509V3_F_V2I_IPADDRBLOCKS			 159
 #define X509V3_F_V2I_ISSUER_ALT				 153
 #define X509V3_F_V2I_NAME_CONSTRAINTS			 147
@@ -855,6 +937,7 @@
 #define X509V3_R_BN_DEC2BN_ERROR			 100
 #define X509V3_R_BN_TO_ASN1_INTEGER_ERROR		 101
 #define X509V3_R_DIRNAME_ERROR				 149
+#define X509V3_R_DISTPOINT_ALREADY_SET			 160
 #define X509V3_R_DUPLICATE_ZONE_ID			 133
 #define X509V3_R_ERROR_CONVERTING_ZONE			 131
 #define X509V3_R_ERROR_CREATING_EXTENSION		 144
@@ -868,12 +951,13 @@
 #define X509V3_R_ILLEGAL_EMPTY_EXTENSION		 151
 #define X509V3_R_ILLEGAL_HEX_DIGIT			 113
 #define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG		 152
-#define X509V3_R_INVALID_ASNUMBER			 160
-#define X509V3_R_INVALID_ASRANGE			 161
+#define X509V3_R_INVALID_MULTIPLE_RDNS			 161
+#define X509V3_R_INVALID_ASNUMBER			 162
+#define X509V3_R_INVALID_ASRANGE			 163
 #define X509V3_R_INVALID_BOOLEAN_STRING			 104
 #define X509V3_R_INVALID_EXTENSION_STRING		 105
-#define X509V3_R_INVALID_INHERITANCE			 162
-#define X509V3_R_INVALID_IPADDRESS			 163
+#define X509V3_R_INVALID_INHERITANCE			 165
+#define X509V3_R_INVALID_IPADDRESS			 166
 #define X509V3_R_INVALID_NAME				 106
 #define X509V3_R_INVALID_NULL_ARGUMENT			 107
 #define X509V3_R_INVALID_NULL_NAME			 108
@@ -901,9 +985,9 @@
 #define X509V3_R_ODD_NUMBER_OF_DIGITS			 112
 #define X509V3_R_OPERATION_NOT_DEFINED			 148
 #define X509V3_R_OTHERNAME_ERROR			 147
-#define X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED	 155
+#define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED	 155
 #define X509V3_R_POLICY_PATH_LENGTH			 156
-#define X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED	 157
+#define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED	 157
 #define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED	 158
 #define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159
 #define X509V3_R_SECTION_NOT_FOUND			 150
@@ -914,6 +998,7 @@
 #define X509V3_R_UNKNOWN_EXTENSION_NAME			 130
 #define X509V3_R_UNKNOWN_OPTION				 120
 #define X509V3_R_UNSUPPORTED_OPTION			 117
+#define X509V3_R_UNSUPPORTED_TYPE			 167
 #define X509V3_R_USER_TOO_LONG				 132
 
 #ifdef  __cplusplus
diff --git a/crypto/x86_64cpuid.pl b/crypto/x86_64cpuid.pl
index 2616a03..a7f98b3 100644
--- a/crypto/x86_64cpuid.pl
+++ b/crypto/x86_64cpuid.pl
@@ -1,69 +1,181 @@
 #!/usr/bin/env perl
 
-$output=shift;
-$masm=1 if ($output =~ /\.asm/);
-open STDOUT,">$output" || die "can't open $output: $!";
+$flavour = shift;
+$output  = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
 
-print<<___ if(defined($masm));
-_TEXT	SEGMENT
-PUBLIC	OPENSSL_rdtsc
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
 
-PUBLIC	OPENSSL_atomic_add
-ALIGN	16
-OPENSSL_atomic_add	PROC
-	mov	eax,DWORD PTR[rcx]
-\$Lspin:	lea	r8,DWORD PTR[rdx+rax]
-lock	cmpxchg	DWORD PTR[rcx],r8d
-	jne	\$Lspin
-	mov	eax,r8d
-	cdqe    
-	ret
-OPENSSL_atomic_add	ENDP
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+open STDOUT,"| $^X ${dir}perlasm/x86_64-xlate.pl $flavour $output";
 
-PUBLIC	OPENSSL_wipe_cpu
-ALIGN	16
-OPENSSL_wipe_cpu	PROC
-	pxor	xmm0,xmm0
-	pxor	xmm1,xmm1
-	pxor	xmm2,xmm2
-	pxor	xmm3,xmm3
-	pxor	xmm4,xmm4
-	pxor	xmm5,xmm5
-	xor	rcx,rcx
-	xor	rdx,rdx
-	xor	r8,r8
-	xor	r9,r9
-	xor	r10,r10
-	xor	r11,r11
-	lea	rax,QWORD PTR[rsp+8]
-	ret
-OPENSSL_wipe_cpu	ENDP
-_TEXT	ENDS
+if ($win64)	{ $arg1="%rcx"; $arg2="%rdx"; }
+else		{ $arg1="%rdi"; $arg2="%rsi"; }
+print<<___;
+.extern		OPENSSL_cpuid_setup
+.section	.init
+	call	OPENSSL_cpuid_setup
 
-CRT\$XIU	SEGMENT
-EXTRN	OPENSSL_cpuid_setup:PROC
-DQ	OPENSSL_cpuid_setup
-CRT\$XIU	ENDS
-
-___
-print<<___ if(!defined($masm));
 .text
 
 .globl	OPENSSL_atomic_add
-.type	OPENSSL_atomic_add,\@function
+.type	OPENSSL_atomic_add,\@abi-omnipotent
 .align	16
 OPENSSL_atomic_add:
-	movl	(%rdi),%eax
-.Lspin:	leaq	(%rsi,%rax),%r8
-lock;	cmpxchgl	%r8d,(%rdi)
+	movl	($arg1),%eax
+.Lspin:	leaq	($arg2,%rax),%r8
+	.byte	0xf0		# lock
+	cmpxchgl	%r8d,($arg1)
 	jne	.Lspin
 	movl	%r8d,%eax
-	.byte	0x48,0x98
+	.byte	0x48,0x98	# cltq/cdqe
 	ret
 .size	OPENSSL_atomic_add,.-OPENSSL_atomic_add
 
+.globl	OPENSSL_rdtsc
+.type	OPENSSL_rdtsc,\@abi-omnipotent
+.align	16
+OPENSSL_rdtsc:
+	rdtsc
+	shl	\$32,%rdx
+	or	%rdx,%rax
+	ret
+.size	OPENSSL_rdtsc,.-OPENSSL_rdtsc
+
+.globl	OPENSSL_ia32_cpuid
+.type	OPENSSL_ia32_cpuid,\@abi-omnipotent
+.align	16
+OPENSSL_ia32_cpuid:
+	mov	%rbx,%r8
+
+	xor	%eax,%eax
+	cpuid
+	mov	%eax,%r11d		# max value for standard query level
+
+	xor	%eax,%eax
+	cmp	\$0x756e6547,%ebx	# "Genu"
+	setne	%al
+	mov	%eax,%r9d
+	cmp	\$0x49656e69,%edx	# "ineI"
+	setne	%al
+	or	%eax,%r9d
+	cmp	\$0x6c65746e,%ecx	# "ntel"
+	setne	%al
+	or	%eax,%r9d		# 0 indicates Intel CPU
+	jz	.Lintel
+
+	cmp	\$0x68747541,%ebx	# "Auth"
+	setne	%al
+	mov	%eax,%r10d
+	cmp	\$0x69746E65,%edx	# "enti"
+	setne	%al
+	or	%eax,%r10d
+	cmp	\$0x444D4163,%ecx	# "cAMD"
+	setne	%al
+	or	%eax,%r10d		# 0 indicates AMD CPU
+	jnz	.Lintel
+
+	# AMD specific
+	mov	\$0x80000000,%eax
+	cpuid
+	cmp	\$0x80000008,%eax
+	jb	.Lintel
+
+	mov	\$0x80000008,%eax
+	cpuid
+	movzb	%cl,%r10		# number of cores - 1
+	inc	%r10			# number of cores
+
+	mov	\$1,%eax
+	cpuid
+	bt	\$28,%edx		# test hyper-threading bit
+	jnc	.Ldone
+	shr	\$16,%ebx		# number of logical processors
+	cmp	%r10b,%bl
+	ja	.Ldone
+	and	\$0xefffffff,%edx	# ~(1<<28)
+	jmp	.Ldone
+
+.Lintel:
+	cmp	\$4,%r11d
+	mov	\$-1,%r10d
+	jb	.Lnocacheinfo
+
+	mov	\$4,%eax
+	mov	\$0,%ecx		# query L1D
+	cpuid
+	mov	%eax,%r10d
+	shr	\$14,%r10d
+	and	\$0xfff,%r10d		# number of cores -1 per L1D
+
+.Lnocacheinfo:
+	mov	\$1,%eax
+	cpuid
+	cmp	\$0,%r9d
+	jne	.Lnotintel
+	or	\$0x00100000,%edx	# use reserved 20th bit to engage RC4_CHAR
+	and	\$15,%ah
+	cmp	\$15,%ah		# examine Family ID
+	je	.Lnotintel
+	or	\$0x40000000,%edx	# use reserved bit to skip unrolled loop
+.Lnotintel:
+	bt	\$28,%edx		# test hyper-threading bit
+	jnc	.Ldone
+	and	\$0xefffffff,%edx	# ~(1<<28)
+	cmp	\$0,%r10d
+	je	.Ldone
+
+	or	\$0x10000000,%edx	# 1<<28
+	shr	\$16,%ebx
+	cmp	\$1,%bl			# see if cache is shared
+	ja	.Ldone
+	and	\$0xefffffff,%edx	# ~(1<<28)
+.Ldone:
+	shl	\$32,%rcx
+	mov	%edx,%eax
+	mov	%r8,%rbx
+	or	%rcx,%rax
+	ret
+.size	OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid
+
+.globl  OPENSSL_cleanse
+.type   OPENSSL_cleanse,\@abi-omnipotent
+.align  16
+OPENSSL_cleanse:
+	xor	%rax,%rax
+	cmp	\$15,$arg2
+	jae	.Lot
+	cmp	\$0,$arg2
+	je	.Lret
+.Little:
+	mov	%al,($arg1)
+	sub	\$1,$arg2
+	lea	1($arg1),$arg1
+	jnz	.Little
+.Lret:	ret
+.align	16
+.Lot:
+	test	\$7,$arg1
+	jz	.Laligned
+	mov	%al,($arg1)
+	lea	-1($arg2),$arg2
+	lea	1($arg1),$arg1
+	jmp	.Lot
+.Laligned:
+	mov	%rax,($arg1)
+	lea	-8($arg2),$arg2
+	test	\$-8,$arg2
+	lea	8($arg1),$arg1
+	jnz	.Laligned
+	cmp	\$0,$arg2
+	jne	.Little
+	ret
+.size	OPENSSL_cleanse,.-OPENSSL_cleanse
+___
+
+print<<___ if (!$win64);
 .globl	OPENSSL_wipe_cpu
-.type	OPENSSL_wipe_cpu,\@function
+.type	OPENSSL_wipe_cpu,\@abi-omnipotent
 .align	16
 OPENSSL_wipe_cpu:
 	pxor	%xmm0,%xmm0
@@ -93,67 +205,27 @@
 	leaq	8(%rsp),%rax
 	ret
 .size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
-
-.section	.init
-	call	OPENSSL_cpuid_setup
-
+___
+print<<___ if ($win64);
+.globl	OPENSSL_wipe_cpu
+.type	OPENSSL_wipe_cpu,\@abi-omnipotent
+.align	16
+OPENSSL_wipe_cpu:
+	pxor	%xmm0,%xmm0
+	pxor	%xmm1,%xmm1
+	pxor	%xmm2,%xmm2
+	pxor	%xmm3,%xmm3
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	xorq	%rcx,%rcx
+	xorq	%rdx,%rdx
+	xorq	%r8,%r8
+	xorq	%r9,%r9
+	xorq	%r10,%r10
+	xorq	%r11,%r11
+	leaq	8(%rsp),%rax
+	ret
+.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
 ___
 
-open STDOUT,"| $^X perlasm/x86_64-xlate.pl $output";
-print<<___;
-.text
-
-.globl	OPENSSL_rdtsc
-.type	OPENSSL_rdtsc,\@abi-omnipotent
-.align	16
-OPENSSL_rdtsc:
-	rdtsc
-	shl	\$32,%rdx
-	or	%rdx,%rax
-	ret
-.size	OPENSSL_rdtsc,.-OPENSSL_rdtsc
-
-.globl	OPENSSL_ia32_cpuid
-.type	OPENSSL_ia32_cpuid,\@abi-omnipotent
-.align	16
-OPENSSL_ia32_cpuid:
-	mov	%rbx,%r8
-
-	xor	%eax,%eax
-	cpuid
-	xor	%eax,%eax
-	cmp	\$0x756e6547,%ebx	# "Genu"
-	setne	%al
-	mov	%eax,%r9d
-	cmp	\$0x49656e69,%edx	# "ineI"
-	setne	%al
-	or	%eax,%r9d
-	cmp	\$0x6c65746e,%ecx	# "ntel"
-	setne	%al
-	or	%eax,%r9d
-
-	mov	\$1,%eax
-	cpuid
-	cmp	\$0,%r9d
-	jne	.Lnotintel
-	or	\$0x00100000,%edx	# use reserved 20th bit to engage RC4_CHAR
-	and	\$15,%ah
-	cmp	\$15,%ah		# examine Family ID
-	je	.Lnotintel
-	or	\$0x40000000,%edx	# use reserved bit to skip unrolled loop
-.Lnotintel:
-	bt	\$28,%edx		# test hyper-threading bit
-	jnc	.Ldone
-	shr	\$16,%ebx
-	cmp	\$1,%bl			# see if cache is shared
-	ja	.Ldone
-	and	\$0xefffffff,%edx	# ~(1<<28)
-.Ldone:
-	shl	\$32,%rcx
-	mov	%edx,%eax
-	mov	%r8,%rbx
-	or	%rcx,%rax
-	ret
-.size	OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid
-___
 close STDOUT;	# flush
diff --git a/crypto/x86cpuid.pl b/crypto/x86cpuid.pl
index 4408ef2..a7464af 100644
--- a/crypto/x86cpuid.pl
+++ b/crypto/x86cpuid.pl
@@ -1,6 +1,7 @@
 #!/usr/bin/env perl
 
-push(@INC,"perlasm");
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC, "${dir}perlasm", "perlasm");
 require "x86asm.pl";
 
 &asm_init($ARGV[0],"x86cpuid");
@@ -22,38 +23,90 @@
 	&jnc	(&label("done"));
 	&xor	("eax","eax");
 	&cpuid	();
+	&mov	("edi","eax");		# max value for standard query level
+
 	&xor	("eax","eax");
 	&cmp	("ebx",0x756e6547);	# "Genu"
-	&data_byte(0x0f,0x95,0xc0);	#&setne	(&LB("eax"));
+	&setne	(&LB("eax"));
 	&mov	("ebp","eax");
 	&cmp	("edx",0x49656e69);	# "ineI"
-	&data_byte(0x0f,0x95,0xc0);	#&setne	(&LB("eax"));
+	&setne	(&LB("eax"));
 	&or	("ebp","eax");
 	&cmp	("ecx",0x6c65746e);	# "ntel"
-	&data_byte(0x0f,0x95,0xc0);	#&setne	(&LB("eax"));
-	&or	("ebp","eax");
+	&setne	(&LB("eax"));
+	&or	("ebp","eax");		# 0 indicates Intel CPU
+	&jz	(&label("intel"));
+
+	&cmp	("ebx",0x68747541);	# "Auth"
+	&setne	(&LB("eax"));
+	&mov	("esi","eax");
+	&cmp	("edx",0x69746E65);	# "enti"
+	&setne	(&LB("eax"));
+	&or	("esi","eax");
+	&cmp	("ecx",0x444D4163);	# "cAMD"
+	&setne	(&LB("eax"));
+	&or	("esi","eax");		# 0 indicates AMD CPU
+	&jnz	(&label("intel"));
+
+	# AMD specific
+	&mov	("eax",0x80000000);
+	&cpuid	();
+	&cmp	("eax",0x80000008);
+	&jb	(&label("intel"));
+
+	&mov	("eax",0x80000008);
+	&cpuid	();
+	&movz	("esi",&LB("ecx"));	# number of cores - 1
+	&inc	("esi");		# number of cores
+
+	&mov	("eax",1);
+	&cpuid	();
+	&bt	("edx",28);
+	&jnc	(&label("done"));
+	&shr	("ebx",16);
+	&and	("ebx",0xff);
+	&cmp	("ebx","esi");
+	&ja	(&label("done"));
+	&and	("edx",0xefffffff);	# clear hyper-threading bit
+	&jmp	(&label("done"));
+	
+&set_label("intel");
+	&cmp	("edi",4);
+	&mov	("edi",-1);
+	&jb	(&label("nocacheinfo"));
+
+	&mov	("eax",4);
+	&mov	("ecx",0);		# query L1D
+	&cpuid	();
+	&mov	("edi","eax");
+	&shr	("edi",14);
+	&and	("edi",0xfff);		# number of cores -1 per L1D
+
+&set_label("nocacheinfo");
 	&mov	("eax",1);
 	&cpuid	();
 	&cmp	("ebp",0);
 	&jne	(&label("notP4"));
-	&and	("eax",15<<8);		# familiy ID
-	&cmp	("eax",15<<8);		# P4?
+	&and	(&HB("eax"),15);	# familiy ID
+	&cmp	(&HB("eax"),15);	# P4?
 	&jne	(&label("notP4"));
 	&or	("edx",1<<20);		# use reserved bit to engage RC4_CHAR
 &set_label("notP4");
 	&bt	("edx",28);		# test hyper-threading bit
 	&jnc	(&label("done"));
+	&and	("edx",0xefffffff);
+	&cmp	("edi",0);
+	&je	(&label("done"));
+
+	&or	("edx",0x10000000);
 	&shr	("ebx",16);
-	&and	("ebx",0xff);
-	&cmp	("ebx",1);		# see if cache is shared(*)
+	&cmp	(&LB("ebx"),1);
 	&ja	(&label("done"));
 	&and	("edx",0xefffffff);	# clear hyper-threading bit if not
 &set_label("done");
 	&mov	("eax","edx");
 	&mov	("edx","ecx");
 &function_end("OPENSSL_ia32_cpuid");
-# (*)	on Core2 this value is set to 2 denoting the fact that L2
-#	cache is shared between cores.
 
 &external_label("OPENSSL_ia32cap_P");
 
@@ -220,6 +273,40 @@
 	}
 &function_end_B("OPENSSL_indirect_call");
 
+&function_begin_B("OPENSSL_cleanse");
+	&mov	("edx",&wparam(0));
+	&mov	("ecx",&wparam(1));
+	&xor	("eax","eax");
+	&cmp	("ecx",7);
+	&jae	(&label("lot"));
+	&cmp	("ecx",0);
+	&je	(&label("ret"));
+&set_label("little");
+	&mov	(&BP(0,"edx"),"al");
+	&sub	("ecx",1);
+	&lea	("edx",&DWP(1,"edx"));
+	&jnz	(&label("little"));
+&set_label("ret");
+	&ret	();
+
+&set_label("lot",16);
+	&test	("edx",3);
+	&jz	(&label("aligned"));
+	&mov	(&BP(0,"edx"),"al");
+	&lea	("ecx",&DWP(-1,"ecx"));
+	&lea	("edx",&DWP(1,"edx"));
+	&jmp	(&label("lot"));
+&set_label("aligned");
+	&mov	(&DWP(0,"edx"),"eax");
+	&lea	("ecx",&DWP(-4,"ecx"));
+	&test	("ecx",-4);
+	&lea	("edx",&DWP(4,"edx"));
+	&jnz	(&label("aligned"));
+	&cmp	("ecx",0);
+	&jne	(&label("little"));
+	&ret	();
+&function_end_B("OPENSSL_cleanse");
+
 &initseg("OPENSSL_cpuid_setup");
 
 &asm_finish();
diff --git a/e_os.h b/e_os.h
index 9c5c6fd..0f4b799 100644
--- a/e_os.h
+++ b/e_os.h
@@ -112,7 +112,7 @@
 /********************************************************************
  The Microsoft section
  ********************************************************************/
-/* The following is used becaue of the small stack in some
+/* The following is used because of the small stack in some
  * Microsoft operating systems */
 #if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYSNAME_WIN32)
 #  define MS_STATIC	static
@@ -123,9 +123,6 @@
 #if defined(OPENSSL_SYS_WIN32) && !defined(WIN32)
 #  define WIN32
 #endif
-#if defined(OPENSSL_SYS_WIN16) && !defined(WIN16)
-#  define WIN16
-#endif
 #if defined(OPENSSL_SYS_WINDOWS) && !defined(WINDOWS)
 #  define WINDOWS
 #endif
@@ -181,6 +178,13 @@
 #define closesocket(s)		    close(s)
 #define readsocket(s,b,n)	    read((s),(b),(n))
 #define writesocket(s,b,n)	    write((s),(char *)(b),(n))
+#elif defined(OPENSSL_SYS_BEOS_R5)
+#define get_last_socket_error() errno
+#define clear_socket_error()    errno=0
+#define FIONBIO SO_NONBLOCK
+#define ioctlsocket(a,b,c)		  setsockopt((a),SOL_SOCKET,(b),(c),sizeof(*(c)))
+#define readsocket(s,b,n)       recv((s),(b),(n),0)
+#define writesocket(s,b,n)      send((s),(b),(n),0)
 #elif defined(OPENSSL_SYS_NETWARE)
 #if defined(NETWARE_BSDSOCK)
 #define get_last_socket_error() errno
@@ -209,7 +213,7 @@
 #define writesocket(s,b,n)	write((s),(b),(n))
 #endif
 
-#ifdef WIN16
+#ifdef WIN16 /* never the case */
 #  define MS_CALLBACK	_far _loadds
 #  define MS_FAR	_far
 #else
@@ -255,19 +259,31 @@
        /*
 	* Defining _WIN32_WINNT here in e_os.h implies certain "discipline."
 	* Most notably we ought to check for availability of each specific
-	* routine with GetProcAddress() and/or quard NT-specific calls with
+	* routine with GetProcAddress() and/or guard NT-specific calls with
 	* GetVersion() < 0x80000000. One can argue that in latter "or" case
 	* we ought to /DELAYLOAD some .DLLs in order to protect ourselves
 	* against run-time link errors. This doesn't seem to be necessary,
 	* because it turned out that already Windows 95, first non-NT Win32
 	* implementation, is equipped with at least NT 3.51 stubs, dummy
 	* routines with same name, but which do nothing. Meaning that it's
-	* apparently appropriate to guard generic NT calls with GetVersion
-	* alone, while NT 4.0 and above calls ought to be additionally
-	* checked upon with GetProcAddress.
+	* apparently sufficient to guard "vanilla" NT calls with GetVersion
+	* alone, while NT 4.0 and above interfaces ought to be linked with
+	* GetProcAddress at run-time.
 	*/
 #      define _WIN32_WINNT 0x0400
 #    endif
+#    if !defined(OPENSSL_NO_SOCK) && defined(_WIN32_WINNT)
+       /*
+        * Just like defining _WIN32_WINNT including winsock2.h implies
+        * certain "discipline" for maintaining [broad] binary compatibility.
+        * As long as structures are invariant among Winsock versions,
+        * it's sufficient to check for specific Winsock2 API availability
+        * at run-time [DSO_global_lookup is recommended]...
+        */
+#      include <winsock2.h>
+#      include <ws2tcpip.h>
+       /* yes, they have to be #included prior to <windows.h> */
+#    endif
 #    include <windows.h>
 #    include <stdio.h>
 #    include <stddef.h>
@@ -308,8 +324,8 @@
          /* 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'.
+	  * but without /MD results in LINK warning LNK4049:
+	  * 'locally defined symbol "__iob" imported'.
           */
          extern FILE *_imp___iob;
 #        define stdin  (&_imp___iob[0])
@@ -322,7 +338,7 @@
 #  include <fcntl.h>
 
 #  ifdef OPENSSL_SYS_WINCE
-#    include <winsock_extras.h>
+#    define OPENSSL_NO_POSIX_IO
 #  endif
 
 #  define ssize_t long
@@ -335,12 +351,7 @@
 #    define _kbhit kbhit
 #  endif
 
-#  if defined(WIN16) && defined(SSLEAY) && defined(_WINEXITNOPERSIST)
-#    define EXIT(n) _wsetexit(_WINEXITNOPERSIST)
-#    define OPENSSL_EXIT(n) do { if (n == 0) EXIT(n); return(n); } while(0)
-#  else
-#    define EXIT(n) exit(n)
-#  endif
+#  define EXIT(n) exit(n)
 #  define LIST_SEPARATOR_CHAR ';'
 #  ifndef X_OK
 #    define X_OK	0
@@ -361,7 +372,7 @@
 #    define DEFAULT_HOME  "C:"
 #  endif
 
-#else /* The non-microsoft world world */
+#else /* The non-microsoft world */
 
 #  ifdef OPENSSL_SYS_VMS
 #    define VMS 1
@@ -414,7 +425,6 @@
        extern int GetThreadID(void);
 /* #      include <conio.h> */
        extern int kbhit(void);
-       extern void delay(unsigned milliseconds);
 #    else
 #      include <screen.h>
 #    endif
@@ -454,6 +464,10 @@
 #      define setvbuf(a, b, c, d) setbuffer((a), (b), (d))
        typedef unsigned long clock_t;
 #    endif
+#    ifdef OPENSSL_SYS_WIN32_CYGWIN
+#      include <io.h>
+#      include <fcntl.h>
+#    endif
 
 #    define OPENSSL_CONF	"openssl.cnf"
 #    define SSLEAY_CONF		OPENSSL_CONF
@@ -480,8 +494,19 @@
 #      define SHUTDOWN(fd)		close(fd)
 #      define SHUTDOWN2(fd)		close(fd)
 #    elif !defined(__DJGPP__)
-#      include <winsock.h>
-extern HINSTANCE _hInstance;
+#      if defined(_WIN32_WCE) && _WIN32_WCE<410
+#        define getservbyname _masked_declaration_getservbyname
+#      endif
+#      if !defined(IPPROTO_IP)
+         /* winsock[2].h was included already? */
+#        include <winsock.h>
+#      endif
+#      ifdef getservbyname
+#        undef getservbyname
+         /* this is used to be wcecompat/include/winsock_extras.h */
+         struct servent* PASCAL getservbyname(const char*,const char*);
+#      endif
+
 #      ifdef _WIN64
 /*
  * Even though sizeof(SOCKET) is 8, it's safe to cast it to int, because
@@ -553,8 +578,10 @@
 #        include <sys/filio.h> /* Added for FIONBIO under unixware */
 #      endif
 #      include <netinet/in.h>
+#      if !defined(OPENSSL_SYS_BEOS_R5)
 #      include <arpa/inet.h>
 #    endif
+#    endif
 
 #    if defined(NeXT) || defined(_NEXT_SOURCE)
 #      include <sys/fcntl.h>
@@ -597,6 +624,18 @@
 #    define INVALID_SOCKET	(-1)
 #    endif /* INVALID_SOCKET */
 #  endif
+
+/* Some IPv6 implementations are broken, disable them in known bad
+ * versions.
+ */
+#  if !defined(OPENSSL_USE_IPV6)
+#    if defined(AF_INET6) && !defined(OPENSSL_SYS_BEOS_BONE) && !defined(NETWARE_CLIB)
+#      define OPENSSL_USE_IPV6 1
+#    else
+#      define OPENSSL_USE_IPV6 0
+#    endif
+#  endif
+
 #endif
 
 #if defined(__ultrix)
@@ -630,18 +669,6 @@
 
 /***********************************************/
 
-/* do we need to do this for getenv.
- * Just define getenv for use under windows */
-
-#ifdef WIN16
-/* How to do this needs to be thought out a bit more.... */
-/*char *GETENV(char *);
-#define Getenv	GETENV*/
-#define Getenv	getenv
-#else
-#define Getenv getenv
-#endif
-
 #define DG_GCC_BUG	/* gcc < 2.6.3 on DGUX */
 
 #ifdef sgi
@@ -703,6 +730,15 @@
 #endif
 /* end vxworks */
 
+/* beos */
+#if defined(OPENSSL_SYS_BEOS_R5)
+#define SO_ERROR 0
+#define NO_SYS_UN
+#define IPPROTO_IP 0
+#include <OS.h>
+#endif
+
+
 #ifdef  __cplusplus
 }
 #endif
diff --git a/e_os2.h b/e_os2.h
index 9da0b65..4c785c6 100644
--- a/e_os2.h
+++ b/e_os2.h
@@ -202,6 +202,17 @@
 # define OPENSSL_SYS_VXWORKS
 #endif
 
+/* --------------------------------- BeOS ---------------------------------- */
+#if defined(__BEOS__)
+# define OPENSSL_SYS_BEOS
+# include <sys/socket.h>
+# if defined(BONE_VERSION)
+#  define OPENSSL_SYS_BEOS_BONE
+# else
+#  define OPENSSL_SYS_BEOS_R5
+# endif
+#endif
+
 /**
  * That's it for OS-specific stuff
  *****************************************************************************/
@@ -251,24 +262,23 @@
 #define OPENSSL_EXTERN OPENSSL_IMPORT
 
 /* Macros to allow global variables to be reached through function calls when
-   required (if a shared library version requvres it, for example.
+   required (if a shared library version requires it, for example.
    The way it's done allows definitions like this:
 
 	// in foobar.c
-	OPENSSL_IMPLEMENT_GLOBAL(int,foobar) = 0;
+	OPENSSL_IMPLEMENT_GLOBAL(int,foobar,0)
 	// in foobar.h
 	OPENSSL_DECLARE_GLOBAL(int,foobar);
 	#define foobar OPENSSL_GLOBAL_REF(foobar)
 */
 #ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION
-# define OPENSSL_IMPLEMENT_GLOBAL(type,name)			     \
-	extern type _hide_##name;				     \
-	type *_shadow_##name(void) { return &_hide_##name; }	     \
-	static type _hide_##name
+# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value)			\
+	type *_shadow_##name(void)					\
+	{ static type _hide_##name=value; return &_hide_##name; }
 # define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void)
 # define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name()))
 #else
-# define OPENSSL_IMPLEMENT_GLOBAL(type,name) OPENSSL_GLOBAL type _shadow_##name
+# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) OPENSSL_GLOBAL type _shadow_##name=value;
 # define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name
 # define OPENSSL_GLOBAL_REF(name) _shadow_##name
 #endif
diff --git a/import_openssl.sh b/import_openssl.sh
index 15efce3..5dcb1c0 100755
--- a/import_openssl.sh
+++ b/import_openssl.sh
@@ -144,6 +144,13 @@
   cp ../patches/crypto_Android.mk crypto/Android.mk
   cp ../patches/ssl_Android.mk ssl/Android.mk
 
+  # Generate asm
+  perl crypto/aes/asm/aes-armv4.pl         > crypto/aes/asm/aes-armv4.s
+  perl crypto/bn/asm/armv4-mont.pl         > crypto/bn/asm/armv4-mont.s
+  perl crypto/sha/asm/sha1-armv4-large.pl  > crypto/sha/asm/sha1-armv4-large.s
+  perl crypto/sha/asm/sha256-armv4.pl      > crypto/sha/asm/sha256-armv4.s
+  perl crypto/sha/asm/sha512-armv4.pl      > crypto/sha/asm/sha512-armv4.s
+
   # Setup android.testssl directory
   mkdir android.testssl
   cat test/testssl | \
@@ -164,6 +171,7 @@
   rm -rf $UNNEEDED_SOURCES
 
   cd ..
+  rm -rf include/
   cp -af openssl-$OPENSSL_VERSION/include .
   rm -rf apps/
   mv openssl-$OPENSSL_VERSION/apps .
diff --git a/include/openssl/aes.h b/include/openssl/aes.h
index 450f2b4..d2c9973 100644
--- a/include/openssl/aes.h
+++ b/include/openssl/aes.h
@@ -58,6 +58,8 @@
 #error AES is disabled.
 #endif
 
+#include <stddef.h>
+
 #define AES_ENCRYPT	1
 #define AES_DECRYPT	0
 
@@ -66,10 +68,6 @@
 #define AES_MAXNR 14
 #define AES_BLOCK_SIZE 16
 
-#ifdef OPENSSL_FIPS
-#define FIPS_AES_SIZE_T	int
-#endif
-
 #ifdef  __cplusplus
 extern "C" {
 #endif
@@ -100,37 +98,32 @@
 void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
 	const AES_KEY *key, const int enc);
 void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const AES_KEY *key,
+	size_t length, const AES_KEY *key,
 	unsigned char *ivec, const int enc);
 void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const AES_KEY *key,
+	size_t length, const AES_KEY *key,
 	unsigned char *ivec, int *num, const int enc);
 void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const AES_KEY *key,
+	size_t length, const AES_KEY *key,
 	unsigned char *ivec, int *num, const int enc);
 void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const AES_KEY *key,
+	size_t length, const AES_KEY *key,
 	unsigned char *ivec, int *num, const int enc);
-void AES_cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
-			    const int nbits,const AES_KEY *key,
-			    unsigned char *ivec,const int enc);
 void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const AES_KEY *key,
+	size_t length, const AES_KEY *key,
 	unsigned char *ivec, int *num);
 void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
-	const unsigned long length, const AES_KEY *key,
+	size_t length, const AES_KEY *key,
 	unsigned char ivec[AES_BLOCK_SIZE],
 	unsigned char ecount_buf[AES_BLOCK_SIZE],
 	unsigned int *num);
-
-/* For IGE, see also http://www.links.org/files/openssl-ige.pdf */
 /* NB: the IV is _two_ blocks long */
 void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
-		     const unsigned long length, const AES_KEY *key,
+		     size_t length, const AES_KEY *key,
 		     unsigned char *ivec, const int enc);
 /* NB: the IV is _four_ blocks long */
 void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
-			const unsigned long length, const AES_KEY *key,
+			size_t length, const AES_KEY *key,
 			const AES_KEY *key2, const unsigned char *ivec,
 			const int enc);
 
@@ -141,6 +134,7 @@
 		unsigned char *out,
 		const unsigned char *in, unsigned int inlen);
 
+
 #ifdef  __cplusplus
 }
 #endif
diff --git a/include/openssl/asn1.h b/include/openssl/asn1.h
index 1958298..f7718b5 100644
--- a/include/openssl/asn1.h
+++ b/include/openssl/asn1.h
@@ -213,7 +213,7 @@
 	const char *sn,*ln;
 	int nid;
 	int length;
-	unsigned char *data;
+	const unsigned char *data;	/* data remains const after init */
 	int flags;	/* Should we free this one */
 	} ASN1_OBJECT;
 
@@ -228,8 +228,12 @@
  * complete and is a place holder for content when it had all been 
  * accessed. The flag will be reset when content has been written to it.
  */
-#define ASN1_STRING_FLAG_CONT 0x020 
 
+#define ASN1_STRING_FLAG_CONT 0x020 
+/* This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING
+ * type.
+ */
+#define ASN1_STRING_FLAG_MSTRING 0x040 
 /* This is the base type that holds just about everything :-) */
 typedef struct asn1_string_st
 	{
@@ -330,6 +334,13 @@
 	type *name##_new(void); \
 	void name##_free(type *a);
 
+#define DECLARE_ASN1_PRINT_FUNCTION(stname) \
+	DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname)
+
+#define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \
+	int fname##_print_ctx(BIO *out, stname *x, int indent, \
+					 const ASN1_PCTX *pctx);
+
 #define D2I_OF(type) type *(*)(type **,const unsigned char **,long)
 #define I2D_OF(type) int (*)(type *,unsigned char **)
 #define I2D_OF_const(type) int (*)(const type *,unsigned char **)
@@ -344,8 +355,6 @@
     ((void*) (1 ? p : (type*)0))
 #define CHECKED_PPTR_OF(type, p) \
     ((void**) (1 ? p : (type**)0))
-#define CHECKED_PTR_OF_TO_CHAR(type, p) \
-    ((char*) (1 ? p : (type*)0))
 
 #define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long)
 #define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **)
@@ -536,28 +545,23 @@
 		 * contain the set or sequence bytes */
 		ASN1_STRING *		set;
 		ASN1_STRING *		sequence;
-		ASN1_VALUE  *		asn1_value;
+		ASN1_VALUE *		asn1_value;
 		} value;
 	} ASN1_TYPE;
 
 DECLARE_STACK_OF(ASN1_TYPE)
 DECLARE_ASN1_SET_OF(ASN1_TYPE)
 
-typedef struct asn1_method_st
-	{
-	i2d_of_void *i2d;
-	d2i_of_void *d2i;
-	void *(*create)(void);
-	void (*destroy)(void *);
-	} ASN1_METHOD;
+typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY;
 
-/* This is used when parsing some Netscape objects */
-typedef struct asn1_header_st
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY)
+
+typedef struct NETSCAPE_X509_st
 	{
 	ASN1_OCTET_STRING *header;
-	void *data;
-	ASN1_METHOD *meth;
-	} ASN1_HEADER;
+	X509 *cert;
+	} NETSCAPE_X509;
 
 /* This is used to contain a list of bit names */
 typedef struct BIT_STRING_BITNAME_st {
@@ -577,32 +581,34 @@
 		ASN1_STRING_type_new(V_ASN1_BIT_STRING)
 #define M_ASN1_BIT_STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
 #define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\
-		ASN1_STRING_dup((ASN1_STRING *)a)
+		ASN1_STRING_dup((const ASN1_STRING *)a)
 #define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\
-		(ASN1_STRING *)a,(ASN1_STRING *)b)
+		(const ASN1_STRING *)a,(const ASN1_STRING *)b)
 #define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c)
 
 #define M_ASN1_INTEGER_new()	(ASN1_INTEGER *)\
 		ASN1_STRING_type_new(V_ASN1_INTEGER)
 #define M_ASN1_INTEGER_free(a)		ASN1_STRING_free((ASN1_STRING *)a)
-#define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)\
+		ASN1_STRING_dup((const ASN1_STRING *)a)
 #define M_ASN1_INTEGER_cmp(a,b)	ASN1_STRING_cmp(\
-		(ASN1_STRING *)a,(ASN1_STRING *)b)
+		(const ASN1_STRING *)a,(const ASN1_STRING *)b)
 
 #define M_ASN1_ENUMERATED_new()	(ASN1_ENUMERATED *)\
 		ASN1_STRING_type_new(V_ASN1_ENUMERATED)
 #define M_ASN1_ENUMERATED_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
-#define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)\
+		ASN1_STRING_dup((const ASN1_STRING *)a)
 #define M_ASN1_ENUMERATED_cmp(a,b)	ASN1_STRING_cmp(\
-		(ASN1_STRING *)a,(ASN1_STRING *)b)
+		(const ASN1_STRING *)a,(const ASN1_STRING *)b)
 
 #define M_ASN1_OCTET_STRING_new()	(ASN1_OCTET_STRING *)\
 		ASN1_STRING_type_new(V_ASN1_OCTET_STRING)
 #define M_ASN1_OCTET_STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
 #define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\
-		ASN1_STRING_dup((ASN1_STRING *)a)
+		ASN1_STRING_dup((const ASN1_STRING *)a)
 #define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\
-		(ASN1_STRING *)a,(ASN1_STRING *)b)
+		(const ASN1_STRING *)a,(const ASN1_STRING *)b)
 #define M_ASN1_OCTET_STRING_set(a,b,c)	ASN1_STRING_set((ASN1_STRING *)a,b,c)
 #define M_ASN1_OCTET_STRING_print(a,b)	ASN1_STRING_print(a,(ASN1_STRING *)b)
 #define M_i2d_ASN1_OCTET_STRING(a,pp) \
@@ -686,7 +692,7 @@
 		ASN1_STRING_type_new(V_ASN1_IA5STRING)
 #define M_ASN1_IA5STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
 #define M_ASN1_IA5STRING_dup(a)	\
-			(ASN1_IA5STRING *)ASN1_STRING_dup((ASN1_STRING *)a)
+		(ASN1_IA5STRING *)ASN1_STRING_dup((const ASN1_STRING *)a)
 #define M_i2d_ASN1_IA5STRING(a,pp) \
 		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\
 			V_ASN1_UNIVERSAL)
@@ -697,18 +703,20 @@
 #define M_ASN1_UTCTIME_new()	(ASN1_UTCTIME *)\
 		ASN1_STRING_type_new(V_ASN1_UTCTIME)
 #define M_ASN1_UTCTIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
-#define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)\
+		ASN1_STRING_dup((const ASN1_STRING *)a)
 
 #define M_ASN1_GENERALIZEDTIME_new()	(ASN1_GENERALIZEDTIME *)\
 		ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME)
 #define M_ASN1_GENERALIZEDTIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
 #define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\
-	(ASN1_STRING *)a)
+	(const ASN1_STRING *)a)
 
 #define M_ASN1_TIME_new()	(ASN1_TIME *)\
 		ASN1_STRING_type_new(V_ASN1_UTCTIME)
 #define M_ASN1_TIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
-#define M_ASN1_TIME_dup(a) (ASN1_TIME *)ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_TIME_dup(a) (ASN1_TIME *)\
+	ASN1_STRING_dup((const ASN1_STRING *)a)
 
 #define M_ASN1_GENERALSTRING_new()	(ASN1_GENERALSTRING *)\
 		ASN1_STRING_type_new(V_ASN1_GENERALSTRING)
@@ -769,6 +777,7 @@
 int ASN1_TYPE_get(ASN1_TYPE *a);
 void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
 int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
+int            ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b);
 
 ASN1_OBJECT *	ASN1_OBJECT_new(void );
 void		ASN1_OBJECT_free(ASN1_OBJECT *a);
@@ -785,14 +794,15 @@
 
 ASN1_STRING *	ASN1_STRING_new(void);
 void		ASN1_STRING_free(ASN1_STRING *a);
-ASN1_STRING *	ASN1_STRING_dup(ASN1_STRING *a);
+int		ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str);
+ASN1_STRING *	ASN1_STRING_dup(const ASN1_STRING *a);
 ASN1_STRING *	ASN1_STRING_type_new(int type );
-int 		ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b);
+int 		ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b);
   /* Since this is used to store all sorts of things, via macros, for now, make
      its data void * */
 int 		ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
 void		ASN1_STRING_set0(ASN1_STRING *str, void *data, int len);
-int ASN1_STRING_length(ASN1_STRING *x);
+int ASN1_STRING_length(const ASN1_STRING *x);
 void ASN1_STRING_length_set(ASN1_STRING *x, int n);
 int ASN1_STRING_type(ASN1_STRING *x);
 unsigned char * ASN1_STRING_data(ASN1_STRING *x);
@@ -805,6 +815,8 @@
 			int length );
 int		ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
 int		ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n);
+int            ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
+                                     unsigned char *flags, int flags_len);
 
 #ifndef OPENSSL_NO_BIO
 int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
@@ -823,13 +835,15 @@
 			long length);
 ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,const unsigned char **pp,
 			long length);
-ASN1_INTEGER *	ASN1_INTEGER_dup(ASN1_INTEGER *x);
-int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y);
+ASN1_INTEGER *	ASN1_INTEGER_dup(const ASN1_INTEGER *x);
+int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y);
 
 DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)
 
 int ASN1_UTCTIME_check(ASN1_UTCTIME *a);
 ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s,time_t t);
+ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
+				int offset_day, long offset_sec);
 int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str);
 int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t);
 #if 0
@@ -838,11 +852,13 @@
 
 int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *a);
 ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,time_t t);
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
+	     time_t t, int offset_day, long offset_sec);
 int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str);
 
 DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
-ASN1_OCTET_STRING *	ASN1_OCTET_STRING_dup(ASN1_OCTET_STRING *a);
-int 	ASN1_OCTET_STRING_cmp(ASN1_OCTET_STRING *a, ASN1_OCTET_STRING *b);
+ASN1_OCTET_STRING *	ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a);
+int 	ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b);
 int 	ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, int len);
 
 DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
@@ -869,14 +885,20 @@
 DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF)
 
 ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t);
+ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s,time_t t,
+				int offset_day, long offset_sec);
 int ASN1_TIME_check(ASN1_TIME *t);
 ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out);
+int ASN1_TIME_set_string(ASN1_TIME *s, const char *str);
 
-int i2d_ASN1_SET(STACK *a, unsigned char **pp,
-		 i2d_of_void *i2d, int ex_tag, int ex_class, int is_set);
-STACK *	d2i_ASN1_SET(STACK **a, const unsigned char **pp, long length,
-		     d2i_of_void *d2i, void (*free_func)(void *),
-		     int ex_tag, int ex_class);
+int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
+		 i2d_of_void *i2d, int ex_tag, int ex_class,
+		 int is_set);
+STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
+			      const unsigned char **pp,
+			      long length, d2i_of_void *d2i,
+			      void (*free_func)(OPENSSL_BLOCK), int ex_tag,
+			      int ex_class);
 
 #ifndef OPENSSL_NO_BIO
 int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
@@ -894,9 +916,9 @@
 	const char *sn, const char *ln);
 
 int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
-long ASN1_INTEGER_get(ASN1_INTEGER *a);
-ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai);
-BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai,BIGNUM *bn);
+long ASN1_INTEGER_get(const ASN1_INTEGER *a);
+ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai);
+BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai,BIGNUM *bn);
 
 int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v);
 long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a);
@@ -930,17 +952,17 @@
 int ASN1_object_size(int constructed, int length, int tag);
 
 /* Used to implement other functions */
-void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x);
+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x);
 
 #define ASN1_dup_of(type,i2d,d2i,x) \
     ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \
 		     CHECKED_D2I_OF(type, d2i), \
-		     CHECKED_PTR_OF_TO_CHAR(type, x)))
+		     CHECKED_PTR_OF(type, x)))
 
 #define ASN1_dup_of_const(type,i2d,d2i,x) \
     ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \
 		     CHECKED_D2I_OF(type, d2i), \
-		     CHECKED_PTR_OF_TO_CHAR(const type, x)))
+		     CHECKED_PTR_OF(const type, x)))
 
 void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
 
@@ -1001,30 +1023,24 @@
 		  CHECKED_PTR_OF(const type, x)))
 
 int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
-int ASN1_UTCTIME_print(BIO *fp,ASN1_UTCTIME *a);
-int ASN1_GENERALIZEDTIME_print(BIO *fp,ASN1_GENERALIZEDTIME *a);
-int ASN1_TIME_print(BIO *fp,ASN1_TIME *a);
-int ASN1_STRING_print(BIO *bp,ASN1_STRING *v);
+int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a);
+int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);
+int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
+int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
 int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
+int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
+				unsigned char *buf, int off);
 int ASN1_parse(BIO *bp,const unsigned char *pp,long len,int indent);
 int ASN1_parse_dump(BIO *bp,const unsigned char *pp,long len,int indent,int dump);
 #endif
 const char *ASN1_tag2str(int tag);
 
-/* Used to load and write netscape format cert/key */
-int i2d_ASN1_HEADER(ASN1_HEADER *a,unsigned char **pp);
-ASN1_HEADER *d2i_ASN1_HEADER(ASN1_HEADER **a,const unsigned char **pp, long length);
-ASN1_HEADER *ASN1_HEADER_new(void );
-void ASN1_HEADER_free(ASN1_HEADER *a);
+/* Used to load and write netscape format cert */
+
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_X509)
 
 int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s);
 
-/* Not used that much at this point, except for the first two */
-ASN1_METHOD *X509_asn1_meth(void);
-ASN1_METHOD *RSAPrivateKey_asn1_meth(void);
-ASN1_METHOD *ASN1_IA5STRING_asn1_meth(void);
-ASN1_METHOD *ASN1_BIT_STRING_asn1_meth(void);
-
 int ASN1_TYPE_set_octetstring(ASN1_TYPE *a,
 	unsigned char *data, int len);
 int ASN1_TYPE_get_octetstring(ASN1_TYPE *a,
@@ -1034,9 +1050,9 @@
 int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a,long *num,
 	unsigned char *data, int max_len);
 
-STACK *ASN1_seq_unpack(const unsigned char *buf, int len,
-		       d2i_of_void *d2i, void (*free_func)(void *));
-unsigned char *ASN1_seq_pack(STACK *safes, i2d_of_void *i2d,
+STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
+				 d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK));
+unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
 			     unsigned char **buf, int *len );
 void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i);
 void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it);
@@ -1079,15 +1095,58 @@
 ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
 ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);
 
-typedef int asn1_output_data_fn(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
-					const ASN1_ITEM *it);
+/* ASN1 Print flags */
 
-int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
+/* Indicate missing OPTIONAL fields */
+#define ASN1_PCTX_FLAGS_SHOW_ABSENT		0x001	
+/* Mark start and end of SEQUENCE */
+#define ASN1_PCTX_FLAGS_SHOW_SEQUENCE		0x002
+/* Mark start and end of SEQUENCE/SET OF */
+#define ASN1_PCTX_FLAGS_SHOW_SSOF		0x004
+/* Show the ASN1 type of primitives */
+#define ASN1_PCTX_FLAGS_SHOW_TYPE		0x008
+/* Don't show ASN1 type of ANY */
+#define ASN1_PCTX_FLAGS_NO_ANY_TYPE		0x010
+/* Don't show ASN1 type of MSTRINGs */
+#define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE		0x020
+/* Don't show field names in SEQUENCE */
+#define ASN1_PCTX_FLAGS_NO_FIELD_NAME		0x040
+/* Show structure names of each SEQUENCE field */
+#define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME	0x080
+/* Don't show structure name even at top level */
+#define ASN1_PCTX_FLAGS_NO_STRUCT_NAME		0x100
+
+int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
+				const ASN1_ITEM *it, const ASN1_PCTX *pctx);
+ASN1_PCTX *ASN1_PCTX_new(void);
+void ASN1_PCTX_free(ASN1_PCTX *p);
+unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags);
+
+BIO_METHOD *BIO_f_asn1(void);
+
+BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it);
+
+int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+				const ASN1_ITEM *it);
+int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+				const char *hdr,
+				const ASN1_ITEM *it);
+int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
 				int ctype_nid, int econt_nid,
 				STACK_OF(X509_ALGOR) *mdalgs,
-				asn1_output_data_fn *data_fn,
 				const ASN1_ITEM *it);
 ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it);
+int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
+int SMIME_text(BIO *in, BIO *out);
 
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -1118,6 +1177,7 @@
 #define ASN1_F_ASN1_ENUMERATED_TO_BN			 113
 #define ASN1_F_ASN1_EX_C2I				 204
 #define ASN1_F_ASN1_FIND_END				 190
+#define ASN1_F_ASN1_GENERALIZEDTIME_ADJ			 216
 #define ASN1_F_ASN1_GENERALIZEDTIME_SET			 185
 #define ASN1_F_ASN1_GENERATE_V3				 178
 #define ASN1_F_ASN1_GET_OBJECT				 114
@@ -1138,7 +1198,7 @@
 #define ASN1_F_ASN1_ITEM_VERIFY				 197
 #define ASN1_F_ASN1_MBSTRING_NCOPY			 122
 #define ASN1_F_ASN1_OBJECT_NEW				 123
-#define ASN1_F_ASN1_OUTPUT_DATA				 207
+#define ASN1_F_ASN1_OUTPUT_DATA				 214
 #define ASN1_F_ASN1_PACK_STRING				 124
 #define ASN1_F_ASN1_PCTX_NEW				 205
 #define ASN1_F_ASN1_PKCS5_PBE_SET			 125
@@ -1152,14 +1212,17 @@
 #define ASN1_F_ASN1_TEMPLATE_EX_D2I			 132
 #define ASN1_F_ASN1_TEMPLATE_NEW			 133
 #define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I			 131
+#define ASN1_F_ASN1_TIME_ADJ				 217
 #define ASN1_F_ASN1_TIME_SET				 175
 #define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING		 134
 #define ASN1_F_ASN1_TYPE_GET_OCTETSTRING		 135
 #define ASN1_F_ASN1_UNPACK_STRING			 136
+#define ASN1_F_ASN1_UTCTIME_ADJ				 218
 #define ASN1_F_ASN1_UTCTIME_SET				 187
 #define ASN1_F_ASN1_VERIFY				 137
-#define ASN1_F_B64_READ_ASN1				 208
-#define ASN1_F_B64_WRITE_ASN1				 209
+#define ASN1_F_B64_READ_ASN1				 209
+#define ASN1_F_B64_WRITE_ASN1				 210
+#define ASN1_F_BIO_NEW_NDEF				 208
 #define ASN1_F_BITSTR_CB				 180
 #define ASN1_F_BN_TO_ASN1_ENUMERATED			 138
 #define ASN1_F_BN_TO_ASN1_INTEGER			 139
@@ -1178,6 +1241,7 @@
 #define ASN1_F_D2I_ASN1_TYPE_BYTES			 149
 #define ASN1_F_D2I_ASN1_UINTEGER			 150
 #define ASN1_F_D2I_ASN1_UTCTIME				 151
+#define ASN1_F_D2I_AUTOPRIVATEKEY			 207
 #define ASN1_F_D2I_NETSCAPE_RSA				 152
 #define ASN1_F_D2I_NETSCAPE_RSA_2			 153
 #define ASN1_F_D2I_PRIVATEKEY				 154
@@ -1187,6 +1251,7 @@
 #define ASN1_F_D2I_X509					 156
 #define ASN1_F_D2I_X509_CINF				 157
 #define ASN1_F_D2I_X509_PKEY				 159
+#define ASN1_F_I2D_ASN1_BIO_STREAM			 211
 #define ASN1_F_I2D_ASN1_SET				 188
 #define ASN1_F_I2D_ASN1_TIME				 160
 #define ASN1_F_I2D_DSA_PUBKEY				 161
@@ -1198,10 +1263,11 @@
 #define ASN1_F_LONG_C2I					 166
 #define ASN1_F_OID_MODULE_INIT				 174
 #define ASN1_F_PARSE_TAGGING				 182
-#define ASN1_F_PKCS5_PBE2_SET				 167
+#define ASN1_F_PKCS5_PBE2_SET_IV			 167
 #define ASN1_F_PKCS5_PBE_SET				 202
-#define ASN1_F_SMIME_READ_ASN1				 210
-#define ASN1_F_SMIME_TEXT				 211
+#define ASN1_F_PKCS5_PBE_SET0_ALGOR			 215
+#define ASN1_F_SMIME_READ_ASN1				 212
+#define ASN1_F_SMIME_TEXT				 213
 #define ASN1_F_X509_CINF_NEW				 168
 #define ASN1_F_X509_CRL_ADD0_REVOKED			 169
 #define ASN1_F_X509_INFO_NEW				 170
@@ -1213,14 +1279,14 @@
 
 /* Reason codes. */
 #define ASN1_R_ADDING_OBJECT				 171
-#define ASN1_R_ASN1_PARSE_ERROR				 198
-#define ASN1_R_ASN1_SIG_PARSE_ERROR			 199
+#define ASN1_R_ASN1_PARSE_ERROR				 203
+#define ASN1_R_ASN1_SIG_PARSE_ERROR			 204
 #define ASN1_R_AUX_ERROR				 100
 #define ASN1_R_BAD_CLASS				 101
 #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_BMPSTRING_IS_WRONG_LENGTH		 214
 #define ASN1_R_BN_LIB					 105
 #define ASN1_R_BOOLEAN_IS_WRONG_LENGTH			 106
 #define ASN1_R_BUFFER_TOO_SMALL				 107
@@ -1229,6 +1295,7 @@
 #define ASN1_R_DECODE_ERROR				 110
 #define ASN1_R_DECODING_ERROR				 111
 #define ASN1_R_DEPTH_EXCEEDED				 174
+#define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED	 198
 #define ASN1_R_ENCODE_ERROR				 112
 #define ASN1_R_ERROR_GETTING_TIME			 173
 #define ASN1_R_ERROR_LOADING_SECTION			 172
@@ -1262,10 +1329,10 @@
 #define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG		 128
 #define ASN1_R_INVALID_BMPSTRING_LENGTH			 129
 #define ASN1_R_INVALID_DIGIT				 130
-#define ASN1_R_INVALID_MIME_TYPE			 200
+#define ASN1_R_INVALID_MIME_TYPE			 205
 #define ASN1_R_INVALID_MODIFIER				 186
 #define ASN1_R_INVALID_NUMBER				 187
-#define ASN1_R_INVALID_OBJECT_ENCODING			 212
+#define ASN1_R_INVALID_OBJECT_ENCODING			 216
 #define ASN1_R_INVALID_SEPARATOR			 131
 #define ASN1_R_INVALID_TIME_FORMAT			 132
 #define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH		 133
@@ -1273,9 +1340,9 @@
 #define ASN1_R_IV_TOO_LARGE				 135
 #define ASN1_R_LENGTH_ERROR				 136
 #define ASN1_R_LIST_ERROR				 188
-#define ASN1_R_MIME_NO_CONTENT_TYPE			 201
-#define ASN1_R_MIME_PARSE_ERROR				 202
-#define ASN1_R_MIME_SIG_PARSE_ERROR			 203
+#define ASN1_R_MIME_NO_CONTENT_TYPE			 206
+#define ASN1_R_MIME_PARSE_ERROR				 207
+#define ASN1_R_MIME_SIG_PARSE_ERROR			 208
 #define ASN1_R_MISSING_EOC				 137
 #define ASN1_R_MISSING_SECOND_NUMBER			 138
 #define ASN1_R_MISSING_VALUE				 189
@@ -1285,11 +1352,12 @@
 #define ASN1_R_NON_HEX_CHARACTERS			 141
 #define ASN1_R_NOT_ASCII_FORMAT				 190
 #define ASN1_R_NOT_ENOUGH_DATA				 142
-#define ASN1_R_NO_CONTENT_TYPE				 204
+#define ASN1_R_NO_CONTENT_TYPE				 209
+#define ASN1_R_NO_DEFAULT_DIGEST			 201
 #define ASN1_R_NO_MATCHING_CHOICE_TYPE			 143
-#define ASN1_R_NO_MULTIPART_BODY_FAILURE		 205
-#define ASN1_R_NO_MULTIPART_BOUNDARY			 206
-#define ASN1_R_NO_SIG_CONTENT_TYPE			 207
+#define ASN1_R_NO_MULTIPART_BODY_FAILURE		 210
+#define ASN1_R_NO_MULTIPART_BOUNDARY			 211
+#define ASN1_R_NO_SIG_CONTENT_TYPE			 212
 #define ASN1_R_NULL_IS_WRONG_LENGTH			 144
 #define ASN1_R_OBJECT_NOT_ASCII_FORMAT			 191
 #define ASN1_R_ODD_NUMBER_OF_CHARS			 145
@@ -1299,8 +1367,8 @@
 #define ASN1_R_SEQUENCE_NOT_CONSTRUCTED			 149
 #define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG		 192
 #define ASN1_R_SHORT_LINE				 150
-#define ASN1_R_SIG_INVALID_MIME_TYPE			 208
-#define ASN1_R_STREAMING_NOT_SUPPORTED			 209
+#define ASN1_R_SIG_INVALID_MIME_TYPE			 213
+#define ASN1_R_STREAMING_NOT_SUPPORTED			 202
 #define ASN1_R_STRING_TOO_LONG				 151
 #define ASN1_R_STRING_TOO_SHORT				 152
 #define ASN1_R_TAG_VALUE_TOO_HIGH			 153
@@ -1311,11 +1379,12 @@
 #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_UNIVERSALSTRING_IS_WRONG_LENGTH		 215
 #define ASN1_R_UNKNOWN_FORMAT				 160
 #define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM		 161
 #define ASN1_R_UNKNOWN_OBJECT_TYPE			 162
 #define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE			 163
+#define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM		 199
 #define ASN1_R_UNKNOWN_TAG				 194
 #define ASN1_R_UNKOWN_FORMAT				 195
 #define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE		 164
@@ -1323,6 +1392,7 @@
 #define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM		 166
 #define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE		 167
 #define ASN1_R_UNSUPPORTED_TYPE				 196
+#define ASN1_R_WRONG_PUBLIC_KEY_TYPE			 200
 #define ASN1_R_WRONG_TAG				 168
 #define ASN1_R_WRONG_TYPE				 169
 
diff --git a/include/openssl/asn1_mac.h b/include/openssl/asn1_mac.h
index d958ca6..87bd0e9 100644
--- a/include/openssl/asn1_mac.h
+++ b/include/openssl/asn1_mac.h
@@ -153,6 +153,13 @@
 		M_ASN1_D2I_get(b,func); \
 		}
 
+#define M_ASN1_D2I_get_int_opt(b,func,type) \
+	if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \
+		== (V_ASN1_UNIVERSAL|(type)))) \
+		{ \
+		M_ASN1_D2I_get_int(b,func); \
+		}
+
 #define M_ASN1_D2I_get_imp(b,func, type) \
 	M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \
 	c.q=c.p; \
diff --git a/include/openssl/asn1t.h b/include/openssl/asn1t.h
index ac14f94..d230e4b 100644
--- a/include/openssl/asn1t.h
+++ b/include/openssl/asn1t.h
@@ -3,7 +3,7 @@
  * project 2000.
  */
 /* ====================================================================
- * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 2000-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
@@ -218,6 +218,18 @@
 		#stname \
 	ASN1_ITEM_end(tname)
 
+#define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_NDEF_SEQUENCE,\
+		V_ASN1_SEQUENCE,\
+		tname##_seq_tt,\
+		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+		&tname##_aux,\
+		sizeof(stname),\
+		#stname \
+	ASN1_ITEM_end(tname)
+
 
 /* This pair helps declare a CHOICE type. We can do:
  *
@@ -651,8 +663,13 @@
 typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
 typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
 
+typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval, 
+						int indent, const char *fname, 
+						const ASN1_PCTX *pctx);
+
 typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
 typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
+typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
 
 typedef struct ASN1_COMPAT_FUNCS_st {
 	ASN1_new_func *asn1_new;
@@ -668,6 +685,7 @@
 	ASN1_ex_free_func *asn1_ex_clear;
 	ASN1_ex_d2i *asn1_ex_d2i;
 	ASN1_ex_i2d *asn1_ex_i2d;
+	ASN1_ex_print_func *asn1_ex_print;
 } ASN1_EXTERN_FUNCS;
 
 typedef struct ASN1_PRIMITIVE_FUNCS_st {
@@ -678,6 +696,7 @@
 	ASN1_ex_free_func *prim_clear;
 	ASN1_primitive_c2i *prim_c2i;
 	ASN1_primitive_i2c *prim_i2c;
+	ASN1_primitive_print *prim_print;
 } ASN1_PRIMITIVE_FUNCS;
 
 /* This is the ASN1_AUX structure: it handles various
@@ -697,7 +716,8 @@
  * then an external type is more appropriate.
  */
 
-typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it);
+typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it,
+				void *exarg);
 
 typedef struct ASN1_AUX_st {
 	void *app_data;
@@ -708,6 +728,23 @@
 	int enc_offset;		/* Offset of ASN1_ENCODING structure */
 } ASN1_AUX;
 
+/* For print related callbacks exarg points to this structure */
+typedef struct ASN1_PRINT_ARG_st {
+	BIO *out;
+	int indent;
+	const ASN1_PCTX *pctx;
+} ASN1_PRINT_ARG;
+
+/* For streaming related callbacks exarg points to this structure */
+typedef struct ASN1_STREAM_ARG_st {
+	/* BIO to stream through */
+	BIO *out;
+	/* BIO with filters appended */
+	BIO *ndef_bio;
+	/* Streaming I/O boundary */
+	unsigned char **boundary;
+} ASN1_STREAM_ARG;
+
 /* Flags in ASN1_AUX */
 
 /* Use a reference count */
@@ -727,6 +764,12 @@
 #define ASN1_OP_D2I_POST	5
 #define ASN1_OP_I2D_PRE		6
 #define ASN1_OP_I2D_POST	7
+#define ASN1_OP_PRINT_PRE	8
+#define ASN1_OP_PRINT_POST	9
+#define ASN1_OP_STREAM_PRE	10
+#define ASN1_OP_STREAM_POST	11
+#define ASN1_OP_DETACHED_PRE	12
+#define ASN1_OP_DETACHED_POST	13
 
 /* Macro to implement a primitive type */
 #define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)
@@ -782,9 +825,22 @@
 #define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \
 			IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)
 
+#define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \
+		IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname)
+
 #define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \
 		IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)
 
+#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \
+	pre stname *fname##_new(void) \
+	{ \
+		return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
+	} \
+	pre void fname##_free(stname *a) \
+	{ \
+		ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
+	}
+
 #define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \
 	stname *fname##_new(void) \
 	{ \
@@ -834,6 +890,17 @@
         return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \
         }
 
+#define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \
+	IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname)
+
+#define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \
+	int fname##_print_ctx(BIO *out, stname *x, int indent, \
+						const ASN1_PCTX *pctx) \
+	{ \
+		return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \
+			ASN1_ITEM_rptr(itname), pctx); \
+	} 
+
 #define IMPLEMENT_ASN1_FUNCTIONS_const(name) \
 		IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)
 
diff --git a/include/openssl/bio.h b/include/openssl/bio.h
index ebb4278..152802f 100644
--- a/include/openssl/bio.h
+++ b/include/openssl/bio.h
@@ -95,6 +95,7 @@
 #define BIO_TYPE_BIO		(19|0x0400)		/* (half a) BIO pair */
 #define BIO_TYPE_LINEBUFFER	(20|0x0200)		/* filter */
 #define BIO_TYPE_DGRAM		(21|0x0400|0x0100)
+#define BIO_TYPE_ASN1 		(22|0x0200)		/* filter */
 #define BIO_TYPE_COMP 		(23|0x0200)		/* filter */
 
 #define BIO_TYPE_DESCRIPTOR	0x0100	/* socket, fd, connect or accept */
@@ -265,7 +266,6 @@
 
 typedef void bio_info_cb(struct bio_st *, int, const char *, int, long, long);
 
-#ifndef OPENSSL_SYS_WIN16
 typedef struct bio_method_st
 	{
 	int type;
@@ -279,21 +279,6 @@
 	int (*destroy)(BIO *);
         long (*callback_ctrl)(BIO *, int, bio_info_cb *);
 	} BIO_METHOD;
-#else
-typedef struct bio_method_st
-	{
-	int type;
-	const char *name;
-	int (_far *bwrite)();
-	int (_far *bread)();
-	int (_far *bputs)();
-	int (_far *bgets)();
-	long (_far *ctrl)();
-	int (_far *create)();
-	int (_far *destroy)();
-	long (_far *callback_ctrl)();
-	} BIO_METHOD;
-#endif
 
 struct bio_st
 	{
@@ -334,6 +319,9 @@
 	int obuf_off;		/* write/read offset */
 	} BIO_F_BUFFER_CTX;
 
+/* Prefix and suffix callback in ASN1 BIO */
+typedef int asn1_ps_func(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+
 /* connect BIO stuff */
 #define BIO_CONN_S_BEFORE		1
 #define BIO_CONN_S_GET_IP		2
@@ -396,6 +384,13 @@
 #define BIO_C_RESET_READ_REQUEST		147
 #define BIO_C_SET_MD_CTX			148
 
+#define BIO_C_SET_PREFIX			149
+#define BIO_C_GET_PREFIX			150
+#define BIO_C_SET_SUFFIX			151
+#define BIO_C_GET_SUFFIX			152
+
+#define BIO_C_SET_EX_ARG			153
+#define BIO_C_GET_EX_ARG			154
 
 #define BIO_set_app_data(s,arg)		BIO_set_ex_data(s,0,arg)
 #define BIO_get_app_data(s)		BIO_get_ex_data(s,0)
@@ -559,22 +554,21 @@
 unsigned long BIO_number_read(BIO *bio);
 unsigned long BIO_number_written(BIO *bio);
 
+/* For BIO_f_asn1() */
+int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
+					asn1_ps_func *prefix_free);
+int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
+					asn1_ps_func **pprefix_free);
+int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
+					asn1_ps_func *suffix_free);
+int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
+					asn1_ps_func **psuffix_free);
+
 # ifndef OPENSSL_NO_FP_API
-#  if defined(OPENSSL_SYS_WIN16) && defined(_WINDLL)
-BIO_METHOD *BIO_s_file_internal(void);
-BIO *BIO_new_file_internal(char *filename, char *mode);
-BIO *BIO_new_fp_internal(FILE *stream, int close_flag);
-#    define BIO_s_file	BIO_s_file_internal
-#    define BIO_new_file	BIO_new_file_internal
-#    define BIO_new_fp	BIO_new_fp_internal
-#  else /* FP_API */
 BIO_METHOD *BIO_s_file(void );
 BIO *BIO_new_file(const char *filename, const char *mode);
 BIO *BIO_new_fp(FILE *stream, int close_flag);
-#    define BIO_s_file_internal		BIO_s_file
-#    define BIO_new_file_internal	BIO_new_file
-#    define BIO_new_fp_internal		BIO_s_file
-#  endif /* FP_API */
+# define BIO_s_file_internal	BIO_s_file
 # endif
 BIO *	BIO_new(BIO_METHOD *type);
 int	BIO_set(BIO *a,BIO_METHOD *type);
@@ -603,13 +597,8 @@
 int BIO_nwrite0(BIO *bio, char **buf);
 int BIO_nwrite(BIO *bio, char **buf, int num);
 
-#ifndef OPENSSL_SYS_WIN16
 long BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
 	long argl,long ret);
-#else
-long _far _loadds BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
-	long argl,long ret);
-#endif
 
 BIO_METHOD *BIO_s_mem(void);
 BIO *BIO_new_mem_buf(void *buf, int len);
diff --git a/include/openssl/bn.h b/include/openssl/bn.h
index f1719a5..e484b7f 100644
--- a/include/openssl/bn.h
+++ b/include/openssl/bn.h
@@ -56,6 +56,59 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
+ * Copyright (c) 1998-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
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
  *
  * Portions of the attached software ("Contribution") are developed by 
@@ -77,6 +130,7 @@
 #include <stdio.h> /* FILE */
 #endif
 #include <openssl/ossl_typ.h>
+#include <openssl/crypto.h>
 
 #ifdef  __cplusplus
 extern "C" {
@@ -94,9 +148,11 @@
 /* #define BN_DEBUG */
 /* #define BN_DEBUG_RAND */
 
+#ifndef OPENSSL_SMALL_FOOTPRINT
 #define BN_MUL_COMBA
 #define BN_SQR_COMBA
 #define BN_RECURSION
+#endif
 
 /* This next option uses the C libraries (2 word)/(1 word) function.
  * If it is not defined, I use my C version (which is slower).
@@ -137,6 +193,8 @@
 #define BN_DEC_FMT1	"%lu"
 #define BN_DEC_FMT2	"%019lu"
 #define BN_DEC_NUM	19
+#define BN_HEX_FMT1	"%lX"
+#define BN_HEX_FMT2	"%016lX"
 #endif
 
 /* This is where the long long data type is 64 bits, but long is 32.
@@ -162,83 +220,37 @@
 #define BN_DEC_FMT1	"%llu"
 #define BN_DEC_FMT2	"%019llu"
 #define BN_DEC_NUM	19
+#define BN_HEX_FMT1	"%llX"
+#define BN_HEX_FMT2	"%016llX"
 #endif
 
 #ifdef THIRTY_TWO_BIT
 #ifdef BN_LLONG
-# if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__)
+# if defined(_WIN32) && !defined(__GNUC__)
 #  define BN_ULLONG	unsigned __int64
+#  define BN_MASK	(0xffffffffffffffffI64)
 # else
 #  define BN_ULLONG	unsigned long long
+#  define BN_MASK	(0xffffffffffffffffLL)
 # endif
 #endif
-#define BN_ULONG	unsigned long
-#define BN_LONG		long
+#define BN_ULONG	unsigned int
+#define BN_LONG		int
 #define BN_BITS		64
 #define BN_BYTES	4
 #define BN_BITS2	32
 #define BN_BITS4	16
-#ifdef OPENSSL_SYS_WIN32
-/* VC++ doesn't like the LL suffix */
-#define BN_MASK		(0xffffffffffffffffL)
-#else
-#define BN_MASK		(0xffffffffffffffffLL)
-#endif
 #define BN_MASK2	(0xffffffffL)
 #define BN_MASK2l	(0xffff)
 #define BN_MASK2h1	(0xffff8000L)
 #define BN_MASK2h	(0xffff0000L)
 #define BN_TBIT		(0x80000000L)
 #define BN_DEC_CONV	(1000000000L)
-#define BN_DEC_FMT1	"%lu"
-#define BN_DEC_FMT2	"%09lu"
+#define BN_DEC_FMT1	"%u"
+#define BN_DEC_FMT2	"%09u"
 #define BN_DEC_NUM	9
-#endif
-
-#ifdef SIXTEEN_BIT
-#ifndef BN_DIV2W
-#define BN_DIV2W
-#endif
-#define BN_ULLONG	unsigned long
-#define BN_ULONG	unsigned short
-#define BN_LONG		short
-#define BN_BITS		32
-#define BN_BYTES	2
-#define BN_BITS2	16
-#define BN_BITS4	8
-#define BN_MASK		(0xffffffff)
-#define BN_MASK2	(0xffff)
-#define BN_MASK2l	(0xff)
-#define BN_MASK2h1	(0xff80)
-#define BN_MASK2h	(0xff00)
-#define BN_TBIT		(0x8000)
-#define BN_DEC_CONV	(100000)
-#define BN_DEC_FMT1	"%u"
-#define BN_DEC_FMT2	"%05u"
-#define BN_DEC_NUM	5
-#endif
-
-#ifdef EIGHT_BIT
-#ifndef BN_DIV2W
-#define BN_DIV2W
-#endif
-#define BN_ULLONG	unsigned short
-#define BN_ULONG	unsigned char
-#define BN_LONG		char
-#define BN_BITS		16
-#define BN_BYTES	1
-#define BN_BITS2	8
-#define BN_BITS4	4
-#define BN_MASK		(0xffff)
-#define BN_MASK2	(0xff)
-#define BN_MASK2l	(0xf)
-#define BN_MASK2h1	(0xf8)
-#define BN_MASK2h	(0xf0)
-#define BN_TBIT		(0x80)
-#define BN_DEC_CONV	(100)
-#define BN_DEC_FMT1	"%u"
-#define BN_DEC_FMT2	"%02u"
-#define BN_DEC_NUM	2
+#define BN_HEX_FMT1	"%X"
+#define BN_HEX_FMT2	"%08X"
 #endif
 
 #define BN_DEFAULT_BITS	1280
@@ -303,12 +315,8 @@
 	BIGNUM N;      /* The modulus */
 	BIGNUM Ni;     /* R*(1/R mod N) - N*Ni = 1
 	                * (Ni is only stored for bignum algorithm) */
-#if 0
-	/* OpenSSL 0.9.9 preview: */
-	BN_ULONG n0[2];/* least significant word(s) of Ni */
-#else
-	BN_ULONG n0;   /* least significant word of Ni */
-#endif
+	BN_ULONG n0[2];/* least significant word(s) of Ni;
+	                  (type changed with 0.9.9, was "BN_ULONG n0;" before) */
 	int flags;
 	};
 
@@ -504,6 +512,7 @@
 char *	BN_bn2dec(const BIGNUM *a);
 int 	BN_hex2bn(BIGNUM **a, const char *str);
 int 	BN_dec2bn(BIGNUM **a, const char *str);
+int	BN_asc2bn(BIGNUM **a, const char *str);
 int	BN_gcd(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx);
 int	BN_kronecker(const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx); /* returns -2 for error */
 BIGNUM *BN_mod_inverse(BIGNUM *ret,
@@ -531,17 +540,6 @@
 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,
@@ -560,19 +558,22 @@
 #define	BN_BLINDING_NO_UPDATE	0x00000001
 #define	BN_BLINDING_NO_RECREATE	0x00000002
 
-BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGNUM *mod);
+BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod);
 void BN_BLINDING_free(BN_BLINDING *b);
 int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
 int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
 int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
 int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *);
 int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *);
+#ifndef OPENSSL_NO_DEPRECATED
 unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
 void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
+#endif
+CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *);
 unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
 void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
 BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
-	const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx,
+	const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
 	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
 			  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
 	BN_MONT_CTX *m_ctx);
@@ -625,24 +626,24 @@
  *     t^p[0] + t^p[1] + ... + t^p[k]
  * where m = p[0] > p[1] > ... > p[k] = 0.
  */
-int	BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[]);
+int	BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]);
 	/* r = a mod p */
 int	BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
-	const unsigned int p[], BN_CTX *ctx); /* r = (a * b) mod p */
-int	BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[],
+	const int p[], BN_CTX *ctx); /* r = (a * b) mod p */
+int	BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[],
 	BN_CTX *ctx); /* r = (a * a) mod p */
-int	BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const unsigned int p[],
+int	BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[],
 	BN_CTX *ctx); /* r = (1 / b) mod p */
 int	BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
-	const unsigned int p[], BN_CTX *ctx); /* r = (a / b) mod p */
+	const int p[], BN_CTX *ctx); /* r = (a / b) mod p */
 int	BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
-	const unsigned int p[], BN_CTX *ctx); /* r = (a ^ b) mod p */
+	const int p[], BN_CTX *ctx); /* r = (a ^ b) mod p */
 int	BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a,
-	const unsigned int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */
+	const int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */
 int	BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a,
-	const unsigned int p[], BN_CTX *ctx); /* r^2 + r = a mod p */
-int	BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max);
-int	BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a);
+	const int p[], BN_CTX *ctx); /* r^2 + r = a mod p */
+int	BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max);
+int	BN_GF2m_arr2poly(const int p[], BIGNUM *a);
 
 /* faster mod functions for the 'NIST primes' 
  * 0 <= a < p^2 */
@@ -751,10 +752,12 @@
 #define bn_correct_top(a) \
         { \
         BN_ULONG *ftl; \
-	if ((a)->top > 0) \
+	int tmp_top = (a)->top; \
+	if (tmp_top > 0) \
 		{ \
-		for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \
-		if (*(ftl--)) break; \
+		for (ftl= &((a)->d[tmp_top-1]); tmp_top > 0; tmp_top--) \
+			if (*(ftl--)) break; \
+		(a)->top = tmp_top; \
 		} \
 	bn_pollute(a); \
 	}
diff --git a/include/openssl/buffer.h b/include/openssl/buffer.h
index 1db9607..178e418 100644
--- a/include/openssl/buffer.h
+++ b/include/openssl/buffer.h
@@ -76,18 +76,19 @@
 
 struct buf_mem_st
 	{
-	int length;	/* current number of bytes */
+	size_t length;	/* current number of bytes */
 	char *data;
-	int max;	/* size of buffer */
+	size_t max;	/* size of buffer */
 	};
 
 BUF_MEM *BUF_MEM_new(void);
 void	BUF_MEM_free(BUF_MEM *a);
-int	BUF_MEM_grow(BUF_MEM *str, int len);
-int	BUF_MEM_grow_clean(BUF_MEM *str, int len);
+int	BUF_MEM_grow(BUF_MEM *str, size_t len);
+int	BUF_MEM_grow_clean(BUF_MEM *str, size_t len);
 char *	BUF_strdup(const char *str);
 char *	BUF_strndup(const char *str, size_t siz);
 void *	BUF_memdup(const void *data, size_t siz);
+void	BUF_reverse(unsigned char *out, unsigned char *in, size_t siz);
 
 /* safe string functions */
 size_t BUF_strlcpy(char *dst,const char *src,size_t siz);
diff --git a/include/openssl/conf.h b/include/openssl/conf.h
index 8aa06bc..c219997 100644
--- a/include/openssl/conf.h
+++ b/include/openssl/conf.h
@@ -79,8 +79,7 @@
 	} CONF_VALUE;
 
 DECLARE_STACK_OF(CONF_VALUE)
-DECLARE_STACK_OF(CONF_MODULE)
-DECLARE_STACK_OF(CONF_IMODULE)
+DECLARE_LHASH_OF(CONF_VALUE);
 
 struct conf_st;
 struct conf_method_st;
@@ -105,6 +104,9 @@
 typedef struct conf_imodule_st CONF_IMODULE;
 typedef struct conf_module_st CONF_MODULE;
 
+DECLARE_STACK_OF(CONF_MODULE)
+DECLARE_STACK_OF(CONF_IMODULE)
+
 /* DSO module function typedefs */
 typedef int conf_init_func(CONF_IMODULE *md, const CONF *cnf);
 typedef void conf_finish_func(CONF_IMODULE *md);
@@ -117,18 +119,23 @@
 #define CONF_MFLAGS_DEFAULT_SECTION	0x20
 
 int CONF_set_default_method(CONF_METHOD *meth);
-void CONF_set_nconf(CONF *conf,LHASH *hash);
-LHASH *CONF_load(LHASH *conf,const char *file,long *eline);
+void CONF_set_nconf(CONF *conf,LHASH_OF(CONF_VALUE) *hash);
+LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf,const char *file,
+				long *eline);
 #ifndef OPENSSL_NO_FP_API
-LHASH *CONF_load_fp(LHASH *conf, FILE *fp,long *eline);
+LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
+				   long *eline);
 #endif
-LHASH *CONF_load_bio(LHASH *conf, BIO *bp,long *eline);
-STACK_OF(CONF_VALUE) *CONF_get_section(LHASH *conf,const char *section);
-char *CONF_get_string(LHASH *conf,const char *group,const char *name);
-long CONF_get_number(LHASH *conf,const char *group,const char *name);
-void CONF_free(LHASH *conf);
-int CONF_dump_fp(LHASH *conf, FILE *out);
-int CONF_dump_bio(LHASH *conf, BIO *out);
+LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,long *eline);
+STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
+				       const char *section);
+char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf,const char *group,
+		      const char *name);
+long CONF_get_number(LHASH_OF(CONF_VALUE) *conf,const char *group,
+		     const char *name);
+void CONF_free(LHASH_OF(CONF_VALUE) *conf);
+int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out);
+int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out);
 
 void OPENSSL_config(const char *config_name);
 void OPENSSL_no_config(void);
@@ -140,7 +147,7 @@
 	{
 	CONF_METHOD *meth;
 	void *meth_data;
-	LHASH *data;
+	LHASH_OF(CONF_VALUE) *data;
 	};
 
 CONF *NCONF_new(CONF_METHOD *meth);
@@ -214,6 +221,7 @@
 #define CONF_F_CONF_LOAD_BIO				 102
 #define CONF_F_CONF_LOAD_FP				 103
 #define CONF_F_CONF_MODULES_LOAD			 116
+#define CONF_F_CONF_PARSE_LIST				 119
 #define CONF_F_DEF_LOAD					 120
 #define CONF_F_DEF_LOAD_BIO				 121
 #define CONF_F_MODULE_INIT				 115
@@ -233,6 +241,7 @@
 
 /* Reason codes. */
 #define CONF_R_ERROR_LOADING_DSO			 110
+#define CONF_R_LIST_CANNOT_BE_NULL			 115
 #define CONF_R_MISSING_CLOSE_SQUARE_BRACKET		 100
 #define CONF_R_MISSING_EQUAL_SIGN			 101
 #define CONF_R_MISSING_FINISH_FUNCTION			 111
diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h
index 0e4fb07..b0360ce 100644
--- a/include/openssl/crypto.h
+++ b/include/openssl/crypto.h
@@ -1,6 +1,6 @@
 /* crypto/crypto.h */
 /* ====================================================================
- * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -219,13 +219,9 @@
 #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
@@ -288,9 +284,10 @@
 
 struct crypto_ex_data_st
 	{
-	STACK *sk;
+	STACK_OF(void) *sk;
 	int dummy; /* gcc is screwing up this data structure :-( */
 	};
+DECLARE_STACK_OF(void)
 
 /* This stuff is basically class callback functions
  * The current classes are SSL_CTX, SSL, SSL_SESSION, and a few more */
@@ -347,7 +344,14 @@
 
 /* Set standard debugging functions (not done by default
  * unless CRYPTO_MDEBUG is defined) */
-void CRYPTO_malloc_debug_init(void);
+#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)
 
 int CRYPTO_mem_ctrl(int mode);
 int CRYPTO_is_mem_check_on(void);
@@ -420,16 +424,32 @@
 					      const char *file, int line));
 int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
 					  const char *file,int line);
+
+/* Don't use this structure directly. */
+typedef struct crypto_threadid_st
+	{
+	void *ptr;
+	unsigned long val;
+	} CRYPTO_THREADID;
+/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */
+void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val);
+void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
+int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *));
+void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *);
+void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
+int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b);
+void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src);
+unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id);
+#ifndef OPENSSL_NO_DEPRECATED
 void CRYPTO_set_id_callback(unsigned long (*func)(void));
 unsigned long (*CRYPTO_get_id_callback(void))(void);
 unsigned long CRYPTO_thread_id(void);
+#endif
+
 const char *CRYPTO_get_lock_name(int type);
 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);
@@ -454,10 +474,6 @@
 				   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),
@@ -514,9 +530,6 @@
 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 *);
@@ -534,69 +547,12 @@
 #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
  * made after this point may be overwritten when the script is next run.
  */
 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 10475ac..849309a 100644
--- a/include/openssl/dh.h
+++ b/include/openssl/dh.h
@@ -77,8 +77,6 @@
 # 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
@@ -159,7 +157,6 @@
    this for backward compatibility: */
 #define DH_CHECK_P_NOT_STRONG_PRIME	DH_CHECK_P_NOT_SAFE_PRIME
 
-#define DHparams_dup(x) ASN1_dup_of_const(DH,i2d_DHparams,d2i_DHparams,x)
 #define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
 		(char *(*)())d2i_DHparams,(fp),(unsigned char **)(x))
 #define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \
@@ -167,12 +164,9 @@
 #define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x)
 #define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x)
 
-const DH_METHOD *DH_OpenSSL(void);
+DH *DHparams_dup(DH *);
 
-#ifdef OPENSSL_FIPS
-DH *	FIPS_dh_new(void);
-void	FIPS_dh_free(DH *dh);
-#endif
+const DH_METHOD *DH_OpenSSL(void);
 
 void DH_set_default_method(const DH_METHOD *meth);
 const DH_METHOD *DH_get_default_method(void);
@@ -212,6 +206,18 @@
 int	DHparams_print(char *bp, const DH *x);
 #endif
 
+#define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+			EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL)
+
+#define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+			EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL)
+
+#define	EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN	(EVP_PKEY_ALG_CTRL + 1)
+#define	EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR	(EVP_PKEY_ALG_CTRL + 2)
+		
+
 /* 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.
@@ -222,22 +228,31 @@
 
 /* Function codes. */
 #define DH_F_COMPUTE_KEY				 102
-#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_DH_PARAM_DECODE				 107
+#define DH_F_DH_PRIV_DECODE				 110
+#define DH_F_DH_PRIV_ENCODE				 111
+#define DH_F_DH_PUB_DECODE				 108
+#define DH_F_DH_PUB_ENCODE				 109
+#define DH_F_DO_DH_PRINT				 100
 #define DH_F_GENERATE_KEY				 103
 #define DH_F_GENERATE_PARAMETERS			 104
+#define DH_F_PKEY_DH_DERIVE				 112
+#define DH_F_PKEY_DH_KEYGEN				 113
 
 /* Reason codes. */
 #define DH_R_BAD_GENERATOR				 101
+#define DH_R_BN_DECODE_ERROR				 109
+#define DH_R_BN_ERROR					 106
+#define DH_R_DECODE_ERROR				 104
 #define DH_R_INVALID_PUBKEY				 102
-#define DH_R_KEY_SIZE_TOO_SMALL				 104
+#define DH_R_KEYS_NOT_SET				 108
 #define DH_R_MODULUS_TOO_LARGE				 103
+#define DH_R_NO_PARAMETERS_SET				 107
 #define DH_R_NO_PRIVATE_VALUE				 100
+#define DH_R_PARAMETER_ENCODING_ERROR			 105
 
 #ifdef  __cplusplus
 }
diff --git a/include/openssl/dsa.h b/include/openssl/dsa.h
index 702c50d..ac50a5c 100644
--- a/include/openssl/dsa.h
+++ b/include/openssl/dsa.h
@@ -88,8 +88,6 @@
 # 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
@@ -99,25 +97,6 @@
                                               * 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
@@ -139,7 +118,7 @@
 	int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
 								BIGNUM **rp);
 	int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len,
-							DSA_SIG *sig, DSA *dsa);
+			     DSA_SIG *sig, DSA *dsa);
 	int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
 			BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
 			BN_MONT_CTX *in_mont);
@@ -152,7 +131,7 @@
 	char *app_data;
 	/* If this is non-NULL, it is used to generate DSA parameters */
 	int (*dsa_paramgen)(DSA *dsa, int bits,
-			unsigned char *seed, int seed_len,
+			const unsigned char *seed, int seed_len,
 			int *counter_ret, unsigned long *h_ret,
 			BN_GENCB *cb);
 	/* If this is non-NULL, it is used to generate DSA keys */
@@ -186,7 +165,6 @@
 	ENGINE *engine;
 	};
 
-#define DSAparams_dup(x) ASN1_dup_of_const(DSA,i2d_DSAparams,d2i_DSAparams,x)
 #define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \
 		(char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x))
 #define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \
@@ -195,6 +173,7 @@
 #define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x)
 
 
+DSA *DSAparams_dup(DSA *x);
 DSA_SIG * DSA_SIG_new(void);
 void	DSA_SIG_free(DSA_SIG *a);
 int	i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp);
@@ -210,11 +189,6 @@
 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);
@@ -246,7 +220,7 @@
 
 /* New version */
 int	DSA_generate_parameters_ex(DSA *dsa, int bits,
-		unsigned char *seed,int seed_len,
+		const unsigned char *seed,int seed_len,
 		int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
 
 int	DSA_generate_key(DSA *a);
@@ -275,10 +249,13 @@
 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
+#define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \
+				EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL)
+
+#define	EVP_PKEY_CTRL_DSA_PARAMGEN_BITS		(EVP_PKEY_ALG_CTRL + 1)
+#define	EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS	(EVP_PKEY_ALG_CTRL + 2)
+#define	EVP_PKEY_CTRL_DSA_PARAMGEN_MD		(EVP_PKEY_ALG_CTRL + 3)
 
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -290,33 +267,39 @@
 
 /* Function codes. */
 #define DSA_F_D2I_DSA_SIG				 110
+#define DSA_F_DO_DSA_PRINT				 104
 #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_PARAM_DECODE				 119
 #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_PRIV_DECODE				 115
+#define DSA_F_DSA_PRIV_ENCODE				 116
+#define DSA_F_DSA_PUB_DECODE				 117
+#define DSA_F_DSA_PUB_ENCODE				 118
 #define DSA_F_DSA_SIGN					 106
 #define DSA_F_DSA_SIGN_SETUP				 107
 #define DSA_F_DSA_SIG_NEW				 109
 #define DSA_F_DSA_VERIFY				 108
 #define DSA_F_I2D_DSA_SIG				 111
+#define DSA_F_OLD_DSA_PRIV_DECODE			 122
+#define DSA_F_PKEY_DSA_CTRL				 120
+#define DSA_F_PKEY_DSA_KEYGEN				 121
 #define DSA_F_SIG_CB					 114
 
 /* Reason codes. */
 #define DSA_R_BAD_Q_VALUE				 102
+#define DSA_R_BN_DECODE_ERROR				 108
+#define DSA_R_BN_ERROR					 109
 #define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE		 100
-#define DSA_R_KEY_SIZE_TOO_SMALL			 106
+#define DSA_R_DECODE_ERROR				 104
+#define DSA_R_INVALID_DIGEST_TYPE			 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
+#define DSA_R_NO_PARAMETERS_SET				 107
+#define DSA_R_PARAMETER_ENCODING_ERROR			 105
 
 #ifdef  __cplusplus
 }
diff --git a/include/openssl/dso.h b/include/openssl/dso.h
index 3e51913..839f2e0 100644
--- a/include/openssl/dso.h
+++ b/include/openssl/dso.h
@@ -170,6 +170,11 @@
 	/* [De]Initialisation handlers. */
 	int (*init)(DSO *dso);
 	int (*finish)(DSO *dso);
+
+	/* Return pathname of the module containing location */
+	int (*pathbyaddr)(void *addr,char *path,int sz);
+	/* Perform global symbol lookup, i.e. among *all* modules */
+	void *(*globallookup)(const char *symname);
 	} DSO_METHOD;
 
 /**********************************************************************/
@@ -183,7 +188,7 @@
 	 * for use in the dso_bind handler. All in all, let each
 	 * method control its own destiny. "Handles" and such go in
 	 * a STACK. */
-	STACK *meth_data;
+	STACK_OF(void) *meth_data;
 	int references;
 	int flags;
 	/* For use by applications etc ... use this for your bits'n'pieces,
@@ -296,6 +301,30 @@
 /* If VMS is defined, use shared images. If not, return NULL. */
 DSO_METHOD *DSO_METHOD_vms(void);
 
+/* This function writes null-terminated pathname of DSO module
+ * containing 'addr' into 'sz' large caller-provided 'path' and
+ * returns the number of characters [including trailing zero]
+ * written to it. If 'sz' is 0 or negative, 'path' is ignored and
+ * required amount of charachers [including trailing zero] to
+ * accomodate pathname is returned. If 'addr' is NULL, then
+ * pathname of cryptolib itself is returned. Negative or zero
+ * return value denotes error.
+ */
+int DSO_pathbyaddr(void *addr,char *path,int sz);
+
+/* This function should be used with caution! It looks up symbols in
+ * *all* loaded modules and if module gets unloaded by somebody else
+ * attempt to dereference the pointer is doomed to have fatal
+ * consequences. Primary usage for this function is to probe *core*
+ * system functionality, e.g. check if getnameinfo(3) is available
+ * at run-time without bothering about OS-specific details such as
+ * libc.so.versioning or where does it actually reside: in libc
+ * itself or libsocket. */
+void *DSO_global_lookup(const char *name);
+
+/* If BeOS is defined, use shared images. If not, return NULL. */
+DSO_METHOD *DSO_METHOD_beos(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.
@@ -305,6 +334,11 @@
 /* Error codes for the DSO functions. */
 
 /* Function codes. */
+#define DSO_F_BEOS_BIND_FUNC				 144
+#define DSO_F_BEOS_BIND_VAR				 145
+#define DSO_F_BEOS_LOAD					 146
+#define DSO_F_BEOS_NAME_CONVERTER			 147
+#define DSO_F_BEOS_UNLOAD				 148
 #define DSO_F_DLFCN_BIND_FUNC				 100
 #define DSO_F_DLFCN_BIND_VAR				 101
 #define DSO_F_DLFCN_LOAD				 102
@@ -324,22 +358,29 @@
 #define DSO_F_DSO_FREE					 111
 #define DSO_F_DSO_GET_FILENAME				 127
 #define DSO_F_DSO_GET_LOADED_FILENAME			 128
+#define DSO_F_DSO_GLOBAL_LOOKUP				 139
 #define DSO_F_DSO_LOAD					 112
 #define DSO_F_DSO_MERGE					 132
 #define DSO_F_DSO_NEW_METHOD				 113
+#define DSO_F_DSO_PATHBYADDR				 140
 #define DSO_F_DSO_SET_FILENAME				 129
 #define DSO_F_DSO_SET_NAME_CONVERTER			 122
 #define DSO_F_DSO_UP_REF				 114
+#define DSO_F_GLOBAL_LOOKUP_FUNC			 138
+#define DSO_F_PATHBYADDR				 137
 #define DSO_F_VMS_BIND_SYM				 115
 #define DSO_F_VMS_LOAD					 116
 #define DSO_F_VMS_MERGER				 133
 #define DSO_F_VMS_UNLOAD				 117
 #define DSO_F_WIN32_BIND_FUNC				 118
 #define DSO_F_WIN32_BIND_VAR				 119
+#define DSO_F_WIN32_GLOBALLOOKUP			 142
+#define DSO_F_WIN32_GLOBALLOOKUP_FUNC			 143
 #define DSO_F_WIN32_JOINER				 135
 #define DSO_F_WIN32_LOAD				 120
 #define DSO_F_WIN32_MERGER				 134
 #define DSO_F_WIN32_NAME_CONVERTER			 125
+#define DSO_F_WIN32_PATHBYADDR				 141
 #define DSO_F_WIN32_SPLITTER				 136
 #define DSO_F_WIN32_UNLOAD				 121
 
diff --git a/include/openssl/dtls1.h b/include/openssl/dtls1.h
index a8ce51a..af363a9 100644
--- a/include/openssl/dtls1.h
+++ b/include/openssl/dtls1.h
@@ -108,15 +108,17 @@
 
 typedef struct dtls1_bitmap_st
 	{
-	PQ_64BIT map;
-	unsigned long length;     /* sizeof the bitmap in bits */
-	PQ_64BIT max_seq_num;  /* max record number seen so far */
+	unsigned long map;		/* track 32 packets on 32-bit systems
+					   and 64 - on 64-bit systems */
+	unsigned char max_seq_num[8];	/* max record number seen so far,
+					   64-bit value in big-endian
+					   encoding */
 	} DTLS1_BITMAP;
 
 struct dtls1_retransmit_state
 	{
 	EVP_CIPHER_CTX *enc_write_ctx;	/* cryptographic state */
-	const EVP_MD *write_hash;		/* used for mac generation */
+	EVP_MD_CTX *write_hash;			/* used for mac generation */
 #ifndef OPENSSL_NO_COMP
 	COMP_CTX *compress;				/* compression */
 #else
diff --git a/include/openssl/e_os2.h b/include/openssl/e_os2.h
index 9da0b65..4c785c6 100644
--- a/include/openssl/e_os2.h
+++ b/include/openssl/e_os2.h
@@ -202,6 +202,17 @@
 # define OPENSSL_SYS_VXWORKS
 #endif
 
+/* --------------------------------- BeOS ---------------------------------- */
+#if defined(__BEOS__)
+# define OPENSSL_SYS_BEOS
+# include <sys/socket.h>
+# if defined(BONE_VERSION)
+#  define OPENSSL_SYS_BEOS_BONE
+# else
+#  define OPENSSL_SYS_BEOS_R5
+# endif
+#endif
+
 /**
  * That's it for OS-specific stuff
  *****************************************************************************/
@@ -251,24 +262,23 @@
 #define OPENSSL_EXTERN OPENSSL_IMPORT
 
 /* Macros to allow global variables to be reached through function calls when
-   required (if a shared library version requvres it, for example.
+   required (if a shared library version requires it, for example.
    The way it's done allows definitions like this:
 
 	// in foobar.c
-	OPENSSL_IMPLEMENT_GLOBAL(int,foobar) = 0;
+	OPENSSL_IMPLEMENT_GLOBAL(int,foobar,0)
 	// in foobar.h
 	OPENSSL_DECLARE_GLOBAL(int,foobar);
 	#define foobar OPENSSL_GLOBAL_REF(foobar)
 */
 #ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION
-# define OPENSSL_IMPLEMENT_GLOBAL(type,name)			     \
-	extern type _hide_##name;				     \
-	type *_shadow_##name(void) { return &_hide_##name; }	     \
-	static type _hide_##name
+# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value)			\
+	type *_shadow_##name(void)					\
+	{ static type _hide_##name=value; return &_hide_##name; }
 # define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void)
 # define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name()))
 #else
-# define OPENSSL_IMPLEMENT_GLOBAL(type,name) OPENSSL_GLOBAL type _shadow_##name
+# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) OPENSSL_GLOBAL type _shadow_##name=value;
 # define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name
 # define OPENSSL_GLOBAL_REF(name) _shadow_##name
 #endif
diff --git a/include/openssl/ec.h b/include/openssl/ec.h
index 8bc2a23..ee70781 100644
--- a/include/openssl/ec.h
+++ b/include/openssl/ec.h
@@ -2,8 +2,12 @@
 /*
  * Originally written by Bodo Moeller for the OpenSSL project.
  */
+/**
+ * \file crypto/ec/ec.h Include file for the OpenSSL EC functions
+ * \author Originally written by Bodo Moeller for the OpenSSL project
+ */
 /* ====================================================================
- * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -92,15 +96,21 @@
 # endif
 #endif
 
-
+  
 #ifndef OPENSSL_ECC_MAX_FIELD_BITS
 # define OPENSSL_ECC_MAX_FIELD_BITS 661
 #endif
 
+/** Enum for the point conversion form as defined in X9.62 (ECDSA)
+ *  for the encoding of a elliptic curve point (x,y) */
 typedef enum {
-	/* values as defined in X9.62 (ECDSA) and elsewhere */
+	/** the point is encoded as z||x, where the octet z specifies 
+	 *  which solution of the quadratic equation y is  */
 	POINT_CONVERSION_COMPRESSED = 2,
+	/** the point is encoded as z||x||y, where z is the octet 0x02  */
 	POINT_CONVERSION_UNCOMPRESSED = 4,
+	/** the point is encoded as z||x||y, where the octet z specifies
+         *  which solution of the quadratic equation y is  */
 	POINT_CONVERSION_HYBRID = 6
 } point_conversion_form_t;
 
@@ -121,37 +131,129 @@
 typedef struct ec_point_st EC_POINT;
 
 
-/* EC_METHODs for curves over GF(p).
- * EC_GFp_simple_method provides the basis for the optimized methods.
+/********************************************************************/
+/*               EC_METHODs for curves over GF(p)                   */       
+/********************************************************************/
+
+/** Returns the basic GFp ec methods which provides the basis for the
+ *  optimized methods. 
+ *  \return  EC_METHOD object
  */
 const EC_METHOD *EC_GFp_simple_method(void);
+
+/** Returns GFp methods using montgomery multiplication.
+ *  \return  EC_METHOD object
+ */
 const EC_METHOD *EC_GFp_mont_method(void);
+
+/** Returns GFp methods using optimized methods for NIST recommended curves
+ *  \return  EC_METHOD object
+ */
 const EC_METHOD *EC_GFp_nist_method(void);
 
-/* EC_METHOD for curves over GF(2^m).
+
+/********************************************************************/ 
+/*           EC_METHOD for curves over GF(2^m)                      */
+/********************************************************************/
+
+/** Returns the basic GF2m ec method 
+ *  \return  EC_METHOD object
  */
 const EC_METHOD *EC_GF2m_simple_method(void);
 
 
-EC_GROUP *EC_GROUP_new(const EC_METHOD *);
-void EC_GROUP_free(EC_GROUP *);
-void EC_GROUP_clear_free(EC_GROUP *);
-int EC_GROUP_copy(EC_GROUP *, const EC_GROUP *);
-EC_GROUP *EC_GROUP_dup(const EC_GROUP *);
+/********************************************************************/
+/*                   EC_GROUP functions                             */
+/********************************************************************/
 
-const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *);
-int EC_METHOD_get_field_type(const EC_METHOD *);
+/** Creates a new EC_GROUP object
+ *  \param   meth  EC_METHOD to use
+ *  \return  newly created EC_GROUP object or NULL in case of an error.
+ */
+EC_GROUP *EC_GROUP_new(const EC_METHOD *meth);
 
-int EC_GROUP_set_generator(EC_GROUP *, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor);
-const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *);
-int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *);
-int EC_GROUP_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *);
+/** Frees a EC_GROUP object
+ *  \param  group  EC_GROUP object to be freed.
+ */
+void EC_GROUP_free(EC_GROUP *group);
 
-void EC_GROUP_set_curve_name(EC_GROUP *, int nid);
-int EC_GROUP_get_curve_name(const EC_GROUP *);
+/** Clears and frees a EC_GROUP object
+ *  \param  group  EC_GROUP object to be cleared and freed.
+ */
+void EC_GROUP_clear_free(EC_GROUP *group);
 
-void EC_GROUP_set_asn1_flag(EC_GROUP *, int flag);
-int EC_GROUP_get_asn1_flag(const EC_GROUP *);
+/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD.
+ *  \param  dst  destination EC_GROUP object
+ *  \param  src  source EC_GROUP object
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src);
+
+/** Creates a new EC_GROUP object and copies the copies the content
+ *  form src to the newly created EC_KEY object
+ *  \param  src  source EC_GROUP object
+ *  \return newly created EC_GROUP object or NULL in case of an error.
+ */
+EC_GROUP *EC_GROUP_dup(const EC_GROUP *src);
+
+/** Returns the EC_METHOD of the EC_GROUP object.
+ *  \param  group  EC_GROUP object 
+ *  \return EC_METHOD used in this EC_GROUP object.
+ */
+const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group);
+
+/** Returns the field type of the EC_METHOD.
+ *  \param  meth  EC_METHOD object
+ *  \return NID of the underlying field type OID.
+ */
+int EC_METHOD_get_field_type(const EC_METHOD *meth);
+
+/** Sets the generator and it's order/cofactor of a EC_GROUP object.
+ *  \param  group      EC_GROUP object 
+ *  \param  generator  EC_POINT object with the generator.
+ *  \param  order      the order of the group generated by the generator.
+ *  \param  cofactor   the index of the sub-group generated by the generator
+ *                     in the group of all points on the elliptic curve.
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor);
+
+/** Returns the generator of a EC_GROUP object.
+ *  \param  group  EC_GROUP object
+ *  \return the currently used generator (possibly NULL).
+ */
+const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);
+
+/** Gets the order of a EC_GROUP
+ *  \param  group  EC_GROUP object
+ *  \param  order  BIGNUM to which the order is copied
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx);
+
+/** Gets the cofactor of a EC_GROUP
+ *  \param  group     EC_GROUP object
+ *  \param  cofactor  BIGNUM to which the cofactor is copied
+ *  \param  ctx       BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx);
+
+/** Sets the name of a EC_GROUP object
+ *  \param  group  EC_GROUP object
+ *  \param  nid    NID of the curve name OID
+ */
+void EC_GROUP_set_curve_name(EC_GROUP *group, int nid);
+
+/** Returns the curve name of a EC_GROUP object
+ *  \param  group  EC_GROUP object
+ *  \return NID of the curve name OID or 0 if not set.
+ */
+int EC_GROUP_get_curve_name(const EC_GROUP *group);
+
+void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
+int EC_GROUP_get_asn1_flag(const EC_GROUP *group);
 
 void EC_GROUP_set_point_conversion_form(EC_GROUP *, point_conversion_form_t);
 point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
@@ -160,36 +262,114 @@
 size_t EC_GROUP_get_seed_len(const EC_GROUP *);
 size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
 
-int EC_GROUP_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
-int EC_GROUP_get_curve_GFp(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
-int EC_GROUP_set_curve_GF2m(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
-int EC_GROUP_get_curve_GF2m(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
+/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM with the prime number
+ *  \param  a      BIGNUM with parameter a of the equation
+ *  \param  b      BIGNUM with parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
 
-/* returns the number of bits needed to represent a field element */
-int EC_GROUP_get_degree(const EC_GROUP *);
+/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM for the prime number
+ *  \param  a      BIGNUM for parameter a of the equation
+ *  \param  b      BIGNUM for parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
 
-/* EC_GROUP_check() returns 1 if 'group' defines a valid group, 0 otherwise */
+/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM with the polynomial defining the underlying field
+ *  \param  a      BIGNUM with parameter a of the equation
+ *  \param  b      BIGNUM with parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+
+/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM for the polynomial defining the underlying field
+ *  \param  a      BIGNUM for parameter a of the equation
+ *  \param  b      BIGNUM for parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
+
+/** Returns the number of bits needed to represent a field element 
+ *  \param  group  EC_GROUP object
+ *  \return number of bits needed to represent a field element
+ */
+int EC_GROUP_get_degree(const EC_GROUP *group);
+
+/** Checks whether the parameter in the EC_GROUP define a valid ec group
+ *  \param  group  EC_GROUP object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 if group is a valid ec group and 0 otherwise
+ */
 int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
-/* EC_GROUP_check_discriminant() returns 1 if the discriminant of the
- * elliptic curve is not zero, 0 otherwise */
-int EC_GROUP_check_discriminant(const EC_GROUP *, BN_CTX *);
 
-/* EC_GROUP_cmp() returns 0 if both groups are equal and 1 otherwise */
-int EC_GROUP_cmp(const EC_GROUP *, const EC_GROUP *, BN_CTX *);
+/** Checks whether the discriminant of the elliptic curve is zero or not
+ *  \param  group  EC_GROUP object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 if the discriminant is not zero and 0 otherwise
+ */
+int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx);
+
+/** Compares two EC_GROUP objects
+ *  \param  a    first EC_GROUP object
+ *  \param  b    second EC_GROUP object
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return 0 if both groups are equal and 1 otherwise
+ */
+int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx);
 
 /* EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*()
  * after choosing an appropriate EC_METHOD */
-EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
-EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
 
-/* EC_GROUP_new_by_curve_name() creates a EC_GROUP structure
- * specified by a curve name (in form of a NID) */
+/** Creates a new EC_GROUP object with the specified parameters defined
+ *  over GFp (defined by the equation y^2 = x^3 + a*x + b)
+ *  \param  p    BIGNUM with the prime number
+ *  \param  a    BIGNUM with the parameter a of the equation
+ *  \param  b    BIGNUM with the parameter b of the equation
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return newly created EC_GROUP object with the specified parameters
+ */
+EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+
+/** Creates a new EC_GROUP object with the specified parameters defined
+ *  over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b)
+ *  \param  p    BIGNUM with the polynomial defining the underlying field
+ *  \param  a    BIGNUM with the parameter a of the equation
+ *  \param  b    BIGNUM with the parameter b of the equation
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return newly created EC_GROUP object with the specified parameters
+ */
+EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+
+/** Creates a EC_GROUP object with a curve specified by a NID
+ *  \param  nid  NID of the OID of the curve name
+ *  \return newly created EC_GROUP object with specified curve or NULL
+ *          if an error occurred
+ */
 EC_GROUP *EC_GROUP_new_by_curve_name(int nid);
-/* handling of internal curves */
+
+
+/********************************************************************/
+/*               handling of internal curves                        */
+/********************************************************************/
+
 typedef struct { 
 	int nid;
 	const char *comment;
 	} EC_builtin_curve;
+
 /* EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number 
  * of all available curves or zero if a error occurred. 
  * In case r ist not zero nitems EC_builtin_curve structures 
@@ -197,39 +377,168 @@
 size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);
 
 
-/* EC_POINT functions */
+/********************************************************************/
+/*                    EC_POINT functions                            */
+/********************************************************************/
 
-EC_POINT *EC_POINT_new(const EC_GROUP *);
-void EC_POINT_free(EC_POINT *);
-void EC_POINT_clear_free(EC_POINT *);
-int EC_POINT_copy(EC_POINT *, const EC_POINT *);
-EC_POINT *EC_POINT_dup(const EC_POINT *, const EC_GROUP *);
+/** Creates a new EC_POINT object for the specified EC_GROUP
+ *  \param  group  EC_GROUP the underlying EC_GROUP object
+ *  \return newly created EC_POINT object or NULL if an error occurred
+ */
+EC_POINT *EC_POINT_new(const EC_GROUP *group);
+
+/** Frees a EC_POINT object
+ *  \param  point  EC_POINT object to be freed
+ */
+void EC_POINT_free(EC_POINT *point);
+
+/** Clears and frees a EC_POINT object
+ *  \param  point  EC_POINT object to be cleared and freed
+ */
+void EC_POINT_clear_free(EC_POINT *point);
+
+/** Copies EC_POINT object
+ *  \param  dst  destination EC_POINT object
+ *  \param  src  source EC_POINT object
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src);
+
+/** Creates a new EC_POINT object and copies the content of the supplied
+ *  EC_POINT
+ *  \param  src    source EC_POINT object
+ *  \param  group  underlying the EC_GROUP object
+ *  \return newly created EC_POINT object or NULL if an error occurred 
+ */
+EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group);
  
-const EC_METHOD *EC_POINT_method_of(const EC_POINT *);
+/** Returns the EC_METHOD used in EC_POINT object 
+ *  \param  point  EC_POINT object
+ *  \return the EC_METHOD used
+ */
+const EC_METHOD *EC_POINT_method_of(const EC_POINT *point);
 
-int EC_POINT_set_to_infinity(const EC_GROUP *, EC_POINT *);
-int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *,
-	const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
-int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
-	BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
-int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *, EC_POINT *,
-	const BIGNUM *x, const BIGNUM *y, BN_CTX *);
-int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
-	BIGNUM *x, BIGNUM *y, BN_CTX *);
-int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *, EC_POINT *,
-	const BIGNUM *x, int y_bit, BN_CTX *);
+/** Sets a point to infinity (neutral element)
+ *  \param  group  underlying EC_GROUP object
+ *  \param  point  EC_POINT to set to infinity
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point);
 
-int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *, EC_POINT *,
-	const BIGNUM *x, const BIGNUM *y, BN_CTX *);
-int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *, const EC_POINT *,
-	BIGNUM *x, BIGNUM *y, BN_CTX *);
-int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *, EC_POINT *,
-	const BIGNUM *x, int y_bit, BN_CTX *);
+/** Sets the jacobian projective coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with the x-coordinate
+ *  \param  y      BIGNUM with the y-coordinate
+ *  \param  z      BIGNUM with the z-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
+	const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx);
 
-size_t EC_POINT_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
-        unsigned char *buf, size_t len, BN_CTX *);
-int EC_POINT_oct2point(const EC_GROUP *, EC_POINT *,
-        const unsigned char *buf, size_t len, BN_CTX *);
+/** Gets the jacobian projective coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM for the x-coordinate
+ *  \param  y      BIGNUM for the y-coordinate
+ *  \param  z      BIGNUM for the z-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
+	const EC_POINT *p, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx);
+
+/** Sets the affine coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with the x-coordinate
+ *  \param  y      BIGNUM with the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
+	const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
+
+/** Gets the affine coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM for the x-coordinate
+ *  \param  y      BIGNUM for the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
+	const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
+
+/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with x-coordinate
+ *  \param  y_bit  integer with the y-Bit (either 0 or 1)
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
+	const BIGNUM *x, int y_bit, BN_CTX *ctx);
+
+/** Sets the affine coordinates of a EC_POINT over GF2m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with the x-coordinate
+ *  \param  y      BIGNUM with the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
+	const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
+
+/** Gets the affine coordinates of a EC_POINT over GF2m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM for the x-coordinate
+ *  \param  y      BIGNUM for the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
+	const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
+
+/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with x-coordinate
+ *  \param  y_bit  integer with the y-Bit (either 0 or 1)
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
+	const BIGNUM *x, int y_bit, BN_CTX *ctx);
+
+/** Encodes a EC_POINT object to a octet string
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  form   point conversion form
+ *  \param  buf    memory buffer for the result. If NULL the function returns
+ *                 required buffer size.
+ *  \param  len    length of the memory buffer
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return the length of the encoded octet string or 0 if an error occurred
+ */
+size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p,
+	point_conversion_form_t form,
+        unsigned char *buf, size_t len, BN_CTX *ctx);
+
+/** Decodes a EC_POINT from a octet string
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  buf    memory buffer with the encoded ec point
+ *  \param  len    length of the encoded ec point
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p,
+        const unsigned char *buf, size_t len, BN_CTX *ctx);
 
 /* other interfaces to point2oct/oct2point: */
 BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
@@ -241,29 +550,105 @@
 EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *,
 	EC_POINT *, BN_CTX *);
 
-int EC_POINT_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
-int EC_POINT_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
-int EC_POINT_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
 
-int EC_POINT_is_at_infinity(const EC_GROUP *, const EC_POINT *);
-int EC_POINT_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
-int EC_POINT_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
+/********************************************************************/
+/*         functions for doing EC_POINT arithmetic                  */
+/********************************************************************/
+
+/** Computes the sum of two EC_POINT 
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result (r = a + b)
+ *  \param  a      EC_POINT object with the first summand
+ *  \param  b      EC_POINT object with the second summand
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
+
+/** Computes the double of a EC_POINT
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result (r = 2 * a)
+ *  \param  a      EC_POINT object 
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx);
+
+/** Computes the inverse of a EC_POINT
+ *  \param  group  underlying EC_GROUP object
+ *  \param  a      EC_POINT object to be inverted (it's used for the result as well)
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx);
+
+/** Checks whether the point is the neutral element of the group
+ *  \param  group  the underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \return 1 if the point is the neutral element and 0 otherwise
+ */
+int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p);
+
+/** Checks whether the point is on the curve 
+ *  \param  group  underlying EC_GROUP object
+ *  \param  point  EC_POINT object to check
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 if point if on the curve and 0 otherwise
+ */
+int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx);
+
+/** Compares two EC_POINTs 
+ *  \param  group  underlying EC_GROUP object
+ *  \param  a      first EC_POINT object
+ *  \param  b      second EC_POINT object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 0 if both points are equal and a value != 0 otherwise
+ */
+int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
 
 int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
 int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
 
+/** Computes r = generator * n sum_{i=0}^num p[i] * m[i]
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result
+ *  \param  n      BIGNUM with the multiplier for the group generator (optional)
+ *  \param  num    number futher summands
+ *  \param  p      array of size num of EC_POINT objects
+ *  \param  m      array of size num of BIGNUM objects
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, size_t num, const EC_POINT *p[], const BIGNUM *m[], BN_CTX *ctx);
 
-int EC_POINTs_mul(const EC_GROUP *, EC_POINT *r, const BIGNUM *, size_t num, const EC_POINT *[], const BIGNUM *[], BN_CTX *);
-int EC_POINT_mul(const EC_GROUP *, EC_POINT *r, const BIGNUM *, const EC_POINT *, const BIGNUM *, BN_CTX *);
+/** Computes r = generator * n + q * m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result
+ *  \param  n      BIGNUM with the multiplier for the group generator (optional)
+ *  \param  q      EC_POINT object with the first factor of the second summand
+ *  \param  m      BIGNUM with the second factor of the second summand
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
 
-/* EC_GROUP_precompute_mult() stores multiples of generator for faster point multiplication */
-int EC_GROUP_precompute_mult(EC_GROUP *, BN_CTX *);
-/* EC_GROUP_have_precompute_mult() reports whether such precomputation has been done */
-int EC_GROUP_have_precompute_mult(const EC_GROUP *);
+/** Stores multiples of generator for faster point multiplication
+ *  \param  group  EC_GROUP object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+
+/** Reports whether a precomputation has been done
+ *  \param  group  EC_GROUP object
+ *  \return 1 if a pre-computation has been done and 0 otherwise
+ */
+int EC_GROUP_have_precompute_mult(const EC_GROUP *group);
 
 
-
-/* ASN1 stuff */
+/********************************************************************/
+/*                       ASN1 stuff                                 */
+/********************************************************************/
 
 /* EC_GROUP_get_basis_type() returns the NID of the basis type
  * used to represent the field elements */
@@ -293,28 +678,96 @@
 int     ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
 #endif
 
-/* the EC_KEY stuff */
+
+/********************************************************************/
+/*                      EC_KEY functions                            */
+/********************************************************************/
+
 typedef struct ec_key_st EC_KEY;
 
 /* some values for the encoding_flag */
 #define EC_PKEY_NO_PARAMETERS	0x001
 #define EC_PKEY_NO_PUBKEY	0x002
 
+/** Creates a new EC_KEY object.
+ *  \return EC_KEY object or NULL if an error occurred.
+ */
 EC_KEY *EC_KEY_new(void);
+
+/** Creates a new EC_KEY object using a named curve as underlying
+ *  EC_GROUP object.
+ *  \param  nid  NID of the named curve.
+ *  \return EC_KEY object or NULL if an error occurred. 
+ */
 EC_KEY *EC_KEY_new_by_curve_name(int nid);
-void EC_KEY_free(EC_KEY *);
-EC_KEY *EC_KEY_copy(EC_KEY *, const EC_KEY *);
-EC_KEY *EC_KEY_dup(const EC_KEY *);
 
-int EC_KEY_up_ref(EC_KEY *);
+/** Frees a EC_KEY object.
+ *  \param  key  EC_KEY object to be freed.
+ */
+void EC_KEY_free(EC_KEY *key);
 
-const EC_GROUP *EC_KEY_get0_group(const EC_KEY *);
-int EC_KEY_set_group(EC_KEY *, const EC_GROUP *);
-const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *);
-int EC_KEY_set_private_key(EC_KEY *, const BIGNUM *);
-const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *);
-int EC_KEY_set_public_key(EC_KEY *, const EC_POINT *);
-unsigned EC_KEY_get_enc_flags(const EC_KEY *);
+/** Copies a EC_KEY object.
+ *  \param  dst  destination EC_KEY object
+ *  \param  src  src EC_KEY object
+ *  \return dst or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src);
+
+/** Creates a new EC_KEY object and copies the content from src to it.
+ *  \param  src  the source EC_KEY object
+ *  \return newly created EC_KEY object or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_dup(const EC_KEY *src);
+
+/** Increases the internal reference count of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_up_ref(EC_KEY *key);
+
+/** Returns the EC_GROUP object of a EC_KEY object
+ *  \param  key  EC_KEY object
+ *  \return the EC_GROUP object (possibly NULL).
+ */
+const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key);
+
+/** Sets the EC_GROUP of a EC_KEY object.
+ *  \param  key    EC_KEY object
+ *  \param  group  EC_GROUP to use in the EC_KEY object (note: the EC_KEY
+ *                 object will use an own copy of the EC_GROUP).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group);
+
+/** Returns the private key of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \return a BIGNUM with the private key (possibly NULL).
+ */
+const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key);
+
+/** Sets the private key of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \param  prv  BIGNUM with the private key (note: the EC_KEY object
+ *               will use an own copy of the BIGNUM).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv);
+
+/** Returns the public key of a EC_KEY object.
+ *  \param  key  the EC_KEY object
+ *  \return a EC_POINT object with the public key (possibly NULL)
+ */
+const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
+
+/** Sets the public key of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \param  pub  EC_POINT object with the public key (note: the EC_KEY object
+ *               will use an own copy of the EC_POINT object).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
+
+unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
 void EC_KEY_set_enc_flags(EC_KEY *, unsigned int);
 point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *);
 void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t);
@@ -325,31 +778,126 @@
 	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
 /* wrapper functions for the underlying EC_GROUP object */
 void EC_KEY_set_asn1_flag(EC_KEY *, int);
-int EC_KEY_precompute_mult(EC_KEY *, BN_CTX *ctx);
 
-/* EC_KEY_generate_key() creates a ec private (public) key */
-int EC_KEY_generate_key(EC_KEY *);
-/* EC_KEY_check_key() */
-int EC_KEY_check_key(const EC_KEY *);
+/** Creates a table of pre-computed multiples of the generator to 
+ *  accelerate further EC_KEY operations.
+ *  \param  key  EC_KEY object
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);
 
-/* de- and encoding functions for SEC1 ECPrivateKey */
-EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len);
-int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out);
-/* de- and encoding functions for EC parameters */
-EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len);
-int i2d_ECParameters(EC_KEY *a, unsigned char **out);
-/* de- and encoding functions for EC public key
- * (octet string, not DER -- hence 'o2i' and 'i2o') */
-EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len);
-int i2o_ECPublicKey(EC_KEY *a, unsigned char **out);
+/** Creates a new ec private (and optional a new public) key.
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_generate_key(EC_KEY *key);
+
+/** Verifies that a private and/or public key is valid.
+ *  \param  key  the EC_KEY object
+ *  \return 1 on success and 0 otherwise.
+ */
+int EC_KEY_check_key(const EC_KEY *key);
+
+
+/********************************************************************/
+/*        de- and encoding functions for SEC1 ECPrivateKey          */
+/********************************************************************/
+
+/** Decodes a private key from a memory buffer.
+ *  \param  key  a pointer to a EC_KEY object which should be used (or NULL)
+ *  \param  in   pointer to memory with the DER encoded private key
+ *  \param  len  length of the DER encoded private key
+ *  \return the decoded private key or NULL if an error occurred.
+ */
+EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len);
+
+/** Encodes a private key object and stores the result in a buffer.
+ *  \param  key  the EC_KEY object to encode
+ *  \param  out  the buffer for the result (if NULL the function returns number
+ *               of bytes needed).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out);
+
+
+/********************************************************************/
+/*        de- and encoding functions for EC parameters              */
+/********************************************************************/
+
+/** Decodes ec parameter from a memory buffer.
+ *  \param  key  a pointer to a EC_KEY object which should be used (or NULL)
+ *  \param  in   pointer to memory with the DER encoded ec parameters
+ *  \param  len  length of the DER encoded ec parameters
+ *  \return a EC_KEY object with the decoded parameters or NULL if an error
+ *          occurred.
+ */
+EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len);
+
+/** Encodes ec parameter and stores the result in a buffer.
+ *  \param  key  the EC_KEY object with ec paramters to encode
+ *  \param  out  the buffer for the result (if NULL the function returns number
+ *               of bytes needed).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int i2d_ECParameters(EC_KEY *key, unsigned char **out);
+
+
+/********************************************************************/
+/*         de- and encoding functions for EC public key             */
+/*         (octet string, not DER -- hence 'o2i' and 'i2o')         */
+/********************************************************************/
+
+/** Decodes a ec public key from a octet string.
+ *  \param  key  a pointer to a EC_KEY object which should be used
+ *  \param  in   memory buffer with the encoded public key
+ *  \param  len  length of the encoded public key
+ *  \return EC_KEY object with decoded public key or NULL if an error
+ *          occurred.
+ */
+EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len);
+
+/** Encodes a ec public key in an octet string.
+ *  \param  key  the EC_KEY object with the public key
+ *  \param  out  the buffer for the result (if NULL the function returns number
+ *               of bytes needed).
+ *  \return 1 on success and 0 if an error occurred
+ */
+int i2o_ECPublicKey(EC_KEY *key, unsigned char **out);
 
 #ifndef OPENSSL_NO_BIO
-int	ECParameters_print(BIO *bp, const EC_KEY *x);
-int	EC_KEY_print(BIO *bp, const EC_KEY *x, int off);
+/** Prints out the ec parameters on human readable form.
+ *  \param  bp   BIO object to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred
+ */
+int	ECParameters_print(BIO *bp, const EC_KEY *key);
+
+/** Prints out the contents of a EC_KEY object
+ *  \param  bp   BIO object to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \param  off  line offset 
+ *  \return 1 on success and 0 if an error occurred
+ */
+int	EC_KEY_print(BIO *bp, const EC_KEY *key, int off);
+
 #endif
 #ifndef OPENSSL_NO_FP_API
-int	ECParameters_print_fp(FILE *fp, const EC_KEY *x);
-int	EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off);
+/** Prints out the ec parameters on human readable form.
+ *  \param  fp   file descriptor to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred
+ */
+int	ECParameters_print_fp(FILE *fp, const EC_KEY *key);
+
+/** Prints out the contents of a EC_KEY object
+ *  \param  fp   file descriptor to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \param  off  line offset 
+ *  \return 1 on success and 0 if an error occurred
+ */
+int	EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);
+
 #endif
 
 #define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x)
@@ -362,6 +910,13 @@
 # endif
 #endif
 
+#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_PARAMGEN, \
+				EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL)
+
+
+#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID		(EVP_PKEY_ALG_CTRL + 1)
+
 /* 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.
@@ -375,6 +930,14 @@
 #define EC_F_D2I_ECPARAMETERS				 144
 #define EC_F_D2I_ECPKPARAMETERS				 145
 #define EC_F_D2I_ECPRIVATEKEY				 146
+#define EC_F_DO_EC_KEY_PRINT				 221
+#define EC_F_ECKEY_PARAM2TYPE				 223
+#define EC_F_ECKEY_PARAM_DECODE				 212
+#define EC_F_ECKEY_PRIV_DECODE				 213
+#define EC_F_ECKEY_PRIV_ENCODE				 214
+#define EC_F_ECKEY_PUB_DECODE				 215
+#define EC_F_ECKEY_PUB_ENCODE				 216
+#define EC_F_ECKEY_TYPE2PARAM				 220
 #define EC_F_ECPARAMETERS_PRINT				 147
 #define EC_F_ECPARAMETERS_PRINT_FP			 148
 #define EC_F_ECPKPARAMETERS_PRINT			 149
@@ -448,7 +1011,6 @@
 #define EC_F_EC_KEY_PRINT				 180
 #define EC_F_EC_KEY_PRINT_FP				 181
 #define EC_F_EC_POINTS_MAKE_AFFINE			 136
-#define EC_F_EC_POINTS_MUL				 138
 #define EC_F_EC_POINT_ADD				 112
 #define EC_F_EC_POINT_CMP				 113
 #define EC_F_EC_POINT_COPY				 114
@@ -479,21 +1041,31 @@
 #define EC_F_I2D_ECPRIVATEKEY				 192
 #define EC_F_I2O_ECPUBLICKEY				 151
 #define EC_F_O2I_ECPUBLICKEY				 152
+#define EC_F_OLD_EC_PRIV_DECODE				 222
+#define EC_F_PKEY_EC_CTRL				 197
+#define EC_F_PKEY_EC_CTRL_STR				 198
+#define EC_F_PKEY_EC_DERIVE				 217
+#define EC_F_PKEY_EC_KEYGEN				 199
+#define EC_F_PKEY_EC_PARAMGEN				 219
+#define EC_F_PKEY_EC_SIGN				 218
 
 /* Reason codes. */
 #define EC_R_ASN1_ERROR					 115
 #define EC_R_ASN1_UNKNOWN_FIELD				 116
 #define EC_R_BUFFER_TOO_SMALL				 100
 #define EC_R_D2I_ECPKPARAMETERS_FAILURE			 117
+#define EC_R_DECODE_ERROR				 142
 #define EC_R_DISCRIMINANT_IS_ZERO			 118
 #define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE		 119
-#define EC_R_FIELD_TOO_LARGE				 138
+#define EC_R_FIELD_TOO_LARGE				 143
 #define EC_R_GROUP2PKPARAMETERS_FAILURE			 120
 #define EC_R_I2D_ECPKPARAMETERS_FAILURE			 121
 #define EC_R_INCOMPATIBLE_OBJECTS			 101
 #define EC_R_INVALID_ARGUMENT				 112
 #define EC_R_INVALID_COMPRESSED_POINT			 110
 #define EC_R_INVALID_COMPRESSION_BIT			 109
+#define EC_R_INVALID_CURVE				 141
+#define EC_R_INVALID_DIGEST_TYPE			 138
 #define EC_R_INVALID_ENCODING				 102
 #define EC_R_INVALID_FIELD				 103
 #define EC_R_INVALID_FORM				 104
@@ -501,6 +1073,7 @@
 #define EC_R_INVALID_PENTANOMIAL_BASIS			 132
 #define EC_R_INVALID_PRIVATE_KEY			 123
 #define EC_R_INVALID_TRINOMIAL_BASIS			 137
+#define EC_R_KEYS_NOT_SET				 140
 #define EC_R_MISSING_PARAMETERS				 124
 #define EC_R_MISSING_PRIVATE_KEY			 125
 #define EC_R_NOT_A_NIST_PRIME				 135
@@ -508,6 +1081,7 @@
 #define EC_R_NOT_IMPLEMENTED				 126
 #define EC_R_NOT_INITIALIZED				 111
 #define EC_R_NO_FIELD_MOD				 133
+#define EC_R_NO_PARAMETERS_SET				 139
 #define EC_R_PASSED_NULL_PARAMETER			 134
 #define EC_R_PKPARAMETERS2GROUP_FAILURE			 127
 #define EC_R_POINT_AT_INFINITY				 106
diff --git a/include/openssl/ecdsa.h b/include/openssl/ecdsa.h
index f20c8ee..e61c539 100644
--- a/include/openssl/ecdsa.h
+++ b/include/openssl/ecdsa.h
@@ -4,7 +4,7 @@
  * \author Written by Nils Larsch for the OpenSSL project
  */
 /* ====================================================================
- * Copyright (c) 2000-2003 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 2000-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
@@ -81,156 +81,143 @@
 	BIGNUM *s;
 	} ECDSA_SIG;
 
-/** ECDSA_SIG *ECDSA_SIG_new(void)
- * allocates and initialize a ECDSA_SIG structure
- * \return pointer to a ECDSA_SIG structure or NULL if an error occurred
+/** Allocates and initialize a ECDSA_SIG structure
+ *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
  */
 ECDSA_SIG *ECDSA_SIG_new(void);
 
-/** ECDSA_SIG_free
- * frees a ECDSA_SIG structure
- * \param a pointer to the ECDSA_SIG structure
+/** frees a ECDSA_SIG structure
+ *  \param  sig  pointer to the ECDSA_SIG structure
  */
-void	  ECDSA_SIG_free(ECDSA_SIG *a);
+void	  ECDSA_SIG_free(ECDSA_SIG *sig);
 
-/** i2d_ECDSA_SIG
- * DER encode content of ECDSA_SIG object (note: this function modifies *pp
- * (*pp += length of the DER encoded signature)).
- * \param a  pointer to the ECDSA_SIG object
- * \param pp pointer to a unsigned char pointer for the output or NULL
- * \return the length of the DER encoded ECDSA_SIG object or 0 
+/** DER encode content of ECDSA_SIG object (note: this function modifies *pp
+ *  (*pp += length of the DER encoded signature)).
+ *  \param  sig  pointer to the ECDSA_SIG object
+ *  \param  pp   pointer to a unsigned char pointer for the output or NULL
+ *  \return the length of the DER encoded ECDSA_SIG object or 0 
  */
-int	  i2d_ECDSA_SIG(const ECDSA_SIG *a, unsigned char **pp);
+int	  i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
 
-/** d2i_ECDSA_SIG
- * decodes a DER encoded ECDSA signature (note: this function changes *pp
- * (*pp += len)). 
- * \param v pointer to ECDSA_SIG pointer (may be NULL)
- * \param pp buffer with the DER encoded signature
- * \param len bufferlength
- * \return pointer to the decoded ECDSA_SIG structure (or NULL)
+/** Decodes a DER encoded ECDSA signature (note: this function changes *pp
+ *  (*pp += len)). 
+ *  \param  sig  pointer to ECDSA_SIG pointer (may be NULL)
+ *  \param  pp   memory buffer with the DER encoded signature
+ *  \param  len  length of the buffer
+ *  \return pointer to the decoded ECDSA_SIG structure (or NULL)
  */
-ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **v, const unsigned char **pp, long len);
+ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len);
 
-/** ECDSA_do_sign
- * computes the ECDSA signature of the given hash value using
- * the supplied private key and returns the created signature.
- * \param dgst pointer to the hash value
- * \param dgst_len length of the hash value
- * \param eckey pointer to the EC_KEY object containing a private EC key
- * \return pointer to a ECDSA_SIG structure or NULL
+/** Computes the ECDSA signature of the given hash value using
+ *  the supplied private key and returns the created signature.
+ *  \param  dgst      pointer to the hash value
+ *  \param  dgst_len  length of the hash value
+ *  \param  eckey     EC_KEY object containing a private EC key
+ *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
  */
 ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst,int dgst_len,EC_KEY *eckey);
 
-/** ECDSA_do_sign_ex
- * computes ECDSA signature of a given hash value using the supplied
- * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
- * \param dgst pointer to the hash value to sign
- * \param dgstlen length of the hash value
- * \param kinv optional pointer to a pre-computed inverse k
- * \param rp optional pointer to the pre-computed rp value (see 
- *        ECDSA_sign_setup
- * \param eckey pointer to the EC_KEY object containing a private EC key
- * \return pointer to a ECDSA_SIG structure or NULL
+/** Computes ECDSA signature of a given hash value using the supplied
+ *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ *  \param  dgst     pointer to the hash value to sign
+ *  \param  dgstlen  length of the hash value
+ *  \param  kinv     BIGNUM with a pre-computed inverse k (optional)
+ *  \param  rp       BIGNUM with a pre-computed rp value (optioanl), 
+ *                   see ECDSA_sign_setup
+ *  \param  eckey    EC_KEY object containing a private EC key
+ *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
  */
 ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, 
 		const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey);
 
-/** ECDSA_do_verify
- * verifies that the supplied signature is a valid ECDSA
- * signature of the supplied hash value using the supplied public key.
- * \param dgst pointer to the hash value
- * \param dgst_len length of the hash value
- * \param sig  pointer to the ECDSA_SIG structure
- * \param eckey pointer to the EC_KEY object containing a public EC key
- * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error
+/** Verifies that the supplied signature is a valid ECDSA
+ *  signature of the supplied hash value using the supplied public key.
+ *  \param  dgst      pointer to the hash value
+ *  \param  dgst_len  length of the hash value
+ *  \param  sig       ECDSA_SIG structure
+ *  \param  eckey     EC_KEY object containing a public EC key
+ *  \return 1 if the signature is valid, 0 if the signature is invalid
+ *          and -1 on error
  */
 int	  ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
 		const ECDSA_SIG *sig, EC_KEY* eckey);
 
 const ECDSA_METHOD *ECDSA_OpenSSL(void);
 
-/** ECDSA_set_default_method
- * sets the default ECDSA method
- * \param meth the new default ECDSA_METHOD
+/** Sets the default ECDSA method
+ *  \param  meth  new default ECDSA_METHOD
  */
 void	  ECDSA_set_default_method(const ECDSA_METHOD *meth);
 
-/** ECDSA_get_default_method
- * returns the default ECDSA method
- * \return pointer to ECDSA_METHOD structure containing the default method
+/** Returns the default ECDSA method
+ *  \return pointer to ECDSA_METHOD structure containing the default method
  */
 const ECDSA_METHOD *ECDSA_get_default_method(void);
 
-/** ECDSA_set_method
- * sets method to be used for the ECDSA operations
- * \param eckey pointer to the EC_KEY object
- * \param meth  pointer to the new method
- * \return 1 on success and 0 otherwise 
+/** Sets method to be used for the ECDSA operations
+ *  \param  eckey  EC_KEY object
+ *  \param  meth   new method
+ *  \return 1 on success and 0 otherwise 
  */
 int 	  ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth);
 
-/** ECDSA_size
- * returns the maximum length of the DER encoded signature
- * \param  eckey pointer to a EC_KEY object
- * \return numbers of bytes required for the DER encoded signature
+/** Returns the maximum length of the DER encoded signature
+ *  \param  eckey  EC_KEY object
+ *  \return numbers of bytes required for the DER encoded signature
  */
 int	  ECDSA_size(const EC_KEY *eckey);
 
-/** ECDSA_sign_setup
- * precompute parts of the signing operation. 
- * \param eckey pointer to the EC_KEY object containing a private EC key
- * \param ctx  pointer to a BN_CTX object (may be NULL)
- * \param kinv pointer to a BIGNUM pointer for the inverse of k
- * \param rp   pointer to a BIGNUM pointer for x coordinate of k * generator
- * \return 1 on success and 0 otherwise
+/** Precompute parts of the signing operation
+ *  \param  eckey  EC_KEY object containing a private EC key
+ *  \param  ctx    BN_CTX object (optional)
+ *  \param  kinv   BIGNUM pointer for the inverse of k
+ *  \param  rp     BIGNUM pointer for x coordinate of k * generator
+ *  \return 1 on success and 0 otherwise
  */
 int 	  ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, 
 		BIGNUM **rp);
 
-/** ECDSA_sign
- * computes ECDSA signature of a given hash value using the supplied
- * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
- * \param type this parameter is ignored
- * \param dgst pointer to the hash value to sign
- * \param dgstlen length of the hash value
- * \param sig buffer to hold the DER encoded signature
- * \param siglen pointer to the length of the returned signature
- * \param eckey pointer to the EC_KEY object containing a private EC key
- * \return 1 on success and 0 otherwise
+/** Computes ECDSA signature of a given hash value using the supplied
+ *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ *  \param  type     this parameter is ignored
+ *  \param  dgst     pointer to the hash value to sign
+ *  \param  dgstlen  length of the hash value
+ *  \param  sig      memory for the DER encoded created signature
+ *  \param  siglen   pointer to the length of the returned signature
+ *  \param  eckey    EC_KEY object containing a private EC key
+ *  \return 1 on success and 0 otherwise
  */
 int	  ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, 
 		unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);
 
 
-/** ECDSA_sign_ex
- * computes ECDSA signature of a given hash value using the supplied
- * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
- * \param type this parameter is ignored
- * \param dgst pointer to the hash value to sign
- * \param dgstlen length of the hash value
- * \param sig buffer to hold the DER encoded signature
- * \param siglen pointer to the length of the returned signature
- * \param kinv optional pointer to a pre-computed inverse k
- * \param rp optional pointer to the pre-computed rp value (see 
- *        ECDSA_sign_setup
- * \param eckey pointer to the EC_KEY object containing a private EC key
- * \return 1 on success and 0 otherwise
+/** Computes ECDSA signature of a given hash value using the supplied
+ *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ *  \param  type     this parameter is ignored
+ *  \param  dgst     pointer to the hash value to sign
+ *  \param  dgstlen  length of the hash value
+ *  \param  sig      buffer to hold the DER encoded signature
+ *  \param  siglen   pointer to the length of the returned signature
+ *  \param  kinv     BIGNUM with a pre-computed inverse k (optional)
+ *  \param  rp       BIGNUM with a pre-computed rp value (optioanl), 
+ *                   see ECDSA_sign_setup
+ *  \param  eckey    EC_KEY object containing a private EC key
+ *  \return 1 on success and 0 otherwise
  */
 int	  ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, 
 		unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv,
 		const BIGNUM *rp, EC_KEY *eckey);
 
-/** ECDSA_verify
- * verifies that the given signature is valid ECDSA signature
- * of the supplied hash value using the specified public key.
- * \param type this parameter is ignored
- * \param dgst pointer to the hash value 
- * \param dgstlen length of the hash value
- * \param sig  pointer to the DER encoded signature
- * \param siglen length of the DER encoded signature
- * \param eckey pointer to the EC_KEY object containing a public EC key
- * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error
+/** Verifies that the given signature is valid ECDSA signature
+ *  of the supplied hash value using the specified public key.
+ *  \param  type     this parameter is ignored
+ *  \param  dgst     pointer to the hash value 
+ *  \param  dgstlen  length of the hash value
+ *  \param  sig      pointer to the DER encoded signature
+ *  \param  siglen   length of the DER encoded signature
+ *  \param  eckey    EC_KEY object containing a public EC key
+ *  \return 1 if the signature is valid, 0 if the signature is invalid
+ *          and -1 on error
  */
 int 	  ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, 
 		const unsigned char *sig, int siglen, EC_KEY *eckey);
diff --git a/include/openssl/engine.h b/include/openssl/engine.h
index d4bc1ef..7fbd95f 100644
--- a/include/openssl/engine.h
+++ b/include/openssl/engine.h
@@ -88,16 +88,15 @@
 #include <openssl/ecdsa.h>
 #endif
 #include <openssl/rand.h>
-#include <openssl/store.h>
 #include <openssl/ui.h>
 #include <openssl/err.h>
 #endif
 
-#include <openssl/x509.h>
-
 #include <openssl/ossl_typ.h>
 #include <openssl/symhacks.h>
 
+#include <openssl/x509.h>
+
 #ifdef  __cplusplus
 extern "C" {
 #endif
@@ -113,6 +112,8 @@
 #define ENGINE_METHOD_CIPHERS		(unsigned int)0x0040
 #define ENGINE_METHOD_DIGESTS		(unsigned int)0x0080
 #define ENGINE_METHOD_STORE		(unsigned int)0x0100
+#define ENGINE_METHOD_PKEY_METHS	(unsigned int)0x0200
+#define ENGINE_METHOD_PKEY_ASN1_METHS	(unsigned int)0x0400
 /* Obvious all-or-nothing cases. */
 #define ENGINE_METHOD_ALL		(unsigned int)0xFFFF
 #define ENGINE_METHOD_NONE		(unsigned int)0x0000
@@ -297,7 +298,8 @@
  * parameter is non-NULL it is set to the size of the returned array. */
 typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int);
 typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int);
-
+typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, EVP_PKEY_METHOD **, const int **, int);
+typedef int (*ENGINE_PKEY_ASN1_METHS_PTR)(ENGINE *, EVP_PKEY_ASN1_METHOD **, const int **, int);
 /* STRUCTURE functions ... all of these functions deal with pointers to ENGINE
  * structures where the pointers have a "structural reference". This means that
  * their reference is to allowed access to the structure but it does not imply
@@ -329,21 +331,20 @@
 void ENGINE_load_atalla(void);
 void ENGINE_load_chil(void);
 void ENGINE_load_cswift(void);
-#ifndef OPENSSL_NO_GMP
-void ENGINE_load_gmp(void);
-#endif
 void ENGINE_load_nuron(void);
 void ENGINE_load_sureware(void);
 void ENGINE_load_ubsec(void);
+void ENGINE_load_padlock(void);
+void ENGINE_load_capi(void);
+#ifndef OPENSSL_NO_GMP
+void ENGINE_load_gmp(void);
+#endif
+#ifndef OPENSSL_NO_GOST
+void ENGINE_load_gost(void);
+#endif
 #endif
 void ENGINE_load_cryptodev(void);
-void ENGINE_load_padlock(void);
 void ENGINE_load_builtin_engines(void);
-#ifdef OPENSSL_SYS_WIN32
-#ifndef OPENSSL_NO_CAPIENG
-void ENGINE_load_capi(void);
-#endif
-#endif
 
 /* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
  * "registry" handling. */
@@ -394,6 +395,14 @@
 void ENGINE_unregister_digests(ENGINE *e);
 void ENGINE_register_all_digests(void);
 
+int ENGINE_register_pkey_meths(ENGINE *e);
+void ENGINE_unregister_pkey_meths(ENGINE *e);
+void ENGINE_register_all_pkey_meths(void);
+
+int ENGINE_register_pkey_asn1_meths(ENGINE *e);
+void ENGINE_unregister_pkey_asn1_meths(ENGINE *e);
+void ENGINE_register_all_pkey_asn1_meths(void);
+
 /* These functions register all support from the above categories. Note, use of
  * these functions can result in static linkage of code your application may not
  * need. If you only need a subset of functionality, consider using more
@@ -473,6 +482,8 @@
 				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_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f);
+int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f);
 int ENGINE_set_flags(ENGINE *e, int flags);
 int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
 /* These functions allow control over any per-structure ENGINE data. */
@@ -509,8 +520,16 @@
 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);
+ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e);
+ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e);
 const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
 const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
+const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
+					const char *str, int len);
+const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
+					const char *str, int len);
 const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
 int ENGINE_get_flags(const ENGINE *e);
 
@@ -562,6 +581,8 @@
  * ciphering or digesting corresponding to "nid". */
 ENGINE *ENGINE_get_cipher_engine(int nid);
 ENGINE *ENGINE_get_digest_engine(int nid);
+ENGINE *ENGINE_get_pkey_meth_engine(int nid);
+ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid);
 
 /* This sets a new default ENGINE structure for performing RSA
  * operations. If the result is non-zero (success) then the ENGINE
@@ -577,6 +598,8 @@
 int ENGINE_set_default_RAND(ENGINE *e);
 int ENGINE_set_default_ciphers(ENGINE *e);
 int ENGINE_set_default_digests(ENGINE *e);
+int ENGINE_set_default_pkey_meths(ENGINE *e);
+int ENGINE_set_default_pkey_asn1_meths(ENGINE *e);
 
 /* The combination "set" - the flags are bitwise "OR"d from the
  * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
@@ -705,7 +728,7 @@
  * values. */
 void *ENGINE_get_static_state(void);
 
-#if defined(__OpenBSD__) || defined(__FreeBSD__)
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
 void ENGINE_setup_bsd_cryptodev(void);
 #endif
 
@@ -734,13 +757,15 @@
 #define ENGINE_F_ENGINE_GET_DEFAULT_TYPE		 177
 #define ENGINE_F_ENGINE_GET_DIGEST			 186
 #define ENGINE_F_ENGINE_GET_NEXT			 115
+#define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH		 193
+#define ENGINE_F_ENGINE_GET_PKEY_METH			 192
 #define ENGINE_F_ENGINE_GET_PREV			 116
 #define ENGINE_F_ENGINE_INIT				 119
 #define ENGINE_F_ENGINE_LIST_ADD			 120
 #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_LOAD_SSL_CLIENT_CERT		 194
 #define ENGINE_F_ENGINE_NEW				 122
 #define ENGINE_F_ENGINE_REMOVE				 123
 #define ENGINE_F_ENGINE_SET_DEFAULT_STRING		 189
@@ -769,7 +794,7 @@
 #define ENGINE_R_DSO_FAILURE				 104
 #define ENGINE_R_DSO_NOT_FOUND				 132
 #define ENGINE_R_ENGINES_SECTION_ERROR			 148
-#define ENGINE_R_ENGINE_CONFIGURATION_ERROR		 101
+#define ENGINE_R_ENGINE_CONFIGURATION_ERROR		 102
 #define ENGINE_R_ENGINE_IS_NOT_IN_LIST			 105
 #define ENGINE_R_ENGINE_SECTION_ERROR			 149
 #define ENGINE_R_FAILED_LOADING_PRIVATE_KEY		 128
@@ -796,6 +821,7 @@
 #define ENGINE_R_RSA_NOT_IMPLEMENTED			 141
 #define ENGINE_R_UNIMPLEMENTED_CIPHER			 146
 #define ENGINE_R_UNIMPLEMENTED_DIGEST			 147
+#define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD	 101
 #define ENGINE_R_VERSION_INCOMPATIBILITY		 145
 
 #ifdef  __cplusplus
diff --git a/include/openssl/err.h b/include/openssl/err.h
index dcac415..b9f8c16 100644
--- a/include/openssl/err.h
+++ b/include/openssl/err.h
@@ -55,6 +55,59 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
+/* ====================================================================
+ * Copyright (c) 1998-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
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
 
 #ifndef HEADER_ERR_H
 #define HEADER_ERR_H
@@ -94,7 +147,7 @@
 #define ERR_NUM_ERRORS	16
 typedef struct err_state_st
 	{
-	unsigned long pid;
+	CRYPTO_THREADID tid;
 	int err_flags[ERR_NUM_ERRORS];
 	unsigned long err_buffer[ERR_NUM_ERRORS];
 	char *err_data[ERR_NUM_ERRORS];
@@ -142,7 +195,9 @@
 #define ERR_LIB_STORE           44
 #define ERR_LIB_FIPS		45
 #define ERR_LIB_CMS		46
-#define ERR_LIB_JPAKE		47
+#define ERR_LIB_TS		47
+#define ERR_LIB_HMAC		48
+#define ERR_LIB_JPAKE		49
 
 #define ERR_LIB_USER		128
 
@@ -176,6 +231,8 @@
 #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 TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),__FILE__,__LINE__)
+#define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(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
@@ -232,6 +289,7 @@
 #define ERR_R_ECDSA_LIB ERR_LIB_ECDSA	 /* 42 */
 #define ERR_R_ECDH_LIB  ERR_LIB_ECDH	 /* 43 */
 #define ERR_R_STORE_LIB ERR_LIB_STORE    /* 44 */
+#define ERR_R_TS_LIB	ERR_LIB_TS       /* 45 */
 
 #define ERR_R_NESTED_ASN1_ERROR			58
 #define ERR_R_BAD_ASN1_OBJECT_HEADER		59
@@ -294,13 +352,16 @@
 void ERR_load_crypto_strings(void);
 void ERR_free_strings(void);
 
+void ERR_remove_thread_state(const CRYPTO_THREADID *tid);
+#ifndef OPENSSL_NO_DEPRECATED
 void ERR_remove_state(unsigned long pid); /* if zero we look it up */
+#endif
 ERR_STATE *ERR_get_state(void);
 
 #ifndef OPENSSL_NO_LHASH
-LHASH *ERR_get_string_table(void);
-LHASH *ERR_get_err_state_table(void);
-void ERR_release_err_state_table(LHASH **hash);
+LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void);
+LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void);
+void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash);
 #endif
 
 int ERR_get_next_error_library(void);
@@ -308,12 +369,6 @@
 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 79c0971..9f9795e 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -75,10 +75,6 @@
 #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
@@ -119,6 +115,7 @@
 #define EVP_PKEY_DSA4	NID_dsaWithSHA1_2
 #define EVP_PKEY_DH	NID_dhKeyAgreement
 #define EVP_PKEY_EC	NID_X9_62_id_ecPublicKey
+#define EVP_PKEY_HMAC	NID_hmac
 
 #ifdef	__cplusplus
 extern "C" {
@@ -132,6 +129,8 @@
 	int type;
 	int save_type;
 	int references;
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	ENGINE *engine;
 	union	{
 		char *ptr;
 #ifndef OPENSSL_NO_RSA
@@ -156,73 +155,6 @@
 #define EVP_PKEY_MO_ENCRYPT	0x0004
 #define EVP_PKEY_MO_DECRYPT	0x0008
 
-#if 0
-/* This structure is required to tie the message digest and signing together.
- * The lookup can be done by md/pkey_method, oid, oid/pkey_method, or
- * oid, md and pkey.
- * This is required because for various smart-card perform the digest and
- * signing/verification on-board.  To handle this case, the specific
- * EVP_MD and EVP_PKEY_METHODs need to be closely associated.
- * When a PKEY is created, it will have a EVP_PKEY_METHOD associated with it.
- * This can either be software or a token to provide the required low level
- * routines.
- */
-typedef struct evp_pkey_md_st
-	{
-	int oid;
-	EVP_MD *md;
-	EVP_PKEY_METHOD *pkey;
-	} EVP_PKEY_MD;
-
-#define EVP_rsa_md2() \
-		EVP_PKEY_MD_add(NID_md2WithRSAEncryption,\
-			EVP_rsa_pkcs1(),EVP_md2())
-#define EVP_rsa_md5() \
-		EVP_PKEY_MD_add(NID_md5WithRSAEncryption,\
-			EVP_rsa_pkcs1(),EVP_md5())
-#define EVP_rsa_sha0() \
-		EVP_PKEY_MD_add(NID_shaWithRSAEncryption,\
-			EVP_rsa_pkcs1(),EVP_sha())
-#define EVP_rsa_sha1() \
-		EVP_PKEY_MD_add(NID_sha1WithRSAEncryption,\
-			EVP_rsa_pkcs1(),EVP_sha1())
-#define EVP_rsa_ripemd160() \
-		EVP_PKEY_MD_add(NID_ripemd160WithRSA,\
-			EVP_rsa_pkcs1(),EVP_ripemd160())
-#define EVP_rsa_mdc2() \
-		EVP_PKEY_MD_add(NID_mdc2WithRSA,\
-			EVP_rsa_octet_string(),EVP_mdc2())
-#define EVP_dsa_sha() \
-		EVP_PKEY_MD_add(NID_dsaWithSHA,\
-			EVP_dsa(),EVP_sha())
-#define EVP_dsa_sha1() \
-		EVP_PKEY_MD_add(NID_dsaWithSHA1,\
-			EVP_dsa(),EVP_sha1())
-
-typedef struct evp_pkey_method_st
-	{
-	char *name;
-	int flags;
-	int type;		/* RSA, DSA, an SSLeay specific constant */
-	int oid;		/* For the pub-key type */
-	int encrypt_oid;	/* pub/priv key encryption */
-
-	int (*sign)();
-	int (*verify)();
-	struct	{
-		int (*set)();	/* get and/or set the underlying type */
-		int (*get)();
-		int (*encrypt)();
-		int (*decrypt)();
-		int (*i2d)();
-		int (*d2i)();
-		int (*dup)();
-		} pub,priv;
-	int (*set_asn1_parameters)();
-	int (*get_asn1_parameters)();
-	} EVP_PKEY_METHOD;
-#endif
-
 #ifndef EVP_MD
 struct env_md_st
 	{
@@ -245,6 +177,8 @@
 	int required_pkey_type[5]; /*EVP_PKEY_xxx */
 	int block_size;
 	int ctx_size; /* how big does the ctx->md_data need to be */
+	/* control function */
+	int (*md_ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
 	} /* EVP_MD */;
 
 typedef int evp_sign_method(int type,const unsigned char *m,
@@ -254,18 +188,42 @@
 			    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_PKEY_DIGEST	0x0002 /* digest is a "clone" digest used
+					* which is a copy of an existing
+					* one for a specific public key type.
+					* EVP_dss1() etc */
 
-#define EVP_MD_FLAG_SVCTX	0x0800 /* pass EVP_MD_SVCTX to sign/verify */
+/* Digest uses EVP_PKEY_METHOD for signing instead of MD specific signing */
+
+#define EVP_MD_FLAG_PKEY_METHOD_SIGNATURE	0x0004
+
+/* DigestAlgorithmIdentifier flags... */
+
+#define EVP_MD_FLAG_DIGALGID_MASK		0x0018
+
+/* NULL or absent parameter accepted. Use NULL */
+
+#define EVP_MD_FLAG_DIGALGID_NULL		0x0000
+
+/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */
+
+#define EVP_MD_FLAG_DIGALGID_ABSENT		0x0008
+
+/* Custom handling via ctrl */
+
+#define EVP_MD_FLAG_DIGALGID_CUSTOM		0x0018
+
+/* Digest ctrls */
+
+#define	EVP_MD_CTRL_DIGALGID			0x1
+#define	EVP_MD_CTRL_MICALG			0x2
+
+/* Minimum Algorithm specific ctrl value */
+
+#define	EVP_MD_CTRL_ALG_CTRL			0x1000
 
 #define EVP_PKEY_NULL_method	NULL,NULL,{0,0,0,0}
 
@@ -307,6 +265,10 @@
 	ENGINE *engine; /* functional reference if 'digest' is ENGINE-provided */
 	unsigned long flags;
 	void *md_data;
+	/* Public key context for sign/verify */
+	EVP_PKEY_CTX *pctx;
+	/* Update function: usually copied from EVP_MD */
+	int (*update)(EVP_MD_CTX *ctx,const void *data,size_t count);
 	} /* EVP_MD_CTX */;
 
 /* values for EVP_MD_CTX flags */
@@ -317,17 +279,23 @@
 						* cleaned */
 #define EVP_MD_CTX_FLAG_REUSE		0x0004 /* Don't free up ctx->md_data
 						* in EVP_MD_CTX_cleanup */
+/* FIPS and pad options are ignored in 1.0.0, definitions are here
+ * so we don't accidentally reuse the values for other purposes.
+ */
+
 #define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW	0x0008	/* Allow use of non FIPS digest
 						 * in FIPS mode */
 
+/* The following PAD options are also currently ignored in 1.0.0, digest
+ * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*()
+ * instead.
+ */
 #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 */
+
+#define EVP_MD_CTX_FLAG_NO_INIT		0x0100 /* Don't initialize md_data */
 
 struct evp_cipher_st
 	{
@@ -339,7 +307,7 @@
 	int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key,
 		    const unsigned char *iv, int enc);	/* init key */
 	int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out,
-			 const unsigned char *in, unsigned int inl);/* encrypt/decrypt data */
+			 const unsigned char *in, size_t inl);/* encrypt/decrypt data */
 	int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */
 	int ctx_size;		/* how big ctx->cipher_data needs to be */
 	int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */
@@ -357,7 +325,7 @@
 #define		EVP_CIPH_CBC_MODE		0x2
 #define		EVP_CIPH_CFB_MODE		0x3
 #define		EVP_CIPH_OFB_MODE		0x4
-#define 	EVP_CIPH_MODE			0x7
+#define 	EVP_CIPH_MODE			0xF0007
 /* Set if variable length cipher */
 #define 	EVP_CIPH_VARIABLE_LENGTH	0x8
 /* Set if the iv handling should be done by the cipher itself */
@@ -372,10 +340,8 @@
 #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
+/* cipher has its own additional copying logic */
+#define 	EVP_CIPH_CUSTOM_COPY		0x400
 /* Allow use default ASN1 get/set iv */
 #define		EVP_CIPH_FLAG_DEFAULT_ASN1	0x1000
 /* Buffer length in bits not bytes: CFB1 mode only */
@@ -390,6 +356,8 @@
 #define 	EVP_CTRL_GET_RC5_ROUNDS		0x4
 #define 	EVP_CTRL_SET_RC5_ROUNDS		0x5
 #define 	EVP_CTRL_RAND_KEY		0x6
+#define 	EVP_CTRL_PBE_PRF_NID		0x7
+#define 	EVP_CTRL_COPY			0x8
 
 typedef struct evp_cipher_info_st
 	{
@@ -462,26 +430,15 @@
 #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))
 int EVP_MD_pkey_type(const EVP_MD *md);	
 int EVP_MD_size(const EVP_MD *md);
 int EVP_MD_block_size(const EVP_MD *md);
+unsigned long EVP_MD_flags(const EVP_MD *md);
 
-const EVP_MD * EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
+const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
 #define EVP_MD_CTX_size(e)		EVP_MD_size(EVP_MD_CTX_md(e))
 #define EVP_MD_CTX_block_size(e)	EVP_MD_block_size(EVP_MD_CTX_md(e))
 #define EVP_MD_CTX_type(e)		EVP_MD_type(EVP_MD_CTX_md(e))
@@ -499,6 +456,7 @@
 int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx);
 int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx);
 int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in);
 void * EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx);
 void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data);
 #define EVP_CIPHER_CTX_type(c)         EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c))
@@ -516,6 +474,8 @@
 #define	EVP_VerifyUpdate(a,b,c)		EVP_DigestUpdate(a,b,c)
 #define EVP_OpenUpdate(a,b,c,d,e)	EVP_DecryptUpdate(a,b,c,d,e)
 #define EVP_SealUpdate(a,b,c,d,e)	EVP_EncryptUpdate(a,b,c,d,e)	
+#define EVP_DigestSignUpdate(a,b,c)	EVP_DigestUpdate(a,b,c)
+#define EVP_DigestVerifyUpdate(a,b,c)	EVP_DigestUpdate(a,b,c)
 
 #ifdef CONST_STRICT
 void BIO_set_md(BIO *,const EVP_MD *md);
@@ -562,6 +522,7 @@
 int	EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);
 
 int	EVP_read_pw_string(char *buf,int length,const char *prompt,int verify);
+int	EVP_read_pw_string_min(char *buf,int minlen,int maxlen,const char *prompt,int verify);
 void	EVP_set_pw_prompt(const char *prompt);
 char *	EVP_get_pw_prompt(void);
 
@@ -608,6 +569,16 @@
 int	EVP_VerifyFinal(EVP_MD_CTX *ctx,const unsigned char *sigbuf,
 		unsigned int siglen,EVP_PKEY *pkey);
 
+int	EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
+int	EVP_DigestSignFinal(EVP_MD_CTX *ctx,
+			unsigned char *sigret, size_t *siglen);
+
+int	EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+			const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
+int	EVP_DigestVerifyFinal(EVP_MD_CTX *ctx,
+			unsigned char *sig, size_t siglen);
+
 int	EVP_OpenInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type,
 		const unsigned char *ek, int ekl, const unsigned char *iv,
 		EVP_PKEY *priv);
@@ -680,6 +651,9 @@
 #ifndef OPENSSL_NO_RIPEMD
 const EVP_MD *EVP_ripemd160(void);
 #endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+const EVP_MD *EVP_whirlpool(void);
+#endif
 const EVP_CIPHER *EVP_enc_null(void);		/* does nothing :-) */
 #ifndef OPENSSL_NO_DES
 const EVP_CIPHER *EVP_des_ecb(void);
@@ -847,16 +821,31 @@
 const EVP_MD *EVP_get_digestbyname(const char *name);
 void EVP_cleanup(void);
 
-int		EVP_PKEY_decrypt(unsigned char *dec_key,
+void EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph,
+		const char *from, const char *to, void *x), void *arg);
+void EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph,
+		const char *from, const char *to, void *x), void *arg);
+
+void EVP_MD_do_all(void (*fn)(const EVP_MD *ciph,
+		const char *from, const char *to, void *x), void *arg);
+void EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *ciph,
+		const char *from, const char *to, void *x), void *arg);
+
+int		EVP_PKEY_decrypt_old(unsigned char *dec_key,
 			const unsigned char *enc_key,int enc_key_len,
 			EVP_PKEY *private_key);
-int		EVP_PKEY_encrypt(unsigned char *enc_key,
+int		EVP_PKEY_encrypt_old(unsigned char *enc_key,
 			const unsigned char *key,int key_len,
 			EVP_PKEY *pub_key);
 int		EVP_PKEY_type(int type);
+int		EVP_PKEY_id(const EVP_PKEY *pkey);
+int		EVP_PKEY_base_id(const EVP_PKEY *pkey);
 int		EVP_PKEY_bits(EVP_PKEY *pkey);
 int		EVP_PKEY_size(EVP_PKEY *pkey);
-int 		EVP_PKEY_assign(EVP_PKEY *pkey,int type,char *key);
+int 		EVP_PKEY_set_type(EVP_PKEY *pkey,int type);
+int		EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len);
+int 		EVP_PKEY_assign(EVP_PKEY *pkey,int type,void *key);
+void *		EVP_PKEY_get0(EVP_PKEY *pkey);
 
 #ifndef OPENSSL_NO_RSA
 struct rsa_st;
@@ -899,6 +888,15 @@
 
 int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
 
+int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
+				int indent, ASN1_PCTX *pctx);
+int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
+				int indent, ASN1_PCTX *pctx);
+int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
+				int indent, ASN1_PCTX *pctx);
+
+int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
+
 int EVP_CIPHER_type(const EVP_CIPHER *ctx);
 
 /* calls methods */
@@ -916,6 +914,10 @@
 int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
 			   const unsigned char *salt, int saltlen, int iter,
 			   int keylen, unsigned char *out);
+int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
+			   const unsigned char *salt, int saltlen, int iter,
+			   const EVP_MD *digest,
+		      int keylen, unsigned char *out);
 int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
 			 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md,
 			 int en_de);
@@ -924,27 +926,260 @@
 
 int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
 	     ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de);
+
+/* PBE type */
+
+/* Can appear as the outermost AlgorithmIdentifier */
+#define EVP_PBE_TYPE_OUTER	0x0
+/* Is an PRF type OID */
+#define EVP_PBE_TYPE_PRF	0x1
+
+int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid,
+	     EVP_PBE_KEYGEN *keygen);
 int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
 		    EVP_PBE_KEYGEN *keygen);
+int EVP_PBE_find(int type, int pbe_nid,
+			int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen);
 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
+#define ASN1_PKEY_ALIAS		0x1
+#define ASN1_PKEY_DYNAMIC	0x2
+#define ASN1_PKEY_SIGPARAM_NULL	0x4
 
-void EVP_add_alg_module(void);
+#define ASN1_PKEY_CTRL_PKCS7_SIGN	0x1
+#define ASN1_PKEY_CTRL_PKCS7_ENCRYPT	0x2
+#define ASN1_PKEY_CTRL_DEFAULT_MD_NID	0x3
+#define ASN1_PKEY_CTRL_CMS_SIGN		0x5
+#define ASN1_PKEY_CTRL_CMS_ENVELOPE	0x7
+
+int EVP_PKEY_asn1_get_count(void);
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx);
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type);
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
+					const char *str, int len);
+int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth);
+int EVP_PKEY_asn1_add_alias(int to, int from);
+int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, int *ppkey_flags,
+				const char **pinfo, const char **ppem_str,
+					const EVP_PKEY_ASN1_METHOD *ameth);
+
+const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey);
+EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
+					const char *pem_str, const char *info);
+void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, 
+			const EVP_PKEY_ASN1_METHOD *src);
+void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *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));
+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));
+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));
+
+void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
+		void (*pkey_free)(EVP_PKEY *pkey));
+void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
+		int (*pkey_ctrl)(EVP_PKEY *pkey, int op,
+							long arg1, void *arg2));
+
+
+#define EVP_PKEY_OP_UNDEFINED		0
+#define EVP_PKEY_OP_PARAMGEN		(1<<1)
+#define EVP_PKEY_OP_KEYGEN		(1<<2)
+#define EVP_PKEY_OP_SIGN		(1<<3)
+#define EVP_PKEY_OP_VERIFY		(1<<4)
+#define EVP_PKEY_OP_VERIFYRECOVER	(1<<5)
+#define EVP_PKEY_OP_SIGNCTX		(1<<6)
+#define EVP_PKEY_OP_VERIFYCTX		(1<<7)
+#define EVP_PKEY_OP_ENCRYPT		(1<<8)
+#define EVP_PKEY_OP_DECRYPT		(1<<9)
+#define EVP_PKEY_OP_DERIVE		(1<<10)
+
+#define EVP_PKEY_OP_TYPE_SIG	\
+	(EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \
+		| EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX)
+
+#define EVP_PKEY_OP_TYPE_CRYPT \
+	(EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT)
+
+#define EVP_PKEY_OP_TYPE_NOGEN \
+	(EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE)
+
+#define EVP_PKEY_OP_TYPE_GEN \
+		(EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)
+
+#define	 EVP_PKEY_CTX_set_signature_md(ctx, md)	\
+		EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,  \
+					EVP_PKEY_CTRL_MD, 0, (void *)md)
+
+#define EVP_PKEY_CTRL_MD		1
+#define EVP_PKEY_CTRL_PEER_KEY		2
+
+#define EVP_PKEY_CTRL_PKCS7_ENCRYPT	3
+#define EVP_PKEY_CTRL_PKCS7_DECRYPT	4
+
+#define EVP_PKEY_CTRL_PKCS7_SIGN	5
+
+#define EVP_PKEY_CTRL_SET_MAC_KEY	6
+
+#define EVP_PKEY_CTRL_DIGESTINIT	7
+
+/* Used by GOST key encryption in TLS */
+#define EVP_PKEY_CTRL_SET_IV 		8
+
+#define EVP_PKEY_CTRL_CMS_ENCRYPT	9
+#define EVP_PKEY_CTRL_CMS_DECRYPT	10
+#define EVP_PKEY_CTRL_CMS_SIGN		11
+
+#define EVP_PKEY_ALG_CTRL		0x1000
+
+
+#define EVP_PKEY_FLAG_AUTOARGLEN	2
+
+const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type);
+EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags);
+void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth);
+int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth);
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
+EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
+EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx);
+void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
+				int cmd, int p1, void *p2);
+int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
+						const char *value);
+
+int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx);
+void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen);
+
+EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
+				unsigned char *key, int keylen);
+
+void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data);
+void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx);
+EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx);
+
+EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx);
+
+void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data);
+void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
+			unsigned char *sig, size_t *siglen,
+			const unsigned char *tbs, size_t tbslen);
+int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
+			const unsigned char *sig, size_t siglen,
+			const unsigned char *tbs, size_t tbslen);
+int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
+			unsigned char *rout, size_t *routlen,
+			const unsigned char *sig, size_t siglen);
+int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
+			unsigned char *out, size_t *outlen,
+			const unsigned char *in, size_t inlen);
+int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
+			unsigned char *out, size_t *outlen,
+			const unsigned char *in, size_t inlen);
+
+int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
+int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
+
+typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
+int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
+
+void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb);
+EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx);
+
+void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
+	int (*init)(EVP_PKEY_CTX *ctx));
+
+void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
+	int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src));
+
+void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
+	void (*cleanup)(EVP_PKEY_CTX *ctx));
+
+void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
+	int (*paramgen_init)(EVP_PKEY_CTX *ctx),
+	int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey));
+
+void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
+	int (*keygen_init)(EVP_PKEY_CTX *ctx),
+	int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey));
+
+void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
+	int (*sign_init)(EVP_PKEY_CTX *ctx),
+	int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					const unsigned char *tbs, size_t tbslen));
+
+void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
+	int (*verify_init)(EVP_PKEY_CTX *ctx),
+	int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
+					const unsigned char *tbs, size_t tbslen));
+
+void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
+	int (*verify_recover_init)(EVP_PKEY_CTX *ctx),
+	int (*verify_recover)(EVP_PKEY_CTX *ctx,
+					unsigned char *sig, size_t *siglen,
+					const unsigned char *tbs, size_t tbslen));
+
+void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
+	int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
+	int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+					EVP_MD_CTX *mctx));
+
+void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
+	int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
+	int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,int siglen,
+					EVP_MD_CTX *mctx));
+
+void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
+	int (*encrypt_init)(EVP_PKEY_CTX *ctx),
+	int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+					const unsigned char *in, size_t inlen));
+
+void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
+	int (*decrypt_init)(EVP_PKEY_CTX *ctx),
+	int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+					const unsigned char *in, size_t inlen));
+
+void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
+	int (*derive_init)(EVP_PKEY_CTX *ctx),
+	int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen));
+
+void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
+	int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2),
+	int (*ctrl_str)(EVP_PKEY_CTX *ctx,
+					const char *type, const char *value));
 
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -956,46 +1191,66 @@
 
 /* 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_DO_SIGVER_INIT				 161
 #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_COPY			 163
 #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
+#define EVP_F_EVP_MD_SIZE				 162
 #define EVP_F_EVP_OPENINIT				 102
 #define EVP_F_EVP_PBE_ALG_ADD				 115
+#define EVP_F_EVP_PBE_ALG_ADD_TYPE			 160
 #define EVP_F_EVP_PBE_CIPHERINIT			 116
 #define EVP_F_EVP_PKCS82PKEY				 111
+#define EVP_F_EVP_PKCS82PKEY_BROKEN			 136
 #define EVP_F_EVP_PKEY2PKCS8_BROKEN			 113
 #define EVP_F_EVP_PKEY_COPY_PARAMETERS			 103
+#define EVP_F_EVP_PKEY_CTX_CTRL				 137
+#define EVP_F_EVP_PKEY_CTX_CTRL_STR			 150
+#define EVP_F_EVP_PKEY_CTX_DUP				 156
 #define EVP_F_EVP_PKEY_DECRYPT				 104
+#define EVP_F_EVP_PKEY_DECRYPT_INIT			 138
+#define EVP_F_EVP_PKEY_DECRYPT_OLD			 151
+#define EVP_F_EVP_PKEY_DERIVE				 153
+#define EVP_F_EVP_PKEY_DERIVE_INIT			 154
+#define EVP_F_EVP_PKEY_DERIVE_SET_PEER			 155
 #define EVP_F_EVP_PKEY_ENCRYPT				 105
+#define EVP_F_EVP_PKEY_ENCRYPT_INIT			 139
+#define EVP_F_EVP_PKEY_ENCRYPT_OLD			 152
 #define EVP_F_EVP_PKEY_GET1_DH				 119
 #define EVP_F_EVP_PKEY_GET1_DSA				 120
 #define EVP_F_EVP_PKEY_GET1_ECDSA			 130
 #define EVP_F_EVP_PKEY_GET1_EC_KEY			 131
 #define EVP_F_EVP_PKEY_GET1_RSA				 121
+#define EVP_F_EVP_PKEY_KEYGEN				 146
+#define EVP_F_EVP_PKEY_KEYGEN_INIT			 147
 #define EVP_F_EVP_PKEY_NEW				 106
+#define EVP_F_EVP_PKEY_PARAMGEN				 148
+#define EVP_F_EVP_PKEY_PARAMGEN_INIT			 149
+#define EVP_F_EVP_PKEY_SIGN				 140
+#define EVP_F_EVP_PKEY_SIGN_INIT			 141
+#define EVP_F_EVP_PKEY_VERIFY				 142
+#define EVP_F_EVP_PKEY_VERIFY_INIT			 143
+#define EVP_F_EVP_PKEY_VERIFY_RECOVER			 144
+#define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT		 145
 #define EVP_F_EVP_RIJNDAEL				 126
 #define EVP_F_EVP_SIGNFINAL				 107
 #define EVP_F_EVP_VERIFYFINAL				 108
+#define EVP_F_INT_CTX_NEW				 157
 #define EVP_F_PKCS5_PBE_KEYIVGEN			 117
 #define EVP_F_PKCS5_V2_PBE_KEYIVGEN			 118
 #define EVP_F_PKCS8_SET_BROKEN				 112
+#define EVP_F_PKEY_SET_TYPE				 158
 #define EVP_F_RC2_MAGIC_TO_METH				 109
 #define EVP_F_RC5_CTRL					 125
 
@@ -1007,41 +1262,52 @@
 #define EVP_R_BAD_KEY_LENGTH				 137
 #define EVP_R_BN_DECODE_ERROR				 112
 #define EVP_R_BN_PUBKEY_ERROR				 113
+#define EVP_R_BUFFER_TOO_SMALL				 155
 #define EVP_R_CAMELLIA_KEY_SETUP_FAILED			 157
 #define EVP_R_CIPHER_PARAMETER_ERROR			 122
+#define EVP_R_COMMAND_NOT_SUPPORTED			 147
 #define EVP_R_CTRL_NOT_IMPLEMENTED			 132
 #define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED		 133
 #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_DIFFERENT_PARAMETERS			 153
 #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_DIGEST				 152
 #define EVP_R_INVALID_KEY_LENGTH			 130
+#define EVP_R_INVALID_OPERATION				 148
 #define EVP_R_IV_TOO_LARGE				 102
 #define EVP_R_KEYGEN_FAILURE				 120
+#define EVP_R_MESSAGE_DIGEST_IS_NULL			 159
+#define EVP_R_METHOD_NOT_SUPPORTED			 144
 #define EVP_R_MISSING_PARAMETERS			 103
 #define EVP_R_NO_CIPHER_SET				 131
+#define EVP_R_NO_DEFAULT_DIGEST				 158
 #define EVP_R_NO_DIGEST_SET				 139
 #define EVP_R_NO_DSA_PARAMETERS				 116
+#define EVP_R_NO_KEY_SET				 154
+#define EVP_R_NO_OPERATION_SET				 149
 #define EVP_R_NO_SIGN_FUNCTION_CONFIGURED		 104
 #define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED		 105
+#define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE	 150
+#define EVP_R_OPERATON_NOT_INITIALIZED			 151
 #define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE			 117
+#define EVP_R_PRIVATE_KEY_DECODE_ERROR			 145
+#define EVP_R_PRIVATE_KEY_ENCODE_ERROR			 146
 #define EVP_R_PUBLIC_KEY_NOT_RSA			 106
-#define EVP_R_UNKNOWN_OPTION				 149
+#define EVP_R_UNKNOWN_CIPHER				 160
+#define EVP_R_UNKNOWN_DIGEST				 161
 #define EVP_R_UNKNOWN_PBE_ALGORITHM			 121
 #define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS		 135
+#define EVP_R_UNSUPPORTED_ALGORITHM			 156
 #define EVP_R_UNSUPPORTED_CIPHER			 107
 #define EVP_R_UNSUPPORTED_KEYLENGTH			 123
 #define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION	 124
@@ -1051,7 +1317,6 @@
 #define EVP_R_UNSUPPORTED_SALT_TYPE			 126
 #define EVP_R_WRONG_FINAL_BLOCK_LENGTH			 109
 #define EVP_R_WRONG_PUBLIC_KEY_TYPE			 110
-#define EVP_R_SEED_KEY_SETUP_FAILED			 162
 
 #ifdef  __cplusplus
 }
diff --git a/include/openssl/fips.h b/include/openssl/fips.h
deleted file mode 100644
index 42bdcf2..0000000
--- a/include/openssl/fips.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/* ====================================================================
- * 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
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#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
deleted file mode 100644
index a175aaf..0000000
--- a/include/openssl/fips_rand.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* ====================================================================
- * 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
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#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 fc38ffb..1be0022 100644
--- a/include/openssl/hmac.h
+++ b/include/openssl/hmac.h
@@ -90,15 +90,16 @@
 
 #define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx) /* deprecated */
 
-void HMAC_Init(HMAC_CTX *ctx, const void *key, int len,
+int HMAC_Init(HMAC_CTX *ctx, const void *key, int len,
 	       const EVP_MD *md); /* deprecated */
-void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
+int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
 		  const EVP_MD *md, ENGINE *impl);
-void HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len);
-void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
+int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len);
+int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
 unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
 		    const unsigned char *d, size_t n, unsigned char *md,
 		    unsigned int *md_len);
+int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx);
 
 void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags);
 
diff --git a/include/openssl/lhash.h b/include/openssl/lhash.h
index d392d0c..e7d8763 100644
--- a/include/openssl/lhash.h
+++ b/include/openssl/lhash.h
@@ -98,42 +98,42 @@
  * macros if the functions are strictly internal. */
 
 /* First: "hash" functions */
-#define DECLARE_LHASH_HASH_FN(f_name,o_type) \
-	unsigned long f_name##_LHASH_HASH(const void *);
-#define IMPLEMENT_LHASH_HASH_FN(f_name,o_type) \
-	unsigned long f_name##_LHASH_HASH(const void *arg) { \
-		o_type a = (o_type)arg; \
-		return f_name(a); }
-#define LHASH_HASH_FN(f_name) f_name##_LHASH_HASH
+#define DECLARE_LHASH_HASH_FN(name, o_type) \
+	unsigned long name##_LHASH_HASH(const void *);
+#define IMPLEMENT_LHASH_HASH_FN(name, o_type) \
+	unsigned long name##_LHASH_HASH(const void *arg) { \
+		const o_type *a = arg; \
+		return name##_hash(a); }
+#define LHASH_HASH_FN(name) name##_LHASH_HASH
 
 /* Second: "compare" functions */
-#define DECLARE_LHASH_COMP_FN(f_name,o_type) \
-	int f_name##_LHASH_COMP(const void *, const void *);
-#define IMPLEMENT_LHASH_COMP_FN(f_name,o_type) \
-	int f_name##_LHASH_COMP(const void *arg1, const void *arg2) { \
-		o_type a = (o_type)arg1; \
-		o_type b = (o_type)arg2; \
-		return f_name(a,b); }
-#define LHASH_COMP_FN(f_name) f_name##_LHASH_COMP
+#define DECLARE_LHASH_COMP_FN(name, o_type) \
+	int name##_LHASH_COMP(const void *, const void *);
+#define IMPLEMENT_LHASH_COMP_FN(name, o_type) \
+	int name##_LHASH_COMP(const void *arg1, const void *arg2) { \
+		const o_type *a = arg1;		    \
+		const o_type *b = arg2; \
+		return name##_cmp(a,b); }
+#define LHASH_COMP_FN(name) name##_LHASH_COMP
 
 /* Third: "doall" functions */
-#define DECLARE_LHASH_DOALL_FN(f_name,o_type) \
-	void f_name##_LHASH_DOALL(void *);
-#define IMPLEMENT_LHASH_DOALL_FN(f_name,o_type) \
-	void f_name##_LHASH_DOALL(void *arg) { \
-		o_type a = (o_type)arg; \
-		f_name(a); }
-#define LHASH_DOALL_FN(f_name) f_name##_LHASH_DOALL
+#define DECLARE_LHASH_DOALL_FN(name, o_type) \
+	void name##_LHASH_DOALL(void *);
+#define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \
+	void name##_LHASH_DOALL(void *arg) { \
+		o_type *a = arg; \
+		name##_doall(a); }
+#define LHASH_DOALL_FN(name) name##_LHASH_DOALL
 
 /* Fourth: "doall_arg" functions */
-#define DECLARE_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \
-	void f_name##_LHASH_DOALL_ARG(void *, void *);
-#define IMPLEMENT_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \
-	void f_name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
-		o_type a = (o_type)arg1; \
-		a_type b = (a_type)arg2; \
-		f_name(a,b); }
-#define LHASH_DOALL_ARG_FN(f_name) f_name##_LHASH_DOALL_ARG
+#define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
+	void name##_LHASH_DOALL_ARG(void *, void *);
+#define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
+	void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
+		o_type *a = arg1; \
+		a_type *b = arg2; \
+		name##_doall_arg(a, b); }
+#define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG
 
 typedef struct lhash_st
 	{
@@ -163,7 +163,8 @@
 	unsigned long num_hash_comps;
 
 	int error;
-	} LHASH;
+	} _LHASH;	/* Do not use _LHASH directly, use LHASH_OF
+			 * and friends */
 
 #define LH_LOAD_MULT	256
 
@@ -171,27 +172,67 @@
  * in lh_insert(). */
 #define lh_error(lh)	((lh)->error)
 
-LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c);
-void lh_free(LHASH *lh);
-void *lh_insert(LHASH *lh, void *data);
-void *lh_delete(LHASH *lh, const void *data);
-void *lh_retrieve(LHASH *lh, const void *data);
-void lh_doall(LHASH *lh, LHASH_DOALL_FN_TYPE func);
-void lh_doall_arg(LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg);
+_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c);
+void lh_free(_LHASH *lh);
+void *lh_insert(_LHASH *lh, void *data);
+void *lh_delete(_LHASH *lh, const void *data);
+void *lh_retrieve(_LHASH *lh, const void *data);
+void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func);
+void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg);
 unsigned long lh_strhash(const char *c);
-unsigned long lh_num_items(const LHASH *lh);
+unsigned long lh_num_items(const _LHASH *lh);
 
 #ifndef OPENSSL_NO_FP_API
-void lh_stats(const LHASH *lh, FILE *out);
-void lh_node_stats(const LHASH *lh, FILE *out);
-void lh_node_usage_stats(const LHASH *lh, FILE *out);
+void lh_stats(const _LHASH *lh, FILE *out);
+void lh_node_stats(const _LHASH *lh, FILE *out);
+void lh_node_usage_stats(const _LHASH *lh, FILE *out);
 #endif
 
 #ifndef OPENSSL_NO_BIO
-void lh_stats_bio(const LHASH *lh, BIO *out);
-void lh_node_stats_bio(const LHASH *lh, BIO *out);
-void lh_node_usage_stats_bio(const LHASH *lh, BIO *out);
+void lh_stats_bio(const _LHASH *lh, BIO *out);
+void lh_node_stats_bio(const _LHASH *lh, BIO *out);
+void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out);
 #endif
+
+/* Type checking... */
+
+#define LHASH_OF(type) struct lhash_st_##type
+
+#define DECLARE_LHASH_OF(type) LHASH_OF(type) { int dummy; }
+
+#define CHECKED_LHASH_OF(type,lh) \
+  ((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh))
+
+/* Define wrapper functions. */
+#define LHM_lh_new(type, name) \
+  ((LHASH_OF(type) *)lh_new(LHASH_HASH_FN(name), LHASH_COMP_FN(name)))
+#define LHM_lh_error(type, lh) \
+  lh_error(CHECKED_LHASH_OF(type,lh))
+#define LHM_lh_insert(type, lh, inst) \
+  ((type *)lh_insert(CHECKED_LHASH_OF(type, lh), \
+		     CHECKED_PTR_OF(type, inst)))
+#define LHM_lh_retrieve(type, lh, inst) \
+  ((type *)lh_retrieve(CHECKED_LHASH_OF(type, lh), \
+		       CHECKED_PTR_OF(type, inst)))
+#define LHM_lh_delete(type, lh, inst) \
+  ((type *)lh_delete(CHECKED_LHASH_OF(type, lh),			\
+		     CHECKED_PTR_OF(type, inst)))
+#define LHM_lh_doall(type, lh,fn) lh_doall(CHECKED_LHASH_OF(type, lh), fn)
+#define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \
+  lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg))
+#define LHM_lh_num_items(type, lh) lh_num_items(CHECKED_LHASH_OF(type, lh))
+#define LHM_lh_down_load(type, lh) (CHECKED_LHASH_OF(type, lh)->down_load)
+#define LHM_lh_node_stats_bio(type, lh, out) \
+  lh_node_stats_bio(CHECKED_LHASH_OF(type, lh), out)
+#define LHM_lh_node_usage_stats_bio(type, lh, out) \
+  lh_node_usage_stats_bio(CHECKED_LHASH_OF(type, lh), out)
+#define LHM_lh_stats_bio(type, lh, out) \
+  lh_stats_bio(CHECKED_LHASH_OF(type, lh), out)
+#define LHM_lh_free(type, lh) lh_free(CHECKED_LHASH_OF(type, lh))
+
+DECLARE_LHASH_OF(OPENSSL_STRING);
+DECLARE_LHASH_OF(OPENSSL_CSTRING);
+
 #ifdef  __cplusplus
 }
 #endif
diff --git a/include/openssl/md4.h b/include/openssl/md4.h
index ba1fe4a..c3ed9b3 100644
--- a/include/openssl/md4.h
+++ b/include/openssl/md4.h
@@ -77,7 +77,7 @@
  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  */
 
-#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#if defined(__LP32__)
 #define MD4_LONG unsigned long
 #elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
 #define MD4_LONG unsigned long
@@ -105,9 +105,6 @@
 	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 0761f84..4cbf843 100644
--- a/include/openssl/md5.h
+++ b/include/openssl/md5.h
@@ -77,7 +77,7 @@
  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  */
 
-#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#if defined(__LP32__)
 #define MD5_LONG unsigned long
 #elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
 #define MD5_LONG unsigned long
@@ -105,9 +105,6 @@
 	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/modes.h b/include/openssl/modes.h
new file mode 100644
index 0000000..af8d97d
--- /dev/null
+++ b/include/openssl/modes.h
@@ -0,0 +1,59 @@
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
+ *
+ * Rights for redistribution and usage in source and binary
+ * forms are granted according to the OpenSSL license.
+ */
+
+#include <stddef.h>
+
+typedef void (*block128_f)(const unsigned char in[16],
+			unsigned char out[16],
+			const void *key);
+
+typedef void (*cbc128_f)(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], int enc);
+
+void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], block128_f block);
+void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], block128_f block);
+
+void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], unsigned char ecount_buf[16],
+			unsigned int *num, block128_f block);
+
+void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], int *num,
+			block128_f block);
+
+void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], int *num,
+			int enc, block128_f block);
+void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
+			size_t length, const void *key,
+			unsigned char ivec[16], int *num,
+			int enc, block128_f block);
+void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
+			size_t bits, const void *key,
+			unsigned char ivec[16], int *num,
+			int enc, block128_f block);
+
+size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], block128_f block);
+size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], cbc128_f cbc);
+size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], block128_f block);
+size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], cbc128_f cbc);
diff --git a/include/openssl/objects.h b/include/openssl/objects.h
index 7242f76..bd0ee52 100644
--- a/include/openssl/objects.h
+++ b/include/openssl/objects.h
@@ -1011,10 +1011,91 @@
 int		OBJ_ln2nid(const char *s);
 int		OBJ_sn2nid(const char *s);
 int		OBJ_cmp(const ASN1_OBJECT *a,const ASN1_OBJECT *b);
-const char *	OBJ_bsearch(const char *key,const char *base,int num,int size,
-	int (*cmp)(const void *, const void *));
-const char *	OBJ_bsearch_ex(const char *key,const char *base,int num,
-	int size, int (*cmp)(const void *, const void *), int flags);
+const void *	OBJ_bsearch_(const void *key,const void *base,int num,int size,
+			     int (*cmp)(const void *, const void *));
+const void *	OBJ_bsearch_ex_(const void *key,const void *base,int num,
+				int size,
+				int (*cmp)(const void *, const void *),
+				int flags);
+
+#define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm)	\
+  static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \
+  static int nm##_cmp(type1 const *, type2 const *); \
+  scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num)
+
+#define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp)	\
+  _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp)
+#define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm)	\
+  type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num)
+
+/*
+ * Unsolved problem: if a type is actually a pointer type, like
+ * nid_triple is, then its impossible to get a const where you need
+ * it. Consider:
+ *
+ * typedef int nid_triple[3];
+ * const void *a_;
+ * const nid_triple const *a = a_;
+ *
+ * The assignement discards a const because what you really want is:
+ *
+ * const int const * const *a = a_;
+ *
+ * But if you do that, you lose the fact that a is an array of 3 ints,
+ * which breaks comparison functions.
+ *
+ * Thus we end up having to cast, sadly, or unpack the
+ * declarations. Or, as I finally did in this case, delcare nid_triple
+ * to be a struct, which it should have been in the first place.
+ *
+ * Ben, August 2008.
+ *
+ * Also, strictly speaking not all types need be const, but handling
+ * the non-constness means a lot of complication, and in practice
+ * comparison routines do always not touch their arguments.
+ */
+
+#define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm)	\
+  static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)	\
+      { \
+      type1 const *a = a_; \
+      type2 const *b = b_; \
+      return nm##_cmp(a,b); \
+      } \
+  static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \
+      { \
+      return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \
+					nm##_cmp_BSEARCH_CMP_FN); \
+      } \
+      extern void dummy_prototype(void)
+
+#define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm)	\
+  static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)	\
+      { \
+      type1 const *a = a_; \
+      type2 const *b = b_; \
+      return nm##_cmp(a,b); \
+      } \
+  type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \
+      { \
+      return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \
+					nm##_cmp_BSEARCH_CMP_FN); \
+      } \
+      extern void dummy_prototype(void)
+
+#define OBJ_bsearch(type1,key,type2,base,num,cmp)			       \
+  ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \
+			 num,sizeof(type2),				\
+			 ((void)CHECKED_PTR_OF(type1,cmp##_type_1),	\
+			  (void)CHECKED_PTR_OF(type2,cmp##_type_2),	\
+			  cmp##_BSEARCH_CMP_FN)))
+
+#define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags)			\
+  ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \
+			 num,sizeof(type2),				\
+			 ((void)CHECKED_PTR_OF(type1,cmp##_type_1),	\
+			  (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \
+			  cmp##_BSEARCH_CMP_FN)),flags)
 
 int		OBJ_new_nid(int num);
 int		OBJ_add_object(const ASN1_OBJECT *obj);
@@ -1022,6 +1103,14 @@
 void		OBJ_cleanup(void );
 int		OBJ_create_objects(BIO *in);
 
+int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid);
+int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid);
+int OBJ_add_sigid(int signid, int dig_id, int pkey_id);
+void OBJ_sigid_free(void);
+
+extern int obj_cleanup_defer;
+void check_defer(int nid);
+
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
  * made after this point may be overwritten when the script is next run.
diff --git a/include/openssl/ocsp.h b/include/openssl/ocsp.h
index a0577a7..31e4574 100644
--- a/include/openssl/ocsp.h
+++ b/include/openssl/ocsp.h
@@ -64,6 +64,7 @@
 #ifndef HEADER_OCSP_H
 #define HEADER_OCSP_H
 
+#include <openssl/ossl_typ.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 #include <openssl/safestack.h>
@@ -394,17 +395,20 @@
 #define ASN1_BIT_STRING_digest(data,type,md,len) \
 	ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len)
 
-#define OCSP_CERTID_dup(cid) ASN1_dup_of(OCSP_CERTID,i2d_OCSP_CERTID,d2i_OCSP_CERTID,cid)
-
 #define OCSP_CERTSTATUS_dup(cs)\
                 (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\
 		(char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs))
 
+OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id);
+
 OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, char *path, OCSP_REQUEST *req);
 OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req,
 								int maxline);
 int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx);
 void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx);
+int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req);
+int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx,
+		const char *name, const char *value);
 
 OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer);
 
@@ -474,11 +478,6 @@
 			X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
 			STACK_OF(X509) *certs, unsigned long flags);
 
-ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d,
-				void *data, STACK_OF(ASN1_OBJECT) *sk);
-#define ASN1_STRING_encode_of(type,s,i2d,data,sk) \
-	ASN1_STRING_encode(s, CHECKED_I2D_OF(type, i2d), data, sk)
-
 X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim);
 
 X509_EXTENSION *OCSP_accept_responses_new(char **oids);
@@ -547,9 +546,9 @@
 DECLARE_ASN1_FUNCTIONS(OCSP_CRLID)
 DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC)
 
-char *OCSP_response_status_str(long s);
-char *OCSP_cert_status_str(long s);
-char *OCSP_crl_reason_str(long s);
+const char *OCSP_response_status_str(long s);
+const char *OCSP_cert_status_str(long s);
+const char *OCSP_crl_reason_str(long s);
 
 int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* a, unsigned long flags);
 int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags);
@@ -582,7 +581,8 @@
 #define OCSP_F_OCSP_REQUEST_VERIFY			 116
 #define OCSP_F_OCSP_RESPONSE_GET1_BASIC			 111
 #define OCSP_F_OCSP_SENDREQ_BIO				 112
-#define OCSP_F_PARSE_HTTP_LINE1				 117
+#define OCSP_F_OCSP_SENDREQ_NBIO			 117
+#define OCSP_F_PARSE_HTTP_LINE1				 118
 #define OCSP_F_REQUEST_VERIFY				 113
 
 /* Reason codes. */
diff --git a/include/openssl/opensslconf.h b/include/openssl/opensslconf.h
index 4aa0330..394d1d4 100644
--- a/include/openssl/opensslconf.h
+++ b/include/openssl/opensslconf.h
@@ -8,18 +8,9 @@
 #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
-#ifndef OPENSSL_NO_CMS
-# define OPENSSL_NO_CMS
-#endif
 #ifndef OPENSSL_NO_GMP
 # define OPENSSL_NO_GMP
 #endif
@@ -35,9 +26,6 @@
 #ifndef OPENSSL_NO_MD2
 # define OPENSSL_NO_MD2
 #endif
-#ifndef OPENSSL_NO_MDC2
-# define OPENSSL_NO_MDC2
-#endif
 #ifndef OPENSSL_NO_RC5
 # define OPENSSL_NO_RC5
 #endif
@@ -47,6 +35,12 @@
 #ifndef OPENSSL_NO_SEED
 # define OPENSSL_NO_SEED
 #endif
+#ifndef OPENSSL_NO_STORE
+# define OPENSSL_NO_STORE
+#endif
+#ifndef OPENSSL_NO_WHRLPOOL
+# define OPENSSL_NO_WHRLPOOL
+#endif
 
 #endif /* OPENSSL_DOING_MAKEDEPEND */
 
@@ -65,18 +59,9 @@
 # if defined(OPENSSL_NO_BF) && !defined(NO_BF)
 #  define NO_BF
 # endif
-# if defined(OPENSSL_NO_CAMELLIA) && !defined(NO_CAMELLIA)
-#  define NO_CAMELLIA
-# endif
-# if defined(OPENSSL_NO_CAPIENG) && !defined(NO_CAPIENG)
-#  define NO_CAPIENG
-# endif
 # if defined(OPENSSL_NO_CAST) && !defined(NO_CAST)
 #  define NO_CAST
 # endif
-# if defined(OPENSSL_NO_CMS) && !defined(NO_CMS)
-#  define NO_CMS
-# endif
 # if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
 #  define NO_GMP
 # endif
@@ -92,9 +77,6 @@
 # if defined(OPENSSL_NO_MD2) && !defined(NO_MD2)
 #  define NO_MD2
 # endif
-# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
-#  define NO_MDC2
-# endif
 # if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
 #  define NO_RC5
 # endif
@@ -104,25 +86,16 @@
 # if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
 #  define NO_SEED
 # endif
+# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE)
+#  define NO_STORE
+# endif
+# if defined(OPENSSL_NO_WHRLPOOL) && !defined(NO_WHRLPOOL)
+#  define NO_WHRLPOOL
+# 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
 
@@ -186,14 +159,9 @@
 /* Should we define BN_DIV2W here? */
 
 /* Only one for the following should be defined */
-/* The prime number generation stuff may not work when
- * EIGHT_BIT but I don't care since I've only used this mode
- * for debuging the bignum libraries */
 #undef SIXTY_FOUR_BIT_LONG
 #undef SIXTY_FOUR_BIT
 #define THIRTY_TWO_BIT
-#undef SIXTEEN_BIT
-#undef EIGHT_BIT
 #endif
 
 #if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
diff --git a/include/openssl/opensslv.h b/include/openssl/opensslv.h
index 3d794d9..cbe5264 100644
--- a/include/openssl/opensslv.h
+++ b/include/openssl/opensslv.h
@@ -12,7 +12,7 @@
  * 0.9.3-beta2    0x00903002 (same as ...beta2-dev)
  * 0.9.3	  0x0090300f
  * 0.9.3a	  0x0090301f
- * 0.9.4	  0x0090400f
+ * 0.9.4 	  0x0090400f
  * 1.2.3z	  0x102031af
  *
  * For continuity reasons (because 0.9.5 is already out, and is coded
@@ -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	0x009080dfL
+#define OPENSSL_VERSION_NUMBER	0x1000000fL
 #ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.8m-fips 25 Feb 2010"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.0-fips 29 Mar 2010"
 #else
-#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.8m 25 Feb 2010"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.0 29 Mar 2010"
 #endif
 #define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
 
@@ -83,7 +83,7 @@
  * should only keep the versions that are binary compatible with the current.
  */
 #define SHLIB_VERSION_HISTORY ""
-#define SHLIB_VERSION_NUMBER "0.9.8"
+#define SHLIB_VERSION_NUMBER "1.0.0"
 
 
 #endif /* HEADER_OPENSSLV_H */
diff --git a/include/openssl/ossl_typ.h b/include/openssl/ossl_typ.h
index 0e7a380..12bd701 100644
--- a/include/openssl/ossl_typ.h
+++ b/include/openssl/ossl_typ.h
@@ -95,6 +95,8 @@
 typedef int ASN1_NULL;
 #endif
 
+typedef struct asn1_pctx_st ASN1_PCTX;
+
 #ifdef OPENSSL_SYS_WIN32
 #undef X509_NAME
 #undef X509_EXTENSIONS
@@ -122,6 +124,11 @@
 typedef struct env_md_ctx_st EVP_MD_CTX;
 typedef struct evp_pkey_st EVP_PKEY;
 
+typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;
+
+typedef struct evp_pkey_method_st EVP_PKEY_METHOD;
+typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
+
 typedef struct dh_st DH;
 typedef struct dh_method DH_METHOD;
 
@@ -139,11 +146,14 @@
 typedef struct x509_st X509;
 typedef struct X509_algor_st X509_ALGOR;
 typedef struct X509_crl_st X509_CRL;
+typedef struct x509_crl_method_st X509_CRL_METHOD;
+typedef struct x509_revoked_st X509_REVOKED;
 typedef struct X509_name_st X509_NAME;
+typedef struct X509_pubkey_st X509_PUBKEY;
 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 pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;
 
 typedef struct v3_ext_ctx X509V3_CTX;
 typedef struct conf_st CONF;
@@ -157,12 +167,19 @@
 typedef struct st_ERR_FNS ERR_FNS;
 
 typedef struct engine_st ENGINE;
+typedef struct ssl_st SSL;
+typedef struct ssl_ctx_st SSL_CTX;
 
 typedef struct X509_POLICY_NODE_st X509_POLICY_NODE;
 typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL;
 typedef struct X509_POLICY_TREE_st X509_POLICY_TREE;
 typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE;
 
+typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID;
+typedef struct DIST_POINT_st DIST_POINT;
+typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT;
+typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS;
+
   /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */
 #define DECLARE_PKCS12_STACK_OF(type) /* Nothing */
 #define IMPLEMENT_PKCS12_STACK_OF(type) /* Nothing */
diff --git a/include/openssl/pem.h b/include/openssl/pem.h
index 6c193f1..22231c2 100644
--- a/include/openssl/pem.h
+++ b/include/openssl/pem.h
@@ -134,6 +134,7 @@
 #define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
 #define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
 #define PEM_STRING_ECPRIVATEKEY	"EC PRIVATE KEY"
+#define PEM_STRING_PARAMETERS	"PARAMETERS"
 #define PEM_STRING_CMS		"CMS"
 
   /* Note that this structure is initialised by PEM_SealInit and cleaned up
@@ -183,11 +184,8 @@
 	int num_recipient;
 	PEM_USER **recipient;
 
-#ifndef OPENSSL_NO_STACK
-	STACK *x509_chain;	/* certificate chain */
-#else
-	char *x509_chain;	/* certificate chain */
-#endif
+	/* XXX(ben): don#t think this is used! 
+		STACK *x509_chain;	/ * certificate chain */
 	EVP_MD *md;		/* signature type */
 
 	int md_enc;		/* is the md encrypted or not? */
@@ -224,28 +222,19 @@
 #define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \
 type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\
 { \
-    return (type*)PEM_ASN1_read(CHECKED_D2I_OF(type, d2i_##asn1), \
-				str, fp, \
-				CHECKED_PPTR_OF(type, x), \
-				cb, u); \
+return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \
 } 
 
 #define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \
 int PEM_write_##name(FILE *fp, type *x) \
 { \
-    return PEM_ASN1_write(CHECKED_I2D_OF(type, i2d_##asn1), \
-			  str, fp, \
-			  CHECKED_PTR_OF(type, x), \
-			  NULL, NULL, 0, NULL, NULL); \
+return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \
 }
 
 #define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \
 int PEM_write_##name(FILE *fp, const type *x) \
 { \
-    return PEM_ASN1_write(CHECKED_I2D_OF(const type, i2d_##asn1), \
-			  str, fp, \
-			  CHECKED_PTR_OF(const type, x), \
-			  NULL, NULL, 0, NULL, NULL); \
+return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \
 }
 
 #define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \
@@ -253,10 +242,7 @@
 	     unsigned char *kstr, int klen, pem_password_cb *cb, \
 		  void *u) \
 	{ \
-	    return PEM_ASN1_write(CHECKED_I2D_OF(type, i2d_##asn1), \
-				  str, fp, \
-				  CHECKED_PTR_OF(type, x), \
-				  enc, kstr, klen, cb, u); \
+	return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
 	}
 
 #define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \
@@ -264,10 +250,7 @@
 	     unsigned char *kstr, int klen, pem_password_cb *cb, \
 		  void *u) \
 	{ \
-	    return PEM_ASN1_write(CHECKED_I2D_OF(const type, i2d_##asn1), \
-				  str, fp, \
-				  CHECKED_PTR_OF(const type, x), \
-				  enc, kstr, klen, cb, u); \
+	return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
 	}
 
 #endif
@@ -275,48 +258,33 @@
 #define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
 type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\
 { \
-    return (type*)PEM_ASN1_read_bio(CHECKED_D2I_OF(type, d2i_##asn1), \
-				    str, bp, \
-				    CHECKED_PPTR_OF(type, x), \
-				    cb, u); \
+return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \
 }
 
 #define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
 int PEM_write_bio_##name(BIO *bp, type *x) \
 { \
-    return PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d_##asn1), \
-			      str, bp, \
-			      CHECKED_PTR_OF(type, x), \
-			      NULL, NULL, 0, NULL, NULL); \
+return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \
 }
 
 #define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
 int PEM_write_bio_##name(BIO *bp, const type *x) \
 { \
-    return PEM_ASN1_write_bio(CHECKED_I2D_OF(const type, i2d_##asn1), \
-			      str, bp, \
-			      CHECKED_PTR_OF(const type, x), \
-			      NULL, NULL, 0, NULL, NULL); \
+return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \
 }
 
 #define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
 int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
 	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
 	{ \
-	    return PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d_##asn1), \
-				      str, bp, \
-				      CHECKED_PTR_OF(type, x), \
-				      enc, kstr, klen, cb, u); \
+	return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \
 	}
 
 #define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
 int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
 	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
 	{ \
-	    return PEM_ASN1_write_bio(CHECKED_I2D_OF(const type, i2d_##asn1), \
-				      str, bp, \
-				      CHECKED_PTR_OF(const type, x), \
-				      enc, kstr, klen, cb, u); \
+	return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \
 	}
 
 #define IMPLEMENT_PEM_write(name, type, str, asn1) \
@@ -353,11 +321,10 @@
 
 /* These are the same except they are for the declarations */
 
-#if defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_NO_FP_API)
+#if defined(OPENSSL_NO_FP_API)
 
 #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
@@ -428,138 +395,6 @@
 	DECLARE_PEM_read(name, type) \
 	DECLARE_PEM_write_cb(name, type)
 
-#ifdef SSLEAY_MACROS
-
-#define PEM_write_SSL_SESSION(fp,x) \
-		PEM_ASN1_write((int (*)())i2d_SSL_SESSION, \
-			PEM_STRING_SSL_SESSION,fp, (char *)x, NULL,NULL,0,NULL,NULL)
-#define PEM_write_X509(fp,x) \
-		PEM_ASN1_write((int (*)())i2d_X509,PEM_STRING_X509,fp, \
-			(char *)x, NULL,NULL,0,NULL,NULL)
-#define PEM_write_X509_REQ(fp,x) PEM_ASN1_write( \
-		(int (*)())i2d_X509_REQ,PEM_STRING_X509_REQ,fp,(char *)x, \
-			NULL,NULL,0,NULL,NULL)
-#define PEM_write_X509_CRL(fp,x) \
-		PEM_ASN1_write((int (*)())i2d_X509_CRL,PEM_STRING_X509_CRL, \
-			fp,(char *)x, NULL,NULL,0,NULL,NULL)
-#define	PEM_write_RSAPrivateKey(fp,x,enc,kstr,klen,cb,u) \
-		PEM_ASN1_write((int (*)())i2d_RSAPrivateKey,PEM_STRING_RSA,fp,\
-			(char *)x,enc,kstr,klen,cb,u)
-#define	PEM_write_RSAPublicKey(fp,x) \
-		PEM_ASN1_write((int (*)())i2d_RSAPublicKey,\
-			PEM_STRING_RSA_PUBLIC,fp,(char *)x,NULL,NULL,0,NULL,NULL)
-#define	PEM_write_DSAPrivateKey(fp,x,enc,kstr,klen,cb,u) \
-		PEM_ASN1_write((int (*)())i2d_DSAPrivateKey,PEM_STRING_DSA,fp,\
-			(char *)x,enc,kstr,klen,cb,u)
-#define	PEM_write_PrivateKey(bp,x,enc,kstr,klen,cb,u) \
-		PEM_ASN1_write((int (*)())i2d_PrivateKey,\
-		(((x)->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA),\
-			bp,(char *)x,enc,kstr,klen,cb,u)
-#define PEM_write_PKCS7(fp,x) \
-		PEM_ASN1_write((int (*)())i2d_PKCS7,PEM_STRING_PKCS7,fp, \
-			(char *)x, NULL,NULL,0,NULL,NULL)
-#define PEM_write_DHparams(fp,x) \
-		PEM_ASN1_write((int (*)())i2d_DHparams,PEM_STRING_DHPARAMS,fp,\
-			(char *)x,NULL,NULL,0,NULL,NULL)
-
-#define PEM_write_NETSCAPE_CERT_SEQUENCE(fp,x) \
-                PEM_ASN1_write((int (*)())i2d_NETSCAPE_CERT_SEQUENCE, \
-			PEM_STRING_X509,fp, \
-                        (char *)x, NULL,NULL,0,NULL,NULL)
-
-#define	PEM_read_SSL_SESSION(fp,x,cb,u) (SSL_SESSION *)PEM_ASN1_read( \
-	(char *(*)())d2i_SSL_SESSION,PEM_STRING_SSL_SESSION,fp,(char **)x,cb,u)
-#define	PEM_read_X509(fp,x,cb,u) (X509 *)PEM_ASN1_read( \
-	(char *(*)())d2i_X509,PEM_STRING_X509,fp,(char **)x,cb,u)
-#define	PEM_read_X509_REQ(fp,x,cb,u) (X509_REQ *)PEM_ASN1_read( \
-	(char *(*)())d2i_X509_REQ,PEM_STRING_X509_REQ,fp,(char **)x,cb,u)
-#define	PEM_read_X509_CRL(fp,x,cb,u) (X509_CRL *)PEM_ASN1_read( \
-	(char *(*)())d2i_X509_CRL,PEM_STRING_X509_CRL,fp,(char **)x,cb,u)
-#define	PEM_read_RSAPrivateKey(fp,x,cb,u) (RSA *)PEM_ASN1_read( \
-	(char *(*)())d2i_RSAPrivateKey,PEM_STRING_RSA,fp,(char **)x,cb,u)
-#define	PEM_read_RSAPublicKey(fp,x,cb,u) (RSA *)PEM_ASN1_read( \
-	(char *(*)())d2i_RSAPublicKey,PEM_STRING_RSA_PUBLIC,fp,(char **)x,cb,u)
-#define	PEM_read_DSAPrivateKey(fp,x,cb,u) (DSA *)PEM_ASN1_read( \
-	(char *(*)())d2i_DSAPrivateKey,PEM_STRING_DSA,fp,(char **)x,cb,u)
-#define	PEM_read_PrivateKey(fp,x,cb,u) (EVP_PKEY *)PEM_ASN1_read( \
-	(char *(*)())d2i_PrivateKey,PEM_STRING_EVP_PKEY,fp,(char **)x,cb,u)
-#define	PEM_read_PKCS7(fp,x,cb,u) (PKCS7 *)PEM_ASN1_read( \
-	(char *(*)())d2i_PKCS7,PEM_STRING_PKCS7,fp,(char **)x,cb,u)
-#define	PEM_read_DHparams(fp,x,cb,u) (DH *)PEM_ASN1_read( \
-	(char *(*)())d2i_DHparams,PEM_STRING_DHPARAMS,fp,(char **)x,cb,u)
-
-#define PEM_read_NETSCAPE_CERT_SEQUENCE(fp,x,cb,u) \
-		(NETSCAPE_CERT_SEQUENCE *)PEM_ASN1_read( \
-        (char *(*)())d2i_NETSCAPE_CERT_SEQUENCE,PEM_STRING_X509,fp,\
-							(char **)x,cb,u)
-
-#define PEM_write_bio_X509(bp,x) \
-		PEM_ASN1_write_bio((int (*)())i2d_X509,PEM_STRING_X509,bp, \
-			(char *)x, NULL,NULL,0,NULL,NULL)
-#define PEM_write_bio_X509_REQ(bp,x) PEM_ASN1_write_bio( \
-		(int (*)())i2d_X509_REQ,PEM_STRING_X509_REQ,bp,(char *)x, \
-			NULL,NULL,0,NULL,NULL)
-#define PEM_write_bio_X509_CRL(bp,x) \
-		PEM_ASN1_write_bio((int (*)())i2d_X509_CRL,PEM_STRING_X509_CRL,\
-			bp,(char *)x, NULL,NULL,0,NULL,NULL)
-#define	PEM_write_bio_RSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
-		PEM_ASN1_write_bio((int (*)())i2d_RSAPrivateKey,PEM_STRING_RSA,\
-			bp,(char *)x,enc,kstr,klen,cb,u)
-#define	PEM_write_bio_RSAPublicKey(bp,x) \
-		PEM_ASN1_write_bio((int (*)())i2d_RSAPublicKey, \
-			PEM_STRING_RSA_PUBLIC,\
-			bp,(char *)x,NULL,NULL,0,NULL,NULL)
-#define	PEM_write_bio_DSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
-		PEM_ASN1_write_bio((int (*)())i2d_DSAPrivateKey,PEM_STRING_DSA,\
-			bp,(char *)x,enc,kstr,klen,cb,u)
-#define	PEM_write_bio_PrivateKey(bp,x,enc,kstr,klen,cb,u) \
-		PEM_ASN1_write_bio((int (*)())i2d_PrivateKey,\
-		(((x)->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA),\
-			bp,(char *)x,enc,kstr,klen,cb,u)
-#define PEM_write_bio_PKCS7(bp,x) \
-		PEM_ASN1_write_bio((int (*)())i2d_PKCS7,PEM_STRING_PKCS7,bp, \
-			(char *)x, NULL,NULL,0,NULL,NULL)
-#define PEM_write_bio_DHparams(bp,x) \
-		PEM_ASN1_write_bio((int (*)())i2d_DHparams,PEM_STRING_DHPARAMS,\
-			bp,(char *)x,NULL,NULL,0,NULL,NULL)
-#define PEM_write_bio_DSAparams(bp,x) \
-		PEM_ASN1_write_bio((int (*)())i2d_DSAparams, \
-			PEM_STRING_DSAPARAMS,bp,(char *)x,NULL,NULL,0,NULL,NULL)
-
-#define PEM_write_bio_NETSCAPE_CERT_SEQUENCE(bp,x) \
-                PEM_ASN1_write_bio((int (*)())i2d_NETSCAPE_CERT_SEQUENCE, \
-			PEM_STRING_X509,bp, \
-                        (char *)x, NULL,NULL,0,NULL,NULL)
-
-#define	PEM_read_bio_X509(bp,x,cb,u) (X509 *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_X509,PEM_STRING_X509,bp,(char **)x,cb,u)
-#define	PEM_read_bio_X509_REQ(bp,x,cb,u) (X509_REQ *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_X509_REQ,PEM_STRING_X509_REQ,bp,(char **)x,cb,u)
-#define	PEM_read_bio_X509_CRL(bp,x,cb,u) (X509_CRL *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_X509_CRL,PEM_STRING_X509_CRL,bp,(char **)x,cb,u)
-#define	PEM_read_bio_RSAPrivateKey(bp,x,cb,u) (RSA *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_RSAPrivateKey,PEM_STRING_RSA,bp,(char **)x,cb,u)
-#define	PEM_read_bio_RSAPublicKey(bp,x,cb,u) (RSA *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_RSAPublicKey,PEM_STRING_RSA_PUBLIC,bp,(char **)x,cb,u)
-#define	PEM_read_bio_DSAPrivateKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_DSAPrivateKey,PEM_STRING_DSA,bp,(char **)x,cb,u)
-#define	PEM_read_bio_PrivateKey(bp,x,cb,u) (EVP_PKEY *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_PrivateKey,PEM_STRING_EVP_PKEY,bp,(char **)x,cb,u)
-
-#define	PEM_read_bio_PKCS7(bp,x,cb,u) (PKCS7 *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_PKCS7,PEM_STRING_PKCS7,bp,(char **)x,cb,u)
-#define	PEM_read_bio_DHparams(bp,x,cb,u) (DH *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_DHparams,PEM_STRING_DHPARAMS,bp,(char **)x,cb,u)
-#define	PEM_read_bio_DSAparams(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
-	(char *(*)())d2i_DSAparams,PEM_STRING_DSAPARAMS,bp,(char **)x,cb,u)
-
-#define PEM_read_bio_NETSCAPE_CERT_SEQUENCE(bp,x,cb,u) \
-		(NETSCAPE_CERT_SEQUENCE *)PEM_ASN1_read_bio( \
-        (char *(*)())d2i_NETSCAPE_CERT_SEQUENCE,PEM_STRING_X509,bp,\
-							(char **)x,cb,u)
-
-#endif
-
 #if 1
 /* "userdata": new with OpenSSL 0.9.4 */
 typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata);
@@ -581,40 +416,25 @@
 	     pem_password_cb *cb, void *u);
 void *	PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp,
 			  void **x, pem_password_cb *cb, void *u);
-
-#define PEM_ASN1_read_bio_of(type,d2i,name,bp,x,cb,u) \
-    ((type*)PEM_ASN1_read_bio(CHECKED_D2I_OF(type, d2i), \
-			      name, bp,			\
-			      CHECKED_PPTR_OF(type, x), \
-			      cb, u))
-
-int	PEM_ASN1_write_bio(i2d_of_void *i2d,const char *name,BIO *bp,char *x,
+int	PEM_ASN1_write_bio(i2d_of_void *i2d,const char *name,BIO *bp, void *x,
 			   const EVP_CIPHER *enc,unsigned char *kstr,int klen,
 			   pem_password_cb *cb, void *u);
 
-#define PEM_ASN1_write_bio_of(type,i2d,name,bp,x,enc,kstr,klen,cb,u) \
-    (PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d), \
-			name, bp,		   \
-			CHECKED_PTR_OF(type, x), \
-			enc, kstr, klen, cb, u))
-
 STACK_OF(X509_INFO) *	PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u);
 int	PEM_X509_INFO_write_bio(BIO *bp,X509_INFO *xi, EVP_CIPHER *enc,
 		unsigned char *kstr, int klen, pem_password_cb *cd, void *u);
 #endif
 
-#ifndef OPENSSL_SYS_WIN16
 int	PEM_read(FILE *fp, char **name, char **header,
 		unsigned char **data,long *len);
 int	PEM_write(FILE *fp,char *name,char *hdr,unsigned char *data,long len);
 void *  PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
 		      pem_password_cb *cb, void *u);
 int	PEM_ASN1_write(i2d_of_void *i2d,const char *name,FILE *fp,
-		       char *x,const EVP_CIPHER *enc,unsigned char *kstr,
+		       void *x,const EVP_CIPHER *enc,unsigned char *kstr,
 		       int klen,pem_password_cb *callback, void *u);
 STACK_OF(X509_INFO) *	PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
 	pem_password_cb *cb, void *u);
-#endif
 
 int	PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type,
 		EVP_MD *md_type, unsigned char **ek, int *ekl,
@@ -633,7 +453,6 @@
 void	PEM_proc_type(char *buf, int type);
 void	PEM_dek_info(char *buf, const char *type, int len, char *str);
 
-#ifndef SSLEAY_MACROS
 
 #include <openssl/symhacks.h>
 
@@ -719,7 +538,20 @@
 int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc,
 			      char *kstr,int klen, pem_password_cb *cd, void *u);
 
-#endif /* SSLEAY_MACROS */
+EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x);
+int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x);
+
+
+EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length);
+EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length);
+EVP_PKEY *b2i_PrivateKey_bio(BIO *in);
+EVP_PKEY *b2i_PublicKey_bio(BIO *in);
+int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk);
+int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk);
+
+EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u);
+int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
+		pem_password_cb *cb, void *u);
 
 
 /* BEGIN ERROR CODES */
@@ -731,10 +563,22 @@
 /* Error codes for the PEM functions. */
 
 /* Function codes. */
+#define PEM_F_B2I_DSS					 127
+#define PEM_F_B2I_PVK_BIO				 128
+#define PEM_F_B2I_RSA					 129
+#define PEM_F_CHECK_BITLEN_DSA				 130
+#define PEM_F_CHECK_BITLEN_RSA				 131
 #define PEM_F_D2I_PKCS8PRIVATEKEY_BIO			 120
 #define PEM_F_D2I_PKCS8PRIVATEKEY_FP			 121
+#define PEM_F_DO_B2I					 132
+#define PEM_F_DO_B2I_BIO				 133
+#define PEM_F_DO_BLOB_HEADER				 134
 #define PEM_F_DO_PK8PKEY				 126
 #define PEM_F_DO_PK8PKEY_FP				 125
+#define PEM_F_DO_PVK_BODY				 135
+#define PEM_F_DO_PVK_HEADER				 136
+#define PEM_F_I2B_PVK					 137
+#define PEM_F_I2B_PVK_BIO				 138
 #define PEM_F_LOAD_IV					 101
 #define PEM_F_PEM_ASN1_READ				 102
 #define PEM_F_PEM_ASN1_READ_BIO				 103
@@ -747,6 +591,7 @@
 #define PEM_F_PEM_PK8PKEY				 119
 #define PEM_F_PEM_READ					 108
 #define PEM_F_PEM_READ_BIO				 109
+#define PEM_F_PEM_READ_BIO_PARAMETERS			 140
 #define PEM_F_PEM_READ_BIO_PRIVATEKEY			 123
 #define PEM_F_PEM_READ_PRIVATEKEY			 124
 #define PEM_F_PEM_SEALFINAL				 110
@@ -754,6 +599,7 @@
 #define PEM_F_PEM_SIGNFINAL				 112
 #define PEM_F_PEM_WRITE					 113
 #define PEM_F_PEM_WRITE_BIO				 114
+#define PEM_F_PEM_WRITE_PRIVATEKEY			 139
 #define PEM_F_PEM_X509_INFO_READ			 115
 #define PEM_F_PEM_X509_INFO_READ_BIO			 116
 #define PEM_F_PEM_X509_INFO_WRITE_BIO			 117
@@ -763,18 +609,30 @@
 #define PEM_R_BAD_DECRYPT				 101
 #define PEM_R_BAD_END_LINE				 102
 #define PEM_R_BAD_IV_CHARS				 103
+#define PEM_R_BAD_MAGIC_NUMBER				 116
 #define PEM_R_BAD_PASSWORD_READ				 104
+#define PEM_R_BAD_VERSION_NUMBER			 117
+#define PEM_R_BIO_WRITE_FAILURE				 118
+#define PEM_R_CIPHER_IS_NULL				 127
 #define PEM_R_ERROR_CONVERTING_PRIVATE_KEY		 115
+#define PEM_R_EXPECTING_PRIVATE_KEY_BLOB		 119
+#define PEM_R_EXPECTING_PUBLIC_KEY_BLOB			 120
+#define PEM_R_INCONSISTENT_HEADER			 121
+#define PEM_R_KEYBLOB_HEADER_PARSE_ERROR		 122
+#define PEM_R_KEYBLOB_TOO_SHORT				 123
 #define PEM_R_NOT_DEK_INFO				 105
 #define PEM_R_NOT_ENCRYPTED				 106
 #define PEM_R_NOT_PROC_TYPE				 107
 #define PEM_R_NO_START_LINE				 108
 #define PEM_R_PROBLEMS_GETTING_PASSWORD			 109
 #define PEM_R_PUBLIC_KEY_NO_RSA				 110
+#define PEM_R_PVK_DATA_TOO_SHORT			 124
+#define PEM_R_PVK_TOO_SHORT				 125
 #define PEM_R_READ_KEY					 111
 #define PEM_R_SHORT_HEADER				 112
 #define PEM_R_UNSUPPORTED_CIPHER			 113
 #define PEM_R_UNSUPPORTED_ENCRYPTION			 114
+#define PEM_R_UNSUPPORTED_KEY_COMPONENTS		 126
 
 #ifdef  __cplusplus
 }
diff --git a/include/openssl/pkcs12.h b/include/openssl/pkcs12.h
index 78317fb..b17eb9f 100644
--- a/include/openssl/pkcs12.h
+++ b/include/openssl/pkcs12.h
@@ -108,8 +108,6 @@
 PKCS7 *authsafes;
 } PKCS12;
 
-PREDECLARE_STACK_OF(PKCS12_SAFEBAG)
-
 typedef struct {
 ASN1_OBJECT *type;
 union {
@@ -232,14 +230,9 @@
 		   const EVP_MD *md_type);
 int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt,
 					 int saltlen, const EVP_MD *md_type);
-#if defined(NETWARE) || defined(OPENSSL_SYS_NETWARE)
-/* Rename these functions to avoid name clashes on NetWare OS */
 unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen);
 char *OPENSSL_uni2asc(unsigned char *uni, int unilen);
-#else
-unsigned char *asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen);
-char *uni2asc(unsigned char *uni, int unilen);
-#endif
+
 DECLARE_ASN1_FUNCTIONS(PKCS12)
 DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA)
 DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG)
diff --git a/include/openssl/pkcs7.h b/include/openssl/pkcs7.h
index cc092d2..e4d4431 100644
--- a/include/openssl/pkcs7.h
+++ b/include/openssl/pkcs7.h
@@ -232,6 +232,9 @@
 #define PKCS7_type_is_signedAndEnveloped(a) \
 		(OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
 #define PKCS7_type_is_data(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
+#define PKCS7_type_is_digest(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
+#define PKCS7_type_is_encrypted(a) \
+		(OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
 
 #define PKCS7_type_is_digest(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
 
@@ -242,14 +245,6 @@
 
 #define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7))
 
-#ifdef SSLEAY_MACROS
-#ifndef PKCS7_ISSUER_AND_SERIAL_digest
-#define PKCS7_ISSUER_AND_SERIAL_digest(data,type,md,len) \
-        ASN1_digest((int (*)())i2d_PKCS7_ISSUER_AND_SERIAL,type,\
-	                (char *)data,md,len)
-#endif
-#endif
-
 /* S/MIME related flags */
 
 #define PKCS7_TEXT		0x1
@@ -266,6 +261,8 @@
 #define PKCS7_CRLFEOL		0x800
 #define PKCS7_STREAM		0x1000
 #define PKCS7_NOCRL		0x2000
+#define PKCS7_PARTIAL		0x4000
+#define PKCS7_REUSE_DIGEST	0x8000
 
 /* Flags: for compatibility with older code */
 
@@ -281,7 +278,6 @@
 
 DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
 
-#ifndef SSLEAY_MACROS
 int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,const EVP_MD *type,
 	unsigned char *md,unsigned int *len);
 #ifndef OPENSSL_NO_FP_API
@@ -291,7 +287,8 @@
 PKCS7 *PKCS7_dup(PKCS7 *p7);
 PKCS7 *d2i_PKCS7_bio(BIO *bp,PKCS7 **p7);
 int i2d_PKCS7_bio(BIO *bp,PKCS7 *p7);
-#endif
+int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
+int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
 
 DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
 DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
@@ -307,6 +304,7 @@
 DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY)
 
 DECLARE_ASN1_NDEF_FUNCTION(PKCS7)
+DECLARE_ASN1_PRINT_FUNCTION(PKCS7)
 
 long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg);
 
@@ -315,6 +313,7 @@
 int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data);
 int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
 	const EVP_MD *dgst);
+int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si);
 int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
 int PKCS7_add_certificate(PKCS7 *p7, X509 *x509);
 int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
@@ -336,9 +335,13 @@
 STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7);
 
 PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
+void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
+					X509_ALGOR **pdig, X509_ALGOR **psig);
+void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc);
 int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri);
 int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509);
 int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher);
+int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7);
 
 PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx);
 ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk);
@@ -355,6 +358,12 @@
 
 PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
 							BIO *data, int flags);
+
+PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7,
+			X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md,
+			int flags);
+
+int PKCS7_final(PKCS7 *p7, BIO *data, int flags);
 int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
 					BIO *indata, BIO *out, int flags);
 STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags);
@@ -367,10 +376,16 @@
 STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si);
 int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg);
 
+int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid);
+int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t);
+int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
+				const unsigned char *md, int mdlen);
+
 int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags);
 PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont);
-int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
-int SMIME_text(BIO *in, BIO *out);
+
+BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7);
+
 
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -383,12 +398,17 @@
 /* Function codes. */
 #define PKCS7_F_B64_READ_PKCS7				 120
 #define PKCS7_F_B64_WRITE_PKCS7				 121
+#define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB			 136
+#define PKCS7_F_I2D_PKCS7_BIO_STREAM			 140
+#define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME		 135
 #define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP		 118
 #define PKCS7_F_PKCS7_ADD_CERTIFICATE			 100
 #define PKCS7_F_PKCS7_ADD_CRL				 101
 #define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO		 102
+#define PKCS7_F_PKCS7_ADD_SIGNATURE			 131
 #define PKCS7_F_PKCS7_ADD_SIGNER			 103
 #define PKCS7_F_PKCS7_BIO_ADD_DIGEST			 125
+#define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST		 138
 #define PKCS7_F_PKCS7_CTRL				 104
 #define PKCS7_F_PKCS7_DATADECODE			 112
 #define PKCS7_F_PKCS7_DATAFINAL				 128
@@ -396,15 +416,22 @@
 #define PKCS7_F_PKCS7_DATASIGN				 106
 #define PKCS7_F_PKCS7_DATAVERIFY			 107
 #define PKCS7_F_PKCS7_DECRYPT				 114
+#define PKCS7_F_PKCS7_DECRYPT_RINFO			 133
+#define PKCS7_F_PKCS7_ENCODE_RINFO			 132
 #define PKCS7_F_PKCS7_ENCRYPT				 115
+#define PKCS7_F_PKCS7_FINAL				 134
 #define PKCS7_F_PKCS7_FIND_DIGEST			 127
 #define PKCS7_F_PKCS7_GET0_SIGNERS			 124
+#define PKCS7_F_PKCS7_RECIP_INFO_SET			 130
 #define PKCS7_F_PKCS7_SET_CIPHER			 108
 #define PKCS7_F_PKCS7_SET_CONTENT			 109
 #define PKCS7_F_PKCS7_SET_DIGEST			 126
 #define PKCS7_F_PKCS7_SET_TYPE				 110
 #define PKCS7_F_PKCS7_SIGN				 116
 #define PKCS7_F_PKCS7_SIGNATUREVERIFY			 113
+#define PKCS7_F_PKCS7_SIGNER_INFO_SET			 129
+#define PKCS7_F_PKCS7_SIGNER_INFO_SIGN			 139
+#define PKCS7_F_PKCS7_SIGN_ADD_SIGNER			 137
 #define PKCS7_F_PKCS7_SIMPLE_SMIMECAP			 119
 #define PKCS7_F_PKCS7_VERIFY				 117
 #define PKCS7_F_SMIME_READ_PKCS7			 122
@@ -415,10 +442,13 @@
 #define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER		 144
 #define PKCS7_R_CIPHER_NOT_INITIALIZED			 116
 #define PKCS7_R_CONTENT_AND_DATA_PRESENT		 118
+#define PKCS7_R_CTRL_ERROR				 152
 #define PKCS7_R_DECODE_ERROR				 130
 #define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH		 100
 #define PKCS7_R_DECRYPT_ERROR				 119
 #define PKCS7_R_DIGEST_FAILURE				 101
+#define PKCS7_R_ENCRYPTION_CTRL_FAILURE			 149
+#define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150
 #define PKCS7_R_ERROR_ADDING_RECIPIENT			 120
 #define PKCS7_R_ERROR_SETTING_CIPHER			 121
 #define PKCS7_R_INVALID_MIME_TYPE			 131
@@ -429,6 +459,8 @@
 #define PKCS7_R_MISSING_CERIPEND_INFO			 103
 #define PKCS7_R_NO_CONTENT				 122
 #define PKCS7_R_NO_CONTENT_TYPE				 135
+#define PKCS7_R_NO_DEFAULT_DIGEST			 151
+#define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND		 154
 #define PKCS7_R_NO_MULTIPART_BODY_FAILURE		 136
 #define PKCS7_R_NO_MULTIPART_BOUNDARY			 137
 #define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE	 115
@@ -438,6 +470,7 @@
 #define PKCS7_R_NO_SIG_CONTENT_TYPE			 138
 #define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE	 104
 #define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR		 124
+#define PKCS7_R_PKCS7_ADD_SIGNER_ERROR			 153
 #define PKCS7_R_PKCS7_DATAFINAL				 126
 #define PKCS7_R_PKCS7_DATAFINAL_ERROR			 125
 #define PKCS7_R_PKCS7_DATASIGN				 145
@@ -446,6 +479,8 @@
 #define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 127
 #define PKCS7_R_SIGNATURE_FAILURE			 105
 #define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND		 128
+#define PKCS7_R_SIGNING_CTRL_FAILURE			 147
+#define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE	 148
 #define PKCS7_R_SIG_INVALID_MIME_TYPE			 141
 #define PKCS7_R_SMIME_TEXT_ERROR			 129
 #define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE		 106
diff --git a/include/openssl/pq_compat.h b/include/openssl/pq_compat.h
deleted file mode 100644
index 7b2c327..0000000
--- a/include/openssl/pq_compat.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/* crypto/pqueue/pqueue_compat.h */
-/* 
- * DTLS implementation written by Nagendra Modadugu
- * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
- */
-/* ====================================================================
- * Copyright (c) 1999-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
- *    openssl-core@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#ifndef HEADER_PQ_COMPAT_H
-#define HEADER_PQ_COMPAT_H
-
-#include <openssl/opensslconf.h>
-#include <openssl/bn.h>
-
-/* 
- * The purpose of this header file is for supporting 64-bit integer
- * manipulation on 32-bit (and lower) machines.  Currently the only
- * such environment is VMS, Utrix and those with smaller default integer
- * sizes than 32 bits.  For all such environment, we fall back to using
- * BIGNUM.  We may need to fine tune the conditions for systems that
- * are incorrectly configured.
- *
- * The only clients of this code are (1) pqueue for priority, and
- * (2) DTLS, for sequence number manipulation.
- */
-
-#if (defined(THIRTY_TWO_BIT) && !defined(BN_LLONG)) || defined(SIXTEEN_BIT) || defined(EIGHT_BIT)
-
-#define PQ_64BIT_IS_INTEGER 0
-#define PQ_64BIT_IS_BIGNUM 1
-
-#define PQ_64BIT     BIGNUM
-#define PQ_64BIT_CTX BN_CTX
-
-#define pq_64bit_init(x)           BN_init(x)
-#define pq_64bit_free(x)           BN_free(x)
-
-#define pq_64bit_ctx_new(ctx)      BN_CTX_new()
-#define pq_64bit_ctx_free(x)       BN_CTX_free(x)
-
-#define pq_64bit_assign(x, y)      BN_copy(x, y)
-#define pq_64bit_assign_word(x, y) BN_set_word(x, y)
-#define pq_64bit_gt(x, y)          BN_ucmp(x, y) >= 1 ? 1 : 0
-#define pq_64bit_eq(x, y)          BN_ucmp(x, y) == 0 ? 1 : 0
-#define pq_64bit_add_word(x, w)    BN_add_word(x, w)
-#define pq_64bit_sub(r, x, y)      BN_sub(r, x, y)
-#define pq_64bit_sub_word(x, w)    BN_sub_word(x, w)
-#define pq_64bit_mod(r, x, n, ctx) BN_mod(r, x, n, ctx)
-
-#define pq_64bit_bin2num(bn, bytes, len)   BN_bin2bn(bytes, len, bn)
-#define pq_64bit_num2bin(bn, bytes)        BN_bn2bin(bn, bytes)
-#define pq_64bit_get_word(x)               BN_get_word(x)
-#define pq_64bit_is_bit_set(x, offset)     BN_is_bit_set(x, offset)
-#define pq_64bit_lshift(r, x, shift)       BN_lshift(r, x, shift)
-#define pq_64bit_set_bit(x, num)           BN_set_bit(x, num)
-#define pq_64bit_get_length(x)             BN_num_bits((x))
-
-#else
-
-#define PQ_64BIT_IS_INTEGER 1
-#define PQ_64BIT_IS_BIGNUM 0
-
-#if defined(SIXTY_FOUR_BIT)
-#define PQ_64BIT BN_ULONG
-#define PQ_64BIT_PRINT "%lld"
-#elif defined(SIXTY_FOUR_BIT_LONG)
-#define PQ_64BIT BN_ULONG
-#define PQ_64BIT_PRINT "%ld"
-#elif defined(THIRTY_TWO_BIT)
-#define PQ_64BIT BN_ULLONG
-#define PQ_64BIT_PRINT "%lld"
-#endif
-
-#define PQ_64BIT_CTX      void
-
-#define pq_64bit_init(x)
-#define pq_64bit_free(x)
-#define pq_64bit_ctx_new(ctx)        (ctx)
-#define pq_64bit_ctx_free(x)
-
-#define pq_64bit_assign(x, y)        (*(x) = *(y))
-#define pq_64bit_assign_word(x, y)   (*(x) = y)
-#define pq_64bit_gt(x, y)	         (*(x) > *(y))
-#define pq_64bit_eq(x, y)            (*(x) == *(y))
-#define pq_64bit_add_word(x, w)      (*(x) = (*(x) + (w)))
-#define pq_64bit_sub(r, x, y)        (*(r) = (*(x) - *(y)))
-#define pq_64bit_sub_word(x, w)      (*(x) = (*(x) - (w)))
-#define pq_64bit_mod(r, x, n, ctx)
-
-#define pq_64bit_bin2num(num, bytes, len) bytes_to_long_long(bytes, num)
-#define pq_64bit_num2bin(num, bytes)      long_long_to_bytes(num, bytes)
-#define pq_64bit_get_word(x)              *(x)
-#define pq_64bit_lshift(r, x, shift)      (*(r) = (*(x) << (shift)))
-#define pq_64bit_set_bit(x, num)          do { \
-                                              PQ_64BIT mask = 1; \
-                                              mask = mask << (num); \
-                                              *(x) |= mask; \
-                                          } while(0)
-#endif /* OPENSSL_SYS_VMS */
-
-#endif
diff --git a/include/openssl/pqueue.h b/include/openssl/pqueue.h
index 16c4072..87fc903 100644
--- a/include/openssl/pqueue.h
+++ b/include/openssl/pqueue.h
@@ -64,20 +64,18 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <openssl/pq_compat.h>
-
 typedef struct _pqueue *pqueue;
 
 typedef struct _pitem
 	{
-	PQ_64BIT priority;
+	unsigned char priority[8]; /* 64-bit value in big-endian encoding */
 	void *data;
 	struct _pitem *next;
 	} pitem;
 
 typedef struct _pitem *piterator;
 
-pitem *pitem_new(PQ_64BIT priority, void *data);
+pitem *pitem_new(unsigned char *prio64be, void *data);
 void   pitem_free(pitem *item);
 
 pqueue pqueue_new(void);
@@ -86,7 +84,7 @@
 pitem *pqueue_insert(pqueue pq, pitem *item);
 pitem *pqueue_peek(pqueue pq);
 pitem *pqueue_pop(pqueue pq);
-pitem *pqueue_find(pqueue pq, PQ_64BIT priority);
+pitem *pqueue_find(pqueue pq, unsigned char *prio64be);
 pitem *pqueue_iterator(pqueue pq);
 pitem *pqueue_next(piterator *iter);
 
diff --git a/include/openssl/rand.h b/include/openssl/rand.h
index ea89153..ac6c021 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 int
+#define FIPS_RAND_SIZE_T size_t
 #endif
 
 /* Already defined in ossl_typ.h */
@@ -111,15 +111,6 @@
 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)
 
@@ -137,29 +128,11 @@
 /* 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 e542ec9..34c8362 100644
--- a/include/openssl/rc2.h
+++ b/include/openssl/rc2.h
@@ -79,9 +79,7 @@
 	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 2d8620d..29d1acc 100644
--- a/include/openssl/rc4.h
+++ b/include/openssl/rc4.h
@@ -64,6 +64,8 @@
 #error RC4 is disabled.
 #endif
 
+#include <stddef.h>
+
 #ifdef  __cplusplus
 extern "C" {
 #endif
@@ -76,11 +78,8 @@
 
  
 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,
+void RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
 		unsigned char *outdata);
 
 #ifdef  __cplusplus
diff --git a/include/openssl/ripemd.h b/include/openssl/ripemd.h
index 3b6d043..5942eb6 100644
--- a/include/openssl/ripemd.h
+++ b/include/openssl/ripemd.h
@@ -70,7 +70,7 @@
 #error RIPEMD is disabled.
 #endif
 
-#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#if defined(__LP32__)
 #define RIPEMD160_LONG unsigned long
 #elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
 #define RIPEMD160_LONG unsigned long
@@ -90,9 +90,7 @@
 	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 5bb932a..cf74343 100644
--- a/include/openssl/rsa.h
+++ b/include/openssl/rsa.h
@@ -74,25 +74,6 @@
 #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
@@ -136,7 +117,8 @@
 		unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
 	int (*rsa_verify)(int dtype,
 		const unsigned char *m, unsigned int m_length,
-		unsigned char *sigbuf, unsigned int siglen, const RSA *rsa);
+		const unsigned char *sigbuf, unsigned int siglen,
+								const RSA *rsa);
 /* If this callback is NULL, the builtin software RSA key-gen will be used. This
  * is for behavioural compatibility whilst the code gets rewired, but one day
  * it would be nice to assume there are no such things as "builtin software"
@@ -182,8 +164,6 @@
 # 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
@@ -238,11 +218,37 @@
 #endif
 
 
+#define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \
+				pad, NULL)
+
+#define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
+				(EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \
+				EVP_PKEY_CTRL_RSA_PSS_SALTLEN, \
+				len, NULL)
+
+#define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
+				EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL)
+
+#define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \
+	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
+				EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp)
+
+#define EVP_PKEY_CTRL_RSA_PADDING	(EVP_PKEY_ALG_CTRL + 1)
+#define EVP_PKEY_CTRL_RSA_PSS_SALTLEN	(EVP_PKEY_ALG_CTRL + 2)
+
+#define EVP_PKEY_CTRL_RSA_KEYGEN_BITS	(EVP_PKEY_ALG_CTRL + 3)
+#define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP	(EVP_PKEY_ALG_CTRL + 4)
+
 #define RSA_PKCS1_PADDING	1
 #define RSA_SSLV23_PADDING	2
 #define RSA_NO_PADDING		3
 #define RSA_PKCS1_OAEP_PADDING	4
 #define RSA_X931_PADDING	5
+/* EVP_PKEY_ only */
+#define RSA_PKCS1_PSS_PADDING	6
 
 #define RSA_PKCS1_PADDING_SIZE	11
 
@@ -261,11 +267,6 @@
 
 /* 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 */
@@ -283,11 +284,6 @@
 
 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);
@@ -333,7 +329,7 @@
 int RSA_sign(int type, const unsigned char *m, unsigned int m_length,
 	unsigned char *sigret, unsigned int *siglen, RSA *rsa);
 int RSA_verify(int type, const unsigned char *m, unsigned int m_length,
-	unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
+	const unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
 
 /* The following 2 function sign and verify a ASN1_OCTET_STRING
  * object inside PKCS#1 padded RSA encryption */
@@ -401,9 +397,15 @@
 /* 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_CHECK_PADDING_MD				 140
+#define RSA_F_DO_RSA_PRINT				 146
+#define RSA_F_INT_RSA_VERIFY				 145
 #define RSA_F_MEMORY_LOCK				 100
+#define RSA_F_OLD_RSA_PRIV_DECODE			 147
+#define RSA_F_PKEY_RSA_CTRL				 143
+#define RSA_F_PKEY_RSA_CTRL_STR				 144
+#define RSA_F_PKEY_RSA_SIGN				 142
+#define RSA_F_PKEY_RSA_VERIFYRECOVER			 141
 #define RSA_F_RSA_BUILTIN_KEYGEN			 129
 #define RSA_F_RSA_CHECK_KEY				 123
 #define RSA_F_RSA_EAY_PRIVATE_DECRYPT			 101
@@ -434,11 +436,10 @@
 #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_PRIV_DECODE				 137
+#define RSA_F_RSA_PRIV_ENCODE				 138
+#define RSA_F_RSA_PUB_DECODE				 139
 #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
@@ -464,20 +465,25 @@
 #define RSA_R_DMQ1_NOT_CONGRUENT_TO_D			 125
 #define RSA_R_D_E_NOT_CONGRUENT_TO_1			 123
 #define RSA_R_FIRST_OCTET_INVALID			 133
+#define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE	 144
+#define RSA_R_INVALID_DIGEST_LENGTH			 143
 #define RSA_R_INVALID_HEADER				 137
+#define RSA_R_INVALID_KEYBITS				 145
 #define RSA_R_INVALID_MESSAGE_LENGTH			 131
 #define RSA_R_INVALID_PADDING				 138
+#define RSA_R_INVALID_PADDING_MODE			 141
+#define RSA_R_INVALID_PSS_SALTLEN			 146
 #define RSA_R_INVALID_TRAILER				 139
+#define RSA_R_INVALID_X931_DIGEST			 142
 #define RSA_R_IQMP_NOT_INVERSE_OF_Q			 126
 #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_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE	 148
 #define RSA_R_PADDING_CHECK_FAILED			 114
 #define RSA_R_P_NOT_PRIME				 128
 #define RSA_R_Q_NOT_PRIME				 129
@@ -488,6 +494,7 @@
 #define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116
 #define RSA_R_UNKNOWN_ALGORITHM_TYPE			 117
 #define RSA_R_UNKNOWN_PADDING_TYPE			 118
+#define RSA_R_VALUE_MISSING				 147
 #define RSA_R_WRONG_SIGNATURE_LENGTH			 119
 
 #ifdef  __cplusplus
diff --git a/include/openssl/safestack.h b/include/openssl/safestack.h
index 78cc485..d616b4a 100644
--- a/include/openssl/safestack.h
+++ b/include/openssl/safestack.h
@@ -57,18 +57,27 @@
 
 #include <openssl/stack.h>
 
-#ifdef DEBUG_SAFESTACK
-
 #ifndef CHECKED_PTR_OF
 #define CHECKED_PTR_OF(type, p) \
     ((void*) (1 ? p : (type*)0))
 #endif
 
+/* In C++ we get problems because an explicit cast is needed from (void *)
+ * we use CHECKED_STACK_OF to ensure the correct type is passed in the macros
+ * below. 
+ */
+
+#define CHECKED_STACK_OF(type, p) \
+    ((_STACK*) (1 ? p : (STACK_OF(type)*)0))
+
 #define CHECKED_SK_FREE_FUNC(type, p) \
     ((void (*)(void *)) ((1 ? p : (void (*)(type *))0)))
 
+#define CHECKED_SK_FREE_FUNC2(type, p) \
+    ((void (*)(void *)) ((1 ? p : (void (*)(type))0)))
+
 #define CHECKED_SK_CMP_FUNC(type, p) \
-    ((int (*)(const char * const *, const char * const *)) \
+    ((int (*)(const void *, const void *)) \
 	((1 ? p : (int (*)(const type * const *, const type * const *))0)))
 
 #define STACK_OF(type) struct stack_st_##type
@@ -77,11 +86,51 @@
 #define DECLARE_STACK_OF(type) \
 STACK_OF(type) \
     { \
-    STACK stack; \
+    _STACK stack; \
+    };
+#define DECLARE_SPECIAL_STACK_OF(type, type2) \
+STACK_OF(type) \
+    { \
+    _STACK stack; \
     };
 
 #define IMPLEMENT_STACK_OF(type) /* nada (obsolete in new safestack approach)*/
 
+
+/* Strings are special: normally an lhash entry will point to a single
+ * (somewhat) mutable object. In the case of strings:
+ *
+ * a) Instead of a single char, there is an array of chars, NUL-terminated.
+ * b) The string may have be immutable.
+ *
+ * So, they need their own declarations. Especially important for
+ * type-checking tools, such as Deputy.
+ *
+o * In practice, however, it appears to be hard to have a const
+ * string. For now, I'm settling for dealing with the fact it is a
+ * string at all.
+ */
+typedef char *OPENSSL_STRING;
+
+typedef const char *OPENSSL_CSTRING;
+
+/* Confusingly, LHASH_OF(STRING) deals with char ** throughout, but
+ * STACK_OF(STRING) is really more like STACK_OF(char), only, as
+ * mentioned above, instead of a single char each entry is a
+ * NUL-terminated array of chars. So, we have to implement STRING
+ * specially for STACK_OF. This is dealt with in the autogenerated
+ * macros below.
+ */
+
+DECLARE_SPECIAL_STACK_OF(OPENSSL_STRING, char)
+
+/* Similarly, we sometimes use a block of characters, NOT
+ * nul-terminated. These should also be distinguished from "normal"
+ * stacks. */
+
+typedef void *OPENSSL_BLOCK;
+DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)
+
 /* SKM_sk_... stack macros are internal to safestack.h:
  * never use them directly, use sk_<type>_... instead */
 #define SKM_sk_new(type, cmp) \
@@ -89,52 +138,55 @@
 #define SKM_sk_new_null(type) \
 	((STACK_OF(type) *)sk_new_null())
 #define SKM_sk_free(type, st) \
-	sk_free(CHECKED_PTR_OF(STACK_OF(type), st))
+	sk_free(CHECKED_STACK_OF(type, st))
 #define SKM_sk_num(type, st) \
-	sk_num(CHECKED_PTR_OF(STACK_OF(type), st))
+	sk_num(CHECKED_STACK_OF(type, st))
 #define SKM_sk_value(type, st,i) \
-	((type *)sk_value(CHECKED_PTR_OF(STACK_OF(type), st), i))
+	((type *)sk_value(CHECKED_STACK_OF(type, st), i))
 #define SKM_sk_set(type, st,i,val) \
-	sk_set(CHECKED_PTR_OF(STACK_OF(type), st), i, CHECKED_PTR_OF(type, val))
+	sk_set(CHECKED_STACK_OF(type, st), i, CHECKED_PTR_OF(type, val))
 #define SKM_sk_zero(type, st) \
-	sk_zero(CHECKED_PTR_OF(STACK_OF(type), st))
-#define SKM_sk_push(type, st,val) \
-	sk_push(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val))
-#define SKM_sk_unshift(type, st,val) \
-	sk_unshift(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val))
-#define SKM_sk_find(type, st,val) \
-	sk_find(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val))
-#define SKM_sk_delete(type, st,i) \
-	(type *)sk_delete(CHECKED_PTR_OF(STACK_OF(type), st), i)
-#define SKM_sk_delete_ptr(type, st,ptr) \
-	(type *)sk_delete_ptr(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, ptr))
-#define SKM_sk_insert(type, st,val,i) \
-	sk_insert(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_PTR_OF(type, val), i)
-#define SKM_sk_set_cmp_func(type, st,cmp) \
+	sk_zero(CHECKED_STACK_OF(type, st))
+#define SKM_sk_push(type, st, val) \
+	sk_push(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
+#define SKM_sk_unshift(type, st, val) \
+	sk_unshift(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
+#define SKM_sk_find(type, st, val) \
+	sk_find(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
+#define SKM_sk_find_ex(type, st, val) \
+	sk_find_ex(CHECKED_STACK_OF(type, st), \
+		   CHECKED_PTR_OF(type, val))
+#define SKM_sk_delete(type, st, i) \
+	(type *)sk_delete(CHECKED_STACK_OF(type, st), i)
+#define SKM_sk_delete_ptr(type, st, ptr) \
+	(type *)sk_delete_ptr(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, ptr))
+#define SKM_sk_insert(type, st,val, i) \
+	sk_insert(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val), i)
+#define SKM_sk_set_cmp_func(type, st, cmp) \
 	((int (*)(const type * const *,const type * const *)) \
-	sk_set_cmp_func(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_SK_CMP_FUNC(type, cmp)))
+	sk_set_cmp_func(CHECKED_STACK_OF(type, st), CHECKED_SK_CMP_FUNC(type, cmp)))
 #define SKM_sk_dup(type, st) \
-	(STACK_OF(type) *)sk_dup(CHECKED_PTR_OF(STACK_OF(type), st))
-#define SKM_sk_pop_free(type, st,free_func) \
-	sk_pop_free(CHECKED_PTR_OF(STACK_OF(type), st), CHECKED_SK_FREE_FUNC(type, free_func))
+	(STACK_OF(type) *)sk_dup(CHECKED_STACK_OF(type, st))
+#define SKM_sk_pop_free(type, st, free_func) \
+	sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func))
 #define SKM_sk_shift(type, st) \
-	(type *)sk_shift(CHECKED_PTR_OF(STACK_OF(type), st))
+	(type *)sk_shift(CHECKED_STACK_OF(type, st))
 #define SKM_sk_pop(type, st) \
-	(type *)sk_pop(CHECKED_PTR_OF(STACK_OF(type), st))
+	(type *)sk_pop(CHECKED_STACK_OF(type, st))
 #define SKM_sk_sort(type, st) \
-	sk_sort(CHECKED_PTR_OF(STACK_OF(type), st))
+	sk_sort(CHECKED_STACK_OF(type, st))
 #define SKM_sk_is_sorted(type, st) \
-	sk_is_sorted(CHECKED_PTR_OF(STACK_OF(type), st))
+	sk_is_sorted(CHECKED_STACK_OF(type, st))
 
 #define	SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
-	(STACK_OF(type) *)d2i_ASN1_SET(CHECKED_PTR_OF(STACK_OF(type), st), \
+	(STACK_OF(type) *)d2i_ASN1_SET(CHECKED_STACK_OF(type, st), \
 				pp, length, \
 				CHECKED_D2I_OF(type, d2i_func), \
 				CHECKED_SK_FREE_FUNC(type, free_func), \
 				ex_tag, ex_class)
 
 #define	SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \
-	i2d_ASN1_SET(CHECKED_PTR_OF(STACK_OF(type), st), pp, \
+  i2d_ASN1_SET((STACK_OF(OPENSSL_BLOCK) *)CHECKED_STACK_OF(type, st), pp, \
 				CHECKED_I2D_OF(type, i2d_func), \
 				ex_tag, ex_class, is_set)
 
@@ -151,72 +203,8 @@
 				CHECKED_SK_FREE_FUNC(type, free_func), \
 				pass, passlen, oct, seq)
 
-#else
-
-#define STACK_OF(type) STACK
-#define PREDECLARE_STACK_OF(type) /* nada */
-#define DECLARE_STACK_OF(type)    /* nada */
-#define IMPLEMENT_STACK_OF(type)  /* nada */
-
-#define SKM_sk_new(type, cmp) \
-	sk_new((int (*)(const char * const *, const char * const *))(cmp))
-#define SKM_sk_new_null(type) \
-	sk_new_null()
-#define SKM_sk_free(type, st) \
-	sk_free(st)
-#define SKM_sk_num(type, st) \
-	sk_num(st)
-#define SKM_sk_value(type, st,i) \
-	((type *)sk_value(st, i))
-#define SKM_sk_set(type, st,i,val) \
-	((type *)sk_set(st, i,(char *)val))
-#define SKM_sk_zero(type, st) \
-	sk_zero(st)
-#define SKM_sk_push(type, st,val) \
-	sk_push(st, (char *)val)
-#define SKM_sk_unshift(type, st,val) \
-	sk_unshift(st, (char *)val)
-#define SKM_sk_find(type, st,val) \
-	sk_find(st, (char *)val)
-#define SKM_sk_delete(type, st,i) \
-	((type *)sk_delete(st, i))
-#define SKM_sk_delete_ptr(type, st,ptr) \
-	((type *)sk_delete_ptr(st,(char *)ptr))
-#define SKM_sk_insert(type, st,val,i) \
-	sk_insert(st, (char *)val, i)
-#define SKM_sk_set_cmp_func(type, st,cmp) \
-	((int (*)(const type * const *,const type * const *)) \
-	sk_set_cmp_func(st, (int (*)(const char * const *, const char * const *))(cmp)))
-#define SKM_sk_dup(type, st) \
-	sk_dup(st)
-#define SKM_sk_pop_free(type, st,free_func) \
-	sk_pop_free(st, (void (*)(void *))free_func)
-#define SKM_sk_shift(type, st) \
-	((type *)sk_shift(st))
-#define SKM_sk_pop(type, st) \
-	((type *)sk_pop(st))
-#define SKM_sk_sort(type, st) \
-	sk_sort(st)
-#define SKM_sk_is_sorted(type, st) \
-	sk_is_sorted(st)
-
-#define	SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
-	d2i_ASN1_SET(st,pp,length, (void *(*)(void ** ,const unsigned char ** ,long))d2i_func, (void (*)(void *))free_func, ex_tag,ex_class)
-#define	SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \
-	i2d_ASN1_SET(st,pp,(int (*)(void *, unsigned char **))i2d_func,ex_tag,ex_class,is_set)
-
-#define	SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \
-	ASN1_seq_pack(st, (int (*)(void *, unsigned char **))i2d_func, buf, len)
-#define	SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \
-	ASN1_seq_unpack(buf,len,(void *(*)(void **,const unsigned char **,long))d2i_func, (void(*)(void *))free_func)
-
-#define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \
-	((STACK *)PKCS12_decrypt_d2i(algor,(char *(*)())d2i_func, (void(*)(void *))free_func,pass,passlen,oct,seq))
-
-#endif
-
 /* This block of defines is updated by util/mkstack.pl, please do not touch! */
-#define sk_ACCESS_DESCRIPTION_new(st) SKM_sk_new(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_new(cmp) SKM_sk_new(ACCESS_DESCRIPTION, (cmp))
 #define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION)
 #define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st))
 #define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st))
@@ -238,7 +226,7 @@
 #define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st))
 #define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st))
 
-#define sk_ASIdOrRange_new(st) SKM_sk_new(ASIdOrRange, (st))
+#define sk_ASIdOrRange_new(cmp) SKM_sk_new(ASIdOrRange, (cmp))
 #define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange)
 #define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st))
 #define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st))
@@ -260,7 +248,7 @@
 #define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st))
 #define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st))
 
-#define sk_ASN1_GENERALSTRING_new(st) SKM_sk_new(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_new(cmp) SKM_sk_new(ASN1_GENERALSTRING, (cmp))
 #define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING)
 #define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st))
 #define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st))
@@ -282,7 +270,7 @@
 #define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st))
 #define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st))
 
-#define sk_ASN1_INTEGER_new(st) SKM_sk_new(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_new(cmp) SKM_sk_new(ASN1_INTEGER, (cmp))
 #define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER)
 #define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st))
 #define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st))
@@ -304,7 +292,7 @@
 #define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st))
 #define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st))
 
-#define sk_ASN1_OBJECT_new(st) SKM_sk_new(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_new(cmp) SKM_sk_new(ASN1_OBJECT, (cmp))
 #define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT)
 #define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st))
 #define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st))
@@ -326,7 +314,7 @@
 #define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st))
 #define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st))
 
-#define sk_ASN1_STRING_TABLE_new(st) SKM_sk_new(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_new(cmp) SKM_sk_new(ASN1_STRING_TABLE, (cmp))
 #define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE)
 #define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st))
 #define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st))
@@ -348,7 +336,7 @@
 #define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st))
 #define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st))
 
-#define sk_ASN1_TYPE_new(st) SKM_sk_new(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_new(cmp) SKM_sk_new(ASN1_TYPE, (cmp))
 #define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE)
 #define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st))
 #define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st))
@@ -370,7 +358,29 @@
 #define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st))
 #define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st))
 
-#define sk_ASN1_VALUE_new(st) SKM_sk_new(ASN1_VALUE, (st))
+#define sk_ASN1_UTF8STRING_new(cmp) SKM_sk_new(ASN1_UTF8STRING, (cmp))
+#define sk_ASN1_UTF8STRING_new_null() SKM_sk_new_null(ASN1_UTF8STRING)
+#define sk_ASN1_UTF8STRING_free(st) SKM_sk_free(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_num(st) SKM_sk_num(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_value(st, i) SKM_sk_value(ASN1_UTF8STRING, (st), (i))
+#define sk_ASN1_UTF8STRING_set(st, i, val) SKM_sk_set(ASN1_UTF8STRING, (st), (i), (val))
+#define sk_ASN1_UTF8STRING_zero(st) SKM_sk_zero(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_push(st, val) SKM_sk_push(ASN1_UTF8STRING, (st), (val))
+#define sk_ASN1_UTF8STRING_unshift(st, val) SKM_sk_unshift(ASN1_UTF8STRING, (st), (val))
+#define sk_ASN1_UTF8STRING_find(st, val) SKM_sk_find(ASN1_UTF8STRING, (st), (val))
+#define sk_ASN1_UTF8STRING_find_ex(st, val) SKM_sk_find_ex(ASN1_UTF8STRING, (st), (val))
+#define sk_ASN1_UTF8STRING_delete(st, i) SKM_sk_delete(ASN1_UTF8STRING, (st), (i))
+#define sk_ASN1_UTF8STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_UTF8STRING, (st), (ptr))
+#define sk_ASN1_UTF8STRING_insert(st, val, i) SKM_sk_insert(ASN1_UTF8STRING, (st), (val), (i))
+#define sk_ASN1_UTF8STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_UTF8STRING, (st), (cmp))
+#define sk_ASN1_UTF8STRING_dup(st) SKM_sk_dup(ASN1_UTF8STRING, st)
+#define sk_ASN1_UTF8STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_UTF8STRING, (st), (free_func))
+#define sk_ASN1_UTF8STRING_shift(st) SKM_sk_shift(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_pop(st) SKM_sk_pop(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_sort(st) SKM_sk_sort(ASN1_UTF8STRING, (st))
+#define sk_ASN1_UTF8STRING_is_sorted(st) SKM_sk_is_sorted(ASN1_UTF8STRING, (st))
+
+#define sk_ASN1_VALUE_new(cmp) SKM_sk_new(ASN1_VALUE, (cmp))
 #define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE)
 #define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st))
 #define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st))
@@ -392,7 +402,7 @@
 #define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st))
 #define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st))
 
-#define sk_BIO_new(st) SKM_sk_new(BIO, (st))
+#define sk_BIO_new(cmp) SKM_sk_new(BIO, (cmp))
 #define sk_BIO_new_null() SKM_sk_new_null(BIO)
 #define sk_BIO_free(st) SKM_sk_free(BIO, (st))
 #define sk_BIO_num(st) SKM_sk_num(BIO, (st))
@@ -414,7 +424,51 @@
 #define sk_BIO_sort(st) SKM_sk_sort(BIO, (st))
 #define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st))
 
-#define sk_CMS_CertificateChoices_new(st) SKM_sk_new(CMS_CertificateChoices, (st))
+#define sk_BY_DIR_ENTRY_new(cmp) SKM_sk_new(BY_DIR_ENTRY, (cmp))
+#define sk_BY_DIR_ENTRY_new_null() SKM_sk_new_null(BY_DIR_ENTRY)
+#define sk_BY_DIR_ENTRY_free(st) SKM_sk_free(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_num(st) SKM_sk_num(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_value(st, i) SKM_sk_value(BY_DIR_ENTRY, (st), (i))
+#define sk_BY_DIR_ENTRY_set(st, i, val) SKM_sk_set(BY_DIR_ENTRY, (st), (i), (val))
+#define sk_BY_DIR_ENTRY_zero(st) SKM_sk_zero(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_push(st, val) SKM_sk_push(BY_DIR_ENTRY, (st), (val))
+#define sk_BY_DIR_ENTRY_unshift(st, val) SKM_sk_unshift(BY_DIR_ENTRY, (st), (val))
+#define sk_BY_DIR_ENTRY_find(st, val) SKM_sk_find(BY_DIR_ENTRY, (st), (val))
+#define sk_BY_DIR_ENTRY_find_ex(st, val) SKM_sk_find_ex(BY_DIR_ENTRY, (st), (val))
+#define sk_BY_DIR_ENTRY_delete(st, i) SKM_sk_delete(BY_DIR_ENTRY, (st), (i))
+#define sk_BY_DIR_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_ENTRY, (st), (ptr))
+#define sk_BY_DIR_ENTRY_insert(st, val, i) SKM_sk_insert(BY_DIR_ENTRY, (st), (val), (i))
+#define sk_BY_DIR_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_ENTRY, (st), (cmp))
+#define sk_BY_DIR_ENTRY_dup(st) SKM_sk_dup(BY_DIR_ENTRY, st)
+#define sk_BY_DIR_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_ENTRY, (st), (free_func))
+#define sk_BY_DIR_ENTRY_shift(st) SKM_sk_shift(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_pop(st) SKM_sk_pop(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_sort(st) SKM_sk_sort(BY_DIR_ENTRY, (st))
+#define sk_BY_DIR_ENTRY_is_sorted(st) SKM_sk_is_sorted(BY_DIR_ENTRY, (st))
+
+#define sk_BY_DIR_HASH_new(cmp) SKM_sk_new(BY_DIR_HASH, (cmp))
+#define sk_BY_DIR_HASH_new_null() SKM_sk_new_null(BY_DIR_HASH)
+#define sk_BY_DIR_HASH_free(st) SKM_sk_free(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_num(st) SKM_sk_num(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_value(st, i) SKM_sk_value(BY_DIR_HASH, (st), (i))
+#define sk_BY_DIR_HASH_set(st, i, val) SKM_sk_set(BY_DIR_HASH, (st), (i), (val))
+#define sk_BY_DIR_HASH_zero(st) SKM_sk_zero(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_push(st, val) SKM_sk_push(BY_DIR_HASH, (st), (val))
+#define sk_BY_DIR_HASH_unshift(st, val) SKM_sk_unshift(BY_DIR_HASH, (st), (val))
+#define sk_BY_DIR_HASH_find(st, val) SKM_sk_find(BY_DIR_HASH, (st), (val))
+#define sk_BY_DIR_HASH_find_ex(st, val) SKM_sk_find_ex(BY_DIR_HASH, (st), (val))
+#define sk_BY_DIR_HASH_delete(st, i) SKM_sk_delete(BY_DIR_HASH, (st), (i))
+#define sk_BY_DIR_HASH_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_HASH, (st), (ptr))
+#define sk_BY_DIR_HASH_insert(st, val, i) SKM_sk_insert(BY_DIR_HASH, (st), (val), (i))
+#define sk_BY_DIR_HASH_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_HASH, (st), (cmp))
+#define sk_BY_DIR_HASH_dup(st) SKM_sk_dup(BY_DIR_HASH, st)
+#define sk_BY_DIR_HASH_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_HASH, (st), (free_func))
+#define sk_BY_DIR_HASH_shift(st) SKM_sk_shift(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_pop(st) SKM_sk_pop(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_sort(st) SKM_sk_sort(BY_DIR_HASH, (st))
+#define sk_BY_DIR_HASH_is_sorted(st) SKM_sk_is_sorted(BY_DIR_HASH, (st))
+
+#define sk_CMS_CertificateChoices_new(cmp) SKM_sk_new(CMS_CertificateChoices, (cmp))
 #define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices)
 #define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st))
 #define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st))
@@ -436,7 +490,7 @@
 #define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st))
 #define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st))
 
-#define sk_CMS_RecipientInfo_new(st) SKM_sk_new(CMS_RecipientInfo, (st))
+#define sk_CMS_RecipientInfo_new(cmp) SKM_sk_new(CMS_RecipientInfo, (cmp))
 #define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo)
 #define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st))
 #define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st))
@@ -458,7 +512,7 @@
 #define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st))
 #define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st))
 
-#define sk_CMS_RevocationInfoChoice_new(st) SKM_sk_new(CMS_RevocationInfoChoice, (st))
+#define sk_CMS_RevocationInfoChoice_new(cmp) SKM_sk_new(CMS_RevocationInfoChoice, (cmp))
 #define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice)
 #define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st))
 #define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st))
@@ -480,7 +534,7 @@
 #define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st))
 #define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st))
 
-#define sk_CMS_SignerInfo_new(st) SKM_sk_new(CMS_SignerInfo, (st))
+#define sk_CMS_SignerInfo_new(cmp) SKM_sk_new(CMS_SignerInfo, (cmp))
 #define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo)
 #define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st))
 #define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st))
@@ -502,7 +556,7 @@
 #define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st))
 #define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st))
 
-#define sk_CONF_IMODULE_new(st) SKM_sk_new(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_new(cmp) SKM_sk_new(CONF_IMODULE, (cmp))
 #define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE)
 #define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st))
 #define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st))
@@ -524,7 +578,7 @@
 #define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st))
 #define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st))
 
-#define sk_CONF_MODULE_new(st) SKM_sk_new(CONF_MODULE, (st))
+#define sk_CONF_MODULE_new(cmp) SKM_sk_new(CONF_MODULE, (cmp))
 #define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE)
 #define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st))
 #define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st))
@@ -546,7 +600,7 @@
 #define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st))
 #define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st))
 
-#define sk_CONF_VALUE_new(st) SKM_sk_new(CONF_VALUE, (st))
+#define sk_CONF_VALUE_new(cmp) SKM_sk_new(CONF_VALUE, (cmp))
 #define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE)
 #define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st))
 #define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st))
@@ -568,7 +622,7 @@
 #define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st))
 #define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st))
 
-#define sk_CRYPTO_EX_DATA_FUNCS_new(st) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_new(cmp) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (cmp))
 #define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS)
 #define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st))
 #define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st))
@@ -590,7 +644,7 @@
 #define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st))
 #define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st))
 
-#define sk_CRYPTO_dynlock_new(st) SKM_sk_new(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_new(cmp) SKM_sk_new(CRYPTO_dynlock, (cmp))
 #define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock)
 #define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st))
 #define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st))
@@ -612,7 +666,7 @@
 #define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st))
 #define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st))
 
-#define sk_DIST_POINT_new(st) SKM_sk_new(DIST_POINT, (st))
+#define sk_DIST_POINT_new(cmp) SKM_sk_new(DIST_POINT, (cmp))
 #define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT)
 #define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st))
 #define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st))
@@ -634,7 +688,7 @@
 #define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st))
 #define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st))
 
-#define sk_ENGINE_new(st) SKM_sk_new(ENGINE, (st))
+#define sk_ENGINE_new(cmp) SKM_sk_new(ENGINE, (cmp))
 #define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE)
 #define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st))
 #define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st))
@@ -656,7 +710,7 @@
 #define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st))
 #define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st))
 
-#define sk_ENGINE_CLEANUP_ITEM_new(st) SKM_sk_new(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_new(cmp) SKM_sk_new(ENGINE_CLEANUP_ITEM, (cmp))
 #define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM)
 #define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st))
 #define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st))
@@ -678,7 +732,117 @@
 #define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st))
 #define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st))
 
-#define sk_GENERAL_NAME_new(st) SKM_sk_new(GENERAL_NAME, (st))
+#define sk_ESS_CERT_ID_new(cmp) SKM_sk_new(ESS_CERT_ID, (cmp))
+#define sk_ESS_CERT_ID_new_null() SKM_sk_new_null(ESS_CERT_ID)
+#define sk_ESS_CERT_ID_free(st) SKM_sk_free(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_num(st) SKM_sk_num(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_value(st, i) SKM_sk_value(ESS_CERT_ID, (st), (i))
+#define sk_ESS_CERT_ID_set(st, i, val) SKM_sk_set(ESS_CERT_ID, (st), (i), (val))
+#define sk_ESS_CERT_ID_zero(st) SKM_sk_zero(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_push(st, val) SKM_sk_push(ESS_CERT_ID, (st), (val))
+#define sk_ESS_CERT_ID_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID, (st), (val))
+#define sk_ESS_CERT_ID_find(st, val) SKM_sk_find(ESS_CERT_ID, (st), (val))
+#define sk_ESS_CERT_ID_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID, (st), (val))
+#define sk_ESS_CERT_ID_delete(st, i) SKM_sk_delete(ESS_CERT_ID, (st), (i))
+#define sk_ESS_CERT_ID_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID, (st), (ptr))
+#define sk_ESS_CERT_ID_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID, (st), (val), (i))
+#define sk_ESS_CERT_ID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID, (st), (cmp))
+#define sk_ESS_CERT_ID_dup(st) SKM_sk_dup(ESS_CERT_ID, st)
+#define sk_ESS_CERT_ID_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID, (st), (free_func))
+#define sk_ESS_CERT_ID_shift(st) SKM_sk_shift(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_pop(st) SKM_sk_pop(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_sort(st) SKM_sk_sort(ESS_CERT_ID, (st))
+#define sk_ESS_CERT_ID_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID, (st))
+
+#define sk_EVP_MD_new(cmp) SKM_sk_new(EVP_MD, (cmp))
+#define sk_EVP_MD_new_null() SKM_sk_new_null(EVP_MD)
+#define sk_EVP_MD_free(st) SKM_sk_free(EVP_MD, (st))
+#define sk_EVP_MD_num(st) SKM_sk_num(EVP_MD, (st))
+#define sk_EVP_MD_value(st, i) SKM_sk_value(EVP_MD, (st), (i))
+#define sk_EVP_MD_set(st, i, val) SKM_sk_set(EVP_MD, (st), (i), (val))
+#define sk_EVP_MD_zero(st) SKM_sk_zero(EVP_MD, (st))
+#define sk_EVP_MD_push(st, val) SKM_sk_push(EVP_MD, (st), (val))
+#define sk_EVP_MD_unshift(st, val) SKM_sk_unshift(EVP_MD, (st), (val))
+#define sk_EVP_MD_find(st, val) SKM_sk_find(EVP_MD, (st), (val))
+#define sk_EVP_MD_find_ex(st, val) SKM_sk_find_ex(EVP_MD, (st), (val))
+#define sk_EVP_MD_delete(st, i) SKM_sk_delete(EVP_MD, (st), (i))
+#define sk_EVP_MD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_MD, (st), (ptr))
+#define sk_EVP_MD_insert(st, val, i) SKM_sk_insert(EVP_MD, (st), (val), (i))
+#define sk_EVP_MD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_MD, (st), (cmp))
+#define sk_EVP_MD_dup(st) SKM_sk_dup(EVP_MD, st)
+#define sk_EVP_MD_pop_free(st, free_func) SKM_sk_pop_free(EVP_MD, (st), (free_func))
+#define sk_EVP_MD_shift(st) SKM_sk_shift(EVP_MD, (st))
+#define sk_EVP_MD_pop(st) SKM_sk_pop(EVP_MD, (st))
+#define sk_EVP_MD_sort(st) SKM_sk_sort(EVP_MD, (st))
+#define sk_EVP_MD_is_sorted(st) SKM_sk_is_sorted(EVP_MD, (st))
+
+#define sk_EVP_PBE_CTL_new(cmp) SKM_sk_new(EVP_PBE_CTL, (cmp))
+#define sk_EVP_PBE_CTL_new_null() SKM_sk_new_null(EVP_PBE_CTL)
+#define sk_EVP_PBE_CTL_free(st) SKM_sk_free(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_num(st) SKM_sk_num(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_value(st, i) SKM_sk_value(EVP_PBE_CTL, (st), (i))
+#define sk_EVP_PBE_CTL_set(st, i, val) SKM_sk_set(EVP_PBE_CTL, (st), (i), (val))
+#define sk_EVP_PBE_CTL_zero(st) SKM_sk_zero(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_push(st, val) SKM_sk_push(EVP_PBE_CTL, (st), (val))
+#define sk_EVP_PBE_CTL_unshift(st, val) SKM_sk_unshift(EVP_PBE_CTL, (st), (val))
+#define sk_EVP_PBE_CTL_find(st, val) SKM_sk_find(EVP_PBE_CTL, (st), (val))
+#define sk_EVP_PBE_CTL_find_ex(st, val) SKM_sk_find_ex(EVP_PBE_CTL, (st), (val))
+#define sk_EVP_PBE_CTL_delete(st, i) SKM_sk_delete(EVP_PBE_CTL, (st), (i))
+#define sk_EVP_PBE_CTL_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PBE_CTL, (st), (ptr))
+#define sk_EVP_PBE_CTL_insert(st, val, i) SKM_sk_insert(EVP_PBE_CTL, (st), (val), (i))
+#define sk_EVP_PBE_CTL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PBE_CTL, (st), (cmp))
+#define sk_EVP_PBE_CTL_dup(st) SKM_sk_dup(EVP_PBE_CTL, st)
+#define sk_EVP_PBE_CTL_pop_free(st, free_func) SKM_sk_pop_free(EVP_PBE_CTL, (st), (free_func))
+#define sk_EVP_PBE_CTL_shift(st) SKM_sk_shift(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_pop(st) SKM_sk_pop(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_sort(st) SKM_sk_sort(EVP_PBE_CTL, (st))
+#define sk_EVP_PBE_CTL_is_sorted(st) SKM_sk_is_sorted(EVP_PBE_CTL, (st))
+
+#define sk_EVP_PKEY_ASN1_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_ASN1_METHOD, (cmp))
+#define sk_EVP_PKEY_ASN1_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_ASN1_METHOD)
+#define sk_EVP_PKEY_ASN1_METHOD_free(st) SKM_sk_free(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_num(st) SKM_sk_num(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_ASN1_METHOD, (st), (i))
+#define sk_EVP_PKEY_ASN1_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_ASN1_METHOD, (st), (i), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_ASN1_METHOD, (st), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_ASN1_METHOD, (st), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_ASN1_METHOD, (st), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_ASN1_METHOD, (st), (val))
+#define sk_EVP_PKEY_ASN1_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_ASN1_METHOD, (st), (i))
+#define sk_EVP_PKEY_ASN1_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_ASN1_METHOD, (st), (ptr))
+#define sk_EVP_PKEY_ASN1_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_ASN1_METHOD, (st), (val), (i))
+#define sk_EVP_PKEY_ASN1_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_ASN1_METHOD, (st), (cmp))
+#define sk_EVP_PKEY_ASN1_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_ASN1_METHOD, st)
+#define sk_EVP_PKEY_ASN1_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_ASN1_METHOD, (st), (free_func))
+#define sk_EVP_PKEY_ASN1_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_ASN1_METHOD, (st))
+#define sk_EVP_PKEY_ASN1_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_ASN1_METHOD, (st))
+
+#define sk_EVP_PKEY_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_METHOD, (cmp))
+#define sk_EVP_PKEY_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_METHOD)
+#define sk_EVP_PKEY_METHOD_free(st) SKM_sk_free(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_num(st) SKM_sk_num(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_METHOD, (st), (i))
+#define sk_EVP_PKEY_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_METHOD, (st), (i), (val))
+#define sk_EVP_PKEY_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_METHOD, (st), (val))
+#define sk_EVP_PKEY_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_METHOD, (st), (val))
+#define sk_EVP_PKEY_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_METHOD, (st), (val))
+#define sk_EVP_PKEY_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_METHOD, (st), (val))
+#define sk_EVP_PKEY_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_METHOD, (st), (i))
+#define sk_EVP_PKEY_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_METHOD, (st), (ptr))
+#define sk_EVP_PKEY_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_METHOD, (st), (val), (i))
+#define sk_EVP_PKEY_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_METHOD, (st), (cmp))
+#define sk_EVP_PKEY_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_METHOD, st)
+#define sk_EVP_PKEY_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_METHOD, (st), (free_func))
+#define sk_EVP_PKEY_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_METHOD, (st))
+#define sk_EVP_PKEY_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_METHOD, (st))
+
+#define sk_GENERAL_NAME_new(cmp) SKM_sk_new(GENERAL_NAME, (cmp))
 #define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME)
 #define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st))
 #define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st))
@@ -700,7 +864,7 @@
 #define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st))
 #define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st))
 
-#define sk_GENERAL_NAMES_new(st) SKM_sk_new(GENERAL_NAMES, (st))
+#define sk_GENERAL_NAMES_new(cmp) SKM_sk_new(GENERAL_NAMES, (cmp))
 #define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES)
 #define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st))
 #define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st))
@@ -722,7 +886,7 @@
 #define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st))
 #define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st))
 
-#define sk_GENERAL_SUBTREE_new(st) SKM_sk_new(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_new(cmp) SKM_sk_new(GENERAL_SUBTREE, (cmp))
 #define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE)
 #define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st))
 #define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st))
@@ -744,7 +908,7 @@
 #define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st))
 #define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st))
 
-#define sk_IPAddressFamily_new(st) SKM_sk_new(IPAddressFamily, (st))
+#define sk_IPAddressFamily_new(cmp) SKM_sk_new(IPAddressFamily, (cmp))
 #define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily)
 #define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st))
 #define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st))
@@ -766,7 +930,7 @@
 #define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st))
 #define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st))
 
-#define sk_IPAddressOrRange_new(st) SKM_sk_new(IPAddressOrRange, (st))
+#define sk_IPAddressOrRange_new(cmp) SKM_sk_new(IPAddressOrRange, (cmp))
 #define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange)
 #define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st))
 #define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st))
@@ -788,7 +952,7 @@
 #define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st))
 #define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st))
 
-#define sk_KRB5_APREQBODY_new(st) SKM_sk_new(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_new(cmp) SKM_sk_new(KRB5_APREQBODY, (cmp))
 #define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY)
 #define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st))
 #define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st))
@@ -810,7 +974,7 @@
 #define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st))
 #define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st))
 
-#define sk_KRB5_AUTHDATA_new(st) SKM_sk_new(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_new(cmp) SKM_sk_new(KRB5_AUTHDATA, (cmp))
 #define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA)
 #define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st))
 #define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st))
@@ -832,7 +996,7 @@
 #define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st))
 #define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st))
 
-#define sk_KRB5_AUTHENTBODY_new(st) SKM_sk_new(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_new(cmp) SKM_sk_new(KRB5_AUTHENTBODY, (cmp))
 #define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY)
 #define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st))
 #define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st))
@@ -854,7 +1018,7 @@
 #define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st))
 #define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st))
 
-#define sk_KRB5_CHECKSUM_new(st) SKM_sk_new(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_new(cmp) SKM_sk_new(KRB5_CHECKSUM, (cmp))
 #define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM)
 #define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st))
 #define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st))
@@ -876,7 +1040,7 @@
 #define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st))
 #define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st))
 
-#define sk_KRB5_ENCDATA_new(st) SKM_sk_new(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_new(cmp) SKM_sk_new(KRB5_ENCDATA, (cmp))
 #define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA)
 #define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st))
 #define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st))
@@ -898,7 +1062,7 @@
 #define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st))
 #define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st))
 
-#define sk_KRB5_ENCKEY_new(st) SKM_sk_new(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_new(cmp) SKM_sk_new(KRB5_ENCKEY, (cmp))
 #define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY)
 #define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st))
 #define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st))
@@ -920,7 +1084,7 @@
 #define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st))
 #define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st))
 
-#define sk_KRB5_PRINCNAME_new(st) SKM_sk_new(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_new(cmp) SKM_sk_new(KRB5_PRINCNAME, (cmp))
 #define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME)
 #define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st))
 #define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st))
@@ -942,7 +1106,7 @@
 #define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st))
 #define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st))
 
-#define sk_KRB5_TKTBODY_new(st) SKM_sk_new(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_new(cmp) SKM_sk_new(KRB5_TKTBODY, (cmp))
 #define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY)
 #define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st))
 #define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st))
@@ -964,7 +1128,29 @@
 #define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st))
 #define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st))
 
-#define sk_MIME_HEADER_new(st) SKM_sk_new(MIME_HEADER, (st))
+#define sk_MEM_OBJECT_DATA_new(cmp) SKM_sk_new(MEM_OBJECT_DATA, (cmp))
+#define sk_MEM_OBJECT_DATA_new_null() SKM_sk_new_null(MEM_OBJECT_DATA)
+#define sk_MEM_OBJECT_DATA_free(st) SKM_sk_free(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_num(st) SKM_sk_num(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_value(st, i) SKM_sk_value(MEM_OBJECT_DATA, (st), (i))
+#define sk_MEM_OBJECT_DATA_set(st, i, val) SKM_sk_set(MEM_OBJECT_DATA, (st), (i), (val))
+#define sk_MEM_OBJECT_DATA_zero(st) SKM_sk_zero(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_push(st, val) SKM_sk_push(MEM_OBJECT_DATA, (st), (val))
+#define sk_MEM_OBJECT_DATA_unshift(st, val) SKM_sk_unshift(MEM_OBJECT_DATA, (st), (val))
+#define sk_MEM_OBJECT_DATA_find(st, val) SKM_sk_find(MEM_OBJECT_DATA, (st), (val))
+#define sk_MEM_OBJECT_DATA_find_ex(st, val) SKM_sk_find_ex(MEM_OBJECT_DATA, (st), (val))
+#define sk_MEM_OBJECT_DATA_delete(st, i) SKM_sk_delete(MEM_OBJECT_DATA, (st), (i))
+#define sk_MEM_OBJECT_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEM_OBJECT_DATA, (st), (ptr))
+#define sk_MEM_OBJECT_DATA_insert(st, val, i) SKM_sk_insert(MEM_OBJECT_DATA, (st), (val), (i))
+#define sk_MEM_OBJECT_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEM_OBJECT_DATA, (st), (cmp))
+#define sk_MEM_OBJECT_DATA_dup(st) SKM_sk_dup(MEM_OBJECT_DATA, st)
+#define sk_MEM_OBJECT_DATA_pop_free(st, free_func) SKM_sk_pop_free(MEM_OBJECT_DATA, (st), (free_func))
+#define sk_MEM_OBJECT_DATA_shift(st) SKM_sk_shift(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_pop(st) SKM_sk_pop(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_sort(st) SKM_sk_sort(MEM_OBJECT_DATA, (st))
+#define sk_MEM_OBJECT_DATA_is_sorted(st) SKM_sk_is_sorted(MEM_OBJECT_DATA, (st))
+
+#define sk_MIME_HEADER_new(cmp) SKM_sk_new(MIME_HEADER, (cmp))
 #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))
@@ -986,7 +1172,7 @@
 #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(cmp) SKM_sk_new(MIME_PARAM, (cmp))
 #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))
@@ -1008,7 +1194,7 @@
 #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_NAME_FUNCS_new(st) SKM_sk_new(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_new(cmp) SKM_sk_new(NAME_FUNCS, (cmp))
 #define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS)
 #define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st))
 #define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st))
@@ -1030,7 +1216,7 @@
 #define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st))
 #define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st))
 
-#define sk_OCSP_CERTID_new(st) SKM_sk_new(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_new(cmp) SKM_sk_new(OCSP_CERTID, (cmp))
 #define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID)
 #define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st))
 #define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st))
@@ -1052,7 +1238,7 @@
 #define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st))
 #define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st))
 
-#define sk_OCSP_ONEREQ_new(st) SKM_sk_new(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_new(cmp) SKM_sk_new(OCSP_ONEREQ, (cmp))
 #define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ)
 #define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st))
 #define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st))
@@ -1074,7 +1260,7 @@
 #define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st))
 #define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st))
 
-#define sk_OCSP_RESPID_new(st) SKM_sk_new(OCSP_RESPID, (st))
+#define sk_OCSP_RESPID_new(cmp) SKM_sk_new(OCSP_RESPID, (cmp))
 #define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID)
 #define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st))
 #define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st))
@@ -1096,7 +1282,7 @@
 #define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st))
 #define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st))
 
-#define sk_OCSP_SINGLERESP_new(st) SKM_sk_new(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_new(cmp) SKM_sk_new(OCSP_SINGLERESP, (cmp))
 #define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP)
 #define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st))
 #define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st))
@@ -1118,7 +1304,7 @@
 #define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st))
 #define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st))
 
-#define sk_PKCS12_SAFEBAG_new(st) SKM_sk_new(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_new(cmp) SKM_sk_new(PKCS12_SAFEBAG, (cmp))
 #define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG)
 #define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st))
 #define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st))
@@ -1140,7 +1326,7 @@
 #define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st))
 #define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st))
 
-#define sk_PKCS7_new(st) SKM_sk_new(PKCS7, (st))
+#define sk_PKCS7_new(cmp) SKM_sk_new(PKCS7, (cmp))
 #define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7)
 #define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st))
 #define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st))
@@ -1162,7 +1348,7 @@
 #define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st))
 #define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st))
 
-#define sk_PKCS7_RECIP_INFO_new(st) SKM_sk_new(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_new(cmp) SKM_sk_new(PKCS7_RECIP_INFO, (cmp))
 #define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO)
 #define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st))
 #define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st))
@@ -1184,7 +1370,7 @@
 #define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st))
 #define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st))
 
-#define sk_PKCS7_SIGNER_INFO_new(st) SKM_sk_new(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_new(cmp) SKM_sk_new(PKCS7_SIGNER_INFO, (cmp))
 #define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO)
 #define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st))
 #define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st))
@@ -1206,7 +1392,7 @@
 #define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st))
 #define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st))
 
-#define sk_POLICYINFO_new(st) SKM_sk_new(POLICYINFO, (st))
+#define sk_POLICYINFO_new(cmp) SKM_sk_new(POLICYINFO, (cmp))
 #define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO)
 #define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st))
 #define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st))
@@ -1228,7 +1414,7 @@
 #define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st))
 #define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st))
 
-#define sk_POLICYQUALINFO_new(st) SKM_sk_new(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_new(cmp) SKM_sk_new(POLICYQUALINFO, (cmp))
 #define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO)
 #define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st))
 #define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st))
@@ -1250,7 +1436,7 @@
 #define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st))
 #define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st))
 
-#define sk_POLICY_MAPPING_new(st) SKM_sk_new(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_new(cmp) SKM_sk_new(POLICY_MAPPING, (cmp))
 #define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING)
 #define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st))
 #define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st))
@@ -1272,7 +1458,7 @@
 #define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st))
 #define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st))
 
-#define sk_SSL_CIPHER_new(st) SKM_sk_new(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp))
 #define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER)
 #define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st))
 #define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st))
@@ -1294,7 +1480,7 @@
 #define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st))
 #define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st))
 
-#define sk_SSL_COMP_new(st) SKM_sk_new(SSL_COMP, (st))
+#define sk_SSL_COMP_new(cmp) SKM_sk_new(SSL_COMP, (cmp))
 #define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP)
 #define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st))
 #define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st))
@@ -1316,7 +1502,51 @@
 #define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st))
 #define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st))
 
-#define sk_STORE_OBJECT_new(st) SKM_sk_new(STORE_OBJECT, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_new(cmp) SKM_sk_new(STACK_OF_X509_NAME_ENTRY, (cmp))
+#define sk_STACK_OF_X509_NAME_ENTRY_new_null() SKM_sk_new_null(STACK_OF_X509_NAME_ENTRY)
+#define sk_STACK_OF_X509_NAME_ENTRY_free(st) SKM_sk_free(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_num(st) SKM_sk_num(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_value(st, i) SKM_sk_value(STACK_OF_X509_NAME_ENTRY, (st), (i))
+#define sk_STACK_OF_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(STACK_OF_X509_NAME_ENTRY, (st), (i), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_zero(st) SKM_sk_zero(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_push(st, val) SKM_sk_push(STACK_OF_X509_NAME_ENTRY, (st), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(STACK_OF_X509_NAME_ENTRY, (st), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_find(st, val) SKM_sk_find(STACK_OF_X509_NAME_ENTRY, (st), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(STACK_OF_X509_NAME_ENTRY, (st), (val))
+#define sk_STACK_OF_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(STACK_OF_X509_NAME_ENTRY, (st), (i))
+#define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(STACK_OF_X509_NAME_ENTRY, (st), (ptr))
+#define sk_STACK_OF_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(STACK_OF_X509_NAME_ENTRY, (st), (val), (i))
+#define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STACK_OF_X509_NAME_ENTRY, (st), (cmp))
+#define sk_STACK_OF_X509_NAME_ENTRY_dup(st) SKM_sk_dup(STACK_OF_X509_NAME_ENTRY, st)
+#define sk_STACK_OF_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(STACK_OF_X509_NAME_ENTRY, (st), (free_func))
+#define sk_STACK_OF_X509_NAME_ENTRY_shift(st) SKM_sk_shift(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_pop(st) SKM_sk_pop(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_sort(st) SKM_sk_sort(STACK_OF_X509_NAME_ENTRY, (st))
+#define sk_STACK_OF_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(STACK_OF_X509_NAME_ENTRY, (st))
+
+#define sk_STORE_ATTR_INFO_new(cmp) SKM_sk_new(STORE_ATTR_INFO, (cmp))
+#define sk_STORE_ATTR_INFO_new_null() SKM_sk_new_null(STORE_ATTR_INFO)
+#define sk_STORE_ATTR_INFO_free(st) SKM_sk_free(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_num(st) SKM_sk_num(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_value(st, i) SKM_sk_value(STORE_ATTR_INFO, (st), (i))
+#define sk_STORE_ATTR_INFO_set(st, i, val) SKM_sk_set(STORE_ATTR_INFO, (st), (i), (val))
+#define sk_STORE_ATTR_INFO_zero(st) SKM_sk_zero(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_push(st, val) SKM_sk_push(STORE_ATTR_INFO, (st), (val))
+#define sk_STORE_ATTR_INFO_unshift(st, val) SKM_sk_unshift(STORE_ATTR_INFO, (st), (val))
+#define sk_STORE_ATTR_INFO_find(st, val) SKM_sk_find(STORE_ATTR_INFO, (st), (val))
+#define sk_STORE_ATTR_INFO_find_ex(st, val) SKM_sk_find_ex(STORE_ATTR_INFO, (st), (val))
+#define sk_STORE_ATTR_INFO_delete(st, i) SKM_sk_delete(STORE_ATTR_INFO, (st), (i))
+#define sk_STORE_ATTR_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_ATTR_INFO, (st), (ptr))
+#define sk_STORE_ATTR_INFO_insert(st, val, i) SKM_sk_insert(STORE_ATTR_INFO, (st), (val), (i))
+#define sk_STORE_ATTR_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_ATTR_INFO, (st), (cmp))
+#define sk_STORE_ATTR_INFO_dup(st) SKM_sk_dup(STORE_ATTR_INFO, st)
+#define sk_STORE_ATTR_INFO_pop_free(st, free_func) SKM_sk_pop_free(STORE_ATTR_INFO, (st), (free_func))
+#define sk_STORE_ATTR_INFO_shift(st) SKM_sk_shift(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_pop(st) SKM_sk_pop(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_sort(st) SKM_sk_sort(STORE_ATTR_INFO, (st))
+#define sk_STORE_ATTR_INFO_is_sorted(st) SKM_sk_is_sorted(STORE_ATTR_INFO, (st))
+
+#define sk_STORE_OBJECT_new(cmp) SKM_sk_new(STORE_OBJECT, (cmp))
 #define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT)
 #define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st))
 #define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st))
@@ -1338,7 +1568,7 @@
 #define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st))
 #define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st))
 
-#define sk_SXNETID_new(st) SKM_sk_new(SXNETID, (st))
+#define sk_SXNETID_new(cmp) SKM_sk_new(SXNETID, (cmp))
 #define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID)
 #define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st))
 #define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st))
@@ -1360,7 +1590,7 @@
 #define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st))
 #define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st))
 
-#define sk_UI_STRING_new(st) SKM_sk_new(UI_STRING, (st))
+#define sk_UI_STRING_new(cmp) SKM_sk_new(UI_STRING, (cmp))
 #define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING)
 #define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st))
 #define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st))
@@ -1382,7 +1612,7 @@
 #define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st))
 #define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st))
 
-#define sk_X509_new(st) SKM_sk_new(X509, (st))
+#define sk_X509_new(cmp) SKM_sk_new(X509, (cmp))
 #define sk_X509_new_null() SKM_sk_new_null(X509)
 #define sk_X509_free(st) SKM_sk_free(X509, (st))
 #define sk_X509_num(st) SKM_sk_num(X509, (st))
@@ -1404,7 +1634,7 @@
 #define sk_X509_sort(st) SKM_sk_sort(X509, (st))
 #define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st))
 
-#define sk_X509V3_EXT_METHOD_new(st) SKM_sk_new(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_new(cmp) SKM_sk_new(X509V3_EXT_METHOD, (cmp))
 #define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD)
 #define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st))
 #define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st))
@@ -1426,7 +1656,7 @@
 #define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st))
 #define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st))
 
-#define sk_X509_ALGOR_new(st) SKM_sk_new(X509_ALGOR, (st))
+#define sk_X509_ALGOR_new(cmp) SKM_sk_new(X509_ALGOR, (cmp))
 #define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR)
 #define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st))
 #define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st))
@@ -1448,7 +1678,7 @@
 #define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st))
 #define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st))
 
-#define sk_X509_ATTRIBUTE_new(st) SKM_sk_new(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_new(cmp) SKM_sk_new(X509_ATTRIBUTE, (cmp))
 #define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE)
 #define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st))
 #define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st))
@@ -1470,7 +1700,7 @@
 #define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st))
 #define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st))
 
-#define sk_X509_CRL_new(st) SKM_sk_new(X509_CRL, (st))
+#define sk_X509_CRL_new(cmp) SKM_sk_new(X509_CRL, (cmp))
 #define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL)
 #define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st))
 #define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st))
@@ -1492,7 +1722,7 @@
 #define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st))
 #define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st))
 
-#define sk_X509_EXTENSION_new(st) SKM_sk_new(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_new(cmp) SKM_sk_new(X509_EXTENSION, (cmp))
 #define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION)
 #define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st))
 #define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st))
@@ -1514,7 +1744,7 @@
 #define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st))
 #define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st))
 
-#define sk_X509_INFO_new(st) SKM_sk_new(X509_INFO, (st))
+#define sk_X509_INFO_new(cmp) SKM_sk_new(X509_INFO, (cmp))
 #define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO)
 #define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st))
 #define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st))
@@ -1536,7 +1766,7 @@
 #define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st))
 #define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st))
 
-#define sk_X509_LOOKUP_new(st) SKM_sk_new(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_new(cmp) SKM_sk_new(X509_LOOKUP, (cmp))
 #define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP)
 #define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st))
 #define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st))
@@ -1558,7 +1788,7 @@
 #define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st))
 #define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st))
 
-#define sk_X509_NAME_new(st) SKM_sk_new(X509_NAME, (st))
+#define sk_X509_NAME_new(cmp) SKM_sk_new(X509_NAME, (cmp))
 #define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME)
 #define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st))
 #define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st))
@@ -1580,7 +1810,7 @@
 #define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st))
 #define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st))
 
-#define sk_X509_NAME_ENTRY_new(st) SKM_sk_new(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_new(cmp) SKM_sk_new(X509_NAME_ENTRY, (cmp))
 #define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY)
 #define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st))
 #define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st))
@@ -1602,7 +1832,7 @@
 #define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st))
 #define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st))
 
-#define sk_X509_OBJECT_new(st) SKM_sk_new(X509_OBJECT, (st))
+#define sk_X509_OBJECT_new(cmp) SKM_sk_new(X509_OBJECT, (cmp))
 #define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT)
 #define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st))
 #define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st))
@@ -1624,7 +1854,7 @@
 #define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st))
 #define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st))
 
-#define sk_X509_POLICY_DATA_new(st) SKM_sk_new(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_new(cmp) SKM_sk_new(X509_POLICY_DATA, (cmp))
 #define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA)
 #define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st))
 #define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st))
@@ -1646,7 +1876,7 @@
 #define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st))
 #define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st))
 
-#define sk_X509_POLICY_NODE_new(st) SKM_sk_new(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp))
 #define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE)
 #define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st))
 #define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st))
@@ -1668,29 +1898,7 @@
 #define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st))
 #define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st))
 
-#define sk_X509_POLICY_REF_new(st) SKM_sk_new(X509_POLICY_REF, (st))
-#define sk_X509_POLICY_REF_new_null() SKM_sk_new_null(X509_POLICY_REF)
-#define sk_X509_POLICY_REF_free(st) SKM_sk_free(X509_POLICY_REF, (st))
-#define sk_X509_POLICY_REF_num(st) SKM_sk_num(X509_POLICY_REF, (st))
-#define sk_X509_POLICY_REF_value(st, i) SKM_sk_value(X509_POLICY_REF, (st), (i))
-#define sk_X509_POLICY_REF_set(st, i, val) SKM_sk_set(X509_POLICY_REF, (st), (i), (val))
-#define sk_X509_POLICY_REF_zero(st) SKM_sk_zero(X509_POLICY_REF, (st))
-#define sk_X509_POLICY_REF_push(st, val) SKM_sk_push(X509_POLICY_REF, (st), (val))
-#define sk_X509_POLICY_REF_unshift(st, val) SKM_sk_unshift(X509_POLICY_REF, (st), (val))
-#define sk_X509_POLICY_REF_find(st, val) SKM_sk_find(X509_POLICY_REF, (st), (val))
-#define sk_X509_POLICY_REF_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_REF, (st), (val))
-#define sk_X509_POLICY_REF_delete(st, i) SKM_sk_delete(X509_POLICY_REF, (st), (i))
-#define sk_X509_POLICY_REF_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_REF, (st), (ptr))
-#define sk_X509_POLICY_REF_insert(st, val, i) SKM_sk_insert(X509_POLICY_REF, (st), (val), (i))
-#define sk_X509_POLICY_REF_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_REF, (st), (cmp))
-#define sk_X509_POLICY_REF_dup(st) SKM_sk_dup(X509_POLICY_REF, st)
-#define sk_X509_POLICY_REF_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_REF, (st), (free_func))
-#define sk_X509_POLICY_REF_shift(st) SKM_sk_shift(X509_POLICY_REF, (st))
-#define sk_X509_POLICY_REF_pop(st) SKM_sk_pop(X509_POLICY_REF, (st))
-#define sk_X509_POLICY_REF_sort(st) SKM_sk_sort(X509_POLICY_REF, (st))
-#define sk_X509_POLICY_REF_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_REF, (st))
-
-#define sk_X509_PURPOSE_new(st) SKM_sk_new(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_new(cmp) SKM_sk_new(X509_PURPOSE, (cmp))
 #define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE)
 #define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st))
 #define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st))
@@ -1712,7 +1920,7 @@
 #define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st))
 #define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st))
 
-#define sk_X509_REVOKED_new(st) SKM_sk_new(X509_REVOKED, (st))
+#define sk_X509_REVOKED_new(cmp) SKM_sk_new(X509_REVOKED, (cmp))
 #define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED)
 #define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st))
 #define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st))
@@ -1734,7 +1942,7 @@
 #define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st))
 #define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st))
 
-#define sk_X509_TRUST_new(st) SKM_sk_new(X509_TRUST, (st))
+#define sk_X509_TRUST_new(cmp) SKM_sk_new(X509_TRUST, (cmp))
 #define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST)
 #define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st))
 #define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st))
@@ -1756,7 +1964,7 @@
 #define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st))
 #define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st))
 
-#define sk_X509_VERIFY_PARAM_new(st) SKM_sk_new(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_new(cmp) SKM_sk_new(X509_VERIFY_PARAM, (cmp))
 #define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM)
 #define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st))
 #define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st))
@@ -1778,6 +1986,125 @@
 #define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st))
 #define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st))
 
+#define sk_nid_triple_new(cmp) SKM_sk_new(nid_triple, (cmp))
+#define sk_nid_triple_new_null() SKM_sk_new_null(nid_triple)
+#define sk_nid_triple_free(st) SKM_sk_free(nid_triple, (st))
+#define sk_nid_triple_num(st) SKM_sk_num(nid_triple, (st))
+#define sk_nid_triple_value(st, i) SKM_sk_value(nid_triple, (st), (i))
+#define sk_nid_triple_set(st, i, val) SKM_sk_set(nid_triple, (st), (i), (val))
+#define sk_nid_triple_zero(st) SKM_sk_zero(nid_triple, (st))
+#define sk_nid_triple_push(st, val) SKM_sk_push(nid_triple, (st), (val))
+#define sk_nid_triple_unshift(st, val) SKM_sk_unshift(nid_triple, (st), (val))
+#define sk_nid_triple_find(st, val) SKM_sk_find(nid_triple, (st), (val))
+#define sk_nid_triple_find_ex(st, val) SKM_sk_find_ex(nid_triple, (st), (val))
+#define sk_nid_triple_delete(st, i) SKM_sk_delete(nid_triple, (st), (i))
+#define sk_nid_triple_delete_ptr(st, ptr) SKM_sk_delete_ptr(nid_triple, (st), (ptr))
+#define sk_nid_triple_insert(st, val, i) SKM_sk_insert(nid_triple, (st), (val), (i))
+#define sk_nid_triple_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(nid_triple, (st), (cmp))
+#define sk_nid_triple_dup(st) SKM_sk_dup(nid_triple, st)
+#define sk_nid_triple_pop_free(st, free_func) SKM_sk_pop_free(nid_triple, (st), (free_func))
+#define sk_nid_triple_shift(st) SKM_sk_shift(nid_triple, (st))
+#define sk_nid_triple_pop(st) SKM_sk_pop(nid_triple, (st))
+#define sk_nid_triple_sort(st) SKM_sk_sort(nid_triple, (st))
+#define sk_nid_triple_is_sorted(st) SKM_sk_is_sorted(nid_triple, (st))
+
+#define sk_void_new(cmp) SKM_sk_new(void, (cmp))
+#define sk_void_new_null() SKM_sk_new_null(void)
+#define sk_void_free(st) SKM_sk_free(void, (st))
+#define sk_void_num(st) SKM_sk_num(void, (st))
+#define sk_void_value(st, i) SKM_sk_value(void, (st), (i))
+#define sk_void_set(st, i, val) SKM_sk_set(void, (st), (i), (val))
+#define sk_void_zero(st) SKM_sk_zero(void, (st))
+#define sk_void_push(st, val) SKM_sk_push(void, (st), (val))
+#define sk_void_unshift(st, val) SKM_sk_unshift(void, (st), (val))
+#define sk_void_find(st, val) SKM_sk_find(void, (st), (val))
+#define sk_void_find_ex(st, val) SKM_sk_find_ex(void, (st), (val))
+#define sk_void_delete(st, i) SKM_sk_delete(void, (st), (i))
+#define sk_void_delete_ptr(st, ptr) SKM_sk_delete_ptr(void, (st), (ptr))
+#define sk_void_insert(st, val, i) SKM_sk_insert(void, (st), (val), (i))
+#define sk_void_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(void, (st), (cmp))
+#define sk_void_dup(st) SKM_sk_dup(void, st)
+#define sk_void_pop_free(st, free_func) SKM_sk_pop_free(void, (st), (free_func))
+#define sk_void_shift(st) SKM_sk_shift(void, (st))
+#define sk_void_pop(st) SKM_sk_pop(void, (st))
+#define sk_void_sort(st) SKM_sk_sort(void, (st))
+#define sk_void_is_sorted(st) SKM_sk_is_sorted(void, (st))
+
+#define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_SK_CMP_FUNC(void, cmp)))
+#define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null())
+#define sk_OPENSSL_BLOCK_push(st, val) sk_push(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_find(st, val) sk_find(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_value(st, i) ((OPENSSL_BLOCK)sk_value(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), i))
+#define sk_OPENSSL_BLOCK_num(st) SKM_sk_num(OPENSSL_BLOCK, st)
+#define sk_OPENSSL_BLOCK_pop_free(st, free_func) sk_pop_free(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_SK_FREE_FUNC2(OPENSSL_BLOCK, free_func))
+#define sk_OPENSSL_BLOCK_insert(st, val, i) sk_insert(CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, val), i)
+#define sk_OPENSSL_BLOCK_free(st) SKM_sk_free(OPENSSL_BLOCK, st)
+#define sk_OPENSSL_BLOCK_set(st, i, val) sk_set((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), i, CHECKED_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_zero(st) SKM_sk_zero(OPENSSL_BLOCK, (st))
+#define sk_OPENSSL_BLOCK_unshift(st, val) sk_unshift((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_CONST_PTR_OF(void, val))
+#define sk_OPENSSL_BLOCK_delete(st, i) SKM_sk_delete(OPENSSL_BLOCK, (st), (i))
+#define sk_OPENSSL_BLOCK_delete_ptr(st, ptr) (OPENSSL_BLOCK *)sk_delete_ptr((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_PTR_OF(void, ptr))
+#define sk_OPENSSL_BLOCK_set_cmp_func(st, cmp)  \
+	((int (*)(const void * const *,const void * const *)) \
+	sk_set_cmp_func((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_SK_CMP_FUNC(void, cmp)))
+#define sk_OPENSSL_BLOCK_dup(st) SKM_sk_dup(OPENSSL_BLOCK, st)
+#define sk_OPENSSL_BLOCK_shift(st) SKM_sk_shift(OPENSSL_BLOCK, (st))
+#define sk_OPENSSL_BLOCK_pop(st) (void *)sk_pop((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_BLOCK), st))
+#define sk_OPENSSL_BLOCK_sort(st) SKM_sk_sort(OPENSSL_BLOCK, (st))
+#define sk_OPENSSL_BLOCK_is_sorted(st) SKM_sk_is_sorted(OPENSSL_BLOCK, (st))
+
+
+#define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
+#define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null())
+#define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), i))
+#define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st)
+#define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_SK_FREE_FUNC2(OPENSSL_PSTRING, free_func))
+#define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, val), i)
+#define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st)
+#define sk_OPENSSL_PSTRING_set(st, i, val) sk_set((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), i, CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st))
+#define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val))
+#define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i))
+#define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_PTR_OF(OPENSSL_STRING, ptr))
+#define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp)  \
+	((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \
+	sk_set_cmp_func((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
+#define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st)
+#define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st))
+#define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_PSTRING), st))
+#define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st))
+#define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st))
+
+
+#define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)sk_new(CHECKED_SK_CMP_FUNC(char, cmp)))
+#define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)sk_new_null())
+#define sk_OPENSSL_STRING_push(st, val) sk_push(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), i))
+#define sk_OPENSSL_STRING_num(st) SKM_sk_num(OPENSSL_STRING, st)
+#define sk_OPENSSL_STRING_pop_free(st, free_func) sk_pop_free(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_SK_FREE_FUNC2(OPENSSL_STRING, free_func))
+#define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, val), i)
+#define sk_OPENSSL_STRING_free(st) SKM_sk_free(OPENSSL_STRING, st)
+#define sk_OPENSSL_STRING_set(st, i, val) sk_set((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), i, CHECKED_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_zero(st) SKM_sk_zero(OPENSSL_STRING, (st))
+#define sk_OPENSSL_STRING_unshift(st, val) sk_unshift((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_CONST_PTR_OF(char, val))
+#define sk_OPENSSL_STRING_delete(st, i) SKM_sk_delete(OPENSSL_STRING, (st), (i))
+#define sk_OPENSSL_STRING_delete_ptr(st, ptr) (OPENSSL_STRING *)sk_delete_ptr((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_PTR_OF(char, ptr))
+#define sk_OPENSSL_STRING_set_cmp_func(st, cmp)  \
+	((int (*)(const char * const *,const char * const *)) \
+	sk_set_cmp_func((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_SK_CMP_FUNC(char, cmp)))
+#define sk_OPENSSL_STRING_dup(st) SKM_sk_dup(OPENSSL_STRING, st)
+#define sk_OPENSSL_STRING_shift(st) SKM_sk_shift(OPENSSL_STRING, (st))
+#define sk_OPENSSL_STRING_pop(st) (char *)sk_pop((_STACK *)CHECKED_PTR_OF(STACK_OF(OPENSSL_STRING), st))
+#define sk_OPENSSL_STRING_sort(st) SKM_sk_sort(OPENSSL_STRING, (st))
+#define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st))
+
+
 #define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
 	SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
 #define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
@@ -1814,6 +2141,15 @@
 #define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \
 	SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func))
 
+#define d2i_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(ASN1_UTF8STRING, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(ASN1_UTF8STRING, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ASN1_UTF8STRING(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(ASN1_UTF8STRING, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ASN1_UTF8STRING(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(ASN1_UTF8STRING, (buf), (len), (d2i_func), (free_func))
+
 #define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
 	SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
 #define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
@@ -1823,6 +2159,24 @@
 #define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \
 	SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func))
 
+#define d2i_ASN1_SET_OF_ESS_CERT_ID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(ESS_CERT_ID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_ESS_CERT_ID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(ESS_CERT_ID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ESS_CERT_ID(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(ESS_CERT_ID, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ESS_CERT_ID(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(ESS_CERT_ID, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_EVP_MD(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(EVP_MD, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_EVP_MD(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(EVP_MD, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_EVP_MD(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(EVP_MD, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_EVP_MD(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(EVP_MD, (buf), (len), (d2i_func), (free_func))
+
 #define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
 	SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
 #define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \
@@ -1981,6 +2335,240 @@
 
 #define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \
 	SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
+
+#define lh_ADDED_OBJ_new() LHM_lh_new(ADDED_OBJ,added_obj)
+#define lh_ADDED_OBJ_insert(lh,inst) LHM_lh_insert(ADDED_OBJ,lh,inst)
+#define lh_ADDED_OBJ_retrieve(lh,inst) LHM_lh_retrieve(ADDED_OBJ,lh,inst)
+#define lh_ADDED_OBJ_delete(lh,inst) LHM_lh_delete(ADDED_OBJ,lh,inst)
+#define lh_ADDED_OBJ_doall(lh,fn) LHM_lh_doall(ADDED_OBJ,lh,fn)
+#define lh_ADDED_OBJ_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(ADDED_OBJ,lh,fn,arg_type,arg)
+#define lh_ADDED_OBJ_error(lh) LHM_lh_error(ADDED_OBJ,lh)
+#define lh_ADDED_OBJ_num_items(lh) LHM_lh_num_items(ADDED_OBJ,lh)
+#define lh_ADDED_OBJ_down_load(lh) LHM_lh_down_load(ADDED_OBJ,lh)
+#define lh_ADDED_OBJ_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(ADDED_OBJ,lh,out)
+#define lh_ADDED_OBJ_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(ADDED_OBJ,lh,out)
+#define lh_ADDED_OBJ_stats_bio(lh,out) \
+  LHM_lh_stats_bio(ADDED_OBJ,lh,out)
+#define lh_ADDED_OBJ_free(lh) LHM_lh_free(ADDED_OBJ,lh)
+
+#define lh_APP_INFO_new() LHM_lh_new(APP_INFO,app_info)
+#define lh_APP_INFO_insert(lh,inst) LHM_lh_insert(APP_INFO,lh,inst)
+#define lh_APP_INFO_retrieve(lh,inst) LHM_lh_retrieve(APP_INFO,lh,inst)
+#define lh_APP_INFO_delete(lh,inst) LHM_lh_delete(APP_INFO,lh,inst)
+#define lh_APP_INFO_doall(lh,fn) LHM_lh_doall(APP_INFO,lh,fn)
+#define lh_APP_INFO_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(APP_INFO,lh,fn,arg_type,arg)
+#define lh_APP_INFO_error(lh) LHM_lh_error(APP_INFO,lh)
+#define lh_APP_INFO_num_items(lh) LHM_lh_num_items(APP_INFO,lh)
+#define lh_APP_INFO_down_load(lh) LHM_lh_down_load(APP_INFO,lh)
+#define lh_APP_INFO_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(APP_INFO,lh,out)
+#define lh_APP_INFO_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(APP_INFO,lh,out)
+#define lh_APP_INFO_stats_bio(lh,out) \
+  LHM_lh_stats_bio(APP_INFO,lh,out)
+#define lh_APP_INFO_free(lh) LHM_lh_free(APP_INFO,lh)
+
+#define lh_CONF_VALUE_new() LHM_lh_new(CONF_VALUE,conf_value)
+#define lh_CONF_VALUE_insert(lh,inst) LHM_lh_insert(CONF_VALUE,lh,inst)
+#define lh_CONF_VALUE_retrieve(lh,inst) LHM_lh_retrieve(CONF_VALUE,lh,inst)
+#define lh_CONF_VALUE_delete(lh,inst) LHM_lh_delete(CONF_VALUE,lh,inst)
+#define lh_CONF_VALUE_doall(lh,fn) LHM_lh_doall(CONF_VALUE,lh,fn)
+#define lh_CONF_VALUE_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(CONF_VALUE,lh,fn,arg_type,arg)
+#define lh_CONF_VALUE_error(lh) LHM_lh_error(CONF_VALUE,lh)
+#define lh_CONF_VALUE_num_items(lh) LHM_lh_num_items(CONF_VALUE,lh)
+#define lh_CONF_VALUE_down_load(lh) LHM_lh_down_load(CONF_VALUE,lh)
+#define lh_CONF_VALUE_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(CONF_VALUE,lh,out)
+#define lh_CONF_VALUE_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(CONF_VALUE,lh,out)
+#define lh_CONF_VALUE_stats_bio(lh,out) \
+  LHM_lh_stats_bio(CONF_VALUE,lh,out)
+#define lh_CONF_VALUE_free(lh) LHM_lh_free(CONF_VALUE,lh)
+
+#define lh_ENGINE_PILE_new() LHM_lh_new(ENGINE_PILE,engine_pile)
+#define lh_ENGINE_PILE_insert(lh,inst) LHM_lh_insert(ENGINE_PILE,lh,inst)
+#define lh_ENGINE_PILE_retrieve(lh,inst) LHM_lh_retrieve(ENGINE_PILE,lh,inst)
+#define lh_ENGINE_PILE_delete(lh,inst) LHM_lh_delete(ENGINE_PILE,lh,inst)
+#define lh_ENGINE_PILE_doall(lh,fn) LHM_lh_doall(ENGINE_PILE,lh,fn)
+#define lh_ENGINE_PILE_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(ENGINE_PILE,lh,fn,arg_type,arg)
+#define lh_ENGINE_PILE_error(lh) LHM_lh_error(ENGINE_PILE,lh)
+#define lh_ENGINE_PILE_num_items(lh) LHM_lh_num_items(ENGINE_PILE,lh)
+#define lh_ENGINE_PILE_down_load(lh) LHM_lh_down_load(ENGINE_PILE,lh)
+#define lh_ENGINE_PILE_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(ENGINE_PILE,lh,out)
+#define lh_ENGINE_PILE_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(ENGINE_PILE,lh,out)
+#define lh_ENGINE_PILE_stats_bio(lh,out) \
+  LHM_lh_stats_bio(ENGINE_PILE,lh,out)
+#define lh_ENGINE_PILE_free(lh) LHM_lh_free(ENGINE_PILE,lh)
+
+#define lh_ERR_STATE_new() LHM_lh_new(ERR_STATE,err_state)
+#define lh_ERR_STATE_insert(lh,inst) LHM_lh_insert(ERR_STATE,lh,inst)
+#define lh_ERR_STATE_retrieve(lh,inst) LHM_lh_retrieve(ERR_STATE,lh,inst)
+#define lh_ERR_STATE_delete(lh,inst) LHM_lh_delete(ERR_STATE,lh,inst)
+#define lh_ERR_STATE_doall(lh,fn) LHM_lh_doall(ERR_STATE,lh,fn)
+#define lh_ERR_STATE_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(ERR_STATE,lh,fn,arg_type,arg)
+#define lh_ERR_STATE_error(lh) LHM_lh_error(ERR_STATE,lh)
+#define lh_ERR_STATE_num_items(lh) LHM_lh_num_items(ERR_STATE,lh)
+#define lh_ERR_STATE_down_load(lh) LHM_lh_down_load(ERR_STATE,lh)
+#define lh_ERR_STATE_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(ERR_STATE,lh,out)
+#define lh_ERR_STATE_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(ERR_STATE,lh,out)
+#define lh_ERR_STATE_stats_bio(lh,out) \
+  LHM_lh_stats_bio(ERR_STATE,lh,out)
+#define lh_ERR_STATE_free(lh) LHM_lh_free(ERR_STATE,lh)
+
+#define lh_ERR_STRING_DATA_new() LHM_lh_new(ERR_STRING_DATA,err_string_data)
+#define lh_ERR_STRING_DATA_insert(lh,inst) LHM_lh_insert(ERR_STRING_DATA,lh,inst)
+#define lh_ERR_STRING_DATA_retrieve(lh,inst) LHM_lh_retrieve(ERR_STRING_DATA,lh,inst)
+#define lh_ERR_STRING_DATA_delete(lh,inst) LHM_lh_delete(ERR_STRING_DATA,lh,inst)
+#define lh_ERR_STRING_DATA_doall(lh,fn) LHM_lh_doall(ERR_STRING_DATA,lh,fn)
+#define lh_ERR_STRING_DATA_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(ERR_STRING_DATA,lh,fn,arg_type,arg)
+#define lh_ERR_STRING_DATA_error(lh) LHM_lh_error(ERR_STRING_DATA,lh)
+#define lh_ERR_STRING_DATA_num_items(lh) LHM_lh_num_items(ERR_STRING_DATA,lh)
+#define lh_ERR_STRING_DATA_down_load(lh) LHM_lh_down_load(ERR_STRING_DATA,lh)
+#define lh_ERR_STRING_DATA_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(ERR_STRING_DATA,lh,out)
+#define lh_ERR_STRING_DATA_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(ERR_STRING_DATA,lh,out)
+#define lh_ERR_STRING_DATA_stats_bio(lh,out) \
+  LHM_lh_stats_bio(ERR_STRING_DATA,lh,out)
+#define lh_ERR_STRING_DATA_free(lh) LHM_lh_free(ERR_STRING_DATA,lh)
+
+#define lh_EX_CLASS_ITEM_new() LHM_lh_new(EX_CLASS_ITEM,ex_class_item)
+#define lh_EX_CLASS_ITEM_insert(lh,inst) LHM_lh_insert(EX_CLASS_ITEM,lh,inst)
+#define lh_EX_CLASS_ITEM_retrieve(lh,inst) LHM_lh_retrieve(EX_CLASS_ITEM,lh,inst)
+#define lh_EX_CLASS_ITEM_delete(lh,inst) LHM_lh_delete(EX_CLASS_ITEM,lh,inst)
+#define lh_EX_CLASS_ITEM_doall(lh,fn) LHM_lh_doall(EX_CLASS_ITEM,lh,fn)
+#define lh_EX_CLASS_ITEM_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(EX_CLASS_ITEM,lh,fn,arg_type,arg)
+#define lh_EX_CLASS_ITEM_error(lh) LHM_lh_error(EX_CLASS_ITEM,lh)
+#define lh_EX_CLASS_ITEM_num_items(lh) LHM_lh_num_items(EX_CLASS_ITEM,lh)
+#define lh_EX_CLASS_ITEM_down_load(lh) LHM_lh_down_load(EX_CLASS_ITEM,lh)
+#define lh_EX_CLASS_ITEM_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(EX_CLASS_ITEM,lh,out)
+#define lh_EX_CLASS_ITEM_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(EX_CLASS_ITEM,lh,out)
+#define lh_EX_CLASS_ITEM_stats_bio(lh,out) \
+  LHM_lh_stats_bio(EX_CLASS_ITEM,lh,out)
+#define lh_EX_CLASS_ITEM_free(lh) LHM_lh_free(EX_CLASS_ITEM,lh)
+
+#define lh_FUNCTION_new() LHM_lh_new(FUNCTION,function)
+#define lh_FUNCTION_insert(lh,inst) LHM_lh_insert(FUNCTION,lh,inst)
+#define lh_FUNCTION_retrieve(lh,inst) LHM_lh_retrieve(FUNCTION,lh,inst)
+#define lh_FUNCTION_delete(lh,inst) LHM_lh_delete(FUNCTION,lh,inst)
+#define lh_FUNCTION_doall(lh,fn) LHM_lh_doall(FUNCTION,lh,fn)
+#define lh_FUNCTION_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(FUNCTION,lh,fn,arg_type,arg)
+#define lh_FUNCTION_error(lh) LHM_lh_error(FUNCTION,lh)
+#define lh_FUNCTION_num_items(lh) LHM_lh_num_items(FUNCTION,lh)
+#define lh_FUNCTION_down_load(lh) LHM_lh_down_load(FUNCTION,lh)
+#define lh_FUNCTION_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(FUNCTION,lh,out)
+#define lh_FUNCTION_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(FUNCTION,lh,out)
+#define lh_FUNCTION_stats_bio(lh,out) \
+  LHM_lh_stats_bio(FUNCTION,lh,out)
+#define lh_FUNCTION_free(lh) LHM_lh_free(FUNCTION,lh)
+
+#define lh_MEM_new() LHM_lh_new(MEM,mem)
+#define lh_MEM_insert(lh,inst) LHM_lh_insert(MEM,lh,inst)
+#define lh_MEM_retrieve(lh,inst) LHM_lh_retrieve(MEM,lh,inst)
+#define lh_MEM_delete(lh,inst) LHM_lh_delete(MEM,lh,inst)
+#define lh_MEM_doall(lh,fn) LHM_lh_doall(MEM,lh,fn)
+#define lh_MEM_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(MEM,lh,fn,arg_type,arg)
+#define lh_MEM_error(lh) LHM_lh_error(MEM,lh)
+#define lh_MEM_num_items(lh) LHM_lh_num_items(MEM,lh)
+#define lh_MEM_down_load(lh) LHM_lh_down_load(MEM,lh)
+#define lh_MEM_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(MEM,lh,out)
+#define lh_MEM_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(MEM,lh,out)
+#define lh_MEM_stats_bio(lh,out) \
+  LHM_lh_stats_bio(MEM,lh,out)
+#define lh_MEM_free(lh) LHM_lh_free(MEM,lh)
+
+#define lh_OBJ_NAME_new() LHM_lh_new(OBJ_NAME,obj_name)
+#define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst)
+#define lh_OBJ_NAME_retrieve(lh,inst) LHM_lh_retrieve(OBJ_NAME,lh,inst)
+#define lh_OBJ_NAME_delete(lh,inst) LHM_lh_delete(OBJ_NAME,lh,inst)
+#define lh_OBJ_NAME_doall(lh,fn) LHM_lh_doall(OBJ_NAME,lh,fn)
+#define lh_OBJ_NAME_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(OBJ_NAME,lh,fn,arg_type,arg)
+#define lh_OBJ_NAME_error(lh) LHM_lh_error(OBJ_NAME,lh)
+#define lh_OBJ_NAME_num_items(lh) LHM_lh_num_items(OBJ_NAME,lh)
+#define lh_OBJ_NAME_down_load(lh) LHM_lh_down_load(OBJ_NAME,lh)
+#define lh_OBJ_NAME_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(OBJ_NAME,lh,out)
+#define lh_OBJ_NAME_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(OBJ_NAME,lh,out)
+#define lh_OBJ_NAME_stats_bio(lh,out) \
+  LHM_lh_stats_bio(OBJ_NAME,lh,out)
+#define lh_OBJ_NAME_free(lh) LHM_lh_free(OBJ_NAME,lh)
+
+#define lh_OPENSSL_CSTRING_new() LHM_lh_new(OPENSSL_CSTRING,openssl_cstring)
+#define lh_OPENSSL_CSTRING_insert(lh,inst) LHM_lh_insert(OPENSSL_CSTRING,lh,inst)
+#define lh_OPENSSL_CSTRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_CSTRING,lh,inst)
+#define lh_OPENSSL_CSTRING_delete(lh,inst) LHM_lh_delete(OPENSSL_CSTRING,lh,inst)
+#define lh_OPENSSL_CSTRING_doall(lh,fn) LHM_lh_doall(OPENSSL_CSTRING,lh,fn)
+#define lh_OPENSSL_CSTRING_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(OPENSSL_CSTRING,lh,fn,arg_type,arg)
+#define lh_OPENSSL_CSTRING_error(lh) LHM_lh_error(OPENSSL_CSTRING,lh)
+#define lh_OPENSSL_CSTRING_num_items(lh) LHM_lh_num_items(OPENSSL_CSTRING,lh)
+#define lh_OPENSSL_CSTRING_down_load(lh) LHM_lh_down_load(OPENSSL_CSTRING,lh)
+#define lh_OPENSSL_CSTRING_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(OPENSSL_CSTRING,lh,out)
+#define lh_OPENSSL_CSTRING_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(OPENSSL_CSTRING,lh,out)
+#define lh_OPENSSL_CSTRING_stats_bio(lh,out) \
+  LHM_lh_stats_bio(OPENSSL_CSTRING,lh,out)
+#define lh_OPENSSL_CSTRING_free(lh) LHM_lh_free(OPENSSL_CSTRING,lh)
+
+#define lh_OPENSSL_STRING_new() LHM_lh_new(OPENSSL_STRING,openssl_string)
+#define lh_OPENSSL_STRING_insert(lh,inst) LHM_lh_insert(OPENSSL_STRING,lh,inst)
+#define lh_OPENSSL_STRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_STRING,lh,inst)
+#define lh_OPENSSL_STRING_delete(lh,inst) LHM_lh_delete(OPENSSL_STRING,lh,inst)
+#define lh_OPENSSL_STRING_doall(lh,fn) LHM_lh_doall(OPENSSL_STRING,lh,fn)
+#define lh_OPENSSL_STRING_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(OPENSSL_STRING,lh,fn,arg_type,arg)
+#define lh_OPENSSL_STRING_error(lh) LHM_lh_error(OPENSSL_STRING,lh)
+#define lh_OPENSSL_STRING_num_items(lh) LHM_lh_num_items(OPENSSL_STRING,lh)
+#define lh_OPENSSL_STRING_down_load(lh) LHM_lh_down_load(OPENSSL_STRING,lh)
+#define lh_OPENSSL_STRING_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(OPENSSL_STRING,lh,out)
+#define lh_OPENSSL_STRING_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(OPENSSL_STRING,lh,out)
+#define lh_OPENSSL_STRING_stats_bio(lh,out) \
+  LHM_lh_stats_bio(OPENSSL_STRING,lh,out)
+#define lh_OPENSSL_STRING_free(lh) LHM_lh_free(OPENSSL_STRING,lh)
+
+#define lh_SSL_SESSION_new() LHM_lh_new(SSL_SESSION,ssl_session)
+#define lh_SSL_SESSION_insert(lh,inst) LHM_lh_insert(SSL_SESSION,lh,inst)
+#define lh_SSL_SESSION_retrieve(lh,inst) LHM_lh_retrieve(SSL_SESSION,lh,inst)
+#define lh_SSL_SESSION_delete(lh,inst) LHM_lh_delete(SSL_SESSION,lh,inst)
+#define lh_SSL_SESSION_doall(lh,fn) LHM_lh_doall(SSL_SESSION,lh,fn)
+#define lh_SSL_SESSION_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(SSL_SESSION,lh,fn,arg_type,arg)
+#define lh_SSL_SESSION_error(lh) LHM_lh_error(SSL_SESSION,lh)
+#define lh_SSL_SESSION_num_items(lh) LHM_lh_num_items(SSL_SESSION,lh)
+#define lh_SSL_SESSION_down_load(lh) LHM_lh_down_load(SSL_SESSION,lh)
+#define lh_SSL_SESSION_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(SSL_SESSION,lh,out)
+#define lh_SSL_SESSION_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(SSL_SESSION,lh,out)
+#define lh_SSL_SESSION_stats_bio(lh,out) \
+  LHM_lh_stats_bio(SSL_SESSION,lh,out)
+#define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh)
 /* End of util/mkstack.pl block, you may now edit :-) */
 
 #endif /* !defined HEADER_SAFESTACK_H */
diff --git a/include/openssl/sha.h b/include/openssl/sha.h
index 47a2c29..16cacf9 100644
--- a/include/openssl/sha.h
+++ b/include/openssl/sha.h
@@ -81,7 +81,7 @@
  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  */
 
-#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#if defined(__LP32__)
 #define SHA_LONG unsigned long
 #elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
 #define SHA_LONG unsigned long
@@ -106,9 +106,6 @@
 	} 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 4e4964e..7858169 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -56,60 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-/* ====================================================================
- * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -166,6 +113,32 @@
  * ECC cipher suite support in OpenSSL originally developed by 
  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 #ifndef HEADER_SSL_H 
 #define HEADER_SSL_H 
@@ -248,56 +221,88 @@
 #define SSL_MAX_KEY_ARG_LENGTH			8
 #define SSL_MAX_MASTER_KEY_LENGTH		48
 
+
 /* These are used to specify which ciphers to use and not to use */
+
+#define SSL_TXT_EXP40		"EXPORT40"
+#define SSL_TXT_EXP56		"EXPORT56"
 #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"
-#define SSL_TXT_FZA		"FZA"
+
+#define SSL_TXT_kFZA		"kFZA" /* unused! */
+#define	SSL_TXT_aFZA		"aFZA" /* unused! */
+#define SSL_TXT_eFZA		"eFZA" /* unused! */
+#define SSL_TXT_FZA		"FZA"  /* unused! */
 
 #define	SSL_TXT_aNULL		"aNULL"
 #define	SSL_TXT_eNULL		"eNULL"
 #define	SSL_TXT_NULL		"NULL"
 
-#define SSL_TXT_kKRB5     	"kKRB5"
-#define SSL_TXT_aKRB5     	"aKRB5"
-#define SSL_TXT_KRB5      	"KRB5"
-
 #define SSL_TXT_kRSA		"kRSA"
-#define SSL_TXT_kDHr		"kDHr"
-#define SSL_TXT_kDHd		"kDHd"
+#define SSL_TXT_kDHr		"kDHr" /* no such ciphersuites supported! */
+#define SSL_TXT_kDHd		"kDHd" /* no such ciphersuites supported! */
+#define SSL_TXT_kDH 		"kDH"  /* no such ciphersuites supported! */
 #define SSL_TXT_kEDH		"kEDH"
+#define SSL_TXT_kKRB5     	"kKRB5"
+#define SSL_TXT_kECDHr		"kECDHr"
+#define SSL_TXT_kECDHe		"kECDHe"
+#define SSL_TXT_kECDH		"kECDH"
+#define SSL_TXT_kEECDH		"kEECDH"
+#define SSL_TXT_kPSK            "kPSK"
+#define SSL_TXT_kGOST		"kGOST"
+
 #define	SSL_TXT_aRSA		"aRSA"
 #define	SSL_TXT_aDSS		"aDSS"
-#define	SSL_TXT_aDH		"aDH"
+#define	SSL_TXT_aDH		"aDH" /* no such ciphersuites supported! */
+#define	SSL_TXT_aECDH		"aECDH"
+#define SSL_TXT_aKRB5     	"aKRB5"
+#define SSL_TXT_aECDSA		"aECDSA"
+#define SSL_TXT_aPSK            "aPSK"
+#define SSL_TXT_aGOST94	"aGOST94"
+#define SSL_TXT_aGOST01 "aGOST01"
+#define SSL_TXT_aGOST  "aGOST"
+
 #define	SSL_TXT_DSS		"DSS"
 #define SSL_TXT_DH		"DH"
-#define SSL_TXT_EDH		"EDH"
+#define SSL_TXT_EDH		"EDH" /* same as "kEDH:-ADH" */
 #define SSL_TXT_ADH		"ADH"
 #define SSL_TXT_RSA		"RSA"
+#define SSL_TXT_ECDH		"ECDH"
+#define SSL_TXT_EECDH		"EECDH" /* same as "kEECDH:-AECDH" */
+#define SSL_TXT_AECDH		"AECDH"
+#define SSL_TXT_ECDSA		"ECDSA"
+#define SSL_TXT_KRB5      	"KRB5"
+#define SSL_TXT_PSK             "PSK"
+
 #define SSL_TXT_DES		"DES"
 #define SSL_TXT_3DES		"3DES"
 #define SSL_TXT_RC4		"RC4"
 #define SSL_TXT_RC2		"RC2"
 #define SSL_TXT_IDEA		"IDEA"
 #define SSL_TXT_SEED		"SEED"
+#define SSL_TXT_AES128		"AES128"
+#define SSL_TXT_AES256		"AES256"
 #define SSL_TXT_AES		"AES"
+#define SSL_TXT_CAMELLIA128	"CAMELLIA128"
+#define SSL_TXT_CAMELLIA256	"CAMELLIA256"
 #define SSL_TXT_CAMELLIA	"CAMELLIA"
+
 #define SSL_TXT_MD5		"MD5"
 #define SSL_TXT_SHA1		"SHA1"
-#define SSL_TXT_SHA		"SHA"
-#define SSL_TXT_EXP		"EXP"
-#define SSL_TXT_EXPORT		"EXPORT"
-#define SSL_TXT_EXP40		"EXPORT40"
-#define SSL_TXT_EXP56		"EXPORT56"
+#define SSL_TXT_SHA		"SHA" /* same as "SHA1" */
+#define SSL_TXT_GOST94		"GOST94" 
+#define SSL_TXT_GOST89MAC		"GOST89MAC" 
+
 #define SSL_TXT_SSLV2		"SSLv2"
 #define SSL_TXT_SSLV3		"SSLv3"
 #define SSL_TXT_TLSV1		"TLSv1"
+
+#define SSL_TXT_EXP		"EXP"
+#define SSL_TXT_EXPORT		"EXPORT"
+
 #define SSL_TXT_ALL		"ALL"
-#define SSL_TXT_ECC		"ECCdraft" /* ECC ciphersuites are not yet official */
 
 /*
  * COMPLEMENTOF* definitions. These identifiers are used to (de-select)
@@ -319,7 +324,13 @@
 /* The following cipher list is used by default.
  * It also is substituted when an application-defined cipher list string
  * starts with 'DEFAULT'. */
-#define SSL_DEFAULT_CIPHER_LIST	"AES:ALL:!aNULL:!eNULL:+RC4:@STRENGTH" /* low priority for RC4 */
+#define SSL_DEFAULT_CIPHER_LIST	"ALL:!aNULL:!eNULL:!SSLv2"
+/* As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always
+ * starts with a reasonable order, and all we have to do for DEFAULT is
+ * throwing out anonymous and unencrypted ciphersuites!
+ * (The latter are not actually enabled by ALL, but "ALL:RSA" would enable
+ * some of them.)
+ */
 
 /* Used in SSL_set_shutdown()/SSL_get_shutdown(); */
 #define SSL_SENT_SHUTDOWN	1
@@ -344,6 +355,7 @@
  * 'struct ssl_st *' function parameters used to prototype callbacks
  * in SSL_CTX. */
 typedef struct ssl_st *ssl_crock_st;
+typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT;
 
 /* used to hold info on the particular ciphers used */
 typedef struct ssl_cipher_st
@@ -351,17 +363,25 @@
 	int valid;
 	const char *name;		/* text name */
 	unsigned long id;		/* id, 4 bytes, first is version */
-	unsigned long algorithms;	/* what ciphers are used */
+
+	/* changed in 0.9.9: these four used to be portions of a single value 'algorithms' */
+	unsigned long algorithm_mkey;	/* key exchange algorithm */
+	unsigned long algorithm_auth;	/* server authentication */
+	unsigned long algorithm_enc;	/* symmetric encryption */
+	unsigned long algorithm_mac;	/* symmetric authentication */
+	unsigned long algorithm_ssl;	/* (major) protocol version */
+
 	unsigned long algo_strength;	/* strength and export flags */
 	unsigned long algorithm2;	/* Extra flags */
 	int strength_bits;		/* Number of bits really used */
 	int alg_bits;			/* Number of bits for algorithm */
-	unsigned long mask;		/* used for matching */
-	unsigned long mask_strength;	/* also used for matching */
 	} SSL_CIPHER;
 
 DECLARE_STACK_OF(SSL_CIPHER)
 
+typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, int len, void *arg);
+typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg);
+
 /* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
 typedef struct ssl_method_st
 	{
@@ -385,12 +405,12 @@
 	int (*ssl_dispatch_alert)(SSL *s);
 	long (*ssl_ctrl)(SSL *s,int cmd,long larg,void *parg);
 	long (*ssl_ctx_ctrl)(SSL_CTX *ctx,int cmd,long larg,void *parg);
-	SSL_CIPHER *(*get_cipher_by_char)(const unsigned char *ptr);
+	const SSL_CIPHER *(*get_cipher_by_char)(const unsigned char *ptr);
 	int (*put_cipher_by_char)(const SSL_CIPHER *cipher,unsigned char *ptr);
 	int (*ssl_pending)(const SSL *s);
 	int (*num_ciphers)(void);
-	SSL_CIPHER *(*get_cipher)(unsigned ncipher);
-	struct ssl_method_st *(*get_ssl_method)(int version);
+	const SSL_CIPHER *(*get_cipher)(unsigned ncipher);
+	const struct ssl_method_st *(*get_ssl_method)(int version);
 	long (*get_timeout)(void);
 	struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */
 	int (*ssl_version)(void);
@@ -402,17 +422,20 @@
  * SSL_SESSION_ID ::= SEQUENCE {
  *	version 		INTEGER,	-- structure version number
  *	SSLversion 		INTEGER,	-- SSL version number
- *	Cipher 			OCTET_STRING,	-- the 3 byte cipher ID
- *	Session_ID 		OCTET_STRING,	-- the Session ID
- *	Master_key 		OCTET_STRING,	-- the master key
- *	KRB5_principal		OCTET_STRING	-- optional Kerberos principal
- *	Key_Arg [ 0 ] IMPLICIT	OCTET_STRING,	-- the optional Key argument
+ *	Cipher 			OCTET STRING,	-- the 3 byte cipher ID
+ *	Session_ID 		OCTET STRING,	-- the Session ID
+ *	Master_key 		OCTET STRING,	-- the master key
+ *	KRB5_principal		OCTET STRING	-- optional Kerberos principal
+ *	Key_Arg [ 0 ] IMPLICIT	OCTET STRING,	-- the optional Key argument
  *	Time [ 1 ] EXPLICIT	INTEGER,	-- optional Start Time
  *	Timeout [ 2 ] EXPLICIT	INTEGER,	-- optional Timeout ins seconds
  *	Peer [ 3 ] EXPLICIT	X509,		-- optional Peer Certificate
- *	Session_ID_context [ 4 ] EXPLICIT OCTET_STRING,   -- the Session ID context
- *	Verify_result [ 5 ] EXPLICIT INTEGER    -- X509_V_... code for `Peer'
- *	Compression [6] IMPLICIT ASN1_OBJECT	-- compression OID XXXXX
+ *	Session_ID_context [ 4 ] EXPLICIT OCTET STRING,   -- the Session ID context
+ *	Verify_result [ 5 ] EXPLICIT INTEGER,   -- X509_V_... code for `Peer'
+ *	HostName [ 6 ] EXPLICIT OCTET STRING,   -- optional HostName from servername TLS extension 
+ *	ECPointFormatList [ 7 ] OCTET STRING,     -- optional EC point format list from TLS extension
+ *	PSK_identity_hint [ 8 ] EXPLICIT OCTET STRING, -- optional PSK identity hint
+ *	PSK_identity [ 9 ] EXPLICIT OCTET STRING -- optional PSK identity
  *	}
  * Look in ssl/ssl_asn1.c for more details
  * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-).
@@ -440,7 +463,10 @@
         unsigned int krb5_client_princ_len;
         unsigned char krb5_client_princ[SSL_MAX_KRB5_PRINCIPAL_LENGTH];
 #endif /* OPENSSL_NO_KRB5 */
-
+#ifndef OPENSSL_NO_PSK
+	char *psk_identity_hint;
+	char *psk_identity;
+#endif
 	int not_resumable;
 
 	/* The cert is the certificate used to establish this connection */
@@ -459,9 +485,9 @@
 	long timeout;
 	long time;
 
-	int compress_meth;		/* Need to lookup the method */
+	unsigned int compress_meth;	/* Need to lookup the method */
 
-	SSL_CIPHER *cipher;
+	const SSL_CIPHER *cipher;
 	unsigned long cipher_id;	/* when ASN.1 loaded, this
 					 * needs to be used to load
 					 * the 'cipher' structure */
@@ -475,6 +501,12 @@
 	struct ssl_session_st *prev,*next;
 #ifndef OPENSSL_NO_TLSEXT
 	char *tlsext_hostname;
+#ifndef OPENSSL_NO_EC
+	size_t tlsext_ecpointformatlist_length;
+	unsigned char *tlsext_ecpointformatlist; /* peer's list */
+	size_t tlsext_ellipticcurvelist_length;
+	unsigned char *tlsext_ellipticcurvelist; /* peer's list */
+#endif /* OPENSSL_NO_EC */
 	/* RFC4507 info */
 	unsigned char *tlsext_tick;	/* Session ticket */
 	size_t	tlsext_ticklen;		/* Session ticket length */	
@@ -504,7 +536,7 @@
 
 /* SSL_OP_ALL: various bug workarounds that should be rather harmless.
  *             This used to be 0x000FFFFFL before 0.9.7. */
-#define SSL_OP_ALL					0x00000FFFL
+#define SSL_OP_ALL					0x80000FFFL
 
 /* DTLS options */
 #define SSL_OP_NO_QUERY_MTU                 0x00001000L
@@ -517,6 +549,8 @@
 
 /* As server, disallow session resumption on renegotiation */
 #define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION	0x00010000L
+/* Don't use compression even if supported */
+#define SSL_OP_NO_COMPRESSION				0x00020000L
 /* Permit unsafe legacy renegotiation */
 #define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION	0x00040000L
 /* If set, always create a new key when using tmp_ecdh parameters */
@@ -545,7 +579,11 @@
 #define SSL_OP_PKCS1_CHECK_2				0x10000000L
 #define SSL_OP_NETSCAPE_CA_DN_BUG			0x20000000L
 #define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG		0x40000000L
-
+/* Make server add server-hello extension from early version of
+ * cryptopro draft, when GOST ciphersuite is negotiated. 
+ * Required for interoperability with CryptoPro CSP 3.x 
+ */
+#define SSL_OP_CRYPTOPRO_TLSEXT_BUG			0x80000000L
 
 /* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success
  * when just a single record has been written): */
@@ -560,9 +598,13 @@
 #define SSL_MODE_AUTO_RETRY 0x00000004L
 /* Don't attempt to automatically build certificate chain */
 #define SSL_MODE_NO_AUTO_CHAIN 0x00000008L
+/* Save RAM by releasing read and write buffers when they're empty. (SSL3 and
+ * TLS only.)  "Released" buffers are put onto a free-list in the context
+ * or just freed (depending on the context's setting for freelist_max_len). */
+#define SSL_MODE_RELEASE_BUFFERS 0x00000010L
 /* Use small read and write buffers: (a) lazy allocate read buffers for
  * large incoming records, and (b) limit the size of outgoing records. */
-#define SSL_MODE_SMALL_BUFFERS 0x00000010L
+#define SSL_MODE_SMALL_BUFFERS 0x00000020L
 
 /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
  * they cannot be used to clear bits. */
@@ -641,17 +683,18 @@
 	} SSL_COMP;
 
 DECLARE_STACK_OF(SSL_COMP)
+DECLARE_LHASH_OF(SSL_SESSION);
 
 struct ssl_ctx_st
 	{
-	SSL_METHOD *method;
+	const SSL_METHOD *method;
 
 	STACK_OF(SSL_CIPHER) *cipher_list;
 	/* same as above but sorted for lookup */
 	STACK_OF(SSL_CIPHER) *cipher_list_by_id;
 
 	struct x509_store_st /* X509_STORE */ *cert_store;
-	struct lhash_st /* LHASH */ *sessions;	/* a set of SSL_SESSIONs */
+	LHASH_OF(SSL_SESSION) *sessions;
 	/* Most session-ids that will be cached, default is
 	 * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. */
 	unsigned long session_cache_size;
@@ -776,6 +819,12 @@
 
 	int quiet_shutdown;
 
+	/* Maximum amount of data to send in one fragment.
+	 * actual record size can be more than this due to
+	 * padding and MAC overheads.
+	 */
+	unsigned int max_send_fragment;
+
 #ifndef OPENSSL_ENGINE
 	/* Engine to pass requests for client certs to
 	 */
@@ -794,14 +843,33 @@
 	int (*tlsext_ticket_key_cb)(SSL *ssl,
 					unsigned char *name, unsigned char *iv,
 					EVP_CIPHER_CTX *ectx,
-					HMAC_CTX *hctx, int enc);
+ 					HMAC_CTX *hctx, int enc);
 
 	/* certificate status request info */
 	/* Callback for status request */
 	int (*tlsext_status_cb)(SSL *ssl, void *arg);
 	void *tlsext_status_arg;
+
+	/* draft-rescorla-tls-opaque-prf-input-00.txt information */
+	int (*tlsext_opaque_prf_input_callback)(SSL *, void *peerinput, size_t len, void *arg);
+	void *tlsext_opaque_prf_input_callback_arg;
 #endif
 
+#ifndef OPENSSL_NO_PSK
+	char *psk_identity_hint;
+	unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, char *identity,
+		unsigned int max_identity_len, unsigned char *psk,
+		unsigned int max_psk_len);
+	unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
+		unsigned char *psk, unsigned int max_psk_len);
+#endif
+
+#ifndef OPENSSL_NO_BUF_FREELISTS
+#define SSL_MAX_BUF_FREELIST_LEN_DEFAULT 32
+	unsigned int freelist_max_len;
+	struct ssl3_buf_freelist_st *wbuf_freelist;
+	struct ssl3_buf_freelist_st *rbuf_freelist;
+#endif
 	};
 
 #define SSL_SESS_CACHE_OFF			0x0000
@@ -815,7 +883,7 @@
 #define SSL_SESS_CACHE_NO_INTERNAL \
 	(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE)
 
-  struct lhash_st *SSL_CTX_sessions(SSL_CTX *ctx);
+LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
 #define SSL_CTX_sess_number(ctx) \
 	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL)
 #define SSL_CTX_sess_connect(ctx) \
@@ -857,6 +925,31 @@
 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));
 
+#ifndef OPENSSL_NO_PSK
+/* the maximum length of the buffer given to callbacks containing the
+ * resulting identity/psk */
+#define PSK_MAX_IDENTITY_LEN 128
+#define PSK_MAX_PSK_LEN 256
+void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, 
+	unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, 
+		char *identity, unsigned int max_identity_len, unsigned char *psk,
+		unsigned int max_psk_len));
+void SSL_set_psk_client_callback(SSL *ssl, 
+	unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, 
+		char *identity, unsigned int max_identity_len, unsigned char *psk,
+		unsigned int max_psk_len));
+void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, 
+	unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
+		unsigned char *psk, unsigned int max_psk_len));
+void SSL_set_psk_server_callback(SSL *ssl,
+	unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
+		unsigned char *psk, unsigned int max_psk_len));
+int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint);
+int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint);
+const char *SSL_get_psk_identity_hint(const SSL *s);
+const char *SSL_get_psk_identity(const SSL *s);
+#endif
+
 #define SSL_NOTHING	1
 #define SSL_WRITING	2
 #define SSL_READING	3
@@ -868,6 +961,9 @@
 #define SSL_want_write(s)	(SSL_want(s) == SSL_WRITING)
 #define SSL_want_x509_lookup(s)	(SSL_want(s) == SSL_X509_LOOKUP)
 
+#define SSL_MAC_FLAG_READ_MAC_STREAM 1
+#define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
+
 struct ssl_st
 	{
 	/* protocol version
@@ -876,7 +972,7 @@
 	int version;
 	int type; /* SSL_ST_CONNECT or SSL_ST_ACCEPT */
 
-	SSL_METHOD *method; /* SSLv3 */
+	const SSL_METHOD *method; /* SSLv3 */
 
 	/* There are 2 BIO's even though they are normally both the
 	 * same.  This is so data can be read and written to different
@@ -959,9 +1055,9 @@
 
 	/* These are the ones being used, the ones in SSL_SESSION are
 	 * the ones to be 'copied' into these ones */
-
+	int mac_flags; 
 	EVP_CIPHER_CTX *enc_read_ctx;		/* cryptographic state */
-	const EVP_MD *read_hash;		/* used for mac generation */
+	EVP_MD_CTX *read_hash;		/* used for mac generation */
 #ifndef OPENSSL_NO_COMP
 	COMP_CTX *expand;			/* uncompress */
 #else
@@ -969,7 +1065,7 @@
 #endif
 
 	EVP_CIPHER_CTX *enc_write_ctx;		/* cryptographic state */
-	const EVP_MD *write_hash;		/* used for mac generation */
+	EVP_MD_CTX *write_hash;		/* used for mac generation */
 #ifndef OPENSSL_NO_COMP
 	COMP_CTX *compress;			/* compression */
 #else
@@ -1007,6 +1103,14 @@
 	KSSL_CTX *kssl_ctx;     /* Kerberos 5 context */
 #endif	/* OPENSSL_NO_KRB5 */
 
+#ifndef OPENSSL_NO_PSK
+	unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, char *identity,
+		unsigned int max_identity_len, unsigned char *psk,
+		unsigned int max_psk_len);
+	unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
+		unsigned char *psk, unsigned int max_psk_len);
+#endif
+
 	SSL_CTX *ctx;
 	/* set this flag to 1 and a sleep(1) is put into all SSL_read()
 	 * and SSL_write() calls, good for nbio debuging :-) */
@@ -1026,6 +1130,7 @@
 	int first_packet;
 	int client_version;	/* what was passed, used for
 				 * SSLv3/TLS rollback check */
+	unsigned int max_send_fragment;
 #ifndef OPENSSL_NO_TLSEXT
 	/* TLS extension debug callback */
 	void (*tlsext_debug_cb)(SSL *s, int client_server, int type,
@@ -1052,11 +1157,33 @@
 
 	/* RFC4507 session ticket expected to be received or sent */
 	int tlsext_ticket_expected;
+#ifndef OPENSSL_NO_EC
+	size_t tlsext_ecpointformatlist_length;
+	unsigned char *tlsext_ecpointformatlist; /* our list */
+	size_t tlsext_ellipticcurvelist_length;
+	unsigned char *tlsext_ellipticcurvelist; /* our list */
+#endif /* OPENSSL_NO_EC */
+
+	/* draft-rescorla-tls-opaque-prf-input-00.txt information to be used for handshakes */
+	void *tlsext_opaque_prf_input;
+	size_t tlsext_opaque_prf_input_len;
+
+	/* TLS Session Ticket extension override */
+	TLS_SESSION_TICKET_EXT *tlsext_session_ticket;
+
+	/* TLS Session Ticket extension callback */
+	tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb;
+	void *tls_session_ticket_ext_cb_arg;
+
+	/* TLS pre-shared secret session resumption */
+	tls_session_secret_cb_fn tls_session_secret_cb;
+	void *tls_session_secret_cb_arg;
+
 	SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */
 #define session_ctx initial_ctx
 #else
 #define session_ctx ctx
-#endif
+#endif /* OPENSSL_NO_TLSEXT */
 	};
 
 #ifdef __cplusplus
@@ -1163,20 +1290,13 @@
 #define SSL_get_timeout(a)	SSL_SESSION_get_timeout(a)
 #define SSL_set_timeout(a,b)	SSL_SESSION_set_timeout((a),(b))
 
-#if 1 /*SSLEAY_MACROS*/
 #define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id)
 #define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id)
-#define PEM_read_SSL_SESSION(fp,x,cb,u) (SSL_SESSION *)PEM_ASN1_read( \
-	(char *(*)())d2i_SSL_SESSION,PEM_STRING_SSL_SESSION,fp,(char **)x,cb,u)
-#define PEM_read_bio_SSL_SESSION(bp,x,cb,u) PEM_ASN1_read_bio_of(SSL_SESSION,d2i_SSL_SESSION,PEM_STRING_SSL_SESSION,bp,x,cb,u)
-#define PEM_write_SSL_SESSION(fp,x) \
-	PEM_ASN1_write((int (*)())i2d_SSL_SESSION, \
-		PEM_STRING_SSL_SESSION,fp, (char *)x, NULL,NULL,0,NULL,NULL)
-#define PEM_write_bio_SSL_SESSION(bp,x) \
-	PEM_ASN1_write_bio_of(SSL_SESSION,i2d_SSL_SESSION,PEM_STRING_SSL_SESSION,bp,x,NULL,NULL,0,NULL,NULL)
-#endif
 
-#define SSL_AD_REASON_OFFSET		1000
+DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
+
+#define SSL_AD_REASON_OFFSET		1000 /* offset to get SSL_R_... value from SSL_AD_... */
+
 /* These alert types are for SSLv3 and TLSv1 */
 #define SSL_AD_CLOSE_NOTIFY		SSL3_AD_CLOSE_NOTIFY
 #define SSL_AD_UNEXPECTED_MESSAGE	SSL3_AD_UNEXPECTED_MESSAGE /* fatal */
@@ -1206,6 +1326,8 @@
 #define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE
 #define SSL_AD_UNRECOGNIZED_NAME	TLS1_AD_UNRECOGNIZED_NAME
 #define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
+#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
+#define SSL_AD_UNKNOWN_PSK_IDENTITY     TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */
 
 #define SSL_ERROR_NONE			0
 #define SSL_ERROR_SSL			1
@@ -1264,6 +1386,8 @@
 #define SSL_CTRL_GET_MAX_CERT_LIST		50
 #define SSL_CTRL_SET_MAX_CERT_LIST		51
 
+#define SSL_CTRL_SET_MAX_SEND_FRAGMENT		52
+
 /* see tls1.h for macros based on these */
 #ifndef OPENSSL_NO_TLSEXT
 #define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB	53
@@ -1273,7 +1397,9 @@
 #define SSL_CTRL_SET_TLSEXT_DEBUG_ARG		57
 #define SSL_CTRL_GET_TLSEXT_TICKET_KEYS		58
 #define SSL_CTRL_SET_TLSEXT_TICKET_KEYS		59
-
+#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT	60
+#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB	61
+#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62
 #define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB	63
 #define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG	64
 #define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE	65
@@ -1343,7 +1469,7 @@
 #endif
 
 int	SSL_CTX_set_cipher_list(SSL_CTX *,const char *str);
-SSL_CTX *SSL_CTX_new(SSL_METHOD *meth);
+SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth);
 void	SSL_CTX_free(SSL_CTX *);
 long SSL_CTX_set_timeout(SSL_CTX *ctx,long t);
 long SSL_CTX_get_timeout(const SSL_CTX *ctx);
@@ -1354,7 +1480,7 @@
 
 void	SSL_CTX_flush_sessions(SSL_CTX *ctx,long tm);
 
-SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
+const SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
 int	SSL_CIPHER_get_bits(const SSL_CIPHER *c,int *alg_bits);
 char *	SSL_CIPHER_get_version(const SSL_CIPHER *c);
 const char *	SSL_CIPHER_get_name(const SSL_CIPHER *c);
@@ -1425,9 +1551,8 @@
 void	SSL_copy_session_id(SSL *to,const SSL *from);
 
 SSL_SESSION *SSL_SESSION_new(void);
-unsigned long SSL_SESSION_hash(const SSL_SESSION *a);
-int	SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b);
-const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len);
+const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
+					unsigned int *len);
 #ifndef OPENSSL_NO_FP_API
 int	SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses);
 #endif
@@ -1487,6 +1612,9 @@
 int SSL_CTX_set_trust(SSL_CTX *s, int trust);
 int SSL_set_trust(SSL *s, int trust);
 
+int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm);
+int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm);
+
 void	SSL_free(SSL *ssl);
 int 	SSL_accept(SSL *ssl);
 int 	SSL_connect(SSL *ssl);
@@ -1502,27 +1630,29 @@
 const char *SSL_get_version(const SSL *s);
 
 /* This sets the 'default' SSL version that SSL_new() will create */
-int SSL_CTX_set_ssl_version(SSL_CTX *ctx,SSL_METHOD *meth);
+int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth);
 
-SSL_METHOD *SSLv2_method(void);		/* SSLv2 */
-SSL_METHOD *SSLv2_server_method(void);	/* SSLv2 */
-SSL_METHOD *SSLv2_client_method(void);	/* SSLv2 */
+#ifndef OPENSSL_NO_SSL2
+const SSL_METHOD *SSLv2_method(void);		/* SSLv2 */
+const SSL_METHOD *SSLv2_server_method(void);	/* SSLv2 */
+const SSL_METHOD *SSLv2_client_method(void);	/* SSLv2 */
+#endif
 
-SSL_METHOD *SSLv3_method(void);		/* SSLv3 */
-SSL_METHOD *SSLv3_server_method(void);	/* SSLv3 */
-SSL_METHOD *SSLv3_client_method(void);	/* SSLv3 */
+const SSL_METHOD *SSLv3_method(void);		/* SSLv3 */
+const SSL_METHOD *SSLv3_server_method(void);	/* SSLv3 */
+const SSL_METHOD *SSLv3_client_method(void);	/* SSLv3 */
 
-SSL_METHOD *SSLv23_method(void);	/* SSLv3 but can rollback to v2 */
-SSL_METHOD *SSLv23_server_method(void);	/* SSLv3 but can rollback to v2 */
-SSL_METHOD *SSLv23_client_method(void);	/* SSLv3 but can rollback to v2 */
+const SSL_METHOD *SSLv23_method(void);	/* SSLv3 but can rollback to v2 */
+const SSL_METHOD *SSLv23_server_method(void);	/* SSLv3 but can rollback to v2 */
+const SSL_METHOD *SSLv23_client_method(void);	/* SSLv3 but can rollback to v2 */
 
-SSL_METHOD *TLSv1_method(void);		/* TLSv1.0 */
-SSL_METHOD *TLSv1_server_method(void);	/* TLSv1.0 */
-SSL_METHOD *TLSv1_client_method(void);	/* TLSv1.0 */
+const SSL_METHOD *TLSv1_method(void);		/* TLSv1.0 */
+const SSL_METHOD *TLSv1_server_method(void);	/* TLSv1.0 */
+const SSL_METHOD *TLSv1_client_method(void);	/* TLSv1.0 */
 
-SSL_METHOD *DTLSv1_method(void);		/* DTLSv1.0 */
-SSL_METHOD *DTLSv1_server_method(void);	/* DTLSv1.0 */
-SSL_METHOD *DTLSv1_client_method(void);	/* DTLSv1.0 */
+const SSL_METHOD *DTLSv1_method(void);		/* DTLSv1.0 */
+const SSL_METHOD *DTLSv1_server_method(void);	/* DTLSv1.0 */
+const SSL_METHOD *DTLSv1_client_method(void);	/* DTLSv1.0 */
 
 STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
 
@@ -1531,8 +1661,8 @@
 int SSL_renegotiate_pending(SSL *s);
 int SSL_shutdown(SSL *s);
 
-SSL_METHOD *SSL_get_ssl_method(SSL *s);
-int SSL_set_ssl_method(SSL *s,SSL_METHOD *method);
+const SSL_METHOD *SSL_get_ssl_method(SSL *s);
+int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method);
 const char *SSL_alert_type_string_long(int value);
 const char *SSL_alert_type_string(int value);
 const char *SSL_alert_desc_string_long(int value);
@@ -1624,6 +1754,11 @@
 #define SSL_set_max_cert_list(ssl,m) \
 	SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
 
+#define SSL_CTX_set_max_send_fragment(ctx,m) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL)
+#define SSL_set_max_send_fragment(ssl,m) \
+	SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL)
+
      /* NB: the keylength is only applicable when is_export is true */
 #ifndef OPENSSL_NO_RSA
 void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
@@ -1665,6 +1800,15 @@
 int SSL_COMP_add_compression_method(int id,void *cm);
 #endif
 
+/* TLS extensions functions */
+int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len);
+
+int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
+				  void *arg);
+
+/* Pre-shared secret session resumption functions */
+int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg);
+
 /* 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.
@@ -1682,7 +1826,7 @@
 #define SSL_F_DO_DTLS1_WRITE				 245
 #define SSL_F_DO_SSL3_WRITE				 104
 #define SSL_F_DTLS1_ACCEPT				 246
-#define SSL_F_DTLS1_ADD_CERT_TO_BUF			 280
+#define SSL_F_DTLS1_ADD_CERT_TO_BUF			 295
 #define SSL_F_DTLS1_BUFFER_RECORD			 247
 #define SSL_F_DTLS1_CLIENT_HELLO			 248
 #define SSL_F_DTLS1_CONNECT				 249
@@ -1691,9 +1835,9 @@
 #define SSL_F_DTLS1_GET_MESSAGE				 252
 #define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT		 253
 #define SSL_F_DTLS1_GET_RECORD				 254
-#define SSL_F_DTLS1_HANDLE_TIMEOUT			 282
+#define SSL_F_DTLS1_HANDLE_TIMEOUT			 297
 #define SSL_F_DTLS1_OUTPUT_CERT_CHAIN			 255
-#define SSL_F_DTLS1_PREPROCESS_FRAGMENT			 277
+#define SSL_F_DTLS1_PREPROCESS_FRAGMENT			 288
 #define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE		 256
 #define SSL_F_DTLS1_PROCESS_RECORD			 257
 #define SSL_F_DTLS1_READ_BYTES				 258
@@ -1737,7 +1881,7 @@
 #define SSL_F_SSL2_SET_CERTIFICATE			 126
 #define SSL_F_SSL2_WRITE				 127
 #define SSL_F_SSL3_ACCEPT				 128
-#define SSL_F_SSL3_ADD_CERT_TO_BUF			 281
+#define SSL_F_SSL3_ADD_CERT_TO_BUF			 296
 #define SSL_F_SSL3_CALLBACK_CTRL			 233
 #define SSL_F_SSL3_CHANGE_CIPHER_STATE			 129
 #define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM		 130
@@ -1745,11 +1889,12 @@
 #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_DIGEST_CACHED_RECORDS		 293
+#define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC		 292
 #define SSL_F_SSL3_ENC					 134
 #define SSL_F_SSL3_GENERATE_KEY_BLOCK			 238
 #define SSL_F_SSL3_GET_CERTIFICATE_REQUEST		 135
-#define SSL_F_SSL3_GET_CERT_STATUS			 288
+#define SSL_F_SSL3_GET_CERT_STATUS			 289
 #define SSL_F_SSL3_GET_CERT_VERIFY			 136
 #define SSL_F_SSL3_GET_CLIENT_CERTIFICATE		 137
 #define SSL_F_SSL3_GET_CLIENT_HELLO			 138
@@ -1762,7 +1907,8 @@
 #define SSL_F_SSL3_GET_SERVER_CERTIFICATE		 144
 #define SSL_F_SSL3_GET_SERVER_DONE			 145
 #define SSL_F_SSL3_GET_SERVER_HELLO			 146
-#define SSL_F_SSL3_NEW_SESSION_TICKET			 284
+#define SSL_F_SSL3_HANDSHAKE_MAC			 285
+#define SSL_F_SSL3_NEW_SESSION_TICKET			 287
 #define SSL_F_SSL3_OUTPUT_CERT_CHAIN			 147
 #define SSL_F_SSL3_PEEK					 235
 #define SSL_F_SSL3_READ_BYTES				 148
@@ -1774,16 +1920,17 @@
 #define SSL_F_SSL3_SEND_SERVER_CERTIFICATE		 154
 #define SSL_F_SSL3_SEND_SERVER_HELLO			 242
 #define SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE		 155
-#define SSL_F_SSL3_SETUP_BUFFERS			 156
 #define SSL_F_SSL3_SETUP_KEY_BLOCK			 157
+#define SSL_F_SSL3_SETUP_READ_BUFFER			 156
+#define SSL_F_SSL3_SETUP_WRITE_BUFFER			 291
 #define SSL_F_SSL3_WRITE_BYTES				 158
 #define SSL_F_SSL3_WRITE_PENDING			 159
-#define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT	 285
-#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT		 272
+#define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT	 298
+#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT		 277
 #define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK	 215
 #define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK	 216
-#define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT	 286
-#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT		 273
+#define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT	 299
+#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT		 278
 #define SSL_F_SSL_BAD_METHOD				 160
 #define SSL_F_SSL_BYTES_TO_CIPHER_LIST			 161
 #define SSL_F_SSL_CERT_DUP				 221
@@ -1791,7 +1938,8 @@
 #define SSL_F_SSL_CERT_INSTANTIATE			 214
 #define SSL_F_SSL_CERT_NEW				 162
 #define SSL_F_SSL_CHECK_PRIVATE_KEY			 163
-#define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT		 274
+#define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT		 280
+#define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG		 279
 #define SSL_F_SSL_CIPHER_PROCESS_RULESTR		 230
 #define SSL_F_SSL_CIPHER_STRENGTH_SORT			 231
 #define SSL_F_SSL_CLEAR					 164
@@ -1801,7 +1949,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_CLIENT_CERT_ENGINE		 290
 #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
@@ -1813,6 +1961,7 @@
 #define SSL_F_SSL_CTX_USE_PRIVATEKEY			 174
 #define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1		 175
 #define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE		 176
+#define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT		 272
 #define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY			 177
 #define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1		 178
 #define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE		 179
@@ -1824,13 +1973,13 @@
 #define SSL_F_SSL_INIT_WBIO_BUFFER			 184
 #define SSL_F_SSL_LOAD_CLIENT_CA_FILE			 185
 #define SSL_F_SSL_NEW					 186
-#define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT	 287
-#define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT		 290
-#define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT	 289
-#define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT		 291
+#define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT	 300
+#define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT		 302
+#define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT	 301
+#define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT		 303
 #define SSL_F_SSL_PEEK					 270
-#define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT		 275
-#define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT		 276
+#define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT		 281
+#define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT		 282
 #define SSL_F_SSL_READ					 223
 #define SSL_F_SSL_RSA_PRIVATE_DECRYPT			 187
 #define SSL_F_SSL_RSA_PUBLIC_ENCRYPT			 188
@@ -1845,6 +1994,7 @@
 #define SSL_F_SSL_SET_RFD				 194
 #define SSL_F_SSL_SET_SESSION				 195
 #define SSL_F_SSL_SET_SESSION_ID_CONTEXT		 218
+#define SSL_F_SSL_SET_SESSION_TICKET_EXT		 294
 #define SSL_F_SSL_SET_TRUST				 228
 #define SSL_F_SSL_SET_WFD				 196
 #define SSL_F_SSL_SHUTDOWN				 224
@@ -1857,13 +2007,19 @@
 #define SSL_F_SSL_USE_PRIVATEKEY			 201
 #define SSL_F_SSL_USE_PRIVATEKEY_ASN1			 202
 #define SSL_F_SSL_USE_PRIVATEKEY_FILE			 203
+#define SSL_F_SSL_USE_PSK_IDENTITY_HINT			 273
 #define SSL_F_SSL_USE_RSAPRIVATEKEY			 204
 #define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1		 205
 #define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE		 206
 #define SSL_F_SSL_VERIFY_CERT_CHAIN			 207
 #define SSL_F_SSL_WRITE					 208
+#define SSL_F_TLS1_CERT_VERIFY_MAC			 286
 #define SSL_F_TLS1_CHANGE_CIPHER_STATE			 209
+#define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT		 274
 #define SSL_F_TLS1_ENC					 210
+#define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT		 275
+#define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT		 276
+#define SSL_F_TLS1_PRF					 284
 #define SSL_F_TLS1_SETUP_KEY_BLOCK			 211
 #define SSL_F_WRITE_PENDING				 212
 
@@ -1884,12 +2040,15 @@
 #define SSL_R_BAD_ECC_CERT				 304
 #define SSL_R_BAD_ECDSA_SIGNATURE			 305
 #define SSL_R_BAD_ECPOINT				 306
+#define SSL_R_BAD_HANDSHAKE_LENGTH			 332
 #define SSL_R_BAD_HELLO_REQUEST				 105
 #define SSL_R_BAD_LENGTH				 271
 #define SSL_R_BAD_MAC_DECODE				 113
+#define SSL_R_BAD_MAC_LENGTH				 333
 #define SSL_R_BAD_MESSAGE_TYPE				 114
 #define SSL_R_BAD_PACKET_LENGTH				 115
 #define SSL_R_BAD_PROTOCOL_VERSION_NUMBER		 116
+#define SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH		 316
 #define SSL_R_BAD_RESPONSE_ARGUMENT			 117
 #define SSL_R_BAD_RSA_DECRYPT				 118
 #define SSL_R_BAD_RSA_ENCRYPT				 119
@@ -1913,8 +2072,9 @@
 #define SSL_R_CIPHER_CODE_WRONG_LENGTH			 137
 #define SSL_R_CIPHER_OR_HASH_UNAVAILABLE		 138
 #define SSL_R_CIPHER_TABLE_SRC_ERROR			 139
-#define SSL_R_CLIENTHELLO_TLSEXT			 157
+#define SSL_R_CLIENTHELLO_TLSEXT			 226
 #define SSL_R_COMPRESSED_LENGTH_TOO_LONG		 140
+#define SSL_R_COMPRESSION_DISABLED			 343
 #define SSL_R_COMPRESSION_FAILURE			 141
 #define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE	 307
 #define SSL_R_COMPRESSION_LIBRARY_ERROR			 142
@@ -1927,8 +2087,12 @@
 #define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC	 281
 #define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG		 148
 #define SSL_R_DIGEST_CHECK_FAILED			 149
-#define SSL_R_DTLS_MESSAGE_TOO_BIG			 318
+#define SSL_R_DTLS_MESSAGE_TOO_BIG			 334
 #define SSL_R_DUPLICATE_COMPRESSION_ID			 309
+#define SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT		 317
+#define SSL_R_ECC_CERT_NOT_FOR_SIGNING			 318
+#define SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE	 322
+#define SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE	 323
 #define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER		 310
 #define SSL_R_ENCRYPTED_LENGTH_TOO_LONG			 150
 #define SSL_R_ERROR_GENERATING_TMP_RSA_KEY		 282
@@ -1939,11 +2103,13 @@
 #define SSL_R_HTTPS_PROXY_REQUEST			 155
 #define SSL_R_HTTP_REQUEST				 156
 #define SSL_R_ILLEGAL_PADDING				 283
+#define SSL_R_INCONSISTENT_COMPRESSION			 340
 #define SSL_R_INVALID_CHALLENGE_LENGTH			 158
 #define SSL_R_INVALID_COMMAND				 280
+#define SSL_R_INVALID_COMPRESSION_ALGORITHM		 341
 #define SSL_R_INVALID_PURPOSE				 278
-#define SSL_R_INVALID_STATUS_RESPONSE			 316
-#define SSL_R_INVALID_TICKET_KEYS_LENGTH		 275
+#define SSL_R_INVALID_STATUS_RESPONSE			 328
+#define SSL_R_INVALID_TICKET_KEYS_LENGTH		 325
 #define SSL_R_INVALID_TRUST				 279
 #define SSL_R_KEY_ARG_TOO_LONG				 284
 #define SSL_R_KRB5					 285
@@ -1987,23 +2153,27 @@
 #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_METHOD			 331
 #define SSL_R_NO_CLIENT_CERT_RECEIVED			 186
 #define SSL_R_NO_COMPRESSION_SPECIFIED			 187
+#define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER		 330
 #define SSL_R_NO_METHOD_SPECIFIED			 188
 #define SSL_R_NO_PRIVATEKEY				 189
 #define SSL_R_NO_PRIVATE_KEY_ASSIGNED			 190
 #define SSL_R_NO_PROTOCOLS_AVAILABLE			 191
 #define SSL_R_NO_PUBLICKEY				 192
-#define SSL_R_NO_RENEGOTIATION				 319
+#define SSL_R_NO_RENEGOTIATION				 339
+#define SSL_R_NO_REQUIRED_DIGEST			 324
 #define SSL_R_NO_SHARED_CIPHER				 193
 #define SSL_R_NO_VERIFY_CALLBACK			 194
 #define SSL_R_NULL_SSL_CTX				 195
 #define SSL_R_NULL_SSL_METHOD_PASSED			 196
 #define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED		 197
+#define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344
 #define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE		 297
+#define SSL_R_OPAQUE_PRF_INPUT_TOO_LONG			 327
 #define SSL_R_PACKET_LENGTH_TOO_LONG			 198
-#define SSL_R_PARSE_TLSEXT				 223
+#define SSL_R_PARSE_TLSEXT				 227
 #define SSL_R_PATH_TOO_LONG				 270
 #define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE		 199
 #define SSL_R_PEER_ERROR				 200
@@ -2014,6 +2184,9 @@
 #define SSL_R_PRE_MAC_LENGTH_TOO_LONG			 205
 #define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS		 206
 #define SSL_R_PROTOCOL_IS_SHUTDOWN			 207
+#define SSL_R_PSK_IDENTITY_NOT_FOUND			 223
+#define SSL_R_PSK_NO_CLIENT_CB				 224
+#define SSL_R_PSK_NO_SERVER_CB				 225
 #define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR			 208
 #define SSL_R_PUBLIC_KEY_IS_NOT_RSA			 209
 #define SSL_R_PUBLIC_KEY_NOT_RSA			 210
@@ -2023,22 +2196,24 @@
 #define SSL_R_RECORD_LENGTH_MISMATCH			 213
 #define SSL_R_RECORD_TOO_LARGE				 214
 #define SSL_R_RECORD_TOO_SMALL				 298
-#define SSL_R_RENEGOTIATE_EXT_TOO_LONG			 320
-#define SSL_R_RENEGOTIATION_ENCODING_ERR		 321
-#define SSL_R_RENEGOTIATION_MISMATCH			 322
+#define SSL_R_RENEGOTIATE_EXT_TOO_LONG			 335
+#define SSL_R_RENEGOTIATION_ENCODING_ERR		 336
+#define SSL_R_RENEGOTIATION_MISMATCH			 337
 #define SSL_R_REQUIRED_CIPHER_MISSING			 215
+#define SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING	 342
 #define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO		 216
 #define SSL_R_REUSE_CERT_TYPE_NOT_ZERO			 217
 #define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO		 218
-#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING		 324
-#define SSL_R_SERVERHELLO_TLSEXT			 224
+#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING		 345
+#define SSL_R_SERVERHELLO_TLSEXT			 275
 #define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED		 277
 #define SSL_R_SHORT_READ				 219
 #define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE	 220
 #define SSL_R_SSL23_DOING_SESSION_ID_REUSE		 221
 #define SSL_R_SSL2_CONNECTION_ID_TOO_LONG		 299
-#define SSL_R_SSL3_EXT_INVALID_SERVERNAME		 225
-#define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE		 226
+#define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT		 321
+#define SSL_R_SSL3_EXT_INVALID_SERVERNAME		 319
+#define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE		 320
 #define SSL_R_SSL3_SESSION_ID_TOO_LONG			 300
 #define SSL_R_SSL3_SESSION_ID_TOO_SHORT			 222
 #define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE		 1042
@@ -2072,8 +2247,13 @@
 #define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW		 1022
 #define SSL_R_TLSV1_ALERT_UNKNOWN_CA			 1048
 #define SSL_R_TLSV1_ALERT_USER_CANCELLED		 1090
+#define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE		 1114
+#define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE	 1113
+#define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE		 1111
+#define SSL_R_TLSV1_UNRECOGNIZED_NAME			 1112
+#define SSL_R_TLSV1_UNSUPPORTED_EXTENSION		 1110
 #define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER	 232
-#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST		 227
+#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST		 157
 #define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233
 #define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG	 234
 #define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER		 235
@@ -2100,9 +2280,10 @@
 #define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE			 253
 #define SSL_R_UNKNOWN_SSL_VERSION			 254
 #define SSL_R_UNKNOWN_STATE				 255
-#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED	 323
+#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED	 338
 #define SSL_R_UNSUPPORTED_CIPHER			 256
 #define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM		 257
+#define SSL_R_UNSUPPORTED_DIGEST_TYPE			 326
 #define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE		 315
 #define SSL_R_UNSUPPORTED_PROTOCOL			 258
 #define SSL_R_UNSUPPORTED_SSL_VERSION			 259
diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h
index bf71ef9..fb41ca5 100644
--- a/include/openssl/ssl3.h
+++ b/include/openssl/ssl3.h
@@ -123,7 +123,6 @@
 #include <openssl/buffer.h>
 #include <openssl/evp.h>
 #include <openssl/ssl.h>
-#include <openssl/pq_compat.h>
 
 #ifdef  __cplusplus
 extern "C" {
@@ -163,12 +162,14 @@
 #define SSL3_CK_ADH_DES_64_CBC_SHA		0x0300001A
 #define SSL3_CK_ADH_DES_192_CBC_SHA		0x0300001B
 
-#define SSL3_CK_FZA_DMS_NULL_SHA		0x0300001C
-#define SSL3_CK_FZA_DMS_FZA_SHA			0x0300001D
-#if 0 /* Because it clashes with KRB5, is never used any more, and is safe
-	 to remove according to David Hopwood <david.hopwood@zetnet.co.uk>
-	 of the ietf-tls list */
-#define SSL3_CK_FZA_DMS_RC4_SHA			0x0300001E
+#if 0
+	#define SSL3_CK_FZA_DMS_NULL_SHA		0x0300001C
+	#define SSL3_CK_FZA_DMS_FZA_SHA			0x0300001D
+	#if 0 /* Because it clashes with KRB5, is never used any more, and is safe
+		 to remove according to David Hopwood <david.hopwood@zetnet.co.uk>
+		 of the ietf-tls list */
+	#define SSL3_CK_FZA_DMS_RC4_SHA			0x0300001E
+	#endif
 #endif
 
 /*    VRS Additional Kerberos5 entries
@@ -220,9 +221,11 @@
 #define SSL3_TXT_ADH_DES_64_CBC_SHA		"ADH-DES-CBC-SHA"
 #define SSL3_TXT_ADH_DES_192_CBC_SHA		"ADH-DES-CBC3-SHA"
 
-#define SSL3_TXT_FZA_DMS_NULL_SHA		"FZA-NULL-SHA"
-#define SSL3_TXT_FZA_DMS_FZA_SHA		"FZA-FZA-CBC-SHA"
-#define SSL3_TXT_FZA_DMS_RC4_SHA		"FZA-RC4-SHA"
+#if 0
+	#define SSL3_TXT_FZA_DMS_NULL_SHA		"FZA-NULL-SHA"
+	#define SSL3_TXT_FZA_DMS_FZA_SHA		"FZA-FZA-CBC-SHA"
+	#define SSL3_TXT_FZA_DMS_RC4_SHA		"FZA-RC4-SHA"
+#endif
 
 #define SSL3_TXT_KRB5_DES_64_CBC_SHA		"KRB5-DES-CBC-SHA"
 #define SSL3_TXT_KRB5_DES_192_CBC3_SHA		"KRB5-DES-CBC3-SHA"
@@ -248,32 +251,75 @@
 #define SSL3_SESSION_ID_SIZE			32
 #define SSL3_RT_HEADER_LENGTH			5
 
-/* Due to MS stuffing up, this can change.... */
-#if defined(OPENSSL_SYS_WIN16) || \
-	(defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32))
-#define SSL3_RT_MAX_EXTRA			(14000)
+#ifndef SSL3_ALIGN_PAYLOAD
+ /* Some will argue that this increases memory footprint, but it's
+  * not actually true. Point is that malloc has to return at least
+  * 64-bit aligned pointers, meaning that allocating 5 bytes wastes
+  * 3 bytes in either case. Suggested pre-gaping simply moves these
+  * wasted bytes from the end of allocated region to its front,
+  * but makes data payload aligned, which improves performance:-) */
+# define SSL3_ALIGN_PAYLOAD			8
 #else
-#define SSL3_RT_MAX_EXTRA			(16384)
+# if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0
+#  error "insane SSL3_ALIGN_PAYLOAD"
+#  undef SSL3_ALIGN_PAYLOAD
+# endif
 #endif
 
+/* This is the maximum MAC (digest) size used by the SSL library.
+ * Currently maximum of 20 is used by SHA1, but we reserve for
+ * future extension for 512-bit hashes.
+ */
+
+#define SSL3_RT_MAX_MD_SIZE			64
+
+/* Maximum block size used in all ciphersuites. Currently 16 for AES.
+ */
+
+#define	SSL_RT_MAX_CIPHER_BLOCK_SIZE		16
+
+#define SSL3_RT_MAX_EXTRA			(16384)
+
 /* Default buffer length used for writen records.  Thus a generated record
  * will contain plaintext no larger than this value. */
 #define SSL3_RT_DEFAULT_PLAIN_LENGTH	2048
+/* Maximum plaintext length: defined by SSL/TLS standards */
 #define SSL3_RT_MAX_PLAIN_LENGTH		16384
+/* Maximum compression overhead: defined by SSL/TLS standards */
+#define SSL3_RT_MAX_COMPRESSED_OVERHEAD		1024
+
+/* The standards give a maximum encryption overhead of 1024 bytes.
+ * In practice the value is lower than this. The overhead is the maximum
+ * number of padding bytes (256) plus the mac size.
+ */
+#define SSL3_RT_MAX_ENCRYPTED_OVERHEAD	(256 + SSL3_RT_MAX_MD_SIZE)
+
+/* OpenSSL currently only uses a padding length of at most one block so
+ * the send overhead is smaller.
+ */
+
+#define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \
+			(SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE)
+
+/* If compression isn't used don't include the compression overhead */
+
 #ifdef OPENSSL_NO_COMP
-#define SSL3_RT_MAX_COMPRESSED_LENGTH	SSL3_RT_MAX_PLAIN_LENGTH
+#define SSL3_RT_MAX_COMPRESSED_LENGTH		SSL3_RT_MAX_PLAIN_LENGTH
 #else
-#define SSL3_RT_MAX_COMPRESSED_LENGTH	(1024+SSL3_RT_MAX_PLAIN_LENGTH)
+#define SSL3_RT_MAX_COMPRESSED_LENGTH	\
+		(SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD)
 #endif
-#define SSL3_RT_MAX_ENCRYPTED_LENGTH	(1024+SSL3_RT_MAX_COMPRESSED_LENGTH)
+#define SSL3_RT_MAX_ENCRYPTED_LENGTH	\
+		(SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH)
+#define SSL3_RT_MAX_PACKET_SIZE		\
+		(SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
+
 /* Extra space for empty fragment, headers, MAC, and padding. */
 #define SSL3_RT_DEFAULT_WRITE_OVERHEAD  256
 #define SSL3_RT_DEFAULT_PACKET_SIZE     4096 - SSL3_RT_DEFAULT_WRITE_OVERHEAD
 #if SSL3_RT_DEFAULT_PLAIN_LENGTH + SSL3_RT_DEFAULT_WRITE_OVERHEAD > SSL3_RT_DEFAULT_PACKET_SIZE
 #error "Insufficient space allocated for write buffers."
 #endif
-#define SSL3_RT_MAX_PACKET_SIZE		(SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
-#define SSL3_RT_MAX_DATA_SIZE			(1024*1024)
 
 #define SSL3_MD_CLIENT_FINISHED_CONST	"\x43\x4C\x4E\x54"
 #define SSL3_MD_SERVER_FINISHED_CONST	"\x53\x52\x56\x52"
@@ -312,7 +358,7 @@
 /*rw*/	unsigned char *input;   /* where the decode bytes are */
 /*r */	unsigned char *comp;    /* only used with decompression - malloc()ed */
 /*r */  unsigned long epoch;    /* epoch number, needed by DTLS1 */
-/*r */  PQ_64BIT seq_num;       /* sequence number, needed by DTLS1 */
+/*r */  unsigned char seq_num[8]; /* sequence number, needed by DTLS1 */
 	} SSL3_RECORD;
 
 typedef struct ssl3_buffer_st
@@ -335,13 +381,14 @@
  * enough to contain all of the cert types defined either for
  * SSLv3 and TLSv1.
  */
-#define SSL3_CT_NUMBER			7
+#define SSL3_CT_NUMBER			9
 
 
 #define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS	0x0001
 #define SSL3_FLAGS_DELAY_CLIENT_FINISHED	0x0002
 #define SSL3_FLAGS_POP_BUFFER			0x0004
 #define TLS1_FLAGS_TLS_PADDING_BUG		0x0008
+#define TLS1_FLAGS_SKIP_CERT_VERIFY		0x0010
 
 typedef struct ssl3_state_st
 	{
@@ -349,8 +396,10 @@
 	int delay_buf_pop_ret;
 
 	unsigned char read_sequence[8];
+	int read_mac_secret_size;
 	unsigned char read_mac_secret[EVP_MAX_MD_SIZE];
 	unsigned char write_sequence[8];
+	int write_mac_secret_size;
 	unsigned char write_mac_secret[EVP_MAX_MD_SIZE];
 
 	unsigned char server_random[SSL3_RANDOM_SIZE];
@@ -360,6 +409,9 @@
 	int need_empty_fragments;
 	int empty_fragment_done;
 
+	/* The value of 'extra' when the buffers were initialized */
+	int init_extra;
+
 	SSL3_BUFFER rbuf;	/* read IO goes into here */
 	SSL3_BUFFER wbuf;	/* write IO goes into here */
 
@@ -381,9 +433,11 @@
 	const unsigned char *wpend_buf;
 
 	/* used during startup, digest all incoming/outgoing packets */
-	EVP_MD_CTX finish_dgst1;
-	EVP_MD_CTX finish_dgst2;
-
+	BIO *handshake_buffer;
+	/* When set of handshake digests is determined, buffer is hashed
+	 * and freed and MD_CTX-es for all required digests are stored in
+	 * this array */
+	EVP_MD_CTX **handshake_dgst;
 	/* this is set whenerver we see a change_cipher_spec message
 	 * come in when we are not looking for one */
 	int change_cipher_spec;
@@ -403,6 +457,14 @@
 
 	int in_read_app_data;
 
+	/* Opaque PRF input as used for the current handshake.
+	 * These fields are used only if TLSEXT_TYPE_opaque_prf_input is defined
+	 * (otherwise, they are merely present to improve binary compatibility) */
+	void *client_opaque_prf_input;
+	size_t client_opaque_prf_input_len;
+	void *server_opaque_prf_input;
+	size_t server_opaque_prf_input_len;
+
 	struct	{
 		/* actually only needs to be 16+20 */
 		unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2];
@@ -417,7 +479,7 @@
 		int message_type;
 
 		/* used to hold the new cipher we are going to use */
-		SSL_CIPHER *new_cipher;
+		const SSL_CIPHER *new_cipher;
 #ifndef OPENSSL_NO_DH
 		DH *dh;
 #endif
@@ -444,6 +506,8 @@
 
 		const EVP_CIPHER *new_sym_enc;
 		const EVP_MD *new_hash;
+		int new_mac_pkey_type;
+		int new_mac_secret_size;
 #ifndef OPENSSL_NO_COMP
 		const SSL_COMP *new_compression;
 #else
@@ -580,4 +644,3 @@
 }
 #endif
 #endif
-
diff --git a/include/openssl/stack.h b/include/openssl/stack.h
index 5cbb116..ce35e55 100644
--- a/include/openssl/stack.h
+++ b/include/openssl/stack.h
@@ -70,37 +70,36 @@
 	int sorted;
 
 	int num_alloc;
-	int (*comp)(const char * const *, const char * const *);
-	} STACK;
+	int (*comp)(const void *, const void *);
+	} _STACK;  /* Use STACK_OF(...) instead */
 
 #define M_sk_num(sk)		((sk) ? (sk)->num:-1)
 #define M_sk_value(sk,n)	((sk) ? (sk)->data[n] : NULL)
 
-int sk_num(const STACK *);
-char *sk_value(const STACK *, int);
+int sk_num(const _STACK *);
+void *sk_value(const _STACK *, int);
 
-char *sk_set(STACK *, int, char *);
+void *sk_set(_STACK *, int, void *);
 
-STACK *sk_new(int (*cmp)(const char * const *, const char * const *));
-STACK *sk_new_null(void);
-void sk_free(STACK *);
-void sk_pop_free(STACK *st, void (*func)(void *));
-int sk_insert(STACK *sk,char *data,int where);
-char *sk_delete(STACK *st,int loc);
-char *sk_delete_ptr(STACK *st, char *p);
-int sk_find(STACK *st,char *data);
-int sk_find_ex(STACK *st,char *data);
-int sk_push(STACK *st,char *data);
-int sk_unshift(STACK *st,char *data);
-char *sk_shift(STACK *st);
-char *sk_pop(STACK *st);
-void sk_zero(STACK *st);
-int (*sk_set_cmp_func(STACK *sk, int (*c)(const char * const *,
-			const char * const *)))
-			(const char * const *, const char * const *);
-STACK *sk_dup(STACK *st);
-void sk_sort(STACK *st);
-int sk_is_sorted(const STACK *st);
+_STACK *sk_new(int (*cmp)(const void *, const void *));
+_STACK *sk_new_null(void);
+void sk_free(_STACK *);
+void sk_pop_free(_STACK *st, void (*func)(void *));
+int sk_insert(_STACK *sk, void *data, int where);
+void *sk_delete(_STACK *st, int loc);
+void *sk_delete_ptr(_STACK *st, void *p);
+int sk_find(_STACK *st, void *data);
+int sk_find_ex(_STACK *st, void *data);
+int sk_push(_STACK *st, void *data);
+int sk_unshift(_STACK *st, void *data);
+void *sk_shift(_STACK *st);
+void *sk_pop(_STACK *st);
+void sk_zero(_STACK *st);
+int (*sk_set_cmp_func(_STACK *sk, int (*c)(const void *, const void *)))
+	(const void *, const void *);
+_STACK *sk_dup(_STACK *st);
+void sk_sort(_STACK *st);
+int sk_is_sorted(const _STACK *st);
 
 #ifdef  __cplusplus
 }
diff --git a/include/openssl/store.h b/include/openssl/store.h
deleted file mode 100644
index 6458337..0000000
--- a/include/openssl/store.h
+++ /dev/null
@@ -1,554 +0,0 @@
-/* crypto/store/store.h -*- mode:C; c-file-style: "eay" -*- */
-/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
- * project 2003.
- */
-/* ====================================================================
- * 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
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#ifndef HEADER_STORE_H
-#define HEADER_STORE_H
-
-#include <openssl/ossl_typ.h>
-#ifndef OPENSSL_NO_DEPRECATED
-#include <openssl/evp.h>
-#include <openssl/bn.h>
-#include <openssl/x509.h>
-#endif
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-/* Already defined in ossl_typ.h */
-/* typedef struct store_st STORE; */
-/* typedef struct store_method_st STORE_METHOD; */
-
-
-/* All the following functions return 0, a negative number or NULL on error.
-   When everything is fine, they return a positive value or a non-NULL
-   pointer, all depending on their purpose. */
-
-/* Creators and destructor.   */
-STORE *STORE_new_method(const STORE_METHOD *method);
-STORE *STORE_new_engine(ENGINE *engine);
-void STORE_free(STORE *ui);
-
-
-/* Give a user interface parametrised control commands.  This can be used to
-   send down an integer, a data pointer or a function pointer, as well as
-   be used to get information from a STORE. */
-int STORE_ctrl(STORE *store, int cmd, long i, void *p, void (*f)(void));
-
-/* A control to set the directory with keys and certificates.  Used by the
-   built-in directory level method. */
-#define STORE_CTRL_SET_DIRECTORY	0x0001
-/* A control to set a file to load.  Used by the built-in file level method. */
-#define STORE_CTRL_SET_FILE		0x0002
-/* A control to set a configuration file to load.  Can be used by any method
-   that wishes to load a configuration file. */
-#define STORE_CTRL_SET_CONF_FILE	0x0003
-/* A control to set a the section of the loaded configuration file.  Can be
-   used by any method that wishes to load a configuration file. */
-#define STORE_CTRL_SET_CONF_SECTION	0x0004
-
-
-/* Some methods may use extra data */
-#define STORE_set_app_data(s,arg)	STORE_set_ex_data(s,0,arg)
-#define STORE_get_app_data(s)		STORE_get_ex_data(s,0)
-int STORE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
-	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
-int STORE_set_ex_data(STORE *r,int idx,void *arg);
-void *STORE_get_ex_data(STORE *r, int idx);
-
-/* Use specific methods instead of the built-in one */
-const STORE_METHOD *STORE_get_method(STORE *store);
-const STORE_METHOD *STORE_set_method(STORE *store, const STORE_METHOD *meth);
-
-/* The standard OpenSSL methods. */
-/* This is the in-memory method.  It does everything except revoking and updating,
-   and is of course volatile.  It's used by other methods that have an in-memory
-   cache. */
-const STORE_METHOD *STORE_Memory(void);
-#if 0 /* Not yet implemented */
-/* This is the directory store.  It does everything except revoking and updating,
-   and uses STORE_Memory() to cache things in memory. */
-const STORE_METHOD *STORE_Directory(void);
-/* This is the file store.  It does everything except revoking and updating,
-   and uses STORE_Memory() to cache things in memory.  Certificates are added
-   to it with the store operation, and it will only get cached certificates. */
-const STORE_METHOD *STORE_File(void);
-#endif
-
-/* Store functions take a type code for the type of data they should store
-   or fetch */
-typedef enum STORE_object_types
-	{
-	STORE_OBJECT_TYPE_X509_CERTIFICATE=	0x01, /* X509 * */
-	STORE_OBJECT_TYPE_X509_CRL=		0x02, /* X509_CRL * */
-	STORE_OBJECT_TYPE_PRIVATE_KEY=		0x03, /* EVP_PKEY * */
-	STORE_OBJECT_TYPE_PUBLIC_KEY=		0x04, /* EVP_PKEY * */
-	STORE_OBJECT_TYPE_NUMBER=		0x05, /* BIGNUM * */
-	STORE_OBJECT_TYPE_ARBITRARY=		0x06, /* BUF_MEM * */
-	STORE_OBJECT_TYPE_NUM=			0x06  /* The amount of known
-							 object types */
-	} STORE_OBJECT_TYPES;
-/* List of text strings corresponding to the object types. */
-extern const char * const STORE_object_type_string[STORE_OBJECT_TYPE_NUM+1];
-
-/* Some store functions take a parameter list.  Those parameters come with
-   one of the following codes. The comments following the codes below indicate
-   what type the value should be a pointer to. */
-typedef enum STORE_params
-	{
-	STORE_PARAM_EVP_TYPE=			0x01, /* int */
-	STORE_PARAM_BITS=			0x02, /* size_t */
-	STORE_PARAM_KEY_PARAMETERS=		0x03, /* ??? */
-	STORE_PARAM_KEY_NO_PARAMETERS=		0x04, /* N/A */
-	STORE_PARAM_AUTH_PASSPHRASE=		0x05, /* char * */
-	STORE_PARAM_AUTH_KRB5_TICKET=		0x06, /* void * */
-	STORE_PARAM_TYPE_NUM=			0x06  /* The amount of known
-							 parameter types */
-	} STORE_PARAM_TYPES;
-/* Parameter value sizes.  -1 means unknown, anything else is the required size. */
-extern const int STORE_param_sizes[STORE_PARAM_TYPE_NUM+1];
-
-/* Store functions take attribute lists.  Those attributes come with codes.
-   The comments following the codes below indicate what type the value should
-   be a pointer to. */
-typedef enum STORE_attribs
-	{
-	STORE_ATTR_END=				0x00,
-	STORE_ATTR_FRIENDLYNAME=		0x01, /* C string */
-	STORE_ATTR_KEYID=			0x02, /* 160 bit string (SHA1) */
-	STORE_ATTR_ISSUERKEYID=			0x03, /* 160 bit string (SHA1) */
-	STORE_ATTR_SUBJECTKEYID=		0x04, /* 160 bit string (SHA1) */
-	STORE_ATTR_ISSUERSERIALHASH=		0x05, /* 160 bit string (SHA1) */
-	STORE_ATTR_ISSUER=			0x06, /* X509_NAME * */
-	STORE_ATTR_SERIAL=			0x07, /* BIGNUM * */
-	STORE_ATTR_SUBJECT=			0x08, /* X509_NAME * */
-	STORE_ATTR_CERTHASH=			0x09, /* 160 bit string (SHA1) */
-	STORE_ATTR_EMAIL=			0x0a, /* C string */
-	STORE_ATTR_FILENAME=			0x0b, /* C string */
-	STORE_ATTR_TYPE_NUM=			0x0b, /* The amount of known
-							 attribute types */
-	STORE_ATTR_OR=				0xff  /* This is a special
-							 separator, which
-							 expresses the OR
-							 operation.  */
-	} STORE_ATTR_TYPES;
-/* Attribute value sizes.  -1 means unknown, anything else is the required size. */
-extern const int STORE_attr_sizes[STORE_ATTR_TYPE_NUM+1];
-
-typedef enum STORE_certificate_status
-	{
-	STORE_X509_VALID=			0x00,
-	STORE_X509_EXPIRED=			0x01,
-	STORE_X509_SUSPENDED=			0x02,
-	STORE_X509_REVOKED=			0x03
-	} STORE_CERTIFICATE_STATUS;
-
-/* Engine store functions will return a structure that contains all the necessary
- * information, including revokation status for certificates.  This is really not
- * needed for application authors, as the ENGINE framework functions will extract
- * the OpenSSL-specific information when at all possible.  However, for engine
- * authors, it's crucial to know this structure.  */
-typedef struct STORE_OBJECT_st
-	{
-	STORE_OBJECT_TYPES type;
-	union
-		{
-		struct
-			{
-			STORE_CERTIFICATE_STATUS status;
-			X509 *certificate;
-			} x509;
-		X509_CRL *crl;
-		EVP_PKEY *key;
-		BIGNUM *number;
-		BUF_MEM *arbitrary;
-		} data;
-	} STORE_OBJECT;
-DECLARE_STACK_OF(STORE_OBJECT)
-STORE_OBJECT *STORE_OBJECT_new(void);
-void STORE_OBJECT_free(STORE_OBJECT *data);
-
-
-
-/* The following functions handle the storage. They return 0, a negative number
-   or NULL on error, anything else on success. */
-X509 *STORE_get_certificate(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-int STORE_store_certificate(STORE *e, X509 *data, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-int STORE_modify_certificate(STORE *e, OPENSSL_ITEM search_attributes[],
-	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
-	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
-int STORE_revoke_certificate(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-int STORE_delete_certificate(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-void *STORE_list_certificate_start(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-X509 *STORE_list_certificate_next(STORE *e, void *handle);
-int STORE_list_certificate_end(STORE *e, void *handle);
-int STORE_list_certificate_endp(STORE *e, void *handle);
-EVP_PKEY *STORE_generate_key(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-EVP_PKEY *STORE_get_private_key(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-int STORE_store_private_key(STORE *e, EVP_PKEY *data,
-	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
-int STORE_modify_private_key(STORE *e, OPENSSL_ITEM search_attributes[],
-	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
-	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
-int STORE_revoke_private_key(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-int STORE_delete_private_key(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-void *STORE_list_private_key_start(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-EVP_PKEY *STORE_list_private_key_next(STORE *e, void *handle);
-int STORE_list_private_key_end(STORE *e, void *handle);
-int STORE_list_private_key_endp(STORE *e, void *handle);
-EVP_PKEY *STORE_get_public_key(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-int STORE_store_public_key(STORE *e, EVP_PKEY *data, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-int STORE_modify_public_key(STORE *e, OPENSSL_ITEM search_attributes[],
-	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
-	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
-int STORE_revoke_public_key(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-int STORE_delete_public_key(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-void *STORE_list_public_key_start(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-EVP_PKEY *STORE_list_public_key_next(STORE *e, void *handle);
-int STORE_list_public_key_end(STORE *e, void *handle);
-int STORE_list_public_key_endp(STORE *e, void *handle);
-X509_CRL *STORE_generate_crl(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-X509_CRL *STORE_get_crl(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-int STORE_store_crl(STORE *e, X509_CRL *data, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-int STORE_modify_crl(STORE *e, OPENSSL_ITEM search_attributes[],
-	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
-	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
-int STORE_delete_crl(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-void *STORE_list_crl_start(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-X509_CRL *STORE_list_crl_next(STORE *e, void *handle);
-int STORE_list_crl_end(STORE *e, void *handle);
-int STORE_list_crl_endp(STORE *e, void *handle);
-int STORE_store_number(STORE *e, BIGNUM *data, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-int STORE_modify_number(STORE *e, OPENSSL_ITEM search_attributes[],
-	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
-	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
-BIGNUM *STORE_get_number(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-int STORE_delete_number(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-int STORE_store_arbitrary(STORE *e, BUF_MEM *data, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-int STORE_modify_arbitrary(STORE *e, OPENSSL_ITEM search_attributes[],
-	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
-	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
-BUF_MEM *STORE_get_arbitrary(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-int STORE_delete_arbitrary(STORE *e, OPENSSL_ITEM attributes[],
-	OPENSSL_ITEM parameters[]);
-
-
-/* Create and manipulate methods */
-STORE_METHOD *STORE_create_method(char *name);
-void STORE_destroy_method(STORE_METHOD *store_method);
-
-/* These callback types are use for store handlers */
-typedef int (*STORE_INITIALISE_FUNC_PTR)(STORE *);
-typedef void (*STORE_CLEANUP_FUNC_PTR)(STORE *);
-typedef STORE_OBJECT *(*STORE_GENERATE_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
-typedef STORE_OBJECT *(*STORE_GET_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
-typedef void *(*STORE_START_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
-typedef STORE_OBJECT *(*STORE_NEXT_OBJECT_FUNC_PTR)(STORE *, void *handle);
-typedef int (*STORE_END_OBJECT_FUNC_PTR)(STORE *, void *handle);
-typedef int (*STORE_HANDLE_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
-typedef int (*STORE_STORE_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, STORE_OBJECT *data, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
-typedef int (*STORE_MODIFY_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
-typedef int (*STORE_GENERIC_FUNC_PTR)(STORE *, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
-typedef int (*STORE_CTRL_FUNC_PTR)(STORE *, int cmd, long l, void *p, void (*f)(void));
-
-int STORE_method_set_initialise_function(STORE_METHOD *sm, STORE_INITIALISE_FUNC_PTR init_f);
-int STORE_method_set_cleanup_function(STORE_METHOD *sm, STORE_CLEANUP_FUNC_PTR clean_f);
-int STORE_method_set_generate_function(STORE_METHOD *sm, STORE_GENERATE_OBJECT_FUNC_PTR generate_f);
-int STORE_method_set_get_function(STORE_METHOD *sm, STORE_GET_OBJECT_FUNC_PTR get_f);
-int STORE_method_set_store_function(STORE_METHOD *sm, STORE_STORE_OBJECT_FUNC_PTR store_f);
-int STORE_method_set_modify_function(STORE_METHOD *sm, STORE_MODIFY_OBJECT_FUNC_PTR store_f);
-int STORE_method_set_revoke_function(STORE_METHOD *sm, STORE_HANDLE_OBJECT_FUNC_PTR revoke_f);
-int STORE_method_set_delete_function(STORE_METHOD *sm, STORE_HANDLE_OBJECT_FUNC_PTR delete_f);
-int STORE_method_set_list_start_function(STORE_METHOD *sm, STORE_START_OBJECT_FUNC_PTR list_start_f);
-int STORE_method_set_list_next_function(STORE_METHOD *sm, STORE_NEXT_OBJECT_FUNC_PTR list_next_f);
-int STORE_method_set_list_end_function(STORE_METHOD *sm, STORE_END_OBJECT_FUNC_PTR list_end_f);
-int STORE_method_set_update_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR);
-int STORE_method_set_lock_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR);
-int STORE_method_set_unlock_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR);
-int STORE_method_set_ctrl_function(STORE_METHOD *sm, STORE_CTRL_FUNC_PTR ctrl_f);
-
-STORE_INITIALISE_FUNC_PTR STORE_method_get_initialise_function(STORE_METHOD *sm);
-STORE_CLEANUP_FUNC_PTR STORE_method_get_cleanup_function(STORE_METHOD *sm);
-STORE_GENERATE_OBJECT_FUNC_PTR STORE_method_get_generate_function(STORE_METHOD *sm);
-STORE_GET_OBJECT_FUNC_PTR STORE_method_get_get_function(STORE_METHOD *sm);
-STORE_STORE_OBJECT_FUNC_PTR STORE_method_get_store_function(STORE_METHOD *sm);
-STORE_MODIFY_OBJECT_FUNC_PTR STORE_method_get_modify_function(STORE_METHOD *sm);
-STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_revoke_function(STORE_METHOD *sm);
-STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_delete_function(STORE_METHOD *sm);
-STORE_START_OBJECT_FUNC_PTR STORE_method_get_list_start_function(STORE_METHOD *sm);
-STORE_NEXT_OBJECT_FUNC_PTR STORE_method_get_list_next_function(STORE_METHOD *sm);
-STORE_END_OBJECT_FUNC_PTR STORE_method_get_list_end_function(STORE_METHOD *sm);
-STORE_GENERIC_FUNC_PTR STORE_method_get_update_store_function(STORE_METHOD *sm);
-STORE_GENERIC_FUNC_PTR STORE_method_get_lock_store_function(STORE_METHOD *sm);
-STORE_GENERIC_FUNC_PTR STORE_method_get_unlock_store_function(STORE_METHOD *sm);
-STORE_CTRL_FUNC_PTR STORE_method_get_ctrl_function(STORE_METHOD *sm);
-
-/* Method helper structures and functions. */
-
-/* This structure is the result of parsing through the information in a list
-   of OPENSSL_ITEMs.  It stores all the necessary information in a structured
-   way.*/
-typedef struct STORE_attr_info_st STORE_ATTR_INFO;
-
-/* Parse a list of OPENSSL_ITEMs and return a pointer to a STORE_ATTR_INFO.
-   Note that we do this in the list form, since the list of OPENSSL_ITEMs can
-   come in blocks separated with STORE_ATTR_OR.  Note that the value returned
-   by STORE_parse_attrs_next() must be freed with STORE_ATTR_INFO_free(). */
-void *STORE_parse_attrs_start(OPENSSL_ITEM *attributes);
-STORE_ATTR_INFO *STORE_parse_attrs_next(void *handle);
-int STORE_parse_attrs_end(void *handle);
-int STORE_parse_attrs_endp(void *handle);
-
-/* Creator and destructor */
-STORE_ATTR_INFO *STORE_ATTR_INFO_new(void);
-int STORE_ATTR_INFO_free(STORE_ATTR_INFO *attrs);
-
-/* Manipulators */
-char *STORE_ATTR_INFO_get0_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code);
-unsigned char *STORE_ATTR_INFO_get0_sha1str(STORE_ATTR_INFO *attrs,
-	STORE_ATTR_TYPES code);
-X509_NAME *STORE_ATTR_INFO_get0_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code);
-BIGNUM *STORE_ATTR_INFO_get0_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code);
-int STORE_ATTR_INFO_set_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
-	char *cstr, size_t cstr_size);
-int STORE_ATTR_INFO_set_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
-	unsigned char *sha1str, size_t sha1str_size);
-int STORE_ATTR_INFO_set_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
-	X509_NAME *dn);
-int STORE_ATTR_INFO_set_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
-	BIGNUM *number);
-int STORE_ATTR_INFO_modify_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
-	char *cstr, size_t cstr_size);
-int STORE_ATTR_INFO_modify_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
-	unsigned char *sha1str, size_t sha1str_size);
-int STORE_ATTR_INFO_modify_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
-	X509_NAME *dn);
-int STORE_ATTR_INFO_modify_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
-	BIGNUM *number);
-
-/* Compare on basis of a bit pattern formed by the STORE_ATTR_TYPES values
-   in each contained attribute. */
-int STORE_ATTR_INFO_compare(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
-/* Check if the set of attributes in a is within the range of attributes
-   set in b. */
-int STORE_ATTR_INFO_in_range(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
-/* Check if the set of attributes in a are also set in b. */
-int STORE_ATTR_INFO_in(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
-/* Same as STORE_ATTR_INFO_in(), but also checks the attribute values. */
-int STORE_ATTR_INFO_in_ex(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
-
-
-/* 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_STORE_strings(void);
-
-/* Error codes for the STORE functions. */
-
-/* Function codes. */
-#define STORE_F_MEM_DELETE				 134
-#define STORE_F_MEM_GENERATE				 135
-#define STORE_F_MEM_LIST_END				 168
-#define STORE_F_MEM_LIST_NEXT				 136
-#define STORE_F_MEM_LIST_START				 137
-#define STORE_F_MEM_MODIFY				 169
-#define STORE_F_MEM_STORE				 138
-#define STORE_F_STORE_ATTR_INFO_GET0_CSTR		 139
-#define STORE_F_STORE_ATTR_INFO_GET0_DN			 140
-#define STORE_F_STORE_ATTR_INFO_GET0_NUMBER		 141
-#define STORE_F_STORE_ATTR_INFO_GET0_SHA1STR		 142
-#define STORE_F_STORE_ATTR_INFO_MODIFY_CSTR		 143
-#define STORE_F_STORE_ATTR_INFO_MODIFY_DN		 144
-#define STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER		 145
-#define STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR		 146
-#define STORE_F_STORE_ATTR_INFO_SET_CSTR		 147
-#define STORE_F_STORE_ATTR_INFO_SET_DN			 148
-#define STORE_F_STORE_ATTR_INFO_SET_NUMBER		 149
-#define STORE_F_STORE_ATTR_INFO_SET_SHA1STR		 150
-#define STORE_F_STORE_CERTIFICATE			 170
-#define STORE_F_STORE_CTRL				 161
-#define STORE_F_STORE_DELETE_ARBITRARY			 158
-#define STORE_F_STORE_DELETE_CERTIFICATE		 102
-#define STORE_F_STORE_DELETE_CRL			 103
-#define STORE_F_STORE_DELETE_NUMBER			 104
-#define STORE_F_STORE_DELETE_PRIVATE_KEY		 105
-#define STORE_F_STORE_DELETE_PUBLIC_KEY			 106
-#define STORE_F_STORE_GENERATE_CRL			 107
-#define STORE_F_STORE_GENERATE_KEY			 108
-#define STORE_F_STORE_GET_ARBITRARY			 159
-#define STORE_F_STORE_GET_CERTIFICATE			 109
-#define STORE_F_STORE_GET_CRL				 110
-#define STORE_F_STORE_GET_NUMBER			 111
-#define STORE_F_STORE_GET_PRIVATE_KEY			 112
-#define STORE_F_STORE_GET_PUBLIC_KEY			 113
-#define STORE_F_STORE_LIST_CERTIFICATE_END		 114
-#define STORE_F_STORE_LIST_CERTIFICATE_ENDP		 153
-#define STORE_F_STORE_LIST_CERTIFICATE_NEXT		 115
-#define STORE_F_STORE_LIST_CERTIFICATE_START		 116
-#define STORE_F_STORE_LIST_CRL_END			 117
-#define STORE_F_STORE_LIST_CRL_ENDP			 154
-#define STORE_F_STORE_LIST_CRL_NEXT			 118
-#define STORE_F_STORE_LIST_CRL_START			 119
-#define STORE_F_STORE_LIST_PRIVATE_KEY_END		 120
-#define STORE_F_STORE_LIST_PRIVATE_KEY_ENDP		 155
-#define STORE_F_STORE_LIST_PRIVATE_KEY_NEXT		 121
-#define STORE_F_STORE_LIST_PRIVATE_KEY_START		 122
-#define STORE_F_STORE_LIST_PUBLIC_KEY_END		 123
-#define STORE_F_STORE_LIST_PUBLIC_KEY_ENDP		 156
-#define STORE_F_STORE_LIST_PUBLIC_KEY_NEXT		 124
-#define STORE_F_STORE_LIST_PUBLIC_KEY_START		 125
-#define STORE_F_STORE_MODIFY_ARBITRARY			 162
-#define STORE_F_STORE_MODIFY_CERTIFICATE		 163
-#define STORE_F_STORE_MODIFY_CRL			 164
-#define STORE_F_STORE_MODIFY_NUMBER			 165
-#define STORE_F_STORE_MODIFY_PRIVATE_KEY		 166
-#define STORE_F_STORE_MODIFY_PUBLIC_KEY			 167
-#define STORE_F_STORE_NEW_ENGINE			 133
-#define STORE_F_STORE_NEW_METHOD			 132
-#define STORE_F_STORE_PARSE_ATTRS_END			 151
-#define STORE_F_STORE_PARSE_ATTRS_ENDP			 172
-#define STORE_F_STORE_PARSE_ATTRS_NEXT			 152
-#define STORE_F_STORE_PARSE_ATTRS_START			 171
-#define STORE_F_STORE_REVOKE_CERTIFICATE		 129
-#define STORE_F_STORE_REVOKE_PRIVATE_KEY		 130
-#define STORE_F_STORE_REVOKE_PUBLIC_KEY			 131
-#define STORE_F_STORE_STORE_ARBITRARY			 157
-#define STORE_F_STORE_STORE_CERTIFICATE			 100
-#define STORE_F_STORE_STORE_CRL				 101
-#define STORE_F_STORE_STORE_NUMBER			 126
-#define STORE_F_STORE_STORE_PRIVATE_KEY			 127
-#define STORE_F_STORE_STORE_PUBLIC_KEY			 128
-
-/* Reason codes. */
-#define STORE_R_ALREADY_HAS_A_VALUE			 127
-#define STORE_R_FAILED_DELETING_ARBITRARY		 132
-#define STORE_R_FAILED_DELETING_CERTIFICATE		 100
-#define STORE_R_FAILED_DELETING_KEY			 101
-#define STORE_R_FAILED_DELETING_NUMBER			 102
-#define STORE_R_FAILED_GENERATING_CRL			 103
-#define STORE_R_FAILED_GENERATING_KEY			 104
-#define STORE_R_FAILED_GETTING_ARBITRARY		 133
-#define STORE_R_FAILED_GETTING_CERTIFICATE		 105
-#define STORE_R_FAILED_GETTING_KEY			 106
-#define STORE_R_FAILED_GETTING_NUMBER			 107
-#define STORE_R_FAILED_LISTING_CERTIFICATES		 108
-#define STORE_R_FAILED_LISTING_KEYS			 109
-#define STORE_R_FAILED_MODIFYING_ARBITRARY		 138
-#define STORE_R_FAILED_MODIFYING_CERTIFICATE		 139
-#define STORE_R_FAILED_MODIFYING_CRL			 140
-#define STORE_R_FAILED_MODIFYING_NUMBER			 141
-#define STORE_R_FAILED_MODIFYING_PRIVATE_KEY		 142
-#define STORE_R_FAILED_MODIFYING_PUBLIC_KEY		 143
-#define STORE_R_FAILED_REVOKING_CERTIFICATE		 110
-#define STORE_R_FAILED_REVOKING_KEY			 111
-#define STORE_R_FAILED_STORING_ARBITRARY		 134
-#define STORE_R_FAILED_STORING_CERTIFICATE		 112
-#define STORE_R_FAILED_STORING_KEY			 113
-#define STORE_R_FAILED_STORING_NUMBER			 114
-#define STORE_R_NOT_IMPLEMENTED				 128
-#define STORE_R_NO_CONTROL_FUNCTION			 144
-#define STORE_R_NO_DELETE_ARBITRARY_FUNCTION		 135
-#define STORE_R_NO_DELETE_NUMBER_FUNCTION		 115
-#define STORE_R_NO_DELETE_OBJECT_FUNCTION		 116
-#define STORE_R_NO_GENERATE_CRL_FUNCTION		 117
-#define STORE_R_NO_GENERATE_OBJECT_FUNCTION		 118
-#define STORE_R_NO_GET_OBJECT_ARBITRARY_FUNCTION	 136
-#define STORE_R_NO_GET_OBJECT_FUNCTION			 119
-#define STORE_R_NO_GET_OBJECT_NUMBER_FUNCTION		 120
-#define STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION		 131
-#define STORE_R_NO_LIST_OBJECT_END_FUNCTION		 121
-#define STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION		 122
-#define STORE_R_NO_LIST_OBJECT_START_FUNCTION		 123
-#define STORE_R_NO_MODIFY_OBJECT_FUNCTION		 145
-#define STORE_R_NO_REVOKE_OBJECT_FUNCTION		 124
-#define STORE_R_NO_STORE				 129
-#define STORE_R_NO_STORE_OBJECT_ARBITRARY_FUNCTION	 137
-#define STORE_R_NO_STORE_OBJECT_FUNCTION		 125
-#define STORE_R_NO_STORE_OBJECT_NUMBER_FUNCTION		 126
-#define STORE_R_NO_VALUE				 130
-
-#ifdef  __cplusplus
-}
-#endif
-#endif
diff --git a/include/openssl/symhacks.h b/include/openssl/symhacks.h
index 0114093..151b683 100644
--- a/include/openssl/symhacks.h
+++ b/include/openssl/symhacks.h
@@ -67,10 +67,6 @@
    incompatibilities. */
 #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
@@ -151,9 +147,9 @@
 #undef CRYPTO_set_dynlock_create_callback
 #define CRYPTO_set_dynlock_create_callback      CRYPTO_set_dynlock_create_cb
 #undef CRYPTO_set_dynlock_lock_callback
-#define CRYPTO_set_dynlock_lock_callback        CRYPTO_set_dynlock_lock_cb
+#define CRYPTO_set_dynlock_lock_callback	CRYPTO_set_dynlock_lock_cb
 #undef CRYPTO_get_dynlock_lock_callback
-#define CRYPTO_get_dynlock_lock_callback        CRYPTO_get_dynlock_lock_cb
+#define CRYPTO_get_dynlock_lock_callback	CRYPTO_get_dynlock_lock_cb
 #undef CRYPTO_get_dynlock_destroy_callback
 #define CRYPTO_get_dynlock_destroy_callback     CRYPTO_get_dynlock_destroy_cb
 #undef CRYPTO_get_dynlock_create_callback
@@ -165,7 +161,7 @@
 
 /* Hack some long SSL names */
 #undef SSL_CTX_set_default_verify_paths
-#define SSL_CTX_set_default_verify_paths        SSL_CTX_set_def_verify_paths
+#define SSL_CTX_set_default_verify_paths	SSL_CTX_set_def_verify_paths
 #undef SSL_get_ex_data_X509_STORE_CTX_idx
 #define SSL_get_ex_data_X509_STORE_CTX_idx      SSL_get_ex_d_X509_STORE_CTX_idx
 #undef SSL_add_file_cert_subjects_to_stack
@@ -175,7 +171,7 @@
 #undef SSL_CTX_use_certificate_chain_file
 #define SSL_CTX_use_certificate_chain_file      SSL_CTX_use_cert_chain_file
 #undef SSL_CTX_set_cert_verify_callback
-#define SSL_CTX_set_cert_verify_callback        SSL_CTX_set_cert_verify_cb
+#define SSL_CTX_set_cert_verify_callback	SSL_CTX_set_cert_verify_cb
 #undef SSL_CTX_set_default_passwd_cb_userdata
 #define SSL_CTX_set_default_passwd_cb_userdata  SSL_CTX_set_def_passwd_cb_ud
 #undef SSL_COMP_get_compression_methods
@@ -196,9 +192,17 @@
 #undef ENGINE_set_default_BN_mod_exp_crt
 #define ENGINE_set_default_BN_mod_exp_crt	ENGINE_set_def_BN_mod_exp_crt
 #undef ENGINE_set_load_privkey_function
-#define ENGINE_set_load_privkey_function        ENGINE_set_load_privkey_fn
+#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
+#define ENGINE_get_load_privkey_function	ENGINE_get_load_privkey_fn
+#undef ENGINE_unregister_pkey_asn1_meths
+#define ENGINE_unregister_pkey_asn1_meths	ENGINE_unreg_pkey_asn1_meths
+#undef ENGINE_register_all_pkey_asn1_meths
+#define ENGINE_register_all_pkey_asn1_meths	ENGINE_reg_all_pkey_asn1_meths
+#undef ENGINE_set_default_pkey_asn1_meths
+#define ENGINE_set_default_pkey_asn1_meths	ENGINE_set_def_pkey_asn1_meths
+#undef ENGINE_get_pkey_asn1_meth_engine
+#define ENGINE_get_pkey_asn1_meth_engine	ENGINE_get_pkey_asn1_meth_eng
 #undef ENGINE_set_load_ssl_client_cert_function
 #define ENGINE_set_load_ssl_client_cert_function \
 						ENGINE_set_ld_ssl_clnt_cert_fn
@@ -207,7 +211,7 @@
 
 /* Hack some long OCSP names */
 #undef OCSP_REQUEST_get_ext_by_critical
-#define OCSP_REQUEST_get_ext_by_critical        OCSP_REQUEST_get_ext_by_crit
+#define OCSP_REQUEST_get_ext_by_critical	OCSP_REQUEST_get_ext_by_crit
 #undef OCSP_BASICRESP_get_ext_by_critical
 #define OCSP_BASICRESP_get_ext_by_critical      OCSP_BASICRESP_get_ext_by_crit
 #undef OCSP_SINGLERESP_get_ext_by_critical
@@ -224,6 +228,8 @@
 #define OPENSSL_add_all_algorithms_noconf	OPENSSL_add_all_algo_noconf
 #undef OPENSSL_add_all_algorithms_conf
 #define OPENSSL_add_all_algorithms_conf		OPENSSL_add_all_algo_conf
+#undef EVP_PKEY_meth_set_verify_recover
+#define EVP_PKEY_meth_set_verify_recover	EVP_PKEY_meth_set_vrfy_recover
 
 /* Hack some long EC names */
 #undef EC_GROUP_set_point_conversion_form
@@ -252,15 +258,15 @@
 #define EC_POINT_set_compressed_coordinates_GF2m \
                                                 EC_POINT_set_compr_coords_GF2m
 #undef ec_GF2m_simple_group_clear_finish
-#define ec_GF2m_simple_group_clear_finish        ec_GF2m_simple_grp_clr_finish
+#define ec_GF2m_simple_group_clear_finish	ec_GF2m_simple_grp_clr_finish
 #undef ec_GF2m_simple_group_check_discriminant
 #define ec_GF2m_simple_group_check_discriminant	ec_GF2m_simple_grp_chk_discrim
 #undef ec_GF2m_simple_point_clear_finish
-#define ec_GF2m_simple_point_clear_finish        ec_GF2m_simple_pt_clr_finish
+#define ec_GF2m_simple_point_clear_finish	ec_GF2m_simple_pt_clr_finish
 #undef ec_GF2m_simple_point_set_to_infinity
-#define ec_GF2m_simple_point_set_to_infinity     ec_GF2m_simple_pt_set_to_inf
+#define ec_GF2m_simple_point_set_to_infinity	ec_GF2m_simple_pt_set_to_inf
 #undef ec_GF2m_simple_points_make_affine
-#define ec_GF2m_simple_points_make_affine        ec_GF2m_simple_pts_make_affine
+#define ec_GF2m_simple_points_make_affine	ec_GF2m_simple_pts_make_affine
 #undef ec_GF2m_simple_point_set_affine_coordinates
 #define ec_GF2m_simple_point_set_affine_coordinates \
                                                 ec_GF2m_smp_pt_set_af_coords
@@ -275,19 +281,19 @@
 #undef ec_GFp_simple_group_get_curve_GFp
 #define ec_GFp_simple_group_get_curve_GFp       ec_GFp_simple_grp_get_curve_GFp
 #undef ec_GFp_simple_group_clear_finish
-#define ec_GFp_simple_group_clear_finish        ec_GFp_simple_grp_clear_finish
+#define ec_GFp_simple_group_clear_finish	ec_GFp_simple_grp_clear_finish
 #undef ec_GFp_simple_group_set_generator
 #define ec_GFp_simple_group_set_generator       ec_GFp_simple_grp_set_generator
 #undef ec_GFp_simple_group_get0_generator
 #define ec_GFp_simple_group_get0_generator      ec_GFp_simple_grp_gt0_generator
 #undef ec_GFp_simple_group_get_cofactor
-#define ec_GFp_simple_group_get_cofactor        ec_GFp_simple_grp_get_cofactor
+#define ec_GFp_simple_group_get_cofactor	ec_GFp_simple_grp_get_cofactor
 #undef ec_GFp_simple_point_clear_finish
-#define ec_GFp_simple_point_clear_finish        ec_GFp_simple_pt_clear_finish
+#define ec_GFp_simple_point_clear_finish	ec_GFp_simple_pt_clear_finish
 #undef ec_GFp_simple_point_set_to_infinity
 #define ec_GFp_simple_point_set_to_infinity     ec_GFp_simple_pt_set_to_inf
 #undef ec_GFp_simple_points_make_affine
-#define ec_GFp_simple_points_make_affine        ec_GFp_simple_pts_make_affine
+#define ec_GFp_simple_points_make_affine	ec_GFp_simple_pts_make_affine
 #undef ec_GFp_simple_group_get_curve_GFp
 #define ec_GFp_simple_group_get_curve_GFp       ec_GFp_simple_grp_get_curve_GFp
 #undef ec_GFp_simple_set_Jprojective_coordinates_GFp
@@ -367,6 +373,14 @@
 #undef STORE_method_get_unlock_store_function
 #define STORE_method_get_unlock_store_function	STORE_meth_get_unlock_store_fn
 
+/* Hack some long TS names */
+#undef TS_RESP_CTX_set_status_info_cond
+#define TS_RESP_CTX_set_status_info_cond	TS_RESP_CTX_set_stat_info_cond
+#undef TS_RESP_CTX_set_clock_precision_digits
+#define TS_RESP_CTX_set_clock_precision_digits	TS_RESP_CTX_set_clk_prec_digits
+#undef TS_CONF_set_clock_precision_digits
+#define TS_CONF_set_clock_precision_digits	TS_CONF_set_clk_prec_digits
+
 /* Hack some long CMS names */
 #undef CMS_RecipientInfo_ktri_get0_algs
 #define CMS_RecipientInfo_ktri_get0_algs	CMS_RecipInfo_ktri_get0_algs
@@ -388,21 +402,21 @@
 #endif /* defined OPENSSL_SYS_VMS */
 
 
-/* Case insensiteve linking causes problems.... */
-#if defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2)
+/* Case insensitive linking causes problems.... */
+#if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2)
 #undef ERR_load_CRYPTO_strings
 #define ERR_load_CRYPTO_strings			ERR_load_CRYPTOlib_strings
 #undef OCSP_crlID_new
-#define OCSP_crlID_new                          OCSP_crlID2_new
+#define OCSP_crlID_new				OCSP_crlID2_new
 
 #undef d2i_ECPARAMETERS
-#define d2i_ECPARAMETERS                        d2i_UC_ECPARAMETERS
+#define d2i_ECPARAMETERS			d2i_UC_ECPARAMETERS
 #undef i2d_ECPARAMETERS
-#define i2d_ECPARAMETERS                        i2d_UC_ECPARAMETERS
+#define i2d_ECPARAMETERS			i2d_UC_ECPARAMETERS
 #undef d2i_ECPKPARAMETERS
-#define d2i_ECPKPARAMETERS                      d2i_UC_ECPKPARAMETERS
+#define d2i_ECPKPARAMETERS			d2i_UC_ECPKPARAMETERS
 #undef i2d_ECPKPARAMETERS
-#define i2d_ECPKPARAMETERS                      i2d_UC_ECPKPARAMETERS
+#define i2d_ECPKPARAMETERS			i2d_UC_ECPKPARAMETERS
 
 /* These functions do not seem to exist!  However, I'm paranoid...
    Original command in x509v3.h:
@@ -411,19 +425,19 @@
    hide them a little, by giving them an extra 'o' at the
    beginning of the name... */
 #undef X509v3_cleanup_extensions
-#define X509v3_cleanup_extensions               oX509v3_cleanup_extensions
+#define X509v3_cleanup_extensions		oX509v3_cleanup_extensions
 #undef X509v3_add_extension
-#define X509v3_add_extension                    oX509v3_add_extension
+#define X509v3_add_extension			oX509v3_add_extension
 #undef X509v3_add_netscape_extensions
-#define X509v3_add_netscape_extensions          oX509v3_add_netscape_extensions
+#define X509v3_add_netscape_extensions		oX509v3_add_netscape_extensions
 #undef X509v3_add_standard_extensions
-#define X509v3_add_standard_extensions          oX509v3_add_standard_extensions
+#define X509v3_add_standard_extensions		oX509v3_add_standard_extensions
 
+/* This one clashes with CMS_data_create */
+#undef cms_Data_create
+#define cms_Data_create				priv_cms_Data_create
 
 #endif
 
 
 #endif /* ! defined HEADER_VMS_IDHACKS_H */
-/* This one clashes with CMS_data_create */
-#undef cms_Data_create
-#define cms_Data_create				priv_cms_Data_create
diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h
index afe4807..b3cc8f0 100644
--- a/include/openssl/tls1.h
+++ b/include/openssl/tls1.h
@@ -56,6 +56,59 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
+ * Copyright (c) 1998-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
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
  *
  * Portions of the attached software ("Contribution") are developed by 
@@ -68,6 +121,32 @@
  * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
  *
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 #ifndef HEADER_TLS1_H 
 #define HEADER_TLS1_H 
@@ -104,16 +183,23 @@
 #define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114
 #define TLS1_AD_UNKNOWN_PSK_IDENTITY	115	/* fatal */
 
-/* ExtensionType values from RFC 3546 */
+/* ExtensionType values from RFC3546 / RFC4366 */
 #define TLSEXT_TYPE_server_name			0
 #define TLSEXT_TYPE_max_fragment_length		1
 #define TLSEXT_TYPE_client_certificate_url	2
 #define TLSEXT_TYPE_trusted_ca_keys		3
 #define TLSEXT_TYPE_truncated_hmac		4
 #define TLSEXT_TYPE_status_request		5
+/* ExtensionType values from RFC4492 */
 #define TLSEXT_TYPE_elliptic_curves		10
 #define TLSEXT_TYPE_ec_point_formats		11
 #define TLSEXT_TYPE_session_ticket		35
+/* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */
+#if 0 /* will have to be provided externally for now ,
+       * i.e. build with -DTLSEXT_TYPE_opaque_prf_input=38183
+       * using whatever extension number you'd like to try */
+# define TLSEXT_TYPE_opaque_prf_input		?? */
+#endif
 
 /* Temporary extension type */
 #define TLSEXT_TYPE_renegotiate                 0xff01
@@ -123,6 +209,13 @@
 /* status request value from RFC 3546 */
 #define TLSEXT_STATUSTYPE_ocsp 1
 
+/* ECPointFormat values from draft-ietf-tls-ecc-12 */
+#define TLSEXT_ECPOINTFORMAT_first			0
+#define TLSEXT_ECPOINTFORMAT_uncompressed		0
+#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime	1
+#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2	2
+#define TLSEXT_ECPOINTFORMAT_last			2
+
 #ifndef OPENSSL_NO_TLSEXT
 
 #define TLSEXT_MAXLEN_host_name 255
@@ -182,17 +275,31 @@
 #define SSL_CTX_set_tlsext_status_arg(ssl, arg) \
 SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)arg)
 
+#define SSL_set_tlsext_opaque_prf_input(s, src, len) \
+SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT, len, src)
+#define SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) \
+SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB, (void (*)(void))cb)
+#define SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) \
+SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg)
+
 #define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \
 SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
 
 #endif
 
-/* Additional TLS ciphersuites from draft-ietf-tls-56-bit-ciphersuites-00.txt
+/* PSK ciphersuites from 4279 */
+#define TLS1_CK_PSK_WITH_RC4_128_SHA                    0x0300008A
+#define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA               0x0300008B
+#define TLS1_CK_PSK_WITH_AES_128_CBC_SHA                0x0300008C
+#define TLS1_CK_PSK_WITH_AES_256_CBC_SHA                0x0300008D
+
+/* Additional TLS ciphersuites from expired Internet Draft
+ * draft-ietf-tls-56-bit-ciphersuites-01.txt
  * (available if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see
  * s3_lib.c).  We actually treat them like SSL 3.0 ciphers, which we probably
- * shouldn't. */
-#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5		0x03000060
-#define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5	0x03000061
+ * shouldn't.  Note that the first two are actually not in the IDs. */
+#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5		0x03000060 /* not in ID */
+#define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5	0x03000061 /* not in ID */
 #define TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA		0x03000062
 #define TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA	0x03000063
 #define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA		0x03000064
@@ -330,6 +437,12 @@
 #define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA         "AECDH-AES128-SHA"
 #define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA         "AECDH-AES256-SHA"
 
+/* PSK ciphersuites from RFC 4279 */
+#define TLS1_TXT_PSK_WITH_RC4_128_SHA			"PSK-RC4-SHA"
+#define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA		"PSK-3DES-EDE-CBC-SHA"
+#define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA		"PSK-AES128-CBC-SHA"
+#define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA		"PSK-AES256-CBC-SHA"
+
 /* Camellia ciphersuites from RFC4132 */
 #define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA		"CAMELLIA128-SHA"
 #define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA	"DH-DSS-CAMELLIA128-SHA"
@@ -353,6 +466,7 @@
 #define TLS1_TXT_DHE_RSA_WITH_SEED_SHA                  "DHE-RSA-SEED-SHA"
 #define TLS1_TXT_ADH_WITH_SEED_SHA                      "ADH-SEED-SHA"
 
+
 #define TLS_CT_RSA_SIGN			1
 #define TLS_CT_DSS_SIGN			2
 #define TLS_CT_RSA_FIXED_DH		3
@@ -360,7 +474,11 @@
 #define TLS_CT_ECDSA_SIGN		64
 #define TLS_CT_RSA_FIXED_ECDH		65
 #define TLS_CT_ECDSA_FIXED_ECDH 	66
-#define TLS_CT_NUMBER			7
+#define TLS_CT_GOST94_SIGN		21
+#define TLS_CT_GOST01_SIGN		22
+/* when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see
+ * comment there) */
+#define TLS_CT_NUMBER			9
 
 #define TLS1_FINISH_MAC_LENGTH		12
 
@@ -401,10 +519,14 @@
 #define TLS_MD_MASTER_SECRET_CONST    "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"  /*master secret*/
 #endif
 
+/* TLS Session Ticket extension struct */
+struct tls_session_ticket_ext_st
+	{
+	unsigned short length;
+	void *data;
+	};
+
 #ifdef  __cplusplus
 }
 #endif
 #endif
-
-
-
diff --git a/include/openssl/tmdiff.h b/include/openssl/tmdiff.h
deleted file mode 100644
index af5c41c..0000000
--- a/include/openssl/tmdiff.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* crypto/tmdiff.h */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-/* Header for dynamic hash table routines
- * Author - Eric Young
- */
-/* ... erm yeah, "dynamic hash tables" you say?
- * 
- * And what would dynamic hash tables have to do with any of this code *now*?
- * AFAICS, this code is only referenced by crypto/bn/exp.c which is an unused
- * file that I doubt compiles any more. speed.c is the only thing that could
- * use this (and it has nothing to do with hash tables), yet it instead has its
- * own duplication of all this stuff and looks, if anything, more complete. See
- * the corresponding note in apps/speed.c.
- * The Bemused - Geoff
- */
-
-#ifndef HEADER_TMDIFF_H
-#define HEADER_TMDIFF_H
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-typedef struct ms_tm MS_TM;
-
-MS_TM *ms_time_new(void );
-void ms_time_free(MS_TM *a);
-void ms_time_get(MS_TM *a);
-double ms_time_diff(MS_TM *start, MS_TM *end);
-int ms_time_cmp(const MS_TM *ap, const MS_TM *bp);
-
-#ifdef  __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/include/openssl/ts.h b/include/openssl/ts.h
new file mode 100644
index 0000000..190e8a1
--- /dev/null
+++ b/include/openssl/ts.h
@@ -0,0 +1,861 @@
+/* crypto/ts/ts.h */
+/* Written by Zoltan Glozik (zglozik@opentsa.org) for the OpenSSL
+ * project 2002, 2003, 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_TS_H
+#define HEADER_TS_H
+
+#include <openssl/opensslconf.h>
+#include <openssl/symhacks.h>
+#ifndef OPENSSL_NO_BUFFER
+#include <openssl/buffer.h>
+#endif
+#ifndef OPENSSL_NO_EVP
+#include <openssl/evp.h>
+#endif
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#include <openssl/stack.h>
+#include <openssl/asn1.h>
+#include <openssl/safestack.h>
+
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+
+#include <openssl/evp.h>
+
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef WIN32
+/* Under Win32 this is defined in wincrypt.h */
+#undef X509_NAME
+#endif
+
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+/*
+MessageImprint ::= SEQUENCE  {
+     hashAlgorithm                AlgorithmIdentifier,
+     hashedMessage                OCTET STRING  }
+*/
+
+typedef struct TS_msg_imprint_st
+	{
+	X509_ALGOR *hash_algo;
+	ASN1_OCTET_STRING *hashed_msg;
+	} TS_MSG_IMPRINT;
+
+/*
+TimeStampReq ::= SEQUENCE  {
+   version                  INTEGER  { v1(1) },
+   messageImprint           MessageImprint,
+     --a hash algorithm OID and the hash value of the data to be
+     --time-stamped
+   reqPolicy                TSAPolicyId                OPTIONAL,
+   nonce                    INTEGER                    OPTIONAL,
+   certReq                  BOOLEAN                    DEFAULT FALSE,
+   extensions               [0] IMPLICIT Extensions    OPTIONAL  }
+*/
+
+typedef struct TS_req_st
+	{
+	ASN1_INTEGER *version;
+	TS_MSG_IMPRINT *msg_imprint;
+	ASN1_OBJECT *policy_id;		/* OPTIONAL */
+	ASN1_INTEGER *nonce;		/* OPTIONAL */
+	ASN1_BOOLEAN cert_req;		/* DEFAULT FALSE */
+	STACK_OF(X509_EXTENSION) *extensions;	/* [0] OPTIONAL */
+	} TS_REQ;
+
+/*
+Accuracy ::= SEQUENCE {
+                seconds        INTEGER           OPTIONAL,
+                millis     [0] INTEGER  (1..999) OPTIONAL,
+                micros     [1] INTEGER  (1..999) OPTIONAL  }
+*/
+
+typedef struct TS_accuracy_st
+	{
+	ASN1_INTEGER *seconds;
+	ASN1_INTEGER *millis;
+	ASN1_INTEGER *micros;
+	} TS_ACCURACY;
+
+/*
+TSTInfo ::= SEQUENCE  {
+    version                      INTEGER  { v1(1) },
+    policy                       TSAPolicyId,
+    messageImprint               MessageImprint,
+      -- MUST have the same value as the similar field in
+      -- TimeStampReq
+    serialNumber                 INTEGER,
+     -- Time-Stamping users MUST be ready to accommodate integers
+     -- up to 160 bits.
+    genTime                      GeneralizedTime,
+    accuracy                     Accuracy                 OPTIONAL,
+    ordering                     BOOLEAN             DEFAULT FALSE,
+    nonce                        INTEGER                  OPTIONAL,
+      -- MUST be present if the similar field was present
+      -- in TimeStampReq.  In that case it MUST have the same value.
+    tsa                          [0] GeneralName          OPTIONAL,
+    extensions                   [1] IMPLICIT Extensions  OPTIONAL   }
+*/
+
+typedef struct TS_tst_info_st
+	{
+	ASN1_INTEGER *version;
+	ASN1_OBJECT *policy_id;
+	TS_MSG_IMPRINT *msg_imprint;
+	ASN1_INTEGER *serial;
+	ASN1_GENERALIZEDTIME *time;
+	TS_ACCURACY *accuracy;
+	ASN1_BOOLEAN ordering;
+	ASN1_INTEGER *nonce;
+	GENERAL_NAME *tsa;
+	STACK_OF(X509_EXTENSION) *extensions;
+	} TS_TST_INFO;	
+
+/*
+PKIStatusInfo ::= SEQUENCE {
+    status        PKIStatus,
+    statusString  PKIFreeText     OPTIONAL,
+    failInfo      PKIFailureInfo  OPTIONAL  }
+
+From RFC 1510 - section 3.1.1:
+PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
+	-- text encoded as UTF-8 String (note:  each UTF8String SHOULD
+	-- include an RFC 1766 language tag to indicate the language
+	-- of the contained text)
+*/
+
+/* Possible values for status. See ts_resp_print.c && ts_resp_verify.c. */
+
+#define	TS_STATUS_GRANTED			0
+#define	TS_STATUS_GRANTED_WITH_MODS		1
+#define	TS_STATUS_REJECTION			2
+#define	TS_STATUS_WAITING			3
+#define	TS_STATUS_REVOCATION_WARNING		4
+#define	TS_STATUS_REVOCATION_NOTIFICATION	5
+
+/* Possible values for failure_info. See ts_resp_print.c && ts_resp_verify.c */
+
+#define	TS_INFO_BAD_ALG			0
+#define	TS_INFO_BAD_REQUEST		2
+#define	TS_INFO_BAD_DATA_FORMAT		5
+#define	TS_INFO_TIME_NOT_AVAILABLE	14
+#define	TS_INFO_UNACCEPTED_POLICY	15
+#define	TS_INFO_UNACCEPTED_EXTENSION	16
+#define	TS_INFO_ADD_INFO_NOT_AVAILABLE	17
+#define	TS_INFO_SYSTEM_FAILURE		25
+
+typedef struct TS_status_info_st
+	{
+	ASN1_INTEGER *status;
+	STACK_OF(ASN1_UTF8STRING) *text;
+	ASN1_BIT_STRING *failure_info;
+	} TS_STATUS_INFO;
+
+DECLARE_STACK_OF(ASN1_UTF8STRING)
+DECLARE_ASN1_SET_OF(ASN1_UTF8STRING)
+
+/*
+TimeStampResp ::= SEQUENCE  {
+     status                  PKIStatusInfo,
+     timeStampToken          TimeStampToken     OPTIONAL }
+*/
+
+typedef struct TS_resp_st
+	{
+	TS_STATUS_INFO *status_info;
+	PKCS7 *token;
+	TS_TST_INFO *tst_info;
+	} TS_RESP;
+
+/* The structure below would belong to the ESS component. */
+
+/*
+IssuerSerial ::= SEQUENCE {
+	issuer                   GeneralNames,
+	serialNumber             CertificateSerialNumber
+	}
+*/
+
+typedef struct ESS_issuer_serial
+	{
+	STACK_OF(GENERAL_NAME)	*issuer;
+	ASN1_INTEGER		*serial;
+	} ESS_ISSUER_SERIAL;
+
+/*
+ESSCertID ::=  SEQUENCE {
+        certHash                 Hash,
+        issuerSerial             IssuerSerial OPTIONAL
+}
+*/
+
+typedef struct ESS_cert_id
+	{
+	ASN1_OCTET_STRING *hash;	/* Always SHA-1 digest. */
+	ESS_ISSUER_SERIAL *issuer_serial;
+	} ESS_CERT_ID;
+
+DECLARE_STACK_OF(ESS_CERT_ID)
+DECLARE_ASN1_SET_OF(ESS_CERT_ID)
+
+/*
+SigningCertificate ::=  SEQUENCE {
+       certs        SEQUENCE OF ESSCertID,
+       policies     SEQUENCE OF PolicyInformation OPTIONAL
+}
+*/
+
+typedef struct ESS_signing_cert
+	{
+	STACK_OF(ESS_CERT_ID) *cert_ids;
+	STACK_OF(POLICYINFO) *policy_info;
+	} ESS_SIGNING_CERT;
+
+
+TS_REQ	*TS_REQ_new(void);
+void	TS_REQ_free(TS_REQ *a);
+int	i2d_TS_REQ(const TS_REQ *a, unsigned char **pp);
+TS_REQ	*d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length);
+
+TS_REQ	*TS_REQ_dup(TS_REQ *a);
+
+TS_REQ	*d2i_TS_REQ_fp(FILE *fp, TS_REQ **a);
+int	i2d_TS_REQ_fp(FILE *fp, TS_REQ *a);
+TS_REQ	*d2i_TS_REQ_bio(BIO *fp, TS_REQ **a);
+int	i2d_TS_REQ_bio(BIO *fp, TS_REQ *a);
+
+TS_MSG_IMPRINT	*TS_MSG_IMPRINT_new(void);
+void		TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a);
+int		i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp);
+TS_MSG_IMPRINT	*d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a,
+				    const unsigned char **pp, long length);
+
+TS_MSG_IMPRINT	*TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a);
+
+TS_MSG_IMPRINT	*d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a);
+int		i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a);
+TS_MSG_IMPRINT	*d2i_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT **a);
+int		i2d_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT *a);
+
+TS_RESP	*TS_RESP_new(void);
+void	TS_RESP_free(TS_RESP *a);
+int	i2d_TS_RESP(const TS_RESP *a, unsigned char **pp);
+TS_RESP	*d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length);
+TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token);
+TS_RESP	*TS_RESP_dup(TS_RESP *a);
+
+TS_RESP	*d2i_TS_RESP_fp(FILE *fp, TS_RESP **a);
+int	i2d_TS_RESP_fp(FILE *fp, TS_RESP *a);
+TS_RESP	*d2i_TS_RESP_bio(BIO *fp, TS_RESP **a);
+int	i2d_TS_RESP_bio(BIO *fp, TS_RESP *a);
+
+TS_STATUS_INFO	*TS_STATUS_INFO_new(void);
+void		TS_STATUS_INFO_free(TS_STATUS_INFO *a);
+int		i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp);
+TS_STATUS_INFO	*d2i_TS_STATUS_INFO(TS_STATUS_INFO **a, 
+				    const unsigned char **pp, long length);
+TS_STATUS_INFO	*TS_STATUS_INFO_dup(TS_STATUS_INFO *a);
+
+TS_TST_INFO	*TS_TST_INFO_new(void);
+void		TS_TST_INFO_free(TS_TST_INFO *a);
+int		i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp);
+TS_TST_INFO	*d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp,
+				    long length);
+TS_TST_INFO	*TS_TST_INFO_dup(TS_TST_INFO *a);
+
+TS_TST_INFO	*d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a);
+int		i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a);
+TS_TST_INFO	*d2i_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO **a);
+int		i2d_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO *a);
+
+TS_ACCURACY	*TS_ACCURACY_new(void);
+void		TS_ACCURACY_free(TS_ACCURACY *a);
+int		i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp);
+TS_ACCURACY	*d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp,
+				    long length);
+TS_ACCURACY	*TS_ACCURACY_dup(TS_ACCURACY *a);
+
+ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void);
+void		  ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a);
+int		  i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a,
+					unsigned char **pp);
+ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a,
+					 const unsigned char **pp, long length);
+ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a);
+
+ESS_CERT_ID	*ESS_CERT_ID_new(void);
+void		ESS_CERT_ID_free(ESS_CERT_ID *a);
+int		i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp);
+ESS_CERT_ID	*d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp,
+				 long length);
+ESS_CERT_ID	*ESS_CERT_ID_dup(ESS_CERT_ID *a);
+
+ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void);
+void		 ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a);
+int		 i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, 
+				      unsigned char **pp);
+ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a,
+				       const unsigned char **pp, long length);
+ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a);
+
+void ERR_load_TS_strings(void);
+
+int TS_REQ_set_version(TS_REQ *a, long version);
+long TS_REQ_get_version(const TS_REQ *a);
+
+int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint);
+TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a);
+
+int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg);
+X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a);
+
+int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len);
+ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a);
+
+int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy);
+ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a);
+
+int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce);
+const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a);
+
+int TS_REQ_set_cert_req(TS_REQ *a, int cert_req);
+int TS_REQ_get_cert_req(const TS_REQ *a);
+
+STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a);
+void TS_REQ_ext_free(TS_REQ *a);
+int TS_REQ_get_ext_count(TS_REQ *a);
+int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos);
+int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos);
+int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos);
+X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc);
+X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc);
+int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc);
+void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx);
+
+/* Function declarations for TS_REQ defined in ts/ts_req_print.c */
+
+int TS_REQ_print_bio(BIO *bio, TS_REQ *a);
+
+/* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */
+
+int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info);
+TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a);
+
+/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */
+void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info);
+PKCS7 *TS_RESP_get_token(TS_RESP *a);
+TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a);
+
+int TS_TST_INFO_set_version(TS_TST_INFO *a, long version);
+long TS_TST_INFO_get_version(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id);
+ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a);
+
+int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint);
+TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a);
+
+int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial);
+const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime);
+const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy);
+TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a);
+
+int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds);
+const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a);
+
+int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis);
+const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a);
+
+int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros);
+const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a);
+
+int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering);
+int TS_TST_INFO_get_ordering(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce);
+const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa);
+GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a);
+
+STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a);
+void TS_TST_INFO_ext_free(TS_TST_INFO *a);
+int TS_TST_INFO_get_ext_count(TS_TST_INFO *a);
+int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos);
+int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos);
+int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos);
+X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc);
+X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc);
+int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc);
+void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx);
+
+/* Declarations related to response generation, defined in ts/ts_resp_sign.c. */
+
+/* Optional flags for response generation. */
+
+/* Don't include the TSA name in response. */
+#define	TS_TSA_NAME		0x01
+
+/* Set ordering to true in response. */
+#define	TS_ORDERING		0x02
+
+/*
+ * Include the signer certificate and the other specified certificates in
+ * the ESS signing certificate attribute beside the PKCS7 signed data.
+ * Only the signer certificates is included by default.
+ */
+#define	TS_ESS_CERT_ID_CHAIN	0x04
+
+/* Forward declaration. */
+struct TS_resp_ctx;
+
+/* This must return a unique number less than 160 bits long. */
+typedef ASN1_INTEGER *(*TS_serial_cb)(struct TS_resp_ctx *, void *);
+
+/* This must return the seconds and microseconds since Jan 1, 1970 in
+   the sec and usec variables allocated by the caller. 
+   Return non-zero for success and zero for failure. */
+typedef	int (*TS_time_cb)(struct TS_resp_ctx *, void *, long *sec, long *usec);
+
+/* This must process the given extension.
+ * It can modify the TS_TST_INFO object of the context.
+ * Return values: !0 (processed), 0 (error, it must set the 
+ * status info/failure info of the response).
+ */
+typedef	int (*TS_extension_cb)(struct TS_resp_ctx *, X509_EXTENSION *, void *);
+
+typedef struct TS_resp_ctx
+	{
+	X509		*signer_cert;
+	EVP_PKEY	*signer_key;
+	STACK_OF(X509)	*certs;	/* Certs to include in signed data. */
+	STACK_OF(ASN1_OBJECT)	*policies;	/* Acceptable policies. */
+	ASN1_OBJECT	*default_policy; /* It may appear in policies, too. */
+	STACK_OF(EVP_MD)	*mds;	/* Acceptable message digests. */
+	ASN1_INTEGER	*seconds;	/* accuracy, 0 means not specified. */
+	ASN1_INTEGER	*millis;	/* accuracy, 0 means not specified. */
+	ASN1_INTEGER	*micros;	/* accuracy, 0 means not specified. */
+	unsigned	clock_precision_digits; /* fraction of seconds in
+						   time stamp token. */
+	unsigned	flags;		/* Optional info, see values above. */
+
+	/* Callback functions. */
+	TS_serial_cb serial_cb;
+	void *serial_cb_data;	/* User data for serial_cb. */
+	
+	TS_time_cb time_cb;
+	void *time_cb_data;	/* User data for time_cb. */
+	
+	TS_extension_cb extension_cb;
+	void *extension_cb_data;	/* User data for extension_cb. */
+
+	/* These members are used only while creating the response. */
+	TS_REQ		*request;
+	TS_RESP		*response;
+	TS_TST_INFO	*tst_info;
+	} TS_RESP_CTX;
+
+DECLARE_STACK_OF(EVP_MD)
+DECLARE_ASN1_SET_OF(EVP_MD)
+
+/* Creates a response context that can be used for generating responses. */
+TS_RESP_CTX *TS_RESP_CTX_new(void);
+void TS_RESP_CTX_free(TS_RESP_CTX *ctx);
+
+/* This parameter must be set. */
+int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer);
+
+/* This parameter must be set. */
+int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key);
+
+/* This parameter must be set. */
+int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy);
+
+/* No additional certs are included in the response by default. */
+int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs);
+
+/* Adds a new acceptable policy, only the default policy 
+   is accepted by default. */
+int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy);
+
+/* Adds a new acceptable message digest. Note that no message digests 
+   are accepted by default. The md argument is shared with the caller. */
+int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md);
+
+/* Accuracy is not included by default. */
+int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx,
+			     int secs, int millis, int micros);
+
+/* Clock precision digits, i.e. the number of decimal digits: 
+   '0' means sec, '3' msec, '6' usec, and so on. Default is 0. */ 
+int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx,
+					   unsigned clock_precision_digits);
+/* At most we accept usec precision. */	
+#define TS_MAX_CLOCK_PRECISION_DIGITS	6
+
+/* No flags are set by default. */
+void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags);
+
+/* Default callback always returns a constant. */
+void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data);
+
+/* Default callback uses the gettimeofday() and gmtime() system calls. */
+void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data);
+
+/* Default callback rejects all extensions. The extension callback is called 
+ * when the TS_TST_INFO object is already set up and not signed yet. */
+/* FIXME: extension handling is not tested yet. */
+void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, 
+				  TS_extension_cb cb, void *data);
+
+/* The following methods can be used in the callbacks. */
+int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, 
+				int status, const char *text);
+
+/* Sets the status info only if it is still TS_STATUS_GRANTED. */
+int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, 
+				     int status, const char *text);
+
+int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure);
+
+/* The get methods below can be used in the extension callback. */
+TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx);
+
+TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx);
+
+/* 
+ * Creates the signed TS_TST_INFO and puts it in TS_RESP.
+ * In case of errors it sets the status info properly.
+ * Returns NULL only in case of memory allocation/fatal error.
+ */
+TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio);
+
+/*
+ * Declarations related to response verification,
+ * they are defined in ts/ts_resp_verify.c.
+ */
+
+int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
+			     X509_STORE *store, X509 **signer_out);
+
+/* Context structure for the generic verify method. */
+
+/* Verify the signer's certificate and the signature of the response. */
+#define	TS_VFY_SIGNATURE	(1u << 0)
+/* Verify the version number of the response. */
+#define	TS_VFY_VERSION		(1u << 1)
+/* Verify if the policy supplied by the user matches the policy of the TSA. */
+#define	TS_VFY_POLICY		(1u << 2)
+/* Verify the message imprint provided by the user. This flag should not be
+   specified with TS_VFY_DATA. */
+#define	TS_VFY_IMPRINT		(1u << 3)
+/* Verify the message imprint computed by the verify method from the user
+   provided data and the MD algorithm of the response. This flag should not be
+   specified with TS_VFY_IMPRINT. */
+#define	TS_VFY_DATA		(1u << 4)
+/* Verify the nonce value. */
+#define	TS_VFY_NONCE		(1u << 5)
+/* Verify if the TSA name field matches the signer certificate. */
+#define	TS_VFY_SIGNER		(1u << 6)
+/* Verify if the TSA name field equals to the user provided name. */
+#define	TS_VFY_TSA_NAME		(1u << 7)
+
+/* You can use the following convenience constants. */
+#define	TS_VFY_ALL_IMPRINT	(TS_VFY_SIGNATURE	\
+				 | TS_VFY_VERSION	\
+				 | TS_VFY_POLICY	\
+				 | TS_VFY_IMPRINT	\
+				 | TS_VFY_NONCE		\
+				 | TS_VFY_SIGNER	\
+				 | TS_VFY_TSA_NAME)
+#define	TS_VFY_ALL_DATA		(TS_VFY_SIGNATURE	\
+				 | TS_VFY_VERSION	\
+				 | TS_VFY_POLICY	\
+				 | TS_VFY_DATA		\
+				 | TS_VFY_NONCE		\
+				 | TS_VFY_SIGNER	\
+				 | TS_VFY_TSA_NAME)
+
+typedef struct TS_verify_ctx
+	{
+	/* Set this to the union of TS_VFY_... flags you want to carry out. */
+	unsigned	flags;
+
+	/* Must be set only with TS_VFY_SIGNATURE. certs is optional. */
+	X509_STORE	*store;
+	STACK_OF(X509)	*certs;
+
+	/* Must be set only with TS_VFY_POLICY. */
+	ASN1_OBJECT	*policy;
+
+	/* Must be set only with TS_VFY_IMPRINT. If md_alg is NULL, 
+	   the algorithm from the response is used. */
+	X509_ALGOR	*md_alg;
+	unsigned char	*imprint;
+	unsigned	imprint_len;
+
+	/* Must be set only with TS_VFY_DATA. */
+	BIO		*data;
+
+	/* Must be set only with TS_VFY_TSA_NAME. */
+	ASN1_INTEGER	*nonce;
+
+	/* Must be set only with TS_VFY_TSA_NAME. */
+	GENERAL_NAME	*tsa_name;
+	} TS_VERIFY_CTX;
+
+int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response);
+int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token);
+
+/*
+ * Declarations related to response verification context,
+ * they are defined in ts/ts_verify_ctx.c.
+ */
+
+/* Set all fields to zero. */
+TS_VERIFY_CTX *TS_VERIFY_CTX_new(void);
+void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx);
+void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx);
+void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx);
+
+/* 
+ * If ctx is NULL, it allocates and returns a new object, otherwise
+ * it returns ctx. It initialises all the members as follows:
+ * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE)
+ * certs = NULL
+ * store = NULL
+ * policy = policy from the request or NULL if absent (in this case
+ *	TS_VFY_POLICY is cleared from flags as well)
+ * md_alg = MD algorithm from request
+ * imprint, imprint_len = imprint from request
+ * data = NULL
+ * nonce, nonce_len = nonce from the request or NULL if absent (in this case
+ * 	TS_VFY_NONCE is cleared from flags as well)
+ * tsa_name = NULL
+ * Important: after calling this method TS_VFY_SIGNATURE should be added!
+ */
+TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx);
+
+/* Function declarations for TS_RESP defined in ts/ts_resp_print.c */
+
+int TS_RESP_print_bio(BIO *bio, TS_RESP *a);
+int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a);
+int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a);
+
+/* Common utility functions defined in ts/ts_lib.c */
+
+int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num);
+int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj);
+int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions);
+int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg);
+int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg);
+
+/* Function declarations for handling configuration options,
+   defined in ts/ts_conf.c */
+
+X509 *TS_CONF_load_cert(const char *file);
+STACK_OF(X509) *TS_CONF_load_certs(const char *file);
+EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass);
+const char *TS_CONF_get_tsa_section(CONF *conf, const char *section);
+int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb,
+		       TS_RESP_CTX *ctx);
+int TS_CONF_set_crypto_device(CONF *conf, const char *section,
+			      const char *device);
+int TS_CONF_set_default_engine(const char *name);
+int TS_CONF_set_signer_cert(CONF *conf, const char *section,
+			    const char *cert, TS_RESP_CTX *ctx);
+int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs,
+		      TS_RESP_CTX *ctx);
+int TS_CONF_set_signer_key(CONF *conf, const char *section,
+			   const char *key, const char *pass, TS_RESP_CTX *ctx);
+int TS_CONF_set_def_policy(CONF *conf, const char *section,
+			   const char *policy, TS_RESP_CTX *ctx);
+int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section,
+				       TS_RESP_CTX *ctx);
+int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
+				  TS_RESP_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_TS_strings(void);
+
+/* Error codes for the TS functions. */
+
+/* Function codes. */
+#define TS_F_D2I_TS_RESP				 147
+#define TS_F_DEF_SERIAL_CB				 110
+#define TS_F_DEF_TIME_CB				 111
+#define TS_F_ESS_ADD_SIGNING_CERT			 112
+#define TS_F_ESS_CERT_ID_NEW_INIT			 113
+#define TS_F_ESS_SIGNING_CERT_NEW_INIT			 114
+#define TS_F_INT_TS_RESP_VERIFY_TOKEN			 149
+#define TS_F_PKCS7_TO_TS_TST_INFO			 148
+#define TS_F_TS_ACCURACY_SET_MICROS			 115
+#define TS_F_TS_ACCURACY_SET_MILLIS			 116
+#define TS_F_TS_ACCURACY_SET_SECONDS			 117
+#define TS_F_TS_CHECK_IMPRINTS				 100
+#define TS_F_TS_CHECK_NONCES				 101
+#define TS_F_TS_CHECK_POLICY				 102
+#define TS_F_TS_CHECK_SIGNING_CERTS			 103
+#define TS_F_TS_CHECK_STATUS_INFO			 104
+#define TS_F_TS_COMPUTE_IMPRINT				 145
+#define TS_F_TS_CONF_SET_DEFAULT_ENGINE			 146
+#define TS_F_TS_GET_STATUS_TEXT				 105
+#define TS_F_TS_MSG_IMPRINT_SET_ALGO			 118
+#define TS_F_TS_REQ_SET_MSG_IMPRINT			 119
+#define TS_F_TS_REQ_SET_NONCE				 120
+#define TS_F_TS_REQ_SET_POLICY_ID			 121
+#define TS_F_TS_RESP_CREATE_RESPONSE			 122
+#define TS_F_TS_RESP_CREATE_TST_INFO			 123
+#define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO		 124
+#define TS_F_TS_RESP_CTX_ADD_MD				 125
+#define TS_F_TS_RESP_CTX_ADD_POLICY			 126
+#define TS_F_TS_RESP_CTX_NEW				 127
+#define TS_F_TS_RESP_CTX_SET_ACCURACY			 128
+#define TS_F_TS_RESP_CTX_SET_CERTS			 129
+#define TS_F_TS_RESP_CTX_SET_DEF_POLICY			 130
+#define TS_F_TS_RESP_CTX_SET_SIGNER_CERT		 131
+#define TS_F_TS_RESP_CTX_SET_STATUS_INFO		 132
+#define TS_F_TS_RESP_GET_POLICY				 133
+#define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION		 134
+#define TS_F_TS_RESP_SET_STATUS_INFO			 135
+#define TS_F_TS_RESP_SET_TST_INFO			 150
+#define TS_F_TS_RESP_SIGN				 136
+#define TS_F_TS_RESP_VERIFY_SIGNATURE			 106
+#define TS_F_TS_RESP_VERIFY_TOKEN			 107
+#define TS_F_TS_TST_INFO_SET_ACCURACY			 137
+#define TS_F_TS_TST_INFO_SET_MSG_IMPRINT		 138
+#define TS_F_TS_TST_INFO_SET_NONCE			 139
+#define TS_F_TS_TST_INFO_SET_POLICY_ID			 140
+#define TS_F_TS_TST_INFO_SET_SERIAL			 141
+#define TS_F_TS_TST_INFO_SET_TIME			 142
+#define TS_F_TS_TST_INFO_SET_TSA			 143
+#define TS_F_TS_VERIFY					 108
+#define TS_F_TS_VERIFY_CERT				 109
+#define TS_F_TS_VERIFY_CTX_NEW				 144
+
+/* Reason codes. */
+#define TS_R_BAD_PKCS7_TYPE				 132
+#define TS_R_BAD_TYPE					 133
+#define TS_R_CERTIFICATE_VERIFY_ERROR			 100
+#define TS_R_COULD_NOT_SET_ENGINE			 127
+#define TS_R_COULD_NOT_SET_TIME				 115
+#define TS_R_D2I_TS_RESP_INT_FAILED			 128
+#define TS_R_DETACHED_CONTENT				 134
+#define TS_R_ESS_ADD_SIGNING_CERT_ERROR			 116
+#define TS_R_ESS_SIGNING_CERTIFICATE_ERROR		 101
+#define TS_R_INVALID_NULL_POINTER			 102
+#define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE		 117
+#define TS_R_MESSAGE_IMPRINT_MISMATCH			 103
+#define TS_R_NONCE_MISMATCH				 104
+#define TS_R_NONCE_NOT_RETURNED				 105
+#define TS_R_NO_CONTENT					 106
+#define TS_R_NO_TIME_STAMP_TOKEN			 107
+#define TS_R_PKCS7_ADD_SIGNATURE_ERROR			 118
+#define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR		 119
+#define TS_R_PKCS7_TO_TS_TST_INFO_FAILED		 129
+#define TS_R_POLICY_MISMATCH				 108
+#define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 120
+#define TS_R_RESPONSE_SETUP_ERROR			 121
+#define TS_R_SIGNATURE_FAILURE				 109
+#define TS_R_THERE_MUST_BE_ONE_SIGNER			 110
+#define TS_R_TIME_SYSCALL_ERROR				 122
+#define TS_R_TOKEN_NOT_PRESENT				 130
+#define TS_R_TOKEN_PRESENT				 131
+#define TS_R_TSA_NAME_MISMATCH				 111
+#define TS_R_TSA_UNTRUSTED				 112
+#define TS_R_TST_INFO_SETUP_ERROR			 123
+#define TS_R_TS_DATASIGN				 124
+#define TS_R_UNACCEPTABLE_POLICY			 125
+#define TS_R_UNSUPPORTED_MD_ALGORITHM			 126
+#define TS_R_UNSUPPORTED_VERSION			 113
+#define TS_R_WRONG_CONTENT_TYPE				 114
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/include/openssl/txt_db.h b/include/openssl/txt_db.h
index 307e1ba..6abe435 100644
--- a/include/openssl/txt_db.h
+++ b/include/openssl/txt_db.h
@@ -77,16 +77,19 @@
 extern "C" {
 #endif
 
+typedef OPENSSL_STRING *OPENSSL_PSTRING;
+DECLARE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING)
+
 typedef struct txt_db_st
 	{
 	int num_fields;
-	STACK /* char ** */ *data;
-	LHASH **index;
-	int (**qual)(char **);
+	STACK_OF(OPENSSL_PSTRING) *data;
+	LHASH_OF(OPENSSL_STRING) **index;
+	int (**qual)(OPENSSL_STRING *);
 	long error;
 	long arg1;
 	long arg2;
-	char **arg_row;
+	OPENSSL_STRING *arg_row;
 	} TXT_DB;
 
 #ifndef OPENSSL_NO_BIO
@@ -96,11 +99,11 @@
 TXT_DB *TXT_DB_read(char *in, int num);
 long TXT_DB_write(char *out, TXT_DB *db);
 #endif
-int TXT_DB_create_index(TXT_DB *db,int field,int (*qual)(char **),
-		LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp);
+int TXT_DB_create_index(TXT_DB *db,int field,int (*qual)(OPENSSL_STRING *),
+			LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp);
 void TXT_DB_free(TXT_DB *db);
-char **TXT_DB_get_by_index(TXT_DB *db, int idx, char **value);
-int TXT_DB_insert(TXT_DB *db,char **value);
+OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, OPENSSL_STRING *value);
+int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value);
 
 #ifdef  __cplusplus
 }
diff --git a/include/openssl/ui.h b/include/openssl/ui.h
index 0182964..2b1cfa2 100644
--- a/include/openssl/ui.h
+++ b/include/openssl/ui.h
@@ -287,8 +287,8 @@
 /* The UI_STRING type is the data structure that contains all the needed info
    about a string or a prompt, including test data for a verification prompt.
 */
-DECLARE_STACK_OF(UI_STRING)
 typedef struct ui_string_st UI_STRING;
+DECLARE_STACK_OF(UI_STRING)
 
 /* The different types of strings that are currently supported.
    This is only needed by method authors. */
@@ -310,11 +310,13 @@
 int UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui));
 int UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis));
 int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui));
+int UI_method_set_prompt_constructor(UI_METHOD *method, char *(*prompt_constructor)(UI* ui, const char* object_desc, const char* object_name));
 int (*UI_method_get_opener(UI_METHOD *method))(UI*);
 int (*UI_method_get_writer(UI_METHOD *method))(UI*,UI_STRING*);
 int (*UI_method_get_flusher(UI_METHOD *method))(UI*);
 int (*UI_method_get_reader(UI_METHOD *method))(UI*,UI_STRING*);
 int (*UI_method_get_closer(UI_METHOD *method))(UI*);
+char* (*UI_method_get_prompt_constructor(UI_METHOD *method))(UI*, const char*, const char*);
 
 /* The following functions are helpers for method writers to access relevant
    data from a UI_STRING. */
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index 8958e34..604f4fb 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -157,12 +157,12 @@
 	ASN1_TIME *notAfter;
 	} X509_VAL;
 
-typedef struct X509_pubkey_st
+struct X509_pubkey_st
 	{
 	X509_ALGOR *algor;
 	ASN1_BIT_STRING *public_key;
 	EVP_PKEY *pkey;
-	} X509_PUBKEY;
+	};
 
 typedef struct X509_sig_st
 	{
@@ -191,7 +191,9 @@
 #else
 	char *bytes;
 #endif
-	unsigned long hash; /* Keep the hash around for lookups */
+/*	unsigned long hash; Keep the hash around for lookups */
+	unsigned char *canon_enc;
+	int canon_enclen;
 	} /* X509_NAME */;
 
 DECLARE_STACK_OF(X509_NAME)
@@ -290,8 +292,11 @@
 	unsigned long ex_xkusage;
 	unsigned long ex_nscert;
 	ASN1_OCTET_STRING *skid;
-	struct AUTHORITY_KEYID_st *akid;
+	AUTHORITY_KEYID *akid;
 	X509_POLICY_CACHE *policy_cache;
+	STACK_OF(DIST_POINT) *crldp;
+	STACK_OF(GENERAL_NAME) *altname;
+	NAME_CONSTRAINTS *nc;
 #ifndef OPENSSL_NO_RFC3779
 	STACK_OF(IPAddressFamily) *rfc3779_addr;
 	struct ASIdentifiers_st *rfc3779_asid;
@@ -334,10 +339,11 @@
 #define X509_TRUST_OBJECT_SIGN	5
 #define X509_TRUST_OCSP_SIGN	6
 #define X509_TRUST_OCSP_REQUEST	7
+#define X509_TRUST_TSA		8
 
 /* Keep these up to date! */
 #define X509_TRUST_MIN		1
-#define X509_TRUST_MAX		7
+#define X509_TRUST_MAX		8
 
 
 /* trust_flags values */
@@ -424,13 +430,17 @@
 			XN_FLAG_FN_LN | \
 			XN_FLAG_FN_ALIGN)
 
-typedef struct X509_revoked_st
+struct x509_revoked_st
 	{
 	ASN1_INTEGER *serialNumber;
 	ASN1_TIME *revocationDate;
 	STACK_OF(X509_EXTENSION) /* optional */ *extensions;
+	/* Set up if indirect CRL */
+	STACK_OF(GENERAL_NAME) *issuer;
+	/* Revocation reason */
+	int reason;
 	int sequence; /* load sequence */
-	} X509_REVOKED;
+	};
 
 DECLARE_STACK_OF(X509_REVOKED)
 DECLARE_ASN1_SET_OF(X509_REVOKED)
@@ -454,6 +464,22 @@
 	X509_ALGOR *sig_alg;
 	ASN1_BIT_STRING *signature;
 	int references;
+	int flags;
+	/* Copies of various extensions */
+	AUTHORITY_KEYID *akid;
+	ISSUING_DIST_POINT *idp;
+	/* Convenient breakdown of IDP */
+	int idp_flags;
+	int idp_reasons;
+	/* CRL and base CRL numbers for delta processing */
+	ASN1_INTEGER *crl_number;
+	ASN1_INTEGER *base_crl_number;
+#ifndef OPENSSL_NO_SHA
+	unsigned char sha1_hash[SHA_DIGEST_LENGTH];
+#endif
+	STACK_OF(GENERAL_NAMES) *issuers;
+	const X509_CRL_METHOD *meth;
+	void *meth_data;
 	} /* X509_CRL */;
 
 DECLARE_STACK_OF(X509_CRL)
@@ -552,18 +578,19 @@
 
 /* PKCS#8 private key info structure */
 
-typedef struct pkcs8_priv_key_info_st
+struct pkcs8_priv_key_info_st
         {
         int broken;     /* Flag for various broken formats */
 #define PKCS8_OK		0
 #define PKCS8_NO_OCTET		1
 #define PKCS8_EMBEDDED_PARAM	2
 #define PKCS8_NS_DB		3
+#define PKCS8_NEG_PRIVKEY	4
         ASN1_INTEGER *version;
         X509_ALGOR *pkeyalg;
         ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */
         STACK_OF(X509_ATTRIBUTE) *attributes;
-        } PKCS8_PRIV_KEY_INFO;
+        };
 
 #ifdef  __cplusplus
 }
@@ -576,151 +603,6 @@
 extern "C" {
 #endif
 
-#ifdef SSLEAY_MACROS
-#define X509_verify(a,r) ASN1_verify((int (*)())i2d_X509_CINF,a->sig_alg,\
-	a->signature,(char *)a->cert_info,r)
-#define X509_REQ_verify(a,r) ASN1_verify((int (*)())i2d_X509_REQ_INFO, \
-	a->sig_alg,a->signature,(char *)a->req_info,r)
-#define X509_CRL_verify(a,r) ASN1_verify((int (*)())i2d_X509_CRL_INFO, \
-	a->sig_alg, a->signature,(char *)a->crl,r)
-
-#define X509_sign(x,pkey,md) \
-	ASN1_sign((int (*)())i2d_X509_CINF, x->cert_info->signature, \
-		x->sig_alg, x->signature, (char *)x->cert_info,pkey,md)
-#define X509_REQ_sign(x,pkey,md) \
-	ASN1_sign((int (*)())i2d_X509_REQ_INFO,x->sig_alg, NULL, \
-		x->signature, (char *)x->req_info,pkey,md)
-#define X509_CRL_sign(x,pkey,md) \
-	ASN1_sign((int (*)())i2d_X509_CRL_INFO,x->crl->sig_alg,x->sig_alg, \
-		x->signature, (char *)x->crl,pkey,md)
-#define NETSCAPE_SPKI_sign(x,pkey,md) \
-	ASN1_sign((int (*)())i2d_NETSCAPE_SPKAC, x->sig_algor,NULL, \
-		x->signature, (char *)x->spkac,pkey,md)
-
-#define X509_dup(x509) (X509 *)ASN1_dup((int (*)())i2d_X509, \
-		(char *(*)())d2i_X509,(char *)x509)
-#define X509_ATTRIBUTE_dup(xa) (X509_ATTRIBUTE *)ASN1_dup(\
-		(int (*)())i2d_X509_ATTRIBUTE, \
-		(char *(*)())d2i_X509_ATTRIBUTE,(char *)xa)
-#define X509_EXTENSION_dup(ex) (X509_EXTENSION *)ASN1_dup( \
-		(int (*)())i2d_X509_EXTENSION, \
-		(char *(*)())d2i_X509_EXTENSION,(char *)ex)
-#define d2i_X509_fp(fp,x509) (X509 *)ASN1_d2i_fp((char *(*)())X509_new, \
-		(char *(*)())d2i_X509, (fp),(unsigned char **)(x509))
-#define i2d_X509_fp(fp,x509) ASN1_i2d_fp(i2d_X509,fp,(unsigned char *)x509)
-#define d2i_X509_bio(bp,x509) (X509 *)ASN1_d2i_bio((char *(*)())X509_new, \
-		(char *(*)())d2i_X509, (bp),(unsigned char **)(x509))
-#define i2d_X509_bio(bp,x509) ASN1_i2d_bio(i2d_X509,bp,(unsigned char *)x509)
-
-#define X509_CRL_dup(crl) (X509_CRL *)ASN1_dup((int (*)())i2d_X509_CRL, \
-		(char *(*)())d2i_X509_CRL,(char *)crl)
-#define d2i_X509_CRL_fp(fp,crl) (X509_CRL *)ASN1_d2i_fp((char *(*)()) \
-		X509_CRL_new,(char *(*)())d2i_X509_CRL, (fp),\
-		(unsigned char **)(crl))
-#define i2d_X509_CRL_fp(fp,crl) ASN1_i2d_fp(i2d_X509_CRL,fp,\
-		(unsigned char *)crl)
-#define d2i_X509_CRL_bio(bp,crl) (X509_CRL *)ASN1_d2i_bio((char *(*)()) \
-		X509_CRL_new,(char *(*)())d2i_X509_CRL, (bp),\
-		(unsigned char **)(crl))
-#define i2d_X509_CRL_bio(bp,crl) ASN1_i2d_bio(i2d_X509_CRL,bp,\
-		(unsigned char *)crl)
-
-#define PKCS7_dup(p7) (PKCS7 *)ASN1_dup((int (*)())i2d_PKCS7, \
-		(char *(*)())d2i_PKCS7,(char *)p7)
-#define d2i_PKCS7_fp(fp,p7) (PKCS7 *)ASN1_d2i_fp((char *(*)()) \
-		PKCS7_new,(char *(*)())d2i_PKCS7, (fp),\
-		(unsigned char **)(p7))
-#define i2d_PKCS7_fp(fp,p7) ASN1_i2d_fp(i2d_PKCS7,fp,\
-		(unsigned char *)p7)
-#define d2i_PKCS7_bio(bp,p7) (PKCS7 *)ASN1_d2i_bio((char *(*)()) \
-		PKCS7_new,(char *(*)())d2i_PKCS7, (bp),\
-		(unsigned char **)(p7))
-#define i2d_PKCS7_bio(bp,p7) ASN1_i2d_bio(i2d_PKCS7,bp,\
-		(unsigned char *)p7)
-
-#define X509_REQ_dup(req) (X509_REQ *)ASN1_dup((int (*)())i2d_X509_REQ, \
-		(char *(*)())d2i_X509_REQ,(char *)req)
-#define d2i_X509_REQ_fp(fp,req) (X509_REQ *)ASN1_d2i_fp((char *(*)())\
-		X509_REQ_new, (char *(*)())d2i_X509_REQ, (fp),\
-		(unsigned char **)(req))
-#define i2d_X509_REQ_fp(fp,req) ASN1_i2d_fp(i2d_X509_REQ,fp,\
-		(unsigned char *)req)
-#define d2i_X509_REQ_bio(bp,req) (X509_REQ *)ASN1_d2i_bio((char *(*)())\
-		X509_REQ_new, (char *(*)())d2i_X509_REQ, (bp),\
-		(unsigned char **)(req))
-#define i2d_X509_REQ_bio(bp,req) ASN1_i2d_bio(i2d_X509_REQ,bp,\
-		(unsigned char *)req)
-
-#define RSAPublicKey_dup(rsa) (RSA *)ASN1_dup((int (*)())i2d_RSAPublicKey, \
-		(char *(*)())d2i_RSAPublicKey,(char *)rsa)
-#define RSAPrivateKey_dup(rsa) (RSA *)ASN1_dup((int (*)())i2d_RSAPrivateKey, \
-		(char *(*)())d2i_RSAPrivateKey,(char *)rsa)
-
-#define d2i_RSAPrivateKey_fp(fp,rsa) (RSA *)ASN1_d2i_fp((char *(*)())\
-		RSA_new,(char *(*)())d2i_RSAPrivateKey, (fp), \
-		(unsigned char **)(rsa))
-#define i2d_RSAPrivateKey_fp(fp,rsa) ASN1_i2d_fp(i2d_RSAPrivateKey,fp, \
-		(unsigned char *)rsa)
-#define d2i_RSAPrivateKey_bio(bp,rsa) (RSA *)ASN1_d2i_bio((char *(*)())\
-		RSA_new,(char *(*)())d2i_RSAPrivateKey, (bp), \
-		(unsigned char **)(rsa))
-#define i2d_RSAPrivateKey_bio(bp,rsa) ASN1_i2d_bio(i2d_RSAPrivateKey,bp, \
-		(unsigned char *)rsa)
-
-#define d2i_RSAPublicKey_fp(fp,rsa) (RSA *)ASN1_d2i_fp((char *(*)())\
-		RSA_new,(char *(*)())d2i_RSAPublicKey, (fp), \
-		(unsigned char **)(rsa))
-#define i2d_RSAPublicKey_fp(fp,rsa) ASN1_i2d_fp(i2d_RSAPublicKey,fp, \
-		(unsigned char *)rsa)
-#define d2i_RSAPublicKey_bio(bp,rsa) (RSA *)ASN1_d2i_bio((char *(*)())\
-		RSA_new,(char *(*)())d2i_RSAPublicKey, (bp), \
-		(unsigned char **)(rsa))
-#define i2d_RSAPublicKey_bio(bp,rsa) ASN1_i2d_bio(i2d_RSAPublicKey,bp, \
-		(unsigned char *)rsa)
-
-#define d2i_DSAPrivateKey_fp(fp,dsa) (DSA *)ASN1_d2i_fp((char *(*)())\
-		DSA_new,(char *(*)())d2i_DSAPrivateKey, (fp), \
-		(unsigned char **)(dsa))
-#define i2d_DSAPrivateKey_fp(fp,dsa) ASN1_i2d_fp(i2d_DSAPrivateKey,fp, \
-		(unsigned char *)dsa)
-#define d2i_DSAPrivateKey_bio(bp,dsa) (DSA *)ASN1_d2i_bio((char *(*)())\
-		DSA_new,(char *(*)())d2i_DSAPrivateKey, (bp), \
-		(unsigned char **)(dsa))
-#define i2d_DSAPrivateKey_bio(bp,dsa) ASN1_i2d_bio(i2d_DSAPrivateKey,bp, \
-		(unsigned char *)dsa)
-
-#define d2i_ECPrivateKey_fp(fp,ecdsa) (EC_KEY *)ASN1_d2i_fp((char *(*)())\
-		EC_KEY_new,(char *(*)())d2i_ECPrivateKey, (fp), \
-		(unsigned char **)(ecdsa))
-#define i2d_ECPrivateKey_fp(fp,ecdsa) ASN1_i2d_fp(i2d_ECPrivateKey,fp, \
-		(unsigned char *)ecdsa)
-#define d2i_ECPrivateKey_bio(bp,ecdsa) (EC_KEY *)ASN1_d2i_bio((char *(*)())\
-		EC_KEY_new,(char *(*)())d2i_ECPrivateKey, (bp), \
-		(unsigned char **)(ecdsa))
-#define i2d_ECPrivateKey_bio(bp,ecdsa) ASN1_i2d_bio(i2d_ECPrivateKey,bp, \
-		(unsigned char *)ecdsa)
-
-#define X509_ALGOR_dup(xn) (X509_ALGOR *)ASN1_dup((int (*)())i2d_X509_ALGOR,\
-		(char *(*)())d2i_X509_ALGOR,(char *)xn)
-
-#define X509_NAME_dup(xn) (X509_NAME *)ASN1_dup((int (*)())i2d_X509_NAME, \
-		(char *(*)())d2i_X509_NAME,(char *)xn)
-#define X509_NAME_ENTRY_dup(ne) (X509_NAME_ENTRY *)ASN1_dup( \
-		(int (*)())i2d_X509_NAME_ENTRY, \
-		(char *(*)())d2i_X509_NAME_ENTRY,\
-		(char *)ne)
-
-#define X509_digest(data,type,md,len) \
-	ASN1_digest((int (*)())i2d_X509,type,(char *)data,md,len)
-#define X509_NAME_digest(data,type,md,len) \
-	ASN1_digest((int (*)())i2d_X509_NAME,type,(char *)data,md,len)
-#ifndef PKCS7_ISSUER_AND_SERIAL_digest
-#define PKCS7_ISSUER_AND_SERIAL_digest(data,type,md,len) \
-	ASN1_digest((int (*)())i2d_PKCS7_ISSUER_AND_SERIAL,type,\
-		(char *)data,md,len)
-#endif
-#endif
-
 #define X509_EXT_PACK_UNKNOWN	1
 #define X509_EXT_PACK_STRING	2
 
@@ -741,6 +623,18 @@
 #define		X509_CRL_get_issuer(x) ((x)->crl->issuer)
 #define		X509_CRL_get_REVOKED(x) ((x)->crl->revoked)
 
+void X509_CRL_set_default_method(const X509_CRL_METHOD *meth);
+X509_CRL_METHOD *X509_CRL_METHOD_new(
+	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));
+void X509_CRL_METHOD_free(X509_CRL_METHOD *m);
+
+void X509_CRL_set_meth_data(X509_CRL *crl, void *dat);
+void *X509_CRL_get_meth_data(X509_CRL *crl);
+
 /* This one is only used so that a binary form can output, as in
  * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf) */
 #define 	X509_get_X509_PUBKEY(x) ((x)->cert_info->key)
@@ -748,7 +642,6 @@
 
 const char *X509_verify_cert_error_string(long n);
 
-#ifndef SSLEAY_MACROS
 #ifndef OPENSSL_NO_EVP
 int X509_verify(X509 *a, EVP_PKEY *r);
 
@@ -873,11 +766,11 @@
 X509_NAME *X509_NAME_dup(X509_NAME *xn);
 X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
 
-#endif /* !SSLEAY_MACROS */
-
-int		X509_cmp_time(ASN1_TIME *s, time_t *t);
-int		X509_cmp_current_time(ASN1_TIME *s);
+int		X509_cmp_time(const ASN1_TIME *s, time_t *t);
+int		X509_cmp_current_time(const ASN1_TIME *s);
 ASN1_TIME *	X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
+ASN1_TIME *	X509_time_adj_ex(ASN1_TIME *s,
+				int offset_day, long offset_sec, time_t *t);
 ASN1_TIME *	X509_gmtime_adj(ASN1_TIME *s, long adj);
 
 const char *	X509_get_default_cert_area(void );
@@ -965,6 +858,9 @@
 DECLARE_ASN1_FUNCTIONS(X509_CRL)
 
 int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
+int X509_CRL_get0_by_serial(X509_CRL *crl,
+		X509_REVOKED **ret, ASN1_INTEGER *serial);
+int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x);
 
 X509_PKEY *	X509_PKEY_new(void );
 void		X509_PKEY_free(X509_PKEY *a);
@@ -1008,8 +904,8 @@
 X509_NAME *	X509_get_issuer_name(X509 *a);
 int 		X509_set_subject_name(X509 *x, X509_NAME *name);
 X509_NAME *	X509_get_subject_name(X509 *a);
-int 		X509_set_notBefore(X509 *x, ASN1_TIME *tm);
-int 		X509_set_notAfter(X509 *x, ASN1_TIME *tm);
+int 		X509_set_notBefore(X509 *x, const ASN1_TIME *tm);
+int 		X509_set_notAfter(X509 *x, const ASN1_TIME *tm);
 int 		X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
 EVP_PKEY *	X509_get_pubkey(X509 *x);
 ASN1_BIT_STRING * X509_get0_pubkey_bitstr(const X509 *x);
@@ -1046,8 +942,8 @@
 
 int X509_CRL_set_version(X509_CRL *x, long version);
 int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
-int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm);
-int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm);
+int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
+int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
 int X509_CRL_sort(X509_CRL *crl);
 
 int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
@@ -1066,11 +962,18 @@
 int		X509_subject_name_cmp(const X509 *a, const X509 *b);
 unsigned long	X509_subject_name_hash(X509 *x);
 
+#ifndef OPENSSL_NO_MD5
+unsigned long	X509_issuer_name_hash_old(X509 *a);
+unsigned long	X509_subject_name_hash_old(X509 *x);
+#endif
+
 int		X509_cmp(const X509 *a, const X509 *b);
 int		X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
 unsigned long	X509_NAME_hash(X509_NAME *x);
+unsigned long	X509_NAME_hash_old(X509_NAME *x);
 
 int		X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
+int		X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
 #ifndef OPENSSL_NO_FP_API
 int		X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag);
 int		X509_print_fp(FILE *bp,X509 *x);
@@ -1246,9 +1149,16 @@
 DECLARE_ASN1_FUNCTIONS(PBE2PARAM)
 DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM)
 
-X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, int saltlen);
+int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
+				const unsigned char *salt, int saltlen);
+
+X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
+				const unsigned char *salt, int saltlen);
 X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
 					 unsigned char *salt, int saltlen);
+X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
+				 unsigned char *salt, int saltlen,
+				 unsigned char *aiv, int prf_nid);
 
 /* PKCS#8 utilities */
 
@@ -1259,6 +1169,22 @@
 PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
 PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
 
+int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
+			int version, int ptype, void *pval,
+				unsigned char *penc, int penclen);
+int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
+		const unsigned char **pk, int *ppklen,
+		X509_ALGOR **pa,
+		PKCS8_PRIV_KEY_INFO *p8);
+
+int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
+					int ptype, void *pval,
+					unsigned char *penc, int penclen);
+int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
+		const unsigned char **pk, int *ppklen,
+		X509_ALGOR **pa,
+		X509_PUBKEY *pub);
+
 int X509_check_trust(X509 *x, int id, int flags);
 int X509_TRUST_get_count(void);
 X509_TRUST * X509_TRUST_get0(int idx);
@@ -1338,7 +1264,10 @@
 #define X509_R_KEY_VALUES_MISMATCH			 116
 #define X509_R_LOADING_CERT_DIR				 103
 #define X509_R_LOADING_DEFAULTS				 104
+#define X509_R_METHOD_NOT_SUPPORTED			 124
 #define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY		 105
+#define X509_R_PUBLIC_KEY_DECODE_ERROR			 125
+#define X509_R_PUBLIC_KEY_ENCODE_ERROR			 126
 #define X509_R_SHOULD_RETRY				 106
 #define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN	 107
 #define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY		 108
diff --git a/include/openssl/x509_vfy.h b/include/openssl/x509_vfy.h
index 86ae35f..fe09b30 100644
--- a/include/openssl/x509_vfy.h
+++ b/include/openssl/x509_vfy.h
@@ -77,6 +77,7 @@
 extern "C" {
 #endif
 
+#if 0
 /* Outer object */
 typedef struct x509_hash_dir_st
 	{
@@ -85,6 +86,7 @@
 	int *dirs_type;
 	int num_dirs_alloced;
 	} X509_HASH_DIR_CTX;
+#endif
 
 typedef struct x509_file_st
 	{
@@ -198,6 +200,8 @@
 	int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */
 	int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
 	int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
+	STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm);
+	STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm);
 	int (*cleanup)(X509_STORE_CTX *ctx);
 
 	CRYPTO_EX_DATA ex_data;
@@ -246,6 +250,8 @@
 	int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
 	int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
 	int (*check_policy)(X509_STORE_CTX *ctx);
+	STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm);
+	STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm);
 	int (*cleanup)(X509_STORE_CTX *ctx);
 
 	/* The following is built up */
@@ -263,6 +269,11 @@
 	X509 *current_issuer;	/* cert currently being tested as valid issuer */
 	X509_CRL *current_crl;	/* current CRL */
 
+	int current_crl_score;  /* score of current CRL */
+	unsigned int current_reasons;  /* Reason mask */
+
+	X509_STORE_CTX *parent; /* For CRL path validation: parent context */
+
 	CRYPTO_EX_DATA ex_data;
 	} /* X509_STORE_CTX */;
 
@@ -330,8 +341,18 @@
 #define		X509_V_ERR_INVALID_EXTENSION			41
 #define		X509_V_ERR_INVALID_POLICY_EXTENSION		42
 #define		X509_V_ERR_NO_EXPLICIT_POLICY			43
+#define		X509_V_ERR_DIFFERENT_CRL_SCOPE			44
+#define		X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE	45
 
-#define		X509_V_ERR_UNNESTED_RESOURCE			44
+#define		X509_V_ERR_UNNESTED_RESOURCE			46
+
+#define		X509_V_ERR_PERMITTED_VIOLATION			47
+#define		X509_V_ERR_EXCLUDED_VIOLATION			48
+#define		X509_V_ERR_SUBTREE_MINMAX			49
+#define		X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE		51
+#define		X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX	52
+#define		X509_V_ERR_UNSUPPORTED_NAME_SYNTAX		53
+#define		X509_V_ERR_CRL_PATH_VALIDATION_ERROR		54
 
 /* The application is not happy */
 #define		X509_V_ERR_APPLICATION_VERIFICATION		50
@@ -362,10 +383,14 @@
 #define X509_V_FLAG_INHIBIT_MAP			0x400
 /* Notify callback that policy is OK */
 #define X509_V_FLAG_NOTIFY_POLICY		0x800
-
+/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */
+#define X509_V_FLAG_EXTENDED_CRL_SUPPORT	0x1000
+/* Delta CRL support */
+#define X509_V_FLAG_USE_DELTAS			0x2000
 /* Check selfsigned CA signature */
 #define X509_V_FLAG_CHECK_SS_SIGNATURE		0x4000
 
+
 #define X509_VP_FLAG_DEFAULT			0x1
 #define X509_VP_FLAG_OVERWRITE			0x2
 #define X509_VP_FLAG_RESET_FLAGS		0x4
@@ -387,11 +412,16 @@
 X509_STORE *X509_STORE_new(void );
 void X509_STORE_free(X509_STORE *v);
 
+STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm);
+STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm);
 int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
 int X509_STORE_set_purpose(X509_STORE *ctx, int purpose);
 int X509_STORE_set_trust(X509_STORE *ctx, int trust);
 int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);
 
+void X509_STORE_set_verify_cb(X509_STORE *ctx,
+				  int (*verify_cb)(int, X509_STORE_CTX *));
+
 X509_STORE_CTX *X509_STORE_CTX_new(void);
 
 int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
@@ -450,6 +480,9 @@
 void	X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s);
 int	X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
 X509 *	X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
+X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx);
+X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx);
+X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx);
 STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
 STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
 void	X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x);
diff --git a/include/openssl/x509v3.h b/include/openssl/x509v3.h
index 9ef83da..b308abe 100644
--- a/include/openssl/x509v3.h
+++ b/include/openssl/x509v3.h
@@ -76,12 +76,19 @@
 typedef void (*X509V3_EXT_FREE)(void *);
 typedef void * (*X509V3_EXT_D2I)(void *, const unsigned char ** , long);
 typedef int (*X509V3_EXT_I2D)(void *, unsigned char **);
-typedef STACK_OF(CONF_VALUE) * (*X509V3_EXT_I2V)(struct v3_ext_method *method, void *ext, STACK_OF(CONF_VALUE) *extlist);
-typedef void * (*X509V3_EXT_V2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, STACK_OF(CONF_VALUE) *values);
-typedef char * (*X509V3_EXT_I2S)(struct v3_ext_method *method, void *ext);
-typedef void * (*X509V3_EXT_S2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, const char *str);
-typedef int (*X509V3_EXT_I2R)(struct v3_ext_method *method, void *ext, BIO *out, int indent);
-typedef void * (*X509V3_EXT_R2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, const char *str);
+typedef STACK_OF(CONF_VALUE) *
+  (*X509V3_EXT_I2V)(const struct v3_ext_method *method, void *ext,
+		    STACK_OF(CONF_VALUE) *extlist);
+typedef void * (*X509V3_EXT_V2I)(const struct v3_ext_method *method,
+				 struct v3_ext_ctx *ctx,
+				 STACK_OF(CONF_VALUE) *values);
+typedef char * (*X509V3_EXT_I2S)(const struct v3_ext_method *method, void *ext);
+typedef void * (*X509V3_EXT_S2I)(const struct v3_ext_method *method,
+				 struct v3_ext_ctx *ctx, const char *str);
+typedef int (*X509V3_EXT_I2R)(const struct v3_ext_method *method, void *ext,
+			      BIO *out, int indent);
+typedef void * (*X509V3_EXT_R2I)(const struct v3_ext_method *method,
+				 struct v3_ext_ctx *ctx, const char *str);
 
 /* V3 extension structure */
 
@@ -220,24 +227,41 @@
 	GENERAL_NAMES *fullname;
 	STACK_OF(X509_NAME_ENTRY) *relativename;
 } name;
+/* If relativename then this contains the full distribution point name */
+X509_NAME *dpname;
 } DIST_POINT_NAME;
+/* All existing reasons */
+#define CRLDP_ALL_REASONS	0x807f
 
-typedef struct DIST_POINT_st {
+#define CRL_REASON_NONE				-1
+#define CRL_REASON_UNSPECIFIED			0
+#define CRL_REASON_KEY_COMPROMISE		1
+#define CRL_REASON_CA_COMPROMISE		2
+#define CRL_REASON_AFFILIATION_CHANGED		3
+#define CRL_REASON_SUPERSEDED			4
+#define CRL_REASON_CESSATION_OF_OPERATION	5
+#define CRL_REASON_CERTIFICATE_HOLD		6
+#define CRL_REASON_REMOVE_FROM_CRL		8
+#define CRL_REASON_PRIVILEGE_WITHDRAWN		9
+#define CRL_REASON_AA_COMPROMISE		10
+
+struct DIST_POINT_st {
 DIST_POINT_NAME	*distpoint;
 ASN1_BIT_STRING *reasons;
 GENERAL_NAMES *CRLissuer;
-} DIST_POINT;
+int dp_reasons;
+};
 
 typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS;
 
 DECLARE_STACK_OF(DIST_POINT)
 DECLARE_ASN1_SET_OF(DIST_POINT)
 
-typedef struct AUTHORITY_KEYID_st {
+struct AUTHORITY_KEYID_st {
 ASN1_OCTET_STRING *keyid;
 GENERAL_NAMES *issuer;
 ASN1_INTEGER *serial;
-} AUTHORITY_KEYID;
+};
 
 /* Strong extranet structures */
 
@@ -303,10 +327,10 @@
 
 DECLARE_STACK_OF(GENERAL_SUBTREE)
 
-typedef struct NAME_CONSTRAINTS_st {
+struct NAME_CONSTRAINTS_st {
 	STACK_OF(GENERAL_SUBTREE) *permittedSubtrees;
 	STACK_OF(GENERAL_SUBTREE) *excludedSubtrees;
-} NAME_CONSTRAINTS;
+};
 
 typedef struct POLICY_CONSTRAINTS_st {
 	ASN1_INTEGER *requireExplicitPolicy;
@@ -329,6 +353,31 @@
 DECLARE_ASN1_FUNCTIONS(PROXY_POLICY)
 DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
 
+struct ISSUING_DIST_POINT_st
+	{
+	DIST_POINT_NAME *distpoint;
+	int onlyuser;
+	int onlyCA;
+	ASN1_BIT_STRING *onlysomereasons;
+	int indirectCRL;
+	int onlyattr;
+	};
+
+/* Values in idp_flags field */
+/* IDP present */
+#define	IDP_PRESENT	0x1
+/* IDP values inconsistent */
+#define IDP_INVALID	0x2
+/* onlyuser true */
+#define	IDP_ONLYUSER	0x4
+/* onlyCA true */
+#define	IDP_ONLYCA	0x8
+/* onlyattr true */
+#define IDP_ONLYATTR	0x10
+/* indirectCRL true */
+#define IDP_INDIRECT	0x20
+/* onlysomereasons present */
+#define IDP_REASONS	0x40
 
 #define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \
 ",name:", val->name, ",value:", val->value);
@@ -373,6 +422,7 @@
 #define EXFLAG_PROXY		0x400
 
 #define EXFLAG_INVALID_POLICY	0x800
+#define EXFLAG_FRESHEST		0x1000
 
 #define KU_DIGITAL_SIGNATURE	0x0080
 #define KU_NON_REPUDIATION	0x0040
@@ -424,9 +474,10 @@
 #define X509_PURPOSE_CRL_SIGN		6
 #define X509_PURPOSE_ANY		7
 #define X509_PURPOSE_OCSP_HELPER	8
+#define X509_PURPOSE_TIMESTAMP_SIGN	9
 
 #define X509_PURPOSE_MIN		1
-#define X509_PURPOSE_MAX		8
+#define X509_PURPOSE_MAX		9
 
 /* Flags for X509V3_EXT_print() */
 
@@ -471,6 +522,9 @@
 DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
 
 DECLARE_ASN1_FUNCTIONS(GENERAL_NAME)
+GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a);
+int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b);
+
 
 
 ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
@@ -486,11 +540,18 @@
 
 STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
 		GENERAL_NAMES *gen, STACK_OF(CONF_VALUE) *extlist);
-GENERAL_NAMES *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method,
-				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
+				 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
 
 DECLARE_ASN1_FUNCTIONS(OTHERNAME)
 DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME)
+int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b);
+void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value);
+void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype);
+int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
+				ASN1_OBJECT *oid, ASN1_TYPE *value);
+int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, 
+				ASN1_OBJECT **poid, ASN1_TYPE **pvalue);
 
 char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *ia5);
 ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
@@ -507,6 +568,11 @@
 DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS)
 DECLARE_ASN1_FUNCTIONS(DIST_POINT)
 DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME)
+DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
+
+int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname);
+
+int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc);
 
 DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
 DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
@@ -524,11 +590,16 @@
 DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
 DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS)
 
+GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
+			       const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+			       int gen_type, char *value, int is_nc);
+
 #ifdef HEADER_CONF_H
-GENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
-							CONF_VALUE *cnf);
-GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, X509V3_EXT_METHOD *method,
-				X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc);
+GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+			       CONF_VALUE *cnf);
+GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
+				  const X509V3_EXT_METHOD *method,
+				  X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc);
 void X509V3_conf_free(CONF_VALUE *val);
 
 X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, char *value);
@@ -538,18 +609,23 @@
 int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_REQ *req);
 int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl);
 
-X509_EXTENSION *X509V3_EXT_conf_nid(LHASH *conf, X509V3_CTX *ctx, int ext_nid, char *value);
-X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name, char *value);
-int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509 *cert);
-int X509V3_EXT_REQ_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509_REQ *req);
-int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl);
+X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+				    int ext_nid, char *value);
+X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+				char *name, char *value);
+int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+			char *section, X509 *cert);
+int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+			    char *section, X509_REQ *req);
+int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+			    char *section, X509_CRL *crl);
 
 int X509V3_add_value_bool_nf(char *name, int asn1_bool,
-						STACK_OF(CONF_VALUE) **extlist);
+			     STACK_OF(CONF_VALUE) **extlist);
 int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool);
 int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint);
 void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf);
-void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH *lhash);
+void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash);
 #endif
 
 char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section);
@@ -576,8 +652,8 @@
 int X509V3_EXT_add_alias(int nid_to, int nid_from);
 void X509V3_EXT_cleanup(void);
 
-X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext);
-X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid);
+const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext);
+const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid);
 int X509V3_add_standard_extensions(void);
 STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line);
 void *X509V3_EXT_d2i(X509_EXTENSION *ext);
@@ -587,8 +663,8 @@
 X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
 int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags);
 
-char *hex_to_string(unsigned char *buffer, long len);
-unsigned char *string_to_hex(char *str, long *len);
+char *hex_to_string(const unsigned char *buffer, long len);
+unsigned char *string_to_hex(const char *str, long *len);
 int name_cmp(const char *name, const char *cmp);
 
 void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
@@ -603,6 +679,7 @@
 int X509_supported_extension(X509_EXTENSION *ex);
 int X509_PURPOSE_set(int *p, int purpose);
 int X509_check_issued(X509 *issuer, X509 *subject);
+int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid);
 int X509_PURPOSE_get_count(void);
 X509_PURPOSE * X509_PURPOSE_get0(int idx);
 int X509_PURPOSE_get_by_sname(char *sname);
@@ -616,10 +693,10 @@
 void X509_PURPOSE_cleanup(void);
 int X509_PURPOSE_get_id(X509_PURPOSE *);
 
-STACK *X509_get1_email(X509 *x);
-STACK *X509_REQ_get1_email(X509_REQ *x);
-void X509_email_free(STACK *sk);
-STACK *X509_get1_ocsp(X509 *x);
+STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x);
+STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x);
+void X509_email_free(STACK_OF(OPENSSL_STRING) *sk);
+STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x);
 
 ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc);
 ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc);
@@ -628,6 +705,7 @@
 						unsigned long chtype);
 
 void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent);
+DECLARE_STACK_OF(X509_POLICY_NODE)
 
 #ifndef OPENSSL_NO_RFC3779
 
@@ -787,8 +865,9 @@
 /* Error codes for the X509V3 functions. */
 
 /* Function codes. */
-#define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE		 156
-#define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL	 157
+#define X509V3_F_A2I_GENERAL_NAME			 164
+#define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE		 161
+#define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL	 162
 #define X509V3_F_COPY_EMAIL				 122
 #define X509V3_F_COPY_ISSUER				 123
 #define X509V3_F_DO_DIRNAME				 144
@@ -796,6 +875,7 @@
 #define X509V3_F_DO_EXT_I2D				 135
 #define X509V3_F_DO_EXT_NCONF				 151
 #define X509V3_F_DO_I2V_NAME_CONSTRAINTS		 148
+#define X509V3_F_GNAMES_FROM_SECTNAME			 156
 #define X509V3_F_HEX_TO_STRING				 111
 #define X509V3_F_I2S_ASN1_ENUMERATED			 121
 #define X509V3_F_I2S_ASN1_IA5STRING			 149
@@ -812,13 +892,14 @@
 #define X509V3_F_S2I_ASN1_OCTET_STRING			 112
 #define X509V3_F_S2I_ASN1_SKEY_ID			 114
 #define X509V3_F_S2I_SKEY_ID				 115
+#define X509V3_F_SET_DIST_POINT_NAME			 158
 #define X509V3_F_STRING_TO_HEX				 113
 #define X509V3_F_SXNET_ADD_ID_ASC			 125
 #define X509V3_F_SXNET_ADD_ID_INTEGER			 126
 #define X509V3_F_SXNET_ADD_ID_ULONG			 127
 #define X509V3_F_SXNET_GET_ID_ASC			 128
 #define X509V3_F_SXNET_GET_ID_ULONG			 129
-#define X509V3_F_V2I_ASIDENTIFIERS			 158
+#define X509V3_F_V2I_ASIDENTIFIERS			 163
 #define X509V3_F_V2I_ASN1_BIT_STRING			 101
 #define X509V3_F_V2I_AUTHORITY_INFO_ACCESS		 139
 #define X509V3_F_V2I_AUTHORITY_KEYID			 119
@@ -827,6 +908,7 @@
 #define X509V3_F_V2I_EXTENDED_KEY_USAGE			 103
 #define X509V3_F_V2I_GENERAL_NAMES			 118
 #define X509V3_F_V2I_GENERAL_NAME_EX			 117
+#define X509V3_F_V2I_IDP				 157
 #define X509V3_F_V2I_IPADDRBLOCKS			 159
 #define X509V3_F_V2I_ISSUER_ALT				 153
 #define X509V3_F_V2I_NAME_CONSTRAINTS			 147
@@ -855,6 +937,7 @@
 #define X509V3_R_BN_DEC2BN_ERROR			 100
 #define X509V3_R_BN_TO_ASN1_INTEGER_ERROR		 101
 #define X509V3_R_DIRNAME_ERROR				 149
+#define X509V3_R_DISTPOINT_ALREADY_SET			 160
 #define X509V3_R_DUPLICATE_ZONE_ID			 133
 #define X509V3_R_ERROR_CONVERTING_ZONE			 131
 #define X509V3_R_ERROR_CREATING_EXTENSION		 144
@@ -868,12 +951,13 @@
 #define X509V3_R_ILLEGAL_EMPTY_EXTENSION		 151
 #define X509V3_R_ILLEGAL_HEX_DIGIT			 113
 #define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG		 152
-#define X509V3_R_INVALID_ASNUMBER			 160
-#define X509V3_R_INVALID_ASRANGE			 161
+#define X509V3_R_INVALID_MULTIPLE_RDNS			 161
+#define X509V3_R_INVALID_ASNUMBER			 162
+#define X509V3_R_INVALID_ASRANGE			 163
 #define X509V3_R_INVALID_BOOLEAN_STRING			 104
 #define X509V3_R_INVALID_EXTENSION_STRING		 105
-#define X509V3_R_INVALID_INHERITANCE			 162
-#define X509V3_R_INVALID_IPADDRESS			 163
+#define X509V3_R_INVALID_INHERITANCE			 165
+#define X509V3_R_INVALID_IPADDRESS			 166
 #define X509V3_R_INVALID_NAME				 106
 #define X509V3_R_INVALID_NULL_ARGUMENT			 107
 #define X509V3_R_INVALID_NULL_NAME			 108
@@ -901,9 +985,9 @@
 #define X509V3_R_ODD_NUMBER_OF_DIGITS			 112
 #define X509V3_R_OPERATION_NOT_DEFINED			 148
 #define X509V3_R_OTHERNAME_ERROR			 147
-#define X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED	 155
+#define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED	 155
 #define X509V3_R_POLICY_PATH_LENGTH			 156
-#define X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED	 157
+#define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED	 157
 #define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED	 158
 #define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159
 #define X509V3_R_SECTION_NOT_FOUND			 150
@@ -914,6 +998,7 @@
 #define X509V3_R_UNKNOWN_EXTENSION_NAME			 130
 #define X509V3_R_UNKNOWN_OPTION				 120
 #define X509V3_R_UNSUPPORTED_OPTION			 117
+#define X509V3_R_UNSUPPORTED_TYPE			 167
 #define X509V3_R_USER_TOO_LONG				 132
 
 #ifdef  __cplusplus
diff --git a/openssl.config b/openssl.config
index d6fc918..df1f625 100644
--- a/openssl.config
+++ b/openssl.config
@@ -1,34 +1,36 @@
 CONFIGURE_ARGS="\
         linux-generic32 \
-        no-idea no-bf no-cast no-seed no-md2 \
+        no-idea no-bf no-cast no-seed no-md2 no-whrlpool \
         -DL_ENDIAN"
 
 # unneeded directories
 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	    \
+ 	MacOS		\
+	Netware		\
+	VMS		\
+	apps/demoCA	\
+	apps/set	\
+	bugs		\
+	certs		\
+	crypto/bf	\
+	crypto/camellia	\
+	crypto/cast	\
+	crypto/cms	\
+	crypto/idea	\
+	crypto/md2	\
+	crypto/rc5	\
+	crypto/seed	\
+	crypto/whrlpool	\
+	demos		\
+	doc		\
+	engines		\
+	ms		\
+	os2		\
+	perl		\
+	shlib		\
+	test		\
+	times		\
+	tools		\
 	util"
 
 # unneeded files
@@ -59,12 +61,90 @@
 	README.ASN1				\
 	README.ENGINE				\
 	apps/CA.pl.bak				\
+	apps/Makefile				\
+	apps/pkey.c				\
+	apps/pkeyparam.c			\
+	apps/pkeyutl.c				\
+	apps/ts.c				\
+	apps/tsget				\
 	config					\
+	crypto/Makefile				\
+	crypto/aes/Makefile			\
+	crypto/asn1/Makefile			\
+	crypto/bio/Makefile			\
+	crypto/bn/Makefile			\
+	crypto/buffer/Makefile			\
+	crypto/camellia/Makefile		\
+	crypto/comp/Makefile			\
+	crypto/conf/Makefile			\
+	crypto/des/Makefile			\
+	crypto/dh/Makefile			\
+	crypto/dh/dh_prn.c			\
+	crypto/dsa/Makefile			\
+	crypto/dso/Makefile			\
+	crypto/dso/dso_beos.c			\
+	crypto/ec/Makefile			\
+	crypto/ec/ec_ameth.c			\
+	crypto/ec/ec_pmeth.c			\
+	crypto/ec/eck_prn.c			\
+	crypto/ecdh/Makefile			\
+	crypto/ecdsa/Makefile			\
+	crypto/engine/Makefile			\
+	crypto/engine/tb_asnmth.c		\
+	crypto/engine/tb_pkmeth.c		\
+	crypto/err/Makefile			\
+	crypto/evp/Makefile			\
+	crypto/hmac/Makefile			\
+	crypto/jpake/Makefile			\
+	crypto/krb5/Makefile			\
+	crypto/lhash/Makefile			\
+	crypto/md4/Makefile			\
+	crypto/md5/Makefile			\
+	crypto/mdc2/Makefile			\
+	crypto/modes/Makefile			\
+	crypto/modes/cts128.c			\
+	crypto/modes/modes.h			\
+	crypto/objects/Makefile			\
+	crypto/ocsp/Makefile			\
 	crypto/opensslconf.h.bak		\
+	crypto/pem/Makefile			\
+	crypto/pkcs12/Makefile			\
+	crypto/pkcs7/Makefile			\
+	crypto/pkcs7/bio_pk7.c			\
+	crypto/pqueue/Makefile			\
+	crypto/rand/Makefile			\
+	crypto/rc2/Makefile			\
+	crypto/rc4/Makefile			\
+	crypto/ripemd/Makefile			\
+	crypto/rsa/Makefile			\
+	crypto/sha/Makefile			\
+	crypto/stack/Makefile			\
+	crypto/store/Makefile			\
+	crypto/ts/Makefile			\
+	crypto/ts/ts.h				\
+	crypto/ts/ts_asn1.c			\
+	crypto/ts/ts_conf.c			\
+	crypto/ts/ts_lib.c			\
+	crypto/ts/ts_req_print.c		\
+	crypto/ts/ts_req_utils.c		\
+	crypto/ts/ts_rsp_print.c		\
+	crypto/ts/ts_rsp_sign.c			\
+	crypto/ts/ts_rsp_utils.c		\
+	crypto/ts/ts_rsp_verify.c		\
+	crypto/ts/ts_verify_ctx.c		\
+	crypto/txt_db/Makefile			\
+	crypto/ui/Makefile			\
+	crypto/x509/Makefile			\
+	crypto/x509v3/Makefile			\
 	include/openssl/blowfish.h		\
+	include/openssl/camellia.h		\
 	include/openssl/cast.h			\
+	include/openssl/cms.h			\
 	include/openssl/idea.h			\
 	include/openssl/md2.h			\
+	include/openssl/mdc2.h			\
+	include/openssl/seed.h			\
+	include/openssl/whrlpool.h		\
 	install.com				\
 	makevms.com				\
 	openssl.doxy				\
@@ -72,9 +152,7 @@
 
 OPENSSL_PATCHES="\
         progs.patch                 \
-        arm-asm.patch               \
-        small_records.patch         \
-        bad_version.patch"
+        small_records.patch"
 # Disabled for compatibility b/2586347
 #       handshake_cutthrough.patch
 
@@ -82,19 +160,6 @@
 	apps/progs.h \
 	apps/speed.c"
 
-OPENSSL_PATCHES_arm_asm_SOURCES="\
-	0.9.9-dev/README.android          \
-	0.9.9-dev/aes/aes-armv4.pl        \
-	0.9.9-dev/aes/aes-armv4.s         \
-	0.9.9-dev/bn/armv4-mont.pl        \
-	0.9.9-dev/bn/armv4-mont.s         \
-	0.9.9-dev/sha/sha1-armv4-large.pl \
-	0.9.9-dev/sha/sha1-armv4-large.s  \
-	0.9.9-dev/sha/sha256-armv4.pl     \
-	0.9.9-dev/sha/sha256-armv4.s      \
-	0.9.9-dev/sha/sha512-armv4.pl     \
-	0.9.9-dev/sha/sha512-armv4.s"
-
 OPENSSL_PATCHES_handshake_cutthrough_SOURCES="\
 	apps/s_client.c \
 	ssl/s3_clnt.c   \
@@ -105,9 +170,6 @@
 	ssl/ssltest.c   \
 	test/testssl"
 
-OPENSSL_PATCHES_handshake_cutthrough_SOURCES="\
-	crypto/err/err_all.c"
-
 OPENSSL_PATCHES_small_records_SOURCES="\
 	ssl/d1_pkt.c   \
 	ssl/s23_srvr.c \
@@ -117,6 +179,3 @@
 	ssl/ssl3.h     \
 	ssl/ssltest.c  \
 	test/testssl"
-
-OPENSSL_PATCHES_bad_version_SOURCES="\
-	ssl/s3_pkt.c"
diff --git a/openssl.version b/openssl.version
index 6d368e7..61658db 100644
--- a/openssl.version
+++ b/openssl.version
@@ -1 +1 @@
-OPENSSL_VERSION=0.9.8m
+OPENSSL_VERSION=1.0.0
diff --git a/patches/README b/patches/README
index a95646c..856f18a 100644
--- a/patches/README
+++ b/patches/README
@@ -3,11 +3,6 @@
 Fixup sources under the apps/ directory that are not built under the android environment.
 
 
-arm-asm.patch.patch:
-
-ARM assembly routines (AES, BN, SHA1, SHA256, SHA512)
-
-
 small_records.patch:
 
 Reduce OpenSSL memory consumption.
@@ -26,12 +21,3 @@
 Finished message even when negotiating full-handshakes.  With this patch,
 clients can negotiate SSL connections in 1-RTT even when performing
 full-handshakes.
-
-
-bad_version.patch
-
-Addresses CVE-2010-0740 http://www.openssl.org/news/secadv_20100324.txt
-A peer can send us a mal-formed packet and we'll copy its 'version'
-number in order to send an error back. However, if the version number
-is an internal OpenSSL value (like DTLS1_VERSION) then we'll assume
-that we have a valid DTLS state and crash when sending an alert.
diff --git a/patches/apps_Android.mk b/patches/apps_Android.mk
index e9a4981..a908806 100644
--- a/patches/apps_Android.mk
+++ b/patches/apps_Android.mk
@@ -4,13 +4,49 @@
 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
+	app_rand.c \
+	apps.c \
+	asn1pars.c \
+	ca.c \
+	ciphers.c \
+	crl.c \
+	crl2p7.c \
+	dgst.c \
+	dh.c \
+	dhparam.c \
+	dsa.c \
+	dsaparam.c \
+	ecparam.c \
+	enc.c \
+	engine.c \
+	errstr.c \
+	gendh.c \
+	gendsa.c \
+	genpkey.c \
+	genrsa.c \
+	nseq.c \
+	ocsp.c \
+	openssl.c \
+	passwd.c \
+	pkcs12.c \
+	pkcs7.c \
+	pkcs8.c \
+	prime.c \
+	rand.c \
+	req.c \
+	rsa.c \
+	rsautl.c \
+	s_cb.c \
+	s_client.c \
+	s_socket.c \
+	s_time.c \
+	sess_id.c \
+	smime.c \
+	speed.c \
+	spkac.c \
+	verify.c \
+	version.c \
+	x509.c
 
 #   cms.c ec.c s_server.c
 
diff --git a/patches/arm-asm.patch b/patches/arm-asm.patch
deleted file mode 100644
index 9c8cb40..0000000
--- a/patches/arm-asm.patch
+++ /dev/null
@@ -1,5106 +0,0 @@
---- /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 <appro@fy.chalmers.se> for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# AES for ARMv4
-+
-+# January 2007.
-+#
-+# Code uses single 1K S-box and is >2 times faster than code generated
-+# by gcc-3.4.1. This is thanks to unique feature of ARMv4 ISA, which
-+# allows to merge logical or arithmetic operation with shift or rotate
-+# in one instruction and emit combined result every cycle. The module
-+# is endian-neutral. The performance is ~42 cycles/byte for 128-bit
-+# key.
-+
-+# May 2007.
-+#
-+# AES_set_[en|de]crypt_key is added.
-+
-+$s0="r0";
-+$s1="r1";
-+$s2="r2";
-+$s3="r3";
-+$t1="r4";
-+$t2="r5";
-+$t3="r6";
-+$i1="r7";
-+$i2="r8";
-+$i3="r9";
-+
-+$tbl="r10";
-+$key="r11";
-+$rounds="r12";
-+
-+$code=<<___;
-+.text
-+.code	32
-+
-+.type	AES_Te,%object
-+.align	5
-+AES_Te:
-+.word	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d
-+.word	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554
-+.word	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d
-+.word	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a
-+.word	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87
-+.word	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b
-+.word	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea
-+.word	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b
-+.word	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a
-+.word	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f
-+.word	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108
-+.word	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f
-+.word	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e
-+.word	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5
-+.word	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d
-+.word	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f
-+.word	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e
-+.word	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb
-+.word	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce
-+.word	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497
-+.word	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c
-+.word	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed
-+.word	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b
-+.word	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a
-+.word	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16
-+.word	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594
-+.word	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81
-+.word	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3
-+.word	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a
-+.word	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504
-+.word	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163
-+.word	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d
-+.word	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f
-+.word	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739
-+.word	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47
-+.word	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395
-+.word	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f
-+.word	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883
-+.word	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c
-+.word	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76
-+.word	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e
-+.word	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4
-+.word	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6
-+.word	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b
-+.word	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7
-+.word	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0
-+.word	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25
-+.word	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818
-+.word	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72
-+.word	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651
-+.word	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21
-+.word	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85
-+.word	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa
-+.word	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12
-+.word	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0
-+.word	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9
-+.word	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133
-+.word	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7
-+.word	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920
-+.word	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a
-+.word	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17
-+.word	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8
-+.word	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11
-+.word	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
-+@ Te4[256]
-+.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
-+.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
-+.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
-+.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
-+.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
-+.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
-+.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
-+.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
-+.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
-+.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
-+.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
-+.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
-+.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
-+.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
-+.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
-+.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
-+.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
-+.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
-+.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
-+.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
-+.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
-+.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
-+.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
-+.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
-+.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
-+.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
-+.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
-+.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
-+.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
-+.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
-+.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
-+.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-+@ rcon[]
-+.word	0x01000000, 0x02000000, 0x04000000, 0x08000000
-+.word	0x10000000, 0x20000000, 0x40000000, 0x80000000
-+.word	0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
-+.size	AES_Te,.-AES_Te
-+
-+@ void AES_encrypt(const unsigned char *in, unsigned char *out,
-+@ 		 const AES_KEY *key) {
-+.global AES_encrypt
-+.type   AES_encrypt,%function
-+.align	5
-+AES_encrypt:
-+	sub	r3,pc,#8		@ AES_encrypt
-+	stmdb   sp!,{r1,r4-r12,lr}
-+	mov	$rounds,r0		@ inp
-+	mov	$key,r2
-+	sub	$tbl,r3,#AES_encrypt-AES_Te	@ Te
-+
-+	ldrb	$s0,[$rounds,#3]	@ load input data in endian-neutral
-+	ldrb	$t1,[$rounds,#2]	@ manner...
-+	ldrb	$t2,[$rounds,#1]
-+	ldrb	$t3,[$rounds,#0]
-+	orr	$s0,$s0,$t1,lsl#8
-+	orr	$s0,$s0,$t2,lsl#16
-+	orr	$s0,$s0,$t3,lsl#24
-+	ldrb	$s1,[$rounds,#7]
-+	ldrb	$t1,[$rounds,#6]
-+	ldrb	$t2,[$rounds,#5]
-+	ldrb	$t3,[$rounds,#4]
-+	orr	$s1,$s1,$t1,lsl#8
-+	orr	$s1,$s1,$t2,lsl#16
-+	orr	$s1,$s1,$t3,lsl#24
-+	ldrb	$s2,[$rounds,#11]
-+	ldrb	$t1,[$rounds,#10]
-+	ldrb	$t2,[$rounds,#9]
-+	ldrb	$t3,[$rounds,#8]
-+	orr	$s2,$s2,$t1,lsl#8
-+	orr	$s2,$s2,$t2,lsl#16
-+	orr	$s2,$s2,$t3,lsl#24
-+	ldrb	$s3,[$rounds,#15]
-+	ldrb	$t1,[$rounds,#14]
-+	ldrb	$t2,[$rounds,#13]
-+	ldrb	$t3,[$rounds,#12]
-+	orr	$s3,$s3,$t1,lsl#8
-+	orr	$s3,$s3,$t2,lsl#16
-+	orr	$s3,$s3,$t3,lsl#24
-+
-+	bl	_armv4_AES_encrypt
-+
-+	ldr	$rounds,[sp],#4		@ pop out
-+	mov	$t1,$s0,lsr#24		@ write output in endian-neutral
-+	mov	$t2,$s0,lsr#16		@ manner...
-+	mov	$t3,$s0,lsr#8
-+	strb	$t1,[$rounds,#0]
-+	strb	$t2,[$rounds,#1]
-+	strb	$t3,[$rounds,#2]
-+	strb	$s0,[$rounds,#3]
-+	mov	$t1,$s1,lsr#24
-+	mov	$t2,$s1,lsr#16
-+	mov	$t3,$s1,lsr#8
-+	strb	$t1,[$rounds,#4]
-+	strb	$t2,[$rounds,#5]
-+	strb	$t3,[$rounds,#6]
-+	strb	$s1,[$rounds,#7]
-+	mov	$t1,$s2,lsr#24
-+	mov	$t2,$s2,lsr#16
-+	mov	$t3,$s2,lsr#8
-+	strb	$t1,[$rounds,#8]
-+	strb	$t2,[$rounds,#9]
-+	strb	$t3,[$rounds,#10]
-+	strb	$s2,[$rounds,#11]
-+	mov	$t1,$s3,lsr#24
-+	mov	$t2,$s3,lsr#16
-+	mov	$t3,$s3,lsr#8
-+	strb	$t1,[$rounds,#12]
-+	strb	$t2,[$rounds,#13]
-+	strb	$t3,[$rounds,#14]
-+	strb	$s3,[$rounds,#15]
-+
-+	ldmia   sp!,{r4-r12,lr}
-+	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+.size	AES_encrypt,.-AES_encrypt
-+
-+.type   _armv4_AES_encrypt,%function
-+.align	2
-+_armv4_AES_encrypt:
-+	str	lr,[sp,#-4]!		@ push lr
-+	ldr	$t1,[$key],#16
-+	ldr	$t2,[$key,#-12]
-+	ldr	$t3,[$key,#-8]
-+	ldr	$i1,[$key,#-4]
-+	ldr	$rounds,[$key,#240-16]
-+	eor	$s0,$s0,$t1
-+	eor	$s1,$s1,$t2
-+	eor	$s2,$s2,$t3
-+	eor	$s3,$s3,$i1
-+	sub	$rounds,$rounds,#1
-+	mov	lr,#255
-+
-+.Lenc_loop:
-+	and	$i2,lr,$s0,lsr#8
-+	and	$i3,lr,$s0,lsr#16
-+	and	$i1,lr,$s0
-+	mov	$s0,$s0,lsr#24
-+	ldr	$t1,[$tbl,$i1,lsl#2]	@ Te3[s0>>0]
-+	ldr	$s0,[$tbl,$s0,lsl#2]	@ Te0[s0>>24]
-+	ldr	$t2,[$tbl,$i2,lsl#2]	@ Te2[s0>>8]
-+	ldr	$t3,[$tbl,$i3,lsl#2]	@ Te1[s0>>16]
-+
-+	and	$i1,lr,$s1,lsr#16	@ i0
-+	and	$i2,lr,$s1
-+	and	$i3,lr,$s1,lsr#8
-+	mov	$s1,$s1,lsr#24
-+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Te1[s1>>16]
-+	ldr	$s1,[$tbl,$s1,lsl#2]	@ Te0[s1>>24]
-+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Te3[s1>>0]
-+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Te2[s1>>8]
-+	eor	$s0,$s0,$i1,ror#8
-+	eor	$s1,$s1,$t1,ror#24
-+	eor	$t2,$t2,$i2,ror#8
-+	eor	$t3,$t3,$i3,ror#8
-+
-+	and	$i1,lr,$s2,lsr#8	@ i0
-+	and	$i2,lr,$s2,lsr#16	@ i1
-+	and	$i3,lr,$s2
-+	mov	$s2,$s2,lsr#24
-+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Te2[s2>>8]
-+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Te1[s2>>16]
-+	ldr	$s2,[$tbl,$s2,lsl#2]	@ Te0[s2>>24]
-+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Te3[s2>>0]
-+	eor	$s0,$s0,$i1,ror#16
-+	eor	$s1,$s1,$i2,ror#8
-+	eor	$s2,$s2,$t2,ror#16
-+	eor	$t3,$t3,$i3,ror#16
-+
-+	and	$i1,lr,$s3		@ i0
-+	and	$i2,lr,$s3,lsr#8	@ i1
-+	and	$i3,lr,$s3,lsr#16	@ i2
-+	mov	$s3,$s3,lsr#24
-+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Te3[s3>>0]
-+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Te2[s3>>8]
-+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Te1[s3>>16]
-+	ldr	$s3,[$tbl,$s3,lsl#2]	@ Te0[s3>>24]
-+	eor	$s0,$s0,$i1,ror#24
-+	eor	$s1,$s1,$i2,ror#16
-+	eor	$s2,$s2,$i3,ror#8
-+	eor	$s3,$s3,$t3,ror#8
-+
-+	ldr	$t1,[$key],#16
-+	ldr	$t2,[$key,#-12]
-+	ldr	$t3,[$key,#-8]
-+	ldr	$i1,[$key,#-4]
-+	eor	$s0,$s0,$t1
-+	eor	$s1,$s1,$t2
-+	eor	$s2,$s2,$t3
-+	eor	$s3,$s3,$i1
-+
-+	subs	$rounds,$rounds,#1
-+	bne	.Lenc_loop
-+
-+	add	$tbl,$tbl,#2
-+
-+	and	$i1,lr,$s0
-+	and	$i2,lr,$s0,lsr#8
-+	and	$i3,lr,$s0,lsr#16
-+	mov	$s0,$s0,lsr#24
-+	ldrb	$t1,[$tbl,$i1,lsl#2]	@ Te4[s0>>0]
-+	ldrb	$s0,[$tbl,$s0,lsl#2]	@ Te4[s0>>24]
-+	ldrb	$t2,[$tbl,$i2,lsl#2]	@ Te4[s0>>8]
-+	ldrb	$t3,[$tbl,$i3,lsl#2]	@ Te4[s0>>16]
-+
-+	and	$i1,lr,$s1,lsr#16	@ i0
-+	and	$i2,lr,$s1
-+	and	$i3,lr,$s1,lsr#8
-+	mov	$s1,$s1,lsr#24
-+	ldrb	$i1,[$tbl,$i1,lsl#2]	@ Te4[s1>>16]
-+	ldrb	$s1,[$tbl,$s1,lsl#2]	@ Te4[s1>>24]
-+	ldrb	$i2,[$tbl,$i2,lsl#2]	@ Te4[s1>>0]
-+	ldrb	$i3,[$tbl,$i3,lsl#2]	@ Te4[s1>>8]
-+	eor	$s0,$i1,$s0,lsl#8
-+	eor	$s1,$t1,$s1,lsl#24
-+	eor	$t2,$i2,$t2,lsl#8
-+	eor	$t3,$i3,$t3,lsl#8
-+
-+	and	$i1,lr,$s2,lsr#8	@ i0
-+	and	$i2,lr,$s2,lsr#16	@ i1
-+	and	$i3,lr,$s2
-+	mov	$s2,$s2,lsr#24
-+	ldrb	$i1,[$tbl,$i1,lsl#2]	@ Te4[s2>>8]
-+	ldrb	$i2,[$tbl,$i2,lsl#2]	@ Te4[s2>>16]
-+	ldrb	$s2,[$tbl,$s2,lsl#2]	@ Te4[s2>>24]
-+	ldrb	$i3,[$tbl,$i3,lsl#2]	@ Te4[s2>>0]
-+	eor	$s0,$i1,$s0,lsl#8
-+	eor	$s1,$s1,$i2,lsl#16
-+	eor	$s2,$t2,$s2,lsl#24
-+	eor	$t3,$i3,$t3,lsl#8
-+
-+	and	$i1,lr,$s3		@ i0
-+	and	$i2,lr,$s3,lsr#8	@ i1
-+	and	$i3,lr,$s3,lsr#16	@ i2
-+	mov	$s3,$s3,lsr#24
-+	ldrb	$i1,[$tbl,$i1,lsl#2]	@ Te4[s3>>0]
-+	ldrb	$i2,[$tbl,$i2,lsl#2]	@ Te4[s3>>8]
-+	ldrb	$i3,[$tbl,$i3,lsl#2]	@ Te4[s3>>16]
-+	ldrb	$s3,[$tbl,$s3,lsl#2]	@ Te4[s3>>24]
-+	eor	$s0,$i1,$s0,lsl#8
-+	eor	$s1,$s1,$i2,lsl#8
-+	eor	$s2,$s2,$i3,lsl#16
-+	eor	$s3,$t3,$s3,lsl#24
-+
-+	ldr	lr,[sp],#4		@ pop lr
-+	ldr	$t1,[$key,#0]
-+	ldr	$t2,[$key,#4]
-+	ldr	$t3,[$key,#8]
-+	ldr	$i1,[$key,#12]
-+	eor	$s0,$s0,$t1
-+	eor	$s1,$s1,$t2
-+	eor	$s2,$s2,$t3
-+	eor	$s3,$s3,$i1
-+
-+	sub	$tbl,$tbl,#2
-+	mov	pc,lr			@ return
-+.size	_armv4_AES_encrypt,.-_armv4_AES_encrypt
-+
-+.global AES_set_encrypt_key
-+.type   AES_set_encrypt_key,%function
-+.align	5
-+AES_set_encrypt_key:
-+	sub	r3,pc,#8		@ AES_set_encrypt_key
-+	teq	r0,#0
-+	moveq	r0,#-1
-+	beq	.Labrt
-+	teq	r2,#0
-+	moveq	r0,#-1
-+	beq	.Labrt
-+
-+	teq	r1,#128
-+	beq	.Lok
-+	teq	r1,#192
-+	beq	.Lok
-+	teq	r1,#256
-+	movne	r0,#-1
-+	bne	.Labrt
-+
-+.Lok:	stmdb   sp!,{r4-r12,lr}
-+	sub	$tbl,r3,#AES_set_encrypt_key-AES_Te-1024	@ Te4
-+
-+	mov	$rounds,r0		@ inp
-+	mov	lr,r1			@ bits
-+	mov	$key,r2			@ key
-+
-+	ldrb	$s0,[$rounds,#3]	@ load input data in endian-neutral
-+	ldrb	$t1,[$rounds,#2]	@ manner...
-+	ldrb	$t2,[$rounds,#1]
-+	ldrb	$t3,[$rounds,#0]
-+	orr	$s0,$s0,$t1,lsl#8
-+	orr	$s0,$s0,$t2,lsl#16
-+	orr	$s0,$s0,$t3,lsl#24
-+	ldrb	$s1,[$rounds,#7]
-+	ldrb	$t1,[$rounds,#6]
-+	ldrb	$t2,[$rounds,#5]
-+	ldrb	$t3,[$rounds,#4]
-+	orr	$s1,$s1,$t1,lsl#8
-+	orr	$s1,$s1,$t2,lsl#16
-+	orr	$s1,$s1,$t3,lsl#24
-+	ldrb	$s2,[$rounds,#11]
-+	ldrb	$t1,[$rounds,#10]
-+	ldrb	$t2,[$rounds,#9]
-+	ldrb	$t3,[$rounds,#8]
-+	orr	$s2,$s2,$t1,lsl#8
-+	orr	$s2,$s2,$t2,lsl#16
-+	orr	$s2,$s2,$t3,lsl#24
-+	ldrb	$s3,[$rounds,#15]
-+	ldrb	$t1,[$rounds,#14]
-+	ldrb	$t2,[$rounds,#13]
-+	ldrb	$t3,[$rounds,#12]
-+	orr	$s3,$s3,$t1,lsl#8
-+	orr	$s3,$s3,$t2,lsl#16
-+	orr	$s3,$s3,$t3,lsl#24
-+	str	$s0,[$key],#16
-+	str	$s1,[$key,#-12]
-+	str	$s2,[$key,#-8]
-+	str	$s3,[$key,#-4]
-+
-+	teq	lr,#128
-+	bne	.Lnot128
-+	mov	$rounds,#10
-+	str	$rounds,[$key,#240-16]
-+	add	$t3,$tbl,#256			@ rcon
-+	mov	lr,#255
-+
-+.L128_loop:
-+	and	$t2,lr,$s3,lsr#24
-+	and	$i1,lr,$s3,lsr#16
-+	and	$i2,lr,$s3,lsr#8
-+	and	$i3,lr,$s3
-+	ldrb	$t2,[$tbl,$t2]
-+	ldrb	$i1,[$tbl,$i1]
-+	ldrb	$i2,[$tbl,$i2]
-+	ldrb	$i3,[$tbl,$i3]
-+	ldr	$t1,[$t3],#4			@ rcon[i++]
-+	orr	$t2,$t2,$i1,lsl#24
-+	orr	$t2,$t2,$i2,lsl#16
-+	orr	$t2,$t2,$i3,lsl#8
-+	eor	$t2,$t2,$t1
-+	eor	$s0,$s0,$t2			@ rk[4]=rk[0]^...
-+	eor	$s1,$s1,$s0			@ rk[5]=rk[1]^rk[4]
-+	eor	$s2,$s2,$s1			@ rk[6]=rk[2]^rk[5]
-+	eor	$s3,$s3,$s2			@ rk[7]=rk[3]^rk[6]
-+	str	$s0,[$key],#16
-+	str	$s1,[$key,#-12]
-+	str	$s2,[$key,#-8]
-+	str	$s3,[$key,#-4]
-+
-+	subs	$rounds,$rounds,#1
-+	bne	.L128_loop
-+	sub	r2,$key,#176
-+	b	.Ldone
-+
-+.Lnot128:
-+	ldrb	$i2,[$rounds,#19]
-+	ldrb	$t1,[$rounds,#18]
-+	ldrb	$t2,[$rounds,#17]
-+	ldrb	$t3,[$rounds,#16]
-+	orr	$i2,$i2,$t1,lsl#8
-+	orr	$i2,$i2,$t2,lsl#16
-+	orr	$i2,$i2,$t3,lsl#24
-+	ldrb	$i3,[$rounds,#23]
-+	ldrb	$t1,[$rounds,#22]
-+	ldrb	$t2,[$rounds,#21]
-+	ldrb	$t3,[$rounds,#20]
-+	orr	$i3,$i3,$t1,lsl#8
-+	orr	$i3,$i3,$t2,lsl#16
-+	orr	$i3,$i3,$t3,lsl#24
-+	str	$i2,[$key],#8
-+	str	$i3,[$key,#-4]
-+
-+	teq	lr,#192
-+	bne	.Lnot192
-+	mov	$rounds,#12
-+	str	$rounds,[$key,#240-24]
-+	add	$t3,$tbl,#256			@ rcon
-+	mov	lr,#255
-+	mov	$rounds,#8
-+
-+.L192_loop:
-+	and	$t2,lr,$i3,lsr#24
-+	and	$i1,lr,$i3,lsr#16
-+	and	$i2,lr,$i3,lsr#8
-+	and	$i3,lr,$i3
-+	ldrb	$t2,[$tbl,$t2]
-+	ldrb	$i1,[$tbl,$i1]
-+	ldrb	$i2,[$tbl,$i2]
-+	ldrb	$i3,[$tbl,$i3]
-+	ldr	$t1,[$t3],#4			@ rcon[i++]
-+	orr	$t2,$t2,$i1,lsl#24
-+	orr	$t2,$t2,$i2,lsl#16
-+	orr	$t2,$t2,$i3,lsl#8
-+	eor	$i3,$t2,$t1
-+	eor	$s0,$s0,$i3			@ rk[6]=rk[0]^...
-+	eor	$s1,$s1,$s0			@ rk[7]=rk[1]^rk[6]
-+	eor	$s2,$s2,$s1			@ rk[8]=rk[2]^rk[7]
-+	eor	$s3,$s3,$s2			@ rk[9]=rk[3]^rk[8]
-+	str	$s0,[$key],#24
-+	str	$s1,[$key,#-20]
-+	str	$s2,[$key,#-16]
-+	str	$s3,[$key,#-12]
-+
-+	subs	$rounds,$rounds,#1
-+	subeq	r2,$key,#216
-+	beq	.Ldone
-+
-+	ldr	$i1,[$key,#-32]
-+	ldr	$i2,[$key,#-28]
-+	eor	$i1,$i1,$s3			@ rk[10]=rk[4]^rk[9]
-+	eor	$i3,$i2,$i1			@ rk[11]=rk[5]^rk[10]
-+	str	$i1,[$key,#-8]
-+	str	$i3,[$key,#-4]
-+	b	.L192_loop
-+
-+.Lnot192:
-+	ldrb	$i2,[$rounds,#27]
-+	ldrb	$t1,[$rounds,#26]
-+	ldrb	$t2,[$rounds,#25]
-+	ldrb	$t3,[$rounds,#24]
-+	orr	$i2,$i2,$t1,lsl#8
-+	orr	$i2,$i2,$t2,lsl#16
-+	orr	$i2,$i2,$t3,lsl#24
-+	ldrb	$i3,[$rounds,#31]
-+	ldrb	$t1,[$rounds,#30]
-+	ldrb	$t2,[$rounds,#29]
-+	ldrb	$t3,[$rounds,#28]
-+	orr	$i3,$i3,$t1,lsl#8
-+	orr	$i3,$i3,$t2,lsl#16
-+	orr	$i3,$i3,$t3,lsl#24
-+	str	$i2,[$key],#8
-+	str	$i3,[$key,#-4]
-+
-+	mov	$rounds,#14
-+	str	$rounds,[$key,#240-32]
-+	add	$t3,$tbl,#256			@ rcon
-+	mov	lr,#255
-+	mov	$rounds,#7
-+
-+.L256_loop:
-+	and	$t2,lr,$i3,lsr#24
-+	and	$i1,lr,$i3,lsr#16
-+	and	$i2,lr,$i3,lsr#8
-+	and	$i3,lr,$i3
-+	ldrb	$t2,[$tbl,$t2]
-+	ldrb	$i1,[$tbl,$i1]
-+	ldrb	$i2,[$tbl,$i2]
-+	ldrb	$i3,[$tbl,$i3]
-+	ldr	$t1,[$t3],#4			@ rcon[i++]
-+	orr	$t2,$t2,$i1,lsl#24
-+	orr	$t2,$t2,$i2,lsl#16
-+	orr	$t2,$t2,$i3,lsl#8
-+	eor	$i3,$t2,$t1
-+	eor	$s0,$s0,$i3			@ rk[8]=rk[0]^...
-+	eor	$s1,$s1,$s0			@ rk[9]=rk[1]^rk[8]
-+	eor	$s2,$s2,$s1			@ rk[10]=rk[2]^rk[9]
-+	eor	$s3,$s3,$s2			@ rk[11]=rk[3]^rk[10]
-+	str	$s0,[$key],#32
-+	str	$s1,[$key,#-28]
-+	str	$s2,[$key,#-24]
-+	str	$s3,[$key,#-20]
-+
-+	subs	$rounds,$rounds,#1
-+	subeq	r2,$key,#256
-+	beq	.Ldone
-+
-+	and	$t2,lr,$s3
-+	and	$i1,lr,$s3,lsr#8
-+	and	$i2,lr,$s3,lsr#16
-+	and	$i3,lr,$s3,lsr#24
-+	ldrb	$t2,[$tbl,$t2]
-+	ldrb	$i1,[$tbl,$i1]
-+	ldrb	$i2,[$tbl,$i2]
-+	ldrb	$i3,[$tbl,$i3]
-+	orr	$t2,$t2,$i1,lsl#8
-+	orr	$t2,$t2,$i2,lsl#16
-+	orr	$t2,$t2,$i3,lsl#24
-+
-+	ldr	$t1,[$key,#-48]
-+	ldr	$i1,[$key,#-44]
-+	ldr	$i2,[$key,#-40]
-+	ldr	$i3,[$key,#-36]
-+	eor	$t1,$t1,$t2			@ rk[12]=rk[4]^...
-+	eor	$i1,$i1,$t1			@ rk[13]=rk[5]^rk[12]
-+	eor	$i2,$i2,$i1			@ rk[14]=rk[6]^rk[13]
-+	eor	$i3,$i3,$i2			@ rk[15]=rk[7]^rk[14]
-+	str	$t1,[$key,#-16]
-+	str	$i1,[$key,#-12]
-+	str	$i2,[$key,#-8]
-+	str	$i3,[$key,#-4]
-+	b	.L256_loop
-+
-+.Ldone:	mov	r0,#0
-+	ldmia   sp!,{r4-r12,lr}
-+.Labrt:	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+.size	AES_set_encrypt_key,.-AES_set_encrypt_key
-+
-+.global AES_set_decrypt_key
-+.type   AES_set_decrypt_key,%function
-+.align	5
-+AES_set_decrypt_key:
-+	str	lr,[sp,#-4]!            @ push lr
-+	bl	AES_set_encrypt_key
-+	teq	r0,#0
-+	ldrne	lr,[sp],#4              @ pop lr
-+	bne	.Labrt
-+
-+	stmdb   sp!,{r4-r12}
-+
-+	ldr	$rounds,[r2,#240]	@ AES_set_encrypt_key preserves r2,
-+	mov	$key,r2			@ which is AES_KEY *key
-+	mov	$i1,r2
-+	add	$i2,r2,$rounds,lsl#4
-+
-+.Linv:	ldr	$s0,[$i1]
-+	ldr	$s1,[$i1,#4]
-+	ldr	$s2,[$i1,#8]
-+	ldr	$s3,[$i1,#12]
-+	ldr	$t1,[$i2]
-+	ldr	$t2,[$i2,#4]
-+	ldr	$t3,[$i2,#8]
-+	ldr	$i3,[$i2,#12]
-+	str	$s0,[$i2],#-16
-+	str	$s1,[$i2,#16+4]
-+	str	$s2,[$i2,#16+8]
-+	str	$s3,[$i2,#16+12]
-+	str	$t1,[$i1],#16
-+	str	$t2,[$i1,#-12]
-+	str	$t3,[$i1,#-8]
-+	str	$i3,[$i1,#-4]
-+	teq	$i1,$i2
-+	bne	.Linv
-+___
-+$mask80=$i1;
-+$mask1b=$i2;
-+$mask7f=$i3;
-+$code.=<<___;
-+	ldr	$s0,[$key,#16]!		@ prefetch tp1
-+	mov	$mask80,#0x80
-+	mov	$mask1b,#0x1b
-+	orr	$mask80,$mask80,#0x8000
-+	orr	$mask1b,$mask1b,#0x1b00
-+	orr	$mask80,$mask80,$mask80,lsl#16
-+	orr	$mask1b,$mask1b,$mask1b,lsl#16
-+	sub	$rounds,$rounds,#1
-+	mvn	$mask7f,$mask80
-+	mov	$rounds,$rounds,lsl#2	@ (rounds-1)*4
-+
-+.Lmix:	and	$t1,$s0,$mask80
-+	and	$s1,$s0,$mask7f
-+	sub	$t1,$t1,$t1,lsr#7
-+	and	$t1,$t1,$mask1b
-+	eor	$s1,$t1,$s1,lsl#1	@ tp2
-+
-+	and	$t1,$s1,$mask80
-+	and	$s2,$s1,$mask7f
-+	sub	$t1,$t1,$t1,lsr#7
-+	and	$t1,$t1,$mask1b
-+	eor	$s2,$t1,$s2,lsl#1	@ tp4
-+
-+	and	$t1,$s2,$mask80
-+	and	$s3,$s2,$mask7f
-+	sub	$t1,$t1,$t1,lsr#7
-+	and	$t1,$t1,$mask1b
-+	eor	$s3,$t1,$s3,lsl#1	@ tp8
-+
-+	eor	$t1,$s1,$s2
-+	eor	$t2,$s0,$s3		@ tp9
-+	eor	$t1,$t1,$s3		@ tpe
-+	eor	$t1,$t1,$s1,ror#24
-+	eor	$t1,$t1,$t2,ror#24	@ ^= ROTATE(tpb=tp9^tp2,8)
-+	eor	$t1,$t1,$s2,ror#16
-+	eor	$t1,$t1,$t2,ror#16	@ ^= ROTATE(tpd=tp9^tp4,16)
-+	eor	$t1,$t1,$t2,ror#8	@ ^= ROTATE(tp9,24)
-+
-+	ldr	$s0,[$key,#4]		@ prefetch tp1
-+	str	$t1,[$key],#4
-+	subs	$rounds,$rounds,#1
-+	bne	.Lmix
-+
-+	mov	r0,#0
-+	ldmia   sp!,{r4-r12,lr}
-+	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+.size	AES_set_decrypt_key,.-AES_set_decrypt_key
-+
-+.type	AES_Td,%object
-+.align	5
-+AES_Td:
-+.word	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96
-+.word	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393
-+.word	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25
-+.word	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f
-+.word	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1
-+.word	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6
-+.word	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da
-+.word	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844
-+.word	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd
-+.word	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4
-+.word	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45
-+.word	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94
-+.word	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7
-+.word	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a
-+.word	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5
-+.word	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c
-+.word	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1
-+.word	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a
-+.word	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75
-+.word	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051
-+.word	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46
-+.word	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff
-+.word	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77
-+.word	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb
-+.word	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000
-+.word	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e
-+.word	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927
-+.word	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a
-+.word	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e
-+.word	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16
-+.word	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d
-+.word	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8
-+.word	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd
-+.word	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34
-+.word	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163
-+.word	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120
-+.word	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d
-+.word	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0
-+.word	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422
-+.word	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef
-+.word	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36
-+.word	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4
-+.word	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662
-+.word	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5
-+.word	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3
-+.word	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b
-+.word	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8
-+.word	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6
-+.word	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6
-+.word	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0
-+.word	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815
-+.word	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f
-+.word	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df
-+.word	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f
-+.word	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e
-+.word	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713
-+.word	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89
-+.word	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c
-+.word	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf
-+.word	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86
-+.word	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f
-+.word	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541
-+.word	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190
-+.word	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
-+@ Td4[256]
-+.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
-+.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
-+.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
-+.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
-+.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
-+.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
-+.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
-+.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
-+.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
-+.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
-+.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
-+.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
-+.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
-+.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
-+.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
-+.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
-+.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
-+.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
-+.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
-+.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
-+.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
-+.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
-+.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
-+.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
-+.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
-+.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
-+.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
-+.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
-+.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
-+.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
-+.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
-+.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-+.size	AES_Td,.-AES_Td
-+
-+@ void AES_decrypt(const unsigned char *in, unsigned char *out,
-+@ 		 const AES_KEY *key) {
-+.global AES_decrypt
-+.type   AES_decrypt,%function
-+.align	5
-+AES_decrypt:
-+	sub	r3,pc,#8		@ AES_decrypt
-+	stmdb   sp!,{r1,r4-r12,lr}
-+	mov	$rounds,r0		@ inp
-+	mov	$key,r2
-+	sub	$tbl,r3,#AES_decrypt-AES_Td		@ Td
-+
-+	ldrb	$s0,[$rounds,#3]	@ load input data in endian-neutral
-+	ldrb	$t1,[$rounds,#2]	@ manner...
-+	ldrb	$t2,[$rounds,#1]
-+	ldrb	$t3,[$rounds,#0]
-+	orr	$s0,$s0,$t1,lsl#8
-+	orr	$s0,$s0,$t2,lsl#16
-+	orr	$s0,$s0,$t3,lsl#24
-+	ldrb	$s1,[$rounds,#7]
-+	ldrb	$t1,[$rounds,#6]
-+	ldrb	$t2,[$rounds,#5]
-+	ldrb	$t3,[$rounds,#4]
-+	orr	$s1,$s1,$t1,lsl#8
-+	orr	$s1,$s1,$t2,lsl#16
-+	orr	$s1,$s1,$t3,lsl#24
-+	ldrb	$s2,[$rounds,#11]
-+	ldrb	$t1,[$rounds,#10]
-+	ldrb	$t2,[$rounds,#9]
-+	ldrb	$t3,[$rounds,#8]
-+	orr	$s2,$s2,$t1,lsl#8
-+	orr	$s2,$s2,$t2,lsl#16
-+	orr	$s2,$s2,$t3,lsl#24
-+	ldrb	$s3,[$rounds,#15]
-+	ldrb	$t1,[$rounds,#14]
-+	ldrb	$t2,[$rounds,#13]
-+	ldrb	$t3,[$rounds,#12]
-+	orr	$s3,$s3,$t1,lsl#8
-+	orr	$s3,$s3,$t2,lsl#16
-+	orr	$s3,$s3,$t3,lsl#24
-+
-+	bl	_armv4_AES_decrypt
-+
-+	ldr	$rounds,[sp],#4		@ pop out
-+	mov	$t1,$s0,lsr#24		@ write output in endian-neutral
-+	mov	$t2,$s0,lsr#16		@ manner...
-+	mov	$t3,$s0,lsr#8
-+	strb	$t1,[$rounds,#0]
-+	strb	$t2,[$rounds,#1]
-+	strb	$t3,[$rounds,#2]
-+	strb	$s0,[$rounds,#3]
-+	mov	$t1,$s1,lsr#24
-+	mov	$t2,$s1,lsr#16
-+	mov	$t3,$s1,lsr#8
-+	strb	$t1,[$rounds,#4]
-+	strb	$t2,[$rounds,#5]
-+	strb	$t3,[$rounds,#6]
-+	strb	$s1,[$rounds,#7]
-+	mov	$t1,$s2,lsr#24
-+	mov	$t2,$s2,lsr#16
-+	mov	$t3,$s2,lsr#8
-+	strb	$t1,[$rounds,#8]
-+	strb	$t2,[$rounds,#9]
-+	strb	$t3,[$rounds,#10]
-+	strb	$s2,[$rounds,#11]
-+	mov	$t1,$s3,lsr#24
-+	mov	$t2,$s3,lsr#16
-+	mov	$t3,$s3,lsr#8
-+	strb	$t1,[$rounds,#12]
-+	strb	$t2,[$rounds,#13]
-+	strb	$t3,[$rounds,#14]
-+	strb	$s3,[$rounds,#15]
-+
-+	ldmia   sp!,{r4-r12,lr}
-+	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+.size	AES_decrypt,.-AES_decrypt
-+
-+.type   _armv4_AES_decrypt,%function
-+.align	2
-+_armv4_AES_decrypt:
-+	str	lr,[sp,#-4]!		@ push lr
-+	ldr	$t1,[$key],#16
-+	ldr	$t2,[$key,#-12]
-+	ldr	$t3,[$key,#-8]
-+	ldr	$i1,[$key,#-4]
-+	ldr	$rounds,[$key,#240-16]
-+	eor	$s0,$s0,$t1
-+	eor	$s1,$s1,$t2
-+	eor	$s2,$s2,$t3
-+	eor	$s3,$s3,$i1
-+	sub	$rounds,$rounds,#1
-+	mov	lr,#255
-+
-+.Ldec_loop:
-+	and	$i1,lr,$s0,lsr#16
-+	and	$i2,lr,$s0,lsr#8
-+	and	$i3,lr,$s0
-+	mov	$s0,$s0,lsr#24
-+	ldr	$t1,[$tbl,$i1,lsl#2]	@ Td1[s0>>16]
-+	ldr	$s0,[$tbl,$s0,lsl#2]	@ Td0[s0>>24]
-+	ldr	$t2,[$tbl,$i2,lsl#2]	@ Td2[s0>>8]
-+	ldr	$t3,[$tbl,$i3,lsl#2]	@ Td3[s0>>0]
-+
-+	and	$i1,lr,$s1		@ i0
-+	and	$i2,lr,$s1,lsr#16
-+	and	$i3,lr,$s1,lsr#8
-+	mov	$s1,$s1,lsr#24
-+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Td3[s1>>0]
-+	ldr	$s1,[$tbl,$s1,lsl#2]	@ Td0[s1>>24]
-+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Td1[s1>>16]
-+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Td2[s1>>8]
-+	eor	$s0,$s0,$i1,ror#24
-+	eor	$s1,$s1,$t1,ror#8
-+	eor	$t2,$i2,$t2,ror#8
-+	eor	$t3,$i3,$t3,ror#8
-+
-+	and	$i1,lr,$s2,lsr#8	@ i0
-+	and	$i2,lr,$s2		@ i1
-+	and	$i3,lr,$s2,lsr#16
-+	mov	$s2,$s2,lsr#24
-+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Td2[s2>>8]
-+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Td3[s2>>0]
-+	ldr	$s2,[$tbl,$s2,lsl#2]	@ Td0[s2>>24]
-+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Td1[s2>>16]
-+	eor	$s0,$s0,$i1,ror#16
-+	eor	$s1,$s1,$i2,ror#24
-+	eor	$s2,$s2,$t2,ror#8
-+	eor	$t3,$i3,$t3,ror#8
-+
-+	and	$i1,lr,$s3,lsr#16	@ i0
-+	and	$i2,lr,$s3,lsr#8	@ i1
-+	and	$i3,lr,$s3		@ i2
-+	mov	$s3,$s3,lsr#24
-+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Td1[s3>>16]
-+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Td2[s3>>8]
-+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Td3[s3>>0]
-+	ldr	$s3,[$tbl,$s3,lsl#2]	@ Td0[s3>>24]
-+	eor	$s0,$s0,$i1,ror#8
-+	eor	$s1,$s1,$i2,ror#16
-+	eor	$s2,$s2,$i3,ror#24
-+	eor	$s3,$s3,$t3,ror#8
-+
-+	ldr	$t1,[$key],#16
-+	ldr	$t2,[$key,#-12]
-+	ldr	$t3,[$key,#-8]
-+	ldr	$i1,[$key,#-4]
-+	eor	$s0,$s0,$t1
-+	eor	$s1,$s1,$t2
-+	eor	$s2,$s2,$t3
-+	eor	$s3,$s3,$i1
-+
-+	subs	$rounds,$rounds,#1
-+	bne	.Ldec_loop
-+
-+	add	$tbl,$tbl,#1024
-+
-+	ldr	$t1,[$tbl,#0]		@ prefetch Td4
-+	ldr	$t2,[$tbl,#32]
-+	ldr	$t3,[$tbl,#64]
-+	ldr	$i1,[$tbl,#96]
-+	ldr	$i2,[$tbl,#128]
-+	ldr	$i3,[$tbl,#160]
-+	ldr	$t1,[$tbl,#192]
-+	ldr	$t2,[$tbl,#224]
-+
-+	and	$i1,lr,$s0,lsr#16
-+	and	$i2,lr,$s0,lsr#8
-+	and	$i3,lr,$s0
-+	ldrb	$s0,[$tbl,$s0,lsr#24]	@ Td4[s0>>24]
-+	ldrb	$t1,[$tbl,$i1]		@ Td4[s0>>16]
-+	ldrb	$t2,[$tbl,$i2]		@ Td4[s0>>8]
-+	ldrb	$t3,[$tbl,$i3]		@ Td4[s0>>0]
-+
-+	and	$i1,lr,$s1		@ i0
-+	and	$i2,lr,$s1,lsr#16
-+	and	$i3,lr,$s1,lsr#8
-+	ldrb	$i1,[$tbl,$i1]		@ Td4[s1>>0]
-+	ldrb	$s1,[$tbl,$s1,lsr#24]	@ Td4[s1>>24]
-+	ldrb	$i2,[$tbl,$i2]		@ Td4[s1>>16]
-+	ldrb	$i3,[$tbl,$i3]		@ Td4[s1>>8]
-+	eor	$s0,$i1,$s0,lsl#24
-+	eor	$s1,$t1,$s1,lsl#8
-+	eor	$t2,$t2,$i2,lsl#8
-+	eor	$t3,$t3,$i3,lsl#8
-+
-+	and	$i1,lr,$s2,lsr#8	@ i0
-+	and	$i2,lr,$s2		@ i1
-+	and	$i3,lr,$s2,lsr#16
-+	ldrb	$i1,[$tbl,$i1]		@ Td4[s2>>8]
-+	ldrb	$i2,[$tbl,$i2]		@ Td4[s2>>0]
-+	ldrb	$s2,[$tbl,$s2,lsr#24]	@ Td4[s2>>24]
-+	ldrb	$i3,[$tbl,$i3]		@ Td4[s2>>16]
-+	eor	$s0,$s0,$i1,lsl#8
-+	eor	$s1,$i2,$s1,lsl#16
-+	eor	$s2,$t2,$s2,lsl#16
-+	eor	$t3,$t3,$i3,lsl#16
-+
-+	and	$i1,lr,$s3,lsr#16	@ i0
-+	and	$i2,lr,$s3,lsr#8	@ i1
-+	and	$i3,lr,$s3		@ i2
-+	ldrb	$i1,[$tbl,$i1]		@ Td4[s3>>16]
-+	ldrb	$i2,[$tbl,$i2]		@ Td4[s3>>8]
-+	ldrb	$i3,[$tbl,$i3]		@ Td4[s3>>0]
-+	ldrb	$s3,[$tbl,$s3,lsr#24]	@ Td4[s3>>24]
-+	eor	$s0,$s0,$i1,lsl#16
-+	eor	$s1,$s1,$i2,lsl#8
-+	eor	$s2,$i3,$s2,lsl#8
-+	eor	$s3,$t3,$s3,lsl#24
-+
-+	ldr	lr,[sp],#4		@ pop lr
-+	ldr	$t1,[$key,#0]
-+	ldr	$t2,[$key,#4]
-+	ldr	$t3,[$key,#8]
-+	ldr	$i1,[$key,#12]
-+	eor	$s0,$s0,$t1
-+	eor	$s1,$s1,$t2
-+	eor	$s2,$s2,$t3
-+	eor	$s3,$s3,$i1
-+
-+	sub	$tbl,$tbl,#1024
-+	mov	pc,lr			@ return
-+.size	_armv4_AES_decrypt,.-_armv4_AES_decrypt
-+.asciz	"AES for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
-+___
-+
-+$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
-+print $code;
---- /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 <appro@openssl.org>"
-+.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 <appro@fy.chalmers.se> for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# January 2007.
-+
-+# Montgomery multiplication for ARMv4.
-+#
-+# Performance improvement naturally varies among CPU implementations
-+# and compilers. The code was observed to provide +65-35% improvement
-+# [depending on key length, less for longer keys] on ARM920T, and
-+# +115-80% on Intel IXP425. This is compared to pre-bn_mul_mont code
-+# base and compiler generated code with in-lined umull and even umlal
-+# instructions. The latter means that this code didn't really have an 
-+# "advantage" of utilizing some "secret" instruction.
-+#
-+# The code is interoperable with Thumb ISA and is rather compact, less
-+# than 1/2KB. Windows CE port would be trivial, as it's exclusively
-+# about decorations, ABI and instruction syntax are identical.
-+
-+$num="r0";	# starts as num argument, but holds &tp[num-1]
-+$ap="r1";
-+$bp="r2"; $bi="r2"; $rp="r2";
-+$np="r3";
-+$tp="r4";
-+$aj="r5";
-+$nj="r6";
-+$tj="r7";
-+$n0="r8";
-+###########	# r9 is reserved by ELF as platform specific, e.g. TLS pointer
-+$alo="r10";	# sl, gcc uses it to keep @GOT
-+$ahi="r11";	# fp
-+$nlo="r12";	# ip
-+###########	# r13 is stack pointer
-+$nhi="r14";	# lr
-+###########	# r15 is program counter
-+
-+#### argument block layout relative to &tp[num-1], a.k.a. $num
-+$_rp="$num,#12*4";
-+# ap permanently resides in r1
-+$_bp="$num,#13*4";
-+# np permanently resides in r3
-+$_n0="$num,#14*4";
-+$_num="$num,#15*4";	$_bpend=$_num;
-+
-+$code=<<___;
-+.text
-+
-+.global	bn_mul_mont
-+.type	bn_mul_mont,%function
-+
-+.align	2
-+bn_mul_mont:
-+	stmdb	sp!,{r0,r2}		@ sp points at argument block
-+	ldr	$num,[sp,#3*4]		@ load num
-+	cmp	$num,#2
-+	movlt	r0,#0
-+	addlt	sp,sp,#2*4
-+	blt	.Labrt
-+
-+	stmdb	sp!,{r4-r12,lr}		@ save 10 registers
-+
-+	mov	$num,$num,lsl#2		@ rescale $num for byte count
-+	sub	sp,sp,$num		@ alloca(4*num)
-+	sub	sp,sp,#4		@ +extra dword
-+	sub	$num,$num,#4		@ "num=num-1"
-+	add	$tp,$bp,$num		@ &bp[num-1]
-+
-+	add	$num,sp,$num		@ $num to point at &tp[num-1]
-+	ldr	$n0,[$_n0]		@ &n0
-+	ldr	$bi,[$bp]		@ bp[0]
-+	ldr	$aj,[$ap],#4		@ ap[0],ap++
-+	ldr	$nj,[$np],#4		@ np[0],np++
-+	ldr	$n0,[$n0]		@ *n0
-+	str	$tp,[$_bpend]		@ save &bp[num]
-+
-+	umull	$alo,$ahi,$aj,$bi	@ ap[0]*bp[0]
-+	str	$n0,[$_n0]		@ save n0 value
-+	mul	$n0,$alo,$n0		@ "tp[0]"*n0
-+	mov	$nlo,#0
-+	umlal	$alo,$nlo,$nj,$n0	@ np[0]*n0+"t[0]"
-+	mov	$tp,sp
-+
-+.L1st:
-+	ldr	$aj,[$ap],#4		@ ap[j],ap++
-+	mov	$alo,$ahi
-+	mov	$ahi,#0
-+	umlal	$alo,$ahi,$aj,$bi	@ ap[j]*bp[0]
-+	ldr	$nj,[$np],#4		@ np[j],np++
-+	mov	$nhi,#0
-+	umlal	$nlo,$nhi,$nj,$n0	@ np[j]*n0
-+	adds	$nlo,$nlo,$alo
-+	str	$nlo,[$tp],#4		@ tp[j-1]=,tp++
-+	adc	$nlo,$nhi,#0
-+	cmp	$tp,$num
-+	bne	.L1st
-+
-+	adds	$nlo,$nlo,$ahi
-+	mov	$nhi,#0
-+	adc	$nhi,$nhi,#0
-+	ldr	$tp,[$_bp]		@ restore bp
-+	str	$nlo,[$num]		@ tp[num-1]=
-+	ldr	$n0,[$_n0]		@ restore n0
-+	str	$nhi,[$num,#4]		@ tp[num]=
-+
-+.Louter:
-+	sub	$tj,$num,sp		@ "original" $num-1 value
-+	sub	$ap,$ap,$tj		@ "rewind" ap to &ap[1]
-+	sub	$np,$np,$tj		@ "rewind" np to &np[1]
-+	ldr	$bi,[$tp,#4]!		@ *(++bp)
-+	ldr	$aj,[$ap,#-4]		@ ap[0]
-+	ldr	$nj,[$np,#-4]		@ np[0]
-+	ldr	$alo,[sp]		@ tp[0]
-+	ldr	$tj,[sp,#4]		@ tp[1]
-+
-+	mov	$ahi,#0
-+	umlal	$alo,$ahi,$aj,$bi	@ ap[0]*bp[i]+tp[0]
-+	str	$tp,[$_bp]		@ save bp
-+	mul	$n0,$alo,$n0
-+	mov	$nlo,#0
-+	umlal	$alo,$nlo,$nj,$n0	@ np[0]*n0+"tp[0]"
-+	mov	$tp,sp
-+
-+.Linner:
-+	ldr	$aj,[$ap],#4		@ ap[j],ap++
-+	adds	$alo,$ahi,$tj		@ +=tp[j]
-+	mov	$ahi,#0
-+	umlal	$alo,$ahi,$aj,$bi	@ ap[j]*bp[i]
-+	ldr	$nj,[$np],#4		@ np[j],np++
-+	mov	$nhi,#0
-+	umlal	$nlo,$nhi,$nj,$n0	@ np[j]*n0
-+	ldr	$tj,[$tp,#8]		@ tp[j+1]
-+	adc	$ahi,$ahi,#0
-+	adds	$nlo,$nlo,$alo
-+	str	$nlo,[$tp],#4		@ tp[j-1]=,tp++
-+	adc	$nlo,$nhi,#0
-+	cmp	$tp,$num
-+	bne	.Linner
-+
-+	adds	$nlo,$nlo,$ahi
-+	mov	$nhi,#0
-+	adc	$nhi,$nhi,#0
-+	adds	$nlo,$nlo,$tj
-+	adc	$nhi,$nhi,#0
-+	ldr	$tp,[$_bp]		@ restore bp
-+	ldr	$tj,[$_bpend]		@ restore &bp[num]
-+	str	$nlo,[$num]		@ tp[num-1]=
-+	ldr	$n0,[$_n0]		@ restore n0
-+	str	$nhi,[$num,#4]		@ tp[num]=
-+
-+	cmp	$tp,$tj
-+	bne	.Louter
-+
-+	ldr	$rp,[$_rp]		@ pull rp
-+	add	$num,$num,#4		@ $num to point at &tp[num]
-+	sub	$aj,$num,sp		@ "original" num value
-+	mov	$tp,sp			@ "rewind" $tp
-+	mov	$ap,$tp			@ "borrow" $ap
-+	sub	$np,$np,$aj		@ "rewind" $np to &np[0]
-+
-+	subs	$tj,$tj,$tj		@ "clear" carry flag
-+.Lsub:	ldr	$tj,[$tp],#4
-+	ldr	$nj,[$np],#4
-+	sbcs	$tj,$tj,$nj		@ tp[j]-np[j]
-+	str	$tj,[$rp],#4		@ rp[j]=
-+	teq	$tp,$num		@ preserve carry
-+	bne	.Lsub
-+	sbcs	$nhi,$nhi,#0		@ upmost carry
-+	mov	$tp,sp			@ "rewind" $tp
-+	sub	$rp,$rp,$aj		@ "rewind" $rp
-+
-+	and	$ap,$tp,$nhi
-+	bic	$np,$rp,$nhi
-+	orr	$ap,$ap,$np		@ ap=borrow?tp:rp
-+
-+.Lcopy:	ldr	$tj,[$ap],#4		@ copy or in-place refresh
-+	str	sp,[$tp],#4		@ zap tp
-+	str	$tj,[$rp],#4
-+	cmp	$tp,$num
-+	bne	.Lcopy
-+
-+	add	sp,$num,#4		@ skip over tp[num+1]
-+	ldmia	sp!,{r4-r12,lr}		@ restore registers
-+	add	sp,sp,#2*4		@ skip over {r0,r2}
-+	mov	r0,#1
-+.Labrt:	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+.size	bn_mul_mont,.-bn_mul_mont
-+.asciz	"Montgomery multiplication for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
-+___
-+
-+$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
-+print $code;
-+close STDOUT;
---- /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 <appro@openssl.org>"
-+.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 <appro@fy.chalmers.se> for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# 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 <appro@openssl.org>"
---- /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 <appro@fy.chalmers.se> for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# 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 <appro@openssl.org>"
---- /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 <appro@fy.chalmers.se> for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# 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 <appro@openssl.org>"
diff --git a/patches/bad_version.patch b/patches/bad_version.patch
deleted file mode 100644
index e88fecb..0000000
--- a/patches/bad_version.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-diff --git openssl-0.9.8m/ssl/s3_pkt.c openssl-0.9.8m/ssl/s3_pkt.c
-index b4abc11..5964c1d 100644
---- openssl-0.9.8m/ssl/s3_pkt.c
-+++ openssl-0.9.8m/ssl/s3_pkt.c
-@@ -292,9 +292,10 @@ again:
- 			if (version != s->version)
- 				{
- 				SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
--				/* Send back error using their
--				 * version number :-) */
--				s->version=version;
-+				/* If the major versions match then we'll send
-+				 * the error back using the peer's version. */
-+				if ((s->version & 0xFF00) == (version & 0xFF00))
-+					s->version = version;
- 				al=SSL_AD_PROTOCOL_VERSION;
- 				goto f_err;
- 				}
diff --git a/patches/crypto_Android.mk b/patches/crypto_Android.mk
index 23e56b0..14bac8e 100644
--- a/patches/crypto_Android.mk
+++ b/patches/crypto_Android.mk
@@ -3,11 +3,11 @@
 
 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
+	LOCAL_SRC_FILES:= aes/asm/aes-armv4.s \
+	                  bn/asm/armv4-mont.s \
+	                  sha/asm/sha1-armv4-large.s \
+	                  sha/asm/sha256-armv4.s \
+	                  sha/asm/sha512-armv4.s
 else
 	LOCAL_SRC_FILES:= aes/aes_core.c
 endif
@@ -23,255 +23,281 @@
 	mem_clr.c \
 	mem_dbg.c \
 	cversion.c \
-	dyn_lck.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_ecb.c \
+	aes/aes_misc.c \
+	aes/aes_ofb.c \
 	aes/aes_wrap.c \
-	asn1/a_object.c \
 	asn1/a_bitstr.c \
-	asn1/a_utctm.c \
+	asn1/a_bool.c \
+	asn1/a_bytes.c \
+	asn1/a_d2i_fp.c \
+	asn1/a_digest.c \
+	asn1/a_dup.c \
+	asn1/a_enum.c \
 	asn1/a_gentm.c \
-	asn1/a_time.c \
+	asn1/a_i2d_fp.c \
 	asn1/a_int.c \
+	asn1/a_mbstr.c \
+	asn1/a_object.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/a_strnid.c \
+	asn1/a_time.c \
+	asn1/a_type.c \
+	asn1/a_utctm.c \
+	asn1/a_utf8.c \
+	asn1/a_verify.c \
+	asn1/ameth_lib.c \
+	asn1/asn1_err.c \
+	asn1/asn1_gen.c \
+	asn1/asn1_lib.c \
+	asn1/asn1_par.c \
+	asn1/asn_mime.c \
+	asn1/asn_moid.c \
+	asn1/asn_pack.c \
+	asn1/bio_asn1.c \
+	asn1/bio_ndef.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/d2i_pu.c \
+	asn1/evp_asn1.c \
+	asn1/f_enum.c \
 	asn1/f_int.c \
 	asn1/f_string.c \
+	asn1/i2d_pr.c \
+	asn1/i2d_pu.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/nsseq.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 \
+	asn1/t_bitst.c \
+	asn1/t_crl.c \
+	asn1/t_pkey.c \
+	asn1/t_req.c \
+	asn1/t_spki.c \
+	asn1/t_x509.c \
+	asn1/t_x509a.c \
+	asn1/tasn_dec.c \
+	asn1/tasn_enc.c \
+	asn1/tasn_fre.c \
+	asn1/tasn_new.c \
+	asn1/tasn_prn.c \
+	asn1/tasn_typ.c \
+	asn1/tasn_utl.c \
+	asn1/x_algor.c \
+	asn1/x_attrib.c \
+	asn1/x_bignum.c \
+	asn1/x_crl.c \
+	asn1/x_exten.c \
+	asn1/x_info.c \
+	asn1/x_long.c \
+	asn1/x_name.c \
+	asn1/x_nx509.c \
+	asn1/x_pkey.c \
+	asn1/x_pubkey.c \
+	asn1/x_req.c \
+	asn1/x_sig.c \
+	asn1/x_spki.c \
+	asn1/x_val.c \
+	asn1/x_x509.c \
+	asn1/x_x509a.c \
+	bio/b_dump.c \
+	bio/b_print.c \
+	bio/b_sock.c \
+	bio/bf_buff.c \
+	bio/bf_nbio.c \
+	bio/bf_null.c \
 	bio/bio_cb.c \
 	bio/bio_err.c \
-	bio/bss_mem.c \
-	bio/bss_null.c \
+	bio/bio_lib.c \
+	bio/bss_acpt.c \
+	bio/bss_bio.c \
+	bio/bss_conn.c \
+	bio/bss_dgram.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 \
+	bio/bss_mem.c \
+	bio/bss_null.c \
+	bio/bss_sock.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_blind.c \
+	bn/bn_ctx.c \
+	bn/bn_div.c \
+	bn/bn_err.c \
+	bn/bn_exp.c \
+	bn/bn_exp2.c \
+	bn/bn_gcd.c \
+	bn/bn_gf2m.c \
+	bn/bn_kron.c \
+	bn/bn_lib.c \
+	bn/bn_mod.c \
 	bn/bn_mont.c \
 	bn/bn_mpi.c \
-	bn/bn_exp2.c \
+	bn/bn_mul.c \
 	bn/bn_nist.c \
-	bn/bn_gf2m.c \
-	bn/bn_x931p.c \
-	buffer/buffer.c \
+	bn/bn_prime.c \
+	bn/bn_print.c \
+	bn/bn_rand.c \
+	bn/bn_recp.c \
+	bn/bn_shift.c \
+	bn/bn_sqr.c \
+	bn/bn_sqrt.c \
+	bn/bn_word.c \
 	buffer/buf_err.c \
-	buffer/buf_str.c \
-	comp/comp_lib.c \
-	comp/comp_err.c \
+	buffer/buffer.c \
 	comp/c_rle.c \
 	comp/c_zlib.c \
-	conf/conf_err.c \
-	conf/conf_lib.c \
+	comp/comp_err.c \
+	comp/comp_lib.c \
 	conf/conf_api.c \
 	conf/conf_def.c \
-	conf/conf_mod.c \
+	conf/conf_err.c \
+	conf/conf_lib.c \
 	conf/conf_mall.c \
+	conf/conf_mod.c \
 	conf/conf_sap.c \
 	des/cbc_cksm.c \
 	des/cbc_enc.c \
+	des/cfb64ede.c \
 	des/cfb64enc.c \
 	des/cfb_enc.c \
-	des/des_lib.c \
+	des/des_enc.c \
+	des/des_old.c \
+	des/des_old2.c \
 	des/ecb3_enc.c \
 	des/ecb_enc.c \
+	des/ede_cbcm_enc.c \
 	des/enc_read.c \
 	des/enc_writ.c \
 	des/fcrypt.c \
+	des/fcrypt_b.c \
+	des/ofb64ede.c \
 	des/ofb64enc.c \
 	des/ofb_enc.c \
 	des/pcbc_enc.c \
 	des/qud_cksm.c \
 	des/rand_key.c \
+	des/read2pwd.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 \
+	des/xcbc_enc.c \
+	dh/dh_ameth.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 \
+	dh/dh_pmeth.c \
+	dsa/dsa_ameth.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_pmeth.c \
+	dsa/dsa_prn.c \
+	dsa/dsa_sign.c \
+	dsa/dsa_vrf.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 \
+	dso/dso_win32.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/bio_b64.c \
+	evp/bio_enc.c \
+	evp/bio_md.c \
+	evp/bio_ok.c \
+	evp/c_all.c \
+	evp/c_allc.c \
+	evp/c_alld.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_aes.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_null.c \
+	evp/e_old.c \
 	evp/e_rc2.c \
+	evp/e_rc4.c \
 	evp/e_rc5.c \
-	evp/m_null.c \
+	evp/e_xcbc_d.c \
+	evp/encode.c \
+	evp/evp_acnf.c \
+	evp/evp_enc.c \
+	evp/evp_err.c \
+	evp/evp_key.c \
+	evp/evp_lib.c \
+	evp/evp_pbe.c \
+	evp/evp_pkey.c \
+	evp/m_dss.c \
+	evp/m_dss1.c \
 	evp/m_md2.c \
 	evp/m_md4.c \
 	evp/m_md5.c \
+	evp/m_mdc2.c \
+	evp/m_null.c \
+	evp/m_ripemd.c \
 	evp/m_sha.c \
 	evp/m_sha1.c \
-	evp/m_dss.c \
-	evp/m_dss1.c \
-	evp/m_mdc2.c \
+	evp/m_sigver.c \
+	evp/m_wp.c \
+	evp/names.c \
+	evp/p5_crpt.c \
+	evp/p5_crpt2.c \
+	evp/p_dec.c \
+	evp/p_enc.c \
+	evp/p_lib.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 \
+	evp/pmeth_fn.c \
+	evp/pmeth_gn.c \
+	evp/pmeth_lib.c \
+	hmac/hm_ameth.c \
+	hmac/hm_pmeth.c \
 	hmac/hmac.c \
 	krb5/krb5_asn.c \
-	lhash/lhash.c \
 	lhash/lh_stats.c \
+	lhash/lhash.c \
 	md4/md4_dgst.c \
 	md4/md4_one.c \
 	md5/md5_dgst.c \
 	md5/md5_one.c \
+	modes/cbc128.c \
+	modes/cfb128.c \
+	modes/ctr128.c \
+	modes/ofb128.c \
 	objects/o_names.c \
 	objects/obj_dat.c \
-	objects/obj_lib.c \
 	objects/obj_err.c \
+	objects/obj_lib.c \
+	objects/obj_xref.c \
 	ocsp/ocsp_asn.c \
 	ocsp/ocsp_cl.c \
 	ocsp/ocsp_err.c \
@@ -281,17 +307,18 @@
 	ocsp/ocsp_prn.c \
 	ocsp/ocsp_srv.c \
 	ocsp/ocsp_vfy.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_info.c \
+	pem/pem_lib.c \
 	pem/pem_oth.c \
 	pem/pem_pk8.c \
 	pem/pem_pkey.c \
+	pem/pem_seal.c \
+	pem/pem_sign.c \
+	pem/pem_x509.c \
+	pem/pem_xaux.c \
+	pem/pvkfmt.c \
 	pkcs12/p12_add.c \
 	pkcs12/p12_asn.c \
 	pkcs12/p12_attr.c \
@@ -302,139 +329,123 @@
 	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 \
+	pkcs12/p12_utl.c \
+	pkcs12/pk12err.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_doit.c \
+	pkcs7/pk7_lib.c	\
 	pkcs7/pk7_mime.c \
+	pkcs7/pk7_smime.c \
+	pkcs7/pkcs7err.c \
 	rand/md_rand.c \
-	rand/randfile.c \
-	rand/rand_lib.c \
-	rand/rand_err.c \
 	rand/rand_egd.c \
+	rand/rand_err.c \
+	rand/rand_lib.c \
 	rand/rand_unix.c \
+	rand/randfile.c \
+	rc2/rc2_cbc.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 \
+	rc4/rc4_skey.c \
+	ripemd/rmd_dgst.c \
+	ripemd/rmd_one.c \
+	rsa/rsa_ameth.c \
+	rsa/rsa_asn1.c \
+	rsa/rsa_chk.c \
 	rsa/rsa_eay.c \
-	rsa/rsa_eng.c \
+	rsa/rsa_err.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_oaep.c \
+	rsa/rsa_pk1.c \
+	rsa/rsa_pmeth.c \
+	rsa/rsa_prn.c \
 	rsa/rsa_pss.c \
+	rsa/rsa_saos.c \
+	rsa/rsa_sign.c \
+	rsa/rsa_ssl.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/sha1dgst.c \
 	sha/sha256.c \
 	sha/sha512.c \
+	sha/sha_dgst.c \
+	sha/sha_one.c \
 	stack/stack.c \
+	ts/ts_err.c \
 	txt_db/txt_db.c \
+	ui/ui_compat.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 \
+	x509/by_file.c \
+	x509/x509_att.c \
+	x509/x509_cmp.c \
+	x509/x509_d2.c \
+	x509/x509_def.c \
+	x509/x509_err.c \
+	x509/x509_ext.c \
+	x509/x509_lu.c \
+	x509/x509_obj.c \
+	x509/x509_r2x.c \
+	x509/x509_req.c \
+	x509/x509_set.c \
+	x509/x509_trs.c \
+	x509/x509_txt.c \
+	x509/x509_v3.c \
+	x509/x509_vfy.c \
+	x509/x509_vpm.c \
+	x509/x509cset.c \
+	x509/x509name.c \
+	x509/x509rset.c \
+	x509/x509spki.c \
+	x509/x509type.c \
+	x509/x_all.c \
+	x509v3/pcy_cache.c \
+	x509v3/pcy_data.c \
+	x509v3/pcy_lib.c \
+	x509v3/pcy_map.c \
+	x509v3/pcy_node.c \
+	x509v3/pcy_tree.c \
+	x509v3/v3_akey.c \
+	x509v3/v3_akeya.c \
+	x509v3/v3_alt.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_enum.c \
+	x509v3/v3_extku.c \
+	x509v3/v3_genn.c \
+	x509v3/v3_ia5.c \
 	x509v3/v3_info.c \
-	x509v3/v3_akeya.c \
-	x509v3/v3_ocsp.c \
-	x509v3/v3_pcia.c \
-	x509v3/v3_pci.c \
-	x509v3/v3_pmaps.c \
-	x509v3/v3_pcons.c \
+	x509v3/v3_int.c \
+	x509v3/v3_lib.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
+	x509v3/v3_ocsp.c \
+	x509v3/v3_pci.c \
+	x509v3/v3_pcia.c \
+	x509v3/v3_pcons.c \
+	x509v3/v3_pku.c \
+	x509v3/v3_pmaps.c \
+	x509v3/v3_prn.c \
+	x509v3/v3_purp.c \
+	x509v3/v3_skey.c \
+	x509v3/v3_sxnet.c \
+	x509v3/v3_utl.c \
+	x509v3/v3err.c
 
 LOCAL_CFLAGS += -DNO_WINDOWS_BRAINDEATH
 
@@ -442,7 +453,10 @@
 
 LOCAL_C_INCLUDES += \
 	external/openssl \
+	external/openssl/crypto/asn1 \
+	external/openssl/crypto/evp \
 	external/openssl/include \
+	external/openssl/include/openssl \
 	external/zlib
 
 LOCAL_SHARED_LIBRARIES += libz
diff --git a/patches/progs.patch b/patches/progs.patch
index d8249e6..d7b794c 100644
--- a/patches/progs.patch
+++ b/patches/progs.patch
@@ -1,17 +1,6 @@
-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
+--- openssl-1.0.0.orig/apps/progs.h	2009-06-30 08:08:38.000000000 -0700
++++ openssl-1.0.0/apps/progs.h	2010-04-14 14:19:31.000000000 -0700
+@@ -43,7 +43,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[]);
@@ -19,11 +8,11 @@
  extern int ocsp_main(int argc,char *argv[]);
 +#endif
  extern int prime_main(int argc,char *argv[]);
+ extern int ts_main(int argc,char *argv[]);
  
- #define FUNC_TYPE_GENERAL	1
-@@ -97,7 +101,9 @@ FUNCTION functions[] = {
- 	{FUNC_TYPE_GENERAL,"gendsa",gendsa_main},
+@@ -107,7 +109,9 @@ FUNCTION functions[] = {
  #endif
+ 	{FUNC_TYPE_GENERAL,"genpkey",genpkey_main},
  #if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
 -	{FUNC_TYPE_GENERAL,"s_server",s_server_main},
 +#if 0 /* ANDROID */
@@ -32,35 +21,31 @@
  #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},
+@@ -133,9 +137,11 @@ FUNCTION functions[] = {
+ 	{FUNC_TYPE_GENERAL,"pkcs12",pkcs12_main},
  #endif
-+#ifndef OPENSSL_NO_OCSP
- 	{FUNC_TYPE_GENERAL,"ocsp",ocsp_main},
+ 	{FUNC_TYPE_GENERAL,"pkcs8",pkcs8_main},
++#if 0 /* ANDROID */
+ 	{FUNC_TYPE_GENERAL,"pkey",pkey_main},
+ 	{FUNC_TYPE_GENERAL,"pkeyparam",pkeyparam_main},
+ 	{FUNC_TYPE_GENERAL,"pkeyutl",pkeyutl_main},
 +#endif
+ 	{FUNC_TYPE_GENERAL,"spkac",spkac_main},
+ 	{FUNC_TYPE_GENERAL,"smime",smime_main},
+ 	{FUNC_TYPE_GENERAL,"rand",rand_main},
+@@ -146,7 +152,9 @@ FUNCTION functions[] = {
+ 	{FUNC_TYPE_GENERAL,"ocsp",ocsp_main},
+ #endif
  	{FUNC_TYPE_GENERAL,"prime",prime_main},
++#if 0 /* ANDROID */
+ 	{FUNC_TYPE_GENERAL,"ts",ts_main},
++#endif
  #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)
+--- openssl-1.0.0.orig/apps/speed.c	2010-03-03 11:56:17.000000000 -0800
++++ openssl-1.0.0/apps/speed.c	2010-04-13 16:53:43.000000000 -0700
+@@ -1718,6 +1718,7 @@ int MAIN(int argc, char **argv)
  			}
  		}
  
@@ -68,11 +53,23 @@
  	if (doit[D_IGE_128_AES])
  		{
  		for (j=0; j<SIZE_NUM; j++)
-@@ -1879,6 +1880,7 @@ int MAIN(int argc, char **argv)
- 			}
- 		}
+@@ -1763,6 +1764,7 @@ int MAIN(int argc, char **argv)
+ 
+ 
  #endif
 +#endif
  #ifndef OPENSSL_NO_CAMELLIA
  	if (doit[D_CBC_128_CML])
  		{
+--- openssl-1.0.0.orig/apps/s_client.c	2009-12-16 12:28:28.000000000 -0800
++++ openssl-1.0.0/apps/s_client.c	2010-04-14 14:25:09.000000000 -0700
+@@ -216,6 +216,9 @@ static int c_ign_eof=0;
+ /* Default PSK identity and key */
+ static char *psk_identity="Client_identity";
+ /*char *psk_key=NULL;  by default PSK is not used */
++#if 1 /* ANDROID */
++char *psk_key=NULL;
++#endif
+ 
+ static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity,
+ 	unsigned int max_identity_len, unsigned char *psk,
diff --git a/patches/small_records.patch b/patches/small_records.patch
index 01bb1e2..f40c524 100644
--- a/patches/small_records.patch
+++ b/patches/small_records.patch
@@ -1,8 +1,6 @@
-diff --git openssl-0.9.8m/ssl/d1_pkt.c openssl-0.9.8m/ssl/d1_pkt.c
-index ca2d73f..2af5272 100644
---- openssl-0.9.8m/ssl/d1_pkt.c
-+++ openssl-0.9.8m/ssl/d1_pkt.c
-@@ -571,6 +571,24 @@ again:
+--- openssl-1.0.0.orig/ssl/d1_pkt.c	2009-10-04 09:52:35.000000000 -0700
++++ openssl-1.0.0/ssl/d1_pkt.c	2010-04-14 10:18:00.000000000 -0700
+@@ -614,6 +614,24 @@ again:
  			goto again;
  			}
  
@@ -24,10 +22,10 @@
 +			s->packet= &(s->s3->rbuf.buf[0]);
 +			}
 +
- 		s->client_version = version;
  		/* now s->rstate == SSL_ST_READ_BODY */
  		}
-@@ -1300,6 +1318,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
+ 
+@@ -1344,6 +1362,7 @@ int do_dtls1_write(SSL *s, int type, con
  	SSL3_BUFFER *wb;
  	SSL_SESSION *sess;
  	int bs;
@@ -35,7 +33,7 @@
  
  	/* first check if there is a SSL3_BUFFER still being written
  	 * out.  This will happen with non blocking IO */
-@@ -1309,6 +1328,16 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
+@@ -1353,6 +1372,16 @@ int do_dtls1_write(SSL *s, int type, con
  		return(ssl3_write_pending(s,type,buf,len));
  		}
  
@@ -52,11 +50,9 @@
  	/* If we have an alert to send, lets send it */
  	if (s->s3->alert_dispatch)
  		{
-diff --git openssl-0.9.8m/ssl/s23_srvr.c openssl-0.9.8m/ssl/s23_srvr.c
-index be05911..42f7de4 100644
---- openssl-0.9.8m/ssl/s23_srvr.c
-+++ openssl-0.9.8m/ssl/s23_srvr.c
-@@ -412,8 +412,13 @@ int ssl23_get_client_hello(SSL *s)
+--- openssl-1.0.0.orig/ssl/s23_srvr.c	2010-02-16 06:20:40.000000000 -0800
++++ openssl-1.0.0/ssl/s23_srvr.c	2010-04-13 17:01:07.000000000 -0700
+@@ -403,8 +403,13 @@ int ssl23_get_client_hello(SSL *s)
  		v[0] = p[3]; /* == SSL3_VERSION_MAJOR */
  		v[1] = p[4];
  
@@ -71,68 +67,78 @@
  			{
  			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE);
  			goto err;
-diff --git openssl-0.9.8m/ssl/s3_both.c openssl-0.9.8m/ssl/s3_both.c
-index 7f46225..73f6002 100644
---- openssl-0.9.8m/ssl/s3_both.c
-+++ openssl-0.9.8m/ssl/s3_both.c
-@@ -631,11 +631,18 @@ int ssl3_setup_buffers(SSL *s)
+--- openssl-1.0.0.orig/ssl/s3_both.c	2010-03-24 16:16:49.000000000 -0700
++++ openssl-1.0.0/ssl/s3_both.c	2010-04-14 10:11:42.000000000 -0700
+@@ -715,13 +715,20 @@ int ssl3_setup_read_buffer(SSL *s)
  
  	if (s->s3->rbuf.buf == NULL)
  		{
+-		len = SSL3_RT_MAX_PLAIN_LENGTH
+-			+ SSL3_RT_MAX_ENCRYPTED_OVERHEAD
+-			+ headerlen + align;
 -		if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
--			extra=SSL3_RT_MAX_EXTRA;
 +		if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS)
 +			{
 +			len = SSL3_RT_DEFAULT_PACKET_SIZE;
 +			}
- 		else
--			extra=0;
--		len = SSL3_RT_MAX_PACKET_SIZE + extra;
-+			{
++  		else
+ 			{
+-			s->s3->init_extra = 1;
+-			len += SSL3_RT_MAX_EXTRA;
++			len = SSL3_RT_MAX_PLAIN_LENGTH
++				+ SSL3_RT_MAX_ENCRYPTED_OVERHEAD
++				+ headerlen + align;
 +			if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
-+				extra=SSL3_RT_MAX_EXTRA;
-+			else
-+				extra=0;
-+			len = SSL3_RT_MAX_PACKET_SIZE + extra;
-+			}
- 		if ((p=OPENSSL_malloc(len)) == NULL)
- 			goto err;
- 		s->s3->rbuf.buf = p;
-@@ -644,8 +651,17 @@ int ssl3_setup_buffers(SSL *s)
++				{
++				s->s3->init_extra = 1;
++				len += SSL3_RT_MAX_EXTRA;
++				}
+ 			}
+ #ifndef OPENSSL_NO_COMP
+ 		if (!(s->options & SSL_OP_NO_COMPRESSION))
+@@ -757,7 +764,15 @@ int ssl3_setup_write_buffer(SSL *s)
  
  	if (s->s3->wbuf.buf == NULL)
  		{
--		len = SSL3_RT_MAX_PACKET_SIZE;
--		len += headerlen + 256; /* extra space for empty fragment */
+-		len = s->max_send_fragment
 +		if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS)
 +			{
 +			len = SSL3_RT_DEFAULT_PACKET_SIZE;
 +			}
-+		else
++  		else
 +			{
-+			len = SSL3_RT_MAX_PACKET_SIZE;
++			len = s->max_send_fragment;
 +			}
-+		len += SSL3_RT_DEFAULT_WRITE_OVERHEAD; /* extra space for empty
-+                                                          fragment, header, MAC
-+                                                          and padding */
- 		if ((p=OPENSSL_malloc(len)) == NULL)
++		len += 0
+ 			+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD
+ 			+ headerlen + align;
+ #ifndef OPENSSL_NO_COMP
+@@ -767,7 +782,6 @@ int ssl3_setup_write_buffer(SSL *s)
+ 		if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
+ 			len += headerlen + align
+ 				+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
+-
+ 		if ((p=freelist_extract(s->ctx, 0, len)) == NULL)
  			goto err;
  		s->s3->wbuf.buf = p;
-diff --git openssl-0.9.8m/ssl/s3_pkt.c openssl-0.9.8m/ssl/s3_pkt.c
-index a2ba574..6fe4004 100644
---- openssl-0.9.8m/ssl/s3_pkt.c
-+++ openssl-0.9.8m/ssl/s3_pkt.c
-@@ -259,7 +259,8 @@ static int ssl3_get_record(SSL *s)
+@@ -810,4 +824,3 @@ int ssl3_release_read_buffer(SSL *s)
+ 		}
+ 	return 1;
+ 	}
+-
+--- openssl-1.0.0.orig/ssl/s3_pkt.c	2010-03-25 04:22:42.000000000 -0700
++++ openssl-1.0.0/ssl/s3_pkt.c	2010-04-13 17:19:06.000000000 -0700
+@@ -301,7 +301,8 @@ static int ssl3_get_record(SSL *s)
  		extra=SSL3_RT_MAX_EXTRA;
  	else
  		extra=0;
--	if (extra != s->s3->rbuf.len - SSL3_RT_MAX_PACKET_SIZE)
+-	if (extra && !s->s3->init_extra)
 +	if (!(SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) &&
-+		extra != s->s3->rbuf.len - SSL3_RT_MAX_PACKET_SIZE)
++		extra && !s->s3->init_extra)
  		{
- 		/* actually likely an application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER
+ 		/* An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER
  		 * set after ssl3_setup_buffers() was done */
-@@ -312,6 +313,21 @@ again:
+@@ -357,6 +358,21 @@ fprintf(stderr, "Record type=%d, Length=
  			goto f_err;
  			}
  
@@ -154,22 +160,22 @@
  		/* now s->rstate == SSL_ST_READ_BODY */
  		}
  
-@@ -525,6 +541,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
+@@ -576,6 +592,7 @@ int ssl3_write_bytes(SSL *s, int type, c
  	const unsigned char *buf=buf_;
  	unsigned int tot,n,nw;
  	int i;
-+    unsigned int max_plain_length;
++	unsigned int max_plain_length;
  
  	s->rwstate=SSL_NOTHING;
  	tot=s->s3->wnum;
-@@ -544,8 +561,13 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
+@@ -595,8 +612,13 @@ int ssl3_write_bytes(SSL *s, int type, c
  	n=(len-tot);
  	for (;;)
  		{
--		if (n > SSL3_RT_MAX_PLAIN_LENGTH)
--			nw=SSL3_RT_MAX_PLAIN_LENGTH;
+-		if (n > s->max_send_fragment)
+-			nw=s->max_send_fragment;
 +		if (!(SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS))
-+			max_plain_length = SSL3_RT_MAX_PLAIN_LENGTH;
++			max_plain_length = s->max_send_fragment;
 +		else
 +			max_plain_length = SSL3_RT_DEFAULT_PLAIN_LENGTH;
 +
@@ -178,64 +184,52 @@
  		else
  			nw=n;
  
-@@ -629,7 +651,9 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
- 			if (prefix_len <= 0)
- 				goto err;
- 
--			if (s->s3->wbuf.len < (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE)
-+			if (s->s3->wbuf.len < (size_t)prefix_len +
-+				((SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) ? SSL3_RT_DEFAULT_PACKET_SIZE :
-+					SSL3_RT_MAX_PACKET_SIZE))
- 				{
- 				/* insufficient space */
- 				SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
-diff --git openssl-0.9.8m/ssl/ssl.h openssl-0.9.8m/ssl/ssl.h
-index 47ce1ea..16a90a8 100644
---- openssl-0.9.8m/ssl/ssl.h
-+++ openssl-0.9.8m/ssl/ssl.h
-@@ -560,7 +560,9 @@ typedef struct ssl_session_st
- #define SSL_MODE_AUTO_RETRY 0x00000004L
- /* Don't attempt to automatically build certificate chain */
- #define SSL_MODE_NO_AUTO_CHAIN 0x00000008L
--
+--- openssl-1.0.0.orig/ssl/ssl.h	2010-01-06 09:37:38.000000000 -0800
++++ openssl-1.0.0/ssl/ssl.h	2010-04-13 17:06:03.000000000 -0700
+@@ -602,6 +602,9 @@ typedef struct ssl_session_st
+  * TLS only.)  "Released" buffers are put onto a free-list in the context
+  * or just freed (depending on the context's setting for freelist_max_len). */
+ #define SSL_MODE_RELEASE_BUFFERS 0x00000010L
 +/* Use small read and write buffers: (a) lazy allocate read buffers for
 + * large incoming records, and (b) limit the size of outgoing records. */
-+#define SSL_MODE_SMALL_BUFFERS 0x00000010L
++#define SSL_MODE_SMALL_BUFFERS 0x00000020L
  
  /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
   * they cannot be used to clear bits. */
-diff --git openssl-0.9.8m/ssl/ssl3.h openssl-0.9.8m/ssl/ssl3.h
-index 7e6afee..b5b8683 100644
---- openssl-0.9.8m/ssl/ssl3.h
-+++ openssl-0.9.8m/ssl/ssl3.h
-@@ -256,6 +256,9 @@ extern "C" {
+--- openssl-1.0.0.orig/ssl/ssl3.h	2010-01-06 09:37:38.000000000 -0800
++++ openssl-1.0.0/ssl/ssl3.h	2010-04-13 17:07:50.000000000 -0700
+@@ -280,6 +280,9 @@ extern "C" {
+ 
  #define SSL3_RT_MAX_EXTRA			(16384)
- #endif
  
 +/* Default buffer length used for writen records.  Thus a generated record
 + * will contain plaintext no larger than this value. */
 +#define SSL3_RT_DEFAULT_PLAIN_LENGTH	2048
+ /* Maximum plaintext length: defined by SSL/TLS standards */
  #define SSL3_RT_MAX_PLAIN_LENGTH		16384
- #ifdef OPENSSL_NO_COMP
- #define SSL3_RT_MAX_COMPRESSED_LENGTH	SSL3_RT_MAX_PLAIN_LENGTH
-@@ -263,6 +266,12 @@ extern "C" {
- #define SSL3_RT_MAX_COMPRESSED_LENGTH	(1024+SSL3_RT_MAX_PLAIN_LENGTH)
- #endif
- #define SSL3_RT_MAX_ENCRYPTED_LENGTH	(1024+SSL3_RT_MAX_COMPRESSED_LENGTH)
+ /* Maximum compression overhead: defined by SSL/TLS standards */
+@@ -311,6 +314,13 @@ extern "C" {
+ #define SSL3_RT_MAX_PACKET_SIZE		\
+ 		(SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
+ 
 +/* Extra space for empty fragment, headers, MAC, and padding. */
 +#define SSL3_RT_DEFAULT_WRITE_OVERHEAD  256
 +#define SSL3_RT_DEFAULT_PACKET_SIZE     4096 - SSL3_RT_DEFAULT_WRITE_OVERHEAD
 +#if SSL3_RT_DEFAULT_PLAIN_LENGTH + SSL3_RT_DEFAULT_WRITE_OVERHEAD > SSL3_RT_DEFAULT_PACKET_SIZE
 +#error "Insufficient space allocated for write buffers."
 +#endif
- #define SSL3_RT_MAX_PACKET_SIZE		(SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
- #define SSL3_RT_MAX_DATA_SIZE			(1024*1024)
++
+ #define SSL3_MD_CLIENT_FINISHED_CONST	"\x43\x4C\x4E\x54"
+ #define SSL3_MD_SERVER_FINISHED_CONST	"\x53\x52\x56\x52"
  
-diff --git openssl-0.9.8m/ssl/ssltest.c openssl-0.9.8m/ssl/ssltest.c
-index b09c542..09d3502 100644
---- openssl-0.9.8m/ssl/ssltest.c
-+++ openssl-0.9.8m/ssl/ssltest.c
-@@ -277,6 +277,8 @@ static void sv_usage(void)
+@@ -634,4 +644,3 @@ typedef struct ssl3_state_st
+ }
+ #endif
+ #endif
+-
+--- openssl-1.0.0.orig/ssl/ssltest.c	2010-01-24 08:57:38.000000000 -0800
++++ openssl-1.0.0/ssl/ssltest.c	2010-04-13 17:01:07.000000000 -0700
+@@ -316,6 +316,8 @@ static void sv_usage(void)
  	               "                 (default is sect163r2).\n");
  #endif
  	fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
@@ -244,17 +238,17 @@
  	}
  
  static void print_details(SSL *c_ssl, const char *prefix)
-@@ -431,6 +433,9 @@ int main(int argc, char *argv[])
- #ifdef OPENSSL_FIPS
- 	int fips_mode=0;
+@@ -444,6 +446,9 @@ int opaque_prf_input_cb(SSL *ssl, void *
+ 	return arg->ret;
+ 	}
  #endif
 +	int ssl_mode = 0;
 +	int c_small_records=0;
 +	int s_small_records=0;
  
- 	verbose = 0;
- 	debug = 0;
-@@ -619,6 +624,14 @@ int main(int argc, char *argv[])
+ int main(int argc, char *argv[])
+ 	{
+@@ -680,6 +685,14 @@ int main(int argc, char *argv[])
  			{
  			test_cipherlist = 1;
  			}
@@ -269,7 +263,7 @@
  		else
  			{
  			fprintf(stderr,"unknown option %s\n",*argv);
-@@ -755,6 +768,21 @@ bad:
+@@ -802,6 +815,21 @@ bad:
  		SSL_CTX_set_cipher_list(s_ctx,cipher);
  		}
  
@@ -291,11 +285,9 @@
  #ifndef OPENSSL_NO_DH
  	if (!no_dhe)
  		{
-diff --git openssl-0.9.8m/test/testssl openssl-0.9.8m/test/testssl
-index 8ac90ae..a9b2e24 100644
---- openssl-0.9.8m/test/testssl
-+++ openssl-0.9.8m/test/testssl
-@@ -70,6 +70,16 @@ $ssltest -client_auth $CA $extra || exit 1
+--- openssl-1.0.0.orig/test/testssl	2006-03-10 15:06:27.000000000 -0800
++++ openssl-1.0.0/test/testssl	2010-04-13 17:01:07.000000000 -0700
+@@ -70,6 +70,16 @@ $ssltest -client_auth $CA $extra || exit
  echo test sslv2/sslv3 with both client and server authentication
  $ssltest -server_auth -client_auth $CA $extra || exit 1
  
diff --git a/ssl/Makefile b/ssl/Makefile
index 5ac3507..2b275fa 100644
--- a/ssl/Makefile
+++ b/ssl/Makefile
@@ -53,7 +53,7 @@
 top:
 	(cd ..; $(MAKE) DIRS=$(DIR) all)
 
-all:	lib
+all:	shared
 
 lib:	$(LIBOBJ)
 	$(AR) $(LIB) $(LIBOBJ)
@@ -106,45 +106,43 @@
 # DO NOT DELETE THIS LINE -- make depend depends on it.
 
 bio_ssl.o: ../include/openssl/asn1.h ../include/openssl/bio.h
-bio_ssl.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-bio_ssl.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-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/fips.h
+bio_ssl.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+bio_ssl.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
+bio_ssl.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+bio_ssl.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+bio_ssl.o: ../include/openssl/err.h ../include/openssl/evp.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
 bio_ssl.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-bio_ssl.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
-bio_ssl.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
-bio_ssl.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-bio_ssl.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-bio_ssl.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-bio_ssl.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-bio_ssl.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h bio_ssl.c
+bio_ssl.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+bio_ssl.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+bio_ssl.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+bio_ssl.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+bio_ssl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+bio_ssl.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+bio_ssl.o: ../include/openssl/x509_vfy.h bio_ssl.c
 d1_both.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-d1_both.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-d1_both.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-d1_both.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+d1_both.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+d1_both.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+d1_both.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+d1_both.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+d1_both.o: ../include/openssl/evp.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
 d1_both.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 d1_both.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-d1_both.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-d1_both.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-d1_both.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-d1_both.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-d1_both.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-d1_both.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-d1_both.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-d1_both.o: ../include/openssl/x509_vfy.h d1_both.c ssl_locl.h
+d1_both.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+d1_both.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+d1_both.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+d1_both.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+d1_both.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+d1_both.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+d1_both.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_both.c
+d1_both.o: ssl_locl.h
 d1_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 d1_clnt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 d1_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
@@ -152,14 +150,13 @@
 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/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
-d1_clnt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-d1_clnt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-d1_clnt.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
+d1_clnt.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+d1_clnt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+d1_clnt.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
+d1_clnt.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+d1_clnt.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+d1_clnt.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+d1_clnt.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
 d1_clnt.o: ../include/openssl/rand.h ../include/openssl/rsa.h
 d1_clnt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
 d1_clnt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
@@ -168,90 +165,83 @@
 d1_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
 d1_clnt.o: ../include/openssl/x509_vfy.h d1_clnt.c kssl_lcl.h ssl_locl.h
 d1_enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-d1_enc.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-d1_enc.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-d1_enc.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/fips.h ../include/openssl/hmac.h
+d1_enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+d1_enc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+d1_enc.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+d1_enc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+d1_enc.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+d1_enc.o: ../include/openssl/evp.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_enc.o: ../include/openssl/pkcs7.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_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
-d1_lib.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+d1_lib.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+d1_lib.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+d1_lib.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+d1_lib.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+d1_lib.o: ../include/openssl/evp.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
 d1_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 d1_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-d1_lib.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-d1_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-d1_lib.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-d1_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-d1_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-d1_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-d1_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_lib.c
-d1_lib.o: ssl_locl.h
+d1_lib.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+d1_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+d1_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+d1_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+d1_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+d1_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+d1_lib.o: ../include/openssl/x509_vfy.h d1_lib.c ssl_locl.h
 d1_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-d1_meth.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-d1_meth.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-d1_meth.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+d1_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+d1_meth.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+d1_meth.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+d1_meth.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+d1_meth.o: ../include/openssl/evp.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
 d1_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 d1_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-d1_meth.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-d1_meth.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-d1_meth.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-d1_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-d1_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-d1_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-d1_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_meth.c
-d1_meth.o: ssl_locl.h
+d1_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+d1_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+d1_meth.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+d1_meth.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+d1_meth.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+d1_meth.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+d1_meth.o: ../include/openssl/x509_vfy.h d1_meth.c ssl_locl.h
 d1_pkt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-d1_pkt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-d1_pkt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-d1_pkt.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+d1_pkt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+d1_pkt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+d1_pkt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+d1_pkt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+d1_pkt.o: ../include/openssl/evp.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
 d1_pkt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 d1_pkt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-d1_pkt.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-d1_pkt.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-d1_pkt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-d1_pkt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-d1_pkt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-d1_pkt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-d1_pkt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-d1_pkt.o: ../include/openssl/x509_vfy.h d1_pkt.c ssl_locl.h
+d1_pkt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+d1_pkt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+d1_pkt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+d1_pkt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+d1_pkt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+d1_pkt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+d1_pkt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_pkt.c
+d1_pkt.o: ssl_locl.h
 d1_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 d1_srvr.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 d1_srvr.o: ../include/openssl/comp.h ../include/openssl/crypto.h
@@ -259,14 +249,13 @@
 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/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
-d1_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-d1_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-d1_srvr.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
+d1_srvr.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+d1_srvr.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+d1_srvr.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
+d1_srvr.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+d1_srvr.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+d1_srvr.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+d1_srvr.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
 d1_srvr.o: ../include/openssl/rand.h ../include/openssl/rsa.h
 d1_srvr.o: ../include/openssl/safestack.h ../include/openssl/sha.h
 d1_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
@@ -275,276 +264,257 @@
 d1_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
 d1_srvr.o: ../include/openssl/x509_vfy.h d1_srvr.c ssl_locl.h
 kssl.o: ../include/openssl/asn1.h ../include/openssl/bio.h
-kssl.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-kssl.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-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/buffer.h ../include/openssl/comp.h
+kssl.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
+kssl.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+kssl.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+kssl.o: ../include/openssl/evp.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
 kssl.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
 kssl.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-kssl.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
-kssl.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
-kssl.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-kssl.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-kssl.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-kssl.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-kssl.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl.c
+kssl.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+kssl.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+kssl.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+kssl.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+kssl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+kssl.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+kssl.o: ../include/openssl/x509_vfy.h kssl.c kssl_lcl.h
 s23_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s23_clnt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s23_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s23_clnt.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+s23_clnt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s23_clnt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s23_clnt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s23_clnt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s23_clnt.o: ../include/openssl/evp.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
 s23_clnt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 s23_clnt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s23_clnt.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s23_clnt.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-s23_clnt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s23_clnt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s23_clnt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s23_clnt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s23_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s23_clnt.o: ../include/openssl/x509_vfy.h s23_clnt.c ssl_locl.h
+s23_clnt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+s23_clnt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s23_clnt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s23_clnt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s23_clnt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s23_clnt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s23_clnt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s23_clnt.c
+s23_clnt.o: ssl_locl.h
 s23_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s23_lib.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s23_lib.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s23_lib.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+s23_lib.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s23_lib.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s23_lib.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s23_lib.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s23_lib.o: ../include/openssl/evp.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
 s23_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 s23_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s23_lib.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s23_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s23_lib.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s23_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s23_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s23_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s23_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s23_lib.c
-s23_lib.o: ssl_locl.h
+s23_lib.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s23_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s23_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s23_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s23_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s23_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s23_lib.o: ../include/openssl/x509_vfy.h s23_lib.c ssl_locl.h
 s23_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s23_meth.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s23_meth.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s23_meth.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+s23_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s23_meth.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s23_meth.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s23_meth.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s23_meth.o: ../include/openssl/evp.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
 s23_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 s23_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s23_meth.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s23_meth.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s23_meth.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s23_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s23_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s23_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s23_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s23_meth.c
-s23_meth.o: ssl_locl.h
+s23_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s23_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s23_meth.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s23_meth.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s23_meth.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s23_meth.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s23_meth.o: ../include/openssl/x509_vfy.h s23_meth.c ssl_locl.h
 s23_pkt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s23_pkt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s23_pkt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s23_pkt.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+s23_pkt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s23_pkt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s23_pkt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s23_pkt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s23_pkt.o: ../include/openssl/evp.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
 s23_pkt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 s23_pkt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s23_pkt.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s23_pkt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s23_pkt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s23_pkt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s23_pkt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s23_pkt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s23_pkt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s23_pkt.c
-s23_pkt.o: ssl_locl.h
+s23_pkt.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s23_pkt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s23_pkt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s23_pkt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s23_pkt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s23_pkt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s23_pkt.o: ../include/openssl/x509_vfy.h s23_pkt.c ssl_locl.h
 s23_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s23_srvr.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s23_srvr.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s23_srvr.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+s23_srvr.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s23_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s23_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s23_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s23_srvr.o: ../include/openssl/evp.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
 s23_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 s23_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s23_srvr.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s23_srvr.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-s23_srvr.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s23_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s23_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s23_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s23_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s23_srvr.o: ../include/openssl/x509_vfy.h s23_srvr.c ssl_locl.h
+s23_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+s23_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s23_srvr.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s23_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s23_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s23_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s23_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s23_srvr.c
+s23_srvr.o: ssl_locl.h
 s2_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s2_clnt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s2_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s2_clnt.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+s2_clnt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s2_clnt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s2_clnt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s2_clnt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s2_clnt.o: ../include/openssl/evp.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
 s2_clnt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 s2_clnt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s2_clnt.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s2_clnt.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-s2_clnt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s2_clnt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s2_clnt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s2_clnt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s2_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s2_clnt.o: ../include/openssl/x509_vfy.h s2_clnt.c ssl_locl.h
+s2_clnt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+s2_clnt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s2_clnt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s2_clnt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s2_clnt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s2_clnt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s2_clnt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_clnt.c
+s2_clnt.o: ssl_locl.h
 s2_enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s2_enc.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s2_enc.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s2_enc.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+s2_enc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s2_enc.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s2_enc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s2_enc.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s2_enc.o: ../include/openssl/evp.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
 s2_enc.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 s2_enc.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s2_enc.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s2_enc.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s2_enc.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s2_enc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s2_enc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s2_enc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s2_enc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_enc.c
-s2_enc.o: ssl_locl.h
+s2_enc.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s2_enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s2_enc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s2_enc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s2_enc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s2_enc.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s2_enc.o: ../include/openssl/x509_vfy.h s2_enc.c ssl_locl.h
 s2_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s2_lib.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s2_lib.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s2_lib.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+s2_lib.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s2_lib.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s2_lib.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s2_lib.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s2_lib.o: ../include/openssl/evp.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
 s2_lib.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
 s2_lib.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-s2_lib.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
-s2_lib.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
-s2_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s2_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s2_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s2_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s2_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s2_lib.o: ../include/openssl/x509_vfy.h s2_lib.c ssl_locl.h
+s2_lib.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+s2_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s2_lib.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s2_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s2_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s2_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s2_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_lib.c
+s2_lib.o: ssl_locl.h
 s2_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s2_meth.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s2_meth.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s2_meth.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+s2_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s2_meth.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s2_meth.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s2_meth.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s2_meth.o: ../include/openssl/evp.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
 s2_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 s2_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s2_meth.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s2_meth.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s2_meth.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s2_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s2_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s2_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s2_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_meth.c
-s2_meth.o: ssl_locl.h
+s2_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s2_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s2_meth.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s2_meth.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s2_meth.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s2_meth.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s2_meth.o: ../include/openssl/x509_vfy.h s2_meth.c ssl_locl.h
 s2_pkt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s2_pkt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s2_pkt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s2_pkt.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+s2_pkt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s2_pkt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s2_pkt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s2_pkt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s2_pkt.o: ../include/openssl/evp.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
 s2_pkt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 s2_pkt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s2_pkt.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s2_pkt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s2_pkt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s2_pkt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s2_pkt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s2_pkt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s2_pkt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_pkt.c
-s2_pkt.o: ssl_locl.h
+s2_pkt.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s2_pkt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s2_pkt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s2_pkt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s2_pkt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s2_pkt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s2_pkt.o: ../include/openssl/x509_vfy.h s2_pkt.c ssl_locl.h
 s2_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s2_srvr.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s2_srvr.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s2_srvr.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+s2_srvr.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s2_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s2_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s2_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s2_srvr.o: ../include/openssl/evp.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
 s2_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 s2_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s2_srvr.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s2_srvr.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-s2_srvr.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s2_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s2_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s2_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s2_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s2_srvr.o: ../include/openssl/x509_vfy.h s2_srvr.c ssl_locl.h
+s2_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+s2_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s2_srvr.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s2_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s2_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s2_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s2_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_srvr.c
+s2_srvr.o: ssl_locl.h
 s3_both.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s3_both.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s3_both.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s3_both.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+s3_both.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s3_both.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s3_both.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s3_both.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s3_both.o: ../include/openssl/evp.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
 s3_both.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 s3_both.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s3_both.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s3_both.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-s3_both.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s3_both.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s3_both.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s3_both.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s3_both.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s3_both.o: ../include/openssl/x509_vfy.h s3_both.c ssl_locl.h
+s3_both.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+s3_both.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s3_both.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s3_both.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s3_both.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s3_both.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s3_both.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_both.c
+s3_both.o: ssl_locl.h
 s3_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 s3_clnt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 s3_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
@@ -553,13 +523,12 @@
 s3_clnt.o: ../include/openssl/ec.h ../include/openssl/ecdh.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/hmac.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/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
@@ -569,90 +538,84 @@
 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
-s3_enc.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+s3_enc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s3_enc.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s3_enc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s3_enc.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s3_enc.o: ../include/openssl/evp.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
 s3_enc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
 s3_enc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-s3_enc.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
-s3_enc.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
-s3_enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s3_enc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s3_enc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s3_enc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s3_enc.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s3_enc.o: ../include/openssl/x509_vfy.h s3_enc.c ssl_locl.h
-s3_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s3_lib.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s3_lib.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s3_lib.o: ../include/openssl/dh.h ../include/openssl/dsa.h
-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/fips.h
+s3_enc.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+s3_enc.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s3_enc.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s3_enc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s3_enc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s3_enc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s3_enc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_enc.c
+s3_enc.o: ssl_locl.h
+s3_lib.o: ../crypto/ec/ec_lcl.h ../e_os.h ../include/openssl/asn1.h
+s3_lib.o: ../include/openssl/bio.h ../include/openssl/bn.h
+s3_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s3_lib.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+s3_lib.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
+s3_lib.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+s3_lib.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+s3_lib.o: ../include/openssl/err.h ../include/openssl/evp.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
 s3_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 s3_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s3_lib.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s3_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s3_lib.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s3_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s3_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s3_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s3_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl_lcl.h
-s3_lib.o: s3_lib.c ssl_locl.h
+s3_lib.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s3_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s3_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s3_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s3_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s3_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s3_lib.o: ../include/openssl/x509_vfy.h kssl_lcl.h s3_lib.c ssl_locl.h
 s3_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s3_meth.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s3_meth.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s3_meth.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+s3_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s3_meth.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s3_meth.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s3_meth.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s3_meth.o: ../include/openssl/evp.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
 s3_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 s3_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s3_meth.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s3_meth.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s3_meth.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s3_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s3_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s3_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s3_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_meth.c
-s3_meth.o: ssl_locl.h
+s3_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s3_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s3_meth.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s3_meth.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s3_meth.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s3_meth.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s3_meth.o: ../include/openssl/x509_vfy.h s3_meth.c ssl_locl.h
 s3_pkt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s3_pkt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s3_pkt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s3_pkt.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+s3_pkt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s3_pkt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s3_pkt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s3_pkt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s3_pkt.o: ../include/openssl/evp.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
 s3_pkt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 s3_pkt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s3_pkt.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s3_pkt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s3_pkt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s3_pkt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s3_pkt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s3_pkt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s3_pkt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_pkt.c
-s3_pkt.o: ssl_locl.h
+s3_pkt.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+s3_pkt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s3_pkt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s3_pkt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s3_pkt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s3_pkt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s3_pkt.o: ../include/openssl/x509_vfy.h s3_pkt.c ssl_locl.h
 s3_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 s3_srvr.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 s3_srvr.o: ../include/openssl/comp.h ../include/openssl/crypto.h
@@ -660,14 +623,13 @@
 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/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/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/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
@@ -677,47 +639,44 @@
 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
-ssl_algs.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+ssl_algs.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+ssl_algs.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+ssl_algs.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ssl_algs.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+ssl_algs.o: ../include/openssl/evp.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
 ssl_algs.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 ssl_algs.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-ssl_algs.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-ssl_algs.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-ssl_algs.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssl_algs.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssl_algs.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssl_algs.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssl_algs.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_algs.c
-ssl_algs.o: ssl_locl.h
+ssl_algs.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+ssl_algs.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ssl_algs.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssl_algs.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssl_algs.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssl_algs.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssl_algs.o: ../include/openssl/x509_vfy.h ssl_algs.c ssl_locl.h
 ssl_asn1.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/asn1_mac.h
-ssl_asn1.o: ../include/openssl/bio.h ../include/openssl/bn.h
-ssl_asn1.o: ../include/openssl/buffer.h ../include/openssl/comp.h
-ssl_asn1.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
-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/fips.h
+ssl_asn1.o: ../include/openssl/bio.h ../include/openssl/buffer.h
+ssl_asn1.o: ../include/openssl/comp.h ../include/openssl/crypto.h
+ssl_asn1.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
+ssl_asn1.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ssl_asn1.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+ssl_asn1.o: ../include/openssl/err.h ../include/openssl/evp.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
 ssl_asn1.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-ssl_asn1.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
-ssl_asn1.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
-ssl_asn1.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-ssl_asn1.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-ssl_asn1.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-ssl_asn1.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-ssl_asn1.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-ssl_asn1.o: ../include/openssl/x509_vfy.h ssl_asn1.c ssl_locl.h
+ssl_asn1.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+ssl_asn1.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+ssl_asn1.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+ssl_asn1.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ssl_asn1.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ssl_asn1.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ssl_asn1.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_asn1.c
+ssl_asn1.o: ssl_locl.h
 ssl_cert.o: ../crypto/o_dir.h ../e_os.h ../include/openssl/asn1.h
 ssl_cert.o: ../include/openssl/bio.h ../include/openssl/bn.h
 ssl_cert.o: ../include/openssl/buffer.h ../include/openssl/comp.h
@@ -726,13 +685,12 @@
 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/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
-ssl_cert.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-ssl_cert.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
+ssl_cert.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+ssl_cert.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+ssl_cert.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ssl_cert.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ssl_cert.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ssl_cert.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
 ssl_cert.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
 ssl_cert.o: ../include/openssl/safestack.h ../include/openssl/sha.h
 ssl_cert.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
@@ -742,19 +700,18 @@
 ssl_cert.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h
 ssl_cert.o: ssl_cert.c ssl_locl.h
 ssl_ciph.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-ssl_ciph.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-ssl_ciph.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-ssl_ciph.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+ssl_ciph.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+ssl_ciph.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+ssl_ciph.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ssl_ciph.o: ../include/openssl/ecdsa.h ../include/openssl/engine.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
-ssl_ciph.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-ssl_ciph.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-ssl_ciph.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
+ssl_ciph.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+ssl_ciph.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ssl_ciph.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+ssl_ciph.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ssl_ciph.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+ssl_ciph.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
 ssl_ciph.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
 ssl_ciph.o: ../include/openssl/sha.h ../include/openssl/ssl.h
 ssl_ciph.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
@@ -763,276 +720,256 @@
 ssl_ciph.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_ciph.c
 ssl_ciph.o: ssl_locl.h
 ssl_err.o: ../include/openssl/asn1.h ../include/openssl/bio.h
-ssl_err.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-ssl_err.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-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/fips.h
+ssl_err.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+ssl_err.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
+ssl_err.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ssl_err.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+ssl_err.o: ../include/openssl/err.h ../include/openssl/evp.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
 ssl_err.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-ssl_err.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
-ssl_err.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
-ssl_err.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssl_err.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssl_err.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssl_err.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssl_err.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_err.c
+ssl_err.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+ssl_err.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ssl_err.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssl_err.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssl_err.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssl_err.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssl_err.o: ../include/openssl/x509_vfy.h ssl_err.c
 ssl_err2.o: ../include/openssl/asn1.h ../include/openssl/bio.h
-ssl_err2.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-ssl_err2.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-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/fips.h
+ssl_err2.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+ssl_err2.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
+ssl_err2.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ssl_err2.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+ssl_err2.o: ../include/openssl/err.h ../include/openssl/evp.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
 ssl_err2.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-ssl_err2.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
-ssl_err2.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
-ssl_err2.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssl_err2.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssl_err2.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssl_err2.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssl_err2.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_err2.c
+ssl_err2.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+ssl_err2.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ssl_err2.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssl_err2.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssl_err2.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssl_err2.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssl_err2.o: ../include/openssl/x509_vfy.h ssl_err2.c
 ssl_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-ssl_lib.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-ssl_lib.o: ../include/openssl/comp.h ../include/openssl/conf.h
-ssl_lib.o: ../include/openssl/crypto.h ../include/openssl/dh.h
-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/engine.h ../include/openssl/err.h
-ssl_lib.o: ../include/openssl/evp.h ../include/openssl/fips.h
+ssl_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+ssl_lib.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+ssl_lib.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+ssl_lib.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+ssl_lib.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ssl_lib.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+ssl_lib.o: ../include/openssl/err.h ../include/openssl/evp.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_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_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
-ssl_rsa.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+ssl_rsa.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+ssl_rsa.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+ssl_rsa.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ssl_rsa.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+ssl_rsa.o: ../include/openssl/evp.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
 ssl_rsa.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 ssl_rsa.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-ssl_rsa.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-ssl_rsa.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-ssl_rsa.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssl_rsa.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssl_rsa.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssl_rsa.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssl_rsa.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
-ssl_rsa.o: ssl_rsa.c
+ssl_rsa.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+ssl_rsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ssl_rsa.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssl_rsa.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssl_rsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssl_rsa.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssl_rsa.o: ../include/openssl/x509_vfy.h ssl_locl.h ssl_rsa.c
 ssl_sess.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-ssl_sess.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-ssl_sess.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-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/engine.h ../include/openssl/err.h
-ssl_sess.o: ../include/openssl/evp.h ../include/openssl/fips.h
+ssl_sess.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+ssl_sess.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+ssl_sess.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+ssl_sess.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ssl_sess.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+ssl_sess.o: ../include/openssl/err.h ../include/openssl/evp.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_sess.o: ../include/openssl/pkcs7.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_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
-ssl_stat.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+ssl_stat.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+ssl_stat.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+ssl_stat.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ssl_stat.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+ssl_stat.o: ../include/openssl/evp.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
 ssl_stat.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 ssl_stat.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-ssl_stat.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-ssl_stat.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-ssl_stat.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssl_stat.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssl_stat.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssl_stat.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssl_stat.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
-ssl_stat.o: ssl_stat.c
+ssl_stat.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+ssl_stat.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ssl_stat.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssl_stat.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssl_stat.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssl_stat.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssl_stat.o: ../include/openssl/x509_vfy.h ssl_locl.h ssl_stat.c
 ssl_txt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-ssl_txt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-ssl_txt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-ssl_txt.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+ssl_txt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+ssl_txt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+ssl_txt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ssl_txt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+ssl_txt.o: ../include/openssl/evp.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
 ssl_txt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 ssl_txt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-ssl_txt.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-ssl_txt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-ssl_txt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssl_txt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssl_txt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssl_txt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssl_txt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
-ssl_txt.o: ssl_txt.c
+ssl_txt.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+ssl_txt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ssl_txt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssl_txt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssl_txt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssl_txt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssl_txt.o: ../include/openssl/x509_vfy.h ssl_locl.h ssl_txt.c
 t1_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-t1_clnt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-t1_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-t1_clnt.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+t1_clnt.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+t1_clnt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+t1_clnt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+t1_clnt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+t1_clnt.o: ../include/openssl/evp.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
 t1_clnt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 t1_clnt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-t1_clnt.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-t1_clnt.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-t1_clnt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-t1_clnt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-t1_clnt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-t1_clnt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-t1_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-t1_clnt.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_clnt.c
+t1_clnt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+t1_clnt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+t1_clnt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+t1_clnt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+t1_clnt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+t1_clnt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+t1_clnt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
+t1_clnt.o: t1_clnt.c
 t1_enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-t1_enc.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-t1_enc.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-t1_enc.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/fips.h ../include/openssl/hmac.h
+t1_enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+t1_enc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+t1_enc.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+t1_enc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+t1_enc.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+t1_enc.o: ../include/openssl/evp.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_enc.o: ../include/openssl/pkcs7.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_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
-t1_lib.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
-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/fips.h
+t1_lib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+t1_lib.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+t1_lib.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
+t1_lib.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+t1_lib.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+t1_lib.o: ../include/openssl/err.h ../include/openssl/evp.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_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_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
-t1_meth.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+t1_meth.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+t1_meth.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+t1_meth.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+t1_meth.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+t1_meth.o: ../include/openssl/evp.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
 t1_meth.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 t1_meth.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-t1_meth.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-t1_meth.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-t1_meth.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-t1_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-t1_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-t1_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-t1_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
-t1_meth.o: t1_meth.c
+t1_meth.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+t1_meth.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+t1_meth.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+t1_meth.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+t1_meth.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+t1_meth.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+t1_meth.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_meth.c
 t1_reneg.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-t1_reneg.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-t1_reneg.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-t1_reneg.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-t1_reneg.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-t1_reneg.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-t1_reneg.o: ../include/openssl/err.h ../include/openssl/evp.h
-t1_reneg.o: ../include/openssl/fips.h ../include/openssl/hmac.h
+t1_reneg.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+t1_reneg.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+t1_reneg.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+t1_reneg.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+t1_reneg.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+t1_reneg.o: ../include/openssl/evp.h ../include/openssl/hmac.h
 t1_reneg.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 t1_reneg.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 t1_reneg.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
 t1_reneg.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 t1_reneg.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-t1_reneg.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-t1_reneg.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-t1_reneg.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-t1_reneg.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-t1_reneg.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-t1_reneg.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-t1_reneg.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
-t1_reneg.o: t1_reneg.c
+t1_reneg.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+t1_reneg.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+t1_reneg.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+t1_reneg.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+t1_reneg.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+t1_reneg.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+t1_reneg.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_reneg.c
 t1_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-t1_srvr.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-t1_srvr.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-t1_srvr.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-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/buffer.h ../include/openssl/comp.h
+t1_srvr.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+t1_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+t1_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+t1_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+t1_srvr.o: ../include/openssl/evp.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
 t1_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
 t1_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-t1_srvr.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-t1_srvr.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-t1_srvr.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-t1_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-t1_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-t1_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-t1_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-t1_srvr.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_srvr.c
+t1_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+t1_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+t1_srvr.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+t1_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+t1_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+t1_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+t1_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
+t1_srvr.o: t1_srvr.c
diff --git a/ssl/bio_ssl.c b/ssl/bio_ssl.c
index 420deb7..af319af 100644
--- a/ssl/bio_ssl.c
+++ b/ssl/bio_ssl.c
@@ -398,17 +398,19 @@
 			}
 		break;
 	case BIO_CTRL_POP:
-		/* ugly bit of a hack */
-		if (ssl->rbio != ssl->wbio) /* we are in trouble :-( */
+		/* Only detach if we are the BIO explicitly being popped */
+		if (b == ptr)
 			{
-			BIO_free_all(ssl->wbio);
+			/* Shouldn't happen in practice because the
+			 * rbio and wbio are the same when pushed.
+			 */
+			if (ssl->rbio != ssl->wbio)
+				BIO_free_all(ssl->wbio);
+			if (b->next_bio != NULL)
+				CRYPTO_add(&b->next_bio->references,-1,CRYPTO_LOCK_BIO);
+			ssl->wbio=NULL;
+			ssl->rbio=NULL;
 			}
-		if (b->next_bio != NULL)
-			{
-			CRYPTO_add(&b->next_bio->references,1,CRYPTO_LOCK_BIO);
-			}
-		ssl->wbio=NULL;
-		ssl->rbio=NULL;
 		break;
 	case BIO_C_DO_STATE_MACHINE:
 		BIO_clear_retry_flags(b);
@@ -543,7 +545,6 @@
 	return(ret);
 err:
 	if (con != NULL) BIO_free(con);
-	if (ret != NULL) BIO_free(ret);
 	return(NULL);
 	}
 
diff --git a/ssl/d1_both.c b/ssl/d1_both.c
index 0a5c08d..0242f1e 100644
--- a/ssl/d1_both.c
+++ b/ssl/d1_both.c
@@ -226,7 +226,7 @@
 			(int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
 
 	if (s->write_hash)
-		mac_size = EVP_MD_size(s->write_hash);
+		mac_size = EVP_MD_CTX_size(s->write_hash);
 	else
 		mac_size = 0;
 
@@ -312,7 +312,7 @@
 				const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
 				int xlen;
 
-				if (frag_off == 0 && s->client_version != DTLS1_BAD_VER)
+				if (frag_off == 0 && s->version != DTLS1_BAD_VER)
 					{
 					/* reconstruct message header is if it
 					 * is being sent in single fragment */
@@ -419,9 +419,10 @@
 			s2n (msg_hdr->seq,p);
 			l2n3(0,p);
 			l2n3(msg_len,p);
-			if (s->client_version != DTLS1_BAD_VER)
-				p       -= DTLS1_HM_HEADER_LENGTH,
+			if (s->version != DTLS1_BAD_VER) {
+				p       -= DTLS1_HM_HEADER_LENGTH;
 				msg_len += DTLS1_HM_HEADER_LENGTH;
+			}
 
 			ssl3_finish_mac(s, p, msg_len);
 			if (s->msg_callback)
@@ -485,7 +486,7 @@
 		{
 		/* msg_len is limited to 2^24, but is effectively checked
 		 * against max above */
-		if (!BUF_MEM_grow_clean(s->init_buf,(int)msg_len+DTLS1_HM_HEADER_LENGTH))
+		if (!BUF_MEM_grow_clean(s->init_buf,msg_len+DTLS1_HM_HEADER_LENGTH))
 			{
 			SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,ERR_R_BUF_LIB);
 			return SSL_AD_INTERNAL_ERROR;
@@ -567,17 +568,17 @@
 	int i=-1;
 	hm_fragment *frag = NULL;
 	pitem *item = NULL;
-	PQ_64BIT seq64;
+	unsigned char seq64be[8];
 	unsigned long frag_len = msg_hdr->frag_len;
 
 	if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len)
 		goto err;
 
 	/* Try to find item in queue, to prevent duplicate entries */
-	pq_64bit_init(&seq64);
-	pq_64bit_assign_word(&seq64, msg_hdr->seq);
-	item = pqueue_find(s->d1->buffered_messages, seq64);
-	pq_64bit_free(&seq64);
+	memset(seq64be,0,sizeof(seq64be));
+	seq64be[6] = (unsigned char) (msg_hdr->seq>>8);
+	seq64be[7] = (unsigned char) msg_hdr->seq;
+	item = pqueue_find(s->d1->buffered_messages, seq64be);
 	
 	/* Discard the message if sequence number was already there, is
 	 * too far in the future, already in the queue or if we received
@@ -601,29 +602,29 @@
 		}
 
 	if (frag_len)
-	{
+		{
 		frag = dtls1_hm_fragment_new(frag_len);
 		if ( frag == NULL)
 			goto err;
 
 		memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
 
-		/* read the body of the fragment (header has already been read) */
+		/* read the body of the fragment (header has already been read */
 		i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
 			frag->fragment,frag_len,0);
 		if (i<=0 || (unsigned long)i!=frag_len)
 			goto err;
 
-		pq_64bit_init(&seq64);
-		pq_64bit_assign_word(&seq64, msg_hdr->seq);
+		memset(seq64be,0,sizeof(seq64be));
+		seq64be[6] = (unsigned char)(msg_hdr->seq>>8);
+		seq64be[7] = (unsigned char)(msg_hdr->seq);
 
-		item = pitem_new(seq64, frag);
-		pq_64bit_free(&seq64);
+		item = pitem_new(seq64be, frag);
 		if ( item == NULL)
 			goto err;
 
 		pqueue_insert(s->d1->buffered_messages, item);
-	}
+		}
 
 	return DTLS1_HM_FRAGMENT_RETRY;
 
@@ -757,8 +758,6 @@
 		p= &(d[DTLS1_HM_HEADER_LENGTH]);
 
 		i=s->method->ssl3_enc->final_finish_mac(s,
-			&(s->s3->finish_dgst1),
-			&(s->s3->finish_dgst2),
 			sender,slen,s->s3->tmp.finish_md);
 		s->s3->tmp.finish_md_len = i;
 		memcpy(p, s->s3->tmp.finish_md, i);
@@ -823,12 +822,11 @@
 		s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
 		s->init_num=DTLS1_CCS_HEADER_LENGTH;
 
-		if (s->client_version == DTLS1_BAD_VER)
-			{
+		if (s->version == DTLS1_BAD_VER) {
 			s->d1->next_handshake_write_seq++;
 			s2n(s->d1->handshake_write_seq,p);
 			s->init_num+=2;
-			}
+		}
 
 		s->init_off=0;
 
@@ -847,21 +845,21 @@
 
 static int dtls1_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
 	{
-		int n;
-		unsigned char *p;
+	int n;
+	unsigned char *p;
 
-		n=i2d_X509(x,NULL);
-		if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3)))
-			{
-			SSLerr(SSL_F_DTLS1_ADD_CERT_TO_BUF,ERR_R_BUF_LIB);
-			return 0;
-			}
-		p=(unsigned char *)&(buf->data[*l]);
-		l2n3(n,p);
-		i2d_X509(x,&p);
-		*l+=n+3;
+	n=i2d_X509(x,NULL);
+	if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3)))
+		{
+		SSLerr(SSL_F_DTLS1_ADD_CERT_TO_BUF,ERR_R_BUF_LIB);
+		return 0;
+		}
+	p=(unsigned char *)&(buf->data[*l]);
+	l2n3(n,p);
+	i2d_X509(x,&p);
+	*l+=n+3;
 
-		return 1;
+	return 1;
 	}
 unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
 	{
@@ -880,7 +878,7 @@
 	if (x != NULL)
 		{
 		X509_STORE_CTX xs_ctx;
-  
+
 		if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL))
   			{
   			SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
@@ -888,6 +886,8 @@
   			}
   
 		X509_verify_cert(&xs_ctx);
+		/* Don't leave errors in the queue */
+		ERR_clear_error();
 		for (i=0; i < sk_X509_num(xs_ctx.chain); i++)
   			{
 			x = sk_X509_value(xs_ctx.chain, i);
@@ -900,7 +900,7 @@
   			}
   		X509_STORE_CTX_cleanup(&xs_ctx);
   		}
-	/* Thawte special :-) */
+  	/* Thawte special :-) */
 	for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
 		{
 		x=sk_X509_value(s->ctx->extra_certs,i);
@@ -1004,7 +1004,7 @@
 	{
 	pitem *item;
 	hm_fragment *frag;
-	PQ_64BIT seq64;
+	unsigned char seq64be[8];
 
 	/* this function is called immediately after a message has 
 	 * been serialized */
@@ -1017,7 +1017,7 @@
 	if ( is_ccs)
 		{
 		OPENSSL_assert(s->d1->w_msg_hdr.msg_len + 
-			DTLS1_CCS_HEADER_LENGTH <= (unsigned int)s->init_num);
+			       ((s->version==DTLS1_VERSION)?DTLS1_CCS_HEADER_LENGTH:3) == (unsigned int)s->init_num);
 		}
 	else
 		{
@@ -1038,15 +1038,14 @@
 	frag->msg_header.saved_retransmit_state.compress = s->compress;
 	frag->msg_header.saved_retransmit_state.session = s->session;
 	frag->msg_header.saved_retransmit_state.epoch = s->d1->w_epoch;
+	
+	memset(seq64be,0,sizeof(seq64be));
+	seq64be[6] = (unsigned char)(dtls1_get_queue_priority(frag->msg_header.seq,
+														  frag->msg_header.is_ccs)>>8);
+	seq64be[7] = (unsigned char)(dtls1_get_queue_priority(frag->msg_header.seq,
+														  frag->msg_header.is_ccs));
 
-	pq_64bit_init(&seq64);
-
-	pq_64bit_assign_word(&seq64,
-						 dtls1_get_queue_priority(frag->msg_header.seq,
-												  frag->msg_header.is_ccs));
-		
-	item = pitem_new(seq64, frag);
-	pq_64bit_free(&seq64);
+	item = pitem_new(seq64be, frag);
 	if ( item == NULL)
 		{
 		dtls1_hm_fragment_free(frag);
@@ -1072,7 +1071,7 @@
 	pitem *item;
 	hm_fragment *frag ;
 	unsigned long header_length;
-	PQ_64BIT seq64;
+	unsigned char seq64be[8];
 	struct dtls1_retransmit_state saved_state;
 	unsigned char save_write_sequence[8];
 
@@ -1082,11 +1081,11 @@
 	 */
 
 	/* XDTLS:  the requested message ought to be found, otherwise error */
-	pq_64bit_init(&seq64);
-	pq_64bit_assign_word(&seq64, seq);
+	memset(seq64be,0,sizeof(seq64be));
+	seq64be[6] = (unsigned char)(seq>>8);
+	seq64be[7] = (unsigned char)seq;
 
-	item = pqueue_find(s->d1->sent_messages, seq64);
-	pq_64bit_free(&seq64);
+	item = pqueue_find(s->d1->sent_messages, seq64be);
 	if ( item == NULL)
 		{
 		fprintf(stderr, "retransmit:  message %d non-existant\n", seq);
@@ -1237,7 +1236,7 @@
 static unsigned int 
 dtls1_guess_mtu(unsigned int curr_mtu)
 	{
-	size_t i;
+	unsigned int i;
 
 	if ( curr_mtu == 0 )
 		return g_probable_mtu[0] ;
diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c
index 223d116..5bc9eb6 100644
--- a/ssl/d1_clnt.c
+++ b/ssl/d1_clnt.c
@@ -4,7 +4,7 @@
  * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
  */
 /* ====================================================================
- * 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
@@ -115,20 +115,23 @@
 
 #include <stdio.h>
 #include "ssl_locl.h"
+#ifndef OPENSSL_NO_KRB5
 #include "kssl_lcl.h"
+#endif
 #include <openssl/buffer.h>
 #include <openssl/rand.h>
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #include <openssl/md5.h>
+#include <openssl/bn.h>
 #ifndef OPENSSL_NO_DH
 #include <openssl/dh.h>
 #endif
 
-static SSL_METHOD *dtls1_get_client_method(int ver);
+static const SSL_METHOD *dtls1_get_client_method(int ver);
 static int dtls1_get_hello_verify(SSL *s);
 
-static SSL_METHOD *dtls1_get_client_method(int ver)
+static const SSL_METHOD *dtls1_get_client_method(int ver)
 	{
 	if (ver == DTLS1_VERSION || ver == DTLS1_BAD_VER)
 		return(DTLSv1_client_method());
@@ -144,7 +147,7 @@
 int dtls1_connect(SSL *s)
 	{
 	BUF_MEM *buf=NULL;
-	unsigned long Time=(unsigned long)time(NULL),l;
+	unsigned long Time=(unsigned long)time(NULL);
 	void (*cb)(const SSL *ssl,int type,int val)=NULL;
 	int ret= -1;
 	int new_state,state,skip=0;;
@@ -296,8 +299,9 @@
 				break;
 				}
 #endif
-			/* Check if it is anon DH */
-			if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
+			/* Check if it is anon DH or PSK */
+			if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
+			    !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
 				{
 				ret=ssl3_get_server_certificate(s);
 				if (ret <= 0) goto end;
@@ -374,7 +378,6 @@
 			dtls1_start_timer(s);
 			ret=dtls1_send_client_key_exchange(s);
 			if (ret <= 0) goto end;
-			l=s->s3->tmp.new_cipher->algorithms;
 			/* EAY EAY EAY need to check for DH fix cert
 			 * sent back */
 			/* For TLS, cert_req is set to 2, so a cert chain
@@ -471,7 +474,6 @@
 				s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
 				}
 			s->init_num=0;
-
 			break;
 
 #ifndef OPENSSL_NO_TLSEXT
@@ -617,6 +619,7 @@
 		/* else use the pre-loaded session */
 
 		p=s->s3->client_random;
+
 		/* if client_random is initialized, reuse it, we are
 		 * required to use same upon reply to HelloVerify */
 		for (i=0;p[i]=='\0' && i<sizeof(s->s3->client_random);i++) ;
@@ -624,7 +627,7 @@
 			{
 			Time=(unsigned long)time(NULL);	/* Time */
 			l2n(Time,p);
-			RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4);
+			RAND_pseudo_bytes(p,sizeof(s->s3->client_random)-4);
 			}
 
 		/* Do the message type and length last */
@@ -771,7 +774,7 @@
 	{
 	unsigned char *p,*d;
 	int n;
-	unsigned long l;
+	unsigned long alg_k;
 #ifndef OPENSSL_NO_RSA
 	unsigned char *q;
 	EVP_PKEY *pkey=NULL;
@@ -779,18 +782,26 @@
 #ifndef OPENSSL_NO_KRB5
         KSSL_ERR kssl_err;
 #endif /* OPENSSL_NO_KRB5 */
+#ifndef OPENSSL_NO_ECDH
+	EC_KEY *clnt_ecdh = NULL;
+	const EC_POINT *srvr_ecpoint = NULL;
+	EVP_PKEY *srvr_pub_pkey = NULL;
+	unsigned char *encodedPoint = NULL;
+	int encoded_pt_len = 0;
+	BN_CTX * bn_ctx = NULL;
+#endif
 
 	if (s->state == SSL3_ST_CW_KEY_EXCH_A)
 		{
 		d=(unsigned char *)s->init_buf->data;
 		p= &(d[DTLS1_HM_HEADER_LENGTH]);
-
-		l=s->s3->tmp.new_cipher->algorithms;
+		
+		alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
 
                 /* Fool emacs indentation */
                 if (0) {}
 #ifndef OPENSSL_NO_RSA
-		else if (l & SSL_kRSA)
+		else if (alg_k & SSL_kRSA)
 			{
 			RSA *rsa;
 			unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
@@ -849,7 +860,7 @@
 			}
 #endif
 #ifndef OPENSSL_NO_KRB5
-		else if (l & SSL_kKRB5)
+		else if (alg_k & SSL_kKRB5)
                         {
                         krb5_error_code	krb5rc;
                         KSSL_CTX	*kssl_ctx = s->kssl_ctx;
@@ -857,7 +868,7 @@
                         krb5_data	*enc_ticket;
                         krb5_data	authenticator, *authp = NULL;
 			EVP_CIPHER_CTX	ciph_ctx;
-			EVP_CIPHER	*enc = NULL;
+			const EVP_CIPHER *enc = NULL;
 			unsigned char	iv[EVP_MAX_IV_LENGTH];
 			unsigned char	tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
 			unsigned char	epms[SSL_MAX_MASTER_KEY_LENGTH 
@@ -868,7 +879,7 @@
 
 #ifdef KSSL_DEBUG
                         printf("ssl3_send_client_key_exchange(%lx & %lx)\n",
-                                l, SSL_kKRB5);
+                                alg_k, SSL_kKRB5);
 #endif	/* KSSL_DEBUG */
 
 			authp = NULL;
@@ -958,7 +969,7 @@
 				sizeof tmp_buf);
 			EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl);
 			outl += padl;
-			if (outl > sizeof epms)
+			if (outl > (int)sizeof epms)
 				{
 				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
 				goto err;
@@ -981,7 +992,7 @@
                         }
 #endif
 #ifndef OPENSSL_NO_DH
-		else if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
+		else if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
 			{
 			DH *dh_srvr,*dh_clnt;
 
@@ -1036,6 +1047,274 @@
 			/* perhaps clean things up a bit EAY EAY EAY EAY*/
 			}
 #endif
+#ifndef OPENSSL_NO_ECDH 
+		else if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe))
+			{
+			const EC_GROUP *srvr_group = NULL;
+			EC_KEY *tkey;
+			int ecdh_clnt_cert = 0;
+			int field_size = 0;
+
+			/* Did we send out the client's
+			 * ECDH share for use in premaster
+			 * computation as part of client certificate?
+			 * If so, set ecdh_clnt_cert to 1.
+			 */
+			if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->cert != NULL)) 
+				{
+				/* XXX: For now, we do not support client
+				 * authentication using ECDH certificates.
+				 * To add such support, one needs to add
+				 * code that checks for appropriate 
+				 * conditions and sets ecdh_clnt_cert to 1.
+				 * For example, the cert have an ECC
+				 * key on the same curve as the server's
+				 * and the key should be authorized for
+				 * key agreement.
+				 *
+				 * One also needs to add code in ssl3_connect
+				 * to skip sending the certificate verify
+				 * message.
+				 *
+				 * if ((s->cert->key->privatekey != NULL) &&
+				 *     (s->cert->key->privatekey->type ==
+				 *      EVP_PKEY_EC) && ...)
+				 * ecdh_clnt_cert = 1;
+				 */
+				}
+
+			if (s->session->sess_cert->peer_ecdh_tmp != NULL)
+				{
+				tkey = s->session->sess_cert->peer_ecdh_tmp;
+				}
+			else
+				{
+				/* Get the Server Public Key from Cert */
+				srvr_pub_pkey = X509_get_pubkey(s->session-> \
+				    sess_cert->peer_pkeys[SSL_PKEY_ECC].x509);
+				if ((srvr_pub_pkey == NULL) ||
+				    (srvr_pub_pkey->type != EVP_PKEY_EC) ||
+				    (srvr_pub_pkey->pkey.ec == NULL))
+					{
+					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
+					    ERR_R_INTERNAL_ERROR);
+					goto err;
+					}
+
+				tkey = srvr_pub_pkey->pkey.ec;
+				}
+
+			srvr_group   = EC_KEY_get0_group(tkey);
+			srvr_ecpoint = EC_KEY_get0_public_key(tkey);
+
+			if ((srvr_group == NULL) || (srvr_ecpoint == NULL))
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
+				    ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+
+			if ((clnt_ecdh=EC_KEY_new()) == NULL) 
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+
+			if (!EC_KEY_set_group(clnt_ecdh, srvr_group))
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB);
+				goto err;
+				}
+			if (ecdh_clnt_cert) 
+				{ 
+				/* Reuse key info from our certificate
+				 * We only need our private key to perform
+				 * the ECDH computation.
+				 */
+				const BIGNUM *priv_key;
+				tkey = s->cert->key->privatekey->pkey.ec;
+				priv_key = EC_KEY_get0_private_key(tkey);
+				if (priv_key == NULL)
+					{
+					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
+					goto err;
+					}
+				if (!EC_KEY_set_private_key(clnt_ecdh, priv_key))
+					{
+					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB);
+					goto err;
+					}
+				}
+			else 
+				{
+				/* Generate a new ECDH key pair */
+				if (!(EC_KEY_generate_key(clnt_ecdh)))
+					{
+					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB);
+					goto err;
+					}
+				}
+
+			/* use the 'p' output buffer for the ECDH key, but
+			 * make sure to clear it out afterwards
+			 */
+
+			field_size = EC_GROUP_get_degree(srvr_group);
+			if (field_size <= 0)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, 
+				       ERR_R_ECDH_LIB);
+				goto err;
+				}
+			n=ECDH_compute_key(p, (field_size+7)/8, srvr_ecpoint, clnt_ecdh, NULL);
+			if (n <= 0)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, 
+				       ERR_R_ECDH_LIB);
+				goto err;
+				}
+
+			/* generate master key from the result */
+			s->session->master_key_length = s->method->ssl3_enc \
+			    -> generate_master_secret(s, 
+				s->session->master_key,
+				p, n);
+
+			memset(p, 0, n); /* clean up */
+
+			if (ecdh_clnt_cert) 
+				{
+				/* Send empty client key exch message */
+				n = 0;
+				}
+			else 
+				{
+				/* First check the size of encoding and
+				 * allocate memory accordingly.
+				 */
+				encoded_pt_len = 
+				    EC_POINT_point2oct(srvr_group, 
+					EC_KEY_get0_public_key(clnt_ecdh), 
+					POINT_CONVERSION_UNCOMPRESSED, 
+					NULL, 0, NULL);
+
+				encodedPoint = (unsigned char *) 
+				    OPENSSL_malloc(encoded_pt_len * 
+					sizeof(unsigned char)); 
+				bn_ctx = BN_CTX_new();
+				if ((encodedPoint == NULL) || 
+				    (bn_ctx == NULL)) 
+					{
+					SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
+					goto err;
+					}
+
+				/* Encode the public key */
+				n = EC_POINT_point2oct(srvr_group, 
+				    EC_KEY_get0_public_key(clnt_ecdh), 
+				    POINT_CONVERSION_UNCOMPRESSED, 
+				    encodedPoint, encoded_pt_len, bn_ctx);
+
+				*p = n; /* length of encoded point */
+				/* Encoded point will be copied here */
+				p += 1; 
+				/* copy the point */
+				memcpy((unsigned char *)p, encodedPoint, n);
+				/* increment n to account for length field */
+				n += 1; 
+				}
+
+			/* Free allocated memory */
+			BN_CTX_free(bn_ctx);
+			if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
+			if (clnt_ecdh != NULL) 
+				 EC_KEY_free(clnt_ecdh);
+			EVP_PKEY_free(srvr_pub_pkey);
+			}
+#endif /* !OPENSSL_NO_ECDH */
+
+#ifndef OPENSSL_NO_PSK
+		else if (alg_k & SSL_kPSK)
+			{
+			char identity[PSK_MAX_IDENTITY_LEN];
+			unsigned char *t = NULL;
+			unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4];
+			unsigned int pre_ms_len = 0, psk_len = 0;
+			int psk_err = 1;
+
+			n = 0;
+			if (s->psk_client_callback == NULL)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
+					SSL_R_PSK_NO_CLIENT_CB);
+				goto err;
+				}
+
+			psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint,
+				identity, PSK_MAX_IDENTITY_LEN,
+				psk_or_pre_ms, sizeof(psk_or_pre_ms));
+			if (psk_len > PSK_MAX_PSK_LEN)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
+					ERR_R_INTERNAL_ERROR);
+				goto psk_err;
+				}
+			else if (psk_len == 0)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
+					SSL_R_PSK_IDENTITY_NOT_FOUND);
+				goto psk_err;
+				}
+
+			/* create PSK pre_master_secret */
+			pre_ms_len = 2+psk_len+2+psk_len;
+			t = psk_or_pre_ms;
+			memmove(psk_or_pre_ms+psk_len+4, psk_or_pre_ms, psk_len);
+			s2n(psk_len, t);
+			memset(t, 0, psk_len);
+			t+=psk_len;
+			s2n(psk_len, t);
+
+			if (s->session->psk_identity_hint != NULL)
+				OPENSSL_free(s->session->psk_identity_hint);
+			s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint);
+			if (s->ctx->psk_identity_hint != NULL &&
+				s->session->psk_identity_hint == NULL)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
+					ERR_R_MALLOC_FAILURE);
+				goto psk_err;
+				}
+
+			if (s->session->psk_identity != NULL)
+				OPENSSL_free(s->session->psk_identity);
+			s->session->psk_identity = BUF_strdup(identity);
+			if (s->session->psk_identity == NULL)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
+					ERR_R_MALLOC_FAILURE);
+				goto psk_err;
+				}
+
+			s->session->master_key_length =
+				s->method->ssl3_enc->generate_master_secret(s,
+					s->session->master_key,
+					psk_or_pre_ms, pre_ms_len); 
+			n = strlen(identity);
+			s2n(n, p);
+			memcpy(p, identity, n);
+			n+=2;
+			psk_err = 0;
+		psk_err:
+			OPENSSL_cleanse(identity, PSK_MAX_IDENTITY_LEN);
+			OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
+			if (psk_err != 0)
+				{
+				ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+				goto err;
+				}
+			}
+#endif
 		else
 			{
 			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
@@ -1064,6 +1343,13 @@
 	/* SSL3_ST_CW_KEY_EXCH_B */
 	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
 err:
+#ifndef OPENSSL_NO_ECDH
+	BN_CTX_free(bn_ctx);
+	if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
+	if (clnt_ecdh != NULL) 
+		EC_KEY_free(clnt_ecdh);
+	EVP_PKEY_free(srvr_pub_pkey);
+#endif
 	return(-1);
 	}
 
@@ -1076,7 +1362,7 @@
 	unsigned u=0;
 #endif
 	unsigned long n;
-#ifndef OPENSSL_NO_DSA
+#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
 	int j;
 #endif
 
@@ -1086,14 +1372,16 @@
 		p= &(d[DTLS1_HM_HEADER_LENGTH]);
 		pkey=s->cert->key->privatekey;
 
-		s->method->ssl3_enc->cert_verify_mac(s,&(s->s3->finish_dgst2),
+		s->method->ssl3_enc->cert_verify_mac(s,
+		NID_sha1,
 			&(data[MD5_DIGEST_LENGTH]));
 
 #ifndef OPENSSL_NO_RSA
 		if (pkey->type == EVP_PKEY_RSA)
 			{
 			s->method->ssl3_enc->cert_verify_mac(s,
-				&(s->s3->finish_dgst1),&(data[0]));
+				NID_md5,
+				&(data[0]));
 			if (RSA_sign(NID_md5_sha1, data,
 					 MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH,
 					&(p[2]), &u, pkey->pkey.rsa) <= 0 )
@@ -1122,6 +1410,23 @@
 			}
 		else
 #endif
+#ifndef OPENSSL_NO_ECDSA
+			if (pkey->type == EVP_PKEY_EC)
+			{
+			if (!ECDSA_sign(pkey->save_type,
+				&(data[MD5_DIGEST_LENGTH]),
+				SHA_DIGEST_LENGTH,&(p[2]),
+				(unsigned int *)&j,pkey->pkey.ec))
+				{
+				SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,
+				    ERR_R_ECDSA_LIB);
+				goto err;
+				}
+			s2n(j,p);
+			n=j+2;
+			}
+		else
+#endif
 			{
 			SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_INTERNAL_ERROR);
 			goto err;
diff --git a/ssl/d1_enc.c b/ssl/d1_enc.c
index 3dfa5ad..8fa5734 100644
--- a/ssl/d1_enc.c
+++ b/ssl/d1_enc.c
@@ -136,8 +136,12 @@
 
 	if (send)
 		{
-		if (s->write_hash != NULL)
-			n=EVP_MD_size(s->write_hash);
+		if (EVP_MD_CTX_md(s->write_hash))
+			{
+			n=EVP_MD_CTX_size(s->write_hash);
+			if (n < 0)
+				return -1;
+			}
 		ds=s->enc_write_ctx;
 		rec= &(s->s3->wrec);
 		if (s->enc_write_ctx == NULL)
@@ -158,8 +162,12 @@
 		}
 	else
 		{
-		if (s->read_hash != NULL)
-			n=EVP_MD_size(s->read_hash);
+		if (EVP_MD_CTX_md(s->read_hash))
+			{
+			n=EVP_MD_CTX_size(s->read_hash);
+			if (n < 0)
+				return -1;
+			}
 		ds=s->enc_read_ctx;
 		rec= &(s->s3->rrec);
 		if (s->enc_read_ctx == NULL)
@@ -206,11 +214,10 @@
 		{
                 unsigned long ui;
 		printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\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,rec->data,rec->input,l);
+		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
                         ds->buf_len, ds->cipher->key_len,
-                        (unsigned long)DES_KEY_SZ,
-			(unsigned long)DES_SCHEDULE_SZ,
+                        DES_KEY_SZ, DES_SCHEDULE_SZ,
                         ds->cipher->iv_len);
 		printf("\t\tIV: ");
 		for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
@@ -235,10 +242,10 @@
 
 #ifdef KSSL_DEBUG
 		{
-                unsigned long ki;
+                unsigned long i;
                 printf("\trec->data=");
-		for (ki=0; ki<l; ki++)
-                        printf(" %02x", rec->data[ki]);  printf("\n");
+		for (i=0; i<l; i++)
+                        printf(" %02x", rec->data[i]);  printf("\n");
                 }
 #endif	/* KSSL_DEBUG */
 
diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c
index 63bfbac..eeffce3 100644
--- a/ssl/d1_lib.c
+++ b/ssl/d1_lib.c
@@ -91,11 +91,6 @@
 	return(60*60*2);
 	}
 
-IMPLEMENT_dtls1_meth_func(dtlsv1_base_method,
-			ssl_undefined_function,
-			ssl_undefined_function,
-			ssl_bad_method)
-
 int dtls1_new(SSL *s)
 	{
 	DTLS1_STATE *d1;
@@ -105,17 +100,6 @@
 	memset(d1,0, sizeof *d1);
 
 	/* d1->handshake_epoch=0; */
-#if defined(OPENSSL_SYS_VMS) || defined(VMS_TEST)
-	d1->bitmap.length=64;
-#else
-	d1->bitmap.length=sizeof(d1->bitmap.map) * 8;
-#endif
-	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));
 
 	d1->unprocessed_rcds.q=pqueue_new();
 	d1->processed_rcds.q=pqueue_new();
@@ -185,19 +169,13 @@
 	pqueue_free(s->d1->sent_messages);
 
 	while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
-	{
+		{
 		frag = (hm_fragment *)item->data;
 		OPENSSL_free(frag->fragment);
 		OPENSSL_free(frag);
 		pitem_free(item);
-	}
+		}
 	pqueue_free(s->d1->buffered_app_data.q);
-	
-	pq_64bit_free(&(s->d1->bitmap.map));
-	pq_64bit_free(&(s->d1->bitmap.max_seq_num));
-
-	pq_64bit_free(&(s->d1->next_bitmap.map));
-	pq_64bit_free(&(s->d1->next_bitmap.max_seq_num));
 
 	OPENSSL_free(s->d1);
 	}
@@ -244,13 +222,13 @@
  * to explicitly list their SSL_* codes. Currently RC4 is the only one
  * available, but if new ones emerge, they will have to be added...
  */
-SSL_CIPHER *dtls1_get_cipher(unsigned int u)
+const SSL_CIPHER *dtls1_get_cipher(unsigned int u)
 	{
-	SSL_CIPHER *ciph = ssl3_get_cipher(u);
+	const SSL_CIPHER *ciph = ssl3_get_cipher(u);
 
 	if (ciph != NULL)
 		{
-		if ((ciph->algorithms&SSL_ENC_MASK) == SSL_RC4)
+		if (ciph->algorithm_enc == SSL_RC4)
 			return NULL;
 		}
 
diff --git a/ssl/d1_meth.c b/ssl/d1_meth.c
index 8a6cf31..5c4004b 100644
--- a/ssl/d1_meth.c
+++ b/ssl/d1_meth.c
@@ -61,8 +61,8 @@
 #include <openssl/objects.h>
 #include "ssl_locl.h"
 
-static SSL_METHOD *dtls1_get_method(int ver);
-static SSL_METHOD *dtls1_get_method(int ver)
+static const SSL_METHOD *dtls1_get_method(int ver);
+static const SSL_METHOD *dtls1_get_method(int ver)
 	{
 	if (ver == DTLS1_VERSION)
 		return(DTLSv1_method());
diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c
index 2af5272..13ffc75 100644
--- a/ssl/d1_pkt.c
+++ b/ssl/d1_pkt.c
@@ -122,10 +122,53 @@
 #include <openssl/pqueue.h>
 #include <openssl/rand.h>
 
+/* mod 128 saturating subtract of two 64-bit values in big-endian order */
+static int satsub64be(const unsigned char *v1,const unsigned char *v2)
+{	int ret,sat,brw,i;
+
+	if (sizeof(long) == 8) do
+	{	const union { long one; char little; } is_endian = {1};
+		long l;
+
+		if (is_endian.little)			break;
+		/* not reached on little-endians */
+		/* following test is redundant, because input is
+		 * always aligned, but I take no chances... */
+		if (((size_t)v1|(size_t)v2)&0x7)	break;
+
+		l  = *((long *)v1);
+		l -= *((long *)v2);
+		if (l>128)		return 128;
+		else if (l<-128)	return -128;
+		else			return (int)l;
+	} while (0);
+
+	ret = (int)v1[7]-(int)v2[7];
+	sat = 0;
+	brw = ret>>8;	/* brw is either 0 or -1 */
+	if (ret & 0x80)
+	{	for (i=6;i>=0;i--)
+		{	brw += (int)v1[i]-(int)v2[i];
+			sat |= ~brw;
+			brw >>= 8;
+		}
+	}
+	else
+	{	for (i=6;i>=0;i--)
+		{	brw += (int)v1[i]-(int)v2[i];
+			sat |= brw;
+			brw >>= 8;
+		}
+	}
+	brw <<= 8;	/* brw is either 0 or -256 */
+
+	if (sat&0xff)	return brw | 0x80;
+	else		return brw + (ret&0xFF);
+}
+
 static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, 
 	int len, int peek);
-static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap,
-	PQ_64BIT *seq_num);
+static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap);
 static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap);
 static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, 
     unsigned int *is_next_epoch);
@@ -134,11 +177,8 @@
 	unsigned short *priority, unsigned long *offset);
 #endif
 static int dtls1_buffer_record(SSL *s, record_pqueue *q,
-	PQ_64BIT *priority);
+	unsigned char *priority);
 static int dtls1_process_record(SSL *s);
-#if PQ_64BIT_IS_INTEGER
-static PQ_64BIT bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num);
-#endif
 static void dtls1_clear_timeouts(SSL *s);
 
 /* copy buffered record into SSL structure */
@@ -162,9 +202,9 @@
 
 
 static int
-dtls1_buffer_record(SSL *s, record_pqueue *queue, PQ_64BIT *priority)
-{
-    DTLS1_RECORD_DATA *rdata;
+dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
+	{
+	DTLS1_RECORD_DATA *rdata;
 	pitem *item;
 
 	/* Limit the size of the queue to prevent DOS attacks */
@@ -172,7 +212,7 @@
 		return 0;
 		
 	rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA));
-	item = pitem_new(*priority, rdata);
+	item = pitem_new(priority, rdata);
 	if (rdata == NULL || item == NULL)
 		{
 		if (rdata != NULL) OPENSSL_free(rdata);
@@ -211,7 +251,7 @@
 		}
 	
 	return(1);
-    }
+	}
 
 
 static int
@@ -267,7 +307,7 @@
             if ( ! dtls1_process_record(s))
                 return(0);
             dtls1_buffer_record(s, &(s->d1->processed_rcds), 
-                &s->s3->rrec.seq_num);
+                s->s3->rrec.seq_num);
             }
         }
 
@@ -328,17 +368,17 @@
 static int
 dtls1_process_record(SSL *s)
 {
-    int i,al;
+	int i,al;
 	int clear=0;
-    int enc_err;
+	int enc_err;
 	SSL_SESSION *sess;
-    SSL3_RECORD *rr;
+	SSL3_RECORD *rr;
 	unsigned int mac_size;
 	unsigned char md[EVP_MAX_MD_SIZE];
 
 
 	rr= &(s->s3->rrec);
-    sess = s->session;
+	sess = s->session;
 
 	/* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
 	 * and we have that many bytes in s->packet
@@ -384,14 +424,18 @@
 #endif
 
 	/* r->length is now the compressed data plus mac */
-if (	(sess == NULL) ||
+	if (	(sess == NULL) ||
 		(s->enc_read_ctx == NULL) ||
 		(s->read_hash == NULL))
-    clear=1;
+		clear=1;
 
 	if (!clear)
 		{
-		mac_size=EVP_MD_size(s->read_hash);
+		/* !clear => s->read_hash != NULL => mac_size != -1 */
+		int t;
+		t=EVP_MD_CTX_size(s->read_hash);
+		OPENSSL_assert(t >= 0);
+		mac_size=t;
 
 		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size)
 			{
@@ -416,7 +460,7 @@
 			}
 		rr->length-=mac_size;
 		i=s->method->ssl3_enc->mac(s,md,0);
-		if (memcmp(md,&(rr->data[rr->length]),mac_size) != 0)
+		if (i < 0 || memcmp(md,&(rr->data[rr->length]),mac_size) != 0)
 			{
 			goto decryption_failed_or_bad_record_mac;
 			}
@@ -457,8 +501,8 @@
 
 	/* we have pulled in a full packet so zero things */
 	s->packet_length=0;
-    dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */
-    return(1);
+	dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */
+	return(1);
 
 decryption_failed_or_bad_record_mac:
 	/* Separate 'decryption_failed' alert was introduced with TLS 1.0,
@@ -498,10 +542,10 @@
 	rr= &(s->s3->rrec);
 	sess=s->session;
 
-    /* The epoch may have changed.  If so, process all the
-     * pending records.  This is a non-blocking operation. */
-    if ( ! dtls1_process_buffered_records(s))
-        return 0;
+	/* The epoch may have changed.  If so, process all the
+	 * pending records.  This is a non-blocking operation. */
+	if ( ! dtls1_process_buffered_records(s))
+            return 0;
 
 	/* if we're renegotiating, then there may be buffered records */
 	if (dtls1_get_processed_record(s))
@@ -545,7 +589,7 @@
 		/* Lets check version */
 		if (!s->first_packet)
 			{
-			if (version != s->version && version != DTLS1_BAD_VER)
+			if (version != s->version)
 				{
 				/* unexpected version, silently discard */
 				rr->length = 0;
@@ -554,8 +598,7 @@
 				}
 			}
 
-		if ((version & 0xff00) != (DTLS1_VERSION & 0xff00) &&
-		    (version & 0xff00) != (DTLS1_BAD_VER & 0xff00))
+		if ((version & 0xff00) != (s->version & 0xff00))
 			{
 			/* wrong version, silently discard record */
 			rr->length = 0;
@@ -589,7 +632,6 @@
 			s->packet= &(s->s3->rbuf.buf[0]);
 			}
 
-		s->client_version = version;
 		/* now s->rstate == SSL_ST_READ_BODY */
 		}
 
@@ -618,13 +660,13 @@
 	/* match epochs.  NULL means the packet is dropped on the floor */
 	bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
 	if ( bitmap == NULL)
-        {
-	rr->length = 0;
-        s->packet_length = 0;  /* dump this record */
-        goto again;   /* get another record */
+		{
+		rr->length = 0;
+		s->packet_length = 0;  /* dump this record */
+		goto again;   /* get another record */
 		}
 
- 	/* Check whether this is a repeat, or aged record.
+	/* Check whether this is a repeat, or aged record.
 	 * Don't check if we're listening and this message is
 	 * a ClientHello. They can look as if they're replayed,
 	 * since they arrive from different connections and
@@ -632,7 +674,7 @@
 	 */
 	if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE &&
 		*p == SSL3_MT_CLIENT_HELLO) &&
-		! dtls1_record_replay_check(s, bitmap, &(rr->seq_num)))
+		!dtls1_record_replay_check(s, bitmap))
 		{
 		rr->length = 0;
 		s->packet_length=0; /* dump this record */
@@ -642,21 +684,22 @@
 	/* just read a 0 length packet */
 	if (rr->length == 0) goto again;
 
-    /* If this record is from the next epoch (either HM or ALERT), buffer it
-     * since it cannot be processed at this time.
-     * Records from the next epoch are marked as received even though they are 
-     * not processed, so as to prevent any potential resource DoS attack */
-    if (is_next_epoch)
-        {
-        dtls1_record_bitmap_update(s, bitmap);
-        dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), &rr->seq_num);
-	rr->length = 0;
-        s->packet_length = 0;
-        goto again;
-        }
+	/* If this record is from the next epoch (either HM or ALERT),
+	 * buffer it since it cannot be processed at this time. Records
+	 * from the next epoch are marked as received even though they
+	 * are not processed, so as to prevent any potential resource
+	 * DoS attack */
+	if (is_next_epoch)
+		{
+		dtls1_record_bitmap_update(s, bitmap);
+		dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);
+		rr->length = 0;
+		s->packet_length = 0;
+		goto again;
+		}
 
-    if ( ! dtls1_process_record(s))
-        return(0);
+	if ( ! dtls1_process_record(s))
+		return(0);
 
 	dtls1_clear_timeouts(s);  /* done waiting */
 	return(1);
@@ -1066,13 +1109,14 @@
 
 		dtls1_get_ccs_header(rr->data, &ccs_hdr);
 
+		if (s->version == DTLS1_BAD_VER)
+			ccs_hdr_len = 3;
+
 		/* 'Change Cipher Spec' is just a single byte, so we know
 		 * exactly what the record payload has to look like */
 		/* XDTLS: check that epoch is consistent */
-		if (s->client_version == DTLS1_BAD_VER || s->version == DTLS1_BAD_VER)
-			ccs_hdr_len = 3;
-
-		if ((rr->length != ccs_hdr_len) || (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS))
+		if (	(rr->length != ccs_hdr_len) || 
+			(rr->off != 0) || (rr->data[0] != SSL3_MT_CCS))
 			{
 			i=SSL_AD_ILLEGAL_PARAMETER;
 			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC);
@@ -1102,7 +1146,7 @@
 		/* do this whenever CCS is processed */
 		dtls1_reset_seq_numbers(s, SSL3_CC_READ);
 
-		if (s->client_version == DTLS1_BAD_VER)
+		if (s->version == DTLS1_BAD_VER)
 			s->d1->handshake_read_seq++;
 
 		goto start;
@@ -1356,13 +1400,17 @@
 
 	if (	(sess == NULL) ||
 		(s->enc_write_ctx == NULL) ||
-		(s->write_hash == NULL))
+		(EVP_MD_CTX_md(s->write_hash) == NULL))
 		clear=1;
 
 	if (clear)
 		mac_size=0;
 	else
-		mac_size=EVP_MD_size(s->write_hash);
+		{
+		mac_size=EVP_MD_CTX_size(s->write_hash);
+		if (mac_size < 0)
+			goto err;
+		}
 
 	/* DTLS implements explicit IV, so no need for empty fragments */
 #if 0
@@ -1395,7 +1443,6 @@
 		s->s3->empty_fragment_done = 1;
 		}
 #endif
-
 	p = wb->buf + prefix_len;
 
 	/* write the header */
@@ -1403,12 +1450,8 @@
 	*(p++)=type&0xff;
 	wr->type=type;
 
-	if (s->client_version == DTLS1_BAD_VER)
-		*(p++) = DTLS1_BAD_VER>>8,
-		*(p++) = DTLS1_BAD_VER&0xff;
-	else
-		*(p++)=(s->version>>8),
-		*(p++)=s->version&0xff;
+	*(p++)=(s->version>>8);
+	*(p++)=s->version&0xff;
 
 	/* field where we are to write out packet epoch, seq num and len */
 	pseq=p; 
@@ -1453,7 +1496,8 @@
 
 	if (mac_size != 0)
 		{
-		s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1);
+		if(s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1) < 0)
+			goto err;
 		wr->length+=mac_size;
 		}
 
@@ -1530,111 +1574,50 @@
 
 
 
-static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap,
-	PQ_64BIT *seq_num)
+static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap)
 	{
-#if PQ_64BIT_IS_INTEGER
-	PQ_64BIT mask = 0x0000000000000001L;
-#endif
-	PQ_64BIT rcd_num, tmp;
+	int cmp;
+	unsigned int shift;
+	const unsigned char *seq = s->s3->read_sequence;
 
-	pq_64bit_init(&rcd_num);
-	pq_64bit_init(&tmp);
-
-	/* this is the sequence number for the record just read */
-	pq_64bit_bin2num(&rcd_num, s->s3->read_sequence, 8);
-
-	
-	if (pq_64bit_gt(&rcd_num, &(bitmap->max_seq_num)) ||
-		pq_64bit_eq(&rcd_num, &(bitmap->max_seq_num)))
+	cmp = satsub64be(seq,bitmap->max_seq_num);
+	if (cmp > 0)
 		{
-		pq_64bit_assign(seq_num, &rcd_num);
-		pq_64bit_free(&rcd_num);
-		pq_64bit_free(&tmp);
-		return 1;  /* this record is new */
+		memcpy (s->s3->rrec.seq_num,seq,8);
+		return 1; /* this record in new */
 		}
-
-	pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num);
-
-	if ( pq_64bit_get_word(&tmp) > bitmap->length)
-		{
-		pq_64bit_free(&rcd_num);
-		pq_64bit_free(&tmp);
-		return 0;  /* stale, outside the window */
-		}
-
-#if PQ_64BIT_IS_BIGNUM
-	{
-	int offset;
-	pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num);
-	pq_64bit_sub_word(&tmp, 1);
-	offset = pq_64bit_get_word(&tmp);
-	if ( pq_64bit_is_bit_set(&(bitmap->map), offset))
-		{
-		pq_64bit_free(&rcd_num);
-		pq_64bit_free(&tmp);
-		return 0;
-		}
-	}
-#else
-	mask <<= (bitmap->max_seq_num - rcd_num - 1);
-	if (bitmap->map & mask)
+	shift = -cmp;
+	if (shift >= sizeof(bitmap->map)*8)
+		return 0; /* stale, outside the window */
+	else if (bitmap->map & (1UL<<shift))
 		return 0; /* record previously received */
-#endif
-	
-	pq_64bit_assign(seq_num, &rcd_num);
-	pq_64bit_free(&rcd_num);
-	pq_64bit_free(&tmp);
+
+	memcpy (s->s3->rrec.seq_num,seq,8);
 	return 1;
 	}
 
 
 static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap)
 	{
+	int cmp;
 	unsigned int shift;
-	PQ_64BIT rcd_num;
-	PQ_64BIT tmp;
-	PQ_64BIT_CTX *ctx;
+	const unsigned char *seq = s->s3->read_sequence;
 
-	pq_64bit_init(&rcd_num);
-	pq_64bit_init(&tmp);
-
-	pq_64bit_bin2num(&rcd_num, s->s3->read_sequence, 8);
-
-	/* unfortunate code complexity due to 64-bit manipulation support
-	 * on 32-bit machines */
-	if ( pq_64bit_gt(&rcd_num, &(bitmap->max_seq_num)) ||
-		pq_64bit_eq(&rcd_num, &(bitmap->max_seq_num)))
+	cmp = satsub64be(seq,bitmap->max_seq_num);
+	if (cmp > 0)
 		{
-		pq_64bit_sub(&tmp, &rcd_num, &(bitmap->max_seq_num));
-		pq_64bit_add_word(&tmp, 1);
-
-		shift = (unsigned int)pq_64bit_get_word(&tmp);
-
-		pq_64bit_lshift(&(tmp), &(bitmap->map), shift);
-		pq_64bit_assign(&(bitmap->map), &tmp);
-
-		pq_64bit_set_bit(&(bitmap->map), 0);
-		pq_64bit_add_word(&rcd_num, 1);
-		pq_64bit_assign(&(bitmap->max_seq_num), &rcd_num);
-
-		pq_64bit_assign_word(&tmp, 1);
-		pq_64bit_lshift(&tmp, &tmp, bitmap->length);
-		ctx = pq_64bit_ctx_new(&ctx);
-		pq_64bit_mod(&(bitmap->map), &(bitmap->map), &tmp, ctx);
-		pq_64bit_ctx_free(ctx);
+		shift = cmp;
+		if (shift < sizeof(bitmap->map)*8)
+			bitmap->map <<= shift, bitmap->map |= 1UL;
+		else
+			bitmap->map = 1UL;
+		memcpy(bitmap->max_seq_num,seq,8);
 		}
-	else
-		{
-		pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num);
-		pq_64bit_sub_word(&tmp, 1);
-		shift = (unsigned int)pq_64bit_get_word(&tmp);
-
-		pq_64bit_set_bit(&(bitmap->map), shift);
+	else	{
+		shift = -cmp;
+		if (shift < sizeof(bitmap->map)*8)
+			bitmap->map |= 1UL<<shift;
 		}
-
-	pq_64bit_free(&rcd_num);
-	pq_64bit_free(&tmp);
 	}
 
 
@@ -1681,7 +1664,7 @@
 #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)
@@ -1800,17 +1783,8 @@
 		{
 		seq = s->s3->read_sequence;
 		s->d1->r_epoch++;
-
-		pq_64bit_assign(&(s->d1->bitmap.map), &(s->d1->next_bitmap.map));
-		s->d1->bitmap.length = s->d1->next_bitmap.length;
-		pq_64bit_assign(&(s->d1->bitmap.max_seq_num), 
-			&(s->d1->next_bitmap.max_seq_num));
-
-		pq_64bit_free(&(s->d1->next_bitmap.map));
-		pq_64bit_free(&(s->d1->next_bitmap.max_seq_num));
+		memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP));
 		memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP));
-		pq_64bit_init(&(s->d1->next_bitmap.map));
-		pq_64bit_init(&(s->d1->next_bitmap.max_seq_num));
 		}
 	else
 		{
@@ -1822,26 +1796,6 @@
 	memset(seq, 0x00, seq_bytes);
 	}
 
-#if PQ_64BIT_IS_INTEGER
-static PQ_64BIT
-bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num)
-       {
-       PQ_64BIT _num;
-
-       _num = (((PQ_64BIT)bytes[0]) << 56) |
-               (((PQ_64BIT)bytes[1]) << 48) |
-               (((PQ_64BIT)bytes[2]) << 40) |
-               (((PQ_64BIT)bytes[3]) << 32) |
-               (((PQ_64BIT)bytes[4]) << 24) |
-               (((PQ_64BIT)bytes[5]) << 16) |
-               (((PQ_64BIT)bytes[6]) <<  8) |
-               (((PQ_64BIT)bytes[7])      );
-
-	   *num = _num ;
-       return _num;
-       }
-#endif
-
 
 static void
 dtls1_clear_timeouts(SSL *s)
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c
index 5b31366..301ceda 100644
--- a/ssl/d1_srvr.c
+++ b/ssl/d1_srvr.c
@@ -4,7 +4,7 @@
  * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
  */
 /* ====================================================================
- * 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
@@ -121,14 +121,15 @@
 #include <openssl/evp.h>
 #include <openssl/x509.h>
 #include <openssl/md5.h>
+#include <openssl/bn.h>
 #ifndef OPENSSL_NO_DH
 #include <openssl/dh.h>
 #endif
 
-static SSL_METHOD *dtls1_get_server_method(int ver);
+static const SSL_METHOD *dtls1_get_server_method(int ver);
 static int dtls1_send_hello_verify_request(SSL *s);
 
-static SSL_METHOD *dtls1_get_server_method(int ver)
+static const SSL_METHOD *dtls1_get_server_method(int ver)
 	{
 	if (ver == DTLS1_VERSION)
 		return(DTLSv1_server_method());
@@ -144,8 +145,9 @@
 int dtls1_accept(SSL *s)
 	{
 	BUF_MEM *buf;
-	unsigned long l,Time=(unsigned long)time(NULL);
+	unsigned long Time=(unsigned long)time(NULL);
 	void (*cb)(const SSL *ssl,int type,int val)=NULL;
+	unsigned long alg_k;
 	int ret= -1;
 	int new_state,state,skip=0;
 
@@ -290,8 +292,8 @@
 			s->state=SSL3_ST_SW_FLUSH;
 			s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A;
 
-			/* HelloVerifyRequests resets Finished MAC */
-			if (s->client_version != DTLS1_BAD_VER)
+			/* HelloVerifyRequest resets Finished MAC */
+			if (s->version != DTLS1_BAD_VER)
 				ssl3_init_finished_mac(s);
 			break;
 			
@@ -321,8 +323,9 @@
 
 		case SSL3_ST_SW_CERT_A:
 		case SSL3_ST_SW_CERT_B:
-			/* Check if it is anon DH */
-			if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
+			/* Check if it is anon DH or normal PSK */
+			if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
+				&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
 				{
 				dtls1_start_timer(s);
 				ret=dtls1_send_server_certificate(s);
@@ -350,13 +353,13 @@
 
 		case SSL3_ST_SW_KEY_EXCH_A:
 		case SSL3_ST_SW_KEY_EXCH_B:
-			l=s->s3->tmp.new_cipher->algorithms;
+			alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
 			/* clear this, it may get reset by
 			 * send_server_key_exchange */
 			if ((s->options & SSL_OP_EPHEMERAL_RSA)
 #ifndef OPENSSL_NO_KRB5
-				&& !(l & SSL_KRB5)
+				&& !(alg_k & SSL_kKRB5)
 #endif /* OPENSSL_NO_KRB5 */
 				)
 				/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
@@ -367,11 +370,17 @@
 			else
 				s->s3->tmp.use_rsa_tmp=0;
 
-			/* only send if a DH key exchange, fortezza or
+			/* only send if a DH key exchange or
 			 * RSA but we have a sign only certificate */
 			if (s->s3->tmp.use_rsa_tmp
-			    || (l & (SSL_DH|SSL_kFZA))
-			    || ((l & SSL_kRSA)
+			/* PSK: send ServerKeyExchange if PSK identity
+			 * hint if provided */
+#ifndef OPENSSL_NO_PSK
+			    || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint)
+#endif
+			    || (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
+			    || (alg_k & SSL_kEECDH)
+			    || ((alg_k & SSL_kRSA)
 				&& (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
 				    || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
 					&& EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)
@@ -402,12 +411,15 @@
 				/* never request cert in anonymous ciphersuites
 				 * (see section "Certificate request" in SSL 3 drafts
 				 * and in RFC 2246): */
-				((s->s3->tmp.new_cipher->algorithms & SSL_aNULL) &&
+				((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
 				 /* ... except when the application insists on verification
 				  * (against the specs, but s3_clnt.c accepts this for SSL 3) */
 				 !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
-                                 /* never request cert in Kerberos ciphersuites */
-                                (s->s3->tmp.new_cipher->algorithms & SSL_aKRB5))
+				 /* never request cert in Kerberos ciphersuites */
+				(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)
+				/* With normal PSK Certificates and
+				 * Certificate Requests are omitted */
+				|| (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
 				{
 				/* no cert request */
 				skip=1;
@@ -479,15 +491,30 @@
 			s->state=SSL3_ST_SR_CERT_VRFY_A;
 			s->init_num=0;
 
-			/* We need to get hashes here so if there is
-			 * a client cert, it can be verified */ 
-			s->method->ssl3_enc->cert_verify_mac(s,
-				&(s->s3->finish_dgst1),
-				&(s->s3->tmp.cert_verify_md[0]));
-			s->method->ssl3_enc->cert_verify_mac(s,
-				&(s->s3->finish_dgst2),
-				&(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]));
+			if (ret == 2)
+				{
+				/* For the ECDH ciphersuites when
+				 * the client sends its ECDH pub key in
+				 * a certificate, the CertificateVerify
+				 * message is not sent.
+				 */
+				s->state=SSL3_ST_SR_FINISHED_A;
+				s->init_num = 0;
+				}
+			else
+				{
+				s->state=SSL3_ST_SR_CERT_VRFY_A;
+				s->init_num=0;
 
+				/* We need to get hashes here so if there is
+				 * a client cert, it can be verified */ 
+				s->method->ssl3_enc->cert_verify_mac(s,
+					NID_md5,
+					&(s->s3->tmp.cert_verify_md[0]));
+				s->method->ssl3_enc->cert_verify_mac(s,
+					NID_sha1,
+					&(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]));
+				}
 			break;
 
 		case SSL3_ST_SR_CERT_VRFY_A:
@@ -686,12 +713,8 @@
 		buf = (unsigned char *)s->init_buf->data;
 
 		msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]);
-		if (s->client_version == DTLS1_BAD_VER)
-			*(p++) = DTLS1_BAD_VER>>8,
-			*(p++) = DTLS1_BAD_VER&0xff;
-		else
-			*(p++) = s->version >> 8,
-			*(p++) = s->version & 0xFF;
+		*(p++) = s->version >> 8;
+		*(p++) = s->version & 0xFF;
 
 		if (s->ctx->app_gen_cookie_cb == NULL ||
 		     s->ctx->app_gen_cookie_cb(s, s->d1->cookie,
@@ -740,12 +763,8 @@
 		/* Do the message type and length last */
 		d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
 
-		if (s->client_version == DTLS1_BAD_VER)
-			*(p++)=DTLS1_BAD_VER>>8,
-			*(p++)=DTLS1_BAD_VER&0xff;
-		else
-			*(p++)=s->version>>8,
-			*(p++)=s->version&0xff;
+		*(p++)=s->version>>8;
+		*(p++)=s->version&0xff;
 
 		/* Random stuff */
 		memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
@@ -851,6 +870,13 @@
 #ifndef OPENSSL_NO_DH
 	DH *dh=NULL,*dhp;
 #endif
+#ifndef OPENSSL_NO_ECDH
+	EC_KEY *ecdh=NULL, *ecdhp;
+	unsigned char *encodedPoint = NULL;
+	int encodedlen = 0;
+	int curve_id = 0;
+	BN_CTX *bn_ctx = NULL; 
+#endif
 	EVP_PKEY *pkey;
 	unsigned char *p,*d;
 	int al,i;
@@ -865,7 +891,7 @@
 	EVP_MD_CTX_init(&md_ctx);
 	if (s->state == SSL3_ST_SW_KEY_EXCH_A)
 		{
-		type=s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK;
+		type=s->s3->tmp.new_cipher->algorithm_mkey;
 		cert=s->cert;
 
 		buf=s->init_buf;
@@ -959,6 +985,142 @@
 			}
 		else 
 #endif
+#ifndef OPENSSL_NO_ECDH
+			if (type & SSL_kEECDH)
+			{
+			const EC_GROUP *group;
+
+			ecdhp=cert->ecdh_tmp;
+			if ((ecdhp == NULL) && (s->cert->ecdh_tmp_cb != NULL))
+				{
+				ecdhp=s->cert->ecdh_tmp_cb(s,
+				      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
+				      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
+				}
+			if (ecdhp == NULL)
+				{
+				al=SSL_AD_HANDSHAKE_FAILURE;
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_ECDH_KEY);
+				goto f_err;
+				}
+
+			if (s->s3->tmp.ecdh != NULL)
+				{
+				EC_KEY_free(s->s3->tmp.ecdh); 
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+
+			/* Duplicate the ECDH structure. */
+			if (ecdhp == NULL)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
+				goto err;
+				}
+			if (!EC_KEY_up_ref(ecdhp))
+				{
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
+				goto err;
+				}
+			ecdh = ecdhp;
+
+			s->s3->tmp.ecdh=ecdh;
+			if ((EC_KEY_get0_public_key(ecdh) == NULL) ||
+			    (EC_KEY_get0_private_key(ecdh) == NULL) ||
+			    (s->options & SSL_OP_SINGLE_ECDH_USE))
+				{
+				if(!EC_KEY_generate_key(ecdh))
+				    {
+				    SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
+				    goto err;
+				    }
+				}
+
+			if (((group = EC_KEY_get0_group(ecdh)) == NULL) ||
+			    (EC_KEY_get0_public_key(ecdh)  == NULL) ||
+			    (EC_KEY_get0_private_key(ecdh) == NULL))
+				{
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
+				goto err;
+				}
+
+			if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
+			    (EC_GROUP_get_degree(group) > 163)) 
+				{
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER);
+				goto err;
+				}
+
+			/* XXX: For now, we only support ephemeral ECDH
+			 * keys over named (not generic) curves. For 
+			 * supported named curves, curve_id is non-zero.
+			 */
+			if ((curve_id = 
+			    tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group)))
+			    == 0)
+				{
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
+				goto err;
+				}
+
+			/* Encode the public key.
+			 * First check the size of encoding and
+			 * allocate memory accordingly.
+			 */
+			encodedlen = EC_POINT_point2oct(group, 
+			    EC_KEY_get0_public_key(ecdh),
+			    POINT_CONVERSION_UNCOMPRESSED, 
+			    NULL, 0, NULL);
+
+			encodedPoint = (unsigned char *) 
+			    OPENSSL_malloc(encodedlen*sizeof(unsigned char)); 
+			bn_ctx = BN_CTX_new();
+			if ((encodedPoint == NULL) || (bn_ctx == NULL))
+				{
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+
+
+			encodedlen = EC_POINT_point2oct(group, 
+			    EC_KEY_get0_public_key(ecdh), 
+			    POINT_CONVERSION_UNCOMPRESSED, 
+			    encodedPoint, encodedlen, bn_ctx);
+
+			if (encodedlen == 0) 
+				{
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
+				goto err;
+				}
+
+			BN_CTX_free(bn_ctx);  bn_ctx=NULL;
+
+			/* XXX: For now, we only support named (not 
+			 * generic) curves in ECDH ephemeral key exchanges.
+			 * In this situation, we need four additional bytes
+			 * to encode the entire ServerECDHParams
+			 * structure. 
+			 */
+			n = 4 + encodedlen;
+
+			/* We'll generate the serverKeyExchange message
+			 * explicitly so we can set these to NULLs
+			 */
+			r[0]=NULL;
+			r[1]=NULL;
+			r[2]=NULL;
+			r[3]=NULL;
+			}
+		else 
+#endif /* !OPENSSL_NO_ECDH */
+#ifndef OPENSSL_NO_PSK
+			if (type & SSL_kPSK)
+				{
+				/* reserve size for record length and PSK identity hint*/
+				n+=2+strlen(s->ctx->psk_identity_hint);
+				}
+			else
+#endif /* !OPENSSL_NO_PSK */
 			{
 			al=SSL_AD_HANDSHAKE_FAILURE;
 			SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
@@ -970,7 +1132,8 @@
 			n+=2+nr[i];
 			}
 
-		if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
+		if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
+			&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
 			{
 			if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher))
 				== NULL)
@@ -1001,6 +1164,41 @@
 			p+=nr[i];
 			}
 
+#ifndef OPENSSL_NO_ECDH
+		if (type & SSL_kEECDH) 
+			{
+			/* XXX: For now, we only support named (not generic) curves.
+			 * In this situation, the serverKeyExchange message has:
+			 * [1 byte CurveType], [2 byte CurveName]
+			 * [1 byte length of encoded point], followed by
+			 * the actual encoded point itself
+			 */
+			*p = NAMED_CURVE_TYPE;
+			p += 1;
+			*p = 0;
+			p += 1;
+			*p = curve_id;
+			p += 1;
+			*p = encodedlen;
+			p += 1;
+			memcpy((unsigned char*)p, 
+			    (unsigned char *)encodedPoint, 
+			    encodedlen);
+			OPENSSL_free(encodedPoint);
+			p += encodedlen;
+			}
+#endif
+
+#ifndef OPENSSL_NO_PSK
+		if (type & SSL_kPSK)
+			{
+			/* copy PSK identity hint */
+			s2n(strlen(s->ctx->psk_identity_hint), p); 
+			strncpy((char *)p, s->ctx->psk_identity_hint, strlen(s->ctx->psk_identity_hint));
+			p+=strlen(s->ctx->psk_identity_hint);
+			}
+#endif
+
 		/* not anonymous */
 		if (pkey != NULL)
 			{
@@ -1054,6 +1252,25 @@
 				}
 			else
 #endif
+#if !defined(OPENSSL_NO_ECDSA)
+				if (pkey->type == EVP_PKEY_EC)
+				{
+				/* let's do ECDSA */
+				EVP_SignInit_ex(&md_ctx,EVP_ecdsa(), NULL);
+				EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
+				EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
+				EVP_SignUpdate(&md_ctx,&(d[4]),n);
+				if (!EVP_SignFinal(&md_ctx,&(p[2]),
+					(unsigned int *)&i,pkey))
+					{
+					SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_ECDSA);
+					goto err;
+					}
+				s2n(i,p);
+				n+=i+2;
+				}
+			else
+#endif
 				{
 				/* Is this error check actually needed? */
 				al=SSL_AD_HANDSHAKE_FAILURE;
@@ -1080,6 +1297,10 @@
 f_err:
 	ssl3_send_alert(s,SSL3_AL_FATAL,al);
 err:
+#ifndef OPENSSL_NO_ECDH
+	if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
+	BN_CTX_free(bn_ctx);
+#endif
 	EVP_MD_CTX_cleanup(&md_ctx);
 	return(-1);
 	}
@@ -1193,14 +1414,15 @@
 	if (s->state == SSL3_ST_SW_CERT_A)
 		{
 		x=ssl_get_server_send_cert(s);
-		if (x == NULL &&
-                        /* VRS: allow null cert if auth == KRB5 */
-                        (s->s3->tmp.new_cipher->algorithms
-                                & (SSL_MKEY_MASK|SSL_AUTH_MASK))
-                        != (SSL_aKRB5|SSL_kKRB5))
+		if (x == NULL)
 			{
-			SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
-			return(0);
+			/* VRS: allow null cert if auth == KRB5 */
+			if ((s->s3->tmp.new_cipher->algorithm_mkey != SSL_kKRB5) ||
+			    (s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5))
+				{
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
+				return(0);
+				}
 			}
 
 		l=dtls1_output_cert_chain(s,x);
diff --git a/ssl/dtls1.h b/ssl/dtls1.h
index a8ce51a..af363a9 100644
--- a/ssl/dtls1.h
+++ b/ssl/dtls1.h
@@ -108,15 +108,17 @@
 
 typedef struct dtls1_bitmap_st
 	{
-	PQ_64BIT map;
-	unsigned long length;     /* sizeof the bitmap in bits */
-	PQ_64BIT max_seq_num;  /* max record number seen so far */
+	unsigned long map;		/* track 32 packets on 32-bit systems
+					   and 64 - on 64-bit systems */
+	unsigned char max_seq_num[8];	/* max record number seen so far,
+					   64-bit value in big-endian
+					   encoding */
 	} DTLS1_BITMAP;
 
 struct dtls1_retransmit_state
 	{
 	EVP_CIPHER_CTX *enc_write_ctx;	/* cryptographic state */
-	const EVP_MD *write_hash;		/* used for mac generation */
+	EVP_MD_CTX *write_hash;			/* used for mac generation */
 #ifndef OPENSSL_NO_COMP
 	COMP_CTX *compress;				/* compression */
 #else
diff --git a/ssl/kssl.c b/ssl/kssl.c
index 73401c9..b820e37 100644
--- a/ssl/kssl.c
+++ b/ssl/kssl.c
@@ -76,6 +76,7 @@
 #include <openssl/evp.h>
 #include <openssl/objects.h>
 #include <openssl/krb5_asn.h>
+#include "kssl_lcl.h"
 
 #ifndef OPENSSL_NO_KRB5
 
@@ -131,7 +132,7 @@
 #define krb5_principal_compare   kssl_krb5_principal_compare
 #define krb5_decrypt_tkt_part    kssl_krb5_decrypt_tkt_part
 #define krb5_timeofday           kssl_krb5_timeofday
-#define krb5_rc_default           kssl_krb5_rc_default
+#define krb5_rc_default          kssl_krb5_rc_default
 
 #ifdef krb5_rc_initialize
 #undef krb5_rc_initialize
@@ -839,7 +840,7 @@
 **	"62 xx 30 yy" (APPLICATION-2, SEQUENCE), where xx-yy =~ 2, and
 **	xx and yy are possibly multi-byte length fields.
 */
-int 	kssl_test_confound(unsigned char *p)
+static int 	kssl_test_confound(unsigned char *p)
 	{
 	int 	len = 2;
 	int 	xx = 0, yy = 0;
@@ -874,7 +875,7 @@
 **      what the highest assigned CKSUMTYPE_ constant is.  As of 1.2.2
 **      it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3).  So we will use 0x0010.
 */
-size_t  *populate_cksumlens(void)
+static size_t  *populate_cksumlens(void)
 	{
 	int 		i, j, n;
 	static size_t 	*cklens = NULL;
@@ -1025,7 +1026,7 @@
 /*	Display contents of krb5_principal_data struct, for debugging
 **	(krb5_principal is typedef'd == krb5_principal_data *)
 */
-void
+static void
 print_krb5_princ(char *label, krb5_principal_data *princ)
         {
 	int i, ui, uj;
@@ -1224,7 +1225,7 @@
 **				code here.  This tkt should alloc/free just
 **				like the real thing.
 */
-krb5_error_code
+static krb5_error_code
 kssl_TKT2tkt(	/* IN     */	krb5_context	krb5context,
 		/* IN     */	KRB5_TKTBODY	*asn1ticket,
 		/* OUT    */	krb5_ticket	**krb5ticket,
@@ -1802,6 +1803,9 @@
                                      kssl_ctx->service_name ? kssl_ctx->service_name: KRB5SVC,
                                      KRB5_NT_SRV_HST, &princ);
 
+    if (krb5rc)
+	goto exit;
+
     krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, 
                                 princ,
                                 0 /* IGNORE_VNO */,
@@ -1899,7 +1903,7 @@
 **  Return pointer to the (partially) filled in struct tm on success,
 **  return NULL on failure.
 */
-struct tm	*k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm)
+static struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm)
 	{
 	char 		c, *p;
 
@@ -1925,7 +1929,7 @@
 **  So we try to sneek the clockskew out through the replay cache.
 **	If that fails just return a likely default (300 seconds).
 */
-krb5_deltat	get_rc_clockskew(krb5_context context)
+static krb5_deltat get_rc_clockskew(krb5_context context)
 	{
 	krb5_rcache 	rc;
 	krb5_deltat 	clockskew;
@@ -2089,9 +2093,12 @@
         EVP_CIPHER_CTX_cleanup(&ciph_ctx);
 
 #ifdef KSSL_DEBUG
+	{
+	int padl;
 	printf("kssl_check_authent: decrypted authenticator[%d] =\n", outl);
 	for (padl=0; padl < outl; padl++) printf("%02x ",unenc_authent[padl]);
 	printf("\n");
+	}
 #endif	/* KSSL_DEBUG */
 
 	if ((p = kssl_skip_confound(enctype, unenc_authent)) == NULL)
@@ -2121,7 +2128,7 @@
  		tm_g = gmtime(&now);		tg = mktime(tm_g);
  		tz_offset = tg - tl;
 
-		*atimep = tr - tz_offset;
+		*atimep = (krb5_timestamp)(tr - tz_offset);
  		}
 
 #ifdef KSSL_DEBUG
diff --git a/ssl/kssl_lcl.h b/ssl/kssl_lcl.h
index 4cd8dd2..c039c91 100644
--- a/ssl/kssl_lcl.h
+++ b/ssl/kssl_lcl.h
@@ -75,7 +75,7 @@
 char *kstring(char *string);
 char *knumber(int len, krb5_octet *contents);
 
-EVP_CIPHER *kssl_map_enc(krb5_enctype enctype);
+const EVP_CIPHER *kssl_map_enc(krb5_enctype enctype);
 
 int kssl_keytab_is_available(KSSL_CTX *kssl_ctx);
 int kssl_tgt_is_available(KSSL_CTX *kssl_ctx);
diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c
index de02389..c4d8bf2 100644
--- a/ssl/s23_clnt.c
+++ b/ssl/s23_clnt.c
@@ -55,6 +55,59 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
+/* ====================================================================
+ * Copyright (c) 1998-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
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
 
 #include <stdio.h>
 #include "ssl_locl.h"
@@ -63,10 +116,10 @@
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 
-static SSL_METHOD *ssl23_get_client_method(int ver);
+static const SSL_METHOD *ssl23_get_client_method(int ver);
 static int ssl23_client_hello(SSL *s);
 static int ssl23_get_server_hello(SSL *s);
-static SSL_METHOD *ssl23_get_client_method(int ver)
+static const SSL_METHOD *ssl23_get_client_method(int ver)
 	{
 #ifndef OPENSSL_NO_SSL2
 	if (ver == SSL2_VERSION)
@@ -197,6 +250,20 @@
 	return(ret);
 	}
 
+static int ssl23_no_ssl2_ciphers(SSL *s)
+	{
+	SSL_CIPHER *cipher;
+	STACK_OF(SSL_CIPHER) *ciphers;
+	int i;
+	ciphers = SSL_get_ciphers(s);
+	for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++)
+		{
+		cipher = sk_SSL_CIPHER_value(ciphers, i);
+		if (cipher->algorithm_ssl == SSL_SSLV2)
+			return 0;
+		}
+	return 1;
+	}
 
 static int ssl23_client_hello(SSL *s)
 	{
@@ -214,6 +281,9 @@
 
 	ssl2_compat = (s->options & SSL_OP_NO_SSLv2) ? 0 : 1;
 
+	if (ssl2_compat && ssl23_no_ssl2_ciphers(s))
+		ssl2_compat = 0;
+
 	if (!(s->options & SSL_OP_NO_TLSv1))
 		{
 		version = TLS1_VERSION;
@@ -226,7 +296,7 @@
 		{
 		version = SSL2_VERSION;
 		}
-#ifndef OPENSSL_NO_TLSEXT 
+#ifndef OPENSSL_NO_TLSEXT
 	if (version != SSL2_VERSION)
 		{
 		/* have to disable SSL 2.0 compatibility if we need TLS extensions */
@@ -235,6 +305,10 @@
 			ssl2_compat = 0;
 		if (s->tlsext_status_type != -1)
 			ssl2_compat = 0;
+#ifdef TLSEXT_TYPE_opaque_prf_input
+		if (s->ctx->tlsext_opaque_prf_input_callback != 0 || s->tlsext_opaque_prf_input != NULL)
+			ssl2_compat = 0;
+#endif
 		}
 #endif
 
@@ -260,14 +334,6 @@
 			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;
@@ -321,6 +387,10 @@
 				ch_len=SSL2_MAX_CHALLENGE_LENGTH;
 
 			/* write out sslv2 challenge */
+			/* Note that ch_len must be <= SSL3_RANDOM_SIZE (32),
+			   because it is one of SSL2_MAX_CHALLENGE_LENGTH (32)
+			   or SSL2_MAX_CHALLENGE_LENGTH (16), but leave the
+			   check in for futurproofing */
 			if (SSL3_RANDOM_SIZE < ch_len)
 				i=SSL3_RANDOM_SIZE;
 			else
@@ -371,7 +441,11 @@
 			p+=i;
 
 			/* COMPRESSION */
-			if (s->ctx->comp_methods == NULL)
+#ifdef OPENSSL_NO_COMP
+			*(p++)=1;
+#else
+			if ((s->options & SSL_OP_NO_COMPRESSION)
+						|| !s->ctx->comp_methods)
 				j=0;
 			else
 				j=sk_SSL_COMP_num(s->ctx->comp_methods);
@@ -381,8 +455,16 @@
 				comp=sk_SSL_COMP_value(s->ctx->comp_methods,i);
 				*(p++)=comp->id;
 				}
+#endif
 			*(p++)=0; /* Add the NULL method */
+
 #ifndef OPENSSL_NO_TLSEXT
+			/* TLS extensions*/
+			if (ssl_prepare_clienthello_tlsext(s) <= 0)
+				{
+				SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
+				return -1;
+				}
 			if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
 				{
 				SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
@@ -391,7 +473,6 @@
 #endif
 			
 			l = p-d;
-			*p = 42;
 
 			/* fill in 4-byte handshake header */
 			d=&(buf[5]);
@@ -486,6 +567,10 @@
 			ch_len=SSL2_MAX_CHALLENGE_LENGTH;
 
 		/* write out sslv2 challenge */
+		/* Note that ch_len must be <= SSL3_RANDOM_SIZE (32), because
+		   it is one of SSL2_MAX_CHALLENGE_LENGTH (32) or
+		   SSL2_MAX_CHALLENGE_LENGTH (16), but leave the check in for
+		   futurproofing */
 		i=(SSL3_RANDOM_SIZE < ch_len)
 			?SSL3_RANDOM_SIZE:ch_len;
 		s->s2->challenge_length=i;
@@ -506,7 +591,7 @@
 			/* use special padding (SSL 3.0 draft/RFC 2246, App. E.2) */
 			s->s2->ssl2_rollback=1;
 
-		/* setup the 5 bytes we have read so we get them from
+		/* setup the 7 bytes we have read so we get them from
 		 * the sslv2 buffer */
 		s->rstate=SSL_ST_READ_HEADER;
 		s->packet_length=n;
@@ -522,39 +607,16 @@
 		s->handshake_func=s->method->ssl_connect;
 #endif
 		}
-	else if ((p[0] == SSL3_RT_HANDSHAKE) &&
-		 (p[1] == SSL3_VERSION_MAJOR) &&
-		 ((p[2] == SSL3_VERSION_MINOR) ||
-		  (p[2] == TLS1_VERSION_MINOR)) &&
-		 (p[5] == SSL3_MT_SERVER_HELLO))
+	else if (p[1] == SSL3_VERSION_MAJOR &&
+	         (p[2] == SSL3_VERSION_MINOR || p[2] == TLS1_VERSION_MINOR) &&
+	         ((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) ||
+	          (p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2)))
 		{
-		/* we have sslv3 or tls1 */
-
-		if (!ssl_init_wbio_buffer(s,1)) goto err;
-
-		/* we are in this state */
-		s->state=SSL3_ST_CR_SRVR_HELLO_A;
-
-		/* put the 5 bytes we have read into the input buffer
-		 * for SSLv3 */
-		s->rstate=SSL_ST_READ_HEADER;
-		s->packet_length=n;
-		s->packet= &(s->s3->rbuf.buf[0]);
-		memcpy(s->packet,buf,n);
-		s->s3->rbuf.left=n;
-		s->s3->rbuf.offset=0;
+		/* we have sslv3 or tls1 (server hello or alert) */
 
 		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();
 			}
@@ -569,35 +631,52 @@
 			SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
 			goto err;
 			}
-			
-		s->handshake_func=s->method->ssl_connect;
-		}
-	else if ((p[0] == SSL3_RT_ALERT) &&
-		 (p[1] == SSL3_VERSION_MAJOR) &&
-		 ((p[2] == SSL3_VERSION_MINOR) ||
-		  (p[2] == TLS1_VERSION_MINOR)) &&
-		 (p[3] == 0) &&
-		 (p[4] == 2))
-		{
-		void (*cb)(const SSL *ssl,int type,int val)=NULL;
-		int j;
 
-		/* An alert */
-		if (s->info_callback != NULL)
-			cb=s->info_callback;
-		else if (s->ctx->info_callback != NULL)
-			cb=s->ctx->info_callback;
- 
-		i=p[5];
-		if (cb != NULL)
+		if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING)
 			{
-			j=(i<<8)|p[6];
-			cb(s,SSL_CB_READ_ALERT,j);
+			/* fatal alert */
+
+			void (*cb)(const SSL *ssl,int type,int val)=NULL;
+			int j;
+
+			if (s->info_callback != NULL)
+				cb=s->info_callback;
+			else if (s->ctx->info_callback != NULL)
+				cb=s->ctx->info_callback;
+ 
+			i=p[5];
+			if (cb != NULL)
+				{
+				j=(i<<8)|p[6];
+				cb(s,SSL_CB_READ_ALERT,j);
+				}
+			
+			if (s->msg_callback)
+				s->msg_callback(0, s->version, SSL3_RT_ALERT, p+5, 2, s, s->msg_callback_arg);
+
+			s->rwstate=SSL_NOTHING;
+			SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_AD_REASON_OFFSET+p[6]);
+			goto err;
 			}
 
-		s->rwstate=SSL_NOTHING;
-		SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_AD_REASON_OFFSET+p[6]);
-		goto err;
+		if (!ssl_init_wbio_buffer(s,1)) goto err;
+
+		/* we are in this state */
+		s->state=SSL3_ST_CR_SRVR_HELLO_A;
+
+		/* put the 7 bytes we have read into the input buffer
+		 * for SSLv3 */
+		s->rstate=SSL_ST_READ_HEADER;
+		s->packet_length=n;
+		if (s->s3->rbuf.buf == NULL)
+			if (!ssl3_setup_read_buffer(s))
+				goto err;
+		s->packet= &(s->s3->rbuf.buf[0]);
+		memcpy(s->packet,buf,n);
+		s->s3->rbuf.left=n;
+		s->s3->rbuf.offset=0;
+
+		s->handshake_func=s->method->ssl_connect;
 		}
 	else
 		{
@@ -615,4 +694,3 @@
 err:
 	return(-1);
 	}
-
diff --git a/ssl/s23_lib.c b/ssl/s23_lib.c
index fc29813..e3fce53 100644
--- a/ssl/s23_lib.c
+++ b/ssl/s23_lib.c
@@ -65,11 +65,6 @@
 	return(300);
 	}
 
-IMPLEMENT_ssl23_meth_func(sslv23_base_method,
-			ssl_undefined_function,
-			ssl_undefined_function,
-			ssl_bad_method)
-
 int ssl23_num_ciphers(void)
 	{
 	return(ssl3_num_ciphers()
@@ -79,7 +74,7 @@
 	    );
 	}
 
-SSL_CIPHER *ssl23_get_cipher(unsigned int u)
+const SSL_CIPHER *ssl23_get_cipher(unsigned int u)
 	{
 	unsigned int uu=ssl3_num_ciphers();
 
@@ -95,9 +90,10 @@
 
 /* This function needs to check if the ciphers required are actually
  * available */
-SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p)
+const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p)
 	{
-	SSL_CIPHER c,*cp;
+	SSL_CIPHER c;
+	const SSL_CIPHER *cp;
 	unsigned long id;
 	int n;
 
diff --git a/ssl/s23_meth.c b/ssl/s23_meth.c
index 950d9aa..c6099ef 100644
--- a/ssl/s23_meth.c
+++ b/ssl/s23_meth.c
@@ -60,8 +60,8 @@
 #include <openssl/objects.h>
 #include "ssl_locl.h"
 
-static SSL_METHOD *ssl23_get_method(int ver);
-static SSL_METHOD *ssl23_get_method(int ver)
+static const SSL_METHOD *ssl23_get_method(int ver);
+static const SSL_METHOD *ssl23_get_method(int ver)
 	{
 #ifndef OPENSSL_NO_SSL2
 	if (ver == SSL2_VERSION)
diff --git a/ssl/s23_srvr.c b/ssl/s23_srvr.c
index 42f7de4..e22879c 100644
--- a/ssl/s23_srvr.c
+++ b/ssl/s23_srvr.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -116,9 +116,9 @@
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 
-static SSL_METHOD *ssl23_get_server_method(int ver);
+static const SSL_METHOD *ssl23_get_server_method(int ver);
 int ssl23_get_client_hello(SSL *s);
-static SSL_METHOD *ssl23_get_server_method(int ver)
+static const SSL_METHOD *ssl23_get_server_method(int ver)
 	{
 #ifndef OPENSSL_NO_SSL2
 	if (ver == SSL2_VERSION)
@@ -393,15 +393,6 @@
 			}
 		}
 
-#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
@@ -437,7 +428,9 @@
 		n2s(p,sil);
 		n2s(p,cl);
 		d=(unsigned char *)s->init_buf->data;
-		if ((csl+sil+cl+11) != s->packet_length)
+		if ((csl+sil+cl+11) != s->packet_length) /* We can't have TLS extensions in SSL 2.0 format
+		                                          * Client Hello, can we? Error condition should be
+		                                          * '>' otherweise */
 			{
 			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_LENGTH_MISMATCH);
 			goto err;
@@ -480,6 +473,15 @@
 		*(d++)=1;
 		*(d++)=0;
 		
+#if 0
+                /* copy any remaining data with may be extensions */
+	        p = p+csl+sil+cl;
+		while (p <  s->packet+s->packet_length)
+			{
+			*(d++)=*(p++);
+			}
+#endif
+
 		i = (d-(unsigned char *)s->init_buf->data) - 4;
 		l2n3((long)i, d_len);
 
@@ -555,6 +557,10 @@
 			 * for SSLv3 */
 			s->rstate=SSL_ST_READ_HEADER;
 			s->packet_length=n;
+			if (s->s3->rbuf.buf == NULL)
+				if (!ssl3_setup_read_buffer(s))
+					goto err;
+
 			s->packet= &(s->s3->rbuf.buf[0]);
 			memcpy(s->packet,buf,n);
 			s->s3->rbuf.left=n;
diff --git a/ssl/s2_clnt.c b/ssl/s2_clnt.c
index 782129c..00ac158 100644
--- a/ssl/s2_clnt.c
+++ b/ssl/s2_clnt.c
@@ -117,7 +117,7 @@
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 
-static SSL_METHOD *ssl2_get_client_method(int ver);
+static const SSL_METHOD *ssl2_get_client_method(int ver);
 static int get_server_finished(SSL *s);
 static int get_server_verify(SSL *s);
 static int get_server_hello(SSL *s);
@@ -129,7 +129,7 @@
 	unsigned char *to,int padding);
 #define BREAK	break
 
-static SSL_METHOD *ssl2_get_client_method(int ver)
+static const SSL_METHOD *ssl2_get_client_method(int ver)
 	{
 	if (ver == SSL2_VERSION)
 		return(SSLv2_client_method());
@@ -621,7 +621,7 @@
 	if (s->state == SSL2_ST_SEND_CLIENT_MASTER_KEY_A)
 		{
 
-		if (!ssl_cipher_get_evp(s->session,&c,&md,NULL))
+		if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL))
 			{
 			ssl2_return_error(s,SSL2_PE_NO_CIPHER);
 			SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
@@ -863,8 +863,10 @@
 		EVP_SignUpdate(&ctx,s->s2->key_material,
 			       s->s2->key_material_length);
 		EVP_SignUpdate(&ctx,cert_ch,(unsigned int)cert_ch_len);
-		n=i2d_X509(s->session->sess_cert->peer_key->x509,&p);
-		EVP_SignUpdate(&ctx,buf,(unsigned int)n);
+		i=i2d_X509(s->session->sess_cert->peer_key->x509,&p);
+		/* Don't update the signature if it fails - FIXME: probably should handle this better */
+		if(i > 0)
+			EVP_SignUpdate(&ctx,buf,(unsigned int)i);
 
 		p=buf;
 		d=p+6;
diff --git a/ssl/s2_enc.c b/ssl/s2_enc.c
index 1f62acd..ff3395f 100644
--- a/ssl/s2_enc.c
+++ b/ssl/s2_enc.c
@@ -68,15 +68,14 @@
 	const EVP_MD *md;
 	int num;
 
-	if (!ssl_cipher_get_evp(s->session,&c,&md,NULL))
+	if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL))
 		{
 		ssl2_return_error(s,SSL2_PE_NO_CIPHER);
 		SSLerr(SSL_F_SSL2_ENC_INIT,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
 		return(0);
 		}
-
-	s->read_hash=md;
-	s->write_hash=md;
+	ssl_replace_hash(&s->read_hash,md);
+	ssl_replace_hash(&s->write_hash,md);
 
 	if ((s->enc_read_ctx == NULL) &&
 		((s->enc_read_ctx=(EVP_CIPHER_CTX *)
@@ -176,7 +175,7 @@
 
 	/* There has to be a MAC algorithm. */
 	EVP_MD_CTX_init(&c);
-	EVP_DigestInit_ex(&c, s->read_hash, NULL);
+	EVP_MD_CTX_copy(&c, s->read_hash);
 	EVP_DigestUpdate(&c,sec,
 		EVP_CIPHER_CTX_key_length(s->enc_read_ctx));
 	EVP_DigestUpdate(&c,act,len); 
diff --git a/ssl/s2_lib.c b/ssl/s2_lib.c
index 10751b2..9914604 100644
--- a/ssl/s2_lib.c
+++ b/ssl/s2_lib.c
@@ -55,6 +55,59 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
 
 #include "ssl_locl.h"
 #ifndef OPENSSL_NO_SSL2
@@ -68,143 +121,172 @@
 #define SSL2_NUM_CIPHERS (sizeof(ssl2_ciphers)/sizeof(SSL_CIPHER))
 
 /* list of available SSLv2 ciphers (sorted by id) */
-OPENSSL_GLOBAL SSL_CIPHER ssl2_ciphers[]={
-/* NULL_WITH_MD5 v3 */
+OPENSSL_GLOBAL const SSL_CIPHER ssl2_ciphers[]={
 #if 0
+/* NULL_WITH_MD5 v3 */
 	{
 	1,
 	SSL2_TXT_NULL_WITH_MD5,
 	SSL2_CK_NULL_WITH_MD5,
-	SSL_kRSA|SSL_aRSA|SSL_eNULL|SSL_MD5|SSL_SSLV2,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_eNULL,
+	SSL_MD5,
+	SSL_SSLV2,
 	SSL_EXPORT|SSL_EXP40|SSL_STRONG_NONE,
 	0,
 	0,
 	0,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 #endif
+
 /* RC4_128_WITH_MD5 */
 	{
 	1,
 	SSL2_TXT_RC4_128_WITH_MD5,
 	SSL2_CK_RC4_128_WITH_MD5,
-	SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_MD5|SSL_SSLV2,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV2,
 	SSL_NOT_EXP|SSL_MEDIUM,
 	0,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* RC4_128_EXPORT40_WITH_MD5 */
 	{
 	1,
 	SSL2_TXT_RC4_128_EXPORT40_WITH_MD5,
 	SSL2_CK_RC4_128_EXPORT40_WITH_MD5,
-	SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_MD5|SSL_SSLV2,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV2,
 	SSL_EXPORT|SSL_EXP40,
 	SSL2_CF_5_BYTE_ENC,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* RC2_128_CBC_WITH_MD5 */
 	{
 	1,
 	SSL2_TXT_RC2_128_CBC_WITH_MD5,
 	SSL2_CK_RC2_128_CBC_WITH_MD5,
-	SSL_kRSA|SSL_aRSA|SSL_RC2|SSL_MD5|SSL_SSLV2,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC2,
+	SSL_MD5,
+	SSL_SSLV2,
 	SSL_NOT_EXP|SSL_MEDIUM,
 	0,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* RC2_128_CBC_EXPORT40_WITH_MD5 */
 	{
 	1,
 	SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5,
 	SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5,
-	SSL_kRSA|SSL_aRSA|SSL_RC2|SSL_MD5|SSL_SSLV2,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC2,
+	SSL_MD5,
+	SSL_SSLV2,
 	SSL_EXPORT|SSL_EXP40,
 	SSL2_CF_5_BYTE_ENC,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
-/* IDEA_128_CBC_WITH_MD5 */
+
 #ifndef OPENSSL_NO_IDEA
+/* IDEA_128_CBC_WITH_MD5 */
 	{
 	1,
 	SSL2_TXT_IDEA_128_CBC_WITH_MD5,
 	SSL2_CK_IDEA_128_CBC_WITH_MD5,
-	SSL_kRSA|SSL_aRSA|SSL_IDEA|SSL_MD5|SSL_SSLV2,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_IDEA,
+	SSL_MD5,
+	SSL_SSLV2,
 	SSL_NOT_EXP|SSL_MEDIUM,
 	0,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 #endif
+
 /* DES_64_CBC_WITH_MD5 */
 	{
 	1,
 	SSL2_TXT_DES_64_CBC_WITH_MD5,
 	SSL2_CK_DES_64_CBC_WITH_MD5,
-	SSL_kRSA|SSL_aRSA|SSL_DES|SSL_MD5|SSL_SSLV2,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_DES,
+	SSL_MD5,
+	SSL_SSLV2,
 	SSL_NOT_EXP|SSL_LOW,
 	0,
 	56,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* DES_192_EDE3_CBC_WITH_MD5 */
 	{
 	1,
 	SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5,
 	SSL2_CK_DES_192_EDE3_CBC_WITH_MD5,
-	SSL_kRSA|SSL_aRSA|SSL_3DES|SSL_MD5|SSL_SSLV2,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_3DES,
+	SSL_MD5,
+	SSL_SSLV2,
 	SSL_NOT_EXP|SSL_HIGH,
 	0,
 	168,
 	168,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
-/* RC4_64_WITH_MD5 */
+
 #if 0
+/* RC4_64_WITH_MD5 */
 	{
 	1,
 	SSL2_TXT_RC4_64_WITH_MD5,
 	SSL2_CK_RC4_64_WITH_MD5,
-	SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_MD5|SSL_SSLV2,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV2,
 	SSL_NOT_EXP|SSL_LOW,
 	SSL2_CF_8_BYTE_ENC,
 	64,
 	64,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 #endif
-/* NULL SSLeay (testing) */
+
 #if 0
+/* NULL SSLeay (testing) */
 	{	
 	0,
 	SSL2_TXT_NULL,
 	SSL2_CK_NULL,
 	0,
+	0,
+	0,
+	0,
+	SSL_SSLV2,
 	SSL_STRONG_NONE,
 	0,
 	0,
 	0,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 #endif
 
@@ -216,17 +298,12 @@
 	return(300);
 	}
 
-IMPLEMENT_ssl2_meth_func(sslv2_base_method,
-			ssl_undefined_function,
-			ssl_undefined_function,
-			ssl_bad_method)
-
 int ssl2_num_ciphers(void)
 	{
 	return(SSL2_NUM_CIPHERS);
 	}
 
-SSL_CIPHER *ssl2_get_cipher(unsigned int u)
+const SSL_CIPHER *ssl2_get_cipher(unsigned int u)
 	{
 	if (u < SSL2_NUM_CIPHERS)
 		return(&(ssl2_ciphers[SSL2_NUM_CIPHERS-1-u]));
@@ -337,18 +414,16 @@
 
 /* This function needs to check if the ciphers required are actually
  * available */
-SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p)
+const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p)
 	{
-	SSL_CIPHER c,*cp;
+	SSL_CIPHER c;
+	const SSL_CIPHER *cp;
 	unsigned long id;
 
 	id=0x02000000L|((unsigned long)p[0]<<16L)|
 		((unsigned long)p[1]<<8L)|(unsigned long)p[2];
 	c.id=id;
-	cp = (SSL_CIPHER *)OBJ_bsearch((char *)&c,
-		(char *)ssl2_ciphers,
-		SSL2_NUM_CIPHERS,sizeof(SSL_CIPHER),
-		FP_ICC ssl_cipher_id_cmp);
+	cp = OBJ_bsearch_ssl_cipher_id(&c, ssl2_ciphers, SSL2_NUM_CIPHERS);
 	if ((cp == NULL) || (cp->valid == 0))
 		return NULL;
 	else
@@ -377,6 +452,7 @@
 	unsigned char *km;
 	unsigned char c='0';
 	const EVP_MD *md5;
+	int md_size;
 
 	md5 = EVP_md5();
 
@@ -393,10 +469,12 @@
  		SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR);
  		return 0;
  		}
-
-	for (i=0; i<s->s2->key_material_length; i += EVP_MD_size(md5))
+	md_size = EVP_MD_size(md5);
+	if (md_size < 0)
+	    return 0;
+	for (i=0; i<s->s2->key_material_length; i += md_size)
 		{
-		if (((km - s->s2->key_material) + EVP_MD_size(md5)) >
+		if (((km - s->s2->key_material) + md_size) >
 				(int)sizeof(s->s2->key_material))
 			{
 			/* EVP_DigestFinal_ex() below would write beyond buffer */
@@ -415,7 +493,7 @@
 		EVP_DigestUpdate(&ctx,s->s2->challenge,s->s2->challenge_length);
 		EVP_DigestUpdate(&ctx,s->s2->conn_id,s->s2->conn_id_length);
 		EVP_DigestFinal_ex(&ctx,km,NULL);
-		km += EVP_MD_size(md5);
+		km += md_size;
 		}
 
 	EVP_MD_CTX_cleanup(&ctx);
diff --git a/ssl/s2_meth.c b/ssl/s2_meth.c
index a35e435..f0e8ca5 100644
--- a/ssl/s2_meth.c
+++ b/ssl/s2_meth.c
@@ -61,8 +61,8 @@
 #include <stdio.h>
 #include <openssl/objects.h>
 
-static SSL_METHOD *ssl2_get_method(int ver);
-static SSL_METHOD *ssl2_get_method(int ver)
+static const SSL_METHOD *ssl2_get_method(int ver);
+static const SSL_METHOD *ssl2_get_method(int ver)
 	{
 	if (ver == SSL2_VERSION)
 		return(SSLv2_method());
@@ -71,9 +71,9 @@
 	}
 
 IMPLEMENT_ssl2_meth_func(SSLv2_method,
-			ssl2_accept,
-			ssl2_connect,
-			ssl2_get_method)
+			 ssl2_accept,
+			 ssl2_connect,
+			 ssl2_get_method)
 
 #else /* !OPENSSL_NO_SSL2 */
 
diff --git a/ssl/s2_pkt.c b/ssl/s2_pkt.c
index a10929a..ac963b2 100644
--- a/ssl/s2_pkt.c
+++ b/ssl/s2_pkt.c
@@ -116,7 +116,7 @@
 #define USE_SOCKETS
 
 static int read_n(SSL *s,unsigned int n,unsigned int max,unsigned int extend);
-static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len);
+static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len);
 static int write_pending(SSL *s, const unsigned char *buf, unsigned int len);
 static int ssl_mt_error(int n);
 
@@ -130,7 +130,7 @@
 	unsigned char mac[MAX_MAC_SIZE];
 	unsigned char *p;
 	int i;
-	unsigned int mac_size;
+	int mac_size;
 
  ssl2_read_again:
 	if (SSL_in_init(s) && !s->in_handshake)
@@ -246,7 +246,9 @@
 			}
 		else
 			{
-			mac_size=EVP_MD_size(s->read_hash);
+			mac_size=EVP_MD_CTX_size(s->read_hash);
+			if (mac_size < 0)
+				return -1;
 			OPENSSL_assert(mac_size <= MAX_MAC_SIZE);
 			s->s2->mac_data=p;
 			s->s2->ract_data= &p[mac_size];
@@ -261,7 +263,7 @@
 		/* added a check for length > max_size in case
 		 * encryption was not turned on yet due to an error */
 		if ((!s->s2->clear_text) &&
-			(s->s2->rlength >= mac_size))
+			(s->s2->rlength >= (unsigned int)mac_size))
 			{
 			ssl2_enc(s,0);
 			s->s2->ract_data_length-=mac_size;
@@ -447,7 +449,7 @@
 	n=(len-tot);
 	for (;;)
 		{
-		i=do_ssl_write(s,&(buf[tot]),n);
+		i=n_do_ssl_write(s,&(buf[tot]),n);
 		if (i <= 0)
 			{
 			s->s2->wnum=tot;
@@ -511,9 +513,10 @@
 		}
 	}
 
-static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
+static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
 	{
-	unsigned int j,k,olen,p,mac_size,bs;
+	unsigned int j,k,olen,p,bs;
+	int mac_size;
 	register unsigned char *pp;
 
 	olen=len;
@@ -529,7 +532,11 @@
 	if (s->s2->clear_text)
 		mac_size=0;
 	else
-		mac_size=EVP_MD_size(s->write_hash);
+		{
+		mac_size=EVP_MD_CTX_size(s->write_hash);
+		if (mac_size < 0)
+			return -1;
+		}
 
 	/* lets set the pad p */
 	if (s->s2->clear_text)
diff --git a/ssl/s2_srvr.c b/ssl/s2_srvr.c
index 01d62fa..1434e73 100644
--- a/ssl/s2_srvr.c
+++ b/ssl/s2_srvr.c
@@ -117,7 +117,7 @@
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 
-static SSL_METHOD *ssl2_get_server_method(int ver);
+static const SSL_METHOD *ssl2_get_server_method(int ver);
 static int get_client_master_key(SSL *s);
 static int get_client_hello(SSL *s);
 static int server_hello(SSL *s); 
@@ -129,7 +129,7 @@
 	unsigned char *to,int padding);
 #define BREAK	break
 
-static SSL_METHOD *ssl2_get_server_method(int ver)
+static const SSL_METHOD *ssl2_get_server_method(int ver)
 	{
 	if (ver == SSL2_VERSION)
 		return(SSLv2_server_method());
@@ -366,7 +366,7 @@
 	int is_export,i,n,keya,ek;
 	unsigned long len;
 	unsigned char *p;
-	SSL_CIPHER *cp;
+	const SSL_CIPHER *cp;
 	const EVP_CIPHER *c;
 	const EVP_MD *md;
 
@@ -451,7 +451,7 @@
 
 	is_export=SSL_C_IS_EXPORT(s->session->cipher);
 	
-	if (!ssl_cipher_get_evp(s->session,&c,&md,NULL))
+	if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL))
 		{
 		ssl2_return_error(s,SSL2_PE_NO_CIPHER);
 		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
diff --git a/ssl/s3_both.c b/ssl/s3_both.c
index 73f6002..cb391cd 100644
--- a/ssl/s3_both.c
+++ b/ssl/s3_both.c
@@ -160,8 +160,6 @@
 		p= &(d[4]);
 
 		i=s->method->ssl3_enc->final_finish_mac(s,
-			&(s->s3->finish_dgst1),
-			&(s->s3->finish_dgst2),
 			sender,slen,s->s3->tmp.finish_md);
 		s->s3->tmp.finish_md_len = i;
 		memcpy(p, s->s3->tmp.finish_md, i);
@@ -300,21 +298,21 @@
 
 static int ssl3_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
 	{
-		int n;
-		unsigned char *p;
+	int n;
+	unsigned char *p;
 
-		n=i2d_X509(x,NULL);
-		if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3)))
-			{
-				SSLerr(SSL_F_SSL3_ADD_CERT_TO_BUF,ERR_R_BUF_LIB);
-				return(-1);
-			}
-		p=(unsigned char *)&(buf->data[*l]);
-		l2n3(n,p);
-		i2d_X509(x,&p);
-		*l+=n+3;
+	n=i2d_X509(x,NULL);
+	if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3)))
+		{
+		SSLerr(SSL_F_SSL3_ADD_CERT_TO_BUF,ERR_R_BUF_LIB);
+		return(-1);
+		}
+	p=(unsigned char *)&(buf->data[*l]);
+	l2n3(n,p);
+	i2d_X509(x,&p);
+	*l+=n+3;
 
-		return(0);
+	return(0);
 	}
 
 unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
@@ -354,6 +352,8 @@
 				return(0);
 				}
 			X509_verify_cert(&xs_ctx);
+			/* Don't leave errors in the queue */
+			ERR_clear_error();
 			for (i=0; i < sk_X509_num(xs_ctx.chain); i++)
 				{
 				x = sk_X509_value(xs_ctx.chain, i);
@@ -550,9 +550,16 @@
 	else if (i == EVP_PKEY_EC)
 		{
 		ret = SSL_PKEY_ECC;
-		}
+		}	
 #endif
-
+	else if (i == NID_id_GostR3410_94 || i == NID_id_GostR3410_94_cc) 
+		{
+		ret = SSL_PKEY_GOST94;
+		}
+	else if (i == NID_id_GostR3410_2001 || i == NID_id_GostR3410_2001_cc) 
+		{
+		ret = SSL_PKEY_GOST01;
+		}
 err:
 	if(!pkey) EVP_PKEY_free(pk);
 	return(ret);
@@ -618,58 +625,202 @@
 	return(al);
 	}
 
-int ssl3_setup_buffers(SSL *s)
+#ifndef OPENSSL_NO_BUF_FREELISTS
+/* On some platforms, malloc() performance is bad enough that you can't just
+ * free() and malloc() buffers all the time, so we need to use freelists from
+ * unused buffers.  Currently, each freelist holds memory chunks of only a
+ * given size (list->chunklen); other sized chunks are freed and malloced.
+ * This doesn't help much if you're using many different SSL option settings
+ * with a given context.  (The options affecting buffer size are
+ * max_send_fragment, read buffer vs write buffer,
+ * SSL_OP_MICROSOFT_BIG_WRITE_BUFFER, SSL_OP_NO_COMPRESSION, and
+ * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS.)  Using a separate freelist for every
+ * possible size is not an option, since max_send_fragment can take on many
+ * different values.
+ *
+ * If you are on a platform with a slow malloc(), and you're using SSL
+ * connections with many different settings for these options, and you need to
+ * use the SSL_MOD_RELEASE_BUFFERS feature, you have a few options:
+ *    - Link against a faster malloc implementation.
+ *    - Use a separate SSL_CTX for each option set.
+ *    - Improve this code.
+ */
+static void *
+freelist_extract(SSL_CTX *ctx, int for_read, int sz)
+	{
+	SSL3_BUF_FREELIST *list;
+	SSL3_BUF_FREELIST_ENTRY *ent = NULL;
+	void *result = NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+	list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist;
+	if (list != NULL && sz == (int)list->chunklen)
+		ent = list->head;
+	if (ent != NULL)
+		{
+		list->head = ent->next;
+		result = ent;
+		if (--list->len == 0)
+			list->chunklen = 0;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+	if (!result)
+		result = OPENSSL_malloc(sz);
+	return result;
+}
+
+static void
+freelist_insert(SSL_CTX *ctx, int for_read, size_t sz, void *mem)
+	{
+	SSL3_BUF_FREELIST *list;
+	SSL3_BUF_FREELIST_ENTRY *ent;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+	list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist;
+	if (list != NULL &&
+	    (sz == list->chunklen || list->chunklen == 0) &&
+	    list->len < ctx->freelist_max_len &&
+	    sz >= sizeof(*ent))
+		{
+		list->chunklen = sz;
+		ent = mem;
+		ent->next = list->head;
+		list->head = ent;
+		++list->len;
+		mem = NULL;
+		}
+
+	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+	if (mem)
+		OPENSSL_free(mem);
+	}
+#else
+#define freelist_extract(c,fr,sz) OPENSSL_malloc(sz)
+#define freelist_insert(c,fr,sz,m) OPENSSL_free(m)
+#endif
+
+int ssl3_setup_read_buffer(SSL *s)
 	{
 	unsigned char *p;
-	unsigned int extra,headerlen;
-	size_t len;
-
+	size_t len,align=0,headerlen;
+	
 	if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
 		headerlen = DTLS1_RT_HEADER_LENGTH;
 	else
 		headerlen = SSL3_RT_HEADER_LENGTH;
 
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+	align = (-SSL3_RT_HEADER_LENGTH)&(SSL3_ALIGN_PAYLOAD-1);
+#endif
+
 	if (s->s3->rbuf.buf == NULL)
 		{
 		if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS)
 			{
 			len = SSL3_RT_DEFAULT_PACKET_SIZE;
 			}
-		else
+  		else
 			{
+			len = SSL3_RT_MAX_PLAIN_LENGTH
+				+ SSL3_RT_MAX_ENCRYPTED_OVERHEAD
+				+ headerlen + align;
 			if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
-				extra=SSL3_RT_MAX_EXTRA;
-			else
-				extra=0;
-			len = SSL3_RT_MAX_PACKET_SIZE + extra;
+				{
+				s->s3->init_extra = 1;
+				len += SSL3_RT_MAX_EXTRA;
+				}
 			}
-		if ((p=OPENSSL_malloc(len)) == NULL)
+#ifndef OPENSSL_NO_COMP
+		if (!(s->options & SSL_OP_NO_COMPRESSION))
+			len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
+#endif
+		if ((p=freelist_extract(s->ctx, 1, len)) == NULL)
 			goto err;
 		s->s3->rbuf.buf = p;
 		s->s3->rbuf.len = len;
 		}
 
+	s->packet= &(s->s3->rbuf.buf[0]);
+	return 1;
+
+err:
+	SSLerr(SSL_F_SSL3_SETUP_READ_BUFFER,ERR_R_MALLOC_FAILURE);
+	return 0;
+	}
+
+int ssl3_setup_write_buffer(SSL *s)
+	{
+	unsigned char *p;
+	size_t len,align=0,headerlen;
+
+	if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
+		headerlen = DTLS1_RT_HEADER_LENGTH + 1;
+	else
+		headerlen = SSL3_RT_HEADER_LENGTH;
+
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+	align = (-SSL3_RT_HEADER_LENGTH)&(SSL3_ALIGN_PAYLOAD-1);
+#endif
+
 	if (s->s3->wbuf.buf == NULL)
 		{
 		if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS)
 			{
 			len = SSL3_RT_DEFAULT_PACKET_SIZE;
 			}
-		else
+  		else
 			{
-			len = SSL3_RT_MAX_PACKET_SIZE;
+			len = s->max_send_fragment;
 			}
-		len += SSL3_RT_DEFAULT_WRITE_OVERHEAD; /* extra space for empty
-                                                          fragment, header, MAC
-                                                          and padding */
-		if ((p=OPENSSL_malloc(len)) == NULL)
+		len += 0
+			+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD
+			+ headerlen + align;
+#ifndef OPENSSL_NO_COMP
+		if (!(s->options & SSL_OP_NO_COMPRESSION))
+			len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
+#endif
+		if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
+			len += headerlen + align
+				+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
+		if ((p=freelist_extract(s->ctx, 0, len)) == NULL)
 			goto err;
 		s->s3->wbuf.buf = p;
 		s->s3->wbuf.len = len;
 		}
-	s->packet= &(s->s3->rbuf.buf[0]);
-	return(1);
+
+	return 1;
+
 err:
-	SSLerr(SSL_F_SSL3_SETUP_BUFFERS,ERR_R_MALLOC_FAILURE);
-	return(0);
+	SSLerr(SSL_F_SSL3_SETUP_WRITE_BUFFER,ERR_R_MALLOC_FAILURE);
+	return 0;
+	}
+
+
+int ssl3_setup_buffers(SSL *s)
+	{
+	if (!ssl3_setup_read_buffer(s))
+		return 0;
+	if (!ssl3_setup_write_buffer(s))
+		return 0;
+	return 1;
+	}
+
+int ssl3_release_write_buffer(SSL *s)
+	{
+	if (s->s3->wbuf.buf != NULL)
+		{
+		freelist_insert(s->ctx, 0, s->s3->wbuf.len, s->s3->wbuf.buf);
+		s->s3->wbuf.buf = NULL;
+		}
+	return 1;
+	}
+
+int ssl3_release_read_buffer(SSL *s)
+	{
+	if (s->s3->rbuf.buf != NULL)
+		{
+		freelist_insert(s->ctx, 1, s->s3->rbuf.len, s->s3->rbuf.buf);
+		s->s3->rbuf.buf = NULL;
+		}
+	return 1;
 	}
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index e5138b6..41769fe 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -121,6 +121,32 @@
  * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
  *
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 #include <stdio.h>
 #include "ssl_locl.h"
@@ -130,10 +156,6 @@
 #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
@@ -142,15 +164,10 @@
 #include <openssl/engine.h>
 #endif
 
-static SSL_METHOD *ssl3_get_client_method(int ver);
+static const SSL_METHOD *ssl3_get_client_method(int ver);
 static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b);
 
-#ifndef OPENSSL_NO_ECDH
-static int curve_id2nid(int curve_id);
-int check_srvr_ecc_cert_and_alg(X509 *x, SSL_CIPHER *cs);
-#endif
-
-static SSL_METHOD *ssl3_get_client_method(int ver)
+static const SSL_METHOD *ssl3_get_client_method(int ver)
 	{
 	if (ver == SSL3_VERSION)
 		return(SSLv3_client_method());
@@ -166,7 +183,7 @@
 int ssl3_connect(SSL *s)
 	{
 	BUF_MEM *buf=NULL;
-	unsigned long Time=(unsigned long)time(NULL),l;
+	unsigned long Time=(unsigned long)time(NULL);
 	void (*cb)(const SSL *ssl,int type,int val)=NULL;
 	int ret= -1;
 	int new_state,state,skip=0;
@@ -261,6 +278,7 @@
 		case SSL3_ST_CR_SRVR_HELLO_B:
 			ret=ssl3_get_server_hello(s);
 			if (ret <= 0) goto end;
+
 			if (s->hit)
 				s->state=SSL3_ST_CR_FINISHED_A;
 			else
@@ -285,7 +303,9 @@
 				}
 #endif
 			/* Check if it is anon DH/ECDH */
-			if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
+			/* or PSK */
+			if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
+			    !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
 				{
 				ret=ssl3_get_server_certificate(s);
 				if (ret <= 0) goto end;
@@ -360,7 +380,6 @@
 		case SSL3_ST_CW_KEY_EXCH_B:
 			ret=ssl3_send_client_key_exchange(s);
 			if (ret <= 0) goto end;
-			l=s->s3->tmp.new_cipher->algorithms;
 			/* EAY EAY EAY need to check for DH fix cert
 			 * sent back */
 			/* For TLS, cert_req is set to 2, so a cert chain
@@ -381,6 +400,11 @@
 				s->state=SSL3_ST_CW_CHANGE_A;
 				s->s3->change_cipher_spec=0;
 				}
+			if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY)
+				{
+				s->state=SSL3_ST_CW_CHANGE_A;
+				s->s3->change_cipher_spec=0;
+				}
 
 			s->init_num=0;
 			break;
@@ -650,7 +674,9 @@
 #ifdef OPENSSL_NO_COMP
 		*(p++)=1;
 #else
-		if (s->ctx->comp_methods == NULL)
+
+		if ((s->options & SSL_OP_NO_COMPRESSION)
+					|| !s->ctx->comp_methods)
 			j=0;
 		else
 			j=sk_SSL_COMP_num(s->ctx->comp_methods);
@@ -662,13 +688,21 @@
 			}
 #endif
 		*(p++)=0; /* Add the NULL method */
+
 #ifndef OPENSSL_NO_TLSEXT
+		/* TLS extensions*/
+		if (ssl_prepare_clienthello_tlsext(s) <= 0)
+			{
+			SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
+			goto err;
+			}
 		if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
 			{
 			SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
 			goto err;
 			}
-#endif		
+#endif
+		
 		l=(p-d);
 		d=buf;
 		*(d++)=SSL3_MT_CLIENT_HELLO;
@@ -689,7 +723,7 @@
 int ssl3_get_server_hello(SSL *s)
 	{
 	STACK_OF(SSL_CIPHER) *sk;
-	SSL_CIPHER *c;
+	const SSL_CIPHER *c;
 	unsigned char *p,*d;
 	int i,al,ok;
 	unsigned int j;
@@ -758,6 +792,23 @@
 		goto f_err;
 		}
 
+#ifndef OPENSSL_NO_TLSEXT
+	/* check if we want to resume the session based on external pre-shared secret */
+	if (s->version >= TLS1_VERSION && s->tls_session_secret_cb)
+		{
+		SSL_CIPHER *pref_cipher=NULL;
+		s->session->master_key_length=sizeof(s->session->master_key);
+		if (s->tls_session_secret_cb(s, s->session->master_key,
+					     &s->session->master_key_length,
+					     NULL, &pref_cipher,
+					     s->tls_session_secret_cb_arg))
+			{
+			s->session->cipher = pref_cipher ?
+				pref_cipher : ssl_get_cipher_by_char(s, p+j);
+			}
+		}
+#endif /* OPENSSL_NO_TLSEXT */
+
 	if (j != 0 && j == s->session->session_id_length
 	    && memcmp(p,s->session->session_id,j) == 0)
 	    {
@@ -824,6 +875,8 @@
 			}
 		}
 	s->s3->tmp.new_cipher=c;
+	if (!ssl3_digest_cached_records(s))
+		goto f_err;
 
 	/* lets get the compression algorithm */
 	/* COMPRESSION */
@@ -834,10 +887,31 @@
 		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
 		goto f_err;
 		}
+	/* If compression is disabled we'd better not try to resume a session
+	 * using compression.
+	 */
+	if (s->session->compress_meth != 0)
+		{
+		al=SSL_AD_INTERNAL_ERROR;
+		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_INCONSISTENT_COMPRESSION);
+		goto f_err;
+		}
 #else
 	j= *(p++);
+	if (s->hit && j != s->session->compress_meth)
+		{
+		al=SSL_AD_ILLEGAL_PARAMETER;
+		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED);
+		goto f_err;
+		}
 	if (j == 0)
 		comp=NULL;
+	else if (s->options & SSL_OP_NO_COMPRESSION)
+		{
+		al=SSL_AD_ILLEGAL_PARAMETER;
+		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_COMPRESSION_DISABLED);
+		goto f_err;
+		}
 	else
 		comp=ssl3_comp_find(s->ctx->comp_methods,j);
 	
@@ -852,6 +926,7 @@
 		s->s3->tmp.new_compression=comp;
 		}
 #endif
+
 #ifndef OPENSSL_NO_TLSEXT
 	/* TLS extensions*/
 	if (s->version >= SSL3_VERSION)
@@ -870,7 +945,6 @@
 		}
 #endif
 
-
 	if (p != (d+n))
 		{
 		/* wrong packet length */
@@ -908,7 +982,7 @@
 	if (!ok) return((int)n);
 
 	if ((s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE) ||
-		((s->s3->tmp.new_cipher->algorithms & SSL_aKRB5) && 
+		((s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) && 
 		(s->s3->tmp.message_type == SSL3_MT_SERVER_DONE)))
 		{
 		s->s3->tmp.reuse_message=1;
@@ -973,10 +1047,10 @@
 	i=ssl_verify_cert_chain(s,sk);
 	if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0)
 #ifndef OPENSSL_NO_KRB5
-	        && (s->s3->tmp.new_cipher->algorithms & (SSL_MKEY_MASK|SSL_AUTH_MASK))
-	        != (SSL_aKRB5|SSL_kKRB5)
+	    && !((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) &&
+		 (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
 #endif /* OPENSSL_NO_KRB5 */
-	        )
+		)
 		{
 		al=ssl_verify_alarm_type(s->verify_result);
 		SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED);
@@ -1000,15 +1074,15 @@
 	pkey=X509_get_pubkey(x);
 
 	/* VRS: allow null cert if auth == KRB5 */
-	need_cert =	((s->s3->tmp.new_cipher->algorithms
-	                 & (SSL_MKEY_MASK|SSL_AUTH_MASK))
-	                 == (SSL_aKRB5|SSL_kKRB5))? 0: 1;
+	need_cert = ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) &&
+	            (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
+	            ? 0 : 1;
 
 #ifdef KSSL_DEBUG
-	printf("pkey,x = %p, %p\n", (void *)pkey,(void *)x);
+	printf("pkey,x = %p, %p\n", pkey,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);
+	printf("cipher, alg, nc = %s, %lx, %lx, %d\n", s->s3->tmp.new_cipher->name,
+		s->s3->tmp.new_cipher->algorithm_mkey, s->s3->tmp.new_cipher->algorithm_auth, need_cert);
 #endif    /* KSSL_DEBUG */
 
 	if (need_cert && ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey)))
@@ -1080,7 +1154,7 @@
 	EVP_MD_CTX md_ctx;
 	unsigned char *param,*p;
 	int al,i,j,param_len,ok;
-	long n,alg;
+	long n,alg_k,alg_a;
 	EVP_PKEY *pkey=NULL;
 #ifndef OPENSSL_NO_RSA
 	RSA *rsa=NULL;
@@ -1104,17 +1178,28 @@
 		-1,
 		s->max_cert_list,
 		&ok);
-
 	if (!ok) return((int)n);
 
 	if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE)
 		{
+#ifndef OPENSSL_NO_PSK
+		/* In plain PSK ciphersuite, ServerKeyExchange can be
+		   omitted if no identity hint is sent. Set
+		   session->sess_cert anyway to avoid problems
+		   later.*/
+		if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
+			{
+			s->session->sess_cert=ssl_sess_cert_new();
+			if (s->ctx->psk_identity_hint)
+				OPENSSL_free(s->ctx->psk_identity_hint);
+			s->ctx->psk_identity_hint = NULL;
+			}
+#endif
 		s->s3->tmp.reuse_message=1;
 		return(1);
 		}
 
 	param=p=(unsigned char *)s->init_msg;
-
 	if (s->session->sess_cert != NULL)
 		{
 #ifndef OPENSSL_NO_RSA
@@ -1145,11 +1230,57 @@
 		}
 
 	param_len=0;
-	alg=s->s3->tmp.new_cipher->algorithms;
+	alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
+	alg_a=s->s3->tmp.new_cipher->algorithm_auth;
 	EVP_MD_CTX_init(&md_ctx);
 
+#ifndef OPENSSL_NO_PSK
+	if (alg_k & SSL_kPSK)
+		{
+		char tmp_id_hint[PSK_MAX_IDENTITY_LEN+1];
+
+		al=SSL_AD_HANDSHAKE_FAILURE;
+		n2s(p,i);
+		param_len=i+2;
+		/* Store PSK identity hint for later use, hint is used
+		 * in ssl3_send_client_key_exchange.  Assume that the
+		 * maximum length of a PSK identity hint can be as
+		 * long as the maximum length of a PSK identity. */
+		if (i > PSK_MAX_IDENTITY_LEN)
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+				SSL_R_DATA_LENGTH_TOO_LONG);
+			goto f_err;
+			}
+		if (param_len > n)
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+				SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH);
+			goto f_err;
+			}
+		/* If received PSK identity hint contains NULL
+		 * characters, the hint is truncated from the first
+		 * NULL. p may not be ending with NULL, so create a
+		 * NULL-terminated string. */
+		memcpy(tmp_id_hint, p, i);
+		memset(tmp_id_hint+i, 0, PSK_MAX_IDENTITY_LEN+1-i);
+		if (s->ctx->psk_identity_hint != NULL)
+			OPENSSL_free(s->ctx->psk_identity_hint);
+		s->ctx->psk_identity_hint = BUF_strdup(tmp_id_hint);
+		if (s->ctx->psk_identity_hint == NULL)
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
+			goto f_err;
+			}	   
+
+		p+=i;
+		n-=param_len;
+		}
+	else
+#endif /* !OPENSSL_NO_PSK */
 #ifndef OPENSSL_NO_RSA
-	if (alg & SSL_kRSA)
+	if (alg_k & SSL_kRSA)
 		{
 		if ((rsa=RSA_new()) == NULL)
 			{
@@ -1188,7 +1319,7 @@
 		n-=param_len;
 
 		/* this should be because we are using an export cipher */
-		if (alg & SSL_aRSA)
+		if (alg_a & SSL_aRSA)
 			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
 		else
 			{
@@ -1203,7 +1334,7 @@
 		;
 #endif
 #ifndef OPENSSL_NO_DH
-	else if (alg & SSL_kEDH)
+	else if (alg_k & SSL_kEDH)
 		{
 		if ((dh=DH_new()) == NULL)
 			{
@@ -1257,14 +1388,14 @@
 		n-=param_len;
 
 #ifndef OPENSSL_NO_RSA
-		if (alg & SSL_aRSA)
+		if (alg_a & SSL_aRSA)
 			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
 #else
 		if (0)
 			;
 #endif
 #ifndef OPENSSL_NO_DSA
-		else if (alg & SSL_aDSS)
+		else if (alg_a & SSL_aDSS)
 			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].x509);
 #endif
 		/* else anonymous DH, so no certificate or pkey. */
@@ -1272,7 +1403,7 @@
 		s->session->sess_cert->peer_dh_tmp=dh;
 		dh=NULL;
 		}
-	else if ((alg & SSL_kDHr) || (alg & SSL_kDHd))
+	else if ((alg_k & SSL_kDHr) || (alg_k & SSL_kDHd))
 		{
 		al=SSL_AD_ILLEGAL_PARAMETER;
 		SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER);
@@ -1281,7 +1412,7 @@
 #endif /* !OPENSSL_NO_DH */
 
 #ifndef OPENSSL_NO_ECDH
-	else if (alg & SSL_kECDHE)
+	else if (alg_k & SSL_kEECDH)
 		{
 		EC_GROUP *ngroup;
 		const EC_GROUP *group;
@@ -1304,7 +1435,7 @@
 		param_len=3;
 		if ((param_len > n) ||
 		    (*p != NAMED_CURVE_TYPE) || 
-		    ((curve_nid = curve_id2nid(*(p + 2))) == 0)) 
+		    ((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0)) 
 			{
 			al=SSL_AD_INTERNAL_ERROR;
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
@@ -1365,11 +1496,11 @@
 		 */
 		if (0) ;
 #ifndef OPENSSL_NO_RSA
-		else if (alg & SSL_aRSA)
+		else if (alg_a & SSL_aRSA)
 			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
 #endif
 #ifndef OPENSSL_NO_ECDSA
-		else if (alg & SSL_aECDSA)
+		else if (alg_a & SSL_aECDSA)
 			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_ECC].x509);
 #endif
 		/* else anonymous ECDH, so no certificate or pkey. */
@@ -1380,19 +1511,13 @@
 		EC_POINT_free(srvr_ecpoint);
 		srvr_ecpoint = NULL;
 		}
-	else if (alg & SSL_kECDH)
+	else if (alg_k)
 		{
 		al=SSL_AD_UNEXPECTED_MESSAGE;
 		SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
 		goto f_err;
 		}
 #endif /* !OPENSSL_NO_ECDH */
-	if (alg & SSL_aFZA)
-		{
-		al=SSL_AD_HANDSHAKE_FAILURE;
-		SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER);
-		goto f_err;
-		}
 
 
 	/* p points to the next byte, there are 'n' bytes left */
@@ -1421,8 +1546,6 @@
 			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);
@@ -1493,12 +1616,13 @@
 		}
 	else
 		{
-		/* still data left over */
-		if (!(alg & SSL_aNULL))
+		if (!(alg_a & SSL_aNULL) && !(alg_k & SSL_kPSK))
+			/* aNULL or kPSK do not need public keys */
 			{
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
 			goto err;
 			}
+		/* still data left over */
 		if (n != 0)
 			{
 			al=SSL_AD_DECODE_ERROR;
@@ -1568,8 +1692,7 @@
 	/* TLS does not like anon-DH with client cert */
 	if (s->version > SSL3_VERSION)
 		{
-		l=s->s3->tmp.new_cipher->algorithms;
-		if (l & SSL_aNULL)
+		if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
 			{
 			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
 			SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER);
@@ -1771,8 +1894,7 @@
 int ssl3_get_cert_status(SSL *s)
 	{
 	int ok, al;
-	unsigned long resplen;
-	long n;
+	unsigned long resplen,n;
 	const unsigned char *p;
 
 	n=s->method->ssl_get_message(s,
@@ -1798,7 +1920,7 @@
 		goto f_err;
 		}
 	n2l3(p, resplen);
-	if (resplen + 4 != (unsigned long)n)
+	if (resplen + 4 != n)
 		{
 		al = SSL_AD_DECODE_ERROR;
 		SSLerr(SSL_F_SSL3_GET_CERT_STATUS,SSL_R_LENGTH_MISMATCH);
@@ -1867,7 +1989,7 @@
 	{
 	unsigned char *p,*d;
 	int n;
-	unsigned long l;
+	unsigned long alg_k;
 #ifndef OPENSSL_NO_RSA
 	unsigned char *q;
 	EVP_PKEY *pkey=NULL;
@@ -1889,12 +2011,12 @@
 		d=(unsigned char *)s->init_buf->data;
 		p= &(d[4]);
 
-		l=s->s3->tmp.new_cipher->algorithms;
+		alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
 
 		/* Fool emacs indentation */
 		if (0) {}
 #ifndef OPENSSL_NO_RSA
-		else if (l & SSL_kRSA)
+		else if (alg_k & SSL_kRSA)
 			{
 			RSA *rsa;
 			unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
@@ -1953,7 +2075,7 @@
 			}
 #endif
 #ifndef OPENSSL_NO_KRB5
-		else if (l & SSL_kKRB5)
+		else if (alg_k & SSL_kKRB5)
 			{
 			krb5_error_code	krb5rc;
 			KSSL_CTX	*kssl_ctx = s->kssl_ctx;
@@ -1961,7 +2083,7 @@
 			krb5_data	*enc_ticket;
 			krb5_data	authenticator, *authp = NULL;
 			EVP_CIPHER_CTX	ciph_ctx;
-			EVP_CIPHER	*enc = NULL;
+			const EVP_CIPHER *enc = NULL;
 			unsigned char	iv[EVP_MAX_IV_LENGTH];
 			unsigned char	tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
 			unsigned char	epms[SSL_MAX_MASTER_KEY_LENGTH 
@@ -1972,7 +2094,7 @@
 
 #ifdef KSSL_DEBUG
 			printf("ssl3_send_client_key_exchange(%lx & %lx)\n",
-			        l, SSL_kKRB5);
+				alg_k, SSL_kKRB5);
 #endif	/* KSSL_DEBUG */
 
 			authp = NULL;
@@ -2064,7 +2186,7 @@
 				sizeof tmp_buf);
 			EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl);
 			outl += padl;
-			if (outl > sizeof epms)
+			if (outl > (int)sizeof epms)
 				{
 				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
 				goto err;
@@ -2078,7 +2200,7 @@
 			n+=outl + 2;
 
 			s->session->master_key_length=
-			        s->method->ssl3_enc->generate_master_secret(s,
+				s->method->ssl3_enc->generate_master_secret(s,
 					s->session->master_key,
 					tmp_buf, sizeof tmp_buf);
 
@@ -2087,7 +2209,7 @@
 			}
 #endif
 #ifndef OPENSSL_NO_DH
-		else if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
+		else if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
 			{
 			DH *dh_srvr,*dh_clnt;
 
@@ -2096,7 +2218,7 @@
 				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;
@@ -2151,7 +2273,7 @@
 #endif
 
 #ifndef OPENSSL_NO_ECDH 
-		else if ((l & SSL_kECDH) || (l & SSL_kECDHE))
+		else if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe))
 			{
 			const EC_GROUP *srvr_group = NULL;
 			EC_KEY *tkey;
@@ -2163,7 +2285,7 @@
 			 * computation as part of client certificate?
 			 * If so, set ecdh_clnt_cert to 1.
 			 */
-			if ((l & SSL_kECDH) && (s->cert != NULL)) 
+			if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->cert != NULL)) 
 				{
 				/* XXX: For now, we do not support client
 				 * authentication using ECDH certificates.
@@ -2335,6 +2457,178 @@
 			EVP_PKEY_free(srvr_pub_pkey);
 			}
 #endif /* !OPENSSL_NO_ECDH */
+		else if (alg_k & SSL_kGOST) 
+			{
+			/* GOST key exchange message creation */
+			EVP_PKEY_CTX *pkey_ctx;
+			X509 *peer_cert; 
+			size_t msglen;
+			unsigned int md_len;
+			int keytype;
+			unsigned char premaster_secret[32],shared_ukm[32], tmp[256];
+			EVP_MD_CTX *ukm_hash;
+			EVP_PKEY *pub_key;
+
+			/* Get server sertificate PKEY and create ctx from it */
+			peer_cert=s->session->sess_cert->peer_pkeys[(keytype=SSL_PKEY_GOST01)].x509;
+			if (!peer_cert) 
+				peer_cert=s->session->sess_cert->peer_pkeys[(keytype=SSL_PKEY_GOST94)].x509;
+			if (!peer_cert)		{
+					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER);
+					goto err;
+				}	
+				
+			pkey_ctx=EVP_PKEY_CTX_new(pub_key=X509_get_pubkey(peer_cert),NULL);
+			/* If we have send a certificate, and certificate key
+
+			 * parameters match those of server certificate, use
+			 * certificate key for key exchange
+			 */
+
+			 /* Otherwise, generate ephemeral key pair */
+					
+			EVP_PKEY_encrypt_init(pkey_ctx);
+			  /* Generate session key */	
+		    RAND_bytes(premaster_secret,32);
+			/* If we have client certificate, use its secret as peer key */
+			if (s->s3->tmp.cert_req && s->cert->key->privatekey) {
+				if (EVP_PKEY_derive_set_peer(pkey_ctx,s->cert->key->privatekey) <=0) {
+					/* If there was an error - just ignore it. Ephemeral key
+					* would be used
+					*/
+					ERR_clear_error();
+				}
+			}			
+			/* Compute shared IV and store it in algorithm-specific
+			 * context data */
+			ukm_hash = EVP_MD_CTX_create();
+			EVP_DigestInit(ukm_hash,EVP_get_digestbynid(NID_id_GostR3411_94));
+			EVP_DigestUpdate(ukm_hash,s->s3->client_random,SSL3_RANDOM_SIZE);
+			EVP_DigestUpdate(ukm_hash,s->s3->server_random,SSL3_RANDOM_SIZE);
+			EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len);
+			EVP_MD_CTX_destroy(ukm_hash);
+			if (EVP_PKEY_CTX_ctrl(pkey_ctx,-1,EVP_PKEY_OP_ENCRYPT,EVP_PKEY_CTRL_SET_IV,
+				8,shared_ukm)<0) {
+					SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+						SSL_R_LIBRARY_BUG);
+					goto err;
+				}	
+			/* Make GOST keytransport blob message */
+			/*Encapsulate it into sequence */
+			*(p++)=V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED;
+			msglen=255;
+			if (EVP_PKEY_encrypt(pkey_ctx,tmp,&msglen,premaster_secret,32)<0) {
+			SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+					SSL_R_LIBRARY_BUG);
+				goto err;
+			}
+			if (msglen >= 0x80)
+				{
+				*(p++)=0x81;
+				*(p++)= msglen & 0xff;
+				n=msglen+3;
+				}
+			else
+				{
+				*(p++)= msglen & 0xff;
+				n=msglen+2;
+				}
+			memcpy(p, tmp, msglen);
+			/* Check if pubkey from client certificate was used */
+			if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0)
+				{
+				/* Set flag "skip certificate verify" */
+				s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY;
+				}
+			EVP_PKEY_CTX_free(pkey_ctx);
+			s->session->master_key_length=
+				s->method->ssl3_enc->generate_master_secret(s,
+					s->session->master_key,premaster_secret,32);
+			EVP_PKEY_free(pub_key);
+
+			}
+#ifndef OPENSSL_NO_PSK
+		else if (alg_k & SSL_kPSK)
+			{
+			char identity[PSK_MAX_IDENTITY_LEN];
+			unsigned char *t = NULL;
+			unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4];
+			unsigned int pre_ms_len = 0, psk_len = 0;
+			int psk_err = 1;
+
+			n = 0;
+			if (s->psk_client_callback == NULL)
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+					SSL_R_PSK_NO_CLIENT_CB);
+				goto err;
+				}
+
+			psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint,
+				identity, PSK_MAX_IDENTITY_LEN,
+				psk_or_pre_ms, sizeof(psk_or_pre_ms));
+			if (psk_len > PSK_MAX_PSK_LEN)
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+					ERR_R_INTERNAL_ERROR);
+				goto psk_err;
+				}
+			else if (psk_len == 0)
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+					SSL_R_PSK_IDENTITY_NOT_FOUND);
+				goto psk_err;
+				}
+
+			/* create PSK pre_master_secret */
+			pre_ms_len = 2+psk_len+2+psk_len;
+			t = psk_or_pre_ms;
+			memmove(psk_or_pre_ms+psk_len+4, psk_or_pre_ms, psk_len);
+			s2n(psk_len, t);
+			memset(t, 0, psk_len);
+			t+=psk_len;
+			s2n(psk_len, t);
+
+			if (s->session->psk_identity_hint != NULL)
+				OPENSSL_free(s->session->psk_identity_hint);
+			s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint);
+			if (s->ctx->psk_identity_hint != NULL &&
+				s->session->psk_identity_hint == NULL)
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+					ERR_R_MALLOC_FAILURE);
+				goto psk_err;
+				}
+
+			if (s->session->psk_identity != NULL)
+				OPENSSL_free(s->session->psk_identity);
+			s->session->psk_identity = BUF_strdup(identity);
+			if (s->session->psk_identity == NULL)
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+					ERR_R_MALLOC_FAILURE);
+				goto psk_err;
+				}
+
+			s->session->master_key_length =
+				s->method->ssl3_enc->generate_master_secret(s,
+					s->session->master_key,
+					psk_or_pre_ms, pre_ms_len); 
+			n = strlen(identity);
+			s2n(n, p);
+			memcpy(p, identity, n);
+			n+=2;
+			psk_err = 0;
+		psk_err:
+			OPENSSL_cleanse(identity, PSK_MAX_IDENTITY_LEN);
+			OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
+			if (psk_err != 0)
+				{
+				ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+				goto err;
+				}
+			}
+#endif
 		else
 			{
 			ssl3_send_alert(s, SSL3_AL_FATAL,
@@ -2371,28 +2665,37 @@
 	unsigned char *p,*d;
 	unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
 	EVP_PKEY *pkey;
+	EVP_PKEY_CTX *pctx=NULL;
 #ifndef OPENSSL_NO_RSA
 	unsigned u=0;
 #endif
 	unsigned long n;
-#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
 	int j;
-#endif
 
 	if (s->state == SSL3_ST_CW_CERT_VRFY_A)
 		{
 		d=(unsigned char *)s->init_buf->data;
 		p= &(d[4]);
 		pkey=s->cert->key->privatekey;
-
-		s->method->ssl3_enc->cert_verify_mac(s,&(s->s3->finish_dgst2),
-			&(data[MD5_DIGEST_LENGTH]));
-
+/* Create context from key and test if sha1 is allowed as digest */
+		pctx = EVP_PKEY_CTX_new(pkey,NULL);
+		EVP_PKEY_sign_init(pctx);
+		if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1())>0)
+			{
+			s->method->ssl3_enc->cert_verify_mac(s,
+						NID_sha1,
+						&(data[MD5_DIGEST_LENGTH]));
+			}
+		else
+			{
+			ERR_clear_error();
+			}
 #ifndef OPENSSL_NO_RSA
 		if (pkey->type == EVP_PKEY_RSA)
 			{
 			s->method->ssl3_enc->cert_verify_mac(s,
-				&(s->s3->finish_dgst1),&(data[0]));
+				NID_md5,
+			 	&(data[0]));
 			if (RSA_sign(NID_md5_sha1, data,
 					 MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH,
 					&(p[2]), &u, pkey->pkey.rsa) <= 0 )
@@ -2438,10 +2741,30 @@
 			}
 		else
 #endif
-			{
+		if (pkey->type == NID_id_GostR3410_94 || pkey->type == NID_id_GostR3410_2001) 
+		{
+		unsigned char signbuf[64];
+		int i;
+		size_t sigsize=64;
+		s->method->ssl3_enc->cert_verify_mac(s,
+			NID_id_GostR3411_94,
+			data);
+		if (EVP_PKEY_sign(pctx, signbuf, &sigsize, data, 32) <= 0) {
+			SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
+			ERR_R_INTERNAL_ERROR);
+			goto err;
+		}
+		for (i=63,j=0; i>=0; j++, i--) {
+			p[2+j]=signbuf[i];
+		}	
+		s2n(j,p);
+		n=j+2;
+		}
+		else
+		{
 			SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_INTERNAL_ERROR);
 			goto err;
-			}
+		}
 		*(d++)=SSL3_MT_CERTIFICATE_VERIFY;
 		l2n3(n,d);
 
@@ -2449,8 +2772,10 @@
 		s->init_num=(int)n+4;
 		s->init_off=0;
 		}
+	EVP_PKEY_CTX_free(pctx);
 	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
 err:
+	EVP_PKEY_CTX_free(pctx);
 	return(-1);
 	}
 
@@ -2535,7 +2860,7 @@
 int ssl3_check_cert_and_algorithm(SSL *s)
 	{
 	int i,idx;
-	long algs;
+	long alg_k,alg_a;
 	EVP_PKEY *pkey=NULL;
 	SESS_CERT *sc;
 #ifndef OPENSSL_NO_RSA
@@ -2545,14 +2870,14 @@
 	DH *dh;
 #endif
 
-	sc=s->session->sess_cert;
-
-	algs=s->s3->tmp.new_cipher->algorithms;
+	alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
+	alg_a=s->s3->tmp.new_cipher->algorithm_auth;
 
 	/* we don't have a certificate */
-	if (algs & (SSL_aDH|SSL_aNULL|SSL_aKRB5))
+	if ((alg_a & (SSL_aDH|SSL_aNULL|SSL_aKRB5)) || (alg_k & SSL_kPSK))
 		return(1);
 
+	sc=s->session->sess_cert;
 	if (sc == NULL)
 		{
 		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,ERR_R_INTERNAL_ERROR);
@@ -2572,11 +2897,11 @@
 #ifndef OPENSSL_NO_ECDH
 	if (idx == SSL_PKEY_ECC)
 		{
-		if (check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509,
+		if (ssl_check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509,
 		    s->s3->tmp.new_cipher) == 0) 
 			{ /* check failed */
 			SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_BAD_ECC_CERT);
-			goto f_err;			
+			goto f_err;
 			}
 		else 
 			{
@@ -2590,20 +2915,20 @@
 
 	
 	/* Check that we have a certificate if we require one */
-	if ((algs & SSL_aRSA) && !has_bits(i,EVP_PK_RSA|EVP_PKT_SIGN))
+	if ((alg_a & SSL_aRSA) && !has_bits(i,EVP_PK_RSA|EVP_PKT_SIGN))
 		{
 		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_RSA_SIGNING_CERT);
 		goto f_err;
 		}
 #ifndef OPENSSL_NO_DSA
-	else if ((algs & SSL_aDSS) && !has_bits(i,EVP_PK_DSA|EVP_PKT_SIGN))
+	else if ((alg_a & SSL_aDSS) && !has_bits(i,EVP_PK_DSA|EVP_PKT_SIGN))
 		{
 		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DSA_SIGNING_CERT);
 		goto f_err;
 		}
 #endif
 #ifndef OPENSSL_NO_RSA
-	if ((algs & SSL_kRSA) &&
+	if ((alg_k & SSL_kRSA) &&
 		!(has_bits(i,EVP_PK_RSA|EVP_PKT_ENC) || (rsa != NULL)))
 		{
 		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_RSA_ENCRYPTING_CERT);
@@ -2611,19 +2936,19 @@
 		}
 #endif
 #ifndef OPENSSL_NO_DH
-	if ((algs & SSL_kEDH) &&
+	if ((alg_k & SSL_kEDH) &&
 		!(has_bits(i,EVP_PK_DH|EVP_PKT_EXCH) || (dh != NULL)))
 		{
 		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_KEY);
 		goto f_err;
 		}
-	else if ((algs & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA))
+	else if ((alg_k & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA))
 		{
 		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_RSA_CERT);
 		goto f_err;
 		}
 #ifndef OPENSSL_NO_DSA
-	else if ((algs & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_DSA))
+	else if ((alg_k & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_DSA))
 		{
 		SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_DSA_CERT);
 		goto f_err;
@@ -2634,7 +2959,7 @@
 	if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i,EVP_PKT_EXP))
 		{
 #ifndef OPENSSL_NO_RSA
-		if (algs & SSL_kRSA)
+		if (alg_k & SSL_kRSA)
 			{
 			if (rsa == NULL
 			    || RSA_size(rsa)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher))
@@ -2646,7 +2971,7 @@
 		else
 #endif
 #ifndef OPENSSL_NO_DH
-			if (algs & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
+			if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
 			    {
 			    if (dh == NULL
 				|| DH_size(dh)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher))
@@ -2669,49 +2994,6 @@
 	return(0);
 	}
 
-
-#ifndef OPENSSL_NO_ECDH
-/* This is the complement of nid2curve_id in s3_srvr.c. */
-static int curve_id2nid(int curve_id)
-{
-	/* ECC curves from draft-ietf-tls-ecc-01.txt (Mar 15, 2001)
-	 * (no changes in draft-ietf-tls-ecc-03.txt [June 2003]) */
-	static int nid_list[26] =
-	{
-		0,
-		NID_sect163k1, /* sect163k1 (1) */
-		NID_sect163r1, /* sect163r1 (2) */
-		NID_sect163r2, /* sect163r2 (3) */
-		NID_sect193r1, /* sect193r1 (4) */ 
-		NID_sect193r2, /* sect193r2 (5) */ 
-		NID_sect233k1, /* sect233k1 (6) */
-		NID_sect233r1, /* sect233r1 (7) */ 
-		NID_sect239k1, /* sect239k1 (8) */ 
-		NID_sect283k1, /* sect283k1 (9) */
-		NID_sect283r1, /* sect283r1 (10) */ 
-		NID_sect409k1, /* sect409k1 (11) */ 
-		NID_sect409r1, /* sect409r1 (12) */
-		NID_sect571k1, /* sect571k1 (13) */ 
-		NID_sect571r1, /* sect571r1 (14) */ 
-		NID_secp160k1, /* secp160k1 (15) */
-		NID_secp160r1, /* secp160r1 (16) */ 
-		NID_secp160r2, /* secp160r2 (17) */ 
-		NID_secp192k1, /* secp192k1 (18) */
-		NID_X9_62_prime192v1, /* secp192r1 (19) */ 
-		NID_secp224k1, /* secp224k1 (20) */ 
-		NID_secp224r1, /* secp224r1 (21) */
-		NID_secp256k1, /* secp256k1 (22) */ 
-		NID_X9_62_prime256v1, /* secp256r1 (23) */ 
-		NID_secp384r1, /* secp384r1 (24) */
-		NID_secp521r1  /* secp521r1 (25) */	
-	};
-	
-	if ((curve_id < 1) || (curve_id > 25)) return 0;
-
-	return nid_list[curve_id];
-}
-#endif
-
 /* Check to see if handshake is full or resumed. Usually this is just a
  * case of checking to see if a cache hit has occurred. In the case of
  * session tickets we have to check the next message to be sure.
@@ -2722,11 +3004,8 @@
 	{
 	int ok;
 	long n;
-	/* If we have no ticket or session ID is non-zero length (a match of
-	 * a non-zero session length would never reach here) it cannot be a
-	 * resumed session.
-	 */
-	if (!s->session->tlsext_tick || s->session->session_id_length)
+	/* If we have no ticket it cannot be a resumed session. */
+	if (!s->session->tlsext_tick)
 		return 1;
 	/* this function is called when we really expect a Certificate
 	 * message, so permit appropriate message length */
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index 06e5466..3d7aec9 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -108,6 +108,32 @@
  * Hudson (tjh@cryptsoft.com).
  *
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 #include <stdio.h>
 #include "ssl_locl.h"
@@ -129,10 +155,8 @@
 	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,
 	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,
 	0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c };
-
-static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx,
+static int ssl3_handshake_mac(SSL *s, int md_nid,
 	const char *sender, int len, unsigned char *p);
-
 static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
 	{
 	EVP_MD_CTX m5;
@@ -146,7 +170,6 @@
 #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)
 		{
@@ -208,6 +231,8 @@
 	is_exp=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
 	c=s->s3->tmp.new_sym_enc;
 	m=s->s3->tmp.new_hash;
+	/* m == NULL will lead to a crash later */
+	OPENSSL_assert(m);
 #ifndef OPENSSL_NO_COMP
 	if (s->s3->tmp.new_compression == NULL)
 		comp=NULL;
@@ -226,7 +251,8 @@
 			/* make sure it's intialized in case we exit later with an error */
 			EVP_CIPHER_CTX_init(s->enc_read_ctx);
 		dd= s->enc_read_ctx;
-		s->read_hash=m;
+
+		ssl_replace_hash(&s->read_hash,m);
 #ifndef OPENSSL_NO_COMP
 		/* COMPRESS */
 		if (s->expand != NULL)
@@ -262,7 +288,7 @@
 			/* make sure it's intialized in case we exit later with an error */
 			EVP_CIPHER_CTX_init(s->enc_write_ctx);
 		dd= s->enc_write_ctx;
-		s->write_hash=m;
+		ssl_replace_hash(&s->write_hash,m);
 #ifndef OPENSSL_NO_COMP
 		/* COMPRESS */
 		if (s->compress != NULL)
@@ -289,6 +315,8 @@
 
 	p=s->s3->tmp.key_block;
 	i=EVP_MD_size(m);
+	if (i < 0)
+		goto err2;
 	cl=EVP_CIPHER_key_length(c);
 	j=is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
 		 cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
@@ -369,7 +397,7 @@
 	if (s->s3->tmp.key_block_length != 0)
 		return(1);
 
-	if (!ssl_cipher_get_evp(s->session,&c,&hash,&comp))
+	if (!ssl_cipher_get_evp(s->session,&c,&hash,NULL,NULL,&comp))
 		{
 		SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
 		return(0);
@@ -383,7 +411,11 @@
 	s->s3->tmp.new_compression=comp;
 #endif
 
-	num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c);
+	num=EVP_MD_size(hash);
+	if (num < 0)
+		return 0;
+
+	num=EVP_CIPHER_key_length(c)+num+EVP_CIPHER_iv_length(c);
 	num*=2;
 
 	ssl3_cleanup_key_block(s);
@@ -405,11 +437,11 @@
 
 		if (s->session->cipher != NULL)
 			{
-			if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_eNULL)
+			if (s->session->cipher->algorithm_enc == SSL_eNULL)
 				s->s3->need_empty_fragments = 0;
 			
 #ifndef OPENSSL_NO_RC4
-			if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4)
+			if (s->session->cipher->algorithm_enc == SSL_RC4)
 				s->s3->need_empty_fragments = 0;
 #endif
 			}
@@ -519,50 +551,131 @@
 
 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);
+	if (s->s3->handshake_buffer) BIO_free(s->s3->handshake_buffer);
+	if (s->s3->handshake_dgst) ssl3_free_digest_list(s);
+    s->s3->handshake_buffer=BIO_new(BIO_s_mem());	
+	(void)BIO_set_close(s->s3->handshake_buffer,BIO_CLOSE);
 	}
 
+void ssl3_free_digest_list(SSL *s) 
+	{
+	int i;
+	if (!s->s3->handshake_dgst) return;
+	for (i=0;i<SSL_MAX_DIGEST;i++) 
+		{
+		if (s->s3->handshake_dgst[i])
+			EVP_MD_CTX_destroy(s->s3->handshake_dgst[i]);
+		}
+	OPENSSL_free(s->s3->handshake_dgst);
+	s->s3->handshake_dgst=NULL;
+	}	
+		
+
+
 void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
 	{
-	EVP_DigestUpdate(&(s->s3->finish_dgst1),buf,len);
-	EVP_DigestUpdate(&(s->s3->finish_dgst2),buf,len);
+	if (s->s3->handshake_buffer) 
+		{
+		BIO_write (s->s3->handshake_buffer,(void *)buf,len);
+		} 
+	else 
+		{
+		int i;
+		for (i=0;i< SSL_MAX_DIGEST;i++) 
+			{
+			if (s->s3->handshake_dgst[i]!= NULL)
+			EVP_DigestUpdate(s->s3->handshake_dgst[i],buf,len);
+			}
+		}	
 	}
 
-int ssl3_cert_verify_mac(SSL *s, EVP_MD_CTX *ctx, unsigned char *p)
+int ssl3_digest_cached_records(SSL *s)
 	{
-	return(ssl3_handshake_mac(s,ctx,NULL,0,p));
+	int i;
+	long mask;
+	const EVP_MD *md;
+	long hdatalen;
+	void *hdata;
+
+	/* Allocate handshake_dgst array */
+	ssl3_free_digest_list(s);
+	s->s3->handshake_dgst = OPENSSL_malloc(SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *));
+	memset(s->s3->handshake_dgst,0,SSL_MAX_DIGEST *sizeof(EVP_MD_CTX *));
+	hdatalen = BIO_get_mem_data(s->s3->handshake_buffer,&hdata);
+	if (hdatalen <= 0)
+		{
+		SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, SSL_R_BAD_HANDSHAKE_LENGTH);
+		return 0;
+		}
+
+	/* Loop through bitso of algorithm2 field and create MD_CTX-es */
+	for (i=0;ssl_get_handshake_digest(i,&mask,&md); i++) 
+		{
+		if ((mask & s->s3->tmp.new_cipher->algorithm2) && md) 
+			{
+			s->s3->handshake_dgst[i]=EVP_MD_CTX_create();
+			EVP_DigestInit_ex(s->s3->handshake_dgst[i],md,NULL);
+			EVP_DigestUpdate(s->s3->handshake_dgst[i],hdata,hdatalen);
+			} 
+		else 
+			{	
+			s->s3->handshake_dgst[i]=NULL;
+			}
+		}
+	/* Free handshake_buffer BIO */
+	BIO_free(s->s3->handshake_buffer);
+	s->s3->handshake_buffer = NULL;
+
+	return 1;
 	}
 
-int ssl3_final_finish_mac(SSL *s, EVP_MD_CTX *ctx1, EVP_MD_CTX *ctx2,
+int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p)
+	{
+	return(ssl3_handshake_mac(s,md_nid,NULL,0,p));
+	}
+int ssl3_final_finish_mac(SSL *s, 
 	     const char *sender, int len, unsigned char *p)
 	{
 	int ret;
-
-	ret=ssl3_handshake_mac(s,ctx1,sender,len,p);
+	ret=ssl3_handshake_mac(s,NID_md5,sender,len,p);
 	p+=ret;
-	ret+=ssl3_handshake_mac(s,ctx2,sender,len,p);
+	ret+=ssl3_handshake_mac(s,NID_sha1,sender,len,p);
 	return(ret);
 	}
-
-static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx,
+static int ssl3_handshake_mac(SSL *s, int md_nid,
 	     const char *sender, int len, unsigned char *p)
 	{
 	unsigned int ret;
 	int npad,n;
 	unsigned int i;
 	unsigned char md_buf[EVP_MAX_MD_SIZE];
-	EVP_MD_CTX ctx;
+	EVP_MD_CTX ctx,*d=NULL;
 
+	if (s->s3->handshake_buffer) 
+		if (!ssl3_digest_cached_records(s))
+			return 0;
+
+	/* Search for digest of specified type in the handshake_dgst
+	 * array*/
+	for (i=0;i<SSL_MAX_DIGEST;i++) 
+		{
+		  if (s->s3->handshake_dgst[i]&&EVP_MD_CTX_type(s->s3->handshake_dgst[i])==md_nid) 
+		  	{
+		  	d=s->s3->handshake_dgst[i];
+			break;
+			}
+		}
+	if (!d) {
+		SSLerr(SSL_F_SSL3_HANDSHAKE_MAC,SSL_R_NO_REQUIRED_DIGEST);
+		return 0;
+	}	
 	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);
-
+	EVP_MD_CTX_copy_ex(&ctx,d);
 	n=EVP_MD_CTX_size(&ctx);
-	npad=(48/n)*n;
+	if (n < 0)
+		return 0;
 
+	npad=(48/n)*n;
 	if (sender != NULL)
 		EVP_DigestUpdate(&ctx,sender,len);
 	EVP_DigestUpdate(&ctx,s->session->master_key,
@@ -582,15 +695,16 @@
 	return((int)ret);
 	}
 
-int ssl3_mac(SSL *ssl, unsigned char *md, int send)
+int n_ssl3_mac(SSL *ssl, unsigned char *md, int send)
 	{
 	SSL3_RECORD *rec;
 	unsigned char *mac_sec,*seq;
 	EVP_MD_CTX md_ctx;
-	const EVP_MD *hash;
+	const EVP_MD_CTX *hash;
 	unsigned char *p,rec_char;
 	unsigned int md_size;
 	int npad;
+	int t;
 
 	if (send)
 		{
@@ -607,13 +721,16 @@
 		hash=ssl->read_hash;
 		}
 
-	md_size=EVP_MD_size(hash);
+	t=EVP_MD_CTX_size(hash);
+	if (t < 0)
+		return -1;
+	md_size=t;
 	npad=(48/md_size)*md_size;
 
 	/* Chop the digest off the end :-) */
 	EVP_MD_CTX_init(&md_ctx);
 
-	EVP_DigestInit_ex(  &md_ctx,hash, NULL);
+	EVP_MD_CTX_copy_ex( &md_ctx,hash);
 	EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
 	EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad);
 	EVP_DigestUpdate(&md_ctx,seq,8);
@@ -625,7 +742,7 @@
 	EVP_DigestUpdate(&md_ctx,rec->input,rec->length);
 	EVP_DigestFinal_ex( &md_ctx,md,NULL);
 
-	EVP_DigestInit_ex(  &md_ctx,hash, NULL);
+	EVP_MD_CTX_copy_ex( &md_ctx,hash);
 	EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
 	EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad);
 	EVP_DigestUpdate(&md_ctx,md,md_size);
@@ -718,6 +835,12 @@
 	case SSL_AD_INTERNAL_ERROR:	return(SSL3_AD_HANDSHAKE_FAILURE);
 	case SSL_AD_USER_CANCELLED:	return(SSL3_AD_HANDSHAKE_FAILURE);
 	case SSL_AD_NO_RENEGOTIATION:	return(-1); /* Don't send it :-) */
+	case SSL_AD_UNSUPPORTED_EXTENSION: return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_CERTIFICATE_UNOBTAINABLE: return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_UNRECOGNIZED_NAME:	return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(SSL3_AD_HANDSHAKE_FAILURE);
+	case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
 	default:			return(-1);
 		}
 	}
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 8fa4ab0..d6b047c 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -121,16 +121,46 @@
  * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
  *
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 #include <stdio.h>
 #include <openssl/objects.h>
 #include "ssl_locl.h"
 #include "kssl_lcl.h"
+#ifndef OPENSSL_NO_TLSEXT
+#ifndef OPENSSL_NO_EC
+#include "../crypto/ec/ec_lcl.h"
+#endif /* OPENSSL_NO_EC */
+#endif /* OPENSSL_NO_TLSEXT */
 #include <openssl/md5.h>
 #ifndef OPENSSL_NO_DH
 #include <openssl/dh.h>
 #endif
-#include <openssl/pq_compat.h>
 
 const char ssl3_version_str[]="SSLv3" OPENSSL_VERSION_PTEXT;
 
@@ -138,217 +168,265 @@
 
 /* list of available SSLv3 ciphers (sorted by id) */
 OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
+
 /* The RSA ciphers */
 /* Cipher 01 */
 	{
 	1,
 	SSL3_TXT_RSA_NULL_MD5,
 	SSL3_CK_RSA_NULL_MD5,
-	SSL_kRSA|SSL_aRSA|SSL_eNULL |SSL_MD5|SSL_SSLV3,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_eNULL,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	0,
 	0,
-	0,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 02 */
 	{
 	1,
 	SSL3_TXT_RSA_NULL_SHA,
 	SSL3_CK_RSA_NULL_SHA,
-	SSL_kRSA|SSL_aRSA|SSL_eNULL |SSL_SHA1|SSL_SSLV3,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_eNULL,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	0,
 	0,
-	0,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 03 */
 	{
 	1,
 	SSL3_TXT_RSA_RC4_40_MD5,
 	SSL3_CK_RSA_RC4_40_MD5,
-	SSL_kRSA|SSL_aRSA|SSL_RC4  |SSL_MD5 |SSL_SSLV3,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 04 */
 	{
 	1,
 	SSL3_TXT_RSA_RC4_128_MD5,
 	SSL3_CK_RSA_RC4_128_MD5,
-	SSL_kRSA|SSL_aRSA|SSL_RC4  |SSL_MD5|SSL_SSLV3,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 05 */
 	{
 	1,
 	SSL3_TXT_RSA_RC4_128_SHA,
 	SSL3_CK_RSA_RC4_128_SHA,
-	SSL_kRSA|SSL_aRSA|SSL_RC4  |SSL_SHA1|SSL_SSLV3,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 06 */
 	{
 	1,
 	SSL3_TXT_RSA_RC2_40_MD5,
 	SSL3_CK_RSA_RC2_40_MD5,
-	SSL_kRSA|SSL_aRSA|SSL_RC2  |SSL_MD5 |SSL_SSLV3,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC2,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 07 */
 #ifndef OPENSSL_NO_IDEA
 	{
 	1,
 	SSL3_TXT_RSA_IDEA_128_SHA,
 	SSL3_CK_RSA_IDEA_128_SHA,
-	SSL_kRSA|SSL_aRSA|SSL_IDEA |SSL_SHA1|SSL_SSLV3,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_IDEA,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 #endif
+
 /* Cipher 08 */
 	{
 	1,
 	SSL3_TXT_RSA_DES_40_CBC_SHA,
 	SSL3_CK_RSA_DES_40_CBC_SHA,
-	SSL_kRSA|SSL_aRSA|SSL_DES|SSL_SHA1|SSL_SSLV3,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 09 */
 	{
 	1,
 	SSL3_TXT_RSA_DES_64_CBC_SHA,
 	SSL3_CK_RSA_DES_64_CBC_SHA,
-	SSL_kRSA|SSL_aRSA|SSL_DES  |SSL_SHA1|SSL_SSLV3,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_LOW,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	56,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 0A */
 	{
 	1,
 	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_kRSA,
+	SSL_aRSA,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	168,
 	168,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* The DH ciphers */
 /* Cipher 0B */
 	{
 	0,
 	SSL3_TXT_DH_DSS_DES_40_CBC_SHA,
 	SSL3_CK_DH_DSS_DES_40_CBC_SHA,
-	SSL_kDHd |SSL_aDH|SSL_DES|SSL_SHA1|SSL_SSLV3,
+	SSL_kDHd,
+	SSL_aDH,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 0C */
 	{
-	0,
+	0, /* not implemented (non-ephemeral DH) */
 	SSL3_TXT_DH_DSS_DES_64_CBC_SHA,
 	SSL3_CK_DH_DSS_DES_64_CBC_SHA,
-	SSL_kDHd |SSL_aDH|SSL_DES  |SSL_SHA1|SSL_SSLV3,
+	SSL_kDHd,
+	SSL_aDH,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_LOW,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	56,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 0D */
 	{
-	0,
+	0, /* not implemented (non-ephemeral DH) */
 	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_kDHd,
+	SSL_aDH,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	168,
 	168,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 0E */
 	{
-	0,
+	0, /* not implemented (non-ephemeral DH) */
 	SSL3_TXT_DH_RSA_DES_40_CBC_SHA,
 	SSL3_CK_DH_RSA_DES_40_CBC_SHA,
-	SSL_kDHr |SSL_aDH|SSL_DES|SSL_SHA1|SSL_SSLV3,
+	SSL_kDHr,
+	SSL_aDH,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 0F */
 	{
-	0,
+	0, /* not implemented (non-ephemeral DH) */
 	SSL3_TXT_DH_RSA_DES_64_CBC_SHA,
 	SSL3_CK_DH_RSA_DES_64_CBC_SHA,
-	SSL_kDHr |SSL_aDH|SSL_DES  |SSL_SHA1|SSL_SSLV3,
+	SSL_kDHr,
+	SSL_aDH,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_LOW,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	56,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 10 */
 	{
-	0,
+	0, /* not implemented (non-ephemeral DH) */
 	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_kDHr,
+	SSL_aDH,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	168,
 	168,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* The Ephemeral DH ciphers */
@@ -357,158 +435,193 @@
 	1,
 	SSL3_TXT_EDH_DSS_DES_40_CBC_SHA,
 	SSL3_CK_EDH_DSS_DES_40_CBC_SHA,
-	SSL_kEDH|SSL_aDSS|SSL_DES|SSL_SHA1|SSL_SSLV3,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 12 */
 	{
 	1,
 	SSL3_TXT_EDH_DSS_DES_64_CBC_SHA,
 	SSL3_CK_EDH_DSS_DES_64_CBC_SHA,
-	SSL_kEDH|SSL_aDSS|SSL_DES  |SSL_SHA1|SSL_SSLV3,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_LOW,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	56,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 13 */
 	{
 	1,
 	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_kEDH,
+	SSL_aDSS,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	168,
 	168,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 14 */
 	{
 	1,
 	SSL3_TXT_EDH_RSA_DES_40_CBC_SHA,
 	SSL3_CK_EDH_RSA_DES_40_CBC_SHA,
-	SSL_kEDH|SSL_aRSA|SSL_DES|SSL_SHA1|SSL_SSLV3,
+	SSL_kEDH,
+	SSL_aRSA,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 15 */
 	{
 	1,
 	SSL3_TXT_EDH_RSA_DES_64_CBC_SHA,
 	SSL3_CK_EDH_RSA_DES_64_CBC_SHA,
-	SSL_kEDH|SSL_aRSA|SSL_DES  |SSL_SHA1|SSL_SSLV3,
+	SSL_kEDH,
+	SSL_aRSA,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_LOW,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	56,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 16 */
 	{
 	1,
 	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_kEDH,
+	SSL_aRSA,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	168,
 	168,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 17 */
 	{
 	1,
 	SSL3_TXT_ADH_RC4_40_MD5,
 	SSL3_CK_ADH_RC4_40_MD5,
-	SSL_kEDH |SSL_aNULL|SSL_RC4  |SSL_MD5 |SSL_SSLV3,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 18 */
 	{
 	1,
 	SSL3_TXT_ADH_RC4_128_MD5,
 	SSL3_CK_ADH_RC4_128_MD5,
-	SSL_kEDH |SSL_aNULL|SSL_RC4  |SSL_MD5 |SSL_SSLV3,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 19 */
 	{
 	1,
 	SSL3_TXT_ADH_DES_40_CBC_SHA,
 	SSL3_CK_ADH_DES_40_CBC_SHA,
-	SSL_kEDH |SSL_aNULL|SSL_DES|SSL_SHA1|SSL_SSLV3,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 1A */
 	{
 	1,
 	SSL3_TXT_ADH_DES_64_CBC_SHA,
 	SSL3_CK_ADH_DES_64_CBC_SHA,
-	SSL_kEDH |SSL_aNULL|SSL_DES  |SSL_SHA1|SSL_SSLV3,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_LOW,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	56,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 1B */
 	{
 	1,
 	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_kEDH,
+	SSL_aNULL,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	168,
 	168,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
-/* Fortezza */
+/* Fortezza ciphersuite from SSL 3.0 spec */
+#if 0
 /* Cipher 1C */
 	{
 	0,
 	SSL3_TXT_FZA_DMS_NULL_SHA,
 	SSL3_CK_FZA_DMS_NULL_SHA,
-	SSL_kFZA|SSL_aFZA |SSL_eNULL |SSL_SHA1|SSL_SSLV3,
+	SSL_kFZA,
+	SSL_aFZA,
+	SSL_eNULL,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	0,
 	0,
-	0,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 1D */
@@ -516,45 +629,50 @@
 	0,
 	SSL3_TXT_FZA_DMS_FZA_SHA,
 	SSL3_CK_FZA_DMS_FZA_SHA,
-	SSL_kFZA|SSL_aFZA |SSL_eFZA |SSL_SHA1|SSL_SSLV3,
+	SSL_kFZA,
+	SSL_aFZA,
+	SSL_eFZA,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	0,
 	0,
-	0,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
-#if 0
 /* Cipher 1E */
 	{
 	0,
 	SSL3_TXT_FZA_DMS_RC4_SHA,
 	SSL3_CK_FZA_DMS_RC4_SHA,
-	SSL_kFZA|SSL_aFZA |SSL_RC4  |SSL_SHA1|SSL_SSLV3,
+	SSL_kFZA,
+	SSL_aFZA,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 #endif
 
 #ifndef OPENSSL_NO_KRB5
-/* The Kerberos ciphers */
+/* The Kerberos ciphers*/
 /* Cipher 1E */
 	{
 	1,
 	SSL3_TXT_KRB5_DES_64_CBC_SHA,
 	SSL3_CK_KRB5_DES_64_CBC_SHA,
-	SSL_kKRB5|SSL_aKRB5|  SSL_DES|SSL_SHA1   |SSL_SSLV3,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_LOW,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	56,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 1F */
@@ -562,13 +680,15 @@
 	1,
 	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_kKRB5,
+	SSL_aKRB5,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	168,
 	168,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 20 */
@@ -576,13 +696,15 @@
 	1,
 	SSL3_TXT_KRB5_RC4_128_SHA,
 	SSL3_CK_KRB5_RC4_128_SHA,
-	SSL_kKRB5|SSL_aKRB5|  SSL_RC4|SSL_SHA1  |SSL_SSLV3,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 21 */
@@ -590,13 +712,15 @@
 	1,
 	SSL3_TXT_KRB5_IDEA_128_CBC_SHA,
 	SSL3_CK_KRB5_IDEA_128_CBC_SHA,
-	SSL_kKRB5|SSL_aKRB5|  SSL_IDEA|SSL_SHA1  |SSL_SSLV3,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_IDEA,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 22 */
@@ -604,13 +728,15 @@
 	1,
 	SSL3_TXT_KRB5_DES_64_CBC_MD5,
 	SSL3_CK_KRB5_DES_64_CBC_MD5,
-	SSL_kKRB5|SSL_aKRB5|  SSL_DES|SSL_MD5    |SSL_SSLV3,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_DES,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_LOW,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	56,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 23 */
@@ -618,13 +744,15 @@
 	1,
 	SSL3_TXT_KRB5_DES_192_CBC3_MD5,
 	SSL3_CK_KRB5_DES_192_CBC3_MD5,
-	SSL_kKRB5|SSL_aKRB5|  SSL_3DES|SSL_MD5   |SSL_SSLV3,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_3DES,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	168,
 	168,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 24 */
@@ -632,13 +760,15 @@
 	1,
 	SSL3_TXT_KRB5_RC4_128_MD5,
 	SSL3_CK_KRB5_RC4_128_MD5,
-	SSL_kKRB5|SSL_aKRB5|  SSL_RC4|SSL_MD5  |SSL_SSLV3,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 25 */
@@ -646,13 +776,15 @@
 	1,
 	SSL3_TXT_KRB5_IDEA_128_CBC_MD5,
 	SSL3_CK_KRB5_IDEA_128_CBC_MD5,
-	SSL_kKRB5|SSL_aKRB5|  SSL_IDEA|SSL_MD5  |SSL_SSLV3,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_IDEA,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 26 */
@@ -660,13 +792,15 @@
 	1,
 	SSL3_TXT_KRB5_DES_40_CBC_SHA,
 	SSL3_CK_KRB5_DES_40_CBC_SHA,
-	SSL_kKRB5|SSL_aKRB5|  SSL_DES|SSL_SHA1   |SSL_SSLV3,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 27 */
@@ -674,13 +808,15 @@
 	1,
 	SSL3_TXT_KRB5_RC2_40_CBC_SHA,
 	SSL3_CK_KRB5_RC2_40_CBC_SHA,
-	SSL_kKRB5|SSL_aKRB5|  SSL_RC2|SSL_SHA1   |SSL_SSLV3,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_RC2,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 28 */
@@ -688,13 +824,15 @@
 	1,
 	SSL3_TXT_KRB5_RC4_40_SHA,
 	SSL3_CK_KRB5_RC4_40_SHA,
-	SSL_kKRB5|SSL_aKRB5|  SSL_RC4|SSL_SHA1   |SSL_SSLV3,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 29 */
@@ -702,13 +840,15 @@
 	1,
 	SSL3_TXT_KRB5_DES_40_CBC_MD5,
 	SSL3_CK_KRB5_DES_40_CBC_MD5,
-	SSL_kKRB5|SSL_aKRB5|  SSL_DES|SSL_MD5    |SSL_SSLV3,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_DES,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 2A */
@@ -716,13 +856,15 @@
 	1,
 	SSL3_TXT_KRB5_RC2_40_CBC_MD5,
 	SSL3_CK_KRB5_RC2_40_CBC_MD5,
-	SSL_kKRB5|SSL_aKRB5|  SSL_RC2|SSL_MD5    |SSL_SSLV3,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_RC2,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 2B */
@@ -730,13 +872,15 @@
 	1,
 	SSL3_TXT_KRB5_RC4_40_MD5,
 	SSL3_CK_KRB5_RC4_40_MD5,
-	SSL_kKRB5|SSL_aKRB5|  SSL_RC4|SSL_MD5    |SSL_SSLV3,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 #endif	/* OPENSSL_NO_KRB5 */
 
@@ -746,78 +890,90 @@
 	1,
 	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_kRSA,
+	SSL_aRSA,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 /* Cipher 30 */
 	{
 	0,
 	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_kDHd,
+	SSL_aDH,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 /* Cipher 31 */
 	{
 	0,
 	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_kDHr,
+	SSL_aDH,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 /* Cipher 32 */
 	{
 	1,
 	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_kEDH,
+	SSL_aDSS,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 /* Cipher 33 */
 	{
 	1,
 	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_kEDH,
+	SSL_aRSA,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 /* Cipher 34 */
 	{
 	1,
 	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_kEDH,
+	SSL_aNULL,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 35 */
@@ -825,78 +981,94 @@
 	1,
 	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_kRSA,
+	SSL_aRSA,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 /* Cipher 36 */
 	{
 	0,
 	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_kDHd,
+	SSL_aDH,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 37 */
 	{
-	0,
+	0, /* not implemented (non-ephemeral DH) */
 	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_kDHr,
+	SSL_aDH,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 38 */
 	{
 	1,
 	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_kEDH,
+	SSL_aDSS,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 39 */
 	{
 	1,
 	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_kEDH,
+	SSL_aRSA,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 	/* Cipher 3A */
 	{
 	1,
 	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_kEDH,
+	SSL_aNULL,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 #ifndef OPENSSL_NO_CAMELLIA
@@ -907,78 +1079,95 @@
 	1,
 	TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA,
 	TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA,
-	SSL_kRSA|SSL_aRSA|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_CAMELLIA128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
+
 	/* Cipher 42 */
 	{
 	0, /* not implemented (non-ephemeral DH) */
 	TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA,
 	TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA,
-	SSL_kDHd|SSL_aDH|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kDHd,
+	SSL_aDH,
+	SSL_CAMELLIA128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
+
 	/* Cipher 43 */
 	{
 	0, /* not implemented (non-ephemeral DH) */
 	TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA,
 	TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA,
-	SSL_kDHr|SSL_aDH|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kDHr,
+	SSL_aDH,
+	SSL_CAMELLIA128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
+
 	/* Cipher 44 */
 	{
 	1,
 	TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
 	TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
-	SSL_kEDH|SSL_aDSS|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_CAMELLIA128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
+
 	/* Cipher 45 */
 	{
 	1,
 	TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
 	TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
-	SSL_kEDH|SSL_aRSA|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aRSA,
+	SSL_CAMELLIA128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
+
 	/* Cipher 46 */
 	{
 	1,
 	TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA,
 	TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA,
-	SSL_kEDH|SSL_aNULL|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_CAMELLIA128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
 #endif /* OPENSSL_NO_CAMELLIA */
 
@@ -986,98 +1175,174 @@
 	/* New TLS Export CipherSuites from expired ID */
 #if 0
 	/* Cipher 60 */
-	    {
-	    1,
-	    TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5,
-	    TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5,
-	    SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_MD5|SSL_TLSV1,
-	    SSL_EXPORT|SSL_EXP56,
-	    0,
-	    56,
-	    128,
-	    SSL_ALL_CIPHERS,
-	    SSL_ALL_STRENGTHS,
-	    },
+	{
+	1,
+	TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5,
+	TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_TLSV1,
+	SSL_EXPORT|SSL_EXP56,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	128,
+	},
+
 	/* Cipher 61 */
-	    {
-	    1,
-	    TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5,
-	    TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5,
-	    SSL_kRSA|SSL_aRSA|SSL_RC2|SSL_MD5|SSL_TLSV1,
-	    SSL_EXPORT|SSL_EXP56,
-	    0,
-	    56,
-	    128,
-	    SSL_ALL_CIPHERS,
-	    SSL_ALL_STRENGTHS,
-	    },
+	{
+	1,
+	TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5,
+	TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC2,
+	SSL_MD5,
+	SSL_TLSV1,
+	SSL_EXPORT|SSL_EXP56,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	128,
+	},
 #endif
+
 	/* Cipher 62 */
-	    {
-	    1,
-	    TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA,
-	    TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA,
-	    SSL_kRSA|SSL_aRSA|SSL_DES|SSL_SHA|SSL_TLSV1,
-	    SSL_EXPORT|SSL_EXP56,
-	    0,
-	    56,
-	    56,
-	    SSL_ALL_CIPHERS,
-	    SSL_ALL_STRENGTHS,
-	    },
+	{
+	1,
+	TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA,
+	TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_EXPORT|SSL_EXP56,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	56,
+	},
+
 	/* Cipher 63 */
-	    {
-	    1,
-	    TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
-	    TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
-	    SSL_kEDH|SSL_aDSS|SSL_DES|SSL_SHA|SSL_TLSV1,
-	    SSL_EXPORT|SSL_EXP56,
-	    0,
-	    56,
-	    56,
-	    SSL_ALL_CIPHERS,
-	    SSL_ALL_STRENGTHS,
-	    },
+	{
+	1,
+	TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
+	TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_EXPORT|SSL_EXP56,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	56,
+	},
+
 	/* Cipher 64 */
-	    {
-	    1,
-	    TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA,
-	    TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA,
-	    SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_SHA|SSL_TLSV1,
-	    SSL_EXPORT|SSL_EXP56,
-	    0,
-	    56,
-	    128,
-	    SSL_ALL_CIPHERS,
-	    SSL_ALL_STRENGTHS,
-	    },
+	{
+	1,
+	TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA,
+	TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_EXPORT|SSL_EXP56,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	128,
+	},
+
 	/* Cipher 65 */
-	    {
-	    1,
-	    TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
-	    TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
-	    SSL_kEDH|SSL_aDSS|SSL_RC4|SSL_SHA|SSL_TLSV1,
-	    SSL_EXPORT|SSL_EXP56,
-	    0,
-	    56,
-	    128,
-	    SSL_ALL_CIPHERS,
-	    SSL_ALL_STRENGTHS,
-	    },
+	{
+	1,
+	TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
+	TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_EXPORT|SSL_EXP56,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	56,
+	128,
+	},
+
 	/* Cipher 66 */
-	    {
-	    1,
-	    TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA,
-	    TLS1_CK_DHE_DSS_WITH_RC4_128_SHA,
-	    SSL_kEDH|SSL_aDSS|SSL_RC4|SSL_SHA|SSL_TLSV1,
-	    SSL_NOT_EXP|SSL_MEDIUM,
-	    0,
-	    128,
-	    128,
-	    SSL_ALL_CIPHERS,
-	    SSL_ALL_STRENGTHS
-	    },
+	{
+	1,
+	TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA,
+	TLS1_CK_DHE_DSS_WITH_RC4_128_SHA,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
 #endif
+	{
+	1,
+	"GOST94-GOST89-GOST89",
+	0x3000080,
+	SSL_kGOST,
+	SSL_aGOST94,
+	SSL_eGOST2814789CNT,
+	SSL_GOST89MAC,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94|TLS1_STREAM_MAC,
+	256,
+	256
+	},
+	{
+	1,
+	"GOST2001-GOST89-GOST89",
+	0x3000081,
+	SSL_kGOST,
+	SSL_aGOST01,
+	SSL_eGOST2814789CNT,
+	SSL_GOST89MAC,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94|TLS1_STREAM_MAC,
+	256,
+	256
+	},
+	{
+	1,
+	"GOST94-NULL-GOST94",
+	0x3000082,
+	SSL_kGOST,
+	SSL_aGOST94,
+	SSL_eNULL,
+	SSL_GOST94,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94,
+	0,
+	0
+	},
+	{
+	1,
+	"GOST2001-NULL-GOST94",
+	0x3000083,
+	SSL_kGOST,
+	SSL_aGOST01,
+	SSL_eNULL,
+	SSL_GOST94,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94,
+	0,
+	0
+	},
 
 #ifndef OPENSSL_NO_CAMELLIA
 	/* Camellia ciphersuites from RFC4132 (256-bit portion) */
@@ -1087,81 +1352,163 @@
 	1,
 	TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA,
 	TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA,
-	SSL_kRSA|SSL_aRSA|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_CAMELLIA256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
 	/* Cipher 85 */
 	{
 	0, /* not implemented (non-ephemeral DH) */
 	TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA,
 	TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA,
-	SSL_kDHd|SSL_aDH|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kDHd,
+	SSL_aDH,
+	SSL_CAMELLIA256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
+
 	/* Cipher 86 */
 	{
 	0, /* not implemented (non-ephemeral DH) */
 	TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA,
 	TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA,
-	SSL_kDHr|SSL_aDH|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kDHr,
+	SSL_aDH,
+	SSL_CAMELLIA256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
+
 	/* Cipher 87 */
 	{
 	1,
 	TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
 	TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
-	SSL_kEDH|SSL_aDSS|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_CAMELLIA256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
+
 	/* Cipher 88 */
 	{
 	1,
 	TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
 	TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
-	SSL_kEDH|SSL_aRSA|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aRSA,
+	SSL_CAMELLIA256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
+
 	/* Cipher 89 */
 	{
 	1,
 	TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA,
 	TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA,
-	SSL_kEDH|SSL_aNULL|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_CAMELLIA256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
 #endif /* OPENSSL_NO_CAMELLIA */
 
+#ifndef OPENSSL_NO_PSK
+	/* Cipher 8A */
+	{
+	1,
+	TLS1_TXT_PSK_WITH_RC4_128_SHA,
+	TLS1_CK_PSK_WITH_RC4_128_SHA,
+	SSL_kPSK,
+	SSL_aPSK,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher 8B */
+	{
+	1,
+	TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA,
+	TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA,
+	SSL_kPSK,
+	SSL_aPSK,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
+
+	/* Cipher 8C */
+	{
+	1,
+	TLS1_TXT_PSK_WITH_AES_128_CBC_SHA,
+	TLS1_CK_PSK_WITH_AES_128_CBC_SHA,
+	SSL_kPSK,
+	SSL_aPSK,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher 8D */
+	{
+	1,
+	TLS1_TXT_PSK_WITH_AES_256_CBC_SHA,
+	TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
+	SSL_kPSK,
+	SSL_aPSK,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+#endif  /* OPENSSL_NO_PSK */
+
 #ifndef OPENSSL_NO_SEED
 	/* SEED ciphersuites from RFC4162 */
 
@@ -1170,13 +1517,15 @@
 	1,
 	TLS1_TXT_RSA_WITH_SEED_SHA,
 	TLS1_CK_RSA_WITH_SEED_SHA,
-	SSL_kRSA|SSL_aRSA|SSL_SEED|SSL_SHA1|SSL_TLSV1,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_SEED,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 	/* Cipher 97 */
@@ -1184,13 +1533,15 @@
 	0, /* not implemented (non-ephemeral DH) */
 	TLS1_TXT_DH_DSS_WITH_SEED_SHA,
 	TLS1_CK_DH_DSS_WITH_SEED_SHA,
-	SSL_kDHd|SSL_aDH|SSL_SEED|SSL_SHA1|SSL_TLSV1,
+	SSL_kDHd,
+	SSL_aDH,
+	SSL_SEED,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 	/* Cipher 98 */
@@ -1198,13 +1549,15 @@
 	0, /* not implemented (non-ephemeral DH) */
 	TLS1_TXT_DH_RSA_WITH_SEED_SHA,
 	TLS1_CK_DH_RSA_WITH_SEED_SHA,
-	SSL_kDHr|SSL_aDH|SSL_SEED|SSL_SHA1|SSL_TLSV1,
+	SSL_kDHr,
+	SSL_aDH,
+	SSL_SEED,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 	/* Cipher 99 */
@@ -1212,13 +1565,15 @@
 	1,
 	TLS1_TXT_DHE_DSS_WITH_SEED_SHA,
 	TLS1_CK_DHE_DSS_WITH_SEED_SHA,
-	SSL_kEDH|SSL_aDSS|SSL_SEED|SSL_SHA1|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_SEED,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 	/* Cipher 9A */
@@ -1226,13 +1581,15 @@
 	1,
 	TLS1_TXT_DHE_RSA_WITH_SEED_SHA,
 	TLS1_CK_DHE_RSA_WITH_SEED_SHA,
-	SSL_kEDH|SSL_aRSA|SSL_SEED|SSL_SHA1|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aRSA,
+	SSL_SEED,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 	/* Cipher 9B */
@@ -1240,376 +1597,487 @@
 	1,
 	TLS1_TXT_ADH_WITH_SEED_SHA,
 	TLS1_CK_ADH_WITH_SEED_SHA,
-	SSL_kEDH|SSL_aNULL|SSL_SEED|SSL_SHA1|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_SEED,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 #endif /* OPENSSL_NO_SEED */
 
 #ifndef OPENSSL_NO_ECDH
 	/* Cipher C001 */
-	    {
-            1,
-            TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA,
-            TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA,
-            SSL_kECDH|SSL_aECDSA|SSL_eNULL|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            0,
-            0,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA,
+	TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA,
+	SSL_kECDHe,
+	SSL_aECDH,
+	SSL_eNULL,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	0,
+	0,
+	},
 
 	/* Cipher C002 */
-	    {
-            1,
-            TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA,
-            TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA,
-            SSL_kECDH|SSL_aECDSA|SSL_RC4|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA,
+	TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA,
+	SSL_kECDHe,
+	SSL_aECDH,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
 
 	/* Cipher C003 */
-	    {
-            1,
-            TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA,
-            TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA,
-            SSL_kECDH|SSL_aECDSA|SSL_3DES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            168,
-            168,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA,
+	TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA,
+	SSL_kECDHe,
+	SSL_aECDH,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
 
 	/* Cipher C004 */
-	    {
-            1,
-            TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
-            TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
-            SSL_kECDH|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
+	TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
+	SSL_kECDHe,
+	SSL_aECDH,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
 
 	/* Cipher C005 */
-	    {
-            1,
-            TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
-            TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
-            SSL_kECDH|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            256,
-            256,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
+	TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
+	SSL_kECDHe,
+	SSL_aECDH,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
 
 	/* Cipher C006 */
-	    {
-            1,
-            TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA,
-            TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA,
-            SSL_kECDHE|SSL_aECDSA|SSL_eNULL|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            0,
-            0,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA,
+	TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA,
+	SSL_kEECDH,
+	SSL_aECDSA,
+	SSL_eNULL,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	0,
+	0,
+	},
 
 	/* Cipher C007 */
-	    {
-            1,
-            TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA,
-            TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA,
-            SSL_kECDHE|SSL_aECDSA|SSL_RC4|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA,
+	TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA,
+	SSL_kEECDH,
+	SSL_aECDSA,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
 
 	/* Cipher C008 */
-	    {
-            1,
-            TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA,
-            TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA,
-            SSL_kECDHE|SSL_aECDSA|SSL_3DES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            168,
-            168,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA,
+	TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA,
+	SSL_kEECDH,
+	SSL_aECDSA,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
 
 	/* Cipher C009 */
-	    {
-            1,
-            TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
-            TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
-            SSL_kECDHE|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+	TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+	SSL_kEECDH,
+	SSL_aECDSA,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
 
 	/* Cipher C00A */
-	    {
-            1,
-            TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
-            TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
-            SSL_kECDHE|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            256,
-            256,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+	TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+	SSL_kEECDH,
+	SSL_aECDSA,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
 
 	/* Cipher C00B */
-	    {
-            1,
-            TLS1_TXT_ECDH_RSA_WITH_NULL_SHA,
-            TLS1_CK_ECDH_RSA_WITH_NULL_SHA,
-            SSL_kECDH|SSL_aRSA|SSL_eNULL|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            0,
-            0,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDH_RSA_WITH_NULL_SHA,
+	TLS1_CK_ECDH_RSA_WITH_NULL_SHA,
+	SSL_kECDHr,
+	SSL_aECDH,
+	SSL_eNULL,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	0,
+	0,
+	},
 
 	/* Cipher C00C */
-	    {
-            1,
-            TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA,
-            TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA,
-            SSL_kECDH|SSL_aRSA|SSL_RC4|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA,
+	TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA,
+	SSL_kECDHr,
+	SSL_aECDH,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
 
 	/* Cipher C00D */
-	    {
-            1,
-            TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA,
-            TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA,
-            SSL_kECDH|SSL_aRSA|SSL_3DES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            168,
-            168,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA,
+	TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA,
+	SSL_kECDHr,
+	SSL_aECDH,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
 
 	/* Cipher C00E */
-	    {
-            1,
-            TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA,
-            TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA,
-            SSL_kECDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA,
+	TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA,
+	SSL_kECDHr,
+	SSL_aECDH,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
 
 	/* Cipher C00F */
-	    {
-            1,
-            TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA,
-            TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA,
-            SSL_kECDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            256,
-            256,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA,
+	TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA,
+	SSL_kECDHr,
+	SSL_aECDH,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
 
 	/* Cipher C010 */
-	    {
-            1,
-            TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA,
-            TLS1_CK_ECDHE_RSA_WITH_NULL_SHA,
-            SSL_kECDHE|SSL_aRSA|SSL_eNULL|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            0,
-            0,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA,
+	TLS1_CK_ECDHE_RSA_WITH_NULL_SHA,
+	SSL_kEECDH,
+	SSL_aRSA,
+	SSL_eNULL,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	0,
+	0,
+	},
 
 	/* Cipher C011 */
-	    {
-            1,
-            TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA,
-            TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA,
-            SSL_kECDHE|SSL_aRSA|SSL_RC4|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA,
+	TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA,
+	SSL_kEECDH,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
 
 	/* Cipher C012 */
-	    {
-            1,
-            TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA,
-            TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA,
-            SSL_kECDHE|SSL_aRSA|SSL_3DES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            168,
-            168,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA,
+	TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA,
+	SSL_kEECDH,
+	SSL_aRSA,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
 
 	/* Cipher C013 */
-	    {
-            1,
-            TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA,
-            TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
-            SSL_kECDHE|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+	TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+	SSL_kEECDH,
+	SSL_aRSA,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
 
 	/* Cipher C014 */
-	    {
-            1,
-            TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA,
-            TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
-            SSL_kECDHE|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            256,
-            256,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+	TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+	SSL_kEECDH,
+	SSL_aRSA,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
 
 	/* Cipher C015 */
-            {
-            1,
-            TLS1_TXT_ECDH_anon_WITH_NULL_SHA,
-            TLS1_CK_ECDH_anon_WITH_NULL_SHA,
-            SSL_kECDHE|SSL_aNULL|SSL_eNULL|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            0,
-            0,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-	    },
+	{
+	1,
+	TLS1_TXT_ECDH_anon_WITH_NULL_SHA,
+	TLS1_CK_ECDH_anon_WITH_NULL_SHA,
+	SSL_kEECDH,
+	SSL_aNULL,
+	SSL_eNULL,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	0,
+	0,
+	},
 
 	/* Cipher C016 */
-            {
-            1,
-            TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA,
-            TLS1_CK_ECDH_anon_WITH_RC4_128_SHA,
-            SSL_kECDHE|SSL_aNULL|SSL_RC4|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-	    },
+	{
+	1,
+	TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA,
+	TLS1_CK_ECDH_anon_WITH_RC4_128_SHA,
+	SSL_kEECDH,
+	SSL_aNULL,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_MEDIUM,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
 
 	/* Cipher C017 */
-	    {
-            1,
-            TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA,
-            TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA,
-            SSL_kECDHE|SSL_aNULL|SSL_3DES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            168,
-            168,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA,
+	TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA,
+	SSL_kEECDH,
+	SSL_aNULL,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
 
 	/* Cipher C018 */
-	    {
-            1,
-            TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA,
-            TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA,
-            SSL_kECDHE|SSL_aNULL|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA,
+	TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA,
+	SSL_kEECDH,
+	SSL_aNULL,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
 
 	/* Cipher C019 */
-	    {
-            1,
-            TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA,
-            TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA,
-            SSL_kECDHE|SSL_aNULL|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            256,
-            256,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	1,
+	TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA,
+	TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA,
+	SSL_kEECDH,
+	SSL_aNULL,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
 #endif	/* OPENSSL_NO_ECDH */
 
+#ifdef TEMP_GOST_TLS
+/* Cipher FF00 */
+	{
+	1,
+	"GOST-MD5",
+	0x0300ff00,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_eGOST2814789CNT,
+	SSL_MD5,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+	{
+	1,
+	"GOST-GOST94",
+	0x0300ff01,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_eGOST2814789CNT,
+	SSL_GOST94,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256
+	},
+	{
+	1,
+	"GOST-GOST89MAC",
+	0x0300ff02,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_eGOST2814789CNT,
+	SSL_GOST89MAC,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256
+	},
+	{
+	1,
+	"GOST-GOST89STREAM",
+	0x0300ff03,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_eGOST2814789CNT,
+	SSL_GOST89MAC,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF|TLS1_STREAM_MAC,
+	256,
+	256
+	},
+#endif
 
 /* end of list */
 	};
 
 SSL3_ENC_METHOD SSLv3_enc_data={
 	ssl3_enc,
-	ssl3_mac,
+	n_ssl3_mac,
 	ssl3_setup_key_block,
 	ssl3_generate_master_secret,
 	ssl3_change_cipher_state,
@@ -1628,17 +2096,12 @@
 	return(60*60*2);
 	}
 
-IMPLEMENT_ssl3_meth_func(sslv3_base_method,
-			ssl_undefined_function,
-			ssl_undefined_function,
-			ssl_bad_method)
-
 int ssl3_num_ciphers(void)
 	{
 	return(SSL3_NUM_CIPHERS);
 	}
 
-SSL_CIPHER *ssl3_get_cipher(unsigned int u)
+const SSL_CIPHER *ssl3_get_cipher(unsigned int u)
 	{
 	if (u < SSL3_NUM_CIPHERS)
 		return(&(ssl3_ciphers[SSL3_NUM_CIPHERS-1-u]));
@@ -1660,10 +2123,8 @@
 
 	if ((s3=OPENSSL_malloc(sizeof *s3)) == NULL) goto err;
 	memset(s3,0,sizeof *s3);
-	EVP_MD_CTX_init(&s3->finish_dgst1);
-	EVP_MD_CTX_init(&s3->finish_dgst2);
-	pq_64bit_init(&(s3->rrec.seq_num));
-	pq_64bit_init(&(s3->wrec.seq_num));
+	memset(s3->rrec.seq_num,0,sizeof(s3->rrec.seq_num));
+	memset(s3->wrec.seq_num,0,sizeof(s3->wrec.seq_num));
 
 	s->s3=s3;
 
@@ -1678,11 +2139,18 @@
 	if(s == NULL)
 	    return;
 
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	if (s->s3->client_opaque_prf_input != NULL)
+		OPENSSL_free(s->s3->client_opaque_prf_input);
+	if (s->s3->server_opaque_prf_input != NULL)
+		OPENSSL_free(s->s3->server_opaque_prf_input);
+#endif
+
 	ssl3_cleanup_key_block(s);
 	if (s->s3->rbuf.buf != NULL)
-		OPENSSL_free(s->s3->rbuf.buf);
+		ssl3_release_read_buffer(s);
 	if (s->s3->wbuf.buf != NULL)
-		OPENSSL_free(s->s3->wbuf.buf);
+		ssl3_release_write_buffer(s);
 	if (s->s3->rrec.comp != NULL)
 		OPENSSL_free(s->s3->rrec.comp);
 #ifndef OPENSSL_NO_DH
@@ -1696,11 +2164,10 @@
 
 	if (s->s3->tmp.ca_names != NULL)
 		sk_X509_NAME_pop_free(s->s3->tmp.ca_names,X509_NAME_free);
-	EVP_MD_CTX_cleanup(&s->s3->finish_dgst1);
-	EVP_MD_CTX_cleanup(&s->s3->finish_dgst2);
-	pq_64bit_free(&(s->s3->rrec.seq_num));
-	pq_64bit_free(&(s->s3->wrec.seq_num));
-
+	if (s->s3->handshake_buffer) {
+		BIO_free(s->s3->handshake_buffer);
+	}
+	if (s->s3->handshake_dgst) ssl3_free_digest_list(s);
 	OPENSSL_cleanse(s->s3,sizeof *s->s3);
 	OPENSSL_free(s->s3);
 	s->s3=NULL;
@@ -1711,6 +2178,15 @@
 	unsigned char *rp,*wp;
 	size_t rlen, wlen;
 
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	if (s->s3->client_opaque_prf_input != NULL)
+		OPENSSL_free(s->s3->client_opaque_prf_input);
+	s->s3->client_opaque_prf_input = NULL;
+	if (s->s3->server_opaque_prf_input != NULL)
+		OPENSSL_free(s->s3->server_opaque_prf_input);
+	s->s3->server_opaque_prf_input = NULL;
+#endif
+
 	ssl3_cleanup_key_block(s);
 	if (s->s3->tmp.ca_names != NULL)
 		sk_X509_NAME_pop_free(s->s3->tmp.ca_names,X509_NAME_free);
@@ -1733,10 +2209,13 @@
 	wp = s->s3->wbuf.buf;
 	rlen = s->s3->rbuf.len;
  	wlen = s->s3->wbuf.len;
-
-	EVP_MD_CTX_cleanup(&s->s3->finish_dgst1);
-	EVP_MD_CTX_cleanup(&s->s3->finish_dgst2);
-
+	if (s->s3->handshake_buffer) {
+		BIO_free(s->s3->handshake_buffer);
+		s->s3->handshake_buffer = NULL;
+	}
+	if (s->s3->handshake_dgst) {
+		ssl3_free_digest_list(s);
+	}	
 	memset(s->s3,0,sizeof *s->s3);
 	s->s3->rbuf.buf = rp;
 	s->s3->wbuf.buf = wp;
@@ -1936,7 +2415,31 @@
 		s->tlsext_debug_arg=parg;
 		ret = 1;
 		break;
-  
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT:
+		if (larg > 12288) /* actual internal limit is 2^16 for the complete hello message
+		                   * (including the cert chain and everything) */
+			{
+			SSLerr(SSL_F_SSL3_CTRL, SSL_R_OPAQUE_PRF_INPUT_TOO_LONG);
+			break;
+			}
+		if (s->tlsext_opaque_prf_input != NULL)
+			OPENSSL_free(s->tlsext_opaque_prf_input);
+		if ((size_t)larg == 0)
+			s->tlsext_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
+		else
+			s->tlsext_opaque_prf_input = BUF_memdup(parg, (size_t)larg);
+		if (s->tlsext_opaque_prf_input != NULL)
+			{
+			s->tlsext_opaque_prf_input_len = (size_t)larg;
+			ret = 1;
+			}
+		else
+			s->tlsext_opaque_prf_input_len = 0;
+		break;
+#endif
+
 	case SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE:
 		s->tlsext_status_type=larg;
 		ret = 1;
@@ -2194,13 +2697,20 @@
 			}
 		return 1;
 		}
-  
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG:
+		ctx->tlsext_opaque_prf_input_callback_arg = parg;
+		return 1;
+#endif
+
 	case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG:
 		ctx->tlsext_status_arg=parg;
 		return 1;
 		break;
 
 #endif /* !OPENSSL_NO_TLSEXT */
+
 	/* A Thawte special :-) */
 	case SSL_CTRL_EXTRA_CHAIN_CERT:
 		if (ctx->extra_certs == NULL)
@@ -2250,7 +2760,13 @@
 	case SSL_CTRL_SET_TLSEXT_SERVERNAME_CB:
 		ctx->tlsext_servername_callback=(int (*)(SSL *,int *,void *))fp;
 		break;
-  
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB:
+		ctx->tlsext_opaque_prf_input_callback = (int (*)(SSL *,void *, size_t, void *))fp;
+		break;
+#endif
+
 	case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB:
 		ctx->tlsext_status_cb=(int (*)(SSL *,void *))fp;
 		break;
@@ -2271,17 +2787,15 @@
 
 /* This function needs to check if the ciphers required are actually
  * available */
-SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p)
+const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p)
 	{
-	SSL_CIPHER c,*cp;
+	SSL_CIPHER c;
+	const SSL_CIPHER *cp;
 	unsigned long id;
 
 	id=0x03000000L|((unsigned long)p[0]<<8L)|(unsigned long)p[1];
 	c.id=id;
-	cp = (SSL_CIPHER *)OBJ_bsearch((char *)&c,
-		(char *)ssl3_ciphers,
-		SSL3_NUM_CIPHERS,sizeof(SSL_CIPHER),
-		FP_ICC ssl_cipher_id_cmp);
+	cp = OBJ_bsearch_ssl_cipher_id(&c, ssl3_ciphers, SSL3_NUM_CIPHERS);
 	if (cp == NULL || cp->valid == 0)
 		return NULL;
 	else
@@ -2307,10 +2821,14 @@
 	{
 	SSL_CIPHER *c,*ret=NULL;
 	STACK_OF(SSL_CIPHER) *prio, *allow;
-	int i,j,ok;
-
+	int i,ii,ok;
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_EC)
+	unsigned int j;
+	int ec_ok, ec_nid;
+	unsigned char ec_search1 = 0, ec_search2 = 0;
+#endif
 	CERT *cert;
-	unsigned long alg,mask,emask;
+	unsigned long alg_k,alg_a,mask_k,mask_a,emask_k,emask_a;
 
 	/* Let's see which ciphers we can support */
 	cert=s->cert;
@@ -2326,73 +2844,237 @@
 #endif
 
 #ifdef CIPHER_DEBUG
-        printf("Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), srvr);
-        for(i=0 ; i < sk_SSL_CIPHER_num(srvr) ; ++i)
-	    {
-	    c=sk_SSL_CIPHER_value(srvr,i);
-	    printf("%p:%s\n",c,c->name);
-	    }
-        printf("Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), clnt);
-        for(i=0 ; i < sk_SSL_CIPHER_num(clnt) ; ++i)
+	printf("Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), (void *)srvr);
+	for(i=0 ; i < sk_SSL_CIPHER_num(srvr) ; ++i)
+		{
+		c=sk_SSL_CIPHER_value(srvr,i);
+		printf("%p:%s\n",(void *)c,c->name);
+		}
+	printf("Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), (void *)clnt);
+	for(i=0 ; i < sk_SSL_CIPHER_num(clnt) ; ++i)
 	    {
 	    c=sk_SSL_CIPHER_value(clnt,i);
-	    printf("%p:%s\n",c,c->name);
+	    printf("%p:%s\n",(void *)c,c->name);
 	    }
 #endif
 
 	if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
-	    {
-	    prio = srvr;
-	    allow = clnt;
-	    }
+		{
+		prio = srvr;
+		allow = clnt;
+		}
 	else
-	    {
-	    prio = clnt;
-	    allow = srvr;
-	    }
+		{
+		prio = clnt;
+		allow = srvr;
+		}
 
 	for (i=0; i<sk_SSL_CIPHER_num(prio); i++)
 		{
 		c=sk_SSL_CIPHER_value(prio,i);
 
 		ssl_set_cert_masks(cert,c);
-		mask=cert->mask;
-		emask=cert->export_mask;
+		mask_k = cert->mask_k;
+		mask_a = cert->mask_a;
+		emask_k = cert->export_mask_k;
+		emask_a = cert->export_mask_a;
 			
 #ifdef KSSL_DEBUG
-		printf("ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms);
+/*		printf("ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms);*/
 #endif    /* KSSL_DEBUG */
 
-		alg=c->algorithms&(SSL_MKEY_MASK|SSL_AUTH_MASK);
+		alg_k=c->algorithm_mkey;
+		alg_a=c->algorithm_auth;
+
 #ifndef OPENSSL_NO_KRB5
-                if (alg & SSL_KRB5) 
-                        {
-                        if ( !kssl_keytab_is_available(s->kssl_ctx) )
-                            continue;
-                        }
+		if (alg_k & SSL_kKRB5)
+			{
+			if ( !kssl_keytab_is_available(s->kssl_ctx) )
+			    continue;
+			}
 #endif /* OPENSSL_NO_KRB5 */
+#ifndef OPENSSL_NO_PSK
+		/* with PSK there must be server callback set */
+		if ((alg_k & SSL_kPSK) && s->psk_server_callback == NULL)
+			continue;
+#endif /* OPENSSL_NO_PSK */
+
 		if (SSL_C_IS_EXPORT(c))
 			{
-			ok=((alg & emask) == alg)?1:0;
+			ok = (alg_k & emask_k) && (alg_a & emask_a);
 #ifdef CIPHER_DEBUG
-			printf("%d:[%08lX:%08lX]%p:%s (export)\n",ok,alg,emask,
-			       c,c->name);
+			printf("%d:[%08lX:%08lX:%08lX:%08lX]%p:%s (export)\n",ok,alg_k,alg_a,emask_k,emask_a,
+			       (void *)c,c->name);
 #endif
 			}
 		else
 			{
-			ok=((alg & mask) == alg)?1:0;
+			ok = (alg_k & mask_k) && (alg_a & mask_a);
 #ifdef CIPHER_DEBUG
-			printf("%d:[%08lX:%08lX]%p:%s\n",ok,alg,mask,c,
+			printf("%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n",ok,alg_k,alg_a,mask_k,mask_a,(void *)c,
 			       c->name);
 #endif
 			}
 
-		if (!ok) continue;
-		j=sk_SSL_CIPHER_find(allow,c);
-		if (j >= 0)
+#ifndef OPENSSL_NO_TLSEXT
+#ifndef OPENSSL_NO_EC
+		if (
+			/* if we are considering an ECC cipher suite that uses our certificate */
+			(alg_a & SSL_aECDSA || alg_a & SSL_aECDH)
+			/* and we have an ECC certificate */
+			&& (s->cert->pkeys[SSL_PKEY_ECC].x509 != NULL)
+			/* and the client specified a Supported Point Formats extension */
+			&& ((s->session->tlsext_ecpointformatlist_length > 0) && (s->session->tlsext_ecpointformatlist != NULL))
+			/* and our certificate's point is compressed */
+			&& (
+				(s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info != NULL)
+				&& (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key != NULL)
+				&& (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key != NULL)
+				&& (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data != NULL)
+				&& (
+					(*(s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data) == POINT_CONVERSION_COMPRESSED)
+					|| (*(s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data) == POINT_CONVERSION_COMPRESSED + 1)
+					)
+				)
+		)
 			{
-			ret=sk_SSL_CIPHER_value(allow,j);
+			ec_ok = 0;
+			/* if our certificate's curve is over a field type that the client does not support
+			 * then do not allow this cipher suite to be negotiated */
+			if (
+				(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec != NULL)
+				&& (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group != NULL)
+				&& (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth != NULL)
+				&& (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_prime_field)
+			)
+				{
+				for (j = 0; j < s->session->tlsext_ecpointformatlist_length; j++)
+					{
+					if (s->session->tlsext_ecpointformatlist[j] == TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime)
+						{
+						ec_ok = 1;
+						break;
+						}
+					}
+				}
+			else if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_characteristic_two_field)
+				{
+				for (j = 0; j < s->session->tlsext_ecpointformatlist_length; j++)
+					{
+					if (s->session->tlsext_ecpointformatlist[j] == TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2)
+						{
+						ec_ok = 1;
+						break;
+						}
+					}
+				}
+			ok = ok && ec_ok;
+			}
+		if (
+			/* if we are considering an ECC cipher suite that uses our certificate */
+			(alg_a & SSL_aECDSA || alg_a & SSL_aECDH)
+			/* and we have an ECC certificate */
+			&& (s->cert->pkeys[SSL_PKEY_ECC].x509 != NULL)
+			/* and the client specified an EllipticCurves extension */
+			&& ((s->session->tlsext_ellipticcurvelist_length > 0) && (s->session->tlsext_ellipticcurvelist != NULL))
+		)
+			{
+			ec_ok = 0;
+			if (
+				(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec != NULL)
+				&& (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group != NULL)
+			)
+				{
+				ec_nid = EC_GROUP_get_curve_name(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group);
+				if ((ec_nid == 0)
+					&& (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth != NULL)
+				)
+					{
+					if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_prime_field)
+						{
+						ec_search1 = 0xFF;
+						ec_search2 = 0x01;
+						}
+					else if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_characteristic_two_field)
+						{
+						ec_search1 = 0xFF;
+						ec_search2 = 0x02;
+						}
+					}
+				else
+					{
+					ec_search1 = 0x00;
+					ec_search2 = tls1_ec_nid2curve_id(ec_nid);
+					}
+				if ((ec_search1 != 0) || (ec_search2 != 0))
+					{
+					for (j = 0; j < s->session->tlsext_ellipticcurvelist_length / 2; j++)
+						{
+						if ((s->session->tlsext_ellipticcurvelist[2*j] == ec_search1) && (s->session->tlsext_ellipticcurvelist[2*j+1] == ec_search2))
+							{
+							ec_ok = 1;
+							break;
+							}
+						}
+					}
+				}
+			ok = ok && ec_ok;
+			}
+		if (
+			/* if we are considering an ECC cipher suite that uses an ephemeral EC key */
+			(alg_k & SSL_kEECDH)
+			/* and we have an ephemeral EC key */
+			&& (s->cert->ecdh_tmp != NULL)
+			/* and the client specified an EllipticCurves extension */
+			&& ((s->session->tlsext_ellipticcurvelist_length > 0) && (s->session->tlsext_ellipticcurvelist != NULL))
+		)
+			{
+			ec_ok = 0;
+			if (s->cert->ecdh_tmp->group != NULL)
+				{
+				ec_nid = EC_GROUP_get_curve_name(s->cert->ecdh_tmp->group);
+				if ((ec_nid == 0)
+					&& (s->cert->ecdh_tmp->group->meth != NULL)
+				)
+					{
+					if (EC_METHOD_get_field_type(s->cert->ecdh_tmp->group->meth) == NID_X9_62_prime_field)
+						{
+						ec_search1 = 0xFF;
+						ec_search2 = 0x01;
+						}
+					else if (EC_METHOD_get_field_type(s->cert->ecdh_tmp->group->meth) == NID_X9_62_characteristic_two_field)
+						{
+						ec_search1 = 0xFF;
+						ec_search2 = 0x02;
+						}
+					}
+				else
+					{
+					ec_search1 = 0x00;
+					ec_search2 = tls1_ec_nid2curve_id(ec_nid);
+					}
+				if ((ec_search1 != 0) || (ec_search2 != 0))
+					{
+					for (j = 0; j < s->session->tlsext_ellipticcurvelist_length / 2; j++)
+						{
+						if ((s->session->tlsext_ellipticcurvelist[2*j] == ec_search1) && (s->session->tlsext_ellipticcurvelist[2*j+1] == ec_search2))
+							{
+							ec_ok = 1;
+							break;
+							}
+						}
+					}
+				}
+			ok = ok && ec_ok;
+			}
+#endif /* OPENSSL_NO_EC */
+#endif /* OPENSSL_NO_TLSEXT */
+
+		if (!ok) continue;
+		ii=sk_SSL_CIPHER_find(allow,c);
+		if (ii >= 0)
+			{
+			ret=sk_SSL_CIPHER_value(allow,ii);
 			break;
 			}
 		}
@@ -2402,12 +3084,24 @@
 int ssl3_get_req_cert_type(SSL *s, unsigned char *p)
 	{
 	int ret=0;
-	unsigned long alg;
+	unsigned long alg_k;
 
-	alg=s->s3->tmp.new_cipher->algorithms;
+	alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+
+#ifndef OPENSSL_NO_GOST
+	if (s->version >= TLS1_VERSION)
+		{
+		if (alg_k & SSL_kGOST)
+			{
+			p[ret++]=TLS_CT_GOST94_SIGN;
+			p[ret++]=TLS_CT_GOST01_SIGN;
+			return(ret);
+			}
+		}
+#endif
 
 #ifndef OPENSSL_NO_DH
-	if (alg & (SSL_kDHr|SSL_kEDH))
+	if (alg_k & (SSL_kDHr|SSL_kEDH))
 		{
 #  ifndef OPENSSL_NO_RSA
 		p[ret++]=SSL3_CT_RSA_FIXED_DH;
@@ -2417,7 +3111,7 @@
 #  endif
 		}
 	if ((s->version == SSL3_VERSION) &&
-		(alg & (SSL_kEDH|SSL_kDHd|SSL_kDHr)))
+		(alg_k & (SSL_kEDH|SSL_kDHd|SSL_kDHr)))
 		{
 #  ifndef OPENSSL_NO_RSA
 		p[ret++]=SSL3_CT_RSA_EPHEMERAL_DH;
@@ -2434,10 +3128,7 @@
 	p[ret++]=SSL3_CT_DSS_SIGN;
 #endif
 #ifndef OPENSSL_NO_ECDH
-	/* We should ask for fixed ECDH certificates only
-	 * for SSL_kECDH (and not SSL_kECDHE)
-	 */
-	if ((alg & SSL_kECDH) && (s->version >= TLS1_VERSION))
+	if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->version >= TLS1_VERSION))
 		{
 		p[ret++]=TLS_CT_RSA_FIXED_ECDH;
 		p[ret++]=TLS_CT_ECDSA_FIXED_ECDH;
@@ -2446,7 +3137,7 @@
 
 #ifndef OPENSSL_NO_ECDSA
 	/* ECDSA certs can be used with RSA cipher suites as well 
-	 * so we don't need to check for SSL_kECDH or SSL_kECDHE
+	 * so we don't need to check for SSL_kECDH or SSL_kEECDH
 	 */
 	if (s->version >= TLS1_VERSION)
 		{
diff --git a/ssl/s3_meth.c b/ssl/s3_meth.c
index 6a6eb1c..cdddb17 100644
--- a/ssl/s3_meth.c
+++ b/ssl/s3_meth.c
@@ -60,8 +60,8 @@
 #include <openssl/objects.h>
 #include "ssl_locl.h"
 
-static SSL_METHOD *ssl3_get_method(int ver);
-static SSL_METHOD *ssl3_get_method(int ver)
+static const SSL_METHOD *ssl3_get_method(int ver);
+static const SSL_METHOD *ssl3_get_method(int ver)
 	{
 	if (ver == SSL3_VERSION)
 		return(SSLv3_method());
@@ -70,8 +70,8 @@
 	}
 
 IMPLEMENT_ssl3_meth_func(SSLv3_method,
-			ssl3_accept,
-			ssl3_connect,
-			ssl3_get_method)
+			 ssl3_accept,
+			 ssl3_connect,
+			 ssl3_get_method)
 
 
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index 4634b29..9eaaad8 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -129,14 +129,49 @@
 	 * (If s->read_ahead is set, 'max' bytes may be stored in rbuf
 	 * [plus s->packet_length bytes if extend == 1].)
 	 */
-	int i,off,newb;
+	int i,len,left;
+	long align=0;
+	unsigned char *pkt;
+	SSL3_BUFFER *rb;
+
+	if (n <= 0) return n;
+
+	rb    = &(s->s3->rbuf);
+	if (rb->buf == NULL)
+		if (!ssl3_setup_read_buffer(s))
+			return -1;
+
+	left  = rb->left;
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+	align = (long)rb->buf + SSL3_RT_HEADER_LENGTH;
+	align = (-align)&(SSL3_ALIGN_PAYLOAD-1);
+#endif
 
 	if (!extend)
 		{
 		/* start with empty packet ... */
-		if (s->s3->rbuf.left == 0)
-			s->s3->rbuf.offset = 0;
-		s->packet = s->s3->rbuf.buf + s->s3->rbuf.offset;
+		if (left == 0)
+			rb->offset = align;
+		else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH)
+			{
+			/* check if next packet length is large
+			 * enough to justify payload alignment... */
+			pkt = rb->buf + rb->offset;
+			if (pkt[0] == SSL3_RT_APPLICATION_DATA
+			    && (pkt[3]<<8|pkt[4]) >= 128)
+				{
+				/* Note that even if packet is corrupted
+				 * and its length field is insane, we can
+				 * only be led to wrong decision about
+				 * whether memmove will occur or not.
+				 * Header values has no effect on memmove
+				 * arguments and therefore no buffer
+				 * overrun can be triggered. */
+				memmove (rb->buf+align,pkt,left);
+				rb->offset = align;
+				}
+			}
+		s->packet = rb->buf + rb->offset;
 		s->packet_length = 0;
 		/* ... now we can act as if 'extend' was set */
 		}
@@ -144,59 +179,63 @@
 	/* For DTLS/UDP reads should not span multiple packets
 	 * because the read operation returns the whole packet
 	 * at once (as long as it fits into the buffer). */
-	if (SSL_version(s) == DTLS1_VERSION)
+	if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
 		{
-		if ( s->s3->rbuf.left > 0 && n > s->s3->rbuf.left)
-			n = s->s3->rbuf.left;
+		if (left > 0 && n > left)
+			n = left;
 		}
 
 	/* if there is enough in the buffer from a previous read, take some */
-	if (s->s3->rbuf.left >= (int)n)
+	if (left >= n)
 		{
 		s->packet_length+=n;
-		s->s3->rbuf.left-=n;
-		s->s3->rbuf.offset+=n;
+		rb->left=left-n;
+		rb->offset+=n;
 		return(n);
 		}
 
 	/* else we need to read more data */
-	if (!s->read_ahead)
-		max=n;
 
-	{
-		/* avoid buffer overflow */
-		int max_max = s->s3->rbuf.len - s->packet_length;
-		if (max > max_max)
-			max = max_max;
-	}
-	if (n > max) /* does not happen */
+	len = s->packet_length;
+	pkt = rb->buf+align;
+	/* Move any available bytes to front of buffer:
+	 * 'len' bytes already pointed to by 'packet',
+	 * 'left' extra ones at the end */
+	if (s->packet != pkt) /* len > 0 */
+		{
+		memmove(pkt, s->packet, len+left);
+		s->packet = pkt;
+		rb->offset = len + align;
+		}
+
+	if (n > (int)(rb->len - rb->offset)) /* does not happen */
 		{
 		SSLerr(SSL_F_SSL3_READ_N,ERR_R_INTERNAL_ERROR);
 		return -1;
 		}
 
-	off = s->packet_length;
-	newb = s->s3->rbuf.left;
-	/* Move any available bytes to front of buffer:
-	 * 'off' bytes already pointed to by 'packet',
-	 * 'newb' extra ones at the end */
-	if (s->packet != s->s3->rbuf.buf)
+	if (!s->read_ahead)
+		/* ignore max parameter */
+		max = n;
+	else
 		{
-		/*  off > 0 */
-		memmove(s->s3->rbuf.buf, s->packet, off+newb);
-		s->packet = s->s3->rbuf.buf;
+		if (max < n)
+			max = n;
+		if (max > (int)(rb->len - rb->offset))
+			max = rb->len - rb->offset;
 		}
 
-	while (newb < n)
+	while (left < n)
 		{
-		/* Now we have off+newb bytes at the front of s->s3->rbuf.buf and need
-		 * to read in more until we have off+n (up to off+max if possible) */
+		/* Now we have len+left bytes at the front of s->s3->rbuf.buf
+		 * and need to read in more until we have len+n (up to
+		 * len+max if possible) */
 
 		clear_sys_error();
 		if (s->rbio != NULL)
 			{
 			s->rwstate=SSL_READING;
-			i=BIO_read(s->rbio,	&(s->s3->rbuf.buf[off+newb]), max-newb);
+			i=BIO_read(s->rbio,pkt+len+left, max-left);
 			}
 		else
 			{
@@ -206,23 +245,26 @@
 
 		if (i <= 0)
 			{
-			s->s3->rbuf.left = newb;
+			rb->left = left;
+			if (s->mode & SSL_MODE_RELEASE_BUFFERS)
+				if (len+left == 0)
+					ssl3_release_read_buffer(s);
 			return(i);
 			}
-		newb+=i;
+		left+=i;
 		/* reads should *never* span multiple packets for DTLS because
 		 * the underlying transport protocol is message oriented as opposed
 		 * to byte oriented as in the TLS case. */
-		if (SSL_version(s) == DTLS1_VERSION)
+		if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
 			{
-			if (n > newb)
-				n = newb; /* makes the while condition false */
+			if (n > left)
+				n = left; /* makes the while condition false */
 			}
 		}
 
 	/* done reading, now the book-keeping */
-	s->s3->rbuf.offset = off + n;
-	s->s3->rbuf.left = newb - n;
+	rb->offset += n;
+	rb->left = left - n;
 	s->packet_length += n;
 	s->rwstate=SSL_NOTHING;
 	return(n);
@@ -246,7 +288,7 @@
 	unsigned char *p;
 	unsigned char md[EVP_MAX_MD_SIZE];
 	short version;
-	unsigned int mac_size;
+	int mac_size;
 	int clear=0;
 	size_t extra;
 	int decryption_failed_or_bad_record_mac = 0;
@@ -260,9 +302,9 @@
 	else
 		extra=0;
 	if (!(SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) &&
-		extra != s->s3->rbuf.len - SSL3_RT_MAX_PACKET_SIZE)
+		extra && !s->s3->init_extra)
 		{
-		/* actually likely an application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER
+		/* An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER
 		 * set after ssl3_setup_buffers() was done */
 		SSLerr(SSL_F_SSL3_GET_RECORD, ERR_R_INTERNAL_ERROR);
 		return -1;
@@ -285,6 +327,9 @@
 		ssl_minor= *(p++);
 		version=(ssl_major<<8)|ssl_minor;
 		n2s(p,rr->length);
+#if 0
+fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length);
+#endif
 
 		/* Lets check version */
 		if (!s->first_packet)
@@ -292,10 +337,9 @@
 			if (version != s->version)
 				{
 				SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
-				/* If the major versions match then we'll send
-				 * the error back using the peer's version. */
-				if ((s->version & 0xFF00) == (version & 0xFF00))
-					s->version = version;
+                                if ((s->version & 0xFF00) == (version & 0xFF00))
+                                	/* Send back error using their minor version number :-) */
+					s->version = (unsigned short)version;
 				al=SSL_AD_PROTOCOL_VERSION;
 				goto f_err;
 				}
@@ -307,7 +351,7 @@
 			goto err;
 			}
 
-		if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH+extra)
+		if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH)
 			{
 			al=SSL_AD_RECORD_OVERFLOW;
 			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG);
@@ -395,12 +439,14 @@
 	/* r->length is now the compressed data plus mac */
 	if (	(sess == NULL) ||
 		(s->enc_read_ctx == NULL) ||
-		(s->read_hash == NULL))
+		(EVP_MD_CTX_md(s->read_hash) == NULL))
 		clear=1;
 
 	if (!clear)
 		{
-		mac_size=EVP_MD_size(s->read_hash);
+		/* !clear => s->read_hash != NULL => mac_size != -1 */
+		mac_size=EVP_MD_CTX_size(s->read_hash);
+		OPENSSL_assert(mac_size >= 0);
 
 		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size)
 			{
@@ -413,7 +459,7 @@
 #endif			
 			}
 		/* check the MAC for rr->input (it's in mac_size bytes at the tail) */
-		if (rr->length >= mac_size)
+		if (rr->length >= (unsigned int)mac_size)
 			{
 			rr->length -= mac_size;
 			mac = &rr->data[rr->length];
@@ -431,7 +477,7 @@
 #endif
 			}
 		i=s->method->ssl3_enc->mac(s,md,0);
-		if (mac == NULL || memcmp(md, mac, mac_size) != 0)
+		if (i < 0 || mac == NULL || memcmp(md, mac, (size_t)mac_size) != 0)
 			{
 			decryption_failed_or_bad_record_mac = 1;
 			}
@@ -488,6 +534,10 @@
 	/* just read a 0 length packet */
 	if (rr->length == 0) goto again;
 
+#if 0
+fprintf(stderr, "Ultimate Record type=%d, Length=%d\n", rr->type, rr->length);
+#endif
+
 	return(1);
 
 f_err:
@@ -542,7 +592,7 @@
 	const unsigned char *buf=buf_;
 	unsigned int tot,n,nw;
 	int i;
-    unsigned int max_plain_length;
+	unsigned int max_plain_length;
 
 	s->rwstate=SSL_NOTHING;
 	tot=s->s3->wnum;
@@ -563,7 +613,7 @@
 	for (;;)
 		{
 		if (!(SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS))
-			max_plain_length = SSL3_RT_MAX_PLAIN_LENGTH;
+			max_plain_length = s->max_send_fragment;
 		else
 			max_plain_length = SSL3_RT_DEFAULT_PLAIN_LENGTH;
 
@@ -600,14 +650,19 @@
 	{
 	unsigned char *p,*plen;
 	int i,mac_size,clear=0;
-	int prefix_len = 0;
+	int prefix_len=0;
+	long align=0;
 	SSL3_RECORD *wr;
-	SSL3_BUFFER *wb;
+	SSL3_BUFFER *wb=&(s->s3->wbuf);
 	SSL_SESSION *sess;
 
+ 	if (wb->buf == NULL)
+		if (!ssl3_setup_write_buffer(s))
+			return -1;
+
 	/* first check if there is a SSL3_BUFFER still being written
 	 * out.  This will happen with non blocking IO */
-	if (s->s3->wbuf.left != 0)
+	if (wb->left != 0)
 		return(ssl3_write_pending(s,type,buf,len));
 
 	/* If we have an alert to send, lets send it */
@@ -623,18 +678,21 @@
 		return 0;
 
 	wr= &(s->s3->wrec);
-	wb= &(s->s3->wbuf);
 	sess=s->session;
 
 	if (	(sess == NULL) ||
 		(s->enc_write_ctx == NULL) ||
-		(s->write_hash == NULL))
+		(EVP_MD_CTX_md(s->write_hash) == NULL))
 		clear=1;
 
 	if (clear)
 		mac_size=0;
 	else
-		mac_size=EVP_MD_size(s->write_hash);
+		{
+		mac_size=EVP_MD_CTX_size(s->write_hash);
+		if (mac_size < 0)
+			goto err;
+		}
 
 	/* 'create_empty_fragment' is true only when this function calls itself */
 	if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done)
@@ -652,9 +710,8 @@
 			if (prefix_len <= 0)
 				goto err;
 
-			if (s->s3->wbuf.len < (size_t)prefix_len +
-				((SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) ? SSL3_RT_DEFAULT_PACKET_SIZE :
-					SSL3_RT_MAX_PACKET_SIZE))
+			if (prefix_len >
+		(SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD))
 				{
 				/* insufficient space */
 				SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
@@ -665,7 +722,32 @@
 		s->s3->empty_fragment_done = 1;
 		}
 
-	p = wb->buf + prefix_len;
+	if (create_empty_fragment)
+		{
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+		/* extra fragment would be couple of cipher blocks,
+		 * which would be multiple of SSL3_ALIGN_PAYLOAD, so
+		 * if we want to align the real payload, then we can
+		 * just pretent we simply have two headers. */
+		align = (long)wb->buf + 2*SSL3_RT_HEADER_LENGTH;
+		align = (-align)&(SSL3_ALIGN_PAYLOAD-1);
+#endif
+		p = wb->buf + align;
+		wb->offset  = align;
+		}
+	else if (prefix_len)
+		{
+		p = wb->buf + wb->offset + prefix_len;
+		}
+	else
+		{
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+		align = (long)wb->buf + SSL3_RT_HEADER_LENGTH;
+		align = (-align)&(SSL3_ALIGN_PAYLOAD-1);
+#endif
+		p = wb->buf + align;
+		wb->offset  = align;
+		}
 
 	/* write the header */
 
@@ -708,7 +790,8 @@
 
 	if (mac_size != 0)
 		{
-		s->method->ssl3_enc->mac(s,&(p[wr->length]),1);
+		if (s->method->ssl3_enc->mac(s,&(p[wr->length]),1) < 0)
+			goto err;
 		wr->length+=mac_size;
 		wr->input=p;
 		wr->data=p;
@@ -736,7 +819,6 @@
 
 	/* now let's set up wb */
 	wb->left = prefix_len + wr->length;
-	wb->offset = 0;
 
 	/* memorize arguments so that ssl3_write_pending can detect bad write retries later */
 	s->s3->wpend_tot=len;
@@ -755,6 +837,7 @@
 	unsigned int len)
 	{
 	int i;
+	SSL3_BUFFER *wb=&(s->s3->wbuf);
 
 /* XXXX */
 	if ((s->s3->wpend_tot > (int)len)
@@ -773,17 +856,20 @@
 			{
 			s->rwstate=SSL_WRITING;
 			i=BIO_write(s->wbio,
-				(char *)&(s->s3->wbuf.buf[s->s3->wbuf.offset]),
-				(unsigned int)s->s3->wbuf.left);
+				(char *)&(wb->buf[wb->offset]),
+				(unsigned int)wb->left);
 			}
 		else
 			{
 			SSLerr(SSL_F_SSL3_WRITE_PENDING,SSL_R_BIO_NOT_SET);
 			i= -1;
 			}
-		if (i == s->s3->wbuf.left)
+		if (i == wb->left)
 			{
-			s->s3->wbuf.left=0;
+			wb->left=0;
+			wb->offset+=i;
+			if (s->mode & SSL_MODE_RELEASE_BUFFERS)
+				ssl3_release_write_buffer(s);
 			s->rwstate=SSL_NOTHING;
 			return(s->s3->wpend_ret);
 			}
@@ -792,12 +878,12 @@
 			    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;
+				wb->left = 0;
 			}
 			return(i);
 		}
-		s->s3->wbuf.offset+=i;
-		s->s3->wbuf.left-=i;
+		wb->offset+=i;
+		wb->left-=i;
 		}
 	}
 
@@ -836,7 +922,7 @@
 	void (*cb)(const SSL *ssl,int type2,int val)=NULL;
 
 	if (s->s3->rbuf.buf == NULL) /* Not initialized yet */
-		if (!ssl3_setup_buffers(s))
+		if (!ssl3_setup_read_buffer(s))
 			return(-1);
 
 	if ((type && (type != SSL3_RT_APPLICATION_DATA) && (type != SSL3_RT_HANDSHAKE) && type) ||
@@ -945,6 +1031,8 @@
 				{
 				s->rstate=SSL_ST_READ_HEADER;
 				rr->off=0;
+				if (s->mode & SSL_MODE_RELEASE_BUFFERS)
+					ssl3_release_read_buffer(s);
 				}
 			}
 		return(n);
@@ -1328,8 +1416,6 @@
 		}
 
 	s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
-		&(s->s3->finish_dgst1),
-		&(s->s3->finish_dgst2),
 		sender,slen,s->s3->tmp.peer_finish_md);
 
 	return(1);
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index e696450..92f73b6 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -1,4 +1,4 @@
-/* ssl/s3_srvr.c */
+/* ssl/s3_srvr.c -*- mode:C; c-file-style: "eay" -*- */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -121,6 +121,32 @@
  * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
  *
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 #define REUSE_CIPHER_BUG
 #define NETSCAPE_HANG_BUG
@@ -143,12 +169,9 @@
 #endif
 #include <openssl/md5.h>
 
-static SSL_METHOD *ssl3_get_server_method(int ver);
-#ifndef OPENSSL_NO_ECDH
-static int nid2curve_id(int nid);
-#endif
+static const SSL_METHOD *ssl3_get_server_method(int ver);
 
-static SSL_METHOD *ssl3_get_server_method(int ver)
+static const SSL_METHOD *ssl3_get_server_method(int ver)
 	{
 	if (ver == SSL3_VERSION)
 		return(SSLv3_server_method());
@@ -164,7 +187,7 @@
 int ssl3_accept(SSL *s)
 	{
 	BUF_MEM *buf;
-	unsigned long l,Time=(unsigned long)time(NULL);
+	unsigned long alg_k,Time=(unsigned long)time(NULL);
 	void (*cb)(const SSL *ssl,int type,int val)=NULL;
 	int ret= -1;
 	int new_state,state,skip=0;
@@ -292,6 +315,7 @@
 			s->shutdown=0;
 			ret=ssl3_get_client_hello(s);
 			if (ret <= 0) goto end;
+			
 			s->new_session = 2;
 			s->state=SSL3_ST_SW_SRVR_HELLO_A;
 			s->init_num=0;
@@ -320,9 +344,11 @@
 
 		case SSL3_ST_SW_CERT_A:
 		case SSL3_ST_SW_CERT_B:
-			/* Check if it is anon DH or anon ECDH or KRB5 */
-			if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)
-				&& !(s->s3->tmp.new_cipher->algorithms & SSL_aKRB5))
+			/* Check if it is anon DH or anon ECDH, */
+			/* normal PSK or KRB5 */
+			if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
+				&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
+				&& !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
 				{
 				ret=ssl3_send_server_certificate(s);
 				if (ret <= 0) goto end;
@@ -349,13 +375,13 @@
 
 		case SSL3_ST_SW_KEY_EXCH_A:
 		case SSL3_ST_SW_KEY_EXCH_B:
-			l=s->s3->tmp.new_cipher->algorithms;
+			alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
 			/* clear this, it may get reset by
 			 * send_server_key_exchange */
 			if ((s->options & SSL_OP_EPHEMERAL_RSA)
 #ifndef OPENSSL_NO_KRB5
-				&& !(l & SSL_KRB5)
+				&& !(alg_k & SSL_kKRB5)
 #endif /* OPENSSL_NO_KRB5 */
 				)
 				/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
@@ -370,16 +396,23 @@
 			/* only send if a DH key exchange, fortezza or
 			 * RSA but we have a sign only certificate
 			 *
+			 * PSK: may send PSK identity hints
+			 *
 			 * For ECC ciphersuites, we send a serverKeyExchange
 			 * message only if the cipher suite is either
 			 * ECDH-anon or ECDHE. In other cases, the
-			 * server certificate contains the server's 
+			 * server certificate contains the server's
 			 * public key for key exchange.
 			 */
 			if (s->s3->tmp.use_rsa_tmp
-			    || (l & SSL_kECDHE)
-			    || (l & (SSL_DH|SSL_kFZA))
-			    || ((l & SSL_kRSA)
+			/* PSK: send ServerKeyExchange if PSK identity
+			 * hint if provided */
+#ifndef OPENSSL_NO_PSK
+			    || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint)
+#endif
+			    || (alg_k & (SSL_kDHr|SSL_kDHd|SSL_kEDH))
+			    || (alg_k & SSL_kEECDH)
+			    || ((alg_k & SSL_kRSA)
 				&& (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
 				    || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
 					&& EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)
@@ -409,12 +442,15 @@
 				/* never request cert in anonymous ciphersuites
 				 * (see section "Certificate request" in SSL 3 drafts
 				 * and in RFC 2246): */
-				((s->s3->tmp.new_cipher->algorithms & SSL_aNULL) &&
+				((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
 				 /* ... except when the application insists on verification
 				  * (against the specs, but s3_clnt.c accepts this for SSL 3) */
 				 !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
-                                 /* never request cert in Kerberos ciphersuites */
-                                (s->s3->tmp.new_cipher->algorithms & SSL_aKRB5))
+				 /* never request cert in Kerberos ciphersuites */
+				(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)
+				/* With normal PSK Certificates and
+				 * Certificate Requests are omitted */
+				|| (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
 				{
 				/* no cert request */
 				skip=1;
@@ -490,7 +526,7 @@
 		case SSL3_ST_SR_KEY_EXCH_A:
 		case SSL3_ST_SR_KEY_EXCH_B:
 			ret=ssl3_get_client_key_exchange(s);
-			if (ret <= 0) 
+			if (ret <= 0)
 				goto end;
 			if (ret == 2)
 				{
@@ -498,24 +534,43 @@
 				 * the client sends its ECDH pub key in
 				 * a certificate, the CertificateVerify
 				 * message is not sent.
+				 * Also for GOST ciphersuites when
+				 * the client uses its key from the certificate
+				 * for key exchange.
 				 */
 				s->state=SSL3_ST_SR_FINISHED_A;
 				s->init_num = 0;
 				}
-			else   
+			else
 				{
+				int offset=0;
+				int dgst_num;
+
 				s->state=SSL3_ST_SR_CERT_VRFY_A;
 				s->init_num=0;
 
 				/* We need to get hashes here so if there is
 				 * a client cert, it can be verified
-				 */ 
-				s->method->ssl3_enc->cert_verify_mac(s,
-				    &(s->s3->finish_dgst1),
-				    &(s->s3->tmp.cert_verify_md[0]));
-				s->method->ssl3_enc->cert_verify_mac(s,
-				    &(s->s3->finish_dgst2),
-				    &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]));
+				 * FIXME - digest processing for CertificateVerify
+				 * should be generalized. But it is next step
+				 */
+				if (s->s3->handshake_buffer)
+					if (!ssl3_digest_cached_records(s))
+						return -1;
+				for (dgst_num=0; dgst_num<SSL_MAX_DIGEST;dgst_num++)	
+					if (s->s3->handshake_dgst[dgst_num]) 
+						{
+						int dgst_size;
+
+						s->method->ssl3_enc->cert_verify_mac(s,EVP_MD_CTX_type(s->s3->handshake_dgst[dgst_num]),&(s->s3->tmp.cert_verify_md[offset]));
+						dgst_size=EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]);
+						if (dgst_size < 0)
+							{
+							ret = -1;
+							goto end;
+							}
+						offset+=dgst_size;
+						}		
 				}
 			break;
 
@@ -535,11 +590,14 @@
 			ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
 				SSL3_ST_SR_FINISHED_B);
 			if (ret <= 0) goto end;
+#ifndef OPENSSL_NO_TLSEXT
+			if (s->tlsext_ticket_expected)
+				s->state=SSL3_ST_SW_SESSION_TICKET_A;
+			else if (s->hit)
+				s->state=SSL_ST_OK;
+#else
 			if (s->hit)
 				s->state=SSL_ST_OK;
-#ifndef OPENSSL_NO_TLSEXT
-			else if (s->tlsext_ticket_expected)
-				s->state=SSL3_ST_SW_SESSION_TICKET_A;
 #endif
 			else
 				s->state=SSL3_ST_SW_CHANGE_A;
@@ -769,7 +827,7 @@
 	    (s->version != DTLS1_VERSION && s->client_version < s->version))
 		{
 		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER);
-		if ((s->client_version>>8) == SSL3_VERSION_MAJOR) 
+		if ((s->client_version>>8) == SSL3_VERSION_MAJOR)
 			{
 			/* similar to ssl3_get_record, send alert using remote version number */
 			s->version = s->client_version;
@@ -990,13 +1048,110 @@
 			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
 			goto err;
 		}
+
+	/* Check if we want to use external pre-shared secret for this
+	 * handshake for not reused session only. We need to generate
+	 * server_random before calling tls_session_secret_cb in order to allow
+	 * SessionTicket processing to use it in key derivation. */
+	{
+		unsigned long Time;
+		unsigned char *pos;
+		Time=(unsigned long)time(NULL);			/* Time */
+		pos=s->s3->server_random;
+		l2n(Time,pos);
+		if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0)
+			{
+			al=SSL_AD_INTERNAL_ERROR;
+			goto f_err;
+			}
+	}
+
+	if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb)
+		{
+		SSL_CIPHER *pref_cipher=NULL;
+
+		s->session->master_key_length=sizeof(s->session->master_key);
+		if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
+			ciphers, &pref_cipher, s->tls_session_secret_cb_arg))
+			{
+			s->hit=1;
+			s->session->ciphers=ciphers;
+			s->session->verify_result=X509_V_OK;
+
+			ciphers=NULL;
+
+			/* check if some cipher was preferred by call back */
+			pref_cipher=pref_cipher ? pref_cipher : ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
+			if (pref_cipher == NULL)
+				{
+				al=SSL_AD_HANDSHAKE_FAILURE;
+				SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_SHARED_CIPHER);
+				goto f_err;
+				}
+
+			s->session->cipher=pref_cipher;
+
+			if (s->cipher_list)
+				sk_SSL_CIPHER_free(s->cipher_list);
+
+			if (s->cipher_list_by_id)
+				sk_SSL_CIPHER_free(s->cipher_list_by_id);
+
+			s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
+			s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
+			}
+		}
 #endif
+
 	/* Worst case, we will use the NULL compression, but if we have other
 	 * options, we will now look for them.  We have i-1 compression
 	 * algorithms from the client, starting at q. */
 	s->s3->tmp.new_compression=NULL;
 #ifndef OPENSSL_NO_COMP
-	if (s->ctx->comp_methods != NULL)
+	/* This only happens if we have a cache hit */
+	if (s->session->compress_meth != 0)
+		{
+		int m, comp_id = s->session->compress_meth;
+		/* Perform sanity checks on resumed compression algorithm */
+		/* Can't disable compression */
+		if (s->options & SSL_OP_NO_COMPRESSION)
+			{
+			al=SSL_AD_INTERNAL_ERROR;
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INCONSISTENT_COMPRESSION);
+			goto f_err;
+			}
+		/* Look for resumed compression method */
+		for (m = 0; m < sk_SSL_COMP_num(s->ctx->comp_methods); m++)
+			{
+			comp=sk_SSL_COMP_value(s->ctx->comp_methods,m);
+			if (comp_id == comp->id)
+				{
+				s->s3->tmp.new_compression=comp;
+				break;
+				}
+			}
+		if (s->s3->tmp.new_compression == NULL)
+			{
+			al=SSL_AD_INTERNAL_ERROR;
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INVALID_COMPRESSION_ALGORITHM);
+			goto f_err;
+			}
+		/* Look for resumed method in compression list */
+		for (m = 0; m < i; m++)
+			{
+			if (q[m] == comp_id)
+				break;
+			}
+		if (m >= i)
+			{
+			al=SSL_AD_ILLEGAL_PARAMETER;
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING);
+			goto f_err;
+			}
+		}
+	else if (s->hit)
+		comp = NULL;
+	else if (!(s->options & SSL_OP_NO_COMPRESSION) && s->ctx->comp_methods)
 		{ /* See if we have a match */
 		int m,nn,o,v,done=0;
 
@@ -1020,22 +1175,15 @@
 		else
 			comp=NULL;
 		}
-#endif
-
-	/* TLS does not mind if there is extra stuff */
-#if 0   /* SSL 3.0 does not mind either, so we should disable this test
-         * (was enabled in 0.9.6d through 0.9.6j and 0.9.7 through 0.9.7b,
-         * in earlier SSLeay/OpenSSL releases this test existed but was buggy) */
-	if (s->version == SSL3_VERSION)
+#else
+	/* If compression is disabled we'd better not try to resume a session
+	 * using compression.
+	 */
+	if (s->session->compress_meth != 0)
 		{
-		if (p < (d+n))
-			{
-			/* wrong number of bytes,
-			 * there could be more to follow */
-			al=SSL_AD_DECODE_ERROR;
-			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH);
-			goto f_err;
-			}
+		al=SSL_AD_INTERNAL_ERROR;
+		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INCONSISTENT_COMPRESSION);
+		goto f_err;
 		}
 #endif
 
@@ -1084,7 +1232,7 @@
 			for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
 				{
 				c=sk_SSL_CIPHER_value(sk,i);
-				if (c->algorithms & SSL_eNULL)
+				if (c->algorithm_enc & SSL_eNULL)
 					nc=c;
 				if (SSL_C_IS_EXPORT(c))
 					ec=c;
@@ -1100,6 +1248,9 @@
 #endif
 		s->s3->tmp.new_cipher=s->session->cipher;
 		}
+
+	if (!ssl3_digest_cached_records(s))
+		goto f_err;
 	
 	/* we now have the following setup. 
 	 * client_random
@@ -1128,16 +1279,22 @@
 	unsigned char *buf;
 	unsigned char *p,*d;
 	int i,sl;
-	unsigned long l,Time;
+	unsigned long l;
+#ifdef OPENSSL_NO_TLSEXT
+	unsigned long Time;
+#endif
 
 	if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
 		{
 		buf=(unsigned char *)s->init_buf->data;
+#ifdef OPENSSL_NO_TLSEXT
 		p=s->s3->server_random;
+		/* Generate server_random if it was not needed previously */
 		Time=(unsigned long)time(NULL);			/* Time */
 		l2n(Time,p);
 		if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
 			return -1;
+#endif
 		/* Do the message type and length last */
 		d=p= &(buf[4]);
 
@@ -1191,6 +1348,11 @@
 			*(p++)=s->s3->tmp.new_compression->id;
 #endif
 #ifndef OPENSSL_NO_TLSEXT
+		if (ssl_prepare_serverhello_tlsext(s) <= 0)
+			{
+			SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,SSL_R_SERVERHELLO_TLSEXT);
+			return -1;
+			}
 		if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
 			{
 			SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
@@ -1270,7 +1432,7 @@
 	EVP_MD_CTX_init(&md_ctx);
 	if (s->state == SSL3_ST_SW_KEY_EXCH_A)
 		{
-		type=s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK;
+		type=s->s3->tmp.new_cipher->algorithm_mkey;
 		cert=s->cert;
 
 		buf=s->init_buf;
@@ -1365,7 +1527,7 @@
 		else 
 #endif
 #ifndef OPENSSL_NO_ECDH
-			if (type & SSL_kECDHE)
+			if (type & SSL_kEECDH)
 			{
 			const EC_GROUP *group;
 
@@ -1435,7 +1597,7 @@
 			 * supported named curves, curve_id is non-zero.
 			 */
 			if ((curve_id = 
-			    nid2curve_id(EC_GROUP_get_curve_name(group)))
+			    tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group)))
 			    == 0)
 				{
 				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
@@ -1492,6 +1654,14 @@
 			}
 		else 
 #endif /* !OPENSSL_NO_ECDH */
+#ifndef OPENSSL_NO_PSK
+			if (type & SSL_kPSK)
+				{
+				/* reserve size for record length and PSK identity hint*/
+				n+=2+strlen(s->ctx->psk_identity_hint);
+				}
+			else
+#endif /* !OPENSSL_NO_PSK */
 			{
 			al=SSL_AD_HANDSHAKE_FAILURE;
 			SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
@@ -1503,7 +1673,8 @@
 			n+=2+nr[i];
 			}
 
-		if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
+		if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
+			&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
 			{
 			if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher))
 				== NULL)
@@ -1535,7 +1706,7 @@
 			}
 
 #ifndef OPENSSL_NO_ECDH
-		if (type & SSL_kECDHE) 
+		if (type & SSL_kEECDH) 
 			{
 			/* XXX: For now, we only support named (not generic) curves.
 			 * In this situation, the serverKeyExchange message has:
@@ -1559,6 +1730,16 @@
 			}
 #endif
 
+#ifndef OPENSSL_NO_PSK
+		if (type & SSL_kPSK)
+			{
+			/* copy PSK identity hint */
+			s2n(strlen(s->ctx->psk_identity_hint), p); 
+			strncpy((char *)p, s->ctx->psk_identity_hint, strlen(s->ctx->psk_identity_hint));
+			p+=strlen(s->ctx->psk_identity_hint);
+			}
+#endif
+
 		/* not anonymous */
 		if (pkey != NULL)
 			{
@@ -1571,8 +1752,6 @@
 				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);
@@ -1756,7 +1935,7 @@
 	{
 	int i,al,ok;
 	long n;
-	unsigned long l;
+	unsigned long alg_k;
 	unsigned char *p;
 #ifndef OPENSSL_NO_RSA
 	RSA *rsa=NULL;
@@ -1767,7 +1946,7 @@
 	DH *dh_srvr;
 #endif
 #ifndef OPENSSL_NO_KRB5
-        KSSL_ERR kssl_err;
+	KSSL_ERR kssl_err;
 #endif /* OPENSSL_NO_KRB5 */
 
 #ifndef OPENSSL_NO_ECDH
@@ -1787,10 +1966,10 @@
 	if (!ok) return((int)n);
 	p=(unsigned char *)s->init_msg;
 
-	l=s->s3->tmp.new_cipher->algorithms;
+	alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
 
 #ifndef OPENSSL_NO_RSA
-	if (l & SSL_kRSA)
+	if (alg_k & SSL_kRSA)
 		{
 		/* FIX THIS UP EAY EAY EAY EAY */
 		if (s->s3->tmp.use_rsa_tmp)
@@ -1821,9 +2000,8 @@
 			rsa=pkey->pkey.rsa;
 			}
 
-		/* TLS and [incidentally] DTLS, including pre-0.9.8f */
-		if (s->version > SSL3_VERSION &&
-		    s->client_version != DTLS1_BAD_VER)
+		/* TLS and [incidentally] DTLS{0xFEFF} */
+		if (s->version > SSL3_VERSION && s->version != DTLS1_BAD_VER)
 			{
 			n2s(p,i);
 			if (n != i+2)
@@ -1897,7 +2075,7 @@
 	else
 #endif
 #ifndef OPENSSL_NO_DH
-		if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
+		if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
 		{
 		n2s(p,i);
 		if (n != i+2)
@@ -1960,30 +2138,30 @@
 	else
 #endif
 #ifndef OPENSSL_NO_KRB5
-        if (l & SSL_kKRB5)
-                {
-                krb5_error_code		krb5rc;
+	if (alg_k & SSL_kKRB5)
+		{
+		krb5_error_code		krb5rc;
 		krb5_data		enc_ticket;
 		krb5_data		authenticator;
 		krb5_data		enc_pms;
-                KSSL_CTX		*kssl_ctx = s->kssl_ctx;
+		KSSL_CTX		*kssl_ctx = s->kssl_ctx;
 		EVP_CIPHER_CTX		ciph_ctx;
-		EVP_CIPHER		*enc = NULL;
+		const EVP_CIPHER	*enc = NULL;
 		unsigned char		iv[EVP_MAX_IV_LENGTH];
 		unsigned char		pms[SSL_MAX_MASTER_KEY_LENGTH
-                                               + EVP_MAX_BLOCK_LENGTH];
-		int                     padl, outl;
+					       + EVP_MAX_BLOCK_LENGTH];
+		int		     padl, outl;
 		krb5_timestamp		authtime = 0;
 		krb5_ticket_times	ttimes;
 
 		EVP_CIPHER_CTX_init(&ciph_ctx);
 
-                if (!kssl_ctx)  kssl_ctx = kssl_ctx_new();
+		if (!kssl_ctx)  kssl_ctx = kssl_ctx_new();
 
 		n2s(p,i);
 		enc_ticket.length = i;
 
-		if (n < (int)enc_ticket.length + 6)
+		if (n < (long)(enc_ticket.length + 6))
 			{
 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
 				SSL_R_DATA_LENGTH_TOO_LONG);
@@ -1996,7 +2174,7 @@
 		n2s(p,i);
 		authenticator.length = i;
 
-		if (n < (int)(enc_ticket.length + authenticator.length) + 6)
+		if (n < (long)(enc_ticket.length + authenticator.length + 6))
 			{
 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
 				SSL_R_DATA_LENGTH_TOO_LONG);
@@ -2029,19 +2207,19 @@
 			goto err;
 			}
 
-                if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes,
+		if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes,
 					&kssl_err)) != 0)
-                        {
+			{
 #ifdef KSSL_DEBUG
-                        printf("kssl_sget_tkt rtn %d [%d]\n",
-                                krb5rc, kssl_err.reason);
-                        if (kssl_err.text)
-                                printf("kssl_err text= %s\n", kssl_err.text);
+			printf("kssl_sget_tkt rtn %d [%d]\n",
+				krb5rc, kssl_err.reason);
+			if (kssl_err.text)
+				printf("kssl_err text= %s\n", kssl_err.text);
 #endif	/* KSSL_DEBUG */
-                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
-                                kssl_err.reason);
-                        goto err;
-                        }
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				kssl_err.reason);
+			goto err;
+			}
 
 		/*  Note: no authenticator is not considered an error,
 		**  but will return authtime == 0.
@@ -2050,29 +2228,29 @@
 					&authtime, &kssl_err)) != 0)
 			{
 #ifdef KSSL_DEBUG
-                        printf("kssl_check_authent rtn %d [%d]\n",
-                                krb5rc, kssl_err.reason);
-                        if (kssl_err.text)
-                                printf("kssl_err text= %s\n", kssl_err.text);
+			printf("kssl_check_authent rtn %d [%d]\n",
+				krb5rc, kssl_err.reason);
+			if (kssl_err.text)
+				printf("kssl_err text= %s\n", kssl_err.text);
 #endif	/* KSSL_DEBUG */
-                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
-                                kssl_err.reason);
-                        goto err;
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				kssl_err.reason);
+			goto err;
 			}
 
 		if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0)
 			{
 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, krb5rc);
-                        goto err;
+			goto err;
 			}
 
 #ifdef KSSL_DEBUG
-                kssl_ctx_show(kssl_ctx);
+		kssl_ctx_show(kssl_ctx);
 #endif	/* KSSL_DEBUG */
 
 		enc = kssl_map_enc(kssl_ctx->enctype);
-                if (enc == NULL)
-                    goto err;
+		if (enc == NULL)
+		    goto err;
 
 		memset(iv, 0, sizeof iv);	/* per RFC 1510 */
 
@@ -2119,7 +2297,7 @@
 		     * (Perhaps we should have a separate BUG value for the Kerberos cipher)
 		     */
 		    if (!(s->options & SSL_OP_TLS_ROLLBACK_BUG))
-		        {
+			{
 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
 			       SSL_AD_DECODE_ERROR);
 			goto err;
@@ -2128,32 +2306,32 @@
 
 		EVP_CIPHER_CTX_cleanup(&ciph_ctx);
 
-                s->session->master_key_length=
-                        s->method->ssl3_enc->generate_master_secret(s,
-                                s->session->master_key, pms, outl);
+		s->session->master_key_length=
+			s->method->ssl3_enc->generate_master_secret(s,
+				s->session->master_key, pms, outl);
 
-                if (kssl_ctx->client_princ)
-                        {
-                        size_t len = strlen(kssl_ctx->client_princ);
-                        if ( len < SSL_MAX_KRB5_PRINCIPAL_LENGTH ) 
-                                {
-                                s->session->krb5_client_princ_len = len;
-                                memcpy(s->session->krb5_client_princ,kssl_ctx->client_princ,len);
-                                }
-                        }
+		if (kssl_ctx->client_princ)
+			{
+			size_t len = strlen(kssl_ctx->client_princ);
+			if ( len < SSL_MAX_KRB5_PRINCIPAL_LENGTH ) 
+				{
+				s->session->krb5_client_princ_len = len;
+				memcpy(s->session->krb5_client_princ,kssl_ctx->client_princ,len);
+				}
+			}
 
 
-                /*  Was doing kssl_ctx_free() here,
+		/*  Was doing kssl_ctx_free() here,
 		**  but it caused problems for apache.
-                **  kssl_ctx = kssl_ctx_free(kssl_ctx);
-                **  if (s->kssl_ctx)  s->kssl_ctx = NULL;
-                */
-                }
+		**  kssl_ctx = kssl_ctx_free(kssl_ctx);
+		**  if (s->kssl_ctx)  s->kssl_ctx = NULL;
+		*/
+		}
 	else
 #endif	/* OPENSSL_NO_KRB5 */
 
 #ifndef OPENSSL_NO_ECDH
-		if ((l & SSL_kECDH) || (l & SSL_kECDHE))
+		if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe))
 		{
 		int ret = 1;
 		int field_size = 0;
@@ -2161,18 +2339,18 @@
 		const EC_GROUP *group;
 		const BIGNUM *priv_key;
 
-                /* initialize structures for server's ECDH key pair */
+		/* initialize structures for server's ECDH key pair */
 		if ((srvr_ecdh = EC_KEY_new()) == NULL) 
 			{
-                	SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
 			    ERR_R_MALLOC_FAILURE);
-                	goto err;
+			goto err;
 			}
 
 		/* Let's get server private key and group information */
-		if (l & SSL_kECDH) 
+		if (alg_k & (SSL_kECDHr|SSL_kECDHe))
 			{ 
-                        /* use the certificate */
+			/* use the certificate */
 			tkey = s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec;
 			}
 		else
@@ -2202,20 +2380,20 @@
 			goto err;
 			}
 
-                if (n == 0L) 
-                        {
+		if (n == 0L) 
+			{
 			/* Client Publickey was in Client Certificate */
 
-			 if (l & SSL_kECDHE) 
+			 if (alg_k & SSL_kEECDH)
 				 {
 				 al=SSL_AD_HANDSHAKE_FAILURE;
 				 SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_ECDH_KEY);
 				 goto f_err;
 				 }
-                        if (((clnt_pub_pkey=X509_get_pubkey(s->session->peer))
+			if (((clnt_pub_pkey=X509_get_pubkey(s->session->peer))
 			    == NULL) || 
 			    (clnt_pub_pkey->type != EVP_PKEY_EC))
-                        	{
+				{
 				/* XXX: For now, we do not support client
 				 * authentication using ECDH certificates
 				 * so this branch (n == 0L) of the code is
@@ -2227,11 +2405,11 @@
 				 * the two ECDH shares are for the same
 				 * group.
 				 */
-                           	al=SSL_AD_HANDSHAKE_FAILURE;
-                           	SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+			   	al=SSL_AD_HANDSHAKE_FAILURE;
+			   	SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
 				    SSL_R_UNABLE_TO_DECODE_ECDH_CERTS);
-                           	goto f_err;
-                           	}
+			   	goto f_err;
+			   	}
 
 			if (EC_POINT_copy(clnt_ecpoint,
 			    EC_KEY_get0_public_key(clnt_pub_pkey->pkey.ec)) == 0)
@@ -2240,10 +2418,10 @@
 					ERR_R_EC_LIB);
 				goto err;
 				}
-                        ret = 2; /* Skip certificate verify processing */
-                        }
-                else
-                        {
+			ret = 2; /* Skip certificate verify processing */
+			}
+		else
+			{
 			/* Get client's public key from encoded point
 			 * in the ClientKeyExchange message.
 			 */
@@ -2254,21 +2432,21 @@
 				goto err;
 				}
 
-                        /* Get encoded point length */
-                        i = *p; 
+			/* Get encoded point length */
+			i = *p; 
 			p += 1;
-                        if (EC_POINT_oct2point(group, 
+			if (EC_POINT_oct2point(group, 
 			    clnt_ecpoint, p, i, bn_ctx) == 0)
 				{
 				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
 				    ERR_R_EC_LIB);
 				goto err;
 				}
-                        /* p is pointing to somewhere in the buffer
-                         * currently, so set it to the start 
-                         */ 
-                        p=(unsigned char *)s->init_buf->data;
-                        }
+			/* p is pointing to somewhere in the buffer
+			 * currently, so set it to the start 
+			 */ 
+			p=(unsigned char *)s->init_buf->data;
+			}
 
 		/* Compute the shared pre-master secret */
 		field_size = EC_GROUP_get_degree(group);
@@ -2279,28 +2457,190 @@
 			goto err;
 			}
 		i = ECDH_compute_key(p, (field_size+7)/8, clnt_ecpoint, srvr_ecdh, NULL);
-                if (i <= 0)
-                        {
-                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+		if (i <= 0)
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
 			    ERR_R_ECDH_LIB);
-                        goto err;
-                        }
+			goto err;
+			}
 
 		EVP_PKEY_free(clnt_pub_pkey);
 		EC_POINT_free(clnt_ecpoint);
-		if (srvr_ecdh != NULL) 
-			EC_KEY_free(srvr_ecdh);
+		EC_KEY_free(srvr_ecdh);
 		BN_CTX_free(bn_ctx);
+		EC_KEY_free(s->s3->tmp.ecdh);
+		s->s3->tmp.ecdh = NULL; 
 
 		/* Compute the master secret */
-                s->session->master_key_length = s->method->ssl3_enc-> \
+		s->session->master_key_length = s->method->ssl3_enc-> \
 		    generate_master_secret(s, s->session->master_key, p, i);
 		
-                OPENSSL_cleanse(p, i);
-                return (ret);
+		OPENSSL_cleanse(p, i);
+		return (ret);
 		}
 	else
 #endif
+#ifndef OPENSSL_NO_PSK
+		if (alg_k & SSL_kPSK)
+			{
+			unsigned char *t = NULL;
+			unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4];
+			unsigned int pre_ms_len = 0, psk_len = 0;
+			int psk_err = 1;
+			char tmp_id[PSK_MAX_IDENTITY_LEN+1];
+
+			al=SSL_AD_HANDSHAKE_FAILURE;
+
+			n2s(p,i);
+			if (n != i+2)
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+					SSL_R_LENGTH_MISMATCH);
+				goto psk_err;
+				}
+			if (i > PSK_MAX_IDENTITY_LEN)
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+					SSL_R_DATA_LENGTH_TOO_LONG);
+				goto psk_err;
+				}
+			if (s->psk_server_callback == NULL)
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				       SSL_R_PSK_NO_SERVER_CB);
+				goto psk_err;
+				}
+
+			/* Create guaranteed NULL-terminated identity
+			 * string for the callback */
+			memcpy(tmp_id, p, i);
+			memset(tmp_id+i, 0, PSK_MAX_IDENTITY_LEN+1-i);
+			psk_len = s->psk_server_callback(s, tmp_id,
+				psk_or_pre_ms, sizeof(psk_or_pre_ms));
+			OPENSSL_cleanse(tmp_id, PSK_MAX_IDENTITY_LEN+1);
+
+			if (psk_len > PSK_MAX_PSK_LEN)
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+					ERR_R_INTERNAL_ERROR);
+				goto psk_err;
+				}
+			else if (psk_len == 0)
+				{
+				/* PSK related to the given identity not found */
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+				       SSL_R_PSK_IDENTITY_NOT_FOUND);
+				al=SSL_AD_UNKNOWN_PSK_IDENTITY;
+				goto psk_err;
+				}
+
+			/* create PSK pre_master_secret */
+			pre_ms_len=2+psk_len+2+psk_len;
+			t = psk_or_pre_ms;
+			memmove(psk_or_pre_ms+psk_len+4, psk_or_pre_ms, psk_len);
+			s2n(psk_len, t);
+			memset(t, 0, psk_len);
+			t+=psk_len;
+			s2n(psk_len, t);
+
+			if (s->session->psk_identity != NULL)
+				OPENSSL_free(s->session->psk_identity);
+			s->session->psk_identity = BUF_strdup((char *)p);
+			if (s->session->psk_identity == NULL)
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+					ERR_R_MALLOC_FAILURE);
+				goto psk_err;
+				}
+
+			if (s->session->psk_identity_hint != NULL)
+				OPENSSL_free(s->session->psk_identity_hint);
+			s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint);
+			if (s->ctx->psk_identity_hint != NULL &&
+				s->session->psk_identity_hint == NULL)
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+					ERR_R_MALLOC_FAILURE);
+				goto psk_err;
+				}
+
+			s->session->master_key_length=
+				s->method->ssl3_enc->generate_master_secret(s,
+					s->session->master_key, psk_or_pre_ms, pre_ms_len);
+			psk_err = 0;
+		psk_err:
+			OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
+			if (psk_err != 0)
+				goto f_err;
+			}
+		else
+#endif
+		if (alg_k & SSL_kGOST) 
+			{
+			int ret = 0;
+			EVP_PKEY_CTX *pkey_ctx;
+			EVP_PKEY *client_pub_pkey = NULL;
+			unsigned char premaster_secret[32], *start;
+			size_t outlen=32, inlen;			
+
+			/* Get our certificate private key*/
+			pkey_ctx = EVP_PKEY_CTX_new(s->cert->key->privatekey,NULL);	
+			EVP_PKEY_decrypt_init(pkey_ctx);
+			/* If client certificate is present and is of the same type, maybe
+			 * use it for key exchange.  Don't mind errors from
+			 * EVP_PKEY_derive_set_peer, because it is completely valid to use
+			 * a client certificate for authorization only. */
+			client_pub_pkey = X509_get_pubkey(s->session->peer);
+			if (client_pub_pkey)
+				{
+				if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0)
+					ERR_clear_error();
+				}
+			/* Decrypt session key */
+			if ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED))) 
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
+				goto gerr;
+				}
+			if (p[1] == 0x81)
+				{
+				start = p+3;
+				inlen = p[2];
+				}
+			else if (p[1] < 0x80)
+				{
+				start = p+2;
+				inlen = p[1];
+				}
+			else
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
+				goto gerr;
+				}
+			if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0) 
+
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
+				goto gerr;
+				}
+			/* Generate master secret */
+			s->session->master_key_length=
+				s->method->ssl3_enc->generate_master_secret(s,
+					s->session->master_key,premaster_secret,32);
+			/* Check if pubkey from client certificate was used */
+			if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0)
+				ret = 2;
+			else
+				ret = 1;
+		gerr:
+			EVP_PKEY_free(client_pub_pkey);
+			EVP_PKEY_CTX_free(pkey_ctx);
+			if (ret)
+				return ret;
+			else
+				goto err;
+			}
+		else
 		{
 		al=SSL_AD_HANDSHAKE_FAILURE;
 		SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
@@ -2390,15 +2730,25 @@
 
 	/* we now have a signature that we need to verify */
 	p=(unsigned char *)s->init_msg;
-	n2s(p,i);
-	n-=2;
-	if (i > n)
+	/* Check for broken implementations of GOST ciphersuites */
+	/* If key is GOST and n is exactly 64, it is bare
+	 * signature without length field */
+	if (n==64 && (pkey->type==NID_id_GostR3410_94 ||
+		pkey->type == NID_id_GostR3410_2001) )
 		{
-		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_LENGTH_MISMATCH);
-		al=SSL_AD_DECODE_ERROR;
-		goto f_err;
-		}
-
+		i=64;
+		} 
+	else 
+		{	
+		n2s(p,i);
+		n-=2;
+		if (i > n)
+			{
+			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_LENGTH_MISMATCH);
+			al=SSL_AD_DECODE_ERROR;
+			goto f_err;
+			}
+    	}
 	j=EVP_PKEY_size(pkey);
 	if ((i > j) || (n > j) || (n <= 0))
 		{
@@ -2461,6 +2811,28 @@
 		}
 	else
 #endif
+	if (pkey->type == NID_id_GostR3410_94 || pkey->type == NID_id_GostR3410_2001)
+		{   unsigned char signature[64];
+			int idx;
+			EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey,NULL);
+			EVP_PKEY_verify_init(pctx);
+			if (i!=64) {
+				fprintf(stderr,"GOST signature length is %d",i);
+			}	
+			for (idx=0;idx<64;idx++) {
+				signature[63-idx]=p[idx];
+			}	
+			j=EVP_PKEY_verify(pctx,signature,64,s->s3->tmp.cert_verify_md,32);
+			EVP_PKEY_CTX_free(pctx);
+			if (j<=0) 
+				{
+				al=SSL_AD_DECRYPT_ERROR;
+				SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,
+					SSL_R_BAD_ECDSA_SIGNATURE);
+				goto f_err;
+				}	
+		}
+	else	
 		{
 		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,ERR_R_INTERNAL_ERROR);
 		al=SSL_AD_UNSUPPORTED_CERTIFICATE;
@@ -2643,14 +3015,15 @@
 	if (s->state == SSL3_ST_SW_CERT_A)
 		{
 		x=ssl_get_server_send_cert(s);
-		if (x == NULL &&
-                        /* VRS: allow null cert if auth == KRB5 */
-                        (s->s3->tmp.new_cipher->algorithms
-                                & (SSL_MKEY_MASK|SSL_AUTH_MASK))
-                        != (SSL_aKRB5|SSL_kKRB5))
+		if (x == NULL)
 			{
-			SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
-			return(0);
+			/* VRS: allow null cert if auth == KRB5 */
+			if ((s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5) ||
+			    (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5))
+				{
+				SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
+				return(0);
+				}
 			}
 
 		l=ssl3_output_cert_chain(s,x);
@@ -2662,70 +3035,6 @@
 	/* SSL3_ST_SW_CERT_B */
 	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
 	}
-
-
-#ifndef OPENSSL_NO_ECDH
-/* This is the complement of curve_id2nid in s3_clnt.c. */
-static int nid2curve_id(int nid)
-{
-	/* ECC curves from draft-ietf-tls-ecc-01.txt (Mar 15, 2001)
-	 * (no changes in draft-ietf-tls-ecc-03.txt [June 2003]) */
-	switch (nid) {
-	case NID_sect163k1: /* sect163k1 (1) */
-		return 1;
-	case NID_sect163r1: /* sect163r1 (2) */
-		return 2;
-	case NID_sect163r2: /* sect163r2 (3) */
-		return 3;
-	case NID_sect193r1: /* sect193r1 (4) */ 
-		return 4;
-	case NID_sect193r2: /* sect193r2 (5) */ 
-		return 5;
-	case NID_sect233k1: /* sect233k1 (6) */
-		return 6;
-	case NID_sect233r1: /* sect233r1 (7) */ 
-		return 7;
-	case NID_sect239k1: /* sect239k1 (8) */ 
-		return 8;
-	case NID_sect283k1: /* sect283k1 (9) */
-		return 9;
-	case NID_sect283r1: /* sect283r1 (10) */ 
-		return 10;
-	case NID_sect409k1: /* sect409k1 (11) */ 
-		return 11;
-	case NID_sect409r1: /* sect409r1 (12) */
-		return 12;
-	case NID_sect571k1: /* sect571k1 (13) */ 
-		return 13;
-	case NID_sect571r1: /* sect571r1 (14) */ 
-		return 14;
-	case NID_secp160k1: /* secp160k1 (15) */
-		return 15;
-	case NID_secp160r1: /* secp160r1 (16) */ 
-		return 16;
-	case NID_secp160r2: /* secp160r2 (17) */ 
-		return 17;
-	case NID_secp192k1: /* secp192k1 (18) */
-		return 18;
-	case NID_X9_62_prime192v1: /* secp192r1 (19) */ 
-		return 19;
-	case NID_secp224k1: /* secp224k1 (20) */ 
-		return 20;
-	case NID_secp224r1: /* secp224r1 (21) */
-		return 21;
-	case NID_secp256k1: /* secp256k1 (22) */ 
-		return 22;
-	case NID_X9_62_prime256v1: /* secp256r1 (23) */ 
-		return 23;
-	case NID_secp384r1: /* secp384r1 (24) */
-		return 24;
-	case NID_secp521r1:  /* secp521r1 (25) */	
-		return 25;
-	default:
-		return 0;
-	}
-}
-#endif
 #ifndef OPENSSL_NO_TLSEXT
 int ssl3_send_newsession_ticket(SSL *s)
 	{
diff --git a/ssl/ssl.h b/ssl/ssl.h
index 4e4964e..7858169 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -56,60 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-/* ====================================================================
- * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -166,6 +113,32 @@
  * ECC cipher suite support in OpenSSL originally developed by 
  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 #ifndef HEADER_SSL_H 
 #define HEADER_SSL_H 
@@ -248,56 +221,88 @@
 #define SSL_MAX_KEY_ARG_LENGTH			8
 #define SSL_MAX_MASTER_KEY_LENGTH		48
 
+
 /* These are used to specify which ciphers to use and not to use */
+
+#define SSL_TXT_EXP40		"EXPORT40"
+#define SSL_TXT_EXP56		"EXPORT56"
 #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"
-#define SSL_TXT_FZA		"FZA"
+
+#define SSL_TXT_kFZA		"kFZA" /* unused! */
+#define	SSL_TXT_aFZA		"aFZA" /* unused! */
+#define SSL_TXT_eFZA		"eFZA" /* unused! */
+#define SSL_TXT_FZA		"FZA"  /* unused! */
 
 #define	SSL_TXT_aNULL		"aNULL"
 #define	SSL_TXT_eNULL		"eNULL"
 #define	SSL_TXT_NULL		"NULL"
 
-#define SSL_TXT_kKRB5     	"kKRB5"
-#define SSL_TXT_aKRB5     	"aKRB5"
-#define SSL_TXT_KRB5      	"KRB5"
-
 #define SSL_TXT_kRSA		"kRSA"
-#define SSL_TXT_kDHr		"kDHr"
-#define SSL_TXT_kDHd		"kDHd"
+#define SSL_TXT_kDHr		"kDHr" /* no such ciphersuites supported! */
+#define SSL_TXT_kDHd		"kDHd" /* no such ciphersuites supported! */
+#define SSL_TXT_kDH 		"kDH"  /* no such ciphersuites supported! */
 #define SSL_TXT_kEDH		"kEDH"
+#define SSL_TXT_kKRB5     	"kKRB5"
+#define SSL_TXT_kECDHr		"kECDHr"
+#define SSL_TXT_kECDHe		"kECDHe"
+#define SSL_TXT_kECDH		"kECDH"
+#define SSL_TXT_kEECDH		"kEECDH"
+#define SSL_TXT_kPSK            "kPSK"
+#define SSL_TXT_kGOST		"kGOST"
+
 #define	SSL_TXT_aRSA		"aRSA"
 #define	SSL_TXT_aDSS		"aDSS"
-#define	SSL_TXT_aDH		"aDH"
+#define	SSL_TXT_aDH		"aDH" /* no such ciphersuites supported! */
+#define	SSL_TXT_aECDH		"aECDH"
+#define SSL_TXT_aKRB5     	"aKRB5"
+#define SSL_TXT_aECDSA		"aECDSA"
+#define SSL_TXT_aPSK            "aPSK"
+#define SSL_TXT_aGOST94	"aGOST94"
+#define SSL_TXT_aGOST01 "aGOST01"
+#define SSL_TXT_aGOST  "aGOST"
+
 #define	SSL_TXT_DSS		"DSS"
 #define SSL_TXT_DH		"DH"
-#define SSL_TXT_EDH		"EDH"
+#define SSL_TXT_EDH		"EDH" /* same as "kEDH:-ADH" */
 #define SSL_TXT_ADH		"ADH"
 #define SSL_TXT_RSA		"RSA"
+#define SSL_TXT_ECDH		"ECDH"
+#define SSL_TXT_EECDH		"EECDH" /* same as "kEECDH:-AECDH" */
+#define SSL_TXT_AECDH		"AECDH"
+#define SSL_TXT_ECDSA		"ECDSA"
+#define SSL_TXT_KRB5      	"KRB5"
+#define SSL_TXT_PSK             "PSK"
+
 #define SSL_TXT_DES		"DES"
 #define SSL_TXT_3DES		"3DES"
 #define SSL_TXT_RC4		"RC4"
 #define SSL_TXT_RC2		"RC2"
 #define SSL_TXT_IDEA		"IDEA"
 #define SSL_TXT_SEED		"SEED"
+#define SSL_TXT_AES128		"AES128"
+#define SSL_TXT_AES256		"AES256"
 #define SSL_TXT_AES		"AES"
+#define SSL_TXT_CAMELLIA128	"CAMELLIA128"
+#define SSL_TXT_CAMELLIA256	"CAMELLIA256"
 #define SSL_TXT_CAMELLIA	"CAMELLIA"
+
 #define SSL_TXT_MD5		"MD5"
 #define SSL_TXT_SHA1		"SHA1"
-#define SSL_TXT_SHA		"SHA"
-#define SSL_TXT_EXP		"EXP"
-#define SSL_TXT_EXPORT		"EXPORT"
-#define SSL_TXT_EXP40		"EXPORT40"
-#define SSL_TXT_EXP56		"EXPORT56"
+#define SSL_TXT_SHA		"SHA" /* same as "SHA1" */
+#define SSL_TXT_GOST94		"GOST94" 
+#define SSL_TXT_GOST89MAC		"GOST89MAC" 
+
 #define SSL_TXT_SSLV2		"SSLv2"
 #define SSL_TXT_SSLV3		"SSLv3"
 #define SSL_TXT_TLSV1		"TLSv1"
+
+#define SSL_TXT_EXP		"EXP"
+#define SSL_TXT_EXPORT		"EXPORT"
+
 #define SSL_TXT_ALL		"ALL"
-#define SSL_TXT_ECC		"ECCdraft" /* ECC ciphersuites are not yet official */
 
 /*
  * COMPLEMENTOF* definitions. These identifiers are used to (de-select)
@@ -319,7 +324,13 @@
 /* The following cipher list is used by default.
  * It also is substituted when an application-defined cipher list string
  * starts with 'DEFAULT'. */
-#define SSL_DEFAULT_CIPHER_LIST	"AES:ALL:!aNULL:!eNULL:+RC4:@STRENGTH" /* low priority for RC4 */
+#define SSL_DEFAULT_CIPHER_LIST	"ALL:!aNULL:!eNULL:!SSLv2"
+/* As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always
+ * starts with a reasonable order, and all we have to do for DEFAULT is
+ * throwing out anonymous and unencrypted ciphersuites!
+ * (The latter are not actually enabled by ALL, but "ALL:RSA" would enable
+ * some of them.)
+ */
 
 /* Used in SSL_set_shutdown()/SSL_get_shutdown(); */
 #define SSL_SENT_SHUTDOWN	1
@@ -344,6 +355,7 @@
  * 'struct ssl_st *' function parameters used to prototype callbacks
  * in SSL_CTX. */
 typedef struct ssl_st *ssl_crock_st;
+typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT;
 
 /* used to hold info on the particular ciphers used */
 typedef struct ssl_cipher_st
@@ -351,17 +363,25 @@
 	int valid;
 	const char *name;		/* text name */
 	unsigned long id;		/* id, 4 bytes, first is version */
-	unsigned long algorithms;	/* what ciphers are used */
+
+	/* changed in 0.9.9: these four used to be portions of a single value 'algorithms' */
+	unsigned long algorithm_mkey;	/* key exchange algorithm */
+	unsigned long algorithm_auth;	/* server authentication */
+	unsigned long algorithm_enc;	/* symmetric encryption */
+	unsigned long algorithm_mac;	/* symmetric authentication */
+	unsigned long algorithm_ssl;	/* (major) protocol version */
+
 	unsigned long algo_strength;	/* strength and export flags */
 	unsigned long algorithm2;	/* Extra flags */
 	int strength_bits;		/* Number of bits really used */
 	int alg_bits;			/* Number of bits for algorithm */
-	unsigned long mask;		/* used for matching */
-	unsigned long mask_strength;	/* also used for matching */
 	} SSL_CIPHER;
 
 DECLARE_STACK_OF(SSL_CIPHER)
 
+typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, int len, void *arg);
+typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg);
+
 /* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
 typedef struct ssl_method_st
 	{
@@ -385,12 +405,12 @@
 	int (*ssl_dispatch_alert)(SSL *s);
 	long (*ssl_ctrl)(SSL *s,int cmd,long larg,void *parg);
 	long (*ssl_ctx_ctrl)(SSL_CTX *ctx,int cmd,long larg,void *parg);
-	SSL_CIPHER *(*get_cipher_by_char)(const unsigned char *ptr);
+	const SSL_CIPHER *(*get_cipher_by_char)(const unsigned char *ptr);
 	int (*put_cipher_by_char)(const SSL_CIPHER *cipher,unsigned char *ptr);
 	int (*ssl_pending)(const SSL *s);
 	int (*num_ciphers)(void);
-	SSL_CIPHER *(*get_cipher)(unsigned ncipher);
-	struct ssl_method_st *(*get_ssl_method)(int version);
+	const SSL_CIPHER *(*get_cipher)(unsigned ncipher);
+	const struct ssl_method_st *(*get_ssl_method)(int version);
 	long (*get_timeout)(void);
 	struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */
 	int (*ssl_version)(void);
@@ -402,17 +422,20 @@
  * SSL_SESSION_ID ::= SEQUENCE {
  *	version 		INTEGER,	-- structure version number
  *	SSLversion 		INTEGER,	-- SSL version number
- *	Cipher 			OCTET_STRING,	-- the 3 byte cipher ID
- *	Session_ID 		OCTET_STRING,	-- the Session ID
- *	Master_key 		OCTET_STRING,	-- the master key
- *	KRB5_principal		OCTET_STRING	-- optional Kerberos principal
- *	Key_Arg [ 0 ] IMPLICIT	OCTET_STRING,	-- the optional Key argument
+ *	Cipher 			OCTET STRING,	-- the 3 byte cipher ID
+ *	Session_ID 		OCTET STRING,	-- the Session ID
+ *	Master_key 		OCTET STRING,	-- the master key
+ *	KRB5_principal		OCTET STRING	-- optional Kerberos principal
+ *	Key_Arg [ 0 ] IMPLICIT	OCTET STRING,	-- the optional Key argument
  *	Time [ 1 ] EXPLICIT	INTEGER,	-- optional Start Time
  *	Timeout [ 2 ] EXPLICIT	INTEGER,	-- optional Timeout ins seconds
  *	Peer [ 3 ] EXPLICIT	X509,		-- optional Peer Certificate
- *	Session_ID_context [ 4 ] EXPLICIT OCTET_STRING,   -- the Session ID context
- *	Verify_result [ 5 ] EXPLICIT INTEGER    -- X509_V_... code for `Peer'
- *	Compression [6] IMPLICIT ASN1_OBJECT	-- compression OID XXXXX
+ *	Session_ID_context [ 4 ] EXPLICIT OCTET STRING,   -- the Session ID context
+ *	Verify_result [ 5 ] EXPLICIT INTEGER,   -- X509_V_... code for `Peer'
+ *	HostName [ 6 ] EXPLICIT OCTET STRING,   -- optional HostName from servername TLS extension 
+ *	ECPointFormatList [ 7 ] OCTET STRING,     -- optional EC point format list from TLS extension
+ *	PSK_identity_hint [ 8 ] EXPLICIT OCTET STRING, -- optional PSK identity hint
+ *	PSK_identity [ 9 ] EXPLICIT OCTET STRING -- optional PSK identity
  *	}
  * Look in ssl/ssl_asn1.c for more details
  * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-).
@@ -440,7 +463,10 @@
         unsigned int krb5_client_princ_len;
         unsigned char krb5_client_princ[SSL_MAX_KRB5_PRINCIPAL_LENGTH];
 #endif /* OPENSSL_NO_KRB5 */
-
+#ifndef OPENSSL_NO_PSK
+	char *psk_identity_hint;
+	char *psk_identity;
+#endif
 	int not_resumable;
 
 	/* The cert is the certificate used to establish this connection */
@@ -459,9 +485,9 @@
 	long timeout;
 	long time;
 
-	int compress_meth;		/* Need to lookup the method */
+	unsigned int compress_meth;	/* Need to lookup the method */
 
-	SSL_CIPHER *cipher;
+	const SSL_CIPHER *cipher;
 	unsigned long cipher_id;	/* when ASN.1 loaded, this
 					 * needs to be used to load
 					 * the 'cipher' structure */
@@ -475,6 +501,12 @@
 	struct ssl_session_st *prev,*next;
 #ifndef OPENSSL_NO_TLSEXT
 	char *tlsext_hostname;
+#ifndef OPENSSL_NO_EC
+	size_t tlsext_ecpointformatlist_length;
+	unsigned char *tlsext_ecpointformatlist; /* peer's list */
+	size_t tlsext_ellipticcurvelist_length;
+	unsigned char *tlsext_ellipticcurvelist; /* peer's list */
+#endif /* OPENSSL_NO_EC */
 	/* RFC4507 info */
 	unsigned char *tlsext_tick;	/* Session ticket */
 	size_t	tlsext_ticklen;		/* Session ticket length */	
@@ -504,7 +536,7 @@
 
 /* SSL_OP_ALL: various bug workarounds that should be rather harmless.
  *             This used to be 0x000FFFFFL before 0.9.7. */
-#define SSL_OP_ALL					0x00000FFFL
+#define SSL_OP_ALL					0x80000FFFL
 
 /* DTLS options */
 #define SSL_OP_NO_QUERY_MTU                 0x00001000L
@@ -517,6 +549,8 @@
 
 /* As server, disallow session resumption on renegotiation */
 #define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION	0x00010000L
+/* Don't use compression even if supported */
+#define SSL_OP_NO_COMPRESSION				0x00020000L
 /* Permit unsafe legacy renegotiation */
 #define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION	0x00040000L
 /* If set, always create a new key when using tmp_ecdh parameters */
@@ -545,7 +579,11 @@
 #define SSL_OP_PKCS1_CHECK_2				0x10000000L
 #define SSL_OP_NETSCAPE_CA_DN_BUG			0x20000000L
 #define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG		0x40000000L
-
+/* Make server add server-hello extension from early version of
+ * cryptopro draft, when GOST ciphersuite is negotiated. 
+ * Required for interoperability with CryptoPro CSP 3.x 
+ */
+#define SSL_OP_CRYPTOPRO_TLSEXT_BUG			0x80000000L
 
 /* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success
  * when just a single record has been written): */
@@ -560,9 +598,13 @@
 #define SSL_MODE_AUTO_RETRY 0x00000004L
 /* Don't attempt to automatically build certificate chain */
 #define SSL_MODE_NO_AUTO_CHAIN 0x00000008L
+/* Save RAM by releasing read and write buffers when they're empty. (SSL3 and
+ * TLS only.)  "Released" buffers are put onto a free-list in the context
+ * or just freed (depending on the context's setting for freelist_max_len). */
+#define SSL_MODE_RELEASE_BUFFERS 0x00000010L
 /* Use small read and write buffers: (a) lazy allocate read buffers for
  * large incoming records, and (b) limit the size of outgoing records. */
-#define SSL_MODE_SMALL_BUFFERS 0x00000010L
+#define SSL_MODE_SMALL_BUFFERS 0x00000020L
 
 /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
  * they cannot be used to clear bits. */
@@ -641,17 +683,18 @@
 	} SSL_COMP;
 
 DECLARE_STACK_OF(SSL_COMP)
+DECLARE_LHASH_OF(SSL_SESSION);
 
 struct ssl_ctx_st
 	{
-	SSL_METHOD *method;
+	const SSL_METHOD *method;
 
 	STACK_OF(SSL_CIPHER) *cipher_list;
 	/* same as above but sorted for lookup */
 	STACK_OF(SSL_CIPHER) *cipher_list_by_id;
 
 	struct x509_store_st /* X509_STORE */ *cert_store;
-	struct lhash_st /* LHASH */ *sessions;	/* a set of SSL_SESSIONs */
+	LHASH_OF(SSL_SESSION) *sessions;
 	/* Most session-ids that will be cached, default is
 	 * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. */
 	unsigned long session_cache_size;
@@ -776,6 +819,12 @@
 
 	int quiet_shutdown;
 
+	/* Maximum amount of data to send in one fragment.
+	 * actual record size can be more than this due to
+	 * padding and MAC overheads.
+	 */
+	unsigned int max_send_fragment;
+
 #ifndef OPENSSL_ENGINE
 	/* Engine to pass requests for client certs to
 	 */
@@ -794,14 +843,33 @@
 	int (*tlsext_ticket_key_cb)(SSL *ssl,
 					unsigned char *name, unsigned char *iv,
 					EVP_CIPHER_CTX *ectx,
-					HMAC_CTX *hctx, int enc);
+ 					HMAC_CTX *hctx, int enc);
 
 	/* certificate status request info */
 	/* Callback for status request */
 	int (*tlsext_status_cb)(SSL *ssl, void *arg);
 	void *tlsext_status_arg;
+
+	/* draft-rescorla-tls-opaque-prf-input-00.txt information */
+	int (*tlsext_opaque_prf_input_callback)(SSL *, void *peerinput, size_t len, void *arg);
+	void *tlsext_opaque_prf_input_callback_arg;
 #endif
 
+#ifndef OPENSSL_NO_PSK
+	char *psk_identity_hint;
+	unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, char *identity,
+		unsigned int max_identity_len, unsigned char *psk,
+		unsigned int max_psk_len);
+	unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
+		unsigned char *psk, unsigned int max_psk_len);
+#endif
+
+#ifndef OPENSSL_NO_BUF_FREELISTS
+#define SSL_MAX_BUF_FREELIST_LEN_DEFAULT 32
+	unsigned int freelist_max_len;
+	struct ssl3_buf_freelist_st *wbuf_freelist;
+	struct ssl3_buf_freelist_st *rbuf_freelist;
+#endif
 	};
 
 #define SSL_SESS_CACHE_OFF			0x0000
@@ -815,7 +883,7 @@
 #define SSL_SESS_CACHE_NO_INTERNAL \
 	(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE)
 
-  struct lhash_st *SSL_CTX_sessions(SSL_CTX *ctx);
+LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
 #define SSL_CTX_sess_number(ctx) \
 	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL)
 #define SSL_CTX_sess_connect(ctx) \
@@ -857,6 +925,31 @@
 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));
 
+#ifndef OPENSSL_NO_PSK
+/* the maximum length of the buffer given to callbacks containing the
+ * resulting identity/psk */
+#define PSK_MAX_IDENTITY_LEN 128
+#define PSK_MAX_PSK_LEN 256
+void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, 
+	unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, 
+		char *identity, unsigned int max_identity_len, unsigned char *psk,
+		unsigned int max_psk_len));
+void SSL_set_psk_client_callback(SSL *ssl, 
+	unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, 
+		char *identity, unsigned int max_identity_len, unsigned char *psk,
+		unsigned int max_psk_len));
+void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, 
+	unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
+		unsigned char *psk, unsigned int max_psk_len));
+void SSL_set_psk_server_callback(SSL *ssl,
+	unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
+		unsigned char *psk, unsigned int max_psk_len));
+int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint);
+int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint);
+const char *SSL_get_psk_identity_hint(const SSL *s);
+const char *SSL_get_psk_identity(const SSL *s);
+#endif
+
 #define SSL_NOTHING	1
 #define SSL_WRITING	2
 #define SSL_READING	3
@@ -868,6 +961,9 @@
 #define SSL_want_write(s)	(SSL_want(s) == SSL_WRITING)
 #define SSL_want_x509_lookup(s)	(SSL_want(s) == SSL_X509_LOOKUP)
 
+#define SSL_MAC_FLAG_READ_MAC_STREAM 1
+#define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
+
 struct ssl_st
 	{
 	/* protocol version
@@ -876,7 +972,7 @@
 	int version;
 	int type; /* SSL_ST_CONNECT or SSL_ST_ACCEPT */
 
-	SSL_METHOD *method; /* SSLv3 */
+	const SSL_METHOD *method; /* SSLv3 */
 
 	/* There are 2 BIO's even though they are normally both the
 	 * same.  This is so data can be read and written to different
@@ -959,9 +1055,9 @@
 
 	/* These are the ones being used, the ones in SSL_SESSION are
 	 * the ones to be 'copied' into these ones */
-
+	int mac_flags; 
 	EVP_CIPHER_CTX *enc_read_ctx;		/* cryptographic state */
-	const EVP_MD *read_hash;		/* used for mac generation */
+	EVP_MD_CTX *read_hash;		/* used for mac generation */
 #ifndef OPENSSL_NO_COMP
 	COMP_CTX *expand;			/* uncompress */
 #else
@@ -969,7 +1065,7 @@
 #endif
 
 	EVP_CIPHER_CTX *enc_write_ctx;		/* cryptographic state */
-	const EVP_MD *write_hash;		/* used for mac generation */
+	EVP_MD_CTX *write_hash;		/* used for mac generation */
 #ifndef OPENSSL_NO_COMP
 	COMP_CTX *compress;			/* compression */
 #else
@@ -1007,6 +1103,14 @@
 	KSSL_CTX *kssl_ctx;     /* Kerberos 5 context */
 #endif	/* OPENSSL_NO_KRB5 */
 
+#ifndef OPENSSL_NO_PSK
+	unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, char *identity,
+		unsigned int max_identity_len, unsigned char *psk,
+		unsigned int max_psk_len);
+	unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
+		unsigned char *psk, unsigned int max_psk_len);
+#endif
+
 	SSL_CTX *ctx;
 	/* set this flag to 1 and a sleep(1) is put into all SSL_read()
 	 * and SSL_write() calls, good for nbio debuging :-) */
@@ -1026,6 +1130,7 @@
 	int first_packet;
 	int client_version;	/* what was passed, used for
 				 * SSLv3/TLS rollback check */
+	unsigned int max_send_fragment;
 #ifndef OPENSSL_NO_TLSEXT
 	/* TLS extension debug callback */
 	void (*tlsext_debug_cb)(SSL *s, int client_server, int type,
@@ -1052,11 +1157,33 @@
 
 	/* RFC4507 session ticket expected to be received or sent */
 	int tlsext_ticket_expected;
+#ifndef OPENSSL_NO_EC
+	size_t tlsext_ecpointformatlist_length;
+	unsigned char *tlsext_ecpointformatlist; /* our list */
+	size_t tlsext_ellipticcurvelist_length;
+	unsigned char *tlsext_ellipticcurvelist; /* our list */
+#endif /* OPENSSL_NO_EC */
+
+	/* draft-rescorla-tls-opaque-prf-input-00.txt information to be used for handshakes */
+	void *tlsext_opaque_prf_input;
+	size_t tlsext_opaque_prf_input_len;
+
+	/* TLS Session Ticket extension override */
+	TLS_SESSION_TICKET_EXT *tlsext_session_ticket;
+
+	/* TLS Session Ticket extension callback */
+	tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb;
+	void *tls_session_ticket_ext_cb_arg;
+
+	/* TLS pre-shared secret session resumption */
+	tls_session_secret_cb_fn tls_session_secret_cb;
+	void *tls_session_secret_cb_arg;
+
 	SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */
 #define session_ctx initial_ctx
 #else
 #define session_ctx ctx
-#endif
+#endif /* OPENSSL_NO_TLSEXT */
 	};
 
 #ifdef __cplusplus
@@ -1163,20 +1290,13 @@
 #define SSL_get_timeout(a)	SSL_SESSION_get_timeout(a)
 #define SSL_set_timeout(a,b)	SSL_SESSION_set_timeout((a),(b))
 
-#if 1 /*SSLEAY_MACROS*/
 #define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id)
 #define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id)
-#define PEM_read_SSL_SESSION(fp,x,cb,u) (SSL_SESSION *)PEM_ASN1_read( \
-	(char *(*)())d2i_SSL_SESSION,PEM_STRING_SSL_SESSION,fp,(char **)x,cb,u)
-#define PEM_read_bio_SSL_SESSION(bp,x,cb,u) PEM_ASN1_read_bio_of(SSL_SESSION,d2i_SSL_SESSION,PEM_STRING_SSL_SESSION,bp,x,cb,u)
-#define PEM_write_SSL_SESSION(fp,x) \
-	PEM_ASN1_write((int (*)())i2d_SSL_SESSION, \
-		PEM_STRING_SSL_SESSION,fp, (char *)x, NULL,NULL,0,NULL,NULL)
-#define PEM_write_bio_SSL_SESSION(bp,x) \
-	PEM_ASN1_write_bio_of(SSL_SESSION,i2d_SSL_SESSION,PEM_STRING_SSL_SESSION,bp,x,NULL,NULL,0,NULL,NULL)
-#endif
 
-#define SSL_AD_REASON_OFFSET		1000
+DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
+
+#define SSL_AD_REASON_OFFSET		1000 /* offset to get SSL_R_... value from SSL_AD_... */
+
 /* These alert types are for SSLv3 and TLSv1 */
 #define SSL_AD_CLOSE_NOTIFY		SSL3_AD_CLOSE_NOTIFY
 #define SSL_AD_UNEXPECTED_MESSAGE	SSL3_AD_UNEXPECTED_MESSAGE /* fatal */
@@ -1206,6 +1326,8 @@
 #define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE
 #define SSL_AD_UNRECOGNIZED_NAME	TLS1_AD_UNRECOGNIZED_NAME
 #define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
+#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
+#define SSL_AD_UNKNOWN_PSK_IDENTITY     TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */
 
 #define SSL_ERROR_NONE			0
 #define SSL_ERROR_SSL			1
@@ -1264,6 +1386,8 @@
 #define SSL_CTRL_GET_MAX_CERT_LIST		50
 #define SSL_CTRL_SET_MAX_CERT_LIST		51
 
+#define SSL_CTRL_SET_MAX_SEND_FRAGMENT		52
+
 /* see tls1.h for macros based on these */
 #ifndef OPENSSL_NO_TLSEXT
 #define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB	53
@@ -1273,7 +1397,9 @@
 #define SSL_CTRL_SET_TLSEXT_DEBUG_ARG		57
 #define SSL_CTRL_GET_TLSEXT_TICKET_KEYS		58
 #define SSL_CTRL_SET_TLSEXT_TICKET_KEYS		59
-
+#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT	60
+#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB	61
+#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62
 #define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB	63
 #define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG	64
 #define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE	65
@@ -1343,7 +1469,7 @@
 #endif
 
 int	SSL_CTX_set_cipher_list(SSL_CTX *,const char *str);
-SSL_CTX *SSL_CTX_new(SSL_METHOD *meth);
+SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth);
 void	SSL_CTX_free(SSL_CTX *);
 long SSL_CTX_set_timeout(SSL_CTX *ctx,long t);
 long SSL_CTX_get_timeout(const SSL_CTX *ctx);
@@ -1354,7 +1480,7 @@
 
 void	SSL_CTX_flush_sessions(SSL_CTX *ctx,long tm);
 
-SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
+const SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
 int	SSL_CIPHER_get_bits(const SSL_CIPHER *c,int *alg_bits);
 char *	SSL_CIPHER_get_version(const SSL_CIPHER *c);
 const char *	SSL_CIPHER_get_name(const SSL_CIPHER *c);
@@ -1425,9 +1551,8 @@
 void	SSL_copy_session_id(SSL *to,const SSL *from);
 
 SSL_SESSION *SSL_SESSION_new(void);
-unsigned long SSL_SESSION_hash(const SSL_SESSION *a);
-int	SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b);
-const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len);
+const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
+					unsigned int *len);
 #ifndef OPENSSL_NO_FP_API
 int	SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses);
 #endif
@@ -1487,6 +1612,9 @@
 int SSL_CTX_set_trust(SSL_CTX *s, int trust);
 int SSL_set_trust(SSL *s, int trust);
 
+int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm);
+int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm);
+
 void	SSL_free(SSL *ssl);
 int 	SSL_accept(SSL *ssl);
 int 	SSL_connect(SSL *ssl);
@@ -1502,27 +1630,29 @@
 const char *SSL_get_version(const SSL *s);
 
 /* This sets the 'default' SSL version that SSL_new() will create */
-int SSL_CTX_set_ssl_version(SSL_CTX *ctx,SSL_METHOD *meth);
+int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth);
 
-SSL_METHOD *SSLv2_method(void);		/* SSLv2 */
-SSL_METHOD *SSLv2_server_method(void);	/* SSLv2 */
-SSL_METHOD *SSLv2_client_method(void);	/* SSLv2 */
+#ifndef OPENSSL_NO_SSL2
+const SSL_METHOD *SSLv2_method(void);		/* SSLv2 */
+const SSL_METHOD *SSLv2_server_method(void);	/* SSLv2 */
+const SSL_METHOD *SSLv2_client_method(void);	/* SSLv2 */
+#endif
 
-SSL_METHOD *SSLv3_method(void);		/* SSLv3 */
-SSL_METHOD *SSLv3_server_method(void);	/* SSLv3 */
-SSL_METHOD *SSLv3_client_method(void);	/* SSLv3 */
+const SSL_METHOD *SSLv3_method(void);		/* SSLv3 */
+const SSL_METHOD *SSLv3_server_method(void);	/* SSLv3 */
+const SSL_METHOD *SSLv3_client_method(void);	/* SSLv3 */
 
-SSL_METHOD *SSLv23_method(void);	/* SSLv3 but can rollback to v2 */
-SSL_METHOD *SSLv23_server_method(void);	/* SSLv3 but can rollback to v2 */
-SSL_METHOD *SSLv23_client_method(void);	/* SSLv3 but can rollback to v2 */
+const SSL_METHOD *SSLv23_method(void);	/* SSLv3 but can rollback to v2 */
+const SSL_METHOD *SSLv23_server_method(void);	/* SSLv3 but can rollback to v2 */
+const SSL_METHOD *SSLv23_client_method(void);	/* SSLv3 but can rollback to v2 */
 
-SSL_METHOD *TLSv1_method(void);		/* TLSv1.0 */
-SSL_METHOD *TLSv1_server_method(void);	/* TLSv1.0 */
-SSL_METHOD *TLSv1_client_method(void);	/* TLSv1.0 */
+const SSL_METHOD *TLSv1_method(void);		/* TLSv1.0 */
+const SSL_METHOD *TLSv1_server_method(void);	/* TLSv1.0 */
+const SSL_METHOD *TLSv1_client_method(void);	/* TLSv1.0 */
 
-SSL_METHOD *DTLSv1_method(void);		/* DTLSv1.0 */
-SSL_METHOD *DTLSv1_server_method(void);	/* DTLSv1.0 */
-SSL_METHOD *DTLSv1_client_method(void);	/* DTLSv1.0 */
+const SSL_METHOD *DTLSv1_method(void);		/* DTLSv1.0 */
+const SSL_METHOD *DTLSv1_server_method(void);	/* DTLSv1.0 */
+const SSL_METHOD *DTLSv1_client_method(void);	/* DTLSv1.0 */
 
 STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
 
@@ -1531,8 +1661,8 @@
 int SSL_renegotiate_pending(SSL *s);
 int SSL_shutdown(SSL *s);
 
-SSL_METHOD *SSL_get_ssl_method(SSL *s);
-int SSL_set_ssl_method(SSL *s,SSL_METHOD *method);
+const SSL_METHOD *SSL_get_ssl_method(SSL *s);
+int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method);
 const char *SSL_alert_type_string_long(int value);
 const char *SSL_alert_type_string(int value);
 const char *SSL_alert_desc_string_long(int value);
@@ -1624,6 +1754,11 @@
 #define SSL_set_max_cert_list(ssl,m) \
 	SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
 
+#define SSL_CTX_set_max_send_fragment(ctx,m) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL)
+#define SSL_set_max_send_fragment(ssl,m) \
+	SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL)
+
      /* NB: the keylength is only applicable when is_export is true */
 #ifndef OPENSSL_NO_RSA
 void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
@@ -1665,6 +1800,15 @@
 int SSL_COMP_add_compression_method(int id,void *cm);
 #endif
 
+/* TLS extensions functions */
+int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len);
+
+int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
+				  void *arg);
+
+/* Pre-shared secret session resumption functions */
+int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg);
+
 /* 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.
@@ -1682,7 +1826,7 @@
 #define SSL_F_DO_DTLS1_WRITE				 245
 #define SSL_F_DO_SSL3_WRITE				 104
 #define SSL_F_DTLS1_ACCEPT				 246
-#define SSL_F_DTLS1_ADD_CERT_TO_BUF			 280
+#define SSL_F_DTLS1_ADD_CERT_TO_BUF			 295
 #define SSL_F_DTLS1_BUFFER_RECORD			 247
 #define SSL_F_DTLS1_CLIENT_HELLO			 248
 #define SSL_F_DTLS1_CONNECT				 249
@@ -1691,9 +1835,9 @@
 #define SSL_F_DTLS1_GET_MESSAGE				 252
 #define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT		 253
 #define SSL_F_DTLS1_GET_RECORD				 254
-#define SSL_F_DTLS1_HANDLE_TIMEOUT			 282
+#define SSL_F_DTLS1_HANDLE_TIMEOUT			 297
 #define SSL_F_DTLS1_OUTPUT_CERT_CHAIN			 255
-#define SSL_F_DTLS1_PREPROCESS_FRAGMENT			 277
+#define SSL_F_DTLS1_PREPROCESS_FRAGMENT			 288
 #define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE		 256
 #define SSL_F_DTLS1_PROCESS_RECORD			 257
 #define SSL_F_DTLS1_READ_BYTES				 258
@@ -1737,7 +1881,7 @@
 #define SSL_F_SSL2_SET_CERTIFICATE			 126
 #define SSL_F_SSL2_WRITE				 127
 #define SSL_F_SSL3_ACCEPT				 128
-#define SSL_F_SSL3_ADD_CERT_TO_BUF			 281
+#define SSL_F_SSL3_ADD_CERT_TO_BUF			 296
 #define SSL_F_SSL3_CALLBACK_CTRL			 233
 #define SSL_F_SSL3_CHANGE_CIPHER_STATE			 129
 #define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM		 130
@@ -1745,11 +1889,12 @@
 #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_DIGEST_CACHED_RECORDS		 293
+#define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC		 292
 #define SSL_F_SSL3_ENC					 134
 #define SSL_F_SSL3_GENERATE_KEY_BLOCK			 238
 #define SSL_F_SSL3_GET_CERTIFICATE_REQUEST		 135
-#define SSL_F_SSL3_GET_CERT_STATUS			 288
+#define SSL_F_SSL3_GET_CERT_STATUS			 289
 #define SSL_F_SSL3_GET_CERT_VERIFY			 136
 #define SSL_F_SSL3_GET_CLIENT_CERTIFICATE		 137
 #define SSL_F_SSL3_GET_CLIENT_HELLO			 138
@@ -1762,7 +1907,8 @@
 #define SSL_F_SSL3_GET_SERVER_CERTIFICATE		 144
 #define SSL_F_SSL3_GET_SERVER_DONE			 145
 #define SSL_F_SSL3_GET_SERVER_HELLO			 146
-#define SSL_F_SSL3_NEW_SESSION_TICKET			 284
+#define SSL_F_SSL3_HANDSHAKE_MAC			 285
+#define SSL_F_SSL3_NEW_SESSION_TICKET			 287
 #define SSL_F_SSL3_OUTPUT_CERT_CHAIN			 147
 #define SSL_F_SSL3_PEEK					 235
 #define SSL_F_SSL3_READ_BYTES				 148
@@ -1774,16 +1920,17 @@
 #define SSL_F_SSL3_SEND_SERVER_CERTIFICATE		 154
 #define SSL_F_SSL3_SEND_SERVER_HELLO			 242
 #define SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE		 155
-#define SSL_F_SSL3_SETUP_BUFFERS			 156
 #define SSL_F_SSL3_SETUP_KEY_BLOCK			 157
+#define SSL_F_SSL3_SETUP_READ_BUFFER			 156
+#define SSL_F_SSL3_SETUP_WRITE_BUFFER			 291
 #define SSL_F_SSL3_WRITE_BYTES				 158
 #define SSL_F_SSL3_WRITE_PENDING			 159
-#define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT	 285
-#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT		 272
+#define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT	 298
+#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT		 277
 #define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK	 215
 #define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK	 216
-#define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT	 286
-#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT		 273
+#define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT	 299
+#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT		 278
 #define SSL_F_SSL_BAD_METHOD				 160
 #define SSL_F_SSL_BYTES_TO_CIPHER_LIST			 161
 #define SSL_F_SSL_CERT_DUP				 221
@@ -1791,7 +1938,8 @@
 #define SSL_F_SSL_CERT_INSTANTIATE			 214
 #define SSL_F_SSL_CERT_NEW				 162
 #define SSL_F_SSL_CHECK_PRIVATE_KEY			 163
-#define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT		 274
+#define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT		 280
+#define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG		 279
 #define SSL_F_SSL_CIPHER_PROCESS_RULESTR		 230
 #define SSL_F_SSL_CIPHER_STRENGTH_SORT			 231
 #define SSL_F_SSL_CLEAR					 164
@@ -1801,7 +1949,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_CLIENT_CERT_ENGINE		 290
 #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
@@ -1813,6 +1961,7 @@
 #define SSL_F_SSL_CTX_USE_PRIVATEKEY			 174
 #define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1		 175
 #define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE		 176
+#define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT		 272
 #define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY			 177
 #define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1		 178
 #define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE		 179
@@ -1824,13 +1973,13 @@
 #define SSL_F_SSL_INIT_WBIO_BUFFER			 184
 #define SSL_F_SSL_LOAD_CLIENT_CA_FILE			 185
 #define SSL_F_SSL_NEW					 186
-#define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT	 287
-#define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT		 290
-#define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT	 289
-#define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT		 291
+#define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT	 300
+#define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT		 302
+#define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT	 301
+#define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT		 303
 #define SSL_F_SSL_PEEK					 270
-#define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT		 275
-#define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT		 276
+#define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT		 281
+#define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT		 282
 #define SSL_F_SSL_READ					 223
 #define SSL_F_SSL_RSA_PRIVATE_DECRYPT			 187
 #define SSL_F_SSL_RSA_PUBLIC_ENCRYPT			 188
@@ -1845,6 +1994,7 @@
 #define SSL_F_SSL_SET_RFD				 194
 #define SSL_F_SSL_SET_SESSION				 195
 #define SSL_F_SSL_SET_SESSION_ID_CONTEXT		 218
+#define SSL_F_SSL_SET_SESSION_TICKET_EXT		 294
 #define SSL_F_SSL_SET_TRUST				 228
 #define SSL_F_SSL_SET_WFD				 196
 #define SSL_F_SSL_SHUTDOWN				 224
@@ -1857,13 +2007,19 @@
 #define SSL_F_SSL_USE_PRIVATEKEY			 201
 #define SSL_F_SSL_USE_PRIVATEKEY_ASN1			 202
 #define SSL_F_SSL_USE_PRIVATEKEY_FILE			 203
+#define SSL_F_SSL_USE_PSK_IDENTITY_HINT			 273
 #define SSL_F_SSL_USE_RSAPRIVATEKEY			 204
 #define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1		 205
 #define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE		 206
 #define SSL_F_SSL_VERIFY_CERT_CHAIN			 207
 #define SSL_F_SSL_WRITE					 208
+#define SSL_F_TLS1_CERT_VERIFY_MAC			 286
 #define SSL_F_TLS1_CHANGE_CIPHER_STATE			 209
+#define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT		 274
 #define SSL_F_TLS1_ENC					 210
+#define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT		 275
+#define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT		 276
+#define SSL_F_TLS1_PRF					 284
 #define SSL_F_TLS1_SETUP_KEY_BLOCK			 211
 #define SSL_F_WRITE_PENDING				 212
 
@@ -1884,12 +2040,15 @@
 #define SSL_R_BAD_ECC_CERT				 304
 #define SSL_R_BAD_ECDSA_SIGNATURE			 305
 #define SSL_R_BAD_ECPOINT				 306
+#define SSL_R_BAD_HANDSHAKE_LENGTH			 332
 #define SSL_R_BAD_HELLO_REQUEST				 105
 #define SSL_R_BAD_LENGTH				 271
 #define SSL_R_BAD_MAC_DECODE				 113
+#define SSL_R_BAD_MAC_LENGTH				 333
 #define SSL_R_BAD_MESSAGE_TYPE				 114
 #define SSL_R_BAD_PACKET_LENGTH				 115
 #define SSL_R_BAD_PROTOCOL_VERSION_NUMBER		 116
+#define SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH		 316
 #define SSL_R_BAD_RESPONSE_ARGUMENT			 117
 #define SSL_R_BAD_RSA_DECRYPT				 118
 #define SSL_R_BAD_RSA_ENCRYPT				 119
@@ -1913,8 +2072,9 @@
 #define SSL_R_CIPHER_CODE_WRONG_LENGTH			 137
 #define SSL_R_CIPHER_OR_HASH_UNAVAILABLE		 138
 #define SSL_R_CIPHER_TABLE_SRC_ERROR			 139
-#define SSL_R_CLIENTHELLO_TLSEXT			 157
+#define SSL_R_CLIENTHELLO_TLSEXT			 226
 #define SSL_R_COMPRESSED_LENGTH_TOO_LONG		 140
+#define SSL_R_COMPRESSION_DISABLED			 343
 #define SSL_R_COMPRESSION_FAILURE			 141
 #define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE	 307
 #define SSL_R_COMPRESSION_LIBRARY_ERROR			 142
@@ -1927,8 +2087,12 @@
 #define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC	 281
 #define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG		 148
 #define SSL_R_DIGEST_CHECK_FAILED			 149
-#define SSL_R_DTLS_MESSAGE_TOO_BIG			 318
+#define SSL_R_DTLS_MESSAGE_TOO_BIG			 334
 #define SSL_R_DUPLICATE_COMPRESSION_ID			 309
+#define SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT		 317
+#define SSL_R_ECC_CERT_NOT_FOR_SIGNING			 318
+#define SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE	 322
+#define SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE	 323
 #define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER		 310
 #define SSL_R_ENCRYPTED_LENGTH_TOO_LONG			 150
 #define SSL_R_ERROR_GENERATING_TMP_RSA_KEY		 282
@@ -1939,11 +2103,13 @@
 #define SSL_R_HTTPS_PROXY_REQUEST			 155
 #define SSL_R_HTTP_REQUEST				 156
 #define SSL_R_ILLEGAL_PADDING				 283
+#define SSL_R_INCONSISTENT_COMPRESSION			 340
 #define SSL_R_INVALID_CHALLENGE_LENGTH			 158
 #define SSL_R_INVALID_COMMAND				 280
+#define SSL_R_INVALID_COMPRESSION_ALGORITHM		 341
 #define SSL_R_INVALID_PURPOSE				 278
-#define SSL_R_INVALID_STATUS_RESPONSE			 316
-#define SSL_R_INVALID_TICKET_KEYS_LENGTH		 275
+#define SSL_R_INVALID_STATUS_RESPONSE			 328
+#define SSL_R_INVALID_TICKET_KEYS_LENGTH		 325
 #define SSL_R_INVALID_TRUST				 279
 #define SSL_R_KEY_ARG_TOO_LONG				 284
 #define SSL_R_KRB5					 285
@@ -1987,23 +2153,27 @@
 #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_METHOD			 331
 #define SSL_R_NO_CLIENT_CERT_RECEIVED			 186
 #define SSL_R_NO_COMPRESSION_SPECIFIED			 187
+#define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER		 330
 #define SSL_R_NO_METHOD_SPECIFIED			 188
 #define SSL_R_NO_PRIVATEKEY				 189
 #define SSL_R_NO_PRIVATE_KEY_ASSIGNED			 190
 #define SSL_R_NO_PROTOCOLS_AVAILABLE			 191
 #define SSL_R_NO_PUBLICKEY				 192
-#define SSL_R_NO_RENEGOTIATION				 319
+#define SSL_R_NO_RENEGOTIATION				 339
+#define SSL_R_NO_REQUIRED_DIGEST			 324
 #define SSL_R_NO_SHARED_CIPHER				 193
 #define SSL_R_NO_VERIFY_CALLBACK			 194
 #define SSL_R_NULL_SSL_CTX				 195
 #define SSL_R_NULL_SSL_METHOD_PASSED			 196
 #define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED		 197
+#define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344
 #define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE		 297
+#define SSL_R_OPAQUE_PRF_INPUT_TOO_LONG			 327
 #define SSL_R_PACKET_LENGTH_TOO_LONG			 198
-#define SSL_R_PARSE_TLSEXT				 223
+#define SSL_R_PARSE_TLSEXT				 227
 #define SSL_R_PATH_TOO_LONG				 270
 #define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE		 199
 #define SSL_R_PEER_ERROR				 200
@@ -2014,6 +2184,9 @@
 #define SSL_R_PRE_MAC_LENGTH_TOO_LONG			 205
 #define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS		 206
 #define SSL_R_PROTOCOL_IS_SHUTDOWN			 207
+#define SSL_R_PSK_IDENTITY_NOT_FOUND			 223
+#define SSL_R_PSK_NO_CLIENT_CB				 224
+#define SSL_R_PSK_NO_SERVER_CB				 225
 #define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR			 208
 #define SSL_R_PUBLIC_KEY_IS_NOT_RSA			 209
 #define SSL_R_PUBLIC_KEY_NOT_RSA			 210
@@ -2023,22 +2196,24 @@
 #define SSL_R_RECORD_LENGTH_MISMATCH			 213
 #define SSL_R_RECORD_TOO_LARGE				 214
 #define SSL_R_RECORD_TOO_SMALL				 298
-#define SSL_R_RENEGOTIATE_EXT_TOO_LONG			 320
-#define SSL_R_RENEGOTIATION_ENCODING_ERR		 321
-#define SSL_R_RENEGOTIATION_MISMATCH			 322
+#define SSL_R_RENEGOTIATE_EXT_TOO_LONG			 335
+#define SSL_R_RENEGOTIATION_ENCODING_ERR		 336
+#define SSL_R_RENEGOTIATION_MISMATCH			 337
 #define SSL_R_REQUIRED_CIPHER_MISSING			 215
+#define SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING	 342
 #define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO		 216
 #define SSL_R_REUSE_CERT_TYPE_NOT_ZERO			 217
 #define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO		 218
-#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING		 324
-#define SSL_R_SERVERHELLO_TLSEXT			 224
+#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING		 345
+#define SSL_R_SERVERHELLO_TLSEXT			 275
 #define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED		 277
 #define SSL_R_SHORT_READ				 219
 #define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE	 220
 #define SSL_R_SSL23_DOING_SESSION_ID_REUSE		 221
 #define SSL_R_SSL2_CONNECTION_ID_TOO_LONG		 299
-#define SSL_R_SSL3_EXT_INVALID_SERVERNAME		 225
-#define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE		 226
+#define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT		 321
+#define SSL_R_SSL3_EXT_INVALID_SERVERNAME		 319
+#define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE		 320
 #define SSL_R_SSL3_SESSION_ID_TOO_LONG			 300
 #define SSL_R_SSL3_SESSION_ID_TOO_SHORT			 222
 #define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE		 1042
@@ -2072,8 +2247,13 @@
 #define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW		 1022
 #define SSL_R_TLSV1_ALERT_UNKNOWN_CA			 1048
 #define SSL_R_TLSV1_ALERT_USER_CANCELLED		 1090
+#define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE		 1114
+#define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE	 1113
+#define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE		 1111
+#define SSL_R_TLSV1_UNRECOGNIZED_NAME			 1112
+#define SSL_R_TLSV1_UNSUPPORTED_EXTENSION		 1110
 #define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER	 232
-#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST		 227
+#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST		 157
 #define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233
 #define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG	 234
 #define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER		 235
@@ -2100,9 +2280,10 @@
 #define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE			 253
 #define SSL_R_UNKNOWN_SSL_VERSION			 254
 #define SSL_R_UNKNOWN_STATE				 255
-#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED	 323
+#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED	 338
 #define SSL_R_UNSUPPORTED_CIPHER			 256
 #define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM		 257
+#define SSL_R_UNSUPPORTED_DIGEST_TYPE			 326
 #define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE		 315
 #define SSL_R_UNSUPPORTED_PROTOCOL			 258
 #define SSL_R_UNSUPPORTED_SSL_VERSION			 259
diff --git a/ssl/ssl3.h b/ssl/ssl3.h
index bf71ef9..fb41ca5 100644
--- a/ssl/ssl3.h
+++ b/ssl/ssl3.h
@@ -123,7 +123,6 @@
 #include <openssl/buffer.h>
 #include <openssl/evp.h>
 #include <openssl/ssl.h>
-#include <openssl/pq_compat.h>
 
 #ifdef  __cplusplus
 extern "C" {
@@ -163,12 +162,14 @@
 #define SSL3_CK_ADH_DES_64_CBC_SHA		0x0300001A
 #define SSL3_CK_ADH_DES_192_CBC_SHA		0x0300001B
 
-#define SSL3_CK_FZA_DMS_NULL_SHA		0x0300001C
-#define SSL3_CK_FZA_DMS_FZA_SHA			0x0300001D
-#if 0 /* Because it clashes with KRB5, is never used any more, and is safe
-	 to remove according to David Hopwood <david.hopwood@zetnet.co.uk>
-	 of the ietf-tls list */
-#define SSL3_CK_FZA_DMS_RC4_SHA			0x0300001E
+#if 0
+	#define SSL3_CK_FZA_DMS_NULL_SHA		0x0300001C
+	#define SSL3_CK_FZA_DMS_FZA_SHA			0x0300001D
+	#if 0 /* Because it clashes with KRB5, is never used any more, and is safe
+		 to remove according to David Hopwood <david.hopwood@zetnet.co.uk>
+		 of the ietf-tls list */
+	#define SSL3_CK_FZA_DMS_RC4_SHA			0x0300001E
+	#endif
 #endif
 
 /*    VRS Additional Kerberos5 entries
@@ -220,9 +221,11 @@
 #define SSL3_TXT_ADH_DES_64_CBC_SHA		"ADH-DES-CBC-SHA"
 #define SSL3_TXT_ADH_DES_192_CBC_SHA		"ADH-DES-CBC3-SHA"
 
-#define SSL3_TXT_FZA_DMS_NULL_SHA		"FZA-NULL-SHA"
-#define SSL3_TXT_FZA_DMS_FZA_SHA		"FZA-FZA-CBC-SHA"
-#define SSL3_TXT_FZA_DMS_RC4_SHA		"FZA-RC4-SHA"
+#if 0
+	#define SSL3_TXT_FZA_DMS_NULL_SHA		"FZA-NULL-SHA"
+	#define SSL3_TXT_FZA_DMS_FZA_SHA		"FZA-FZA-CBC-SHA"
+	#define SSL3_TXT_FZA_DMS_RC4_SHA		"FZA-RC4-SHA"
+#endif
 
 #define SSL3_TXT_KRB5_DES_64_CBC_SHA		"KRB5-DES-CBC-SHA"
 #define SSL3_TXT_KRB5_DES_192_CBC3_SHA		"KRB5-DES-CBC3-SHA"
@@ -248,32 +251,75 @@
 #define SSL3_SESSION_ID_SIZE			32
 #define SSL3_RT_HEADER_LENGTH			5
 
-/* Due to MS stuffing up, this can change.... */
-#if defined(OPENSSL_SYS_WIN16) || \
-	(defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32))
-#define SSL3_RT_MAX_EXTRA			(14000)
+#ifndef SSL3_ALIGN_PAYLOAD
+ /* Some will argue that this increases memory footprint, but it's
+  * not actually true. Point is that malloc has to return at least
+  * 64-bit aligned pointers, meaning that allocating 5 bytes wastes
+  * 3 bytes in either case. Suggested pre-gaping simply moves these
+  * wasted bytes from the end of allocated region to its front,
+  * but makes data payload aligned, which improves performance:-) */
+# define SSL3_ALIGN_PAYLOAD			8
 #else
-#define SSL3_RT_MAX_EXTRA			(16384)
+# if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0
+#  error "insane SSL3_ALIGN_PAYLOAD"
+#  undef SSL3_ALIGN_PAYLOAD
+# endif
 #endif
 
+/* This is the maximum MAC (digest) size used by the SSL library.
+ * Currently maximum of 20 is used by SHA1, but we reserve for
+ * future extension for 512-bit hashes.
+ */
+
+#define SSL3_RT_MAX_MD_SIZE			64
+
+/* Maximum block size used in all ciphersuites. Currently 16 for AES.
+ */
+
+#define	SSL_RT_MAX_CIPHER_BLOCK_SIZE		16
+
+#define SSL3_RT_MAX_EXTRA			(16384)
+
 /* Default buffer length used for writen records.  Thus a generated record
  * will contain plaintext no larger than this value. */
 #define SSL3_RT_DEFAULT_PLAIN_LENGTH	2048
+/* Maximum plaintext length: defined by SSL/TLS standards */
 #define SSL3_RT_MAX_PLAIN_LENGTH		16384
+/* Maximum compression overhead: defined by SSL/TLS standards */
+#define SSL3_RT_MAX_COMPRESSED_OVERHEAD		1024
+
+/* The standards give a maximum encryption overhead of 1024 bytes.
+ * In practice the value is lower than this. The overhead is the maximum
+ * number of padding bytes (256) plus the mac size.
+ */
+#define SSL3_RT_MAX_ENCRYPTED_OVERHEAD	(256 + SSL3_RT_MAX_MD_SIZE)
+
+/* OpenSSL currently only uses a padding length of at most one block so
+ * the send overhead is smaller.
+ */
+
+#define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \
+			(SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE)
+
+/* If compression isn't used don't include the compression overhead */
+
 #ifdef OPENSSL_NO_COMP
-#define SSL3_RT_MAX_COMPRESSED_LENGTH	SSL3_RT_MAX_PLAIN_LENGTH
+#define SSL3_RT_MAX_COMPRESSED_LENGTH		SSL3_RT_MAX_PLAIN_LENGTH
 #else
-#define SSL3_RT_MAX_COMPRESSED_LENGTH	(1024+SSL3_RT_MAX_PLAIN_LENGTH)
+#define SSL3_RT_MAX_COMPRESSED_LENGTH	\
+		(SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD)
 #endif
-#define SSL3_RT_MAX_ENCRYPTED_LENGTH	(1024+SSL3_RT_MAX_COMPRESSED_LENGTH)
+#define SSL3_RT_MAX_ENCRYPTED_LENGTH	\
+		(SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH)
+#define SSL3_RT_MAX_PACKET_SIZE		\
+		(SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
+
 /* Extra space for empty fragment, headers, MAC, and padding. */
 #define SSL3_RT_DEFAULT_WRITE_OVERHEAD  256
 #define SSL3_RT_DEFAULT_PACKET_SIZE     4096 - SSL3_RT_DEFAULT_WRITE_OVERHEAD
 #if SSL3_RT_DEFAULT_PLAIN_LENGTH + SSL3_RT_DEFAULT_WRITE_OVERHEAD > SSL3_RT_DEFAULT_PACKET_SIZE
 #error "Insufficient space allocated for write buffers."
 #endif
-#define SSL3_RT_MAX_PACKET_SIZE		(SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
-#define SSL3_RT_MAX_DATA_SIZE			(1024*1024)
 
 #define SSL3_MD_CLIENT_FINISHED_CONST	"\x43\x4C\x4E\x54"
 #define SSL3_MD_SERVER_FINISHED_CONST	"\x53\x52\x56\x52"
@@ -312,7 +358,7 @@
 /*rw*/	unsigned char *input;   /* where the decode bytes are */
 /*r */	unsigned char *comp;    /* only used with decompression - malloc()ed */
 /*r */  unsigned long epoch;    /* epoch number, needed by DTLS1 */
-/*r */  PQ_64BIT seq_num;       /* sequence number, needed by DTLS1 */
+/*r */  unsigned char seq_num[8]; /* sequence number, needed by DTLS1 */
 	} SSL3_RECORD;
 
 typedef struct ssl3_buffer_st
@@ -335,13 +381,14 @@
  * enough to contain all of the cert types defined either for
  * SSLv3 and TLSv1.
  */
-#define SSL3_CT_NUMBER			7
+#define SSL3_CT_NUMBER			9
 
 
 #define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS	0x0001
 #define SSL3_FLAGS_DELAY_CLIENT_FINISHED	0x0002
 #define SSL3_FLAGS_POP_BUFFER			0x0004
 #define TLS1_FLAGS_TLS_PADDING_BUG		0x0008
+#define TLS1_FLAGS_SKIP_CERT_VERIFY		0x0010
 
 typedef struct ssl3_state_st
 	{
@@ -349,8 +396,10 @@
 	int delay_buf_pop_ret;
 
 	unsigned char read_sequence[8];
+	int read_mac_secret_size;
 	unsigned char read_mac_secret[EVP_MAX_MD_SIZE];
 	unsigned char write_sequence[8];
+	int write_mac_secret_size;
 	unsigned char write_mac_secret[EVP_MAX_MD_SIZE];
 
 	unsigned char server_random[SSL3_RANDOM_SIZE];
@@ -360,6 +409,9 @@
 	int need_empty_fragments;
 	int empty_fragment_done;
 
+	/* The value of 'extra' when the buffers were initialized */
+	int init_extra;
+
 	SSL3_BUFFER rbuf;	/* read IO goes into here */
 	SSL3_BUFFER wbuf;	/* write IO goes into here */
 
@@ -381,9 +433,11 @@
 	const unsigned char *wpend_buf;
 
 	/* used during startup, digest all incoming/outgoing packets */
-	EVP_MD_CTX finish_dgst1;
-	EVP_MD_CTX finish_dgst2;
-
+	BIO *handshake_buffer;
+	/* When set of handshake digests is determined, buffer is hashed
+	 * and freed and MD_CTX-es for all required digests are stored in
+	 * this array */
+	EVP_MD_CTX **handshake_dgst;
 	/* this is set whenerver we see a change_cipher_spec message
 	 * come in when we are not looking for one */
 	int change_cipher_spec;
@@ -403,6 +457,14 @@
 
 	int in_read_app_data;
 
+	/* Opaque PRF input as used for the current handshake.
+	 * These fields are used only if TLSEXT_TYPE_opaque_prf_input is defined
+	 * (otherwise, they are merely present to improve binary compatibility) */
+	void *client_opaque_prf_input;
+	size_t client_opaque_prf_input_len;
+	void *server_opaque_prf_input;
+	size_t server_opaque_prf_input_len;
+
 	struct	{
 		/* actually only needs to be 16+20 */
 		unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2];
@@ -417,7 +479,7 @@
 		int message_type;
 
 		/* used to hold the new cipher we are going to use */
-		SSL_CIPHER *new_cipher;
+		const SSL_CIPHER *new_cipher;
 #ifndef OPENSSL_NO_DH
 		DH *dh;
 #endif
@@ -444,6 +506,8 @@
 
 		const EVP_CIPHER *new_sym_enc;
 		const EVP_MD *new_hash;
+		int new_mac_pkey_type;
+		int new_mac_secret_size;
 #ifndef OPENSSL_NO_COMP
 		const SSL_COMP *new_compression;
 #else
@@ -580,4 +644,3 @@
 }
 #endif
 #endif
-
diff --git a/ssl/ssl_algs.c b/ssl/ssl_algs.c
index 2d9077e..a26ae43 100644
--- a/ssl/ssl_algs.c
+++ b/ssl/ssl_algs.c
@@ -76,13 +76,16 @@
 #endif  
 #ifndef OPENSSL_NO_RC2
 	EVP_add_cipher(EVP_rc2_cbc());
+	/* Not actually used for SSL/TLS but this makes PKCS#12 work
+	 * if an application only calls SSL_library_init().
+	 */
+	EVP_add_cipher(EVP_rc2_40_cbc());
 #endif
 #ifndef OPENSSL_NO_AES
 	EVP_add_cipher(EVP_aes_128_cbc());
 	EVP_add_cipher(EVP_aes_192_cbc());
 	EVP_add_cipher(EVP_aes_256_cbc());
 #endif
-
 #ifndef OPENSSL_NO_CAMELLIA
 	EVP_add_cipher(EVP_camellia_128_cbc());
 	EVP_add_cipher(EVP_camellia_256_cbc());
@@ -91,7 +94,7 @@
 #ifndef OPENSSL_NO_SEED
 	EVP_add_cipher(EVP_seed_cbc());
 #endif
-
+  
 #ifndef OPENSSL_NO_MD5
 	EVP_add_digest(EVP_md5());
 	EVP_add_digest_alias(SN_md5,"ssl2-md5");
diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c
index d82e47a..2870997 100644
--- a/ssl/ssl_asn1.c
+++ b/ssl/ssl_asn1.c
@@ -55,6 +55,32 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -84,12 +110,16 @@
 	ASN1_INTEGER tlsext_tick_lifetime;
 	ASN1_OCTET_STRING tlsext_tick;
 #endif /* OPENSSL_NO_TLSEXT */
+#ifndef OPENSSL_NO_PSK
+	ASN1_OCTET_STRING psk_identity_hint;
+	ASN1_OCTET_STRING psk_identity;
+#endif /* OPENSSL_NO_PSK */
 	} SSL_SESSION_ASN1;
 
 int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
 	{
 #define LSIZE2 (sizeof(long)*2)
-	int v1=0,v2=0,v3=0,v4=0,v5=0;
+	int v1=0,v2=0,v3=0,v4=0,v5=0,v7=0,v8=0;
 	unsigned char buf[4],ibuf1[LSIZE2],ibuf2[LSIZE2];
 	unsigned char ibuf3[LSIZE2],ibuf4[LSIZE2],ibuf5[LSIZE2];
 #ifndef OPENSSL_NO_TLSEXT
@@ -97,8 +127,8 @@
 	unsigned char ibuf6[LSIZE2];
 #endif
 #ifndef OPENSSL_NO_COMP
-	int v11=0;
 	unsigned char cbuf;
+	int v11=0;
 #endif
 	long l;
 	SSL_SESSION_ASN1 a;
@@ -177,7 +207,7 @@
 		a.krb5_princ.data=in->krb5_client_princ;
 		}
 #endif /* OPENSSL_NO_KRB5 */
- 
+
 	if (in->time != 0L)
 		{
 		a.time.length=LSIZE2;
@@ -223,6 +253,21 @@
 		ASN1_INTEGER_set(&a.tlsext_tick_lifetime,in->tlsext_tick_lifetime_hint);
 		}
 #endif /* OPENSSL_NO_TLSEXT */
+#ifndef OPENSSL_NO_PSK
+	if (in->psk_identity_hint)
+		{
+		a.psk_identity_hint.length=strlen(in->psk_identity_hint);
+		a.psk_identity_hint.type=V_ASN1_OCTET_STRING;
+		a.psk_identity_hint.data=(unsigned char *)(in->psk_identity_hint);
+		}
+	if (in->psk_identity)
+		{
+		a.psk_identity.length=strlen(in->psk_identity);
+		a.psk_identity.type=V_ASN1_OCTET_STRING;
+		a.psk_identity.data=(unsigned char *)(in->psk_identity);
+		}
+#endif /* OPENSSL_NO_PSK */
+
 	M_ASN1_I2D_len(&(a.version),		i2d_ASN1_INTEGER);
 	M_ASN1_I2D_len(&(a.ssl_version),	i2d_ASN1_INTEGER);
 	M_ASN1_I2D_len(&(a.cipher),		i2d_ASN1_OCTET_STRING);
@@ -256,6 +301,13 @@
         	M_ASN1_I2D_len_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11);
 #endif
 #endif /* OPENSSL_NO_TLSEXT */
+#ifndef OPENSSL_NO_PSK
+	if (in->psk_identity_hint)
+        	M_ASN1_I2D_len_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING,7,v7);
+	if (in->psk_identity)
+        	M_ASN1_I2D_len_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8);
+#endif /* OPENSSL_NO_PSK */
+
 	M_ASN1_I2D_seq_total();
 
 	M_ASN1_I2D_put(&(a.version),		i2d_ASN1_INTEGER);
@@ -282,6 +334,14 @@
 #ifndef OPENSSL_NO_TLSEXT
 	if (in->tlsext_hostname)
         	M_ASN1_I2D_put_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING,6,v6);
+#endif /* OPENSSL_NO_TLSEXT */
+#ifndef OPENSSL_NO_PSK
+	if (in->psk_identity_hint)
+		M_ASN1_I2D_put_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING,7,v7);
+	if (in->psk_identity)
+		M_ASN1_I2D_put_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8);
+#endif /* OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_TLSEXT
 	if (in->tlsext_tick_lifetime_hint > 0)
       	 	M_ASN1_I2D_put_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER,9,v9);
 	if (in->tlsext_tick)
@@ -295,7 +355,7 @@
 	}
 
 SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
-	     long length)
+			     long length)
 	{
 	int version,ssl_version=0,i;
 	long id;
@@ -475,6 +535,24 @@
 		}
 	else
 		ret->tlsext_hostname=NULL;
+#endif /* OPENSSL_NO_TLSEXT */
+
+#ifndef OPENSSL_NO_PSK
+	os.length=0;
+	os.data=NULL;
+	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,7);
+	if (os.data)
+		{
+		ret->psk_identity_hint = BUF_strndup((char *)os.data, os.length);
+		OPENSSL_free(os.data);
+		os.data = NULL;
+		os.length = 0;
+		}
+	else
+		ret->psk_identity_hint=NULL;
+#endif /* OPENSSL_NO_PSK */
+
+#ifndef OPENSSL_NO_TLSEXT
 	ai.length=0;
 	M_ASN1_D2I_get_EXP_opt(aip,d2i_ASN1_INTEGER,9);
 	if (ai.data != NULL)
@@ -485,17 +563,17 @@
 	else if (ret->tlsext_ticklen && ret->session_id_length)
 		ret->tlsext_tick_lifetime_hint = -1;
 	else
-		ret->tlsext_tick_lifetime_hint = 0;
- 	os.length=0;
- 	os.data=NULL;
-  	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,10);
- 	if (os.data)
- 		{
+		ret->tlsext_tick_lifetime_hint=0;
+	os.length=0;
+	os.data=NULL;
+	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,10);
+	if (os.data)
+		{
 		ret->tlsext_tick = os.data;
 		ret->tlsext_ticklen = os.length;
- 		os.data = NULL;
- 		os.length = 0;
- 		}
+		os.data = NULL;
+		os.length = 0;
+		}
 	else
 		ret->tlsext_tick=NULL;
 #endif /* OPENSSL_NO_TLSEXT */
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index 16fda5d..27256ee 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -197,8 +197,10 @@
 	 * if you find that more readable */
 
 	ret->valid = cert->valid;
-	ret->mask = cert->mask;
-	ret->export_mask = cert->export_mask;
+	ret->mask_k = cert->mask_k;
+	ret->mask_a = cert->mask_a;
+	ret->export_mask_k = cert->export_mask_k;
+	ret->export_mask_a = cert->export_mask_a;
 
 #ifndef OPENSSL_NO_RSA
 	if (cert->rsa_tmp != NULL)
@@ -753,6 +755,8 @@
 			sk_X509_NAME_push(stack,xn);
 		}
 
+	ERR_clear_error();
+
 	if (0)
 		{
 err:
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index 5e2d436..bee3507 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -113,12 +113,41 @@
  * ECC cipher suite support in OpenSSL originally developed by 
  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
 #include <stdio.h>
 #include <openssl/objects.h>
 #ifndef OPENSSL_NO_COMP
 #include <openssl/comp.h>
 #endif
-
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
 #include "ssl_locl.h"
 
 #define SSL_ENC_DES_IDX		0
@@ -126,18 +155,18 @@
 #define SSL_ENC_RC4_IDX		2
 #define SSL_ENC_RC2_IDX		3
 #define SSL_ENC_IDEA_IDX	4
-#define SSL_ENC_eFZA_IDX	5
-#define SSL_ENC_NULL_IDX	6
-#define SSL_ENC_AES128_IDX	7
-#define SSL_ENC_AES256_IDX	8
-#define SSL_ENC_CAMELLIA128_IDX	9
-#define SSL_ENC_CAMELLIA256_IDX	10
+#define SSL_ENC_NULL_IDX	5
+#define SSL_ENC_AES128_IDX	6
+#define SSL_ENC_AES256_IDX	7
+#define SSL_ENC_CAMELLIA128_IDX	8
+#define SSL_ENC_CAMELLIA256_IDX	9
+#define SSL_ENC_GOST89_IDX	10
 #define SSL_ENC_SEED_IDX    	11
 #define SSL_ENC_NUM_IDX		12
 
 
 static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={
-	NULL,NULL,NULL,NULL,NULL,NULL,
+	NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
 	};
 
 #define SSL_COMP_NULL_IDX	0
@@ -148,9 +177,30 @@
 
 #define SSL_MD_MD5_IDX	0
 #define SSL_MD_SHA1_IDX	1
-#define SSL_MD_NUM_IDX	2
+#define SSL_MD_GOST94_IDX 2
+#define SSL_MD_GOST89MAC_IDX 3
+/*Constant SSL_MAX_DIGEST equal to size of digests array should be 
+ * defined in the
+ * ssl_locl.h */
+#define SSL_MD_NUM_IDX	SSL_MAX_DIGEST 
 static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={
-	NULL,NULL,
+	NULL,NULL,NULL,NULL
+	};
+/* PKEY_TYPE for GOST89MAC is known in advance, but, because
+ * implementation is engine-provided, we'll fill it only if
+ * corresponding EVP_PKEY_METHOD is found 
+ */
+static int  ssl_mac_pkey_id[SSL_MD_NUM_IDX]={
+	EVP_PKEY_HMAC,EVP_PKEY_HMAC,EVP_PKEY_HMAC,NID_undef
+	};
+
+static int ssl_mac_secret_size[SSL_MD_NUM_IDX]={
+	0,0,0,0
+	};
+
+static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX]={
+	SSL_HANDSHAKE_MAC_MD5,SSL_HANDSHAKE_MAC_SHA,
+	SSL_HANDSHAKE_MAC_GOST94,0
 	};
 
 #define CIPHER_ADD	1
@@ -161,72 +211,144 @@
 
 typedef struct cipher_order_st
 	{
-	SSL_CIPHER *cipher;
+	const SSL_CIPHER *cipher;
 	int active;
 	int dead;
 	struct cipher_order_st *next,*prev;
 	} CIPHER_ORDER;
 
 static const SSL_CIPHER cipher_aliases[]={
-	/* Don't include eNULL unless specifically enabled. */
-	/* Don't include ECC in ALL because these ciphers are not yet official. */
-	{0,SSL_TXT_ALL, 0,SSL_ALL & ~SSL_eNULL & ~SSL_kECDH & ~SSL_kECDHE, SSL_ALL ,0,0,0,SSL_ALL,SSL_ALL}, /* must be first */
-	/* TODO: COMPLEMENT OF ALL and COMPLEMENT OF DEFAULT do not have ECC cipher suites handled properly. */
-	{0,SSL_TXT_CMPALL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0},  /* COMPLEMENT OF ALL */
-	{0,SSL_TXT_CMPDEF,0,SSL_ADH, 0,0,0,0,SSL_AUTH_MASK,0},
-	{0,SSL_TXT_kKRB5,0,SSL_kKRB5,0,0,0,0,SSL_MKEY_MASK,0},  /* VRS Kerberos5 */
-	{0,SSL_TXT_kRSA,0,SSL_kRSA,  0,0,0,0,SSL_MKEY_MASK,0},
-	{0,SSL_TXT_kDHr,0,SSL_kDHr,  0,0,0,0,SSL_MKEY_MASK,0},
-	{0,SSL_TXT_kDHd,0,SSL_kDHd,  0,0,0,0,SSL_MKEY_MASK,0},
-	{0,SSL_TXT_kEDH,0,SSL_kEDH,  0,0,0,0,SSL_MKEY_MASK,0},
-	{0,SSL_TXT_kFZA,0,SSL_kFZA,  0,0,0,0,SSL_MKEY_MASK,0},
-	{0,SSL_TXT_DH,	0,SSL_DH,    0,0,0,0,SSL_MKEY_MASK,0},
-	{0,SSL_TXT_ECC,	0,(SSL_kECDH|SSL_kECDHE), 0,0,0,0,SSL_MKEY_MASK,0},
-	{0,SSL_TXT_EDH,	0,SSL_EDH,   0,0,0,0,SSL_MKEY_MASK|SSL_AUTH_MASK,0},
-	{0,SSL_TXT_aKRB5,0,SSL_aKRB5,0,0,0,0,SSL_AUTH_MASK,0},  /* VRS Kerberos5 */
-	{0,SSL_TXT_aRSA,0,SSL_aRSA,  0,0,0,0,SSL_AUTH_MASK,0},
-	{0,SSL_TXT_aDSS,0,SSL_aDSS,  0,0,0,0,SSL_AUTH_MASK,0},
-	{0,SSL_TXT_aFZA,0,SSL_aFZA,  0,0,0,0,SSL_AUTH_MASK,0},
-	{0,SSL_TXT_aNULL,0,SSL_aNULL,0,0,0,0,SSL_AUTH_MASK,0},
-	{0,SSL_TXT_aDH, 0,SSL_aDH,   0,0,0,0,SSL_AUTH_MASK,0},
-	{0,SSL_TXT_DSS,	0,SSL_DSS,   0,0,0,0,SSL_AUTH_MASK,0},
+	/* "ALL" doesn't include eNULL (must be specifically enabled) */
+	{0,SSL_TXT_ALL,0,     0,0,~SSL_eNULL,0,0,0,0,0,0},
+	/* "COMPLEMENTOFALL" */
+	{0,SSL_TXT_CMPALL,0,  0,0,SSL_eNULL,0,0,0,0,0,0},
 
-	{0,SSL_TXT_DES,	0,SSL_DES,   0,0,0,0,SSL_ENC_MASK,0},
-	{0,SSL_TXT_3DES,0,SSL_3DES,  0,0,0,0,SSL_ENC_MASK,0},
-	{0,SSL_TXT_RC4,	0,SSL_RC4,   0,0,0,0,SSL_ENC_MASK,0},
-	{0,SSL_TXT_RC2,	0,SSL_RC2,   0,0,0,0,SSL_ENC_MASK,0},
-#ifndef OPENSSL_NO_IDEA
-	{0,SSL_TXT_IDEA,0,SSL_IDEA,  0,0,0,0,SSL_ENC_MASK,0},
-#endif
-	{0,SSL_TXT_SEED,0,SSL_SEED,  0,0,0,0,SSL_ENC_MASK,0},
-	{0,SSL_TXT_eNULL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0},
-	{0,SSL_TXT_eFZA,0,SSL_eFZA,  0,0,0,0,SSL_ENC_MASK,0},
-	{0,SSL_TXT_AES,	0,SSL_AES,   0,0,0,0,SSL_ENC_MASK,0},
-	{0,SSL_TXT_CAMELLIA,0,SSL_CAMELLIA, 0,0,0,0,SSL_ENC_MASK,0},
+	/* "COMPLEMENTOFDEFAULT" (does *not* include ciphersuites not found in ALL!) */
+	{0,SSL_TXT_CMPDEF,0,  SSL_kEDH|SSL_kEECDH,SSL_aNULL,~SSL_eNULL,0,0,0,0,0,0},
 
-	{0,SSL_TXT_MD5,	0,SSL_MD5,   0,0,0,0,SSL_MAC_MASK,0},
-	{0,SSL_TXT_SHA1,0,SSL_SHA1,  0,0,0,0,SSL_MAC_MASK,0},
-	{0,SSL_TXT_SHA,	0,SSL_SHA,   0,0,0,0,SSL_MAC_MASK,0},
+	/* key exchange aliases
+	 * (some of those using only a single bit here combine
+	 * multiple key exchange algs according to the RFCs,
+	 * e.g. kEDH combines DHE_DSS and DHE_RSA) */
+	{0,SSL_TXT_kRSA,0,    SSL_kRSA,  0,0,0,0,0,0,0,0},
 
-	{0,SSL_TXT_NULL,0,SSL_NULL,  0,0,0,0,SSL_ENC_MASK,0},
-	{0,SSL_TXT_KRB5,0,SSL_KRB5,  0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0},
-	{0,SSL_TXT_RSA,	0,SSL_RSA,   0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0},
-	{0,SSL_TXT_ADH,	0,SSL_ADH,   0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0},
-	{0,SSL_TXT_FZA,	0,SSL_FZA,   0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK|SSL_ENC_MASK,0},
+	{0,SSL_TXT_kDHr,0,    SSL_kDHr,  0,0,0,0,0,0,0,0}, /* no such ciphersuites supported! */
+	{0,SSL_TXT_kDHd,0,    SSL_kDHd,  0,0,0,0,0,0,0,0}, /* no such ciphersuites supported! */
+	{0,SSL_TXT_kDH,0,     SSL_kDHr|SSL_kDHd,0,0,0,0,0,0,0,0}, /* no such ciphersuites supported! */
+	{0,SSL_TXT_kEDH,0,    SSL_kEDH,  0,0,0,0,0,0,0,0},
+	{0,SSL_TXT_DH,0,      SSL_kDHr|SSL_kDHd|SSL_kEDH,0,0,0,0,0,0,0,0},
 
-	{0,SSL_TXT_SSLV2, 0,SSL_SSLV2, 0,0,0,0,SSL_SSL_MASK,0},
-	{0,SSL_TXT_SSLV3, 0,SSL_SSLV3, 0,0,0,0,SSL_SSL_MASK,0},
-	{0,SSL_TXT_TLSV1, 0,SSL_TLSV1, 0,0,0,0,SSL_SSL_MASK,0},
+	{0,SSL_TXT_kKRB5,0,   SSL_kKRB5, 0,0,0,0,0,0,0,0},
 
-	{0,SSL_TXT_EXP   ,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK},
-	{0,SSL_TXT_EXPORT,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK},
-	{0,SSL_TXT_EXP40, 0, 0, SSL_EXP40, 0,0,0,0,SSL_STRONG_MASK},
-	{0,SSL_TXT_EXP56, 0, 0, SSL_EXP56, 0,0,0,0,SSL_STRONG_MASK},
-	{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},
+	{0,SSL_TXT_kECDHr,0,  SSL_kECDHr,0,0,0,0,0,0,0,0},
+	{0,SSL_TXT_kECDHe,0,  SSL_kECDHe,0,0,0,0,0,0,0,0},
+	{0,SSL_TXT_kECDH,0,   SSL_kECDHr|SSL_kECDHe,0,0,0,0,0,0,0,0},
+	{0,SSL_TXT_kEECDH,0,  SSL_kEECDH,0,0,0,0,0,0,0,0},
+	{0,SSL_TXT_ECDH,0,    SSL_kECDHr|SSL_kECDHe|SSL_kEECDH,0,0,0,0,0,0,0,0},
+
+        {0,SSL_TXT_kPSK,0,    SSL_kPSK,  0,0,0,0,0,0,0,0},
+	{0,SSL_TXT_kGOST,0, SSL_kGOST,0,0,0,0,0,0,0,0},
+
+	/* server authentication aliases */
+	{0,SSL_TXT_aRSA,0,    0,SSL_aRSA,  0,0,0,0,0,0,0},
+	{0,SSL_TXT_aDSS,0,    0,SSL_aDSS,  0,0,0,0,0,0,0},
+	{0,SSL_TXT_DSS,0,     0,SSL_aDSS,   0,0,0,0,0,0,0},
+	{0,SSL_TXT_aKRB5,0,   0,SSL_aKRB5, 0,0,0,0,0,0,0},
+	{0,SSL_TXT_aNULL,0,   0,SSL_aNULL, 0,0,0,0,0,0,0},
+	{0,SSL_TXT_aDH,0,     0,SSL_aDH,   0,0,0,0,0,0,0}, /* no such ciphersuites supported! */
+	{0,SSL_TXT_aECDH,0,   0,SSL_aECDH, 0,0,0,0,0,0,0},
+	{0,SSL_TXT_aECDSA,0,  0,SSL_aECDSA,0,0,0,0,0,0,0},
+	{0,SSL_TXT_ECDSA,0,   0,SSL_aECDSA, 0,0,0,0,0,0,0},
+        {0,SSL_TXT_aPSK,0,    0,SSL_aPSK,  0,0,0,0,0,0,0},
+	{0,SSL_TXT_aGOST94,0,0,SSL_aGOST94,0,0,0,0,0,0,0},
+	{0,SSL_TXT_aGOST01,0,0,SSL_aGOST01,0,0,0,0,0,0,0},
+	{0,SSL_TXT_aGOST,0,0,SSL_aGOST94|SSL_aGOST01,0,0,0,0,0,0,0},
+
+	/* aliases combining key exchange and server authentication */
+	{0,SSL_TXT_EDH,0,     SSL_kEDH,~SSL_aNULL,0,0,0,0,0,0,0},
+	{0,SSL_TXT_EECDH,0,   SSL_kEECDH,~SSL_aNULL,0,0,0,0,0,0,0},
+	{0,SSL_TXT_NULL,0,    0,0,SSL_eNULL, 0,0,0,0,0,0},
+	{0,SSL_TXT_KRB5,0,    SSL_kKRB5,SSL_aKRB5,0,0,0,0,0,0,0},
+	{0,SSL_TXT_RSA,0,     SSL_kRSA,SSL_aRSA,0,0,0,0,0,0,0},
+	{0,SSL_TXT_ADH,0,     SSL_kEDH,SSL_aNULL,0,0,0,0,0,0,0},
+	{0,SSL_TXT_AECDH,0,   SSL_kEECDH,SSL_aNULL,0,0,0,0,0,0,0},
+        {0,SSL_TXT_PSK,0,     SSL_kPSK,SSL_aPSK,0,0,0,0,0,0,0},
+
+
+	/* symmetric encryption aliases */
+	{0,SSL_TXT_DES,0,     0,0,SSL_DES,   0,0,0,0,0,0},
+	{0,SSL_TXT_3DES,0,    0,0,SSL_3DES,  0,0,0,0,0,0},
+	{0,SSL_TXT_RC4,0,     0,0,SSL_RC4,   0,0,0,0,0,0},
+	{0,SSL_TXT_RC2,0,     0,0,SSL_RC2,   0,0,0,0,0,0},
+	{0,SSL_TXT_IDEA,0,    0,0,SSL_IDEA,  0,0,0,0,0,0},
+	{0,SSL_TXT_SEED,0,    0,0,SSL_SEED,  0,0,0,0,0,0},
+	{0,SSL_TXT_eNULL,0,   0,0,SSL_eNULL, 0,0,0,0,0,0},
+	{0,SSL_TXT_AES128,0,  0,0,SSL_AES128,0,0,0,0,0,0},
+	{0,SSL_TXT_AES256,0,  0,0,SSL_AES256,0,0,0,0,0,0},
+	{0,SSL_TXT_AES,0,     0,0,SSL_AES128|SSL_AES256,0,0,0,0,0,0},
+	{0,SSL_TXT_CAMELLIA128,0,0,0,SSL_CAMELLIA128,0,0,0,0,0,0},
+	{0,SSL_TXT_CAMELLIA256,0,0,0,SSL_CAMELLIA256,0,0,0,0,0,0},
+	{0,SSL_TXT_CAMELLIA   ,0,0,0,SSL_CAMELLIA128|SSL_CAMELLIA256,0,0,0,0,0,0},
+
+	/* MAC aliases */	
+	{0,SSL_TXT_MD5,0,     0,0,0,SSL_MD5,   0,0,0,0,0},
+	{0,SSL_TXT_SHA1,0,    0,0,0,SSL_SHA1,  0,0,0,0,0},
+	{0,SSL_TXT_SHA,0,     0,0,0,SSL_SHA1,  0,0,0,0,0},
+	{0,SSL_TXT_GOST94,0,     0,0,0,SSL_GOST94,  0,0,0,0,0},
+	{0,SSL_TXT_GOST89MAC,0,     0,0,0,SSL_GOST89MAC,  0,0,0,0,0},
+
+	/* protocol version aliases */
+	{0,SSL_TXT_SSLV2,0,   0,0,0,0,SSL_SSLV2, 0,0,0,0},
+	{0,SSL_TXT_SSLV3,0,   0,0,0,0,SSL_SSLV3, 0,0,0,0},
+	{0,SSL_TXT_TLSV1,0,   0,0,0,0,SSL_TLSV1, 0,0,0,0},
+
+	/* export flag */
+	{0,SSL_TXT_EXP,0,     0,0,0,0,0,SSL_EXPORT,0,0,0},
+	{0,SSL_TXT_EXPORT,0,  0,0,0,0,0,SSL_EXPORT,0,0,0},
+
+	/* strength classes */
+	{0,SSL_TXT_EXP40,0,   0,0,0,0,0,SSL_EXP40, 0,0,0},
+	{0,SSL_TXT_EXP56,0,   0,0,0,0,0,SSL_EXP56, 0,0,0},
+	{0,SSL_TXT_LOW,0,     0,0,0,0,0,SSL_LOW,   0,0,0},
+	{0,SSL_TXT_MEDIUM,0,  0,0,0,0,0,SSL_MEDIUM,0,0,0},
+	{0,SSL_TXT_HIGH,0,    0,0,0,0,0,SSL_HIGH,  0,0,0},
+	/* FIPS 140-2 approved ciphersuite */
+	{0,SSL_TXT_FIPS,0,    0,0,~SSL_eNULL,0,0,SSL_FIPS,  0,0,0},
 	};
+/* Search for public key algorithm with given name and 
+ * return its pkey_id if it is available. Otherwise return 0
+ */
+#ifdef OPENSSL_NO_ENGINE
+
+static int get_optional_pkey_id(const char *pkey_name)
+	{
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	int pkey_id=0;
+	ameth = EVP_PKEY_asn1_find_str(NULL,pkey_name,-1);
+	if (ameth) 
+		{
+		EVP_PKEY_asn1_get0_info(&pkey_id, NULL,NULL,NULL,NULL,ameth);
+		}		
+	return pkey_id;
+	}
+
+#else
+
+static int get_optional_pkey_id(const char *pkey_name)
+	{
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	ENGINE *tmpeng = NULL;
+	int pkey_id=0;
+	ameth = EVP_PKEY_asn1_find_str(&tmpeng,pkey_name,-1);
+	if (ameth)
+		{
+		EVP_PKEY_asn1_get0_info(&pkey_id, NULL,NULL,NULL,NULL,ameth);
+		}
+	if (tmpeng) ENGINE_finish(tmpeng);
+	return pkey_id;
+	}
+
+#endif
 
 void ssl_load_ciphers(void)
 	{
@@ -252,16 +374,37 @@
 	  EVP_get_cipherbyname(SN_camellia_128_cbc);
 	ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX]=
 	  EVP_get_cipherbyname(SN_camellia_256_cbc);
+	ssl_cipher_methods[SSL_ENC_GOST89_IDX]=
+	  EVP_get_cipherbyname(SN_gost89_cnt);
 	ssl_cipher_methods[SSL_ENC_SEED_IDX]=
 	  EVP_get_cipherbyname(SN_seed_cbc);
 
 	ssl_digest_methods[SSL_MD_MD5_IDX]=
 		EVP_get_digestbyname(SN_md5);
+	ssl_mac_secret_size[SSL_MD_MD5_IDX]=
+		EVP_MD_size(ssl_digest_methods[SSL_MD_MD5_IDX]);
+	OPENSSL_assert(ssl_mac_secret_size[SSL_MD_MD5_IDX] >= 0);
 	ssl_digest_methods[SSL_MD_SHA1_IDX]=
 		EVP_get_digestbyname(SN_sha1);
+	ssl_mac_secret_size[SSL_MD_SHA1_IDX]=
+		EVP_MD_size(ssl_digest_methods[SSL_MD_SHA1_IDX]);
+	OPENSSL_assert(ssl_mac_secret_size[SSL_MD_SHA1_IDX] >= 0);
+	ssl_digest_methods[SSL_MD_GOST94_IDX]=
+		EVP_get_digestbyname(SN_id_GostR3411_94);
+	if (ssl_digest_methods[SSL_MD_GOST94_IDX])
+		{	
+		ssl_mac_secret_size[SSL_MD_GOST94_IDX]=
+			EVP_MD_size(ssl_digest_methods[SSL_MD_GOST94_IDX]);
+		OPENSSL_assert(ssl_mac_secret_size[SSL_MD_GOST94_IDX] >= 0);
+		}
+	ssl_digest_methods[SSL_MD_GOST89MAC_IDX]=
+		EVP_get_digestbyname(SN_id_Gost28147_89_MAC);
+		ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id("gost-mac");
+		if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]) {
+			ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX]=32;
+		}		
+
 	}
-
-
 #ifndef OPENSSL_NO_COMP
 
 static int sk_comp_cmp(const SSL_COMP * const *a,
@@ -316,10 +459,10 @@
 #endif
 
 int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
-	     const EVP_MD **md, SSL_COMP **comp)
+	     const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size,SSL_COMP **comp)
 	{
 	int i;
-	SSL_CIPHER *c;
+	const SSL_CIPHER *c;
 
 	c=s->cipher;
 	if (c == NULL) return(0);
@@ -344,7 +487,7 @@
 
 	if ((enc == NULL) || (md == NULL)) return(0);
 
-	switch (c->algorithms & SSL_ENC_MASK)
+	switch (c->algorithm_enc)
 		{
 	case SSL_DES:
 		i=SSL_ENC_DES_IDX;
@@ -364,26 +507,24 @@
 	case SSL_eNULL:
 		i=SSL_ENC_NULL_IDX;
 		break;
-	case SSL_AES:
-		switch(c->alg_bits)
-			{
-		case 128: i=SSL_ENC_AES128_IDX; break;
-		case 256: i=SSL_ENC_AES256_IDX; break;
-		default: i=-1; break;
-			}
+	case SSL_AES128:
+		i=SSL_ENC_AES128_IDX;
 		break;
-	case SSL_CAMELLIA:
-		switch(c->alg_bits)
-			{
-		case 128: i=SSL_ENC_CAMELLIA128_IDX; break;
-		case 256: i=SSL_ENC_CAMELLIA256_IDX; break;
-		default: i=-1; break;
-			}
+	case SSL_AES256:
+		i=SSL_ENC_AES256_IDX;
+		break;
+	case SSL_CAMELLIA128:
+		i=SSL_ENC_CAMELLIA128_IDX;
+		break;
+	case SSL_CAMELLIA256:
+		i=SSL_ENC_CAMELLIA256_IDX;
+		break;
+	case SSL_eGOST2814789CNT:
+		i=SSL_ENC_GOST89_IDX;
 		break;
 	case SSL_SEED:
 		i=SSL_ENC_SEED_IDX;
 		break;
-
 	default:
 		i= -1;
 		break;
@@ -399,7 +540,7 @@
 			*enc=ssl_cipher_methods[i];
 		}
 
-	switch (c->algorithms & SSL_MAC_MASK)
+	switch (c->algorithm_mac)
 		{
 	case SSL_MD5:
 		i=SSL_MD_MD5_IDX;
@@ -407,21 +548,48 @@
 	case SSL_SHA1:
 		i=SSL_MD_SHA1_IDX;
 		break;
+	case SSL_GOST94:
+		i = SSL_MD_GOST94_IDX;
+		break;
+	case SSL_GOST89MAC:
+		i = SSL_MD_GOST89MAC_IDX;
+		break;
 	default:
 		i= -1;
 		break;
 		}
 	if ((i < 0) || (i > SSL_MD_NUM_IDX))
-		*md=NULL;
-	else
-		*md=ssl_digest_methods[i];
+	{
+		*md=NULL; 
+		if (mac_pkey_type!=NULL) *mac_pkey_type = NID_undef;
+		if (mac_secret_size!=NULL) *mac_secret_size = 0;
 
-	if ((*enc != NULL) && (*md != NULL))
+	}
+	else
+	{
+		*md=ssl_digest_methods[i];
+		if (mac_pkey_type!=NULL) *mac_pkey_type = ssl_mac_pkey_id[i];
+		if (mac_secret_size!=NULL) *mac_secret_size = ssl_mac_secret_size[i];
+	}	
+
+	if ((*enc != NULL) && (*md != NULL) && (!mac_pkey_type||*mac_pkey_type != NID_undef))
 		return(1);
 	else
 		return(0);
 	}
 
+int ssl_get_handshake_digest(int idx, long *mask, const EVP_MD **md) 
+{
+	if (idx <0||idx>=SSL_MD_NUM_IDX) 
+		{
+		return 0;
+		}
+	if (ssl_handshake_digest_flag[idx]==0) return 0;
+	*mask = ssl_handshake_digest_flag[idx];
+	*md = ssl_digest_methods[idx];
+	return 1;
+}
+
 #define ITEM_SEP(a) \
 	(((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ','))
 
@@ -433,7 +601,7 @@
 		*head=curr->next;
 	if (curr->prev != NULL)
 		curr->prev->next=curr->next;
-	if (curr->next != NULL) /* should always be true */
+	if (curr->next != NULL)
 		curr->next->prev=curr->prev;
 	(*tail)->next=curr;
 	curr->prev= *tail;
@@ -441,69 +609,105 @@
 	*tail=curr;
 	}
 
-struct disabled_masks { /* This is a kludge no longer needed with OpenSSL 0.9.9,
-                         * where 128-bit and 256-bit algorithms simply will get
-                         * separate bits. */
-  unsigned long mask; /* everything except m256 */
-  unsigned long m256; /* applies to 256-bit algorithms only */
-};
-
-static struct disabled_masks ssl_cipher_get_disabled(void)
+static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr,
+	     CIPHER_ORDER **tail)
 	{
-	unsigned long mask;
-	unsigned long m256;
-	struct disabled_masks ret;
+	if (curr == *head) return;
+	if (curr == *tail)
+		*tail=curr->prev;
+	if (curr->next != NULL)
+		curr->next->prev=curr->prev;
+	if (curr->prev != NULL)
+		curr->prev->next=curr->next;
+	(*head)->prev=curr;
+	curr->next= *head;
+	curr->prev=NULL;
+	*head=curr;
+	}
 
-	mask = SSL_kFZA;
+static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, unsigned long *enc, unsigned long *mac, unsigned long *ssl)
+	{
+	*mkey = 0;
+	*auth = 0;
+	*enc = 0;
+	*mac = 0;
+	*ssl = 0;
+
 #ifdef OPENSSL_NO_RSA
-	mask |= SSL_aRSA|SSL_kRSA;
+	*mkey |= SSL_kRSA;
+	*auth |= SSL_aRSA;
 #endif
 #ifdef OPENSSL_NO_DSA
-	mask |= SSL_aDSS;
+	*auth |= SSL_aDSS;
 #endif
+	*mkey |= SSL_kDHr|SSL_kDHd; /* no such ciphersuites supported! */
+	*auth |= SSL_aDH;
 #ifdef OPENSSL_NO_DH
-	mask |= SSL_kDHr|SSL_kDHd|SSL_kEDH|SSL_aDH;
+	*mkey |= SSL_kDHr|SSL_kDHd|SSL_kEDH;
+	*auth |= SSL_aDH;
 #endif
 #ifdef OPENSSL_NO_KRB5
-	mask |= SSL_kKRB5|SSL_aKRB5;
+	*mkey |= SSL_kKRB5;
+	*auth |= SSL_aKRB5;
+#endif
+#ifdef OPENSSL_NO_ECDSA
+	*auth |= SSL_aECDSA;
 #endif
 #ifdef OPENSSL_NO_ECDH
-	mask |= SSL_kECDH|SSL_kECDHE;
+	*mkey |= SSL_kECDHe|SSL_kECDHr;
+	*auth |= SSL_aECDH;
 #endif
+#ifdef OPENSSL_NO_PSK
+	*mkey |= SSL_kPSK;
+	*auth |= SSL_aPSK;
+#endif
+	/* Check for presence of GOST 34.10 algorithms, and if they
+	 * do not present, disable  appropriate auth and key exchange */
+	if (!get_optional_pkey_id("gost94")) {
+		*auth |= SSL_aGOST94;
+	}
+	if (!get_optional_pkey_id("gost2001")) {
+		*auth |= SSL_aGOST01;
+	}
+	/* Disable GOST key exchange if no GOST signature algs are available * */
+	if ((*auth & (SSL_aGOST94|SSL_aGOST01)) == (SSL_aGOST94|SSL_aGOST01)) {
+		*mkey |= SSL_kGOST;
+	}	
 #ifdef SSL_FORBID_ENULL
-	mask |= SSL_eNULL;
+	*enc |= SSL_eNULL;
 #endif
+		
 
-	mask |= (ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL) ? SSL_DES :0;
-	mask |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES:0;
-	mask |= (ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL) ? SSL_RC4 :0;
-	mask |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0;
-	mask |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0;
-	mask |= (ssl_cipher_methods[SSL_ENC_eFZA_IDX] == NULL) ? SSL_eFZA:0;
-	mask |= (ssl_cipher_methods[SSL_ENC_SEED_IDX] == NULL) ? SSL_SEED:0;
 
-	mask |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0;
-	mask |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL) ? SSL_DES :0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES:0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL) ? SSL_RC4 :0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES128:0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES256:0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == NULL) ? SSL_CAMELLIA128:0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == NULL) ? SSL_CAMELLIA256:0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_GOST89_IDX] == NULL) ? SSL_eGOST2814789CNT:0;
+	*enc |= (ssl_cipher_methods[SSL_ENC_SEED_IDX] == NULL) ? SSL_SEED:0;
 
-	/* finally consider algorithms where mask and m256 differ */
-	m256 = mask;
-	mask |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES:0;
-	mask |= (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == NULL) ? SSL_CAMELLIA:0;
-	m256 |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES:0;
-	m256 |= (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == NULL) ? SSL_CAMELLIA:0;
+	*mac |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0;
+	*mac |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0;
+	*mac |= (ssl_digest_methods[SSL_MD_GOST94_IDX] == NULL) ? SSL_GOST94:0;
+	*mac |= (ssl_digest_methods[SSL_MD_GOST89MAC_IDX] == NULL || ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]==NID_undef)? SSL_GOST89MAC:0;
 
-	ret.mask = mask;
-	ret.m256 = m256;
-	return ret;
 	}
 
 static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
-		int num_of_ciphers, unsigned long mask, unsigned long m256,
-		CIPHER_ORDER *co_list, CIPHER_ORDER **head_p,
-		CIPHER_ORDER **tail_p)
+                int num_of_ciphers,
+                unsigned long disabled_mkey, unsigned long disabled_auth,
+                unsigned long disabled_enc, unsigned long disabled_mac,
+                unsigned long disabled_ssl,
+                CIPHER_ORDER *co_list,
+                CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
 	{
 	int i, co_list_num;
-	SSL_CIPHER *c;
+	const SSL_CIPHER *c;
 
 	/*
 	 * We have num_of_ciphers descriptions compiled in, depending on the
@@ -517,14 +721,13 @@
 	for (i = 0; i < num_of_ciphers; i++)
 		{
 		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
+		if ((c != NULL) && c->valid &&
+		    !(c->algorithm_mkey & disabled_mkey) &&
+		    !(c->algorithm_auth & disabled_auth) &&
+		    !(c->algorithm_enc & disabled_enc) &&
+		    !(c->algorithm_mac & disabled_mac) &&
+		    !(c->algorithm_ssl & disabled_ssl))
 			{
 			co_list[co_list_num].cipher = c;
 			co_list[co_list_num].next = NULL;
@@ -532,7 +735,7 @@
 			co_list[co_list_num].active = 0;
 			co_list_num++;
 #ifdef KSSL_DEBUG
-			printf("\t%d: %s %lx %lx\n",i,c->name,c->id,c->algorithms);
+			printf("\t%d: %s %lx %lx %lx\n",i,c->name,c->id,c->algorithm_mkey,c->algorithm_auth);
 #endif	/* KSSL_DEBUG */
 			/*
 			if (!sk_push(ca_list,(char *)c)) goto err;
@@ -543,29 +746,45 @@
 	/*
 	 * Prepare linked list from list entries
 	 */	
-	for (i = 1; i < co_list_num - 1; i++)
-		{
-		co_list[i].prev = &(co_list[i-1]);
-		co_list[i].next = &(co_list[i+1]);
-		}
 	if (co_list_num > 0)
 		{
-		(*head_p) = &(co_list[0]);
-		(*head_p)->prev = NULL;
-		(*head_p)->next = &(co_list[1]);
-		(*tail_p) = &(co_list[co_list_num - 1]);
-		(*tail_p)->prev = &(co_list[co_list_num - 2]);
-		(*tail_p)->next = NULL;
+		co_list[0].prev = NULL;
+
+		if (co_list_num > 1)
+			{
+			co_list[0].next = &co_list[1];
+			
+			for (i = 1; i < co_list_num - 1; i++)
+				{
+				co_list[i].prev = &co_list[i - 1];
+				co_list[i].next = &co_list[i + 1];
+				}
+
+			co_list[co_list_num - 1].prev = &co_list[co_list_num - 2];
+			}
+		
+		co_list[co_list_num - 1].next = NULL;
+
+		*head_p = &co_list[0];
+		*tail_p = &co_list[co_list_num - 1];
 		}
 	}
 
-static void ssl_cipher_collect_aliases(SSL_CIPHER **ca_list,
-			int num_of_group_aliases, unsigned long mask,
+static void ssl_cipher_collect_aliases(const SSL_CIPHER **ca_list,
+                        int num_of_group_aliases,
+                        unsigned long disabled_mkey, unsigned long disabled_auth,
+                        unsigned long disabled_enc, unsigned long disabled_mac,
+                        unsigned long disabled_ssl,
 			CIPHER_ORDER *head)
 	{
 	CIPHER_ORDER *ciph_curr;
-	SSL_CIPHER **ca_curr;
+	const SSL_CIPHER **ca_curr;
 	int i;
+	unsigned long mask_mkey = ~disabled_mkey;
+	unsigned long mask_auth = ~disabled_auth;
+	unsigned long mask_enc = ~disabled_enc;
+	unsigned long mask_mac = ~disabled_mac;
+	unsigned long mask_ssl = ~disabled_ssl;
 
 	/*
 	 * First, add the real ciphers as already collected
@@ -581,84 +800,118 @@
 
 	/*
 	 * Now we add the available ones from the cipher_aliases[] table.
-	 * They represent either an algorithm, that must be fully
-	 * supported (not match any bit in mask) or represent a cipher
-	 * strength value (will be added in any case because algorithms=0).
+	 * They represent either one or more algorithms, some of which
+	 * in any affected category must be supported (set in enabled_mask),
+	 * or represent a cipher strength value (will be added in any case because algorithms=0).
 	 */
 	for (i = 0; i < num_of_group_aliases; i++)
 		{
-		if ((i == 0) ||		/* always fetch "ALL" */
-		    !(cipher_aliases[i].algorithms & mask))
-			{
-			*ca_curr = (SSL_CIPHER *)(cipher_aliases + i);
-			ca_curr++;
-			}
+		unsigned long algorithm_mkey = cipher_aliases[i].algorithm_mkey;
+		unsigned long algorithm_auth = cipher_aliases[i].algorithm_auth;
+		unsigned long algorithm_enc = cipher_aliases[i].algorithm_enc;
+		unsigned long algorithm_mac = cipher_aliases[i].algorithm_mac;
+		unsigned long algorithm_ssl = cipher_aliases[i].algorithm_ssl;
+
+		if (algorithm_mkey)
+			if ((algorithm_mkey & mask_mkey) == 0)
+				continue;
+	
+		if (algorithm_auth)
+			if ((algorithm_auth & mask_auth) == 0)
+				continue;
+		
+		if (algorithm_enc)
+			if ((algorithm_enc & mask_enc) == 0)
+				continue;
+		
+		if (algorithm_mac)
+			if ((algorithm_mac & mask_mac) == 0)
+				continue;
+		
+		if (algorithm_ssl)
+			if ((algorithm_ssl & mask_ssl) == 0)
+				continue;
+		
+		*ca_curr = (SSL_CIPHER *)(cipher_aliases + i);
+		ca_curr++;
 		}
 
 	*ca_curr = NULL;	/* end of list */
 	}
 
-static void ssl_cipher_apply_rule(unsigned long cipher_id, unsigned long ssl_version,
-		unsigned long algorithms, unsigned long mask,
-		unsigned long algo_strength, unsigned long mask_strength,
-		int rule, int strength_bits, CIPHER_ORDER *co_list,
+static void ssl_cipher_apply_rule(unsigned long cipher_id,
+                unsigned long alg_mkey, unsigned long alg_auth,
+                unsigned long alg_enc, unsigned long alg_mac,
+                unsigned long alg_ssl,
+		unsigned long algo_strength,
+		int rule, int strength_bits,
 		CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
 	{
-	CIPHER_ORDER *head, *tail, *curr, *curr2, *tail2;
-	SSL_CIPHER *cp;
-	unsigned long ma, ma_s;
+	CIPHER_ORDER *head, *tail, *curr, *curr2, *last;
+	const SSL_CIPHER *cp;
+	int reverse = 0;
 
 #ifdef CIPHER_DEBUG
-	printf("Applying rule %d with %08lx %08lx %08lx %08lx (%d)\n",
-		rule, algorithms, mask, algo_strength, mask_strength,
-		strength_bits);
+	printf("Applying rule %d with %08lx/%08lx/%08lx/%08lx/%08lx %08lx (%d)\n",
+		rule, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength, strength_bits);
 #endif
 
-	curr = head = *head_p;
-	curr2 = head;
-	tail2 = tail = *tail_p;
+	if (rule == CIPHER_DEL)
+		reverse = 1; /* needed to maintain sorting between currently deleted ciphers */
+
+	head = *head_p;
+	tail = *tail_p;
+
+	if (reverse)
+		{
+		curr = tail;
+		last = head;
+		}
+	else
+		{
+		curr = head;
+		last = tail;
+		}
+
+	curr2 = curr;
 	for (;;)
 		{
-		if ((curr == NULL) || (curr == tail2)) break;
+		if ((curr == NULL) || (curr == last)) break;
 		curr = curr2;
-		curr2 = curr->next;
+		curr2 = reverse ? curr->prev : curr->next;
 
 		cp = curr->cipher;
 
-		/* If explicit cipher suite, match only that one for its own protocol version.
-		 * Usual selection criteria will be used for similar ciphersuites from other version! */
-
-		if (cipher_id && (cp->algorithms & SSL_SSL_MASK) == ssl_version)
+		/*
+		 * Selection criteria is either the value of strength_bits
+		 * or the algorithms used.
+		 */
+		if (strength_bits >= 0)
 			{
-			if (cp->id != cipher_id)
+			if (strength_bits != cp->strength_bits)
 				continue;
 			}
-
-		/*
-		 * Selection criteria is either the number of strength_bits
-		 * or the algorithm used.
-		 */
-		else if (strength_bits == -1)
+		else
 			{
-			ma = mask & cp->algorithms;
-			ma_s = mask_strength & cp->algo_strength;
-
 #ifdef CIPHER_DEBUG
-			printf("\nName: %s:\nAlgo = %08lx Algo_strength = %08lx\nMask = %08lx Mask_strength %08lx\n", cp->name, cp->algorithms, cp->algo_strength, mask, mask_strength);
-			printf("ma = %08lx ma_s %08lx, ma&algo=%08lx, ma_s&algos=%08lx\n", ma, ma_s, ma&algorithms, ma_s&algo_strength);
+			printf("\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", cp->name, cp->algorithm_mkey, cp->algorithm_auth, cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, cp->algo_strength);
 #endif
-			/*
-			 * Select: if none of the mask bit was met from the
-			 * cipher or not all of the bits were met, the
-			 * selection does not apply.
-			 */
-			if (((ma == 0) && (ma_s == 0)) ||
-			    ((ma & algorithms) != ma) ||
-			    ((ma_s & algo_strength) != ma_s))
-				continue; /* does not apply */
+
+			if (alg_mkey && !(alg_mkey & cp->algorithm_mkey))
+				continue;
+			if (alg_auth && !(alg_auth & cp->algorithm_auth))
+				continue;
+			if (alg_enc && !(alg_enc & cp->algorithm_enc))
+				continue;
+			if (alg_mac && !(alg_mac & cp->algorithm_mac))
+				continue;
+			if (alg_ssl && !(alg_ssl & cp->algorithm_ssl))
+				continue;
+			if ((algo_strength & SSL_EXP_MASK) && !(algo_strength & SSL_EXP_MASK & cp->algo_strength))
+				continue;
+			if ((algo_strength & SSL_STRONG_MASK) && !(algo_strength & SSL_STRONG_MASK & cp->algo_strength))
+				continue;
 			}
-		else if (strength_bits != cp->strength_bits)
-			continue;	/* does not apply */
 
 #ifdef CIPHER_DEBUG
 		printf("Action = %d\n", rule);
@@ -667,38 +920,37 @@
 		/* add the cipher if it has not been added yet. */
 		if (rule == CIPHER_ADD)
 			{
+			/* reverse == 0 */
 			if (!curr->active)
 				{
-				int add_this_cipher = 1;
-
-				if (((cp->algorithms & (SSL_kECDHE|SSL_kECDH|SSL_aECDSA)) != 0))
-					{
-					/* Make sure "ECCdraft" ciphersuites are activated only if
-					 * *explicitly* requested, but not implicitly (such as
-					 * as part of the "AES" alias). */
-
-					add_this_cipher = (mask & (SSL_kECDHE|SSL_kECDH|SSL_aECDSA)) != 0 || cipher_id != 0;
-					}
-				
-				if (add_this_cipher)
-					{
-					ll_append_tail(&head, curr, &tail);
-					curr->active = 1;
-					}
+				ll_append_tail(&head, curr, &tail);
+				curr->active = 1;
 				}
 			}
 		/* Move the added cipher to this location */
 		else if (rule == CIPHER_ORD)
 			{
+			/* reverse == 0 */
 			if (curr->active)
 				{
 				ll_append_tail(&head, curr, &tail);
 				}
 			}
 		else if	(rule == CIPHER_DEL)
-			curr->active = 0;
+			{
+			/* reverse == 1 */
+			if (curr->active)
+				{
+				/* most recently deleted ciphersuites get best positions
+				 * for any future CIPHER_ADD (note that the CIPHER_DEL loop
+				 * works in reverse to maintain the order) */
+				ll_append_head(&head, curr, &tail);
+				curr->active = 0;
+				}
+			}
 		else if (rule == CIPHER_KILL)
 			{
+			/* reverse == 0 */
 			if (head == curr)
 				head = curr->next;
 			else
@@ -719,8 +971,7 @@
 	*tail_p = tail;
 	}
 
-static int ssl_cipher_strength_sort(CIPHER_ORDER *co_list,
-				    CIPHER_ORDER **head_p,
+static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p,
 				    CIPHER_ORDER **tail_p)
 	{
 	int max_strength_bits, i, *number_uses;
@@ -743,10 +994,10 @@
 
 	number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int));
 	if (!number_uses)
-	{
+		{
 		SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT,ERR_R_MALLOC_FAILURE);
 		return(0);
-	}
+		}
 	memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int));
 
 	/*
@@ -765,21 +1016,20 @@
 	 */
 	for (i = max_strength_bits; i >= 0; i--)
 		if (number_uses[i] > 0)
-			ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, CIPHER_ORD, i,
-					co_list, head_p, tail_p);
+			ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, head_p, tail_p);
 
 	OPENSSL_free(number_uses);
 	return(1);
 	}
 
 static int ssl_cipher_process_rulestr(const char *rule_str,
-		CIPHER_ORDER *co_list, CIPHER_ORDER **head_p,
-		CIPHER_ORDER **tail_p, SSL_CIPHER **ca_list)
+                CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p,
+                const SSL_CIPHER **ca_list)
 	{
-	unsigned long algorithms, mask, algo_strength, mask_strength;
+	unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength;
 	const char *l, *start, *buf;
 	int j, multi, found, rule, retval, ok, buflen;
-	unsigned long cipher_id = 0, ssl_version = 0;
+	unsigned long cipher_id = 0;
 	char ch;
 
 	retval = 1;
@@ -807,7 +1057,12 @@
 			continue;
 			}
 
-		algorithms = mask = algo_strength = mask_strength = 0;
+		alg_mkey = 0;
+		alg_auth = 0;
+		alg_enc = 0;
+		alg_mac = 0;
+		alg_ssl = 0;
+		algo_strength = 0;
 
 		start=l;
 		for (;;)
@@ -868,10 +1123,9 @@
 			 * sufficient, we have to strncmp() anyway. (We cannot
 			 * use strcmp(), because buf is not '\0' terminated.)
 			 */
-			 j = found = 0;
-			 cipher_id = 0;
-			 ssl_version = 0;
-			 while (ca_list[j])
+			j = found = 0;
+			cipher_id = 0;
+			while (ca_list[j])
 				{
 				if (!strncmp(buf, ca_list[j]->name, buflen) &&
 				    (ca_list[j]->name[buflen] == '\0'))
@@ -882,31 +1136,100 @@
 				else
 					j++;
 				}
+
 			if (!found)
 				break;	/* ignore this entry */
 
-			/* New algorithms:
-			 *  1 - any old restrictions apply outside new mask
-			 *  2 - any new restrictions apply outside old mask
-			 *  3 - enforce old & new where masks intersect
-			 */
-			algorithms = (algorithms & ~ca_list[j]->mask) |		/* 1 */
-			             (ca_list[j]->algorithms & ~mask) |		/* 2 */
-			             (algorithms & ca_list[j]->algorithms);	/* 3 */
-			mask |= ca_list[j]->mask;
-			algo_strength = (algo_strength & ~ca_list[j]->mask_strength) |
-			                (ca_list[j]->algo_strength & ~mask_strength) |
-			                (algo_strength & ca_list[j]->algo_strength);
-			mask_strength |= ca_list[j]->mask_strength;
-
-			/* explicit ciphersuite found */
-			if (ca_list[j]->valid)
+			if (ca_list[j]->algorithm_mkey)
 				{
-				cipher_id = ca_list[j]->id;
-				ssl_version = ca_list[j]->algorithms & SSL_SSL_MASK;
-				break;
+				if (alg_mkey)
+					{
+					alg_mkey &= ca_list[j]->algorithm_mkey;
+					if (!alg_mkey) { found = 0; break; }
+					}
+				else
+					alg_mkey = ca_list[j]->algorithm_mkey;
 				}
 
+			if (ca_list[j]->algorithm_auth)
+				{
+				if (alg_auth)
+					{
+					alg_auth &= ca_list[j]->algorithm_auth;
+					if (!alg_auth) { found = 0; break; }
+					}
+				else
+					alg_auth = ca_list[j]->algorithm_auth;
+				}
+			
+			if (ca_list[j]->algorithm_enc)
+				{
+				if (alg_enc)
+					{
+					alg_enc &= ca_list[j]->algorithm_enc;
+					if (!alg_enc) { found = 0; break; }
+					}
+				else
+					alg_enc = ca_list[j]->algorithm_enc;
+				}
+						
+			if (ca_list[j]->algorithm_mac)
+				{
+				if (alg_mac)
+					{
+					alg_mac &= ca_list[j]->algorithm_mac;
+					if (!alg_mac) { found = 0; break; }
+					}
+				else
+					alg_mac = ca_list[j]->algorithm_mac;
+				}
+			
+			if (ca_list[j]->algo_strength & SSL_EXP_MASK)
+				{
+				if (algo_strength & SSL_EXP_MASK)
+					{
+					algo_strength &= (ca_list[j]->algo_strength & SSL_EXP_MASK) | ~SSL_EXP_MASK;
+					if (!(algo_strength & SSL_EXP_MASK)) { found = 0; break; }
+					}
+				else
+					algo_strength |= ca_list[j]->algo_strength & SSL_EXP_MASK;
+				}
+
+			if (ca_list[j]->algo_strength & SSL_STRONG_MASK)
+				{
+				if (algo_strength & SSL_STRONG_MASK)
+					{
+					algo_strength &= (ca_list[j]->algo_strength & SSL_STRONG_MASK) | ~SSL_STRONG_MASK;
+					if (!(algo_strength & SSL_STRONG_MASK)) { found = 0; break; }
+					}
+				else
+					algo_strength |= ca_list[j]->algo_strength & SSL_STRONG_MASK;
+				}
+			
+			if (ca_list[j]->valid)
+				{
+				/* explicit ciphersuite found; its protocol version
+				 * does not become part of the search pattern!*/
+
+				cipher_id = ca_list[j]->id;
+				}
+			else
+				{
+				/* not an explicit ciphersuite; only in this case, the
+				 * protocol version is considered part of the search pattern */
+
+				if (ca_list[j]->algorithm_ssl)
+					{
+					if (alg_ssl)
+						{
+						alg_ssl &= ca_list[j]->algorithm_ssl;
+						if (!alg_ssl) { found = 0; break; }
+						}
+					else
+						alg_ssl = ca_list[j]->algorithm_ssl;
+					}
+				}
+			
 			if (!multi) break;
 			}
 
@@ -918,8 +1241,7 @@
 			ok = 0;
 			if ((buflen == 8) &&
 				!strncmp(buf, "STRENGTH", 8))
-				ok = ssl_cipher_strength_sort(co_list,
-					head_p, tail_p);
+				ok = ssl_cipher_strength_sort(head_p, tail_p);
 			else
 				SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,
 					SSL_R_INVALID_COMMAND);
@@ -936,9 +1258,9 @@
 			}
 		else if (found)
 			{
-			ssl_cipher_apply_rule(cipher_id, ssl_version, algorithms, mask,
-				algo_strength, mask_strength, rule, -1,
-				co_list, head_p, tail_p);
+			ssl_cipher_apply_rule(cipher_id,
+				alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength,
+				rule, -1, head_p, tail_p);
 			}
 		else
 			{
@@ -957,12 +1279,11 @@
 		const char *rule_str)
 	{
 	int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;
-	unsigned long disabled_mask;
-	unsigned long disabled_m256;
+	unsigned long disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl;
 	STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list;
 	const char *rule_p;
 	CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
-	SSL_CIPHER **ca_list = NULL;
+	const SSL_CIPHER **ca_list = NULL;
 
 	/*
 	 * Return with error if nothing to do.
@@ -974,12 +1295,7 @@
 	 * To reduce the work to do we only want to process the compiled
 	 * in algorithms, so we first get the mask of disabled ciphers.
 	 */
-	{
-		struct disabled_masks d;
-		d = ssl_cipher_get_disabled();
-		disabled_mask = d.mask;
-		disabled_m256 = d.m256;
-	}
+	ssl_cipher_get_disabled(&disabled_mkey, &disabled_auth, &disabled_enc, &disabled_mac, &disabled_ssl);
 
 	/*
 	 * Now we have to collect the available ciphers from the compiled
@@ -997,8 +1313,52 @@
 		return(NULL);	/* Failure */
 		}
 
-	ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, disabled_mask,
-				   disabled_m256, co_list, &head, &tail);
+	ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers,
+	                           disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl,
+	                           co_list, &head, &tail);
+
+
+	/* Now arrange all ciphers by preference: */
+
+	/* Everything else being equal, prefer ephemeral ECDH over other key exchange mechanisms */
+	ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
+	ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);
+
+	/* AES is our preferred symmetric cipher */
+	ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
+
+	/* Temporarily enable everything else for sorting */
+	ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
+
+	/* Low priority for MD5 */
+	ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head, &tail);
+
+	/* Move anonymous ciphers to the end.  Usually, these will remain disabled.
+	 * (For applications that allow them, they aren't too bad, but we prefer
+	 * authenticated ciphers.) */
+	ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
+
+	/* Move ciphers without forward secrecy to the end */
+	ssl_cipher_apply_rule(0, 0, SSL_aECDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
+	/* ssl_cipher_apply_rule(0, 0, SSL_aDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); */
+	ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
+	ssl_cipher_apply_rule(0, SSL_kPSK, 0,0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
+	ssl_cipher_apply_rule(0, SSL_kKRB5, 0,0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
+
+	/* RC4 is sort-of broken -- move the the end */
+	ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
+
+	/* Now sort by symmetric encryption strength.  The above ordering remains
+	 * in force within each class */
+	if (!ssl_cipher_strength_sort(&head, &tail))
+		{
+		OPENSSL_free(co_list);
+		return NULL;
+		}
+
+	/* Now disable everything (maintaining the ordering!) */
+	ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);
+
 
 	/*
 	 * We also need cipher aliases for selecting based on the rule_str.
@@ -1010,8 +1370,7 @@
 	 */
 	num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER);
 	num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1;
-	ca_list =
-		(SSL_CIPHER **)OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max);
+	ca_list = OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max);
 	if (ca_list == NULL)
 		{
 		OPENSSL_free(co_list);
@@ -1019,7 +1378,8 @@
 		return(NULL);	/* Failure */
 		}
 	ssl_cipher_collect_aliases(ca_list, num_of_group_aliases,
-				   (disabled_mask & disabled_m256), head);
+	                           disabled_mkey, disabled_auth, disabled_enc,
+				   disabled_mac, disabled_ssl, head);
 
 	/*
 	 * If the rule_string begins with DEFAULT, apply the default rule
@@ -1030,23 +1390,23 @@
 	if (strncmp(rule_str,"DEFAULT",7) == 0)
 		{
 		ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST,
-			co_list, &head, &tail, ca_list);
+			&head, &tail, ca_list);
 		rule_p += 7;
 		if (*rule_p == ':')
 			rule_p++;
 		}
 
 	if (ok && (strlen(rule_p) > 0))
-		ok = ssl_cipher_process_rulestr(rule_p, co_list, &head, &tail,
-						ca_list);
+		ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list);
 
-	OPENSSL_free(ca_list);	/* Not needed anymore */
+	OPENSSL_free((void *)ca_list);	/* Not needed anymore */
 
 	if (!ok)
 		{	/* Rule processing failure */
 		OPENSSL_free(co_list);
 		return(NULL);
 		}
+	
 	/*
 	 * Allocate new "cipherstack" for the result, return with error
 	 * if we cannot get one.
@@ -1063,11 +1423,7 @@
 	 */
 	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
@@ -1100,14 +1456,19 @@
 	int is_export,pkl,kl;
 	const char *ver,*exp_str;
 	const char *kx,*au,*enc,*mac;
-	unsigned long alg,alg2,alg_s;
+	unsigned long alg_mkey,alg_auth,alg_enc,alg_mac,alg_ssl,alg2,alg_s;
 #ifdef KSSL_DEBUG
-	static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx\n";
+	static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx/%lx/%lx/%lx/%lx\n";
 #else
 	static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n";
 #endif /* KSSL_DEBUG */
 
-	alg=cipher->algorithms;
+	alg_mkey = cipher->algorithm_mkey;
+	alg_auth = cipher->algorithm_auth;
+	alg_enc = cipher->algorithm_enc;
+	alg_mac = cipher->algorithm_mac;
+	alg_ssl = cipher->algorithm_ssl;
+
 	alg_s=cipher->algo_strength;
 	alg2=cipher->algorithm2;
 
@@ -1116,14 +1477,14 @@
 	kl=SSL_C_EXPORT_KEYLENGTH(cipher);
 	exp_str=is_export?" export":"";
 	
-	if (alg & SSL_SSLV2)
+	if (alg_ssl & SSL_SSLV2)
 		ver="SSLv2";
-	else if (alg & SSL_SSLV3)
+	else if (alg_ssl & SSL_SSLV3)
 		ver="SSLv3";
 	else
 		ver="unknown";
 
-	switch (alg&SSL_MKEY_MASK)
+	switch (alg_mkey)
 		{
 	case SSL_kRSA:
 		kx=is_export?(pkl == 512 ? "RSA(512)" : "RSA(1024)"):"RSA";
@@ -1134,25 +1495,29 @@
 	case SSL_kDHd:
 		kx="DH/DSS";
 		break;
-        case SSL_kKRB5:         /* VRS */
-        case SSL_KRB5:          /* VRS */
-            kx="KRB5";
-            break;
-	case SSL_kFZA:
-		kx="Fortezza";
+        case SSL_kKRB5:
+		kx="KRB5";
 		break;
 	case SSL_kEDH:
 		kx=is_export?(pkl == 512 ? "DH(512)" : "DH(1024)"):"DH";
 		break;
-	case SSL_kECDH:
-	case SSL_kECDHE:
-		kx=is_export?"ECDH(<=163)":"ECDH";
+	case SSL_kECDHr:
+		kx="ECDH/RSA";
+		break;
+	case SSL_kECDHe:
+		kx="ECDH/ECDSA";
+		break;
+	case SSL_kEECDH:
+		kx="ECDH";
+		break;
+	case SSL_kPSK:
+		kx="PSK";
 		break;
 	default:
 		kx="unknown";
 		}
 
-	switch (alg&SSL_AUTH_MASK)
+	switch (alg_auth)
 		{
 	case SSL_aRSA:
 		au="RSA";
@@ -1163,23 +1528,27 @@
 	case SSL_aDH:
 		au="DH";
 		break;
-        case SSL_aKRB5:         /* VRS */
-        case SSL_KRB5:          /* VRS */
-            au="KRB5";
-            break;
-	case SSL_aFZA:
+        case SSL_aKRB5:
+		au="KRB5";
+		break;
+        case SSL_aECDH:
+		au="ECDH";
+		break;
 	case SSL_aNULL:
 		au="None";
 		break;
 	case SSL_aECDSA:
 		au="ECDSA";
 		break;
+	case SSL_aPSK:
+		au="PSK";
+		break;
 	default:
 		au="unknown";
 		break;
 		}
 
-	switch (alg&SSL_ENC_MASK)
+	switch (alg_enc)
 		{
 	case SSL_DES:
 		enc=(is_export && kl == 5)?"DES(40)":"DES(56)";
@@ -1197,39 +1566,30 @@
 	case SSL_IDEA:
 		enc="IDEA(128)";
 		break;
-	case SSL_eFZA:
-		enc="Fortezza";
-		break;
 	case SSL_eNULL:
 		enc="None";
 		break;
-	case SSL_AES:
-		switch(cipher->strength_bits)
-			{
-		case 128: enc="AES(128)"; break;
-		case 192: enc="AES(192)"; break;
-		case 256: enc="AES(256)"; break;
-		default: enc="AES(?""?""?)"; break;
-			}
+	case SSL_AES128:
+		enc="AES(128)";
 		break;
-	case SSL_CAMELLIA:
-		switch(cipher->strength_bits)
-			{
-		case 128: enc="Camellia(128)"; break;
-		case 256: enc="Camellia(256)"; break;
-		default: enc="Camellia(?""?""?)"; break;
-			}
+	case SSL_AES256:
+		enc="AES(256)";
+		break;
+	case SSL_CAMELLIA128:
+		enc="Camellia(128)";
+		break;
+	case SSL_CAMELLIA256:
+		enc="Camellia(256)";
 		break;
 	case SSL_SEED:
 		enc="SEED(128)";
 		break;
-
 	default:
 		enc="unknown";
 		break;
 		}
 
-	switch (alg&SSL_MAC_MASK)
+	switch (alg_mac)
 		{
 	case SSL_MD5:
 		mac="MD5";
@@ -1252,7 +1612,7 @@
 		return("Buffer too small");
 
 #ifdef KSSL_DEBUG
-	BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp_str,alg);
+	BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp_str,alg_mkey,alg_auth,alg_enc,alg_mac,alg_ssl);
 #else
 	BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp_str);
 #endif /* KSSL_DEBUG */
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index 7eb5202..0eed464 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -1,6 +1,6 @@
 /* ssl/ssl_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2008 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2009 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -141,6 +141,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_DIGEST_CACHED_RECORDS),	"SSL3_DIGEST_CACHED_RECORDS"},
 {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"},
@@ -158,6 +159,7 @@
 {ERR_FUNC(SSL_F_SSL3_GET_SERVER_CERTIFICATE),	"SSL3_GET_SERVER_CERTIFICATE"},
 {ERR_FUNC(SSL_F_SSL3_GET_SERVER_DONE),	"SSL3_GET_SERVER_DONE"},
 {ERR_FUNC(SSL_F_SSL3_GET_SERVER_HELLO),	"SSL3_GET_SERVER_HELLO"},
+{ERR_FUNC(SSL_F_SSL3_HANDSHAKE_MAC),	"ssl3_handshake_mac"},
 {ERR_FUNC(SSL_F_SSL3_NEW_SESSION_TICKET),	"SSL3_NEW_SESSION_TICKET"},
 {ERR_FUNC(SSL_F_SSL3_OUTPUT_CERT_CHAIN),	"SSL3_OUTPUT_CERT_CHAIN"},
 {ERR_FUNC(SSL_F_SSL3_PEEK),	"SSL3_PEEK"},
@@ -170,8 +172,9 @@
 {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_CERTIFICATE),	"SSL3_SEND_SERVER_CERTIFICATE"},
 {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_HELLO),	"SSL3_SEND_SERVER_HELLO"},
 {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE),	"SSL3_SEND_SERVER_KEY_EXCHANGE"},
-{ERR_FUNC(SSL_F_SSL3_SETUP_BUFFERS),	"SSL3_SETUP_BUFFERS"},
 {ERR_FUNC(SSL_F_SSL3_SETUP_KEY_BLOCK),	"SSL3_SETUP_KEY_BLOCK"},
+{ERR_FUNC(SSL_F_SSL3_SETUP_READ_BUFFER),	"SSL3_SETUP_READ_BUFFER"},
+{ERR_FUNC(SSL_F_SSL3_SETUP_WRITE_BUFFER),	"SSL3_SETUP_WRITE_BUFFER"},
 {ERR_FUNC(SSL_F_SSL3_WRITE_BYTES),	"SSL3_WRITE_BYTES"},
 {ERR_FUNC(SSL_F_SSL3_WRITE_PENDING),	"SSL3_WRITE_PENDING"},
 {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT),	"SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT"},
@@ -188,6 +191,7 @@
 {ERR_FUNC(SSL_F_SSL_CERT_NEW),	"SSL_CERT_NEW"},
 {ERR_FUNC(SSL_F_SSL_CHECK_PRIVATE_KEY),	"SSL_check_private_key"},
 {ERR_FUNC(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT),	"SSL_CHECK_SERVERHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG),	"SSL_CHECK_SRVR_ECC_CERT_AND_ALG"},
 {ERR_FUNC(SSL_F_SSL_CIPHER_PROCESS_RULESTR),	"SSL_CIPHER_PROCESS_RULESTR"},
 {ERR_FUNC(SSL_F_SSL_CIPHER_STRENGTH_SORT),	"SSL_CIPHER_STRENGTH_SORT"},
 {ERR_FUNC(SSL_F_SSL_CLEAR),	"SSL_clear"},
@@ -209,6 +213,7 @@
 {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY),	"SSL_CTX_use_PrivateKey"},
 {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1),	"SSL_CTX_use_PrivateKey_ASN1"},
 {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE),	"SSL_CTX_use_PrivateKey_file"},
+{ERR_FUNC(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT),	"SSL_CTX_use_psk_identity_hint"},
 {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY),	"SSL_CTX_use_RSAPrivateKey"},
 {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1),	"SSL_CTX_use_RSAPrivateKey_ASN1"},
 {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE),	"SSL_CTX_use_RSAPrivateKey_file"},
@@ -241,6 +246,7 @@
 {ERR_FUNC(SSL_F_SSL_SET_RFD),	"SSL_set_rfd"},
 {ERR_FUNC(SSL_F_SSL_SET_SESSION),	"SSL_set_session"},
 {ERR_FUNC(SSL_F_SSL_SET_SESSION_ID_CONTEXT),	"SSL_set_session_id_context"},
+{ERR_FUNC(SSL_F_SSL_SET_SESSION_TICKET_EXT),	"SSL_set_session_ticket_ext"},
 {ERR_FUNC(SSL_F_SSL_SET_TRUST),	"SSL_set_trust"},
 {ERR_FUNC(SSL_F_SSL_SET_WFD),	"SSL_set_wfd"},
 {ERR_FUNC(SSL_F_SSL_SHUTDOWN),	"SSL_shutdown"},
@@ -253,13 +259,19 @@
 {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY),	"SSL_use_PrivateKey"},
 {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_ASN1),	"SSL_use_PrivateKey_ASN1"},
 {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_FILE),	"SSL_use_PrivateKey_file"},
+{ERR_FUNC(SSL_F_SSL_USE_PSK_IDENTITY_HINT),	"SSL_use_psk_identity_hint"},
 {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY),	"SSL_use_RSAPrivateKey"},
 {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1),	"SSL_use_RSAPrivateKey_ASN1"},
 {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE),	"SSL_use_RSAPrivateKey_file"},
 {ERR_FUNC(SSL_F_SSL_VERIFY_CERT_CHAIN),	"SSL_VERIFY_CERT_CHAIN"},
 {ERR_FUNC(SSL_F_SSL_WRITE),	"SSL_write"},
+{ERR_FUNC(SSL_F_TLS1_CERT_VERIFY_MAC),	"tls1_cert_verify_mac"},
 {ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE),	"TLS1_CHANGE_CIPHER_STATE"},
+{ERR_FUNC(SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT),	"TLS1_CHECK_SERVERHELLO_TLSEXT"},
 {ERR_FUNC(SSL_F_TLS1_ENC),	"TLS1_ENC"},
+{ERR_FUNC(SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT),	"TLS1_PREPARE_CLIENTHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT),	"TLS1_PREPARE_SERVERHELLO_TLSEXT"},
+{ERR_FUNC(SSL_F_TLS1_PRF),	"tls1_prf"},
 {ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK),	"TLS1_SETUP_KEY_BLOCK"},
 {ERR_FUNC(SSL_F_WRITE_PENDING),	"WRITE_PENDING"},
 {0,NULL}
@@ -283,12 +295,15 @@
 {ERR_REASON(SSL_R_BAD_ECC_CERT)          ,"bad ecc cert"},
 {ERR_REASON(SSL_R_BAD_ECDSA_SIGNATURE)   ,"bad ecdsa signature"},
 {ERR_REASON(SSL_R_BAD_ECPOINT)           ,"bad ecpoint"},
+{ERR_REASON(SSL_R_BAD_HANDSHAKE_LENGTH)  ,"bad handshake length"},
 {ERR_REASON(SSL_R_BAD_HELLO_REQUEST)     ,"bad hello request"},
 {ERR_REASON(SSL_R_BAD_LENGTH)            ,"bad length"},
 {ERR_REASON(SSL_R_BAD_MAC_DECODE)        ,"bad mac decode"},
+{ERR_REASON(SSL_R_BAD_MAC_LENGTH)        ,"bad mac length"},
 {ERR_REASON(SSL_R_BAD_MESSAGE_TYPE)      ,"bad message type"},
 {ERR_REASON(SSL_R_BAD_PACKET_LENGTH)     ,"bad packet length"},
 {ERR_REASON(SSL_R_BAD_PROTOCOL_VERSION_NUMBER),"bad protocol version number"},
+{ERR_REASON(SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH),"bad psk identity hint length"},
 {ERR_REASON(SSL_R_BAD_RESPONSE_ARGUMENT) ,"bad response argument"},
 {ERR_REASON(SSL_R_BAD_RSA_DECRYPT)       ,"bad rsa decrypt"},
 {ERR_REASON(SSL_R_BAD_RSA_ENCRYPT)       ,"bad rsa encrypt"},
@@ -314,6 +329,7 @@
 {ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR),"cipher table src error"},
 {ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT)    ,"clienthello tlsext"},
 {ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG),"compressed length too long"},
+{ERR_REASON(SSL_R_COMPRESSION_DISABLED)  ,"compression disabled"},
 {ERR_REASON(SSL_R_COMPRESSION_FAILURE)   ,"compression failure"},
 {ERR_REASON(SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE),"compression id not within private range"},
 {ERR_REASON(SSL_R_COMPRESSION_LIBRARY_ERROR),"compression library error"},
@@ -328,6 +344,10 @@
 {ERR_REASON(SSL_R_DIGEST_CHECK_FAILED)   ,"digest check failed"},
 {ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG)  ,"dtls message too big"},
 {ERR_REASON(SSL_R_DUPLICATE_COMPRESSION_ID),"duplicate compression id"},
+{ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT),"ecc cert not for key agreement"},
+{ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_SIGNING),"ecc cert not for signing"},
+{ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE),"ecc cert should have rsa signature"},
+{ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE),"ecc cert should have sha1 signature"},
 {ERR_REASON(SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER),"ecgroup too large for cipher"},
 {ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG),"encrypted length too long"},
 {ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY),"error generating tmp rsa key"},
@@ -338,8 +358,10 @@
 {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST)   ,"https proxy request"},
 {ERR_REASON(SSL_R_HTTP_REQUEST)          ,"http request"},
 {ERR_REASON(SSL_R_ILLEGAL_PADDING)       ,"illegal padding"},
+{ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION),"inconsistent compression"},
 {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"},
 {ERR_REASON(SSL_R_INVALID_COMMAND)       ,"invalid command"},
+{ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),"invalid compression algorithm"},
 {ERR_REASON(SSL_R_INVALID_PURPOSE)       ,"invalid purpose"},
 {ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE),"invalid status response"},
 {ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH),"invalid ticket keys length"},
@@ -389,18 +411,22 @@
 {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_GOST_CERTIFICATE_SENT_BY_PEER),"Peer haven't sent GOST certificate, required for selected ciphersuite"},
 {ERR_REASON(SSL_R_NO_METHOD_SPECIFIED)   ,"no method specified"},
 {ERR_REASON(SSL_R_NO_PRIVATEKEY)         ,"no privatekey"},
 {ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED),"no private key assigned"},
 {ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE),"no protocols available"},
 {ERR_REASON(SSL_R_NO_PUBLICKEY)          ,"no publickey"},
 {ERR_REASON(SSL_R_NO_RENEGOTIATION)      ,"no renegotiation"},
+{ERR_REASON(SSL_R_NO_REQUIRED_DIGEST)    ,"digest requred for handshake isn't computed"},
 {ERR_REASON(SSL_R_NO_SHARED_CIPHER)      ,"no shared cipher"},
 {ERR_REASON(SSL_R_NO_VERIFY_CALLBACK)    ,"no verify callback"},
 {ERR_REASON(SSL_R_NULL_SSL_CTX)          ,"null ssl ctx"},
 {ERR_REASON(SSL_R_NULL_SSL_METHOD_PASSED),"null ssl method passed"},
 {ERR_REASON(SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED),"old session cipher not returned"},
+{ERR_REASON(SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED),"old session compression algorithm not returned"},
 {ERR_REASON(SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE),"only tls allowed in fips mode"},
+{ERR_REASON(SSL_R_OPAQUE_PRF_INPUT_TOO_LONG),"opaque PRF input too long"},
 {ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG),"packet length too long"},
 {ERR_REASON(SSL_R_PARSE_TLSEXT)          ,"parse tlsext"},
 {ERR_REASON(SSL_R_PATH_TOO_LONG)         ,"path too long"},
@@ -413,6 +439,9 @@
 {ERR_REASON(SSL_R_PRE_MAC_LENGTH_TOO_LONG),"pre mac length too long"},
 {ERR_REASON(SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS),"problems mapping cipher functions"},
 {ERR_REASON(SSL_R_PROTOCOL_IS_SHUTDOWN)  ,"protocol is shutdown"},
+{ERR_REASON(SSL_R_PSK_IDENTITY_NOT_FOUND),"psk identity not found"},
+{ERR_REASON(SSL_R_PSK_NO_CLIENT_CB)      ,"psk no client cb"},
+{ERR_REASON(SSL_R_PSK_NO_SERVER_CB)      ,"psk no server cb"},
 {ERR_REASON(SSL_R_PUBLIC_KEY_ENCRYPT_ERROR),"public key encrypt error"},
 {ERR_REASON(SSL_R_PUBLIC_KEY_IS_NOT_RSA) ,"public key is not rsa"},
 {ERR_REASON(SSL_R_PUBLIC_KEY_NOT_RSA)    ,"public key not rsa"},
@@ -426,6 +455,7 @@
 {ERR_REASON(SSL_R_RENEGOTIATION_ENCODING_ERR),"renegotiation encoding err"},
 {ERR_REASON(SSL_R_RENEGOTIATION_MISMATCH),"renegotiation mismatch"},
 {ERR_REASON(SSL_R_REQUIRED_CIPHER_MISSING),"required cipher missing"},
+{ERR_REASON(SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING),"required compresssion algorithm missing"},
 {ERR_REASON(SSL_R_REUSE_CERT_LENGTH_NOT_ZERO),"reuse cert length not zero"},
 {ERR_REASON(SSL_R_REUSE_CERT_TYPE_NOT_ZERO),"reuse cert type not zero"},
 {ERR_REASON(SSL_R_REUSE_CIPHER_LIST_NOT_ZERO),"reuse cipher list not zero"},
@@ -436,6 +466,7 @@
 {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"},
 {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"},
 {ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG),"ssl2 connection id too long"},
+{ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT),"ssl3 ext invalid ecpointformat"},
 {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME),"ssl3 ext invalid servername"},
 {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE),"ssl3 ext invalid servername type"},
 {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_LONG),"ssl3 session id too long"},
@@ -471,6 +502,11 @@
 {ERR_REASON(SSL_R_TLSV1_ALERT_RECORD_OVERFLOW),"tlsv1 alert record overflow"},
 {ERR_REASON(SSL_R_TLSV1_ALERT_UNKNOWN_CA),"tlsv1 alert unknown ca"},
 {ERR_REASON(SSL_R_TLSV1_ALERT_USER_CANCELLED),"tlsv1 alert user cancelled"},
+{ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE),"tlsv1 bad certificate hash value"},
+{ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE),"tlsv1 bad certificate status response"},
+{ERR_REASON(SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE),"tlsv1 certificate unobtainable"},
+{ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME),"tlsv1 unrecognized name"},
+{ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION),"tlsv1 unsupported extension"},
 {ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER),"tls client cert req with anon cipher"},
 {ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),"tls invalid ecpointformat list"},
 {ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST),"tls peer did not respond with certificate list"},
@@ -502,6 +538,7 @@
 {ERR_REASON(SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED),"unsafe legacy renegotiation disabled"},
 {ERR_REASON(SSL_R_UNSUPPORTED_CIPHER)    ,"unsupported cipher"},
 {ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"},
+{ERR_REASON(SSL_R_UNSUPPORTED_DIGEST_TYPE),"unsupported digest type"},
 {ERR_REASON(SSL_R_UNSUPPORTED_ELLIPTIC_CURVE),"unsupported elliptic curve"},
 {ERR_REASON(SSL_R_UNSUPPORTED_PROTOCOL)  ,"unsupported protocol"},
 {ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION),"unsupported ssl version"},
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 15650da..3157f20 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -58,7 +58,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -115,6 +115,32 @@
  * ECC cipher suite support in OpenSSL originally developed by 
  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 #ifdef REF_CHECK
 #  include <assert.h>
@@ -143,9 +169,9 @@
 	ssl_undefined_function,
 	(int (*)(SSL *, unsigned char *, unsigned char *, int))ssl_undefined_function,
 	(int (*)(SSL*, int))ssl_undefined_function,
-	(int (*)(SSL *, EVP_MD_CTX *, EVP_MD_CTX *, const char*, int, unsigned char *))ssl_undefined_function,
+	(int (*)(SSL *,  const char*, int, unsigned char *))ssl_undefined_function,
 	0,	/* finish_mac_length */
-	(int (*)(SSL *, EVP_MD_CTX *, unsigned char *))ssl_undefined_function,
+	(int (*)(SSL *, int, unsigned char *))ssl_undefined_function,
 	NULL,	/* client_finished_label */
 	0,	/* client_finished_label_len */
 	NULL,	/* server_finished_label */
@@ -204,6 +230,8 @@
 		}
 
 	ssl_clear_cipher_ctx(s);
+	ssl_clear_hash_ctx(&s->read_hash);
+	ssl_clear_hash_ctx(&s->write_hash);
 
 	s->first_packet=0;
 
@@ -224,14 +252,15 @@
 	}
 
 /** Used to change an SSL_CTXs default SSL method type */
-int SSL_CTX_set_ssl_version(SSL_CTX *ctx,SSL_METHOD *meth)
+int SSL_CTX_set_ssl_version(SSL_CTX *ctx,const SSL_METHOD *meth)
 	{
 	STACK_OF(SSL_CIPHER) *sk;
 
 	ctx->method=meth;
 
 	sk=ssl_create_cipher_list(ctx->method,&(ctx->cipher_list),
-		&(ctx->cipher_list_by_id),SSL_DEFAULT_CIPHER_LIST);
+		&(ctx->cipher_list_by_id),
+		meth->version == SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST);
 	if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0))
 		{
 		SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION,SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS);
@@ -308,6 +337,7 @@
 	s->trust = ctx->trust;
 #endif
 	s->quiet_shutdown=ctx->quiet_shutdown;
+	s->max_send_fragment = ctx->max_send_fragment;
 
 	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
 	s->ctx=ctx;
@@ -324,6 +354,7 @@
 	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
 	s->initial_ctx=ctx;
 #endif
+
 	s->verify_result=X509_V_OK;
 
 	s->method=ctx->method;
@@ -338,6 +369,11 @@
 
 	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
 
+#ifndef OPENSSL_NO_PSK
+	s->psk_client_callback=ctx->psk_client_callback;
+	s->psk_server_callback=ctx->psk_server_callback;
+#endif
+
 	return(s);
 err:
 	if (s != NULL)
@@ -425,7 +461,7 @@
 		}
 
 	CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
-	p = (SSL_SESSION *)lh_retrieve(ssl->ctx->sessions, &r);
+	p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r);
 	CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
 	return (p != NULL);
 	}
@@ -450,6 +486,16 @@
 	return X509_VERIFY_PARAM_set_trust(s->param, trust);
 	}
 
+int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm)
+	{
+	return X509_VERIFY_PARAM_set1(ctx->param, vpm);
+	}
+
+int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm)
+	{
+	return X509_VERIFY_PARAM_set1(ssl->param, vpm);
+	}
+
 void SSL_free(SSL *s)
 	{
 	int i;
@@ -504,6 +550,8 @@
 		}
 
 	ssl_clear_cipher_ctx(s);
+	ssl_clear_hash_ctx(&s->read_hash);
+	ssl_clear_hash_ctx(&s->write_hash);
 
 	if (s->cert != NULL) ssl_cert_free(s->cert);
 	/* Free up if allocated */
@@ -512,6 +560,11 @@
 	if (s->tlsext_hostname)
 		OPENSSL_free(s->tlsext_hostname);
 	if (s->initial_ctx) SSL_CTX_free(s->initial_ctx);
+#ifndef OPENSSL_NO_EC
+	if (s->tlsext_ecpointformatlist) OPENSSL_free(s->tlsext_ecpointformatlist);
+	if (s->tlsext_ellipticcurvelist) OPENSSL_free(s->tlsext_ellipticcurvelist);
+#endif /* OPENSSL_NO_EC */
+	if (s->tlsext_opaque_prf_input) OPENSSL_free(s->tlsext_opaque_prf_input);
 	if (s->tlsext_ocsp_exts)
 		sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
 						X509_EXTENSION_free);
@@ -520,6 +573,7 @@
 	if (s->tlsext_ocsp_resp)
 		OPENSSL_free(s->tlsext_ocsp_resp);
 #endif
+
 	if (s->client_CA != NULL)
 		sk_X509_NAME_pop_free(s->client_CA,X509_NAME_free);
 
@@ -844,7 +898,7 @@
 		}
 	if (ssl->cert == NULL)
 		{
-                SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY,SSL_R_NO_CERTIFICATE_ASSIGNED);
+		SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY,SSL_R_NO_CERTIFICATE_ASSIGNED);
 		return 0;
 		}
 	if (ssl->cert->key->x509 == NULL)
@@ -1007,6 +1061,11 @@
 			return larg;
 			}
 		return 0;
+	case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
+		if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
+			return 0;
+		s->max_send_fragment = larg;
+		return 1;
 	case SSL_CTRL_GET_RI_SUPPORT:
 		if (s->s3)
 			return s->s3->send_connection_binding;
@@ -1029,7 +1088,7 @@
 		}
 	}
 
-struct lhash_st *SSL_CTX_sessions(SSL_CTX *ctx)
+LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx)
 	{
 	return ctx->sessions;
 	}
@@ -1072,7 +1131,7 @@
 		return(ctx->session_cache_mode);
 
 	case SSL_CTRL_SESS_NUMBER:
-		return(ctx->sessions->num_items);
+		return(lh_SSL_SESSION_num_items(ctx->sessions));
 	case SSL_CTRL_SESS_CONNECT:
 		return(ctx->stats.sess_connect);
 	case SSL_CTRL_SESS_CONNECT_GOOD:
@@ -1103,6 +1162,11 @@
 		return(ctx->mode|=larg);
 	case SSL_CTRL_CLEAR_MODE:
 		return(ctx->mode&=~larg);
+	case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
+		if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
+			return 0;
+		ctx->max_send_fragment = larg;
+		return 1;
 	default:
 		return(ctx->method->ssl_ctx_ctrl(ctx,cmd,larg,parg));
 		}
@@ -1207,8 +1271,8 @@
 	/* ssl_create_cipher_list may return an empty stack if it
 	 * was unable to find a cipher matching the given rule string
 	 * (for example if the rule string specifies a cipher which
-	 * has been disabled). This is not an error as far as 
-	 * ssl_create_cipher_list is concerned, and hence 
+	 * has been disabled). This is not an error as far as
+	 * ssl_create_cipher_list is concerned, and hence
 	 * ctx->cipher_list and ctx->cipher_list_by_id has been
 	 * updated. */
 	if (sk == NULL)
@@ -1276,13 +1340,13 @@
 	}
 
 int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
-                             int (*put_cb)(const SSL_CIPHER *, unsigned char *))
+			     int (*put_cb)(const SSL_CIPHER *, unsigned char *))
 	{
 	int i,j=0;
 	SSL_CIPHER *c;
 	unsigned char *q;
 #ifndef OPENSSL_NO_KRB5
-        int nokrb5 = !kssl_tgt_is_available(s->kssl_ctx);
+	int nokrb5 = !kssl_tgt_is_available(s->kssl_ctx);
 #endif /* OPENSSL_NO_KRB5 */
 
 	if (sk == NULL) return(0);
@@ -1292,10 +1356,16 @@
 		{
 		c=sk_SSL_CIPHER_value(sk,i);
 #ifndef OPENSSL_NO_KRB5
-                if ((c->algorithms & SSL_KRB5) && nokrb5)
-                    continue;
-#endif /* OPENSSL_NO_KRB5 */                    
-
+		if (((c->algorithm_mkey & SSL_kKRB5) || (c->algorithm_auth & SSL_aKRB5)) &&
+		    nokrb5)
+		    continue;
+#endif /* OPENSSL_NO_KRB5 */
+#ifndef OPENSSL_NO_PSK
+		/* with PSK there must be client callback set */
+		if (((c->algorithm_mkey & SSL_kPSK) || (c->algorithm_auth & SSL_aPSK)) &&
+		    s->psk_client_callback == NULL)
+			continue;
+#endif /* OPENSSL_NO_PSK */
 		j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p);
 		p+=j;
 		}
@@ -1306,7 +1376,7 @@
 		{
 		static SSL_CIPHER scsv =
 			{
-			0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0,
+			0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
 			};
 		j = put_cb ? put_cb(&scsv,p) : ssl_put_cipher_by_char(s,&scsv,p);
 		p+=j;
@@ -1321,7 +1391,7 @@
 STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
 					       STACK_OF(SSL_CIPHER) **skp)
 	{
-	SSL_CIPHER *c;
+	const SSL_CIPHER *c;
 	STACK_OF(SSL_CIPHER) *sk;
 	int i,n;
 	if (s->s3)
@@ -1384,6 +1454,7 @@
 	return(NULL);
 	}
 
+
 #ifndef OPENSSL_NO_TLSEXT
 /** return a servername extension value if provided in Client Hello, or NULL.
  * So far, only host_name types are defined (RFC 3546).
@@ -1407,7 +1478,7 @@
 	}
 #endif
 
-unsigned long SSL_SESSION_hash(const SSL_SESSION *a)
+static unsigned long ssl_session_hash(const SSL_SESSION *a)
 	{
 	unsigned long l;
 
@@ -1424,7 +1495,7 @@
  * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on being
  * able to construct an SSL_SESSION that will collide with any existing session
  * with a matching session ID. */
-int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b)
+static int ssl_session_cmp(const SSL_SESSION *a,const SSL_SESSION *b)
 	{
 	if (a->ssl_version != b->ssl_version)
 		return(1);
@@ -1437,27 +1508,19 @@
  * SSL_SESSION_hash and SSL_SESSION_cmp for void* types and casting each
  * variable. The reason is that the functions aren't static, they're exposed via
  * ssl.h. */
-static IMPLEMENT_LHASH_HASH_FN(SSL_SESSION_hash, SSL_SESSION *)
-static IMPLEMENT_LHASH_COMP_FN(SSL_SESSION_cmp, SSL_SESSION *)
+static IMPLEMENT_LHASH_HASH_FN(ssl_session, SSL_SESSION)
+static IMPLEMENT_LHASH_COMP_FN(ssl_session, SSL_SESSION)
 
-SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
+SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
 	{
 	SSL_CTX *ret=NULL;
-	
+
 	if (meth == NULL)
 		{
 		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_NULL_SSL_METHOD_PASSED);
 		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);
@@ -1520,15 +1583,14 @@
 	ret->app_gen_cookie_cb=0;
 	ret->app_verify_cookie_cb=0;
 
-	ret->sessions=lh_new(LHASH_HASH_FN(SSL_SESSION_hash),
-			LHASH_COMP_FN(SSL_SESSION_cmp));
+	ret->sessions=lh_SSL_SESSION_new();
 	if (ret->sessions == NULL) goto err;
 	ret->cert_store=X509_STORE_new();
 	if (ret->cert_store == NULL) goto err;
 
 	ssl_create_cipher_list(ret->method,
 		&ret->cipher_list,&ret->cipher_list_by_id,
-		SSL_DEFAULT_CIPHER_LIST);
+		meth->version == SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST);
 	if (ret->cipher_list == NULL
 	    || sk_SSL_CIPHER_num(ret->cipher_list) <= 0)
 		{
@@ -1564,6 +1626,8 @@
 	ret->extra_certs=NULL;
 	ret->comp_methods=SSL_COMP_get_compression_methods();
 
+	ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
+
 #ifndef OPENSSL_NO_TLSEXT
 	ret->tlsext_servername_callback = 0;
 	ret->tlsext_servername_arg = NULL;
@@ -1577,7 +1641,29 @@
 	ret->tlsext_status_arg = NULL;
 
 #endif
-
+#ifndef OPENSSL_NO_PSK
+	ret->psk_identity_hint=NULL;
+	ret->psk_client_callback=NULL;
+	ret->psk_server_callback=NULL;
+#endif
+#ifndef OPENSSL_NO_BUF_FREELISTS
+	ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT;
+	ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
+	if (!ret->rbuf_freelist)
+		goto err;
+	ret->rbuf_freelist->chunklen = 0;
+	ret->rbuf_freelist->len = 0;
+	ret->rbuf_freelist->head = NULL;
+	ret->wbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
+	if (!ret->wbuf_freelist)
+		{
+		OPENSSL_free(ret->rbuf_freelist);
+		goto err;
+		}
+	ret->wbuf_freelist->chunklen = 0;
+	ret->wbuf_freelist->len = 0;
+	ret->wbuf_freelist->head = NULL;
+#endif
 #ifndef OPENSSL_NO_ENGINE
 	ret->client_cert_engine = NULL;
 #ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO
@@ -1616,6 +1702,20 @@
     { OPENSSL_free(comp); }
 #endif
 
+#ifndef OPENSSL_NO_BUF_FREELISTS
+static void
+ssl_buf_freelist_free(SSL3_BUF_FREELIST *list)
+	{
+	SSL3_BUF_FREELIST_ENTRY *ent, *next;
+	for (ent = list->head; ent; ent = next)
+		{
+		next = ent->next;
+		OPENSSL_free(ent);
+		}
+	OPENSSL_free(list);
+	}
+#endif
+
 void SSL_CTX_free(SSL_CTX *a)
 	{
 	int i;
@@ -1653,7 +1753,7 @@
 	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data);
 
 	if (a->sessions != NULL)
-		lh_free(a->sessions);
+		lh_SSL_SESSION_free(a->sessions);
 
 	if (a->cert_store != NULL)
 		X509_STORE_free(a->cert_store);
@@ -1673,10 +1773,23 @@
 #else
 	a->comp_methods = NULL;
 #endif
+
+#ifndef OPENSSL_NO_PSK
+	if (a->psk_identity_hint)
+		OPENSSL_free(a->psk_identity_hint);
+#endif
 #ifndef OPENSSL_NO_ENGINE
 	if (a->client_cert_engine)
 		ENGINE_finish(a->client_cert_engine);
 #endif
+
+#ifndef OPENSSL_NO_BUF_FREELISTS
+	if (a->wbuf_freelist)
+		ssl_buf_freelist_free(a->wbuf_freelist);
+	if (a->rbuf_freelist)
+		ssl_buf_freelist_free(a->rbuf_freelist);
+#endif
+
 	OPENSSL_free(a);
 	}
 
@@ -1707,13 +1820,13 @@
 	X509_VERIFY_PARAM_set_depth(ctx->param, depth);
 	}
 
-void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher)
+void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
 	{
 	CERT_PKEY *cpk;
 	int rsa_enc,rsa_tmp,rsa_sign,dh_tmp,dh_rsa,dh_dsa,dsa_sign;
 	int rsa_enc_export,dh_rsa_export,dh_dsa_export;
 	int rsa_tmp_export,dh_tmp_export,kl;
-	unsigned long mask,emask;
+	unsigned long mask_k,mask_a,emask_k,emask_a;
 	int have_ecc_cert, ecdh_ok, ecdsa_ok, ecc_pkey_size;
 #ifndef OPENSSL_NO_ECDH
 	int have_ecdh_tmp;
@@ -1760,60 +1873,77 @@
 	dh_dsa_export=(dh_dsa && EVP_PKEY_size(cpk->privatekey)*8 <= kl);
 	cpk= &(c->pkeys[SSL_PKEY_ECC]);
 	have_ecc_cert= (cpk->x509 != NULL && cpk->privatekey != NULL);
-	mask=0;
-	emask=0;
+	mask_k=0;
+	mask_a=0;
+	emask_k=0;
+	emask_a=0;
+
+	
 
 #ifdef CIPHER_DEBUG
-	printf("rt=%d rte=%d dht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n",
-		rsa_tmp,rsa_tmp_export,dh_tmp,
+	printf("rt=%d rte=%d dht=%d ecdht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n",
+	        rsa_tmp,rsa_tmp_export,dh_tmp,have_ecdh_tmp,
 		rsa_enc,rsa_enc_export,rsa_sign,dsa_sign,dh_rsa,dh_dsa);
 #endif
+	
+	cpk = &(c->pkeys[SSL_PKEY_GOST01]);
+	if (cpk->x509 != NULL && cpk->privatekey !=NULL) {
+		mask_k |= SSL_kGOST;
+		mask_a |= SSL_aGOST01;
+	}
+	cpk = &(c->pkeys[SSL_PKEY_GOST94]);
+	if (cpk->x509 != NULL && cpk->privatekey !=NULL) {
+		mask_k |= SSL_kGOST;
+		mask_a |= SSL_aGOST94;
+	}
 
 	if (rsa_enc || (rsa_tmp && rsa_sign))
-		mask|=SSL_kRSA;
+		mask_k|=SSL_kRSA;
 	if (rsa_enc_export || (rsa_tmp_export && (rsa_sign || rsa_enc)))
-		emask|=SSL_kRSA;
+		emask_k|=SSL_kRSA;
 
 #if 0
 	/* The match needs to be both kEDH and aRSA or aDSA, so don't worry */
-	if (	(dh_tmp || dh_rsa || dh_dsa) && 
+	if (	(dh_tmp || dh_rsa || dh_dsa) &&
 		(rsa_enc || rsa_sign || dsa_sign))
-		mask|=SSL_kEDH;
+		mask_k|=SSL_kEDH;
 	if ((dh_tmp_export || dh_rsa_export || dh_dsa_export) &&
 		(rsa_enc || rsa_sign || dsa_sign))
-		emask|=SSL_kEDH;
+		emask_k|=SSL_kEDH;
 #endif
 
-	if (dh_tmp_export) 
-		emask|=SSL_kEDH;
+	if (dh_tmp_export)
+		emask_k|=SSL_kEDH;
 
 	if (dh_tmp)
-		mask|=SSL_kEDH;
+		mask_k|=SSL_kEDH;
 
-	if (dh_rsa) mask|=SSL_kDHr;
-	if (dh_rsa_export) emask|=SSL_kDHr;
+	if (dh_rsa) mask_k|=SSL_kDHr;
+	if (dh_rsa_export) emask_k|=SSL_kDHr;
 
-	if (dh_dsa) mask|=SSL_kDHd;
-	if (dh_dsa_export) emask|=SSL_kDHd;
+	if (dh_dsa) mask_k|=SSL_kDHd;
+	if (dh_dsa_export) emask_k|=SSL_kDHd;
 
 	if (rsa_enc || rsa_sign)
 		{
-		mask|=SSL_aRSA;
-		emask|=SSL_aRSA;
+		mask_a|=SSL_aRSA;
+		emask_a|=SSL_aRSA;
 		}
 
 	if (dsa_sign)
 		{
-		mask|=SSL_aDSS;
-		emask|=SSL_aDSS;
+		mask_a|=SSL_aDSS;
+		emask_a|=SSL_aDSS;
 		}
 
-	mask|=SSL_aNULL;
-	emask|=SSL_aNULL;
+	mask_a|=SSL_aNULL;
+	emask_a|=SSL_aNULL;
 
 #ifndef OPENSSL_NO_KRB5
-	mask|=SSL_kKRB5|SSL_aKRB5;
-	emask|=SSL_kKRB5|SSL_aKRB5;
+	mask_k|=SSL_kKRB5;
+	mask_a|=SSL_aKRB5;
+	emask_k|=SSL_kKRB5;
+	emask_a|=SSL_aKRB5;
 #endif
 
 	/* An ECC certificate may be usable for ECDH and/or
@@ -1821,7 +1951,7 @@
 	 */
 	if (have_ecc_cert)
 		{
-                /* This call populates extension flags (ex_flags) */
+		/* This call populates extension flags (ex_flags) */
 		x = (c->pkeys[SSL_PKEY_ECC]).x509;
 		X509_check_purpose(x, -1, 0);
 		ecdh_ok = (x->ex_flags & EXFLAG_KUSAGE) ?
@@ -1829,7 +1959,7 @@
 		ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ?
 		    (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1;
 		ecc_pkey = X509_get_pubkey(x);
-		ecc_pkey_size = (ecc_pkey != NULL) ? 
+		ecc_pkey_size = (ecc_pkey != NULL) ?
 		    EVP_PKEY_bits(ecc_pkey) : 0;
 		EVP_PKEY_free(ecc_pkey);
 		if ((x->sig_alg) && (x->sig_alg->algorithm))
@@ -1837,27 +1967,41 @@
 #ifndef OPENSSL_NO_ECDH
 		if (ecdh_ok)
 			{
-			if ((signature_nid == NID_md5WithRSAEncryption) ||
-			    (signature_nid == NID_md4WithRSAEncryption) ||
-			    (signature_nid == NID_md2WithRSAEncryption))
+			const char *sig = OBJ_nid2ln(signature_nid);
+			if (sig == NULL)
 				{
-				mask|=SSL_kECDH|SSL_aRSA;
-				if (ecc_pkey_size <= 163)
-					emask|=SSL_kECDH|SSL_aRSA;
+				ERR_clear_error();
+				sig = "unknown";
 				}
+				
+			if (strstr(sig, "WithRSA"))
+				{
+				mask_k|=SSL_kECDHr;
+				mask_a|=SSL_aECDH;
+				if (ecc_pkey_size <= 163)
+					{
+					emask_k|=SSL_kECDHr;
+					emask_a|=SSL_aECDH;
+					}
+				}
+
 			if (signature_nid == NID_ecdsa_with_SHA1)
 				{
-				mask|=SSL_kECDH|SSL_aECDSA;
+				mask_k|=SSL_kECDHe;
+				mask_a|=SSL_aECDH;
 				if (ecc_pkey_size <= 163)
-					emask|=SSL_kECDH|SSL_aECDSA;
+					{
+					emask_k|=SSL_kECDHe;
+					emask_a|=SSL_aECDH;
+					}
 				}
 			}
 #endif
 #ifndef OPENSSL_NO_ECDSA
 		if (ecdsa_ok)
 			{
-			mask|=SSL_aECDSA;
-			emask|=SSL_aECDSA;
+			mask_a|=SSL_aECDSA;
+			emask_a|=SSL_aECDSA;
 			}
 #endif
 		}
@@ -1865,12 +2009,22 @@
 #ifndef OPENSSL_NO_ECDH
 	if (have_ecdh_tmp)
 		{
-		mask|=SSL_kECDHE;
-		emask|=SSL_kECDHE;
+		mask_k|=SSL_kEECDH;
+		emask_k|=SSL_kEECDH;
 		}
 #endif
-	c->mask=mask;
-	c->export_mask=emask;
+
+#ifndef OPENSSL_NO_PSK
+	mask_k |= SSL_kPSK;
+	mask_a |= SSL_aPSK;
+	emask_k |= SSL_kPSK;
+	emask_a |= SSL_aPSK;
+#endif
+
+	c->mask_k=mask_k;
+	c->mask_a=mask_a;
+	c->export_mask_k=emask_k;
+	c->export_mask_a=emask_a;
 	c->valid=1;
 	}
 
@@ -1878,13 +2032,18 @@
 #define ku_reject(x, usage) \
 	(((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
 
-int check_srvr_ecc_cert_and_alg(X509 *x, SSL_CIPHER *cs)
+#ifndef OPENSSL_NO_EC
+
+int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs)
 	{
-	unsigned long alg = cs->algorithms;
+	unsigned long alg_k, alg_a;
 	EVP_PKEY *pkey = NULL;
 	int keysize = 0;
 	int signature_nid = 0;
 
+	alg_k = cs->algorithm_mkey;
+	alg_a = cs->algorithm_auth;
+
 	if (SSL_C_IS_EXPORT(cs))
 		{
 		/* ECDH key length in export ciphers must be <= 163 bits */
@@ -1899,37 +2058,46 @@
 	X509_check_purpose(x, -1, 0);
 	if ((x->sig_alg) && (x->sig_alg->algorithm))
 		signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
-	if (alg & SSL_kECDH) 
+	if (alg_k & SSL_kECDHe || alg_k & SSL_kECDHr)
 		{
 		/* key usage, if present, must allow key agreement */
 		if (ku_reject(x, X509v3_KU_KEY_AGREEMENT))
 			{
+			SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT);
 			return 0;
 			}
-		if (alg & SSL_aECDSA) 
+		if (alg_k & SSL_kECDHe)
 			{
 			/* signature alg must be ECDSA */
 			if (signature_nid != NID_ecdsa_with_SHA1)
 				{
+				SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE);
 				return 0;
 				}
 			}
-		if (alg & SSL_aRSA)
+		if (alg_k & SSL_kECDHr)
 			{
 			/* signature alg must be RSA */
-			if ((signature_nid != NID_md5WithRSAEncryption) &&
-			    (signature_nid != NID_md4WithRSAEncryption) &&
-			    (signature_nid != NID_md2WithRSAEncryption))
+
+			const char *sig = OBJ_nid2ln(signature_nid);
+			if (sig == NULL)
 				{
+				ERR_clear_error();
+				sig = "unknown";
+				}
+			if (strstr(sig, "WithRSA") == NULL)
+				{
+				SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE);
 				return 0;
 				}
 			}
-		} 
-	else if (alg & SSL_aECDSA)
+		}
+	if (alg_a & SSL_aECDSA)
 		{
 		/* key usage, if present, must allow signing */
 		if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE))
 			{
+			SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_NOT_FOR_SIGNING);
 			return 0;
 			}
 		}
@@ -1937,58 +2105,74 @@
 	return 1;  /* all checks are ok */
 	}
 
+#endif
+
 /* THIS NEEDS CLEANING UP */
 X509 *ssl_get_server_send_cert(SSL *s)
 	{
-	unsigned long alg,mask,kalg;
+	unsigned long alg_k,alg_a,mask_k,mask_a;
 	CERT *c;
 	int i,is_export;
 
 	c=s->cert;
 	ssl_set_cert_masks(c, s->s3->tmp.new_cipher);
-	alg=s->s3->tmp.new_cipher->algorithms;
 	is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
-	mask=is_export?c->export_mask:c->mask;
-	kalg=alg&(SSL_MKEY_MASK|SSL_AUTH_MASK);
-
-	if (kalg & SSL_kECDH)
+	if (is_export)
 		{
-		/* we don't need to look at SSL_kECDHE 
+		mask_k = c->export_mask_k;
+		mask_a = c->export_mask_a;
+		}
+	else
+		{
+		mask_k = c->mask_k;
+		mask_a = c->mask_a;
+		}
+	
+	alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+	alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+
+	if (alg_k & (SSL_kECDHr|SSL_kECDHe))
+		{
+		/* we don't need to look at SSL_kEECDH
 		 * since no certificate is needed for
 		 * anon ECDH and for authenticated
-		 * ECDHE, the check for the auth 
+		 * EECDH, the check for the auth
 		 * algorithm will set i correctly
 		 * NOTE: For ECDH-RSA, we need an ECC
-		 * not an RSA cert but for ECDHE-RSA
+		 * not an RSA cert but for EECDH-RSA
 		 * we need an RSA cert. Placing the
 		 * checks for SSL_kECDH before RSA
 		 * checks ensures the correct cert is chosen.
 		 */
 		i=SSL_PKEY_ECC;
 		}
-	else if (kalg & SSL_aECDSA)
+	else if (alg_a & SSL_aECDSA)
 		{
 		i=SSL_PKEY_ECC;
 		}
-	else if (kalg & SSL_kDHr)
+	else if (alg_k & SSL_kDHr)
 		i=SSL_PKEY_DH_RSA;
-	else if (kalg & SSL_kDHd)
+	else if (alg_k & SSL_kDHd)
 		i=SSL_PKEY_DH_DSA;
-	else if (kalg & SSL_aDSS)
+	else if (alg_a & SSL_aDSS)
 		i=SSL_PKEY_DSA_SIGN;
-	else if (kalg & SSL_aRSA)
+	else if (alg_a & SSL_aRSA)
 		{
 		if (c->pkeys[SSL_PKEY_RSA_ENC].x509 == NULL)
 			i=SSL_PKEY_RSA_SIGN;
 		else
 			i=SSL_PKEY_RSA_ENC;
 		}
-	else if (kalg & SSL_aKRB5)
+	else if (alg_a & SSL_aKRB5)
 		{
 		/* VRS something else here? */
 		return(NULL);
 		}
-	else /* if (kalg & SSL_aNULL) */
+	else if (alg_a & SSL_aGOST94) 
+		i=SSL_PKEY_GOST94;
+	else if (alg_a & SSL_aGOST01)
+		i=SSL_PKEY_GOST01;
+	else /* if (alg_a & SSL_aNULL) */
 		{
 		SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,ERR_R_INTERNAL_ERROR);
 		return(NULL);
@@ -1998,18 +2182,18 @@
 	return(c->pkeys[i].x509);
 	}
 
-EVP_PKEY *ssl_get_sign_pkey(SSL *s,SSL_CIPHER *cipher)
+EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher)
 	{
-	unsigned long alg;
+	unsigned long alg_a;
 	CERT *c;
 
-	alg=cipher->algorithms;
+	alg_a = cipher->algorithm_auth;
 	c=s->cert;
 
-	if ((alg & SSL_aDSS) &&
+	if ((alg_a & SSL_aDSS) &&
 		(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL))
 		return(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey);
-	else if (alg & SSL_aRSA)
+	else if (alg_a & SSL_aRSA)
 		{
 		if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL)
 			return(c->pkeys[SSL_PKEY_RSA_SIGN].privatekey);
@@ -2018,10 +2202,10 @@
 		else
 			return(NULL);
 		}
-	else if ((alg & SSL_aECDSA) &&
+	else if ((alg_a & SSL_aECDSA) &&
 	         (c->pkeys[SSL_PKEY_ECC].privatekey != NULL))
 		return(c->pkeys[SSL_PKEY_ECC].privatekey);
-	else /* if (alg & SSL_aNULL) */
+	else /* if (alg_a & SSL_aNULL) */
 		{
 		SSLerr(SSL_F_SSL_GET_SIGN_PKEY,ERR_R_INTERNAL_ERROR);
 		return(NULL);
@@ -2036,14 +2220,14 @@
 	 * and it would be rather hard to do anyway :-) */
 	if (s->session->session_id_length == 0) return;
 
-	i=s->ctx->session_cache_mode;
+	i=s->session_ctx->session_cache_mode;
 	if ((i & mode) && (!s->hit)
 		&& ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE)
-		    || SSL_CTX_add_session(s->ctx,s->session))
-		&& (s->ctx->new_session_cb != NULL))
+		    || SSL_CTX_add_session(s->session_ctx,s->session))
+		&& (s->session_ctx->new_session_cb != NULL))
 		{
 		CRYPTO_add(&s->session->references,1,CRYPTO_LOCK_SSL_SESSION);
-		if (!s->ctx->new_session_cb(s,s->session))
+		if (!s->session_ctx->new_session_cb(s,s->session))
 			SSL_SESSION_free(s->session);
 		}
 
@@ -2052,20 +2236,20 @@
 		((i & mode) == mode))
 		{
 		if (  (((mode & SSL_SESS_CACHE_CLIENT)
-			?s->ctx->stats.sess_connect_good
-			:s->ctx->stats.sess_accept_good) & 0xff) == 0xff)
+			?s->session_ctx->stats.sess_connect_good
+			:s->session_ctx->stats.sess_accept_good) & 0xff) == 0xff)
 			{
-			SSL_CTX_flush_sessions(s->ctx,(unsigned long)time(NULL));
+			SSL_CTX_flush_sessions(s->session_ctx,(unsigned long)time(NULL));
 			}
 		}
 	}
 
-SSL_METHOD *SSL_get_ssl_method(SSL *s)
+const SSL_METHOD *SSL_get_ssl_method(SSL *s)
 	{
 	return(s->method);
 	}
 
-int SSL_set_ssl_method(SSL *s,SSL_METHOD *meth)
+int SSL_set_ssl_method(SSL *s, const SSL_METHOD *meth)
 	{
 	int conn= -1;
 	int ret=1;
@@ -2208,6 +2392,8 @@
 	s->handshake_func=s->method->ssl_accept;
 	/* clear the current cipher */
 	ssl_clear_cipher_ctx(s);
+	ssl_clear_hash_ctx(&s->read_hash);
+	ssl_clear_hash_ctx(&s->write_hash);
 	}
 
 void SSL_set_connect_state(SSL *s)
@@ -2218,6 +2404,8 @@
 	s->handshake_func=s->method->ssl_connect;
 	/* clear the current cipher */
 	ssl_clear_cipher_ctx(s);
+	ssl_clear_hash_ctx(&s->read_hash);
+	ssl_clear_hash_ctx(&s->write_hash);
 	}
 
 int ssl_undefined_function(SSL *s)
@@ -2262,7 +2450,7 @@
 	X509_NAME *xn;
 	SSL *ret;
 	int i;
-		 
+	
 	if ((ret=SSL_new(SSL_get_SSL_CTX(s))) == NULL)
 	    return(NULL);
 
@@ -2432,7 +2620,7 @@
 		return(NULL);
 	}
 
-SSL_CIPHER *SSL_get_current_cipher(const SSL *s)
+const SSL_CIPHER *SSL_get_current_cipher(const SSL *s)
 	{
 	if ((s->session != NULL) && (s->session->cipher != NULL))
 		return(s->session->cipher);
@@ -2510,7 +2698,7 @@
 		s->wbio=BIO_pop(s->wbio);
 #ifdef REF_CHECK /* not the usual REF_CHECK, but this avoids adding one more preprocessor symbol */
 		assert(s->wbio != NULL);
-#endif	
+#endif
 	}
 	BIO_free(s->bbio);
 	s->bbio=NULL;
@@ -2595,7 +2783,7 @@
 
 /* One compiler (Diab DCC) doesn't like argument names in returned
    function pointer.  */
-void (*SSL_get_info_callback(const SSL *ssl))(const SSL * /*ssl*/,int /*type*/,int /*val*/) 
+void (*SSL_get_info_callback(const SSL *ssl))(const SSL * /*ssl*/,int /*type*/,int /*val*/)
 	{
 	return ssl->info_callback;
 	}
@@ -2716,13 +2904,13 @@
 
 #ifndef OPENSSL_NO_DH
 void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,DH *(*dh)(SSL *ssl,int is_export,
-							int keylength))
+                                                        int keylength))
 	{
 	SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TMP_DH_CB,(void (*)(void))dh);
 	}
 
 void SSL_set_tmp_dh_callback(SSL *ssl,DH *(*dh)(SSL *ssl,int is_export,
-						int keylength))
+                                                int keylength))
 	{
 	SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_DH_CB,(void (*)(void))dh);
 	}
@@ -2730,18 +2918,109 @@
 
 #ifndef OPENSSL_NO_ECDH
 void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,EC_KEY *(*ecdh)(SSL *ssl,int is_export,
-							int keylength))
+                                                                int keylength))
 	{
 	SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH_CB,(void (*)(void))ecdh);
 	}
 
 void SSL_set_tmp_ecdh_callback(SSL *ssl,EC_KEY *(*ecdh)(SSL *ssl,int is_export,
-						int keylength))
+                                                        int keylength))
 	{
 	SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH_CB,(void (*)(void))ecdh);
 	}
 #endif
 
+#ifndef OPENSSL_NO_PSK
+int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint)
+	{
+	if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN)
+		{
+		SSLerr(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG);
+		return 0;
+		}
+	if (ctx->psk_identity_hint != NULL)
+		OPENSSL_free(ctx->psk_identity_hint);
+	if (identity_hint != NULL)
+		{
+		ctx->psk_identity_hint = BUF_strdup(identity_hint);
+		if (ctx->psk_identity_hint == NULL)
+			return 0;
+		}
+	else
+		ctx->psk_identity_hint = NULL;
+	return 1;
+	}
+
+int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint)
+	{
+	if (s == NULL)
+		return 0;
+
+	if (s->session == NULL)
+		return 1; /* session not created yet, ignored */
+
+	if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN)
+		{
+		SSLerr(SSL_F_SSL_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG);
+		return 0;
+		}
+	if (s->session->psk_identity_hint != NULL)
+		OPENSSL_free(s->session->psk_identity_hint);
+	if (identity_hint != NULL)
+		{
+		s->session->psk_identity_hint = BUF_strdup(identity_hint);
+		if (s->session->psk_identity_hint == NULL)
+			return 0;
+		}
+	else
+		s->session->psk_identity_hint = NULL;
+	return 1;
+	}
+
+const char *SSL_get_psk_identity_hint(const SSL *s)
+	{
+	if (s == NULL || s->session == NULL)
+		return NULL;
+	return(s->session->psk_identity_hint);
+	}
+
+const char *SSL_get_psk_identity(const SSL *s)
+	{
+	if (s == NULL || s->session == NULL)
+		return NULL;
+	return(s->session->psk_identity);
+	}
+
+void SSL_set_psk_client_callback(SSL *s,
+    unsigned int (*cb)(SSL *ssl, const char *hint,
+                       char *identity, unsigned int max_identity_len, unsigned char *psk,
+                       unsigned int max_psk_len))
+	{
+	s->psk_client_callback = cb;
+	}
+
+void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx,
+    unsigned int (*cb)(SSL *ssl, const char *hint,
+                       char *identity, unsigned int max_identity_len, unsigned char *psk,
+                       unsigned int max_psk_len))
+	{
+	ctx->psk_client_callback = cb;
+	}
+
+void SSL_set_psk_server_callback(SSL *s,
+    unsigned int (*cb)(SSL *ssl, const char *identity,
+                       unsigned char *psk, unsigned int max_psk_len))
+	{
+	s->psk_server_callback = cb;
+	}
+
+void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx,
+    unsigned int (*cb)(SSL *ssl, const char *identity,
+                       unsigned char *psk, unsigned int max_psk_len))
+	{
+	ctx->psk_server_callback = cb;
+	}
+#endif
 
 void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg))
 	{
@@ -2752,7 +3031,25 @@
 	SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
 	}
 
+/* Allocates new EVP_MD_CTX and sets pointer to it into given pointer
+ * vairable, freeing  EVP_MD_CTX previously stored in that variable, if
+ * any. If EVP_MD pointer is passed, initializes ctx with this md
+ * Returns newly allocated ctx;
+ */
 
+EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) 
+{
+	ssl_clear_hash_ctx(hash);
+	*hash = EVP_MD_CTX_create();
+	if (md) EVP_DigestInit_ex(*hash,md,NULL);
+	return *hash;
+}
+void ssl_clear_hash_ctx(EVP_MD_CTX **hash) 
+{
+
+	if (*hash) EVP_MD_CTX_destroy(*hash);
+	*hash=NULL;
+}
 
 #if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16)
 #include "../crypto/bio/bss_file.c"
@@ -2760,3 +3057,6 @@
 
 IMPLEMENT_STACK_OF(SSL_CIPHER)
 IMPLEMENT_STACK_OF(SSL_COMP)
+IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER,
+				    ssl_cipher_id);
+
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index e305db4..4c78393 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -113,6 +113,32 @@
  * ECC cipher suite support in OpenSSL originally developed by 
  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 #ifndef HEADER_SSL_LOCL_H
 #define HEADER_SSL_LOCL_H
@@ -251,58 +277,84 @@
  * that the different entities within are mutually exclusive:
  * ONLY ONE BIT PER MASK CAN BE SET AT A TIME.
  */
-#define SSL_MKEY_MASK		0x000000FFL
+
+/* Bits for algorithm_mkey (key exchange algorithm) */
 #define SSL_kRSA		0x00000001L /* RSA key exchange */
-#define SSL_kDHr		0x00000002L /* DH cert RSA CA cert */
-#define SSL_kDHd		0x00000004L /* DH cert DSA CA cert */
-#define SSL_kFZA		0x00000008L
-#define SSL_kEDH		0x00000010L /* tmp DH key no DH cert */
-#define SSL_kKRB5		0x00000020L /* Kerberos5 key exchange */
-#define SSL_kECDH               0x00000040L /* ECDH w/ long-term keys */
-#define SSL_kECDHE              0x00000080L /* ephemeral ECDH */
-#define SSL_EDH			(SSL_kEDH|(SSL_AUTH_MASK^SSL_aNULL))
+#define SSL_kDHr		0x00000002L /* DH cert, RSA CA cert */ /* no such ciphersuites supported! */
+#define SSL_kDHd		0x00000004L /* DH cert, DSA CA cert */ /* no such ciphersuite supported! */
+#define SSL_kEDH		0x00000008L /* tmp DH key no DH cert */
+#define SSL_kKRB5		0x00000010L /* Kerberos5 key exchange */
+#define SSL_kECDHr		0x00000020L /* ECDH cert, RSA CA cert */
+#define SSL_kECDHe		0x00000040L /* ECDH cert, ECDSA CA cert */
+#define SSL_kEECDH		0x00000080L /* ephemeral ECDH */
+#define SSL_kPSK		0x00000100L /* PSK */
+#define SSL_kGOST       0x00000200L /* GOST key exchange */
 
-#define SSL_AUTH_MASK		0x00007F00L
-#define SSL_aRSA		0x00000100L /* Authenticate with RSA */
-#define SSL_aDSS 		0x00000200L /* Authenticate with DSS */
-#define SSL_DSS 		SSL_aDSS
-#define SSL_aFZA 		0x00000400L
-#define SSL_aNULL 		0x00000800L /* no Authenticate, ADH */
-#define SSL_aDH 		0x00001000L /* no Authenticate, ADH */
-#define SSL_aKRB5               0x00002000L /* Authenticate with KRB5 */
-#define SSL_aECDSA              0x00004000L /* Authenticate with ECDSA */
+/* Bits for algorithm_auth (server authentication) */
+#define SSL_aRSA		0x00000001L /* RSA auth */
+#define SSL_aDSS 		0x00000002L /* DSS auth */
+#define SSL_aNULL 		0x00000004L /* no auth (i.e. use ADH or AECDH) */
+#define SSL_aDH 		0x00000008L /* Fixed DH auth (kDHd or kDHr) */ /* no such ciphersuites supported! */
+#define SSL_aECDH 		0x00000010L /* Fixed ECDH auth (kECDHe or kECDHr) */
+#define SSL_aKRB5               0x00000020L /* KRB5 auth */
+#define SSL_aECDSA              0x00000040L /* ECDSA auth*/
+#define SSL_aPSK                0x00000080L /* PSK auth */
+#define SSL_aGOST94				0x00000100L /* GOST R 34.10-94 signature auth */
+#define SSL_aGOST01 			0x00000200L /* GOST R 34.10-2001 signature auth */
 
-#define SSL_NULL		(SSL_eNULL)
-#define SSL_ADH			(SSL_kEDH|SSL_aNULL)
-#define SSL_RSA			(SSL_kRSA|SSL_aRSA)
-#define SSL_DH			(SSL_kDHr|SSL_kDHd|SSL_kEDH)
-#define SSL_ECDH		(SSL_kECDH|SSL_kECDHE)
-#define SSL_FZA			(SSL_aFZA|SSL_kFZA|SSL_eFZA)
-#define SSL_KRB5                (SSL_kKRB5|SSL_aKRB5)
 
-#define SSL_ENC_MASK		0x1C3F8000L
-#define SSL_DES			0x00008000L
-#define SSL_3DES		0x00010000L
-#define SSL_RC4			0x00020000L
-#define SSL_RC2			0x00040000L
-#define SSL_IDEA		0x00080000L
-#define SSL_eFZA		0x00100000L
-#define SSL_eNULL		0x00200000L
-#define SSL_AES			0x04000000L
-#define SSL_CAMELLIA		0x08000000L
-#define SSL_SEED          	0x10000000L
+/* Bits for algorithm_enc (symmetric encryption) */
+#define SSL_DES			0x00000001L
+#define SSL_3DES		0x00000002L
+#define SSL_RC4			0x00000004L
+#define SSL_RC2			0x00000008L
+#define SSL_IDEA		0x00000010L
+#define SSL_eNULL		0x00000020L
+#define SSL_AES128		0x00000040L
+#define SSL_AES256		0x00000080L
+#define SSL_CAMELLIA128		0x00000100L
+#define SSL_CAMELLIA256		0x00000200L
+#define SSL_eGOST2814789CNT	0x00000400L
+#define SSL_SEED		0x00000800L
 
-#define SSL_MAC_MASK		0x00c00000L
-#define SSL_MD5			0x00400000L
-#define SSL_SHA1		0x00800000L
-#define SSL_SHA			(SSL_SHA1)
+#define SSL_AES        		(SSL_AES128|SSL_AES256)
+#define SSL_CAMELLIA		(SSL_CAMELLIA128|SSL_CAMELLIA256)
 
-#define SSL_SSL_MASK		0x03000000L
-#define SSL_SSLV2		0x01000000L
-#define SSL_SSLV3		0x02000000L
+
+/* Bits for algorithm_mac (symmetric authentication) */
+#define SSL_MD5			0x00000001L
+#define SSL_SHA1		0x00000002L
+#define SSL_GOST94      0x00000004L
+#define SSL_GOST89MAC   0x00000008L
+
+/* Bits for algorithm_ssl (protocol version) */
+#define SSL_SSLV2		0x00000001L
+#define SSL_SSLV3		0x00000002L
 #define SSL_TLSV1		SSL_SSLV3	/* for now */
 
-/* we have used 1fffffff - 3 bits left to go. */
+
+/* Bits for algorithm2 (handshake digests and other extra flags) */
+
+#define SSL_HANDSHAKE_MAC_MD5 0x10
+#define SSL_HANDSHAKE_MAC_SHA 0x20
+#define SSL_HANDSHAKE_MAC_GOST94 0x40
+#define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA)
+
+/* When adding new digest in the ssl_ciph.c and increment SSM_MD_NUM_IDX
+ * make sure to update this constant too */
+#define SSL_MAX_DIGEST 4
+
+#define TLS1_PRF_DGST_SHIFT 8
+#define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT)
+#define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT)
+#define TLS1_PRF_GOST94 (SSL_HANDSHAKE_MAC_GOST94 << TLS1_PRF_DGST_SHIFT)
+#define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1)
+
+/* Stream MAC for GOST ciphersuites from cryptopro draft
+ * (currently this also goes into algorithm2) */
+#define TLS1_STREAM_MAC 0x04
+
+
 
 /*
  * Export and cipher strength information. For each cipher we have to decide
@@ -320,10 +372,11 @@
  * be possible.
  */
 #define SSL_EXP_MASK		0x00000003L
+#define SSL_STRONG_MASK		0x000001fcL
+
 #define SSL_NOT_EXP		0x00000001L
 #define SSL_EXPORT		0x00000002L
 
-#define SSL_STRONG_MASK		0x000000fcL
 #define SSL_STRONG_NONE		0x00000004L
 #define SSL_EXP40		0x00000008L
 #define SSL_MICRO		(SSL_EXP40)
@@ -357,17 +410,14 @@
 #define SSL_C_IS_EXPORT40(c)	SSL_IS_EXPORT40((c)->algo_strength)
 
 #define SSL_EXPORT_KEYLENGTH(a,s)	(SSL_IS_EXPORT40(s) ? 5 : \
-				 ((a)&SSL_ENC_MASK) == SSL_DES ? 8 : 7)
+				 (a) == SSL_DES ? 8 : 7)
 #define SSL_EXPORT_PKEYLENGTH(a) (SSL_IS_EXPORT40(a) ? 512 : 1024)
-#define SSL_C_EXPORT_KEYLENGTH(c)	SSL_EXPORT_KEYLENGTH((c)->algorithms, \
+#define SSL_C_EXPORT_KEYLENGTH(c)	SSL_EXPORT_KEYLENGTH((c)->algorithm_enc, \
 				(c)->algo_strength)
 #define SSL_C_EXPORT_PKEYLENGTH(c)	SSL_EXPORT_PKEYLENGTH((c)->algo_strength)
 
 
-#define SSL_ALL			0xffffffffL
-#define SSL_ALL_CIPHERS		(SSL_MKEY_MASK|SSL_AUTH_MASK|SSL_ENC_MASK|\
-				SSL_MAC_MASK)
-#define SSL_ALL_STRENGTHS	(SSL_EXP_MASK|SSL_STRONG_MASK)
+
 
 /* Mostly for SSLv3 */
 #define SSL_PKEY_RSA_ENC	0
@@ -376,7 +426,9 @@
 #define SSL_PKEY_DH_RSA		3
 #define SSL_PKEY_DH_DSA		4
 #define SSL_PKEY_ECC            5
-#define SSL_PKEY_NUM		6
+#define SSL_PKEY_GOST94		6
+#define SSL_PKEY_GOST01		7
+#define SSL_PKEY_NUM		8
 
 /* SSL_kRSA <- RSA_ENC | (RSA_TMP & RSA_SIGN) |
  * 	    <- (EXPORT & (RSA_ENC | RSA_TMP) & RSA_SIGN)
@@ -417,8 +469,10 @@
 	/* The following masks are for the key and auth
 	 * algorithms that are supported by the certs below */
 	int valid;
-	unsigned long mask;
-	unsigned long export_mask;
+	unsigned long mask_k;
+	unsigned long mask_a;
+	unsigned long export_mask_k;
+	unsigned long export_mask_a;
 #ifndef OPENSSL_NO_RSA
 	RSA *rsa_tmp;
 	RSA *(*rsa_tmp_cb)(SSL *ssl,int is_export,int keysize);
@@ -492,9 +546,9 @@
 	int (*setup_key_block)(SSL *);
 	int (*generate_master_secret)(SSL *, unsigned char *, unsigned char *, int);
 	int (*change_cipher_state)(SSL *, int);
-	int (*final_finish_mac)(SSL *, EVP_MD_CTX *, EVP_MD_CTX *, const char *, int, unsigned char *);
+	int (*final_finish_mac)(SSL *,  const char *, int, unsigned char *);
 	int finish_mac_length;
-	int (*cert_verify_mac)(SSL *, EVP_MD_CTX *, unsigned char *);
+	int (*cert_verify_mac)(SSL *, int, unsigned char *);
 	const char *client_finished_label;
 	int client_finished_label_len;
 	const char *server_finished_label;
@@ -512,24 +566,35 @@
 	} SSL3_COMP;
 #endif
 
+#ifndef OPENSSL_NO_BUF_FREELISTS
+typedef struct ssl3_buf_freelist_st
+	{
+	size_t chunklen;
+	unsigned int len;
+	struct ssl3_buf_freelist_entry_st *head;
+	} SSL3_BUF_FREELIST;
+
+typedef struct ssl3_buf_freelist_entry_st
+	{
+	struct ssl3_buf_freelist_entry_st *next;
+	} SSL3_BUF_FREELIST_ENTRY;
+#endif
+
 extern SSL3_ENC_METHOD ssl3_undef_enc_method;
-OPENSSL_EXTERN SSL_CIPHER ssl2_ciphers[];
+OPENSSL_EXTERN const SSL_CIPHER ssl2_ciphers[];
 OPENSSL_EXTERN SSL_CIPHER ssl3_ciphers[];
 
 
 SSL_METHOD *ssl_bad_method(int ver);
-SSL_METHOD *sslv2_base_method(void);
-SSL_METHOD *sslv23_base_method(void);
-SSL_METHOD *sslv3_base_method(void);
 
 extern SSL3_ENC_METHOD TLSv1_enc_data;
 extern SSL3_ENC_METHOD SSLv3_enc_data;
 extern SSL3_ENC_METHOD DTLSv1_enc_data;
 
 #define IMPLEMENT_tls1_meth_func(func_name, s_accept, s_connect, s_get_meth) \
-SSL_METHOD *func_name(void)  \
+const SSL_METHOD *func_name(void)  \
 	{ \
-	static SSL_METHOD func_name##_data= { \
+	static const SSL_METHOD func_name##_data= { \
 		TLS1_VERSION, \
 		tls1_new, \
 		tls1_clear, \
@@ -564,9 +629,9 @@
 	}
 
 #define IMPLEMENT_ssl3_meth_func(func_name, s_accept, s_connect, s_get_meth) \
-SSL_METHOD *func_name(void)  \
+const SSL_METHOD *func_name(void)  \
 	{ \
-	static SSL_METHOD func_name##_data= { \
+	static const SSL_METHOD func_name##_data= { \
 		SSL3_VERSION, \
 		ssl3_new, \
 		ssl3_clear, \
@@ -601,9 +666,9 @@
 	}
 
 #define IMPLEMENT_ssl23_meth_func(func_name, s_accept, s_connect, s_get_meth) \
-SSL_METHOD *func_name(void)  \
+const SSL_METHOD *func_name(void)  \
 	{ \
-	static SSL_METHOD func_name##_data= { \
+	static const SSL_METHOD func_name##_data= { \
 	TLS1_VERSION, \
 	tls1_new, \
 	tls1_clear, \
@@ -638,9 +703,9 @@
 	}
 
 #define IMPLEMENT_ssl2_meth_func(func_name, s_accept, s_connect, s_get_meth) \
-SSL_METHOD *func_name(void)  \
+const SSL_METHOD *func_name(void)  \
 	{ \
-	static SSL_METHOD func_name##_data= { \
+	static const SSL_METHOD func_name##_data= { \
 		SSL2_VERSION, \
 		ssl2_new,	/* local */ \
 		ssl2_clear,	/* local */ \
@@ -675,9 +740,9 @@
 	}
 
 #define IMPLEMENT_dtls1_meth_func(func_name, s_accept, s_connect, s_get_meth) \
-SSL_METHOD *func_name(void)  \
+const SSL_METHOD *func_name(void)  \
 	{ \
-	static SSL_METHOD func_name##_data= { \
+	static const SSL_METHOD func_name##_data= { \
 		DTLS1_VERSION, \
 		dtls1_new, \
 		dtls1_clear, \
@@ -723,6 +788,8 @@
 int ssl_get_new_session(SSL *s, int session);
 int ssl_get_prev_session(SSL *s, unsigned char *session,int len, const unsigned char *limit);
 int ssl_cipher_id_cmp(const SSL_CIPHER *a,const SSL_CIPHER *b);
+DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER,
+				  ssl_cipher_id);
 int ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const *ap,
 			const SSL_CIPHER * const *bp);
 STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
@@ -735,15 +802,16 @@
 					     const char *rule_str);
 void ssl_update_cache(SSL *s, int mode);
 int ssl_cipher_get_evp(const SSL_SESSION *s,const EVP_CIPHER **enc,
-		       const EVP_MD **md,SSL_COMP **comp);
+		       const EVP_MD **md,int *mac_pkey_type,int *mac_secret_size, SSL_COMP **comp);
+int ssl_get_handshake_digest(int i,long *mask,const EVP_MD **md);			   
 int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk);
 int ssl_undefined_function(SSL *s);
 int ssl_undefined_void_function(void);
 int ssl_undefined_const_function(const SSL *s);
 X509 *ssl_get_server_send_cert(SSL *);
-EVP_PKEY *ssl_get_sign_pkey(SSL *,SSL_CIPHER *);
+EVP_PKEY *ssl_get_sign_pkey(SSL *,const SSL_CIPHER *);
 int ssl_cert_type(X509 *x,EVP_PKEY *pkey);
-void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher);
+void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher);
 STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);
 int ssl_verify_alarm_type(long type);
 void ssl_load_ciphers(void);
@@ -752,7 +820,7 @@
 int ssl2_generate_key_material(SSL *s);
 void ssl2_enc(SSL *s,int send_data);
 void ssl2_mac(SSL *s,unsigned char *mac,int send_data);
-SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p);
+const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p);
 int ssl2_put_cipher_by_char(const SSL_CIPHER *c,unsigned char *p);
 int ssl2_part_read(SSL *s, unsigned long f, int i);
 int ssl2_do_write(SSL *s);
@@ -760,7 +828,7 @@
 void ssl2_return_error(SSL *s,int reason);
 void ssl2_write_error(SSL *s);
 int ssl2_num_ciphers(void);
-SSL_CIPHER *ssl2_get_cipher(unsigned int u);
+const SSL_CIPHER *ssl2_get_cipher(unsigned int u);
 int	ssl2_new(SSL *s);
 void	ssl2_free(SSL *s);
 int	ssl2_accept(SSL *s);
@@ -777,7 +845,7 @@
 int	ssl2_pending(const SSL *s);
 long	ssl2_default_timeout(void );
 
-SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p);
+const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p);
 int ssl3_put_cipher_by_char(const SSL_CIPHER *c,unsigned char *p);
 void ssl3_init_finished_mac(SSL *s);
 int ssl3_send_server_certificate(SSL *s);
@@ -796,22 +864,27 @@
 long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok);
 int ssl3_send_finished(SSL *s, int a, int b, const char *sender,int slen);
 int ssl3_num_ciphers(void);
-SSL_CIPHER *ssl3_get_cipher(unsigned int u);
+const SSL_CIPHER *ssl3_get_cipher(unsigned int u);
 int ssl3_renegotiate(SSL *ssl); 
 int ssl3_renegotiate_check(SSL *ssl); 
 int ssl3_dispatch_alert(SSL *s);
 int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek);
 int ssl3_write_bytes(SSL *s, int type, const void *buf, int len);
-int ssl3_final_finish_mac(SSL *s, EVP_MD_CTX *ctx1, EVP_MD_CTX *ctx2,
-	const char *sender, int slen,unsigned char *p);
-int ssl3_cert_verify_mac(SSL *s, EVP_MD_CTX *in, unsigned char *p);
+int ssl3_final_finish_mac(SSL *s, const char *sender, int slen,unsigned char *p);
+int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
 void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len);
 int ssl3_enc(SSL *s, int send_data);
-int ssl3_mac(SSL *ssl, unsigned char *md, int send_data);
+int n_ssl3_mac(SSL *ssl, unsigned char *md, int send_data);
+void ssl3_free_digest_list(SSL *s);
 unsigned long ssl3_output_cert_chain(SSL *s, X509 *x);
 SSL_CIPHER *ssl3_choose_cipher(SSL *ssl,STACK_OF(SSL_CIPHER) *clnt,
 			       STACK_OF(SSL_CIPHER) *srvr);
 int	ssl3_setup_buffers(SSL *s);
+int	ssl3_setup_read_buffer(SSL *s);
+int	ssl3_setup_write_buffer(SSL *s);
+int	ssl3_release_read_buffer(SSL *s);
+int	ssl3_release_write_buffer(SSL *s);
+int	ssl3_digest_cached_records(SSL *s);
 int	ssl3_new(SSL *s);
 void	ssl3_free(SSL *s);
 int	ssl3_accept(SSL *s);
@@ -832,12 +905,12 @@
 long ssl3_default_timeout(void );
 
 int ssl23_num_ciphers(void );
-SSL_CIPHER *ssl23_get_cipher(unsigned int u);
+const SSL_CIPHER *ssl23_get_cipher(unsigned int u);
 int ssl23_read(SSL *s, void *buf, int len);
 int ssl23_peek(SSL *s, void *buf, int len);
 int ssl23_write(SSL *s, const void *buf, int len);
 int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p);
-SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p);
+const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p);
 long ssl23_default_timeout(void );
 
 long tls1_default_timeout(void);
@@ -871,14 +944,13 @@
 long dtls1_default_timeout(void);
 struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft);
 int dtls1_handle_timeout(SSL *s);
-SSL_CIPHER *dtls1_get_cipher(unsigned int u);
+const SSL_CIPHER *dtls1_get_cipher(unsigned int u);
 void dtls1_start_timer(SSL *s);
 void dtls1_stop_timer(SSL *s);
 int dtls1_is_timer_expired(SSL *s);
 void dtls1_double_timeout(SSL *s);
 int dtls1_send_newsession_ticket(SSL *s);
 
-
 /* some client-only functions */
 int ssl3_client_hello(SSL *s);
 int ssl3_get_server_hello(SSL *s);
@@ -887,8 +959,8 @@
 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 ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey);
 int ssl3_send_client_key_exchange(SSL *s);
 int ssl3_get_key_exchange(SSL *s);
 int ssl3_get_server_certificate(SSL *s);
@@ -933,7 +1005,6 @@
 void tls1_clear(SSL *s);
 long tls1_ctrl(SSL *s,int cmd, long larg, void *parg);
 long tls1_callback_ctrl(SSL *s,int cmd, void (*fp)(void));
-SSL_METHOD *tlsv1_base_method(void );
 
 int dtls1_new(SSL *s);
 int	dtls1_accept(SSL *s);
@@ -941,7 +1012,6 @@
 void dtls1_free(SSL *s);
 void dtls1_clear(SSL *s);
 long dtls1_ctrl(SSL *s,int cmd, long larg, void *parg);
-SSL_METHOD *dtlsv1_base_method(void );
 
 long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok);
 int dtls1_get_record(SSL *s);
@@ -956,9 +1026,9 @@
 int tls1_change_cipher_state(SSL *s, int which);
 int tls1_setup_key_block(SSL *s);
 int tls1_enc(SSL *s, int snd);
-int tls1_final_finish_mac(SSL *s, EVP_MD_CTX *in1_ctx, EVP_MD_CTX *in2_ctx,
+int tls1_final_finish_mac(SSL *s,
 	const char *str, int slen, unsigned char *p);
-int tls1_cert_verify_mac(SSL *s, EVP_MD_CTX *in, unsigned char *p);
+int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
 int tls1_mac(SSL *ssl, unsigned char *md, int snd);
 int tls1_generate_master_secret(SSL *s, unsigned char *out,
 	unsigned char *p, int len);
@@ -966,10 +1036,17 @@
 int ssl3_alert_code(int code);
 int ssl_ok(SSL *s);
 
-int check_srvr_ecc_cert_and_alg(X509 *x, SSL_CIPHER *cs);
+#ifndef OPENSSL_NO_ECDH
+int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs);
+#endif
 
 SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n);
 
+#ifndef OPENSSL_NO_EC
+int tls1_ec_curve_id2nid(int curve_id);
+int tls1_ec_nid2curve_id(int nid);
+#endif /* OPENSSL_NO_EC */
+
 #ifndef OPENSSL_NO_TLSEXT
 unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit); 
 unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit); 
@@ -987,9 +1064,9 @@
 #endif
 int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
 				const unsigned char *limit, SSL_SESSION **ret);
+#endif
 EVP_MD_CTX* ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) ;
 void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
-
 int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
 					int maxlen);
 int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len,
@@ -999,5 +1076,3 @@
 int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
 					  int *al);
 #endif
-
-#endif
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
index e7802e1..8e5d8a0 100644
--- a/ssl/ssl_sess.c
+++ b/ssl/ssl_sess.c
@@ -55,6 +55,85 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
+/* ====================================================================
+ * Copyright (c) 1998-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
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 #include <stdio.h>
 #include <openssl/lhash.h>
@@ -127,8 +206,18 @@
 	ss->compress_meth=0;
 #ifndef OPENSSL_NO_TLSEXT
 	ss->tlsext_hostname = NULL; 
+#ifndef OPENSSL_NO_EC
+	ss->tlsext_ecpointformatlist_length = 0;
+	ss->tlsext_ecpointformatlist = NULL;
+	ss->tlsext_ellipticcurvelist_length = 0;
+	ss->tlsext_ellipticcurvelist = NULL;
+#endif
 #endif
 	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
+#ifndef OPENSSL_NO_PSK
+	ss->psk_identity_hint=NULL;
+	ss->psk_identity=NULL;
+#endif
 	return(ss);
 	}
 
@@ -183,10 +272,10 @@
 	if ((ss=SSL_SESSION_new()) == NULL) return(0);
 
 	/* If the context has a default timeout, use it */
-	if (s->ctx->session_timeout == 0)
+	if (s->session_ctx->session_timeout == 0)
 		ss->timeout=SSL_get_default_timeout(s);
 	else
-		ss->timeout=s->ctx->session_timeout;
+		ss->timeout=s->session_ctx->session_timeout;
 
 	if (s->session != NULL)
 		{
@@ -239,8 +328,8 @@
 		CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
 		if(s->generate_session_id)
 			cb = s->generate_session_id;
-		else if(s->ctx->generate_session_id)
-			cb = s->ctx->generate_session_id;
+		else if(s->session_ctx->generate_session_id)
+			cb = s->session_ctx->generate_session_id;
 		CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
 		/* Choose a session ID */
 		tmp = ss->session_id_length;
@@ -286,6 +375,32 @@
 				return 0;
 				}
 			}
+#ifndef OPENSSL_NO_EC
+		if (s->tlsext_ecpointformatlist)
+			{
+			if (ss->tlsext_ecpointformatlist != NULL) OPENSSL_free(ss->tlsext_ecpointformatlist);
+			if ((ss->tlsext_ecpointformatlist = OPENSSL_malloc(s->tlsext_ecpointformatlist_length)) == NULL)
+				{
+				SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE);
+				SSL_SESSION_free(ss);
+				return 0;
+				}
+			ss->tlsext_ecpointformatlist_length = s->tlsext_ecpointformatlist_length;
+			memcpy(ss->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
+			}
+		if (s->tlsext_ellipticcurvelist)
+			{
+			if (ss->tlsext_ellipticcurvelist != NULL) OPENSSL_free(ss->tlsext_ellipticcurvelist);
+			if ((ss->tlsext_ellipticcurvelist = OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL)
+				{
+				SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE);
+				SSL_SESSION_free(ss);
+				return 0;
+				}
+			ss->tlsext_ellipticcurvelist_length = s->tlsext_ellipticcurvelist_length;
+			memcpy(ss->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
+			}
+#endif
 #endif
 		}
 	else
@@ -318,15 +433,15 @@
 #ifndef OPENSSL_NO_TLSEXT
 	int r;
 #endif
-  
+
 	if (len > SSL_MAX_SSL_SESSION_ID_LENGTH)
 		goto err;
 #ifndef OPENSSL_NO_TLSEXT
- 	r = tls1_process_ticket(s, session_id, len, limit, &ret);
+	r = tls1_process_ticket(s, session_id, len, limit, &ret);
 	if (r == -1)
 		{
 		fatal = 1;
- 		goto err;
+		goto err;
 		}
 	else if (r == 0 || (!ret && !len))
 		goto err;
@@ -334,7 +449,7 @@
 #else
 	if (len == 0)
 		goto err;
-	if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
+	if (!(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
 #endif
 		{
 		SSL_SESSION data;
@@ -342,9 +457,9 @@
 		data.session_id_length=len;
 		if (len == 0)
 			return 0;
- 		memcpy(data.session_id,session_id,len);
+		memcpy(data.session_id,session_id,len);
 		CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
-		ret=(SSL_SESSION *)lh_retrieve(s->ctx->sessions,&data);
+		ret=lh_SSL_SESSION_retrieve(s->session_ctx->sessions,&data);
 		if (ret != NULL)
 		    /* don't allow other threads to steal it: */
 		    CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
@@ -355,13 +470,13 @@
 		{
 		int copy=1;
 	
-		s->ctx->stats.sess_miss++;
+		s->session_ctx->stats.sess_miss++;
 		ret=NULL;
-		if (s->ctx->get_session_cb != NULL
-		    && (ret=s->ctx->get_session_cb(s,session_id,len,&copy))
+		if (s->session_ctx->get_session_cb != NULL
+		    && (ret=s->session_ctx->get_session_cb(s,session_id,len,&copy))
 		       != NULL)
 			{
-			s->ctx->stats.sess_cb_hit++;
+			s->session_ctx->stats.sess_cb_hit++;
 
 			/* Increment reference count now if the session callback
 			 * asks us to do so (note that if the session structures
@@ -373,10 +488,10 @@
 
 			/* Add the externally cached session to the internal
 			 * cache as well if and only if we are supposed to. */
-			if(!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE))
+			if(!(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE))
 				/* The following should not return 1, otherwise,
 				 * things are very strange */
-				SSL_CTX_add_session(s->ctx,ret);
+				SSL_CTX_add_session(s->session_ctx,ret);
 			}
 		if (ret == NULL)
 			goto err;
@@ -443,13 +558,13 @@
 
 	if (ret->timeout < (long)(time(NULL) - ret->time)) /* timeout */
 		{
-		s->ctx->stats.sess_timeout++;
+		s->session_ctx->stats.sess_timeout++;
 		/* remove it from the cache */
-		SSL_CTX_remove_session(s->ctx,ret);
+		SSL_CTX_remove_session(s->session_ctx,ret);
 		goto err;
 		}
 
-	s->ctx->stats.sess_hit++;
+	s->session_ctx->stats.sess_hit++;
 
 	/* ret->time=time(NULL); */ /* rezero timeout? */
 	/* again, just leave the session 
@@ -482,7 +597,7 @@
 	/* if session c is in already in cache, we take back the increment later */
 
 	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
-	s=(SSL_SESSION *)lh_insert(ctx->sessions,c);
+	s=lh_SSL_SESSION_insert(ctx->sessions,c);
 	
 	/* s != NULL iff we already had a session with the given PID.
 	 * In this case, s == c should hold (then we did not really modify
@@ -548,10 +663,10 @@
 	if ((c != NULL) && (c->session_id_length != 0))
 		{
 		if(lck) CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
-		if ((r = (SSL_SESSION *)lh_retrieve(ctx->sessions,c)) == c)
+		if ((r = lh_SSL_SESSION_retrieve(ctx->sessions,c)) == c)
 			{
 			ret=1;
-			r=(SSL_SESSION *)lh_delete(ctx->sessions,c);
+			r=lh_SSL_SESSION_delete(ctx->sessions,c);
 			SSL_SESSION_list_remove(ctx,c);
 			}
 
@@ -601,6 +716,18 @@
 #ifndef OPENSSL_NO_TLSEXT
 	if (ss->tlsext_hostname != NULL) OPENSSL_free(ss->tlsext_hostname);
 	if (ss->tlsext_tick != NULL) OPENSSL_free(ss->tlsext_tick);
+#ifndef OPENSSL_NO_EC
+	ss->tlsext_ecpointformatlist_length = 0;
+	if (ss->tlsext_ecpointformatlist != NULL) OPENSSL_free(ss->tlsext_ecpointformatlist);
+	ss->tlsext_ellipticcurvelist_length = 0;
+	if (ss->tlsext_ellipticcurvelist != NULL) OPENSSL_free(ss->tlsext_ellipticcurvelist);
+#endif /* OPENSSL_NO_EC */
+#endif
+#ifndef OPENSSL_NO_PSK
+	if (ss->psk_identity_hint != NULL)
+		OPENSSL_free(ss->psk_identity_hint);
+	if (ss->psk_identity != NULL)
+		OPENSSL_free(ss->psk_identity);
 #endif
 	OPENSSL_cleanse(ss,sizeof(*ss));
 	OPENSSL_free(ss);
@@ -609,7 +736,7 @@
 int SSL_set_session(SSL *s, SSL_SESSION *session)
 	{
 	int ret=0;
-	SSL_METHOD *meth;
+	const SSL_METHOD *meth;
 
 	if (session != NULL)
 		{
@@ -712,20 +839,75 @@
 	return(s->session_timeout);
 	}
 
+#ifndef OPENSSL_NO_TLSEXT
+int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len,
+	STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg), void *arg)
+	{
+	if (s == NULL) return(0);
+	s->tls_session_secret_cb = tls_session_secret_cb;
+	s->tls_session_secret_cb_arg = arg;
+	return(1);
+	}
+
+int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
+				  void *arg)
+	{
+	if (s == NULL) return(0);
+	s->tls_session_ticket_ext_cb = cb;
+	s->tls_session_ticket_ext_cb_arg = arg;
+	return(1);
+	}
+
+int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len)
+	{
+	if (s->version >= TLS1_VERSION)
+		{
+		if (s->tlsext_session_ticket)
+			{
+			OPENSSL_free(s->tlsext_session_ticket);
+			s->tlsext_session_ticket = NULL;
+			}
+
+		s->tlsext_session_ticket = OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len);
+		if (!s->tlsext_session_ticket)
+			{
+			SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+
+		if (ext_data)
+			{
+			s->tlsext_session_ticket->length = ext_len;
+			s->tlsext_session_ticket->data = s->tlsext_session_ticket + 1;
+			memcpy(s->tlsext_session_ticket->data, ext_data, ext_len);
+			}
+		else
+			{
+			s->tlsext_session_ticket->length = 0;
+			s->tlsext_session_ticket->data = NULL;
+			}
+
+		return 1;
+		}
+
+	return 0;
+	}
+#endif /* OPENSSL_NO_TLSEXT */
+
 typedef struct timeout_param_st
 	{
 	SSL_CTX *ctx;
 	long time;
-	LHASH *cache;
+	LHASH_OF(SSL_SESSION) *cache;
 	} TIMEOUT_PARAM;
 
-static void timeout(SSL_SESSION *s, TIMEOUT_PARAM *p)
+static void timeout_doall_arg(SSL_SESSION *s, TIMEOUT_PARAM *p)
 	{
 	if ((p->time == 0) || (p->time > (s->time+s->timeout))) /* timeout */
 		{
 		/* The reason we don't call SSL_CTX_remove_session() is to
 		 * save on locking overhead */
-		lh_delete(p->cache,s);
+		(void)lh_SSL_SESSION_delete(p->cache,s);
 		SSL_SESSION_list_remove(p->ctx,s);
 		s->not_resumable=1;
 		if (p->ctx->remove_session_cb != NULL)
@@ -734,7 +916,7 @@
 		}
 	}
 
-static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION *, TIMEOUT_PARAM *)
+static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION, TIMEOUT_PARAM)
 
 void SSL_CTX_flush_sessions(SSL_CTX *s, long t)
 	{
@@ -746,10 +928,11 @@
 	if (tp.cache == NULL) return;
 	tp.time=t;
 	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
-	i=tp.cache->down_load;
-	tp.cache->down_load=0;
-	lh_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout), &tp);
-	tp.cache->down_load=i;
+	i=CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load;
+	CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load=0;
+	lh_SSL_SESSION_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout),
+				 TIMEOUT_PARAM, &tp);
+	CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load=i;
 	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
 	}
 
@@ -909,3 +1092,4 @@
 	ctx->app_verify_cookie_cb=cb;
 	}
 
+IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
diff --git a/ssl/ssl_stat.c b/ssl/ssl_stat.c
index e7509f0..144b81e 100644
--- a/ssl/ssl_stat.c
+++ b/ssl/ssl_stat.c
@@ -55,6 +55,32 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 #include <stdio.h>
 #include "ssl_locl.h"
@@ -414,6 +440,12 @@
 	case TLS1_AD_INTERNAL_ERROR:		str="IE"; break;
 	case TLS1_AD_USER_CANCELLED:		str="US"; break;
 	case TLS1_AD_NO_RENEGOTIATION:		str="NR"; break;
+	case TLS1_AD_UNSUPPORTED_EXTENSION:	str="UE"; break;
+	case TLS1_AD_CERTIFICATE_UNOBTAINABLE:	str="CO"; break;
+	case TLS1_AD_UNRECOGNIZED_NAME:		str="UN"; break;
+	case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: str="BR"; break;
+	case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: str="BH"; break;
+	case TLS1_AD_UNKNOWN_PSK_IDENTITY:	str="UP"; break;
 	default:				str="UK"; break;
 		}
 	return(str);
@@ -497,6 +529,24 @@
 	case TLS1_AD_NO_RENEGOTIATION:
 		str="no renegotiation";
 		break;
+	case TLS1_AD_UNSUPPORTED_EXTENSION:
+		str="unsupported extension";
+		break;
+	case TLS1_AD_CERTIFICATE_UNOBTAINABLE:
+		str="certificate unobtainable";
+		break;
+	case TLS1_AD_UNRECOGNIZED_NAME:
+		str="unrecognized name";
+		break;
+	case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
+		str="bad certificate status response";
+		break;
+	case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE:
+		str="bad certificate hash value";
+		break;
+	case TLS1_AD_UNKNOWN_PSK_IDENTITY:
+		str="unknown PSK identity";
+		break;
 	default: str="unknown"; break;
 		}
 	return(str);
diff --git a/ssl/ssl_txt.c b/ssl/ssl_txt.c
index 81c1361..3122440 100644
--- a/ssl/ssl_txt.c
+++ b/ssl/ssl_txt.c
@@ -55,6 +55,32 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 #include <stdio.h>
 #include <openssl/buffer.h>
@@ -155,6 +181,12 @@
 			if (BIO_printf(bp,"%02X",x->krb5_client_princ[i]) <= 0) goto err;
 			}
 #endif /* OPENSSL_NO_KRB5 */
+#ifndef OPENSSL_NO_PSK
+	if (BIO_puts(bp,"\n    PSK identity: ") <= 0) goto err;
+	if (BIO_printf(bp, "%s", x->psk_identity ? x->psk_identity : "None") <= 0) goto err;
+	if (BIO_puts(bp,"\n    PSK identity hint: ") <= 0) goto err;
+	if (BIO_printf(bp, "%s", x->psk_identity_hint ? x->psk_identity_hint : "None") <= 0) goto err;
+#endif
 #ifndef OPENSSL_NO_TLSEXT
 	if (x->tlsext_tick_lifetime_hint)
 		{
@@ -170,12 +202,13 @@
 			goto err;
 		}
 #endif
+
 #ifndef OPENSSL_NO_COMP
 	if (x->compress_meth != 0)
 		{
 		SSL_COMP *comp = NULL;
 
-		ssl_cipher_get_evp(x,NULL,NULL,&comp);
+		ssl_cipher_get_evp(x,NULL,NULL,NULL,NULL,&comp);
 		if (comp == NULL)
 			{
 			if (BIO_printf(bp,"\n    Compression: %d",x->compress_meth) <= 0) goto err;
diff --git a/ssl/ssltest.c b/ssl/ssltest.c
index 09d3502..39cb541 100644
--- a/ssl/ssltest.c
+++ b/ssl/ssltest.c
@@ -113,6 +113,32 @@
  * ECC cipher suite support in OpenSSL originally developed by 
  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 #define _BSD_SOURCE 1		/* Or gethostname won't be declared properly
 				   on Linux and GNU platforms. */
@@ -128,8 +154,11 @@
 #define USE_SOCKETS
 #include "e_os.h"
 
+#ifdef OPENSSL_SYS_VMS
 #define _XOPEN_SOURCE 500	/* Or isascii won't be declared properly on
 				   VMS (at least with DECompHP C).  */
+#endif
+
 #include <ctype.h>
 
 #include <openssl/bio.h>
@@ -207,6 +236,16 @@
 static DH *get_dh1024dsa(void);
 #endif
 
+
+static char *psk_key=NULL; /* by default PSK is not used */
+#ifndef OPENSSL_NO_PSK
+static unsigned int psk_client_callback(SSL *ssl, const char *hint, char *identity,
+	unsigned int max_identity_len, unsigned char *psk,
+	unsigned int max_psk_len);
+static unsigned int psk_server_callback(SSL *ssl, const char *identity, unsigned char *psk,
+	unsigned int max_psk_len);
+#endif
+
 static BIO *bio_err=NULL;
 static BIO *bio_stdout=NULL;
 
@@ -229,9 +268,6 @@
 	{
 	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");
@@ -250,6 +286,9 @@
 #ifndef OPENSSL_NO_ECDH
 	fprintf(stderr," -no_ecdhe     - disable ECDHE\n");
 #endif
+#ifndef OPENSSL_NO_PSK
+	fprintf(stderr," -psk arg      - PSK in hex (without 0x)\n");
+#endif
 #ifndef OPENSSL_NO_SSL2
 	fprintf(stderr," -ssl2         - use SSLv2\n");
 #endif
@@ -283,7 +322,7 @@
 
 static void print_details(SSL *c_ssl, const char *prefix)
 	{
-	SSL_CIPHER *ciph;
+	const SSL_CIPHER *ciph;
 	X509 *cert;
 		
 	ciph=SSL_get_current_cipher(c_ssl);
@@ -388,6 +427,28 @@
 		}
 	}
 
+#ifdef TLSEXT_TYPE_opaque_prf_input
+struct cb_info_st { void *input; size_t len; int ret; };
+struct cb_info_st co1 = { "C", 1, 1 }; /* try to negotiate oqaque PRF input */
+struct cb_info_st co2 = { "C", 1, 2 }; /* insist on oqaque PRF input */
+struct cb_info_st so1 = { "S", 1, 1 }; /* try to negotiate oqaque PRF input */
+struct cb_info_st so2 = { "S", 1, 2 }; /* insist on oqaque PRF input */
+
+int opaque_prf_input_cb(SSL *ssl, void *peerinput, size_t len, void *arg_)
+	{
+	struct cb_info_st *arg = arg_;
+
+	if (arg == NULL)
+		return 1;
+	
+	if (!SSL_set_tlsext_opaque_prf_input(ssl, arg->input, arg->len))
+		return 0;
+	return arg->ret;
+	}
+#endif
+	int ssl_mode = 0;
+	int c_small_records=0;
+	int s_small_records=0;
 
 int main(int argc, char *argv[])
 	{
@@ -409,19 +470,20 @@
 #endif
 	SSL_CTX *s_ctx=NULL;
 	SSL_CTX *c_ctx=NULL;
-	SSL_METHOD *meth=NULL;
+	const SSL_METHOD *meth=NULL;
 	SSL *c_ssl,*s_ssl;
 	int number=1,reuse=0;
 	long bytes=256L;
 #ifndef OPENSSL_NO_DH
 	DH *dh;
-	int dhe1024 = 1, dhe1024dsa = 0;
+	int dhe1024 = 0, dhe1024dsa = 0;
 #endif
 #ifndef OPENSSL_NO_ECDH
 	EC_KEY *ecdh = NULL;
 #endif
 	int no_dhe = 0;
 	int no_ecdhe = 0;
+	int no_psk = 0;
 	int print_time = 0;
 	clock_t s_time = 0, c_time = 0;
 	int comp = 0;
@@ -430,18 +492,12 @@
 #endif
 	STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
 	int test_cipherlist = 0;
-#ifdef OPENSSL_FIPS
-	int fips_mode=0;
-#endif
-	int ssl_mode = 0;
-	int c_small_records=0;
-	int s_small_records=0;
 
 	verbose = 0;
 	debug = 0;
 	cipher = 0;
 
-	bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);	
+	bio_err=BIO_new_fp(stderr,BIO_NOCLOSE|BIO_FP_TEXT);	
 
 	CRYPTO_set_locking_callback(lock_dbg_cb);
 
@@ -460,23 +516,14 @@
 
 	RAND_seed(rnd_seed, sizeof rnd_seed);
 
-	bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE);
+	bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE|BIO_FP_TEXT);
 
 	argc--;
 	argv++;
 
 	while (argc >= 1)
 		{
-		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)
+		if	(strcmp(*argv,"-server_auth") == 0)
 			server_auth=1;
 		else if	(strcmp(*argv,"-client_auth") == 0)
 			client_auth=1;
@@ -516,6 +563,20 @@
 			no_dhe=1;
 		else if	(strcmp(*argv,"-no_ecdhe") == 0)
 			no_ecdhe=1;
+		else if (strcmp(*argv,"-psk") == 0)
+			{
+			if (--argc < 1) goto bad;
+			psk_key=*(++argv);
+#ifndef OPENSSL_NO_PSK
+			if (strspn(psk_key, "abcdefABCDEF1234567890") != strlen(psk_key))
+				{
+				BIO_printf(bio_err,"Not a hex number '%s'\n",*argv);
+				goto bad;
+				}
+#else
+			no_psk=1;
+#endif
+			}
 		else if	(strcmp(*argv,"-ssl2") == 0)
 			ssl2=1;
 		else if	(strcmp(*argv,"-tls1") == 0)
@@ -666,20 +727,6 @@
 		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)
@@ -839,6 +886,13 @@
 	SSL_CTX_set_tmp_rsa_callback(s_ctx,tmp_rsa_cb);
 #endif
 
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	SSL_CTX_set_tlsext_opaque_prf_input_callback(c_ctx, opaque_prf_input_cb);
+	SSL_CTX_set_tlsext_opaque_prf_input_callback(s_ctx, opaque_prf_input_cb);
+	SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(c_ctx, &co1); /* or &co2 or NULL */
+	SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(s_ctx, &so1); /* or &so2 or NULL */
+#endif
+
 	if (!SSL_CTX_use_certificate_file(s_ctx,server_cert,SSL_FILETYPE_PEM))
 		{
 		ERR_print_errors(bio_err);
@@ -890,6 +944,31 @@
 		SSL_CTX_set_session_id_context(s_ctx, (void *)&session_id_context, sizeof session_id_context);
 	}
 
+	/* Use PSK only if PSK key is given */
+	if (psk_key != NULL)
+		{
+		/* no_psk is used to avoid putting psk command to openssl tool */
+		if (no_psk)
+			{
+			/* if PSK is not compiled in and psk key is
+			 * given, do nothing and exit successfully */
+			ret=0;
+			goto end;
+			}
+#ifndef OPENSSL_NO_PSK
+		SSL_CTX_set_psk_client_callback(c_ctx, psk_client_callback);
+		SSL_CTX_set_psk_server_callback(s_ctx, psk_server_callback);
+		if (debug)
+			BIO_printf(bio_err,"setting PSK identity hint to s_ctx\n");
+		if (!SSL_CTX_use_psk_identity_hint(s_ctx, "ctx server identity_hint"))
+			{
+			BIO_printf(bio_err,"error setting PSK identity hint to s_ctx\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+#endif
+		}
+
 	c_ssl=SSL_new(c_ctx);
 	s_ssl=SSL_new(s_ctx);
 
@@ -966,7 +1045,7 @@
 #endif
 	CRYPTO_cleanup_all_ex_data();
 	ERR_free_strings();
-	ERR_remove_state(0);
+	ERR_remove_thread_state(NULL);
 	EVP_cleanup();
 	CRYPTO_mem_leaks(bio_err);
 	if (bio_err != NULL) BIO_free(bio_err);
@@ -2116,7 +2195,15 @@
 		}
 
 #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)
@@ -2285,11 +2372,74 @@
 	}
 #endif
 
+#ifndef OPENSSL_NO_PSK
+/* convert the PSK key (psk_key) in ascii to binary (psk) */
+static int psk_key2bn(const char *pskkey, unsigned char *psk,
+	unsigned int max_psk_len)
+	{
+	int ret;
+	BIGNUM *bn = NULL;
+
+	ret = BN_hex2bn(&bn, pskkey);
+	if (!ret)
+		{
+		BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", pskkey); 
+		if (bn)
+			BN_free(bn);
+		return 0;
+		}
+	if (BN_num_bytes(bn) > (int)max_psk_len)
+		{
+		BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n",
+			max_psk_len, BN_num_bytes(bn));
+		BN_free(bn);
+		return 0;
+		}
+	ret = BN_bn2bin(bn, psk);
+	BN_free(bn);
+	return ret;
+	}
+
+static unsigned int psk_client_callback(SSL *ssl, const char *hint, char *identity,
+	unsigned int max_identity_len, unsigned char *psk,
+	unsigned int max_psk_len)
+	{
+	int ret;
+	unsigned int psk_len = 0;
+
+	ret = BIO_snprintf(identity, max_identity_len, "Client_identity");
+	if (ret < 0)
+		goto out_err;
+	if (debug)
+		fprintf(stderr, "client: created identity '%s' len=%d\n", identity, ret);
+	ret = psk_key2bn(psk_key, psk, max_psk_len);
+	if (ret < 0)
+		goto out_err;
+	psk_len = ret;
+out_err:
+	return psk_len;
+	}
+
+static unsigned int psk_server_callback(SSL *ssl, const char *identity,
+	unsigned char *psk, unsigned int max_psk_len)
+	{
+	unsigned int psk_len=0;
+
+	if (strcmp(identity, "Client_identity") != 0)
+		{
+		BIO_printf(bio_err, "server: PSK error: client identity not found\n");
+		return 0;
+		}
+	psk_len=psk_key2bn(psk_key, psk, max_psk_len);
+	return psk_len;
+	}
+#endif
+
 static int do_test_cipherlist(void)
 	{
 	int i = 0;
 	const SSL_METHOD *meth;
-	SSL_CIPHER *ci, *tci = NULL;
+	const SSL_CIPHER *ci, *tci = NULL;
 
 #ifndef OPENSSL_NO_SSL2
 	fprintf(stderr, "testing SSLv2 cipher list order: ");
diff --git a/ssl/t1_clnt.c b/ssl/t1_clnt.c
index 4d1e198..c87af17 100644
--- a/ssl/t1_clnt.c
+++ b/ssl/t1_clnt.c
@@ -63,8 +63,8 @@
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 
-static SSL_METHOD *tls1_get_client_method(int ver);
-static SSL_METHOD *tls1_get_client_method(int ver)
+static const SSL_METHOD *tls1_get_client_method(int ver);
+static const SSL_METHOD *tls1_get_client_method(int ver)
 	{
 	if (ver == TLS1_VERSION)
 		return(TLSv1_client_method());
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index dab6e44..d9cb059 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
@@ -108,6 +108,32 @@
  * Hudson (tjh@cryptsoft.com).
  *
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 #include <stdio.h>
 #include "ssl_locl.h"
@@ -121,8 +147,14 @@
 #include <openssl/des.h>
 #endif
 
+/* seed1 through seed5 are virtually concatenated */
 static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
-			int sec_len, unsigned char *seed, int seed_len,
+			int sec_len,
+			const void *seed1, int seed1_len,
+			const void *seed2, int seed2_len,
+			const void *seed3, int seed3_len,
+			const void *seed4, int seed4_len,
+			const void *seed5, int seed5_len,
 			unsigned char *out, int olen)
 	{
 	int chunk,n;
@@ -133,14 +165,17 @@
 	unsigned int A1_len;
 	
 	chunk=EVP_MD_size(md);
+	OPENSSL_assert(chunk >= 0);
 
 	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);
+	if (seed1 != NULL) HMAC_Update(&ctx,seed1,seed1_len);
+	if (seed2 != NULL) HMAC_Update(&ctx,seed2,seed2_len);
+	if (seed3 != NULL) HMAC_Update(&ctx,seed3,seed3_len);
+	if (seed4 != NULL) HMAC_Update(&ctx,seed4,seed4_len);
+	if (seed5 != NULL) HMAC_Update(&ctx,seed5,seed5_len);
 	HMAC_Final(&ctx,A1,&A1_len);
 
 	n=0;
@@ -150,7 +185,11 @@
 		HMAC_Init_ex(&ctx_tmp,NULL,0,NULL,NULL); /* re-init */
 		HMAC_Update(&ctx,A1,A1_len);
 		HMAC_Update(&ctx_tmp,A1,A1_len);
-		HMAC_Update(&ctx,seed,seed_len);
+		if (seed1 != NULL) HMAC_Update(&ctx,seed1,seed1_len);
+		if (seed2 != NULL) HMAC_Update(&ctx,seed2,seed2_len);
+		if (seed3 != NULL) HMAC_Update(&ctx,seed3,seed3_len);
+		if (seed4 != NULL) HMAC_Update(&ctx,seed4,seed4_len);
+		if (seed5 != NULL) HMAC_Update(&ctx,seed5,seed5_len);
 
 		if (olen > chunk)
 			{
@@ -171,44 +210,57 @@
 	OPENSSL_cleanse(A1,sizeof(A1));
 	}
 
-static void tls1_PRF(const EVP_MD *md5, const EVP_MD *sha1,
-		     unsigned char *label, int label_len,
-		     const unsigned char *sec, int slen, unsigned char *out1,
+/* seed1 through seed5 are virtually concatenated */
+static void tls1_PRF(long digest_mask,
+		     const void *seed1, int seed1_len,
+		     const void *seed2, int seed2_len,
+		     const void *seed3, int seed3_len,
+		     const void *seed4, int seed4_len,
+		     const void *seed5, int seed5_len,
+		     const unsigned char *sec, int slen,
+		     unsigned char *out1,
 		     unsigned char *out2, int olen)
 	{
-	int len,i;
-	const unsigned char *S1,*S2;
+	int len,i,idx,count;
+	const unsigned char *S1;
+	long m;
+	const EVP_MD *md;
 
-	len=slen/2;
+	/* Count number of digests and partition sec evenly */
+	count=0;
+	for (idx=0;ssl_get_handshake_digest(idx,&m,&md);idx++) {
+		if ((m<<TLS1_PRF_DGST_SHIFT) & digest_mask) count++;
+	}	
+	len=slen/count;
 	S1=sec;
-	S2= &(sec[len]);
-	len+=(slen&1); /* add for odd, make longer */
-
-	
-	tls1_P_hash(md5 ,S1,len,label,label_len,out1,olen);
-	tls1_P_hash(sha1,S2,len,label,label_len,out2,olen);
-
-	for (i=0; i<olen; i++)
-		out1[i]^=out2[i];
+	memset(out1,0,olen);
+	for (idx=0;ssl_get_handshake_digest(idx,&m,&md);idx++) {
+		if ((m<<TLS1_PRF_DGST_SHIFT) & digest_mask) {
+			if (!md) {
+				SSLerr(SSL_F_TLS1_PRF,
+				SSL_R_UNSUPPORTED_DIGEST_TYPE);
+				return;				
+			}
+			tls1_P_hash(md ,S1,len+(slen&1),
+			            seed1,seed1_len,seed2,seed2_len,seed3,seed3_len,seed4,seed4_len,seed5,seed5_len,
+			            out2,olen);
+			S1+=len;
+			for (i=0; i<olen; i++)
+			{
+				out1[i]^=out2[i];
+			}
+		}
 	}
 
+}
 static void tls1_generate_key_block(SSL *s, unsigned char *km,
 	     unsigned char *tmp, int num)
 	{
-	unsigned char *p;
-	unsigned char buf[SSL3_RANDOM_SIZE*2+
-		TLS_MD_MAX_CONST_SIZE];
-	p=buf;
-
-	memcpy(p,TLS_MD_KEY_EXPANSION_CONST,
-		TLS_MD_KEY_EXPANSION_CONST_SIZE);
-	p+=TLS_MD_KEY_EXPANSION_CONST_SIZE;
-	memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
-	p+=SSL3_RANDOM_SIZE;
-	memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
-	p+=SSL3_RANDOM_SIZE;
-
-	tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(p-buf),
+	tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+		 TLS_MD_KEY_EXPANSION_CONST,TLS_MD_KEY_EXPANSION_CONST_SIZE,
+		 s->s3->server_random,SSL3_RANDOM_SIZE,
+		 s->s3->client_random,SSL3_RANDOM_SIZE,
+		 NULL,0,NULL,0,
 		 s->session->master_key,s->session->master_key_length,
 		 km,tmp,num);
 #ifdef KSSL_DEBUG
@@ -228,8 +280,7 @@
 	{
 	static const unsigned char empty[]="";
 	unsigned char *p,*key_block,*mac_secret;
-	unsigned char *exp_label,buf[TLS_MD_MAX_CONST_SIZE+
-		SSL3_RANDOM_SIZE*2];
+	unsigned char *exp_label;
 	unsigned char tmp1[EVP_MAX_KEY_LENGTH];
 	unsigned char tmp2[EVP_MAX_KEY_LENGTH];
 	unsigned char iv1[EVP_MAX_IV_LENGTH*2];
@@ -242,12 +293,17 @@
 	const SSL_COMP *comp;
 #endif
 	const EVP_MD *m;
+	int mac_type;
+	int *mac_secret_size;
+	EVP_MD_CTX *mac_ctx;
+	EVP_PKEY *mac_key;
 	int is_export,n,i,j,k,exp_label_len,cl;
 	int reuse_dd = 0;
 
 	is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
 	c=s->s3->tmp.new_sym_enc;
 	m=s->s3->tmp.new_hash;
+	mac_type = s->s3->tmp.new_mac_pkey_type;
 #ifndef OPENSSL_NO_COMP
 	comp=s->s3->tmp.new_compression;
 #endif
@@ -255,21 +311,28 @@
 
 #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,
-                (void *)comp);
-	printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", (void *)c);
+	printf("\talg= %ld/%ld, comp= %p\n",
+	       s->s3->tmp.new_cipher->algorithm_mkey,
+	       s->s3->tmp.new_cipher->algorithm_auth,
+	       comp);
+	printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", 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 ki;
-        for (ki=0; ki<s->s3->tmp.key_block_length; ki++)
-		printf("%02x", key_block[ki]);  printf("\n");
+        int i;
+        for (i=0; i<s->s3->tmp.key_block_length; i++)
+		printf("%02x", key_block[i]);  printf("\n");
         }
 #endif	/* KSSL_DEBUG */
 
 	if (which & SSL3_CC_READ)
 		{
+		if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
+			s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM;
+			else
+			s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;
+
 		if (s->enc_read_ctx != NULL)
 			reuse_dd = 1;
 		else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
@@ -278,7 +341,7 @@
 			/* make sure it's intialized in case we exit later with an error */
 			EVP_CIPHER_CTX_init(s->enc_read_ctx);
 		dd= s->enc_read_ctx;
-		s->read_hash=m;
+		mac_ctx=ssl_replace_hash(&s->read_hash,NULL);
 #ifndef OPENSSL_NO_COMP
 		if (s->expand != NULL)
 			{
@@ -304,9 +367,14 @@
  		if (s->version != DTLS1_VERSION)
 			memset(&(s->s3->read_sequence[0]),0,8);
 		mac_secret= &(s->s3->read_mac_secret[0]);
+		mac_secret_size=&(s->s3->read_mac_secret_size);
 		}
 	else
 		{
+		if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
+			s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
+			else
+			s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM;
 		if (s->enc_write_ctx != NULL)
 			reuse_dd = 1;
 		else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
@@ -315,7 +383,7 @@
 			/* make sure it's intialized in case we exit later with an error */
 			EVP_CIPHER_CTX_init(s->enc_write_ctx);
 		dd= s->enc_write_ctx;
-		s->write_hash=m;
+		mac_ctx = ssl_replace_hash(&s->write_hash,NULL);
 #ifndef OPENSSL_NO_COMP
 		if (s->compress != NULL)
 			{
@@ -336,13 +404,15 @@
  		if (s->version != DTLS1_VERSION)
 			memset(&(s->s3->write_sequence[0]),0,8);
 		mac_secret= &(s->s3->write_mac_secret[0]);
+		mac_secret_size = &(s->s3->write_mac_secret_size);
 		}
 
 	if (reuse_dd)
 		EVP_CIPHER_CTX_cleanup(dd);
 
 	p=s->s3->tmp.key_block;
-	i=EVP_MD_size(m);
+	i=*mac_secret_size=s->s3->tmp.new_mac_secret_size;
+
 	cl=EVP_CIPHER_key_length(c);
 	j=is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
 	               cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
@@ -378,6 +448,10 @@
 		}
 
 	memcpy(mac_secret,ms,i);
+	mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,
+			mac_secret,*mac_secret_size);
+	EVP_DigestSignInit(mac_ctx,NULL,m,NULL,mac_key);
+	EVP_PKEY_free(mac_key);
 #ifdef TLS_DEBUG
 printf("which = %04X\nmac key=",which);
 { int z; for (z=0; z<i; z++) printf("%02X%c",ms[z],((z+1)%16)?' ':'\n'); }
@@ -387,29 +461,22 @@
 		/* In here I set both the read and write key/iv to the
 		 * same value since only the correct one will be used :-).
 		 */
-		p=buf;
-		memcpy(p,exp_label,exp_label_len);
-		p+=exp_label_len;
-		memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
-		p+=SSL3_RANDOM_SIZE;
-		memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
-		p+=SSL3_RANDOM_SIZE;
-		tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(p-buf),key,j,
-			 tmp1,tmp2,EVP_CIPHER_key_length(c));
+		tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+			 exp_label,exp_label_len,
+			 s->s3->client_random,SSL3_RANDOM_SIZE,
+			 s->s3->server_random,SSL3_RANDOM_SIZE,
+			 NULL,0,NULL,0,
+			 key,j,tmp1,tmp2,EVP_CIPHER_key_length(c));
 		key=tmp1;
 
 		if (k > 0)
 			{
-			p=buf;
-			memcpy(p,TLS_MD_IV_BLOCK_CONST,
-				TLS_MD_IV_BLOCK_CONST_SIZE);
-			p+=TLS_MD_IV_BLOCK_CONST_SIZE;
-			memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
-			p+=SSL3_RANDOM_SIZE;
-			memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
-			p+=SSL3_RANDOM_SIZE;
-			tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,p-buf,empty,0,
-				 iv1,iv2,k*2);
+			tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+				 TLS_MD_IV_BLOCK_CONST,TLS_MD_IV_BLOCK_CONST_SIZE,
+				 s->s3->client_random,SSL3_RANDOM_SIZE,
+				 s->s3->server_random,SSL3_RANDOM_SIZE,
+				 NULL,0,NULL,0,
+				 empty,0,iv1,iv2,k*2);
 			if (client_write)
 				iv=iv1;
 			else
@@ -420,13 +487,11 @@
 	s->session->key_arg_length=0;
 #ifdef KSSL_DEBUG
 	{
-        int ki;
+        int i;
 	printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n");
-	printf("\tkey= ");
-	for (ki=0; ki<c->key_len; ki++) printf("%02x", key[ki]);
+	printf("\tkey= "); for (i=0; i<c->key_len; i++) printf("%02x", key[i]);
 	printf("\n");
-	printf("\t iv= ");
-	for (ki=0; ki<c->iv_len; ki++) printf("%02x", iv[ki]);
+	printf("\t iv= "); for (i=0; i<c->iv_len; i++) printf("%02x", iv[i]);
 	printf("\n");
 	}
 #endif	/* KSSL_DEBUG */
@@ -458,6 +523,7 @@
 	const EVP_MD *hash;
 	int num;
 	SSL_COMP *comp;
+	int mac_type= NID_undef,mac_secret_size=0;
 
 #ifdef KSSL_DEBUG
 	printf ("tls1_setup_key_block()\n");
@@ -466,7 +532,7 @@
 	if (s->s3->tmp.key_block_length != 0)
 		return(1);
 
-	if (!ssl_cipher_get_evp(s->session,&c,&hash,&comp))
+	if (!ssl_cipher_get_evp(s->session,&c,&hash,&mac_type,&mac_secret_size,&comp))
 		{
 		SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
 		return(0);
@@ -474,8 +540,9 @@
 
 	s->s3->tmp.new_sym_enc=c;
 	s->s3->tmp.new_hash=hash;
-
-	num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c);
+	s->s3->tmp.new_mac_pkey_type = mac_type;
+	s->s3->tmp.new_mac_secret_size = mac_secret_size;
+	num=EVP_CIPHER_key_length(c)+mac_secret_size+EVP_CIPHER_iv_length(c);
 	num*=2;
 
 	ssl3_cleanup_key_block(s);
@@ -514,11 +581,11 @@
 
 		if (s->session->cipher != NULL)
 			{
-			if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_eNULL)
+			if (s->session->cipher->algorithm_enc == SSL_eNULL)
 				s->s3->need_empty_fragments = 0;
 			
 #ifndef OPENSSL_NO_RC4
-			if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4)
+			if (s->session->cipher->algorithm_enc == SSL_RC4)
 				s->s3->need_empty_fragments = 0;
 #endif
 			}
@@ -540,8 +607,11 @@
 
 	if (send)
 		{
-		if (s->write_hash != NULL)
-			n=EVP_MD_size(s->write_hash);
+		if (EVP_MD_CTX_md(s->write_hash))
+			{
+			n=EVP_MD_CTX_size(s->write_hash);
+			OPENSSL_assert(n >= 0);
+			}
 		ds=s->enc_write_ctx;
 		rec= &(s->s3->wrec);
 		if (s->enc_write_ctx == NULL)
@@ -551,8 +621,11 @@
 		}
 	else
 		{
-		if (s->read_hash != NULL)
-			n=EVP_MD_size(s->read_hash);
+		if (EVP_MD_CTX_md(s->read_hash))
+			{
+			n=EVP_MD_CTX_size(s->read_hash);
+			OPENSSL_assert(n >= 0);
+			}
 		ds=s->enc_read_ctx;
 		rec= &(s->s3->rrec);
 		if (s->enc_read_ctx == NULL)
@@ -599,11 +672,10 @@
 		{
                 unsigned long ui;
 		printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\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,rec->data,rec->input,l);
+		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
                         ds->buf_len, ds->cipher->key_len,
-                        (unsigned long)DES_KEY_SZ,
-			(unsigned long)DES_SCHEDULE_SZ,
+                        DES_KEY_SZ, DES_SCHEDULE_SZ,
                         ds->cipher->iv_len);
 		printf("\t\tIV: ");
 		for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
@@ -628,10 +700,10 @@
 
 #ifdef KSSL_DEBUG
 		{
-                unsigned long ki;
+                unsigned long i;
                 printf("\trec->data=");
-		for (ki=0; ki<l; i++)
-                        printf(" %02x", rec->data[ki]);  printf("\n");
+		for (i=0; i<l; i++)
+                        printf(" %02x", rec->data[i]);  printf("\n");
                 }
 #endif	/* KSSL_DEBUG */
 
@@ -679,56 +751,100 @@
 		}
 	return(1);
 	}
-
-int tls1_cert_verify_mac(SSL *s, EVP_MD_CTX *in_ctx, unsigned char *out)
+int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out)
 	{
 	unsigned int ret;
-	EVP_MD_CTX ctx;
+	EVP_MD_CTX ctx, *d=NULL;
+	int i;
+
+	if (s->s3->handshake_buffer) 
+		if (!ssl3_digest_cached_records(s))
+			return 0;
+
+	for (i=0;i<SSL_MAX_DIGEST;i++) 
+		{
+		  if (s->s3->handshake_dgst[i]&&EVP_MD_CTX_type(s->s3->handshake_dgst[i])==md_nid) 
+		  	{
+		  	d=s->s3->handshake_dgst[i];
+			break;
+			}
+		}
+	if (!d) {
+		SSLerr(SSL_F_TLS1_CERT_VERIFY_MAC,SSL_R_NO_REQUIRED_DIGEST);
+		return 0;
+	}	
 
 	EVP_MD_CTX_init(&ctx);
-	EVP_MD_CTX_copy_ex(&ctx,in_ctx);
+	EVP_MD_CTX_copy_ex(&ctx,d);
 	EVP_DigestFinal_ex(&ctx,out,&ret);
 	EVP_MD_CTX_cleanup(&ctx);
 	return((int)ret);
 	}
 
-int tls1_final_finish_mac(SSL *s, EVP_MD_CTX *in1_ctx, EVP_MD_CTX *in2_ctx,
+int tls1_final_finish_mac(SSL *s,
 	     const char *str, int slen, unsigned char *out)
 	{
 	unsigned int i;
 	EVP_MD_CTX ctx;
-	unsigned char buf[TLS_MD_MAX_CONST_SIZE+MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
+	unsigned char buf[2*EVP_MAX_MD_SIZE];
 	unsigned char *q,buf2[12];
+	int idx;
+	long mask;
+	int err=0;
+	const EVP_MD *md; 
 
 	q=buf;
-	memcpy(q,str,slen);
-	q+=slen;
+
+	if (s->s3->handshake_buffer) 
+		if (!ssl3_digest_cached_records(s))
+			return 0;
 
 	EVP_MD_CTX_init(&ctx);
-	EVP_MD_CTX_copy_ex(&ctx,in1_ctx);
-	EVP_DigestFinal_ex(&ctx,q,&i);
-	q+=i;
-	EVP_MD_CTX_copy_ex(&ctx,in2_ctx);
-	EVP_DigestFinal_ex(&ctx,q,&i);
-	q+=i;
 
-	tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(q-buf),
-		s->session->master_key,s->session->master_key_length,
-		out,buf2,sizeof buf2);
+	for (idx=0;ssl_get_handshake_digest(idx,&mask,&md);idx++)
+		{
+		if (mask & s->s3->tmp.new_cipher->algorithm2)
+			{
+			int hashsize = EVP_MD_size(md);
+			if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
+				{
+				/* internal error: 'buf' is too small for this cipersuite! */
+				err = 1;
+				}
+			else
+				{
+				EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
+				EVP_DigestFinal_ex(&ctx,q,&i);
+				if (i != (unsigned int)hashsize) /* can't really happen */
+					err = 1;
+				q+=i;
+				}
+			}
+		}
+		
+	tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+		 str,slen, buf,(int)(q-buf), NULL,0, NULL,0, NULL,0,
+		 s->session->master_key,s->session->master_key_length,
+		 out,buf2,sizeof buf2);
 	EVP_MD_CTX_cleanup(&ctx);
 
-	return sizeof buf2;
+	if (err)
+		return 0;
+	else
+		return sizeof buf2;
 	}
 
 int tls1_mac(SSL *ssl, unsigned char *md, int send)
 	{
 	SSL3_RECORD *rec;
 	unsigned char *mac_sec,*seq;
-	const EVP_MD *hash;
-	unsigned int md_size;
+	EVP_MD_CTX *hash;
+	size_t md_size;
 	int i;
-	HMAC_CTX hmac;
+	EVP_MD_CTX hmac, *mac_ctx;
 	unsigned char buf[5]; 
+	int stream_mac = (send?(ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM):(ssl->mac_flags&SSL_MAC_FLAG_READ_MAC_STREAM));
+	int t;
 
 	if (send)
 		{
@@ -745,43 +861,45 @@
 		hash=ssl->read_hash;
 		}
 
-	md_size=EVP_MD_size(hash);
+	t=EVP_MD_CTX_size(hash);
+	OPENSSL_assert(t >= 0);
+	md_size=t;
 
 	buf[0]=rec->type;
-	if (ssl->version == DTLS1_VERSION && ssl->client_version == DTLS1_BAD_VER)
-		{
-		buf[1]=TLS1_VERSION_MAJOR;
-		buf[2]=TLS1_VERSION_MINOR;
-		}
-	else	{
-		buf[1]=(unsigned char)(ssl->version>>8);
-		buf[2]=(unsigned char)(ssl->version);
-		}
-
+	buf[1]=(unsigned char)(ssl->version>>8);
+	buf[2]=(unsigned char)(ssl->version);
 	buf[3]=rec->length>>8;
 	buf[4]=rec->length&0xff;
 
 	/* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */
-	HMAC_CTX_init(&hmac);
-	HMAC_Init_ex(&hmac,mac_sec,EVP_MD_size(hash),hash,NULL);
+	if (stream_mac) 
+		{
+			mac_ctx = hash;
+		}
+		else
+		{
+			EVP_MD_CTX_copy(&hmac,hash);
+			mac_ctx = &hmac;
+		}
 
-	if (ssl->version == DTLS1_BAD_VER ||
-	    (ssl->version == DTLS1_VERSION && ssl->client_version != DTLS1_BAD_VER))
+	if (ssl->version == DTLS1_VERSION || ssl->version == DTLS1_BAD_VER)
 		{
 		unsigned char dtlsseq[8],*p=dtlsseq;
+
 		s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p);
 		memcpy (p,&seq[2],6);
 
-		HMAC_Update(&hmac,dtlsseq,8);
+		EVP_DigestSignUpdate(mac_ctx,dtlsseq,8);
 		}
 	else
-		HMAC_Update(&hmac,seq,8);
+		EVP_DigestSignUpdate(mac_ctx,seq,8);
 
-	HMAC_Update(&hmac,buf,5);
-	HMAC_Update(&hmac,rec->input,rec->length);
-	HMAC_Final(&hmac,md,&md_size);
-	HMAC_CTX_cleanup(&hmac);
-
+	EVP_DigestSignUpdate(mac_ctx,buf,5);
+	EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length);
+	t=EVP_DigestSignFinal(mac_ctx,md,&md_size);
+	OPENSSL_assert(t > 0);
+		
+	if (!stream_mac) EVP_MD_CTX_cleanup(&hmac);
 #ifdef TLS_DEBUG
 printf("sec=");
 {unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); }
@@ -793,7 +911,7 @@
 {unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); }
 #endif
 
-	if ( SSL_version(ssl) != DTLS1_VERSION && SSL_version(ssl) != DTLS1_BAD_VER)
+	if (ssl->version != DTLS1_VERSION && ssl->version != DTLS1_BAD_VER)
 		{
 		for (i=7; i>=0; i--)
 			{
@@ -811,23 +929,35 @@
 int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
 	     int len)
 	{
-	unsigned char buf[SSL3_RANDOM_SIZE*2+TLS_MD_MASTER_SECRET_CONST_SIZE];
 	unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH];
+	const void *co = NULL, *so = NULL;
+	int col = 0, sol = 0;
 
 #ifdef KSSL_DEBUG
-	printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", (void *)s,out, p,len);
+	printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
 #endif	/* KSSL_DEBUG */
 
-	/* Setup the stuff to munge */
-	memcpy(buf,TLS_MD_MASTER_SECRET_CONST,
-		TLS_MD_MASTER_SECRET_CONST_SIZE);
-	memcpy(&(buf[TLS_MD_MASTER_SECRET_CONST_SIZE]),
-		s->s3->client_random,SSL3_RANDOM_SIZE);
-	memcpy(&(buf[SSL3_RANDOM_SIZE+TLS_MD_MASTER_SECRET_CONST_SIZE]),
-		s->s3->server_random,SSL3_RANDOM_SIZE);
-	tls1_PRF(s->ctx->md5,s->ctx->sha1,
-		buf,TLS_MD_MASTER_SECRET_CONST_SIZE+SSL3_RANDOM_SIZE*2,p,len,
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	if (s->s3->client_opaque_prf_input != NULL && s->s3->server_opaque_prf_input != NULL &&
+	    s->s3->client_opaque_prf_input_len > 0 &&
+	    s->s3->client_opaque_prf_input_len == s->s3->server_opaque_prf_input_len)
+		{
+		co = s->s3->client_opaque_prf_input;
+		col = s->s3->server_opaque_prf_input_len;
+		so = s->s3->server_opaque_prf_input;
+		sol = s->s3->client_opaque_prf_input_len; /* must be same as col (see draft-rescorla-tls-opaque-prf-input-00.txt, section 3.1) */
+		}
+#endif
+
+	tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+		TLS_MD_MASTER_SECRET_CONST,TLS_MD_MASTER_SECRET_CONST_SIZE,
+		s->s3->client_random,SSL3_RANDOM_SIZE,
+		co, col,
+		s->s3->server_random,SSL3_RANDOM_SIZE,
+		so, sol,
+		p,len,
 		s->session->master_key,buff,sizeof buff);
+
 #ifdef KSSL_DEBUG
 	printf ("tls1_generate_master_secret() complete\n");
 #endif	/* KSSL_DEBUG */
@@ -862,7 +992,13 @@
 	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 SSL_AD_UNSUPPORTED_EXTENSION: return(TLS1_AD_UNSUPPORTED_EXTENSION);
+	case SSL_AD_CERTIFICATE_UNOBTAINABLE: return(TLS1_AD_CERTIFICATE_UNOBTAINABLE);
+	case SSL_AD_UNRECOGNIZED_NAME:	return(TLS1_AD_UNRECOGNIZED_NAME);
+	case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE);
+	case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
+	case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
+#if 0 /* not appropriate for TLS, not used for DTLS */
 	case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return 
 					  (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
 #endif
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 8b53112..e8bc34c 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -55,6 +55,59 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
 
 #include <stdio.h>
 #include <openssl/objects.h>
@@ -92,11 +145,6 @@
 	return(60*60*2);
 	}
 
-IMPLEMENT_tls1_meth_func(tlsv1_base_method,
-			ssl_undefined_function,
-			ssl_undefined_function,
-			ssl_bad_method)
-
 int tls1_new(SSL *s)
 	{
 	if (!ssl3_new(s)) return(0);
@@ -106,6 +154,12 @@
 
 void tls1_free(SSL *s)
 	{
+#ifndef OPENSSL_NO_TLSEXT
+	if (s->tlsext_session_ticket)
+		{
+		OPENSSL_free(s->tlsext_session_ticket);
+		}
+#endif /* OPENSSL_NO_TLSEXT */
 	ssl3_free(s);
 	}
 
@@ -115,17 +169,105 @@
 	s->version=TLS1_VERSION;
 	}
 
-#if 0
-long tls1_ctrl(SSL *s, int cmd, long larg, char *parg)
+#ifndef OPENSSL_NO_EC
+static int nid_list[] =
 	{
-	return(0);
+		NID_sect163k1, /* sect163k1 (1) */
+		NID_sect163r1, /* sect163r1 (2) */
+		NID_sect163r2, /* sect163r2 (3) */
+		NID_sect193r1, /* sect193r1 (4) */ 
+		NID_sect193r2, /* sect193r2 (5) */ 
+		NID_sect233k1, /* sect233k1 (6) */
+		NID_sect233r1, /* sect233r1 (7) */ 
+		NID_sect239k1, /* sect239k1 (8) */ 
+		NID_sect283k1, /* sect283k1 (9) */
+		NID_sect283r1, /* sect283r1 (10) */ 
+		NID_sect409k1, /* sect409k1 (11) */ 
+		NID_sect409r1, /* sect409r1 (12) */
+		NID_sect571k1, /* sect571k1 (13) */ 
+		NID_sect571r1, /* sect571r1 (14) */ 
+		NID_secp160k1, /* secp160k1 (15) */
+		NID_secp160r1, /* secp160r1 (16) */ 
+		NID_secp160r2, /* secp160r2 (17) */ 
+		NID_secp192k1, /* secp192k1 (18) */
+		NID_X9_62_prime192v1, /* secp192r1 (19) */ 
+		NID_secp224k1, /* secp224k1 (20) */ 
+		NID_secp224r1, /* secp224r1 (21) */
+		NID_secp256k1, /* secp256k1 (22) */ 
+		NID_X9_62_prime256v1, /* secp256r1 (23) */ 
+		NID_secp384r1, /* secp384r1 (24) */
+		NID_secp521r1  /* secp521r1 (25) */	
+	};
+	
+int tls1_ec_curve_id2nid(int curve_id)
+	{
+	/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
+	if ((curve_id < 1) || ((unsigned int)curve_id >
+				sizeof(nid_list)/sizeof(nid_list[0])))
+		return 0;
+	return nid_list[curve_id-1];
 	}
 
-long tls1_callback_ctrl(SSL *s, int cmd, void *(*fp)())
+int tls1_ec_nid2curve_id(int nid)
 	{
-	return(0);
+	/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
+	switch (nid)
+		{
+	case NID_sect163k1: /* sect163k1 (1) */
+		return 1;
+	case NID_sect163r1: /* sect163r1 (2) */
+		return 2;
+	case NID_sect163r2: /* sect163r2 (3) */
+		return 3;
+	case NID_sect193r1: /* sect193r1 (4) */ 
+		return 4;
+	case NID_sect193r2: /* sect193r2 (5) */ 
+		return 5;
+	case NID_sect233k1: /* sect233k1 (6) */
+		return 6;
+	case NID_sect233r1: /* sect233r1 (7) */ 
+		return 7;
+	case NID_sect239k1: /* sect239k1 (8) */ 
+		return 8;
+	case NID_sect283k1: /* sect283k1 (9) */
+		return 9;
+	case NID_sect283r1: /* sect283r1 (10) */ 
+		return 10;
+	case NID_sect409k1: /* sect409k1 (11) */ 
+		return 11;
+	case NID_sect409r1: /* sect409r1 (12) */
+		return 12;
+	case NID_sect571k1: /* sect571k1 (13) */ 
+		return 13;
+	case NID_sect571r1: /* sect571r1 (14) */ 
+		return 14;
+	case NID_secp160k1: /* secp160k1 (15) */
+		return 15;
+	case NID_secp160r1: /* secp160r1 (16) */ 
+		return 16;
+	case NID_secp160r2: /* secp160r2 (17) */ 
+		return 17;
+	case NID_secp192k1: /* secp192k1 (18) */
+		return 18;
+	case NID_X9_62_prime192v1: /* secp192r1 (19) */ 
+		return 19;
+	case NID_secp224k1: /* secp224k1 (20) */ 
+		return 20;
+	case NID_secp224r1: /* secp224r1 (21) */
+		return 21;
+	case NID_secp256k1: /* secp256k1 (22) */ 
+		return 22;
+	case NID_X9_62_prime256v1: /* secp256r1 (23) */ 
+		return 23;
+	case NID_secp384r1: /* secp384r1 (24) */
+		return 24;
+	case NID_secp521r1:  /* secp521r1 (25) */	
+		return 25;
+	default:
+		return 0;
+		}
 	}
-#endif
+#endif /* OPENSSL_NO_EC */
 
 #ifndef OPENSSL_NO_TLSEXT
 unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
@@ -157,7 +299,7 @@
 		*/
 		   
 		if ((lenmax = limit - ret - 9) < 0 
-		|| (size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax) 
+		    || (size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax) 
 			return NULL;
 			
 		/* extension type and length */
@@ -172,9 +314,8 @@
 		s2n(size_str,ret);
 		memcpy(ret, s->tlsext_hostname, size_str);
 		ret+=size_str;
-
 		}
- 
+
         /* Add RI if renegotiating */
         if (s->new_session)
           {
@@ -200,19 +341,81 @@
           ret += el;
         }
 
-           
+#ifndef OPENSSL_NO_EC
+	if (s->tlsext_ecpointformatlist != NULL &&
+	    s->version != DTLS1_VERSION)
+		{
+		/* Add TLS extension ECPointFormats to the ClientHello message */
+		long lenmax; 
+
+		if ((lenmax = limit - ret - 5) < 0) return NULL; 
+		if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) return NULL;
+		if (s->tlsext_ecpointformatlist_length > 255)
+			{
+			SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+			return NULL;
+			}
+		
+		s2n(TLSEXT_TYPE_ec_point_formats,ret);
+		s2n(s->tlsext_ecpointformatlist_length + 1,ret);
+		*(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length;
+		memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
+		ret+=s->tlsext_ecpointformatlist_length;
+		}
+	if (s->tlsext_ellipticcurvelist != NULL &&
+	    s->version != DTLS1_VERSION)
+		{
+		/* Add TLS extension EllipticCurves to the ClientHello message */
+		long lenmax; 
+
+		if ((lenmax = limit - ret - 6) < 0) return NULL; 
+		if (s->tlsext_ellipticcurvelist_length > (unsigned long)lenmax) return NULL;
+		if (s->tlsext_ellipticcurvelist_length > 65532)
+			{
+			SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+			return NULL;
+			}
+		
+		s2n(TLSEXT_TYPE_elliptic_curves,ret);
+		s2n(s->tlsext_ellipticcurvelist_length + 2, ret);
+
+		/* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
+		 * elliptic_curve_list, but the examples use two bytes.
+		 * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
+		 * resolves this to two bytes.
+		 */
+		s2n(s->tlsext_ellipticcurvelist_length, ret);
+		memcpy(ret, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
+		ret+=s->tlsext_ellipticcurvelist_length;
+		}
+#endif /* OPENSSL_NO_EC */
+
 	if (!(SSL_get_options(s) & SSL_OP_NO_TICKET))
 		{
 		int ticklen;
 		if (!s->new_session && s->session && s->session->tlsext_tick)
 			ticklen = s->session->tlsext_ticklen;
+		else if (s->session && s->tlsext_session_ticket &&
+			 s->tlsext_session_ticket->data)
+			{
+			ticklen = s->tlsext_session_ticket->length;
+			s->session->tlsext_tick = OPENSSL_malloc(ticklen);
+			if (!s->session->tlsext_tick)
+				return NULL;
+			memcpy(s->session->tlsext_tick,
+			       s->tlsext_session_ticket->data,
+			       ticklen);
+			s->session->tlsext_ticklen = ticklen;
+			}
 		else
 			ticklen = 0;
+		if (ticklen == 0 && s->tlsext_session_ticket &&
+		    s->tlsext_session_ticket->data == NULL)
+			goto skip_ext;
 		/* Check for enough room 2 for extension type, 2 for len
  		 * rest for ticket
   		 */
-		if (limit - ret - 4 - ticklen < 0)
-			return NULL;
+		if ((long)(limit - ret - 4 - ticklen) < 0) return NULL;
 		s2n(TLSEXT_TYPE_session_ticket,ret); 
 		s2n(ticklen,ret);
 		if (ticklen)
@@ -221,6 +424,26 @@
 			ret += ticklen;
 			}
 		}
+		skip_ext:
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	if (s->s3->client_opaque_prf_input != NULL &&
+	    s->version != DTLS1_VERSION)
+		{
+		size_t col = s->s3->client_opaque_prf_input_len;
+		
+		if ((long)(limit - ret - 6 - col < 0))
+			return NULL;
+		if (col > 0xFFFD) /* can't happen */
+			return NULL;
+
+		s2n(TLSEXT_TYPE_opaque_prf_input, ret); 
+		s2n(col + 2, ret);
+		s2n(col, ret);
+		memcpy(ret, s->s3->client_opaque_prf_input, col);
+		ret += col;
+		}
+#endif
 
 	if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp &&
 	    s->version != DTLS1_VERSION)
@@ -292,7 +515,7 @@
 
 	if (!s->hit && s->servername_done == 1 && s->session->tlsext_hostname != NULL)
 		{ 
-		if (limit - ret - 4 < 0) return NULL; 
+		if ((long)(limit - ret - 4) < 0) return NULL; 
 
 		s2n(TLSEXT_TYPE_server_name,ret);
 		s2n(0,ret);
@@ -321,11 +544,36 @@
 
           ret += el;
         }
-	
+
+#ifndef OPENSSL_NO_EC
+	if (s->tlsext_ecpointformatlist != NULL &&
+	    s->version != DTLS1_VERSION)
+		{
+		/* Add TLS extension ECPointFormats to the ServerHello message */
+		long lenmax; 
+
+		if ((lenmax = limit - ret - 5) < 0) return NULL; 
+		if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) return NULL;
+		if (s->tlsext_ecpointformatlist_length > 255)
+			{
+			SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+			return NULL;
+			}
+		
+		s2n(TLSEXT_TYPE_ec_point_formats,ret);
+		s2n(s->tlsext_ecpointformatlist_length + 1,ret);
+		*(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length;
+		memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
+		ret+=s->tlsext_ecpointformatlist_length;
+
+		}
+	/* Currently the server should not respond with a SupportedCurves extension */
+#endif /* OPENSSL_NO_EC */
+
 	if (s->tlsext_ticket_expected
 		&& !(SSL_get_options(s) & SSL_OP_NO_TICKET)) 
 		{ 
-		if (limit - ret - 4 < 0) return NULL; 
+		if ((long)(limit - ret - 4) < 0) return NULL; 
 		s2n(TLSEXT_TYPE_session_ticket,ret);
 		s2n(0,ret);
 		}
@@ -337,6 +585,39 @@
 		s2n(0,ret);
 		}
 
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	if (s->s3->server_opaque_prf_input != NULL &&
+	    s->version != DTLS1_VERSION)
+		{
+		size_t sol = s->s3->server_opaque_prf_input_len;
+		
+		if ((long)(limit - ret - 6 - sol) < 0)
+			return NULL;
+		if (sol > 0xFFFD) /* can't happen */
+			return NULL;
+
+		s2n(TLSEXT_TYPE_opaque_prf_input, ret); 
+		s2n(sol + 2, ret);
+		s2n(sol, ret);
+		memcpy(ret, s->s3->server_opaque_prf_input, sol);
+		ret += sol;
+		}
+#endif
+	if (((s->s3->tmp.new_cipher->id & 0xFFFF)==0x80 || (s->s3->tmp.new_cipher->id & 0xFFFF)==0x81) 
+		&& (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG))
+		{ const unsigned char cryptopro_ext[36] = {
+			0xfd, 0xe8, /*65000*/
+			0x00, 0x20, /*32 bytes length*/
+			0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85, 
+			0x03,   0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06, 
+			0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08, 
+			0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17};
+			if (limit-ret<36) return NULL;
+			memcpy(ret,cryptopro_ext,36);
+			ret+=36;
+
+		}
+
 	if ((extdatalen = ret-p-2)== 0) 
 		return p;
 
@@ -357,7 +638,6 @@
 
 	if (data >= (d+n-2))
 		goto ri_check;
-
 	n2s(data,len);
 
 	if (data > (d+n-len)) 
@@ -370,7 +650,9 @@
 
 		if (data+size > (d+n))
 	   		goto ri_check;
-
+#if 0
+		fprintf(stderr,"Received extension type %d size %d\n",type,size);
+#endif
 		if (s->tlsext_debug_cb)
 			s->tlsext_debug_cb(s, 0, type, data, size,
 						s->tlsext_debug_arg);
@@ -470,6 +752,106 @@
 				}
 
 			}
+
+#ifndef OPENSSL_NO_EC
+		else if (type == TLSEXT_TYPE_ec_point_formats &&
+	             s->version != DTLS1_VERSION)
+			{
+			unsigned char *sdata = data;
+			int ecpointformatlist_length = *(sdata++);
+
+			if (ecpointformatlist_length != size - 1)
+				{
+				*al = TLS1_AD_DECODE_ERROR;
+				return 0;
+				}
+			s->session->tlsext_ecpointformatlist_length = 0;
+			if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist);
+			if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
+				{
+				*al = TLS1_AD_INTERNAL_ERROR;
+				return 0;
+				}
+			s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
+			memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
+#if 0
+			fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ", s->session->tlsext_ecpointformatlist_length);
+			sdata = s->session->tlsext_ecpointformatlist;
+			for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
+				fprintf(stderr,"%i ",*(sdata++));
+			fprintf(stderr,"\n");
+#endif
+			}
+		else if (type == TLSEXT_TYPE_elliptic_curves &&
+	             s->version != DTLS1_VERSION)
+			{
+			unsigned char *sdata = data;
+			int ellipticcurvelist_length = (*(sdata++) << 8);
+			ellipticcurvelist_length += (*(sdata++));
+
+			if (ellipticcurvelist_length != size - 2)
+				{
+				*al = TLS1_AD_DECODE_ERROR;
+				return 0;
+				}
+			s->session->tlsext_ellipticcurvelist_length = 0;
+			if (s->session->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->session->tlsext_ellipticcurvelist);
+			if ((s->session->tlsext_ellipticcurvelist = OPENSSL_malloc(ellipticcurvelist_length)) == NULL)
+				{
+				*al = TLS1_AD_INTERNAL_ERROR;
+				return 0;
+				}
+			s->session->tlsext_ellipticcurvelist_length = ellipticcurvelist_length;
+			memcpy(s->session->tlsext_ellipticcurvelist, sdata, ellipticcurvelist_length);
+#if 0
+			fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ", s->session->tlsext_ellipticcurvelist_length);
+			sdata = s->session->tlsext_ellipticcurvelist;
+			for (i = 0; i < s->session->tlsext_ellipticcurvelist_length; i++)
+				fprintf(stderr,"%i ",*(sdata++));
+			fprintf(stderr,"\n");
+#endif
+			}
+#endif /* OPENSSL_NO_EC */
+#ifdef TLSEXT_TYPE_opaque_prf_input
+		else if (type == TLSEXT_TYPE_opaque_prf_input &&
+	             s->version != DTLS1_VERSION)
+			{
+			unsigned char *sdata = data;
+
+			if (size < 2)
+				{
+				*al = SSL_AD_DECODE_ERROR;
+				return 0;
+				}
+			n2s(sdata, s->s3->client_opaque_prf_input_len);
+			if (s->s3->client_opaque_prf_input_len != size - 2)
+				{
+				*al = SSL_AD_DECODE_ERROR;
+				return 0;
+				}
+
+			if (s->s3->client_opaque_prf_input != NULL) /* shouldn't really happen */
+				OPENSSL_free(s->s3->client_opaque_prf_input);
+			if (s->s3->client_opaque_prf_input_len == 0)
+				s->s3->client_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
+			else
+				s->s3->client_opaque_prf_input = BUF_memdup(sdata, s->s3->client_opaque_prf_input_len);
+			if (s->s3->client_opaque_prf_input == NULL)
+				{
+				*al = TLS1_AD_INTERNAL_ERROR;
+				return 0;
+				}
+			}
+#endif
+		else if (type == TLSEXT_TYPE_session_ticket)
+			{
+			if (s->tls_session_ticket_ext_cb &&
+			    !s->tls_session_ticket_ext_cb(s, data, size, s->tls_session_ticket_ext_cb_arg))
+				{
+				*al = TLS1_AD_INTERNAL_ERROR;
+				return 0;
+				}
+			}
 		else if (type == TLSEXT_TYPE_renegotiate)
 			{
 			if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
@@ -578,9 +960,9 @@
 			}
 
 		/* session ticket processed earlier */
-
-		data+=size;		
+		data+=size;
 		}
+				
 	*p = data;
 
 	ri_check:
@@ -634,8 +1016,46 @@
 				}
 			tlsext_servername = 1;   
 			}
+
+#ifndef OPENSSL_NO_EC
+		else if (type == TLSEXT_TYPE_ec_point_formats &&
+	             s->version != DTLS1_VERSION)
+			{
+			unsigned char *sdata = data;
+			int ecpointformatlist_length = *(sdata++);
+
+			if (ecpointformatlist_length != size - 1)
+				{
+				*al = TLS1_AD_DECODE_ERROR;
+				return 0;
+				}
+			s->session->tlsext_ecpointformatlist_length = 0;
+			if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist);
+			if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
+				{
+				*al = TLS1_AD_INTERNAL_ERROR;
+				return 0;
+				}
+			s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
+			memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
+#if 0
+			fprintf(stderr,"ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist ");
+			sdata = s->session->tlsext_ecpointformatlist;
+			for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
+				fprintf(stderr,"%i ",*(sdata++));
+			fprintf(stderr,"\n");
+#endif
+			}
+#endif /* OPENSSL_NO_EC */
+
 		else if (type == TLSEXT_TYPE_session_ticket)
 			{
+			if (s->tls_session_ticket_ext_cb &&
+			    !s->tls_session_ticket_ext_cb(s, data, size, s->tls_session_ticket_ext_cb_arg))
+				{
+				*al = TLS1_AD_INTERNAL_ERROR;
+				return 0;
+				}
 			if ((SSL_get_options(s) & SSL_OP_NO_TICKET)
 				|| (size > 0))
 				{
@@ -644,6 +1064,38 @@
 				}
 			s->tlsext_ticket_expected = 1;
 			}
+#ifdef TLSEXT_TYPE_opaque_prf_input
+		else if (type == TLSEXT_TYPE_opaque_prf_input &&
+	             s->version != DTLS1_VERSION)
+			{
+			unsigned char *sdata = data;
+
+			if (size < 2)
+				{
+				*al = SSL_AD_DECODE_ERROR;
+				return 0;
+				}
+			n2s(sdata, s->s3->server_opaque_prf_input_len);
+			if (s->s3->server_opaque_prf_input_len != size - 2)
+				{
+				*al = SSL_AD_DECODE_ERROR;
+				return 0;
+				}
+			
+			if (s->s3->server_opaque_prf_input != NULL) /* shouldn't really happen */
+				OPENSSL_free(s->s3->server_opaque_prf_input);
+			if (s->s3->server_opaque_prf_input_len == 0)
+				s->s3->server_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
+			else
+				s->s3->server_opaque_prf_input = BUF_memdup(sdata, s->s3->server_opaque_prf_input_len);
+
+			if (s->s3->server_opaque_prf_input == NULL)
+				{
+				*al = TLS1_AD_INTERNAL_ERROR;
+				return 0;
+				}
+			}
+#endif
 		else if (type == TLSEXT_TYPE_status_request &&
 		         s->version != DTLS1_VERSION)
 			{
@@ -718,11 +1170,142 @@
 	return 1;
 	}
 
+
+int ssl_prepare_clienthello_tlsext(SSL *s)
+	{
+#ifndef OPENSSL_NO_EC
+	/* If we are client and using an elliptic curve cryptography cipher suite, send the point formats 
+	 * and elliptic curves we support.
+	 */
+	int using_ecc = 0;
+	int i;
+	unsigned char *j;
+	unsigned long alg_k, alg_a;
+	STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
+
+	for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++)
+		{
+		SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
+
+		alg_k = c->algorithm_mkey;
+		alg_a = c->algorithm_auth;
+		if ((alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe) || (alg_a & SSL_aECDSA)))
+			{
+			using_ecc = 1;
+			break;
+			}
+		}
+	using_ecc = using_ecc && (s->version == TLS1_VERSION);
+	if (using_ecc)
+		{
+		if (s->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->tlsext_ecpointformatlist);
+		if ((s->tlsext_ecpointformatlist = OPENSSL_malloc(3)) == NULL)
+			{
+			SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
+			return -1;
+			}
+		s->tlsext_ecpointformatlist_length = 3;
+		s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed;
+		s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
+		s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
+
+		/* we support all named elliptic curves in draft-ietf-tls-ecc-12 */
+		if (s->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->tlsext_ellipticcurvelist);
+		s->tlsext_ellipticcurvelist_length = sizeof(nid_list)/sizeof(nid_list[0]) * 2;
+		if ((s->tlsext_ellipticcurvelist = OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL)
+			{
+			s->tlsext_ellipticcurvelist_length = 0;
+			SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
+			return -1;
+			}
+		for (i = 1, j = s->tlsext_ellipticcurvelist; (unsigned int)i <=
+				sizeof(nid_list)/sizeof(nid_list[0]); i++)
+			s2n(i,j);
+		}
+#endif /* OPENSSL_NO_EC */
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+ 	{
+		int r = 1;
+	
+		if (s->ctx->tlsext_opaque_prf_input_callback != 0)
+			{
+			r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, s->ctx->tlsext_opaque_prf_input_callback_arg);
+			if (!r)
+				return -1;
+			}
+
+		if (s->tlsext_opaque_prf_input != NULL)
+			{
+			if (s->s3->client_opaque_prf_input != NULL) /* shouldn't really happen */
+				OPENSSL_free(s->s3->client_opaque_prf_input);
+
+			if (s->tlsext_opaque_prf_input_len == 0)
+				s->s3->client_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
+			else
+				s->s3->client_opaque_prf_input = BUF_memdup(s->tlsext_opaque_prf_input, s->tlsext_opaque_prf_input_len);
+			if (s->s3->client_opaque_prf_input == NULL)
+				{
+				SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
+				return -1;
+				}
+			s->s3->client_opaque_prf_input_len = s->tlsext_opaque_prf_input_len;
+			}
+
+		if (r == 2)
+			/* at callback's request, insist on receiving an appropriate server opaque PRF input */
+			s->s3->server_opaque_prf_input_len = s->tlsext_opaque_prf_input_len;
+	}
+#endif
+
+	return 1;
+	}
+
+int ssl_prepare_serverhello_tlsext(SSL *s)
+	{
+#ifndef OPENSSL_NO_EC
+	/* If we are server and using an ECC cipher suite, send the point formats we support 
+	 * if the client sent us an ECPointsFormat extension.  Note that the server is not
+	 * supposed to send an EllipticCurves extension.
+	 */
+
+	unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+	unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+	int using_ecc = (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA);
+	using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
+	
+	if (using_ecc)
+		{
+		if (s->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->tlsext_ecpointformatlist);
+		if ((s->tlsext_ecpointformatlist = OPENSSL_malloc(3)) == NULL)
+			{
+			SSLerr(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
+			return -1;
+			}
+		s->tlsext_ecpointformatlist_length = 3;
+		s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed;
+		s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
+		s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
+		}
+#endif /* OPENSSL_NO_EC */
+
+	return 1;
+	}
+
 int ssl_check_clienthello_tlsext(SSL *s)
 	{
 	int ret=SSL_TLSEXT_ERR_NOACK;
 	int al = SSL_AD_UNRECOGNIZED_NAME;
 
+#ifndef OPENSSL_NO_EC
+	/* The handling of the ECPointFormats extension is done elsewhere, namely in 
+	 * ssl3_choose_cipher in s3_lib.c.
+	 */
+	/* The handling of the EllipticCurves extension is done elsewhere, namely in 
+	 * ssl3_choose_cipher in s3_lib.c.
+	 */
+#endif
+
 	if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) 
 		ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg);
 	else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) 		
@@ -732,7 +1315,7 @@
  	 * Note: this must be called after servername callbacks in case 
  	 * the certificate has changed.
  	 */
-	if ((s->tlsext_status_type != -1) && s->ctx->tlsext_status_cb)
+	if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb)
 		{
 		int r;
 		r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
@@ -758,7 +1341,65 @@
 		}
 	else
 		s->tlsext_status_expected = 0;
-	err:
+
+#ifdef TLSEXT_TYPE_opaque_prf_input
+ 	{
+		/* This sort of belongs into ssl_prepare_serverhello_tlsext(),
+		 * but we might be sending an alert in response to the client hello,
+		 * so this has to happen here in ssl_check_clienthello_tlsext(). */
+
+		int r = 1;
+	
+		if (s->ctx->tlsext_opaque_prf_input_callback != 0)
+			{
+			r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, s->ctx->tlsext_opaque_prf_input_callback_arg);
+			if (!r)
+				{
+				ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+				al = SSL_AD_INTERNAL_ERROR;
+				goto err;
+				}
+			}
+
+		if (s->s3->server_opaque_prf_input != NULL) /* shouldn't really happen */
+			OPENSSL_free(s->s3->server_opaque_prf_input);
+		s->s3->server_opaque_prf_input = NULL;
+
+		if (s->tlsext_opaque_prf_input != NULL)
+			{
+			if (s->s3->client_opaque_prf_input != NULL &&
+				s->s3->client_opaque_prf_input_len == s->tlsext_opaque_prf_input_len)
+				{
+				/* can only use this extension if we have a server opaque PRF input
+				 * of the same length as the client opaque PRF input! */
+
+				if (s->tlsext_opaque_prf_input_len == 0)
+					s->s3->server_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte just to get non-NULL */
+				else
+					s->s3->server_opaque_prf_input = BUF_memdup(s->tlsext_opaque_prf_input, s->tlsext_opaque_prf_input_len);
+				if (s->s3->server_opaque_prf_input == NULL)
+					{
+					ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+					al = SSL_AD_INTERNAL_ERROR;
+					goto err;
+					}
+				s->s3->server_opaque_prf_input_len = s->tlsext_opaque_prf_input_len;
+				}
+			}
+
+		if (r == 2 && s->s3->server_opaque_prf_input == NULL)
+			{
+			/* The callback wants to enforce use of the extension,
+			 * but we can't do that with the client opaque PRF input;
+			 * abort the handshake.
+			 */
+			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+			al = SSL_AD_HANDSHAKE_FAILURE;
+			}
+	}
+
+#endif
+ err:
 	switch (ret)
 		{
 		case SSL_TLSEXT_ERR_ALERT_FATAL:
@@ -781,16 +1422,75 @@
 	int ret=SSL_TLSEXT_ERR_NOACK;
 	int al = SSL_AD_UNRECOGNIZED_NAME;
 
+#ifndef OPENSSL_NO_EC
+	/* If we are client and using an elliptic curve cryptography cipher suite, then server
+	 * must return a an EC point formats lists containing uncompressed.
+	 */
+	unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+	unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+	if ((s->tlsext_ecpointformatlist != NULL) && (s->tlsext_ecpointformatlist_length > 0) && 
+	    ((alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA)))
+		{
+		/* we are using an ECC cipher */
+		size_t i;
+		unsigned char *list;
+		int found_uncompressed = 0;
+		if ((s->session->tlsext_ecpointformatlist == NULL) || (s->session->tlsext_ecpointformatlist_length == 0))
+			{
+			SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT,SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
+			return -1;
+			}
+		list = s->session->tlsext_ecpointformatlist;
+		for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
+			{
+			if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed)
+				{
+				found_uncompressed = 1;
+				break;
+				}
+			}
+		if (!found_uncompressed)
+			{
+			SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT,SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
+			return -1;
+			}
+		}
+	ret = SSL_TLSEXT_ERR_OK;
+#endif /* OPENSSL_NO_EC */
+
 	if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) 
 		ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg);
 	else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) 		
 		ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg);
 
+#ifdef TLSEXT_TYPE_opaque_prf_input
+	if (s->s3->server_opaque_prf_input_len > 0)
+		{
+		/* This case may indicate that we, as a client, want to insist on using opaque PRF inputs.
+		 * So first verify that we really have a value from the server too. */
+
+		if (s->s3->server_opaque_prf_input == NULL)
+			{
+			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+			al = SSL_AD_HANDSHAKE_FAILURE;
+			}
+		
+		/* Anytime the server *has* sent an opaque PRF input, we need to check
+		 * that we have a client opaque PRF input of the same size. */
+		if (s->s3->client_opaque_prf_input == NULL ||
+		    s->s3->client_opaque_prf_input_len != s->s3->server_opaque_prf_input_len)
+			{
+			ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+			al = SSL_AD_ILLEGAL_PARAMETER;
+			}
+		}
+#endif
+
 	/* If we've requested certificate status and we wont get one
  	 * tell the callback
  	 */
 	if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected)
-			&& s->ctx->tlsext_status_cb)
+			&& s->ctx && s->ctx->tlsext_status_cb)
 		{
 		int r;
 		/* Set resp to NULL, resplen to -1 so callback knows
@@ -885,6 +1585,11 @@
 			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 1;
 			/* If zero length note client will accept a ticket
  			 * and indicate cache miss to trigger full handshake
  			 */
@@ -893,6 +1598,15 @@
 				s->tlsext_ticket_expected = 1;
 				return 0;	/* Cache miss */
 				}
+			if (s->tls_session_secret_cb)
+				{
+				/* Indicate cache miss here and instead of
+				 * generating the session from ticket now,
+				 * trigger abbreviated handshake based on
+				 * external mechanism to calculate the master
+				 * secret later. */
+				return 0;
+				}
 			return tls_decrypt_ticket(s, p, size, session_id, len,
 									ret);
 			}
@@ -945,6 +1659,11 @@
  	 * integrity checks on ticket.
  	 */
 	mlen = HMAC_size(&hctx);
+	if (mlen < 0)
+		{
+		EVP_CIPHER_CTX_cleanup(&ctx);
+		return -1;
+		}
 	eticklen -= mlen;
 	/* Check HMAC of encrypted ticket */
 	HMAC_Update(&hctx, etick, eticklen);
diff --git a/ssl/t1_meth.c b/ssl/t1_meth.c
index f5d8df6..6ce7c0b 100644
--- a/ssl/t1_meth.c
+++ b/ssl/t1_meth.c
@@ -60,8 +60,8 @@
 #include <openssl/objects.h>
 #include "ssl_locl.h"
 
-static SSL_METHOD *tls1_get_method(int ver);
-static SSL_METHOD *tls1_get_method(int ver)
+static const SSL_METHOD *tls1_get_method(int ver);
+static const SSL_METHOD *tls1_get_method(int ver)
 	{
 	if (ver == TLS1_VERSION)
 		return(TLSv1_method());
diff --git a/ssl/t1_srvr.c b/ssl/t1_srvr.c
index b75636a..42525e9 100644
--- a/ssl/t1_srvr.c
+++ b/ssl/t1_srvr.c
@@ -64,8 +64,8 @@
 #include <openssl/evp.h>
 #include <openssl/x509.h>
 
-static SSL_METHOD *tls1_get_server_method(int ver);
-static SSL_METHOD *tls1_get_server_method(int ver)
+static const SSL_METHOD *tls1_get_server_method(int ver);
+static const SSL_METHOD *tls1_get_server_method(int ver)
 	{
 	if (ver == TLS1_VERSION)
 		return(TLSv1_server_method());
diff --git a/ssl/tls1.h b/ssl/tls1.h
index afe4807..b3cc8f0 100644
--- a/ssl/tls1.h
+++ b/ssl/tls1.h
@@ -56,6 +56,59 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
+ * Copyright (c) 1998-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
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
  *
  * Portions of the attached software ("Contribution") are developed by 
@@ -68,6 +121,32 @@
  * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
  *
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 #ifndef HEADER_TLS1_H 
 #define HEADER_TLS1_H 
@@ -104,16 +183,23 @@
 #define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114
 #define TLS1_AD_UNKNOWN_PSK_IDENTITY	115	/* fatal */
 
-/* ExtensionType values from RFC 3546 */
+/* ExtensionType values from RFC3546 / RFC4366 */
 #define TLSEXT_TYPE_server_name			0
 #define TLSEXT_TYPE_max_fragment_length		1
 #define TLSEXT_TYPE_client_certificate_url	2
 #define TLSEXT_TYPE_trusted_ca_keys		3
 #define TLSEXT_TYPE_truncated_hmac		4
 #define TLSEXT_TYPE_status_request		5
+/* ExtensionType values from RFC4492 */
 #define TLSEXT_TYPE_elliptic_curves		10
 #define TLSEXT_TYPE_ec_point_formats		11
 #define TLSEXT_TYPE_session_ticket		35
+/* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */
+#if 0 /* will have to be provided externally for now ,
+       * i.e. build with -DTLSEXT_TYPE_opaque_prf_input=38183
+       * using whatever extension number you'd like to try */
+# define TLSEXT_TYPE_opaque_prf_input		?? */
+#endif
 
 /* Temporary extension type */
 #define TLSEXT_TYPE_renegotiate                 0xff01
@@ -123,6 +209,13 @@
 /* status request value from RFC 3546 */
 #define TLSEXT_STATUSTYPE_ocsp 1
 
+/* ECPointFormat values from draft-ietf-tls-ecc-12 */
+#define TLSEXT_ECPOINTFORMAT_first			0
+#define TLSEXT_ECPOINTFORMAT_uncompressed		0
+#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime	1
+#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2	2
+#define TLSEXT_ECPOINTFORMAT_last			2
+
 #ifndef OPENSSL_NO_TLSEXT
 
 #define TLSEXT_MAXLEN_host_name 255
@@ -182,17 +275,31 @@
 #define SSL_CTX_set_tlsext_status_arg(ssl, arg) \
 SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)arg)
 
+#define SSL_set_tlsext_opaque_prf_input(s, src, len) \
+SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT, len, src)
+#define SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) \
+SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB, (void (*)(void))cb)
+#define SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) \
+SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg)
+
 #define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \
 SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
 
 #endif
 
-/* Additional TLS ciphersuites from draft-ietf-tls-56-bit-ciphersuites-00.txt
+/* PSK ciphersuites from 4279 */
+#define TLS1_CK_PSK_WITH_RC4_128_SHA                    0x0300008A
+#define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA               0x0300008B
+#define TLS1_CK_PSK_WITH_AES_128_CBC_SHA                0x0300008C
+#define TLS1_CK_PSK_WITH_AES_256_CBC_SHA                0x0300008D
+
+/* Additional TLS ciphersuites from expired Internet Draft
+ * draft-ietf-tls-56-bit-ciphersuites-01.txt
  * (available if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see
  * s3_lib.c).  We actually treat them like SSL 3.0 ciphers, which we probably
- * shouldn't. */
-#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5		0x03000060
-#define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5	0x03000061
+ * shouldn't.  Note that the first two are actually not in the IDs. */
+#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5		0x03000060 /* not in ID */
+#define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5	0x03000061 /* not in ID */
 #define TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA		0x03000062
 #define TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA	0x03000063
 #define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA		0x03000064
@@ -330,6 +437,12 @@
 #define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA         "AECDH-AES128-SHA"
 #define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA         "AECDH-AES256-SHA"
 
+/* PSK ciphersuites from RFC 4279 */
+#define TLS1_TXT_PSK_WITH_RC4_128_SHA			"PSK-RC4-SHA"
+#define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA		"PSK-3DES-EDE-CBC-SHA"
+#define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA		"PSK-AES128-CBC-SHA"
+#define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA		"PSK-AES256-CBC-SHA"
+
 /* Camellia ciphersuites from RFC4132 */
 #define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA		"CAMELLIA128-SHA"
 #define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA	"DH-DSS-CAMELLIA128-SHA"
@@ -353,6 +466,7 @@
 #define TLS1_TXT_DHE_RSA_WITH_SEED_SHA                  "DHE-RSA-SEED-SHA"
 #define TLS1_TXT_ADH_WITH_SEED_SHA                      "ADH-SEED-SHA"
 
+
 #define TLS_CT_RSA_SIGN			1
 #define TLS_CT_DSS_SIGN			2
 #define TLS_CT_RSA_FIXED_DH		3
@@ -360,7 +474,11 @@
 #define TLS_CT_ECDSA_SIGN		64
 #define TLS_CT_RSA_FIXED_ECDH		65
 #define TLS_CT_ECDSA_FIXED_ECDH 	66
-#define TLS_CT_NUMBER			7
+#define TLS_CT_GOST94_SIGN		21
+#define TLS_CT_GOST01_SIGN		22
+/* when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see
+ * comment there) */
+#define TLS_CT_NUMBER			9
 
 #define TLS1_FINISH_MAC_LENGTH		12
 
@@ -401,10 +519,14 @@
 #define TLS_MD_MASTER_SECRET_CONST    "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"  /*master secret*/
 #endif
 
+/* TLS Session Ticket extension struct */
+struct tls_session_ticket_ext_st
+	{
+	unsigned short length;
+	void *data;
+	};
+
 #ifdef  __cplusplus
 }
 #endif
 #endif
-
-
-