aboutsummaryrefslogtreecommitdiff
path: root/openssl/engines
diff options
context:
space:
mode:
Diffstat (limited to 'openssl/engines')
-rw-r--r--openssl/engines/Makefile301
-rw-r--r--openssl/engines/e_4758cca.c994
-rw-r--r--openssl/engines/e_4758cca.ec1
-rw-r--r--openssl/engines/e_4758cca_err.c153
-rw-r--r--openssl/engines/e_4758cca_err.h97
-rw-r--r--openssl/engines/e_aep.c1144
-rw-r--r--openssl/engines/e_aep.ec1
-rw-r--r--openssl/engines/e_aep_err.c161
-rw-r--r--openssl/engines/e_aep_err.h105
-rw-r--r--openssl/engines/e_atalla.c607
-rw-r--r--openssl/engines/e_atalla.ec1
-rw-r--r--openssl/engines/e_atalla_err.c149
-rw-r--r--openssl/engines/e_atalla_err.h93
-rw-r--r--openssl/engines/e_capi.c1781
-rw-r--r--openssl/engines/e_capi.ec1
-rw-r--r--openssl/engines/e_capi_err.c183
-rw-r--r--openssl/engines/e_capi_err.h123
-rw-r--r--openssl/engines/e_chil.c1368
-rw-r--r--openssl/engines/e_chil.ec1
-rw-r--r--openssl/engines/e_chil_err.c160
-rw-r--r--openssl/engines/e_chil_err.h104
-rw-r--r--openssl/engines/e_cswift.c1131
-rw-r--r--openssl/engines/e_cswift.ec1
-rw-r--r--openssl/engines/e_cswift_err.c154
-rw-r--r--openssl/engines/e_cswift_err.h98
-rw-r--r--openssl/engines/e_gmp.c476
-rw-r--r--openssl/engines/e_gmp.ec1
-rw-r--r--openssl/engines/e_gmp_err.c141
-rw-r--r--openssl/engines/e_gmp_err.h85
-rw-r--r--openssl/engines/e_nuron.c434
-rw-r--r--openssl/engines/e_nuron.ec1
-rw-r--r--openssl/engines/e_nuron_err.c146
-rw-r--r--openssl/engines/e_nuron_err.h90
-rw-r--r--openssl/engines/e_sureware.c1057
-rw-r--r--openssl/engines/e_sureware.ec1
-rw-r--r--openssl/engines/e_sureware_err.c158
-rw-r--r--openssl/engines/e_sureware_err.h102
-rw-r--r--openssl/engines/e_ubsec.c1070
-rw-r--r--openssl/engines/e_ubsec.ec1
-rw-r--r--openssl/engines/e_ubsec_err.c157
-rw-r--r--openssl/engines/e_ubsec_err.h101
-rw-r--r--openssl/engines/engine_vector.mar24
-rw-r--r--openssl/engines/makeengines.com903
-rw-r--r--openssl/engines/vendor_defns/aep.h178
-rw-r--r--openssl/engines/vendor_defns/atalla.h48
-rw-r--r--openssl/engines/vendor_defns/cswift.h234
-rw-r--r--openssl/engines/vendor_defns/hw_4758_cca.h149
-rw-r--r--openssl/engines/vendor_defns/hw_ubsec.h100
-rw-r--r--openssl/engines/vendor_defns/hwcryptohook.h486
-rw-r--r--openssl/engines/vendor_defns/sureware.h239
50 files changed, 15294 insertions, 0 deletions
diff --git a/openssl/engines/Makefile b/openssl/engines/Makefile
new file mode 100644
index 000000000..002d40c96
--- /dev/null
+++ b/openssl/engines/Makefile
@@ -0,0 +1,301 @@
+#
+# OpenSSL/engines/Makefile
+#
+
+DIR= engines
+TOP= ..
+CC= cc
+INCLUDES= -I../include
+CFLAG=-g
+MAKEFILE= Makefile
+AR= ar r
+
+PEX_LIBS=
+EX_LIBS=
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile engines.com install.com engine_vector.mar
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBNAMES= 4758cca aep atalla cswift gmp chil nuron sureware ubsec capi
+
+LIBSRC= e_4758cca.c \
+ e_aep.c \
+ e_atalla.c \
+ e_cswift.c \
+ e_gmp.c \
+ e_chil.c \
+ e_nuron.c \
+ e_sureware.c \
+ e_ubsec.c \
+ e_capi.c
+LIBOBJ= e_4758cca.o \
+ e_aep.o \
+ e_atalla.o \
+ e_cswift.o \
+ e_gmp.o \
+ e_chil.o \
+ e_nuron.o \
+ e_sureware.o \
+ e_ubsec.o \
+ e_capi.o
+
+SRC= $(LIBSRC)
+
+EXHEADER=
+HEADER= e_4758cca_err.c e_4758cca_err.h \
+ e_aep_err.c e_aep_err.h \
+ e_atalla_err.c e_atalla_err.h \
+ e_cswift_err.c e_cswift_err.h \
+ e_gmp_err.c e_gmp_err.h \
+ e_chil_err.c e_chil_err.h \
+ e_nuron_err.c e_nuron_err.h \
+ e_sureware_err.c e_sureware_err.h \
+ e_ubsec_err.c e_ubsec_err.h \
+ e_capi_err.c e_capi_err.h
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+top:
+ (cd ..; $(MAKE) DIRS=$(DIR) all)
+
+all: lib
+
+lib: $(LIBOBJ)
+ @if [ -n "$(SHARED_LIBS)" ]; then \
+ set -e; \
+ for l in $(LIBNAMES); do \
+ $(MAKE) -f ../Makefile.shared -e \
+ LIBNAME=$$l LIBEXTRAS=e_$$l.o \
+ LIBDEPS='-L.. -lcrypto $(EX_LIBS)' \
+ link_o.$(SHLIB_TARGET); \
+ done; \
+ else \
+ $(AR) $(LIB) $(LIBOBJ); \
+ $(RANLIB) $(LIB) || echo Never mind.; \
+ fi; \
+ touch lib
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+
+# XXXXX This currently only works on systems that use .so as suffix
+# for shared libraries as well as for Cygwin which uses the
+# dlfcn_name_converter and therefore stores the engines with .so suffix, too.
+# XXXXX This was extended to HP-UX dl targets, which use .sl suffix.
+install:
+ @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+ @if [ -n "$(SHARED_LIBS)" ]; then \
+ set -e; \
+ for l in $(LIBNAMES); do \
+ ( echo installing $$l; \
+ if [ "$(PLATFORM)" != "Cygwin" ]; then \
+ case "$(CFLAGS)" in \
+ *DSO_DLFCN*) sfx="so";; \
+ *DSO_DL*) sfx="sl";; \
+ *) sfx="bad";; \
+ esac; \
+ cp lib$$l.$$sfx $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/lib$$l.$$sfx.new; \
+ else \
+ sfx="so"; \
+ cp cyg$$l.dll $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/lib$$l.$$sfx.new; \
+ fi; \
+ chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/lib$$l.$$sfx.new; \
+ mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/lib$$l.$$sfx.new $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/lib$$l.$$sfx ); \
+ done; \
+ fi
+
+tags:
+ ctags $(SRC)
+
+errors:
+ set -e; for l in $(LIBNAMES); do \
+ $(PERL) ../util/mkerr.pl -conf e_$$l.ec \
+ -nostatic -staticloader -write e_$$l.c; \
+ done
+
+tests:
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ @if [ -z "$(THIS)" ]; then \
+ $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
+ else \
+ $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC); \
+ 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
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+e_4758cca.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_4758cca.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_4758cca.o: ../include/openssl/crypto.h ../include/openssl/dso.h
+e_4758cca.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+e_4758cca.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+e_4758cca.o: ../include/openssl/engine.h ../include/openssl/err.h
+e_4758cca.o: ../include/openssl/evp.h ../include/openssl/fips.h
+e_4758cca.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+e_4758cca.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+e_4758cca.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+e_4758cca.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+e_4758cca.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+e_4758cca.o: ../include/openssl/sha.h ../include/openssl/stack.h
+e_4758cca.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
+e_4758cca.o: ../include/openssl/x509_vfy.h e_4758cca.c e_4758cca_err.c
+e_4758cca.o: e_4758cca_err.h vendor_defns/hw_4758_cca.h
+e_aep.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_aep.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_aep.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+e_aep.o: ../include/openssl/dsa.h ../include/openssl/dso.h
+e_aep.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+e_aep.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+e_aep.o: ../include/openssl/engine.h ../include/openssl/err.h
+e_aep.o: ../include/openssl/evp.h ../include/openssl/fips.h
+e_aep.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+e_aep.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+e_aep.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+e_aep.o: ../include/openssl/pkcs7.h ../include/openssl/rsa.h
+e_aep.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+e_aep.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+e_aep.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h e_aep.c
+e_aep.o: e_aep_err.c e_aep_err.h vendor_defns/aep.h
+e_atalla.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_atalla.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_atalla.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+e_atalla.o: ../include/openssl/dsa.h ../include/openssl/dso.h
+e_atalla.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+e_atalla.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+e_atalla.o: ../include/openssl/engine.h ../include/openssl/err.h
+e_atalla.o: ../include/openssl/evp.h ../include/openssl/fips.h
+e_atalla.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+e_atalla.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+e_atalla.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+e_atalla.o: ../include/openssl/pkcs7.h ../include/openssl/rsa.h
+e_atalla.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+e_atalla.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+e_atalla.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h e_atalla.c
+e_atalla.o: e_atalla_err.c e_atalla_err.h vendor_defns/atalla.h
+e_capi.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_capi.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_capi.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+e_capi.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+e_capi.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+e_capi.o: ../include/openssl/evp.h ../include/openssl/fips.h
+e_capi.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+e_capi.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+e_capi.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+e_capi.o: ../include/openssl/pkcs7.h ../include/openssl/rsa.h
+e_capi.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+e_capi.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+e_capi.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h e_capi.c
+e_chil.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_chil.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_chil.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+e_chil.o: ../include/openssl/dso.h ../include/openssl/e_os2.h
+e_chil.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+e_chil.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+e_chil.o: ../include/openssl/err.h ../include/openssl/evp.h
+e_chil.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+e_chil.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+e_chil.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+e_chil.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+e_chil.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+e_chil.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+e_chil.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+e_chil.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+e_chil.o: ../include/openssl/ui.h ../include/openssl/x509.h
+e_chil.o: ../include/openssl/x509_vfy.h e_chil.c e_chil_err.c e_chil_err.h
+e_chil.o: vendor_defns/hwcryptohook.h
+e_cswift.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_cswift.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_cswift.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+e_cswift.o: ../include/openssl/dsa.h ../include/openssl/dso.h
+e_cswift.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+e_cswift.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+e_cswift.o: ../include/openssl/engine.h ../include/openssl/err.h
+e_cswift.o: ../include/openssl/evp.h ../include/openssl/fips.h
+e_cswift.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+e_cswift.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+e_cswift.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+e_cswift.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+e_cswift.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+e_cswift.o: ../include/openssl/sha.h ../include/openssl/stack.h
+e_cswift.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
+e_cswift.o: ../include/openssl/x509_vfy.h e_cswift.c e_cswift_err.c
+e_cswift.o: e_cswift_err.h vendor_defns/cswift.h
+e_gmp.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_gmp.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_gmp.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+e_gmp.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+e_gmp.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+e_gmp.o: ../include/openssl/evp.h ../include/openssl/fips.h
+e_gmp.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+e_gmp.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+e_gmp.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+e_gmp.o: ../include/openssl/pkcs7.h ../include/openssl/rsa.h
+e_gmp.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+e_gmp.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+e_gmp.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h e_gmp.c
+e_nuron.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_nuron.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_nuron.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+e_nuron.o: ../include/openssl/dsa.h ../include/openssl/dso.h
+e_nuron.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+e_nuron.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+e_nuron.o: ../include/openssl/engine.h ../include/openssl/err.h
+e_nuron.o: ../include/openssl/evp.h ../include/openssl/fips.h
+e_nuron.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+e_nuron.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+e_nuron.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+e_nuron.o: ../include/openssl/pkcs7.h ../include/openssl/rsa.h
+e_nuron.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+e_nuron.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+e_nuron.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h e_nuron.c
+e_nuron.o: e_nuron_err.c e_nuron_err.h
+e_sureware.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_sureware.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_sureware.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+e_sureware.o: ../include/openssl/dsa.h ../include/openssl/dso.h
+e_sureware.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+e_sureware.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+e_sureware.o: ../include/openssl/engine.h ../include/openssl/err.h
+e_sureware.o: ../include/openssl/evp.h ../include/openssl/fips.h
+e_sureware.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+e_sureware.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+e_sureware.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+e_sureware.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+e_sureware.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+e_sureware.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+e_sureware.o: ../include/openssl/sha.h ../include/openssl/stack.h
+e_sureware.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
+e_sureware.o: ../include/openssl/x509_vfy.h e_sureware.c e_sureware_err.c
+e_sureware.o: e_sureware_err.h vendor_defns/sureware.h
+e_ubsec.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+e_ubsec.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+e_ubsec.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+e_ubsec.o: ../include/openssl/dsa.h ../include/openssl/dso.h
+e_ubsec.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+e_ubsec.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+e_ubsec.o: ../include/openssl/engine.h ../include/openssl/err.h
+e_ubsec.o: ../include/openssl/evp.h ../include/openssl/fips.h
+e_ubsec.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+e_ubsec.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+e_ubsec.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+e_ubsec.o: ../include/openssl/pkcs7.h ../include/openssl/rsa.h
+e_ubsec.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+e_ubsec.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+e_ubsec.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h e_ubsec.c
+e_ubsec.o: e_ubsec_err.c e_ubsec_err.h vendor_defns/hw_ubsec.h
diff --git a/openssl/engines/e_4758cca.c b/openssl/engines/e_4758cca.c
new file mode 100644
index 000000000..0f1dae756
--- /dev/null
+++ b/openssl/engines/e_4758cca.c
@@ -0,0 +1,994 @@
+/* Author: Maurice Gittens <maurice@gittens.nl> */
+/* ====================================================================
+ * Copyright (c) 1999 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/crypto.h>
+#include <openssl/dso.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/engine.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_4758_CCA
+
+#ifdef FLAT_INC
+#include "hw_4758_cca.h"
+#else
+#include "vendor_defns/hw_4758_cca.h"
+#endif
+
+#include "e_4758cca_err.c"
+
+static int ibm_4758_cca_destroy(ENGINE *e);
+static int ibm_4758_cca_init(ENGINE *e);
+static int ibm_4758_cca_finish(ENGINE *e);
+static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+
+/* rsa functions */
+/*---------------*/
+#ifndef OPENSSL_NO_RSA
+static int cca_rsa_pub_enc(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa,int padding);
+static int cca_rsa_priv_dec(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa,int padding);
+static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
+ unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
+static int cca_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
+ unsigned char *sigbuf, unsigned int siglen, const RSA *rsa);
+
+/* utility functions */
+/*-----------------------*/
+static EVP_PKEY *ibm_4758_load_privkey(ENGINE*, const char*,
+ UI_METHOD *ui_method, void *callback_data);
+static EVP_PKEY *ibm_4758_load_pubkey(ENGINE*, const char*,
+ UI_METHOD *ui_method, void *callback_data);
+
+static int getModulusAndExponent(const unsigned char *token, long *exponentLength,
+ unsigned char *exponent, long *modulusLength,
+ long *modulusFieldLength, unsigned char *modulus);
+#endif
+
+/* RAND number functions */
+/*-----------------------*/
+static int cca_get_random_bytes(unsigned char*, int );
+static int cca_random_status(void);
+
+#ifndef OPENSSL_NO_RSA
+static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
+ int idx,long argl, void *argp);
+#endif
+
+/* Function pointers for CCA verbs */
+/*---------------------------------*/
+#ifndef OPENSSL_NO_RSA
+static F_KEYRECORDREAD keyRecordRead;
+static F_DIGITALSIGNATUREGENERATE digitalSignatureGenerate;
+static F_DIGITALSIGNATUREVERIFY digitalSignatureVerify;
+static F_PUBLICKEYEXTRACT publicKeyExtract;
+static F_PKAENCRYPT pkaEncrypt;
+static F_PKADECRYPT pkaDecrypt;
+#endif
+static F_RANDOMNUMBERGENERATE randomNumberGenerate;
+
+/* static variables */
+/*------------------*/
+static const char *CCA4758_LIB_NAME = NULL;
+static const char *get_CCA4758_LIB_NAME(void)
+ {
+ if(CCA4758_LIB_NAME)
+ return CCA4758_LIB_NAME;
+ return CCA_LIB_NAME;
+ }
+static void free_CCA4758_LIB_NAME(void)
+ {
+ if(CCA4758_LIB_NAME)
+ OPENSSL_free((void*)CCA4758_LIB_NAME);
+ CCA4758_LIB_NAME = NULL;
+ }
+static long set_CCA4758_LIB_NAME(const char *name)
+ {
+ free_CCA4758_LIB_NAME();
+ return (((CCA4758_LIB_NAME = BUF_strdup(name)) != NULL) ? 1 : 0);
+ }
+#ifndef OPENSSL_NO_RSA
+static const char* n_keyRecordRead = CSNDKRR;
+static const char* n_digitalSignatureGenerate = CSNDDSG;
+static const char* n_digitalSignatureVerify = CSNDDSV;
+static const char* n_publicKeyExtract = CSNDPKX;
+static const char* n_pkaEncrypt = CSNDPKE;
+static const char* n_pkaDecrypt = CSNDPKD;
+#endif
+static const char* n_randomNumberGenerate = CSNBRNG;
+
+#ifndef OPENSSL_NO_RSA
+static int hndidx = -1;
+#endif
+static DSO *dso = NULL;
+
+/* openssl engine initialization structures */
+/*------------------------------------------*/
+
+#define CCA4758_CMD_SO_PATH ENGINE_CMD_BASE
+static const ENGINE_CMD_DEFN cca4758_cmd_defns[] = {
+ {CCA4758_CMD_SO_PATH,
+ "SO_PATH",
+ "Specifies the path to the '4758cca' shared library",
+ ENGINE_CMD_FLAG_STRING},
+ {0, NULL, NULL, 0}
+ };
+
+#ifndef OPENSSL_NO_RSA
+static RSA_METHOD ibm_4758_cca_rsa =
+ {
+ "IBM 4758 CCA RSA method",
+ cca_rsa_pub_enc,
+ NULL,
+ NULL,
+ cca_rsa_priv_dec,
+ NULL, /*rsa_mod_exp,*/
+ NULL, /*mod_exp_mont,*/
+ NULL, /* init */
+ NULL, /* finish */
+ RSA_FLAG_SIGN_VER, /* flags */
+ NULL, /* app_data */
+ cca_rsa_sign, /* rsa_sign */
+ cca_rsa_verify, /* rsa_verify */
+ NULL /* rsa_keygen */
+ };
+#endif
+
+static RAND_METHOD ibm_4758_cca_rand =
+ {
+ /* "IBM 4758 RAND method", */
+ NULL, /* seed */
+ cca_get_random_bytes, /* get random bytes from the card */
+ NULL, /* cleanup */
+ NULL, /* add */
+ cca_get_random_bytes, /* pseudo rand */
+ cca_random_status, /* status */
+ };
+
+static const char *engine_4758_cca_id = "4758cca";
+static const char *engine_4758_cca_name = "IBM 4758 CCA hardware engine support";
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+/* Compatibility hack, the dynamic library uses this form in the path */
+static const char *engine_4758_cca_id_alt = "4758_cca";
+#endif
+
+/* engine implementation */
+/*-----------------------*/
+static int bind_helper(ENGINE *e)
+ {
+ if(!ENGINE_set_id(e, engine_4758_cca_id) ||
+ !ENGINE_set_name(e, engine_4758_cca_name) ||
+#ifndef OPENSSL_NO_RSA
+ !ENGINE_set_RSA(e, &ibm_4758_cca_rsa) ||
+#endif
+ !ENGINE_set_RAND(e, &ibm_4758_cca_rand) ||
+ !ENGINE_set_destroy_function(e, ibm_4758_cca_destroy) ||
+ !ENGINE_set_init_function(e, ibm_4758_cca_init) ||
+ !ENGINE_set_finish_function(e, ibm_4758_cca_finish) ||
+ !ENGINE_set_ctrl_function(e, ibm_4758_cca_ctrl) ||
+#ifndef OPENSSL_NO_RSA
+ !ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) ||
+ !ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) ||
+#endif
+ !ENGINE_set_cmd_defns(e, cca4758_cmd_defns))
+ return 0;
+ /* Ensure the error handling is set up */
+ ERR_load_CCA4758_strings();
+ return 1;
+ }
+
+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+static ENGINE *engine_4758_cca(void)
+ {
+ ENGINE *ret = ENGINE_new();
+ if(!ret)
+ return NULL;
+ if(!bind_helper(ret))
+ {
+ ENGINE_free(ret);
+ return NULL;
+ }
+ return ret;
+ }
+
+void ENGINE_load_4758cca(void)
+ {
+ ENGINE *e_4758 = engine_4758_cca();
+ if (!e_4758) return;
+ ENGINE_add(e_4758);
+ ENGINE_free(e_4758);
+ ERR_clear_error();
+ }
+#endif
+
+static int ibm_4758_cca_destroy(ENGINE *e)
+ {
+ ERR_unload_CCA4758_strings();
+ free_CCA4758_LIB_NAME();
+ return 1;
+ }
+
+static int ibm_4758_cca_init(ENGINE *e)
+ {
+ if(dso)
+ {
+ CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_ALREADY_LOADED);
+ goto err;
+ }
+
+ dso = DSO_load(NULL, get_CCA4758_LIB_NAME(), NULL, 0);
+ if(!dso)
+ {
+ CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
+ goto err;
+ }
+
+#ifndef OPENSSL_NO_RSA
+ if(!(keyRecordRead = (F_KEYRECORDREAD)
+ DSO_bind_func(dso, n_keyRecordRead)) ||
+ !(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
+ DSO_bind_func(dso, n_randomNumberGenerate)) ||
+ !(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)
+ DSO_bind_func(dso, n_digitalSignatureGenerate)) ||
+ !(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)
+ DSO_bind_func(dso, n_digitalSignatureVerify)) ||
+ !(publicKeyExtract = (F_PUBLICKEYEXTRACT)
+ DSO_bind_func(dso, n_publicKeyExtract)) ||
+ !(pkaEncrypt = (F_PKAENCRYPT)
+ DSO_bind_func(dso, n_pkaEncrypt)) ||
+ !(pkaDecrypt = (F_PKADECRYPT)
+ DSO_bind_func(dso, n_pkaDecrypt)))
+ {
+ CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
+ goto err;
+ }
+#else
+ if(!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
+ DSO_bind_func(dso, n_randomNumberGenerate)))
+ {
+ CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
+ goto err;
+ }
+#endif
+
+#ifndef OPENSSL_NO_RSA
+ hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle",
+ NULL, NULL, cca_ex_free);
+#endif
+
+ return 1;
+err:
+ if(dso)
+ DSO_free(dso);
+ dso = NULL;
+
+#ifndef OPENSSL_NO_RSA
+ keyRecordRead = (F_KEYRECORDREAD)0;
+ digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)0;
+ digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0;
+ publicKeyExtract = (F_PUBLICKEYEXTRACT)0;
+ pkaEncrypt = (F_PKAENCRYPT)0;
+ pkaDecrypt = (F_PKADECRYPT)0;
+#endif
+ randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
+ return 0;
+ }
+
+static int ibm_4758_cca_finish(ENGINE *e)
+ {
+ free_CCA4758_LIB_NAME();
+ if(!dso)
+ {
+ CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
+ CCA4758_R_NOT_LOADED);
+ return 0;
+ }
+ if(!DSO_free(dso))
+ {
+ CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
+ CCA4758_R_UNIT_FAILURE);
+ return 0;
+ }
+ dso = NULL;
+#ifndef OPENSSL_NO_RSA
+ keyRecordRead = (F_KEYRECORDREAD)0;
+ randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
+ digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)0;
+ digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0;
+ publicKeyExtract = (F_PUBLICKEYEXTRACT)0;
+ pkaEncrypt = (F_PKAENCRYPT)0;
+ pkaDecrypt = (F_PKADECRYPT)0;
+#endif
+ randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
+ return 1;
+ }
+
+static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+ {
+ int initialised = ((dso == NULL) ? 0 : 1);
+ switch(cmd)
+ {
+ case CCA4758_CMD_SO_PATH:
+ if(p == NULL)
+ {
+ CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ if(initialised)
+ {
+ CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
+ CCA4758_R_ALREADY_LOADED);
+ return 0;
+ }
+ return set_CCA4758_LIB_NAME((const char *)p);
+ default:
+ break;
+ }
+ CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
+ CCA4758_R_COMMAND_NOT_IMPLEMENTED);
+ return 0;
+ }
+
+#ifndef OPENSSL_NO_RSA
+
+#define MAX_CCA_PKA_TOKEN_SIZE 2500
+
+static EVP_PKEY *ibm_4758_load_privkey(ENGINE* e, const char* key_id,
+ UI_METHOD *ui_method, void *callback_data)
+ {
+ RSA *rtmp = NULL;
+ EVP_PKEY *res = NULL;
+ unsigned char* keyToken = NULL;
+ unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE];
+ long pubKeyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
+ long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
+ long returnCode;
+ long reasonCode;
+ long exitDataLength = 0;
+ long ruleArrayLength = 0;
+ unsigned char exitData[8];
+ unsigned char ruleArray[8];
+ unsigned char keyLabel[64];
+ unsigned long keyLabelLength = strlen(key_id);
+ unsigned char modulus[256];
+ long modulusFieldLength = sizeof(modulus);
+ long modulusLength = 0;
+ unsigned char exponent[256];
+ long exponentLength = sizeof(exponent);
+
+ if (keyLabelLength > sizeof(keyLabel))
+ {
+ CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
+ CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+ return NULL;
+ }
+
+ memset(keyLabel,' ', sizeof(keyLabel));
+ memcpy(keyLabel, key_id, keyLabelLength);
+
+ keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
+ if (!keyToken)
+ {
+ CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ keyRecordRead(&returnCode, &reasonCode, &exitDataLength,
+ exitData, &ruleArrayLength, ruleArray, keyLabel,
+ &keyTokenLength, keyToken+sizeof(long));
+
+ if (returnCode)
+ {
+ CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
+ CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
+ goto err;
+ }
+
+ publicKeyExtract(&returnCode, &reasonCode, &exitDataLength,
+ exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
+ keyToken+sizeof(long), &pubKeyTokenLength, pubKeyToken);
+
+ if (returnCode)
+ {
+ CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
+ CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
+ goto err;
+ }
+
+ if (!getModulusAndExponent(pubKeyToken, &exponentLength,
+ exponent, &modulusLength, &modulusFieldLength,
+ modulus))
+ {
+ CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
+ CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
+ goto err;
+ }
+
+ (*(long*)keyToken) = keyTokenLength;
+ rtmp = RSA_new_method(e);
+ RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
+
+ rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
+ rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
+ rtmp->flags |= RSA_FLAG_EXT_PKEY;
+
+ res = EVP_PKEY_new();
+ EVP_PKEY_assign_RSA(res, rtmp);
+
+ return res;
+err:
+ if (keyToken)
+ OPENSSL_free(keyToken);
+ if (res)
+ EVP_PKEY_free(res);
+ if (rtmp)
+ RSA_free(rtmp);
+ return NULL;
+ }
+
+static EVP_PKEY *ibm_4758_load_pubkey(ENGINE* e, const char* key_id,
+ UI_METHOD *ui_method, void *callback_data)
+ {
+ RSA *rtmp = NULL;
+ EVP_PKEY *res = NULL;
+ unsigned char* keyToken = NULL;
+ long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
+ long returnCode;
+ long reasonCode;
+ long exitDataLength = 0;
+ long ruleArrayLength = 0;
+ unsigned char exitData[8];
+ unsigned char ruleArray[8];
+ unsigned char keyLabel[64];
+ unsigned long keyLabelLength = strlen(key_id);
+ unsigned char modulus[512];
+ long modulusFieldLength = sizeof(modulus);
+ long modulusLength = 0;
+ unsigned char exponent[512];
+ long exponentLength = sizeof(exponent);
+
+ if (keyLabelLength > sizeof(keyLabel))
+ {
+ CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
+ CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+ return NULL;
+ }
+
+ memset(keyLabel,' ', sizeof(keyLabel));
+ memcpy(keyLabel, key_id, keyLabelLength);
+
+ keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
+ if (!keyToken)
+ {
+ CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData,
+ &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength,
+ keyToken+sizeof(long));
+
+ if (returnCode)
+ {
+ CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!getModulusAndExponent(keyToken+sizeof(long), &exponentLength,
+ exponent, &modulusLength, &modulusFieldLength, modulus))
+ {
+ CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
+ CCA4758_R_FAILED_LOADING_PUBLIC_KEY);
+ goto err;
+ }
+
+ (*(long*)keyToken) = keyTokenLength;
+ rtmp = RSA_new_method(e);
+ RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
+ rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
+ rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
+ rtmp->flags |= RSA_FLAG_EXT_PKEY;
+ res = EVP_PKEY_new();
+ EVP_PKEY_assign_RSA(res, rtmp);
+
+ return res;
+err:
+ if (keyToken)
+ OPENSSL_free(keyToken);
+ if (res)
+ EVP_PKEY_free(res);
+ if (rtmp)
+ RSA_free(rtmp);
+ return NULL;
+ }
+
+static int cca_rsa_pub_enc(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa,int padding)
+ {
+ long returnCode;
+ long reasonCode;
+ long lflen = flen;
+ long exitDataLength = 0;
+ unsigned char exitData[8];
+ long ruleArrayLength = 1;
+ unsigned char ruleArray[8] = "PKCS-1.2";
+ long dataStructureLength = 0;
+ unsigned char dataStructure[8];
+ long outputLength = RSA_size(rsa);
+ long keyTokenLength;
+ unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
+
+ keyTokenLength = *(long*)keyToken;
+ keyToken+=sizeof(long);
+
+ pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
+ &ruleArrayLength, ruleArray, &lflen, (unsigned char*)from,
+ &dataStructureLength, dataStructure, &keyTokenLength,
+ keyToken, &outputLength, to);
+
+ if (returnCode || reasonCode)
+ return -(returnCode << 16 | reasonCode);
+ return outputLength;
+ }
+
+static int cca_rsa_priv_dec(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa,int padding)
+ {
+ long returnCode;
+ long reasonCode;
+ long lflen = flen;
+ long exitDataLength = 0;
+ unsigned char exitData[8];
+ long ruleArrayLength = 1;
+ unsigned char ruleArray[8] = "PKCS-1.2";
+ long dataStructureLength = 0;
+ unsigned char dataStructure[8];
+ long outputLength = RSA_size(rsa);
+ long keyTokenLength;
+ unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
+
+ keyTokenLength = *(long*)keyToken;
+ keyToken+=sizeof(long);
+
+ pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
+ &ruleArrayLength, ruleArray, &lflen, (unsigned char*)from,
+ &dataStructureLength, dataStructure, &keyTokenLength,
+ keyToken, &outputLength, to);
+
+ return (returnCode | reasonCode) ? 0 : 1;
+ }
+
+#define SSL_SIG_LEN 36
+
+static int cca_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
+ unsigned char *sigbuf, unsigned int siglen, const RSA *rsa)
+ {
+ long returnCode;
+ long reasonCode;
+ long lsiglen = siglen;
+ long exitDataLength = 0;
+ unsigned char exitData[8];
+ long ruleArrayLength = 1;
+ unsigned char ruleArray[8] = "PKCS-1.1";
+ long keyTokenLength;
+ unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
+ long length = SSL_SIG_LEN;
+ long keyLength ;
+ unsigned char *hashBuffer = NULL;
+ X509_SIG sig;
+ ASN1_TYPE parameter;
+ X509_ALGOR algorithm;
+ ASN1_OCTET_STRING digest;
+
+ keyTokenLength = *(long*)keyToken;
+ keyToken+=sizeof(long);
+
+ if (type == NID_md5 || type == NID_sha1)
+ {
+ sig.algor = &algorithm;
+ algorithm.algorithm = OBJ_nid2obj(type);
+
+ if (!algorithm.algorithm)
+ {
+ CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
+ CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
+ return 0;
+ }
+
+ if (!algorithm.algorithm->length)
+ {
+ CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
+ CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
+ return 0;
+ }
+
+ parameter.type = V_ASN1_NULL;
+ parameter.value.ptr = NULL;
+ algorithm.parameter = &parameter;
+
+ sig.digest = &digest;
+ sig.digest->data = (unsigned char*)m;
+ sig.digest->length = m_len;
+
+ length = i2d_X509_SIG(&sig, NULL);
+ }
+
+ keyLength = RSA_size(rsa);
+
+ if (length - RSA_PKCS1_PADDING > keyLength)
+ {
+ CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
+ CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+ return 0;
+ }
+
+ switch (type)
+ {
+ case NID_md5_sha1 :
+ if (m_len != SSL_SIG_LEN)
+ {
+ CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
+ CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+ return 0;
+ }
+
+ hashBuffer = (unsigned char *)m;
+ length = m_len;
+ break;
+ case NID_md5 :
+ {
+ unsigned char *ptr;
+ ptr = hashBuffer = OPENSSL_malloc(
+ (unsigned int)keyLength+1);
+ if (!hashBuffer)
+ {
+ CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
+ ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ i2d_X509_SIG(&sig, &ptr);
+ }
+ break;
+ case NID_sha1 :
+ {
+ unsigned char *ptr;
+ ptr = hashBuffer = OPENSSL_malloc(
+ (unsigned int)keyLength+1);
+ if (!hashBuffer)
+ {
+ CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
+ ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ i2d_X509_SIG(&sig, &ptr);
+ }
+ break;
+ default:
+ return 0;
+ }
+
+ digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength,
+ exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
+ keyToken, &length, hashBuffer, &lsiglen, sigbuf);
+
+ if (type == NID_sha1 || type == NID_md5)
+ {
+ OPENSSL_cleanse(hashBuffer, keyLength+1);
+ OPENSSL_free(hashBuffer);
+ }
+
+ return ((returnCode || reasonCode) ? 0 : 1);
+ }
+
+#define SSL_SIG_LEN 36
+
+static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
+ unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
+ {
+ long returnCode;
+ long reasonCode;
+ long exitDataLength = 0;
+ unsigned char exitData[8];
+ long ruleArrayLength = 1;
+ unsigned char ruleArray[8] = "PKCS-1.1";
+ long outputLength=256;
+ long outputBitLength;
+ long keyTokenLength;
+ unsigned char *hashBuffer = NULL;
+ unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
+ long length = SSL_SIG_LEN;
+ long keyLength ;
+ X509_SIG sig;
+ ASN1_TYPE parameter;
+ X509_ALGOR algorithm;
+ ASN1_OCTET_STRING digest;
+
+ keyTokenLength = *(long*)keyToken;
+ keyToken+=sizeof(long);
+
+ if (type == NID_md5 || type == NID_sha1)
+ {
+ sig.algor = &algorithm;
+ algorithm.algorithm = OBJ_nid2obj(type);
+
+ if (!algorithm.algorithm)
+ {
+ CCA4758err(CCA4758_F_CCA_RSA_SIGN,
+ CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
+ return 0;
+ }
+
+ if (!algorithm.algorithm->length)
+ {
+ CCA4758err(CCA4758_F_CCA_RSA_SIGN,
+ CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
+ return 0;
+ }
+
+ parameter.type = V_ASN1_NULL;
+ parameter.value.ptr = NULL;
+ algorithm.parameter = &parameter;
+
+ sig.digest = &digest;
+ sig.digest->data = (unsigned char*)m;
+ sig.digest->length = m_len;
+
+ length = i2d_X509_SIG(&sig, NULL);
+ }
+
+ keyLength = RSA_size(rsa);
+
+ if (length - RSA_PKCS1_PADDING > keyLength)
+ {
+ CCA4758err(CCA4758_F_CCA_RSA_SIGN,
+ CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+ return 0;
+ }
+
+ switch (type)
+ {
+ case NID_md5_sha1 :
+ if (m_len != SSL_SIG_LEN)
+ {
+ CCA4758err(CCA4758_F_CCA_RSA_SIGN,
+ CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+ return 0;
+ }
+ hashBuffer = (unsigned char*)m;
+ length = m_len;
+ break;
+ case NID_md5 :
+ {
+ unsigned char *ptr;
+ ptr = hashBuffer = OPENSSL_malloc(
+ (unsigned int)keyLength+1);
+ if (!hashBuffer)
+ {
+ CCA4758err(CCA4758_F_CCA_RSA_SIGN,
+ ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ i2d_X509_SIG(&sig, &ptr);
+ }
+ break;
+ case NID_sha1 :
+ {
+ unsigned char *ptr;
+ ptr = hashBuffer = OPENSSL_malloc(
+ (unsigned int)keyLength+1);
+ if (!hashBuffer)
+ {
+ CCA4758err(CCA4758_F_CCA_RSA_SIGN,
+ ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ i2d_X509_SIG(&sig, &ptr);
+ }
+ break;
+ default:
+ return 0;
+ }
+
+ digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength,
+ exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
+ keyToken, &length, hashBuffer, &outputLength, &outputBitLength,
+ sigret);
+
+ if (type == NID_sha1 || type == NID_md5)
+ {
+ OPENSSL_cleanse(hashBuffer, keyLength+1);
+ OPENSSL_free(hashBuffer);
+ }
+
+ *siglen = outputLength;
+
+ return ((returnCode || reasonCode) ? 0 : 1);
+ }
+
+static int getModulusAndExponent(const unsigned char*token, long *exponentLength,
+ unsigned char *exponent, long *modulusLength, long *modulusFieldLength,
+ unsigned char *modulus)
+ {
+ unsigned long len;
+
+ if (*token++ != (char)0x1E) /* internal PKA token? */
+ return 0;
+
+ if (*token++) /* token version must be zero */
+ return 0;
+
+ len = *token++;
+ len = len << 8;
+ len |= (unsigned char)*token++;
+
+ token += 4; /* skip reserved bytes */
+
+ if (*token++ == (char)0x04)
+ {
+ if (*token++) /* token version must be zero */
+ return 0;
+
+ len = *token++;
+ len = len << 8;
+ len |= (unsigned char)*token++;
+
+ token+=2; /* skip reserved section */
+
+ len = *token++;
+ len = len << 8;
+ len |= (unsigned char)*token++;
+
+ *exponentLength = len;
+
+ len = *token++;
+ len = len << 8;
+ len |= (unsigned char)*token++;
+
+ *modulusLength = len;
+
+ len = *token++;
+ len = len << 8;
+ len |= (unsigned char)*token++;
+
+ *modulusFieldLength = len;
+
+ memcpy(exponent, token, *exponentLength);
+ token+= *exponentLength;
+
+ memcpy(modulus, token, *modulusFieldLength);
+ return 1;
+ }
+ return 0;
+ }
+
+#endif /* OPENSSL_NO_RSA */
+
+static int cca_random_status(void)
+ {
+ return 1;
+ }
+
+static int cca_get_random_bytes(unsigned char* buf, int num)
+ {
+ long ret_code;
+ long reason_code;
+ long exit_data_length;
+ unsigned char exit_data[4];
+ unsigned char form[] = "RANDOM ";
+ unsigned char rand_buf[8];
+
+ while(num >= (int)sizeof(rand_buf))
+ {
+ randomNumberGenerate(&ret_code, &reason_code, &exit_data_length,
+ exit_data, form, rand_buf);
+ if (ret_code)
+ return 0;
+ num -= sizeof(rand_buf);
+ memcpy(buf, rand_buf, sizeof(rand_buf));
+ buf += sizeof(rand_buf);
+ }
+
+ if (num)
+ {
+ randomNumberGenerate(&ret_code, &reason_code, NULL, NULL,
+ form, rand_buf);
+ if (ret_code)
+ return 0;
+ memcpy(buf, rand_buf, num);
+ }
+
+ return 1;
+ }
+
+#ifndef OPENSSL_NO_RSA
+static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx,
+ long argl, void *argp)
+ {
+ if (item)
+ OPENSSL_free(item);
+ }
+#endif
+
+/* Goo to handle building as a dynamic engine */
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_fn(ENGINE *e, const char *id)
+ {
+ if(id && (strcmp(id, engine_4758_cca_id) != 0) &&
+ (strcmp(id, engine_4758_cca_id_alt) != 0))
+ return 0;
+ if(!bind_helper(e))
+ return 0;
+ return 1;
+ }
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
+
+#endif /* !OPENSSL_NO_HW_4758_CCA */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_4758cca.ec b/openssl/engines/e_4758cca.ec
new file mode 100644
index 000000000..f30ed02c0
--- /dev/null
+++ b/openssl/engines/e_4758cca.ec
@@ -0,0 +1 @@
+L CCA4758 e_4758cca_err.h e_4758cca_err.c
diff --git a/openssl/engines/e_4758cca_err.c b/openssl/engines/e_4758cca_err.c
new file mode 100644
index 000000000..6ecdc6e62
--- /dev/null
+++ b/openssl/engines/e_4758cca_err.c
@@ -0,0 +1,153 @@
+/* e_4758cca_err.c */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+/* 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 "e_4758cca_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA CCA4758_str_functs[]=
+ {
+{ERR_FUNC(CCA4758_F_CCA_RSA_SIGN), "CCA_RSA_SIGN"},
+{ERR_FUNC(CCA4758_F_CCA_RSA_VERIFY), "CCA_RSA_VERIFY"},
+{ERR_FUNC(CCA4758_F_IBM_4758_CCA_CTRL), "IBM_4758_CCA_CTRL"},
+{ERR_FUNC(CCA4758_F_IBM_4758_CCA_FINISH), "IBM_4758_CCA_FINISH"},
+{ERR_FUNC(CCA4758_F_IBM_4758_CCA_INIT), "IBM_4758_CCA_INIT"},
+{ERR_FUNC(CCA4758_F_IBM_4758_LOAD_PRIVKEY), "IBM_4758_LOAD_PRIVKEY"},
+{ERR_FUNC(CCA4758_F_IBM_4758_LOAD_PUBKEY), "IBM_4758_LOAD_PUBKEY"},
+{0,NULL}
+ };
+
+static ERR_STRING_DATA CCA4758_str_reasons[]=
+ {
+{ERR_REASON(CCA4758_R_ALREADY_LOADED) ,"already loaded"},
+{ERR_REASON(CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD),"asn1 oid unknown for md"},
+{ERR_REASON(CCA4758_R_COMMAND_NOT_IMPLEMENTED),"command not implemented"},
+{ERR_REASON(CCA4758_R_DSO_FAILURE) ,"dso failure"},
+{ERR_REASON(CCA4758_R_FAILED_LOADING_PRIVATE_KEY),"failed loading private key"},
+{ERR_REASON(CCA4758_R_FAILED_LOADING_PUBLIC_KEY),"failed loading public key"},
+{ERR_REASON(CCA4758_R_NOT_LOADED) ,"not loaded"},
+{ERR_REASON(CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL),"size too large or too small"},
+{ERR_REASON(CCA4758_R_UNIT_FAILURE) ,"unit failure"},
+{ERR_REASON(CCA4758_R_UNKNOWN_ALGORITHM_TYPE),"unknown algorithm type"},
+{0,NULL}
+ };
+
+#endif
+
+#ifdef CCA4758_LIB_NAME
+static ERR_STRING_DATA CCA4758_lib_name[]=
+ {
+{0 ,CCA4758_LIB_NAME},
+{0,NULL}
+ };
+#endif
+
+
+static int CCA4758_lib_error_code=0;
+static int CCA4758_error_init=1;
+
+static void ERR_load_CCA4758_strings(void)
+ {
+ if (CCA4758_lib_error_code == 0)
+ CCA4758_lib_error_code=ERR_get_next_error_library();
+
+ if (CCA4758_error_init)
+ {
+ CCA4758_error_init=0;
+#ifndef OPENSSL_NO_ERR
+ ERR_load_strings(CCA4758_lib_error_code,CCA4758_str_functs);
+ ERR_load_strings(CCA4758_lib_error_code,CCA4758_str_reasons);
+#endif
+
+#ifdef CCA4758_LIB_NAME
+ CCA4758_lib_name->error = ERR_PACK(CCA4758_lib_error_code,0,0);
+ ERR_load_strings(0,CCA4758_lib_name);
+#endif
+ }
+ }
+
+static void ERR_unload_CCA4758_strings(void)
+ {
+ if (CCA4758_error_init == 0)
+ {
+#ifndef OPENSSL_NO_ERR
+ ERR_unload_strings(CCA4758_lib_error_code,CCA4758_str_functs);
+ ERR_unload_strings(CCA4758_lib_error_code,CCA4758_str_reasons);
+#endif
+
+#ifdef CCA4758_LIB_NAME
+ ERR_unload_strings(0,CCA4758_lib_name);
+#endif
+ CCA4758_error_init=1;
+ }
+ }
+
+static void ERR_CCA4758_error(int function, int reason, char *file, int line)
+ {
+ if (CCA4758_lib_error_code == 0)
+ CCA4758_lib_error_code=ERR_get_next_error_library();
+ ERR_PUT_error(CCA4758_lib_error_code,function,reason,file,line);
+ }
diff --git a/openssl/engines/e_4758cca_err.h b/openssl/engines/e_4758cca_err.h
new file mode 100644
index 000000000..26087edbf
--- /dev/null
+++ b/openssl/engines/e_4758cca_err.h
@@ -0,0 +1,97 @@
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * 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_CCA4758_ERR_H
+#define HEADER_CCA4758_ERR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_CCA4758_strings(void);
+static void ERR_unload_CCA4758_strings(void);
+static void ERR_CCA4758_error(int function, int reason, char *file, int line);
+#define CCA4758err(f,r) ERR_CCA4758_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the CCA4758 functions. */
+
+/* Function codes. */
+#define CCA4758_F_CCA_RSA_SIGN 105
+#define CCA4758_F_CCA_RSA_VERIFY 106
+#define CCA4758_F_IBM_4758_CCA_CTRL 100
+#define CCA4758_F_IBM_4758_CCA_FINISH 101
+#define CCA4758_F_IBM_4758_CCA_INIT 102
+#define CCA4758_F_IBM_4758_LOAD_PRIVKEY 103
+#define CCA4758_F_IBM_4758_LOAD_PUBKEY 104
+
+/* Reason codes. */
+#define CCA4758_R_ALREADY_LOADED 100
+#define CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD 101
+#define CCA4758_R_COMMAND_NOT_IMPLEMENTED 102
+#define CCA4758_R_DSO_FAILURE 103
+#define CCA4758_R_FAILED_LOADING_PRIVATE_KEY 104
+#define CCA4758_R_FAILED_LOADING_PUBLIC_KEY 105
+#define CCA4758_R_NOT_LOADED 106
+#define CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL 107
+#define CCA4758_R_UNIT_FAILURE 108
+#define CCA4758_R_UNKNOWN_ALGORITHM_TYPE 109
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/e_aep.c b/openssl/engines/e_aep.c
new file mode 100644
index 000000000..e24e4b424
--- /dev/null
+++ b/openssl/engines/e_aep.c
@@ -0,0 +1,1144 @@
+/* ====================================================================
+ * Copyright (c) 1999 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>
+#include <string.h>
+
+#include <openssl/e_os2.h>
+#if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__)
+#include <sys/types.h>
+#include <unistd.h>
+#else
+#include <process.h>
+typedef int pid_t;
+#endif
+
+#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
+#define getpid GetThreadID
+extern int GetThreadID(void);
+#endif
+
+#include <openssl/crypto.h>
+#include <openssl/dso.h>
+#include <openssl/engine.h>
+#include <openssl/buffer.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/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_AEP
+#ifdef FLAT_INC
+#include "aep.h"
+#else
+#include "vendor_defns/aep.h"
+#endif
+
+#define AEP_LIB_NAME "aep engine"
+#define FAIL_TO_SW 0x10101010
+
+#include "e_aep_err.c"
+
+static int aep_init(ENGINE *e);
+static int aep_finish(ENGINE *e);
+static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+static int aep_destroy(ENGINE *e);
+
+static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR hConnection);
+static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection);
+static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection);
+static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use);
+
+/* BIGNUM stuff */
+#ifndef OPENSSL_NO_RSA
+static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+
+static AEP_RV aep_mod_exp_crt(BIGNUM *r,const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *q, const BIGNUM *dmp1,const BIGNUM *dmq1,
+ const BIGNUM *iqmp, BN_CTX *ctx);
+#endif
+
+/* RSA stuff */
+#ifndef OPENSSL_NO_RSA
+static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+#endif
+
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+#ifndef OPENSSL_NO_RSA
+static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+#endif
+
+/* DSA stuff */
+#ifndef OPENSSL_NO_DSA
+static int aep_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);
+
+static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+ const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx);
+#endif
+
+/* DH stuff */
+/* This function is aliased to mod_exp (with the DH and mont dropped). */
+#ifndef OPENSSL_NO_DH
+static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+#endif
+
+/* rand stuff */
+#ifdef AEPRAND
+static int aep_rand(unsigned char *buf, int num);
+static int aep_rand_status(void);
+#endif
+
+/* Bignum conversion stuff */
+static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize);
+static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
+ unsigned char* AEP_BigNum);
+static AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize,
+ unsigned char* AEP_BigNum);
+
+/* The definitions for control commands specific to this engine */
+#define AEP_CMD_SO_PATH ENGINE_CMD_BASE
+static const ENGINE_CMD_DEFN aep_cmd_defns[] =
+ {
+ { AEP_CMD_SO_PATH,
+ "SO_PATH",
+ "Specifies the path to the 'aep' shared library",
+ ENGINE_CMD_FLAG_STRING
+ },
+ {0, NULL, NULL, 0}
+ };
+
+#ifndef OPENSSL_NO_RSA
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD aep_rsa =
+ {
+ "Aep RSA method",
+ NULL, /*rsa_pub_encrypt*/
+ NULL, /*rsa_pub_decrypt*/
+ NULL, /*rsa_priv_encrypt*/
+ NULL, /*rsa_priv_encrypt*/
+ aep_rsa_mod_exp, /*rsa_mod_exp*/
+ aep_mod_exp_mont, /*bn_mod_exp*/
+ NULL, /*init*/
+ NULL, /*finish*/
+ 0, /*flags*/
+ NULL, /*app_data*/
+ NULL, /*rsa_sign*/
+ NULL, /*rsa_verify*/
+ NULL /*rsa_keygen*/
+ };
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* Our internal DSA_METHOD that we provide pointers to */
+static DSA_METHOD aep_dsa =
+ {
+ "Aep DSA method",
+ NULL, /* dsa_do_sign */
+ NULL, /* dsa_sign_setup */
+ NULL, /* dsa_do_verify */
+ aep_dsa_mod_exp, /* dsa_mod_exp */
+ aep_mod_exp_dsa, /* bn_mod_exp */
+ NULL, /* init */
+ NULL, /* finish */
+ 0, /* flags */
+ NULL, /* app_data */
+ NULL, /* dsa_paramgen */
+ NULL /* dsa_keygen */
+ };
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* Our internal DH_METHOD that we provide pointers to */
+static DH_METHOD aep_dh =
+ {
+ "Aep DH method",
+ NULL,
+ NULL,
+ aep_mod_exp_dh,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ NULL
+ };
+#endif
+
+#ifdef AEPRAND
+/* our internal RAND_method that we provide pointers to */
+static RAND_METHOD aep_random =
+ {
+ /*"AEP RAND method", */
+ NULL,
+ aep_rand,
+ NULL,
+ NULL,
+ aep_rand,
+ aep_rand_status,
+ };
+#endif
+
+/*Define an array of structures to hold connections*/
+static AEP_CONNECTION_ENTRY aep_app_conn_table[MAX_PROCESS_CONNECTIONS];
+
+/*Used to determine if this is a new process*/
+static pid_t recorded_pid = 0;
+
+#ifdef AEPRAND
+static AEP_U8 rand_block[RAND_BLK_SIZE];
+static AEP_U32 rand_block_bytes = 0;
+#endif
+
+/* Constants used when creating the ENGINE */
+static const char *engine_aep_id = "aep";
+static const char *engine_aep_name = "Aep hardware engine support";
+
+static int max_key_len = 2176;
+
+
+/* This internal function is used by ENGINE_aep() and possibly by the
+ * "dynamic" ENGINE support too */
+static int bind_aep(ENGINE *e)
+ {
+#ifndef OPENSSL_NO_RSA
+ const RSA_METHOD *meth1;
+#endif
+#ifndef OPENSSL_NO_DSA
+ const DSA_METHOD *meth2;
+#endif
+#ifndef OPENSSL_NO_DH
+ const DH_METHOD *meth3;
+#endif
+
+ if(!ENGINE_set_id(e, engine_aep_id) ||
+ !ENGINE_set_name(e, engine_aep_name) ||
+#ifndef OPENSSL_NO_RSA
+ !ENGINE_set_RSA(e, &aep_rsa) ||
+#endif
+#ifndef OPENSSL_NO_DSA
+ !ENGINE_set_DSA(e, &aep_dsa) ||
+#endif
+#ifndef OPENSSL_NO_DH
+ !ENGINE_set_DH(e, &aep_dh) ||
+#endif
+#ifdef AEPRAND
+ !ENGINE_set_RAND(e, &aep_random) ||
+#endif
+ !ENGINE_set_init_function(e, aep_init) ||
+ !ENGINE_set_destroy_function(e, aep_destroy) ||
+ !ENGINE_set_finish_function(e, aep_finish) ||
+ !ENGINE_set_ctrl_function(e, aep_ctrl) ||
+ !ENGINE_set_cmd_defns(e, aep_cmd_defns))
+ return 0;
+
+#ifndef OPENSSL_NO_RSA
+ /* We know that the "PKCS1_SSLeay()" functions hook properly
+ * to the aep-specific mod_exp and mod_exp_crt so we use
+ * those functions. NB: We don't use ENGINE_openssl() or
+ * anything "more generic" because something like the RSAref
+ * code may not hook properly, and if you own one of these
+ * cards then you have the right to do RSA operations on it
+ * anyway! */
+ meth1 = RSA_PKCS1_SSLeay();
+ aep_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+ aep_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+ aep_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
+ aep_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
+#endif
+
+
+#ifndef OPENSSL_NO_DSA
+ /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
+ * bits. */
+ meth2 = DSA_OpenSSL();
+ aep_dsa.dsa_do_sign = meth2->dsa_do_sign;
+ aep_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
+ aep_dsa.dsa_do_verify = meth2->dsa_do_verify;
+
+ aep_dsa = *DSA_get_default_method();
+ aep_dsa.dsa_mod_exp = aep_dsa_mod_exp;
+ aep_dsa.bn_mod_exp = aep_mod_exp_dsa;
+#endif
+
+#ifndef OPENSSL_NO_DH
+ /* Much the same for Diffie-Hellman */
+ meth3 = DH_OpenSSL();
+ aep_dh.generate_key = meth3->generate_key;
+ aep_dh.compute_key = meth3->compute_key;
+ aep_dh.bn_mod_exp = meth3->bn_mod_exp;
+#endif
+
+ /* Ensure the aep error handling is set up */
+ ERR_load_AEPHK_strings();
+
+ return 1;
+}
+
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_helper(ENGINE *e, const char *id)
+ {
+ if(id && (strcmp(id, engine_aep_id) != 0))
+ return 0;
+ if(!bind_aep(e))
+ return 0;
+ return 1;
+ }
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
+#else
+static ENGINE *engine_aep(void)
+ {
+ ENGINE *ret = ENGINE_new();
+ if(!ret)
+ return NULL;
+ if(!bind_aep(ret))
+ {
+ ENGINE_free(ret);
+ return NULL;
+ }
+ return ret;
+ }
+
+void ENGINE_load_aep(void)
+ {
+ /* Copied from eng_[openssl|dyn].c */
+ ENGINE *toadd = engine_aep();
+ if(!toadd) return;
+ ENGINE_add(toadd);
+ ENGINE_free(toadd);
+ ERR_clear_error();
+ }
+#endif
+
+/* This is a process-global DSO handle used for loading and unloading
+ * the Aep library. NB: This is only set (or unset) during an
+ * init() or finish() call (reference counts permitting) and they're
+ * operating with global locks, so this should be thread-safe
+ * implicitly. */
+static DSO *aep_dso = NULL;
+
+/* These are the static string constants for the DSO file name and the function
+ * symbol names to bind to.
+*/
+static const char *AEP_LIBNAME = NULL;
+static const char *get_AEP_LIBNAME(void)
+ {
+ if(AEP_LIBNAME)
+ return AEP_LIBNAME;
+ return "aep";
+ }
+static void free_AEP_LIBNAME(void)
+ {
+ if(AEP_LIBNAME)
+ OPENSSL_free((void*)AEP_LIBNAME);
+ AEP_LIBNAME = NULL;
+ }
+static long set_AEP_LIBNAME(const char *name)
+ {
+ free_AEP_LIBNAME();
+ return ((AEP_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
+ }
+
+static const char *AEP_F1 = "AEP_ModExp";
+static const char *AEP_F2 = "AEP_ModExpCrt";
+#ifdef AEPRAND
+static const char *AEP_F3 = "AEP_GenRandom";
+#endif
+static const char *AEP_F4 = "AEP_Finalize";
+static const char *AEP_F5 = "AEP_Initialize";
+static const char *AEP_F6 = "AEP_OpenConnection";
+static const char *AEP_F7 = "AEP_SetBNCallBacks";
+static const char *AEP_F8 = "AEP_CloseConnection";
+
+/* These are the function pointers that are (un)set when the library has
+ * successfully (un)loaded. */
+static t_AEP_OpenConnection *p_AEP_OpenConnection = NULL;
+static t_AEP_CloseConnection *p_AEP_CloseConnection = NULL;
+static t_AEP_ModExp *p_AEP_ModExp = NULL;
+static t_AEP_ModExpCrt *p_AEP_ModExpCrt = NULL;
+#ifdef AEPRAND
+static t_AEP_GenRandom *p_AEP_GenRandom = NULL;
+#endif
+static t_AEP_Initialize *p_AEP_Initialize = NULL;
+static t_AEP_Finalize *p_AEP_Finalize = NULL;
+static t_AEP_SetBNCallBacks *p_AEP_SetBNCallBacks = NULL;
+
+/* (de)initialisation functions. */
+static int aep_init(ENGINE *e)
+ {
+ t_AEP_ModExp *p1;
+ t_AEP_ModExpCrt *p2;
+#ifdef AEPRAND
+ t_AEP_GenRandom *p3;
+#endif
+ t_AEP_Finalize *p4;
+ t_AEP_Initialize *p5;
+ t_AEP_OpenConnection *p6;
+ t_AEP_SetBNCallBacks *p7;
+ t_AEP_CloseConnection *p8;
+
+ int to_return = 0;
+
+ if(aep_dso != NULL)
+ {
+ AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_ALREADY_LOADED);
+ goto err;
+ }
+ /* Attempt to load libaep.so. */
+
+ aep_dso = DSO_load(NULL, get_AEP_LIBNAME(), NULL, 0);
+
+ if(aep_dso == NULL)
+ {
+ AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
+ goto err;
+ }
+
+ if( !(p1 = (t_AEP_ModExp *) DSO_bind_func( aep_dso,AEP_F1)) ||
+ !(p2 = (t_AEP_ModExpCrt*) DSO_bind_func( aep_dso,AEP_F2)) ||
+#ifdef AEPRAND
+ !(p3 = (t_AEP_GenRandom*) DSO_bind_func( aep_dso,AEP_F3)) ||
+#endif
+ !(p4 = (t_AEP_Finalize*) DSO_bind_func( aep_dso,AEP_F4)) ||
+ !(p5 = (t_AEP_Initialize*) DSO_bind_func( aep_dso,AEP_F5)) ||
+ !(p6 = (t_AEP_OpenConnection*) DSO_bind_func( aep_dso,AEP_F6)) ||
+ !(p7 = (t_AEP_SetBNCallBacks*) DSO_bind_func( aep_dso,AEP_F7)) ||
+ !(p8 = (t_AEP_CloseConnection*) DSO_bind_func( aep_dso,AEP_F8)))
+ {
+ AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
+ goto err;
+ }
+
+ /* Copy the pointers */
+
+ p_AEP_ModExp = p1;
+ p_AEP_ModExpCrt = p2;
+#ifdef AEPRAND
+ p_AEP_GenRandom = p3;
+#endif
+ p_AEP_Finalize = p4;
+ p_AEP_Initialize = p5;
+ p_AEP_OpenConnection = p6;
+ p_AEP_SetBNCallBacks = p7;
+ p_AEP_CloseConnection = p8;
+
+ to_return = 1;
+
+ return to_return;
+
+ err:
+
+ if(aep_dso)
+ DSO_free(aep_dso);
+ aep_dso = NULL;
+
+ p_AEP_OpenConnection = NULL;
+ p_AEP_ModExp = NULL;
+ p_AEP_ModExpCrt = NULL;
+#ifdef AEPRAND
+ p_AEP_GenRandom = NULL;
+#endif
+ p_AEP_Initialize = NULL;
+ p_AEP_Finalize = NULL;
+ p_AEP_SetBNCallBacks = NULL;
+ p_AEP_CloseConnection = NULL;
+
+ return to_return;
+ }
+
+/* Destructor (complements the "ENGINE_aep()" constructor) */
+static int aep_destroy(ENGINE *e)
+ {
+ free_AEP_LIBNAME();
+ ERR_unload_AEPHK_strings();
+ return 1;
+ }
+
+static int aep_finish(ENGINE *e)
+ {
+ int to_return = 0, in_use;
+ AEP_RV rv;
+
+ if(aep_dso == NULL)
+ {
+ AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_NOT_LOADED);
+ goto err;
+ }
+
+ rv = aep_close_all_connections(0, &in_use);
+ if (rv != AEP_R_OK)
+ {
+ AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CLOSE_HANDLES_FAILED);
+ goto err;
+ }
+ if (in_use)
+ {
+ AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CONNECTIONS_IN_USE);
+ goto err;
+ }
+
+ rv = p_AEP_Finalize();
+ if (rv != AEP_R_OK)
+ {
+ AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_FINALIZE_FAILED);
+ goto err;
+ }
+
+ if(!DSO_free(aep_dso))
+ {
+ AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_UNIT_FAILURE);
+ goto err;
+ }
+
+ aep_dso = NULL;
+ p_AEP_CloseConnection = NULL;
+ p_AEP_OpenConnection = NULL;
+ p_AEP_ModExp = NULL;
+ p_AEP_ModExpCrt = NULL;
+#ifdef AEPRAND
+ p_AEP_GenRandom = NULL;
+#endif
+ p_AEP_Initialize = NULL;
+ p_AEP_Finalize = NULL;
+ p_AEP_SetBNCallBacks = NULL;
+
+ to_return = 1;
+ err:
+ return to_return;
+ }
+
+static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+ {
+ int initialised = ((aep_dso == NULL) ? 0 : 1);
+ switch(cmd)
+ {
+ case AEP_CMD_SO_PATH:
+ if(p == NULL)
+ {
+ AEPHKerr(AEPHK_F_AEP_CTRL,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ if(initialised)
+ {
+ AEPHKerr(AEPHK_F_AEP_CTRL,
+ AEPHK_R_ALREADY_LOADED);
+ return 0;
+ }
+ return set_AEP_LIBNAME((const char*)p);
+ default:
+ break;
+ }
+ AEPHKerr(AEPHK_F_AEP_CTRL,AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+ return 0;
+ }
+
+static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx)
+ {
+ int to_return = 0;
+ int r_len = 0;
+ AEP_CONNECTION_HNDL hConnection;
+ AEP_RV rv;
+
+ r_len = BN_num_bits(m);
+
+ /* Perform in software if modulus is too large for hardware. */
+
+ if (r_len > max_key_len){
+ AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+ return BN_mod_exp(r, a, p, m, ctx);
+ }
+
+ /*Grab a connection from the pool*/
+ rv = aep_get_connection(&hConnection);
+ if (rv != AEP_R_OK)
+ {
+ AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_GET_HANDLE_FAILED);
+ return BN_mod_exp(r, a, p, m, ctx);
+ }
+
+ /*To the card with the mod exp*/
+ rv = p_AEP_ModExp(hConnection,(void*)a, (void*)p,(void*)m, (void*)r,NULL);
+
+ if (rv != AEP_R_OK)
+ {
+ AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_MOD_EXP_FAILED);
+ rv = aep_close_connection(hConnection);
+ return BN_mod_exp(r, a, p, m, ctx);
+ }
+
+ /*Return the connection to the pool*/
+ rv = aep_return_connection(hConnection);
+ if (rv != AEP_R_OK)
+ {
+ AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_RETURN_CONNECTION_FAILED);
+ goto err;
+ }
+
+ to_return = 1;
+ err:
+ return to_return;
+ }
+
+#ifndef OPENSSL_NO_RSA
+static AEP_RV aep_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *q, const BIGNUM *dmp1,
+ const BIGNUM *dmq1,const BIGNUM *iqmp, BN_CTX *ctx)
+ {
+ AEP_RV rv = AEP_R_OK;
+ AEP_CONNECTION_HNDL hConnection;
+
+ /*Grab a connection from the pool*/
+ rv = aep_get_connection(&hConnection);
+ if (rv != AEP_R_OK)
+ {
+ AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_GET_HANDLE_FAILED);
+ return FAIL_TO_SW;
+ }
+
+ /*To the card with the mod exp*/
+ rv = p_AEP_ModExpCrt(hConnection,(void*)a, (void*)p, (void*)q, (void*)dmp1,(void*)dmq1,
+ (void*)iqmp,(void*)r,NULL);
+ if (rv != AEP_R_OK)
+ {
+ AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_MOD_EXP_CRT_FAILED);
+ rv = aep_close_connection(hConnection);
+ return FAIL_TO_SW;
+ }
+
+ /*Return the connection to the pool*/
+ rv = aep_return_connection(hConnection);
+ if (rv != AEP_R_OK)
+ {
+ AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_RETURN_CONNECTION_FAILED);
+ goto err;
+ }
+
+ err:
+ return rv;
+ }
+#endif
+
+
+#ifdef AEPRAND
+static int aep_rand(unsigned char *buf,int len )
+ {
+ AEP_RV rv = AEP_R_OK;
+ AEP_CONNECTION_HNDL hConnection;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+
+ /*Can the request be serviced with what's already in the buffer?*/
+ if (len <= rand_block_bytes)
+ {
+ memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
+ rand_block_bytes -= len;
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ }
+ else
+ /*If not the get another block of random bytes*/
+ {
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+
+ rv = aep_get_connection(&hConnection);
+ if (rv != AEP_R_OK)
+ {
+ AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_HANDLE_FAILED);
+ goto err_nounlock;
+ }
+
+ if (len > RAND_BLK_SIZE)
+ {
+ rv = p_AEP_GenRandom(hConnection, len, 2, buf, NULL);
+ if (rv != AEP_R_OK)
+ {
+ AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED);
+ goto err_nounlock;
+ }
+ }
+ else
+ {
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+
+ rv = p_AEP_GenRandom(hConnection, RAND_BLK_SIZE, 2, &rand_block[0], NULL);
+ if (rv != AEP_R_OK)
+ {
+ AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED);
+
+ goto err;
+ }
+
+ rand_block_bytes = RAND_BLK_SIZE;
+
+ memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
+ rand_block_bytes -= len;
+
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ }
+
+ rv = aep_return_connection(hConnection);
+ if (rv != AEP_R_OK)
+ {
+ AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED);
+
+ goto err_nounlock;
+ }
+ }
+
+ return 1;
+ err:
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ err_nounlock:
+ return 0;
+ }
+
+static int aep_rand_status(void)
+{
+ return 1;
+}
+#endif
+
+#ifndef OPENSSL_NO_RSA
+static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+ {
+ int to_return = 0;
+ AEP_RV rv = AEP_R_OK;
+
+ if (!aep_dso)
+ {
+ AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_NOT_LOADED);
+ goto err;
+ }
+
+ /*See if we have all the necessary bits for a crt*/
+ if (rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp)
+ {
+ rv = aep_mod_exp_crt(r0,I,rsa->p,rsa->q, rsa->dmp1,rsa->dmq1,rsa->iqmp,ctx);
+
+ if (rv == FAIL_TO_SW){
+ const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
+ to_return = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
+ goto err;
+ }
+ else if (rv != AEP_R_OK)
+ goto err;
+ }
+ else
+ {
+ if (!rsa->d || !rsa->n)
+ {
+ AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_MISSING_KEY_COMPONENTS);
+ goto err;
+ }
+
+ rv = aep_mod_exp(r0,I,rsa->d,rsa->n,ctx);
+ if (rv != AEP_R_OK)
+ goto err;
+
+ }
+
+ to_return = 1;
+
+ err:
+ return to_return;
+}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+static int aep_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)
+ {
+ BIGNUM t;
+ int to_return = 0;
+ BN_init(&t);
+
+ /* let rr = a1 ^ p1 mod m */
+ if (!aep_mod_exp(rr,a1,p1,m,ctx)) goto end;
+ /* let t = a2 ^ p2 mod m */
+ if (!aep_mod_exp(&t,a2,p2,m,ctx)) goto end;
+ /* let rr = rr * t mod m */
+ if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
+ to_return = 1;
+ end:
+ BN_free(&t);
+ return to_return;
+ }
+
+static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+ const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx)
+ {
+ return aep_mod_exp(r, a, p, m, ctx);
+ }
+#endif
+
+#ifndef OPENSSL_NO_RSA
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+ {
+ return aep_mod_exp(r, a, p, m, ctx);
+ }
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx)
+ {
+ return aep_mod_exp(r, a, p, m, ctx);
+ }
+#endif
+
+static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection)
+ {
+ int count;
+ AEP_RV rv = AEP_R_OK;
+
+ /*Get the current process id*/
+ pid_t curr_pid;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+
+#ifdef NETWARE_CLIB
+ curr_pid = GetThreadID();
+#elif defined(_WIN32)
+ curr_pid = _getpid();
+#else
+ curr_pid = getpid();
+#endif
+
+ /*Check if this is the first time this is being called from the current
+ process*/
+ if (recorded_pid != curr_pid)
+ {
+ /*Remember our pid so we can check if we're in a new process*/
+ recorded_pid = curr_pid;
+
+ /*Call Finalize to make sure we have not inherited some data
+ from a parent process*/
+ p_AEP_Finalize();
+
+ /*Initialise the AEP API*/
+ rv = p_AEP_Initialize(NULL);
+
+ if (rv != AEP_R_OK)
+ {
+ AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_INIT_FAILURE);
+ recorded_pid = 0;
+ goto end;
+ }
+
+ /*Set the AEP big num call back functions*/
+ rv = p_AEP_SetBNCallBacks(&GetBigNumSize, &MakeAEPBigNum,
+ &ConvertAEPBigNum);
+
+ if (rv != AEP_R_OK)
+ {
+ AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_SETBNCALLBACK_FAILURE);
+ recorded_pid = 0;
+ goto end;
+ }
+
+#ifdef AEPRAND
+ /*Reset the rand byte count*/
+ rand_block_bytes = 0;
+#endif
+
+ /*Init the structures*/
+ for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
+ {
+ aep_app_conn_table[count].conn_state = NotConnected;
+ aep_app_conn_table[count].conn_hndl = 0;
+ }
+
+ /*Open a connection*/
+ rv = p_AEP_OpenConnection(phConnection);
+
+ if (rv != AEP_R_OK)
+ {
+ AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
+ recorded_pid = 0;
+ goto end;
+ }
+
+ aep_app_conn_table[0].conn_state = InUse;
+ aep_app_conn_table[0].conn_hndl = *phConnection;
+ goto end;
+ }
+ /*Check the existing connections to see if we can find a free one*/
+ for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
+ {
+ if (aep_app_conn_table[count].conn_state == Connected)
+ {
+ aep_app_conn_table[count].conn_state = InUse;
+ *phConnection = aep_app_conn_table[count].conn_hndl;
+ goto end;
+ }
+ }
+ /*If no connections available, we're going to have to try
+ to open a new one*/
+ for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
+ {
+ if (aep_app_conn_table[count].conn_state == NotConnected)
+ {
+ /*Open a connection*/
+ rv = p_AEP_OpenConnection(phConnection);
+
+ if (rv != AEP_R_OK)
+ {
+ AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
+ goto end;
+ }
+
+ aep_app_conn_table[count].conn_state = InUse;
+ aep_app_conn_table[count].conn_hndl = *phConnection;
+ goto end;
+ }
+ }
+ rv = AEP_R_GENERAL_ERROR;
+ end:
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ return rv;
+ }
+
+
+static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection)
+ {
+ int count;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+
+ /*Find the connection item that matches this connection handle*/
+ for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
+ {
+ if (aep_app_conn_table[count].conn_hndl == hConnection)
+ {
+ aep_app_conn_table[count].conn_state = Connected;
+ break;
+ }
+ }
+
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+
+ return AEP_R_OK;
+ }
+
+static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection)
+ {
+ int count;
+ AEP_RV rv = AEP_R_OK;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+
+ /*Find the connection item that matches this connection handle*/
+ for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
+ {
+ if (aep_app_conn_table[count].conn_hndl == hConnection)
+ {
+ rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
+ if (rv != AEP_R_OK)
+ goto end;
+ aep_app_conn_table[count].conn_state = NotConnected;
+ aep_app_conn_table[count].conn_hndl = 0;
+ break;
+ }
+ }
+
+ end:
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ return rv;
+ }
+
+static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use)
+ {
+ int count;
+ AEP_RV rv = AEP_R_OK;
+
+ *in_use = 0;
+ if (use_engine_lock) CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
+ {
+ switch (aep_app_conn_table[count].conn_state)
+ {
+ case Connected:
+ rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
+ if (rv != AEP_R_OK)
+ goto end;
+ aep_app_conn_table[count].conn_state = NotConnected;
+ aep_app_conn_table[count].conn_hndl = 0;
+ break;
+ case InUse:
+ (*in_use)++;
+ break;
+ case NotConnected:
+ break;
+ }
+ }
+ end:
+ if (use_engine_lock) CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ return rv;
+ }
+
+/*BigNum call back functions, used to convert OpenSSL bignums into AEP bignums.
+ Note only 32bit Openssl build support*/
+
+static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize)
+ {
+ BIGNUM* bn;
+
+ /*Cast the ArbBigNum pointer to our BIGNUM struct*/
+ bn = (BIGNUM*) ArbBigNum;
+
+#ifdef SIXTY_FOUR_BIT_LONG
+ *BigNumSize = bn->top << 3;
+#else
+ /*Size of the bignum in bytes is equal to the bn->top (no of 32 bit
+ words) multiplies by 4*/
+ *BigNumSize = bn->top << 2;
+#endif
+
+ return AEP_R_OK;
+ }
+
+static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
+ unsigned char* AEP_BigNum)
+ {
+ BIGNUM* bn;
+
+#ifndef SIXTY_FOUR_BIT_LONG
+ unsigned char* buf;
+ int i;
+#endif
+
+ /*Cast the ArbBigNum pointer to our BIGNUM struct*/
+ bn = (BIGNUM*) ArbBigNum;
+
+#ifdef SIXTY_FOUR_BIT_LONG
+ memcpy(AEP_BigNum, bn->d, BigNumSize);
+#else
+ /*Must copy data into a (monotone) least significant byte first format
+ performing endian conversion if necessary*/
+ for(i=0;i<bn->top;i++)
+ {
+ buf = (unsigned char*)&bn->d[i];
+
+ *((AEP_U32*)AEP_BigNum) = (AEP_U32)
+ ((unsigned) buf[1] << 8 | buf[0]) |
+ ((unsigned) buf[3] << 8 | buf[2]) << 16;
+
+ AEP_BigNum += 4;
+ }
+#endif
+
+ return AEP_R_OK;
+ }
+
+/*Turn an AEP Big Num back to a user big num*/
+static AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize,
+ unsigned char* AEP_BigNum)
+ {
+ BIGNUM* bn;
+#ifndef SIXTY_FOUR_BIT_LONG
+ int i;
+#endif
+
+ bn = (BIGNUM*)ArbBigNum;
+
+ /*Expand the result bn so that it can hold our big num.
+ Size is in bits*/
+ bn_expand(bn, (int)(BigNumSize << 3));
+
+#ifdef SIXTY_FOUR_BIT_LONG
+ bn->top = BigNumSize >> 3;
+
+ if((BigNumSize & 7) != 0)
+ bn->top++;
+
+ memset(bn->d, 0, bn->top << 3);
+
+ memcpy(bn->d, AEP_BigNum, BigNumSize);
+#else
+ bn->top = BigNumSize >> 2;
+
+ for(i=0;i<bn->top;i++)
+ {
+ bn->d[i] = (AEP_U32)
+ ((unsigned) AEP_BigNum[3] << 8 | AEP_BigNum[2]) << 16 |
+ ((unsigned) AEP_BigNum[1] << 8 | AEP_BigNum[0]);
+ AEP_BigNum += 4;
+ }
+#endif
+
+ return AEP_R_OK;
+}
+
+#endif /* !OPENSSL_NO_HW_AEP */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_aep.ec b/openssl/engines/e_aep.ec
new file mode 100644
index 000000000..8eae642e0
--- /dev/null
+++ b/openssl/engines/e_aep.ec
@@ -0,0 +1 @@
+L AEPHK e_aep_err.h e_aep_err.c
diff --git a/openssl/engines/e_aep_err.c b/openssl/engines/e_aep_err.c
new file mode 100644
index 000000000..3f95881ca
--- /dev/null
+++ b/openssl/engines/e_aep_err.c
@@ -0,0 +1,161 @@
+/* e_aep_err.c */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+/* 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 "e_aep_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA AEPHK_str_functs[]=
+ {
+{ERR_FUNC(AEPHK_F_AEP_CTRL), "AEP_CTRL"},
+{ERR_FUNC(AEPHK_F_AEP_FINISH), "AEP_FINISH"},
+{ERR_FUNC(AEPHK_F_AEP_GET_CONNECTION), "AEP_GET_CONNECTION"},
+{ERR_FUNC(AEPHK_F_AEP_INIT), "AEP_INIT"},
+{ERR_FUNC(AEPHK_F_AEP_MOD_EXP), "AEP_MOD_EXP"},
+{ERR_FUNC(AEPHK_F_AEP_MOD_EXP_CRT), "AEP_MOD_EXP_CRT"},
+{ERR_FUNC(AEPHK_F_AEP_RAND), "AEP_RAND"},
+{ERR_FUNC(AEPHK_F_AEP_RSA_MOD_EXP), "AEP_RSA_MOD_EXP"},
+{0,NULL}
+ };
+
+static ERR_STRING_DATA AEPHK_str_reasons[]=
+ {
+{ERR_REASON(AEPHK_R_ALREADY_LOADED) ,"already loaded"},
+{ERR_REASON(AEPHK_R_CLOSE_HANDLES_FAILED),"close handles failed"},
+{ERR_REASON(AEPHK_R_CONNECTIONS_IN_USE) ,"connections in use"},
+{ERR_REASON(AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
+{ERR_REASON(AEPHK_R_FINALIZE_FAILED) ,"finalize failed"},
+{ERR_REASON(AEPHK_R_GET_HANDLE_FAILED) ,"get handle failed"},
+{ERR_REASON(AEPHK_R_GET_RANDOM_FAILED) ,"get random failed"},
+{ERR_REASON(AEPHK_R_INIT_FAILURE) ,"init failure"},
+{ERR_REASON(AEPHK_R_MISSING_KEY_COMPONENTS),"missing key components"},
+{ERR_REASON(AEPHK_R_MOD_EXP_CRT_FAILED) ,"mod exp crt failed"},
+{ERR_REASON(AEPHK_R_MOD_EXP_FAILED) ,"mod exp failed"},
+{ERR_REASON(AEPHK_R_NOT_LOADED) ,"not loaded"},
+{ERR_REASON(AEPHK_R_OK) ,"ok"},
+{ERR_REASON(AEPHK_R_RETURN_CONNECTION_FAILED),"return connection failed"},
+{ERR_REASON(AEPHK_R_SETBNCALLBACK_FAILURE),"setbncallback failure"},
+{ERR_REASON(AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL),"size too large or too small"},
+{ERR_REASON(AEPHK_R_UNIT_FAILURE) ,"unit failure"},
+{0,NULL}
+ };
+
+#endif
+
+#ifdef AEPHK_LIB_NAME
+static ERR_STRING_DATA AEPHK_lib_name[]=
+ {
+{0 ,AEPHK_LIB_NAME},
+{0,NULL}
+ };
+#endif
+
+
+static int AEPHK_lib_error_code=0;
+static int AEPHK_error_init=1;
+
+static void ERR_load_AEPHK_strings(void)
+ {
+ if (AEPHK_lib_error_code == 0)
+ AEPHK_lib_error_code=ERR_get_next_error_library();
+
+ if (AEPHK_error_init)
+ {
+ AEPHK_error_init=0;
+#ifndef OPENSSL_NO_ERR
+ ERR_load_strings(AEPHK_lib_error_code,AEPHK_str_functs);
+ ERR_load_strings(AEPHK_lib_error_code,AEPHK_str_reasons);
+#endif
+
+#ifdef AEPHK_LIB_NAME
+ AEPHK_lib_name->error = ERR_PACK(AEPHK_lib_error_code,0,0);
+ ERR_load_strings(0,AEPHK_lib_name);
+#endif
+ }
+ }
+
+static void ERR_unload_AEPHK_strings(void)
+ {
+ if (AEPHK_error_init == 0)
+ {
+#ifndef OPENSSL_NO_ERR
+ ERR_unload_strings(AEPHK_lib_error_code,AEPHK_str_functs);
+ ERR_unload_strings(AEPHK_lib_error_code,AEPHK_str_reasons);
+#endif
+
+#ifdef AEPHK_LIB_NAME
+ ERR_unload_strings(0,AEPHK_lib_name);
+#endif
+ AEPHK_error_init=1;
+ }
+ }
+
+static void ERR_AEPHK_error(int function, int reason, char *file, int line)
+ {
+ if (AEPHK_lib_error_code == 0)
+ AEPHK_lib_error_code=ERR_get_next_error_library();
+ ERR_PUT_error(AEPHK_lib_error_code,function,reason,file,line);
+ }
diff --git a/openssl/engines/e_aep_err.h b/openssl/engines/e_aep_err.h
new file mode 100644
index 000000000..35b2e7426
--- /dev/null
+++ b/openssl/engines/e_aep_err.h
@@ -0,0 +1,105 @@
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * 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_AEPHK_ERR_H
+#define HEADER_AEPHK_ERR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_AEPHK_strings(void);
+static void ERR_unload_AEPHK_strings(void);
+static void ERR_AEPHK_error(int function, int reason, char *file, int line);
+#define AEPHKerr(f,r) ERR_AEPHK_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the AEPHK functions. */
+
+/* Function codes. */
+#define AEPHK_F_AEP_CTRL 100
+#define AEPHK_F_AEP_FINISH 101
+#define AEPHK_F_AEP_GET_CONNECTION 102
+#define AEPHK_F_AEP_INIT 103
+#define AEPHK_F_AEP_MOD_EXP 104
+#define AEPHK_F_AEP_MOD_EXP_CRT 105
+#define AEPHK_F_AEP_RAND 106
+#define AEPHK_F_AEP_RSA_MOD_EXP 107
+
+/* Reason codes. */
+#define AEPHK_R_ALREADY_LOADED 100
+#define AEPHK_R_CLOSE_HANDLES_FAILED 101
+#define AEPHK_R_CONNECTIONS_IN_USE 102
+#define AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED 103
+#define AEPHK_R_FINALIZE_FAILED 104
+#define AEPHK_R_GET_HANDLE_FAILED 105
+#define AEPHK_R_GET_RANDOM_FAILED 106
+#define AEPHK_R_INIT_FAILURE 107
+#define AEPHK_R_MISSING_KEY_COMPONENTS 108
+#define AEPHK_R_MOD_EXP_CRT_FAILED 109
+#define AEPHK_R_MOD_EXP_FAILED 110
+#define AEPHK_R_NOT_LOADED 111
+#define AEPHK_R_OK 112
+#define AEPHK_R_RETURN_CONNECTION_FAILED 113
+#define AEPHK_R_SETBNCALLBACK_FAILURE 114
+#define AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL 116
+#define AEPHK_R_UNIT_FAILURE 115
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/e_atalla.c b/openssl/engines/e_atalla.c
new file mode 100644
index 000000000..fabaa86a5
--- /dev/null
+++ b/openssl/engines/e_atalla.c
@@ -0,0 +1,607 @@
+/* crypto/engine/hw_atalla.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * 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/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/dso.h>
+#include <openssl/engine.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/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_ATALLA
+
+#ifdef FLAT_INC
+#include "atalla.h"
+#else
+#include "vendor_defns/atalla.h"
+#endif
+
+#define ATALLA_LIB_NAME "atalla engine"
+#include "e_atalla_err.c"
+
+static int atalla_destroy(ENGINE *e);
+static int atalla_init(ENGINE *e);
+static int atalla_finish(ENGINE *e);
+static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+
+/* BIGNUM stuff */
+static int atalla_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+
+#ifndef OPENSSL_NO_RSA
+/* RSA stuff */
+static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int atalla_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* DSA stuff */
+static int atalla_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);
+static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+ const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx);
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* DH stuff */
+/* This function is alised to mod_exp (with the DH and mont dropped). */
+static int atalla_mod_exp_dh(const DH *dh, BIGNUM *r,
+ const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+#endif
+
+/* The definitions for control commands specific to this engine */
+#define ATALLA_CMD_SO_PATH ENGINE_CMD_BASE
+static const ENGINE_CMD_DEFN atalla_cmd_defns[] = {
+ {ATALLA_CMD_SO_PATH,
+ "SO_PATH",
+ "Specifies the path to the 'atasi' shared library",
+ ENGINE_CMD_FLAG_STRING},
+ {0, NULL, NULL, 0}
+ };
+
+#ifndef OPENSSL_NO_RSA
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD atalla_rsa =
+ {
+ "Atalla RSA method",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ atalla_rsa_mod_exp,
+ atalla_mod_exp_mont,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* Our internal DSA_METHOD that we provide pointers to */
+static DSA_METHOD atalla_dsa =
+ {
+ "Atalla DSA method",
+ NULL, /* dsa_do_sign */
+ NULL, /* dsa_sign_setup */
+ NULL, /* dsa_do_verify */
+ atalla_dsa_mod_exp, /* dsa_mod_exp */
+ atalla_mod_exp_dsa, /* bn_mod_exp */
+ NULL, /* init */
+ NULL, /* finish */
+ 0, /* flags */
+ NULL, /* app_data */
+ NULL, /* dsa_paramgen */
+ NULL /* dsa_keygen */
+ };
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* Our internal DH_METHOD that we provide pointers to */
+static DH_METHOD atalla_dh =
+ {
+ "Atalla DH method",
+ NULL,
+ NULL,
+ atalla_mod_exp_dh,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ NULL
+ };
+#endif
+
+/* Constants used when creating the ENGINE */
+static const char *engine_atalla_id = "atalla";
+static const char *engine_atalla_name = "Atalla hardware engine support";
+
+/* This internal function is used by ENGINE_atalla() and possibly by the
+ * "dynamic" ENGINE support too */
+static int bind_helper(ENGINE *e)
+ {
+#ifndef OPENSSL_NO_RSA
+ const RSA_METHOD *meth1;
+#endif
+#ifndef OPENSSL_NO_DSA
+ const DSA_METHOD *meth2;
+#endif
+#ifndef OPENSSL_NO_DH
+ const DH_METHOD *meth3;
+#endif
+ if(!ENGINE_set_id(e, engine_atalla_id) ||
+ !ENGINE_set_name(e, engine_atalla_name) ||
+#ifndef OPENSSL_NO_RSA
+ !ENGINE_set_RSA(e, &atalla_rsa) ||
+#endif
+#ifndef OPENSSL_NO_DSA
+ !ENGINE_set_DSA(e, &atalla_dsa) ||
+#endif
+#ifndef OPENSSL_NO_DH
+ !ENGINE_set_DH(e, &atalla_dh) ||
+#endif
+ !ENGINE_set_destroy_function(e, atalla_destroy) ||
+ !ENGINE_set_init_function(e, atalla_init) ||
+ !ENGINE_set_finish_function(e, atalla_finish) ||
+ !ENGINE_set_ctrl_function(e, atalla_ctrl) ||
+ !ENGINE_set_cmd_defns(e, atalla_cmd_defns))
+ return 0;
+
+#ifndef OPENSSL_NO_RSA
+ /* We know that the "PKCS1_SSLeay()" functions hook properly
+ * to the atalla-specific mod_exp and mod_exp_crt so we use
+ * those functions. NB: We don't use ENGINE_openssl() or
+ * anything "more generic" because something like the RSAref
+ * code may not hook properly, and if you own one of these
+ * cards then you have the right to do RSA operations on it
+ * anyway! */
+ meth1 = RSA_PKCS1_SSLeay();
+ atalla_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+ atalla_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+ atalla_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
+ atalla_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
+#endif
+
+#ifndef OPENSSL_NO_DSA
+ /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
+ * bits. */
+ meth2 = DSA_OpenSSL();
+ atalla_dsa.dsa_do_sign = meth2->dsa_do_sign;
+ atalla_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
+ atalla_dsa.dsa_do_verify = meth2->dsa_do_verify;
+#endif
+
+#ifndef OPENSSL_NO_DH
+ /* Much the same for Diffie-Hellman */
+ meth3 = DH_OpenSSL();
+ atalla_dh.generate_key = meth3->generate_key;
+ atalla_dh.compute_key = meth3->compute_key;
+#endif
+
+ /* Ensure the atalla error handling is set up */
+ ERR_load_ATALLA_strings();
+ return 1;
+ }
+
+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+static ENGINE *engine_atalla(void)
+ {
+ ENGINE *ret = ENGINE_new();
+ if(!ret)
+ return NULL;
+ if(!bind_helper(ret))
+ {
+ ENGINE_free(ret);
+ return NULL;
+ }
+ return ret;
+ }
+
+void ENGINE_load_atalla(void)
+ {
+ /* Copied from eng_[openssl|dyn].c */
+ ENGINE *toadd = engine_atalla();
+ if(!toadd) return;
+ ENGINE_add(toadd);
+ ENGINE_free(toadd);
+ ERR_clear_error();
+ }
+#endif
+
+/* This is a process-global DSO handle used for loading and unloading
+ * the Atalla library. NB: This is only set (or unset) during an
+ * init() or finish() call (reference counts permitting) and they're
+ * operating with global locks, so this should be thread-safe
+ * implicitly. */
+static DSO *atalla_dso = NULL;
+
+/* These are the function pointers that are (un)set when the library has
+ * successfully (un)loaded. */
+static tfnASI_GetHardwareConfig *p_Atalla_GetHardwareConfig = NULL;
+static tfnASI_RSAPrivateKeyOpFn *p_Atalla_RSAPrivateKeyOpFn = NULL;
+static tfnASI_GetPerformanceStatistics *p_Atalla_GetPerformanceStatistics = NULL;
+
+/* These are the static string constants for the DSO file name and the function
+ * symbol names to bind to. Regrettably, the DSO name on *nix appears to be
+ * "atasi.so" rather than something more consistent like "libatasi.so". At the
+ * time of writing, I'm not sure what the file name on win32 is but clearly
+ * native name translation is not possible (eg libatasi.so on *nix, and
+ * atasi.dll on win32). For the purposes of testing, I have created a symbollic
+ * link called "libatasi.so" so that we can use native name-translation - a
+ * better solution will be needed. */
+static const char *ATALLA_LIBNAME = NULL;
+static const char *get_ATALLA_LIBNAME(void)
+ {
+ if(ATALLA_LIBNAME)
+ return ATALLA_LIBNAME;
+ return "atasi";
+ }
+static void free_ATALLA_LIBNAME(void)
+ {
+ if(ATALLA_LIBNAME)
+ OPENSSL_free((void*)ATALLA_LIBNAME);
+ ATALLA_LIBNAME = NULL;
+ }
+static long set_ATALLA_LIBNAME(const char *name)
+ {
+ free_ATALLA_LIBNAME();
+ return (((ATALLA_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
+ }
+static const char *ATALLA_F1 = "ASI_GetHardwareConfig";
+static const char *ATALLA_F2 = "ASI_RSAPrivateKeyOpFn";
+static const char *ATALLA_F3 = "ASI_GetPerformanceStatistics";
+
+/* Destructor (complements the "ENGINE_atalla()" constructor) */
+static int atalla_destroy(ENGINE *e)
+ {
+ free_ATALLA_LIBNAME();
+ /* Unload the atalla error strings so any error state including our
+ * functs or reasons won't lead to a segfault (they simply get displayed
+ * without corresponding string data because none will be found). */
+ ERR_unload_ATALLA_strings();
+ return 1;
+ }
+
+/* (de)initialisation functions. */
+static int atalla_init(ENGINE *e)
+ {
+ tfnASI_GetHardwareConfig *p1;
+ tfnASI_RSAPrivateKeyOpFn *p2;
+ tfnASI_GetPerformanceStatistics *p3;
+ /* Not sure of the origin of this magic value, but Ben's code had it
+ * and it seemed to have been working for a few people. :-) */
+ unsigned int config_buf[1024];
+
+ if(atalla_dso != NULL)
+ {
+ ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_ALREADY_LOADED);
+ goto err;
+ }
+ /* Attempt to load libatasi.so/atasi.dll/whatever. Needs to be
+ * changed unfortunately because the Atalla drivers don't have
+ * standard library names that can be platform-translated well. */
+ /* TODO: Work out how to actually map to the names the Atalla
+ * drivers really use - for now a symbollic link needs to be
+ * created on the host system from libatasi.so to atasi.so on
+ * unix variants. */
+ atalla_dso = DSO_load(NULL, get_ATALLA_LIBNAME(), NULL, 0);
+ if(atalla_dso == NULL)
+ {
+ ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_NOT_LOADED);
+ goto err;
+ }
+ if(!(p1 = (tfnASI_GetHardwareConfig *)DSO_bind_func(
+ atalla_dso, ATALLA_F1)) ||
+ !(p2 = (tfnASI_RSAPrivateKeyOpFn *)DSO_bind_func(
+ atalla_dso, ATALLA_F2)) ||
+ !(p3 = (tfnASI_GetPerformanceStatistics *)DSO_bind_func(
+ atalla_dso, ATALLA_F3)))
+ {
+ ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_NOT_LOADED);
+ goto err;
+ }
+ /* Copy the pointers */
+ p_Atalla_GetHardwareConfig = p1;
+ p_Atalla_RSAPrivateKeyOpFn = p2;
+ p_Atalla_GetPerformanceStatistics = p3;
+ /* Perform a basic test to see if there's actually any unit
+ * running. */
+ if(p1(0L, config_buf) != 0)
+ {
+ ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_UNIT_FAILURE);
+ goto err;
+ }
+ /* Everything's fine. */
+ return 1;
+err:
+ if(atalla_dso)
+ DSO_free(atalla_dso);
+ atalla_dso = NULL;
+ p_Atalla_GetHardwareConfig = NULL;
+ p_Atalla_RSAPrivateKeyOpFn = NULL;
+ p_Atalla_GetPerformanceStatistics = NULL;
+ return 0;
+ }
+
+static int atalla_finish(ENGINE *e)
+ {
+ free_ATALLA_LIBNAME();
+ if(atalla_dso == NULL)
+ {
+ ATALLAerr(ATALLA_F_ATALLA_FINISH,ATALLA_R_NOT_LOADED);
+ return 0;
+ }
+ if(!DSO_free(atalla_dso))
+ {
+ ATALLAerr(ATALLA_F_ATALLA_FINISH,ATALLA_R_UNIT_FAILURE);
+ return 0;
+ }
+ atalla_dso = NULL;
+ p_Atalla_GetHardwareConfig = NULL;
+ p_Atalla_RSAPrivateKeyOpFn = NULL;
+ p_Atalla_GetPerformanceStatistics = NULL;
+ return 1;
+ }
+
+static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+ {
+ int initialised = ((atalla_dso == NULL) ? 0 : 1);
+ switch(cmd)
+ {
+ case ATALLA_CMD_SO_PATH:
+ if(p == NULL)
+ {
+ ATALLAerr(ATALLA_F_ATALLA_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ if(initialised)
+ {
+ ATALLAerr(ATALLA_F_ATALLA_CTRL,ATALLA_R_ALREADY_LOADED);
+ return 0;
+ }
+ return set_ATALLA_LIBNAME((const char *)p);
+ default:
+ break;
+ }
+ ATALLAerr(ATALLA_F_ATALLA_CTRL,ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+ return 0;
+ }
+
+static int atalla_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx)
+ {
+ /* I need somewhere to store temporary serialised values for
+ * use with the Atalla API calls. A neat cheat - I'll use
+ * BIGNUMs from the BN_CTX but access their arrays directly as
+ * byte arrays <grin>. This way I don't have to clean anything
+ * up. */
+ BIGNUM *modulus;
+ BIGNUM *exponent;
+ BIGNUM *argument;
+ BIGNUM *result;
+ RSAPrivateKey keydata;
+ int to_return, numbytes;
+
+ modulus = exponent = argument = result = NULL;
+ to_return = 0; /* expect failure */
+
+ if(!atalla_dso)
+ {
+ ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_NOT_LOADED);
+ goto err;
+ }
+ /* Prepare the params */
+ BN_CTX_start(ctx);
+ modulus = BN_CTX_get(ctx);
+ exponent = BN_CTX_get(ctx);
+ argument = BN_CTX_get(ctx);
+ result = BN_CTX_get(ctx);
+ if (!result)
+ {
+ ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_BN_CTX_FULL);
+ goto err;
+ }
+ if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, m->top) ||
+ !bn_wexpand(argument, m->top) || !bn_wexpand(result, m->top))
+ {
+ ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+ /* Prepare the key-data */
+ memset(&keydata, 0,sizeof keydata);
+ numbytes = BN_num_bytes(m);
+ memset(exponent->d, 0, numbytes);
+ memset(modulus->d, 0, numbytes);
+ BN_bn2bin(p, (unsigned char *)exponent->d + numbytes - BN_num_bytes(p));
+ BN_bn2bin(m, (unsigned char *)modulus->d + numbytes - BN_num_bytes(m));
+ keydata.privateExponent.data = (unsigned char *)exponent->d;
+ keydata.privateExponent.len = numbytes;
+ keydata.modulus.data = (unsigned char *)modulus->d;
+ keydata.modulus.len = numbytes;
+ /* Prepare the argument */
+ memset(argument->d, 0, numbytes);
+ memset(result->d, 0, numbytes);
+ BN_bn2bin(a, (unsigned char *)argument->d + numbytes - BN_num_bytes(a));
+ /* Perform the operation */
+ if(p_Atalla_RSAPrivateKeyOpFn(&keydata, (unsigned char *)result->d,
+ (unsigned char *)argument->d,
+ keydata.modulus.len) != 0)
+ {
+ ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_REQUEST_FAILED);
+ goto err;
+ }
+ /* Convert the response */
+ BN_bin2bn((unsigned char *)result->d, numbytes, r);
+ to_return = 1;
+err:
+ BN_CTX_end(ctx);
+ return to_return;
+ }
+
+#ifndef OPENSSL_NO_RSA
+static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+ {
+ int to_return = 0;
+
+ if(!atalla_dso)
+ {
+ ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP,ATALLA_R_NOT_LOADED);
+ goto err;
+ }
+ if(!rsa->d || !rsa->n)
+ {
+ ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP,ATALLA_R_MISSING_KEY_COMPONENTS);
+ goto err;
+ }
+ to_return = atalla_mod_exp(r0, I, rsa->d, rsa->n, ctx);
+err:
+ return to_return;
+ }
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* This code was liberated and adapted from the commented-out code in
+ * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration
+ * (it doesn't have a CRT form for RSA), this function means that an
+ * Atalla system running with a DSA server certificate can handshake
+ * around 5 or 6 times faster/more than an equivalent system running with
+ * RSA. Just check out the "signs" statistics from the RSA and DSA parts
+ * of "openssl speed -engine atalla dsa1024 rsa1024". */
+static int atalla_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)
+ {
+ BIGNUM t;
+ int to_return = 0;
+
+ BN_init(&t);
+ /* let rr = a1 ^ p1 mod m */
+ if (!atalla_mod_exp(rr,a1,p1,m,ctx)) goto end;
+ /* let t = a2 ^ p2 mod m */
+ if (!atalla_mod_exp(&t,a2,p2,m,ctx)) goto end;
+ /* let rr = rr * t mod m */
+ if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
+ to_return = 1;
+end:
+ BN_free(&t);
+ return to_return;
+ }
+
+static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+ const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx)
+ {
+ return atalla_mod_exp(r, a, p, m, ctx);
+ }
+#endif
+
+#ifndef OPENSSL_NO_RSA
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int atalla_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+ {
+ return atalla_mod_exp(r, a, p, m, ctx);
+ }
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int atalla_mod_exp_dh(const DH *dh, BIGNUM *r,
+ const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+ {
+ return atalla_mod_exp(r, a, p, m, ctx);
+ }
+#endif
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library. */
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_fn(ENGINE *e, const char *id)
+ {
+ if(id && (strcmp(id, engine_atalla_id) != 0))
+ return 0;
+ if(!bind_helper(e))
+ return 0;
+ return 1;
+ }
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
+
+#endif /* !OPENSSL_NO_HW_ATALLA */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_atalla.ec b/openssl/engines/e_atalla.ec
new file mode 100644
index 000000000..1d735e1b2
--- /dev/null
+++ b/openssl/engines/e_atalla.ec
@@ -0,0 +1 @@
+L ATALLA e_atalla_err.h e_atalla_err.c
diff --git a/openssl/engines/e_atalla_err.c b/openssl/engines/e_atalla_err.c
new file mode 100644
index 000000000..fd3e0049c
--- /dev/null
+++ b/openssl/engines/e_atalla_err.c
@@ -0,0 +1,149 @@
+/* e_atalla_err.c */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+/* 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 "e_atalla_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA ATALLA_str_functs[]=
+ {
+{ERR_FUNC(ATALLA_F_ATALLA_CTRL), "ATALLA_CTRL"},
+{ERR_FUNC(ATALLA_F_ATALLA_FINISH), "ATALLA_FINISH"},
+{ERR_FUNC(ATALLA_F_ATALLA_INIT), "ATALLA_INIT"},
+{ERR_FUNC(ATALLA_F_ATALLA_MOD_EXP), "ATALLA_MOD_EXP"},
+{ERR_FUNC(ATALLA_F_ATALLA_RSA_MOD_EXP), "ATALLA_RSA_MOD_EXP"},
+{0,NULL}
+ };
+
+static ERR_STRING_DATA ATALLA_str_reasons[]=
+ {
+{ERR_REASON(ATALLA_R_ALREADY_LOADED) ,"already loaded"},
+{ERR_REASON(ATALLA_R_BN_CTX_FULL) ,"bn ctx full"},
+{ERR_REASON(ATALLA_R_BN_EXPAND_FAIL) ,"bn expand fail"},
+{ERR_REASON(ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
+{ERR_REASON(ATALLA_R_MISSING_KEY_COMPONENTS),"missing key components"},
+{ERR_REASON(ATALLA_R_NOT_LOADED) ,"not loaded"},
+{ERR_REASON(ATALLA_R_REQUEST_FAILED) ,"request failed"},
+{ERR_REASON(ATALLA_R_UNIT_FAILURE) ,"unit failure"},
+{0,NULL}
+ };
+
+#endif
+
+#ifdef ATALLA_LIB_NAME
+static ERR_STRING_DATA ATALLA_lib_name[]=
+ {
+{0 ,ATALLA_LIB_NAME},
+{0,NULL}
+ };
+#endif
+
+
+static int ATALLA_lib_error_code=0;
+static int ATALLA_error_init=1;
+
+static void ERR_load_ATALLA_strings(void)
+ {
+ if (ATALLA_lib_error_code == 0)
+ ATALLA_lib_error_code=ERR_get_next_error_library();
+
+ if (ATALLA_error_init)
+ {
+ ATALLA_error_init=0;
+#ifndef OPENSSL_NO_ERR
+ ERR_load_strings(ATALLA_lib_error_code,ATALLA_str_functs);
+ ERR_load_strings(ATALLA_lib_error_code,ATALLA_str_reasons);
+#endif
+
+#ifdef ATALLA_LIB_NAME
+ ATALLA_lib_name->error = ERR_PACK(ATALLA_lib_error_code,0,0);
+ ERR_load_strings(0,ATALLA_lib_name);
+#endif
+ }
+ }
+
+static void ERR_unload_ATALLA_strings(void)
+ {
+ if (ATALLA_error_init == 0)
+ {
+#ifndef OPENSSL_NO_ERR
+ ERR_unload_strings(ATALLA_lib_error_code,ATALLA_str_functs);
+ ERR_unload_strings(ATALLA_lib_error_code,ATALLA_str_reasons);
+#endif
+
+#ifdef ATALLA_LIB_NAME
+ ERR_unload_strings(0,ATALLA_lib_name);
+#endif
+ ATALLA_error_init=1;
+ }
+ }
+
+static void ERR_ATALLA_error(int function, int reason, char *file, int line)
+ {
+ if (ATALLA_lib_error_code == 0)
+ ATALLA_lib_error_code=ERR_get_next_error_library();
+ ERR_PUT_error(ATALLA_lib_error_code,function,reason,file,line);
+ }
diff --git a/openssl/engines/e_atalla_err.h b/openssl/engines/e_atalla_err.h
new file mode 100644
index 000000000..36e09bf42
--- /dev/null
+++ b/openssl/engines/e_atalla_err.h
@@ -0,0 +1,93 @@
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * 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_ATALLA_ERR_H
+#define HEADER_ATALLA_ERR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_ATALLA_strings(void);
+static void ERR_unload_ATALLA_strings(void);
+static void ERR_ATALLA_error(int function, int reason, char *file, int line);
+#define ATALLAerr(f,r) ERR_ATALLA_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the ATALLA functions. */
+
+/* Function codes. */
+#define ATALLA_F_ATALLA_CTRL 100
+#define ATALLA_F_ATALLA_FINISH 101
+#define ATALLA_F_ATALLA_INIT 102
+#define ATALLA_F_ATALLA_MOD_EXP 103
+#define ATALLA_F_ATALLA_RSA_MOD_EXP 104
+
+/* Reason codes. */
+#define ATALLA_R_ALREADY_LOADED 100
+#define ATALLA_R_BN_CTX_FULL 101
+#define ATALLA_R_BN_EXPAND_FAIL 102
+#define ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED 103
+#define ATALLA_R_MISSING_KEY_COMPONENTS 104
+#define ATALLA_R_NOT_LOADED 105
+#define ATALLA_R_REQUEST_FAILED 106
+#define ATALLA_R_UNIT_FAILURE 107
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/e_capi.c b/openssl/engines/e_capi.c
new file mode 100644
index 000000000..e98946c85
--- /dev/null
+++ b/openssl/engines/e_capi.c
@@ -0,0 +1,1781 @@
+/* engines/e_capi.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 <stdio.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/rsa.h>
+#include <openssl/bn.h>
+
+#ifdef OPENSSL_SYS_WIN32
+#ifndef OPENSSL_NO_CAPIENG
+
+
+#include <windows.h>
+
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0400
+#endif
+
+#include <wincrypt.h>
+
+#undef X509_EXTENSIONS
+#undef X509_CERT_PAIR
+
+/* Definitions which may be missing from earlier version of headers */
+#ifndef CERT_STORE_OPEN_EXISTING_FLAG
+#define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000
+#endif
+
+#ifndef CERT_STORE_CREATE_NEW_FLAG
+#define CERT_STORE_CREATE_NEW_FLAG 0x00002000
+#endif
+
+#include <openssl/engine.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+
+#include "e_capi_err.h"
+#include "e_capi_err.c"
+
+
+static const char *engine_capi_id = "capi";
+static const char *engine_capi_name = "CryptoAPI ENGINE";
+
+typedef struct CAPI_CTX_st CAPI_CTX;
+typedef struct CAPI_KEY_st CAPI_KEY;
+
+static void capi_addlasterror(void);
+static void capi_adderror(DWORD err);
+
+static void CAPI_trace(CAPI_CTX *ctx, char *format, ...);
+
+static int capi_list_providers(CAPI_CTX *ctx, BIO *out);
+static int capi_list_containers(CAPI_CTX *ctx, BIO *out);
+int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *storename);
+void capi_free_key(CAPI_KEY *key);
+
+static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE hstore);
+
+CAPI_KEY *capi_find_key(CAPI_CTX *ctx, const char *id);
+
+static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id,
+ UI_METHOD *ui_method, void *callback_data);
+static int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len,
+ unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
+static int capi_rsa_priv_enc(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding);
+static int capi_rsa_priv_dec(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding);
+static int capi_rsa_free(RSA *rsa);
+
+static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen,
+ DSA *dsa);
+static int capi_dsa_free(DSA *dsa);
+
+static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
+ STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
+ STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data);
+
+static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
+#ifdef OPENSSL_CAPIENG_DIALOG
+static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
+#endif
+
+typedef PCCERT_CONTEXT (WINAPI *CERTDLG)(HCERTSTORE, HWND, LPCWSTR,
+ LPCWSTR, DWORD, DWORD,
+ void *);
+typedef HWND (WINAPI *GETCONSWIN)(void);
+
+/* This structure contains CAPI ENGINE specific data:
+ * it contains various global options and affects how
+ * other functions behave.
+ */
+
+#define CAPI_DBG_TRACE 2
+#define CAPI_DBG_ERROR 1
+
+struct CAPI_CTX_st {
+ int debug_level;
+ char *debug_file;
+ /* Parameters to use for container lookup */
+ DWORD keytype;
+ LPTSTR cspname;
+ DWORD csptype;
+ /* Certificate store name to use */
+ LPTSTR storename;
+ LPTSTR ssl_client_store;
+ /* System store flags */
+ DWORD store_flags;
+
+/* Lookup string meanings in load_private_key */
+/* Substring of subject: uses "storename" */
+#define CAPI_LU_SUBSTR 0
+/* Friendly name: uses storename */
+#define CAPI_LU_FNAME 1
+/* Container name: uses cspname, keytype */
+#define CAPI_LU_CONTNAME 2
+ int lookup_method;
+/* Info to dump with dumpcerts option */
+/* Issuer and serial name strings */
+#define CAPI_DMP_SUMMARY 0x1
+/* Friendly name */
+#define CAPI_DMP_FNAME 0x2
+/* Full X509_print dump */
+#define CAPI_DMP_FULL 0x4
+/* Dump PEM format certificate */
+#define CAPI_DMP_PEM 0x8
+/* Dump pseudo key (if possible) */
+#define CAPI_DMP_PSKEY 0x10
+/* Dump key info (if possible) */
+#define CAPI_DMP_PKEYINFO 0x20
+
+ DWORD dump_flags;
+ int (*client_cert_select)(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
+
+ CERTDLG certselectdlg;
+ GETCONSWIN getconswindow;
+};
+
+
+static CAPI_CTX *capi_ctx_new();
+static void capi_ctx_free(CAPI_CTX *ctx);
+static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int check);
+static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx);
+
+#define CAPI_CMD_LIST_CERTS ENGINE_CMD_BASE
+#define CAPI_CMD_LOOKUP_CERT (ENGINE_CMD_BASE + 1)
+#define CAPI_CMD_DEBUG_LEVEL (ENGINE_CMD_BASE + 2)
+#define CAPI_CMD_DEBUG_FILE (ENGINE_CMD_BASE + 3)
+#define CAPI_CMD_KEYTYPE (ENGINE_CMD_BASE + 4)
+#define CAPI_CMD_LIST_CSPS (ENGINE_CMD_BASE + 5)
+#define CAPI_CMD_SET_CSP_IDX (ENGINE_CMD_BASE + 6)
+#define CAPI_CMD_SET_CSP_NAME (ENGINE_CMD_BASE + 7)
+#define CAPI_CMD_SET_CSP_TYPE (ENGINE_CMD_BASE + 8)
+#define CAPI_CMD_LIST_CONTAINERS (ENGINE_CMD_BASE + 9)
+#define CAPI_CMD_LIST_OPTIONS (ENGINE_CMD_BASE + 10)
+#define CAPI_CMD_LOOKUP_METHOD (ENGINE_CMD_BASE + 11)
+#define CAPI_CMD_STORE_NAME (ENGINE_CMD_BASE + 12)
+#define CAPI_CMD_STORE_FLAGS (ENGINE_CMD_BASE + 13)
+
+static const ENGINE_CMD_DEFN capi_cmd_defns[] = {
+ {CAPI_CMD_LIST_CERTS,
+ "list_certs",
+ "List all certificates in store",
+ ENGINE_CMD_FLAG_NO_INPUT},
+ {CAPI_CMD_LOOKUP_CERT,
+ "lookup_cert",
+ "Lookup and output certificates",
+ ENGINE_CMD_FLAG_STRING},
+ {CAPI_CMD_DEBUG_LEVEL,
+ "debug_level",
+ "debug level (1=errors, 2=trace)",
+ ENGINE_CMD_FLAG_NUMERIC},
+ {CAPI_CMD_DEBUG_FILE,
+ "debug_file",
+ "debugging filename)",
+ ENGINE_CMD_FLAG_STRING},
+ {CAPI_CMD_KEYTYPE,
+ "key_type",
+ "Key type: 1=AT_KEYEXCHANGE (default), 2=AT_SIGNATURE",
+ ENGINE_CMD_FLAG_NUMERIC},
+ {CAPI_CMD_LIST_CSPS,
+ "list_csps",
+ "List all CSPs",
+ ENGINE_CMD_FLAG_NO_INPUT},
+ {CAPI_CMD_SET_CSP_IDX,
+ "csp_idx",
+ "Set CSP by index",
+ ENGINE_CMD_FLAG_NUMERIC},
+ {CAPI_CMD_SET_CSP_NAME,
+ "csp_name",
+ "Set CSP name, (default CSP used if not specified)",
+ ENGINE_CMD_FLAG_STRING},
+ {CAPI_CMD_SET_CSP_TYPE,
+ "csp_type",
+ "Set CSP type, (default RSA_PROV_FULL)",
+ ENGINE_CMD_FLAG_NUMERIC},
+ {CAPI_CMD_LIST_CONTAINERS,
+ "list_containers",
+ "list container names",
+ ENGINE_CMD_FLAG_NO_INPUT},
+ {CAPI_CMD_LIST_OPTIONS,
+ "list_options",
+ "Set list options (1=summary,2=friendly name, 4=full printout, 8=PEM output, 16=XXX, "
+ "32=private key info)",
+ ENGINE_CMD_FLAG_NUMERIC},
+ {CAPI_CMD_LOOKUP_METHOD,
+ "lookup_method",
+ "Set key lookup method (1=substring, 2=friendlyname, 3=container name)",
+ ENGINE_CMD_FLAG_NUMERIC},
+ {CAPI_CMD_STORE_NAME,
+ "store_name",
+ "certificate store name, default \"MY\"",
+ ENGINE_CMD_FLAG_STRING},
+ {CAPI_CMD_STORE_FLAGS,
+ "store_flags",
+ "Certificate store flags: 1 = system store",
+ ENGINE_CMD_FLAG_NUMERIC},
+
+ {0, NULL, NULL, 0}
+ };
+
+static int capi_idx = -1;
+static int rsa_capi_idx = -1;
+static int dsa_capi_idx = -1;
+static int cert_capi_idx = -1;
+
+static int capi_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+ {
+ int ret = 1;
+ CAPI_CTX *ctx;
+ BIO *out;
+ if (capi_idx == -1)
+ {
+ CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_ENGINE_NOT_INITIALIZED);
+ return 0;
+ }
+ ctx = ENGINE_get_ex_data(e, capi_idx);
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+ switch (cmd)
+ {
+ case CAPI_CMD_LIST_CSPS:
+ ret = capi_list_providers(ctx, out);
+ break;
+
+ case CAPI_CMD_LIST_CERTS:
+ ret = capi_list_certs(ctx, out, NULL);
+ break;
+
+ case CAPI_CMD_LOOKUP_CERT:
+ ret = capi_list_certs(ctx, out, p);
+ break;
+
+ case CAPI_CMD_LIST_CONTAINERS:
+ ret = capi_list_containers(ctx, out);
+ break;
+
+ case CAPI_CMD_STORE_NAME:
+ if (ctx->storename)
+ OPENSSL_free(ctx->storename);
+ ctx->storename = BUF_strdup(p);
+ CAPI_trace(ctx, "Setting store name to %s\n", p);
+ break;
+
+ case CAPI_CMD_STORE_FLAGS:
+ if (i & 1)
+ {
+ ctx->store_flags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
+ ctx->store_flags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
+ }
+ else
+ {
+ ctx->store_flags |= CERT_SYSTEM_STORE_CURRENT_USER;
+ ctx->store_flags &= ~CERT_SYSTEM_STORE_LOCAL_MACHINE;
+ }
+ CAPI_trace(ctx, "Setting flags to %d\n", i);
+ break;
+
+ case CAPI_CMD_DEBUG_LEVEL:
+ ctx->debug_level = (int)i;
+ CAPI_trace(ctx, "Setting debug level to %d\n", ctx->debug_level);
+ break;
+
+ case CAPI_CMD_DEBUG_FILE:
+ ctx->debug_file = BUF_strdup(p);
+ CAPI_trace(ctx, "Setting debug file to %s\n", ctx->debug_file);
+ break;
+
+ case CAPI_CMD_KEYTYPE:
+ ctx->keytype = i;
+ CAPI_trace(ctx, "Setting key type to %d\n", ctx->keytype);
+ break;
+
+ case CAPI_CMD_SET_CSP_IDX:
+ ret = capi_ctx_set_provname_idx(ctx, i);
+ break;
+
+ case CAPI_CMD_LIST_OPTIONS:
+ ctx->dump_flags = i;
+ break;
+
+ case CAPI_CMD_LOOKUP_METHOD:
+ if (i < 1 || i > 3)
+ {
+ CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_INVALID_LOOKUP_METHOD);
+ return 0;
+ }
+ ctx->lookup_method = i;
+ break;
+
+ case CAPI_CMD_SET_CSP_NAME:
+ ret = capi_ctx_set_provname(ctx, p, ctx->csptype, 1);
+ break;
+
+ case CAPI_CMD_SET_CSP_TYPE:
+ ctx->csptype = i;
+ break;
+
+ default:
+ CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_UNKNOWN_COMMAND);
+ ret = 0;
+ }
+
+ BIO_free(out);
+ return ret;
+
+ }
+
+static RSA_METHOD capi_rsa_method =
+ {
+ "CryptoAPI RSA method",
+ 0, /* pub_enc */
+ 0, /* pub_dec */
+ capi_rsa_priv_enc, /* priv_enc */
+ capi_rsa_priv_dec, /* priv_dec */
+ 0, /* rsa_mod_exp */
+ 0, /* bn_mod_exp */
+ 0, /* init */
+ capi_rsa_free, /* finish */
+ RSA_FLAG_SIGN_VER, /* flags */
+ NULL, /* app_data */
+ capi_rsa_sign, /* rsa_sign */
+ 0 /* rsa_verify */
+ };
+
+static DSA_METHOD capi_dsa_method =
+ {
+ "CryptoAPI DSA method",
+ capi_dsa_do_sign, /* dsa_do_sign */
+ 0, /* dsa_sign_setup */
+ 0, /* dsa_do_verify */
+ 0, /* dsa_mod_exp */
+ 0, /* bn_mod_exp */
+ 0, /* init */
+ capi_dsa_free, /* finish */
+ 0, /* flags */
+ NULL, /* app_data */
+ 0, /* dsa_paramgen */
+ 0 /* dsa_keygen */
+ };
+
+static int capi_init(ENGINE *e)
+ {
+ CAPI_CTX *ctx;
+ const RSA_METHOD *ossl_rsa_meth;
+ const DSA_METHOD *ossl_dsa_meth;
+ capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0);
+ cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0);
+
+ ctx = capi_ctx_new();
+ if (!ctx || (capi_idx < 0))
+ goto memerr;
+
+ ENGINE_set_ex_data(e, capi_idx, ctx);
+ /* Setup RSA_METHOD */
+ rsa_capi_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
+ ossl_rsa_meth = RSA_PKCS1_SSLeay();
+ capi_rsa_method.rsa_pub_enc = ossl_rsa_meth->rsa_pub_enc;
+ capi_rsa_method.rsa_pub_dec = ossl_rsa_meth->rsa_pub_dec;
+ capi_rsa_method.rsa_mod_exp = ossl_rsa_meth->rsa_mod_exp;
+ capi_rsa_method.bn_mod_exp = ossl_rsa_meth->bn_mod_exp;
+
+ /* Setup DSA Method */
+ dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
+ ossl_dsa_meth = DSA_OpenSSL();
+ capi_dsa_method.dsa_do_verify = ossl_dsa_meth->dsa_do_verify;
+ capi_dsa_method.dsa_mod_exp = ossl_dsa_meth->dsa_mod_exp;
+ capi_dsa_method.bn_mod_exp = ossl_dsa_meth->bn_mod_exp;
+
+#ifdef OPENSSL_CAPIENG_DIALOG
+ {
+ HMODULE cryptui = LoadLibrary(TEXT("CRYPTUI.DLL"));
+ HMODULE kernel = LoadLibrary(TEXT("KERNEL32.DLL"));
+ if (cryptui)
+ ctx->certselectdlg = (CERTDLG)GetProcAddress(cryptui, "CryptUIDlgSelectCertificateFromStore");
+ if (kernel)
+ ctx->getconswindow = (GETCONSWIN)GetProcAddress(kernel, "GetConsoleWindow");
+ if (cryptui && !OPENSSL_isservice())
+ ctx->client_cert_select = cert_select_dialog;
+ }
+#endif
+
+
+ return 1;
+
+ memerr:
+ CAPIerr(CAPI_F_CAPI_INIT, ERR_R_MALLOC_FAILURE);
+ return 0;
+
+ return 1;
+ }
+
+static int capi_destroy(ENGINE *e)
+ {
+ ERR_unload_CAPI_strings();
+ return 1;
+ }
+
+static int capi_finish(ENGINE *e)
+ {
+ CAPI_CTX *ctx;
+ ctx = ENGINE_get_ex_data(e, capi_idx);
+ capi_ctx_free(ctx);
+ ENGINE_set_ex_data(e, capi_idx, NULL);
+ return 1;
+ }
+
+
+/* CryptoAPI key application data. This contains
+ * a handle to the private key container (for sign operations)
+ * and a handle to the key (for decrypt operations).
+ */
+
+struct CAPI_KEY_st
+ {
+ /* Associated certificate context (if any) */
+ PCCERT_CONTEXT pcert;
+ HCRYPTPROV hprov;
+ HCRYPTKEY key;
+ DWORD keyspec;
+ };
+
+static int bind_capi(ENGINE *e)
+ {
+ if (!ENGINE_set_id(e, engine_capi_id)
+ || !ENGINE_set_name(e, engine_capi_name)
+ || !ENGINE_set_init_function(e, capi_init)
+ || !ENGINE_set_finish_function(e, capi_finish)
+ || !ENGINE_set_destroy_function(e, capi_destroy)
+ || !ENGINE_set_RSA(e, &capi_rsa_method)
+ || !ENGINE_set_DSA(e, &capi_dsa_method)
+ || !ENGINE_set_load_privkey_function(e, capi_load_privkey)
+ || !ENGINE_set_load_ssl_client_cert_function(e,
+ capi_load_ssl_client_cert)
+ || !ENGINE_set_cmd_defns(e, capi_cmd_defns)
+ || !ENGINE_set_ctrl_function(e, capi_ctrl))
+ return 0;
+ ERR_load_CAPI_strings();
+
+ return 1;
+
+ }
+
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_helper(ENGINE *e, const char *id)
+ {
+ if(id && (strcmp(id, engine_capi_id) != 0))
+ return 0;
+ if(!bind_capi(e))
+ return 0;
+ return 1;
+ }
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
+#else
+static ENGINE *engine_capi(void)
+ {
+ ENGINE *ret = ENGINE_new();
+ if(!ret)
+ return NULL;
+ if(!bind_capi(ret))
+ {
+ ENGINE_free(ret);
+ return NULL;
+ }
+ return ret;
+ }
+
+void ENGINE_load_capi(void)
+ {
+ /* Copied from eng_[openssl|dyn].c */
+ ENGINE *toadd = engine_capi();
+ if(!toadd) return;
+ ENGINE_add(toadd);
+ ENGINE_free(toadd);
+ ERR_clear_error();
+ }
+#endif
+
+
+static int lend_tobn(BIGNUM *bn, unsigned char *bin, int binlen)
+ {
+ int i;
+ /* Reverse buffer in place: since this is a keyblob structure
+ * that will be freed up after conversion anyway it doesn't
+ * matter if we change it.
+ */
+ for(i = 0; i < binlen / 2; i++)
+ {
+ unsigned char c;
+ c = bin[i];
+ bin[i] = bin[binlen - i - 1];
+ bin[binlen - i - 1] = c;
+ }
+
+ if (!BN_bin2bn(bin, binlen, bn))
+ return 0;
+ return 1;
+ }
+
+/* Given a CAPI_KEY get an EVP_PKEY structure */
+
+static EVP_PKEY *capi_get_pkey(ENGINE *eng, CAPI_KEY *key)
+ {
+ unsigned char *pubkey = NULL;
+ DWORD len;
+ BLOBHEADER *bh;
+ RSA *rkey = NULL;
+ DSA *dkey = NULL;
+ EVP_PKEY *ret = NULL;
+ if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, NULL, &len))
+ {
+ CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR);
+ capi_addlasterror();
+ return NULL;
+ }
+
+ pubkey = OPENSSL_malloc(len);
+
+ if (!pubkey)
+ goto memerr;
+
+ if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, pubkey, &len))
+ {
+ CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_ERROR);
+ capi_addlasterror();
+ goto err;
+ }
+
+ bh = (BLOBHEADER *)pubkey;
+ if (bh->bType != PUBLICKEYBLOB)
+ {
+ CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_PUBLIC_KEY_BLOB);
+ goto err;
+ }
+ if (bh->aiKeyAlg == CALG_RSA_SIGN || bh->aiKeyAlg == CALG_RSA_KEYX)
+ {
+ RSAPUBKEY *rp;
+ DWORD rsa_modlen;
+ unsigned char *rsa_modulus;
+ rp = (RSAPUBKEY *)(bh + 1);
+ if (rp->magic != 0x31415352)
+ {
+ char magstr[10];
+ BIO_snprintf(magstr, 10, "%lx", rp->magic);
+ CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER);
+ ERR_add_error_data(2, "magic=0x", magstr);
+ goto err;
+ }
+ rsa_modulus = (unsigned char *)(rp + 1);
+ rkey = RSA_new_method(eng);
+ if (!rkey)
+ goto memerr;
+
+ rkey->e = BN_new();
+ rkey->n = BN_new();
+
+ if (!rkey->e || !rkey->n)
+ goto memerr;
+
+ if (!BN_set_word(rkey->e, rp->pubexp))
+ goto memerr;
+
+ rsa_modlen = rp->bitlen / 8;
+ if (!lend_tobn(rkey->n, rsa_modulus, rsa_modlen))
+ goto memerr;
+
+ RSA_set_ex_data(rkey, rsa_capi_idx, key);
+
+ if (!(ret = EVP_PKEY_new()))
+ goto memerr;
+
+ EVP_PKEY_assign_RSA(ret, rkey);
+ rkey = NULL;
+
+ }
+ else if (bh->aiKeyAlg == CALG_DSS_SIGN)
+ {
+ DSSPUBKEY *dp;
+ DWORD dsa_plen;
+ unsigned char *btmp;
+ dp = (DSSPUBKEY *)(bh + 1);
+ if (dp->magic != 0x31535344)
+ {
+ char magstr[10];
+ BIO_snprintf(magstr, 10, "%lx", dp->magic);
+ CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER);
+ ERR_add_error_data(2, "magic=0x", magstr);
+ goto err;
+ }
+ dsa_plen = dp->bitlen / 8;
+ btmp = (unsigned char *)(dp + 1);
+ dkey = DSA_new_method(eng);
+ if (!dkey)
+ goto memerr;
+ dkey->p = BN_new();
+ dkey->q = BN_new();
+ dkey->g = BN_new();
+ dkey->pub_key = BN_new();
+ if (!dkey->p || !dkey->q || !dkey->g || !dkey->pub_key)
+ goto memerr;
+ if (!lend_tobn(dkey->p, btmp, dsa_plen))
+ goto memerr;
+ btmp += dsa_plen;
+ if (!lend_tobn(dkey->q, btmp, 20))
+ goto memerr;
+ btmp += 20;
+ if (!lend_tobn(dkey->g, btmp, dsa_plen))
+ goto memerr;
+ btmp += dsa_plen;
+ if (!lend_tobn(dkey->pub_key, btmp, dsa_plen))
+ goto memerr;
+ btmp += dsa_plen;
+
+ DSA_set_ex_data(dkey, dsa_capi_idx, key);
+
+ if (!(ret = EVP_PKEY_new()))
+ goto memerr;
+
+ EVP_PKEY_assign_DSA(ret, dkey);
+ dkey = NULL;
+ }
+ else
+ {
+ char algstr[10];
+ BIO_snprintf(algstr, 10, "%lx", bh->aiKeyAlg);
+ CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM);
+ ERR_add_error_data(2, "aiKeyAlg=0x", algstr);
+ goto err;
+ }
+
+
+ err:
+ if (pubkey)
+ OPENSSL_free(pubkey);
+ if (!ret)
+ {
+ if (rkey)
+ RSA_free(rkey);
+ if (dkey)
+ DSA_free(dkey);
+ }
+
+ return ret;
+
+memerr:
+ CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_MALLOC_FAILURE);
+ goto err;
+
+ }
+
+static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id,
+ UI_METHOD *ui_method, void *callback_data)
+ {
+ CAPI_CTX *ctx;
+ CAPI_KEY *key;
+ EVP_PKEY *ret;
+ ctx = ENGINE_get_ex_data(eng, capi_idx);
+
+ if (!ctx)
+ {
+ CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_CANT_FIND_CAPI_CONTEXT);
+ return NULL;
+ }
+
+ key = capi_find_key(ctx, key_id);
+
+ if (!key)
+ return NULL;
+
+ ret = capi_get_pkey(eng, key);
+
+ if (!ret)
+ capi_free_key(key);
+ return ret;
+
+ }
+
+/* CryptoAPI RSA operations */
+
+int capi_rsa_priv_enc(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding)
+ {
+ CAPIerr(CAPI_F_CAPI_RSA_PRIV_ENC, CAPI_R_FUNCTION_NOT_SUPPORTED);
+ return -1;
+ }
+
+int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len,
+ unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
+ {
+ ALG_ID alg;
+ HCRYPTHASH hash;
+ DWORD slen;
+ unsigned int i;
+ int ret = -1;
+ CAPI_KEY *capi_key;
+ CAPI_CTX *ctx;
+
+ ctx = ENGINE_get_ex_data(rsa->engine, capi_idx);
+
+ CAPI_trace(ctx, "Called CAPI_rsa_sign()\n");
+
+ capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
+ if (!capi_key)
+ {
+ CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_GET_KEY);
+ return -1;
+ }
+/* Convert the signature type to a CryptoAPI algorithm ID */
+ switch(dtype)
+ {
+ case NID_sha1:
+ alg = CALG_SHA1;
+ break;
+
+ case NID_md5:
+ alg = CALG_MD5;
+ break;
+
+ case NID_md5_sha1:
+ alg = CALG_SSL3_SHAMD5;
+ break;
+ default:
+ {
+ char algstr[10];
+ BIO_snprintf(algstr, 10, "%lx", dtype);
+ CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_UNSUPPORTED_ALGORITHM_NID);
+ ERR_add_error_data(2, "NID=0x", algstr);
+ return -1;
+ }
+ }
+
+
+
+/* Create the hash object */
+ if(!CryptCreateHash(capi_key->hprov, alg, 0, 0, &hash))
+ {
+ CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT);
+ capi_addlasterror();
+ return -1;
+ }
+/* Set the hash value to the value passed */
+
+ if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)m, 0))
+ {
+ CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
+ capi_addlasterror();
+ goto err;
+ }
+
+
+/* Finally sign it */
+ slen = RSA_size(rsa);
+ if(!CryptSignHash(hash, capi_key->keyspec, NULL, 0, sigret, &slen))
+ {
+ CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_ERROR_SIGNING_HASH);
+ capi_addlasterror();
+ goto err;
+ }
+ else
+ {
+ ret = 1;
+ /* Inplace byte reversal of signature */
+ for(i = 0; i < slen / 2; i++)
+ {
+ unsigned char c;
+ c = sigret[i];
+ sigret[i] = sigret[slen - i - 1];
+ sigret[slen - i - 1] = c;
+ }
+ *siglen = slen;
+ }
+
+ /* Now cleanup */
+
+err:
+ CryptDestroyHash(hash);
+
+ return ret;
+ }
+
+int capi_rsa_priv_dec(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding)
+ {
+ int i;
+ unsigned char *tmpbuf;
+ CAPI_KEY *capi_key;
+ CAPI_CTX *ctx;
+ ctx = ENGINE_get_ex_data(rsa->engine, capi_idx);
+
+ CAPI_trace(ctx, "Called capi_rsa_priv_dec()\n");
+
+
+ capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
+ if (!capi_key)
+ {
+ CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_CANT_GET_KEY);
+ return -1;
+ }
+
+ if(padding != RSA_PKCS1_PADDING)
+ {
+ char errstr[10];
+ BIO_snprintf(errstr, 10, "%d", padding);
+ CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_UNSUPPORTED_PADDING);
+ ERR_add_error_data(2, "padding=", errstr);
+ return -1;
+ }
+
+ /* Create temp reverse order version of input */
+ if(!(tmpbuf = OPENSSL_malloc(flen)) )
+ {
+ CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ for(i = 0; i < flen; i++)
+ tmpbuf[flen - i - 1] = from[i];
+
+ /* Finally decrypt it */
+ if(!CryptDecrypt(capi_key->key, 0, TRUE, 0, tmpbuf, &flen))
+ {
+ CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_DECRYPT_ERROR);
+ capi_addlasterror();
+ OPENSSL_free(tmpbuf);
+ return -1;
+ }
+ else memcpy(to, tmpbuf, flen);
+
+ OPENSSL_free(tmpbuf);
+
+ return flen;
+ }
+
+static int capi_rsa_free(RSA *rsa)
+ {
+ CAPI_KEY *capi_key;
+ capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
+ capi_free_key(capi_key);
+ RSA_set_ex_data(rsa, rsa_capi_idx, 0);
+ return 1;
+ }
+
+/* CryptoAPI DSA operations */
+
+static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen,
+ DSA *dsa)
+ {
+ HCRYPTHASH hash;
+ DWORD slen;
+ DSA_SIG *ret = NULL;
+ CAPI_KEY *capi_key;
+ CAPI_CTX *ctx;
+ unsigned char csigbuf[40];
+
+ ctx = ENGINE_get_ex_data(dsa->engine, capi_idx);
+
+ CAPI_trace(ctx, "Called CAPI_dsa_do_sign()\n");
+
+ capi_key = DSA_get_ex_data(dsa, dsa_capi_idx);
+
+ if (!capi_key)
+ {
+ CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_GET_KEY);
+ return NULL;
+ }
+
+ if (dlen != 20)
+ {
+ CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_INVALID_DIGEST_LENGTH);
+ return NULL;
+ }
+
+ /* Create the hash object */
+ if(!CryptCreateHash(capi_key->hprov, CALG_SHA1, 0, 0, &hash))
+ {
+ CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT);
+ capi_addlasterror();
+ return NULL;
+ }
+
+ /* Set the hash value to the value passed */
+ if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)digest, 0))
+ {
+ CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
+ capi_addlasterror();
+ goto err;
+ }
+
+
+ /* Finally sign it */
+ slen = sizeof(csigbuf);
+ if(!CryptSignHash(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen))
+ {
+ CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_ERROR_SIGNING_HASH);
+ capi_addlasterror();
+ goto err;
+ }
+ else
+ {
+ ret = DSA_SIG_new();
+ if (!ret)
+ goto err;
+ ret->r = BN_new();
+ ret->s = BN_new();
+ if (!ret->r || !ret->s)
+ goto err;
+ if (!lend_tobn(ret->r, csigbuf, 20)
+ || !lend_tobn(ret->s, csigbuf + 20, 20))
+ {
+ DSA_SIG_free(ret);
+ ret = NULL;
+ goto err;
+ }
+ }
+
+ /* Now cleanup */
+
+err:
+ OPENSSL_cleanse(csigbuf, 40);
+ CryptDestroyHash(hash);
+ return ret;
+ }
+
+static int capi_dsa_free(DSA *dsa)
+ {
+ CAPI_KEY *capi_key;
+ capi_key = DSA_get_ex_data(dsa, dsa_capi_idx);
+ capi_free_key(capi_key);
+ DSA_set_ex_data(dsa, dsa_capi_idx, 0);
+ return 1;
+ }
+
+static void capi_vtrace(CAPI_CTX *ctx, int level, char *format, va_list argptr)
+ {
+ BIO *out;
+
+ if (!ctx || (ctx->debug_level < level) || (!ctx->debug_file))
+ return;
+ out = BIO_new_file(ctx->debug_file, "a+");
+ BIO_vprintf(out, format, argptr);
+ BIO_free(out);
+ }
+
+static void CAPI_trace(CAPI_CTX *ctx, char *format, ...)
+ {
+ va_list args;
+ va_start(args, format);
+ capi_vtrace(ctx, CAPI_DBG_TRACE, format, args);
+ va_end(args);
+ }
+
+static void capi_addlasterror(void)
+ {
+ capi_adderror(GetLastError());
+ }
+
+static void capi_adderror(DWORD err)
+ {
+ char errstr[10];
+ BIO_snprintf(errstr, 10, "%lX", err);
+ ERR_add_error_data(2, "Error code= 0x", errstr);
+ }
+
+static char *wide_to_asc(LPWSTR wstr)
+ {
+ char *str;
+ if (!wstr)
+ return NULL;
+ str = OPENSSL_malloc(wcslen(wstr) + 1);
+ if (!str)
+ {
+ CAPIerr(CAPI_F_WIDE_TO_ASC, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ sprintf(str, "%S", wstr);
+ return str;
+ }
+
+static int capi_get_provname(CAPI_CTX *ctx, LPSTR *pname, DWORD *ptype, DWORD idx)
+ {
+ LPSTR name;
+ DWORD len, err;
+ CAPI_trace(ctx, "capi_get_provname, index=%d\n", idx);
+ if (!CryptEnumProviders(idx, NULL, 0, ptype, NULL, &len))
+ {
+ err = GetLastError();
+ if (err == ERROR_NO_MORE_ITEMS)
+ return 2;
+ CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR);
+ capi_adderror(err);
+ return 0;
+ }
+ name = OPENSSL_malloc(len);
+ if (!CryptEnumProviders(idx, NULL, 0, ptype, name, &len))
+ {
+ err = GetLastError();
+ if (err == ERROR_NO_MORE_ITEMS)
+ return 2;
+ CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR);
+ capi_adderror(err);
+ return 0;
+ }
+ *pname = name;
+ CAPI_trace(ctx, "capi_get_provname, returned name=%s, type=%d\n", name, *ptype);
+
+ return 1;
+ }
+
+static int capi_list_providers(CAPI_CTX *ctx, BIO *out)
+ {
+ DWORD idx, ptype;
+ int ret;
+ LPTSTR provname = NULL;
+ CAPI_trace(ctx, "capi_list_providers\n");
+ BIO_printf(out, "Available CSPs:\n");
+ for(idx = 0; ; idx++)
+ {
+ ret = capi_get_provname(ctx, &provname, &ptype, idx);
+ if (ret == 2)
+ break;
+ if (ret == 0)
+ break;
+ BIO_printf(out, "%d. %s, type %d\n", idx, provname, ptype);
+ OPENSSL_free(provname);
+ }
+ return 1;
+ }
+
+static int capi_list_containers(CAPI_CTX *ctx, BIO *out)
+ {
+ int ret = 1;
+ HCRYPTPROV hprov;
+ DWORD err, idx, flags, buflen = 0, clen;
+ LPSTR cname;
+ CAPI_trace(ctx, "Listing containers CSP=%s, type = %d\n", ctx->cspname, ctx->csptype);
+ if (!CryptAcquireContext(&hprov, NULL, ctx->cspname, ctx->csptype, CRYPT_VERIFYCONTEXT))
+ {
+ CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
+ capi_addlasterror();
+ return 0;
+ }
+ if (!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, NULL, &buflen, CRYPT_FIRST))
+ {
+ CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR);
+ capi_addlasterror();
+ return 0;
+ }
+ CAPI_trace(ctx, "Got max container len %d\n", buflen);
+ if (buflen == 0)
+ buflen = 1024;
+ cname = OPENSSL_malloc(buflen);
+ if (!cname)
+ {
+ CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ for (idx = 0;;idx++)
+ {
+ clen = buflen;
+ cname[0] = 0;
+
+ if (idx == 0)
+ flags = CRYPT_FIRST;
+ else
+ flags = 0;
+ if(!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, cname, &clen, flags))
+ {
+ err = GetLastError();
+ if (err == ERROR_NO_MORE_ITEMS)
+ goto done;
+ CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR);
+ capi_adderror(err);
+ goto err;
+ }
+ CAPI_trace(ctx, "Container name %s, len=%d, index=%d, flags=%d\n", cname, clen, idx, flags);
+ if (!cname[0] && (clen == buflen))
+ {
+ CAPI_trace(ctx, "Enumerate bug: using workaround\n");
+ goto done;
+ }
+ BIO_printf(out, "%d. %s\n", idx, cname);
+ }
+ err:
+
+ ret = 0;
+
+ done:
+ if (cname)
+ OPENSSL_free(cname);
+ CryptReleaseContext(hprov, 0);
+
+ return ret;
+ }
+
+CRYPT_KEY_PROV_INFO *capi_get_prov_info(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
+ {
+ DWORD len;
+ CRYPT_KEY_PROV_INFO *pinfo;
+
+ if(!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len))
+ return NULL;
+ pinfo = OPENSSL_malloc(len);
+ if (!pinfo)
+ {
+ CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ if(!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len))
+ {
+ CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO);
+ capi_addlasterror();
+ OPENSSL_free(pinfo);
+ return NULL;
+ }
+ return pinfo;
+ }
+
+static void capi_dump_prov_info(CAPI_CTX *ctx, BIO *out, CRYPT_KEY_PROV_INFO *pinfo)
+ {
+ char *provname = NULL, *contname = NULL;
+ if (!pinfo)
+ {
+ BIO_printf(out, " No Private Key\n");
+ return;
+ }
+ provname = wide_to_asc(pinfo->pwszProvName);
+ contname = wide_to_asc(pinfo->pwszContainerName);
+ if (!provname || !contname)
+ goto err;
+
+ BIO_printf(out, " Private Key Info:\n");
+ BIO_printf(out, " Provider Name: %s, Provider Type %d\n", provname, pinfo->dwProvType);
+ BIO_printf(out, " Container Name: %s, Key Type %d\n", contname, pinfo->dwKeySpec);
+ err:
+ if (provname)
+ OPENSSL_free(provname);
+ if (contname)
+ OPENSSL_free(contname);
+ }
+
+char * capi_cert_get_fname(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
+ {
+ LPWSTR wfname;
+ DWORD dlen;
+
+ CAPI_trace(ctx, "capi_cert_get_fname\n");
+ if (!CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dlen))
+ return NULL;
+ wfname = OPENSSL_malloc(dlen);
+ if (CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, wfname, &dlen))
+ {
+ char *fname = wide_to_asc(wfname);
+ OPENSSL_free(wfname);
+ return fname;
+ }
+ CAPIerr(CAPI_F_CAPI_CERT_GET_FNAME, CAPI_R_ERROR_GETTING_FRIENDLY_NAME);
+ capi_addlasterror();
+
+ OPENSSL_free(wfname);
+ return NULL;
+ }
+
+
+void capi_dump_cert(CAPI_CTX *ctx, BIO *out, PCCERT_CONTEXT cert)
+ {
+ X509 *x;
+ unsigned char *p;
+ unsigned long flags = ctx->dump_flags;
+ if (flags & CAPI_DMP_FNAME)
+ {
+ char *fname;
+ fname = capi_cert_get_fname(ctx, cert);
+ if (fname)
+ {
+ BIO_printf(out, " Friendly Name \"%s\"\n", fname);
+ OPENSSL_free(fname);
+ }
+ else
+ BIO_printf(out, " <No Friendly Name>\n");
+ }
+
+ p = cert->pbCertEncoded;
+ x = d2i_X509(NULL, &p, cert->cbCertEncoded);
+ if (!x)
+ BIO_printf(out, " <Can't parse certificate>\n");
+ if (flags & CAPI_DMP_SUMMARY)
+ {
+ BIO_printf(out, " Subject: ");
+ X509_NAME_print_ex(out, X509_get_subject_name(x), 0, XN_FLAG_ONELINE);
+ BIO_printf(out, "\n Issuer: ");
+ X509_NAME_print_ex(out, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE);
+ BIO_printf(out, "\n");
+ }
+ if (flags & CAPI_DMP_FULL)
+ X509_print_ex(out, x, XN_FLAG_ONELINE,0);
+
+ if (flags & CAPI_DMP_PKEYINFO)
+ {
+ CRYPT_KEY_PROV_INFO *pinfo;
+ pinfo = capi_get_prov_info(ctx, cert);
+ capi_dump_prov_info(ctx, out, pinfo);
+ if (pinfo)
+ OPENSSL_free(pinfo);
+ }
+
+ if (flags & CAPI_DMP_PEM)
+ PEM_write_bio_X509(out, x);
+ X509_free(x);
+ }
+
+HCERTSTORE capi_open_store(CAPI_CTX *ctx, char *storename)
+ {
+ HCERTSTORE hstore;
+
+ if (!storename)
+ storename = ctx->storename;
+ if (!storename)
+ storename = "MY";
+ CAPI_trace(ctx, "Opening certificate store %s\n", storename);
+
+ hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0,
+ ctx->store_flags, storename);
+ if (!hstore)
+ {
+ CAPIerr(CAPI_F_CAPI_OPEN_STORE, CAPI_R_ERROR_OPENING_STORE);
+ capi_addlasterror();
+ }
+ return hstore;
+ }
+
+int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *id)
+ {
+ char *storename;
+ int idx;
+ int ret = 1;
+ HCERTSTORE hstore;
+ PCCERT_CONTEXT cert = NULL;
+
+ storename = ctx->storename;
+ if (!storename)
+ storename = "MY";
+ CAPI_trace(ctx, "Listing certs for store %s\n", storename);
+
+ hstore = capi_open_store(ctx, storename);
+ if (!hstore)
+ return 0;
+ if (id)
+ {
+ cert = capi_find_cert(ctx, id, hstore);
+ if (!cert)
+ {
+ ret = 0;
+ goto err;
+ }
+ capi_dump_cert(ctx, out, cert);
+ CertFreeCertificateContext(cert);
+ }
+ else
+ {
+ for(idx = 0;;idx++)
+ {
+ LPWSTR fname = NULL;
+ cert = CertEnumCertificatesInStore(hstore, cert);
+ if (!cert)
+ break;
+ BIO_printf(out, "Certificate %d\n", idx);
+ capi_dump_cert(ctx, out, cert);
+ }
+ }
+ err:
+ CertCloseStore(hstore, 0);
+ return ret;
+ }
+
+static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE hstore)
+ {
+ PCCERT_CONTEXT cert = NULL;
+ char *fname = NULL;
+ int match;
+ switch(ctx->lookup_method)
+ {
+ case CAPI_LU_SUBSTR:
+ return CertFindCertificateInStore(hstore,
+ X509_ASN_ENCODING, 0,
+ CERT_FIND_SUBJECT_STR_A, id, NULL);
+ case CAPI_LU_FNAME:
+ for(;;)
+ {
+ cert = CertEnumCertificatesInStore(hstore, cert);
+ if (!cert)
+ return NULL;
+ fname = capi_cert_get_fname(ctx, cert);
+ if (fname)
+ {
+ if (strcmp(fname, id))
+ match = 0;
+ else
+ match = 1;
+ OPENSSL_free(fname);
+ if (match)
+ return cert;
+ }
+ }
+ default:
+ return NULL;
+ }
+ }
+
+static CAPI_KEY *capi_get_key(CAPI_CTX *ctx, const char *contname, char *provname, DWORD ptype, DWORD keyspec)
+ {
+ CAPI_KEY *key;
+ key = OPENSSL_malloc(sizeof(CAPI_KEY));
+ CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n",
+ contname, provname, ptype);
+ if (!CryptAcquireContext(&key->hprov, contname, provname, ptype, 0))
+ {
+ CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
+ capi_addlasterror();
+ goto err;
+ }
+ if (!CryptGetUserKey(key->hprov, keyspec, &key->key))
+ {
+ CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_GETUSERKEY_ERROR);
+ capi_addlasterror();
+ CryptReleaseContext(key->hprov, 0);
+ goto err;
+ }
+ key->keyspec = keyspec;
+ key->pcert = NULL;
+ return key;
+
+ err:
+ OPENSSL_free(key);
+ return NULL;
+ }
+
+static CAPI_KEY *capi_get_cert_key(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
+ {
+ CAPI_KEY *key = NULL;
+ CRYPT_KEY_PROV_INFO *pinfo = NULL;
+ char *provname = NULL, *contname = NULL;
+ pinfo = capi_get_prov_info(ctx, cert);
+ if (!pinfo)
+ goto err;
+ provname = wide_to_asc(pinfo->pwszProvName);
+ contname = wide_to_asc(pinfo->pwszContainerName);
+ if (!provname || !contname)
+ goto err;
+ key = capi_get_key(ctx, contname, provname,
+ pinfo->dwProvType, pinfo->dwKeySpec);
+
+ err:
+ if (pinfo)
+ OPENSSL_free(pinfo);
+ if (provname)
+ OPENSSL_free(provname);
+ if (contname)
+ OPENSSL_free(contname);
+ return key;
+ }
+
+CAPI_KEY *capi_find_key(CAPI_CTX *ctx, const char *id)
+ {
+ PCCERT_CONTEXT cert;
+ HCERTSTORE hstore;
+ CAPI_KEY *key = NULL;
+ switch (ctx->lookup_method)
+ {
+ case CAPI_LU_SUBSTR:
+ case CAPI_LU_FNAME:
+ hstore = capi_open_store(ctx, NULL);
+ if (!hstore)
+ return NULL;
+ cert = capi_find_cert(ctx, id, hstore);
+ if (cert)
+ {
+ key = capi_get_cert_key(ctx, cert);
+ CertFreeCertificateContext(cert);
+ }
+ CertCloseStore(hstore, 0);
+ break;
+
+ case CAPI_LU_CONTNAME:
+ key = capi_get_key(ctx, id, ctx->cspname, ctx->csptype,
+ ctx->keytype);
+ break;
+ }
+
+ return key;
+ }
+
+void capi_free_key(CAPI_KEY *key)
+ {
+ if (!key)
+ return;
+ CryptDestroyKey(key->key);
+ CryptReleaseContext(key->hprov, 0);
+ if (key->pcert)
+ CertFreeCertificateContext(key->pcert);
+ OPENSSL_free(key);
+ }
+
+
+/* Initialize a CAPI_CTX structure */
+
+static CAPI_CTX *capi_ctx_new()
+ {
+ CAPI_CTX *ctx;
+ ctx = OPENSSL_malloc(sizeof(CAPI_CTX));
+ if (!ctx)
+ {
+ CAPIerr(CAPI_F_CAPI_CTX_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ ctx->cspname = NULL;
+ ctx->csptype = PROV_RSA_FULL;
+ ctx->dump_flags = CAPI_DMP_SUMMARY|CAPI_DMP_FNAME;
+ ctx->keytype = AT_KEYEXCHANGE;
+ ctx->storename = NULL;
+ ctx->ssl_client_store = NULL;
+ ctx->store_flags = CERT_STORE_OPEN_EXISTING_FLAG |
+ CERT_STORE_READONLY_FLAG |
+ CERT_SYSTEM_STORE_CURRENT_USER;
+ ctx->lookup_method = CAPI_LU_SUBSTR;
+ ctx->debug_level = 0;
+ ctx->debug_file = NULL;
+ ctx->client_cert_select = cert_select_simple;
+ return ctx;
+ }
+
+static void capi_ctx_free(CAPI_CTX *ctx)
+ {
+ CAPI_trace(ctx, "Calling capi_ctx_free with %lx\n", ctx);
+ if (!ctx)
+ return;
+ if (ctx->cspname)
+ OPENSSL_free(ctx->cspname);
+ if (ctx->debug_file)
+ OPENSSL_free(ctx->debug_file);
+ if (ctx->storename)
+ OPENSSL_free(ctx->storename);
+ if (ctx->ssl_client_store)
+ OPENSSL_free(ctx->ssl_client_store);
+ OPENSSL_free(ctx);
+ }
+
+static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int check)
+ {
+ CAPI_trace(ctx, "capi_ctx_set_provname, name=%s, type=%d\n", pname, type);
+ if (check)
+ {
+ HCRYPTPROV hprov;
+ if (!CryptAcquireContext(&hprov, NULL, pname, type,
+ CRYPT_VERIFYCONTEXT))
+ {
+ CAPIerr(CAPI_F_CAPI_CTX_SET_PROVNAME, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
+ capi_addlasterror();
+ return 0;
+ }
+ CryptReleaseContext(hprov, 0);
+ }
+ ctx->cspname = BUF_strdup(pname);
+ ctx->csptype = type;
+ return 1;
+ }
+
+static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx)
+ {
+ LPSTR pname;
+ DWORD type;
+ if (capi_get_provname(ctx, &pname, &type, idx) != 1)
+ return 0;
+ return capi_ctx_set_provname(ctx, pname, type, 0);
+ }
+
+static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x)
+ {
+ int i;
+ X509_NAME *nm;
+ /* Special case: empty list: match anything */
+ if (sk_X509_NAME_num(ca_dn) <= 0)
+ return 1;
+ for (i = 0; i < sk_X509_NAME_num(ca_dn); i++)
+ {
+ nm = sk_X509_NAME_value(ca_dn, i);
+ if (!X509_NAME_cmp(nm, X509_get_issuer_name(x)))
+ return 1;
+ }
+ return 0;
+ }
+
+
+
+static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
+ STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
+ STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data)
+ {
+ STACK_OF(X509) *certs = NULL;
+ X509 *x;
+ char *storename;
+ const char *p;
+ int i, client_cert_idx;
+ HCERTSTORE hstore;
+ PCCERT_CONTEXT cert = NULL, excert = NULL;
+ CAPI_CTX *ctx;
+ CAPI_KEY *key;
+ ctx = ENGINE_get_ex_data(e, capi_idx);
+
+ *pcert = NULL;
+ *pkey = NULL;
+
+ storename = ctx->ssl_client_store;
+ if (!storename)
+ storename = "MY";
+
+ hstore = capi_open_store(ctx, storename);
+ if (!hstore)
+ return 0;
+ /* Enumerate all certificates collect any matches */
+ for(i = 0;;i++)
+ {
+ cert = CertEnumCertificatesInStore(hstore, cert);
+ if (!cert)
+ break;
+ p = cert->pbCertEncoded;
+ x = d2i_X509(NULL, &p, cert->cbCertEncoded);
+ if (!x)
+ {
+ CAPI_trace(ctx, "Can't Parse Certificate %d\n", i);
+ continue;
+ }
+ if (cert_issuer_match(ca_dn, x)
+ && X509_check_purpose(x, X509_PURPOSE_SSL_CLIENT, 0))
+ {
+ key = capi_get_cert_key(ctx, cert);
+ if (!key)
+ {
+ X509_free(x);
+ continue;
+ }
+ /* Match found: attach extra data to it so
+ * we can retrieve the key later.
+ */
+ excert = CertDuplicateCertificateContext(cert);
+ key->pcert = excert;
+ X509_set_ex_data(x, cert_capi_idx, key);
+
+ if (!certs)
+ certs = sk_X509_new_null();
+
+ sk_X509_push(certs, x);
+ }
+ else
+ X509_free(x);
+
+ }
+
+ if (cert)
+ CertFreeCertificateContext(cert);
+ if (hstore)
+ CertCloseStore(hstore, 0);
+
+ if (!certs)
+ return 0;
+
+
+ /* Select the appropriate certificate */
+
+ client_cert_idx = ctx->client_cert_select(e, ssl, certs);
+
+ /* Set the selected certificate and free the rest */
+
+ for(i = 0; i < sk_X509_num(certs); i++)
+ {
+ x = sk_X509_value(certs, i);
+ if (i == client_cert_idx)
+ *pcert = x;
+ else
+ {
+ key = X509_get_ex_data(x, cert_capi_idx);
+ capi_free_key(key);
+ X509_free(x);
+ }
+ }
+
+ sk_X509_free(certs);
+
+ if (!*pcert)
+ return 0;
+
+ /* Setup key for selected certificate */
+
+ key = X509_get_ex_data(*pcert, cert_capi_idx);
+ *pkey = capi_get_pkey(e, key);
+ X509_set_ex_data(*pcert, cert_capi_idx, NULL);
+
+ return 1;
+
+ }
+
+
+/* Simple client cert selection function: always select first */
+
+static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
+ {
+ return 0;
+ }
+
+#ifdef OPENSSL_CAPIENG_DIALOG
+
+/* More complex cert selection function, using standard function
+ * CryptUIDlgSelectCertificateFromStore() to produce a dialog box.
+ */
+
+/* Definitions which are in cryptuiapi.h but this is not present in older
+ * versions of headers.
+ */
+
+#ifndef CRYPTUI_SELECT_LOCATION_COLUMN
+#define CRYPTUI_SELECT_LOCATION_COLUMN 0x000000010
+#define CRYPTUI_SELECT_INTENDEDUSE_COLUMN 0x000000004
+#endif
+
+#define dlg_title L"OpenSSL Application SSL Client Certificate Selection"
+#define dlg_prompt L"Select a certificate to use for authentication"
+#define dlg_columns CRYPTUI_SELECT_LOCATION_COLUMN \
+ |CRYPTUI_SELECT_INTENDEDUSE_COLUMN
+
+static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
+ {
+ X509 *x;
+ HCERTSTORE dstore;
+ PCCERT_CONTEXT cert;
+ CAPI_CTX *ctx;
+ CAPI_KEY *key;
+ HWND hwnd;
+ int i, idx = -1;
+ if (sk_X509_num(certs) == 1)
+ return 0;
+ ctx = ENGINE_get_ex_data(e, capi_idx);
+ /* Create an in memory store of certificates */
+ dstore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
+ CERT_STORE_CREATE_NEW_FLAG, NULL);
+ if (!dstore)
+ {
+ CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_CREATING_STORE);
+ capi_addlasterror();
+ goto err;
+ }
+ /* Add all certificates to store */
+ for(i = 0; i < sk_X509_num(certs); i++)
+ {
+ x = sk_X509_value(certs, i);
+ key = X509_get_ex_data(x, cert_capi_idx);
+
+ if (!CertAddCertificateContextToStore(dstore, key->pcert,
+ CERT_STORE_ADD_NEW, NULL))
+ {
+ CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_ADDING_CERT);
+ capi_addlasterror();
+ goto err;
+ }
+
+ }
+ hwnd = GetForegroundWindow();
+ if (!hwnd)
+ hwnd = GetActiveWindow();
+ if (!hwnd && ctx->getconswindow)
+ hwnd = ctx->getconswindow();
+ /* Call dialog to select one */
+ cert = ctx->certselectdlg(dstore, hwnd, dlg_title, dlg_prompt,
+ dlg_columns, 0, NULL);
+
+ /* Find matching cert from list */
+ if (cert)
+ {
+ for(i = 0; i < sk_X509_num(certs); i++)
+ {
+ x = sk_X509_value(certs, i);
+ key = X509_get_ex_data(x, cert_capi_idx);
+ if (CertCompareCertificate(
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ cert->pCertInfo,
+ key->pcert->pCertInfo))
+ {
+ idx = i;
+ break;
+ }
+ }
+ }
+
+ err:
+ if (dstore)
+ CertCloseStore(dstore, 0);
+ return idx;
+
+ }
+#endif
+
+#endif
+#else /* !WIN32 */
+#include <openssl/engine.h>
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+OPENSSL_EXPORT
+int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; }
+IMPLEMENT_DYNAMIC_CHECK_FN()
+#endif
+#endif
diff --git a/openssl/engines/e_capi.ec b/openssl/engines/e_capi.ec
new file mode 100644
index 000000000..d2ad668a9
--- /dev/null
+++ b/openssl/engines/e_capi.ec
@@ -0,0 +1 @@
+L CAPI e_capi_err.h e_capi_err.c
diff --git a/openssl/engines/e_capi_err.c b/openssl/engines/e_capi_err.c
new file mode 100644
index 000000000..73bbaaa71
--- /dev/null
+++ b/openssl/engines/e_capi_err.c
@@ -0,0 +1,183 @@
+/* e_capi_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include "e_capi_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA CAPI_str_functs[]=
+ {
+{ERR_FUNC(CAPI_F_CAPI_CERT_GET_FNAME), "CAPI_CERT_GET_FNAME"},
+{ERR_FUNC(CAPI_F_CAPI_CTRL), "CAPI_CTRL"},
+{ERR_FUNC(CAPI_F_CAPI_CTX_NEW), "CAPI_CTX_NEW"},
+{ERR_FUNC(CAPI_F_CAPI_CTX_SET_PROVNAME), "CAPI_CTX_SET_PROVNAME"},
+{ERR_FUNC(CAPI_F_CAPI_DSA_DO_SIGN), "CAPI_DSA_DO_SIGN"},
+{ERR_FUNC(CAPI_F_CAPI_GET_KEY), "CAPI_GET_KEY"},
+{ERR_FUNC(CAPI_F_CAPI_GET_PKEY), "CAPI_GET_PKEY"},
+{ERR_FUNC(CAPI_F_CAPI_GET_PROVNAME), "CAPI_GET_PROVNAME"},
+{ERR_FUNC(CAPI_F_CAPI_GET_PROV_INFO), "CAPI_GET_PROV_INFO"},
+{ERR_FUNC(CAPI_F_CAPI_INIT), "CAPI_INIT"},
+{ERR_FUNC(CAPI_F_CAPI_LIST_CONTAINERS), "CAPI_LIST_CONTAINERS"},
+{ERR_FUNC(CAPI_F_CAPI_LOAD_PRIVKEY), "CAPI_LOAD_PRIVKEY"},
+{ERR_FUNC(CAPI_F_CAPI_OPEN_STORE), "CAPI_OPEN_STORE"},
+{ERR_FUNC(CAPI_F_CAPI_RSA_PRIV_DEC), "CAPI_RSA_PRIV_DEC"},
+{ERR_FUNC(CAPI_F_CAPI_RSA_PRIV_ENC), "CAPI_RSA_PRIV_ENC"},
+{ERR_FUNC(CAPI_F_CAPI_RSA_SIGN), "CAPI_RSA_SIGN"},
+{ERR_FUNC(CAPI_F_CERT_SELECT_DIALOG), "CERT_SELECT_DIALOG"},
+{ERR_FUNC(CAPI_F_CLIENT_CERT_SELECT), "CLIENT_CERT_SELECT"},
+{ERR_FUNC(CAPI_F_WIDE_TO_ASC), "WIDE_TO_ASC"},
+{0,NULL}
+ };
+
+static ERR_STRING_DATA CAPI_str_reasons[]=
+ {
+{ERR_REASON(CAPI_R_CANT_CREATE_HASH_OBJECT),"cant create hash object"},
+{ERR_REASON(CAPI_R_CANT_FIND_CAPI_CONTEXT),"cant find capi context"},
+{ERR_REASON(CAPI_R_CANT_GET_KEY) ,"cant get key"},
+{ERR_REASON(CAPI_R_CANT_SET_HASH_VALUE) ,"cant set hash value"},
+{ERR_REASON(CAPI_R_CRYPTACQUIRECONTEXT_ERROR),"cryptacquirecontext error"},
+{ERR_REASON(CAPI_R_CRYPTENUMPROVIDERS_ERROR),"cryptenumproviders error"},
+{ERR_REASON(CAPI_R_DECRYPT_ERROR) ,"decrypt error"},
+{ERR_REASON(CAPI_R_ENGINE_NOT_INITIALIZED),"engine not initialized"},
+{ERR_REASON(CAPI_R_ENUMCONTAINERS_ERROR) ,"enumcontainers error"},
+{ERR_REASON(CAPI_R_ERROR_ADDING_CERT) ,"error adding cert"},
+{ERR_REASON(CAPI_R_ERROR_CREATING_STORE) ,"error creating store"},
+{ERR_REASON(CAPI_R_ERROR_GETTING_FRIENDLY_NAME),"error getting friendly name"},
+{ERR_REASON(CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO),"error getting key provider info"},
+{ERR_REASON(CAPI_R_ERROR_OPENING_STORE) ,"error opening store"},
+{ERR_REASON(CAPI_R_ERROR_SIGNING_HASH) ,"error signing hash"},
+{ERR_REASON(CAPI_R_FUNCTION_NOT_SUPPORTED),"function not supported"},
+{ERR_REASON(CAPI_R_GETUSERKEY_ERROR) ,"getuserkey error"},
+{ERR_REASON(CAPI_R_INVALID_DIGEST_LENGTH),"invalid digest length"},
+{ERR_REASON(CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER),"invalid dsa public key blob magic number"},
+{ERR_REASON(CAPI_R_INVALID_LOOKUP_METHOD),"invalid lookup method"},
+{ERR_REASON(CAPI_R_INVALID_PUBLIC_KEY_BLOB),"invalid public key blob"},
+{ERR_REASON(CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER),"invalid rsa public key blob magic number"},
+{ERR_REASON(CAPI_R_PUBKEY_EXPORT_ERROR) ,"pubkey export error"},
+{ERR_REASON(CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR),"pubkey export length error"},
+{ERR_REASON(CAPI_R_UNKNOWN_COMMAND) ,"unknown command"},
+{ERR_REASON(CAPI_R_UNSUPPORTED_ALGORITHM_NID),"unsupported algorithm nid"},
+{ERR_REASON(CAPI_R_UNSUPPORTED_PADDING) ,"unsupported padding"},
+{ERR_REASON(CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM),"unsupported public key algorithm"},
+{0,NULL}
+ };
+
+#endif
+
+#ifdef CAPI_LIB_NAME
+static ERR_STRING_DATA CAPI_lib_name[]=
+ {
+{0 ,CAPI_LIB_NAME},
+{0,NULL}
+ };
+#endif
+
+
+static int CAPI_lib_error_code=0;
+static int CAPI_error_init=1;
+
+static void ERR_load_CAPI_strings(void)
+ {
+ if (CAPI_lib_error_code == 0)
+ CAPI_lib_error_code=ERR_get_next_error_library();
+
+ if (CAPI_error_init)
+ {
+ CAPI_error_init=0;
+#ifndef OPENSSL_NO_ERR
+ ERR_load_strings(CAPI_lib_error_code,CAPI_str_functs);
+ ERR_load_strings(CAPI_lib_error_code,CAPI_str_reasons);
+#endif
+
+#ifdef CAPI_LIB_NAME
+ CAPI_lib_name->error = ERR_PACK(CAPI_lib_error_code,0,0);
+ ERR_load_strings(0,CAPI_lib_name);
+#endif
+ }
+ }
+
+static void ERR_unload_CAPI_strings(void)
+ {
+ if (CAPI_error_init == 0)
+ {
+#ifndef OPENSSL_NO_ERR
+ ERR_unload_strings(CAPI_lib_error_code,CAPI_str_functs);
+ ERR_unload_strings(CAPI_lib_error_code,CAPI_str_reasons);
+#endif
+
+#ifdef CAPI_LIB_NAME
+ ERR_unload_strings(0,CAPI_lib_name);
+#endif
+ CAPI_error_init=1;
+ }
+ }
+
+static void ERR_CAPI_error(int function, int reason, char *file, int line)
+ {
+ if (CAPI_lib_error_code == 0)
+ CAPI_lib_error_code=ERR_get_next_error_library();
+ ERR_PUT_error(CAPI_lib_error_code,function,reason,file,line);
+ }
diff --git a/openssl/engines/e_capi_err.h b/openssl/engines/e_capi_err.h
new file mode 100644
index 000000000..efdb75125
--- /dev/null
+++ b/openssl/engines/e_capi_err.h
@@ -0,0 +1,123 @@
+/* ====================================================================
+ * Copyright (c) 2001-2008 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_CAPI_ERR_H
+#define HEADER_CAPI_ERR_H
+
+/* 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.
+ */
+static void ERR_load_CAPI_strings(void);
+static void ERR_unload_CAPI_strings(void);
+static void ERR_CAPI_error(int function, int reason, char *file, int line);
+#define CAPIerr(f,r) ERR_CAPI_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the CAPI functions. */
+
+/* Function codes. */
+#define CAPI_F_CAPI_CERT_GET_FNAME 99
+#define CAPI_F_CAPI_CTRL 100
+#define CAPI_F_CAPI_CTX_NEW 101
+#define CAPI_F_CAPI_CTX_SET_PROVNAME 102
+#define CAPI_F_CAPI_DSA_DO_SIGN 114
+#define CAPI_F_CAPI_GET_KEY 103
+#define CAPI_F_CAPI_GET_PKEY 115
+#define CAPI_F_CAPI_GET_PROVNAME 104
+#define CAPI_F_CAPI_GET_PROV_INFO 105
+#define CAPI_F_CAPI_INIT 106
+#define CAPI_F_CAPI_LIST_CONTAINERS 107
+#define CAPI_F_CAPI_LOAD_PRIVKEY 108
+#define CAPI_F_CAPI_OPEN_STORE 109
+#define CAPI_F_CAPI_RSA_PRIV_DEC 110
+#define CAPI_F_CAPI_RSA_PRIV_ENC 111
+#define CAPI_F_CAPI_RSA_SIGN 112
+#define CAPI_F_CERT_SELECT_DIALOG 117
+#define CAPI_F_CLIENT_CERT_SELECT 116
+#define CAPI_F_WIDE_TO_ASC 113
+
+/* Reason codes. */
+#define CAPI_R_CANT_CREATE_HASH_OBJECT 99
+#define CAPI_R_CANT_FIND_CAPI_CONTEXT 100
+#define CAPI_R_CANT_GET_KEY 101
+#define CAPI_R_CANT_SET_HASH_VALUE 102
+#define CAPI_R_CRYPTACQUIRECONTEXT_ERROR 103
+#define CAPI_R_CRYPTENUMPROVIDERS_ERROR 104
+#define CAPI_R_DECRYPT_ERROR 105
+#define CAPI_R_ENGINE_NOT_INITIALIZED 106
+#define CAPI_R_ENUMCONTAINERS_ERROR 107
+#define CAPI_R_ERROR_ADDING_CERT 125
+#define CAPI_R_ERROR_CREATING_STORE 126
+#define CAPI_R_ERROR_GETTING_FRIENDLY_NAME 108
+#define CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO 109
+#define CAPI_R_ERROR_OPENING_STORE 110
+#define CAPI_R_ERROR_SIGNING_HASH 111
+#define CAPI_R_FUNCTION_NOT_SUPPORTED 112
+#define CAPI_R_GETUSERKEY_ERROR 113
+#define CAPI_R_INVALID_DIGEST_LENGTH 124
+#define CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER 122
+#define CAPI_R_INVALID_LOOKUP_METHOD 114
+#define CAPI_R_INVALID_PUBLIC_KEY_BLOB 115
+#define CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER 123
+#define CAPI_R_PUBKEY_EXPORT_ERROR 116
+#define CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR 117
+#define CAPI_R_UNKNOWN_COMMAND 118
+#define CAPI_R_UNSUPPORTED_ALGORITHM_NID 119
+#define CAPI_R_UNSUPPORTED_PADDING 120
+#define CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM 121
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/e_chil.c b/openssl/engines/e_chil.c
new file mode 100644
index 000000000..e1847622e
--- /dev/null
+++ b/openssl/engines/e_chil.c
@@ -0,0 +1,1368 @@
+/* crypto/engine/e_chil.c -*- mode: C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org), Geoff Thorpe
+ * (geoff@geoffthorpe.net) and Dr Stephen N Henson (steve@openssl.org)
+ * for the OpenSSL project 2000.
+ */
+/* ====================================================================
+ * 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/crypto.h>
+#include <openssl/pem.h>
+#include <openssl/dso.h>
+#include <openssl/engine.h>
+#include <openssl/ui.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_CHIL
+
+/* Attribution notice: nCipher have said several times that it's OK for
+ * us to implement a general interface to their boxes, and recently declared
+ * their HWCryptoHook to be public, and therefore available for us to use.
+ * Thanks, nCipher.
+ *
+ * The hwcryptohook.h included here is from May 2000.
+ * [Richard Levitte]
+ */
+#ifdef FLAT_INC
+#include "hwcryptohook.h"
+#else
+#include "vendor_defns/hwcryptohook.h"
+#endif
+
+#define HWCRHK_LIB_NAME "CHIL engine"
+#include "e_chil_err.c"
+
+static int hwcrhk_destroy(ENGINE *e);
+static int hwcrhk_init(ENGINE *e);
+static int hwcrhk_finish(ENGINE *e);
+static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+
+/* Functions to handle mutexes */
+static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*);
+static int hwcrhk_mutex_lock(HWCryptoHook_Mutex*);
+static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex*);
+static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*);
+
+/* BIGNUM stuff */
+static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+
+#ifndef OPENSSL_NO_RSA
+/* RSA stuff */
+static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+#endif
+#ifndef OPENSSL_NO_RSA
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* DH stuff */
+/* This function is alised to mod_exp (with the DH and mont dropped). */
+static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
+ const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+#endif
+
+/* RAND stuff */
+static int hwcrhk_rand_bytes(unsigned char *buf, int num);
+static int hwcrhk_rand_status(void);
+
+/* KM stuff */
+static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
+ UI_METHOD *ui_method, void *callback_data);
+static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
+ UI_METHOD *ui_method, void *callback_data);
+#ifndef OPENSSL_NO_RSA
+static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
+ int ind,long argl, void *argp);
+#endif
+
+/* Interaction stuff */
+static int hwcrhk_insert_card(const char *prompt_info,
+ const char *wrong_info,
+ HWCryptoHook_PassphraseContext *ppctx,
+ HWCryptoHook_CallerContext *cactx);
+static int hwcrhk_get_pass(const char *prompt_info,
+ int *len_io, char *buf,
+ HWCryptoHook_PassphraseContext *ppctx,
+ HWCryptoHook_CallerContext *cactx);
+static void hwcrhk_log_message(void *logstr, const char *message);
+
+/* The definitions for control commands specific to this engine */
+#define HWCRHK_CMD_SO_PATH ENGINE_CMD_BASE
+#define HWCRHK_CMD_FORK_CHECK (ENGINE_CMD_BASE + 1)
+#define HWCRHK_CMD_THREAD_LOCKING (ENGINE_CMD_BASE + 2)
+#define HWCRHK_CMD_SET_USER_INTERFACE (ENGINE_CMD_BASE + 3)
+#define HWCRHK_CMD_SET_CALLBACK_DATA (ENGINE_CMD_BASE + 4)
+static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = {
+ {HWCRHK_CMD_SO_PATH,
+ "SO_PATH",
+ "Specifies the path to the 'hwcrhk' shared library",
+ ENGINE_CMD_FLAG_STRING},
+ {HWCRHK_CMD_FORK_CHECK,
+ "FORK_CHECK",
+ "Turns fork() checking on (non-zero) or off (zero)",
+ ENGINE_CMD_FLAG_NUMERIC},
+ {HWCRHK_CMD_THREAD_LOCKING,
+ "THREAD_LOCKING",
+ "Turns thread-safe locking on (zero) or off (non-zero)",
+ ENGINE_CMD_FLAG_NUMERIC},
+ {HWCRHK_CMD_SET_USER_INTERFACE,
+ "SET_USER_INTERFACE",
+ "Set the global user interface (internal)",
+ ENGINE_CMD_FLAG_INTERNAL},
+ {HWCRHK_CMD_SET_CALLBACK_DATA,
+ "SET_CALLBACK_DATA",
+ "Set the global user interface extra data (internal)",
+ ENGINE_CMD_FLAG_INTERNAL},
+ {0, NULL, NULL, 0}
+ };
+
+#ifndef OPENSSL_NO_RSA
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD hwcrhk_rsa =
+ {
+ "CHIL RSA method",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ hwcrhk_rsa_mod_exp,
+ hwcrhk_mod_exp_mont,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* Our internal DH_METHOD that we provide pointers to */
+static DH_METHOD hwcrhk_dh =
+ {
+ "CHIL DH method",
+ NULL,
+ NULL,
+ hwcrhk_mod_exp_dh,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ NULL
+ };
+#endif
+
+static RAND_METHOD hwcrhk_rand =
+ {
+ /* "CHIL RAND method", */
+ NULL,
+ hwcrhk_rand_bytes,
+ NULL,
+ NULL,
+ hwcrhk_rand_bytes,
+ hwcrhk_rand_status,
+ };
+
+/* Constants used when creating the ENGINE */
+static const char *engine_hwcrhk_id = "chil";
+static const char *engine_hwcrhk_name = "CHIL hardware engine support";
+
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+/* Compatibility hack, the dynamic library uses this form in the path */
+static const char *engine_hwcrhk_id_alt = "ncipher";
+#endif
+
+/* Internal stuff for HWCryptoHook */
+
+/* Some structures needed for proper use of thread locks */
+/* hwcryptohook.h has some typedefs that turn struct HWCryptoHook_MutexValue
+ into HWCryptoHook_Mutex */
+struct HWCryptoHook_MutexValue
+ {
+ int lockid;
+ };
+
+/* hwcryptohook.h has some typedefs that turn
+ struct HWCryptoHook_PassphraseContextValue
+ into HWCryptoHook_PassphraseContext */
+struct HWCryptoHook_PassphraseContextValue
+ {
+ UI_METHOD *ui_method;
+ void *callback_data;
+ };
+
+/* hwcryptohook.h has some typedefs that turn
+ struct HWCryptoHook_CallerContextValue
+ into HWCryptoHook_CallerContext */
+struct HWCryptoHook_CallerContextValue
+ {
+ pem_password_cb *password_callback; /* Deprecated! Only present for
+ backward compatibility! */
+ UI_METHOD *ui_method;
+ void *callback_data;
+ };
+
+/* The MPI structure in HWCryptoHook is pretty compatible with OpenSSL
+ BIGNUM's, so lets define a couple of conversion macros */
+#define BN2MPI(mp, bn) \
+ {mp.size = bn->top * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
+#define MPI2BN(bn, mp) \
+ {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
+
+static BIO *logstream = NULL;
+static int disable_mutex_callbacks = 0;
+
+/* One might wonder why these are needed, since one can pass down at least
+ a UI_METHOD and a pointer to callback data to the key-loading functions.
+ The thing is that the ModExp and RSAImmed functions can load keys as well,
+ if the data they get is in a special, nCipher-defined format (hint: if you
+ look at the private exponent of the RSA data as a string, you'll see this
+ string: "nCipher KM tool key id", followed by some bytes, followed a key
+ identity string, followed by more bytes. This happens when you use "embed"
+ keys instead of "hwcrhk" keys). Unfortunately, those functions do not take
+ any passphrase or caller context, and our functions can't really take any
+ callback data either. Still, the "insert_card" and "get_passphrase"
+ callbacks may be called down the line, and will need to know what user
+ interface callbacks to call, and having callback data from the application
+ may be a nice thing as well, so we need to keep track of that globally. */
+static HWCryptoHook_CallerContext password_context = { NULL, NULL, NULL };
+
+/* Stuff to pass to the HWCryptoHook library */
+static HWCryptoHook_InitInfo hwcrhk_globals = {
+ HWCryptoHook_InitFlags_SimpleForkCheck, /* Flags */
+ &logstream, /* logstream */
+ sizeof(BN_ULONG), /* limbsize */
+ 0, /* mslimb first: false for BNs */
+ -1, /* msbyte first: use native */
+ 0, /* Max mutexes, 0 = no small limit */
+ 0, /* Max simultaneous, 0 = default */
+
+ /* The next few are mutex stuff: we write wrapper functions
+ around the OS mutex functions. We initialise them to 0
+ here, and change that to actual function pointers in hwcrhk_init()
+ if dynamic locks are supported (that is, if the application
+ programmer has made sure of setting up callbacks bafore starting
+ this engine) *and* if disable_mutex_callbacks hasn't been set by
+ a call to ENGINE_ctrl(ENGINE_CTRL_CHIL_NO_LOCKING). */
+ sizeof(HWCryptoHook_Mutex),
+ 0,
+ 0,
+ 0,
+ 0,
+
+ /* The next few are condvar stuff: we write wrapper functions
+ round the OS functions. Currently not implemented and not
+ and absolute necessity even in threaded programs, therefore
+ 0'ed. Will hopefully be implemented some day, since it
+ enhances the efficiency of HWCryptoHook. */
+ 0, /* sizeof(HWCryptoHook_CondVar), */
+ 0, /* hwcrhk_cv_init, */
+ 0, /* hwcrhk_cv_wait, */
+ 0, /* hwcrhk_cv_signal, */
+ 0, /* hwcrhk_cv_broadcast, */
+ 0, /* hwcrhk_cv_destroy, */
+
+ hwcrhk_get_pass, /* pass phrase */
+ hwcrhk_insert_card, /* insert a card */
+ hwcrhk_log_message /* Log message */
+};
+
+
+/* Now, to our own code */
+
+/* This internal function is used by ENGINE_chil() and possibly by the
+ * "dynamic" ENGINE support too */
+static int bind_helper(ENGINE *e)
+ {
+#ifndef OPENSSL_NO_RSA
+ const RSA_METHOD *meth1;
+#endif
+#ifndef OPENSSL_NO_DH
+ const DH_METHOD *meth2;
+#endif
+ if(!ENGINE_set_id(e, engine_hwcrhk_id) ||
+ !ENGINE_set_name(e, engine_hwcrhk_name) ||
+#ifndef OPENSSL_NO_RSA
+ !ENGINE_set_RSA(e, &hwcrhk_rsa) ||
+#endif
+#ifndef OPENSSL_NO_DH
+ !ENGINE_set_DH(e, &hwcrhk_dh) ||
+#endif
+ !ENGINE_set_RAND(e, &hwcrhk_rand) ||
+ !ENGINE_set_destroy_function(e, hwcrhk_destroy) ||
+ !ENGINE_set_init_function(e, hwcrhk_init) ||
+ !ENGINE_set_finish_function(e, hwcrhk_finish) ||
+ !ENGINE_set_ctrl_function(e, hwcrhk_ctrl) ||
+ !ENGINE_set_load_privkey_function(e, hwcrhk_load_privkey) ||
+ !ENGINE_set_load_pubkey_function(e, hwcrhk_load_pubkey) ||
+ !ENGINE_set_cmd_defns(e, hwcrhk_cmd_defns))
+ return 0;
+
+#ifndef OPENSSL_NO_RSA
+ /* We know that the "PKCS1_SSLeay()" functions hook properly
+ * to the cswift-specific mod_exp and mod_exp_crt so we use
+ * those functions. NB: We don't use ENGINE_openssl() or
+ * anything "more generic" because something like the RSAref
+ * code may not hook properly, and if you own one of these
+ * cards then you have the right to do RSA operations on it
+ * anyway! */
+ meth1 = RSA_PKCS1_SSLeay();
+ hwcrhk_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+ hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+ hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
+ hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
+#endif
+
+#ifndef OPENSSL_NO_DH
+ /* Much the same for Diffie-Hellman */
+ meth2 = DH_OpenSSL();
+ hwcrhk_dh.generate_key = meth2->generate_key;
+ hwcrhk_dh.compute_key = meth2->compute_key;
+#endif
+
+ /* Ensure the hwcrhk error handling is set up */
+ ERR_load_HWCRHK_strings();
+ return 1;
+ }
+
+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+static ENGINE *engine_chil(void)
+ {
+ ENGINE *ret = ENGINE_new();
+ if(!ret)
+ return NULL;
+ if(!bind_helper(ret))
+ {
+ ENGINE_free(ret);
+ return NULL;
+ }
+ return ret;
+ }
+
+void ENGINE_load_chil(void)
+ {
+ /* Copied from eng_[openssl|dyn].c */
+ ENGINE *toadd = engine_chil();
+ if(!toadd) return;
+ ENGINE_add(toadd);
+ ENGINE_free(toadd);
+ ERR_clear_error();
+ }
+#endif
+
+/* This is a process-global DSO handle used for loading and unloading
+ * the HWCryptoHook library. NB: This is only set (or unset) during an
+ * init() or finish() call (reference counts permitting) and they're
+ * operating with global locks, so this should be thread-safe
+ * implicitly. */
+static DSO *hwcrhk_dso = NULL;
+static HWCryptoHook_ContextHandle hwcrhk_context = 0;
+#ifndef OPENSSL_NO_RSA
+static int hndidx_rsa = -1; /* Index for KM handle. Not really used yet. */
+#endif
+
+/* These are the function pointers that are (un)set when the library has
+ * successfully (un)loaded. */
+static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL;
+static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL;
+static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL;
+#ifndef OPENSSL_NO_RSA
+static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL;
+#endif
+static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL;
+#ifndef OPENSSL_NO_RSA
+static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL;
+static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL;
+static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL;
+#endif
+static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL;
+
+/* Used in the DSO operations. */
+static const char *HWCRHK_LIBNAME = NULL;
+static void free_HWCRHK_LIBNAME(void)
+ {
+ if(HWCRHK_LIBNAME)
+ OPENSSL_free((void*)HWCRHK_LIBNAME);
+ HWCRHK_LIBNAME = NULL;
+ }
+static const char *get_HWCRHK_LIBNAME(void)
+ {
+ if(HWCRHK_LIBNAME)
+ return HWCRHK_LIBNAME;
+ return "nfhwcrhk";
+ }
+static long set_HWCRHK_LIBNAME(const char *name)
+ {
+ free_HWCRHK_LIBNAME();
+ return (((HWCRHK_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
+ }
+static const char *n_hwcrhk_Init = "HWCryptoHook_Init";
+static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish";
+static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp";
+#ifndef OPENSSL_NO_RSA
+static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA";
+#endif
+static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes";
+#ifndef OPENSSL_NO_RSA
+static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey";
+static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey";
+static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey";
+#endif
+static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT";
+
+/* HWCryptoHook library functions and mechanics - these are used by the
+ * higher-level functions further down. NB: As and where there's no
+ * error checking, take a look lower down where these functions are
+ * called, the checking and error handling is probably down there. */
+
+/* utility function to obtain a context */
+static int get_context(HWCryptoHook_ContextHandle *hac,
+ HWCryptoHook_CallerContext *cac)
+ {
+ char tempbuf[1024];
+ HWCryptoHook_ErrMsgBuf rmsg;
+
+ rmsg.buf = tempbuf;
+ rmsg.size = sizeof(tempbuf);
+
+ *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg,
+ cac);
+ if (!*hac)
+ return 0;
+ return 1;
+ }
+
+/* similarly to release one. */
+static void release_context(HWCryptoHook_ContextHandle hac)
+ {
+ p_hwcrhk_Finish(hac);
+ }
+
+/* Destructor (complements the "ENGINE_chil()" constructor) */
+static int hwcrhk_destroy(ENGINE *e)
+ {
+ free_HWCRHK_LIBNAME();
+ ERR_unload_HWCRHK_strings();
+ return 1;
+ }
+
+/* (de)initialisation functions. */
+static int hwcrhk_init(ENGINE *e)
+ {
+ HWCryptoHook_Init_t *p1;
+ HWCryptoHook_Finish_t *p2;
+ HWCryptoHook_ModExp_t *p3;
+#ifndef OPENSSL_NO_RSA
+ HWCryptoHook_RSA_t *p4;
+ HWCryptoHook_RSALoadKey_t *p5;
+ HWCryptoHook_RSAGetPublicKey_t *p6;
+ HWCryptoHook_RSAUnloadKey_t *p7;
+#endif
+ HWCryptoHook_RandomBytes_t *p8;
+ HWCryptoHook_ModExpCRT_t *p9;
+
+ if(hwcrhk_dso != NULL)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_ALREADY_LOADED);
+ goto err;
+ }
+ /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */
+ hwcrhk_dso = DSO_load(NULL, get_HWCRHK_LIBNAME(), NULL, 0);
+ if(hwcrhk_dso == NULL)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE);
+ goto err;
+ }
+ if(!(p1 = (HWCryptoHook_Init_t *)
+ DSO_bind_func(hwcrhk_dso, n_hwcrhk_Init)) ||
+ !(p2 = (HWCryptoHook_Finish_t *)
+ DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) ||
+ !(p3 = (HWCryptoHook_ModExp_t *)
+ DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) ||
+#ifndef OPENSSL_NO_RSA
+ !(p4 = (HWCryptoHook_RSA_t *)
+ DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) ||
+ !(p5 = (HWCryptoHook_RSALoadKey_t *)
+ DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSALoadKey)) ||
+ !(p6 = (HWCryptoHook_RSAGetPublicKey_t *)
+ DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAGetPublicKey)) ||
+ !(p7 = (HWCryptoHook_RSAUnloadKey_t *)
+ DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAUnloadKey)) ||
+#endif
+ !(p8 = (HWCryptoHook_RandomBytes_t *)
+ DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) ||
+ !(p9 = (HWCryptoHook_ModExpCRT_t *)
+ DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT)))
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE);
+ goto err;
+ }
+ /* Copy the pointers */
+ p_hwcrhk_Init = p1;
+ p_hwcrhk_Finish = p2;
+ p_hwcrhk_ModExp = p3;
+#ifndef OPENSSL_NO_RSA
+ p_hwcrhk_RSA = p4;
+ p_hwcrhk_RSALoadKey = p5;
+ p_hwcrhk_RSAGetPublicKey = p6;
+ p_hwcrhk_RSAUnloadKey = p7;
+#endif
+ p_hwcrhk_RandomBytes = p8;
+ p_hwcrhk_ModExpCRT = p9;
+
+ /* Check if the application decided to support dynamic locks,
+ and if it does, use them. */
+ if (disable_mutex_callbacks == 0)
+ {
+ if (CRYPTO_get_dynlock_create_callback() != NULL &&
+ CRYPTO_get_dynlock_lock_callback() != NULL &&
+ CRYPTO_get_dynlock_destroy_callback() != NULL)
+ {
+ hwcrhk_globals.mutex_init = hwcrhk_mutex_init;
+ hwcrhk_globals.mutex_acquire = hwcrhk_mutex_lock;
+ hwcrhk_globals.mutex_release = hwcrhk_mutex_unlock;
+ hwcrhk_globals.mutex_destroy = hwcrhk_mutex_destroy;
+ }
+ }
+
+ /* Try and get a context - if not, we may have a DSO but no
+ * accelerator! */
+ if(!get_context(&hwcrhk_context, &password_context))
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_UNIT_FAILURE);
+ goto err;
+ }
+ /* Everything's fine. */
+#ifndef OPENSSL_NO_RSA
+ if (hndidx_rsa == -1)
+ hndidx_rsa = RSA_get_ex_new_index(0,
+ "nFast HWCryptoHook RSA key handle",
+ NULL, NULL, hwcrhk_ex_free);
+#endif
+ return 1;
+err:
+ if(hwcrhk_dso)
+ DSO_free(hwcrhk_dso);
+ hwcrhk_dso = NULL;
+ p_hwcrhk_Init = NULL;
+ p_hwcrhk_Finish = NULL;
+ p_hwcrhk_ModExp = NULL;
+#ifndef OPENSSL_NO_RSA
+ p_hwcrhk_RSA = NULL;
+ p_hwcrhk_RSALoadKey = NULL;
+ p_hwcrhk_RSAGetPublicKey = NULL;
+ p_hwcrhk_RSAUnloadKey = NULL;
+#endif
+ p_hwcrhk_ModExpCRT = NULL;
+ p_hwcrhk_RandomBytes = NULL;
+ return 0;
+ }
+
+static int hwcrhk_finish(ENGINE *e)
+ {
+ int to_return = 1;
+ free_HWCRHK_LIBNAME();
+ if(hwcrhk_dso == NULL)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_NOT_LOADED);
+ to_return = 0;
+ goto err;
+ }
+ release_context(hwcrhk_context);
+ if(!DSO_free(hwcrhk_dso))
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_DSO_FAILURE);
+ to_return = 0;
+ goto err;
+ }
+ err:
+ if (logstream)
+ BIO_free(logstream);
+ hwcrhk_dso = NULL;
+ p_hwcrhk_Init = NULL;
+ p_hwcrhk_Finish = NULL;
+ p_hwcrhk_ModExp = NULL;
+#ifndef OPENSSL_NO_RSA
+ p_hwcrhk_RSA = NULL;
+ p_hwcrhk_RSALoadKey = NULL;
+ p_hwcrhk_RSAGetPublicKey = NULL;
+ p_hwcrhk_RSAUnloadKey = NULL;
+#endif
+ p_hwcrhk_ModExpCRT = NULL;
+ p_hwcrhk_RandomBytes = NULL;
+ return to_return;
+ }
+
+static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+ {
+ int to_return = 1;
+
+ switch(cmd)
+ {
+ case HWCRHK_CMD_SO_PATH:
+ if(hwcrhk_dso)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_ALREADY_LOADED);
+ return 0;
+ }
+ if(p == NULL)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ return set_HWCRHK_LIBNAME((const char *)p);
+ case ENGINE_CTRL_SET_LOGSTREAM:
+ {
+ BIO *bio = (BIO *)p;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ if (logstream)
+ {
+ BIO_free(logstream);
+ logstream = NULL;
+ }
+ if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1)
+ logstream = bio;
+ else
+ HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_BIO_WAS_FREED);
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ break;
+ case ENGINE_CTRL_SET_PASSWORD_CALLBACK:
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ password_context.password_callback = (pem_password_cb *)f;
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ break;
+ case ENGINE_CTRL_SET_USER_INTERFACE:
+ case HWCRHK_CMD_SET_USER_INTERFACE:
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ password_context.ui_method = (UI_METHOD *)p;
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ break;
+ case ENGINE_CTRL_SET_CALLBACK_DATA:
+ case HWCRHK_CMD_SET_CALLBACK_DATA:
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ password_context.callback_data = p;
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ break;
+ /* this enables or disables the "SimpleForkCheck" flag used in the
+ * initialisation structure. */
+ case ENGINE_CTRL_CHIL_SET_FORKCHECK:
+ case HWCRHK_CMD_FORK_CHECK:
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ if(i)
+ hwcrhk_globals.flags |=
+ HWCryptoHook_InitFlags_SimpleForkCheck;
+ else
+ hwcrhk_globals.flags &=
+ ~HWCryptoHook_InitFlags_SimpleForkCheck;
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ break;
+ /* This will prevent the initialisation function from "installing"
+ * the mutex-handling callbacks, even if they are available from
+ * within the library (or were provided to the library from the
+ * calling application). This is to remove any baggage for
+ * applications not using multithreading. */
+ case ENGINE_CTRL_CHIL_NO_LOCKING:
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ disable_mutex_callbacks = 1;
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ break;
+ case HWCRHK_CMD_THREAD_LOCKING:
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ disable_mutex_callbacks = ((i == 0) ? 0 : 1);
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ break;
+
+ /* The command isn't understood by this engine */
+ default:
+ HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,
+ HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+ to_return = 0;
+ break;
+ }
+
+ return to_return;
+ }
+
+static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
+ UI_METHOD *ui_method, void *callback_data)
+ {
+#ifndef OPENSSL_NO_RSA
+ RSA *rtmp = NULL;
+#endif
+ EVP_PKEY *res = NULL;
+#ifndef OPENSSL_NO_RSA
+ HWCryptoHook_MPI e, n;
+ HWCryptoHook_RSAKeyHandle *hptr;
+#endif
+#if !defined(OPENSSL_NO_RSA)
+ char tempbuf[1024];
+ HWCryptoHook_ErrMsgBuf rmsg;
+ HWCryptoHook_PassphraseContext ppctx;
+#endif
+
+#if !defined(OPENSSL_NO_RSA)
+ rmsg.buf = tempbuf;
+ rmsg.size = sizeof(tempbuf);
+#endif
+
+ if(!hwcrhk_context)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
+ HWCRHK_R_NOT_INITIALISED);
+ goto err;
+ }
+#ifndef OPENSSL_NO_RSA
+ hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle));
+ if (!hptr)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ ppctx.ui_method = ui_method;
+ ppctx.callback_data = callback_data;
+ if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr,
+ &rmsg, &ppctx))
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
+ HWCRHK_R_CHIL_ERROR);
+ ERR_add_error_data(1,rmsg.buf);
+ goto err;
+ }
+ if (!*hptr)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
+ HWCRHK_R_NO_KEY);
+ goto err;
+ }
+#endif
+#ifndef OPENSSL_NO_RSA
+ rtmp = RSA_new_method(eng);
+ RSA_set_ex_data(rtmp, hndidx_rsa, (char *)hptr);
+ rtmp->e = BN_new();
+ rtmp->n = BN_new();
+ rtmp->flags |= RSA_FLAG_EXT_PKEY;
+ MPI2BN(rtmp->e, e);
+ MPI2BN(rtmp->n, n);
+ if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)
+ != HWCRYPTOHOOK_ERROR_MPISIZE)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,HWCRHK_R_CHIL_ERROR);
+ ERR_add_error_data(1,rmsg.buf);
+ goto err;
+ }
+
+ bn_expand2(rtmp->e, e.size/sizeof(BN_ULONG));
+ bn_expand2(rtmp->n, n.size/sizeof(BN_ULONG));
+ MPI2BN(rtmp->e, e);
+ MPI2BN(rtmp->n, n);
+
+ if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg))
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
+ HWCRHK_R_CHIL_ERROR);
+ ERR_add_error_data(1,rmsg.buf);
+ goto err;
+ }
+ rtmp->e->top = e.size / sizeof(BN_ULONG);
+ bn_fix_top(rtmp->e);
+ rtmp->n->top = n.size / sizeof(BN_ULONG);
+ bn_fix_top(rtmp->n);
+
+ res = EVP_PKEY_new();
+ EVP_PKEY_assign_RSA(res, rtmp);
+#endif
+
+ if (!res)
+ HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
+ HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED);
+
+ return res;
+ err:
+ if (res)
+ EVP_PKEY_free(res);
+#ifndef OPENSSL_NO_RSA
+ if (rtmp)
+ RSA_free(rtmp);
+#endif
+ return NULL;
+ }
+
+static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
+ UI_METHOD *ui_method, void *callback_data)
+ {
+ EVP_PKEY *res = NULL;
+
+#ifndef OPENSSL_NO_RSA
+ res = hwcrhk_load_privkey(eng, key_id,
+ ui_method, callback_data);
+#endif
+
+ if (res)
+ switch(res->type)
+ {
+#ifndef OPENSSL_NO_RSA
+ case EVP_PKEY_RSA:
+ {
+ RSA *rsa = NULL;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
+ rsa = res->pkey.rsa;
+ res->pkey.rsa = RSA_new();
+ res->pkey.rsa->n = rsa->n;
+ res->pkey.rsa->e = rsa->e;
+ rsa->n = NULL;
+ rsa->e = NULL;
+ CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+ RSA_free(rsa);
+ }
+ break;
+#endif
+ default:
+ HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,
+ HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+ goto err;
+ }
+
+ return res;
+ err:
+ if (res)
+ EVP_PKEY_free(res);
+ return NULL;
+ }
+
+/* A little mod_exp */
+static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx)
+ {
+ char tempbuf[1024];
+ HWCryptoHook_ErrMsgBuf rmsg;
+ /* Since HWCryptoHook_MPI is pretty compatible with BIGNUM's,
+ we use them directly, plus a little macro magic. We only
+ thing we need to make sure of is that enough space is allocated. */
+ HWCryptoHook_MPI m_a, m_p, m_n, m_r;
+ int to_return, ret;
+
+ to_return = 0; /* expect failure */
+ rmsg.buf = tempbuf;
+ rmsg.size = sizeof(tempbuf);
+
+ if(!hwcrhk_context)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_NOT_INITIALISED);
+ goto err;
+ }
+ /* Prepare the params */
+ bn_expand2(r, m->top); /* Check for error !! */
+ BN2MPI(m_a, a);
+ BN2MPI(m_p, p);
+ BN2MPI(m_n, m);
+ MPI2BN(r, m_r);
+
+ /* Perform the operation */
+ ret = p_hwcrhk_ModExp(hwcrhk_context, m_a, m_p, m_n, &m_r, &rmsg);
+
+ /* Convert the response */
+ r->top = m_r.size / sizeof(BN_ULONG);
+ bn_fix_top(r);
+
+ if (ret < 0)
+ {
+ /* FIXME: When this error is returned, HWCryptoHook is
+ telling us that falling back to software computation
+ might be a good thing. */
+ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FALLBACK);
+ }
+ else
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FAILED);
+ }
+ ERR_add_error_data(1,rmsg.buf);
+ goto err;
+ }
+
+ to_return = 1;
+err:
+ return to_return;
+ }
+
+#ifndef OPENSSL_NO_RSA
+static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+ {
+ char tempbuf[1024];
+ HWCryptoHook_ErrMsgBuf rmsg;
+ HWCryptoHook_RSAKeyHandle *hptr;
+ int to_return = 0, ret;
+
+ rmsg.buf = tempbuf;
+ rmsg.size = sizeof(tempbuf);
+
+ if(!hwcrhk_context)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,HWCRHK_R_NOT_INITIALISED);
+ goto err;
+ }
+
+ /* This provides support for nForce keys. Since that's opaque data
+ all we do is provide a handle to the proper key and let HWCryptoHook
+ take care of the rest. */
+ if ((hptr = (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx_rsa))
+ != NULL)
+ {
+ HWCryptoHook_MPI m_a, m_r;
+
+ if(!rsa->n)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
+ HWCRHK_R_MISSING_KEY_COMPONENTS);
+ goto err;
+ }
+
+ /* Prepare the params */
+ bn_expand2(r, rsa->n->top); /* Check for error !! */
+ BN2MPI(m_a, I);
+ MPI2BN(r, m_r);
+
+ /* Perform the operation */
+ ret = p_hwcrhk_RSA(m_a, *hptr, &m_r, &rmsg);
+
+ /* Convert the response */
+ r->top = m_r.size / sizeof(BN_ULONG);
+ bn_fix_top(r);
+
+ if (ret < 0)
+ {
+ /* FIXME: When this error is returned, HWCryptoHook is
+ telling us that falling back to software computation
+ might be a good thing. */
+ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
+ HWCRHK_R_REQUEST_FALLBACK);
+ }
+ else
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
+ HWCRHK_R_REQUEST_FAILED);
+ }
+ ERR_add_error_data(1,rmsg.buf);
+ goto err;
+ }
+ }
+ else
+ {
+ HWCryptoHook_MPI m_a, m_p, m_q, m_dmp1, m_dmq1, m_iqmp, m_r;
+
+ if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
+ HWCRHK_R_MISSING_KEY_COMPONENTS);
+ goto err;
+ }
+
+ /* Prepare the params */
+ bn_expand2(r, rsa->n->top); /* Check for error !! */
+ BN2MPI(m_a, I);
+ BN2MPI(m_p, rsa->p);
+ BN2MPI(m_q, rsa->q);
+ BN2MPI(m_dmp1, rsa->dmp1);
+ BN2MPI(m_dmq1, rsa->dmq1);
+ BN2MPI(m_iqmp, rsa->iqmp);
+ MPI2BN(r, m_r);
+
+ /* Perform the operation */
+ ret = p_hwcrhk_ModExpCRT(hwcrhk_context, m_a, m_p, m_q,
+ m_dmp1, m_dmq1, m_iqmp, &m_r, &rmsg);
+
+ /* Convert the response */
+ r->top = m_r.size / sizeof(BN_ULONG);
+ bn_fix_top(r);
+
+ if (ret < 0)
+ {
+ /* FIXME: When this error is returned, HWCryptoHook is
+ telling us that falling back to software computation
+ might be a good thing. */
+ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
+ HWCRHK_R_REQUEST_FALLBACK);
+ }
+ else
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
+ HWCRHK_R_REQUEST_FAILED);
+ }
+ ERR_add_error_data(1,rmsg.buf);
+ goto err;
+ }
+ }
+ /* If we're here, we must be here with some semblance of success :-) */
+ to_return = 1;
+err:
+ return to_return;
+ }
+#endif
+
+#ifndef OPENSSL_NO_RSA
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+ {
+ return hwcrhk_mod_exp(r, a, p, m, ctx);
+ }
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
+ const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+ {
+ return hwcrhk_mod_exp(r, a, p, m, ctx);
+ }
+#endif
+
+/* Random bytes are good */
+static int hwcrhk_rand_bytes(unsigned char *buf, int num)
+ {
+ char tempbuf[1024];
+ HWCryptoHook_ErrMsgBuf rmsg;
+ int to_return = 0; /* assume failure */
+ int ret;
+
+ rmsg.buf = tempbuf;
+ rmsg.size = sizeof(tempbuf);
+
+ if(!hwcrhk_context)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,HWCRHK_R_NOT_INITIALISED);
+ goto err;
+ }
+
+ ret = p_hwcrhk_RandomBytes(hwcrhk_context, buf, num, &rmsg);
+ if (ret < 0)
+ {
+ /* FIXME: When this error is returned, HWCryptoHook is
+ telling us that falling back to software computation
+ might be a good thing. */
+ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,
+ HWCRHK_R_REQUEST_FALLBACK);
+ }
+ else
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,
+ HWCRHK_R_REQUEST_FAILED);
+ }
+ ERR_add_error_data(1,rmsg.buf);
+ goto err;
+ }
+ to_return = 1;
+ err:
+ return to_return;
+ }
+
+static int hwcrhk_rand_status(void)
+ {
+ return 1;
+ }
+
+/* This cleans up an RSA KM key, called when ex_data is freed */
+#ifndef OPENSSL_NO_RSA
+static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
+ int ind,long argl, void *argp)
+{
+ char tempbuf[1024];
+ HWCryptoHook_ErrMsgBuf rmsg;
+#ifndef OPENSSL_NO_RSA
+ HWCryptoHook_RSAKeyHandle *hptr;
+#endif
+#if !defined(OPENSSL_NO_RSA)
+ int ret;
+#endif
+
+ rmsg.buf = tempbuf;
+ rmsg.size = sizeof(tempbuf);
+
+#ifndef OPENSSL_NO_RSA
+ hptr = (HWCryptoHook_RSAKeyHandle *) item;
+ if(hptr)
+ {
+ ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL);
+ OPENSSL_free(hptr);
+ }
+#endif
+}
+#endif
+
+/* Mutex calls: since the HWCryptoHook model closely follows the POSIX model
+ * these just wrap the POSIX functions and add some logging.
+ */
+
+static int hwcrhk_mutex_init(HWCryptoHook_Mutex* mt,
+ HWCryptoHook_CallerContext *cactx)
+ {
+ mt->lockid = CRYPTO_get_new_dynlockid();
+ if (mt->lockid == 0)
+ return 1; /* failure */
+ return 0; /* success */
+ }
+
+static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt)
+ {
+ CRYPTO_w_lock(mt->lockid);
+ return 0;
+ }
+
+static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt)
+ {
+ CRYPTO_w_unlock(mt->lockid);
+ }
+
+static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex *mt)
+ {
+ CRYPTO_destroy_dynlockid(mt->lockid);
+ }
+
+static int hwcrhk_get_pass(const char *prompt_info,
+ int *len_io, char *buf,
+ HWCryptoHook_PassphraseContext *ppctx,
+ HWCryptoHook_CallerContext *cactx)
+ {
+ pem_password_cb *callback = NULL;
+ void *callback_data = NULL;
+ UI_METHOD *ui_method = NULL;
+
+ if (cactx)
+ {
+ if (cactx->ui_method)
+ ui_method = cactx->ui_method;
+ if (cactx->password_callback)
+ callback = cactx->password_callback;
+ if (cactx->callback_data)
+ callback_data = cactx->callback_data;
+ }
+ if (ppctx)
+ {
+ if (ppctx->ui_method)
+ {
+ ui_method = ppctx->ui_method;
+ callback = NULL;
+ }
+ if (ppctx->callback_data)
+ callback_data = ppctx->callback_data;
+ }
+ if (callback == NULL && ui_method == NULL)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_GET_PASS,HWCRHK_R_NO_CALLBACK);
+ return -1;
+ }
+
+ if (ui_method)
+ {
+ UI *ui = UI_new_method(ui_method);
+ if (ui)
+ {
+ int ok;
+ char *prompt = UI_construct_prompt(ui,
+ "pass phrase", prompt_info);
+
+ ok = UI_add_input_string(ui,prompt,
+ UI_INPUT_FLAG_DEFAULT_PWD,
+ buf,0,(*len_io) - 1);
+ UI_add_user_data(ui, callback_data);
+ UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
+
+ if (ok >= 0)
+ do
+ {
+ ok=UI_process(ui);
+ }
+ while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
+
+ if (ok >= 0)
+ *len_io = strlen(buf);
+
+ UI_free(ui);
+ OPENSSL_free(prompt);
+ }
+ }
+ else
+ {
+ *len_io = callback(buf, *len_io, 0, callback_data);
+ }
+ if(!*len_io)
+ return -1;
+ return 0;
+ }
+
+static int hwcrhk_insert_card(const char *prompt_info,
+ const char *wrong_info,
+ HWCryptoHook_PassphraseContext *ppctx,
+ HWCryptoHook_CallerContext *cactx)
+ {
+ int ok = -1;
+ UI *ui;
+ void *callback_data = NULL;
+ UI_METHOD *ui_method = NULL;
+
+ if (cactx)
+ {
+ if (cactx->ui_method)
+ ui_method = cactx->ui_method;
+ if (cactx->callback_data)
+ callback_data = cactx->callback_data;
+ }
+ if (ppctx)
+ {
+ if (ppctx->ui_method)
+ ui_method = ppctx->ui_method;
+ if (ppctx->callback_data)
+ callback_data = ppctx->callback_data;
+ }
+ if (ui_method == NULL)
+ {
+ HWCRHKerr(HWCRHK_F_HWCRHK_INSERT_CARD,
+ HWCRHK_R_NO_CALLBACK);
+ return -1;
+ }
+
+ ui = UI_new_method(ui_method);
+
+ if (ui)
+ {
+ char answer;
+ char buf[BUFSIZ];
+
+ if (wrong_info)
+ BIO_snprintf(buf, sizeof(buf)-1,
+ "Current card: \"%s\"\n", wrong_info);
+ ok = UI_dup_info_string(ui, buf);
+ if (ok >= 0 && prompt_info)
+ {
+ BIO_snprintf(buf, sizeof(buf)-1,
+ "Insert card \"%s\"", prompt_info);
+ ok = UI_dup_input_boolean(ui, buf,
+ "\n then hit <enter> or C<enter> to cancel\n",
+ "\r\n", "Cc", UI_INPUT_FLAG_ECHO, &answer);
+ }
+ UI_add_user_data(ui, callback_data);
+
+ if (ok >= 0)
+ ok = UI_process(ui);
+ UI_free(ui);
+
+ if (ok == -2 || (ok >= 0 && answer == 'C'))
+ ok = 1;
+ else if (ok < 0)
+ ok = -1;
+ else
+ ok = 0;
+ }
+ return ok;
+ }
+
+static void hwcrhk_log_message(void *logstr, const char *message)
+ {
+ BIO *lstream = NULL;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_BIO);
+ if (logstr)
+ lstream=*(BIO **)logstr;
+ if (lstream)
+ {
+ BIO_printf(lstream, "%s\n", message);
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_BIO);
+ }
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library. */
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_fn(ENGINE *e, const char *id)
+ {
+ if(id && (strcmp(id, engine_hwcrhk_id) != 0) &&
+ (strcmp(id, engine_hwcrhk_id_alt) != 0))
+ return 0;
+ if(!bind_helper(e))
+ return 0;
+ return 1;
+ }
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
+
+#endif /* !OPENSSL_NO_HW_CHIL */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_chil.ec b/openssl/engines/e_chil.ec
new file mode 100644
index 000000000..b5a76e17d
--- /dev/null
+++ b/openssl/engines/e_chil.ec
@@ -0,0 +1 @@
+L HWCRHK e_chil_err.h e_chil_err.c
diff --git a/openssl/engines/e_chil_err.c b/openssl/engines/e_chil_err.c
new file mode 100644
index 000000000..c5983b2fd
--- /dev/null
+++ b/openssl/engines/e_chil_err.c
@@ -0,0 +1,160 @@
+/* e_chil_err.c */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+/* 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 "e_chil_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA HWCRHK_str_functs[]=
+ {
+{ERR_FUNC(HWCRHK_F_HWCRHK_CTRL), "HWCRHK_CTRL"},
+{ERR_FUNC(HWCRHK_F_HWCRHK_FINISH), "HWCRHK_FINISH"},
+{ERR_FUNC(HWCRHK_F_HWCRHK_GET_PASS), "HWCRHK_GET_PASS"},
+{ERR_FUNC(HWCRHK_F_HWCRHK_INIT), "HWCRHK_INIT"},
+{ERR_FUNC(HWCRHK_F_HWCRHK_INSERT_CARD), "HWCRHK_INSERT_CARD"},
+{ERR_FUNC(HWCRHK_F_HWCRHK_LOAD_PRIVKEY), "HWCRHK_LOAD_PRIVKEY"},
+{ERR_FUNC(HWCRHK_F_HWCRHK_LOAD_PUBKEY), "HWCRHK_LOAD_PUBKEY"},
+{ERR_FUNC(HWCRHK_F_HWCRHK_MOD_EXP), "HWCRHK_MOD_EXP"},
+{ERR_FUNC(HWCRHK_F_HWCRHK_RAND_BYTES), "HWCRHK_RAND_BYTES"},
+{ERR_FUNC(HWCRHK_F_HWCRHK_RSA_MOD_EXP), "HWCRHK_RSA_MOD_EXP"},
+{0,NULL}
+ };
+
+static ERR_STRING_DATA HWCRHK_str_reasons[]=
+ {
+{ERR_REASON(HWCRHK_R_ALREADY_LOADED) ,"already loaded"},
+{ERR_REASON(HWCRHK_R_BIO_WAS_FREED) ,"bio was freed"},
+{ERR_REASON(HWCRHK_R_CHIL_ERROR) ,"chil error"},
+{ERR_REASON(HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
+{ERR_REASON(HWCRHK_R_DSO_FAILURE) ,"dso failure"},
+{ERR_REASON(HWCRHK_R_MISSING_KEY_COMPONENTS),"missing key components"},
+{ERR_REASON(HWCRHK_R_NOT_INITIALISED) ,"not initialised"},
+{ERR_REASON(HWCRHK_R_NOT_LOADED) ,"not loaded"},
+{ERR_REASON(HWCRHK_R_NO_CALLBACK) ,"no callback"},
+{ERR_REASON(HWCRHK_R_NO_KEY) ,"no key"},
+{ERR_REASON(HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED),"private key algorithms disabled"},
+{ERR_REASON(HWCRHK_R_REQUEST_FAILED) ,"request failed"},
+{ERR_REASON(HWCRHK_R_REQUEST_FALLBACK) ,"request fallback"},
+{ERR_REASON(HWCRHK_R_UNIT_FAILURE) ,"unit failure"},
+{0,NULL}
+ };
+
+#endif
+
+#ifdef HWCRHK_LIB_NAME
+static ERR_STRING_DATA HWCRHK_lib_name[]=
+ {
+{0 ,HWCRHK_LIB_NAME},
+{0,NULL}
+ };
+#endif
+
+
+static int HWCRHK_lib_error_code=0;
+static int HWCRHK_error_init=1;
+
+static void ERR_load_HWCRHK_strings(void)
+ {
+ if (HWCRHK_lib_error_code == 0)
+ HWCRHK_lib_error_code=ERR_get_next_error_library();
+
+ if (HWCRHK_error_init)
+ {
+ HWCRHK_error_init=0;
+#ifndef OPENSSL_NO_ERR
+ ERR_load_strings(HWCRHK_lib_error_code,HWCRHK_str_functs);
+ ERR_load_strings(HWCRHK_lib_error_code,HWCRHK_str_reasons);
+#endif
+
+#ifdef HWCRHK_LIB_NAME
+ HWCRHK_lib_name->error = ERR_PACK(HWCRHK_lib_error_code,0,0);
+ ERR_load_strings(0,HWCRHK_lib_name);
+#endif
+ }
+ }
+
+static void ERR_unload_HWCRHK_strings(void)
+ {
+ if (HWCRHK_error_init == 0)
+ {
+#ifndef OPENSSL_NO_ERR
+ ERR_unload_strings(HWCRHK_lib_error_code,HWCRHK_str_functs);
+ ERR_unload_strings(HWCRHK_lib_error_code,HWCRHK_str_reasons);
+#endif
+
+#ifdef HWCRHK_LIB_NAME
+ ERR_unload_strings(0,HWCRHK_lib_name);
+#endif
+ HWCRHK_error_init=1;
+ }
+ }
+
+static void ERR_HWCRHK_error(int function, int reason, char *file, int line)
+ {
+ if (HWCRHK_lib_error_code == 0)
+ HWCRHK_lib_error_code=ERR_get_next_error_library();
+ ERR_PUT_error(HWCRHK_lib_error_code,function,reason,file,line);
+ }
diff --git a/openssl/engines/e_chil_err.h b/openssl/engines/e_chil_err.h
new file mode 100644
index 000000000..3c42a0239
--- /dev/null
+++ b/openssl/engines/e_chil_err.h
@@ -0,0 +1,104 @@
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * 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_HWCRHK_ERR_H
+#define HEADER_HWCRHK_ERR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_HWCRHK_strings(void);
+static void ERR_unload_HWCRHK_strings(void);
+static void ERR_HWCRHK_error(int function, int reason, char *file, int line);
+#define HWCRHKerr(f,r) ERR_HWCRHK_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the HWCRHK functions. */
+
+/* Function codes. */
+#define HWCRHK_F_HWCRHK_CTRL 100
+#define HWCRHK_F_HWCRHK_FINISH 101
+#define HWCRHK_F_HWCRHK_GET_PASS 102
+#define HWCRHK_F_HWCRHK_INIT 103
+#define HWCRHK_F_HWCRHK_INSERT_CARD 104
+#define HWCRHK_F_HWCRHK_LOAD_PRIVKEY 105
+#define HWCRHK_F_HWCRHK_LOAD_PUBKEY 106
+#define HWCRHK_F_HWCRHK_MOD_EXP 107
+#define HWCRHK_F_HWCRHK_RAND_BYTES 108
+#define HWCRHK_F_HWCRHK_RSA_MOD_EXP 109
+
+/* Reason codes. */
+#define HWCRHK_R_ALREADY_LOADED 100
+#define HWCRHK_R_BIO_WAS_FREED 101
+#define HWCRHK_R_CHIL_ERROR 102
+#define HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED 103
+#define HWCRHK_R_DSO_FAILURE 104
+#define HWCRHK_R_MISSING_KEY_COMPONENTS 105
+#define HWCRHK_R_NOT_INITIALISED 106
+#define HWCRHK_R_NOT_LOADED 107
+#define HWCRHK_R_NO_CALLBACK 108
+#define HWCRHK_R_NO_KEY 109
+#define HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED 110
+#define HWCRHK_R_REQUEST_FAILED 111
+#define HWCRHK_R_REQUEST_FALLBACK 112
+#define HWCRHK_R_UNIT_FAILURE 113
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/e_cswift.c b/openssl/engines/e_cswift.c
new file mode 100644
index 000000000..bc6517984
--- /dev/null
+++ b/openssl/engines/e_cswift.c
@@ -0,0 +1,1131 @@
+/* crypto/engine/hw_cswift.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * 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/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/dso.h>
+#include <openssl/engine.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/rand.h>
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_CSWIFT
+
+/* Attribution notice: Rainbow have generously allowed me to reproduce
+ * the necessary definitions here from their API. This means the support
+ * can build independently of whether application builders have the
+ * API or hardware. This will allow developers to easily produce software
+ * that has latent hardware support for any users that have accelerators
+ * installed, without the developers themselves needing anything extra.
+ *
+ * I have only clipped the parts from the CryptoSwift header files that
+ * are (or seem) relevant to the CryptoSwift support code. This is
+ * simply to keep the file sizes reasonable.
+ * [Geoff]
+ */
+#ifdef FLAT_INC
+#include "cswift.h"
+#else
+#include "vendor_defns/cswift.h"
+#endif
+
+#define CSWIFT_LIB_NAME "cswift engine"
+#include "e_cswift_err.c"
+
+#define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1)
+
+static int cswift_destroy(ENGINE *e);
+static int cswift_init(ENGINE *e);
+static int cswift_finish(ENGINE *e);
+static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+#ifndef OPENSSL_NO_RSA
+static int cswift_bn_32copy(SW_LARGENUMBER * out, const BIGNUM * in);
+#endif
+
+/* BIGNUM stuff */
+static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+#ifndef OPENSSL_NO_RSA
+static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
+ const BIGNUM *iqmp, BN_CTX *ctx);
+#endif
+
+#ifndef OPENSSL_NO_RSA
+/* RSA stuff */
+static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* DSA stuff */
+static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
+static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
+ DSA_SIG *sig, DSA *dsa);
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* DH stuff */
+/* This function is alised to mod_exp (with the DH and mont dropped). */
+static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
+ const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+#endif
+
+/* RAND stuff */
+static int cswift_rand_bytes(unsigned char *buf, int num);
+static int cswift_rand_status(void);
+
+/* The definitions for control commands specific to this engine */
+#define CSWIFT_CMD_SO_PATH ENGINE_CMD_BASE
+static const ENGINE_CMD_DEFN cswift_cmd_defns[] = {
+ {CSWIFT_CMD_SO_PATH,
+ "SO_PATH",
+ "Specifies the path to the 'cswift' shared library",
+ ENGINE_CMD_FLAG_STRING},
+ {0, NULL, NULL, 0}
+ };
+
+#ifndef OPENSSL_NO_RSA
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD cswift_rsa =
+ {
+ "CryptoSwift RSA method",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ cswift_rsa_mod_exp,
+ cswift_mod_exp_mont,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* Our internal DSA_METHOD that we provide pointers to */
+static DSA_METHOD cswift_dsa =
+ {
+ "CryptoSwift DSA method",
+ cswift_dsa_sign,
+ NULL, /* dsa_sign_setup */
+ cswift_dsa_verify,
+ NULL, /* dsa_mod_exp */
+ NULL, /* bn_mod_exp */
+ NULL, /* init */
+ NULL, /* finish */
+ 0, /* flags */
+ NULL, /* app_data */
+ NULL, /* dsa_paramgen */
+ NULL /* dsa_keygen */
+ };
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* Our internal DH_METHOD that we provide pointers to */
+static DH_METHOD cswift_dh =
+ {
+ "CryptoSwift DH method",
+ NULL,
+ NULL,
+ cswift_mod_exp_dh,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ NULL
+ };
+#endif
+
+static RAND_METHOD cswift_random =
+ {
+ /* "CryptoSwift RAND method", */
+ NULL,
+ cswift_rand_bytes,
+ NULL,
+ NULL,
+ cswift_rand_bytes,
+ cswift_rand_status,
+ };
+
+
+/* Constants used when creating the ENGINE */
+static const char *engine_cswift_id = "cswift";
+static const char *engine_cswift_name = "CryptoSwift hardware engine support";
+
+/* This internal function is used by ENGINE_cswift() and possibly by the
+ * "dynamic" ENGINE support too */
+static int bind_helper(ENGINE *e)
+ {
+#ifndef OPENSSL_NO_RSA
+ const RSA_METHOD *meth1;
+#endif
+#ifndef OPENSSL_NO_DH
+ const DH_METHOD *meth2;
+#endif
+ if(!ENGINE_set_id(e, engine_cswift_id) ||
+ !ENGINE_set_name(e, engine_cswift_name) ||
+#ifndef OPENSSL_NO_RSA
+ !ENGINE_set_RSA(e, &cswift_rsa) ||
+#endif
+#ifndef OPENSSL_NO_DSA
+ !ENGINE_set_DSA(e, &cswift_dsa) ||
+#endif
+#ifndef OPENSSL_NO_DH
+ !ENGINE_set_DH(e, &cswift_dh) ||
+#endif
+ !ENGINE_set_RAND(e, &cswift_random) ||
+ !ENGINE_set_destroy_function(e, cswift_destroy) ||
+ !ENGINE_set_init_function(e, cswift_init) ||
+ !ENGINE_set_finish_function(e, cswift_finish) ||
+ !ENGINE_set_ctrl_function(e, cswift_ctrl) ||
+ !ENGINE_set_cmd_defns(e, cswift_cmd_defns))
+ return 0;
+
+#ifndef OPENSSL_NO_RSA
+ /* We know that the "PKCS1_SSLeay()" functions hook properly
+ * to the cswift-specific mod_exp and mod_exp_crt so we use
+ * those functions. NB: We don't use ENGINE_openssl() or
+ * anything "more generic" because something like the RSAref
+ * code may not hook properly, and if you own one of these
+ * cards then you have the right to do RSA operations on it
+ * anyway! */
+ meth1 = RSA_PKCS1_SSLeay();
+ cswift_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+ cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+ cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
+ cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
+#endif
+
+#ifndef OPENSSL_NO_DH
+ /* Much the same for Diffie-Hellman */
+ meth2 = DH_OpenSSL();
+ cswift_dh.generate_key = meth2->generate_key;
+ cswift_dh.compute_key = meth2->compute_key;
+#endif
+
+ /* Ensure the cswift error handling is set up */
+ ERR_load_CSWIFT_strings();
+ return 1;
+ }
+
+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+static ENGINE *engine_cswift(void)
+ {
+ ENGINE *ret = ENGINE_new();
+ if(!ret)
+ return NULL;
+ if(!bind_helper(ret))
+ {
+ ENGINE_free(ret);
+ return NULL;
+ }
+ return ret;
+ }
+
+void ENGINE_load_cswift(void)
+ {
+ /* Copied from eng_[openssl|dyn].c */
+ ENGINE *toadd = engine_cswift();
+ if(!toadd) return;
+ ENGINE_add(toadd);
+ ENGINE_free(toadd);
+ ERR_clear_error();
+ }
+#endif
+
+/* This is a process-global DSO handle used for loading and unloading
+ * the CryptoSwift library. NB: This is only set (or unset) during an
+ * init() or finish() call (reference counts permitting) and they're
+ * operating with global locks, so this should be thread-safe
+ * implicitly. */
+static DSO *cswift_dso = NULL;
+
+/* These are the function pointers that are (un)set when the library has
+ * successfully (un)loaded. */
+t_swAcquireAccContext *p_CSwift_AcquireAccContext = NULL;
+t_swAttachKeyParam *p_CSwift_AttachKeyParam = NULL;
+t_swSimpleRequest *p_CSwift_SimpleRequest = NULL;
+t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL;
+
+/* Used in the DSO operations. */
+static const char *CSWIFT_LIBNAME = NULL;
+static const char *get_CSWIFT_LIBNAME(void)
+ {
+ if(CSWIFT_LIBNAME)
+ return CSWIFT_LIBNAME;
+ return "swift";
+ }
+static void free_CSWIFT_LIBNAME(void)
+ {
+ if(CSWIFT_LIBNAME)
+ OPENSSL_free((void*)CSWIFT_LIBNAME);
+ CSWIFT_LIBNAME = NULL;
+ }
+static long set_CSWIFT_LIBNAME(const char *name)
+ {
+ free_CSWIFT_LIBNAME();
+ return (((CSWIFT_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
+ }
+static const char *CSWIFT_F1 = "swAcquireAccContext";
+static const char *CSWIFT_F2 = "swAttachKeyParam";
+static const char *CSWIFT_F3 = "swSimpleRequest";
+static const char *CSWIFT_F4 = "swReleaseAccContext";
+
+
+/* CryptoSwift library functions and mechanics - these are used by the
+ * higher-level functions further down. NB: As and where there's no
+ * error checking, take a look lower down where these functions are
+ * called, the checking and error handling is probably down there. */
+
+/* utility function to obtain a context */
+static int get_context(SW_CONTEXT_HANDLE *hac)
+ {
+ SW_STATUS status;
+
+ status = p_CSwift_AcquireAccContext(hac);
+ if(status != SW_OK)
+ return 0;
+ return 1;
+ }
+
+/* similarly to release one. */
+static void release_context(SW_CONTEXT_HANDLE hac)
+ {
+ p_CSwift_ReleaseAccContext(hac);
+ }
+
+/* Destructor (complements the "ENGINE_cswift()" constructor) */
+static int cswift_destroy(ENGINE *e)
+ {
+ free_CSWIFT_LIBNAME();
+ ERR_unload_CSWIFT_strings();
+ return 1;
+ }
+
+/* (de)initialisation functions. */
+static int cswift_init(ENGINE *e)
+ {
+ SW_CONTEXT_HANDLE hac;
+ t_swAcquireAccContext *p1;
+ t_swAttachKeyParam *p2;
+ t_swSimpleRequest *p3;
+ t_swReleaseAccContext *p4;
+
+ if(cswift_dso != NULL)
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_ALREADY_LOADED);
+ goto err;
+ }
+ /* Attempt to load libswift.so/swift.dll/whatever. */
+ cswift_dso = DSO_load(NULL, get_CSWIFT_LIBNAME(), NULL, 0);
+ if(cswift_dso == NULL)
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
+ goto err;
+ }
+ if(!(p1 = (t_swAcquireAccContext *)
+ DSO_bind_func(cswift_dso, CSWIFT_F1)) ||
+ !(p2 = (t_swAttachKeyParam *)
+ DSO_bind_func(cswift_dso, CSWIFT_F2)) ||
+ !(p3 = (t_swSimpleRequest *)
+ DSO_bind_func(cswift_dso, CSWIFT_F3)) ||
+ !(p4 = (t_swReleaseAccContext *)
+ DSO_bind_func(cswift_dso, CSWIFT_F4)))
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
+ goto err;
+ }
+ /* Copy the pointers */
+ p_CSwift_AcquireAccContext = p1;
+ p_CSwift_AttachKeyParam = p2;
+ p_CSwift_SimpleRequest = p3;
+ p_CSwift_ReleaseAccContext = p4;
+ /* Try and get a context - if not, we may have a DSO but no
+ * accelerator! */
+ if(!get_context(&hac))
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_UNIT_FAILURE);
+ goto err;
+ }
+ release_context(hac);
+ /* Everything's fine. */
+ return 1;
+err:
+ if(cswift_dso)
+ {
+ DSO_free(cswift_dso);
+ cswift_dso = NULL;
+ }
+ p_CSwift_AcquireAccContext = NULL;
+ p_CSwift_AttachKeyParam = NULL;
+ p_CSwift_SimpleRequest = NULL;
+ p_CSwift_ReleaseAccContext = NULL;
+ return 0;
+ }
+
+static int cswift_finish(ENGINE *e)
+ {
+ free_CSWIFT_LIBNAME();
+ if(cswift_dso == NULL)
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_NOT_LOADED);
+ return 0;
+ }
+ if(!DSO_free(cswift_dso))
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_UNIT_FAILURE);
+ return 0;
+ }
+ cswift_dso = NULL;
+ p_CSwift_AcquireAccContext = NULL;
+ p_CSwift_AttachKeyParam = NULL;
+ p_CSwift_SimpleRequest = NULL;
+ p_CSwift_ReleaseAccContext = NULL;
+ return 1;
+ }
+
+static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+ {
+ int initialised = ((cswift_dso == NULL) ? 0 : 1);
+ switch(cmd)
+ {
+ case CSWIFT_CMD_SO_PATH:
+ if(p == NULL)
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ if(initialised)
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_ALREADY_LOADED);
+ return 0;
+ }
+ return set_CSWIFT_LIBNAME((const char *)p);
+ default:
+ break;
+ }
+ CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+ return 0;
+ }
+
+/* Un petit mod_exp */
+static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx)
+ {
+ /* I need somewhere to store temporary serialised values for
+ * use with the CryptoSwift API calls. A neat cheat - I'll use
+ * BIGNUMs from the BN_CTX but access their arrays directly as
+ * byte arrays <grin>. This way I don't have to clean anything
+ * up. */
+ BIGNUM *modulus;
+ BIGNUM *exponent;
+ BIGNUM *argument;
+ BIGNUM *result;
+ SW_STATUS sw_status;
+ SW_LARGENUMBER arg, res;
+ SW_PARAM sw_param;
+ SW_CONTEXT_HANDLE hac;
+ int to_return, acquired;
+
+ modulus = exponent = argument = result = NULL;
+ to_return = 0; /* expect failure */
+ acquired = 0;
+
+ if(!get_context(&hac))
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_UNIT_FAILURE);
+ goto err;
+ }
+ acquired = 1;
+ /* Prepare the params */
+ BN_CTX_start(ctx);
+ modulus = BN_CTX_get(ctx);
+ exponent = BN_CTX_get(ctx);
+ argument = BN_CTX_get(ctx);
+ result = BN_CTX_get(ctx);
+ if(!result)
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_CTX_FULL);
+ goto err;
+ }
+ if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) ||
+ !bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top))
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+ sw_param.type = SW_ALG_EXP;
+ sw_param.up.exp.modulus.nbytes = BN_bn2bin(m,
+ (unsigned char *)modulus->d);
+ sw_param.up.exp.modulus.value = (unsigned char *)modulus->d;
+ sw_param.up.exp.exponent.nbytes = BN_bn2bin(p,
+ (unsigned char *)exponent->d);
+ sw_param.up.exp.exponent.value = (unsigned char *)exponent->d;
+ /* Attach the key params */
+ sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
+ switch(sw_status)
+ {
+ case SW_OK:
+ break;
+ case SW_ERR_INPUT_SIZE:
+ CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BAD_KEY_SIZE);
+ goto err;
+ default:
+ {
+ char tmpbuf[DECIMAL_SIZE(sw_status)+1];
+ CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
+ sprintf(tmpbuf, "%ld", sw_status);
+ ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+ }
+ goto err;
+ }
+ /* Prepare the argument and response */
+ arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
+ arg.value = (unsigned char *)argument->d;
+ res.nbytes = BN_num_bytes(m);
+ memset(result->d, 0, res.nbytes);
+ res.value = (unsigned char *)result->d;
+ /* Perform the operation */
+ if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1,
+ &res, 1)) != SW_OK)
+ {
+ char tmpbuf[DECIMAL_SIZE(sw_status)+1];
+ CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
+ sprintf(tmpbuf, "%ld", sw_status);
+ ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+ goto err;
+ }
+ /* Convert the response */
+ BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
+ to_return = 1;
+err:
+ if(acquired)
+ release_context(hac);
+ BN_CTX_end(ctx);
+ return to_return;
+ }
+
+
+#ifndef OPENSSL_NO_RSA
+int cswift_bn_32copy(SW_LARGENUMBER * out, const BIGNUM * in)
+{
+ int mod;
+ int numbytes = BN_num_bytes(in);
+
+ mod = 0;
+ while( ((out->nbytes = (numbytes+mod)) % 32) )
+ {
+ mod++;
+ }
+ out->value = (unsigned char*)OPENSSL_malloc(out->nbytes);
+ if(!out->value)
+ {
+ return 0;
+ }
+ BN_bn2bin(in, &out->value[mod]);
+ if(mod)
+ memset(out->value, 0, mod);
+
+ return 1;
+}
+#endif
+
+#ifndef OPENSSL_NO_RSA
+/* Un petit mod_exp chinois */
+static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *q, const BIGNUM *dmp1,
+ const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx)
+ {
+ SW_STATUS sw_status;
+ SW_LARGENUMBER arg, res;
+ SW_PARAM sw_param;
+ SW_CONTEXT_HANDLE hac;
+ BIGNUM *result = NULL;
+ BIGNUM *argument = NULL;
+ int to_return = 0; /* expect failure */
+ int acquired = 0;
+
+ sw_param.up.crt.p.value = NULL;
+ sw_param.up.crt.q.value = NULL;
+ sw_param.up.crt.dmp1.value = NULL;
+ sw_param.up.crt.dmq1.value = NULL;
+ sw_param.up.crt.iqmp.value = NULL;
+
+ if(!get_context(&hac))
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_UNIT_FAILURE);
+ goto err;
+ }
+ acquired = 1;
+
+ /* Prepare the params */
+ argument = BN_new();
+ result = BN_new();
+ if(!result || !argument)
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_CTX_FULL);
+ goto err;
+ }
+
+
+ sw_param.type = SW_ALG_CRT;
+ /************************************************************************/
+ /* 04/02/2003 */
+ /* Modified by Frederic Giudicelli (deny-all.com) to overcome the */
+ /* limitation of cswift with values not a multiple of 32 */
+ /************************************************************************/
+ if(!cswift_bn_32copy(&sw_param.up.crt.p, p))
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+ if(!cswift_bn_32copy(&sw_param.up.crt.q, q))
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+ if(!cswift_bn_32copy(&sw_param.up.crt.dmp1, dmp1))
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+ if(!cswift_bn_32copy(&sw_param.up.crt.dmq1, dmq1))
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+ if(!cswift_bn_32copy(&sw_param.up.crt.iqmp, iqmp))
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+ if( !bn_wexpand(argument, a->top) ||
+ !bn_wexpand(result, p->top + q->top))
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+
+ /* Attach the key params */
+ sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
+ switch(sw_status)
+ {
+ case SW_OK:
+ break;
+ case SW_ERR_INPUT_SIZE:
+ CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BAD_KEY_SIZE);
+ goto err;
+ default:
+ {
+ char tmpbuf[DECIMAL_SIZE(sw_status)+1];
+ CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
+ sprintf(tmpbuf, "%ld", sw_status);
+ ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+ }
+ goto err;
+ }
+ /* Prepare the argument and response */
+ arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
+ arg.value = (unsigned char *)argument->d;
+ res.nbytes = 2 * BN_num_bytes(p);
+ memset(result->d, 0, res.nbytes);
+ res.value = (unsigned char *)result->d;
+ /* Perform the operation */
+ if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1,
+ &res, 1)) != SW_OK)
+ {
+ char tmpbuf[DECIMAL_SIZE(sw_status)+1];
+ CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
+ sprintf(tmpbuf, "%ld", sw_status);
+ ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+ goto err;
+ }
+ /* Convert the response */
+ BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
+ to_return = 1;
+err:
+ if(sw_param.up.crt.p.value)
+ OPENSSL_free(sw_param.up.crt.p.value);
+ if(sw_param.up.crt.q.value)
+ OPENSSL_free(sw_param.up.crt.q.value);
+ if(sw_param.up.crt.dmp1.value)
+ OPENSSL_free(sw_param.up.crt.dmp1.value);
+ if(sw_param.up.crt.dmq1.value)
+ OPENSSL_free(sw_param.up.crt.dmq1.value);
+ if(sw_param.up.crt.iqmp.value)
+ OPENSSL_free(sw_param.up.crt.iqmp.value);
+ if(result)
+ BN_free(result);
+ if(argument)
+ BN_free(argument);
+ if(acquired)
+ release_context(hac);
+ return to_return;
+ }
+#endif
+
+#ifndef OPENSSL_NO_RSA
+static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+ {
+ int to_return = 0;
+ const RSA_METHOD * def_rsa_method;
+
+ if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_RSA_MOD_EXP,CSWIFT_R_MISSING_KEY_COMPONENTS);
+ goto err;
+ }
+
+ /* Try the limits of RSA (2048 bits) */
+ if(BN_num_bytes(rsa->p) > 128 ||
+ BN_num_bytes(rsa->q) > 128 ||
+ BN_num_bytes(rsa->dmp1) > 128 ||
+ BN_num_bytes(rsa->dmq1) > 128 ||
+ BN_num_bytes(rsa->iqmp) > 128)
+ {
+#ifdef RSA_NULL
+ def_rsa_method=RSA_null_method();
+#else
+#if 0
+ def_rsa_method=RSA_PKCS1_RSAref();
+#else
+ def_rsa_method=RSA_PKCS1_SSLeay();
+#endif
+#endif
+ if(def_rsa_method)
+ return def_rsa_method->rsa_mod_exp(r0, I, rsa, ctx);
+ }
+
+ to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
+ rsa->dmq1, rsa->iqmp, ctx);
+err:
+ return to_return;
+ }
+
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+ {
+ const RSA_METHOD * def_rsa_method;
+
+ /* Try the limits of RSA (2048 bits) */
+ if(BN_num_bytes(r) > 256 ||
+ BN_num_bytes(a) > 256 ||
+ BN_num_bytes(m) > 256)
+ {
+#ifdef RSA_NULL
+ def_rsa_method=RSA_null_method();
+#else
+#if 0
+ def_rsa_method=RSA_PKCS1_RSAref();
+#else
+ def_rsa_method=RSA_PKCS1_SSLeay();
+#endif
+#endif
+ if(def_rsa_method)
+ return def_rsa_method->bn_mod_exp(r, a, p, m, ctx, m_ctx);
+ }
+
+ return cswift_mod_exp(r, a, p, m, ctx);
+ }
+#endif /* OPENSSL_NO_RSA */
+
+#ifndef OPENSSL_NO_DSA
+static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+ {
+ SW_CONTEXT_HANDLE hac;
+ SW_PARAM sw_param;
+ SW_STATUS sw_status;
+ SW_LARGENUMBER arg, res;
+ unsigned char *ptr;
+ BN_CTX *ctx;
+ BIGNUM *dsa_p = NULL;
+ BIGNUM *dsa_q = NULL;
+ BIGNUM *dsa_g = NULL;
+ BIGNUM *dsa_key = NULL;
+ BIGNUM *result = NULL;
+ DSA_SIG *to_return = NULL;
+ int acquired = 0;
+
+ if((ctx = BN_CTX_new()) == NULL)
+ goto err;
+ if(!get_context(&hac))
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_UNIT_FAILURE);
+ goto err;
+ }
+ acquired = 1;
+ /* Prepare the params */
+ BN_CTX_start(ctx);
+ dsa_p = BN_CTX_get(ctx);
+ dsa_q = BN_CTX_get(ctx);
+ dsa_g = BN_CTX_get(ctx);
+ dsa_key = BN_CTX_get(ctx);
+ result = BN_CTX_get(ctx);
+ if(!result)
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_CTX_FULL);
+ goto err;
+ }
+ if(!bn_wexpand(dsa_p, dsa->p->top) ||
+ !bn_wexpand(dsa_q, dsa->q->top) ||
+ !bn_wexpand(dsa_g, dsa->g->top) ||
+ !bn_wexpand(dsa_key, dsa->priv_key->top) ||
+ !bn_wexpand(result, dsa->p->top))
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+ sw_param.type = SW_ALG_DSA;
+ sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
+ (unsigned char *)dsa_p->d);
+ sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
+ sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
+ (unsigned char *)dsa_q->d);
+ sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
+ sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
+ (unsigned char *)dsa_g->d);
+ sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
+ sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->priv_key,
+ (unsigned char *)dsa_key->d);
+ sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
+ /* Attach the key params */
+ sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
+ switch(sw_status)
+ {
+ case SW_OK:
+ break;
+ case SW_ERR_INPUT_SIZE:
+ CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BAD_KEY_SIZE);
+ goto err;
+ default:
+ {
+ char tmpbuf[DECIMAL_SIZE(sw_status)+1];
+ CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
+ sprintf(tmpbuf, "%ld", sw_status);
+ ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+ }
+ goto err;
+ }
+ /* Prepare the argument and response */
+ arg.nbytes = dlen;
+ arg.value = (unsigned char *)dgst;
+ res.nbytes = BN_num_bytes(dsa->p);
+ memset(result->d, 0, res.nbytes);
+ res.value = (unsigned char *)result->d;
+ /* Perform the operation */
+ sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_SIGN, &arg, 1,
+ &res, 1);
+ if(sw_status != SW_OK)
+ {
+ char tmpbuf[DECIMAL_SIZE(sw_status)+1];
+ CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
+ sprintf(tmpbuf, "%ld", sw_status);
+ ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+ goto err;
+ }
+ /* Convert the response */
+ ptr = (unsigned char *)result->d;
+ if((to_return = DSA_SIG_new()) == NULL)
+ goto err;
+ to_return->r = BN_bin2bn((unsigned char *)result->d, 20, NULL);
+ to_return->s = BN_bin2bn((unsigned char *)result->d + 20, 20, NULL);
+
+err:
+ if(acquired)
+ release_context(hac);
+ if(ctx)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return to_return;
+ }
+
+static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
+ DSA_SIG *sig, DSA *dsa)
+ {
+ SW_CONTEXT_HANDLE hac;
+ SW_PARAM sw_param;
+ SW_STATUS sw_status;
+ SW_LARGENUMBER arg[2], res;
+ unsigned long sig_result;
+ BN_CTX *ctx;
+ BIGNUM *dsa_p = NULL;
+ BIGNUM *dsa_q = NULL;
+ BIGNUM *dsa_g = NULL;
+ BIGNUM *dsa_key = NULL;
+ BIGNUM *argument = NULL;
+ int to_return = -1;
+ int acquired = 0;
+
+ if((ctx = BN_CTX_new()) == NULL)
+ goto err;
+ if(!get_context(&hac))
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_UNIT_FAILURE);
+ goto err;
+ }
+ acquired = 1;
+ /* Prepare the params */
+ BN_CTX_start(ctx);
+ dsa_p = BN_CTX_get(ctx);
+ dsa_q = BN_CTX_get(ctx);
+ dsa_g = BN_CTX_get(ctx);
+ dsa_key = BN_CTX_get(ctx);
+ argument = BN_CTX_get(ctx);
+ if(!argument)
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_CTX_FULL);
+ goto err;
+ }
+ if(!bn_wexpand(dsa_p, dsa->p->top) ||
+ !bn_wexpand(dsa_q, dsa->q->top) ||
+ !bn_wexpand(dsa_g, dsa->g->top) ||
+ !bn_wexpand(dsa_key, dsa->pub_key->top) ||
+ !bn_wexpand(argument, 40))
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+ sw_param.type = SW_ALG_DSA;
+ sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
+ (unsigned char *)dsa_p->d);
+ sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
+ sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
+ (unsigned char *)dsa_q->d);
+ sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
+ sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
+ (unsigned char *)dsa_g->d);
+ sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
+ sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->pub_key,
+ (unsigned char *)dsa_key->d);
+ sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
+ /* Attach the key params */
+ sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
+ switch(sw_status)
+ {
+ case SW_OK:
+ break;
+ case SW_ERR_INPUT_SIZE:
+ CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BAD_KEY_SIZE);
+ goto err;
+ default:
+ {
+ char tmpbuf[DECIMAL_SIZE(sw_status)+1];
+ CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
+ sprintf(tmpbuf, "%ld", sw_status);
+ ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+ }
+ goto err;
+ }
+ /* Prepare the argument and response */
+ arg[0].nbytes = dgst_len;
+ arg[0].value = (unsigned char *)dgst;
+ arg[1].nbytes = 40;
+ arg[1].value = (unsigned char *)argument->d;
+ memset(arg[1].value, 0, 40);
+ BN_bn2bin(sig->r, arg[1].value + 20 - BN_num_bytes(sig->r));
+ BN_bn2bin(sig->s, arg[1].value + 40 - BN_num_bytes(sig->s));
+ res.nbytes = 4; /* unsigned long */
+ res.value = (unsigned char *)(&sig_result);
+ /* Perform the operation */
+ sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_VERIFY, arg, 2,
+ &res, 1);
+ if(sw_status != SW_OK)
+ {
+ char tmpbuf[DECIMAL_SIZE(sw_status)+1];
+ CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
+ sprintf(tmpbuf, "%ld", sw_status);
+ ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+ goto err;
+ }
+ /* Convert the response */
+ to_return = ((sig_result == 0) ? 0 : 1);
+
+err:
+ if(acquired)
+ release_context(hac);
+ if(ctx)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return to_return;
+ }
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
+ const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+ {
+ return cswift_mod_exp(r, a, p, m, ctx);
+ }
+#endif
+
+/* Random bytes are good */
+static int cswift_rand_bytes(unsigned char *buf, int num)
+{
+ SW_CONTEXT_HANDLE hac;
+ SW_STATUS swrc;
+ SW_LARGENUMBER largenum;
+ int acquired = 0;
+ int to_return = 0; /* assume failure */
+ unsigned char buf32[1024];
+
+
+ if (!get_context(&hac))
+ {
+ CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_UNIT_FAILURE);
+ goto err;
+ }
+ acquired = 1;
+
+ /************************************************************************/
+ /* 04/02/2003 */
+ /* Modified by Frederic Giudicelli (deny-all.com) to overcome the */
+ /* limitation of cswift with values not a multiple of 32 */
+ /************************************************************************/
+
+ while(num >= (int)sizeof(buf32))
+ {
+ largenum.value = buf;
+ largenum.nbytes = sizeof(buf32);
+ /* tell CryptoSwift how many bytes we want and where we want it.
+ * Note: - CryptoSwift cannot do more than 4096 bytes at a time.
+ * - CryptoSwift can only do multiple of 32-bits. */
+ swrc = p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1);
+ if (swrc != SW_OK)
+ {
+ char tmpbuf[20];
+ CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_REQUEST_FAILED);
+ sprintf(tmpbuf, "%ld", swrc);
+ ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf);
+ goto err;
+ }
+ buf += sizeof(buf32);
+ num -= sizeof(buf32);
+ }
+ if(num)
+ {
+ largenum.nbytes = sizeof(buf32);
+ largenum.value = buf32;
+ swrc = p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1);
+ if (swrc != SW_OK)
+ {
+ char tmpbuf[20];
+ CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_REQUEST_FAILED);
+ sprintf(tmpbuf, "%ld", swrc);
+ ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf);
+ goto err;
+ }
+ memcpy(buf, largenum.value, num);
+ }
+
+ to_return = 1; /* success */
+err:
+ if (acquired)
+ release_context(hac);
+
+ return to_return;
+}
+
+static int cswift_rand_status(void)
+{
+ return 1;
+}
+
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library. */
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_fn(ENGINE *e, const char *id)
+ {
+ if(id && (strcmp(id, engine_cswift_id) != 0))
+ return 0;
+ if(!bind_helper(e))
+ return 0;
+ return 1;
+ }
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
+
+#endif /* !OPENSSL_NO_HW_CSWIFT */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_cswift.ec b/openssl/engines/e_cswift.ec
new file mode 100644
index 000000000..a7f9d1143
--- /dev/null
+++ b/openssl/engines/e_cswift.ec
@@ -0,0 +1 @@
+L CSWIFT e_cswift_err.h e_cswift_err.c
diff --git a/openssl/engines/e_cswift_err.c b/openssl/engines/e_cswift_err.c
new file mode 100644
index 000000000..c7942a31f
--- /dev/null
+++ b/openssl/engines/e_cswift_err.c
@@ -0,0 +1,154 @@
+/* e_cswift_err.c */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+/* 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 "e_cswift_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA CSWIFT_str_functs[]=
+ {
+{ERR_FUNC(CSWIFT_F_CSWIFT_CTRL), "CSWIFT_CTRL"},
+{ERR_FUNC(CSWIFT_F_CSWIFT_DSA_SIGN), "CSWIFT_DSA_SIGN"},
+{ERR_FUNC(CSWIFT_F_CSWIFT_DSA_VERIFY), "CSWIFT_DSA_VERIFY"},
+{ERR_FUNC(CSWIFT_F_CSWIFT_FINISH), "CSWIFT_FINISH"},
+{ERR_FUNC(CSWIFT_F_CSWIFT_INIT), "CSWIFT_INIT"},
+{ERR_FUNC(CSWIFT_F_CSWIFT_MOD_EXP), "CSWIFT_MOD_EXP"},
+{ERR_FUNC(CSWIFT_F_CSWIFT_MOD_EXP_CRT), "CSWIFT_MOD_EXP_CRT"},
+{ERR_FUNC(CSWIFT_F_CSWIFT_RAND_BYTES), "CSWIFT_RAND_BYTES"},
+{ERR_FUNC(CSWIFT_F_CSWIFT_RSA_MOD_EXP), "CSWIFT_RSA_MOD_EXP"},
+{0,NULL}
+ };
+
+static ERR_STRING_DATA CSWIFT_str_reasons[]=
+ {
+{ERR_REASON(CSWIFT_R_ALREADY_LOADED) ,"already loaded"},
+{ERR_REASON(CSWIFT_R_BAD_KEY_SIZE) ,"bad key size"},
+{ERR_REASON(CSWIFT_R_BN_CTX_FULL) ,"bn ctx full"},
+{ERR_REASON(CSWIFT_R_BN_EXPAND_FAIL) ,"bn expand fail"},
+{ERR_REASON(CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
+{ERR_REASON(CSWIFT_R_MISSING_KEY_COMPONENTS),"missing key components"},
+{ERR_REASON(CSWIFT_R_NOT_LOADED) ,"not loaded"},
+{ERR_REASON(CSWIFT_R_REQUEST_FAILED) ,"request failed"},
+{ERR_REASON(CSWIFT_R_UNIT_FAILURE) ,"unit failure"},
+{0,NULL}
+ };
+
+#endif
+
+#ifdef CSWIFT_LIB_NAME
+static ERR_STRING_DATA CSWIFT_lib_name[]=
+ {
+{0 ,CSWIFT_LIB_NAME},
+{0,NULL}
+ };
+#endif
+
+
+static int CSWIFT_lib_error_code=0;
+static int CSWIFT_error_init=1;
+
+static void ERR_load_CSWIFT_strings(void)
+ {
+ if (CSWIFT_lib_error_code == 0)
+ CSWIFT_lib_error_code=ERR_get_next_error_library();
+
+ if (CSWIFT_error_init)
+ {
+ CSWIFT_error_init=0;
+#ifndef OPENSSL_NO_ERR
+ ERR_load_strings(CSWIFT_lib_error_code,CSWIFT_str_functs);
+ ERR_load_strings(CSWIFT_lib_error_code,CSWIFT_str_reasons);
+#endif
+
+#ifdef CSWIFT_LIB_NAME
+ CSWIFT_lib_name->error = ERR_PACK(CSWIFT_lib_error_code,0,0);
+ ERR_load_strings(0,CSWIFT_lib_name);
+#endif
+ }
+ }
+
+static void ERR_unload_CSWIFT_strings(void)
+ {
+ if (CSWIFT_error_init == 0)
+ {
+#ifndef OPENSSL_NO_ERR
+ ERR_unload_strings(CSWIFT_lib_error_code,CSWIFT_str_functs);
+ ERR_unload_strings(CSWIFT_lib_error_code,CSWIFT_str_reasons);
+#endif
+
+#ifdef CSWIFT_LIB_NAME
+ ERR_unload_strings(0,CSWIFT_lib_name);
+#endif
+ CSWIFT_error_init=1;
+ }
+ }
+
+static void ERR_CSWIFT_error(int function, int reason, char *file, int line)
+ {
+ if (CSWIFT_lib_error_code == 0)
+ CSWIFT_lib_error_code=ERR_get_next_error_library();
+ ERR_PUT_error(CSWIFT_lib_error_code,function,reason,file,line);
+ }
diff --git a/openssl/engines/e_cswift_err.h b/openssl/engines/e_cswift_err.h
new file mode 100644
index 000000000..69c2a9f87
--- /dev/null
+++ b/openssl/engines/e_cswift_err.h
@@ -0,0 +1,98 @@
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * 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_CSWIFT_ERR_H
+#define HEADER_CSWIFT_ERR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_CSWIFT_strings(void);
+static void ERR_unload_CSWIFT_strings(void);
+static void ERR_CSWIFT_error(int function, int reason, char *file, int line);
+#define CSWIFTerr(f,r) ERR_CSWIFT_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the CSWIFT functions. */
+
+/* Function codes. */
+#define CSWIFT_F_CSWIFT_CTRL 100
+#define CSWIFT_F_CSWIFT_DSA_SIGN 101
+#define CSWIFT_F_CSWIFT_DSA_VERIFY 102
+#define CSWIFT_F_CSWIFT_FINISH 103
+#define CSWIFT_F_CSWIFT_INIT 104
+#define CSWIFT_F_CSWIFT_MOD_EXP 105
+#define CSWIFT_F_CSWIFT_MOD_EXP_CRT 106
+#define CSWIFT_F_CSWIFT_RAND_BYTES 108
+#define CSWIFT_F_CSWIFT_RSA_MOD_EXP 107
+
+/* Reason codes. */
+#define CSWIFT_R_ALREADY_LOADED 100
+#define CSWIFT_R_BAD_KEY_SIZE 101
+#define CSWIFT_R_BN_CTX_FULL 102
+#define CSWIFT_R_BN_EXPAND_FAIL 103
+#define CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED 104
+#define CSWIFT_R_MISSING_KEY_COMPONENTS 105
+#define CSWIFT_R_NOT_LOADED 106
+#define CSWIFT_R_REQUEST_FAILED 107
+#define CSWIFT_R_UNIT_FAILURE 108
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/e_gmp.c b/openssl/engines/e_gmp.c
new file mode 100644
index 000000000..a1a2d2bda
--- /dev/null
+++ b/openssl/engines/e_gmp.c
@@ -0,0 +1,476 @@
+/* crypto/engine/e_gmp.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2003.
+ */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+/* This engine is not (currently) compiled in by default. Do enable it,
+ * reconfigure OpenSSL with "enable-gmp -lgmp". The GMP libraries and
+ * headers must reside in one of the paths searched by the compiler/linker,
+ * otherwise paths must be specified - eg. try configuring with
+ * "enable-gmp -I<includepath> -L<libpath> -lgmp". YMMV. */
+
+/* As for what this does - it's a largely unoptimised implementation of an
+ * ENGINE that uses the GMP library to perform RSA private key operations. To
+ * obtain more information about what "unoptimised" means, see my original mail
+ * on the subject (though ignore the build instructions which have since
+ * changed);
+ *
+ * http://www.mail-archive.com/openssl-dev@openssl.org/msg12227.html
+ *
+ * On my athlon system at least, it appears the builtin OpenSSL code is now
+ * slightly faster, which is to say that the RSA-related MPI performance
+ * between OpenSSL's BIGNUM and GMP's mpz implementations is probably pretty
+ * balanced for this chip, and so the performance degradation in this ENGINE by
+ * having to convert to/from GMP formats (and not being able to cache
+ * montgomery forms) is probably the difference. However, if some unconfirmed
+ * reports from users is anything to go by, the situation on some other
+ * chipsets might be a good deal more favourable to the GMP version (eg. PPC).
+ * Feedback welcome. */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/engine.h>
+#include <openssl/rsa.h>
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_GMP
+
+#include <gmp.h>
+
+#define E_GMP_LIB_NAME "gmp engine"
+#include "e_gmp_err.c"
+
+static int e_gmp_destroy(ENGINE *e);
+static int e_gmp_init(ENGINE *e);
+static int e_gmp_finish(ENGINE *e);
+static int e_gmp_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+
+#ifndef OPENSSL_NO_RSA
+/* RSA stuff */
+static int e_gmp_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+static int e_gmp_rsa_finish(RSA *r);
+#endif
+
+/* The definitions for control commands specific to this engine */
+/* #define E_GMP_CMD_SO_PATH ENGINE_CMD_BASE */
+static const ENGINE_CMD_DEFN e_gmp_cmd_defns[] = {
+#if 0
+ {E_GMP_CMD_SO_PATH,
+ "SO_PATH",
+ "Specifies the path to the 'e_gmp' shared library",
+ ENGINE_CMD_FLAG_STRING},
+#endif
+ {0, NULL, NULL, 0}
+ };
+
+#ifndef OPENSSL_NO_RSA
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD e_gmp_rsa =
+ {
+ "GMP RSA method",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ e_gmp_rsa_mod_exp,
+ NULL,
+ NULL,
+ e_gmp_rsa_finish,
+ /* These flags initialise montgomery crud that GMP ignores, however it
+ * makes sure the public key ops (which are done in openssl) don't seem
+ * *slower* than usual :-) */
+ RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE,
+ NULL,
+ NULL,
+ NULL
+ };
+#endif
+
+/* Constants used when creating the ENGINE */
+static const char *engine_e_gmp_id = "gmp";
+static const char *engine_e_gmp_name = "GMP engine support";
+
+/* This internal function is used by ENGINE_gmp() and possibly by the
+ * "dynamic" ENGINE support too */
+static int bind_helper(ENGINE *e)
+ {
+#ifndef OPENSSL_NO_RSA
+ const RSA_METHOD *meth1;
+#endif
+ if(!ENGINE_set_id(e, engine_e_gmp_id) ||
+ !ENGINE_set_name(e, engine_e_gmp_name) ||
+#ifndef OPENSSL_NO_RSA
+ !ENGINE_set_RSA(e, &e_gmp_rsa) ||
+#endif
+ !ENGINE_set_destroy_function(e, e_gmp_destroy) ||
+ !ENGINE_set_init_function(e, e_gmp_init) ||
+ !ENGINE_set_finish_function(e, e_gmp_finish) ||
+ !ENGINE_set_ctrl_function(e, e_gmp_ctrl) ||
+ !ENGINE_set_cmd_defns(e, e_gmp_cmd_defns))
+ return 0;
+
+#ifndef OPENSSL_NO_RSA
+ meth1 = RSA_PKCS1_SSLeay();
+ e_gmp_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+ e_gmp_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+ e_gmp_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
+ e_gmp_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
+ e_gmp_rsa.bn_mod_exp = meth1->bn_mod_exp;
+#endif
+
+ /* Ensure the e_gmp error handling is set up */
+ ERR_load_GMP_strings();
+ return 1;
+ }
+
+static ENGINE *engine_gmp(void)
+ {
+ ENGINE *ret = ENGINE_new();
+ if(!ret)
+ return NULL;
+ if(!bind_helper(ret))
+ {
+ ENGINE_free(ret);
+ return NULL;
+ }
+ return ret;
+ }
+
+void ENGINE_load_gmp(void)
+ {
+ /* Copied from eng_[openssl|dyn].c */
+ ENGINE *toadd = engine_gmp();
+ if(!toadd) return;
+ ENGINE_add(toadd);
+ ENGINE_free(toadd);
+ ERR_clear_error();
+ }
+
+#ifndef OPENSSL_NO_RSA
+/* Used to attach our own key-data to an RSA structure */
+static int hndidx_rsa = -1;
+#endif
+
+static int e_gmp_destroy(ENGINE *e)
+ {
+ ERR_unload_GMP_strings();
+ return 1;
+ }
+
+/* (de)initialisation functions. */
+static int e_gmp_init(ENGINE *e)
+ {
+#ifndef OPENSSL_NO_RSA
+ if (hndidx_rsa == -1)
+ hndidx_rsa = RSA_get_ex_new_index(0,
+ "GMP-based RSA key handle",
+ NULL, NULL, NULL);
+#endif
+ if (hndidx_rsa == -1)
+ return 0;
+ return 1;
+ }
+
+static int e_gmp_finish(ENGINE *e)
+ {
+ return 1;
+ }
+
+static int e_gmp_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+ {
+ int to_return = 1;
+
+ switch(cmd)
+ {
+#if 0
+ case E_GMP_CMD_SO_PATH:
+ /* ... */
+#endif
+ /* The command isn't understood by this engine */
+ default:
+ GMPerr(GMP_F_E_GMP_CTRL,
+ GMP_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+ to_return = 0;
+ break;
+ }
+
+ return to_return;
+ }
+
+
+/* Most often limb sizes will be the same. If not, we use hex conversion
+ * which is neat, but extremely inefficient. */
+static int bn2gmp(const BIGNUM *bn, mpz_t g)
+ {
+ bn_check_top(bn);
+ if(((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) &&
+ (BN_BITS2 == GMP_NUMB_BITS))
+ {
+ /* The common case */
+ if(!_mpz_realloc (g, bn->top))
+ return 0;
+ memcpy(&g->_mp_d[0], &bn->d[0], bn->top * sizeof(bn->d[0]));
+ g->_mp_size = bn->top;
+ if(bn->neg)
+ g->_mp_size = -g->_mp_size;
+ return 1;
+ }
+ else
+ {
+ int toret;
+ char *tmpchar = BN_bn2hex(bn);
+ if(!tmpchar) return 0;
+ toret = (mpz_set_str(g, tmpchar, 16) == 0 ? 1 : 0);
+ OPENSSL_free(tmpchar);
+ return toret;
+ }
+ }
+
+static int gmp2bn(mpz_t g, BIGNUM *bn)
+ {
+ if(((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) &&
+ (BN_BITS2 == GMP_NUMB_BITS))
+ {
+ /* The common case */
+ int s = (g->_mp_size >= 0) ? g->_mp_size : -g->_mp_size;
+ BN_zero(bn);
+ if(bn_expand2 (bn, s) == NULL)
+ return 0;
+ bn->top = s;
+ memcpy(&bn->d[0], &g->_mp_d[0], s * sizeof(bn->d[0]));
+ bn_correct_top(bn);
+ bn->neg = g->_mp_size >= 0 ? 0 : 1;
+ return 1;
+ }
+ else
+ {
+ int toret;
+ char *tmpchar = OPENSSL_malloc(mpz_sizeinbase(g, 16) + 10);
+ if(!tmpchar) return 0;
+ mpz_get_str(tmpchar, 16, g);
+ toret = BN_hex2bn(&bn, tmpchar);
+ OPENSSL_free(tmpchar);
+ return toret;
+ }
+ }
+
+#ifndef OPENSSL_NO_RSA
+typedef struct st_e_gmp_rsa_ctx
+ {
+ int public_only;
+ mpz_t n;
+ mpz_t d;
+ mpz_t e;
+ mpz_t p;
+ mpz_t q;
+ mpz_t dmp1;
+ mpz_t dmq1;
+ mpz_t iqmp;
+ mpz_t r0, r1, I0, m1;
+ } E_GMP_RSA_CTX;
+
+static E_GMP_RSA_CTX *e_gmp_get_rsa(RSA *rsa)
+ {
+ E_GMP_RSA_CTX *hptr = RSA_get_ex_data(rsa, hndidx_rsa);
+ if(hptr) return hptr;
+ hptr = OPENSSL_malloc(sizeof(E_GMP_RSA_CTX));
+ if(!hptr) return NULL;
+ /* These inits could probably be replaced by more intelligent
+ * mpz_init2() versions, to reduce malloc-thrashing. */
+ mpz_init(hptr->n);
+ mpz_init(hptr->d);
+ mpz_init(hptr->e);
+ mpz_init(hptr->p);
+ mpz_init(hptr->q);
+ mpz_init(hptr->dmp1);
+ mpz_init(hptr->dmq1);
+ mpz_init(hptr->iqmp);
+ mpz_init(hptr->r0);
+ mpz_init(hptr->r1);
+ mpz_init(hptr->I0);
+ mpz_init(hptr->m1);
+ if(!bn2gmp(rsa->n, hptr->n) || !bn2gmp(rsa->e, hptr->e))
+ goto err;
+ if(!rsa->p || !rsa->q || !rsa->d || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
+ {
+ hptr->public_only = 1;
+ return hptr;
+ }
+ if(!bn2gmp(rsa->d, hptr->d) || !bn2gmp(rsa->p, hptr->p) ||
+ !bn2gmp(rsa->q, hptr->q) || !bn2gmp(rsa->dmp1, hptr->dmp1) ||
+ !bn2gmp(rsa->dmq1, hptr->dmq1) || !bn2gmp(rsa->iqmp, hptr->iqmp))
+ goto err;
+ hptr->public_only = 0;
+ RSA_set_ex_data(rsa, hndidx_rsa, hptr);
+ return hptr;
+err:
+ mpz_clear(hptr->n);
+ mpz_clear(hptr->d);
+ mpz_clear(hptr->e);
+ mpz_clear(hptr->p);
+ mpz_clear(hptr->q);
+ mpz_clear(hptr->dmp1);
+ mpz_clear(hptr->dmq1);
+ mpz_clear(hptr->iqmp);
+ mpz_clear(hptr->r0);
+ mpz_clear(hptr->r1);
+ mpz_clear(hptr->I0);
+ mpz_clear(hptr->m1);
+ OPENSSL_free(hptr);
+ return NULL;
+ }
+
+static int e_gmp_rsa_finish(RSA *rsa)
+ {
+ E_GMP_RSA_CTX *hptr = RSA_get_ex_data(rsa, hndidx_rsa);
+ if(!hptr) return 0;
+ mpz_clear(hptr->n);
+ mpz_clear(hptr->d);
+ mpz_clear(hptr->e);
+ mpz_clear(hptr->p);
+ mpz_clear(hptr->q);
+ mpz_clear(hptr->dmp1);
+ mpz_clear(hptr->dmq1);
+ mpz_clear(hptr->iqmp);
+ mpz_clear(hptr->r0);
+ mpz_clear(hptr->r1);
+ mpz_clear(hptr->I0);
+ mpz_clear(hptr->m1);
+ OPENSSL_free(hptr);
+ RSA_set_ex_data(rsa, hndidx_rsa, NULL);
+ return 1;
+ }
+
+static int e_gmp_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+ {
+ E_GMP_RSA_CTX *hptr;
+ int to_return = 0;
+
+ hptr = e_gmp_get_rsa(rsa);
+ if(!hptr)
+ {
+ GMPerr(GMP_F_E_GMP_RSA_MOD_EXP,
+ GMP_R_KEY_CONTEXT_ERROR);
+ return 0;
+ }
+ if(hptr->public_only)
+ {
+ GMPerr(GMP_F_E_GMP_RSA_MOD_EXP,
+ GMP_R_MISSING_KEY_COMPONENTS);
+ return 0;
+ }
+
+ /* ugh!!! */
+ if(!bn2gmp(I, hptr->I0))
+ return 0;
+
+ /* This is basically the CRT logic in crypto/rsa/rsa_eay.c reworded into
+ * GMP-speak. It may be that GMP's API facilitates cleaner formulations
+ * of this stuff, eg. better handling of negatives, or functions that
+ * combine operations. */
+
+ mpz_mod(hptr->r1, hptr->I0, hptr->q);
+ mpz_powm(hptr->m1, hptr->r1, hptr->dmq1, hptr->q);
+
+ mpz_mod(hptr->r1, hptr->I0, hptr->p);
+ mpz_powm(hptr->r0, hptr->r1, hptr->dmp1, hptr->p);
+
+ mpz_sub(hptr->r0, hptr->r0, hptr->m1);
+
+ if(mpz_sgn(hptr->r0) < 0)
+ mpz_add(hptr->r0, hptr->r0, hptr->p);
+ mpz_mul(hptr->r1, hptr->r0, hptr->iqmp);
+ mpz_mod(hptr->r0, hptr->r1, hptr->p);
+
+ if(mpz_sgn(hptr->r0) < 0)
+ mpz_add(hptr->r0, hptr->r0, hptr->p);
+ mpz_mul(hptr->r1, hptr->r0, hptr->q);
+ mpz_add(hptr->r0, hptr->r1, hptr->m1);
+
+ /* ugh!!! */
+ if(gmp2bn(hptr->r0, r))
+ to_return = 1;
+
+ return 1;
+ }
+#endif
+
+#endif /* !OPENSSL_NO_GMP */
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library. */
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+IMPLEMENT_DYNAMIC_CHECK_FN()
+#ifndef OPENSSL_NO_GMP
+static int bind_fn(ENGINE *e, const char *id)
+ {
+ if(id && (strcmp(id, engine_e_gmp_id) != 0))
+ return 0;
+ if(!bind_helper(e))
+ return 0;
+ return 1;
+ }
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#else
+OPENSSL_EXPORT
+int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; }
+#endif
+#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
+
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_gmp.ec b/openssl/engines/e_gmp.ec
new file mode 100644
index 000000000..72ec447fb
--- /dev/null
+++ b/openssl/engines/e_gmp.ec
@@ -0,0 +1 @@
+L GMP e_gmp_err.h e_gmp_err.c
diff --git a/openssl/engines/e_gmp_err.c b/openssl/engines/e_gmp_err.c
new file mode 100644
index 000000000..61db95679
--- /dev/null
+++ b/openssl/engines/e_gmp_err.c
@@ -0,0 +1,141 @@
+/* e_gmp_err.c */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+/* 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 "e_gmp_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA GMP_str_functs[]=
+ {
+{ERR_FUNC(GMP_F_E_GMP_CTRL), "E_GMP_CTRL"},
+{ERR_FUNC(GMP_F_E_GMP_RSA_MOD_EXP), "E_GMP_RSA_MOD_EXP"},
+{0,NULL}
+ };
+
+static ERR_STRING_DATA GMP_str_reasons[]=
+ {
+{ERR_REASON(GMP_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
+{ERR_REASON(GMP_R_KEY_CONTEXT_ERROR) ,"key context error"},
+{ERR_REASON(GMP_R_MISSING_KEY_COMPONENTS),"missing key components"},
+{0,NULL}
+ };
+
+#endif
+
+#ifdef GMP_LIB_NAME
+static ERR_STRING_DATA GMP_lib_name[]=
+ {
+{0 ,GMP_LIB_NAME},
+{0,NULL}
+ };
+#endif
+
+
+static int GMP_lib_error_code=0;
+static int GMP_error_init=1;
+
+static void ERR_load_GMP_strings(void)
+ {
+ if (GMP_lib_error_code == 0)
+ GMP_lib_error_code=ERR_get_next_error_library();
+
+ if (GMP_error_init)
+ {
+ GMP_error_init=0;
+#ifndef OPENSSL_NO_ERR
+ ERR_load_strings(GMP_lib_error_code,GMP_str_functs);
+ ERR_load_strings(GMP_lib_error_code,GMP_str_reasons);
+#endif
+
+#ifdef GMP_LIB_NAME
+ GMP_lib_name->error = ERR_PACK(GMP_lib_error_code,0,0);
+ ERR_load_strings(0,GMP_lib_name);
+#endif
+ }
+ }
+
+static void ERR_unload_GMP_strings(void)
+ {
+ if (GMP_error_init == 0)
+ {
+#ifndef OPENSSL_NO_ERR
+ ERR_unload_strings(GMP_lib_error_code,GMP_str_functs);
+ ERR_unload_strings(GMP_lib_error_code,GMP_str_reasons);
+#endif
+
+#ifdef GMP_LIB_NAME
+ ERR_unload_strings(0,GMP_lib_name);
+#endif
+ GMP_error_init=1;
+ }
+ }
+
+static void ERR_GMP_error(int function, int reason, char *file, int line)
+ {
+ if (GMP_lib_error_code == 0)
+ GMP_lib_error_code=ERR_get_next_error_library();
+ ERR_PUT_error(GMP_lib_error_code,function,reason,file,line);
+ }
diff --git a/openssl/engines/e_gmp_err.h b/openssl/engines/e_gmp_err.h
new file mode 100644
index 000000000..dd05dfd80
--- /dev/null
+++ b/openssl/engines/e_gmp_err.h
@@ -0,0 +1,85 @@
+/* ====================================================================
+ * Copyright (c) 2001-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).
+ *
+ */
+
+#ifndef HEADER_GMP_ERR_H
+#define HEADER_GMP_ERR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_GMP_strings(void);
+static void ERR_unload_GMP_strings(void);
+static void ERR_GMP_error(int function, int reason, char *file, int line);
+#define GMPerr(f,r) ERR_GMP_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the GMP functions. */
+
+/* Function codes. */
+#define GMP_F_E_GMP_CTRL 100
+#define GMP_F_E_GMP_RSA_MOD_EXP 101
+
+/* Reason codes. */
+#define GMP_R_CTRL_COMMAND_NOT_IMPLEMENTED 100
+#define GMP_R_KEY_CONTEXT_ERROR 101
+#define GMP_R_MISSING_KEY_COMPONENTS 102
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/e_nuron.c b/openssl/engines/e_nuron.c
new file mode 100644
index 000000000..4c2537cbc
--- /dev/null
+++ b/openssl/engines/e_nuron.c
@@ -0,0 +1,434 @@
+/* crypto/engine/hw_nuron.c */
+/* Written by Ben Laurie for the OpenSSL Project, leaning heavily on Geoff
+ * Thorpe's Atalla implementation.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-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/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/dso.h>
+#include <openssl/engine.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/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_NURON
+
+#define NURON_LIB_NAME "nuron engine"
+#include "e_nuron_err.c"
+
+static const char *NURON_LIBNAME = NULL;
+static const char *get_NURON_LIBNAME(void)
+ {
+ if(NURON_LIBNAME)
+ return NURON_LIBNAME;
+ return "nuronssl";
+ }
+static void free_NURON_LIBNAME(void)
+ {
+ if(NURON_LIBNAME)
+ OPENSSL_free((void*)NURON_LIBNAME);
+ NURON_LIBNAME = NULL;
+ }
+static long set_NURON_LIBNAME(const char *name)
+ {
+ free_NURON_LIBNAME();
+ return (((NURON_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
+ }
+static const char *NURON_F1 = "nuron_mod_exp";
+
+/* The definitions for control commands specific to this engine */
+#define NURON_CMD_SO_PATH ENGINE_CMD_BASE
+static const ENGINE_CMD_DEFN nuron_cmd_defns[] = {
+ {NURON_CMD_SO_PATH,
+ "SO_PATH",
+ "Specifies the path to the 'nuronssl' shared library",
+ ENGINE_CMD_FLAG_STRING},
+ {0, NULL, NULL, 0}
+ };
+
+typedef int tfnModExp(BIGNUM *r,const BIGNUM *a,const BIGNUM *p,const BIGNUM *m);
+static tfnModExp *pfnModExp = NULL;
+
+static DSO *pvDSOHandle = NULL;
+
+static int nuron_destroy(ENGINE *e)
+ {
+ free_NURON_LIBNAME();
+ ERR_unload_NURON_strings();
+ return 1;
+ }
+
+static int nuron_init(ENGINE *e)
+ {
+ if(pvDSOHandle != NULL)
+ {
+ NURONerr(NURON_F_NURON_INIT,NURON_R_ALREADY_LOADED);
+ return 0;
+ }
+
+ pvDSOHandle = DSO_load(NULL, get_NURON_LIBNAME(), NULL,
+ DSO_FLAG_NAME_TRANSLATION_EXT_ONLY);
+ if(!pvDSOHandle)
+ {
+ NURONerr(NURON_F_NURON_INIT,NURON_R_DSO_NOT_FOUND);
+ return 0;
+ }
+
+ pfnModExp = (tfnModExp *)DSO_bind_func(pvDSOHandle, NURON_F1);
+ if(!pfnModExp)
+ {
+ NURONerr(NURON_F_NURON_INIT,NURON_R_DSO_FUNCTION_NOT_FOUND);
+ return 0;
+ }
+
+ return 1;
+ }
+
+static int nuron_finish(ENGINE *e)
+ {
+ free_NURON_LIBNAME();
+ if(pvDSOHandle == NULL)
+ {
+ NURONerr(NURON_F_NURON_FINISH,NURON_R_NOT_LOADED);
+ return 0;
+ }
+ if(!DSO_free(pvDSOHandle))
+ {
+ NURONerr(NURON_F_NURON_FINISH,NURON_R_DSO_FAILURE);
+ return 0;
+ }
+ pvDSOHandle=NULL;
+ pfnModExp=NULL;
+ return 1;
+ }
+
+static int nuron_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+ {
+ int initialised = ((pvDSOHandle == NULL) ? 0 : 1);
+ switch(cmd)
+ {
+ case NURON_CMD_SO_PATH:
+ if(p == NULL)
+ {
+ NURONerr(NURON_F_NURON_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ if(initialised)
+ {
+ NURONerr(NURON_F_NURON_CTRL,NURON_R_ALREADY_LOADED);
+ return 0;
+ }
+ return set_NURON_LIBNAME((const char *)p);
+ default:
+ break;
+ }
+ NURONerr(NURON_F_NURON_CTRL,NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+ return 0;
+}
+
+static int nuron_mod_exp(BIGNUM *r,const BIGNUM *a,const BIGNUM *p,
+ const BIGNUM *m,BN_CTX *ctx)
+ {
+ if(!pvDSOHandle)
+ {
+ NURONerr(NURON_F_NURON_MOD_EXP,NURON_R_NOT_LOADED);
+ return 0;
+ }
+ return pfnModExp(r,a,p,m);
+ }
+
+#ifndef OPENSSL_NO_RSA
+static int nuron_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+ {
+ return nuron_mod_exp(r0,I,rsa->d,rsa->n,ctx);
+ }
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* This code was liberated and adapted from the commented-out code in
+ * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration
+ * (it doesn't have a CRT form for RSA), this function means that an
+ * Atalla system running with a DSA server certificate can handshake
+ * around 5 or 6 times faster/more than an equivalent system running with
+ * RSA. Just check out the "signs" statistics from the RSA and DSA parts
+ * of "openssl speed -engine atalla dsa1024 rsa1024". */
+static int nuron_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)
+ {
+ BIGNUM t;
+ int to_return = 0;
+
+ BN_init(&t);
+ /* let rr = a1 ^ p1 mod m */
+ if (!nuron_mod_exp(rr,a1,p1,m,ctx))
+ goto end;
+ /* let t = a2 ^ p2 mod m */
+ if (!nuron_mod_exp(&t,a2,p2,m,ctx))
+ goto end;
+ /* let rr = rr * t mod m */
+ if (!BN_mod_mul(rr,rr,&t,m,ctx))
+ goto end;
+ to_return = 1;
+end:
+ BN_free(&t);
+ return to_return;
+ }
+
+
+static int nuron_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+ const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx)
+ {
+ return nuron_mod_exp(r, a, p, m, ctx);
+ }
+#endif
+
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+#ifndef OPENSSL_NO_RSA
+static int nuron_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+ {
+ return nuron_mod_exp(r, a, p, m, ctx);
+ }
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int nuron_mod_exp_dh(const DH *dh, BIGNUM *r,
+ const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+ {
+ return nuron_mod_exp(r, a, p, m, ctx);
+ }
+#endif
+
+#ifndef OPENSSL_NO_RSA
+static RSA_METHOD nuron_rsa =
+ {
+ "Nuron RSA method",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ nuron_rsa_mod_exp,
+ nuron_mod_exp_mont,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+#endif
+
+#ifndef OPENSSL_NO_DSA
+static DSA_METHOD nuron_dsa =
+ {
+ "Nuron DSA method",
+ NULL, /* dsa_do_sign */
+ NULL, /* dsa_sign_setup */
+ NULL, /* dsa_do_verify */
+ nuron_dsa_mod_exp, /* dsa_mod_exp */
+ nuron_mod_exp_dsa, /* bn_mod_exp */
+ NULL, /* init */
+ NULL, /* finish */
+ 0, /* flags */
+ NULL, /* app_data */
+ NULL, /* dsa_paramgen */
+ NULL /* dsa_keygen */
+ };
+#endif
+
+#ifndef OPENSSL_NO_DH
+static DH_METHOD nuron_dh =
+ {
+ "Nuron DH method",
+ NULL,
+ NULL,
+ nuron_mod_exp_dh,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ NULL
+ };
+#endif
+
+/* Constants used when creating the ENGINE */
+static const char *engine_nuron_id = "nuron";
+static const char *engine_nuron_name = "Nuron hardware engine support";
+
+/* This internal function is used by ENGINE_nuron() and possibly by the
+ * "dynamic" ENGINE support too */
+static int bind_helper(ENGINE *e)
+ {
+#ifndef OPENSSL_NO_RSA
+ const RSA_METHOD *meth1;
+#endif
+#ifndef OPENSSL_NO_DSA
+ const DSA_METHOD *meth2;
+#endif
+#ifndef OPENSSL_NO_DH
+ const DH_METHOD *meth3;
+#endif
+ if(!ENGINE_set_id(e, engine_nuron_id) ||
+ !ENGINE_set_name(e, engine_nuron_name) ||
+#ifndef OPENSSL_NO_RSA
+ !ENGINE_set_RSA(e, &nuron_rsa) ||
+#endif
+#ifndef OPENSSL_NO_DSA
+ !ENGINE_set_DSA(e, &nuron_dsa) ||
+#endif
+#ifndef OPENSSL_NO_DH
+ !ENGINE_set_DH(e, &nuron_dh) ||
+#endif
+ !ENGINE_set_destroy_function(e, nuron_destroy) ||
+ !ENGINE_set_init_function(e, nuron_init) ||
+ !ENGINE_set_finish_function(e, nuron_finish) ||
+ !ENGINE_set_ctrl_function(e, nuron_ctrl) ||
+ !ENGINE_set_cmd_defns(e, nuron_cmd_defns))
+ return 0;
+
+#ifndef OPENSSL_NO_RSA
+ /* We know that the "PKCS1_SSLeay()" functions hook properly
+ * to the nuron-specific mod_exp and mod_exp_crt so we use
+ * those functions. NB: We don't use ENGINE_openssl() or
+ * anything "more generic" because something like the RSAref
+ * code may not hook properly, and if you own one of these
+ * cards then you have the right to do RSA operations on it
+ * anyway! */
+ meth1=RSA_PKCS1_SSLeay();
+ nuron_rsa.rsa_pub_enc=meth1->rsa_pub_enc;
+ nuron_rsa.rsa_pub_dec=meth1->rsa_pub_dec;
+ nuron_rsa.rsa_priv_enc=meth1->rsa_priv_enc;
+ nuron_rsa.rsa_priv_dec=meth1->rsa_priv_dec;
+#endif
+
+#ifndef OPENSSL_NO_DSA
+ /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
+ * bits. */
+ meth2=DSA_OpenSSL();
+ nuron_dsa.dsa_do_sign=meth2->dsa_do_sign;
+ nuron_dsa.dsa_sign_setup=meth2->dsa_sign_setup;
+ nuron_dsa.dsa_do_verify=meth2->dsa_do_verify;
+#endif
+
+#ifndef OPENSSL_NO_DH
+ /* Much the same for Diffie-Hellman */
+ meth3=DH_OpenSSL();
+ nuron_dh.generate_key=meth3->generate_key;
+ nuron_dh.compute_key=meth3->compute_key;
+#endif
+
+ /* Ensure the nuron error handling is set up */
+ ERR_load_NURON_strings();
+ return 1;
+ }
+
+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+static ENGINE *engine_nuron(void)
+ {
+ ENGINE *ret = ENGINE_new();
+ if(!ret)
+ return NULL;
+ if(!bind_helper(ret))
+ {
+ ENGINE_free(ret);
+ return NULL;
+ }
+ return ret;
+ }
+
+void ENGINE_load_nuron(void)
+ {
+ /* Copied from eng_[openssl|dyn].c */
+ ENGINE *toadd = engine_nuron();
+ if(!toadd) return;
+ ENGINE_add(toadd);
+ ENGINE_free(toadd);
+ ERR_clear_error();
+ }
+#endif
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library. */
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_fn(ENGINE *e, const char *id)
+ {
+ if(id && (strcmp(id, engine_nuron_id) != 0))
+ return 0;
+ if(!bind_helper(e))
+ return 0;
+ return 1;
+ }
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
+
+#endif /* !OPENSSL_NO_HW_NURON */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_nuron.ec b/openssl/engines/e_nuron.ec
new file mode 100644
index 000000000..cfa430dfc
--- /dev/null
+++ b/openssl/engines/e_nuron.ec
@@ -0,0 +1 @@
+L NURON e_nuron_err.h e_nuron_err.c
diff --git a/openssl/engines/e_nuron_err.c b/openssl/engines/e_nuron_err.c
new file mode 100644
index 000000000..9a7864f42
--- /dev/null
+++ b/openssl/engines/e_nuron_err.c
@@ -0,0 +1,146 @@
+/* e_nuron_err.c */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+/* 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 "e_nuron_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA NURON_str_functs[]=
+ {
+{ERR_FUNC(NURON_F_NURON_CTRL), "NURON_CTRL"},
+{ERR_FUNC(NURON_F_NURON_FINISH), "NURON_FINISH"},
+{ERR_FUNC(NURON_F_NURON_INIT), "NURON_INIT"},
+{ERR_FUNC(NURON_F_NURON_MOD_EXP), "NURON_MOD_EXP"},
+{0,NULL}
+ };
+
+static ERR_STRING_DATA NURON_str_reasons[]=
+ {
+{ERR_REASON(NURON_R_ALREADY_LOADED) ,"already loaded"},
+{ERR_REASON(NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
+{ERR_REASON(NURON_R_DSO_FAILURE) ,"dso failure"},
+{ERR_REASON(NURON_R_DSO_FUNCTION_NOT_FOUND),"dso function not found"},
+{ERR_REASON(NURON_R_DSO_NOT_FOUND) ,"dso not found"},
+{ERR_REASON(NURON_R_NOT_LOADED) ,"not loaded"},
+{0,NULL}
+ };
+
+#endif
+
+#ifdef NURON_LIB_NAME
+static ERR_STRING_DATA NURON_lib_name[]=
+ {
+{0 ,NURON_LIB_NAME},
+{0,NULL}
+ };
+#endif
+
+
+static int NURON_lib_error_code=0;
+static int NURON_error_init=1;
+
+static void ERR_load_NURON_strings(void)
+ {
+ if (NURON_lib_error_code == 0)
+ NURON_lib_error_code=ERR_get_next_error_library();
+
+ if (NURON_error_init)
+ {
+ NURON_error_init=0;
+#ifndef OPENSSL_NO_ERR
+ ERR_load_strings(NURON_lib_error_code,NURON_str_functs);
+ ERR_load_strings(NURON_lib_error_code,NURON_str_reasons);
+#endif
+
+#ifdef NURON_LIB_NAME
+ NURON_lib_name->error = ERR_PACK(NURON_lib_error_code,0,0);
+ ERR_load_strings(0,NURON_lib_name);
+#endif
+ }
+ }
+
+static void ERR_unload_NURON_strings(void)
+ {
+ if (NURON_error_init == 0)
+ {
+#ifndef OPENSSL_NO_ERR
+ ERR_unload_strings(NURON_lib_error_code,NURON_str_functs);
+ ERR_unload_strings(NURON_lib_error_code,NURON_str_reasons);
+#endif
+
+#ifdef NURON_LIB_NAME
+ ERR_unload_strings(0,NURON_lib_name);
+#endif
+ NURON_error_init=1;
+ }
+ }
+
+static void ERR_NURON_error(int function, int reason, char *file, int line)
+ {
+ if (NURON_lib_error_code == 0)
+ NURON_lib_error_code=ERR_get_next_error_library();
+ ERR_PUT_error(NURON_lib_error_code,function,reason,file,line);
+ }
diff --git a/openssl/engines/e_nuron_err.h b/openssl/engines/e_nuron_err.h
new file mode 100644
index 000000000..219babbb4
--- /dev/null
+++ b/openssl/engines/e_nuron_err.h
@@ -0,0 +1,90 @@
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * 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_NURON_ERR_H
+#define HEADER_NURON_ERR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_NURON_strings(void);
+static void ERR_unload_NURON_strings(void);
+static void ERR_NURON_error(int function, int reason, char *file, int line);
+#define NURONerr(f,r) ERR_NURON_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the NURON functions. */
+
+/* Function codes. */
+#define NURON_F_NURON_CTRL 100
+#define NURON_F_NURON_FINISH 101
+#define NURON_F_NURON_INIT 102
+#define NURON_F_NURON_MOD_EXP 103
+
+/* Reason codes. */
+#define NURON_R_ALREADY_LOADED 100
+#define NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED 101
+#define NURON_R_DSO_FAILURE 102
+#define NURON_R_DSO_FUNCTION_NOT_FOUND 103
+#define NURON_R_DSO_NOT_FOUND 104
+#define NURON_R_NOT_LOADED 105
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/e_sureware.c b/openssl/engines/e_sureware.c
new file mode 100644
index 000000000..58fa9a98e
--- /dev/null
+++ b/openssl/engines/e_sureware.c
@@ -0,0 +1,1057 @@
+/* Written by Corinne Dive-Reclus(cdive@baltimore.com)
+*
+*
+* 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/)"
+*
+* Written by Corinne Dive-Reclus(cdive@baltimore.com)
+*
+* Copyright@2001 Baltimore Technologies Ltd.
+* All right Reserved.
+* *
+* THIS FILE IS PROVIDED BY BALTIMORE TECHNOLOGIES ``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 BALTIMORE TECHNOLOGIES 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 <stdio.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/pem.h>
+#include <openssl/dso.h>
+#include <openssl/engine.h>
+#include <openssl/rand.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/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_SUREWARE
+
+#ifdef FLAT_INC
+#include "sureware.h"
+#else
+#include "vendor_defns/sureware.h"
+#endif
+
+#define SUREWARE_LIB_NAME "sureware engine"
+#include "e_sureware_err.c"
+
+static int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+static int surewarehk_destroy(ENGINE *e);
+static int surewarehk_init(ENGINE *e);
+static int surewarehk_finish(ENGINE *e);
+static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+
+/* RSA stuff */
+#ifndef OPENSSL_NO_RSA
+static int surewarehk_rsa_priv_dec(int flen,const unsigned char *from,unsigned char *to,
+ RSA *rsa,int padding);
+static int surewarehk_rsa_sign(int flen,const unsigned char *from,unsigned char *to,
+ RSA *rsa,int padding);
+#endif
+
+/* RAND stuff */
+static int surewarehk_rand_bytes(unsigned char *buf, int num);
+static void surewarehk_rand_seed(const void *buf, int num);
+static void surewarehk_rand_add(const void *buf, int num, double entropy);
+
+/* KM stuff */
+static EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id,
+ UI_METHOD *ui_method, void *callback_data);
+static EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id,
+ UI_METHOD *ui_method, void *callback_data);
+static void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
+ int idx,long argl, void *argp);
+#if 0
+static void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
+ int idx,long argl, void *argp);
+#endif
+
+#ifndef OPENSSL_NO_RSA
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int surewarehk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+{
+ return surewarehk_modexp(r, a, p, m, ctx);
+}
+
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD surewarehk_rsa =
+ {
+ "SureWare RSA method",
+ NULL, /* pub_enc*/
+ NULL, /* pub_dec*/
+ surewarehk_rsa_sign, /* our rsa_sign is OpenSSL priv_enc*/
+ surewarehk_rsa_priv_dec, /* priv_dec*/
+ NULL, /*mod_exp*/
+ surewarehk_mod_exp_mont, /*mod_exp_mongomery*/
+ NULL, /* init*/
+ NULL, /* finish*/
+ 0, /* RSA flag*/
+ NULL,
+ NULL, /* OpenSSL sign*/
+ NULL, /* OpenSSL verify*/
+ NULL /* keygen */
+ };
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* Our internal DH_METHOD that we provide pointers to */
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int surewarehk_modexp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+{
+ return surewarehk_modexp(r, a, p, m, ctx);
+}
+
+static DH_METHOD surewarehk_dh =
+ {
+ "SureWare DH method",
+ NULL,/*gen_key*/
+ NULL,/*agree,*/
+ surewarehk_modexp_dh, /*dh mod exp*/
+ NULL, /* init*/
+ NULL, /* finish*/
+ 0, /* flags*/
+ NULL,
+ NULL
+ };
+#endif
+
+static RAND_METHOD surewarehk_rand =
+ {
+ /* "SureWare RAND method", */
+ surewarehk_rand_seed,
+ surewarehk_rand_bytes,
+ NULL,/*cleanup*/
+ surewarehk_rand_add,
+ surewarehk_rand_bytes,
+ NULL,/*rand_status*/
+ };
+
+#ifndef OPENSSL_NO_DSA
+/* DSA stuff */
+static DSA_SIG * surewarehk_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
+static int surewarehk_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)
+{
+ BIGNUM t;
+ int to_return = 0;
+ BN_init(&t);
+ /* let rr = a1 ^ p1 mod m */
+ if (!surewarehk_modexp(rr,a1,p1,m,ctx)) goto end;
+ /* let t = a2 ^ p2 mod m */
+ if (!surewarehk_modexp(&t,a2,p2,m,ctx)) goto end;
+ /* let rr = rr * t mod m */
+ if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
+ to_return = 1;
+end:
+ BN_free(&t);
+ return to_return;
+}
+
+static DSA_METHOD surewarehk_dsa =
+ {
+ "SureWare DSA method",
+ surewarehk_dsa_do_sign,
+ NULL,/*sign setup*/
+ NULL,/*verify,*/
+ surewarehk_dsa_mod_exp,/*mod exp*/
+ NULL,/*bn mod exp*/
+ NULL, /*init*/
+ NULL,/*finish*/
+ 0,
+ NULL,
+ NULL,
+ NULL
+ };
+#endif
+
+static const char *engine_sureware_id = "sureware";
+static const char *engine_sureware_name = "SureWare hardware engine support";
+
+/* Now, to our own code */
+
+/* As this is only ever called once, there's no need for locking
+ * (indeed - the lock will already be held by our caller!!!) */
+static int bind_sureware(ENGINE *e)
+{
+#ifndef OPENSSL_NO_RSA
+ const RSA_METHOD *meth1;
+#endif
+#ifndef OPENSSL_NO_DSA
+ const DSA_METHOD *meth2;
+#endif
+#ifndef OPENSSL_NO_DH
+ const DH_METHOD *meth3;
+#endif
+
+ if(!ENGINE_set_id(e, engine_sureware_id) ||
+ !ENGINE_set_name(e, engine_sureware_name) ||
+#ifndef OPENSSL_NO_RSA
+ !ENGINE_set_RSA(e, &surewarehk_rsa) ||
+#endif
+#ifndef OPENSSL_NO_DSA
+ !ENGINE_set_DSA(e, &surewarehk_dsa) ||
+#endif
+#ifndef OPENSSL_NO_DH
+ !ENGINE_set_DH(e, &surewarehk_dh) ||
+#endif
+ !ENGINE_set_RAND(e, &surewarehk_rand) ||
+ !ENGINE_set_destroy_function(e, surewarehk_destroy) ||
+ !ENGINE_set_init_function(e, surewarehk_init) ||
+ !ENGINE_set_finish_function(e, surewarehk_finish) ||
+ !ENGINE_set_ctrl_function(e, surewarehk_ctrl) ||
+ !ENGINE_set_load_privkey_function(e, surewarehk_load_privkey) ||
+ !ENGINE_set_load_pubkey_function(e, surewarehk_load_pubkey))
+ return 0;
+
+#ifndef OPENSSL_NO_RSA
+ /* We know that the "PKCS1_SSLeay()" functions hook properly
+ * to the cswift-specific mod_exp and mod_exp_crt so we use
+ * those functions. NB: We don't use ENGINE_openssl() or
+ * anything "more generic" because something like the RSAref
+ * code may not hook properly, and if you own one of these
+ * cards then you have the right to do RSA operations on it
+ * anyway! */
+ meth1 = RSA_PKCS1_SSLeay();
+ if (meth1)
+ {
+ surewarehk_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+ surewarehk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+ }
+#endif
+
+#ifndef OPENSSL_NO_DSA
+ /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
+ * bits. */
+ meth2 = DSA_OpenSSL();
+ if (meth2)
+ {
+ surewarehk_dsa.dsa_do_verify = meth2->dsa_do_verify;
+ }
+#endif
+
+#ifndef OPENSSL_NO_DH
+ /* Much the same for Diffie-Hellman */
+ meth3 = DH_OpenSSL();
+ if (meth3)
+ {
+ surewarehk_dh.generate_key = meth3->generate_key;
+ surewarehk_dh.compute_key = meth3->compute_key;
+ }
+#endif
+
+ /* Ensure the sureware error handling is set up */
+ ERR_load_SUREWARE_strings();
+ return 1;
+}
+
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_helper(ENGINE *e, const char *id)
+ {
+ if(id && (strcmp(id, engine_sureware_id) != 0))
+ return 0;
+ if(!bind_sureware(e))
+ return 0;
+ return 1;
+ }
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
+#else
+static ENGINE *engine_sureware(void)
+ {
+ ENGINE *ret = ENGINE_new();
+ if(!ret)
+ return NULL;
+ if(!bind_sureware(ret))
+ {
+ ENGINE_free(ret);
+ return NULL;
+ }
+ return ret;
+ }
+
+void ENGINE_load_sureware(void)
+ {
+ /* Copied from eng_[openssl|dyn].c */
+ ENGINE *toadd = engine_sureware();
+ if(!toadd) return;
+ ENGINE_add(toadd);
+ ENGINE_free(toadd);
+ ERR_clear_error();
+ }
+#endif
+
+/* This is a process-global DSO handle used for loading and unloading
+ * the SureWareHook library. NB: This is only set (or unset) during an
+ * init() or finish() call (reference counts permitting) and they're
+ * operating with global locks, so this should be thread-safe
+ * implicitly. */
+static DSO *surewarehk_dso = NULL;
+#ifndef OPENSSL_NO_RSA
+static int rsaHndidx = -1; /* Index for KM handle. Not really used yet. */
+#endif
+#ifndef OPENSSL_NO_DSA
+static int dsaHndidx = -1; /* Index for KM handle. Not really used yet. */
+#endif
+
+/* These are the function pointers that are (un)set when the library has
+ * successfully (un)loaded. */
+static SureWareHook_Init_t *p_surewarehk_Init = NULL;
+static SureWareHook_Finish_t *p_surewarehk_Finish = NULL;
+static SureWareHook_Rand_Bytes_t *p_surewarehk_Rand_Bytes = NULL;
+static SureWareHook_Rand_Seed_t *p_surewarehk_Rand_Seed = NULL;
+static SureWareHook_Load_Privkey_t *p_surewarehk_Load_Privkey = NULL;
+static SureWareHook_Info_Pubkey_t *p_surewarehk_Info_Pubkey = NULL;
+static SureWareHook_Load_Rsa_Pubkey_t *p_surewarehk_Load_Rsa_Pubkey = NULL;
+static SureWareHook_Load_Dsa_Pubkey_t *p_surewarehk_Load_Dsa_Pubkey = NULL;
+static SureWareHook_Free_t *p_surewarehk_Free=NULL;
+static SureWareHook_Rsa_Priv_Dec_t *p_surewarehk_Rsa_Priv_Dec=NULL;
+static SureWareHook_Rsa_Sign_t *p_surewarehk_Rsa_Sign=NULL;
+static SureWareHook_Dsa_Sign_t *p_surewarehk_Dsa_Sign=NULL;
+static SureWareHook_Mod_Exp_t *p_surewarehk_Mod_Exp=NULL;
+
+/* Used in the DSO operations. */
+static const char *surewarehk_LIBNAME = "SureWareHook";
+static const char *n_surewarehk_Init = "SureWareHook_Init";
+static const char *n_surewarehk_Finish = "SureWareHook_Finish";
+static const char *n_surewarehk_Rand_Bytes="SureWareHook_Rand_Bytes";
+static const char *n_surewarehk_Rand_Seed="SureWareHook_Rand_Seed";
+static const char *n_surewarehk_Load_Privkey="SureWareHook_Load_Privkey";
+static const char *n_surewarehk_Info_Pubkey="SureWareHook_Info_Pubkey";
+static const char *n_surewarehk_Load_Rsa_Pubkey="SureWareHook_Load_Rsa_Pubkey";
+static const char *n_surewarehk_Load_Dsa_Pubkey="SureWareHook_Load_Dsa_Pubkey";
+static const char *n_surewarehk_Free="SureWareHook_Free";
+static const char *n_surewarehk_Rsa_Priv_Dec="SureWareHook_Rsa_Priv_Dec";
+static const char *n_surewarehk_Rsa_Sign="SureWareHook_Rsa_Sign";
+static const char *n_surewarehk_Dsa_Sign="SureWareHook_Dsa_Sign";
+static const char *n_surewarehk_Mod_Exp="SureWareHook_Mod_Exp";
+static BIO *logstream = NULL;
+
+/* SureWareHook library functions and mechanics - these are used by the
+ * higher-level functions further down. NB: As and where there's no
+ * error checking, take a look lower down where these functions are
+ * called, the checking and error handling is probably down there.
+*/
+static int threadsafe=1;
+static int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+{
+ int to_return = 1;
+
+ switch(cmd)
+ {
+ case ENGINE_CTRL_SET_LOGSTREAM:
+ {
+ BIO *bio = (BIO *)p;
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ if (logstream)
+ {
+ BIO_free(logstream);
+ logstream = NULL;
+ }
+ if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1)
+ logstream = bio;
+ else
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL,SUREWARE_R_BIO_WAS_FREED);
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ break;
+ /* This will prevent the initialisation function from "installing"
+ * the mutex-handling callbacks, even if they are available from
+ * within the library (or were provided to the library from the
+ * calling application). This is to remove any baggage for
+ * applications not using multithreading. */
+ case ENGINE_CTRL_CHIL_NO_LOCKING:
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ threadsafe = 0;
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ break;
+
+ /* The command isn't understood by this engine */
+ default:
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL,
+ ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+ to_return = 0;
+ break;
+ }
+
+ return to_return;
+}
+
+/* Destructor (complements the "ENGINE_surewarehk()" constructor) */
+static int surewarehk_destroy(ENGINE *e)
+{
+ ERR_unload_SUREWARE_strings();
+ return 1;
+}
+
+/* (de)initialisation functions. */
+static int surewarehk_init(ENGINE *e)
+{
+ char msg[64]="ENGINE_init";
+ SureWareHook_Init_t *p1=NULL;
+ SureWareHook_Finish_t *p2=NULL;
+ SureWareHook_Rand_Bytes_t *p3=NULL;
+ SureWareHook_Rand_Seed_t *p4=NULL;
+ SureWareHook_Load_Privkey_t *p5=NULL;
+ SureWareHook_Load_Rsa_Pubkey_t *p6=NULL;
+ SureWareHook_Free_t *p7=NULL;
+ SureWareHook_Rsa_Priv_Dec_t *p8=NULL;
+ SureWareHook_Rsa_Sign_t *p9=NULL;
+ SureWareHook_Dsa_Sign_t *p12=NULL;
+ SureWareHook_Info_Pubkey_t *p13=NULL;
+ SureWareHook_Load_Dsa_Pubkey_t *p14=NULL;
+ SureWareHook_Mod_Exp_t *p15=NULL;
+
+ if(surewarehk_dso != NULL)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_ALREADY_LOADED);
+ goto err;
+ }
+ /* Attempt to load libsurewarehk.so/surewarehk.dll/whatever. */
+ surewarehk_dso = DSO_load(NULL, surewarehk_LIBNAME, NULL, 0);
+ if(surewarehk_dso == NULL)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_DSO_FAILURE);
+ goto err;
+ }
+ if(!(p1=(SureWareHook_Init_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Init)) ||
+ !(p2=(SureWareHook_Finish_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Finish)) ||
+ !(p3=(SureWareHook_Rand_Bytes_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rand_Bytes)) ||
+ !(p4=(SureWareHook_Rand_Seed_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rand_Seed)) ||
+ !(p5=(SureWareHook_Load_Privkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Privkey)) ||
+ !(p6=(SureWareHook_Load_Rsa_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Rsa_Pubkey)) ||
+ !(p7=(SureWareHook_Free_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Free)) ||
+ !(p8=(SureWareHook_Rsa_Priv_Dec_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rsa_Priv_Dec)) ||
+ !(p9=(SureWareHook_Rsa_Sign_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rsa_Sign)) ||
+ !(p12=(SureWareHook_Dsa_Sign_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Dsa_Sign)) ||
+ !(p13=(SureWareHook_Info_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Info_Pubkey)) ||
+ !(p14=(SureWareHook_Load_Dsa_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Dsa_Pubkey)) ||
+ !(p15=(SureWareHook_Mod_Exp_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Mod_Exp)))
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_DSO_FAILURE);
+ goto err;
+ }
+ /* Copy the pointers */
+ p_surewarehk_Init = p1;
+ p_surewarehk_Finish = p2;
+ p_surewarehk_Rand_Bytes = p3;
+ p_surewarehk_Rand_Seed = p4;
+ p_surewarehk_Load_Privkey = p5;
+ p_surewarehk_Load_Rsa_Pubkey = p6;
+ p_surewarehk_Free = p7;
+ p_surewarehk_Rsa_Priv_Dec = p8;
+ p_surewarehk_Rsa_Sign = p9;
+ p_surewarehk_Dsa_Sign = p12;
+ p_surewarehk_Info_Pubkey = p13;
+ p_surewarehk_Load_Dsa_Pubkey = p14;
+ p_surewarehk_Mod_Exp = p15;
+ /* Contact the hardware and initialises it. */
+ if(p_surewarehk_Init(msg,threadsafe)==SUREWAREHOOK_ERROR_UNIT_FAILURE)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,SUREWARE_R_UNIT_FAILURE);
+ goto err;
+ }
+ if(p_surewarehk_Init(msg,threadsafe)==SUREWAREHOOK_ERROR_UNIT_FAILURE)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,SUREWARE_R_UNIT_FAILURE);
+ goto err;
+ }
+ /* try to load the default private key, if failed does not return a failure but
+ wait for an explicit ENGINE_load_privakey */
+ surewarehk_load_privkey(e,NULL,NULL,NULL);
+
+ /* Everything's fine. */
+#ifndef OPENSSL_NO_RSA
+ if (rsaHndidx == -1)
+ rsaHndidx = RSA_get_ex_new_index(0,
+ "SureWareHook RSA key handle",
+ NULL, NULL, surewarehk_ex_free);
+#endif
+#ifndef OPENSSL_NO_DSA
+ if (dsaHndidx == -1)
+ dsaHndidx = DSA_get_ex_new_index(0,
+ "SureWareHook DSA key handle",
+ NULL, NULL, surewarehk_ex_free);
+#endif
+
+ return 1;
+err:
+ if(surewarehk_dso)
+ DSO_free(surewarehk_dso);
+ surewarehk_dso = NULL;
+ p_surewarehk_Init = NULL;
+ p_surewarehk_Finish = NULL;
+ p_surewarehk_Rand_Bytes = NULL;
+ p_surewarehk_Rand_Seed = NULL;
+ p_surewarehk_Load_Privkey = NULL;
+ p_surewarehk_Load_Rsa_Pubkey = NULL;
+ p_surewarehk_Free = NULL;
+ p_surewarehk_Rsa_Priv_Dec = NULL;
+ p_surewarehk_Rsa_Sign = NULL;
+ p_surewarehk_Dsa_Sign = NULL;
+ p_surewarehk_Info_Pubkey = NULL;
+ p_surewarehk_Load_Dsa_Pubkey = NULL;
+ p_surewarehk_Mod_Exp = NULL;
+ return 0;
+}
+
+static int surewarehk_finish(ENGINE *e)
+{
+ int to_return = 1;
+ if(surewarehk_dso == NULL)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH,ENGINE_R_NOT_LOADED);
+ to_return = 0;
+ goto err;
+ }
+ p_surewarehk_Finish();
+ if(!DSO_free(surewarehk_dso))
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH,ENGINE_R_DSO_FAILURE);
+ to_return = 0;
+ goto err;
+ }
+ err:
+ if (logstream)
+ BIO_free(logstream);
+ surewarehk_dso = NULL;
+ p_surewarehk_Init = NULL;
+ p_surewarehk_Finish = NULL;
+ p_surewarehk_Rand_Bytes = NULL;
+ p_surewarehk_Rand_Seed = NULL;
+ p_surewarehk_Load_Privkey = NULL;
+ p_surewarehk_Load_Rsa_Pubkey = NULL;
+ p_surewarehk_Free = NULL;
+ p_surewarehk_Rsa_Priv_Dec = NULL;
+ p_surewarehk_Rsa_Sign = NULL;
+ p_surewarehk_Dsa_Sign = NULL;
+ p_surewarehk_Info_Pubkey = NULL;
+ p_surewarehk_Load_Dsa_Pubkey = NULL;
+ p_surewarehk_Mod_Exp = NULL;
+ return to_return;
+}
+
+static void surewarehk_error_handling(char *const msg,int func,int ret)
+{
+ switch (ret)
+ {
+ case SUREWAREHOOK_ERROR_UNIT_FAILURE:
+ ENGINEerr(func,SUREWARE_R_UNIT_FAILURE);
+ break;
+ case SUREWAREHOOK_ERROR_FALLBACK:
+ ENGINEerr(func,SUREWARE_R_REQUEST_FALLBACK);
+ break;
+ case SUREWAREHOOK_ERROR_DATA_SIZE:
+ ENGINEerr(func,SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+ break;
+ case SUREWAREHOOK_ERROR_INVALID_PAD:
+ ENGINEerr(func,SUREWARE_R_PADDING_CHECK_FAILED);
+ break;
+ default:
+ ENGINEerr(func,SUREWARE_R_REQUEST_FAILED);
+ break;
+ case 1:/*nothing*/
+ msg[0]='\0';
+ }
+ if (*msg)
+ {
+ ERR_add_error_data(1,msg);
+ if (logstream)
+ {
+ CRYPTO_w_lock(CRYPTO_LOCK_BIO);
+ BIO_write(logstream, msg, strlen(msg));
+ CRYPTO_w_unlock(CRYPTO_LOCK_BIO);
+ }
+ }
+}
+
+static int surewarehk_rand_bytes(unsigned char *buf, int num)
+{
+ int ret=0;
+ char msg[64]="ENGINE_rand_bytes";
+ if(!p_surewarehk_Rand_Bytes)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_BYTES,ENGINE_R_NOT_INITIALISED);
+ }
+ else
+ {
+ ret = p_surewarehk_Rand_Bytes(msg,buf, num);
+ surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RAND_BYTES,ret);
+ }
+ return ret==1 ? 1 : 0;
+}
+
+static void surewarehk_rand_seed(const void *buf, int num)
+{
+ int ret=0;
+ char msg[64]="ENGINE_rand_seed";
+ if(!p_surewarehk_Rand_Seed)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_SEED,ENGINE_R_NOT_INITIALISED);
+ }
+ else
+ {
+ ret = p_surewarehk_Rand_Seed(msg,buf, num);
+ surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RAND_SEED,ret);
+ }
+}
+
+static void surewarehk_rand_add(const void *buf, int num, double entropy)
+{
+ surewarehk_rand_seed(buf,num);
+}
+
+static EVP_PKEY* sureware_load_public(ENGINE *e,const char *key_id,char *hptr,unsigned long el,char keytype)
+{
+ EVP_PKEY *res = NULL;
+#ifndef OPENSSL_NO_RSA
+ RSA *rsatmp = NULL;
+#endif
+#ifndef OPENSSL_NO_DSA
+ DSA *dsatmp=NULL;
+#endif
+ char msg[64]="sureware_load_public";
+ int ret=0;
+ if(!p_surewarehk_Load_Rsa_Pubkey || !p_surewarehk_Load_Dsa_Pubkey)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_NOT_INITIALISED);
+ goto err;
+ }
+ switch (keytype)
+ {
+#ifndef OPENSSL_NO_RSA
+ case 1: /*RSA*/
+ /* set private external reference */
+ rsatmp = RSA_new_method(e);
+ RSA_set_ex_data(rsatmp,rsaHndidx,hptr);
+ rsatmp->flags |= RSA_FLAG_EXT_PKEY;
+
+ /* set public big nums*/
+ rsatmp->e = BN_new();
+ rsatmp->n = BN_new();
+ bn_expand2(rsatmp->e, el/sizeof(BN_ULONG));
+ bn_expand2(rsatmp->n, el/sizeof(BN_ULONG));
+ if (!rsatmp->e || rsatmp->e->dmax!=(int)(el/sizeof(BN_ULONG))||
+ !rsatmp->n || rsatmp->n->dmax!=(int)(el/sizeof(BN_ULONG)))
+ goto err;
+ ret=p_surewarehk_Load_Rsa_Pubkey(msg,key_id,el,
+ (unsigned long *)rsatmp->n->d,
+ (unsigned long *)rsatmp->e->d);
+ surewarehk_error_handling(msg,SUREWARE_F_SUREWARE_LOAD_PUBLIC,ret);
+ if (ret!=1)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
+ goto err;
+ }
+ /* normalise pub e and pub n */
+ rsatmp->e->top=el/sizeof(BN_ULONG);
+ bn_fix_top(rsatmp->e);
+ rsatmp->n->top=el/sizeof(BN_ULONG);
+ bn_fix_top(rsatmp->n);
+ /* create an EVP object: engine + rsa key */
+ res = EVP_PKEY_new();
+ EVP_PKEY_assign_RSA(res, rsatmp);
+ break;
+#endif
+
+#ifndef OPENSSL_NO_DSA
+ case 2:/*DSA*/
+ /* set private/public external reference */
+ dsatmp = DSA_new_method(e);
+ DSA_set_ex_data(dsatmp,dsaHndidx,hptr);
+ /*dsatmp->flags |= DSA_FLAG_EXT_PKEY;*/
+
+ /* set public key*/
+ dsatmp->pub_key = BN_new();
+ dsatmp->p = BN_new();
+ dsatmp->q = BN_new();
+ dsatmp->g = BN_new();
+ bn_expand2(dsatmp->pub_key, el/sizeof(BN_ULONG));
+ bn_expand2(dsatmp->p, el/sizeof(BN_ULONG));
+ bn_expand2(dsatmp->q, 20/sizeof(BN_ULONG));
+ bn_expand2(dsatmp->g, el/sizeof(BN_ULONG));
+ if (!dsatmp->pub_key || dsatmp->pub_key->dmax!=(int)(el/sizeof(BN_ULONG))||
+ !dsatmp->p || dsatmp->p->dmax!=(int)(el/sizeof(BN_ULONG)) ||
+ !dsatmp->q || dsatmp->q->dmax!=20/sizeof(BN_ULONG) ||
+ !dsatmp->g || dsatmp->g->dmax!=(int)(el/sizeof(BN_ULONG)))
+ goto err;
+
+ ret=p_surewarehk_Load_Dsa_Pubkey(msg,key_id,el,
+ (unsigned long *)dsatmp->pub_key->d,
+ (unsigned long *)dsatmp->p->d,
+ (unsigned long *)dsatmp->q->d,
+ (unsigned long *)dsatmp->g->d);
+ surewarehk_error_handling(msg,SUREWARE_F_SUREWARE_LOAD_PUBLIC,ret);
+ if (ret!=1)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
+ goto err;
+ }
+ /* set parameters */
+ /* normalise pubkey and parameters in case of */
+ dsatmp->pub_key->top=el/sizeof(BN_ULONG);
+ bn_fix_top(dsatmp->pub_key);
+ dsatmp->p->top=el/sizeof(BN_ULONG);
+ bn_fix_top(dsatmp->p);
+ dsatmp->q->top=20/sizeof(BN_ULONG);
+ bn_fix_top(dsatmp->q);
+ dsatmp->g->top=el/sizeof(BN_ULONG);
+ bn_fix_top(dsatmp->g);
+
+ /* create an EVP object: engine + rsa key */
+ res = EVP_PKEY_new();
+ EVP_PKEY_assign_DSA(res, dsatmp);
+ break;
+#endif
+
+ default:
+ SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
+ goto err;
+ }
+ return res;
+ err:
+ if (res)
+ EVP_PKEY_free(res);
+#ifndef OPENSSL_NO_RSA
+ if (rsatmp)
+ RSA_free(rsatmp);
+#endif
+#ifndef OPENSSL_NO_DSA
+ if (dsatmp)
+ DSA_free(dsatmp);
+#endif
+ return NULL;
+}
+
+static EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id,
+ UI_METHOD *ui_method, void *callback_data)
+{
+ EVP_PKEY *res = NULL;
+ int ret=0;
+ unsigned long el=0;
+ char *hptr=NULL;
+ char keytype=0;
+ char msg[64]="ENGINE_load_privkey";
+
+ if(!p_surewarehk_Load_Privkey)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY,ENGINE_R_NOT_INITIALISED);
+ }
+ else
+ {
+ ret=p_surewarehk_Load_Privkey(msg,key_id,&hptr,&el,&keytype);
+ if (ret!=1)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY,ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
+ ERR_add_error_data(1,msg);
+ }
+ else
+ res=sureware_load_public(e,key_id,hptr,el,keytype);
+ }
+ return res;
+}
+
+static EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id,
+ UI_METHOD *ui_method, void *callback_data)
+{
+ EVP_PKEY *res = NULL;
+ int ret=0;
+ unsigned long el=0;
+ char *hptr=NULL;
+ char keytype=0;
+ char msg[64]="ENGINE_load_pubkey";
+
+ if(!p_surewarehk_Info_Pubkey)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY,ENGINE_R_NOT_INITIALISED);
+ }
+ else
+ {
+ /* call once to identify if DSA or RSA */
+ ret=p_surewarehk_Info_Pubkey(msg,key_id,&el,&keytype);
+ if (ret!=1)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY,ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
+ ERR_add_error_data(1,msg);
+ }
+ else
+ res=sureware_load_public(e,key_id,hptr,el,keytype);
+ }
+ return res;
+}
+
+/* This cleans up an RSA/DSA KM key(do not destroy the key into the hardware)
+, called when ex_data is freed */
+static void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
+ int idx,long argl, void *argp)
+{
+ if(!p_surewarehk_Free)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_EX_FREE,ENGINE_R_NOT_INITIALISED);
+ }
+ else
+ p_surewarehk_Free((char *)item,0);
+}
+
+#if 0
+/* not currently used (bug?) */
+/* This cleans up an DH KM key (destroys the key into hardware),
+called when ex_data is freed */
+static void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
+ int idx,long argl, void *argp)
+{
+ if(!p_surewarehk_Free)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_DH_EX_FREE,ENGINE_R_NOT_INITIALISED);
+ }
+ else
+ p_surewarehk_Free((char *)item,1);
+}
+#endif
+
+/*
+* return number of decrypted bytes
+*/
+#ifndef OPENSSL_NO_RSA
+static int surewarehk_rsa_priv_dec(int flen,const unsigned char *from,unsigned char *to,
+ RSA *rsa,int padding)
+{
+ int ret=0,tlen;
+ char *buf=NULL,*hptr=NULL;
+ char msg[64]="ENGINE_rsa_priv_dec";
+ if (!p_surewarehk_Rsa_Priv_Dec)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ENGINE_R_NOT_INITIALISED);
+ }
+ /* extract ref to private key */
+ else if (!(hptr=RSA_get_ex_data(rsa, rsaHndidx)))
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,SUREWARE_R_MISSING_KEY_COMPONENTS);
+ goto err;
+ }
+ /* analyse what padding we can do into the hardware */
+ if (padding==RSA_PKCS1_PADDING)
+ {
+ /* do it one shot */
+ ret=p_surewarehk_Rsa_Priv_Dec(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_PKCS1_PAD);
+ surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ret);
+ if (ret!=1)
+ goto err;
+ ret=tlen;
+ }
+ else /* do with no padding into hardware */
+ {
+ ret=p_surewarehk_Rsa_Priv_Dec(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_NO_PAD);
+ surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ret);
+ if (ret!=1)
+ goto err;
+ /* intermediate buffer for padding */
+ if ((buf=OPENSSL_malloc(tlen)) == NULL)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ memcpy(buf,to,tlen);/* transfert to into buf */
+ switch (padding) /* check padding in software */
+ {
+#ifndef OPENSSL_NO_SHA
+ case RSA_PKCS1_OAEP_PADDING:
+ ret=RSA_padding_check_PKCS1_OAEP(to,tlen,(unsigned char *)buf,tlen,tlen,NULL,0);
+ break;
+#endif
+ case RSA_SSLV23_PADDING:
+ ret=RSA_padding_check_SSLv23(to,tlen,(unsigned char *)buf,flen,tlen);
+ break;
+ case RSA_NO_PADDING:
+ ret=RSA_padding_check_none(to,tlen,(unsigned char *)buf,flen,tlen);
+ break;
+ default:
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,SUREWARE_R_UNKNOWN_PADDING_TYPE);
+ goto err;
+ }
+ if (ret < 0)
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,SUREWARE_R_PADDING_CHECK_FAILED);
+ }
+err:
+ if (buf)
+ {
+ OPENSSL_cleanse(buf,tlen);
+ OPENSSL_free(buf);
+ }
+ return ret;
+}
+
+/*
+* Does what OpenSSL rsa_priv_enc does.
+*/
+static int surewarehk_rsa_sign(int flen,const unsigned char *from,unsigned char *to,
+ RSA *rsa,int padding)
+{
+ int ret=0,tlen;
+ char *hptr=NULL;
+ char msg[64]="ENGINE_rsa_sign";
+ if (!p_surewarehk_Rsa_Sign)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN,ENGINE_R_NOT_INITIALISED);
+ }
+ /* extract ref to private key */
+ else if (!(hptr=RSA_get_ex_data(rsa, rsaHndidx)))
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN,SUREWARE_R_MISSING_KEY_COMPONENTS);
+ }
+ else
+ {
+ switch (padding)
+ {
+ case RSA_PKCS1_PADDING: /* do it in one shot */
+ ret=p_surewarehk_Rsa_Sign(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_PKCS1_PAD);
+ surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_SIGN,ret);
+ break;
+ case RSA_NO_PADDING:
+ default:
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN,SUREWARE_R_UNKNOWN_PADDING_TYPE);
+ }
+ }
+ return ret==1 ? tlen : ret;
+}
+
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* DSA sign and verify */
+static DSA_SIG * surewarehk_dsa_do_sign(const unsigned char *from, int flen, DSA *dsa)
+{
+ int ret=0;
+ char *hptr=NULL;
+ DSA_SIG *psign=NULL;
+ char msg[64]="ENGINE_dsa_do_sign";
+ if (!p_surewarehk_Dsa_Sign)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ENGINE_R_NOT_INITIALISED);
+ goto err;
+ }
+ /* extract ref to private key */
+ else if (!(hptr=DSA_get_ex_data(dsa, dsaHndidx)))
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,SUREWARE_R_MISSING_KEY_COMPONENTS);
+ goto err;
+ }
+ else
+ {
+ if((psign = DSA_SIG_new()) == NULL)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ psign->r=BN_new();
+ psign->s=BN_new();
+ bn_expand2(psign->r, 20/sizeof(BN_ULONG));
+ bn_expand2(psign->s, 20/sizeof(BN_ULONG));
+ if (!psign->r || psign->r->dmax!=20/sizeof(BN_ULONG) ||
+ !psign->s || psign->s->dmax!=20/sizeof(BN_ULONG))
+ goto err;
+ ret=p_surewarehk_Dsa_Sign(msg,flen,from,
+ (unsigned long *)psign->r->d,
+ (unsigned long *)psign->s->d,
+ hptr);
+ surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ret);
+ }
+ psign->r->top=20/sizeof(BN_ULONG);
+ bn_fix_top(psign->r);
+ psign->s->top=20/sizeof(BN_ULONG);
+ bn_fix_top(psign->s);
+
+err:
+ if (psign)
+ {
+ DSA_SIG_free(psign);
+ psign=NULL;
+ }
+ return psign;
+}
+#endif
+
+static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx)
+{
+ int ret=0;
+ char msg[64]="ENGINE_modexp";
+ if (!p_surewarehk_Mod_Exp)
+ {
+ SUREWAREerr(SUREWARE_F_SUREWAREHK_MODEXP,ENGINE_R_NOT_INITIALISED);
+ }
+ else
+ {
+ bn_expand2(r,m->top);
+ if (r && r->dmax==m->top)
+ {
+ /* do it*/
+ ret=p_surewarehk_Mod_Exp(msg,
+ m->top*sizeof(BN_ULONG),
+ (unsigned long *)m->d,
+ p->top*sizeof(BN_ULONG),
+ (unsigned long *)p->d,
+ a->top*sizeof(BN_ULONG),
+ (unsigned long *)a->d,
+ (unsigned long *)r->d);
+ surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_MODEXP,ret);
+ if (ret==1)
+ {
+ /* normalise result */
+ r->top=m->top;
+ bn_fix_top(r);
+ }
+ }
+ }
+ return ret;
+}
+#endif /* !OPENSSL_NO_HW_SureWare */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_sureware.ec b/openssl/engines/e_sureware.ec
new file mode 100644
index 000000000..3d266b8b7
--- /dev/null
+++ b/openssl/engines/e_sureware.ec
@@ -0,0 +1 @@
+L SUREWARE e_sureware_err.h e_sureware_err.c
diff --git a/openssl/engines/e_sureware_err.c b/openssl/engines/e_sureware_err.c
new file mode 100644
index 000000000..d4ca68c1d
--- /dev/null
+++ b/openssl/engines/e_sureware_err.c
@@ -0,0 +1,158 @@
+/* e_sureware_err.c */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+/* 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 "e_sureware_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA SUREWARE_str_functs[]=
+ {
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_CTRL), "SUREWAREHK_CTRL"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_DH_EX_FREE), "SUREWAREHK_DH_EX_FREE"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN), "SUREWAREHK_DSA_DO_SIGN"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_EX_FREE), "SUREWAREHK_EX_FREE"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_FINISH), "SUREWAREHK_FINISH"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_INIT), "SUREWAREHK_INIT"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY), "SUREWAREHK_LOAD_PRIVKEY"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY), "SUREWAREHK_LOAD_PUBKEY"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_MODEXP), "SUREWAREHK_MODEXP"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_RAND_BYTES), "SUREWAREHK_RAND_BYTES"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_RAND_SEED), "SUREWAREHK_RAND_SEED"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC), "SUREWAREHK_RSA_PRIV_DEC"},
+{ERR_FUNC(SUREWARE_F_SUREWAREHK_RSA_SIGN), "SUREWAREHK_RSA_SIGN"},
+{ERR_FUNC(SUREWARE_F_SUREWARE_LOAD_PUBLIC), "SUREWARE_LOAD_PUBLIC"},
+{0,NULL}
+ };
+
+static ERR_STRING_DATA SUREWARE_str_reasons[]=
+ {
+{ERR_REASON(SUREWARE_R_BIO_WAS_FREED) ,"bio was freed"},
+{ERR_REASON(SUREWARE_R_MISSING_KEY_COMPONENTS),"missing key components"},
+{ERR_REASON(SUREWARE_R_PADDING_CHECK_FAILED),"padding check failed"},
+{ERR_REASON(SUREWARE_R_REQUEST_FAILED) ,"request failed"},
+{ERR_REASON(SUREWARE_R_REQUEST_FALLBACK) ,"request fallback"},
+{ERR_REASON(SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL),"size too large or too small"},
+{ERR_REASON(SUREWARE_R_UNIT_FAILURE) ,"unit failure"},
+{ERR_REASON(SUREWARE_R_UNKNOWN_PADDING_TYPE),"unknown padding type"},
+{0,NULL}
+ };
+
+#endif
+
+#ifdef SUREWARE_LIB_NAME
+static ERR_STRING_DATA SUREWARE_lib_name[]=
+ {
+{0 ,SUREWARE_LIB_NAME},
+{0,NULL}
+ };
+#endif
+
+
+static int SUREWARE_lib_error_code=0;
+static int SUREWARE_error_init=1;
+
+static void ERR_load_SUREWARE_strings(void)
+ {
+ if (SUREWARE_lib_error_code == 0)
+ SUREWARE_lib_error_code=ERR_get_next_error_library();
+
+ if (SUREWARE_error_init)
+ {
+ SUREWARE_error_init=0;
+#ifndef OPENSSL_NO_ERR
+ ERR_load_strings(SUREWARE_lib_error_code,SUREWARE_str_functs);
+ ERR_load_strings(SUREWARE_lib_error_code,SUREWARE_str_reasons);
+#endif
+
+#ifdef SUREWARE_LIB_NAME
+ SUREWARE_lib_name->error = ERR_PACK(SUREWARE_lib_error_code,0,0);
+ ERR_load_strings(0,SUREWARE_lib_name);
+#endif
+ }
+ }
+
+static void ERR_unload_SUREWARE_strings(void)
+ {
+ if (SUREWARE_error_init == 0)
+ {
+#ifndef OPENSSL_NO_ERR
+ ERR_unload_strings(SUREWARE_lib_error_code,SUREWARE_str_functs);
+ ERR_unload_strings(SUREWARE_lib_error_code,SUREWARE_str_reasons);
+#endif
+
+#ifdef SUREWARE_LIB_NAME
+ ERR_unload_strings(0,SUREWARE_lib_name);
+#endif
+ SUREWARE_error_init=1;
+ }
+ }
+
+static void ERR_SUREWARE_error(int function, int reason, char *file, int line)
+ {
+ if (SUREWARE_lib_error_code == 0)
+ SUREWARE_lib_error_code=ERR_get_next_error_library();
+ ERR_PUT_error(SUREWARE_lib_error_code,function,reason,file,line);
+ }
diff --git a/openssl/engines/e_sureware_err.h b/openssl/engines/e_sureware_err.h
new file mode 100644
index 000000000..ec8ed0c59
--- /dev/null
+++ b/openssl/engines/e_sureware_err.h
@@ -0,0 +1,102 @@
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * 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_SUREWARE_ERR_H
+#define HEADER_SUREWARE_ERR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_SUREWARE_strings(void);
+static void ERR_unload_SUREWARE_strings(void);
+static void ERR_SUREWARE_error(int function, int reason, char *file, int line);
+#define SUREWAREerr(f,r) ERR_SUREWARE_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the SUREWARE functions. */
+
+/* Function codes. */
+#define SUREWARE_F_SUREWAREHK_CTRL 100
+#define SUREWARE_F_SUREWAREHK_DH_EX_FREE 112
+#define SUREWARE_F_SUREWAREHK_DSA_DO_SIGN 101
+#define SUREWARE_F_SUREWAREHK_EX_FREE 102
+#define SUREWARE_F_SUREWAREHK_FINISH 103
+#define SUREWARE_F_SUREWAREHK_INIT 104
+#define SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY 105
+#define SUREWARE_F_SUREWAREHK_LOAD_PUBKEY 113
+#define SUREWARE_F_SUREWAREHK_MODEXP 107
+#define SUREWARE_F_SUREWAREHK_RAND_BYTES 108
+#define SUREWARE_F_SUREWAREHK_RAND_SEED 109
+#define SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC 110
+#define SUREWARE_F_SUREWAREHK_RSA_SIGN 111
+#define SUREWARE_F_SUREWARE_LOAD_PUBLIC 106
+
+/* Reason codes. */
+#define SUREWARE_R_BIO_WAS_FREED 100
+#define SUREWARE_R_MISSING_KEY_COMPONENTS 105
+#define SUREWARE_R_PADDING_CHECK_FAILED 106
+#define SUREWARE_R_REQUEST_FAILED 101
+#define SUREWARE_R_REQUEST_FALLBACK 102
+#define SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL 103
+#define SUREWARE_R_UNIT_FAILURE 104
+#define SUREWARE_R_UNKNOWN_PADDING_TYPE 107
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/e_ubsec.c b/openssl/engines/e_ubsec.c
new file mode 100644
index 000000000..e8389de6a
--- /dev/null
+++ b/openssl/engines/e_ubsec.c
@@ -0,0 +1,1070 @@
+/* crypto/engine/hw_ubsec.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ *
+ * Cloned shamelessly by Joe Tardo.
+ */
+/* ====================================================================
+ * 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/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/dso.h>
+#include <openssl/engine.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/bn.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_UBSEC
+
+#ifdef FLAT_INC
+#include "hw_ubsec.h"
+#else
+#include "vendor_defns/hw_ubsec.h"
+#endif
+
+#define UBSEC_LIB_NAME "ubsec engine"
+#include "e_ubsec_err.c"
+
+#define FAIL_TO_SOFTWARE -15
+
+static int ubsec_destroy(ENGINE *e);
+static int ubsec_init(ENGINE *e);
+static int ubsec_finish(ENGINE *e);
+static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *q, const BIGNUM *dp,
+ const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx);
+#ifndef OPENSSL_NO_RSA
+static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+#endif
+static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+#ifndef OPENSSL_NO_DSA
+#ifdef NOT_USED
+static int ubsec_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);
+static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+ const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx);
+#endif
+static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
+static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
+ DSA_SIG *sig, DSA *dsa);
+#endif
+#ifndef OPENSSL_NO_DH
+static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx);
+static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh);
+static int ubsec_dh_generate_key(DH *dh);
+#endif
+
+#ifdef NOT_USED
+static int ubsec_rand_bytes(unsigned char *buf, int num);
+static int ubsec_rand_status(void);
+#endif
+
+#define UBSEC_CMD_SO_PATH ENGINE_CMD_BASE
+static const ENGINE_CMD_DEFN ubsec_cmd_defns[] = {
+ {UBSEC_CMD_SO_PATH,
+ "SO_PATH",
+ "Specifies the path to the 'ubsec' shared library",
+ ENGINE_CMD_FLAG_STRING},
+ {0, NULL, NULL, 0}
+ };
+
+#ifndef OPENSSL_NO_RSA
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD ubsec_rsa =
+ {
+ "UBSEC RSA method",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ ubsec_rsa_mod_exp,
+ ubsec_mod_exp_mont,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* Our internal DSA_METHOD that we provide pointers to */
+static DSA_METHOD ubsec_dsa =
+ {
+ "UBSEC DSA method",
+ ubsec_dsa_do_sign, /* dsa_do_sign */
+ NULL, /* dsa_sign_setup */
+ ubsec_dsa_verify, /* dsa_do_verify */
+ NULL, /* ubsec_dsa_mod_exp */ /* dsa_mod_exp */
+ NULL, /* ubsec_mod_exp_dsa */ /* bn_mod_exp */
+ NULL, /* init */
+ NULL, /* finish */
+ 0, /* flags */
+ NULL, /* app_data */
+ NULL, /* dsa_paramgen */
+ NULL /* dsa_keygen */
+ };
+#endif
+
+#ifndef OPENSSL_NO_DH
+/* Our internal DH_METHOD that we provide pointers to */
+static DH_METHOD ubsec_dh =
+ {
+ "UBSEC DH method",
+ ubsec_dh_generate_key,
+ ubsec_dh_compute_key,
+ ubsec_mod_exp_dh,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ NULL
+ };
+#endif
+
+/* Constants used when creating the ENGINE */
+static const char *engine_ubsec_id = "ubsec";
+static const char *engine_ubsec_name = "UBSEC hardware engine support";
+
+/* This internal function is used by ENGINE_ubsec() and possibly by the
+ * "dynamic" ENGINE support too */
+static int bind_helper(ENGINE *e)
+ {
+#ifndef OPENSSL_NO_RSA
+ const RSA_METHOD *meth1;
+#endif
+#ifndef OPENSSL_NO_DH
+#ifndef HAVE_UBSEC_DH
+ const DH_METHOD *meth3;
+#endif /* HAVE_UBSEC_DH */
+#endif
+ if(!ENGINE_set_id(e, engine_ubsec_id) ||
+ !ENGINE_set_name(e, engine_ubsec_name) ||
+#ifndef OPENSSL_NO_RSA
+ !ENGINE_set_RSA(e, &ubsec_rsa) ||
+#endif
+#ifndef OPENSSL_NO_DSA
+ !ENGINE_set_DSA(e, &ubsec_dsa) ||
+#endif
+#ifndef OPENSSL_NO_DH
+ !ENGINE_set_DH(e, &ubsec_dh) ||
+#endif
+ !ENGINE_set_destroy_function(e, ubsec_destroy) ||
+ !ENGINE_set_init_function(e, ubsec_init) ||
+ !ENGINE_set_finish_function(e, ubsec_finish) ||
+ !ENGINE_set_ctrl_function(e, ubsec_ctrl) ||
+ !ENGINE_set_cmd_defns(e, ubsec_cmd_defns))
+ return 0;
+
+#ifndef OPENSSL_NO_RSA
+ /* We know that the "PKCS1_SSLeay()" functions hook properly
+ * to the Broadcom-specific mod_exp and mod_exp_crt so we use
+ * those functions. NB: We don't use ENGINE_openssl() or
+ * anything "more generic" because something like the RSAref
+ * code may not hook properly, and if you own one of these
+ * cards then you have the right to do RSA operations on it
+ * anyway! */
+ meth1 = RSA_PKCS1_SSLeay();
+ ubsec_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+ ubsec_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+ ubsec_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
+ ubsec_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
+#endif
+
+#ifndef OPENSSL_NO_DH
+#ifndef HAVE_UBSEC_DH
+ /* Much the same for Diffie-Hellman */
+ meth3 = DH_OpenSSL();
+ ubsec_dh.generate_key = meth3->generate_key;
+ ubsec_dh.compute_key = meth3->compute_key;
+#endif /* HAVE_UBSEC_DH */
+#endif
+
+ /* Ensure the ubsec error handling is set up */
+ ERR_load_UBSEC_strings();
+ return 1;
+ }
+
+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+static ENGINE *engine_ubsec(void)
+ {
+ ENGINE *ret = ENGINE_new();
+ if(!ret)
+ return NULL;
+ if(!bind_helper(ret))
+ {
+ ENGINE_free(ret);
+ return NULL;
+ }
+ return ret;
+ }
+
+void ENGINE_load_ubsec(void)
+ {
+ /* Copied from eng_[openssl|dyn].c */
+ ENGINE *toadd = engine_ubsec();
+ if(!toadd) return;
+ ENGINE_add(toadd);
+ ENGINE_free(toadd);
+ ERR_clear_error();
+ }
+#endif
+
+/* This is a process-global DSO handle used for loading and unloading
+ * the UBSEC library. NB: This is only set (or unset) during an
+ * init() or finish() call (reference counts permitting) and they're
+ * operating with global locks, so this should be thread-safe
+ * implicitly. */
+
+static DSO *ubsec_dso = NULL;
+
+/* These are the function pointers that are (un)set when the library has
+ * successfully (un)loaded. */
+
+static t_UBSEC_ubsec_bytes_to_bits *p_UBSEC_ubsec_bytes_to_bits = NULL;
+static t_UBSEC_ubsec_bits_to_bytes *p_UBSEC_ubsec_bits_to_bytes = NULL;
+static t_UBSEC_ubsec_open *p_UBSEC_ubsec_open = NULL;
+static t_UBSEC_ubsec_close *p_UBSEC_ubsec_close = NULL;
+#ifndef OPENSSL_NO_DH
+static t_UBSEC_diffie_hellman_generate_ioctl
+ *p_UBSEC_diffie_hellman_generate_ioctl = NULL;
+static t_UBSEC_diffie_hellman_agree_ioctl *p_UBSEC_diffie_hellman_agree_ioctl = NULL;
+#endif
+/* #ifndef OPENSSL_NO_RSA */
+static t_UBSEC_rsa_mod_exp_ioctl *p_UBSEC_rsa_mod_exp_ioctl = NULL;
+static t_UBSEC_rsa_mod_exp_crt_ioctl *p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
+/* #endif */
+#ifndef OPENSSL_NO_DSA
+static t_UBSEC_dsa_sign_ioctl *p_UBSEC_dsa_sign_ioctl = NULL;
+static t_UBSEC_dsa_verify_ioctl *p_UBSEC_dsa_verify_ioctl = NULL;
+#endif
+static t_UBSEC_math_accelerate_ioctl *p_UBSEC_math_accelerate_ioctl = NULL;
+static t_UBSEC_rng_ioctl *p_UBSEC_rng_ioctl = NULL;
+static t_UBSEC_max_key_len_ioctl *p_UBSEC_max_key_len_ioctl = NULL;
+
+static int max_key_len = 1024; /* ??? */
+
+/*
+ * These are the static string constants for the DSO file name and the function
+ * symbol names to bind to.
+ */
+
+static const char *UBSEC_LIBNAME = NULL;
+static const char *get_UBSEC_LIBNAME(void)
+ {
+ if(UBSEC_LIBNAME)
+ return UBSEC_LIBNAME;
+ return "ubsec";
+ }
+static void free_UBSEC_LIBNAME(void)
+ {
+ if(UBSEC_LIBNAME)
+ OPENSSL_free((void*)UBSEC_LIBNAME);
+ UBSEC_LIBNAME = NULL;
+ }
+static long set_UBSEC_LIBNAME(const char *name)
+ {
+ free_UBSEC_LIBNAME();
+ return (((UBSEC_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
+ }
+static const char *UBSEC_F1 = "ubsec_bytes_to_bits";
+static const char *UBSEC_F2 = "ubsec_bits_to_bytes";
+static const char *UBSEC_F3 = "ubsec_open";
+static const char *UBSEC_F4 = "ubsec_close";
+#ifndef OPENSSL_NO_DH
+static const char *UBSEC_F5 = "diffie_hellman_generate_ioctl";
+static const char *UBSEC_F6 = "diffie_hellman_agree_ioctl";
+#endif
+/* #ifndef OPENSSL_NO_RSA */
+static const char *UBSEC_F7 = "rsa_mod_exp_ioctl";
+static const char *UBSEC_F8 = "rsa_mod_exp_crt_ioctl";
+/* #endif */
+#ifndef OPENSSL_NO_DSA
+static const char *UBSEC_F9 = "dsa_sign_ioctl";
+static const char *UBSEC_F10 = "dsa_verify_ioctl";
+#endif
+static const char *UBSEC_F11 = "math_accelerate_ioctl";
+static const char *UBSEC_F12 = "rng_ioctl";
+static const char *UBSEC_F13 = "ubsec_max_key_len_ioctl";
+
+/* Destructor (complements the "ENGINE_ubsec()" constructor) */
+static int ubsec_destroy(ENGINE *e)
+ {
+ free_UBSEC_LIBNAME();
+ ERR_unload_UBSEC_strings();
+ return 1;
+ }
+
+/* (de)initialisation functions. */
+static int ubsec_init(ENGINE *e)
+ {
+ t_UBSEC_ubsec_bytes_to_bits *p1;
+ t_UBSEC_ubsec_bits_to_bytes *p2;
+ t_UBSEC_ubsec_open *p3;
+ t_UBSEC_ubsec_close *p4;
+#ifndef OPENSSL_NO_DH
+ t_UBSEC_diffie_hellman_generate_ioctl *p5;
+ t_UBSEC_diffie_hellman_agree_ioctl *p6;
+#endif
+/* #ifndef OPENSSL_NO_RSA */
+ t_UBSEC_rsa_mod_exp_ioctl *p7;
+ t_UBSEC_rsa_mod_exp_crt_ioctl *p8;
+/* #endif */
+#ifndef OPENSSL_NO_DSA
+ t_UBSEC_dsa_sign_ioctl *p9;
+ t_UBSEC_dsa_verify_ioctl *p10;
+#endif
+ t_UBSEC_math_accelerate_ioctl *p11;
+ t_UBSEC_rng_ioctl *p12;
+ t_UBSEC_max_key_len_ioctl *p13;
+ int fd = 0;
+
+ if(ubsec_dso != NULL)
+ {
+ UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_ALREADY_LOADED);
+ goto err;
+ }
+ /*
+ * Attempt to load libubsec.so/ubsec.dll/whatever.
+ */
+ ubsec_dso = DSO_load(NULL, get_UBSEC_LIBNAME(), NULL, 0);
+ if(ubsec_dso == NULL)
+ {
+ UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
+ goto err;
+ }
+
+ if (
+ !(p1 = (t_UBSEC_ubsec_bytes_to_bits *) DSO_bind_func(ubsec_dso, UBSEC_F1)) ||
+ !(p2 = (t_UBSEC_ubsec_bits_to_bytes *) DSO_bind_func(ubsec_dso, UBSEC_F2)) ||
+ !(p3 = (t_UBSEC_ubsec_open *) DSO_bind_func(ubsec_dso, UBSEC_F3)) ||
+ !(p4 = (t_UBSEC_ubsec_close *) DSO_bind_func(ubsec_dso, UBSEC_F4)) ||
+#ifndef OPENSSL_NO_DH
+ !(p5 = (t_UBSEC_diffie_hellman_generate_ioctl *)
+ DSO_bind_func(ubsec_dso, UBSEC_F5)) ||
+ !(p6 = (t_UBSEC_diffie_hellman_agree_ioctl *)
+ DSO_bind_func(ubsec_dso, UBSEC_F6)) ||
+#endif
+/* #ifndef OPENSSL_NO_RSA */
+ !(p7 = (t_UBSEC_rsa_mod_exp_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F7)) ||
+ !(p8 = (t_UBSEC_rsa_mod_exp_crt_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F8)) ||
+/* #endif */
+#ifndef OPENSSL_NO_DSA
+ !(p9 = (t_UBSEC_dsa_sign_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F9)) ||
+ !(p10 = (t_UBSEC_dsa_verify_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F10)) ||
+#endif
+ !(p11 = (t_UBSEC_math_accelerate_ioctl *)
+ DSO_bind_func(ubsec_dso, UBSEC_F11)) ||
+ !(p12 = (t_UBSEC_rng_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F12)) ||
+ !(p13 = (t_UBSEC_max_key_len_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F13)))
+ {
+ UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
+ goto err;
+ }
+
+ /* Copy the pointers */
+ p_UBSEC_ubsec_bytes_to_bits = p1;
+ p_UBSEC_ubsec_bits_to_bytes = p2;
+ p_UBSEC_ubsec_open = p3;
+ p_UBSEC_ubsec_close = p4;
+#ifndef OPENSSL_NO_DH
+ p_UBSEC_diffie_hellman_generate_ioctl = p5;
+ p_UBSEC_diffie_hellman_agree_ioctl = p6;
+#endif
+#ifndef OPENSSL_NO_RSA
+ p_UBSEC_rsa_mod_exp_ioctl = p7;
+ p_UBSEC_rsa_mod_exp_crt_ioctl = p8;
+#endif
+#ifndef OPENSSL_NO_DSA
+ p_UBSEC_dsa_sign_ioctl = p9;
+ p_UBSEC_dsa_verify_ioctl = p10;
+#endif
+ p_UBSEC_math_accelerate_ioctl = p11;
+ p_UBSEC_rng_ioctl = p12;
+ p_UBSEC_max_key_len_ioctl = p13;
+
+ /* Perform an open to see if there's actually any unit running. */
+ if (((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) > 0) && (p_UBSEC_max_key_len_ioctl(fd, &max_key_len) == 0))
+ {
+ p_UBSEC_ubsec_close(fd);
+ return 1;
+ }
+ else
+ {
+ UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
+ }
+
+err:
+ if(ubsec_dso)
+ DSO_free(ubsec_dso);
+ ubsec_dso = NULL;
+ p_UBSEC_ubsec_bytes_to_bits = NULL;
+ p_UBSEC_ubsec_bits_to_bytes = NULL;
+ p_UBSEC_ubsec_open = NULL;
+ p_UBSEC_ubsec_close = NULL;
+#ifndef OPENSSL_NO_DH
+ p_UBSEC_diffie_hellman_generate_ioctl = NULL;
+ p_UBSEC_diffie_hellman_agree_ioctl = NULL;
+#endif
+#ifndef OPENSSL_NO_RSA
+ p_UBSEC_rsa_mod_exp_ioctl = NULL;
+ p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
+#endif
+#ifndef OPENSSL_NO_DSA
+ p_UBSEC_dsa_sign_ioctl = NULL;
+ p_UBSEC_dsa_verify_ioctl = NULL;
+#endif
+ p_UBSEC_math_accelerate_ioctl = NULL;
+ p_UBSEC_rng_ioctl = NULL;
+ p_UBSEC_max_key_len_ioctl = NULL;
+
+ return 0;
+ }
+
+static int ubsec_finish(ENGINE *e)
+ {
+ free_UBSEC_LIBNAME();
+ if(ubsec_dso == NULL)
+ {
+ UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_NOT_LOADED);
+ return 0;
+ }
+ if(!DSO_free(ubsec_dso))
+ {
+ UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_DSO_FAILURE);
+ return 0;
+ }
+ ubsec_dso = NULL;
+ p_UBSEC_ubsec_bytes_to_bits = NULL;
+ p_UBSEC_ubsec_bits_to_bytes = NULL;
+ p_UBSEC_ubsec_open = NULL;
+ p_UBSEC_ubsec_close = NULL;
+#ifndef OPENSSL_NO_DH
+ p_UBSEC_diffie_hellman_generate_ioctl = NULL;
+ p_UBSEC_diffie_hellman_agree_ioctl = NULL;
+#endif
+#ifndef OPENSSL_NO_RSA
+ p_UBSEC_rsa_mod_exp_ioctl = NULL;
+ p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
+#endif
+#ifndef OPENSSL_NO_DSA
+ p_UBSEC_dsa_sign_ioctl = NULL;
+ p_UBSEC_dsa_verify_ioctl = NULL;
+#endif
+ p_UBSEC_math_accelerate_ioctl = NULL;
+ p_UBSEC_rng_ioctl = NULL;
+ p_UBSEC_max_key_len_ioctl = NULL;
+ return 1;
+ }
+
+static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+ {
+ int initialised = ((ubsec_dso == NULL) ? 0 : 1);
+ switch(cmd)
+ {
+ case UBSEC_CMD_SO_PATH:
+ if(p == NULL)
+ {
+ UBSECerr(UBSEC_F_UBSEC_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ if(initialised)
+ {
+ UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_ALREADY_LOADED);
+ return 0;
+ }
+ return set_UBSEC_LIBNAME((const char *)p);
+ default:
+ break;
+ }
+ UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+ return 0;
+ }
+
+static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx)
+ {
+ int y_len = 0;
+ int fd;
+
+ if(ubsec_dso == NULL)
+ {
+ UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_NOT_LOADED);
+ return 0;
+ }
+
+ /* Check if hardware can't handle this argument. */
+ y_len = BN_num_bits(m);
+ if (y_len > max_key_len) {
+ UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+ return BN_mod_exp(r, a, p, m, ctx);
+ }
+
+ if(!bn_wexpand(r, m->top))
+ {
+ UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_BN_EXPAND_FAIL);
+ return 0;
+ }
+
+ if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
+ fd = 0;
+ UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_UNIT_FAILURE);
+ return BN_mod_exp(r, a, p, m, ctx);
+ }
+
+ if (p_UBSEC_rsa_mod_exp_ioctl(fd, (unsigned char *)a->d, BN_num_bits(a),
+ (unsigned char *)m->d, BN_num_bits(m), (unsigned char *)p->d,
+ BN_num_bits(p), (unsigned char *)r->d, &y_len) != 0)
+ {
+ UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED);
+ p_UBSEC_ubsec_close(fd);
+
+ return BN_mod_exp(r, a, p, m, ctx);
+ }
+
+ p_UBSEC_ubsec_close(fd);
+
+ r->top = (BN_num_bits(m)+BN_BITS2-1)/BN_BITS2;
+ return 1;
+ }
+
+#ifndef OPENSSL_NO_RSA
+static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+ {
+ int to_return = 0;
+
+ if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
+ {
+ UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP, UBSEC_R_MISSING_KEY_COMPONENTS);
+ goto err;
+ }
+
+ to_return = ubsec_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
+ rsa->dmq1, rsa->iqmp, ctx);
+ if (to_return == FAIL_TO_SOFTWARE)
+ {
+ /*
+ * Do in software as hardware failed.
+ */
+ const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
+ to_return = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
+ }
+err:
+ return to_return;
+ }
+#endif
+
+static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *q, const BIGNUM *dp,
+ const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx)
+ {
+ int y_len,
+ m_len,
+ fd;
+
+ m_len = BN_num_bytes(p) + BN_num_bytes(q) + 1;
+ y_len = BN_num_bits(p) + BN_num_bits(q);
+
+ /* Check if hardware can't handle this argument. */
+ if (y_len > max_key_len) {
+ UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+ return FAIL_TO_SOFTWARE;
+ }
+
+ if (!bn_wexpand(r, p->top + q->top + 1)) {
+ UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_BN_EXPAND_FAIL);
+ return 0;
+ }
+
+ if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
+ fd = 0;
+ UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_UNIT_FAILURE);
+ return FAIL_TO_SOFTWARE;
+ }
+
+ if (p_UBSEC_rsa_mod_exp_crt_ioctl(fd,
+ (unsigned char *)a->d, BN_num_bits(a),
+ (unsigned char *)qinv->d, BN_num_bits(qinv),
+ (unsigned char *)dp->d, BN_num_bits(dp),
+ (unsigned char *)p->d, BN_num_bits(p),
+ (unsigned char *)dq->d, BN_num_bits(dq),
+ (unsigned char *)q->d, BN_num_bits(q),
+ (unsigned char *)r->d, &y_len) != 0) {
+ UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_REQUEST_FAILED);
+ p_UBSEC_ubsec_close(fd);
+ return FAIL_TO_SOFTWARE;
+ }
+
+ p_UBSEC_ubsec_close(fd);
+
+ r->top = (BN_num_bits(p) + BN_num_bits(q) + BN_BITS2 - 1)/BN_BITS2;
+ return 1;
+}
+
+#ifndef OPENSSL_NO_DSA
+#ifdef NOT_USED
+static int ubsec_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)
+ {
+ BIGNUM t;
+ int to_return = 0;
+
+ BN_init(&t);
+ /* let rr = a1 ^ p1 mod m */
+ if (!ubsec_mod_exp(rr,a1,p1,m,ctx)) goto end;
+ /* let t = a2 ^ p2 mod m */
+ if (!ubsec_mod_exp(&t,a2,p2,m,ctx)) goto end;
+ /* let rr = rr * t mod m */
+ if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
+ to_return = 1;
+end:
+ BN_free(&t);
+ return to_return;
+ }
+
+static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+ const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx)
+ {
+ return ubsec_mod_exp(r, a, p, m, ctx);
+ }
+#endif
+#endif
+
+/*
+ * This function is aliased to mod_exp (with the mont stuff dropped).
+ */
+static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+ {
+ int ret = 0;
+
+#ifndef OPENSSL_NO_RSA
+ /* Do in software if the key is too large for the hardware. */
+ if (BN_num_bits(m) > max_key_len)
+ {
+ const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
+ ret = (*meth->bn_mod_exp)(r, a, p, m, ctx, m_ctx);
+ }
+ else
+#endif
+ {
+ ret = ubsec_mod_exp(r, a, p, m, ctx);
+ }
+
+ return ret;
+ }
+
+#ifndef OPENSSL_NO_DH
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx)
+ {
+ return ubsec_mod_exp(r, a, p, m, ctx);
+ }
+#endif
+
+#ifndef OPENSSL_NO_DSA
+static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+ {
+ DSA_SIG *to_return = NULL;
+ int s_len = 160, r_len = 160, d_len, fd;
+ BIGNUM m, *r=NULL, *s=NULL;
+
+ BN_init(&m);
+
+ s = BN_new();
+ r = BN_new();
+ if ((s == NULL) || (r==NULL))
+ goto err;
+
+ d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dlen);
+
+ if(!bn_wexpand(r, (160+BN_BITS2-1)/BN_BITS2) ||
+ (!bn_wexpand(s, (160+BN_BITS2-1)/BN_BITS2))) {
+ UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+
+ if (BN_bin2bn(dgst,dlen,&m) == NULL) {
+ UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+
+ if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
+ const DSA_METHOD *meth;
+ fd = 0;
+ UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_UNIT_FAILURE);
+ meth = DSA_OpenSSL();
+ to_return = meth->dsa_do_sign(dgst, dlen, dsa);
+ goto err;
+ }
+
+ if (p_UBSEC_dsa_sign_ioctl(fd, 0, /* compute hash before signing */
+ (unsigned char *)dgst, d_len,
+ NULL, 0, /* compute random value */
+ (unsigned char *)dsa->p->d, BN_num_bits(dsa->p),
+ (unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
+ (unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
+ (unsigned char *)dsa->priv_key->d, BN_num_bits(dsa->priv_key),
+ (unsigned char *)r->d, &r_len,
+ (unsigned char *)s->d, &s_len ) != 0) {
+ const DSA_METHOD *meth;
+
+ UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_REQUEST_FAILED);
+ p_UBSEC_ubsec_close(fd);
+ meth = DSA_OpenSSL();
+ to_return = meth->dsa_do_sign(dgst, dlen, dsa);
+
+ goto err;
+ }
+
+ p_UBSEC_ubsec_close(fd);
+
+ r->top = (160+BN_BITS2-1)/BN_BITS2;
+ s->top = (160+BN_BITS2-1)/BN_BITS2;
+
+ to_return = DSA_SIG_new();
+ if(to_return == NULL) {
+ UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+
+ to_return->r = r;
+ to_return->s = s;
+
+err:
+ if (!to_return) {
+ if (r) BN_free(r);
+ if (s) BN_free(s);
+ }
+ BN_clear_free(&m);
+ return to_return;
+}
+
+static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
+ DSA_SIG *sig, DSA *dsa)
+ {
+ int v_len, d_len;
+ int to_return = 0;
+ int fd;
+ BIGNUM v, *pv = &v;
+
+ BN_init(&v);
+
+ if(!bn_wexpand(pv, dsa->p->top)) {
+ UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+
+ v_len = BN_num_bits(dsa->p);
+
+ d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dgst_len);
+
+ if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
+ const DSA_METHOD *meth;
+ fd = 0;
+ UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_UNIT_FAILURE);
+ meth = DSA_OpenSSL();
+ to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
+ goto err;
+ }
+
+ if (p_UBSEC_dsa_verify_ioctl(fd, 0, /* compute hash before signing */
+ (unsigned char *)dgst, d_len,
+ (unsigned char *)dsa->p->d, BN_num_bits(dsa->p),
+ (unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
+ (unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
+ (unsigned char *)dsa->pub_key->d, BN_num_bits(dsa->pub_key),
+ (unsigned char *)sig->r->d, BN_num_bits(sig->r),
+ (unsigned char *)sig->s->d, BN_num_bits(sig->s),
+ (unsigned char *)v.d, &v_len) != 0) {
+ const DSA_METHOD *meth;
+ UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_REQUEST_FAILED);
+ p_UBSEC_ubsec_close(fd);
+
+ meth = DSA_OpenSSL();
+ to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
+
+ goto err;
+ }
+
+ p_UBSEC_ubsec_close(fd);
+
+ to_return = 1;
+err:
+ BN_clear_free(&v);
+ return to_return;
+ }
+#endif
+
+#ifndef OPENSSL_NO_DH
+static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh)
+ {
+ int ret = -1,
+ k_len,
+ fd;
+
+ k_len = BN_num_bits(dh->p);
+
+ if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
+ {
+ const DH_METHOD *meth;
+ UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_UNIT_FAILURE);
+ meth = DH_OpenSSL();
+ ret = meth->compute_key(key, pub_key, dh);
+ goto err;
+ }
+
+ if (p_UBSEC_diffie_hellman_agree_ioctl(fd,
+ (unsigned char *)dh->priv_key->d, BN_num_bits(dh->priv_key),
+ (unsigned char *)pub_key->d, BN_num_bits(pub_key),
+ (unsigned char *)dh->p->d, BN_num_bits(dh->p),
+ key, &k_len) != 0)
+ {
+ /* Hardware's a no go, failover to software */
+ const DH_METHOD *meth;
+ UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_REQUEST_FAILED);
+ p_UBSEC_ubsec_close(fd);
+
+ meth = DH_OpenSSL();
+ ret = meth->compute_key(key, pub_key, dh);
+
+ goto err;
+ }
+
+ p_UBSEC_ubsec_close(fd);
+
+ ret = p_UBSEC_ubsec_bits_to_bytes(k_len);
+err:
+ return ret;
+ }
+
+static int ubsec_dh_generate_key(DH *dh)
+ {
+ int ret = 0,
+ random_bits = 0,
+ pub_key_len = 0,
+ priv_key_len = 0,
+ fd;
+ BIGNUM *pub_key = NULL;
+ BIGNUM *priv_key = NULL;
+
+ /*
+ * How many bits should Random x be? dh_key.c
+ * sets the range from 0 to num_bits(modulus) ???
+ */
+
+ if (dh->priv_key == NULL)
+ {
+ priv_key = BN_new();
+ if (priv_key == NULL) goto err;
+ priv_key_len = BN_num_bits(dh->p);
+ bn_wexpand(priv_key, dh->p->top);
+ do
+ if (!BN_rand_range(priv_key, dh->p)) goto err;
+ while (BN_is_zero(priv_key));
+ random_bits = BN_num_bits(priv_key);
+ }
+ else
+ {
+ priv_key = dh->priv_key;
+ }
+
+ if (dh->pub_key == NULL)
+ {
+ pub_key = BN_new();
+ pub_key_len = BN_num_bits(dh->p);
+ bn_wexpand(pub_key, dh->p->top);
+ if(pub_key == NULL) goto err;
+ }
+ else
+ {
+ pub_key = dh->pub_key;
+ }
+
+ if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
+ {
+ const DH_METHOD *meth;
+ UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_UNIT_FAILURE);
+ meth = DH_OpenSSL();
+ ret = meth->generate_key(dh);
+ goto err;
+ }
+
+ if (p_UBSEC_diffie_hellman_generate_ioctl(fd,
+ (unsigned char *)priv_key->d, &priv_key_len,
+ (unsigned char *)pub_key->d, &pub_key_len,
+ (unsigned char *)dh->g->d, BN_num_bits(dh->g),
+ (unsigned char *)dh->p->d, BN_num_bits(dh->p),
+ 0, 0, random_bits) != 0)
+ {
+ /* Hardware's a no go, failover to software */
+ const DH_METHOD *meth;
+
+ UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_REQUEST_FAILED);
+ p_UBSEC_ubsec_close(fd);
+
+ meth = DH_OpenSSL();
+ ret = meth->generate_key(dh);
+
+ goto err;
+ }
+
+ p_UBSEC_ubsec_close(fd);
+
+ dh->pub_key = pub_key;
+ dh->pub_key->top = (pub_key_len + BN_BITS2-1) / BN_BITS2;
+ dh->priv_key = priv_key;
+ dh->priv_key->top = (priv_key_len + BN_BITS2-1) / BN_BITS2;
+
+ ret = 1;
+err:
+ return ret;
+ }
+#endif
+
+#ifdef NOT_USED
+static int ubsec_rand_bytes(unsigned char * buf,
+ int num)
+ {
+ int ret = 0,
+ fd;
+
+ if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
+ {
+ const RAND_METHOD *meth;
+ UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_UNIT_FAILURE);
+ num = p_UBSEC_ubsec_bits_to_bytes(num);
+ meth = RAND_SSLeay();
+ meth->seed(buf, num);
+ ret = meth->bytes(buf, num);
+ goto err;
+ }
+
+ num *= 8; /* bytes to bits */
+
+ if (p_UBSEC_rng_ioctl(fd,
+ UBSEC_RNG_DIRECT,
+ buf,
+ &num) != 0)
+ {
+ /* Hardware's a no go, failover to software */
+ const RAND_METHOD *meth;
+
+ UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_REQUEST_FAILED);
+ p_UBSEC_ubsec_close(fd);
+
+ num = p_UBSEC_ubsec_bits_to_bytes(num);
+ meth = RAND_SSLeay();
+ meth->seed(buf, num);
+ ret = meth->bytes(buf, num);
+
+ goto err;
+ }
+
+ p_UBSEC_ubsec_close(fd);
+
+ ret = 1;
+err:
+ return(ret);
+ }
+
+
+static int ubsec_rand_status(void)
+ {
+ return 0;
+ }
+#endif
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library. */
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_fn(ENGINE *e, const char *id)
+ {
+ if(id && (strcmp(id, engine_ubsec_id) != 0))
+ return 0;
+ if(!bind_helper(e))
+ return 0;
+ return 1;
+ }
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
+
+#endif /* !OPENSSL_NO_HW_UBSEC */
+#endif /* !OPENSSL_NO_HW */
diff --git a/openssl/engines/e_ubsec.ec b/openssl/engines/e_ubsec.ec
new file mode 100644
index 000000000..99b923356
--- /dev/null
+++ b/openssl/engines/e_ubsec.ec
@@ -0,0 +1 @@
+L UBSEC e_ubsec_err.h e_ubsec_err.c
diff --git a/openssl/engines/e_ubsec_err.c b/openssl/engines/e_ubsec_err.c
new file mode 100644
index 000000000..14c3d61e2
--- /dev/null
+++ b/openssl/engines/e_ubsec_err.c
@@ -0,0 +1,157 @@
+/* e_ubsec_err.c */
+/* ====================================================================
+ * 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).
+ *
+ */
+
+/* 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 "e_ubsec_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA UBSEC_str_functs[]=
+ {
+{ERR_FUNC(UBSEC_F_UBSEC_CTRL), "UBSEC_CTRL"},
+{ERR_FUNC(UBSEC_F_UBSEC_DH_COMPUTE_KEY), "UBSEC_DH_COMPUTE_KEY"},
+{ERR_FUNC(UBSEC_F_UBSEC_DH_GENERATE_KEY), "UBSEC_DH_GENERATE_KEY"},
+{ERR_FUNC(UBSEC_F_UBSEC_DSA_DO_SIGN), "UBSEC_DSA_DO_SIGN"},
+{ERR_FUNC(UBSEC_F_UBSEC_DSA_VERIFY), "UBSEC_DSA_VERIFY"},
+{ERR_FUNC(UBSEC_F_UBSEC_FINISH), "UBSEC_FINISH"},
+{ERR_FUNC(UBSEC_F_UBSEC_INIT), "UBSEC_INIT"},
+{ERR_FUNC(UBSEC_F_UBSEC_MOD_EXP), "UBSEC_MOD_EXP"},
+{ERR_FUNC(UBSEC_F_UBSEC_MOD_EXP_CRT), "UBSEC_MOD_EXP_CRT"},
+{ERR_FUNC(UBSEC_F_UBSEC_RAND_BYTES), "UBSEC_RAND_BYTES"},
+{ERR_FUNC(UBSEC_F_UBSEC_RSA_MOD_EXP), "UBSEC_RSA_MOD_EXP"},
+{ERR_FUNC(UBSEC_F_UBSEC_RSA_MOD_EXP_CRT), "UBSEC_RSA_MOD_EXP_CRT"},
+{0,NULL}
+ };
+
+static ERR_STRING_DATA UBSEC_str_reasons[]=
+ {
+{ERR_REASON(UBSEC_R_ALREADY_LOADED) ,"already loaded"},
+{ERR_REASON(UBSEC_R_BN_EXPAND_FAIL) ,"bn expand fail"},
+{ERR_REASON(UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
+{ERR_REASON(UBSEC_R_DSO_FAILURE) ,"dso failure"},
+{ERR_REASON(UBSEC_R_MISSING_KEY_COMPONENTS),"missing key components"},
+{ERR_REASON(UBSEC_R_NOT_LOADED) ,"not loaded"},
+{ERR_REASON(UBSEC_R_REQUEST_FAILED) ,"request failed"},
+{ERR_REASON(UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL),"size too large or too small"},
+{ERR_REASON(UBSEC_R_UNIT_FAILURE) ,"unit failure"},
+{0,NULL}
+ };
+
+#endif
+
+#ifdef UBSEC_LIB_NAME
+static ERR_STRING_DATA UBSEC_lib_name[]=
+ {
+{0 ,UBSEC_LIB_NAME},
+{0,NULL}
+ };
+#endif
+
+
+static int UBSEC_lib_error_code=0;
+static int UBSEC_error_init=1;
+
+static void ERR_load_UBSEC_strings(void)
+ {
+ if (UBSEC_lib_error_code == 0)
+ UBSEC_lib_error_code=ERR_get_next_error_library();
+
+ if (UBSEC_error_init)
+ {
+ UBSEC_error_init=0;
+#ifndef OPENSSL_NO_ERR
+ ERR_load_strings(UBSEC_lib_error_code,UBSEC_str_functs);
+ ERR_load_strings(UBSEC_lib_error_code,UBSEC_str_reasons);
+#endif
+
+#ifdef UBSEC_LIB_NAME
+ UBSEC_lib_name->error = ERR_PACK(UBSEC_lib_error_code,0,0);
+ ERR_load_strings(0,UBSEC_lib_name);
+#endif
+ }
+ }
+
+static void ERR_unload_UBSEC_strings(void)
+ {
+ if (UBSEC_error_init == 0)
+ {
+#ifndef OPENSSL_NO_ERR
+ ERR_unload_strings(UBSEC_lib_error_code,UBSEC_str_functs);
+ ERR_unload_strings(UBSEC_lib_error_code,UBSEC_str_reasons);
+#endif
+
+#ifdef UBSEC_LIB_NAME
+ ERR_unload_strings(0,UBSEC_lib_name);
+#endif
+ UBSEC_error_init=1;
+ }
+ }
+
+static void ERR_UBSEC_error(int function, int reason, char *file, int line)
+ {
+ if (UBSEC_lib_error_code == 0)
+ UBSEC_lib_error_code=ERR_get_next_error_library();
+ ERR_PUT_error(UBSEC_lib_error_code,function,reason,file,line);
+ }
diff --git a/openssl/engines/e_ubsec_err.h b/openssl/engines/e_ubsec_err.h
new file mode 100644
index 000000000..b10b2387f
--- /dev/null
+++ b/openssl/engines/e_ubsec_err.h
@@ -0,0 +1,101 @@
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * 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_UBSEC_ERR_H
+#define HEADER_UBSEC_ERR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+static void ERR_load_UBSEC_strings(void);
+static void ERR_unload_UBSEC_strings(void);
+static void ERR_UBSEC_error(int function, int reason, char *file, int line);
+#define UBSECerr(f,r) ERR_UBSEC_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the UBSEC functions. */
+
+/* Function codes. */
+#define UBSEC_F_UBSEC_CTRL 100
+#define UBSEC_F_UBSEC_DH_COMPUTE_KEY 101
+#define UBSEC_F_UBSEC_DH_GENERATE_KEY 111
+#define UBSEC_F_UBSEC_DSA_DO_SIGN 102
+#define UBSEC_F_UBSEC_DSA_VERIFY 103
+#define UBSEC_F_UBSEC_FINISH 104
+#define UBSEC_F_UBSEC_INIT 105
+#define UBSEC_F_UBSEC_MOD_EXP 106
+#define UBSEC_F_UBSEC_MOD_EXP_CRT 110
+#define UBSEC_F_UBSEC_RAND_BYTES 107
+#define UBSEC_F_UBSEC_RSA_MOD_EXP 108
+#define UBSEC_F_UBSEC_RSA_MOD_EXP_CRT 109
+
+/* Reason codes. */
+#define UBSEC_R_ALREADY_LOADED 100
+#define UBSEC_R_BN_EXPAND_FAIL 101
+#define UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED 102
+#define UBSEC_R_DSO_FAILURE 103
+#define UBSEC_R_MISSING_KEY_COMPONENTS 104
+#define UBSEC_R_NOT_LOADED 105
+#define UBSEC_R_REQUEST_FAILED 106
+#define UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL 107
+#define UBSEC_R_UNIT_FAILURE 108
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/engines/engine_vector.mar b/openssl/engines/engine_vector.mar
new file mode 100644
index 000000000..7d968e7b4
--- /dev/null
+++ b/openssl/engines/engine_vector.mar
@@ -0,0 +1,24 @@
+;
+; Transfer vector for VAX shareable image
+;
+ .TITLE ENGINE
+ .IDENT /ENGINE/
+;
+; Define macro to assist in building transfer vector entries. Each entry
+; should take no more than 8 bytes.
+;
+ .MACRO FTRANSFER_ENTRY routine
+ .ALIGN QUAD
+ .TRANSFER routine
+ .MASK routine
+ JMP routine+2
+ .ENDM FTRANSFER_ENTRY
+;
+; Place entries in own program section.
+;
+ .PSECT $$ENGINE,QUAD,PIC,USR,CON,REL,LCL,SHR,EXE,RD,NOWRT
+ENGINE_xfer:
+ FTRANSFER_ENTRY bind_engine
+ FTRANSFER_ENTRY v_check
+ .BLKB 32768-<.-ENGINE_xfer> ; 64 pages total.
+ .END
diff --git a/openssl/engines/makeengines.com b/openssl/engines/makeengines.com
new file mode 100644
index 000000000..840864f7c
--- /dev/null
+++ b/openssl/engines/makeengines.com
@@ -0,0 +1,903 @@
+$!
+$! MAKEAPPS.COM
+$! Written By: Richard Levitte
+$! richard@levitte.org
+$!
+$! This command file compiles and creates the various engines in form
+$! of shared images. They are placed in [.xxx.EXE.ENGINES], where "xxx"
+$! is either AXP or VAX depending on your hardware.
+$!
+$! P1 if this is ENGINES or ALL, the engines will build, otherwise not.
+$!
+$! P2 DEBUG or NODEBUG to compile with or without debugger information.
+$!
+$! P3 VAXC for VAX C
+$! DECC for DEC C
+$! GNUC for GNU C (untested)
+$!
+$! P4 if defined, sets the TCP/IP libraries to use. UCX or TCPIP is
+$! used by default since most other implementations come with a
+$! compatibility library. The value must be one of the following:
+$!
+$! UCX for UCX
+$! SOCKETSHR for SOCKETSHR+NETLIB
+$! TCPIP for TCPIP (post UCX)
+$!
+$! P5 if defined, tells the compiler not to use special threads.
+$!
+$! P6 if defined, denotes which engines to build. If not defined,
+$! all available engines are built.
+$!
+$!-----------------------------------------------------------------------------
+$!
+$! Set the names of the engines we want to build
+$!
+$ ENGINES = "," + P6
+$ IF ENGINES .EQS. "," THEN -
+ ENGINES = ",4758cca,aep,atalla,cswift,chil,nuron,sureware,ubsec,capi"
+$!
+$! Set the default TCP/IP library to link against if needed
+$!
+$ TCPIP_LIB = ""
+$!
+$! Set the architecture name
+$!
+$ ARCH := VAX
+$ IF F$GETSYI("CPU") .GE. 128 THEN ARCH := AXP
+$!
+$! Set the goal directories, and creat them if necessary
+$!
+$ OBJ_DIR := SYS$DISK:[-.'ARCH'.OBJ.ENGINES]
+$ EXE_DIR := SYS$DISK:[-.'ARCH'.EXE.ENGINES]
+$ IF F$PARSE(OBJ_DIR) .EQS. "" THEN CREATE/DIRECTORY 'OBJ_DIR'
+$ IF F$PARSE(EXE_DIR) .EQS. "" THEN CREATE/DIRECTORY 'EXE_DIR'
+$!
+$! Set the goal files, and create them if necessary
+$!
+$ CRYPTO_LIB :=SYS$DISK:[-.'ARCH'.EXE.CRYPTO]LIBCRYPTO.OLB
+$ CRYPTO_EXE :=SYS$DISK:[-.'ARCH'.EXE.CRYPTO]LIBCRYPTO.EXE
+$ IF F$SEARCH(CRYPTO_LIB) .EQS. "" THEN LIBRARY/CREATE/OBJECT 'CRYPTO_LIB'
+$!
+$! OK, time to check options and initialise
+$!
+$ OPT_PHASE = P1
+$ ACCEPT_PHASE = "ALL,ENGINES"
+$ OPT_DEBUG = P2
+$ OPT_COMPILER = P3
+$ OPT_TCPIP_LIB = P4
+$ OPT_SPECIAL_THREADS = P5
+$
+$ GOSUB CHECK_OPTIONS
+$ GOSUB INITIALISE
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Define what goes into each engine
+$!
+$ ENGINE_ = ""
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$ ENGINE_ = "engine_vector.mar"
+$ EXTRA_OBJ := ,'OBJ_DIR'ENGINE_VECTOR.OBJ
+$ ENDIF
+$ ENGINE_4758CCA = "e_4758cca"
+$ ENGINE_aep = "e_aep"
+$ ENGINE_atalla = "e_atalla"
+$ ENGINE_cswift = "e_cswift"
+$ ENGINE_chil = "e_chil"
+$ ENGINE_nuron = "e_nuron"
+$ ENGINE_sureware = "e_sureware"
+$ ENGINE_ubsec = "e_ubsec"
+$ ENGINE_capi = "e_capi"
+$!
+$! Define which programs need to be linked with a TCP/IP library
+$!
+$ TCPIP_ENGINES = ",,"
+$ IF COMPILER .EQS. "VAXC" THEN -
+ TCPIP_ENGINES = ",,"
+$!
+$! Set up two loops, one that keeps track of the engines,
+$! and one that keeps track of all the files going into
+$! the current engine.
+$!
+$! Here's the start of the engine loop.
+$!
+$ ENGINE_COUNTER = 0
+$ ENGINE_NEXT:
+$!
+$! Extract the current engine name, and if we've reached the end, stop
+$!
+$ ENGINE_NAME = F$ELEMENT(ENGINE_COUNTER,",",ENGINES)
+$ IF (ENGINE_NAME.EQS.",") THEN GOTO ENGINE_DONE
+$!
+$ ENGINE_COUNTER = ENGINE_COUNTER + 1
+$!
+$! Set up the engine library names.
+$!
+$ LIB_ENGINE = "ENGINE_" + ENGINE_NAME
+$!
+$! Check if the library module name actually is defined
+$!
+$ IF F$TYPE('LIB_ENGINE') .EQS. ""
+$ THEN
+$ WRITE SYS$ERROR ""
+$ WRITE SYS$ERROR "The module ",ENGINE_NAME," does not exist. Continuing..."
+$ WRITE SYS$ERROR ""
+$ GOTO ENGINE_NEXT
+$ ENDIF
+$!
+$! Talk to the user
+$!
+$ IF ENGINE_NAME .NES. ""
+$ THEN
+$ WRITE SYS$OUTPUT "Compiling The ",ENGINE_NAME," Library Files. (",BUILDALL,")"
+$ ELSE
+$ WRITE SYS$OUTPUT "Compiling Support Files. (",BUILDALL,")"
+$ ENDIF
+$!
+$! Here's the start of per-engine module loop.
+$!
+$ FILE_COUNTER = 0
+$ FILE_NEXT:
+$!
+$! Extract the file name from the file list, and if we've reached the end, stop
+$!
+$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",'LIB_ENGINE')
+$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE
+$!
+$ FILE_COUNTER = FILE_COUNTER + 1
+$!
+$ IF FILE_NAME .EQS. "" THEN GOTO FILE_NEXT
+$!
+$! Set up the source and object reference
+$!
+$ SOURCE_FILE = F$PARSE(FILE_NAME,"SYS$DISK:[].C",,,"SYNTAX_ONLY")
+$ OBJECT_FILE = OBJ_DIR + F$PARSE(FILE_NAME,,,"NAME","SYNTAX_ONLY") + ".OBJ"
+$!
+$! If we get some problem, we just go on trying to build the next module.
+$ ON WARNING THEN GOTO FILE_NEXT
+$!
+$! Check if the module we want to compile is actually there.
+$!
+$ IF F$SEARCH(SOURCE_FILE) .EQS. ""
+$ THEN
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Doesn't Exist."
+$ WRITE SYS$OUTPUT ""
+$ GOTO EXIT
+$ ENDIF
+$!
+$! Talk to the user.
+$!
+$ WRITE SYS$OUTPUT " ",FILE_NAME,""
+$!
+$! Do the dirty work.
+$!
+$ ON ERROR THEN GOTO FILE_NEXT
+$ IF FILE_NAME - ".MAR" .NES. FILE_NAME
+$ THEN
+$ MACRO/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ELSE
+$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ ENDIF
+$!
+$! Now, there are two ways to handle this. We can either build
+$! shareable images or stick the engine object file into libcrypto.
+$! For now, the latter is NOT supported.
+$!
+$!!!!! LIBRARY/REPLACE 'CRYPTO_LIB' 'OBJECT_FILE'
+$!
+$! For shareable libraries, we need to do things a little differently
+$! depending on if we link with a TCP/IP library or not.
+$!
+$ ENGINE_OPT := SYS$DISK:[]'ARCH'.OPT
+$ IF TCPIP_LIB .NES. ""
+$ THEN
+$ LINK/'DEBUGGER'/'TRACEBACK' /SHARE='EXE_DIR''ENGINE_NAME'.EXE -
+ 'OBJECT_FILE''EXTRA_OBJ', -
+ 'CRYPTO_LIB'/LIBRARY, -
+ 'ENGINE_OPT'/OPTION,'TCPIP_LIB','OPT_FILE'/OPTION
+$ ELSE
+$ LINK/'DEBUGGER'/'TRACEBACK' /SHARE='EXE_DIR''ENGINE_NAME'.EXE -
+ 'OBJECT_FILE''EXTRA_OBJ', -
+ 'CRYPTO_LIB'/LIBRARY, -
+ 'ENGINE_OPT'/OPTION,'OPT_FILE'/OPTION
+$ ENDIF
+$!
+$! Clean up
+$!
+$ DELETE 'OBJECT_FILE';*
+$!
+$! Next file
+$!
+$ GOTO FILE_NEXT
+$!
+$ FILE_DONE:
+$!
+$! Next engine
+$!
+$ GOTO ENGINE_NEXT
+$!
+$ ENGINE_DONE:
+$!
+$! Talk to the user
+$!
+$ WRITE SYS$OUTPUT "All Done..."
+$ EXIT:
+$ GOSUB CLEANUP
+$ EXIT
+$!
+$! Check For The Link Option FIle.
+$!
+$ CHECK_OPT_FILE:
+$!
+$! Check To See If We Need To Make A VAX C Option File.
+$!
+$ IF (COMPILER.EQS."VAXC")
+$ THEN
+$!
+$! Check To See If We Already Have A VAX C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! We Need A VAX C Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst
+! The Sharable VAX C Runtime Library.
+!
+SYS$SHARE:VAXCRTL.EXE/SHARE
+$EOD
+$!
+$! End The Option File Check.
+$!
+$ ENDIF
+$!
+$! End The VAXC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A GNU C Option File.
+$!
+$ IF (COMPILER.EQS."GNUC")
+$ THEN
+$!
+$! Check To See If We Already Have A GNU C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! We Need A GNU C Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst
+! The Sharable C Runtime Library.
+!
+GNU_CC:[000000]GCCLIB/LIBRARY
+SYS$SHARE:VAXCRTL/SHARE
+$EOD
+$!
+$! End The Option File Check.
+$!
+$ ENDIF
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A DEC C Option File.
+$!
+$ IF (COMPILER.EQS."DECC")
+$ THEN
+$!
+$! Check To See If We Already Have A DEC C Linker Option File.
+$!
+$ IF (F$SEARCH(OPT_FILE).EQS."")
+$ THEN
+$!
+$! Figure Out If We Need An AXP Or A VAX Linker Option File.
+$!
+$ IF ARCH .EQS. "VAX"
+$ THEN
+$!
+$! We Need A DEC C Linker Option File For VAX.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst
+! The Sharable DEC C Runtime Library.
+!
+SYS$SHARE:DECC$SHR.EXE/SHARE
+$EOD
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Create The AXP Linker Option File.
+$!
+$ CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File For AXP To Link Agianst
+! The Sharable C Runtime Library.
+!
+SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
+SYS$SHARE:CMA$OPEN_RTL/SHARE
+$EOD
+$!
+$! End The VAX/AXP DEC C Option File Check.
+$!
+$ ENDIF
+$!
+$! End The Option File Search.
+$!
+$ ENDIF
+$!
+$! End The DEC C Check.
+$!
+$ ENDIF
+$!
+$! Tell The User What Linker Option File We Are Using.
+$!
+$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$!
+$! Check The User's Options.
+$!
+$ CHECK_OPTIONS:
+$!
+$! Check To See If OPT_PHASE Is Blank.
+$!
+$ IF (OPT_PHASE.EQS."ALL")
+$ THEN
+$!
+$! OPT_PHASE Is Blank, So Build Everything.
+$!
+$ BUILDALL = "ALL"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Else, Check To See If OPT_PHASE Has A Valid Arguement.
+$!
+$ IF ("," + ACCEPT_PHASE + ",") - ("," + OPT_PHASE + ",") -
+ .NES. ("," + ACCEPT_PHASE + ",")
+$ THEN
+$!
+$! A Valid Arguement.
+$!
+$ BUILDALL = OPT_PHASE
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The option ",OPT_PHASE," is invalid. The valid options are:"
+$ WRITE SYS$OUTPUT ""
+$ IF ("," + ACCEPT_PHASE + ",") - ",ALL," -
+ .NES. ("," + ACCEPT_PHASE + ",") THEN -
+ WRITE SYS$OUTPUT " ALL : just build everything."
+$ IF ("," + ACCEPT_PHASE + ",") - ",ENGINES," -
+ .NES. ("," + ACCEPT_PHASE + ",") THEN -
+ WRITE SYS$OUTPUT " ENGINES : to compile just the [.xxx.EXE.ENGINES]*.EXE hareable images."
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " where 'xxx' stands for:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " AXP : Alpha architecture."
+$ WRITE SYS$OUTPUT " VAX : VAX architecture."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! End The Valid Arguement Check.
+$!
+$ ENDIF
+$!
+$! End The OPT_PHASE Check.
+$!
+$ ENDIF
+$!
+$! Check To See If OPT_DEBUG Is Blank.
+$!
+$ IF (OPT_DEBUG.EQS."NODEBUG")
+$ THEN
+$!
+$! OPT_DEBUG Is NODEBUG, So Compile Without The Debugger Information.
+$!
+$ DEBUGGER = "NODEBUG"
+$ TRACEBACK = "NOTRACEBACK"
+$ GCC_OPTIMIZE = "OPTIMIZE"
+$ CC_OPTIMIZE = "OPTIMIZE"
+$ MACRO_OPTIMIZE = "OPTIMIZE"
+$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
+$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
+$ ELSE
+$!
+$! Check To See If We Are To Compile With Debugger Information.
+$!
+$ IF (OPT_DEBUG.EQS."DEBUG")
+$ THEN
+$!
+$! Compile With Debugger Information.
+$!
+$ DEBUGGER = "DEBUG"
+$ TRACEBACK = "TRACEBACK"
+$ GCC_OPTIMIZE = "NOOPTIMIZE"
+$ CC_OPTIMIZE = "NOOPTIMIZE"
+$ MACRO_OPTIMIZE = "NOOPTIMIZE"
+$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
+$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
+$ ELSE
+$!
+$! They Entered An Invalid Option..
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",OPT_DEBUG," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information."
+$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! End The Valid Arguement Check.
+$!
+$ ENDIF
+$!
+$! End The OPT_DEBUG Check.
+$!
+$ ENDIF
+$!
+$! Special Threads For OpenVMS v7.1 Or Later
+$!
+$! Written By: Richard Levitte
+$! richard@levitte.org
+$!
+$!
+$! Check To See If We Have A Option For OPT_SPECIAL_THREADS.
+$!
+$ IF (OPT_SPECIAL_THREADS.EQS."")
+$ THEN
+$!
+$! Get The Version Of VMS We Are Using.
+$!
+$ ISSEVEN :=
+$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
+$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
+$!
+$! Check To See If The VMS Version Is v7.1 Or Later.
+$!
+$ IF (TMP.GE.71)
+$ THEN
+$!
+$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
+$!
+$ ISSEVEN := ,PTHREAD_USE_D4
+$!
+$! End The VMS Version Check.
+$!
+$ ENDIF
+$!
+$! End The OPT_SPECIAL_THREADS Check.
+$!
+$ ENDIF
+$!
+$! Check To See If OPT_COMPILER Is Blank.
+$!
+$ IF (OPT_COMPILER.EQS."")
+$ THEN
+$!
+$! O.K., The User Didn't Specify A Compiler, Let's Try To
+$! Find Out Which One To Use.
+$!
+$! Check To See If We Have GNU C.
+$!
+$ IF (F$TRNLNM("GNU_CC").NES."")
+$ THEN
+$!
+$! Looks Like GNUC, Set To Use GNUC.
+$!
+$ OPT_COMPILER = "GNUC"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Check To See If We Have VAXC Or DECC.
+$!
+$ IF (ARCH.EQS."AXP").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
+$ THEN
+$!
+$! Looks Like DECC, Set To Use DECC.
+$!
+$ OPT_COMPILER = "DECC"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Looks Like VAXC, Set To Use VAXC.
+$!
+$ OPT_COMPILER = "VAXC"
+$!
+$! End The VAXC Compiler Check.
+$!
+$ ENDIF
+$!
+$! End The DECC & VAXC Compiler Check.
+$!
+$ ENDIF
+$!
+$! End The Compiler Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have A Option For OPT_TCPIP_LIB.
+$!
+$ IF (OPT_TCPIP_LIB.EQS."")
+$ THEN
+$!
+$! Find out what socket library we have available
+$!
+$ IF F$PARSE("SOCKETSHR:") .NES. ""
+$ THEN
+$!
+$! We have SOCKETSHR, and it is my opinion that it's the best to use.
+$!
+$ OPT_TCPIP_LIB = "SOCKETSHR"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
+$!
+$! Else, let's look for something else
+$!
+$ ELSE
+$!
+$! Like UCX (the reason to do this before Multinet is that the UCX
+$! emulation is easier to use...)
+$!
+$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
+ .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
+ .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
+$ THEN
+$!
+$! Last resort: a UCX or UCX-compatible library
+$!
+$ OPT_TCPIP_LIB = "UCX"
+$!
+$! Tell the user
+$!
+$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
+$!
+$! That was all...
+$!
+$ ENDIF
+$ ENDIF
+$ ENDIF
+$!
+$! Set Up Initial CC Definitions, Possibly With User Ones
+$!
+$ CCDEFS = "TCPIP_TYPE_''OPT_TCPIP_LIB',DSO_VMS"
+$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
+$ CCEXTRAFLAGS = ""
+$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
+$ CCDISABLEWARNINGS = "LONGLONGTYPE,LONGLONGSUFX"
+$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
+ CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
+$!
+$! Check To See If The User Entered A Valid Paramter.
+$!
+$ IF (OPT_COMPILER.EQS."VAXC").OR.(OPT_COMPILER.EQS."DECC").OR.(OPT_COMPILER.EQS."GNUC")
+$ THEN
+$!
+$! Check To See If The User Wanted DECC.
+$!
+$ IF (OPT_COMPILER.EQS."DECC")
+$ THEN
+$!
+$! Looks Like DECC, Set To Use DECC.
+$!
+$ COMPILER = "DECC"
+$!
+$! Tell The User We Are Using DECC.
+$!
+$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$! Use DECC...
+$!
+$ CC = "CC"
+$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
+ THEN CC = "CC/DECC"
+$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/STANDARD=ANSI89" + -
+ "/NOLIST/PREFIX=ALL" + -
+ "/INCLUDE=(SYS$DISK:[],SYS$DISK:[.VENDOR_DEFNS])" + -
+ CCEXTRAFLAGS
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "SYS$DISK:[]VAX_DECC_OPTIONS.OPT"
+$!
+$! End DECC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Use VAXC.
+$!
+$ IF (OPT_COMPILER.EQS."VAXC")
+$ THEN
+$!
+$! Looks Like VAXC, Set To Use VAXC.
+$!
+$ COMPILER = "VAXC"
+$!
+$! Tell The User We Are Using VAX C.
+$!
+$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$! Compile Using VAXC.
+$!
+$ CC = "CC"
+$ IF ARCH.EQS."AXP"
+$ THEN
+$ WRITE SYS$OUTPUT "There is no VAX C on Alpha!"
+$ EXIT
+$ ENDIF
+$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
+$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+ "/INCLUDE=(SYS$DISK:[],SYS$DISK:[-],SYS$DISK:[.ENGINE.VENDOR_DEFNS])" + -
+ CCEXTRAFLAGS
+$ CCDEFS = """VAXC""," + CCDEFS
+$!
+$! Define <sys> As SYS$COMMON:[SYSLIB]
+$!
+$ DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "SYS$DISK:[]VAX_VAXC_OPTIONS.OPT"
+$!
+$! End VAXC Check
+$!
+$ ENDIF
+$!
+$! Check To See If We Are To Use GNU C.
+$!
+$ IF (OPT_COMPILER.EQS."GNUC")
+$ THEN
+$!
+$! Looks Like GNUC, Set To Use GNUC.
+$!
+$ COMPILER = "GNUC"
+$!
+$! Tell The User We Are Using GNUC.
+$!
+$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$! Use GNU C...
+$!
+$ CC = "GCC/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+ "/INCLUDE=(SYS$DISK:[],SYS$DISK:[-],SYS$DISK:[.ENGINE.VENDOR_DEFNS])" + -
+ CCEXTRAFLAGS
+$!
+$! Define The Linker Options File Name.
+$!
+$ OPT_FILE = "SYS$DISK:[]VAX_GNUC_OPTIONS.OPT"
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Set up default defines
+$!
+$ CCDEFS = """FLAT_INC=1""," + CCDEFS
+$!
+$! Finish up the definition of CC.
+$!
+$ IF COMPILER .EQS. "DECC"
+$ THEN
+$ IF CCDISABLEWARNINGS .NES. ""
+$ THEN
+$ CCDISABLEWARNINGS = "/WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
+$ ENDIF
+$ ELSE
+$ CCDISABLEWARNINGS = ""
+$ ENDIF
+$ CC = CC + "/DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
+$!
+$! Show user the result
+$!
+$ WRITE/SYMBOL SYS$OUTPUT "Main C Compiling Command: ",CC
+$!
+$! Else The User Entered An Invalid Arguement.
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",OPT_COMPILER," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C."
+$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C."
+$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! End The Valid Arguement Check.
+$!
+$ ENDIF
+$!
+$! Build a MACRO command for the architecture at hand
+$!
+$ IF ARCH .EQS. "VAX" THEN MACRO = "MACRO/''DEBUGGER'"
+$ IF ARCH .EQS. "AXP" THEN MACRO = "MACRO/MIGRATION/''DEBUGGER'/''MACRO_OPTIMIZE'"
+$!
+$! Show user the result
+$!
+$ WRITE/SYMBOL SYS$OUTPUT "Main MACRO Compiling Command: ",MACRO
+$!
+$! Time to check the contents, and to make sure we get the correct library.
+$!
+$ IF OPT_TCPIP_LIB.EQS."SOCKETSHR" .OR. OPT_TCPIP_LIB.EQS."MULTINET" -
+ .OR. OPT_TCPIP_LIB.EQS."UCX" .OR. OPT_TCPIP_LIB.EQS."TCPIP" -
+ .OR. OPT_TCPIP_LIB.EQS."NONE"
+$ THEN
+$!
+$! Check to see if SOCKETSHR was chosen
+$!
+$ IF OPT_TCPIP_LIB.EQS."SOCKETSHR"
+$ THEN
+$!
+$! Set the library to use SOCKETSHR
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT/OPT"
+$!
+$! Done with SOCKETSHR
+$!
+$ ENDIF
+$!
+$! Check to see if MULTINET was chosen
+$!
+$ IF OPT_TCPIP_LIB.EQS."MULTINET"
+$ THEN
+$!
+$! Set the library to use UCX emulation.
+$!
+$ OPT_TCPIP_LIB = "UCX"
+$!
+$! Done with MULTINET
+$!
+$ ENDIF
+$!
+$! Check to see if UCX was chosen
+$!
+$ IF OPT_TCPIP_LIB.EQS."UCX"
+$ THEN
+$!
+$! Set the library to use UCX.
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT/OPT"
+$ IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
+$ THEN
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT/OPT"
+$ ELSE
+$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
+ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT/OPT"
+$ ENDIF
+$!
+$! Done with UCX
+$!
+$ ENDIF
+$!
+$! Check to see if TCPIP was chosen
+$!
+$ IF OPT_TCPIP_LIB.EQS."TCPIP"
+$ THEN
+$!
+$! Set the library to use TCPIP (post UCX).
+$!
+$ TCPIP_LIB = "SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT/OPT"
+$!
+$! Done with TCPIP
+$!
+$ ENDIF
+$!
+$! Check to see if NONE was chosen
+$!
+$ IF OPT_TCPIP_LIB.EQS."NONE"
+$ THEN
+$!
+$! Do not use a TCPIP library.
+$!
+$ TCPIP_LIB = ""
+$!
+$! Done with TCPIP
+$!
+$ ENDIF
+$!
+$! Print info
+$!
+$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB
+$!
+$! Else The User Entered An Invalid Arguement.
+$!
+$ ELSE
+$!
+$! Tell The User We Don't Know What They Want.
+$!
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT "The Option ",OPT_TCPIP_LIB," Is Invalid. The Valid Options Are:"
+$ WRITE SYS$OUTPUT ""
+$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library."
+$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library."
+$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library."
+$ WRITE SYS$OUTPUT ""
+$!
+$! Time To EXIT.
+$!
+$ EXIT
+$!
+$! Done with TCP/IP libraries
+$!
+$ ENDIF
+$!
+$! Time To RETURN...
+$!
+$ RETURN
+$!
+$ INITIALISE:
+$!
+$! Save old value of the logical name OPENSSL
+$!
+$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
+$!
+$! Save directory information
+$!
+$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
+$ __HERE = F$EDIT(__HERE,"UPCASE")
+$ __TOP = __HERE - "ENGINES]"
+$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
+$!
+$! Set up the logical name OPENSSL to point at the include directory
+$!
+$ DEFINE OPENSSL/NOLOG '__INCLUDE'
+$!
+$! Done
+$!
+$ RETURN
+$!
+$ CLEANUP:
+$!
+$! Restore the logical name OPENSSL if it had a value
+$!
+$ IF __SAVE_OPENSSL .EQS. ""
+$ THEN
+$ DEASSIGN OPENSSL
+$ ELSE
+$ DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL'
+$ ENDIF
+$!
+$! Done
+$!
+$ RETURN
diff --git a/openssl/engines/vendor_defns/aep.h b/openssl/engines/vendor_defns/aep.h
new file mode 100644
index 000000000..5e9754fe4
--- /dev/null
+++ b/openssl/engines/vendor_defns/aep.h
@@ -0,0 +1,178 @@
+/* This header declares the necessary definitions for using the exponentiation
+ * acceleration capabilities, and rnd number generation of the AEP card.
+ *
+ */
+
+/*
+ *
+ * Some AEP defines
+ *
+ */
+
+/*Successful return value*/
+#define AEP_R_OK 0x00000000
+
+/*Miscelleanous unsuccessful return value*/
+#define AEP_R_GENERAL_ERROR 0x10000001
+
+/*Insufficient host memory*/
+#define AEP_R_HOST_MEMORY 0x10000002
+
+#define AEP_R_FUNCTION_FAILED 0x10000006
+
+/*Invalid arguments in function call*/
+#define AEP_R_ARGUMENTS_BAD 0x10020000
+
+#define AEP_R_NO_TARGET_RESOURCES 0x10030000
+
+/*Error occuring on socket operation*/
+#define AEP_R_SOCKERROR 0x10000010
+
+/*Socket has been closed from the other end*/
+#define AEP_R_SOCKEOF 0x10000011
+
+/*Invalid handles*/
+#define AEP_R_CONNECTION_HANDLE_INVALID 0x100000B3
+
+#define AEP_R_TRANSACTION_HANDLE_INVALID 0x10040000
+
+/*Transaction has not yet returned from accelerator*/
+#define AEP_R_TRANSACTION_NOT_READY 0x00010000
+
+/*There is already a thread waiting on this transaction*/
+#define AEP_R_TRANSACTION_CLAIMED 0x10050000
+
+/*The transaction timed out*/
+#define AEP_R_TIMED_OUT 0x10060000
+
+#define AEP_R_FXN_NOT_IMPLEMENTED 0x10070000
+
+#define AEP_R_TARGET_ERROR 0x10080000
+
+/*Error in the AEP daemon process*/
+#define AEP_R_DAEMON_ERROR 0x10090000
+
+/*Invalid ctx id*/
+#define AEP_R_INVALID_CTX_ID 0x10009000
+
+#define AEP_R_NO_KEY_MANAGER 0x1000a000
+
+/*Error obtaining a mutex*/
+#define AEP_R_MUTEX_BAD 0x000001A0
+
+/*Fxn call before AEP_Initialise ot after AEP_Finialise*/
+#define AEP_R_AEPAPI_NOT_INITIALIZED 0x10000190
+
+/*AEP_Initialise has already been called*/
+#define AEP_R_AEPAPI_ALREADY_INITIALIZED 0x10000191
+
+/*Maximum number of connections to daemon reached*/
+#define AEP_R_NO_MORE_CONNECTION_HNDLS 0x10000200
+
+/*
+ *
+ * Some AEP Type definitions
+ *
+ */
+
+/* an unsigned 8-bit value */
+typedef unsigned char AEP_U8;
+
+/* an unsigned 8-bit character */
+typedef char AEP_CHAR;
+
+/* a BYTE-sized Boolean flag */
+typedef AEP_U8 AEP_BBOOL;
+
+/*Unsigned value, at least 16 bits long*/
+typedef unsigned short AEP_U16;
+
+/* an unsigned value, at least 32 bits long */
+#ifdef SIXTY_FOUR_BIT_LONG
+typedef unsigned int AEP_U32;
+#else
+typedef unsigned long AEP_U32;
+#endif
+
+#ifdef SIXTY_FOUR_BIT_LONG
+typedef unsigned long AEP_U64;
+#else
+typedef struct { unsigned long l1, l2; } AEP_U64;
+#endif
+
+/* at least 32 bits; each bit is a Boolean flag */
+typedef AEP_U32 AEP_FLAGS;
+
+typedef AEP_U8 *AEP_U8_PTR;
+typedef AEP_CHAR *AEP_CHAR_PTR;
+typedef AEP_U32 *AEP_U32_PTR;
+typedef AEP_U64 *AEP_U64_PTR;
+typedef void *AEP_VOID_PTR;
+
+/* Pointer to a AEP_VOID_PTR-- i.e., pointer to pointer to void */
+typedef AEP_VOID_PTR *AEP_VOID_PTR_PTR;
+
+/*Used to identify an AEP connection handle*/
+typedef AEP_U32 AEP_CONNECTION_HNDL;
+
+/*Pointer to an AEP connection handle*/
+typedef AEP_CONNECTION_HNDL *AEP_CONNECTION_HNDL_PTR;
+
+/*Used by an application (in conjunction with the apps process id) to
+identify an individual transaction*/
+typedef AEP_U32 AEP_TRANSACTION_ID;
+
+/*Pointer to an applications transaction identifier*/
+typedef AEP_TRANSACTION_ID *AEP_TRANSACTION_ID_PTR;
+
+/*Return value type*/
+typedef AEP_U32 AEP_RV;
+
+#define MAX_PROCESS_CONNECTIONS 256
+
+#define RAND_BLK_SIZE 1024
+
+typedef enum{
+ NotConnected= 0,
+ Connected= 1,
+ InUse= 2
+} AEP_CONNECTION_STATE;
+
+
+typedef struct AEP_CONNECTION_ENTRY{
+ AEP_CONNECTION_STATE conn_state;
+ AEP_CONNECTION_HNDL conn_hndl;
+} AEP_CONNECTION_ENTRY;
+
+
+typedef AEP_RV t_AEP_OpenConnection(AEP_CONNECTION_HNDL_PTR phConnection);
+typedef AEP_RV t_AEP_CloseConnection(AEP_CONNECTION_HNDL hConnection);
+
+typedef AEP_RV t_AEP_ModExp(AEP_CONNECTION_HNDL hConnection,
+ AEP_VOID_PTR pA, AEP_VOID_PTR pP,
+ AEP_VOID_PTR pN,
+ AEP_VOID_PTR pResult,
+ AEP_TRANSACTION_ID* pidTransID);
+
+typedef AEP_RV t_AEP_ModExpCrt(AEP_CONNECTION_HNDL hConnection,
+ AEP_VOID_PTR pA, AEP_VOID_PTR pP,
+ AEP_VOID_PTR pQ,
+ AEP_VOID_PTR pDmp1, AEP_VOID_PTR pDmq1,
+ AEP_VOID_PTR pIqmp,
+ AEP_VOID_PTR pResult,
+ AEP_TRANSACTION_ID* pidTransID);
+
+#ifdef AEPRAND
+typedef AEP_RV t_AEP_GenRandom(AEP_CONNECTION_HNDL hConnection,
+ AEP_U32 Len,
+ AEP_U32 Type,
+ AEP_VOID_PTR pResult,
+ AEP_TRANSACTION_ID* pidTransID);
+#endif
+
+typedef AEP_RV t_AEP_Initialize(AEP_VOID_PTR pInitArgs);
+typedef AEP_RV t_AEP_Finalize(void);
+typedef AEP_RV t_AEP_SetBNCallBacks(AEP_RV (*GetBigNumSizeFunc)(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize),
+ AEP_RV (*MakeAEPBigNumFunc)(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize, unsigned char* AEP_BigNum),
+ AEP_RV (*ConverAEPBigNumFunc)(void* ArbBigNum, AEP_U32 BigNumSize, unsigned char* AEP_BigNum));
+
diff --git a/openssl/engines/vendor_defns/atalla.h b/openssl/engines/vendor_defns/atalla.h
new file mode 100644
index 000000000..149970d44
--- /dev/null
+++ b/openssl/engines/vendor_defns/atalla.h
@@ -0,0 +1,48 @@
+/* This header declares the necessary definitions for using the exponentiation
+ * acceleration capabilities of Atalla cards. The only cryptographic operation
+ * is performed by "ASI_RSAPrivateKeyOpFn" and this takes a structure that
+ * defines an "RSA private key". However, it is really only performing a
+ * regular mod_exp using the supplied modulus and exponent - no CRT form is
+ * being used. Hence, it is a generic mod_exp function in disguise, and we use
+ * it as such.
+ *
+ * Thanks to the people at Atalla for letting me know these definitions are
+ * fine and that they can be reproduced here.
+ *
+ * Geoff.
+ */
+
+typedef struct ItemStr
+ {
+ unsigned char *data;
+ int len;
+ } Item;
+
+typedef struct RSAPrivateKeyStr
+ {
+ void *reserved;
+ Item version;
+ Item modulus;
+ Item publicExponent;
+ Item privateExponent;
+ Item prime[2];
+ Item exponent[2];
+ Item coefficient;
+ } RSAPrivateKey;
+
+/* Predeclare the function pointer types that we dynamically load from the DSO.
+ * These use the same names and form that Ben's original support code had (in
+ * crypto/bn/bn_exp.c) unless of course I've inadvertently changed the style
+ * somewhere along the way!
+ */
+
+typedef int tfnASI_GetPerformanceStatistics(int reset_flag,
+ unsigned int *ret_buf);
+
+typedef int tfnASI_GetHardwareConfig(long card_num, unsigned int *ret_buf);
+
+typedef int tfnASI_RSAPrivateKeyOpFn(RSAPrivateKey * rsaKey,
+ unsigned char *output,
+ unsigned char *input,
+ unsigned int modulus_len);
+
diff --git a/openssl/engines/vendor_defns/cswift.h b/openssl/engines/vendor_defns/cswift.h
new file mode 100644
index 000000000..60079326b
--- /dev/null
+++ b/openssl/engines/vendor_defns/cswift.h
@@ -0,0 +1,234 @@
+/* Attribution notice: Rainbow have generously allowed me to reproduce
+ * the necessary definitions here from their API. This means the support
+ * can build independently of whether application builders have the
+ * API or hardware. This will allow developers to easily produce software
+ * that has latent hardware support for any users that have accelertors
+ * installed, without the developers themselves needing anything extra.
+ *
+ * I have only clipped the parts from the CryptoSwift header files that
+ * are (or seem) relevant to the CryptoSwift support code. This is
+ * simply to keep the file sizes reasonable.
+ * [Geoff]
+ */
+
+
+/* NB: These type widths do *not* seem right in general, in particular
+ * they're not terribly friendly to 64-bit architectures (unsigned long)
+ * will be 64-bit on IA-64 for a start. I'm leaving these alone as they
+ * agree with Rainbow's API and this will only be called into question
+ * on platforms with Rainbow support anyway! ;-) */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef long SW_STATUS; /* status */
+typedef unsigned char SW_BYTE; /* 8 bit byte */
+typedef unsigned short SW_U16; /* 16 bit number */
+#if defined(_IRIX)
+#include <sgidefs.h>
+typedef __uint32_t SW_U32;
+#else
+typedef unsigned long SW_U32; /* 32 bit integer */
+#endif
+
+#if defined(OPENSSL_SYS_WIN32)
+ typedef struct _SW_U64 {
+ SW_U32 low32;
+ SW_U32 high32;
+ } SW_U64; /* 64 bit integer */
+#elif defined(OPENSSL_SYS_MACINTOSH_CLASSIC)
+ typedef longlong SW_U64
+#else /* Unix variants */
+ typedef struct _SW_U64 {
+ SW_U32 low32;
+ SW_U32 high32;
+ } SW_U64; /* 64 bit integer */
+#endif
+
+/* status codes */
+#define SW_OK (0L)
+#define SW_ERR_BASE (-10000L)
+#define SW_ERR_NO_CARD (SW_ERR_BASE-1) /* The Card is not present */
+#define SW_ERR_CARD_NOT_READY (SW_ERR_BASE-2) /* The card has not powered */
+ /* up yet */
+#define SW_ERR_TIME_OUT (SW_ERR_BASE-3) /* Execution of a command */
+ /* time out */
+#define SW_ERR_NO_EXECUTE (SW_ERR_BASE-4) /* The Card failed to */
+ /* execute the command */
+#define SW_ERR_INPUT_NULL_PTR (SW_ERR_BASE-5) /* a required pointer is */
+ /* NULL */
+#define SW_ERR_INPUT_SIZE (SW_ERR_BASE-6) /* size is invalid, too */
+ /* small, too large. */
+#define SW_ERR_INVALID_HANDLE (SW_ERR_BASE-7) /* Invalid SW_ACC_CONTEXT */
+ /* handle */
+#define SW_ERR_PENDING (SW_ERR_BASE-8) /* A request is already out- */
+ /* standing at this */
+ /* context handle */
+#define SW_ERR_AVAILABLE (SW_ERR_BASE-9) /* A result is available. */
+#define SW_ERR_NO_PENDING (SW_ERR_BASE-10)/* No request is pending. */
+#define SW_ERR_NO_MEMORY (SW_ERR_BASE-11)/* Not enough memory */
+#define SW_ERR_BAD_ALGORITHM (SW_ERR_BASE-12)/* Invalid algorithm type */
+ /* in SW_PARAM structure */
+#define SW_ERR_MISSING_KEY (SW_ERR_BASE-13)/* No key is associated with */
+ /* context. */
+ /* swAttachKeyParam() is */
+ /* not called. */
+#define SW_ERR_KEY_CMD_MISMATCH \
+ (SW_ERR_BASE-14)/* Cannot perform requested */
+ /* SW_COMMAND_CODE since */
+ /* key attached via */
+ /* swAttachKeyParam() */
+ /* cannot be used for this*/
+ /* SW_COMMAND_CODE. */
+#define SW_ERR_NOT_IMPLEMENTED \
+ (SW_ERR_BASE-15)/* Not implemented */
+#define SW_ERR_BAD_COMMAND (SW_ERR_BASE-16)/* Bad command code */
+#define SW_ERR_BAD_ITEM_SIZE (SW_ERR_BASE-17)/* too small or too large in */
+ /* the "initems" or */
+ /* "outitems". */
+#define SW_ERR_BAD_ACCNUM (SW_ERR_BASE-18)/* Bad accelerator number */
+#define SW_ERR_SELFTEST_FAIL (SW_ERR_BASE-19)/* At least one of the self */
+ /* test fail, look at the */
+ /* selfTestBitmap in */
+ /* SW_ACCELERATOR_INFO for*/
+ /* details. */
+#define SW_ERR_MISALIGN (SW_ERR_BASE-20)/* Certain alogrithms require*/
+ /* key materials aligned */
+ /* in certain order, e.g. */
+ /* 128 bit for CRT */
+#define SW_ERR_OUTPUT_NULL_PTR \
+ (SW_ERR_BASE-21)/* a required pointer is */
+ /* NULL */
+#define SW_ERR_OUTPUT_SIZE \
+ (SW_ERR_BASE-22)/* size is invalid, too */
+ /* small, too large. */
+#define SW_ERR_FIRMWARE_CHECKSUM \
+ (SW_ERR_BASE-23)/* firmware checksum mismatch*/
+ /* download failed. */
+#define SW_ERR_UNKNOWN_FIRMWARE \
+ (SW_ERR_BASE-24)/* unknown firmware error */
+#define SW_ERR_INTERRUPT (SW_ERR_BASE-25)/* request is abort when */
+ /* it's waiting to be */
+ /* completed. */
+#define SW_ERR_NVWRITE_FAIL (SW_ERR_BASE-26)/* error in writing to Non- */
+ /* volatile memory */
+#define SW_ERR_NVWRITE_RANGE (SW_ERR_BASE-27)/* out of range error in */
+ /* writing to NV memory */
+#define SW_ERR_RNG_ERROR (SW_ERR_BASE-28)/* Random Number Generation */
+ /* failure */
+#define SW_ERR_DSS_FAILURE (SW_ERR_BASE-29)/* DSS Sign or Verify failure*/
+#define SW_ERR_MODEXP_FAILURE (SW_ERR_BASE-30)/* Failure in various math */
+ /* calculations */
+#define SW_ERR_ONBOARD_MEMORY (SW_ERR_BASE-31)/* Error in accessing on - */
+ /* board memory */
+#define SW_ERR_FIRMWARE_VERSION \
+ (SW_ERR_BASE-32)/* Wrong version in firmware */
+ /* update */
+#define SW_ERR_ZERO_WORKING_ACCELERATOR \
+ (SW_ERR_BASE-44)/* All accelerators are bad */
+
+
+ /* algorithm type */
+#define SW_ALG_CRT 1
+#define SW_ALG_EXP 2
+#define SW_ALG_DSA 3
+#define SW_ALG_NVDATA 4
+
+ /* command code */
+#define SW_CMD_MODEXP_CRT 1 /* perform Modular Exponentiation using */
+ /* Chinese Remainder Theorem (CRT) */
+#define SW_CMD_MODEXP 2 /* perform Modular Exponentiation */
+#define SW_CMD_DSS_SIGN 3 /* perform DSS sign */
+#define SW_CMD_DSS_VERIFY 4 /* perform DSS verify */
+#define SW_CMD_RAND 5 /* perform random number generation */
+#define SW_CMD_NVREAD 6 /* perform read to nonvolatile RAM */
+#define SW_CMD_NVWRITE 7 /* perform write to nonvolatile RAM */
+
+typedef SW_U32 SW_ALGTYPE; /* alogrithm type */
+typedef SW_U32 SW_STATE; /* state */
+typedef SW_U32 SW_COMMAND_CODE; /* command code */
+typedef SW_U32 SW_COMMAND_BITMAP[4]; /* bitmap */
+
+typedef struct _SW_LARGENUMBER {
+ SW_U32 nbytes; /* number of bytes in the buffer "value" */
+ SW_BYTE* value; /* the large integer as a string of */
+ /* bytes in network (big endian) order */
+} SW_LARGENUMBER;
+
+#if defined(OPENSSL_SYS_WIN32)
+ #include <windows.h>
+ typedef HANDLE SW_OSHANDLE; /* handle to kernel object */
+ #define SW_OS_INVALID_HANDLE INVALID_HANDLE_VALUE
+ #define SW_CALLCONV _stdcall
+#elif defined(OPENSSL_SYS_MACINTOSH_CLASSIC)
+ /* async callback mechanisms */
+ /* swiftCallbackLevel */
+ #define SW_MAC_CALLBACK_LEVEL_NO 0
+ #define SW_MAC_CALLBACK_LEVEL_HARDWARE 1 /* from the hardware ISR */
+ #define SW_MAC_CALLBACK_LEVEL_SECONDARY 2 /* as secondary ISR */
+ typedef int SW_MAC_CALLBACK_LEVEL;
+ typedef int SW_OSHANDLE;
+ #define SW_OS_INVALID_HANDLE (-1)
+ #define SW_CALLCONV
+#else /* Unix variants */
+ typedef int SW_OSHANDLE; /* handle to driver */
+ #define SW_OS_INVALID_HANDLE (-1)
+ #define SW_CALLCONV
+#endif
+
+typedef struct _SW_CRT {
+ SW_LARGENUMBER p; /* prime number p */
+ SW_LARGENUMBER q; /* prime number q */
+ SW_LARGENUMBER dmp1; /* exponent1 */
+ SW_LARGENUMBER dmq1; /* exponent2 */
+ SW_LARGENUMBER iqmp; /* CRT coefficient */
+} SW_CRT;
+
+typedef struct _SW_EXP {
+ SW_LARGENUMBER modulus; /* modulus */
+ SW_LARGENUMBER exponent;/* exponent */
+} SW_EXP;
+
+typedef struct _SW_DSA {
+ SW_LARGENUMBER p; /* */
+ SW_LARGENUMBER q; /* */
+ SW_LARGENUMBER g; /* */
+ SW_LARGENUMBER key; /* private/public key */
+} SW_DSA;
+
+typedef struct _SW_NVDATA {
+ SW_U32 accnum; /* accelerator board number */
+ SW_U32 offset; /* offset in byte */
+} SW_NVDATA;
+
+typedef struct _SW_PARAM {
+ SW_ALGTYPE type; /* type of the alogrithm */
+ union {
+ SW_CRT crt;
+ SW_EXP exp;
+ SW_DSA dsa;
+ SW_NVDATA nvdata;
+ } up;
+} SW_PARAM;
+
+typedef SW_U32 SW_CONTEXT_HANDLE; /* opaque context handle */
+
+
+/* Now the OpenSSL bits, these function types are the for the function
+ * pointers that will bound into the Rainbow shared libraries. */
+typedef SW_STATUS SW_CALLCONV t_swAcquireAccContext(SW_CONTEXT_HANDLE *hac);
+typedef SW_STATUS SW_CALLCONV t_swAttachKeyParam(SW_CONTEXT_HANDLE hac,
+ SW_PARAM *key_params);
+typedef SW_STATUS SW_CALLCONV t_swSimpleRequest(SW_CONTEXT_HANDLE hac,
+ SW_COMMAND_CODE cmd,
+ SW_LARGENUMBER pin[],
+ SW_U32 pin_count,
+ SW_LARGENUMBER pout[],
+ SW_U32 pout_count);
+typedef SW_STATUS SW_CALLCONV t_swReleaseAccContext(SW_CONTEXT_HANDLE hac);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
diff --git a/openssl/engines/vendor_defns/hw_4758_cca.h b/openssl/engines/vendor_defns/hw_4758_cca.h
new file mode 100644
index 000000000..296636e81
--- /dev/null
+++ b/openssl/engines/vendor_defns/hw_4758_cca.h
@@ -0,0 +1,149 @@
+/**********************************************************************/
+/* */
+/* Prototypes of the CCA verbs used by the 4758 CCA openssl driver */
+/* */
+/* Maurice Gittens <maurice@gittens.nl> */
+/* */
+/**********************************************************************/
+
+#ifndef __HW_4758_CCA__
+#define __HW_4758_CCA__
+
+/*
+ * Only WIN32 support for now
+ */
+#if defined(WIN32)
+
+ #define CCA_LIB_NAME "CSUNSAPI"
+
+ #define CSNDPKX "CSNDPKX_32"
+ #define CSNDKRR "CSNDKRR_32"
+ #define CSNDPKE "CSNDPKE_32"
+ #define CSNDPKD "CSNDPKD_32"
+ #define CSNDDSV "CSNDDSV_32"
+ #define CSNDDSG "CSNDDSG_32"
+ #define CSNBRNG "CSNBRNG_32"
+
+ #define SECURITYAPI __stdcall
+#else
+ /* Fixme!!
+ Find out the values of these constants for other platforms.
+ */
+ #define CCA_LIB_NAME "CSUNSAPI"
+
+ #define CSNDPKX "CSNDPKX"
+ #define CSNDKRR "CSNDKRR"
+ #define CSNDPKE "CSNDPKE"
+ #define CSNDPKD "CSNDPKD"
+ #define CSNDDSV "CSNDDSV"
+ #define CSNDDSG "CSNDDSG"
+ #define CSNBRNG "CSNBRNG"
+
+ #define SECURITYAPI
+#endif
+
+/*
+ * security API prototypes
+ */
+
+/* PKA Key Record Read */
+typedef void (SECURITYAPI *F_KEYRECORDREAD)
+ (long * return_code,
+ long * reason_code,
+ long * exit_data_length,
+ unsigned char * exit_data,
+ long * rule_array_count,
+ unsigned char * rule_array,
+ unsigned char * key_label,
+ long * key_token_length,
+ unsigned char * key_token);
+
+/* Random Number Generate */
+typedef void (SECURITYAPI *F_RANDOMNUMBERGENERATE)
+ (long * return_code,
+ long * reason_code,
+ long * exit_data_length,
+ unsigned char * exit_data,
+ unsigned char * form,
+ unsigned char * random_number);
+
+/* Digital Signature Generate */
+typedef void (SECURITYAPI *F_DIGITALSIGNATUREGENERATE)
+ (long * return_code,
+ long * reason_code,
+ long * exit_data_length,
+ unsigned char * exit_data,
+ long * rule_array_count,
+ unsigned char * rule_array,
+ long * PKA_private_key_id_length,
+ unsigned char * PKA_private_key_id,
+ long * hash_length,
+ unsigned char * hash,
+ long * signature_field_length,
+ long * signature_bit_length,
+ unsigned char * signature_field);
+
+/* Digital Signature Verify */
+typedef void (SECURITYAPI *F_DIGITALSIGNATUREVERIFY)(
+ long * return_code,
+ long * reason_code,
+ long * exit_data_length,
+ unsigned char * exit_data,
+ long * rule_array_count,
+ unsigned char * rule_array,
+ long * PKA_public_key_id_length,
+ unsigned char * PKA_public_key_id,
+ long * hash_length,
+ unsigned char * hash,
+ long * signature_field_length,
+ unsigned char * signature_field);
+
+/* PKA Public Key Extract */
+typedef void (SECURITYAPI *F_PUBLICKEYEXTRACT)(
+ long * return_code,
+ long * reason_code,
+ long * exit_data_length,
+ unsigned char * exit_data,
+ long * rule_array_count,
+ unsigned char * rule_array,
+ long * source_key_identifier_length,
+ unsigned char * source_key_identifier,
+ long * target_key_token_length,
+ unsigned char * target_key_token);
+
+/* PKA Encrypt */
+typedef void (SECURITYAPI *F_PKAENCRYPT)
+ (long * return_code,
+ long * reason_code,
+ long * exit_data_length,
+ unsigned char * exit_data,
+ long * rule_array_count,
+ unsigned char * rule_array,
+ long * key_value_length,
+ unsigned char * key_value,
+ long * data_struct_length,
+ unsigned char * data_struct,
+ long * RSA_public_key_length,
+ unsigned char * RSA_public_key,
+ long * RSA_encipher_length,
+ unsigned char * RSA_encipher );
+
+/* PKA Decrypt */
+typedef void (SECURITYAPI *F_PKADECRYPT)
+ (long * return_code,
+ long * reason_code,
+ long * exit_data_length,
+ unsigned char * exit_data,
+ long * rule_array_count,
+ unsigned char * rule_array,
+ long * enciphered_key_length,
+ unsigned char * enciphered_key,
+ long * data_struct_length,
+ unsigned char * data_struct,
+ long * RSA_private_key_length,
+ unsigned char * RSA_private_key,
+ long * key_value_length,
+ unsigned char * key_value );
+
+
+#endif
diff --git a/openssl/engines/vendor_defns/hw_ubsec.h b/openssl/engines/vendor_defns/hw_ubsec.h
new file mode 100644
index 000000000..b6619d40f
--- /dev/null
+++ b/openssl/engines/vendor_defns/hw_ubsec.h
@@ -0,0 +1,100 @@
+/******************************************************************************
+ *
+ * Copyright 2000
+ * Broadcom Corporation
+ * 16215 Alton Parkway
+ * PO Box 57013
+ * Irvine CA 92619-7013
+ *
+ *****************************************************************************/
+/*
+ * Broadcom Corporation uBSec SDK
+ */
+/*
+ * Character device header file.
+ */
+/*
+ * Revision History:
+ *
+ * October 2000 JTT Created.
+ */
+
+#define MAX_PUBLIC_KEY_BITS (1024)
+#define MAX_PUBLIC_KEY_BYTES (1024/8)
+#define SHA_BIT_SIZE (160)
+#define MAX_CRYPTO_KEY_LENGTH 24
+#define MAX_MAC_KEY_LENGTH 64
+#define UBSEC_CRYPTO_DEVICE_NAME ((unsigned char *)"/dev/ubscrypt")
+#define UBSEC_KEY_DEVICE_NAME ((unsigned char *)"/dev/ubskey")
+
+/* Math command types. */
+#define UBSEC_MATH_MODADD 0x0001
+#define UBSEC_MATH_MODSUB 0x0002
+#define UBSEC_MATH_MODMUL 0x0004
+#define UBSEC_MATH_MODEXP 0x0008
+#define UBSEC_MATH_MODREM 0x0010
+#define UBSEC_MATH_MODINV 0x0020
+
+typedef long ubsec_MathCommand_t;
+typedef long ubsec_RNGCommand_t;
+
+typedef struct ubsec_crypto_context_s {
+ unsigned int flags;
+ unsigned char crypto[MAX_CRYPTO_KEY_LENGTH];
+ unsigned char auth[MAX_MAC_KEY_LENGTH];
+} ubsec_crypto_context_t, *ubsec_crypto_context_p;
+
+/*
+ * Predeclare the function pointer types that we dynamically load from the DSO.
+ */
+
+typedef int t_UBSEC_ubsec_bytes_to_bits(unsigned char *n, int bytes);
+
+typedef int t_UBSEC_ubsec_bits_to_bytes(int bits);
+
+typedef int t_UBSEC_ubsec_open(unsigned char *device);
+
+typedef int t_UBSEC_ubsec_close(int fd);
+
+typedef int t_UBSEC_diffie_hellman_generate_ioctl (int fd,
+ unsigned char *x, int *x_len, unsigned char *y, int *y_len,
+ unsigned char *g, int g_len, unsigned char *m, int m_len,
+ unsigned char *userX, int userX_len, int random_bits);
+
+typedef int t_UBSEC_diffie_hellman_agree_ioctl (int fd,
+ unsigned char *x, int x_len, unsigned char *y, int y_len,
+ unsigned char *m, int m_len, unsigned char *k, int *k_len);
+
+typedef int t_UBSEC_rsa_mod_exp_ioctl (int fd,
+ unsigned char *x, int x_len, unsigned char *m, int m_len,
+ unsigned char *e, int e_len, unsigned char *y, int *y_len);
+
+typedef int t_UBSEC_rsa_mod_exp_crt_ioctl (int fd,
+ unsigned char *x, int x_len, unsigned char *qinv, int qinv_len,
+ unsigned char *edq, int edq_len, unsigned char *q, int q_len,
+ unsigned char *edp, int edp_len, unsigned char *p, int p_len,
+ unsigned char *y, int *y_len);
+
+typedef int t_UBSEC_dsa_sign_ioctl (int fd,
+ int hash, unsigned char *data, int data_len,
+ unsigned char *rndom, int random_len,
+ unsigned char *p, int p_len, unsigned char *q, int q_len,
+ unsigned char *g, int g_len, unsigned char *key, int key_len,
+ unsigned char *r, int *r_len, unsigned char *s, int *s_len);
+
+typedef int t_UBSEC_dsa_verify_ioctl (int fd,
+ int hash, unsigned char *data, int data_len,
+ unsigned char *p, int p_len, unsigned char *q, int q_len,
+ unsigned char *g, int g_len, unsigned char *key, int key_len,
+ unsigned char *r, int r_len, unsigned char *s, int s_len,
+ unsigned char *v, int *v_len);
+
+typedef int t_UBSEC_math_accelerate_ioctl(int fd, ubsec_MathCommand_t command,
+ unsigned char *ModN, int *ModN_len, unsigned char *ExpE, int *ExpE_len,
+ unsigned char *ParamA, int *ParamA_len, unsigned char *ParamB, int *ParamB_len,
+ unsigned char *Result, int *Result_len);
+
+typedef int t_UBSEC_rng_ioctl(int fd, ubsec_RNGCommand_t command,
+ unsigned char *Result, int *Result_len);
+
+typedef int t_UBSEC_max_key_len_ioctl(int fd, int *max_key_len);
diff --git a/openssl/engines/vendor_defns/hwcryptohook.h b/openssl/engines/vendor_defns/hwcryptohook.h
new file mode 100644
index 000000000..482f1f2d1
--- /dev/null
+++ b/openssl/engines/vendor_defns/hwcryptohook.h
@@ -0,0 +1,486 @@
+/*
+ * ModExp / RSA (with/without KM) plugin API
+ *
+ * The application will load a dynamic library which
+ * exports entrypoint(s) defined in this file.
+ *
+ * This set of entrypoints provides only a multithreaded,
+ * synchronous-within-each-thread, facility.
+ *
+ *
+ * This file is Copyright 1998-2000 nCipher Corporation Limited.
+ *
+ * Redistribution and use in source and binary forms, with opr 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
+ *
+ * IN NO EVENT SHALL NCIPHER CORPORATION LIMITED (`NCIPHER') AND/OR
+ * ANY OTHER AUTHORS OR DISTRIBUTORS OF THIS FILE BE LIABLE for any
+ * damages arising directly or indirectly from this file, its use or
+ * this licence. Without prejudice to the generality of the
+ * foregoing: all liability shall be excluded for direct, indirect,
+ * special, incidental, consequential or other damages or any loss of
+ * profits, business, revenue goodwill or anticipated savings;
+ * liability shall be excluded even if nCipher or anyone else has been
+ * advised of the possibility of damage. In any event, if the
+ * exclusion of liability is not effective, the liability of nCipher
+ * or any author or distributor shall be limited to the lesser of the
+ * price paid and 1,000 pounds sterling. This licence only fails to
+ * exclude or limit liability for death or personal injury arising out
+ * of negligence, and only to the extent that such an exclusion or
+ * limitation is not effective.
+ *
+ * NCIPHER AND THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ALL
+ * AND ANY WARRANTIES (WHETHER EXPRESS OR IMPLIED), including, but not
+ * limited to, any implied warranties of merchantability, fitness for
+ * a particular purpose, satisfactory quality, and/or non-infringement
+ * of any third party rights.
+ *
+ * US Government use: This software and documentation is Commercial
+ * Computer Software and Computer Software Documentation, as defined in
+ * sub-paragraphs (a)(1) and (a)(5) of DFAR 252.227-7014, "Rights in
+ * Noncommercial Computer Software and Noncommercial Computer Software
+ * Documentation." Use, duplication or disclosure by the Government is
+ * subject to the terms and conditions specified here.
+ *
+ * By using or distributing this file you will be accepting these
+ * terms and conditions, including the limitation of liability and
+ * lack of warranty. If you do not wish to accept these terms and
+ * conditions, DO NOT USE THE FILE.
+ *
+ *
+ * The actual dynamically loadable plugin, and the library files for
+ * static linking, which are also provided in some distributions, are
+ * not covered by the licence described above. You should have
+ * received a separate licence with terms and conditions for these
+ * library files; if you received the library files without a licence,
+ * please contact nCipher.
+ *
+ *
+ * $Id: hwcryptohook.h,v 1.1 2002/10/11 17:10:59 levitte Exp $
+ */
+
+#ifndef HWCRYPTOHOOK_H
+#define HWCRYPTOHOOK_H
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#ifndef HWCRYPTOHOOK_DECLARE_APPTYPES
+#define HWCRYPTOHOOK_DECLARE_APPTYPES 1
+#endif
+
+#define HWCRYPTOHOOK_ERROR_FAILED -1
+#define HWCRYPTOHOOK_ERROR_FALLBACK -2
+#define HWCRYPTOHOOK_ERROR_MPISIZE -3
+
+#if HWCRYPTOHOOK_DECLARE_APPTYPES
+
+/* These structs are defined by the application and opaque to the
+ * crypto plugin. The application may define these as it sees fit.
+ * Default declarations are provided here, but the application may
+ * #define HWCRYPTOHOOK_DECLARE_APPTYPES 0
+ * to prevent these declarations, and instead provide its own
+ * declarations of these types. (Pointers to them must still be
+ * ordinary pointers to structs or unions, or the resulting combined
+ * program will have a type inconsistency.)
+ */
+typedef struct HWCryptoHook_MutexValue HWCryptoHook_Mutex;
+typedef struct HWCryptoHook_CondVarValue HWCryptoHook_CondVar;
+typedef struct HWCryptoHook_PassphraseContextValue HWCryptoHook_PassphraseContext;
+typedef struct HWCryptoHook_CallerContextValue HWCryptoHook_CallerContext;
+
+#endif /* HWCRYPTOHOOK_DECLARE_APPTYPES */
+
+/* These next two structs are opaque to the application. The crypto
+ * plugin will return pointers to them; the caller simply manipulates
+ * the pointers.
+ */
+typedef struct HWCryptoHook_Context *HWCryptoHook_ContextHandle;
+typedef struct HWCryptoHook_RSAKey *HWCryptoHook_RSAKeyHandle;
+
+typedef struct {
+ char *buf;
+ size_t size;
+} HWCryptoHook_ErrMsgBuf;
+/* Used for error reporting. When a HWCryptoHook function fails it
+ * will return a sentinel value (0 for pointer-valued functions, or a
+ * negative number, usually HWCRYPTOHOOK_ERROR_FAILED, for
+ * integer-valued ones). It will, if an ErrMsgBuf is passed, also put
+ * an error message there.
+ *
+ * size is the size of the buffer, and will not be modified. If you
+ * pass 0 for size you must pass 0 for buf, and nothing will be
+ * recorded (just as if you passed 0 for the struct pointer).
+ * Messages written to the buffer will always be null-terminated, even
+ * when truncated to fit within size bytes.
+ *
+ * The contents of the buffer are not defined if there is no error.
+ */
+
+typedef struct HWCryptoHook_MPIStruct {
+ unsigned char *buf;
+ size_t size;
+} HWCryptoHook_MPI;
+/* When one of these is returned, a pointer is passed to the function.
+ * At call, size is the space available. Afterwards it is updated to
+ * be set to the actual length (which may be more than the space available,
+ * if there was not enough room and the result was truncated).
+ * buf (the pointer) is not updated.
+ *
+ * size is in bytes and may be zero at call or return, but must be a
+ * multiple of the limb size. Zero limbs at the MS end are not
+ * permitted.
+ */
+
+#define HWCryptoHook_InitFlags_FallbackModExp 0x0002UL
+#define HWCryptoHook_InitFlags_FallbackRSAImmed 0x0004UL
+/* Enable requesting fallback to software in case of problems with the
+ * hardware support. This indicates to the crypto provider that the
+ * application is prepared to fall back to software operation if the
+ * ModExp* or RSAImmed* functions return HWCRYPTOHOOK_ERROR_FALLBACK.
+ * Without this flag those calls will never return
+ * HWCRYPTOHOOK_ERROR_FALLBACK. The flag will also cause the crypto
+ * provider to avoid repeatedly attempting to contact dead hardware
+ * within a short interval, if appropriate.
+ */
+
+#define HWCryptoHook_InitFlags_SimpleForkCheck 0x0010UL
+/* Without _SimpleForkCheck the library is allowed to assume that the
+ * application will not fork and call the library in the child(ren).
+ *
+ * When it is specified, this is allowed. However, after a fork
+ * neither parent nor child may unload any loaded keys or call
+ * _Finish. Instead, they should call exit (or die with a signal)
+ * without calling _Finish. After all the children have died the
+ * parent may unload keys or call _Finish.
+ *
+ * This flag only has any effect on UN*X platforms.
+ */
+
+typedef struct {
+ unsigned long flags;
+ void *logstream; /* usually a FILE*. See below. */
+
+ size_t limbsize; /* bignum format - size of radix type, must be power of 2 */
+ int mslimbfirst; /* 0 or 1 */
+ int msbytefirst; /* 0 or 1; -1 = native */
+
+ /* All the callback functions should return 0 on success, or a
+ * nonzero integer (whose value will be visible in the error message
+ * put in the buffer passed to the call).
+ *
+ * If a callback is not available pass a null function pointer.
+ *
+ * The callbacks may not call down again into the crypto plugin.
+ */
+
+ /* For thread-safety. Set everything to 0 if you promise only to be
+ * singlethreaded. maxsimultaneous is the number of calls to
+ * ModExp[Crt]/RSAImmed{Priv,Pub}/RSA. If you don't know what to
+ * put there then say 0 and the hook library will use a default.
+ *
+ * maxmutexes is a small limit on the number of simultaneous mutexes
+ * which will be requested by the library. If there is no small
+ * limit, set it to 0. If the crypto plugin cannot create the
+ * advertised number of mutexes the calls to its functions may fail.
+ * If a low number of mutexes is advertised the plugin will try to
+ * do the best it can. Making larger numbers of mutexes available
+ * may improve performance and parallelism by reducing contention
+ * over critical sections. Unavailability of any mutexes, implying
+ * single-threaded operation, should be indicated by the setting
+ * mutex_init et al to 0.
+ */
+ int maxmutexes;
+ int maxsimultaneous;
+ size_t mutexsize;
+ int (*mutex_init)(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext *cactx);
+ int (*mutex_acquire)(HWCryptoHook_Mutex*);
+ void (*mutex_release)(HWCryptoHook_Mutex*);
+ void (*mutex_destroy)(HWCryptoHook_Mutex*);
+
+ /* For greater efficiency, can use condition vars internally for
+ * synchronisation. In this case maxsimultaneous is ignored, but
+ * the other mutex stuff must be available. In singlethreaded
+ * programs, set everything to 0.
+ */
+ size_t condvarsize;
+ int (*condvar_init)(HWCryptoHook_CondVar*, HWCryptoHook_CallerContext *cactx);
+ int (*condvar_wait)(HWCryptoHook_CondVar*, HWCryptoHook_Mutex*);
+ void (*condvar_signal)(HWCryptoHook_CondVar*);
+ void (*condvar_broadcast)(HWCryptoHook_CondVar*);
+ void (*condvar_destroy)(HWCryptoHook_CondVar*);
+
+ /* The semantics of acquiring and releasing mutexes and broadcasting
+ * and waiting on condition variables are expected to be those from
+ * POSIX threads (pthreads). The mutexes may be (in pthread-speak)
+ * fast mutexes, recursive mutexes, or nonrecursive ones.
+ *
+ * The _release/_signal/_broadcast and _destroy functions must
+ * always succeed when given a valid argument; if they are given an
+ * invalid argument then the program (crypto plugin + application)
+ * has an internal error, and they should abort the program.
+ */
+
+ int (*getpassphrase)(const char *prompt_info,
+ int *len_io, char *buf,
+ HWCryptoHook_PassphraseContext *ppctx,
+ HWCryptoHook_CallerContext *cactx);
+ /* Passphrases and the prompt_info, if they contain high-bit-set
+ * characters, are UTF-8. The prompt_info may be a null pointer if
+ * no prompt information is available (it should not be an empty
+ * string). It will not contain text like `enter passphrase';
+ * instead it might say something like `Operator Card for John
+ * Smith' or `SmartCard in nFast Module #1, Slot #1'.
+ *
+ * buf points to a buffer in which to return the passphrase; on
+ * entry *len_io is the length of the buffer. It should be updated
+ * by the callback. The returned passphrase should not be
+ * null-terminated by the callback.
+ */
+
+ int (*getphystoken)(const char *prompt_info,
+ const char *wrong_info,
+ HWCryptoHook_PassphraseContext *ppctx,
+ HWCryptoHook_CallerContext *cactx);
+ /* Requests that the human user physically insert a different
+ * smartcard, DataKey, etc. The plugin should check whether the
+ * currently inserted token(s) are appropriate, and if they are it
+ * should not make this call.
+ *
+ * prompt_info is as before. wrong_info is a description of the
+ * currently inserted token(s) so that the user is told what
+ * something is. wrong_info, like prompt_info, may be null, but
+ * should not be an empty string. Its contents should be
+ * syntactically similar to that of prompt_info.
+ */
+
+ /* Note that a single LoadKey operation might cause several calls to
+ * getpassphrase and/or requestphystoken. If requestphystoken is
+ * not provided (ie, a null pointer is passed) then the plugin may
+ * not support loading keys for which authorisation by several cards
+ * is required. If getpassphrase is not provided then cards with
+ * passphrases may not be supported.
+ *
+ * getpassphrase and getphystoken do not need to check that the
+ * passphrase has been entered correctly or the correct token
+ * inserted; the crypto plugin will do that. If this is not the
+ * case then the crypto plugin is responsible for calling these
+ * routines again as appropriate until the correct token(s) and
+ * passphrase(s) are supplied as required, or until any retry limits
+ * implemented by the crypto plugin are reached.
+ *
+ * In either case, the application must allow the user to say `no'
+ * or `cancel' to indicate that they do not know the passphrase or
+ * have the appropriate token; this should cause the callback to
+ * return nonzero indicating error.
+ */
+
+ void (*logmessage)(void *logstream, const char *message);
+ /* A log message will be generated at least every time something goes
+ * wrong and an ErrMsgBuf is filled in (or would be if one was
+ * provided). Other diagnostic information may be written there too,
+ * including more detailed reasons for errors which are reported in an
+ * ErrMsgBuf.
+ *
+ * When a log message is generated, this callback is called. It
+ * should write a message to the relevant logging arrangements.
+ *
+ * The message string passed will be null-terminated and may be of arbitrary
+ * length. It will not be prefixed by the time and date, nor by the
+ * name of the library that is generating it - if this is required,
+ * the logmessage callback must do it. The message will not have a
+ * trailing newline (though it may contain internal newlines).
+ *
+ * If a null pointer is passed for logmessage a default function is
+ * used. The default function treats logstream as a FILE* which has
+ * been converted to a void*. If logstream is 0 it does nothing.
+ * Otherwise it prepends the date and time and library name and
+ * writes the message to logstream. Each line will be prefixed by a
+ * descriptive string containing the date, time and identity of the
+ * crypto plugin. Errors on the logstream are not reported
+ * anywhere, and the default function doesn't flush the stream, so
+ * the application must set the buffering how it wants it.
+ *
+ * The crypto plugin may also provide a facility to have copies of
+ * log messages sent elsewhere, and or for adjusting the verbosity
+ * of the log messages; any such facilities will be configured by
+ * external means.
+ */
+
+} HWCryptoHook_InitInfo;
+
+typedef
+HWCryptoHook_ContextHandle HWCryptoHook_Init_t(const HWCryptoHook_InitInfo *initinfo,
+ size_t initinfosize,
+ const HWCryptoHook_ErrMsgBuf *errors,
+ HWCryptoHook_CallerContext *cactx);
+extern HWCryptoHook_Init_t HWCryptoHook_Init;
+
+/* Caller should set initinfosize to the size of the HWCryptoHook struct,
+ * so it can be extended later.
+ *
+ * On success, a message for display or logging by the server,
+ * including the name and version number of the plugin, will be filled
+ * in into *errors; on failure *errors is used for error handling, as
+ * usual.
+ */
+
+/* All these functions return 0 on success, HWCRYPTOHOOK_ERROR_FAILED
+ * on most failures. HWCRYPTOHOOK_ERROR_MPISIZE means at least one of
+ * the output MPI buffer(s) was too small; the sizes of all have been
+ * set to the desired size (and for those where the buffer was large
+ * enough, the value may have been copied in), and no error message
+ * has been recorded.
+ *
+ * You may pass 0 for the errors struct. In any case, unless you set
+ * _NoStderr at init time then messages may be reported to stderr.
+ */
+
+/* The RSAImmed* functions (and key managed RSA) only work with
+ * modules which have an RSA patent licence - currently that means KM
+ * units; the ModExp* ones work with all modules, so you need a patent
+ * licence in the software in the US. They are otherwise identical.
+ */
+
+typedef
+void HWCryptoHook_Finish_t(HWCryptoHook_ContextHandle hwctx);
+extern HWCryptoHook_Finish_t HWCryptoHook_Finish;
+/* You must not have any calls going or keys loaded when you call this. */
+
+typedef
+int HWCryptoHook_RandomBytes_t(HWCryptoHook_ContextHandle hwctx,
+ unsigned char *buf, size_t len,
+ const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_RandomBytes_t HWCryptoHook_RandomBytes;
+
+typedef
+int HWCryptoHook_ModExp_t(HWCryptoHook_ContextHandle hwctx,
+ HWCryptoHook_MPI a,
+ HWCryptoHook_MPI p,
+ HWCryptoHook_MPI n,
+ HWCryptoHook_MPI *r,
+ const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_ModExp_t HWCryptoHook_ModExp;
+
+typedef
+int HWCryptoHook_RSAImmedPub_t(HWCryptoHook_ContextHandle hwctx,
+ HWCryptoHook_MPI m,
+ HWCryptoHook_MPI e,
+ HWCryptoHook_MPI n,
+ HWCryptoHook_MPI *r,
+ const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_RSAImmedPub_t HWCryptoHook_RSAImmedPub;
+
+typedef
+int HWCryptoHook_ModExpCRT_t(HWCryptoHook_ContextHandle hwctx,
+ HWCryptoHook_MPI a,
+ HWCryptoHook_MPI p,
+ HWCryptoHook_MPI q,
+ HWCryptoHook_MPI dmp1,
+ HWCryptoHook_MPI dmq1,
+ HWCryptoHook_MPI iqmp,
+ HWCryptoHook_MPI *r,
+ const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_ModExpCRT_t HWCryptoHook_ModExpCRT;
+
+typedef
+int HWCryptoHook_RSAImmedPriv_t(HWCryptoHook_ContextHandle hwctx,
+ HWCryptoHook_MPI m,
+ HWCryptoHook_MPI p,
+ HWCryptoHook_MPI q,
+ HWCryptoHook_MPI dmp1,
+ HWCryptoHook_MPI dmq1,
+ HWCryptoHook_MPI iqmp,
+ HWCryptoHook_MPI *r,
+ const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_RSAImmedPriv_t HWCryptoHook_RSAImmedPriv;
+
+/* The RSAImmed* and ModExp* functions may return E_FAILED or
+ * E_FALLBACK for failure.
+ *
+ * E_FAILED means the failure is permanent and definite and there
+ * should be no attempt to fall back to software. (Eg, for some
+ * applications, which support only the acceleration-only
+ * functions, the `key material' may actually be an encoded key
+ * identifier, and doing the operation in software would give wrong
+ * answers.)
+ *
+ * E_FALLBACK means that doing the computation in software would seem
+ * reasonable. If an application pays attention to this and is
+ * able to fall back, it should also set the Fallback init flags.
+ */
+
+typedef
+int HWCryptoHook_RSALoadKey_t(HWCryptoHook_ContextHandle hwctx,
+ const char *key_ident,
+ HWCryptoHook_RSAKeyHandle *keyhandle_r,
+ const HWCryptoHook_ErrMsgBuf *errors,
+ HWCryptoHook_PassphraseContext *ppctx);
+extern HWCryptoHook_RSALoadKey_t HWCryptoHook_RSALoadKey;
+/* The key_ident is a null-terminated string configured by the
+ * user via the application's usual configuration mechanisms.
+ * It is provided to the user by the crypto provider's key management
+ * system. The user must be able to enter at least any string of between
+ * 1 and 1023 characters inclusive, consisting of printable 7-bit
+ * ASCII characters. The provider should avoid using
+ * any characters except alphanumerics and the punctuation
+ * characters _ - + . / @ ~ (the user is expected to be able
+ * to enter these without quoting). The string may be case-sensitive.
+ * The application may allow the user to enter other NULL-terminated strings,
+ * and the provider must cope (returning an error if the string is not
+ * valid).
+ *
+ * If the key does not exist, no error is recorded and 0 is returned;
+ * keyhandle_r will be set to 0 instead of to a key handle.
+ */
+
+typedef
+int HWCryptoHook_RSAGetPublicKey_t(HWCryptoHook_RSAKeyHandle k,
+ HWCryptoHook_MPI *n,
+ HWCryptoHook_MPI *e,
+ const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_RSAGetPublicKey_t HWCryptoHook_RSAGetPublicKey;
+/* The crypto plugin will not store certificates.
+ *
+ * Although this function for acquiring the public key value is
+ * provided, it is not the purpose of this API to deal fully with the
+ * handling of the public key.
+ *
+ * It is expected that the crypto supplier's key generation program
+ * will provide general facilities for producing X.509
+ * self-certificates and certificate requests in PEM format. These
+ * will be given to the user so that they can configure them in the
+ * application, send them to CAs, or whatever.
+ *
+ * In case this kind of certificate handling is not appropriate, the
+ * crypto supplier's key generation program should be able to be
+ * configured not to generate such a self-certificate or certificate
+ * request. Then the application will need to do all of this, and
+ * will need to store and handle the public key and certificates
+ * itself.
+ */
+
+typedef
+int HWCryptoHook_RSAUnloadKey_t(HWCryptoHook_RSAKeyHandle k,
+ const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_RSAUnloadKey_t HWCryptoHook_RSAUnloadKey;
+/* Might fail due to locking problems, or other serious internal problems. */
+
+typedef
+int HWCryptoHook_RSA_t(HWCryptoHook_MPI m,
+ HWCryptoHook_RSAKeyHandle k,
+ HWCryptoHook_MPI *r,
+ const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_RSA_t HWCryptoHook_RSA;
+/* RSA private key operation (sign or decrypt) - raw, unpadded. */
+
+#endif /*HWCRYPTOHOOK_H*/
diff --git a/openssl/engines/vendor_defns/sureware.h b/openssl/engines/vendor_defns/sureware.h
new file mode 100644
index 000000000..e46b000dd
--- /dev/null
+++ b/openssl/engines/vendor_defns/sureware.h
@@ -0,0 +1,239 @@
+/*
+* Written by Corinne Dive-Reclus(cdive@baltimore.com)
+*
+* Copyright@2001 Baltimore Technologies Ltd.
+* *
+* THIS FILE IS PROVIDED BY BALTIMORE TECHNOLOGIES ``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 BALTIMORE TECHNOLOGIES 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. *
+*
+*
+*/
+#ifdef WIN32
+#define SW_EXPORT __declspec ( dllexport )
+#else
+#define SW_EXPORT
+#endif
+
+/*
+* List of exposed SureWare errors
+*/
+#define SUREWAREHOOK_ERROR_FAILED -1
+#define SUREWAREHOOK_ERROR_FALLBACK -2
+#define SUREWAREHOOK_ERROR_UNIT_FAILURE -3
+#define SUREWAREHOOK_ERROR_DATA_SIZE -4
+#define SUREWAREHOOK_ERROR_INVALID_PAD -5
+/*
+* -----------------WARNING-----------------------------------
+* In all the following functions:
+* msg is a string with at least 24 bytes free.
+* A 24 bytes string will be concatenated to the existing content of msg.
+*/
+/*
+* SureWare Initialisation function
+* in param threadsafe, if !=0, thread safe enabled
+* return SureWareHOOK_ERROR_UNIT_FAILURE if failure, 1 if success
+*/
+typedef int SureWareHook_Init_t(char*const msg,int threadsafe);
+extern SW_EXPORT SureWareHook_Init_t SureWareHook_Init;
+/*
+* SureWare Finish function
+*/
+typedef void SureWareHook_Finish_t(void);
+extern SW_EXPORT SureWareHook_Finish_t SureWareHook_Finish;
+/*
+* PRE_CONDITION:
+* DO NOT CALL ANY OF THE FOLLOWING FUNCTIONS IN CASE OF INIT FAILURE
+*/
+/*
+* SureWare RAND Bytes function
+* In case of failure, the content of buf is unpredictable.
+* return 1 if success
+* SureWareHOOK_ERROR_FALLBACK if function not available in hardware
+* SureWareHOOK_ERROR_FAILED if error while processing
+* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
+* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
+*
+* in/out param buf : a num bytes long buffer where random bytes will be put
+* in param num : the number of bytes into buf
+*/
+typedef int SureWareHook_Rand_Bytes_t(char*const msg,unsigned char *buf, int num);
+extern SW_EXPORT SureWareHook_Rand_Bytes_t SureWareHook_Rand_Bytes;
+
+/*
+* SureWare RAND Seed function
+* Adds some seed to the Hardware Random Number Generator
+* return 1 if success
+* SureWareHOOK_ERROR_FALLBACK if function not available in hardware
+* SureWareHOOK_ERROR_FAILED if error while processing
+* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
+* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
+*
+* in param buf : the seed to add into the HRNG
+* in param num : the number of bytes into buf
+*/
+typedef int SureWareHook_Rand_Seed_t(char*const msg,const void *buf, int num);
+extern SW_EXPORT SureWareHook_Rand_Seed_t SureWareHook_Rand_Seed;
+
+/*
+* SureWare Load Private Key function
+* return 1 if success
+* SureWareHOOK_ERROR_FAILED if error while processing
+* No hardware is contact for this function.
+*
+* in param key_id :the name of the private protected key file without the extension
+ ".sws"
+* out param hptr : a pointer to a buffer allocated by SureWare_Hook
+* out param num: the effective key length in bytes
+* out param keytype: 1 if RSA 2 if DSA
+*/
+typedef int SureWareHook_Load_Privkey_t(char*const msg,const char *key_id,char **hptr,unsigned long *num,char *keytype);
+extern SW_EXPORT SureWareHook_Load_Privkey_t SureWareHook_Load_Privkey;
+
+/*
+* SureWare Info Public Key function
+* return 1 if success
+* SureWareHOOK_ERROR_FAILED if error while processing
+* No hardware is contact for this function.
+*
+* in param key_id :the name of the private protected key file without the extension
+ ".swp"
+* out param hptr : a pointer to a buffer allocated by SureWare_Hook
+* out param num: the effective key length in bytes
+* out param keytype: 1 if RSA 2 if DSA
+*/
+typedef int SureWareHook_Info_Pubkey_t(char*const msg,const char *key_id,unsigned long *num,
+ char *keytype);
+extern SW_EXPORT SureWareHook_Info_Pubkey_t SureWareHook_Info_Pubkey;
+
+/*
+* SureWare Load Public Key function
+* return 1 if success
+* SureWareHOOK_ERROR_FAILED if error while processing
+* No hardware is contact for this function.
+*
+* in param key_id :the name of the public protected key file without the extension
+ ".swp"
+* in param num : the bytes size of n and e
+* out param n: where to write modulus in bn format
+* out param e: where to write exponent in bn format
+*/
+typedef int SureWareHook_Load_Rsa_Pubkey_t(char*const msg,const char *key_id,unsigned long num,
+ unsigned long *n, unsigned long *e);
+extern SW_EXPORT SureWareHook_Load_Rsa_Pubkey_t SureWareHook_Load_Rsa_Pubkey;
+
+/*
+* SureWare Load DSA Public Key function
+* return 1 if success
+* SureWareHOOK_ERROR_FAILED if error while processing
+* No hardware is contact for this function.
+*
+* in param key_id :the name of the public protected key file without the extension
+ ".swp"
+* in param num : the bytes size of n and e
+* out param pub: where to write pub key in bn format
+* out param p: where to write prime in bn format
+* out param q: where to write sunprime (length 20 bytes) in bn format
+* out param g: where to write base in bn format
+*/
+typedef int SureWareHook_Load_Dsa_Pubkey_t(char*const msg,const char *key_id,unsigned long num,
+ unsigned long *pub, unsigned long *p,unsigned long*q,
+ unsigned long *g);
+extern SW_EXPORT SureWareHook_Load_Dsa_Pubkey_t SureWareHook_Load_Dsa_Pubkey;
+
+/*
+* SureWare Free function
+* Destroy the key into the hardware if destroy==1
+*/
+typedef void SureWareHook_Free_t(char *p,int destroy);
+extern SW_EXPORT SureWareHook_Free_t SureWareHook_Free;
+
+#define SUREWARE_PKCS1_PAD 1
+#define SUREWARE_ISO9796_PAD 2
+#define SUREWARE_NO_PAD 0
+/*
+* SureWare RSA Private Decryption
+* return 1 if success
+* SureWareHOOK_ERROR_FAILED if error while processing
+* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
+* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
+*
+* in param flen : byte size of from and to
+* in param from : encrypted data buffer, should be a not-null valid pointer
+* out param tlen: byte size of decrypted data, if error, unexpected value
+* out param to : decrypted data buffer, should be a not-null valid pointer
+* in param prsa: a protected key pointer, should be a not-null valid pointer
+* int padding: padding id as follow
+* SUREWARE_PKCS1_PAD
+* SUREWARE_NO_PAD
+*
+*/
+typedef int SureWareHook_Rsa_Priv_Dec_t(char*const msg,int flen,unsigned char *from,
+ int *tlen,unsigned char *to,
+ char *prsa,int padding);
+extern SW_EXPORT SureWareHook_Rsa_Priv_Dec_t SureWareHook_Rsa_Priv_Dec;
+/*
+* SureWare RSA Signature
+* return 1 if success
+* SureWareHOOK_ERROR_FAILED if error while processing
+* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
+* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
+*
+* in param flen : byte size of from and to
+* in param from : encrypted data buffer, should be a not-null valid pointer
+* out param tlen: byte size of decrypted data, if error, unexpected value
+* out param to : decrypted data buffer, should be a not-null valid pointer
+* in param prsa: a protected key pointer, should be a not-null valid pointer
+* int padding: padding id as follow
+* SUREWARE_PKCS1_PAD
+* SUREWARE_ISO9796_PAD
+*
+*/
+typedef int SureWareHook_Rsa_Sign_t(char*const msg,int flen,unsigned char *from,
+ int *tlen,unsigned char *to,
+ char *prsa,int padding);
+extern SW_EXPORT SureWareHook_Rsa_Sign_t SureWareHook_Rsa_Sign;
+/*
+* SureWare DSA Signature
+* return 1 if success
+* SureWareHOOK_ERROR_FAILED if error while processing
+* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
+* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
+*
+* in param flen : byte size of from and to
+* in param from : encrypted data buffer, should be a not-null valid pointer
+* out param to : decrypted data buffer, should be a 40bytes valid pointer
+* in param pdsa: a protected key pointer, should be a not-null valid pointer
+*
+*/
+typedef int SureWareHook_Dsa_Sign_t(char*const msg,int flen,const unsigned char *from,
+ unsigned long *r,unsigned long *s,char *pdsa);
+extern SW_EXPORT SureWareHook_Dsa_Sign_t SureWareHook_Dsa_Sign;
+
+
+/*
+* SureWare Mod Exp
+* return 1 if success
+* SureWareHOOK_ERROR_FAILED if error while processing
+* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
+* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
+*
+* mod and res are mlen bytes long.
+* exp is elen bytes long
+* data is dlen bytes long
+* mlen,elen and dlen are all multiple of sizeof(unsigned long)
+*/
+typedef int SureWareHook_Mod_Exp_t(char*const msg,int mlen,const unsigned long *mod,
+ int elen,const unsigned long *exponent,
+ int dlen,unsigned long *data,
+ unsigned long *res);
+extern SW_EXPORT SureWareHook_Mod_Exp_t SureWareHook_Mod_Exp;
+