From b64270d1e45fe7f3241e4c9b6ce60d5ac89bc2e9 Mon Sep 17 00:00:00 2001 From: beck <> Date: Wed, 15 May 2002 02:29:21 +0000 Subject: OpenSSL 0.9.7 stable 2002 05 08 merge --- src/lib/libcrypto/engine/Makefile.ssl | 507 ++++++--- src/lib/libcrypto/engine/README | 483 ++++----- src/lib/libcrypto/engine/eng_all.c | 118 +++ src/lib/libcrypto/engine/eng_cnf.c | 242 +++++ src/lib/libcrypto/engine/eng_ctrl.c | 387 +++++++ src/lib/libcrypto/engine/eng_dyn.c | 446 ++++++++ src/lib/libcrypto/engine/eng_err.c | 165 +++ src/lib/libcrypto/engine/eng_fat.c | 148 +++ src/lib/libcrypto/engine/eng_init.c | 158 +++ src/lib/libcrypto/engine/eng_int.h | 185 ++++ src/lib/libcrypto/engine/eng_lib.c | 321 ++++++ src/lib/libcrypto/engine/eng_list.c | 383 +++++++ src/lib/libcrypto/engine/eng_openssl.c | 347 ++++++ src/lib/libcrypto/engine/eng_pkey.c | 157 +++ src/lib/libcrypto/engine/eng_table.c | 361 +++++++ src/lib/libcrypto/engine/engine.h | 653 +++++++++--- src/lib/libcrypto/engine/enginetest.c | 45 +- src/lib/libcrypto/engine/hw.ec | 8 + src/lib/libcrypto/engine/hw_4758_cca.c | 950 +++++++++++++++++ src/lib/libcrypto/engine/hw_4758_cca_err.c | 149 +++ src/lib/libcrypto/engine/hw_4758_cca_err.h | 93 ++ src/lib/libcrypto/engine/hw_aep.c | 1101 ++++++++++++++++++++ src/lib/libcrypto/engine/hw_aep_err.c | 157 +++ src/lib/libcrypto/engine/hw_aep_err.h | 101 ++ src/lib/libcrypto/engine/hw_atalla.c | 283 +++-- src/lib/libcrypto/engine/hw_atalla_err.c | 145 +++ src/lib/libcrypto/engine/hw_atalla_err.h | 89 ++ src/lib/libcrypto/engine/hw_cryptodev.c | 926 ++++++++++++++++ src/lib/libcrypto/engine/hw_cswift.c | 322 ++++-- src/lib/libcrypto/engine/hw_cswift_err.c | 149 +++ src/lib/libcrypto/engine/hw_cswift_err.h | 93 ++ src/lib/libcrypto/engine/hw_ncipher.c | 662 ++++++++---- src/lib/libcrypto/engine/hw_ncipher_err.c | 156 +++ src/lib/libcrypto/engine/hw_ncipher_err.h | 100 ++ src/lib/libcrypto/engine/hw_nuron.c | 399 +++++++ src/lib/libcrypto/engine/hw_nuron_err.c | 142 +++ src/lib/libcrypto/engine/hw_nuron_err.h | 86 ++ src/lib/libcrypto/engine/hw_openbsd_dev_crypto.c | 594 +++++++++++ src/lib/libcrypto/engine/hw_sureware_err.c | 150 +++ src/lib/libcrypto/engine/hw_sureware_err.h | 94 ++ src/lib/libcrypto/engine/hw_ubsec.c | 1041 ++++++++++++++++++ src/lib/libcrypto/engine/hw_ubsec_err.c | 151 +++ src/lib/libcrypto/engine/hw_ubsec_err.h | 95 ++ src/lib/libcrypto/engine/tb_cipher.c | 145 +++ src/lib/libcrypto/engine/tb_dh.c | 120 +++ src/lib/libcrypto/engine/tb_digest.c | 145 +++ src/lib/libcrypto/engine/tb_dsa.c | 120 +++ src/lib/libcrypto/engine/tb_rand.c | 120 +++ src/lib/libcrypto/engine/tb_rsa.c | 120 +++ src/lib/libcrypto/engine/vendor_defns/aep.h | 178 ++++ src/lib/libcrypto/engine/vendor_defns/atalla.h | 13 - src/lib/libcrypto/engine/vendor_defns/cswift.h | 45 +- .../libcrypto/engine/vendor_defns/hw_4758_cca.h | 149 +++ 53 files changed, 13515 insertions(+), 982 deletions(-) create mode 100644 src/lib/libcrypto/engine/eng_all.c create mode 100644 src/lib/libcrypto/engine/eng_cnf.c create mode 100644 src/lib/libcrypto/engine/eng_ctrl.c create mode 100644 src/lib/libcrypto/engine/eng_dyn.c create mode 100644 src/lib/libcrypto/engine/eng_err.c create mode 100644 src/lib/libcrypto/engine/eng_fat.c create mode 100644 src/lib/libcrypto/engine/eng_init.c create mode 100644 src/lib/libcrypto/engine/eng_int.h create mode 100644 src/lib/libcrypto/engine/eng_lib.c create mode 100644 src/lib/libcrypto/engine/eng_list.c create mode 100644 src/lib/libcrypto/engine/eng_openssl.c create mode 100644 src/lib/libcrypto/engine/eng_pkey.c create mode 100644 src/lib/libcrypto/engine/eng_table.c create mode 100644 src/lib/libcrypto/engine/hw.ec create mode 100644 src/lib/libcrypto/engine/hw_4758_cca.c create mode 100644 src/lib/libcrypto/engine/hw_4758_cca_err.c create mode 100644 src/lib/libcrypto/engine/hw_4758_cca_err.h create mode 100644 src/lib/libcrypto/engine/hw_aep.c create mode 100644 src/lib/libcrypto/engine/hw_aep_err.c create mode 100644 src/lib/libcrypto/engine/hw_aep_err.h create mode 100644 src/lib/libcrypto/engine/hw_atalla_err.c create mode 100644 src/lib/libcrypto/engine/hw_atalla_err.h create mode 100644 src/lib/libcrypto/engine/hw_cryptodev.c create mode 100644 src/lib/libcrypto/engine/hw_cswift_err.c create mode 100644 src/lib/libcrypto/engine/hw_cswift_err.h create mode 100644 src/lib/libcrypto/engine/hw_ncipher_err.c create mode 100644 src/lib/libcrypto/engine/hw_ncipher_err.h create mode 100644 src/lib/libcrypto/engine/hw_nuron.c create mode 100644 src/lib/libcrypto/engine/hw_nuron_err.c create mode 100644 src/lib/libcrypto/engine/hw_nuron_err.h create mode 100644 src/lib/libcrypto/engine/hw_openbsd_dev_crypto.c create mode 100644 src/lib/libcrypto/engine/hw_sureware_err.c create mode 100644 src/lib/libcrypto/engine/hw_sureware_err.h create mode 100644 src/lib/libcrypto/engine/hw_ubsec.c create mode 100644 src/lib/libcrypto/engine/hw_ubsec_err.c create mode 100644 src/lib/libcrypto/engine/hw_ubsec_err.h create mode 100644 src/lib/libcrypto/engine/tb_cipher.c create mode 100644 src/lib/libcrypto/engine/tb_dh.c create mode 100644 src/lib/libcrypto/engine/tb_digest.c create mode 100644 src/lib/libcrypto/engine/tb_dsa.c create mode 100644 src/lib/libcrypto/engine/tb_rand.c create mode 100644 src/lib/libcrypto/engine/tb_rsa.c create mode 100644 src/lib/libcrypto/engine/vendor_defns/aep.h create mode 100644 src/lib/libcrypto/engine/vendor_defns/hw_4758_cca.h (limited to 'src/lib/libcrypto/engine') diff --git a/src/lib/libcrypto/engine/Makefile.ssl b/src/lib/libcrypto/engine/Makefile.ssl index d49b7c8159..eeea47fbf5 100644 --- a/src/lib/libcrypto/engine/Makefile.ssl +++ b/src/lib/libcrypto/engine/Makefile.ssl @@ -5,13 +5,14 @@ DIR= engine TOP= ../.. CC= cc -INCLUDES= -I.. -I../../include +INCLUDES= -I.. -I$(TOP) -I../../include CFLAG=-g INSTALL_PREFIX= OPENSSLDIR= /usr/local/ssl INSTALLTOP=/usr/local/ssl MAKE= make -f Makefile.ssl -MAKEDEPEND= $(TOP)/util/domd $(TOP) +MAKEDEPPROG= makedepend +MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG) MAKEFILE= Makefile.ssl AR= ar r @@ -22,10 +23,18 @@ TEST= enginetest.c APPS= LIB=$(TOP)/libcrypto.a -LIBSRC= engine_err.c engine_lib.c engine_list.c engine_openssl.c \ - hw_atalla.c hw_cswift.c hw_ncipher.c -LIBOBJ= engine_err.o engine_lib.o engine_list.o engine_openssl.o \ - hw_atalla.o hw_cswift.o hw_ncipher.o +LIBSRC= eng_err.c eng_lib.c eng_list.c eng_init.c eng_ctrl.c \ + eng_table.c eng_pkey.c eng_fat.c eng_all.c \ + tb_rsa.c tb_dsa.c tb_dh.c tb_rand.c tb_cipher.c tb_digest.c \ + eng_openssl.c eng_dyn.c eng_cnf.c \ + hw_atalla.c hw_cswift.c hw_ncipher.c hw_nuron.c hw_ubsec.c \ + hw_openbsd_dev_crypto.c hw_aep.c hw_sureware.c hw_4758_cca.c +LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \ + eng_table.o eng_pkey.o eng_fat.o eng_all.o \ + tb_rsa.o tb_dsa.o tb_dh.o tb_rand.o tb_cipher.o tb_digest.o \ + eng_openssl.o eng_dyn.o eng_cnf.o \ + hw_atalla.o hw_cswift.o hw_ncipher.o hw_nuron.o hw_ubsec.o \ + hw_openbsd_dev_crypto.o hw_aep.o hw_sureware.o hw_4758_cca.o SRC= $(LIBSRC) @@ -48,7 +57,7 @@ files: $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO links: - @$(SHELL) $(TOP)/util/point.sh Makefile.ssl Makefile + @$(TOP)/util/point.sh Makefile.ssl Makefile @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) @@ -63,6 +72,10 @@ install: tags: ctags $(SRC) +errors: + $(PERL) $(TOP)/util/mkerr.pl -conf hw.ec \ + -nostatic -staticloader -write hw_*.c; \ + tests: lint: @@ -80,141 +93,361 @@ clean: # DO NOT DELETE THIS LINE -- make depend depends on it. -engine_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h -engine_err.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h -engine_err.o: ../../include/openssl/cast.h ../../include/openssl/crypto.h -engine_err.o: ../../include/openssl/des.h ../../include/openssl/dh.h -engine_err.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h -engine_err.o: ../../include/openssl/engine.h ../../include/openssl/err.h -engine_err.o: ../../include/openssl/evp.h ../../include/openssl/idea.h -engine_err.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h -engine_err.o: ../../include/openssl/md4.h ../../include/openssl/md5.h -engine_err.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h -engine_err.o: ../../include/openssl/objects.h -engine_err.o: ../../include/openssl/opensslconf.h -engine_err.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h -engine_err.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h -engine_err.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h -engine_err.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h -engine_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h -engine_err.o: ../../include/openssl/symhacks.h -engine_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h -engine_lib.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h -engine_lib.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h -engine_lib.o: ../../include/openssl/crypto.h ../../include/openssl/des.h -engine_lib.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h -engine_lib.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h -engine_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h -engine_lib.o: ../../include/openssl/evp.h ../../include/openssl/idea.h -engine_lib.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h -engine_lib.o: ../../include/openssl/md4.h ../../include/openssl/md5.h -engine_lib.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h -engine_lib.o: ../../include/openssl/objects.h -engine_lib.o: ../../include/openssl/opensslconf.h -engine_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h -engine_lib.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h -engine_lib.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h -engine_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h -engine_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h -engine_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h -engine_list.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h -engine_list.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h -engine_list.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h -engine_list.o: ../../include/openssl/crypto.h ../../include/openssl/des.h -engine_list.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h -engine_list.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h -engine_list.o: ../../include/openssl/engine.h ../../include/openssl/err.h -engine_list.o: ../../include/openssl/evp.h ../../include/openssl/idea.h -engine_list.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h -engine_list.o: ../../include/openssl/md4.h ../../include/openssl/md5.h -engine_list.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h -engine_list.o: ../../include/openssl/objects.h -engine_list.o: ../../include/openssl/opensslconf.h -engine_list.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h -engine_list.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h -engine_list.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h -engine_list.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h -engine_list.o: ../../include/openssl/sha.h ../../include/openssl/stack.h -engine_list.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h -engine_openssl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h -engine_openssl.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h -engine_openssl.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h -engine_openssl.o: ../../include/openssl/crypto.h ../../include/openssl/des.h -engine_openssl.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h -engine_openssl.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h -engine_openssl.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h -engine_openssl.o: ../../include/openssl/err.h ../../include/openssl/evp.h -engine_openssl.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h -engine_openssl.o: ../../include/openssl/md2.h ../../include/openssl/md4.h -engine_openssl.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h -engine_openssl.o: ../../include/openssl/obj_mac.h -engine_openssl.o: ../../include/openssl/objects.h -engine_openssl.o: ../../include/openssl/opensslconf.h -engine_openssl.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h -engine_openssl.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h -engine_openssl.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h -engine_openssl.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h -engine_openssl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h -engine_openssl.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h -hw_atalla.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h -hw_atalla.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h -hw_atalla.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h -hw_atalla.o: ../../include/openssl/crypto.h ../../include/openssl/des.h +eng_all.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +eng_all.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +eng_all.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +eng_all.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +eng_all.o: ../../include/openssl/err.h ../../include/openssl/lhash.h +eng_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h +eng_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +eng_all.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h +eng_all.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +eng_all.o: ../../include/openssl/ui.h eng_all.c eng_int.h +eng_cnf.o: ../../e_os.h ../../include/openssl/asn1.h +eng_cnf.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +eng_cnf.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h +eng_cnf.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h +eng_cnf.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +eng_cnf.o: ../../include/openssl/engine.h ../../include/openssl/err.h +eng_cnf.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h +eng_cnf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +eng_cnf.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +eng_cnf.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +eng_cnf.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h +eng_cnf.o: ../cryptlib.h eng_cnf.c +eng_ctrl.o: ../../e_os.h ../../include/openssl/asn1.h +eng_ctrl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +eng_ctrl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +eng_ctrl.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +eng_ctrl.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +eng_ctrl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h +eng_ctrl.o: ../../include/openssl/opensslconf.h +eng_ctrl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +eng_ctrl.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +eng_ctrl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +eng_ctrl.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h +eng_ctrl.o: ../cryptlib.h eng_ctrl.c eng_int.h +eng_dyn.o: ../../e_os.h ../../include/openssl/asn1.h +eng_dyn.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +eng_dyn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +eng_dyn.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +eng_dyn.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h +eng_dyn.o: ../../include/openssl/engine.h ../../include/openssl/err.h +eng_dyn.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h +eng_dyn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +eng_dyn.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +eng_dyn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +eng_dyn.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h +eng_dyn.o: ../cryptlib.h eng_dyn.c eng_int.h +eng_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +eng_err.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +eng_err.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +eng_err.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +eng_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h +eng_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h +eng_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +eng_err.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h +eng_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +eng_err.o: ../../include/openssl/ui.h eng_err.c +eng_fat.o: ../../e_os.h ../../include/openssl/asn1.h +eng_fat.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +eng_fat.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h +eng_fat.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h +eng_fat.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +eng_fat.o: ../../include/openssl/engine.h ../../include/openssl/err.h +eng_fat.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h +eng_fat.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +eng_fat.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +eng_fat.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +eng_fat.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h +eng_fat.o: ../cryptlib.h eng_fat.c eng_int.h +eng_init.o: ../../e_os.h ../../include/openssl/asn1.h +eng_init.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +eng_init.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +eng_init.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +eng_init.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +eng_init.o: ../../include/openssl/err.h ../../include/openssl/lhash.h +eng_init.o: ../../include/openssl/opensslconf.h +eng_init.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +eng_init.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +eng_init.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +eng_init.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h +eng_init.o: ../cryptlib.h eng_init.c eng_int.h +eng_lib.o: ../../e_os.h ../../include/openssl/asn1.h +eng_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +eng_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +eng_lib.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +eng_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +eng_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h +eng_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h +eng_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +eng_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h +eng_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +eng_lib.o: ../../include/openssl/ui.h ../cryptlib.h eng_int.h eng_lib.c +eng_list.o: ../../e_os.h ../../include/openssl/asn1.h +eng_list.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +eng_list.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +eng_list.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +eng_list.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +eng_list.o: ../../include/openssl/err.h ../../include/openssl/lhash.h +eng_list.o: ../../include/openssl/opensslconf.h +eng_list.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +eng_list.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +eng_list.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +eng_list.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h +eng_list.o: ../cryptlib.h eng_int.h eng_list.c +eng_openssl.o: ../../e_os.h ../../include/openssl/asn1.h +eng_openssl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +eng_openssl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +eng_openssl.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +eng_openssl.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h +eng_openssl.o: ../../include/openssl/engine.h ../../include/openssl/err.h +eng_openssl.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h +eng_openssl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +eng_openssl.o: ../../include/openssl/opensslconf.h +eng_openssl.o: ../../include/openssl/opensslv.h +eng_openssl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h +eng_openssl.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h +eng_openssl.o: ../../include/openssl/rand.h ../../include/openssl/rc4.h +eng_openssl.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h +eng_openssl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +eng_openssl.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h +eng_openssl.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h +eng_openssl.o: ../cryptlib.h eng_openssl.c +eng_pkey.o: ../../e_os.h ../../include/openssl/asn1.h +eng_pkey.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +eng_pkey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +eng_pkey.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +eng_pkey.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +eng_pkey.o: ../../include/openssl/err.h ../../include/openssl/lhash.h +eng_pkey.o: ../../include/openssl/opensslconf.h +eng_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +eng_pkey.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +eng_pkey.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +eng_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h +eng_pkey.o: ../cryptlib.h eng_int.h eng_pkey.c +eng_table.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +eng_table.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +eng_table.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +eng_table.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +eng_table.o: ../../include/openssl/err.h ../../include/openssl/evp.h +eng_table.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +eng_table.o: ../../include/openssl/objects.h +eng_table.o: ../../include/openssl/opensslconf.h +eng_table.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +eng_table.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +eng_table.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +eng_table.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h +eng_table.o: eng_int.h eng_table.c +hw_4758_cca.o: ../../e_os.h ../../include/openssl/asn1.h +hw_4758_cca.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +hw_4758_cca.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +hw_4758_cca.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +hw_4758_cca.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h +hw_4758_cca.o: ../../include/openssl/engine.h ../../include/openssl/err.h +hw_4758_cca.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h +hw_4758_cca.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +hw_4758_cca.o: ../../include/openssl/opensslconf.h +hw_4758_cca.o: ../../include/openssl/opensslv.h +hw_4758_cca.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h +hw_4758_cca.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +hw_4758_cca.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +hw_4758_cca.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +hw_4758_cca.o: ../../include/openssl/ui.h ../../include/openssl/x509.h +hw_4758_cca.o: ../../include/openssl/x509_vfy.h ../cryptlib.h hw_4758_cca.c +hw_4758_cca.o: hw_4758_cca_err.c hw_4758_cca_err.h vendor_defns/hw_4758_cca.h +hw_aep.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +hw_aep.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +hw_aep.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +hw_aep.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h +hw_aep.o: ../../include/openssl/engine.h ../../include/openssl/err.h +hw_aep.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h +hw_aep.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +hw_aep.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +hw_aep.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +hw_aep.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h hw_aep.c +hw_aep.o: hw_aep_err.c hw_aep_err.h vendor_defns/aep.h +hw_atalla.o: ../../e_os.h ../../include/openssl/asn1.h +hw_atalla.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +hw_atalla.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h hw_atalla.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h -hw_atalla.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h -hw_atalla.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h -hw_atalla.o: ../../include/openssl/err.h ../../include/openssl/evp.h -hw_atalla.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h -hw_atalla.o: ../../include/openssl/md2.h ../../include/openssl/md4.h -hw_atalla.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h -hw_atalla.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h -hw_atalla.o: ../../include/openssl/opensslconf.h -hw_atalla.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h -hw_atalla.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h -hw_atalla.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h -hw_atalla.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h -hw_atalla.o: ../../include/openssl/sha.h ../../include/openssl/stack.h -hw_atalla.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h +hw_atalla.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h +hw_atalla.o: ../../include/openssl/engine.h ../../include/openssl/err.h +hw_atalla.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h +hw_atalla.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +hw_atalla.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +hw_atalla.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +hw_atalla.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h +hw_atalla.o: ../cryptlib.h hw_atalla.c hw_atalla_err.c hw_atalla_err.h hw_atalla.o: vendor_defns/atalla.h -hw_cswift.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h -hw_cswift.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h -hw_cswift.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h -hw_cswift.o: ../../include/openssl/crypto.h ../../include/openssl/des.h +hw_cswift.o: ../../e_os.h ../../include/openssl/asn1.h +hw_cswift.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +hw_cswift.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h hw_cswift.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h -hw_cswift.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h -hw_cswift.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h -hw_cswift.o: ../../include/openssl/err.h ../../include/openssl/evp.h -hw_cswift.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h -hw_cswift.o: ../../include/openssl/md2.h ../../include/openssl/md4.h -hw_cswift.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h -hw_cswift.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h -hw_cswift.o: ../../include/openssl/opensslconf.h -hw_cswift.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h -hw_cswift.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h -hw_cswift.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h -hw_cswift.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h -hw_cswift.o: ../../include/openssl/sha.h ../../include/openssl/stack.h -hw_cswift.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h +hw_cswift.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h +hw_cswift.o: ../../include/openssl/engine.h ../../include/openssl/err.h +hw_cswift.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h +hw_cswift.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +hw_cswift.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +hw_cswift.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +hw_cswift.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h +hw_cswift.o: ../cryptlib.h hw_cswift.c hw_cswift_err.c hw_cswift_err.h hw_cswift.o: vendor_defns/cswift.h -hw_ncipher.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h -hw_ncipher.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h -hw_ncipher.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h -hw_ncipher.o: ../../include/openssl/crypto.h ../../include/openssl/des.h +hw_ncipher.o: ../../e_os.h ../../include/openssl/asn1.h +hw_ncipher.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +hw_ncipher.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h hw_ncipher.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h -hw_ncipher.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h -hw_ncipher.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h -hw_ncipher.o: ../../include/openssl/err.h ../../include/openssl/evp.h -hw_ncipher.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h -hw_ncipher.o: ../../include/openssl/md2.h ../../include/openssl/md4.h -hw_ncipher.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h +hw_ncipher.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h +hw_ncipher.o: ../../include/openssl/engine.h ../../include/openssl/err.h +hw_ncipher.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h hw_ncipher.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h hw_ncipher.o: ../../include/openssl/opensslconf.h -hw_ncipher.o: ../../include/openssl/opensslv.h ../../include/openssl/pem.h -hw_ncipher.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h -hw_ncipher.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h -hw_ncipher.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h -hw_ncipher.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h -hw_ncipher.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h -hw_ncipher.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +hw_ncipher.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +hw_ncipher.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h +hw_ncipher.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h +hw_ncipher.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h +hw_ncipher.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +hw_ncipher.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h hw_ncipher.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h -hw_ncipher.o: ../cryptlib.h engine_int.h vendor_defns/hwcryptohook.h +hw_ncipher.o: ../cryptlib.h hw_ncipher.c hw_ncipher_err.c hw_ncipher_err.h +hw_ncipher.o: vendor_defns/hwcryptohook.h +hw_nuron.o: ../../e_os.h ../../include/openssl/asn1.h +hw_nuron.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +hw_nuron.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +hw_nuron.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +hw_nuron.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h +hw_nuron.o: ../../include/openssl/engine.h ../../include/openssl/err.h +hw_nuron.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h +hw_nuron.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +hw_nuron.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +hw_nuron.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +hw_nuron.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h +hw_nuron.o: ../cryptlib.h hw_nuron.c hw_nuron_err.c hw_nuron_err.h +hw_openbsd_dev_crypto.o: ../../include/openssl/asn1.h +hw_openbsd_dev_crypto.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +hw_openbsd_dev_crypto.o: ../../include/openssl/conf.h +hw_openbsd_dev_crypto.o: ../../include/openssl/crypto.h +hw_openbsd_dev_crypto.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +hw_openbsd_dev_crypto.o: ../../include/openssl/e_os2.h +hw_openbsd_dev_crypto.o: ../../include/openssl/engine.h +hw_openbsd_dev_crypto.o: ../../include/openssl/err.h +hw_openbsd_dev_crypto.o: ../../include/openssl/evp.h +hw_openbsd_dev_crypto.o: ../../include/openssl/lhash.h +hw_openbsd_dev_crypto.o: ../../include/openssl/obj_mac.h +hw_openbsd_dev_crypto.o: ../../include/openssl/objects.h +hw_openbsd_dev_crypto.o: ../../include/openssl/opensslconf.h +hw_openbsd_dev_crypto.o: ../../include/openssl/opensslv.h +hw_openbsd_dev_crypto.o: ../../include/openssl/ossl_typ.h +hw_openbsd_dev_crypto.o: ../../include/openssl/rand.h +hw_openbsd_dev_crypto.o: ../../include/openssl/rsa.h +hw_openbsd_dev_crypto.o: ../../include/openssl/safestack.h +hw_openbsd_dev_crypto.o: ../../include/openssl/stack.h +hw_openbsd_dev_crypto.o: ../../include/openssl/symhacks.h +hw_openbsd_dev_crypto.o: ../../include/openssl/ui.h ../evp/evp_locl.h eng_int.h +hw_openbsd_dev_crypto.o: hw_openbsd_dev_crypto.c +hw_sureware.o: ../../e_os.h ../../include/openssl/asn1.h +hw_sureware.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +hw_sureware.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +hw_sureware.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +hw_sureware.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h +hw_sureware.o: ../../include/openssl/engine.h ../../include/openssl/err.h +hw_sureware.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h +hw_sureware.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +hw_sureware.o: ../../include/openssl/opensslconf.h +hw_sureware.o: ../../include/openssl/opensslv.h +hw_sureware.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h +hw_sureware.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h +hw_sureware.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +hw_sureware.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +hw_sureware.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +hw_sureware.o: ../../include/openssl/ui.h ../../include/openssl/x509.h +hw_sureware.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h +hw_sureware.o: engine.h hw_sureware.c hw_sureware_err.c hw_sureware_err.h +hw_sureware.o: vendor_defns/sureware.h +hw_ubsec.o: ../../e_os.h ../../include/openssl/asn1.h +hw_ubsec.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +hw_ubsec.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +hw_ubsec.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +hw_ubsec.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h +hw_ubsec.o: ../../include/openssl/engine.h ../../include/openssl/err.h +hw_ubsec.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h +hw_ubsec.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +hw_ubsec.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +hw_ubsec.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +hw_ubsec.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h +hw_ubsec.o: ../cryptlib.h hw_ubsec.c hw_ubsec_err.c hw_ubsec_err.h +hw_ubsec.o: vendor_defns/hw_ubsec.h +tb_cipher.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +tb_cipher.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +tb_cipher.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +tb_cipher.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +tb_cipher.o: ../../include/openssl/err.h ../../include/openssl/evp.h +tb_cipher.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +tb_cipher.o: ../../include/openssl/objects.h +tb_cipher.o: ../../include/openssl/opensslconf.h +tb_cipher.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +tb_cipher.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +tb_cipher.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +tb_cipher.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h +tb_cipher.o: eng_int.h tb_cipher.c +tb_dh.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +tb_dh.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +tb_dh.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +tb_dh.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +tb_dh.o: ../../include/openssl/err.h ../../include/openssl/evp.h +tb_dh.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +tb_dh.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +tb_dh.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +tb_dh.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +tb_dh.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +tb_dh.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h eng_int.h +tb_dh.o: tb_dh.c +tb_digest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +tb_digest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +tb_digest.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +tb_digest.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +tb_digest.o: ../../include/openssl/err.h ../../include/openssl/evp.h +tb_digest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +tb_digest.o: ../../include/openssl/objects.h +tb_digest.o: ../../include/openssl/opensslconf.h +tb_digest.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +tb_digest.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +tb_digest.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +tb_digest.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h +tb_digest.o: eng_int.h tb_digest.c +tb_dsa.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +tb_dsa.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +tb_dsa.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +tb_dsa.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +tb_dsa.o: ../../include/openssl/err.h ../../include/openssl/evp.h +tb_dsa.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +tb_dsa.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +tb_dsa.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +tb_dsa.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +tb_dsa.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +tb_dsa.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h eng_int.h +tb_dsa.o: tb_dsa.c +tb_rand.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +tb_rand.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +tb_rand.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +tb_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +tb_rand.o: ../../include/openssl/err.h ../../include/openssl/evp.h +tb_rand.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +tb_rand.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +tb_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +tb_rand.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +tb_rand.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +tb_rand.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h +tb_rand.o: eng_int.h tb_rand.c +tb_rsa.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +tb_rsa.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +tb_rsa.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +tb_rsa.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +tb_rsa.o: ../../include/openssl/err.h ../../include/openssl/evp.h +tb_rsa.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +tb_rsa.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +tb_rsa.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +tb_rsa.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +tb_rsa.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +tb_rsa.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h eng_int.h +tb_rsa.o: tb_rsa.c diff --git a/src/lib/libcrypto/engine/README b/src/lib/libcrypto/engine/README index 96595e6f35..6b69b70f57 100644 --- a/src/lib/libcrypto/engine/README +++ b/src/lib/libcrypto/engine/README @@ -1,278 +1,211 @@ -NOTES, THOUGHTS, and EVERYTHING -------------------------------- - -(1) Concurrency and locking ... I made a change to the ENGINE_free code - because I spotted a potential hold-up in proceedings (doing too - much inside a lock including calling a callback), there may be - other bits like this. What do the speed/optimisation freaks think - of this aspect of the code and design? There's lots of locking for - manipulation functions and I need that to keep things nice and - solid, but this manipulation is mostly (de)initialisation, I would - think that most run-time locking is purely in the ENGINE_init and - ENGINE_finish calls that might be made when getting handles for - RSA (and friends') structures. These would be mostly reference - count operations as the functional references should always be 1 - or greater at run-time to prevent init/deinit thrashing. - -(2) nCipher support, via the HWCryptoHook API, is now in the code. - Apparently this hasn't been tested too much yet, but it looks - good. :-) Atalla support has been added too, but shares a lot in - common with Ben's original hooks in bn_exp.c (although it has been - ENGINE-ified, and error handling wrapped around it) and it's also - had some low-volume testing, so it should be usable. - -(3) Of more concern, we need to work out (a) how to put together usable - RAND_METHODs for units that just have one "get n or less random - bytes" function, (b) we also need to determine how to hook the code - in crypto/rand/ to use the ENGINE defaults in a way similar to what - has been done in crypto/rsa/, crypto/dsa/, etc. - -(4) ENGINE should really grow to encompass more than 3 public key - algorithms and randomness gathering. The structure/data level of - the engine code is hidden from code outside the crypto/engine/ - directory so change shouldn't be too viral. More important though - is how things should evolve ... this needs thought and discussion. - - ------------------------------------==*==----------------------------------- - -More notes 2000-08-01 ---------------------- - -Geoff Thorpe, who designed the engine part, wrote a pretty good description -of the thoughts he had when he built it, good enough to include verbatim here -(with his permission) -- Richard Levitte - - -Date: Tue, 1 Aug 2000 16:54:08 +0100 (BST) -From: Geoff Thorpe -Subject: Re: The thoughts to merge BRANCH_engine into the main trunk are - emerging - -Hi there, - -I'm going to try and do some justice to this, but I'm a little short on -time and the there is an endless amount that could be discussed on this -subject. sigh ... please bear with me :-) - -> The changes in BRANCH_engine dig deep into the core of OpenSSL, for example -> into the RSA and RAND routines, adding a level of indirection which is needed -> to keep the abstraction, as far as I understand. It would be a good thing if -> those who do play with those things took a look at the changes that have been -> done in the branch and say out loud how much (or hopefully little) we've made -> fools of ourselves. - -The point here is that the code that has emerged in the BRANCH_engine -branch was based on some initial requirements of mine that I went in and -addressed, and Richard has picked up the ball and run with it too. It -would be really useful to get some review of the approach we've taken, but -first I think I need to describe as best I can the reasons behind what has -been done so far, in particular what issues we have tried to address when -doing this, and what issues we have intentionally (or necessarily) tried -to avoid. - -methods, engines, and evps --------------------------- - -There has been some dicussion, particularly with Steve, about where this -ENGINE stuff might fit into the conceptual picture as/when we start to -abstract algorithms a little bit to make the library more extensible. In -particular, it would desirable to have algorithms (symmetric, hash, pkc, -etc) abstracted in some way that allows them to be just objects sitting in -a list (or database) ... it'll just happen that the "DSA" object doesn't -support encryption whereas the "RSA" object does. This requires a lot of -consideration to begin to know how to tackle it; in particular how -encapsulated should these things be? If the objects also understand their -own ASN1 encodings and what-not, then it would for example be possible to -add support for elliptic-curve DSA in as a new algorithm and automatically -have ECC-DSA certificates supported in SSL applications. Possible, but not -easy. :-) - -Whatever, it seems that the way to go (if I've grok'd Steve's comments on -this in the past) is to amalgamate these things in EVP as is already done -(I think) for ciphers or hashes (Steve, please correct/elaborate). I -certainly think something should be done in this direction because right -now we have different source directories, types, functions, and methods -for each algorithm - even when conceptually they are very much different -feathers of the same bird. (This is certainly all true for the public-key -stuff, and may be partially true for the other parts.) - -ENGINE was *not* conceived as a way of solving this, far from it. Nor was -it conceived as a way of replacing the various "***_METHOD"s. It was -conceived as an abstraction of a sort of "virtual crypto device". If we -lived in a world where "EVP_ALGO"s (or something like them) encapsulated -particular algorithms like RSA,DSA,MD5,RC4,etc, and "***_METHOD"s -encapsulated interfaces to algorithms (eg. some algo's might support a -PKC_METHOD, a HASH_METHOD, or a CIPHER_METHOD, who knows?), then I would -think that ENGINE would encapsulate an implementation of arbitrarily many -of those algorithms - perhaps as alternatives to existing algorithms -and/or perhaps as new previously unimplemented algorithms. An ENGINE could -be used to contain an alternative software implementation, a wrapper for a -hardware acceleration and/or key-management unit, a comms-wrapper for -distributing cryptographic operations to remote machines, or any other -"devices" your imagination can dream up. - -However, what has been done in the ENGINE branch so far is nothing more -than starting to get our toes wet. I had a couple of self-imposed -requirements when putting the initial abstraction together, and I may have -already posed these in one form or another on the list, but briefly; - - (i) only bother with public key algorithms for now, and maybe RAND too - (motivated by the need to get hardware support going and the fact - this was a comparitively easy subset to address to begin with). - - (ii) don't change (if at all possible) the existing crypto code, ie. the - implementations, the way the ***_METHODs work, etc. - - (iii) ensure that if no function from the ENGINE code is ever called then - things work the way they always did, and there is no memory - allocation (otherwise the failure to cleanup would be a problem - - this is part of the reason no STACKs were used, the other part of - the reason being I found them inappropriate). - - (iv) ensure that all the built-in crypto was encapsulated by one of - these "ENGINE"s and that this engine was automatically selected as - the default. - - (v) provide the minimum hooking possible in the existing crypto code - so that global functions (eg. RSA_public_encrypt) do not need any - extra parameter, yet will use whatever the current default ENGINE - for that RSA key is, and that the default can be set "per-key" - and globally (new keys will assume the global default, and keys - without their own default will be operated on using the global - default). NB: Try and make (v) conflict as little as possible with - (ii). :-) - - (vi) wrap the ENGINE code up in duct tape so you can't even see the - corners. Ie. expose no structures at all, just black-box pointers. - - (v) maintain internally a list of ENGINEs on which a calling - application can iterate, interrogate, etc. Allow a calling - application to hook in new ENGINEs, remove ENGINEs from the list, - and enforce uniqueness within the global list of each ENGINE's - "unique id". - - (vi) keep reference counts for everything - eg. this includes storing a - reference inside each RSA structure to the ENGINE that it uses. - This is freed when the RSA structure is destroyed, or has its - ENGINE explicitly changed. The net effect needs to be that at any - time, it is deterministic to know whether an ENGINE is in use or - can be safely removed (or unloaded in the case of the other type - of reference) without invalidating function pointers that may or - may not be used indavertently in the future. This was actually - one of the biggest problems to overcome in the existing OpenSSL - code - implementations had always been assumed to be ever-present, - so there was no trivial way to get round this. - - (vii) distinguish between structural references and functional - references. - -A *little* detail +Notes: 2001-09-24 ----------------- -While my mind is on it; I'll illustrate the bit in item (vii). This idea -turned out to be very handy - the ENGINEs themselves need to be operated -on and manipulated simply as objects without necessarily trying to -"enable" them for use. Eg. most host machines will not have the necessary -hardware or software to support all the engines one might compile into -OpenSSL, yet it needs to be possible to iterate across the ENGINEs, -querying their names, properties, etc - all happening in a thread-safe -manner that uses reference counts (if you imagine two threads iterating -through a list and one thread removing the ENGINE the other is currently -looking at - you can see the gotcha waiting to happen). For all of this, -*structural references* are used and operate much like the other reference -counts in OpenSSL. - -The other kind of reference count is for *functional* references - these -indicate a reference on which the caller can actually assume the -particular ENGINE to be initialised and usable to perform the operations -it implements. Any increment or decrement of the functional reference -count automatically invokes a corresponding change in the structural -reference count, as it is fairly obvious that a functional reference is a -restricted case of a structural reference. So struct_ref >= funct_ref at -all times. NB: functional references are usually obtained by a call to -ENGINE_init(), but can also be created implicitly by calls that require a -new functional reference to be created, eg. ENGINE_set_default(). Either -way the only time the underlying ENGINE's "init" function is really called -is when the (functional) reference count increases to 1, similarly the -underlying "finish" handler is only called as the count goes down to 0. -The effect of this, for example, is that if you set the default ENGINE for -RSA operations to be "cswift", then its functional reference count will -already be at least 1 so the CryptoSwift shared-library and the card will -stay loaded and initialised until such time as all RSA keys using the -cswift ENGINE are changed or destroyed and the default ENGINE for RSA -operations has been changed. This prevents repeated thrashing of init and -finish handling if the count keeps getting down as far as zero. - -Otherwise, the way the ENGINE code has been put together I think pretty -much reflects the above points. The reason for the ENGINE structure having -individual RSA_METHOD, DSA_METHOD, etc pointers is simply that it was the -easiest way to go about things for now, to hook it all into the raw -RSA,DSA,etc code, and I was trying to the keep the structure invisible -anyway so that the way this is internally managed could be easily changed -later on when we start to work out what's to be done about these other -abstractions. - -Down the line, if some EVP-based technique emerges for adequately -encapsulating algorithms and all their various bits and pieces, then I can -imagine that "ENGINE" would turn into a reference-counting database of -these EVP things, of which the default "openssl" ENGINE would be the -library's own object database of pre-built software implemented algorithms -(and such). It would also be cool to see the idea of "METHOD"s detached -from the algorithms themselves ... so RSA, DSA, ElGamal, etc can all -expose essentially the same METHOD (aka interface), which would include -any querying/flagging stuff to identify what the algorithm can/can't do, -its name, and other stuff like max/min block sizes, key sizes, etc. This -would result in ENGINE similarly detaching its internal database of -algorithm implementations from the function definitions that return -interfaces to them. I think ... - -As for DSOs etc. Well the DSO code is pretty handy (but could be made much -more so) for loading vendor's driver-libraries and talking to them in some -generic way, but right now there's still big problems associated with -actually putting OpenSSL code (ie. new ENGINEs, or anything else for that -matter) in dynamically loadable libraries. These problems won't go away in -a hurry so I don't think we should expect to have any kind of -shared-library extensions any time soon - but solving the problems is a -good thing to aim for, and would as a side-effect probably help make -OpenSSL more usable as a shared-library itself (looking at the things -needed to do this will show you why). - -One of the problems is that if you look at any of the ENGINE -implementations, eg. hw_cswift.c or hw_ncipher.c, you'll see how it needs -a variety of functionality and definitions from various areas of OpenSSL, -including crypto/bn/, crypto/err/, crypto/ itself (locking for example), -crypto/dso/, crypto/engine/, crypto/rsa, etc etc etc. So if similar code -were to be suctioned off into shared libraries, the shared libraries would -either have to duplicate all the definitions and code and avoid loader -conflicts, or OpenSSL would have to somehow expose all that functionality -to the shared-library. If this isn't a big enough problem, the issue of -binary compatibility will be - anyone writing Apache modules can tell you -that (Ralf? Ben? :-). However, I don't think OpenSSL would need to be -quite so forgiving as Apache should be, so OpenSSL could simply tell its -version to the DSO and leave the DSO with the problem of deciding whether -to proceed or bail out for fear of binary incompatibilities. - -Certainly one thing that would go a long way to addressing this is to -embark on a bit of an opaqueness mission. I've set the ENGINE code up with -this in mind - it's so draconian that even to declare your own ENGINE, you -have to get the engine code to create the underlying ENGINE structure, and -then feed in the new ENGINE's function/method pointers through various -"set" functions. The more of the code that takes on such a black-box -approach, the more of the code that will be (a) easy to expose to shared -libraries that need it, and (b) easy to expose to applications wanting to -use OpenSSL itself as a shared-library. From my own explorations in -OpenSSL, the biggest leviathan I've seen that is a problem in this respect -is the BIGNUM code. Trying to "expose" the bignum code through any kind of -organised "METHODs", let alone do all the necessary bignum operations -solely through functions rather than direct access to the structures and -macros, will be a massive pain in the "r"s. - -Anyway, I'm done for now - hope it was readable. Thoughts? - -Cheers, -Geoff - - ------------------------------------==*==----------------------------------- +This "description" (if one chooses to call it that) needed some major updating +so here goes. This update addresses a change being made at the same time to +OpenSSL, and it pretty much completely restructures the underlying mechanics of +the "ENGINE" code. So it serves a double purpose of being a "ENGINE internals +for masochists" document *and* a rather extensive commit log message. (I'd get +lynched for sticking all this in CHANGES or the commit mails :-). + +ENGINE_TABLE underlies this restructuring, as described in the internal header +"eng_int.h", implemented in eng_table.c, and used in each of the "class" files; +tb_rsa.c, tb_dsa.c, etc. + +However, "EVP_CIPHER" underlies the motivation and design of ENGINE_TABLE so +I'll mention a bit about that first. EVP_CIPHER (and most of this applies +equally to EVP_MD for digests) is both a "method" and a algorithm/mode +identifier that, in the current API, "lingers". These cipher description + +implementation structures can be defined or obtained directly by applications, +or can be loaded "en masse" into EVP storage so that they can be catalogued and +searched in various ways, ie. two ways of encrypting with the "des_cbc" +algorithm/mode pair are; + +(i) directly; + const EVP_CIPHER *cipher = EVP_des_cbc(); + EVP_EncryptInit(&ctx, cipher, key, iv); + [ ... use EVP_EncryptUpdate() and EVP_EncryptFinal() ...] + +(ii) indirectly; + OpenSSL_add_all_ciphers(); + cipher = EVP_get_cipherbyname("des_cbc"); + EVP_EncryptInit(&ctx, cipher, key, iv); + [ ... etc ... ] + +The latter is more generally used because it also allows ciphers/digests to be +looked up based on other identifiers which can be useful for automatic cipher +selection, eg. in SSL/TLS, or by user-controllable configuration. + +The important point about this is that EVP_CIPHER definitions and structures are +passed around with impunity and there is no safe way, without requiring massive +rewrites of many applications, to assume that EVP_CIPHERs can be reference +counted. One an EVP_CIPHER is exposed to the caller, neither it nor anything it +comes from can "safely" be destroyed. Unless of course the way of getting to +such ciphers is via entirely distinct API calls that didn't exist before. +However existing API usage cannot be made to understand when an EVP_CIPHER +pointer, that has been passed to the caller, is no longer being used. + +The other problem with the existing API w.r.t. to hooking EVP_CIPHER support +into ENGINE is storage - the OBJ_NAME-based storage used by EVP to register +ciphers simultaneously registers cipher *types* and cipher *implementations* - +they are effectively the same thing, an "EVP_CIPHER" pointer. The problem with +hooking in ENGINEs is that multiple ENGINEs may implement the same ciphers. The +solution is necessarily that ENGINE-provided ciphers simply are not registered, +stored, or exposed to the caller in the same manner as existing ciphers. This is +especially necessary considering the fact ENGINE uses reference counts to allow +for cleanup, modularity, and DSO support - yet EVP_CIPHERs, as exposed to +callers in the current API, support no such controls. + +Another sticking point for integrating cipher support into ENGINE is linkage. +Already there is a problem with the way ENGINE supports RSA, DSA, etc whereby +they are available *because* they're part of a giant ENGINE called "openssl". +Ie. all implementations *have* to come from an ENGINE, but we get round that by +having a giant ENGINE with all the software support encapsulated. This creates +linker hassles if nothing else - linking a 1-line application that calls 2 basic +RSA functions (eg. "RSA_free(RSA_new());") will result in large quantities of +ENGINE code being linked in *and* because of that DSA, DH, and RAND also. If we +continue with this approach for EVP_CIPHER support (even if it *was* possible) +we would lose our ability to link selectively by selectively loading certain +implementations of certain functionality. Touching any part of any kind of +crypto would result in massive static linkage of everything else. So the +solution is to change the way ENGINE feeds existing "classes", ie. how the +hooking to ENGINE works from RSA, DSA, DH, RAND, as well as adding new hooking +for EVP_CIPHER, and EVP_MD. + +The way this is now being done is by mostly reverting back to how things used to +work prior to ENGINE :-). Ie. RSA now has a "RSA_METHOD" pointer again - this +was previously replaced by an "ENGINE" pointer and all RSA code that required +the RSA_METHOD would call ENGINE_get_RSA() each time on its ENGINE handle to +temporarily get and use the ENGINE's RSA implementation. Apart from being more +efficient, switching back to each RSA having an RSA_METHOD pointer also allows +us to conceivably operate with *no* ENGINE. As we'll see, this removes any need +for a fallback ENGINE that encapsulates default implementations - we can simply +have our RSA structure pointing its RSA_METHOD pointer to the software +implementation and have its ENGINE pointer set to NULL. + +A look at the EVP_CIPHER hooking is most explanatory, the RSA, DSA (etc) cases +turn out to be degenerate forms of the same thing. The EVP storage of ciphers, +and the existing EVP API functions that return "software" implementations and +descriptions remain untouched. However, the storage takes more meaning in terms +of "cipher description" and less meaning in terms of "implementation". When an +EVP_CIPHER_CTX is actually initialised with an EVP_CIPHER method and is about to +begin en/decryption, the hooking to ENGINE comes into play. What happens is that +cipher-specific ENGINE code is asked for an ENGINE pointer (a functional +reference) for any ENGINE that is registered to perform the algo/mode that the +provided EVP_CIPHER structure represents. Under normal circumstances, that +ENGINE code will return NULL because no ENGINEs will have had any cipher +implementations *registered*. As such, a NULL ENGINE pointer is stored in the +EVP_CIPHER_CTX context, and the EVP_CIPHER structure is left hooked into the +context and so is used as the implementation. Pretty much how things work now +except we'd have a redundant ENGINE pointer set to NULL and doing nothing. + +Conversely, if an ENGINE *has* been registered to perform the algorithm/mode +combination represented by the provided EVP_CIPHER, then a functional reference +to that ENGINE will be returned to the EVP_CIPHER_CTX during initialisation. +That functional reference will be stored in the context (and released on +cleanup) - and having that reference provides a *safe* way to use an EVP_CIPHER +definition that is private to the ENGINE. Ie. the EVP_CIPHER provided by the +application will actually be replaced by an EVP_CIPHER from the registered +ENGINE - it will support the same algorithm/mode as the original but will be a +completely different implementation. Because this EVP_CIPHER isn't stored in the +EVP storage, nor is it returned to applications from traditional API functions, +there is no associated problem with it not having reference counts. And of +course, when one of these "private" cipher implementations is hooked into +EVP_CIPHER_CTX, it is done whilst the EVP_CIPHER_CTX holds a functional +reference to the ENGINE that owns it, thus the use of the ENGINE's EVP_CIPHER is +safe. + +The "cipher-specific ENGINE code" I mentioned is implemented in tb_cipher.c but +in essence it is simply an instantiation of "ENGINE_TABLE" code for use by +EVP_CIPHER code. tb_digest.c is virtually identical but, of course, it is for +use by EVP_MD code. Ditto for tb_rsa.c, tb_dsa.c, etc. These instantiations of +ENGINE_TABLE essentially provide linker-separation of the classes so that even +if ENGINEs implement *all* possible algorithms, an application using only +EVP_CIPHER code will link at most code relating to EVP_CIPHER, tb_cipher.c, core +ENGINE code that is independant of class, and of course the ENGINE +implementation that the application loaded. It will *not* however link any +class-specific ENGINE code for digests, RSA, etc nor will it bleed over into +other APIs, such as the RSA/DSA/etc library code. + +ENGINE_TABLE is a little more complicated than may seem necessary but this is +mostly to avoid a lot of "init()"-thrashing on ENGINEs (that may have to load +DSOs, and other expensive setup that shouldn't be thrashed unnecessarily) *and* +to duplicate "default" behaviour. Basically an ENGINE_TABLE instantiation, for +example tb_cipher.c, implements a hash-table keyed by integer "nid" values. +These nids provide the uniquenness of an algorithm/mode - and each nid will hash +to a potentially NULL "ENGINE_PILE". An ENGINE_PILE is essentially a list of +pointers to ENGINEs that implement that particular 'nid'. Each "pile" uses some +caching tricks such that requests on that 'nid' will be cached and all future +requests will return immediately (well, at least with minimal operation) unless +a change is made to the pile, eg. perhaps an ENGINE was unloaded. The reason is +that an application could have support for 10 ENGINEs statically linked +in, and the machine in question may not have any of the hardware those 10 +ENGINEs support. If each of those ENGINEs has a "des_cbc" implementation, we +want to avoid every EVP_CIPHER_CTX setup from trying (and failing) to initialise +each of those 10 ENGINEs. Instead, the first such request will try to do that +and will either return (and cache) a NULL ENGINE pointer or will return a +functional reference to the first that successfully initialised. In the latter +case it will also cache an extra functional reference to the ENGINE as a +"default" for that 'nid'. The caching is acknowledged by a 'uptodate' variable +that is unset only if un/registration takes place on that pile. Ie. if +implementations of "des_cbc" are added or removed. This behaviour can be +tweaked; the ENGINE_TABLE_FLAG_NOINIT value can be passed to +ENGINE_set_table_flags(), in which case the only ENGINEs that tb_cipher.c will +try to initialise from the "pile" will be those that are already initialised +(ie. it's simply an increment of the functional reference count, and no real +"initialisation" will take place). + +RSA, DSA, DH, and RAND all have their own ENGINE_TABLE code as well, and the +difference is that they all use an implicit 'nid' of 1. Whereas EVP_CIPHERs are +actually qualitatively different depending on 'nid' (the "des_cbc" EVP_CIPHER is +not an interoperable implementation of "aes_256_cbc"), RSA_METHODs are +necessarily interoperable and don't have different flavours, only different +implementations. In other words, the ENGINE_TABLE for RSA will either be empty, +or will have a single ENGING_PILE hashed to by the 'nid' 1 and that pile +represents ENGINEs that implement the single "type" of RSA there is. + +Cleanup - the registration and unregistration may pose questions about how +cleanup works with the ENGINE_PILE doing all this caching nonsense (ie. when the +application or EVP_CIPHER code releases its last reference to an ENGINE, the +ENGINE_PILE code may still have references and thus those ENGINEs will stay +hooked in forever). The way this is handled is via "unregistration". With these +new ENGINE changes, an abstract ENGINE can be loaded and initialised, but that +is an algorithm-agnostic process. Even if initialised, it will not have +registered any of its implementations (to do so would link all class "table" +code despite the fact the application may use only ciphers, for example). This +is deliberately a distinct step. Moreover, registration and unregistration has +nothing to do with whether an ENGINE is *functional* or not (ie. you can even +register an ENGINE and its implementations without it being operational, you may +not even have the drivers to make it operate). What actually happens with +respect to cleanup is managed inside eng_lib.c with the "engine_cleanup_***" +functions. These functions are internal-only and each part of ENGINE code that +could require cleanup will, upon performing its first allocation, register a +callback with the "engine_cleanup" code. The other part of this that makes it +tick is that the ENGINE_TABLE instantiations (tb_***.c) use NULL as their +initialised state. So if RSA code asks for an ENGINE and no ENGINE has +registered an implementation, the code will simply return NULL and the tb_rsa.c +state will be unchanged. Thus, no cleanup is required unless registration takes +place. ENGINE_cleanup() will simply iterate across a list of registered cleanup +callbacks calling each in turn, and will then internally delete its own storage +(a STACK). When a cleanup callback is next registered (eg. if the cleanup() is +part of a gracefull restart and the application wants to cleanup all state then +start again), the internal STACK storage will be freshly allocated. This is much +the same as the situation in the ENGINE_TABLE instantiations ... NULL is the +initialised state, so only modification operations (not queries) will cause that +code to have to register a cleanup. + +What else? The bignum callbacks and associated ENGINE functions have been +removed for two obvious reasons; (i) there was no way to generalise them to the +mechanism now used by RSA/DSA/..., because there's no such thing as a BIGNUM +method, and (ii) because of (i), there was no meaningful way for library or +application code to automatically hook and use ENGINE supplied bignum functions +anyway. Also, ENGINE_cpy() has been removed (although an internal-only version +exists) - the idea of providing an ENGINE_cpy() function probably wasn't a good +one and now certainly doesn't make sense in any generalised way. Some of the +RSA, DSA, DH, and RAND functions that were fiddled during the original ENGINE +changes have now, as a consequence, been reverted back. This is because the +hooking of ENGINE is now automatic (and passive, it can interally use a NULL +ENGINE pointer to simply ignore ENGINE from then on). + +Hell, that should be enough for now ... comments welcome: geoff@openssl.org diff --git a/src/lib/libcrypto/engine/eng_all.c b/src/lib/libcrypto/engine/eng_all.c new file mode 100644 index 0000000000..a35b3db9e8 --- /dev/null +++ b/src/lib/libcrypto/engine/eng_all.c @@ -0,0 +1,118 @@ +/* crypto/engine/eng_all.c -*- mode: C; c-file-style: "eay" -*- */ +/* Written by Richard Levitte for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * 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 +#include +#include "eng_int.h" + +#ifdef __OpenBSD__ +static int openbsd_default_loaded = 0; +#endif + +void ENGINE_load_builtin_engines(void) + { + /* There's no longer any need for an "openssl" ENGINE unless, one day, + * it is the *only* way for standard builtin implementations to be be + * accessed (ie. it would be possible to statically link binaries with + * *no* builtin implementations). */ +#if 0 + ENGINE_load_openssl(); +#endif + ENGINE_load_dynamic(); +#ifndef OPENSSL_NO_HW +#ifndef OPENSSL_NO_HW_CSWIFT + ENGINE_load_cswift(); +#endif +#ifndef OPENSSL_NO_HW_NCIPHER + ENGINE_load_chil(); +#endif +#ifndef OPENSSL_NO_HW_ATALLA + ENGINE_load_atalla(); +#endif +#ifndef OPENSSL_NO_HW_NURON + ENGINE_load_nuron(); +#endif +#ifndef OPENSSL_NO_HW_UBSEC + ENGINE_load_ubsec(); +#endif +#ifndef OPENSSL_NO_HW_AEP + ENGINE_load_aep(); +#endif +#ifndef OPENSSL_NO_HW_SUREWARE + ENGINE_load_sureware(); +#endif +#ifdef OPENSSL_OPENBSD_DEV_CRYPTO + ENGINE_load_openbsd_dev_crypto(); +#endif +#ifdef __OpenBSD__ + ENGINE_load_cryptodev(); +#endif +#endif + } + +#ifdef __OpenBSD__ +void ENGINE_setup_openbsd(void) { + if (!openbsd_default_loaded) { + ENGINE_load_cryptodev(); + ENGINE_register_all_complete(); + } + openbsd_default_loaded=1; +} +#endif + + diff --git a/src/lib/libcrypto/engine/eng_cnf.c b/src/lib/libcrypto/engine/eng_cnf.c new file mode 100644 index 0000000000..8c0ae8a1ad --- /dev/null +++ b/src/lib/libcrypto/engine/eng_cnf.c @@ -0,0 +1,242 @@ +/* eng_cnf.c */ +/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * 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 + * 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 +#include +#include "cryptlib.h" +#include +#include + +/* #define ENGINE_CONF_DEBUG */ + +/* ENGINE config module */ + +static char *skip_dot(char *name) + { + char *p; + p = strchr(name, '.'); + if (p) + return p + 1; + return name; + } + +static STACK_OF(ENGINE) *initialized_engines = NULL; + +static int int_engine_init(ENGINE *e) + { + if (!ENGINE_init(e)) + return 0; + if (!initialized_engines) + initialized_engines = sk_ENGINE_new_null(); + if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e)) + { + ENGINE_finish(e); + return 0; + } + return 1; + } + + +int int_engine_configure(char *name, char *value, const CONF *cnf) + { + int i; + int ret = 0; + long do_init = -1; + STACK_OF(CONF_VALUE) *ecmds; + CONF_VALUE *ecmd; + char *ctrlname, *ctrlvalue; + ENGINE *e = NULL; + name = skip_dot(name); +#ifdef ENGINE_CONF_DEBUG + fprintf(stderr, "Configuring engine %s\n", name); +#endif + /* Value is a section containing ENGINE commands */ + ecmds = NCONF_get_section(cnf, value); + + if (!ecmds) + { + ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_SECTION_ERROR); + return 0; + } + + for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++) + { + ecmd = sk_CONF_VALUE_value(ecmds, i); + ctrlname = skip_dot(ecmd->name); + ctrlvalue = ecmd->value; +#ifdef ENGINE_CONF_DEBUG + fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname, ctrlvalue); +#endif + + /* First handle some special pseudo ctrls */ + + /* Override engine name to use */ + if (!strcmp(ctrlname, "engine_id")) + name = ctrlvalue; + /* Load a dynamic ENGINE */ + else if (!strcmp(ctrlname, "dynamic_path")) + { + e = ENGINE_by_id("dynamic"); + if (!e) + goto err; + if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0)) + goto err; + if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0)) + goto err; + if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) + goto err; + } + /* ... add other pseudos here ... */ + else + { + /* At this point we need an ENGINE structural reference + * if we don't already have one. + */ + if (!e) + { + e = ENGINE_by_id(name); + if (!e) + return 0; + } + /* Allow "EMPTY" to mean no value: this allows a valid + * "value" to be passed to ctrls of type NO_INPUT + */ + if (!strcmp(ctrlvalue, "EMPTY")) + ctrlvalue = NULL; + else if (!strcmp(ctrlname, "init")) + { + if (!NCONF_get_number_e(cnf, value, "init", &do_init)) + goto err; + if (do_init == 1) + { + if (!int_engine_init(e)) + goto err; + } + else if (do_init != 0) + { + ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_INVALID_INIT_VALUE); + goto err; + } + } + else if (!strcmp(ctrlname, "default_algorithms")) + { + if (!ENGINE_set_default_string(e, ctrlvalue)) + goto err; + } + else if (!ENGINE_ctrl_cmd_string(e, + ctrlname, ctrlvalue, 0)) + return 0; + } + + + + } + if (e && (do_init == -1) && !int_engine_init(e)) + goto err; + ret = 1; + err: + if (e) + ENGINE_free(e); + return ret; + } + + +static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf) + { + STACK_OF(CONF_VALUE) *elist; + CONF_VALUE *cval; + int i; +#ifdef ENGINE_CONF_DEBUG + fprintf(stderr, "Called engine module: name %s, value %s\n", + CONF_imodule_get_name(md), CONF_imodule_get_value(md)); +#endif + /* Value is a section containing ENGINEs to configure */ + elist = NCONF_get_section(cnf, CONF_imodule_get_value(md)); + + if (!elist) + { + ENGINEerr(ENGINE_F_ENGINE_MODULE_INIT, ENGINE_R_ENGINES_SECTION_ERROR); + return 0; + } + + for (i = 0; i < sk_CONF_VALUE_num(elist); i++) + { + cval = sk_CONF_VALUE_value(elist, i); + if (!int_engine_configure(cval->name, cval->value, cnf)) + return 0; + } + + return 1; + } + +static void int_engine_module_finish(CONF_IMODULE *md) + { + ENGINE *e; + while ((e = sk_ENGINE_pop(initialized_engines))) + ENGINE_finish(e); + sk_ENGINE_free(initialized_engines); + initialized_engines = NULL; + } + + +void ENGINE_add_conf_module(void) + { + CONF_module_add("engines", + int_engine_module_init, + int_engine_module_finish); + } diff --git a/src/lib/libcrypto/engine/eng_ctrl.c b/src/lib/libcrypto/engine/eng_ctrl.c new file mode 100644 index 0000000000..ad3858395b --- /dev/null +++ b/src/lib/libcrypto/engine/eng_ctrl.c @@ -0,0 +1,387 @@ +/* crypto/engine/eng_ctrl.c */ +/* ==================================================================== + * 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 +#include "cryptlib.h" +#include "eng_int.h" +#include + +/* When querying a ENGINE-specific control command's 'description', this string + * is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. */ +static const char *int_no_description = ""; + +/* These internal functions handle 'CMD'-related control commands when the + * ENGINE in question has asked us to take care of it (ie. the ENGINE did not + * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. */ + +static int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn) + { + if((defn->cmd_num == 0) || (defn->cmd_name == NULL)) + return 1; + return 0; + } + +static int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s) + { + int idx = 0; + while(!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0)) + { + idx++; + defn++; + } + if(int_ctrl_cmd_is_null(defn)) + /* The given name wasn't found */ + return -1; + return idx; + } + +static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num) + { + int idx = 0; + /* NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So + * our searches don't need to take any longer than necessary. */ + while(!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num)) + { + idx++; + defn++; + } + if(defn->cmd_num == num) + return idx; + /* The given cmd_num wasn't found */ + return -1; + } + +static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, void (*f)()) + { + int idx; + char *s = (char *)p; + /* Take care of the easy one first (eg. it requires no searches) */ + if(cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE) + { + if((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns)) + return 0; + return e->cmd_defns->cmd_num; + } + /* One or two commands require that "p" be a valid string buffer */ + if((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) || + (cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) || + (cmd == ENGINE_CTRL_GET_DESC_FROM_CMD)) + { + if(s == NULL) + { + ENGINEerr(ENGINE_F_INT_CTRL_HELPER, + ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + } + /* Now handle cmd_name -> cmd_num conversion */ + if(cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) + { + if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_name( + e->cmd_defns, s)) < 0)) + { + ENGINEerr(ENGINE_F_INT_CTRL_HELPER, + ENGINE_R_INVALID_CMD_NAME); + return -1; + } + return e->cmd_defns[idx].cmd_num; + } + /* For the rest of the commands, the 'long' argument must specify a + * valie command number - so we need to conduct a search. */ + if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns, + (unsigned int)i)) < 0)) + { + ENGINEerr(ENGINE_F_INT_CTRL_HELPER, + ENGINE_R_INVALID_CMD_NUMBER); + return -1; + } + /* Now the logic splits depending on command type */ + switch(cmd) + { + case ENGINE_CTRL_GET_NEXT_CMD_TYPE: + idx++; + if(int_ctrl_cmd_is_null(e->cmd_defns + idx)) + /* end-of-list */ + return 0; + else + return e->cmd_defns[idx].cmd_num; + case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD: + return strlen(e->cmd_defns[idx].cmd_name); + case ENGINE_CTRL_GET_NAME_FROM_CMD: + return sprintf(s, "%s", e->cmd_defns[idx].cmd_name); + case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD: + if(e->cmd_defns[idx].cmd_desc) + return strlen(e->cmd_defns[idx].cmd_desc); + return strlen(int_no_description); + case ENGINE_CTRL_GET_DESC_FROM_CMD: + if(e->cmd_defns[idx].cmd_desc) + return sprintf(s, "%s", e->cmd_defns[idx].cmd_desc); + return sprintf(s, "%s", int_no_description); + case ENGINE_CTRL_GET_CMD_FLAGS: + return e->cmd_defns[idx].cmd_flags; + } + /* Shouldn't really be here ... */ + ENGINEerr(ENGINE_F_INT_CTRL_HELPER,ENGINE_R_INTERNAL_LIST_ERROR); + return -1; + } + +int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) + { + int ctrl_exists, ref_exists; + if(e == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_CTRL,ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + ref_exists = ((e->struct_ref > 0) ? 1 : 0); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + ctrl_exists = ((e->ctrl == NULL) ? 0 : 1); + if(!ref_exists) + { + ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_REFERENCE); + return 0; + } + /* Intercept any "root-level" commands before trying to hand them on to + * ctrl() handlers. */ + switch(cmd) + { + case ENGINE_CTRL_HAS_CTRL_FUNCTION: + return ctrl_exists; + case ENGINE_CTRL_GET_FIRST_CMD_TYPE: + case ENGINE_CTRL_GET_NEXT_CMD_TYPE: + case ENGINE_CTRL_GET_CMD_FROM_NAME: + case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD: + case ENGINE_CTRL_GET_NAME_FROM_CMD: + case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD: + case ENGINE_CTRL_GET_DESC_FROM_CMD: + case ENGINE_CTRL_GET_CMD_FLAGS: + if(ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL)) + return int_ctrl_helper(e,cmd,i,p,f); + if(!ctrl_exists) + { + ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION); + /* For these cmd-related functions, failure is indicated + * by a -1 return value (because 0 is used as a valid + * return in some places). */ + return -1; + } + default: + break; + } + /* Anything else requires a ctrl() handler to exist. */ + if(!ctrl_exists) + { + ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION); + return 0; + } + return e->ctrl(e, cmd, i, p, f); + } + +int ENGINE_cmd_is_executable(ENGINE *e, int cmd) + { + int flags; + if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0) + { + ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE, + ENGINE_R_INVALID_CMD_NUMBER); + return 0; + } + if(!(flags & ENGINE_CMD_FLAG_NO_INPUT) && + !(flags & ENGINE_CMD_FLAG_NUMERIC) && + !(flags & ENGINE_CMD_FLAG_STRING)) + return 0; + return 1; + } + +int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, + long i, void *p, void (*f)(), int cmd_optional) + { + int num; + + if((e == NULL) || (cmd_name == NULL)) + { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e, + ENGINE_CTRL_GET_CMD_FROM_NAME, + 0, (void *)cmd_name, NULL)) <= 0)) + { + /* If the command didn't *have* to be supported, we fake + * success. This allows certain settings to be specified for + * multiple ENGINEs and only require a change of ENGINE id + * (without having to selectively apply settings). Eg. changing + * from a hardware device back to the regular software ENGINE + * without editing the config file, etc. */ + if(cmd_optional) + { + ERR_clear_error(); + return 1; + } + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD, + ENGINE_R_INVALID_CMD_NAME); + return 0; + } + /* Force the result of the control command to 0 or 1, for the reasons + * mentioned before. */ + if (ENGINE_ctrl(e, num, i, p, f)) + return 1; + return 0; + } + +int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, + int cmd_optional) + { + int num, flags; + long l; + char *ptr; + if((e == NULL) || (cmd_name == NULL)) + { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e, + ENGINE_CTRL_GET_CMD_FROM_NAME, + 0, (void *)cmd_name, NULL)) <= 0)) + { + /* If the command didn't *have* to be supported, we fake + * success. This allows certain settings to be specified for + * multiple ENGINEs and only require a change of ENGINE id + * (without having to selectively apply settings). Eg. changing + * from a hardware device back to the regular software ENGINE + * without editing the config file, etc. */ + if(cmd_optional) + { + ERR_clear_error(); + return 1; + } + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_INVALID_CMD_NAME); + return 0; + } + if(!ENGINE_cmd_is_executable(e, num)) + { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_CMD_NOT_EXECUTABLE); + return 0; + } + if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL)) < 0) + { + /* Shouldn't happen, given that ENGINE_cmd_is_executable() + * returned success. */ + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_INTERNAL_LIST_ERROR); + return 0; + } + /* If the command takes no input, there must be no input. And vice + * versa. */ + if(flags & ENGINE_CMD_FLAG_NO_INPUT) + { + if(arg != NULL) + { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_COMMAND_TAKES_NO_INPUT); + return 0; + } + /* We deliberately force the result of ENGINE_ctrl() to 0 or 1 + * rather than returning it as "return data". This is to ensure + * usage of these commands is consistent across applications and + * that certain applications don't understand it one way, and + * others another. */ + if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL)) + return 1; + return 0; + } + /* So, we require input */ + if(arg == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_COMMAND_TAKES_INPUT); + return 0; + } + /* If it takes string input, that's easy */ + if(flags & ENGINE_CMD_FLAG_STRING) + { + /* Same explanation as above */ + if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL)) + return 1; + return 0; + } + /* If it doesn't take numeric either, then it is unsupported for use in + * a config-setting situation, which is what this function is for. This + * should never happen though, because ENGINE_cmd_is_executable() was + * used. */ + if(!(flags & ENGINE_CMD_FLAG_NUMERIC)) + { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_INTERNAL_LIST_ERROR); + return 0; + } + l = strtol(arg, &ptr, 10); + if((arg == ptr) || (*ptr != '\0')) + { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER); + return 0; + } + /* Force the result of the control command to 0 or 1, for the reasons + * mentioned before. */ + if(ENGINE_ctrl(e, num, l, NULL, NULL)) + return 1; + return 0; + } diff --git a/src/lib/libcrypto/engine/eng_dyn.c b/src/lib/libcrypto/engine/eng_dyn.c new file mode 100644 index 0000000000..4fefcc0cae --- /dev/null +++ b/src/lib/libcrypto/engine/eng_dyn.c @@ -0,0 +1,446 @@ +/* crypto/engine/eng_dyn.c */ +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * 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 +#include +#include "cryptlib.h" +#include "eng_int.h" +#include +#include + +/* Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE loader + * should implement the hook-up functions with the following prototypes. */ + +/* Our ENGINE handlers */ +static int dynamic_init(ENGINE *e); +static int dynamic_finish(ENGINE *e); +static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); +/* Predeclare our context type */ +typedef struct st_dynamic_data_ctx dynamic_data_ctx; +/* The implementation for the important control command */ +static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx); + +#define DYNAMIC_CMD_SO_PATH ENGINE_CMD_BASE +#define DYNAMIC_CMD_NO_VCHECK (ENGINE_CMD_BASE + 1) +#define DYNAMIC_CMD_ID (ENGINE_CMD_BASE + 2) +#define DYNAMIC_CMD_LIST_ADD (ENGINE_CMD_BASE + 3) +#define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 4) + +/* The constants used when creating the ENGINE */ +static const char *engine_dynamic_id = "dynamic"; +static const char *engine_dynamic_name = "Dynamic engine loading support"; +static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = { + {DYNAMIC_CMD_SO_PATH, + "SO_PATH", + "Specifies the path to the new ENGINE shared library", + ENGINE_CMD_FLAG_STRING}, + {DYNAMIC_CMD_NO_VCHECK, + "NO_VCHECK", + "Specifies to continue even if version checking fails (boolean)", + ENGINE_CMD_FLAG_NUMERIC}, + {DYNAMIC_CMD_ID, + "ID", + "Specifies an ENGINE id name for loading", + ENGINE_CMD_FLAG_STRING}, + {DYNAMIC_CMD_LIST_ADD, + "LIST_ADD", + "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)", + ENGINE_CMD_FLAG_NUMERIC}, + {DYNAMIC_CMD_LOAD, + "LOAD", + "Load up the ENGINE specified by other settings", + ENGINE_CMD_FLAG_NO_INPUT}, + {0, NULL, NULL, 0} + }; +static const ENGINE_CMD_DEFN dynamic_cmd_defns_empty[] = { + {0, NULL, NULL, 0} + }; + +/* Loading code stores state inside the ENGINE structure via the "ex_data" + * element. We load all our state into a single structure and use that as a + * single context in the "ex_data" stack. */ +struct st_dynamic_data_ctx + { + /* The DSO object we load that supplies the ENGINE code */ + DSO *dynamic_dso; + /* The function pointer to the version checking shared library function */ + dynamic_v_check_fn v_check; + /* The function pointer to the engine-binding shared library function */ + dynamic_bind_engine bind_engine; + /* The default name/path for loading the shared library */ + const char *DYNAMIC_LIBNAME; + /* Whether to continue loading on a version check failure */ + int no_vcheck; + /* If non-NULL, stipulates the 'id' of the ENGINE to be loaded */ + const char *engine_id; + /* If non-zero, a successfully loaded ENGINE should be added to the internal + * ENGINE list. If 2, the add must succeed or the entire load should fail. */ + int list_add_value; + /* The symbol name for the version checking function */ + const char *DYNAMIC_F1; + /* The symbol name for the "initialise ENGINE structure" function */ + const char *DYNAMIC_F2; + }; + +/* This is the "ex_data" index we obtain and reserve for use with our context + * structure. */ +static int dynamic_ex_data_idx = -1; + +/* Because our ex_data element may or may not get allocated depending on whether + * a "first-use" occurs before the ENGINE is freed, we have a memory leak + * problem to solve. We can't declare a "new" handler for the ex_data as we + * don't want a dynamic_data_ctx in *all* ENGINE structures of all types (this + * is a bug in the design of CRYPTO_EX_DATA). As such, we just declare a "free" + * handler and that will get called if an ENGINE is being destroyed and there + * was an ex_data element corresponding to our context type. */ +static void dynamic_data_ctx_free_func(void *parent, void *ptr, + CRYPTO_EX_DATA *ad, int idx, long argl, void *argp) + { + if(ptr) + { + dynamic_data_ctx *ctx = (dynamic_data_ctx *)ptr; + if(ctx->dynamic_dso) + DSO_free(ctx->dynamic_dso); + OPENSSL_free(ctx); + } + } + +/* Construct the per-ENGINE context. We create it blindly and then use a lock to + * check for a race - if so, all but one of the threads "racing" will have + * wasted their time. The alternative involves creating everything inside the + * lock which is far worse. */ +static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx) + { + dynamic_data_ctx *c; + c = OPENSSL_malloc(sizeof(dynamic_data_ctx)); + if(!ctx) + { + ENGINEerr(ENGINE_F_SET_DATA_CTX,ERR_R_MALLOC_FAILURE); + return 0; + } + memset(c, 0, sizeof(dynamic_data_ctx)); + c->dynamic_dso = NULL; + c->v_check = NULL; + c->bind_engine = NULL; + c->DYNAMIC_LIBNAME = NULL; + c->no_vcheck = 0; + c->engine_id = NULL; + c->list_add_value = 0; + c->DYNAMIC_F1 = "v_check"; + c->DYNAMIC_F2 = "bind_engine"; + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, + dynamic_ex_data_idx)) == NULL) + { + /* Good, we're the first */ + ENGINE_set_ex_data(e, dynamic_ex_data_idx, c); + *ctx = c; + c = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + /* If we lost the race to set the context, c is non-NULL and *ctx is the + * context of the thread that won. */ + if(c) + OPENSSL_free(c); + return 1; + } + +/* This function retrieves the context structure from an ENGINE's "ex_data", or + * if it doesn't exist yet, sets it up. */ +static dynamic_data_ctx *dynamic_get_data_ctx(ENGINE *e) + { + dynamic_data_ctx *ctx; + if(dynamic_ex_data_idx < 0) + { + /* Create and register the ENGINE ex_data, and associate our + * "free" function with it to ensure any allocated contexts get + * freed when an ENGINE goes underground. */ + int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, + dynamic_data_ctx_free_func); + if(new_idx == -1) + { + ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX,ENGINE_R_NO_INDEX); + return NULL; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + /* Avoid a race by checking again inside this lock */ + if(dynamic_ex_data_idx < 0) + { + /* Good, someone didn't beat us to it */ + dynamic_ex_data_idx = new_idx; + new_idx = -1; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + /* In theory we could "give back" the index here if + * (new_idx>-1), but it's not possible and wouldn't gain us much + * if it were. */ + } + ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx); + /* Check if the context needs to be created */ + if((ctx == NULL) && !dynamic_set_data_ctx(e, &ctx)) + /* "set_data" will set errors if necessary */ + return NULL; + return ctx; + } + +static ENGINE *engine_dynamic(void) + { + ENGINE *ret = ENGINE_new(); + if(!ret) + return NULL; + if(!ENGINE_set_id(ret, engine_dynamic_id) || + !ENGINE_set_name(ret, engine_dynamic_name) || + !ENGINE_set_init_function(ret, dynamic_init) || + !ENGINE_set_finish_function(ret, dynamic_finish) || + !ENGINE_set_ctrl_function(ret, dynamic_ctrl) || + !ENGINE_set_flags(ret, ENGINE_FLAGS_BY_ID_COPY) || + !ENGINE_set_cmd_defns(ret, dynamic_cmd_defns)) + { + ENGINE_free(ret); + return NULL; + } + return ret; + } + +void ENGINE_load_dynamic(void) + { + ENGINE *toadd = engine_dynamic(); + if(!toadd) return; + ENGINE_add(toadd); + /* If the "add" worked, it gets a structural reference. So either way, + * we release our just-created reference. */ + ENGINE_free(toadd); + /* If the "add" didn't work, it was probably a conflict because it was + * already added (eg. someone calling ENGINE_load_blah then calling + * ENGINE_load_builtin_engines() perhaps). */ + ERR_clear_error(); + } + +static int dynamic_init(ENGINE *e) + { + /* We always return failure - the "dyanamic" engine itself can't be used + * for anything. */ + return 0; + } + +static int dynamic_finish(ENGINE *e) + { + /* This should never be called on account of "dynamic_init" always + * failing. */ + return 0; + } + +static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) + { + dynamic_data_ctx *ctx = dynamic_get_data_ctx(e); + int initialised; + + if(!ctx) + { + ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_NOT_LOADED); + return 0; + } + initialised = ((ctx->dynamic_dso == NULL) ? 0 : 1); + /* All our control commands require the ENGINE to be uninitialised */ + if(initialised) + { + ENGINEerr(ENGINE_F_DYNAMIC_CTRL, + ENGINE_R_ALREADY_LOADED); + return 0; + } + switch(cmd) + { + case DYNAMIC_CMD_SO_PATH: + /* a NULL 'p' or a string of zero-length is the same thing */ + if(p && (strlen((const char *)p) < 1)) + p = NULL; + ctx->DYNAMIC_LIBNAME = (const char *)p; + return 1; + case DYNAMIC_CMD_NO_VCHECK: + ctx->no_vcheck = ((i == 0) ? 0 : 1); + return 1; + case DYNAMIC_CMD_ID: + /* a NULL 'p' or a string of zero-length is the same thing */ + if(p && (strlen((const char *)p) < 1)) + p = NULL; + ctx->engine_id = (const char *)p; + return 1; + case DYNAMIC_CMD_LIST_ADD: + if((i < 0) || (i > 2)) + { + ENGINEerr(ENGINE_F_DYNAMIC_CTRL, + ENGINE_R_INVALID_ARGUMENT); + return 0; + } + ctx->list_add_value = (int)i; + return 1; + case DYNAMIC_CMD_LOAD: + return dynamic_load(e, ctx); + default: + break; + } + ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); + return 0; + } + +static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx) + { + ENGINE cpy; + dynamic_fns fns; + + if(!ctx->DYNAMIC_LIBNAME || ((ctx->dynamic_dso = DSO_load(NULL, + ctx->DYNAMIC_LIBNAME, NULL, 0)) == NULL)) + { + ENGINEerr(ENGINE_F_DYNAMIC_LOAD, + ENGINE_R_DSO_NOT_FOUND); + return 0; + } + /* We have to find a bind function otherwise it'll always end badly */ + if(!(ctx->bind_engine = (dynamic_bind_engine)DSO_bind_func( + ctx->dynamic_dso, ctx->DYNAMIC_F2))) + { + ctx->bind_engine = NULL; + DSO_free(ctx->dynamic_dso); + ctx->dynamic_dso = NULL; + ENGINEerr(ENGINE_F_DYNAMIC_LOAD, + ENGINE_R_DSO_FAILURE); + return 0; + } + /* Do we perform version checking? */ + if(!ctx->no_vcheck) + { + unsigned long vcheck_res = 0; + /* Now we try to find a version checking function and decide how + * to cope with failure if/when it fails. */ + ctx->v_check = (dynamic_v_check_fn)DSO_bind_func( + ctx->dynamic_dso, ctx->DYNAMIC_F1); + if(ctx->v_check) + vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION); + /* We fail if the version checker veto'd the load *or* if it is + * deferring to us (by returning its version) and we think it is + * too old. */ + if(vcheck_res < OSSL_DYNAMIC_OLDEST) + { + /* Fail */ + ctx->bind_engine = NULL; + ctx->v_check = NULL; + DSO_free(ctx->dynamic_dso); + ctx->dynamic_dso = NULL; + ENGINEerr(ENGINE_F_DYNAMIC_LOAD, + ENGINE_R_VERSION_INCOMPATIBILITY); + return 0; + } + } + /* First binary copy the ENGINE structure so that we can roll back if + * the hand-over fails */ + memcpy(&cpy, e, sizeof(ENGINE)); + /* Provide the ERR, "ex_data", memory, and locking callbacks so the + * loaded library uses our state rather than its own. FIXME: As noted in + * engine.h, much of this would be simplified if each area of code + * provided its own "summary" structure of all related callbacks. It + * would also increase opaqueness. */ + fns.err_fns = ERR_get_implementation(); + fns.ex_data_fns = CRYPTO_get_ex_data_implementation(); + CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb, + &fns.mem_fns.realloc_cb, + &fns.mem_fns.free_cb); + fns.lock_fns.lock_locking_cb = CRYPTO_get_locking_callback(); + fns.lock_fns.lock_add_lock_cb = CRYPTO_get_add_lock_callback(); + fns.lock_fns.dynlock_create_cb = CRYPTO_get_dynlock_create_callback(); + fns.lock_fns.dynlock_lock_cb = CRYPTO_get_dynlock_lock_callback(); + fns.lock_fns.dynlock_destroy_cb = CRYPTO_get_dynlock_destroy_callback(); + /* Now that we've loaded the dynamic engine, make sure no "dynamic" + * ENGINE elements will show through. */ + engine_set_all_null(e); + + /* Try to bind the ENGINE onto our own ENGINE structure */ + if(!ctx->bind_engine(e, ctx->engine_id, &fns)) + { + ctx->bind_engine = NULL; + ctx->v_check = NULL; + DSO_free(ctx->dynamic_dso); + ctx->dynamic_dso = NULL; + ENGINEerr(ENGINE_F_DYNAMIC_LOAD,ENGINE_R_INIT_FAILED); + /* Copy the original ENGINE structure back */ + memcpy(e, &cpy, sizeof(ENGINE)); + return 0; + } + /* Do we try to add this ENGINE to the internal list too? */ + if(ctx->list_add_value > 0) + { + if(!ENGINE_add(e)) + { + /* Do we tolerate this or fail? */ + if(ctx->list_add_value > 1) + { + /* Fail - NB: By this time, it's too late to + * rollback, and trying to do so allows the + * bind_engine() code to have created leaks. We + * just have to fail where we are, after the + * ENGINE has changed. */ + ENGINEerr(ENGINE_F_DYNAMIC_LOAD, + ENGINE_R_CONFLICTING_ENGINE_ID); + return 0; + } + /* Tolerate */ + ERR_clear_error(); + } + } + return 1; + } diff --git a/src/lib/libcrypto/engine/eng_err.c b/src/lib/libcrypto/engine/eng_err.c new file mode 100644 index 0000000000..f6c5630395 --- /dev/null +++ b/src/lib/libcrypto/engine/eng_err.c @@ -0,0 +1,165 @@ +/* crypto/engine/eng_err.c */ +/* ==================================================================== + * 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 + * 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 +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR +static ERR_STRING_DATA ENGINE_str_functs[]= + { +{ERR_PACK(0,ENGINE_F_DYNAMIC_CTRL,0), "DYNAMIC_CTRL"}, +{ERR_PACK(0,ENGINE_F_DYNAMIC_GET_DATA_CTX,0), "DYNAMIC_GET_DATA_CTX"}, +{ERR_PACK(0,ENGINE_F_DYNAMIC_LOAD,0), "DYNAMIC_LOAD"}, +{ERR_PACK(0,ENGINE_F_ENGINE_ADD,0), "ENGINE_add"}, +{ERR_PACK(0,ENGINE_F_ENGINE_BY_ID,0), "ENGINE_by_id"}, +{ERR_PACK(0,ENGINE_F_ENGINE_CMD_IS_EXECUTABLE,0), "ENGINE_cmd_is_executable"}, +{ERR_PACK(0,ENGINE_F_ENGINE_CTRL,0), "ENGINE_ctrl"}, +{ERR_PACK(0,ENGINE_F_ENGINE_CTRL_CMD,0), "ENGINE_ctrl_cmd"}, +{ERR_PACK(0,ENGINE_F_ENGINE_CTRL_CMD_STRING,0), "ENGINE_ctrl_cmd_string"}, +{ERR_PACK(0,ENGINE_F_ENGINE_FINISH,0), "ENGINE_finish"}, +{ERR_PACK(0,ENGINE_F_ENGINE_FREE,0), "ENGINE_free"}, +{ERR_PACK(0,ENGINE_F_ENGINE_GET_CIPHER,0), "ENGINE_get_cipher"}, +{ERR_PACK(0,ENGINE_F_ENGINE_GET_DEFAULT_TYPE,0), "ENGINE_GET_DEFAULT_TYPE"}, +{ERR_PACK(0,ENGINE_F_ENGINE_GET_DIGEST,0), "ENGINE_get_digest"}, +{ERR_PACK(0,ENGINE_F_ENGINE_GET_NEXT,0), "ENGINE_get_next"}, +{ERR_PACK(0,ENGINE_F_ENGINE_GET_PREV,0), "ENGINE_get_prev"}, +{ERR_PACK(0,ENGINE_F_ENGINE_INIT,0), "ENGINE_init"}, +{ERR_PACK(0,ENGINE_F_ENGINE_LIST_ADD,0), "ENGINE_LIST_ADD"}, +{ERR_PACK(0,ENGINE_F_ENGINE_LIST_REMOVE,0), "ENGINE_LIST_REMOVE"}, +{ERR_PACK(0,ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,0), "ENGINE_load_private_key"}, +{ERR_PACK(0,ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,0), "ENGINE_load_public_key"}, +{ERR_PACK(0,ENGINE_F_ENGINE_MODULE_INIT,0), "ENGINE_MODULE_INIT"}, +{ERR_PACK(0,ENGINE_F_ENGINE_NEW,0), "ENGINE_new"}, +{ERR_PACK(0,ENGINE_F_ENGINE_REMOVE,0), "ENGINE_remove"}, +{ERR_PACK(0,ENGINE_F_ENGINE_SET_DEFAULT_STRING,0), "ENGINE_set_default_string"}, +{ERR_PACK(0,ENGINE_F_ENGINE_SET_DEFAULT_TYPE,0), "ENGINE_SET_DEFAULT_TYPE"}, +{ERR_PACK(0,ENGINE_F_ENGINE_SET_ID,0), "ENGINE_set_id"}, +{ERR_PACK(0,ENGINE_F_ENGINE_SET_NAME,0), "ENGINE_set_name"}, +{ERR_PACK(0,ENGINE_F_ENGINE_TABLE_REGISTER,0), "ENGINE_TABLE_REGISTER"}, +{ERR_PACK(0,ENGINE_F_ENGINE_UNLOAD_KEY,0), "ENGINE_UNLOAD_KEY"}, +{ERR_PACK(0,ENGINE_F_INT_CTRL_HELPER,0), "INT_CTRL_HELPER"}, +{ERR_PACK(0,ENGINE_F_INT_ENGINE_CONFIGURE,0), "INT_ENGINE_CONFIGURE"}, +{ERR_PACK(0,ENGINE_F_LOG_MESSAGE,0), "LOG_MESSAGE"}, +{ERR_PACK(0,ENGINE_F_SET_DATA_CTX,0), "SET_DATA_CTX"}, +{0,NULL} + }; + +static ERR_STRING_DATA ENGINE_str_reasons[]= + { +{ENGINE_R_ALREADY_LOADED ,"already loaded"}, +{ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER ,"argument is not a number"}, +{ENGINE_R_CMD_NOT_EXECUTABLE ,"cmd not executable"}, +{ENGINE_R_COMMAND_TAKES_INPUT ,"command takes input"}, +{ENGINE_R_COMMAND_TAKES_NO_INPUT ,"command takes no input"}, +{ENGINE_R_CONFLICTING_ENGINE_ID ,"conflicting engine id"}, +{ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"}, +{ENGINE_R_DH_NOT_IMPLEMENTED ,"dh not implemented"}, +{ENGINE_R_DSA_NOT_IMPLEMENTED ,"dsa not implemented"}, +{ENGINE_R_DSO_FAILURE ,"DSO failure"}, +{ENGINE_R_DSO_NOT_FOUND ,"dso not found"}, +{ENGINE_R_ENGINES_SECTION_ERROR ,"engines section error"}, +{ENGINE_R_ENGINE_IS_NOT_IN_LIST ,"engine is not in the list"}, +{ENGINE_R_ENGINE_SECTION_ERROR ,"engine section error"}, +{ENGINE_R_FAILED_LOADING_PRIVATE_KEY ,"failed loading private key"}, +{ENGINE_R_FAILED_LOADING_PUBLIC_KEY ,"failed loading public key"}, +{ENGINE_R_FINISH_FAILED ,"finish failed"}, +{ENGINE_R_GET_HANDLE_FAILED ,"could not obtain hardware handle"}, +{ENGINE_R_ID_OR_NAME_MISSING ,"'id' or 'name' missing"}, +{ENGINE_R_INIT_FAILED ,"init failed"}, +{ENGINE_R_INTERNAL_LIST_ERROR ,"internal list error"}, +{ENGINE_R_INVALID_ARGUMENT ,"invalid argument"}, +{ENGINE_R_INVALID_CMD_NAME ,"invalid cmd name"}, +{ENGINE_R_INVALID_CMD_NUMBER ,"invalid cmd number"}, +{ENGINE_R_INVALID_INIT_VALUE ,"invalid init value"}, +{ENGINE_R_INVALID_STRING ,"invalid string"}, +{ENGINE_R_NOT_INITIALISED ,"not initialised"}, +{ENGINE_R_NOT_LOADED ,"not loaded"}, +{ENGINE_R_NO_CONTROL_FUNCTION ,"no control function"}, +{ENGINE_R_NO_INDEX ,"no index"}, +{ENGINE_R_NO_LOAD_FUNCTION ,"no load function"}, +{ENGINE_R_NO_REFERENCE ,"no reference"}, +{ENGINE_R_NO_SUCH_ENGINE ,"no such engine"}, +{ENGINE_R_NO_UNLOAD_FUNCTION ,"no unload function"}, +{ENGINE_R_PROVIDE_PARAMETERS ,"provide parameters"}, +{ENGINE_R_RSA_NOT_IMPLEMENTED ,"rsa not implemented"}, +{ENGINE_R_UNIMPLEMENTED_CIPHER ,"unimplemented cipher"}, +{ENGINE_R_UNIMPLEMENTED_DIGEST ,"unimplemented digest"}, +{ENGINE_R_VERSION_INCOMPATIBILITY ,"version incompatibility"}, +{0,NULL} + }; + +#endif + +void ERR_load_ENGINE_strings(void) + { + static int init=1; + + if (init) + { + init=0; +#ifndef OPENSSL_NO_ERR + ERR_load_strings(ERR_LIB_ENGINE,ENGINE_str_functs); + ERR_load_strings(ERR_LIB_ENGINE,ENGINE_str_reasons); +#endif + + } + } diff --git a/src/lib/libcrypto/engine/eng_fat.c b/src/lib/libcrypto/engine/eng_fat.c new file mode 100644 index 0000000000..af918b1499 --- /dev/null +++ b/src/lib/libcrypto/engine/eng_fat.c @@ -0,0 +1,148 @@ +/* crypto/engine/eng_fat.c */ +/* ==================================================================== + * 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 +#include "cryptlib.h" +#include "eng_int.h" +#include +#include + +int ENGINE_set_default(ENGINE *e, unsigned int flags) + { + if((flags & ENGINE_METHOD_CIPHERS) && !ENGINE_set_default_ciphers(e)) + return 0; + if((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e)) + return 0; +#ifndef OPENSSL_NO_RSA + if((flags & ENGINE_METHOD_RSA) & !ENGINE_set_default_RSA(e)) + return 0; +#endif +#ifndef OPENSSL_NO_DSA + if((flags & ENGINE_METHOD_DSA) & !ENGINE_set_default_DSA(e)) + return 0; +#endif +#ifndef OPENSSL_NO_DH + if((flags & ENGINE_METHOD_DH) & !ENGINE_set_default_DH(e)) + return 0; +#endif + if((flags & ENGINE_METHOD_RAND) & !ENGINE_set_default_RAND(e)) + return 0; + return 1; + } + +/* Set default algorithms using a string */ + +int int_def_cb(const char *alg, int len, void *arg) + { + unsigned int *pflags = arg; + if (!strncmp(alg, "ALL", len)) + *pflags |= ENGINE_METHOD_ALL; + else if (!strncmp(alg, "RSA", len)) + *pflags |= ENGINE_METHOD_RSA; + else if (!strncmp(alg, "DSA", len)) + *pflags |= ENGINE_METHOD_DSA; + else if (!strncmp(alg, "DH", len)) + *pflags |= ENGINE_METHOD_DH; + else if (!strncmp(alg, "RAND", len)) + *pflags |= ENGINE_METHOD_RAND; + else if (!strncmp(alg, "CIPHERS", len)) + *pflags |= ENGINE_METHOD_CIPHERS; + else if (!strncmp(alg, "DIGESTS", len)) + *pflags |= ENGINE_METHOD_DIGESTS; + else + return 0; + return 1; + } + + +int ENGINE_set_default_string(ENGINE *e, const char *list) + { + unsigned int flags = 0; + if (!CONF_parse_list(list, ',', 1, int_def_cb, &flags)) + { + ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_STRING, + ENGINE_R_INVALID_STRING); + ERR_add_error_data(2, "str=",list); + return 0; + } + return ENGINE_set_default(e, flags); + } + +int ENGINE_register_complete(ENGINE *e) + { + ENGINE_register_ciphers(e); + ENGINE_register_digests(e); +#ifndef OPENSSL_NO_RSA + ENGINE_register_RSA(e); +#endif +#ifndef OPENSSL_NO_DSA + ENGINE_register_DSA(e); +#endif +#ifndef OPENSSL_NO_DH + ENGINE_register_DH(e); +#endif + ENGINE_register_RAND(e); + return 1; + } + +int ENGINE_register_all_complete(void) + { + ENGINE *e; + + for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) { + ENGINE_register_complete(e); + } + return 1; + } diff --git a/src/lib/libcrypto/engine/eng_init.c b/src/lib/libcrypto/engine/eng_init.c new file mode 100644 index 0000000000..cc9396e863 --- /dev/null +++ b/src/lib/libcrypto/engine/eng_init.c @@ -0,0 +1,158 @@ +/* crypto/engine/eng_init.c */ +/* ==================================================================== + * 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 +#include "cryptlib.h" +#include "eng_int.h" +#include + +/* Initialise a engine type for use (or up its functional reference count + * if it's already in use). This version is only used internally. */ +int engine_unlocked_init(ENGINE *e) + { + int to_return = 1; + + if((e->funct_ref == 0) && e->init) + /* This is the first functional reference and the engine + * requires initialisation so we do it now. */ + to_return = e->init(e); + if(to_return) + { + /* OK, we return a functional reference which is also a + * structural reference. */ + e->struct_ref++; + e->funct_ref++; + engine_ref_debug(e, 0, 1) + engine_ref_debug(e, 1, 1) + } + return to_return; + } + +/* Free a functional reference to a engine type. This version is only used + * internally. */ +int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers) + { + int to_return = 1; + + /* Reduce the functional reference count here so if it's the terminating + * case, we can release the lock safely and call the finish() handler + * without risk of a race. We get a race if we leave the count until + * after and something else is calling "finish" at the same time - + * there's a chance that both threads will together take the count from + * 2 to 0 without either calling finish(). */ + e->funct_ref--; + engine_ref_debug(e, 1, -1); + if((e->funct_ref == 0) && e->finish) + { + if(unlock_for_handlers) + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + to_return = e->finish(e); + if(unlock_for_handlers) + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if(!to_return) + return 0; + } +#ifdef REF_CHECK + if(e->funct_ref < 0) + { + fprintf(stderr,"ENGINE_finish, bad functional reference count\n"); + abort(); + } +#endif + /* Release the structural reference too */ + if(!engine_free_util(e, 0)) + { + ENGINEerr(ENGINE_F_ENGINE_FINISH,ENGINE_R_FINISH_FAILED); + return 0; + } + return to_return; + } + +/* The API (locked) version of "init" */ +int ENGINE_init(ENGINE *e) + { + int ret; + if(e == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_INIT,ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + ret = engine_unlocked_init(e); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return ret; + } + +/* The API (locked) version of "finish" */ +int ENGINE_finish(ENGINE *e) + { + int to_return = 1; + + if(e == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_FINISH,ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + to_return = engine_unlocked_finish(e, 1); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + if(!to_return) + { + ENGINEerr(ENGINE_F_ENGINE_FINISH,ENGINE_R_FINISH_FAILED); + return 0; + } + return to_return; + } + diff --git a/src/lib/libcrypto/engine/eng_int.h b/src/lib/libcrypto/engine/eng_int.h new file mode 100644 index 0000000000..38335f99cd --- /dev/null +++ b/src/lib/libcrypto/engine/eng_int.h @@ -0,0 +1,185 @@ +/* crypto/engine/eng_int.h */ +/* 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). + * + */ + +#ifndef HEADER_ENGINE_INT_H +#define HEADER_ENGINE_INT_H + +/* Take public definitions from engine.h */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* If we compile with this symbol defined, then both reference counts in the + * ENGINE structure will be monitored with a line of output on stderr for each + * change. This prints the engine's pointer address (truncated to unsigned int), + * "struct" or "funct" to indicate the reference type, the before and after + * reference count, and the file:line-number pair. The "engine_ref_debug" + * statements must come *after* the change. */ +#ifdef ENGINE_REF_COUNT_DEBUG + +#define engine_ref_debug(e, isfunct, diff) \ + fprintf(stderr, "engine: %08x %s from %d to %d (%s:%d)\n", \ + (unsigned int)(e), (isfunct ? "funct" : "struct"), \ + ((isfunct) ? ((e)->funct_ref - (diff)) : ((e)->struct_ref - (diff))), \ + ((isfunct) ? (e)->funct_ref : (e)->struct_ref), \ + (__FILE__), (__LINE__)); + +#else + +#define engine_ref_debug(e, isfunct, diff) + +#endif + +/* Any code that will need cleanup operations should use these functions to + * register callbacks. ENGINE_cleanup() will call all registered callbacks in + * order. NB: both the "add" functions assume CRYPTO_LOCK_ENGINE to already be + * held (in "write" mode). */ +typedef void (ENGINE_CLEANUP_CB)(void); +typedef struct st_engine_cleanup_item + { + ENGINE_CLEANUP_CB *cb; + } ENGINE_CLEANUP_ITEM; +DECLARE_STACK_OF(ENGINE_CLEANUP_ITEM) +void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb); +void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb); + +/* We need stacks of ENGINEs for use in eng_table.c */ +DECLARE_STACK_OF(ENGINE) + +/* If this symbol is defined then engine_table_select(), the function that is + * used by RSA, DSA (etc) code to select registered ENGINEs, cache defaults and + * functional references (etc), will display debugging summaries to stderr. */ +/* #define ENGINE_TABLE_DEBUG */ + +/* This represents an implementation table. Dependent code should instantiate it + * as a (ENGINE_TABLE *) pointer value set initially to NULL. */ +typedef struct st_engine_table ENGINE_TABLE; +int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, + ENGINE *e, const int *nids, int num_nids, int setdefault); +void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e); +void engine_table_cleanup(ENGINE_TABLE **table); +#ifndef ENGINE_TABLE_DEBUG +ENGINE *engine_table_select(ENGINE_TABLE **table, int nid); +#else +ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l); +#define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__) +#endif + +/* Internal versions of API functions that have control over locking. These are + * used between C files when functionality needs to be shared but the caller may + * already be controlling of the CRYPTO_LOCK_ENGINE lock. */ +int engine_unlocked_init(ENGINE *e); +int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers); +int engine_free_util(ENGINE *e, int locked); + +/* This function will reset all "set"able values in an ENGINE to NULL. This + * won't touch reference counts or ex_data, but is equivalent to calling all the + * ENGINE_set_***() functions with a NULL value. */ +void engine_set_all_null(ENGINE *e); + +/* NB: Bitwise OR-able values for the "flags" variable in ENGINE are now exposed + * in engine.h. */ + +/* This is a structure for storing implementations of various crypto + * algorithms and functions. */ +struct engine_st + { + const char *id; + const char *name; + const RSA_METHOD *rsa_meth; + const DSA_METHOD *dsa_meth; + const DH_METHOD *dh_meth; + const RAND_METHOD *rand_meth; + /* Cipher handling is via this callback */ + ENGINE_CIPHERS_PTR ciphers; + /* Digest handling is via this callback */ + ENGINE_DIGESTS_PTR digests; + + + ENGINE_GEN_INT_FUNC_PTR destroy; + + ENGINE_GEN_INT_FUNC_PTR init; + ENGINE_GEN_INT_FUNC_PTR finish; + ENGINE_CTRL_FUNC_PTR ctrl; + ENGINE_LOAD_KEY_PTR load_privkey; + ENGINE_LOAD_KEY_PTR load_pubkey; + + const ENGINE_CMD_DEFN *cmd_defns; + int flags; + /* reference count on the structure itself */ + int struct_ref; + /* reference count on usability of the engine type. NB: This + * controls the loading and initialisation of any functionlity + * required by this engine, whereas the previous count is + * simply to cope with (de)allocation of this structure. Hence, + * running_ref <= struct_ref at all times. */ + int funct_ref; + /* A place to store per-ENGINE data */ + CRYPTO_EX_DATA ex_data; + /* Used to maintain the linked-list of engines. */ + struct engine_st *prev; + struct engine_st *next; + }; + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_ENGINE_INT_H */ diff --git a/src/lib/libcrypto/engine/eng_lib.c b/src/lib/libcrypto/engine/eng_lib.c new file mode 100644 index 0000000000..a66d0f08af --- /dev/null +++ b/src/lib/libcrypto/engine/eng_lib.c @@ -0,0 +1,321 @@ +/* crypto/engine/eng_lib.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 +#include "cryptlib.h" +#include "eng_int.h" +#include /* FIXME: This shouldn't be needed */ +#include + +/* The "new"/"free" stuff first */ + +ENGINE *ENGINE_new(void) + { + ENGINE *ret; + + ret = (ENGINE *)OPENSSL_malloc(sizeof(ENGINE)); + if(ret == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + memset(ret, 0, sizeof(ENGINE)); + ret->struct_ref = 1; + engine_ref_debug(ret, 0, 1) + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data); + return ret; + } + +/* Placed here (close proximity to ENGINE_new) so that modifications to the + * elements of the ENGINE structure are more likely to be caught and changed + * here. */ +void engine_set_all_null(ENGINE *e) + { + e->id = NULL; + e->name = NULL; + e->rsa_meth = NULL; + e->dsa_meth = NULL; + e->dh_meth = NULL; + e->rand_meth = NULL; + e->ciphers = NULL; + e->digests = NULL; + e->destroy = NULL; + e->init = NULL; + e->finish = NULL; + e->ctrl = NULL; + e->load_privkey = NULL; + e->load_pubkey = NULL; + e->cmd_defns = NULL; + e->flags = 0; + } + +int engine_free_util(ENGINE *e, int locked) + { + int i; + + if(e == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_FREE, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if(locked) + i = CRYPTO_add(&e->struct_ref,-1,CRYPTO_LOCK_ENGINE); + else + i = --e->struct_ref; + engine_ref_debug(e, 0, -1) + if (i > 0) return 1; +#ifdef REF_CHECK + if (i < 0) + { + fprintf(stderr,"ENGINE_free, bad structural reference count\n"); + abort(); + } +#endif + /* Give the ENGINE a chance to do any structural cleanup corresponding + * to allocation it did in its constructor (eg. unload error strings) */ + if(e->destroy) + e->destroy(e); + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ENGINE, e, &e->ex_data); + OPENSSL_free(e); + return 1; + } + +int ENGINE_free(ENGINE *e) + { + return engine_free_util(e, 1); + } + +/* Cleanup stuff */ + +/* ENGINE_cleanup() is coded such that anything that does work that will need + * cleanup can register a "cleanup" callback here. That way we don't get linker + * bloat by referring to all *possible* cleanups, but any linker bloat into code + * "X" will cause X's cleanup function to end up here. */ +static STACK_OF(ENGINE_CLEANUP_ITEM) *cleanup_stack = NULL; +static int int_cleanup_check(int create) + { + if(cleanup_stack) return 1; + if(!create) return 0; + cleanup_stack = sk_ENGINE_CLEANUP_ITEM_new_null(); + return (cleanup_stack ? 1 : 0); + } +static ENGINE_CLEANUP_ITEM *int_cleanup_item(ENGINE_CLEANUP_CB *cb) + { + ENGINE_CLEANUP_ITEM *item = OPENSSL_malloc(sizeof( + ENGINE_CLEANUP_ITEM)); + if(!item) return NULL; + item->cb = cb; + return item; + } +void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb) + { + ENGINE_CLEANUP_ITEM *item; + if(!int_cleanup_check(1)) return; + item = int_cleanup_item(cb); + if(item) + sk_ENGINE_CLEANUP_ITEM_insert(cleanup_stack, item, 0); + } +void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb) + { + ENGINE_CLEANUP_ITEM *item; + if(!int_cleanup_check(1)) return; + item = int_cleanup_item(cb); + if(item) + sk_ENGINE_CLEANUP_ITEM_push(cleanup_stack, item); + } +/* The API function that performs all cleanup */ +static void engine_cleanup_cb_free(ENGINE_CLEANUP_ITEM *item) + { + (*(item->cb))(); + OPENSSL_free(item); + } +void ENGINE_cleanup(void) + { + if(int_cleanup_check(0)) + { + sk_ENGINE_CLEANUP_ITEM_pop_free(cleanup_stack, + engine_cleanup_cb_free); + cleanup_stack = NULL; + } + /* FIXME: This should be handled (somehow) through RAND, eg. by it + * registering a cleanup callback. */ + RAND_set_rand_method(NULL); + } + +/* Now the "ex_data" support */ + +int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) + { + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ENGINE, argl, argp, + new_func, dup_func, free_func); + } + +int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg) + { + return(CRYPTO_set_ex_data(&e->ex_data, idx, arg)); + } + +void *ENGINE_get_ex_data(const ENGINE *e, int idx) + { + return(CRYPTO_get_ex_data(&e->ex_data, idx)); + } + +/* Functions to get/set an ENGINE's elements - mainly to avoid exposing the + * ENGINE structure itself. */ + +int ENGINE_set_id(ENGINE *e, const char *id) + { + if(id == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_SET_ID, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + e->id = id; + return 1; + } + +int ENGINE_set_name(ENGINE *e, const char *name) + { + if(name == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_SET_NAME, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + e->name = name; + return 1; + } + +int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f) + { + e->destroy = destroy_f; + return 1; + } + +int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f) + { + e->init = init_f; + return 1; + } + +int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f) + { + e->finish = finish_f; + return 1; + } + +int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f) + { + e->ctrl = ctrl_f; + return 1; + } + +int ENGINE_set_flags(ENGINE *e, int flags) + { + e->flags = flags; + return 1; + } + +int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns) + { + e->cmd_defns = defns; + return 1; + } + +const char *ENGINE_get_id(const ENGINE *e) + { + return e->id; + } + +const char *ENGINE_get_name(const ENGINE *e) + { + return e->name; + } + +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e) + { + return e->destroy; + } + +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e) + { + return e->init; + } + +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e) + { + return e->finish; + } + +ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e) + { + return e->ctrl; + } + +int ENGINE_get_flags(const ENGINE *e) + { + return e->flags; + } + +const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e) + { + return e->cmd_defns; + } diff --git a/src/lib/libcrypto/engine/eng_list.c b/src/lib/libcrypto/engine/eng_list.c new file mode 100644 index 0000000000..ce48d2255a --- /dev/null +++ b/src/lib/libcrypto/engine/eng_list.c @@ -0,0 +1,383 @@ +/* crypto/engine/eng_list.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 +#include "cryptlib.h" +#include "eng_int.h" +#include + +/* The linked-list of pointers to engine types. engine_list_head + * incorporates an implicit structural reference but engine_list_tail + * does not - the latter is a computational niceity and only points + * to something that is already pointed to by its predecessor in the + * list (or engine_list_head itself). In the same way, the use of the + * "prev" pointer in each ENGINE is to save excessive list iteration, + * it doesn't correspond to an extra structural reference. Hence, + * engine_list_head, and each non-null "next" pointer account for + * the list itself assuming exactly 1 structural reference on each + * list member. */ +static ENGINE *engine_list_head = NULL; +static ENGINE *engine_list_tail = NULL; + +/* This cleanup function is only needed internally. If it should be called, we + * register it with the "ENGINE_cleanup()" stack to be called during cleanup. */ + +static void engine_list_cleanup(void) + { + ENGINE *iterator = engine_list_head; + + while(iterator != NULL) + { + ENGINE_remove(iterator); + iterator = engine_list_head; + } + return; + } + +/* These static functions starting with a lower case "engine_" always + * take place when CRYPTO_LOCK_ENGINE has been locked up. */ +static int engine_list_add(ENGINE *e) + { + int conflict = 0; + ENGINE *iterator = NULL; + + if(e == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + iterator = engine_list_head; + while(iterator && !conflict) + { + conflict = (strcmp(iterator->id, e->id) == 0); + iterator = iterator->next; + } + if(conflict) + { + ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, + ENGINE_R_CONFLICTING_ENGINE_ID); + return 0; + } + if(engine_list_head == NULL) + { + /* We are adding to an empty list. */ + if(engine_list_tail) + { + ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, + ENGINE_R_INTERNAL_LIST_ERROR); + return 0; + } + engine_list_head = e; + e->prev = NULL; + /* The first time the list allocates, we should register the + * cleanup. */ + engine_cleanup_add_last(engine_list_cleanup); + } + else + { + /* We are adding to the tail of an existing list. */ + if((engine_list_tail == NULL) || + (engine_list_tail->next != NULL)) + { + ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, + ENGINE_R_INTERNAL_LIST_ERROR); + return 0; + } + engine_list_tail->next = e; + e->prev = engine_list_tail; + } + /* Having the engine in the list assumes a structural + * reference. */ + e->struct_ref++; + engine_ref_debug(e, 0, 1) + /* However it came to be, e is the last item in the list. */ + engine_list_tail = e; + e->next = NULL; + return 1; + } + +static int engine_list_remove(ENGINE *e) + { + ENGINE *iterator; + + if(e == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + /* We need to check that e is in our linked list! */ + iterator = engine_list_head; + while(iterator && (iterator != e)) + iterator = iterator->next; + if(iterator == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE, + ENGINE_R_ENGINE_IS_NOT_IN_LIST); + return 0; + } + /* un-link e from the chain. */ + if(e->next) + e->next->prev = e->prev; + if(e->prev) + e->prev->next = e->next; + /* Correct our head/tail if necessary. */ + if(engine_list_head == e) + engine_list_head = e->next; + if(engine_list_tail == e) + engine_list_tail = e->prev; + engine_free_util(e, 0); + return 1; + } + +/* Get the first/last "ENGINE" type available. */ +ENGINE *ENGINE_get_first(void) + { + ENGINE *ret; + + CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); + ret = engine_list_head; + if(ret) + { + ret->struct_ref++; + engine_ref_debug(ret, 0, 1) + } + CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); + return ret; + } + +ENGINE *ENGINE_get_last(void) + { + ENGINE *ret; + + CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); + ret = engine_list_tail; + if(ret) + { + ret->struct_ref++; + engine_ref_debug(ret, 0, 1) + } + CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); + return ret; + } + +/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */ +ENGINE *ENGINE_get_next(ENGINE *e) + { + ENGINE *ret = NULL; + if(e == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_GET_NEXT, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); + ret = e->next; + if(ret) + { + /* Return a valid structural refernce to the next ENGINE */ + ret->struct_ref++; + engine_ref_debug(ret, 0, 1) + } + CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); + /* Release the structural reference to the previous ENGINE */ + ENGINE_free(e); + return ret; + } + +ENGINE *ENGINE_get_prev(ENGINE *e) + { + ENGINE *ret = NULL; + if(e == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_GET_PREV, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); + ret = e->prev; + if(ret) + { + /* Return a valid structural reference to the next ENGINE */ + ret->struct_ref++; + engine_ref_debug(ret, 0, 1) + } + CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); + /* Release the structural reference to the previous ENGINE */ + ENGINE_free(e); + return ret; + } + +/* Add another "ENGINE" type into the list. */ +int ENGINE_add(ENGINE *e) + { + int to_return = 1; + if(e == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_ADD, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if((e->id == NULL) || (e->name == NULL)) + { + ENGINEerr(ENGINE_F_ENGINE_ADD, + ENGINE_R_ID_OR_NAME_MISSING); + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if(!engine_list_add(e)) + { + ENGINEerr(ENGINE_F_ENGINE_ADD, + ENGINE_R_INTERNAL_LIST_ERROR); + to_return = 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return to_return; + } + +/* Remove an existing "ENGINE" type from the array. */ +int ENGINE_remove(ENGINE *e) + { + int to_return = 1; + if(e == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_REMOVE, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if(!engine_list_remove(e)) + { + ENGINEerr(ENGINE_F_ENGINE_REMOVE, + ENGINE_R_INTERNAL_LIST_ERROR); + to_return = 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return to_return; + } + +static void engine_cpy(ENGINE *dest, const ENGINE *src) + { + dest->id = src->id; + dest->name = src->name; +#ifndef OPENSSL_NO_RSA + dest->rsa_meth = src->rsa_meth; +#endif +#ifndef OPENSSL_NO_DSA + dest->dsa_meth = src->dsa_meth; +#endif +#ifndef OPENSSL_NO_DH + dest->dh_meth = src->dh_meth; +#endif + dest->rand_meth = src->rand_meth; + dest->ciphers = src->ciphers; + dest->digests = src->digests; + dest->destroy = src->destroy; + dest->init = src->init; + dest->finish = src->finish; + dest->ctrl = src->ctrl; + dest->load_privkey = src->load_privkey; + dest->load_pubkey = src->load_pubkey; + dest->cmd_defns = src->cmd_defns; + dest->flags = src->flags; + } + +ENGINE *ENGINE_by_id(const char *id) + { + ENGINE *iterator; + if(id == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_BY_ID, + ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); + iterator = engine_list_head; + while(iterator && (strcmp(id, iterator->id) != 0)) + iterator = iterator->next; + if(iterator) + { + /* We need to return a structural reference. If this is an + * ENGINE type that returns copies, make a duplicate - otherwise + * increment the existing ENGINE's reference count. */ + if(iterator->flags & ENGINE_FLAGS_BY_ID_COPY) + { + ENGINE *cp = ENGINE_new(); + if(!cp) + iterator = NULL; + else + { + engine_cpy(cp, iterator); + iterator = cp; + } + } + else + { + iterator->struct_ref++; + engine_ref_debug(iterator, 0, 1) + } + } + CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); + if(iterator == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_BY_ID, + ENGINE_R_NO_SUCH_ENGINE); + ERR_add_error_data(2, "id=", id); + } + return iterator; + } diff --git a/src/lib/libcrypto/engine/eng_openssl.c b/src/lib/libcrypto/engine/eng_openssl.c new file mode 100644 index 0000000000..e9d976f46b --- /dev/null +++ b/src/lib/libcrypto/engine/eng_openssl.c @@ -0,0 +1,347 @@ +/* crypto/engine/eng_openssl.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 +#include +#include "cryptlib.h" +#include +#include +#include + +/* This testing gunk is implemented (and explained) lower down. It also assumes + * the application explicitly calls "ENGINE_load_openssl()" because this is no + * longer automatic in ENGINE_load_builtin_engines(). */ +#define TEST_ENG_OPENSSL_RC4 +#define TEST_ENG_OPENSSL_PKEY +/* #define TEST_ENG_OPENSSL_RC4_OTHERS */ +#define TEST_ENG_OPENSSL_RC4_P_INIT +/* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */ +#define TEST_ENG_OPENSSL_SHA +/* #define TEST_ENG_OPENSSL_SHA_OTHERS */ +/* #define TEST_ENG_OPENSSL_SHA_P_INIT */ +/* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */ +/* #define TEST_ENG_OPENSSL_SHA_P_FINAL */ + +#ifdef TEST_ENG_OPENSSL_RC4 +static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid); +#endif +#ifdef TEST_ENG_OPENSSL_SHA +static int openssl_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid); +#endif + +#ifdef TEST_ENG_OPENSSL_PKEY +static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +#endif + +/* The constants used when creating the ENGINE */ +static const char *engine_openssl_id = "openssl"; +static const char *engine_openssl_name = "Software engine support"; + +/* This internal function is used by ENGINE_openssl() and possibly by the + * "dynamic" ENGINE support too */ +static int bind_helper(ENGINE *e) + { + if(!ENGINE_set_id(e, engine_openssl_id) + || !ENGINE_set_name(e, engine_openssl_name) +#ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS +#ifndef OPENSSL_NO_RSA + || !ENGINE_set_RSA(e, RSA_get_default_method()) +#endif +#ifndef OPENSSL_NO_DSA + || !ENGINE_set_DSA(e, DSA_get_default_method()) +#endif +#ifndef OPENSSL_NO_DH + || !ENGINE_set_DH(e, DH_get_default_method()) +#endif + || !ENGINE_set_RAND(e, RAND_SSLeay()) +#ifdef TEST_ENG_OPENSSL_RC4 + || !ENGINE_set_ciphers(e, openssl_ciphers) +#endif +#ifdef TEST_ENG_OPENSSL_SHA + || !ENGINE_set_digests(e, openssl_digests) +#endif +#endif +#ifdef TEST_ENG_OPENSSL_PKEY + || !ENGINE_set_load_privkey_function(e, openssl_load_privkey) +#endif + ) + return 0; + /* If we add errors to this ENGINE, ensure the error handling is setup here */ + /* openssl_load_error_strings(); */ + return 1; + } + +static ENGINE *engine_openssl(void) + { + ENGINE *ret = ENGINE_new(); + if(!ret) + return NULL; + if(!bind_helper(ret)) + { + ENGINE_free(ret); + return NULL; + } + return ret; + } + +void ENGINE_load_openssl(void) + { + ENGINE *toadd = engine_openssl(); + if(!toadd) return; + ENGINE_add(toadd); + /* If the "add" worked, it gets a structural reference. So either way, + * we release our just-created reference. */ + ENGINE_free(toadd); + ERR_clear_error(); + } + +/* This stuff is needed if this ENGINE is being compiled into a self-contained + * shared-library. */ +#ifdef ENGINE_DYNAMIC_SUPPORT +static int bind_fn(ENGINE *e, const char *id) + { + if(id && (strcmp(id, engine_openssl_id) != 0)) + return 0; + if(!bind_helper(e)) + return 0; + return 1; + } +IMPLEMENT_DYNAMIC_CHECK_FN() +IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) +#endif /* ENGINE_DYNAMIC_SUPPORT */ + +#ifdef TEST_ENG_OPENSSL_RC4 +/* This section of code compiles an "alternative implementation" of two modes of + * RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4" + * should under normal circumstances go via this support rather than the default + * EVP support. There are other symbols to tweak the testing; + * TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time + * we're asked for a cipher we don't support (should not happen). + * TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time + * the "init_key" handler is called. + * TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler. + */ +#include +#include +#define TEST_RC4_KEY_SIZE 16 +static int test_cipher_nids[] = {NID_rc4,NID_rc4_40}; +static int test_cipher_nids_number = 2; +typedef struct { + unsigned char key[TEST_RC4_KEY_SIZE]; + RC4_KEY ks; + } TEST_RC4_KEY; +#define test(ctx) ((TEST_RC4_KEY *)(ctx)->cipher_data) +static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) + { +#ifdef TEST_ENG_OPENSSL_RC4_P_INIT + fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n"); +#endif + memcpy(&test(ctx)->key[0],key,EVP_CIPHER_CTX_key_length(ctx)); + RC4_set_key(&test(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx), + test(ctx)->key); + return 1; + } +static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) + { +#ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER + fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n"); +#endif + RC4(&test(ctx)->ks,inl,in,out); + return 1; + } +static const EVP_CIPHER test_r4_cipher= + { + NID_rc4, + 1,TEST_RC4_KEY_SIZE,0, + EVP_CIPH_VARIABLE_LENGTH, + test_rc4_init_key, + test_rc4_cipher, + NULL, + sizeof(TEST_RC4_KEY), + NULL, + NULL, + NULL + }; +static const EVP_CIPHER test_r4_40_cipher= + { + NID_rc4_40, + 1,5 /* 40 bit */,0, + EVP_CIPH_VARIABLE_LENGTH, + test_rc4_init_key, + test_rc4_cipher, + NULL, + sizeof(TEST_RC4_KEY), + NULL, + NULL, + NULL + }; +static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid) + { + if(!cipher) + { + /* We are returning a list of supported nids */ + *nids = test_cipher_nids; + return test_cipher_nids_number; + } + /* We are being asked for a specific cipher */ + if(nid == NID_rc4) + *cipher = &test_r4_cipher; + else if(nid == NID_rc4_40) + *cipher = &test_r4_40_cipher; + else + { +#ifdef TEST_ENG_OPENSSL_RC4_OTHERS + fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) returning NULL for " + "nid %d\n", nid); +#endif + *cipher = NULL; + return 0; + } + return 1; + } +#endif + +#ifdef TEST_ENG_OPENSSL_SHA +/* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */ +#include +#include +static int test_digest_nids[] = {NID_sha1}; +static int test_digest_nids_number = 1; +static int test_sha1_init(EVP_MD_CTX *ctx) + { +#ifdef TEST_ENG_OPENSSL_SHA_P_INIT + fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n"); +#endif + return SHA1_Init(ctx->md_data); + } +static int test_sha1_update(EVP_MD_CTX *ctx,const void *data,unsigned long count) + { +#ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE + fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n"); +#endif + return SHA1_Update(ctx->md_data,data,count); + } +static int test_sha1_final(EVP_MD_CTX *ctx,unsigned char *md) + { +#ifdef TEST_ENG_OPENSSL_SHA_P_FINAL + fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n"); +#endif + return SHA1_Final(md,ctx->md_data); + } +static const EVP_MD test_sha_md= + { + NID_sha1, + NID_sha1WithRSAEncryption, + SHA_DIGEST_LENGTH, + 0, + test_sha1_init, + test_sha1_update, + test_sha1_final, + NULL, + NULL, + EVP_PKEY_RSA_method, + SHA_CBLOCK, + sizeof(EVP_MD *)+sizeof(SHA_CTX), + }; +static int openssl_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid) + { + if(!digest) + { + /* We are returning a list of supported nids */ + *nids = test_digest_nids; + return test_digest_nids_number; + } + /* We are being asked for a specific digest */ + if(nid == NID_sha1) + *digest = &test_sha_md; + else + { +#ifdef TEST_ENG_OPENSSL_SHA_OTHERS + fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for " + "nid %d\n", nid); +#endif + *digest = NULL; + return 0; + } + return 1; + } +#endif + +#ifdef TEST_ENG_OPENSSL_PKEY +static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, void *callback_data) + { + BIO *in; + EVP_PKEY *key; + fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n", key_id); + in = BIO_new_file(key_id, "r"); + if (!in) + return NULL; + key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL); + BIO_free(in); + return key; + } +#endif diff --git a/src/lib/libcrypto/engine/eng_pkey.c b/src/lib/libcrypto/engine/eng_pkey.c new file mode 100644 index 0000000000..8c69171511 --- /dev/null +++ b/src/lib/libcrypto/engine/eng_pkey.c @@ -0,0 +1,157 @@ +/* crypto/engine/eng_pkey.c */ +/* ==================================================================== + * 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 +#include "cryptlib.h" +#include "eng_int.h" +#include + +/* Basic get/set stuff */ + +int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f) + { + e->load_privkey = loadpriv_f; + return 1; + } + +int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f) + { + e->load_pubkey = loadpub_f; + return 1; + } + +ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e) + { + return e->load_privkey; + } + +ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e) + { + return e->load_pubkey; + } + +/* API functions to load public/private keys */ + +EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data) + { + EVP_PKEY *pkey; + + if(e == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if(e->funct_ref == 0) + { + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, + ENGINE_R_NOT_INITIALISED); + return 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + if (!e->load_privkey) + { + ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, + ENGINE_R_NO_LOAD_FUNCTION); + return 0; + } + pkey = e->load_privkey(e, key_id, ui_method, callback_data); + if (!pkey) + { + ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, + ENGINE_R_FAILED_LOADING_PRIVATE_KEY); + return 0; + } + return pkey; + } + +EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data) + { + EVP_PKEY *pkey; + + if(e == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if(e->funct_ref == 0) + { + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, + ENGINE_R_NOT_INITIALISED); + return 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + if (!e->load_pubkey) + { + ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, + ENGINE_R_NO_LOAD_FUNCTION); + return 0; + } + pkey = e->load_pubkey(e, key_id, ui_method, callback_data); + if (!pkey) + { + ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, + ENGINE_R_FAILED_LOADING_PUBLIC_KEY); + return 0; + } + return pkey; + } diff --git a/src/lib/libcrypto/engine/eng_table.c b/src/lib/libcrypto/engine/eng_table.c new file mode 100644 index 0000000000..c69a84a8bf --- /dev/null +++ b/src/lib/libcrypto/engine/eng_table.c @@ -0,0 +1,361 @@ +/* ==================================================================== + * 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 + * 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 +#include +#include "eng_int.h" + +/* This is the type of item in the 'implementation' table. Each 'nid' hashes to + * a (potentially NULL) ENGINE_PILE structure which contains a stack of ENGINE* + * pointers. These pointers aren't references, because they're inserted and + * removed during ENGINE creation and ENGINE destruction. They point to ENGINEs + * that *exist* (ie. have a structural reference count greater than zero) rather + * than ENGINEs that are *functional*. Each pointer in those stacks are to + * ENGINEs that implements the algorithm corresponding to each 'nid'. */ + +/* The type of the items in the table */ +typedef struct st_engine_pile + { + /* The 'nid' of the algorithm/mode this ENGINE_PILE structure represents + * */ + int nid; + /* A stack of ENGINE pointers for ENGINEs that support this + * algorithm/mode. In the event that 'funct' is NULL, the first entry in + * this stack that initialises will be set as 'funct' and assumed as the + * default for operations of this type. */ + STACK_OF(ENGINE) *sk; + /* The default ENGINE to perform this algorithm/mode. */ + ENGINE *funct; + /* This value optimises engine_table_select(). If it is called it sets + * this value to 1. Any changes to this ENGINE_PILE resets it to zero. + * As such, no ENGINE_init() thrashing is done unless ENGINEs + * continually register (and/or unregister). */ + int uptodate; + } ENGINE_PILE; + +/* The type of the hash table of ENGINE_PILE structures such that each are + * unique and keyed by the 'nid' value. */ +struct st_engine_table + { + LHASH piles; + }; /* ENGINE_TABLE */ + +/* This value stores global options controlling behaviour of (mostly) the + * engine_table_select() function. It's a bitmask of flag values of the form + * ENGINE_TABLE_FLAG_*** (as defined in engine.h) and is controlled by the + * ENGINE_[get|set]_table_flags() function. */ +static unsigned int table_flags = 0; + +/* API function manipulating 'table_flags' */ +unsigned int ENGINE_get_table_flags(void) + { + return table_flags; + } +void ENGINE_set_table_flags(unsigned int flags) + { + table_flags = flags; + } + +/* Internal functions for the "piles" hash table */ +static unsigned long engine_pile_hash(const ENGINE_PILE *c) + { + return c->nid; + } +static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b) + { + return a->nid - b->nid; + } +static IMPLEMENT_LHASH_HASH_FN(engine_pile_hash, const ENGINE_PILE *) +static IMPLEMENT_LHASH_COMP_FN(engine_pile_cmp, const ENGINE_PILE *) +static int int_table_check(ENGINE_TABLE **t, int create) + { + LHASH *lh; + if(*t) + return 1; + if(!create) + return 0; + if((lh = lh_new(LHASH_HASH_FN(engine_pile_hash), + LHASH_COMP_FN(engine_pile_cmp))) == NULL) + return 0; + *t = (ENGINE_TABLE *)lh; + return 1; + } + +/* Privately exposed (via eng_int.h) functions for adding and/or removing + * ENGINEs from the implementation table */ +int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, + ENGINE *e, const int *nids, int num_nids, int setdefault) + { + int ret = 0, added = 0; + ENGINE_PILE tmplate, *fnd; + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if(!(*table)) + added = 1; + if(!int_table_check(table, 1)) + goto end; + if(added) + /* The cleanup callback needs to be added */ + engine_cleanup_add_first(cleanup); + while(num_nids--) + { + tmplate.nid = *nids; + fnd = lh_retrieve(&(*table)->piles, &tmplate); + if(!fnd) + { + fnd = OPENSSL_malloc(sizeof(ENGINE_PILE)); + if(!fnd) + goto end; + fnd->uptodate = 1; + fnd->nid = *nids; + fnd->sk = sk_ENGINE_new_null(); + if(!fnd->sk) + { + OPENSSL_free(fnd); + goto end; + } + fnd->funct= NULL; + lh_insert(&(*table)->piles, fnd); + } + /* A registration shouldn't add duplciate entries */ + sk_ENGINE_delete_ptr(fnd->sk, e); + /* if 'setdefault', this ENGINE goes to the head of the list */ + if(!sk_ENGINE_push(fnd->sk, e)) + goto end; + /* "touch" this ENGINE_PILE */ + fnd->uptodate = 0; + if(setdefault) + { + if(!engine_unlocked_init(e)) + { + ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER, + ENGINE_R_INIT_FAILED); + goto end; + } + if(fnd->funct) + engine_unlocked_finish(fnd->funct, 0); + fnd->funct = e; + } + nids++; + } + ret = 1; +end: + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return ret; + } +static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e) + { + int n; + /* Iterate the 'c->sk' stack removing any occurance of 'e' */ + while((n = sk_ENGINE_find(pile->sk, e)) >= 0) + { + sk_ENGINE_delete(pile->sk, n); + /* "touch" this ENGINE_CIPHER */ + pile->uptodate = 0; + } + if(pile->funct == e) + { + engine_unlocked_finish(e, 0); + pile->funct = NULL; + } + } +static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb,ENGINE_PILE *,ENGINE *) +void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e) + { + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if(int_table_check(table, 0)) + lh_doall_arg(&(*table)->piles, + LHASH_DOALL_ARG_FN(int_unregister_cb), e); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + } + +static void int_cleanup_cb(ENGINE_PILE *p) + { + sk_ENGINE_free(p->sk); + if(p->funct) + engine_unlocked_finish(p->funct, 0); + OPENSSL_free(p); + } +static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb,ENGINE_PILE *) +void engine_table_cleanup(ENGINE_TABLE **table) + { + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if(*table) + { + lh_doall(&(*table)->piles, LHASH_DOALL_FN(int_cleanup_cb)); + lh_free(&(*table)->piles); + *table = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + } + +/* Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references) for a given cipher 'nid' */ +#ifndef ENGINE_TABLE_DEBUG +ENGINE *engine_table_select(ENGINE_TABLE **table, int nid) +#else +ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l) +#endif + { + ENGINE *ret = NULL; + ENGINE_PILE tmplate, *fnd=NULL; + int initres, loop = 0; + + /* If 'engine_ciphers' is NULL, then it's absolutely *sure* that no + * ENGINEs have registered any implementations! */ + if(!(*table)) + { +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no " + "registered for anything!\n", f, l, nid); +#endif + return NULL; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + /* Check again inside the lock otherwise we could race against cleanup + * operations. But don't worry about a fprintf(stderr). */ + if(!int_table_check(table, 0)) + goto end; + tmplate.nid = nid; + fnd = lh_retrieve(&(*table)->piles, &tmplate); + if(!fnd) + goto end; + if(fnd->funct && engine_unlocked_init(fnd->funct)) + { +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " + "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id); +#endif + ret = fnd->funct; + goto end; + } + if(fnd->uptodate) + { + ret = fnd->funct; + goto end; + } +trynext: + ret = sk_ENGINE_value(fnd->sk, loop++); + if(!ret) + { +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no " + "registered implementations would initialise\n", + f, l, nid); +#endif + goto end; + } +#if 0 + /* Don't need to get a reference if we hold the lock. If the locking has + * to change in future, that would be different ... */ + ret->struct_ref++; engine_ref_debug(ret, 0, 1) +#endif + /* Try and initialise the ENGINE if it's already functional *or* if the + * ENGINE_TABLE_FLAG_NOINIT flag is not set. */ + if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT)) + initres = engine_unlocked_init(ret); + else + initres = 0; +#if 0 + /* Release the structural reference */ + ret->struct_ref--; engine_ref_debug(ret, 0, -1); +#endif + if(initres) + { + /* If we didn't have a default (functional reference) for this + * 'nid' (or we had one but for whatever reason we're now + * initialising a different one), use this opportunity to set + * 'funct'. */ + if((fnd->funct != ret) && engine_unlocked_init(ret)) + { + /* If there was a previous default we release it. */ + if(fnd->funct) + engine_unlocked_finish(fnd->funct, 0); + /* We got an extra functional reference for the + * per-'nid' default */ + fnd->funct = ret; +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, " + "setting default to '%s'\n", f, l, nid, ret->id); +#endif + } +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " + "newly initialised '%s'\n", f, l, nid, ret->id); +#endif + goto end; + } + goto trynext; +end: + /* Whatever happened - we should "untouch" our uptodate file seeing as + * we have tried our best to find a functional reference for 'nid'. If + * it failed, it is unlikely to succeed again until some future + * registrations (or unregistrations) have taken place that affect that + * 'nid'. */ + if(fnd) + fnd->uptodate = 1; +#ifdef ENGINE_TABLE_DEBUG + if(ret) + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " + "ENGINE '%s'\n", f, l, nid, ret->id); + else + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " + "'no matching ENGINE'\n", f, l, nid); +#endif + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + /* Whatever happened, any failed init()s are not failures in this + * context, so clear our error state. */ + ERR_clear_error(); + return ret; + } diff --git a/src/lib/libcrypto/engine/engine.h b/src/lib/libcrypto/engine/engine.h index 2983f47034..97f5de9e12 100644 --- a/src/lib/libcrypto/engine/engine.h +++ b/src/lib/libcrypto/engine/engine.h @@ -3,7 +3,7 @@ * project 2000. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * 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 @@ -59,36 +59,171 @@ #ifndef HEADER_ENGINE_H #define HEADER_ENGINE_H +#include #include +#ifndef OPENSSL_NO_RSA #include +#endif +#ifndef OPENSSL_NO_DSA #include +#endif +#ifndef OPENSSL_NO_DH #include +#endif #include -#include +#include #include +#include #ifdef __cplusplus extern "C" { #endif +/* Fixups for missing algorithms */ +#ifdef OPENSSL_NO_RSA +typedef void RSA_METHOD; +#endif +#ifdef OPENSSL_NO_DSA +typedef void DSA_METHOD; +#endif +#ifdef OPENSSL_NO_DH +typedef void DH_METHOD; +#endif + /* These flags are used to control combinations of algorithm (methods) * by bitwise "OR"ing. */ #define ENGINE_METHOD_RSA (unsigned int)0x0001 #define ENGINE_METHOD_DSA (unsigned int)0x0002 #define ENGINE_METHOD_DH (unsigned int)0x0004 #define ENGINE_METHOD_RAND (unsigned int)0x0008 -#define ENGINE_METHOD_BN_MOD_EXP (unsigned int)0x0010 -#define ENGINE_METHOD_BN_MOD_EXP_CRT (unsigned int)0x0020 +#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040 +#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080 /* Obvious all-or-nothing cases. */ #define ENGINE_METHOD_ALL (unsigned int)0xFFFF #define ENGINE_METHOD_NONE (unsigned int)0x0000 +/* This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used + * internally to control registration of ENGINE implementations, and can be set + * by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to + * initialise registered ENGINEs if they are not already initialised. */ +#define ENGINE_TABLE_FLAG_NOINIT (unsigned int)0x0001 + +/* ENGINE flags that can be set by ENGINE_set_flags(). */ +/* #define ENGINE_FLAGS_MALLOCED 0x0001 */ /* Not used */ + +/* This flag is for ENGINEs that wish to handle the various 'CMD'-related + * control commands on their own. Without this flag, ENGINE_ctrl() handles these + * control commands on behalf of the ENGINE using their "cmd_defns" data. */ +#define ENGINE_FLAGS_MANUAL_CMD_CTRL (int)0x0002 + +/* This flag is for ENGINEs who return new duplicate structures when found via + * "ENGINE_by_id()". When an ENGINE must store state (eg. if ENGINE_ctrl() + * commands are called in sequence as part of some stateful process like + * key-generation setup and execution), it can set this flag - then each attempt + * to obtain the ENGINE will result in it being copied into a new structure. + * Normally, ENGINEs don't declare this flag so ENGINE_by_id() just increments + * the existing ENGINE's structural reference count. */ +#define ENGINE_FLAGS_BY_ID_COPY (int)0x0004 + +/* ENGINEs can support their own command types, and these flags are used in + * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input each + * command expects. Currently only numeric and string input is supported. If a + * control command supports none of the _NUMERIC, _STRING, or _NO_INPUT options, + * then it is regarded as an "internal" control command - and not for use in + * config setting situations. As such, they're not available to the + * ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() access. Changes to + * this list of 'command types' should be reflected carefully in + * ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). */ + +/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */ +#define ENGINE_CMD_FLAG_NUMERIC (unsigned int)0x0001 +/* accepts string input (cast from 'void*' to 'const char *', 4th parameter to + * ENGINE_ctrl) */ +#define ENGINE_CMD_FLAG_STRING (unsigned int)0x0002 +/* Indicates that the control command takes *no* input. Ie. the control command + * is unparameterised. */ +#define ENGINE_CMD_FLAG_NO_INPUT (unsigned int)0x0004 +/* Indicates that the control command is internal. This control command won't + * be shown in any output, and is only usable through the ENGINE_ctrl_cmd() + * function. */ +#define ENGINE_CMD_FLAG_INTERNAL (unsigned int)0x0008 + +/* NB: These 3 control commands are deprecated and should not be used. ENGINEs + * relying on these commands should compile conditional support for + * compatibility (eg. if these symbols are defined) but should also migrate the + * same functionality to their own ENGINE-specific control functions that can be + * "discovered" by calling applications. The fact these control commands + * wouldn't be "executable" (ie. usable by text-based config) doesn't change the + * fact that application code can find and use them without requiring per-ENGINE + * hacking. */ + /* These flags are used to tell the ctrl function what should be done. * All command numbers are shared between all engines, even if some don't * make sense to some engines. In such a case, they do nothing but return * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */ #define ENGINE_CTRL_SET_LOGSTREAM 1 #define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2 +#define ENGINE_CTRL_HUP 3 /* Close and reinitialise any + handles/connections etc. */ +#define ENGINE_CTRL_SET_USER_INTERFACE 4 /* Alternative to callback */ +#define ENGINE_CTRL_SET_CALLBACK_DATA 5 /* User-specific data, used + when calling the password + callback and the user + interface */ + +/* These control commands allow an application to deal with an arbitrary engine + * in a dynamic way. Warn: Negative return values indicate errors FOR THESE + * COMMANDS because zero is used to indicate 'end-of-list'. Other commands, + * including ENGINE-specific command types, return zero for an error. + * + * An ENGINE can choose to implement these ctrl functions, and can internally + * manage things however it chooses - it does so by setting the + * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise the + * ENGINE_ctrl() code handles this on the ENGINE's behalf using the cmd_defns + * data (set using ENGINE_set_cmd_defns()). This means an ENGINE's ctrl() + * handler need only implement its own commands - the above "meta" commands will + * be taken care of. */ + +/* Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", then + * all the remaining control commands will return failure, so it is worth + * checking this first if the caller is trying to "discover" the engine's + * capabilities and doesn't want errors generated unnecessarily. */ +#define ENGINE_CTRL_HAS_CTRL_FUNCTION 10 +/* Returns a positive command number for the first command supported by the + * engine. Returns zero if no ctrl commands are supported. */ +#define ENGINE_CTRL_GET_FIRST_CMD_TYPE 11 +/* The 'long' argument specifies a command implemented by the engine, and the + * return value is the next command supported, or zero if there are no more. */ +#define ENGINE_CTRL_GET_NEXT_CMD_TYPE 12 +/* The 'void*' argument is a command name (cast from 'const char *'), and the + * return value is the command that corresponds to it. */ +#define ENGINE_CTRL_GET_CMD_FROM_NAME 13 +/* The next two allow a command to be converted into its corresponding string + * form. In each case, the 'long' argument supplies the command. In the NAME_LEN + * case, the return value is the length of the command name (not counting a + * trailing EOL). In the NAME case, the 'void*' argument must be a string buffer + * large enough, and it will be populated with the name of the command (WITH a + * trailing EOL). */ +#define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD 14 +#define ENGINE_CTRL_GET_NAME_FROM_CMD 15 +/* The next two are similar but give a "short description" of a command. */ +#define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD 16 +#define ENGINE_CTRL_GET_DESC_FROM_CMD 17 +/* With this command, the return value is the OR'd combination of + * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given + * engine-specific ctrl command expects. */ +#define ENGINE_CTRL_GET_CMD_FLAGS 18 + +/* ENGINE implementations should start the numbering of their own control + * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). */ +#define ENGINE_CMD_BASE 200 + +/* NB: These 2 nCipher "chil" control commands are deprecated, and their + * functionality is now available through ENGINE-specific control commands + * (exposed through the above-mentioned 'CMD'-handling). Code using these 2 + * commands should be migrated to the more general command handling before these + * are removed. */ + /* Flags specific to the nCipher "chil" engine */ #define ENGINE_CTRL_CHIL_SET_FORKCHECK 100 /* Depending on the value of the (long)i argument, this sets or @@ -99,45 +234,55 @@ extern "C" { /* This prevents the initialisation function from providing mutex * callbacks to the nCipher library. */ -/* As we're missing a BIGNUM_METHOD, we need a couple of locally - * defined function types that engines can implement. */ - -#ifndef HEADER_ENGINE_INT_H -/* mod_exp operation, calculates; r = a ^ p mod m - * NB: ctx can be NULL, but if supplied, the implementation may use - * it if it wishes. */ -typedef int (*BN_MOD_EXP)(BIGNUM *r, BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx); - -/* private key operation for RSA, provided seperately in case other - * RSA implementations wish to use it. */ -typedef int (*BN_MOD_EXP_CRT)(BIGNUM *r, BIGNUM *a, const BIGNUM *p, - const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1, - const BIGNUM *iqmp, BN_CTX *ctx); +/* If an ENGINE supports its own specific control commands and wishes the + * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on its + * behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN entries + * to ENGINE_set_cmd_defns(). It should also implement a ctrl() handler that + * supports the stated commands (ie. the "cmd_num" entries as described by the + * array). NB: The array must be ordered in increasing order of cmd_num. + * "null-terminated" means that the last ENGINE_CMD_DEFN element has cmd_num set + * to zero and/or cmd_name set to NULL. */ +typedef struct ENGINE_CMD_DEFN_st + { + unsigned int cmd_num; /* The command number */ + const char *cmd_name; /* The command name itself */ + const char *cmd_desc; /* A short description of the command */ + unsigned int cmd_flags; /* The input the command expects */ + } ENGINE_CMD_DEFN; /* Generic function pointer */ -typedef void (*ENGINE_GEN_FUNC_PTR)(); +typedef int (*ENGINE_GEN_FUNC_PTR)(); /* Generic function pointer taking no arguments */ -typedef void (*ENGINE_GEN_INT_FUNC_PTR)(void); +typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *); /* Specific control function pointer */ -typedef int (*ENGINE_CTRL_FUNC_PTR)(int cmd, long i, void *p, void (*f)()); - -/* The list of "engine" types is a static array of (const ENGINE*) - * pointers (not dynamic because static is fine for now and we otherwise - * have to hook an appropriate load/unload function in to initialise and - * cleanup). */ -typedef struct engine_st ENGINE; -#endif +typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, void (*f)()); +/* Generic load_key function pointer */ +typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *, + UI_METHOD *ui_method, void *callback_data); +/* These callback types are for an ENGINE's handler for cipher and digest logic. + * These handlers have these prototypes; + * int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); + * int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid); + * Looking at how to implement these handlers in the case of cipher support, if + * the framework wants the EVP_CIPHER for 'nid', it will call; + * foo(e, &p_evp_cipher, NULL, nid); (return zero for failure) + * If the framework wants a list of supported 'nid's, it will call; + * foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error) + */ +/* Returns to a pointer to the array of supported cipher 'nid's. If the second + * parameter is non-NULL it is set to the size of the returned array. */ +typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int); +typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int); -/* STRUCTURE functions ... all of these functions deal with pointers to - * ENGINE structures where the pointers have a "structural reference". - * This means that their reference is to allow access to the structure - * but it does not imply that the structure is functional. To simply - * increment or decrement the structural reference count, use ENGINE_new - * and ENGINE_free. NB: This is not required when iterating using - * ENGINE_get_next as it will automatically decrement the structural - * reference count of the "current" ENGINE and increment the structural - * reference count of the ENGINE it returns (unless it is NULL). */ +/* STRUCTURE functions ... all of these functions deal with pointers to ENGINE + * structures where the pointers have a "structural reference". This means that + * their reference is to allowed access to the structure but it does not imply + * that the structure is functional. To simply increment or decrement the + * structural reference count, use ENGINE_by_id and ENGINE_free. NB: This is not + * required when iterating using ENGINE_get_next as it will automatically + * decrement the structural reference count of the "current" ENGINE and + * increment the structural reference count of the ENGINE it returns (unless it + * is NULL). */ /* Get the first/last "ENGINE" type available. */ ENGINE *ENGINE_get_first(void); @@ -151,67 +296,170 @@ int ENGINE_add(ENGINE *e); int ENGINE_remove(ENGINE *e); /* Retrieve an engine from the list by its unique "id" value. */ ENGINE *ENGINE_by_id(const char *id); +/* Add all the built-in engines. */ +void ENGINE_load_openssl(void); +void ENGINE_load_dynamic(void); +void ENGINE_load_cswift(void); +void ENGINE_load_chil(void); +void ENGINE_load_atalla(void); +void ENGINE_load_nuron(void); +void ENGINE_load_ubsec(void); +void ENGINE_load_aep(void); +void ENGINE_load_sureware(void); +void ENGINE_load_4758cca(void); +void ENGINE_load_openbsd_dev_crypto(void); +void ENGINE_load_builtin_engines(void); +#ifdef __OpenBSD__ +void ENGINE_load_cryptodev(void); +#endif + +/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation + * "registry" handling. */ +unsigned int ENGINE_get_table_flags(void); +void ENGINE_set_table_flags(unsigned int flags); -/* These functions are useful for manufacturing new ENGINE - * structures. They don't address reference counting at all - - * one uses them to populate an ENGINE structure with personalised - * implementations of things prior to using it directly or adding - * it to the builtin ENGINE list in OpenSSL. These are also here - * so that the ENGINE structure doesn't have to be exposed and - * break binary compatibility! - * - * NB: I'm changing ENGINE_new to force the ENGINE structure to - * be allocated from within OpenSSL. See the comment for - * ENGINE_get_struct_size(). - */ -#if 0 -ENGINE *ENGINE_new(ENGINE *e); -#else +/* Manage registration of ENGINEs per "table". For each type, there are 3 + * functions; + * ENGINE_register_***(e) - registers the implementation from 'e' (if it has one) + * ENGINE_unregister_***(e) - unregister the implementation from 'e' + * ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list + * Cleanup is automatically registered from each table when required, so + * ENGINE_cleanup() will reverse any "register" operations. */ + +int ENGINE_register_RSA(ENGINE *e); +void ENGINE_unregister_RSA(ENGINE *e); +void ENGINE_register_all_RSA(void); + +int ENGINE_register_DSA(ENGINE *e); +void ENGINE_unregister_DSA(ENGINE *e); +void ENGINE_register_all_DSA(void); + +int ENGINE_register_DH(ENGINE *e); +void ENGINE_unregister_DH(ENGINE *e); +void ENGINE_register_all_DH(void); + +int ENGINE_register_RAND(ENGINE *e); +void ENGINE_unregister_RAND(ENGINE *e); +void ENGINE_register_all_RAND(void); + +int ENGINE_register_ciphers(ENGINE *e); +void ENGINE_unregister_ciphers(ENGINE *e); +void ENGINE_register_all_ciphers(void); + +int ENGINE_register_digests(ENGINE *e); +void ENGINE_unregister_digests(ENGINE *e); +void ENGINE_register_all_digests(void); + +/* These functions register all support from the above categories. Note, use of + * these functions can result in static linkage of code your application may not + * need. If you only need a subset of functionality, consider using more + * selective initialisation. */ +int ENGINE_register_complete(ENGINE *e); +int ENGINE_register_all_complete(void); + +/* Send parametrised control commands to the engine. The possibilities to send + * down an integer, a pointer to data or a function pointer are provided. Any of + * the parameters may or may not be NULL, depending on the command number. In + * actuality, this function only requires a structural (rather than functional) + * reference to an engine, but many control commands may require the engine be + * functional. The caller should be aware of trying commands that require an + * operational ENGINE, and only use functional references in such situations. */ +int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); + +/* This function tests if an ENGINE-specific command is usable as a "setting". + * Eg. in an application's config file that gets processed through + * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to + * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). */ +int ENGINE_cmd_is_executable(ENGINE *e, int cmd); + +/* This function works like ENGINE_ctrl() with the exception of taking a + * command name instead of a command number, and can handle optional commands. + * See the comment on ENGINE_ctrl_cmd_string() for an explanation on how to + * use the cmd_name and cmd_optional. */ +int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, + long i, void *p, void (*f)(), int cmd_optional); + +/* This function passes a command-name and argument to an ENGINE. The cmd_name + * is converted to a command number and the control command is called using + * 'arg' as an argument (unless the ENGINE doesn't support such a command, in + * which case no control command is called). The command is checked for input + * flags, and if necessary the argument will be converted to a numeric value. If + * cmd_optional is non-zero, then if the ENGINE doesn't support the given + * cmd_name the return value will be success anyway. This function is intended + * for applications to use so that users (or config files) can supply + * engine-specific config data to the ENGINE at run-time to control behaviour of + * specific engines. As such, it shouldn't be used for calling ENGINE_ctrl() + * functions that return data, deal with binary data, or that are otherwise + * supposed to be used directly through ENGINE_ctrl() in application code. Any + * "return" data from an ENGINE_ctrl() operation in this function will be lost - + * the return value is interpreted as failure if the return value is zero, + * success otherwise, and this function returns a boolean value as a result. In + * other words, vendors of 'ENGINE'-enabled devices should write ENGINE + * implementations with parameterisations that work in this scheme, so that + * compliant ENGINE-based applications can work consistently with the same + * configuration for the same ENGINE-enabled devices, across applications. */ +int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, + int cmd_optional); + +/* These functions are useful for manufacturing new ENGINE structures. They + * don't address reference counting at all - one uses them to populate an ENGINE + * structure with personalised implementations of things prior to using it + * directly or adding it to the builtin ENGINE list in OpenSSL. These are also + * here so that the ENGINE structure doesn't have to be exposed and break binary + * compatibility! */ ENGINE *ENGINE_new(void); -#endif int ENGINE_free(ENGINE *e); int ENGINE_set_id(ENGINE *e, const char *id); int ENGINE_set_name(ENGINE *e, const char *name); -int ENGINE_set_RSA(ENGINE *e, RSA_METHOD *rsa_meth); -int ENGINE_set_DSA(ENGINE *e, DSA_METHOD *dsa_meth); -int ENGINE_set_DH(ENGINE *e, DH_METHOD *dh_meth); -int ENGINE_set_RAND(ENGINE *e, RAND_METHOD *rand_meth); -int ENGINE_set_BN_mod_exp(ENGINE *e, BN_MOD_EXP bn_mod_exp); -int ENGINE_set_BN_mod_exp_crt(ENGINE *e, BN_MOD_EXP_CRT bn_mod_exp_crt); +int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth); +int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth); +int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth); +int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth); +int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f); int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f); int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f); +int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f); +int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f); +int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f); +int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f); +int ENGINE_set_flags(ENGINE *e, int flags); +int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns); +/* These functions (and the "get" function lower down) allow control over any + * per-structure ENGINE data. */ +int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg); -/* These return values from within the ENGINE structure. These can - * be useful with functional references as well as structural - * references - it depends which you obtained. Using the result - * for functional purposes if you only obtained a structural - * reference may be problematic! */ -const char *ENGINE_get_id(ENGINE *e); -const char *ENGINE_get_name(ENGINE *e); -RSA_METHOD *ENGINE_get_RSA(ENGINE *e); -DSA_METHOD *ENGINE_get_DSA(ENGINE *e); -DH_METHOD *ENGINE_get_DH(ENGINE *e); -RAND_METHOD *ENGINE_get_RAND(ENGINE *e); -BN_MOD_EXP ENGINE_get_BN_mod_exp(ENGINE *e); -BN_MOD_EXP_CRT ENGINE_get_BN_mod_exp_crt(ENGINE *e); -ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(ENGINE *e); -ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(ENGINE *e); -ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(ENGINE *e); - -/* ENGINE_new is normally passed a NULL in the first parameter because - * the calling code doesn't have access to the definition of the ENGINE - * structure (for good reason). However, if the caller wishes to use - * its own memory allocation or use a static array, the following call - * should be used to check the amount of memory the ENGINE structure - * will occupy. This will make the code more future-proof. - * - * NB: I'm "#if 0"-ing this out because it's better to force the use of - * internally allocated memory. See similar change in ENGINE_new(). - */ -#if 0 -int ENGINE_get_struct_size(void); -#endif +/* This function cleans up anything that needs it. Eg. the ENGINE_add() function + * automatically ensures the list cleanup function is registered to be called + * from ENGINE_cleanup(). Similarly, all ENGINE_register_*** functions ensure + * ENGINE_cleanup() will clean up after them. */ +void ENGINE_cleanup(void); + +/* These return values from within the ENGINE structure. These can be useful + * with functional references as well as structural references - it depends + * which you obtained. Using the result for functional purposes if you only + * obtained a structural reference may be problematic! */ +const char *ENGINE_get_id(const ENGINE *e); +const char *ENGINE_get_name(const ENGINE *e); +const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e); +const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e); +const DH_METHOD *ENGINE_get_DH(const ENGINE *e); +const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e); +ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e); +ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e); +ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e); +ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e); +ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e); +const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid); +const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid); +const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e); +int ENGINE_get_flags(const ENGINE *e); +void *ENGINE_get_ex_data(const ENGINE *e, int idx); /* FUNCTIONAL functions. These functions deal with ENGINE structures * that have (or will) be initialised for use. Broadly speaking, the @@ -233,20 +481,14 @@ int ENGINE_init(ENGINE *e); * a corresponding call to ENGINE_free as it also releases a structural * reference. */ int ENGINE_finish(ENGINE *e); -/* Send control parametrised commands to the engine. The possibilities - * to send down an integer, a pointer to data or a function pointer are - * provided. Any of the parameters may or may not be NULL, depending - * on the command number */ -/* WARNING: This is currently experimental and may change radically! */ -int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); /* The following functions handle keys that are stored in some secondary * location, handled by the engine. The storage may be on a card or * whatever. */ EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, - const char *passphrase); + UI_METHOD *ui_method, void *callback_data); EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, - const char *passphrase); + UI_METHOD *ui_method, void *callback_data); /* This returns a pointer for the current ENGINE structure that * is (by default) performing any RSA operations. The value returned @@ -257,117 +499,192 @@ ENGINE *ENGINE_get_default_RSA(void); ENGINE *ENGINE_get_default_DSA(void); ENGINE *ENGINE_get_default_DH(void); ENGINE *ENGINE_get_default_RAND(void); -ENGINE *ENGINE_get_default_BN_mod_exp(void); -ENGINE *ENGINE_get_default_BN_mod_exp_crt(void); +/* These functions can be used to get a functional reference to perform + * ciphering or digesting corresponding to "nid". */ +ENGINE *ENGINE_get_cipher_engine(int nid); +ENGINE *ENGINE_get_digest_engine(int nid); /* This sets a new default ENGINE structure for performing RSA * operations. If the result is non-zero (success) then the ENGINE * structure will have had its reference count up'd so the caller * should still free their own reference 'e'. */ int ENGINE_set_default_RSA(ENGINE *e); +int ENGINE_set_default_string(ENGINE *e, const char *list); /* Same for the other "methods" */ int ENGINE_set_default_DSA(ENGINE *e); int ENGINE_set_default_DH(ENGINE *e); int ENGINE_set_default_RAND(ENGINE *e); -int ENGINE_set_default_BN_mod_exp(ENGINE *e); -int ENGINE_set_default_BN_mod_exp_crt(ENGINE *e); +int ENGINE_set_default_ciphers(ENGINE *e); +int ENGINE_set_default_digests(ENGINE *e); /* The combination "set" - the flags are bitwise "OR"d from the - * ENGINE_METHOD_*** defines above. */ + * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()" + * function, this function can result in unnecessary static linkage. If your + * application requires only specific functionality, consider using more + * selective functions. */ int ENGINE_set_default(ENGINE *e, unsigned int flags); -/* Obligatory error function. */ -void ERR_load_ENGINE_strings(void); +void ENGINE_add_conf_module(void); -/* - * Error codes for all engine functions. NB: We use "generic" - * function names instead of per-implementation ones because this - * levels the playing field for externally implemented bootstrapped - * support code. As the filename and line number is included, it's - * more important to indicate the type of function, so that - * bootstrapped code (that can't easily add its own errors in) can - * use the same error codes too. - */ +/* Deprecated functions ... */ +/* int ENGINE_clear_defaults(void); */ + +/**************************/ +/* DYNAMIC ENGINE SUPPORT */ +/**************************/ + +/* Binary/behaviour compatibility levels */ +#define OSSL_DYNAMIC_VERSION (unsigned long)0x00010100 +/* Binary versions older than this are too old for us (whether we're a loader or + * a loadee) */ +#define OSSL_DYNAMIC_OLDEST (unsigned long)0x00010100 + +/* When compiling an ENGINE entirely as an external shared library, loadable by + * the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' structure + * type provides the calling application's (or library's) error functionality + * and memory management function pointers to the loaded library. These should + * be used/set in the loaded library code so that the loading application's + * 'state' will be used/changed in all operations. */ +typedef void *(*dyn_MEM_malloc_cb)(size_t); +typedef void *(*dyn_MEM_realloc_cb)(void *, size_t); +typedef void (*dyn_MEM_free_cb)(void *); +typedef struct st_dynamic_MEM_fns { + dyn_MEM_malloc_cb malloc_cb; + dyn_MEM_realloc_cb realloc_cb; + dyn_MEM_free_cb free_cb; + } dynamic_MEM_fns; +/* FIXME: Perhaps the memory and locking code (crypto.h) should declare and use + * these types so we (and any other dependant code) can simplify a bit?? */ +typedef void (*dyn_lock_locking_cb)(int,int,const char *,int); +typedef int (*dyn_lock_add_lock_cb)(int*,int,int,const char *,int); +typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb)( + const char *,int); +typedef void (*dyn_dynlock_lock_cb)(int,struct CRYPTO_dynlock_value *, + const char *,int); +typedef void (*dyn_dynlock_destroy_cb)(struct CRYPTO_dynlock_value *, + const char *,int); +typedef struct st_dynamic_LOCK_fns { + dyn_lock_locking_cb lock_locking_cb; + dyn_lock_add_lock_cb lock_add_lock_cb; + dyn_dynlock_create_cb dynlock_create_cb; + dyn_dynlock_lock_cb dynlock_lock_cb; + dyn_dynlock_destroy_cb dynlock_destroy_cb; + } dynamic_LOCK_fns; +/* The top-level structure */ +typedef struct st_dynamic_fns { + const ERR_FNS *err_fns; + const CRYPTO_EX_DATA_IMPL *ex_data_fns; + dynamic_MEM_fns mem_fns; + dynamic_LOCK_fns lock_fns; + } dynamic_fns; + +/* The version checking function should be of this prototype. NB: The + * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading code. + * If this function returns zero, it indicates a (potential) version + * incompatibility and the loaded library doesn't believe it can proceed. + * Otherwise, the returned value is the (latest) version supported by the + * loading library. The loader may still decide that the loaded code's version + * is unsatisfactory and could veto the load. The function is expected to + * be implemented with the symbol name "v_check", and a default implementation + * can be fully instantiated with IMPLEMENT_DYNAMIC_CHECK_FN(). */ +typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version); +#define IMPLEMENT_DYNAMIC_CHECK_FN() \ + unsigned long v_check(unsigned long v) { \ + if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \ + return 0; } + +/* This function is passed the ENGINE structure to initialise with its own + * function and command settings. It should not adjust the structural or + * functional reference counts. If this function returns zero, (a) the load will + * be aborted, (b) the previous ENGINE state will be memcpy'd back onto the + * structure, and (c) the shared library will be unloaded. So implementations + * should do their own internal cleanup in failure circumstances otherwise they + * could leak. The 'id' parameter, if non-NULL, represents the ENGINE id that + * the loader is looking for. If this is NULL, the shared library can choose to + * return failure or to initialise a 'default' ENGINE. If non-NULL, the shared + * library must initialise only an ENGINE matching the passed 'id'. The function + * is expected to be implemented with the symbol name "bind_engine". A standard + * implementation can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where + * the parameter 'fn' is a callback function that populates the ENGINE structure + * and returns an int value (zero for failure). 'fn' should have prototype; + * [static] int fn(ENGINE *e, const char *id); */ +typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id, + const dynamic_fns *fns); +#define IMPLEMENT_DYNAMIC_BIND_FN(fn) \ + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \ + if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \ + fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \ + return 0; \ + CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \ + CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \ + CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \ + CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \ + CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \ + if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \ + return 0; \ + if(!ERR_set_implementation(fns->err_fns)) return 0; \ + if(!fn(e,id)) return 0; \ + return 1; } /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. */ +void ERR_load_ENGINE_strings(void); /* Error codes for the ENGINE functions. */ /* Function codes. */ -#define ENGINE_F_ATALLA_FINISH 135 -#define ENGINE_F_ATALLA_INIT 136 -#define ENGINE_F_ATALLA_MOD_EXP 137 -#define ENGINE_F_ATALLA_RSA_MOD_EXP 138 -#define ENGINE_F_CSWIFT_DSA_SIGN 133 -#define ENGINE_F_CSWIFT_DSA_VERIFY 134 -#define ENGINE_F_CSWIFT_FINISH 100 -#define ENGINE_F_CSWIFT_INIT 101 -#define ENGINE_F_CSWIFT_MOD_EXP 102 -#define ENGINE_F_CSWIFT_MOD_EXP_CRT 103 -#define ENGINE_F_CSWIFT_RSA_MOD_EXP 104 +#define ENGINE_F_DYNAMIC_CTRL 180 +#define ENGINE_F_DYNAMIC_GET_DATA_CTX 181 +#define ENGINE_F_DYNAMIC_LOAD 182 #define ENGINE_F_ENGINE_ADD 105 #define ENGINE_F_ENGINE_BY_ID 106 +#define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170 #define ENGINE_F_ENGINE_CTRL 142 +#define ENGINE_F_ENGINE_CTRL_CMD 178 +#define ENGINE_F_ENGINE_CTRL_CMD_STRING 171 #define ENGINE_F_ENGINE_FINISH 107 #define ENGINE_F_ENGINE_FREE 108 -#define ENGINE_F_ENGINE_GET_BN_MOD_EXP 109 -#define ENGINE_F_ENGINE_GET_BN_MOD_EXP_CRT 110 -#define ENGINE_F_ENGINE_GET_CTRL_FUNCTION 144 -#define ENGINE_F_ENGINE_GET_DH 111 -#define ENGINE_F_ENGINE_GET_DSA 112 -#define ENGINE_F_ENGINE_GET_FINISH_FUNCTION 145 -#define ENGINE_F_ENGINE_GET_ID 113 -#define ENGINE_F_ENGINE_GET_INIT_FUNCTION 146 -#define ENGINE_F_ENGINE_GET_NAME 114 +#define ENGINE_F_ENGINE_GET_CIPHER 185 +#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177 +#define ENGINE_F_ENGINE_GET_DIGEST 186 #define ENGINE_F_ENGINE_GET_NEXT 115 #define ENGINE_F_ENGINE_GET_PREV 116 -#define ENGINE_F_ENGINE_GET_RAND 117 -#define ENGINE_F_ENGINE_GET_RSA 118 #define ENGINE_F_ENGINE_INIT 119 #define ENGINE_F_ENGINE_LIST_ADD 120 #define ENGINE_F_ENGINE_LIST_REMOVE 121 #define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 #define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 +#define ENGINE_F_ENGINE_MODULE_INIT 187 #define ENGINE_F_ENGINE_NEW 122 #define ENGINE_F_ENGINE_REMOVE 123 -#define ENGINE_F_ENGINE_SET_BN_MOD_EXP 124 -#define ENGINE_F_ENGINE_SET_BN_MOD_EXP_CRT 125 -#define ENGINE_F_ENGINE_SET_CTRL_FUNCTION 147 +#define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189 #define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126 -#define ENGINE_F_ENGINE_SET_DH 127 -#define ENGINE_F_ENGINE_SET_DSA 128 -#define ENGINE_F_ENGINE_SET_FINISH_FUNCTION 148 #define ENGINE_F_ENGINE_SET_ID 129 -#define ENGINE_F_ENGINE_SET_INIT_FUNCTION 149 #define ENGINE_F_ENGINE_SET_NAME 130 -#define ENGINE_F_ENGINE_SET_RAND 131 -#define ENGINE_F_ENGINE_SET_RSA 132 +#define ENGINE_F_ENGINE_TABLE_REGISTER 184 #define ENGINE_F_ENGINE_UNLOAD_KEY 152 -#define ENGINE_F_HWCRHK_CTRL 143 -#define ENGINE_F_HWCRHK_FINISH 135 -#define ENGINE_F_HWCRHK_GET_PASS 155 -#define ENGINE_F_HWCRHK_INIT 136 -#define ENGINE_F_HWCRHK_LOAD_PRIVKEY 153 -#define ENGINE_F_HWCRHK_LOAD_PUBKEY 154 -#define ENGINE_F_HWCRHK_MOD_EXP 137 -#define ENGINE_F_HWCRHK_MOD_EXP_CRT 138 -#define ENGINE_F_HWCRHK_RAND_BYTES 139 -#define ENGINE_F_HWCRHK_RSA_MOD_EXP 140 +#define ENGINE_F_INT_CTRL_HELPER 172 +#define ENGINE_F_INT_ENGINE_CONFIGURE 188 #define ENGINE_F_LOG_MESSAGE 141 +#define ENGINE_F_SET_DATA_CTX 183 /* Reason codes. */ #define ENGINE_R_ALREADY_LOADED 100 -#define ENGINE_R_BIO_WAS_FREED 121 -#define ENGINE_R_BN_CTX_FULL 101 -#define ENGINE_R_BN_EXPAND_FAIL 102 -#define ENGINE_R_CHIL_ERROR 123 +#define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER 133 +#define ENGINE_R_CMD_NOT_EXECUTABLE 134 +#define ENGINE_R_COMMAND_TAKES_INPUT 135 +#define ENGINE_R_COMMAND_TAKES_NO_INPUT 136 #define ENGINE_R_CONFLICTING_ENGINE_ID 103 #define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119 +#define ENGINE_R_DH_NOT_IMPLEMENTED 139 +#define ENGINE_R_DSA_NOT_IMPLEMENTED 140 #define ENGINE_R_DSO_FAILURE 104 +#define ENGINE_R_DSO_NOT_FOUND 132 +#define ENGINE_R_ENGINES_SECTION_ERROR 148 #define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105 +#define ENGINE_R_ENGINE_SECTION_ERROR 149 #define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128 #define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129 #define ENGINE_R_FINISH_FAILED 106 @@ -375,24 +692,26 @@ void ERR_load_ENGINE_strings(void); #define ENGINE_R_ID_OR_NAME_MISSING 108 #define ENGINE_R_INIT_FAILED 109 #define ENGINE_R_INTERNAL_LIST_ERROR 110 -#define ENGINE_R_MISSING_KEY_COMPONENTS 111 +#define ENGINE_R_INVALID_ARGUMENT 143 +#define ENGINE_R_INVALID_CMD_NAME 137 +#define ENGINE_R_INVALID_CMD_NUMBER 138 +#define ENGINE_R_INVALID_INIT_VALUE 151 +#define ENGINE_R_INVALID_STRING 150 #define ENGINE_R_NOT_INITIALISED 117 #define ENGINE_R_NOT_LOADED 112 -#define ENGINE_R_NO_CALLBACK 127 #define ENGINE_R_NO_CONTROL_FUNCTION 120 -#define ENGINE_R_NO_KEY 124 +#define ENGINE_R_NO_INDEX 144 #define ENGINE_R_NO_LOAD_FUNCTION 125 #define ENGINE_R_NO_REFERENCE 130 #define ENGINE_R_NO_SUCH_ENGINE 116 #define ENGINE_R_NO_UNLOAD_FUNCTION 126 #define ENGINE_R_PROVIDE_PARAMETERS 113 -#define ENGINE_R_REQUEST_FAILED 114 -#define ENGINE_R_REQUEST_FALLBACK 118 -#define ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL 122 -#define ENGINE_R_UNIT_FAILURE 115 +#define ENGINE_R_RSA_NOT_IMPLEMENTED 141 +#define ENGINE_R_UNIMPLEMENTED_CIPHER 146 +#define ENGINE_R_UNIMPLEMENTED_DIGEST 147 +#define ENGINE_R_VERSION_INCOMPATIBILITY 145 #ifdef __cplusplus } #endif #endif - diff --git a/src/lib/libcrypto/engine/enginetest.c b/src/lib/libcrypto/engine/enginetest.c index a5a3c47fcb..87fa8c57b7 100644 --- a/src/lib/libcrypto/engine/enginetest.c +++ b/src/lib/libcrypto/engine/enginetest.c @@ -3,7 +3,7 @@ * project 2000. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * 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 @@ -56,8 +56,11 @@ * */ +#include #include #include +#include +#include #include #include @@ -76,6 +79,9 @@ static void display_engine_list() h = ENGINE_get_next(h); } printf("end of list\n"); + /* ENGINE_get_first() increases the struct_ref counter, so we + must call ENGINE_free() to decrease it again */ + ENGINE_free(h); } int main(int argc, char *argv[]) @@ -91,6 +97,18 @@ int main(int argc, char *argv[]) ENGINE *new_h3 = NULL; ENGINE *new_h4 = NULL; + /* enable memory leak checking unless explicitly disabled */ + if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) + { + CRYPTO_malloc_debug_init(); + CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); + } + else + { + /* OPENSSL_DEBUG_MEMORY=off */ + CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); + } + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); ERR_load_crypto_strings(); memset(block, 0, 512 * sizeof(ENGINE *)); @@ -124,6 +142,8 @@ int main(int argc, char *argv[]) printf("Remove failed!\n"); goto end; } + if (ptr) + ENGINE_free(ptr); display_engine_list(); if(!ENGINE_add(new_h3) || !ENGINE_add(new_h2)) { @@ -158,12 +178,7 @@ int main(int argc, char *argv[]) } else printf("Remove that should fail did.\n"); - if(!ENGINE_remove(new_h1)) - { - printf("Remove failed!\n"); - goto end; - } - display_engine_list(); + ERR_clear_error(); if(!ENGINE_remove(new_h3)) { printf("Remove failed!\n"); @@ -183,6 +198,8 @@ int main(int argc, char *argv[]) if(!ENGINE_remove(ptr)) printf("Remove failed!i - probably no hardware " "support present.\n"); + if (ptr) + ENGINE_free(ptr); display_engine_list(); if(!ENGINE_add(new_h1) || !ENGINE_remove(new_h1)) { @@ -195,9 +212,9 @@ int main(int argc, char *argv[]) for(loop = 0; loop < 512; loop++) { sprintf(buf, "id%i", loop); - id = strdup(buf); + id = BUF_strdup(buf); sprintf(buf, "Fake engine type %i", loop); - name = strdup(buf); + name = BUF_strdup(buf); if(((block[loop] = ENGINE_new()) == NULL) || !ENGINE_set_id(block[loop], id) || !ENGINE_set_name(block[loop], name)) @@ -228,12 +245,13 @@ cleanup_loop: printf("\nRemove failed!\n"); goto end; } + ENGINE_free(ptr); printf("."); fflush(stdout); } for(loop = 0; loop < 512; loop++) { - free((char *)(ENGINE_get_id(block[loop]))); - free((char *)(ENGINE_get_name(block[loop]))); + OPENSSL_free((void *)ENGINE_get_id(block[loop])); + OPENSSL_free((void *)ENGINE_get_name(block[loop])); } printf("\nTests completed happily\n"); to_return = 0; @@ -247,5 +265,10 @@ end: for(loop = 0; loop < 512; loop++) if(block[loop]) ENGINE_free(block[loop]); + ENGINE_cleanup(); + CRYPTO_cleanup_all_ex_data(); + ERR_free_strings(); + ERR_remove_state(0); + CRYPTO_mem_leaks_fp(stderr); return to_return; } diff --git a/src/lib/libcrypto/engine/hw.ec b/src/lib/libcrypto/engine/hw.ec new file mode 100644 index 0000000000..5481a43918 --- /dev/null +++ b/src/lib/libcrypto/engine/hw.ec @@ -0,0 +1,8 @@ +L AEPHK hw_aep_err.h hw_aep_err.c +L ATALLA hw_atalla_err.h hw_atalla_err.c +L CSWIFT hw_cswift_err.h hw_cswift_err.c +L HWCRHK hw_ncipher_err.h hw_ncipher_err.c +L NURON hw_nuron_err.h hw_nuron_err.c +L SUREWARE hw_sureware_err.h hw_sureware_err.c +L UBSEC hw_ubsec_err.h hw_ubsec_err.c +L CCA4758 hw_4758_cca_err.h hw_4758_cca_err.c diff --git a/src/lib/libcrypto/engine/hw_4758_cca.c b/src/lib/libcrypto/engine/hw_4758_cca.c new file mode 100644 index 0000000000..959d8f1a61 --- /dev/null +++ b/src/lib/libcrypto/engine/hw_4758_cca.c @@ -0,0 +1,950 @@ +/* Author: Maurice Gittens */ +/* ==================================================================== + * 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 +#include +/* #include */ +#include "cryptlib.h" +#include +#include +#include +#include + +#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 "hw_4758_cca_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)()); + +/* 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); + +static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, + int idx,long argl, void *argp); + +/* 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 def_CCA4758_LIB_NAME[] = CCA_LIB_NAME; +static const char *CCA4758_LIB_NAME = def_CCA4758_LIB_NAME; +#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; + +static int hndidx = -1; +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 */ + }; +#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"; + +/* 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) || + !ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) || + !ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) || + !ENGINE_set_cmd_defns(e, cca4758_cmd_defns)) + return 0; + /* Ensure the error handling is set up */ + ERR_load_CCA4758_strings(); + return 1; + } + +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(); + } + +static int ibm_4758_cca_destroy(ENGINE *e) + { + ERR_unload_CCA4758_strings(); + 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, 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 + + hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle", + NULL, NULL, cca_ex_free); + + return 1; +err: + if(dso) + DSO_free(dso); + dso = NULL; + + keyRecordRead = (F_KEYRECORDREAD)NULL; + randomNumberGenerate = (F_RANDOMNUMBERGENERATE)NULL; + digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)NULL; + digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)NULL; + publicKeyExtract = (F_PUBLICKEYEXTRACT)NULL; + pkaEncrypt = (F_PKAENCRYPT)NULL; + pkaDecrypt = (F_PKADECRYPT)NULL; + return 0; + } + +static int ibm_4758_cca_finish(ENGINE *e) + { + 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; + keyRecordRead = (F_KEYRECORDREAD)NULL; + randomNumberGenerate = (F_RANDOMNUMBERGENERATE)NULL; + digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)NULL; + digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)NULL; + publicKeyExtract = (F_PUBLICKEYEXTRACT)NULL; + pkaEncrypt = (F_PKAENCRYPT)NULL; + pkaDecrypt = (F_PKADECRYPT)NULL; + return 1; + } + +static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) + { + 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; + } + CCA4758_LIB_NAME = (const char *)p; + return 1; + 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]; + 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_CCA_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_CCA_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_CCA_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_CCA_LOAD_PRIVKEY, + CCA4758_R_FAILED_LOADING_PRIVATE_KEY); + goto err; + } + + if (!getModulusAndExponent(pubKeyToken, &exponentLength, + exponent, &modulusLength, &modulusFieldLength, + modulus)) + { + CCA4758err(CCA4758_F_IBM_4758_CCA_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]; + 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_CCA_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_CCA_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_CCA_LOAD_PRIVKEY, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!getModulusAndExponent(keyToken+sizeof(long), &exponentLength, + exponent, &modulusLength, &modulusFieldLength, modulus)) + { + CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY, + 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_IBM_4758_CCA_VERIFY, + CCA4758_R_UNKNOWN_ALGORITHM_TYPE); + return 0; + } + + if (!algorithm.algorithm->length) + { + CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY, + CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); + return 0; + } + + parameter.type = V_ASN1_NULL; + parameter.value.ptr = NULL; + algorithm.parameter = ¶meter; + + 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_IBM_4758_CCA_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_IBM_4758_CCA_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_IBM_4758_CCA_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_IBM_4758_CCA_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) + { + memset(hashBuffer, keyLength+1, 0); + 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_IBM_4758_CCA_SIGN, + CCA4758_R_UNKNOWN_ALGORITHM_TYPE); + return 0; + } + + if (!algorithm.algorithm->length) + { + CCA4758err(CCA4758_F_IBM_4758_CCA_SIGN, + CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); + return 0; + } + + parameter.type = V_ASN1_NULL; + parameter.value.ptr = NULL; + algorithm.parameter = ¶meter; + + 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_IBM_4758_CCA_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_IBM_4758_CCA_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_IBM_4758_CCA_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_IBM_4758_CCA_VERIFY, + 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) + { + memset(hashBuffer, keyLength+1, 0); + 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 >= 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; + } + +static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx, + long argl, void *argp) + { + if (item) + OPENSSL_free(item); + } + +/* Goo to handle building as a dynamic engine */ +#ifdef ENGINE_DYNAMIC_SUPPORT +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 /* ENGINE_DYNAMIC_SUPPORT */ + +#endif /* !OPENSSL_NO_HW_4758_CCA */ +#endif /* !OPENSSL_NO_HW */ diff --git a/src/lib/libcrypto/engine/hw_4758_cca_err.c b/src/lib/libcrypto/engine/hw_4758_cca_err.c new file mode 100644 index 0000000000..7ea5c63707 --- /dev/null +++ b/src/lib/libcrypto/engine/hw_4758_cca_err.c @@ -0,0 +1,149 @@ +/* hw_4758_cca_err.c */ +/* ==================================================================== + * Copyright (c) 1999-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). + * + */ + +/* 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 +#include +#include "hw_4758_cca_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR +static ERR_STRING_DATA CCA4758_str_functs[]= + { +{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_CTRL,0), "IBM_4758_CCA_CTRL"}, +{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_FINISH,0), "IBM_4758_CCA_FINISH"}, +{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_INIT,0), "IBM_4758_CCA_INIT"}, +{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,0), "IBM_4758_CCA_LOAD_PRIVKEY"}, +{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_LOAD_PUBKEY,0), "IBM_4758_CCA_LOAD_PUBKEY"}, +{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_SIGN,0), "IBM_4758_CCA_SIGN"}, +{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_VERIFY,0), "IBM_4758_CCA_VERIFY"}, +{0,NULL} + }; + +static ERR_STRING_DATA CCA4758_str_reasons[]= + { +{CCA4758_R_ALREADY_LOADED ,"already loaded"}, +{CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD ,"asn1 oid unknown for md"}, +{CCA4758_R_COMMAND_NOT_IMPLEMENTED ,"command not implemented"}, +{CCA4758_R_DSO_FAILURE ,"dso failure"}, +{CCA4758_R_FAILED_LOADING_PRIVATE_KEY ,"failed loading private key"}, +{CCA4758_R_FAILED_LOADING_PUBLIC_KEY ,"failed loading public key"}, +{CCA4758_R_NOT_LOADED ,"not loaded"}, +{CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"}, +{CCA4758_R_UNIT_FAILURE ,"unit failure"}, +{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/src/lib/libcrypto/engine/hw_4758_cca_err.h b/src/lib/libcrypto/engine/hw_4758_cca_err.h new file mode 100644 index 0000000000..2fc563ab11 --- /dev/null +++ b/src/lib/libcrypto/engine/hw_4758_cca_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_CCA4758_ERR_H +#define HEADER_CCA4758_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_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_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_CCA_LOAD_PRIVKEY 103 +#define CCA4758_F_IBM_4758_CCA_LOAD_PUBKEY 104 +#define CCA4758_F_IBM_4758_CCA_SIGN 105 +#define CCA4758_F_IBM_4758_CCA_VERIFY 106 + +/* 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/src/lib/libcrypto/engine/hw_aep.c b/src/lib/libcrypto/engine/hw_aep.c new file mode 100644 index 0000000000..cf4507cff1 --- /dev/null +++ b/src/lib/libcrypto/engine/hw_aep.c @@ -0,0 +1,1101 @@ +/* crypto/engine/hw_aep.c */ +/* + */ +/* ==================================================================== + * 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 +#include +#include + +#include +#ifndef OPENSSL_SYS_MSDOS +#include +#include +#else +#include +typedef int pid_t; +#endif + +#include +#include +#include + +#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 "hw_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)()); +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 */ +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); + +/* RSA stuff */ +#ifndef OPENSSL_NO_RSA +static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa); +#endif + +/* 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); + +/* 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*/ + }; +#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 */ + }; +#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 + }; +#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; +} + +#ifdef ENGINE_DYNAMIC_SUPPORT +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 = "aep"; + +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, 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); + + 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) + { + 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)()) + { + 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; + } + AEP_LIBNAME = (const char *)p; + return 1; + 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_RAND,AEPHK_R_RETURN_CONNECTION_FAILED); + goto err; + } + + to_return = 1; + err: + return to_return; + } + +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_RAND,AEPHK_R_RETURN_CONNECTION_FAILED); + goto err; + } + + err: + return rv; + } + + +#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 = NULL; + int to_return = 0; + AEP_RV rv = AEP_R_OK; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + 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); + 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: + if(ctx) + BN_CTX_free(ctx); + 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 + +/* 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); + } + +#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); + + curr_pid = getpid(); + + /*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;itop;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;itop;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/src/lib/libcrypto/engine/hw_aep_err.c b/src/lib/libcrypto/engine/hw_aep_err.c new file mode 100644 index 0000000000..092f532946 --- /dev/null +++ b/src/lib/libcrypto/engine/hw_aep_err.c @@ -0,0 +1,157 @@ +/* hw_aep_err.c */ +/* ==================================================================== + * 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 + * 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 +#include +#include "hw_aep_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR +static ERR_STRING_DATA AEPHK_str_functs[]= + { +{ERR_PACK(0,AEPHK_F_AEP_CTRL,0), "AEP_CTRL"}, +{ERR_PACK(0,AEPHK_F_AEP_FINISH,0), "AEP_FINISH"}, +{ERR_PACK(0,AEPHK_F_AEP_GET_CONNECTION,0), "AEP_GET_CONNECTION"}, +{ERR_PACK(0,AEPHK_F_AEP_INIT,0), "AEP_INIT"}, +{ERR_PACK(0,AEPHK_F_AEP_MOD_EXP,0), "AEP_MOD_EXP"}, +{ERR_PACK(0,AEPHK_F_AEP_MOD_EXP_CRT,0), "AEP_MOD_EXP_CRT"}, +{ERR_PACK(0,AEPHK_F_AEP_RAND,0), "AEP_RAND"}, +{ERR_PACK(0,AEPHK_F_AEP_RSA_MOD_EXP,0), "AEP_RSA_MOD_EXP"}, +{0,NULL} + }; + +static ERR_STRING_DATA AEPHK_str_reasons[]= + { +{AEPHK_R_ALREADY_LOADED ,"already loaded"}, +{AEPHK_R_CLOSE_HANDLES_FAILED ,"close handles failed"}, +{AEPHK_R_CONNECTIONS_IN_USE ,"connections in use"}, +{AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"}, +{AEPHK_R_FINALIZE_FAILED ,"finalize failed"}, +{AEPHK_R_GET_HANDLE_FAILED ,"get handle failed"}, +{AEPHK_R_GET_RANDOM_FAILED ,"get random failed"}, +{AEPHK_R_INIT_FAILURE ,"init failure"}, +{AEPHK_R_MISSING_KEY_COMPONENTS ,"missing key components"}, +{AEPHK_R_MOD_EXP_CRT_FAILED ,"mod exp crt failed"}, +{AEPHK_R_MOD_EXP_FAILED ,"mod exp failed"}, +{AEPHK_R_NOT_LOADED ,"not loaded"}, +{AEPHK_R_OK ,"ok"}, +{AEPHK_R_RETURN_CONNECTION_FAILED ,"return connection failed"}, +{AEPHK_R_SETBNCALLBACK_FAILURE ,"setbncallback failure"}, +{AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"}, +{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/src/lib/libcrypto/engine/hw_aep_err.h b/src/lib/libcrypto/engine/hw_aep_err.h new file mode 100644 index 0000000000..8fe4cf921f --- /dev/null +++ b/src/lib/libcrypto/engine/hw_aep_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_AEPHK_ERR_H +#define HEADER_AEPHK_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_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/src/lib/libcrypto/engine/hw_atalla.c b/src/lib/libcrypto/engine/hw_atalla.c index 3bb992a193..696cfcf156 100644 --- a/src/lib/libcrypto/engine/hw_atalla.c +++ b/src/lib/libcrypto/engine/hw_atalla.c @@ -3,7 +3,7 @@ * project 2000. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * 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 @@ -60,11 +60,10 @@ #include #include "cryptlib.h" #include -#include "engine_int.h" #include -#ifndef NO_HW -#ifndef NO_HW_ATALLA +#ifndef OPENSSL_NO_HW +#ifndef OPENSSL_NO_HW_ATALLA #ifdef FLAT_INC #include "atalla.h" @@ -72,19 +71,27 @@ #include "vendor_defns/atalla.h" #endif -static int atalla_init(void); -static int atalla_finish(void); +#define ATALLA_LIB_NAME "atalla engine" +#include "hw_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)()); /* BIGNUM stuff */ -static int atalla_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, +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, BIGNUM *I, RSA *rsa); +static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa); +#endif /* This function is aliased to mod_exp (with the mont stuff dropped). */ -static int atalla_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, +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); +#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, @@ -92,13 +99,27 @@ static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, 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(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, +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 = { @@ -116,7 +137,9 @@ static RSA_METHOD atalla_rsa = NULL, NULL }; +#endif +#ifndef OPENSSL_NO_DSA /* Our internal DSA_METHOD that we provide pointers to */ static DSA_METHOD atalla_dsa = { @@ -131,7 +154,9 @@ static DSA_METHOD atalla_dsa = 0, /* flags */ NULL /* app_data */ }; +#endif +#ifndef OPENSSL_NO_DH /* Our internal DH_METHOD that we provide pointers to */ static DH_METHOD atalla_dh = { @@ -144,36 +169,44 @@ static DH_METHOD atalla_dh = 0, NULL }; +#endif -/* Our ENGINE structure. */ -static ENGINE engine_atalla = - { - "atalla", - "Atalla hardware engine support", - &atalla_rsa, - &atalla_dsa, - &atalla_dh, - NULL, - atalla_mod_exp, - NULL, - atalla_init, - atalla_finish, - NULL, /* no ctrl() */ - NULL, /* no load_privkey() */ - NULL, /* no load_pubkey() */ - 0, /* no flags */ - 0, 0, /* no references */ - NULL, NULL /* unlinked */ - }; - -/* As this is only ever called once, there's no need for locking - * (indeed - the lock will already be held by our caller!!!) */ -ENGINE *ENGINE_atalla() +/* 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) { - RSA_METHOD *meth1; - DSA_METHOD *meth2; - DH_METHOD *meth3; +#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 @@ -186,19 +219,50 @@ ENGINE *ENGINE_atalla() 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; - return &engine_atalla; +#endif + + /* Ensure the atalla error handling is set up */ + ERR_load_ATALLA_strings(); + return 1; + } + +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(); } /* This is a process-global DSO handle used for loading and unloading @@ -214,8 +278,32 @@ 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 def_ATALLA_LIBNAME[] = "atasi"; +static const char *ATALLA_LIBNAME = def_ATALLA_LIBNAME; +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) + { + /* 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() +static int atalla_init(ENGINE *e) { tfnASI_GetHardwareConfig *p1; tfnASI_RSAPrivateKeyOpFn *p2; @@ -226,7 +314,7 @@ static int atalla_init() if(atalla_dso != NULL) { - ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_ALREADY_LOADED); + ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_ALREADY_LOADED); goto err; } /* Attempt to load libatasi.so/atasi.dll/whatever. Needs to be @@ -236,11 +324,10 @@ static int atalla_init() * 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, ATALLA_LIBNAME, NULL, - DSO_FLAG_NAME_TRANSLATION); + atalla_dso = DSO_load(NULL, ATALLA_LIBNAME, NULL, 0); if(atalla_dso == NULL) { - ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_DSO_FAILURE); + ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_NOT_LOADED); goto err; } if(!(p1 = (tfnASI_GetHardwareConfig *)DSO_bind_func( @@ -250,7 +337,7 @@ static int atalla_init() !(p3 = (tfnASI_GetPerformanceStatistics *)DSO_bind_func( atalla_dso, ATALLA_F3))) { - ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_DSO_FAILURE); + ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_NOT_LOADED); goto err; } /* Copy the pointers */ @@ -261,7 +348,7 @@ static int atalla_init() * running. */ if(p1(0L, config_buf) != 0) { - ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_UNIT_FAILURE); + ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_UNIT_FAILURE); goto err; } /* Everything's fine. */ @@ -275,16 +362,16 @@ err: return 0; } -static int atalla_finish() +static int atalla_finish(ENGINE *e) { if(atalla_dso == NULL) { - ENGINEerr(ENGINE_F_ATALLA_FINISH,ENGINE_R_NOT_LOADED); + ATALLAerr(ATALLA_F_ATALLA_FINISH,ATALLA_R_NOT_LOADED); return 0; } if(!DSO_free(atalla_dso)) { - ENGINEerr(ENGINE_F_ATALLA_FINISH,ENGINE_R_DSO_FAILURE); + ATALLAerr(ATALLA_F_ATALLA_FINISH,ATALLA_R_UNIT_FAILURE); return 0; } atalla_dso = NULL; @@ -294,7 +381,32 @@ static int atalla_finish() return 1; } -static int atalla_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, +static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) + { + 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; + } + ATALLA_LIBNAME = (const char *)p; + return 1; + 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 @@ -313,26 +425,27 @@ static int atalla_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, to_return = 0; /* expect failure */ if(!atalla_dso) - { - ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_NOT_LOADED); + { + 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(!modulus || !exponent || !argument || !result) - { - ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_BN_CTX_FULL); + 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)) - { - ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_BN_EXPAND_FAIL); + { + 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); @@ -352,36 +465,34 @@ static int atalla_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, if(p_Atalla_RSAPrivateKeyOpFn(&keydata, (unsigned char *)result->d, (unsigned char *)argument->d, keydata.modulus.len) != 0) - { - ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_REQUEST_FAILED); + { + 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: - if(modulus) ctx->tos--; - if(exponent) ctx->tos--; - if(argument) ctx->tos--; - if(result) ctx->tos--; + BN_CTX_end(ctx); return to_return; } -static int atalla_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa) +#ifndef OPENSSL_NO_RSA +static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) { BN_CTX *ctx = NULL; int to_return = 0; if(!atalla_dso) - { - ENGINEerr(ENGINE_F_ATALLA_RSA_MOD_EXP,ENGINE_R_NOT_LOADED); + { + ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP,ATALLA_R_NOT_LOADED); goto err; - } + } if((ctx = BN_CTX_new()) == NULL) goto err; if(!rsa->d || !rsa->n) { - ENGINEerr(ENGINE_F_ATALLA_RSA_MOD_EXP,ENGINE_R_MISSING_KEY_COMPONENTS); + 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); @@ -390,7 +501,9 @@ err: BN_CTX_free(ctx); 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 @@ -418,27 +531,45 @@ end: 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 /* This function is aliased to mod_exp (with the mont stuff dropped). */ -static int atalla_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, +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); } +#ifndef OPENSSL_NO_DH /* This function is aliased to mod_exp (with the dh and mont dropped). */ -static int atalla_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, +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. */ +#ifdef ENGINE_DYNAMIC_SUPPORT +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 /* ENGINE_DYNAMIC_SUPPORT */ -#endif /* !NO_HW_ATALLA */ -#endif /* !NO_HW */ +#endif /* !OPENSSL_NO_HW_ATALLA */ +#endif /* !OPENSSL_NO_HW */ diff --git a/src/lib/libcrypto/engine/hw_atalla_err.c b/src/lib/libcrypto/engine/hw_atalla_err.c new file mode 100644 index 0000000000..1df9c4570c --- /dev/null +++ b/src/lib/libcrypto/engine/hw_atalla_err.c @@ -0,0 +1,145 @@ +/* hw_atalla_err.c */ +/* ==================================================================== + * 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 + * 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 +#include +#include "hw_atalla_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR +static ERR_STRING_DATA ATALLA_str_functs[]= + { +{ERR_PACK(0,ATALLA_F_ATALLA_CTRL,0), "ATALLA_CTRL"}, +{ERR_PACK(0,ATALLA_F_ATALLA_FINISH,0), "ATALLA_FINISH"}, +{ERR_PACK(0,ATALLA_F_ATALLA_INIT,0), "ATALLA_INIT"}, +{ERR_PACK(0,ATALLA_F_ATALLA_MOD_EXP,0), "ATALLA_MOD_EXP"}, +{ERR_PACK(0,ATALLA_F_ATALLA_RSA_MOD_EXP,0), "ATALLA_RSA_MOD_EXP"}, +{0,NULL} + }; + +static ERR_STRING_DATA ATALLA_str_reasons[]= + { +{ATALLA_R_ALREADY_LOADED ,"already loaded"}, +{ATALLA_R_BN_CTX_FULL ,"bn ctx full"}, +{ATALLA_R_BN_EXPAND_FAIL ,"bn expand fail"}, +{ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"}, +{ATALLA_R_MISSING_KEY_COMPONENTS ,"missing key components"}, +{ATALLA_R_NOT_LOADED ,"not loaded"}, +{ATALLA_R_REQUEST_FAILED ,"request failed"}, +{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/src/lib/libcrypto/engine/hw_atalla_err.h b/src/lib/libcrypto/engine/hw_atalla_err.h new file mode 100644 index 0000000000..cdac052d8c --- /dev/null +++ b/src/lib/libcrypto/engine/hw_atalla_err.h @@ -0,0 +1,89 @@ +/* ==================================================================== + * 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 + +/* 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/src/lib/libcrypto/engine/hw_cryptodev.c b/src/lib/libcrypto/engine/hw_cryptodev.c new file mode 100644 index 0000000000..7c3728f395 --- /dev/null +++ b/src/lib/libcrypto/engine/hw_cryptodev.c @@ -0,0 +1,926 @@ +/* + * Copyright (c) 2002 Bob Beck + * Copyright (c) 2002 Theo de Raadt + * 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. Neither the name of the author nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int cryptodev_fd = -1; +static int cryptodev_sessions = 0; +static u_int32_t cryptodev_symfeat = 0; + +static int bn2crparam(const BIGNUM *a, struct crparam *crp); +static int crparam2bn(struct crparam *crp, BIGNUM *a); +static void zapparams(struct crypt_kop *kop); + +static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa); +static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, + int dlen, DSA *dsa); +static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); +static int cryptodev_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 cryptodev_dh_compute_key(unsigned char *key, + const BIGNUM *pub_key, DH *dh); + +static const ENGINE_CMD_DEFN cryptodev_defns[] = { + { 0, NULL, NULL, 0 } +}; + +static struct { + int id; + int nid; + int ivmax; + int keylen; +} ciphers[] = { + { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, }, + { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, }, + { CRYPTO_AES_CBC, NID_undef, 8, 24, }, + { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, }, + { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 8, }, + { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, }, + { CRYPTO_ARC4, NID_rc4, 8, 16, }, + { 0, NID_undef, 0, 0, }, +}; + +static struct { + int id; + int nid; +} digests[] = { + { CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, }, + { CRYPTO_RIPEMD160_HMAC, NID_ripemd160, }, + { CRYPTO_MD5_KPDK, NID_undef, }, + { CRYPTO_SHA1_KPDK, NID_undef, }, + { CRYPTO_MD5, NID_md5, }, + { CRYPTO_SHA1, NID_undef, }, + { 0, NID_undef, }, +}; + +/* + * Return 1 if /dev/crypto seems usable, 0 otherwise , also + * does most of the work of initting the device, if not already + * done.. This should leave is with global fd initialized with CRIOGET. + */ +static int +check_dev_crypto() +{ + int fd; + + if (cryptodev_fd == -1) { + if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1) + return (0); + if (ioctl(fd, CRIOGET, &cryptodev_fd) == -1) { + close(fd); + return (0); + } + close(fd); + /* close on exec */ + if (fcntl(cryptodev_fd, F_SETFD, 1) == -1) { + close(cryptodev_fd); + cryptodev_fd = -1; + return (0); + } + } + ioctl(cryptodev_fd, CIOCSYMFEAT, &cryptodev_symfeat); + + return (1); +} + +/* + * XXXX this needs to be set for each alg - and determined from + * a running card. + */ +static int +cryptodev_max_iv(int cipher) +{ + int i; + + for (i = 0; ciphers[i].id; i++) + if (ciphers[i].id == cipher) + return (ciphers[i].ivmax); + return (0); +} + +/* + * XXXX this needs to be set for each alg - and determined from + * a running card. For now, fake it out - but most of these + * for real devices should return 1 for the supported key + * sizes the device can handle. + */ +static int +cryptodev_key_length_valid(int cipher, int len) +{ + int i; + + for (i = 0; ciphers[i].id; i++) + if (ciphers[i].id == cipher) + return (ciphers[i].keylen == len); + return (0); +} + +/* convert libcrypto nids to cryptodev */ +static int +cipher_nid_to_cryptodev(int nid) +{ + int i; + + for (i = 0; ciphers[i].id; i++) + if (ciphers[i].nid == nid) + return (ciphers[i].id); + return (0); +} + +/* + * Find out what ciphers /dev/crypto will let us have a session for. + * XXX note, that some of these openssl doesn't deal with yet! + * returning them here is harmless, as long as we return NULL + * when asked for a handler in the cryptodev_engine_ciphers routine + */ +static int +get_cryptodev_ciphers(const int **cnids) +{ + static int nids[CRYPTO_ALGORITHM_MAX]; + struct session_op sess; + int i, count = 0; + + memset(&sess, 0, sizeof(sess)); + sess.key = (caddr_t)"123456781234567812345678"; + + for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { + if (ciphers[i].nid == NID_undef) + continue; + sess.cipher = ciphers[i].id; + sess.keylen = ciphers[i].keylen; + sess.mac = 0; + if (ioctl(cryptodev_fd, CIOCGSESSION, &sess) != -1 && + ioctl(cryptodev_fd, CIOCFSESSION, &sess.ses) != -1) + nids[count++] = ciphers[i].nid; + } + if (count > 0) + *cnids = nids; + else + *cnids = NULL; + return (count); +} + +/* + * Find out what digests /dev/crypto will let us have a session for. + * XXX note, that some of these openssl doesn't deal with yet! + * returning them here is harmless, as long as we return NULL + * when asked for a handler in the cryptodev_engine_digests routine + */ +static int +get_cryptodev_digests(const int **cnids) +{ + static int nids[CRYPTO_ALGORITHM_MAX]; + struct session_op sess; + int i, count = 0; + + memset(&sess, 0, sizeof(sess)); + for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { + if (digests[i].nid == NID_undef) + continue; + sess.mac = digests[i].id; + sess.cipher = 0; + if (ioctl(cryptodev_fd, CIOCGSESSION, &sess) != -1 && + ioctl(cryptodev_fd, CIOCFSESSION, &sess.ses) != -1) + nids[count++] = digests[i].nid; + } + if (count > 0) + *cnids = nids; + else + *cnids = NULL; + return (count); +} + +/* + * Find the useable ciphers|digests from dev/crypto - this is the first + * thing called by the engine init crud which determines what it + * can use for ciphers from this engine. We want to return + * only what we can do, anythine else is handled by software. + * + * If we can't initialize the device to do anything useful for + * any reason, we want to return a NULL array, and 0 length, + * which forces everything to be done is software. By putting + * the initalization of the device in here, we ensure we can + * use this engine as the default, and if for whatever reason + * /dev/crypto won't do what we want it will just be done in + * software + * + * This can (should) be greatly expanded to perhaps take into + * account speed of the device, and what we want to do. + * (although the disabling of particular alg's could be controlled + * by the device driver with sysctl's.) - this is where we + * want most of the decisions made about what we actually want + * to use from /dev/crypto. + */ +int +cryptodev_usable_ciphers(const int **nids) +{ + if (!check_dev_crypto()) { + *nids = NULL; + return (0); + } + + /* find what the device can do. Unfortunately, we don't + * necessarily want all of these yet, because we aren't + * yet set up to do them + */ + return (get_cryptodev_ciphers(nids)); +} + +int +cryptodev_usable_digests(const int **nids) +{ +#if 1 + /* + * XXXX just disable all digests for now, because it sucks. + * we need a better way to decide this - i.e. I may not + * want digests on slow cards like hifn on fast machines, + * but might want them on slow or loaded machines, etc. + * will also want them when using crypto cards that don't + * suck moose gonads - would be nice to be able to decide something + * as reasonable default without having hackery that's card dependent. + * of course, the default should probably be just do everything, + * with perhaps a sysctl to turn algoritms off (or have them off + * by default) on cards that generally suck like the hifn. + */ + *nids = NULL; + return (0); +#endif + + if (!check_dev_crypto()) { + *nids = NULL; + return (0); + } + return (get_cryptodev_digests(nids)); +} + + +int +cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) +{ + struct crypt_op cryp; + struct session_op *sess = ctx->cipher_data; + void *iiv; + unsigned char save_iv[EVP_MAX_IV_LENGTH]; + struct syslog_data sd = SYSLOG_DATA_INIT; + + if (cryptodev_fd == -1) + return (0); + if (sess == NULL) + return (0); + if (!inl) + return (1); + if ((inl % ctx->cipher->block_size) != 0) + return (0); + + memset(&cryp, 0, sizeof(cryp)); + + cryp.ses = sess->ses; + cryp.flags = 0; + cryp.len = inl; + cryp.src = (caddr_t) in; + cryp.dst = (caddr_t) out; + cryp.mac = 0; + + cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT; + + if (ctx->cipher->iv_len) { + cryp.iv = (caddr_t) ctx->iv; + if (!ctx->encrypt) { + iiv = (void *) in + inl - ctx->cipher->iv_len; + memcpy(save_iv, iiv, ctx->cipher->iv_len); + } + } else + cryp.iv = NULL; + + if (ioctl(cryptodev_fd, CIOCCRYPT, &cryp) == -1) { + /* XXX need better errror handling + * this can fail for a number of different reasons. + */ + syslog_r(LOG_ERR, &sd, "CIOCCRYPT failed (%m)"); + return (0); + } + + if (ctx->cipher->iv_len) { + if (ctx->encrypt) + iiv = (void *) out + inl - ctx->cipher->iv_len; + else + iiv = save_iv; + memcpy(ctx->iv, iiv, ctx->cipher->iv_len); + } + return (1); +} + +int +cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + struct session_op *sess = ctx->cipher_data; + struct syslog_data sd = SYSLOG_DATA_INIT; + int cipher; + + if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef) + return (0); + + if (!check_dev_crypto()) + return (0); + + if (ctx->cipher->iv_len > cryptodev_max_iv(cipher)) + return (0); + + if (!cryptodev_key_length_valid(cipher, ctx->key_len)) + return (0); + + memset(sess, 0, sizeof(struct session_op)); + + sess->key = (unsigned char *)key; + sess->keylen = ctx->key_len; + sess->cipher = cipher; + + if (ioctl(cryptodev_fd, CIOCGSESSION, sess) == -1) { + syslog_r(LOG_ERR, &sd, "CIOCGSESSION failed (%m)"); + return (0); + } + cryptodev_sessions++; + return (1); +} + +/* + * free anything we allocated earlier when initting a + * session, and close the session. + */ +int +cryptodev_cleanup(EVP_CIPHER_CTX *ctx) +{ + int ret = 0; + struct session_op *sess = ctx->cipher_data; + struct syslog_data sd = SYSLOG_DATA_INIT; + + if (sess == NULL) + return (0); + + /* XXX if this ioctl fails, someting's wrong. the invoker + * may have called us with a bogus ctx, or we could + * have a device that for whatever reason just doesn't + * want to play ball - it's not clear what's right + * here - should this be an error? should it just + * increase a counter, hmm. For right now, we return + * 0 - I don't believe that to be "right". we could + * call the gorpy openssl lib error handlers that + * print messages to users of the library. hmm.. + */ + + if (ioctl(cryptodev_fd, CIOCFSESSION, &sess->ses) == -1) { + syslog_r(LOG_ERR, &sd, "CIOCFSESSION failed (%m)"); + ret = 0; + } else { + cryptodev_sessions--; + ret = 1; + } + if (cryptodev_sessions == 0 && cryptodev_fd != -1 ) { + close(cryptodev_fd); /* XXX should this be closed? */ + cryptodev_fd = -1; + } + return (ret); +} + +/* + * libcrypto EVP stuff - this is how we get wired to EVP so the engine + * gets called when libcrypto requests a cipher NID. + */ + +/* ARC4 (16 byte key) */ +const EVP_CIPHER cryptodev_arc4_cipher = { + NID_rc4, + 1, 16, 0, + EVP_CIPH_VARIABLE_LENGTH, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct session_op), + NULL, + NULL, + NULL +}; + +/* DES CBC EVP */ +const EVP_CIPHER cryptodev_des_cbc = { + NID_des_cbc, + 8, 8, 8, + EVP_CIPH_CBC_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct session_op), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + +/* 3DES CBC EVP */ +const EVP_CIPHER cryptodev_3des_cbc = { + NID_des_ede3_cbc, + 8, 24, 8, + EVP_CIPH_CBC_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct session_op), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + + +/* + * Registered by the ENGINE when used to find out how to deal with + * a particular NID in the ENGINE. this says what we'll do at the + * top level - note, that list is restricted by what we answer with + */ +int +cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid) +{ + if (!cipher) + return (cryptodev_usable_ciphers(nids)); + + switch (nid) { + case NID_rc4: + *cipher = &cryptodev_arc4_cipher; + break; + case NID_des_ede3_cbc: + *cipher = &cryptodev_3des_cbc; + break; + case NID_des_cbc: + *cipher = &cryptodev_des_cbc; + break; + default: + *cipher = NULL; + break; + } + return (*cipher != NULL); +} + +int +cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid) +{ + if (!digest) + return (cryptodev_usable_digests(nids)); + + switch (nid) { + case NID_md5: + *digest = NULL; /* need to make a clean md5 critter */ + break; + default: + *digest = NULL; + break; + } + return (*digest != NULL); +} + + +/* + * Convert a BIGNUM to the representation that /dev/crypto needs. + * Upon completion of use, the caller is responsible for freeing + * crp->crp_p. + */ +static int +bn2crparam(const BIGNUM *a, struct crparam *crp) +{ + int i, j, n; + ssize_t words, bytes, bits; + u_char *b; + + crp->crp_p = NULL; + crp->crp_nbits = 0; + + bits = BN_num_bits(a); + bytes = (bits + 7) / 8; + + b = malloc(bytes); + if (b == NULL) + return (1); + + crp->crp_p = b; + crp->crp_nbits = bits; + + words = (bits + BN_BITS2 - 1) / BN_BITS2; + + n = 0; + for (i = 0; i < words && n < bytes; i++) { + BN_ULONG word; + + word = a->d[i]; + for (j = 0 ; j < BN_BYTES && n < bytes; j++, n++) { + *b++ = (word & 0xff); + word >>= 8; + } + } + return (0); +} + +/* Convert a /dev/crypto parameter to a BIGNUM */ +static int +crparam2bn(struct crparam *crp, BIGNUM *a) +{ + int i, bytes; + + bytes = (crp->crp_nbits + 7)/8; + + BN_zero(a); + for (i = bytes - 1; i >= 0; i--) { + BN_lshift(a, a, 8); + BN_add_word(a, (u_char)crp->crp_p[i]); + } + + return (0); +} + +static void +zapparams(struct crypt_kop *kop) +{ + int i; + + for (i = 0; i <= kop->crk_iparams + kop->crk_oparams; i++) { + if (kop->crk_param[i].crp_p) + free(kop->crk_param[i].crp_p); + kop->crk_param[i].crp_p = NULL; + kop->crk_param[i].crp_nbits = 0; + } +} + +static int +cryptodev_sym(struct crypt_kop *kop, BIGNUM *r, BIGNUM *s) +{ + int ret = -1; + + if (r) { + kop->crk_param[kop->crk_iparams].crp_p = malloc(256); + kop->crk_param[kop->crk_iparams].crp_nbits = 256 * 8; + kop->crk_oparams++; + } + if (s) { + kop->crk_param[kop->crk_iparams+1].crp_p = malloc(256); + kop->crk_param[kop->crk_iparams+1].crp_nbits = 256 * 8; + kop->crk_oparams++; + } + + if (ioctl(cryptodev_fd, CIOCKEY, &kop) == 0) { + crparam2bn(&kop->crk_param[3], r); + ret = 0; + } + return (ret); +} + +static int +cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + struct crypt_kop kop; + int ret = 0; + + memset(&kop, 0, sizeof kop); + kop.crk_op = CRK_MOD_EXP; + + /* inputs: a m p */ + if (bn2crparam(a, &kop.crk_param[0])) + goto err; + if (bn2crparam(m, &kop.crk_param[1])) + goto err; + if (bn2crparam(p, &kop.crk_param[2])) + goto err; + kop.crk_iparams = 3; + + if (cryptodev_sym(&kop, r, NULL) == -1) { + ret = BN_mod_exp(r, a, p, m, ctx); + } +err: + zapparams(&kop); + return (ret); +} + + +static int +cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) +{ + struct crypt_kop kop; + int ret = 0; + + if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { + /* XXX 0 means failure?? */ + goto err; + } + + memset(&kop, 0, sizeof kop); + kop.crk_op = CRK_MOD_EXP_CRT; + /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */ + if (bn2crparam(rsa->p, &kop.crk_param[0])) + goto err; + if (bn2crparam(rsa->q, &kop.crk_param[1])) + goto err; + if (bn2crparam(I, &kop.crk_param[2])) + goto err; + if (bn2crparam(rsa->dmp1, &kop.crk_param[3])) + goto err; + if (bn2crparam(rsa->dmq1, &kop.crk_param[4])) + goto err; + if (bn2crparam(rsa->iqmp, &kop.crk_param[5])) + goto err; + kop.crk_iparams = 6; + + if (cryptodev_sym(&kop, r0, NULL) == -1) { + const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + + ret = (*meth->rsa_mod_exp)(r0, I, rsa); + } +err: + zapparams(&kop); + return (ret); +} + +static RSA_METHOD cryptodev_rsa = { + "cryptodev RSA method", + NULL, /* rsa_pub_enc */ + NULL, /* rsa_pub_dec */ + NULL, /* rsa_priv_enc */ + NULL, /* rsa_priv_dec */ + cryptodev_rsa_mod_exp, /* rsa_mod_exp */ + cryptodev_bn_mod_exp, /* bn_mod_exp */ + NULL, /* init */ + NULL, /* finish */ + 0, /* flags */ + NULL, /* app_data */ + NULL, /* rsa_sign */ + NULL /* rsa_verify */ +}; + +static int +cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); +} + +static DSA_SIG * +cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) +{ + struct crypt_kop kop; + BIGNUM *r = NULL, *s = NULL; + DSA_SIG *dsaret = NULL; + + if ((r = BN_new()) == NULL) + goto err; + if ((s = BN_new()) == NULL) { + BN_free(r); + goto err; + } + + memset(&kop, 0, sizeof kop); + kop.crk_op = CRK_DSA_SIGN; + + /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ + kop.crk_param[0].crp_p = (caddr_t)dgst; + kop.crk_param[0].crp_nbits = dlen * 8; + if (bn2crparam(dsa->p, &kop.crk_param[1])) + goto err; + if (bn2crparam(dsa->q, &kop.crk_param[2])) + goto err; + if (bn2crparam(dsa->g, &kop.crk_param[3])) + goto err; + if (bn2crparam(dsa->priv_key, &kop.crk_param[4])) + goto err; + kop.crk_iparams = 5; + + if (cryptodev_sym(&kop, r, s) == 0) { + dsaret = DSA_SIG_new(); + dsaret->r = r; + dsaret->s = s; + } else { + const DSA_METHOD *meth = DSA_OpenSSL(); + + BN_free(r); + BN_free(s); + dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa); + } +err: + kop.crk_param[0].crp_p = NULL; + zapparams(&kop); + return (dsaret); +} + +static int +cryptodev_dsa_verify(const unsigned char *dgst, int dlen, + DSA_SIG *sig, DSA *dsa) +{ + struct crypt_kop kop; + int dsaret = 0; + + memset(&kop, 0, sizeof kop); + kop.crk_op = CRK_DSA_VERIFY; + + /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */ + kop.crk_param[0].crp_p = (caddr_t)dgst; + kop.crk_param[0].crp_nbits = dlen * 8; + if (bn2crparam(dsa->p, &kop.crk_param[1])) + goto err; + if (bn2crparam(dsa->q, &kop.crk_param[2])) + goto err; + if (bn2crparam(dsa->g, &kop.crk_param[3])) + goto err; + if (bn2crparam(dsa->pub_key, &kop.crk_param[4])) + goto err; + if (bn2crparam(sig->r, &kop.crk_param[5])) + goto err; + if (bn2crparam(sig->s, &kop.crk_param[6])) + goto err; + kop.crk_iparams = 7; + + if (cryptodev_sym(&kop, NULL, NULL) == 0) { + dsaret = kop.crk_status; + } else { + const DSA_METHOD *meth = DSA_OpenSSL(); + + dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa); + } +err: + kop.crk_param[0].crp_p = NULL; + zapparams(&kop); + return (dsaret); +} + +static DSA_METHOD cryptodev_dsa = { + "cryptodev DSA method", + cryptodev_dsa_do_sign, + NULL, /* dsa_sign_setup */ + cryptodev_dsa_verify, + NULL, /* dsa_mod_exp */ + cryptodev_dsa_bn_mod_exp, /* bn_mod_exp */ + NULL, /* init */ + NULL, /* finish */ + 0, /* flags */ + NULL /* app_data */ +}; + +static int +cryptodev_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 (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); +} + +static int +cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) +{ + struct crypt_kop kop; + int dhret = 0; + int keylen; + + keylen = BN_num_bits(dh->p); + + memset(&kop, 0, sizeof kop); + kop.crk_op = CRK_DH_COMPUTE_KEY; + + /* inputs: dh->priv_key pub_key dh->p key */ + if (bn2crparam(dh->priv_key, &kop.crk_param[0])) + goto err; + if (bn2crparam(pub_key, &kop.crk_param[1])) + goto err; + if (bn2crparam(dh->p, &kop.crk_param[2])) + goto err; + kop.crk_iparams = 3; + + kop.crk_param[3].crp_p = key; + kop.crk_param[3].crp_nbits = keylen * 8; + kop.crk_oparams = 1; + + if (ioctl(cryptodev_fd, CIOCKEY, &kop) == -1) { + const DH_METHOD *meth = DH_OpenSSL(); + + dhret = (meth->compute_key)(key, pub_key, dh); + } +err: + kop.crk_param[3].crp_p = NULL; + zapparams(&kop); + return (dhret); +} + +static DH_METHOD cryptodev_dh = { + "cryptodev DH method", + NULL, /* cryptodev_dh_generate_key */ + cryptodev_dh_compute_key, + cryptodev_mod_exp_dh, + NULL, + NULL, + 0, /* flags */ + NULL /* app_data */ +}; + +/* + * ctrl right now is just a wrapper that doesn't do much + * but I expect we'll want some options soon. + */ +static int +cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) +{ + struct syslog_data sd = SYSLOG_DATA_INIT; + + switch (cmd) { + default: + syslog_r(LOG_ERR, &sd, + "cryptodev_ctrl: unknown command %d", cmd); + break; + } + return (1); +} + +void +ENGINE_load_cryptodev(void) +{ + ENGINE *engine = ENGINE_new(); + const RSA_METHOD *rsa_meth; + const DH_METHOD *dh_meth; + + if (engine == NULL) + return; + + if (!ENGINE_set_id(engine, "cryptodev") || + !ENGINE_set_name(engine, "OpenBSD cryptodev engine") || + !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) || + !ENGINE_set_digests(engine, cryptodev_engine_digests) || + !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) || + !ENGINE_set_cmd_defns(engine, cryptodev_defns)) { + ENGINE_free(engine); + return; + } + + if ((cryptodev_symfeat & CRSFEAT_RSA) && + ENGINE_set_RSA(engine, &cryptodev_rsa)) { + rsa_meth = RSA_PKCS1_SSLeay(); + cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc; + cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec; + cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_dec; + cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec; + } + + if ((cryptodev_symfeat & CRSFEAT_DSA) && + ENGINE_set_DSA(engine, &cryptodev_dsa)) { + } + + if ((cryptodev_symfeat & CRSFEAT_DH) && + ENGINE_set_DH(engine, &cryptodev_dh)) { + dh_meth = DH_OpenSSL(); + cryptodev_dh.generate_key = dh_meth->generate_key; + cryptodev_dh.compute_key = dh_meth->compute_key; + } + + ENGINE_add(engine); + ENGINE_free(engine); + ERR_clear_error(); +} diff --git a/src/lib/libcrypto/engine/hw_cswift.c b/src/lib/libcrypto/engine/hw_cswift.c index 77608b8983..d8b380550f 100644 --- a/src/lib/libcrypto/engine/hw_cswift.c +++ b/src/lib/libcrypto/engine/hw_cswift.c @@ -3,7 +3,7 @@ * project 2000. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * 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 @@ -60,11 +60,10 @@ #include #include "cryptlib.h" #include -#include "engine_int.h" #include -#ifndef NO_HW -#ifndef NO_HW_CSWIFT +#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 @@ -84,33 +83,55 @@ #include "vendor_defns/cswift.h" #endif -static int cswift_init(void); -static int cswift_finish(void); +#define CSWIFT_LIB_NAME "cswift engine" +#include "hw_cswift_err.c" + +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)()); /* BIGNUM stuff */ -static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, +static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx); -static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, +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); +#ifndef OPENSSL_NO_RSA /* RSA stuff */ -static int cswift_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa); +static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa); +#endif /* This function is aliased to mod_exp (with the mont stuff dropped). */ -static int cswift_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, +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); +#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(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, +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 +/* 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 = { @@ -128,7 +149,9 @@ static RSA_METHOD cswift_rsa = NULL, NULL }; +#endif +#ifndef OPENSSL_NO_DSA /* Our internal DSA_METHOD that we provide pointers to */ static DSA_METHOD cswift_dsa = { @@ -143,7 +166,9 @@ static DSA_METHOD cswift_dsa = 0, /* flags */ NULL /* app_data */ }; +#endif +#ifndef OPENSSL_NO_DH /* Our internal DH_METHOD that we provide pointers to */ static DH_METHOD cswift_dh = { @@ -156,35 +181,41 @@ static DH_METHOD cswift_dh = 0, NULL }; +#endif -/* Our ENGINE structure. */ -static ENGINE engine_cswift = - { - "cswift", - "CryptoSwift hardware engine support", - &cswift_rsa, - &cswift_dsa, - &cswift_dh, - NULL, - cswift_mod_exp, - cswift_mod_exp_crt, - cswift_init, - cswift_finish, - NULL, /* no ctrl() */ - NULL, /* no load_privkey() */ - NULL, /* no load_pubkey() */ - 0, /* no flags */ - 0, 0, /* no references */ - NULL, NULL /* unlinked */ - }; - -/* As this is only ever called once, there's no need for locking - * (indeed - the lock will already be held by our caller!!!) */ -ENGINE *ENGINE_cswift() +/* 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) { - RSA_METHOD *meth1; - DH_METHOD *meth2; +#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_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 @@ -197,12 +228,41 @@ ENGINE *ENGINE_cswift() 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; - return &engine_cswift; +#endif + + /* Ensure the cswift error handling is set up */ + ERR_load_CSWIFT_strings(); + return 1; + } + +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(); } /* This is a process-global DSO handle used for loading and unloading @@ -220,7 +280,8 @@ t_swSimpleRequest *p_CSwift_SimpleRequest = NULL; t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL; /* Used in the DSO operations. */ -static const char *CSWIFT_LIBNAME = "swift"; +static const char def_CSWIFT_LIBNAME[] = "swift"; +static const char *CSWIFT_LIBNAME = def_CSWIFT_LIBNAME; static const char *CSWIFT_F1 = "swAcquireAccContext"; static const char *CSWIFT_F2 = "swAttachKeyParam"; static const char *CSWIFT_F3 = "swSimpleRequest"; @@ -249,8 +310,15 @@ static void release_context(SW_CONTEXT_HANDLE hac) p_CSwift_ReleaseAccContext(hac); } +/* Destructor (complements the "ENGINE_cswift()" constructor) */ +static int cswift_destroy(ENGINE *e) + { + ERR_unload_CSWIFT_strings(); + return 1; + } + /* (de)initialisation functions. */ -static int cswift_init() +static int cswift_init(ENGINE *e) { SW_CONTEXT_HANDLE hac; t_swAcquireAccContext *p1; @@ -260,15 +328,14 @@ static int cswift_init() if(cswift_dso != NULL) { - ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_ALREADY_LOADED); + CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_ALREADY_LOADED); goto err; } /* Attempt to load libswift.so/swift.dll/whatever. */ - cswift_dso = DSO_load(NULL, CSWIFT_LIBNAME, NULL, - DSO_FLAG_NAME_TRANSLATION); + cswift_dso = DSO_load(NULL, CSWIFT_LIBNAME, NULL, 0); if(cswift_dso == NULL) { - ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_DSO_FAILURE); + CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED); goto err; } if(!(p1 = (t_swAcquireAccContext *) @@ -280,7 +347,7 @@ static int cswift_init() !(p4 = (t_swReleaseAccContext *) DSO_bind_func(cswift_dso, CSWIFT_F4))) { - ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_DSO_FAILURE); + CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED); goto err; } /* Copy the pointers */ @@ -292,7 +359,7 @@ static int cswift_init() * accelerator! */ if(!get_context(&hac)) { - ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_UNIT_FAILURE); + CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_UNIT_FAILURE); goto err; } release_context(hac); @@ -308,16 +375,16 @@ err: return 0; } -static int cswift_finish() +static int cswift_finish(ENGINE *e) { if(cswift_dso == NULL) { - ENGINEerr(ENGINE_F_CSWIFT_FINISH,ENGINE_R_NOT_LOADED); + CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_NOT_LOADED); return 0; } if(!DSO_free(cswift_dso)) { - ENGINEerr(ENGINE_F_CSWIFT_FINISH,ENGINE_R_DSO_FAILURE); + CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_UNIT_FAILURE); return 0; } cswift_dso = NULL; @@ -328,8 +395,33 @@ static int cswift_finish() return 1; } +static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) + { + 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; + } + CSWIFT_LIBNAME = (const char *)p; + return 1; + 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, BIGNUM *a, const BIGNUM *p, +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 @@ -353,24 +445,25 @@ static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, if(!get_context(&hac)) { - ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_GET_HANDLE_FAILED); + 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(!modulus || !exponent || !argument || !result) + if(!result) { - ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_BN_CTX_FULL); + 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)) { - ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_BN_EXPAND_FAIL); + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_EXPAND_FAIL); goto err; } sw_param.type = SW_ALG_EXP; @@ -387,13 +480,12 @@ static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, case SW_OK: break; case SW_ERR_INPUT_SIZE: - ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP, - ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BAD_KEY_SIZE); goto err; default: { char tmpbuf[20]; - ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_REQUEST_FAILED); + 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); } @@ -410,7 +502,7 @@ static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, &res, 1)) != SW_OK) { char tmpbuf[20]; - ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_REQUEST_FAILED); + 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; @@ -421,15 +513,12 @@ static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, err: if(acquired) release_context(hac); - if(modulus) ctx->tos--; - if(exponent) ctx->tos--; - if(argument) ctx->tos--; - if(result) ctx->tos--; + BN_CTX_end(ctx); return to_return; } /* Un petit mod_exp chinois */ -static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, +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) { @@ -449,11 +538,12 @@ static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, if(!get_context(&hac)) { - ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_GET_HANDLE_FAILED); + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_UNIT_FAILURE); goto err; } acquired = 1; /* Prepare the params */ + BN_CTX_start(ctx); rsa_p = BN_CTX_get(ctx); rsa_q = BN_CTX_get(ctx); rsa_dmp1 = BN_CTX_get(ctx); @@ -461,10 +551,9 @@ static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, rsa_iqmp = BN_CTX_get(ctx); argument = BN_CTX_get(ctx); result = BN_CTX_get(ctx); - if(!rsa_p || !rsa_q || !rsa_dmp1 || !rsa_dmq1 || !rsa_iqmp || - !argument || !result) + if(!result) { - ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_BN_CTX_FULL); + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_CTX_FULL); goto err; } if(!bn_wexpand(rsa_p, p->top) || !bn_wexpand(rsa_q, q->top) || @@ -474,7 +563,7 @@ static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, !bn_wexpand(argument, a->top) || !bn_wexpand(result, p->top + q->top)) { - ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_BN_EXPAND_FAIL); + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL); goto err; } sw_param.type = SW_ALG_CRT; @@ -498,13 +587,12 @@ static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, case SW_OK: break; case SW_ERR_INPUT_SIZE: - ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT, - ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BAD_KEY_SIZE); goto err; default: { char tmpbuf[20]; - ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_REQUEST_FAILED); + 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); } @@ -521,7 +609,7 @@ static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, &res, 1)) != SW_OK) { char tmpbuf[20]; - ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_REQUEST_FAILED); + 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; @@ -532,17 +620,12 @@ static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, err: if(acquired) release_context(hac); - if(rsa_p) ctx->tos--; - if(rsa_q) ctx->tos--; - if(rsa_dmp1) ctx->tos--; - if(rsa_dmq1) ctx->tos--; - if(rsa_iqmp) ctx->tos--; - if(argument) ctx->tos--; - if(result) ctx->tos--; + BN_CTX_end(ctx); return to_return; } -static int cswift_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa) +#ifndef OPENSSL_NO_RSA +static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) { BN_CTX *ctx; int to_return = 0; @@ -551,7 +634,7 @@ static int cswift_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa) goto err; if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { - ENGINEerr(ENGINE_F_CSWIFT_RSA_MOD_EXP,ENGINE_R_MISSING_KEY_COMPONENTS); + CSWIFTerr(CSWIFT_F_CSWIFT_RSA_MOD_EXP,CSWIFT_R_MISSING_KEY_COMPONENTS); goto err; } to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1, @@ -561,14 +644,16 @@ err: BN_CTX_free(ctx); return to_return; } +#endif /* This function is aliased to mod_exp (with the mont stuff dropped). */ -static int cswift_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, +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) { return cswift_mod_exp(r, a, p, m, ctx); } +#ifndef OPENSSL_NO_DSA static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa) { SW_CONTEXT_HANDLE hac; @@ -589,19 +674,20 @@ static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa) goto err; if(!get_context(&hac)) { - ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_GET_HANDLE_FAILED); + 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(!dsa_p || !dsa_q || !dsa_g || !dsa_key || !result) + if(!result) { - ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_BN_CTX_FULL); + CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_CTX_FULL); goto err; } if(!bn_wexpand(dsa_p, dsa->p->top) || @@ -610,7 +696,7 @@ static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa) !bn_wexpand(dsa_key, dsa->priv_key->top) || !bn_wexpand(result, dsa->p->top)) { - ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_BN_EXPAND_FAIL); + CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_EXPAND_FAIL); goto err; } sw_param.type = SW_ALG_DSA; @@ -633,13 +719,12 @@ static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa) case SW_OK: break; case SW_ERR_INPUT_SIZE: - ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN, - ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BAD_KEY_SIZE); goto err; default: { char tmpbuf[20]; - ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_REQUEST_FAILED); + 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); } @@ -657,7 +742,7 @@ static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa) if(sw_status != SW_OK) { char tmpbuf[20]; - ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_REQUEST_FAILED); + 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; @@ -672,13 +757,11 @@ static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa) err: if(acquired) release_context(hac); - if(dsa_p) ctx->tos--; - if(dsa_q) ctx->tos--; - if(dsa_g) ctx->tos--; - if(dsa_key) ctx->tos--; - if(result) ctx->tos--; if(ctx) + { + BN_CTX_end(ctx); BN_CTX_free(ctx); + } return to_return; } @@ -703,19 +786,20 @@ static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len, goto err; if(!get_context(&hac)) { - ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_GET_HANDLE_FAILED); + 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(!dsa_p || !dsa_q || !dsa_g || !dsa_key || !argument) + if(!argument) { - ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_BN_CTX_FULL); + CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_CTX_FULL); goto err; } if(!bn_wexpand(dsa_p, dsa->p->top) || @@ -724,7 +808,7 @@ static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len, !bn_wexpand(dsa_key, dsa->pub_key->top) || !bn_wexpand(argument, 40)) { - ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_BN_EXPAND_FAIL); + CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_EXPAND_FAIL); goto err; } sw_param.type = SW_ALG_DSA; @@ -747,13 +831,12 @@ static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len, case SW_OK: break; case SW_ERR_INPUT_SIZE: - ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY, - ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BAD_KEY_SIZE); goto err; default: { char tmpbuf[20]; - ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_REQUEST_FAILED); + 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); } @@ -775,7 +858,7 @@ static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len, if(sw_status != SW_OK) { char tmpbuf[20]; - ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_REQUEST_FAILED); + 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; @@ -786,22 +869,39 @@ static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len, err: if(acquired) release_context(hac); - if(dsa_p) ctx->tos--; - if(dsa_q) ctx->tos--; - if(dsa_g) ctx->tos--; - if(dsa_key) ctx->tos--; - if(argument) ctx->tos--; 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(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, +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 + +/* This stuff is needed if this ENGINE is being compiled into a self-contained + * shared-library. */ +#ifdef ENGINE_DYNAMIC_SUPPORT +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 /* ENGINE_DYNAMIC_SUPPORT */ -#endif /* !NO_HW_CSWIFT */ -#endif /* !NO_HW */ +#endif /* !OPENSSL_NO_HW_CSWIFT */ +#endif /* !OPENSSL_NO_HW */ diff --git a/src/lib/libcrypto/engine/hw_cswift_err.c b/src/lib/libcrypto/engine/hw_cswift_err.c new file mode 100644 index 0000000000..684f53bf27 --- /dev/null +++ b/src/lib/libcrypto/engine/hw_cswift_err.c @@ -0,0 +1,149 @@ +/* hw_cswift_err.c */ +/* ==================================================================== + * 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 + * 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 +#include +#include "hw_cswift_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR +static ERR_STRING_DATA CSWIFT_str_functs[]= + { +{ERR_PACK(0,CSWIFT_F_CSWIFT_CTRL,0), "CSWIFT_CTRL"}, +{ERR_PACK(0,CSWIFT_F_CSWIFT_DSA_SIGN,0), "CSWIFT_DSA_SIGN"}, +{ERR_PACK(0,CSWIFT_F_CSWIFT_DSA_VERIFY,0), "CSWIFT_DSA_VERIFY"}, +{ERR_PACK(0,CSWIFT_F_CSWIFT_FINISH,0), "CSWIFT_FINISH"}, +{ERR_PACK(0,CSWIFT_F_CSWIFT_INIT,0), "CSWIFT_INIT"}, +{ERR_PACK(0,CSWIFT_F_CSWIFT_MOD_EXP,0), "CSWIFT_MOD_EXP"}, +{ERR_PACK(0,CSWIFT_F_CSWIFT_MOD_EXP_CRT,0), "CSWIFT_MOD_EXP_CRT"}, +{ERR_PACK(0,CSWIFT_F_CSWIFT_RSA_MOD_EXP,0), "CSWIFT_RSA_MOD_EXP"}, +{0,NULL} + }; + +static ERR_STRING_DATA CSWIFT_str_reasons[]= + { +{CSWIFT_R_ALREADY_LOADED ,"already loaded"}, +{CSWIFT_R_BAD_KEY_SIZE ,"bad key size"}, +{CSWIFT_R_BN_CTX_FULL ,"bn ctx full"}, +{CSWIFT_R_BN_EXPAND_FAIL ,"bn expand fail"}, +{CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"}, +{CSWIFT_R_MISSING_KEY_COMPONENTS ,"missing key components"}, +{CSWIFT_R_NOT_LOADED ,"not loaded"}, +{CSWIFT_R_REQUEST_FAILED ,"request failed"}, +{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/src/lib/libcrypto/engine/hw_cswift_err.h b/src/lib/libcrypto/engine/hw_cswift_err.h new file mode 100644 index 0000000000..7120c3216f --- /dev/null +++ b/src/lib/libcrypto/engine/hw_cswift_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_CSWIFT_ERR_H +#define HEADER_CSWIFT_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_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_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/src/lib/libcrypto/engine/hw_ncipher.c b/src/lib/libcrypto/engine/hw_ncipher.c index 41f5900676..4762a54e3d 100644 --- a/src/lib/libcrypto/engine/hw_ncipher.c +++ b/src/lib/libcrypto/engine/hw_ncipher.c @@ -4,7 +4,7 @@ * for the OpenSSL project 2000. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * 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 @@ -58,15 +58,16 @@ */ #include +#include #include #include #include "cryptlib.h" #include -#include "engine_int.h" #include +#include -#ifndef NO_HW -#ifndef NO_HW_NCIPHER +#ifndef OPENSSL_NO_HW +#ifndef OPENSSL_NO_HW_NCIPHER /* Attribution notice: nCipher have said several times that it's OK for * us to implement a general interface to their boxes, and recently declared @@ -82,9 +83,13 @@ #include "vendor_defns/hwcryptohook.h" #endif -static int hwcrhk_init(void); -static int hwcrhk_finish(void); -static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)()); +#define HWCRHK_LIB_NAME "hwcrhk engine" +#include "hw_ncipher_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)()); /* Functions to handle mutexes */ static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*); @@ -93,39 +98,77 @@ static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex*); static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*); /* BIGNUM stuff */ -static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, +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, BIGNUM *I, RSA *rsa); +static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa); +#endif /* This function is aliased to mod_exp (with the mont stuff dropped). */ -static int hwcrhk_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, +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); /* DH stuff */ /* This function is alised to mod_exp (with the DH and mont dropped). */ -static int hwcrhk_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +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); /* 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(const char *key_id, - const char *passphrase); -static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, - const char *passphrase); +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); static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, - int index,long argl, void *argp); + int ind,long argl, void *argp); /* 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 *logstream, const char *message); +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 or off (boolean)", + ENGINE_CMD_FLAG_NUMERIC}, + {HWCRHK_CMD_THREAD_LOCKING, + "THREAD_LOCKING", + "Turns thread-safe locking on or off (boolean)", + 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 = { @@ -143,7 +186,9 @@ static RSA_METHOD hwcrhk_rsa = NULL, NULL }; +#endif +#ifndef OPENSSL_NO_DH /* Our internal DH_METHOD that we provide pointers to */ static DH_METHOD hwcrhk_dh = { @@ -156,6 +201,7 @@ static DH_METHOD hwcrhk_dh = 0, NULL }; +#endif static RAND_METHOD hwcrhk_rand = { @@ -168,26 +214,9 @@ static RAND_METHOD hwcrhk_rand = hwcrhk_rand_status, }; -/* Our ENGINE structure. */ -static ENGINE engine_hwcrhk = - { - "chil", - "nCipher hardware engine support", - &hwcrhk_rsa, - NULL, - &hwcrhk_dh, - &hwcrhk_rand, - hwcrhk_mod_exp, - NULL, - hwcrhk_init, - hwcrhk_finish, - hwcrhk_ctrl, - hwcrhk_load_privkey, - hwcrhk_load_pubkey, - 0, /* no flags */ - 0, 0, /* no references */ - NULL, NULL /* unlinked */ - }; +/* Constants used when creating the ENGINE */ +static const char *engine_hwcrhk_id = "chil"; +static const char *engine_hwcrhk_name = "nCipher hardware engine support"; /* Internal stuff for HWCryptoHook */ @@ -204,7 +233,8 @@ struct HWCryptoHook_MutexValue into HWCryptoHook_PassphraseContext */ struct HWCryptoHook_PassphraseContextValue { - void *any; + UI_METHOD *ui_method; + void *callback_data; }; /* hwcryptohook.h has some typedefs that turn @@ -212,7 +242,10 @@ struct HWCryptoHook_PassphraseContextValue into HWCryptoHook_CallerContext */ struct HWCryptoHook_CallerContextValue { - void *any; + 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 @@ -222,31 +255,27 @@ struct HWCryptoHook_CallerContextValue #define MPI2BN(bn, mp) \ {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;} -#if 0 /* Card and password management is not yet supported */ -/* HWCryptoHook callbacks. insert_card() and get_pass() are not yet - defined, because we haven't quite decided on the proper form yet. - log_message() just adds an entry in the error stack. I don't know - if that's good or bad... */ -static int insert_card(const char *prompt_info, - const char *wrong_info, - HWCryptoHook_PassphraseContext *ppctx, - HWCryptoHook_CallerContext *cactx); -static int get_pass(const char *prompt_info, - int *len_io, char *buf, - HWCryptoHook_PassphraseContext *ppctx, - HWCryptoHook_CallerContext *cactx); -#endif - static BIO *logstream = NULL; -static pem_password_cb *password_callback = NULL; -#if 0 -static void *password_callback_userdata = NULL; -#endif 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 = { - 0, /* Flags */ + HWCryptoHook_InitFlags_SimpleForkCheck, /* Flags */ &logstream, /* logstream */ sizeof(BN_ULONG), /* limbsize */ 0, /* mslimb first: false for BNs */ @@ -280,20 +309,42 @@ static HWCryptoHook_InitInfo hwcrhk_globals = { 0, /* hwcrhk_cv_destroy, */ hwcrhk_get_pass, /* pass phrase */ - 0, /* insert_card, */ /* insert a card */ + hwcrhk_insert_card, /* insert a card */ hwcrhk_log_message /* Log message */ }; /* 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!!!) */ -ENGINE *ENGINE_ncipher() +/* This internal function is used by ENGINE_ncipher() and possibly by the + * "dynamic" ENGINE support too */ +static int bind_helper(ENGINE *e) { - RSA_METHOD *meth1; - DH_METHOD *meth2; +#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 @@ -306,12 +357,41 @@ ENGINE *ENGINE_ncipher() 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; - return &engine_hwcrhk; +#endif + + /* Ensure the hwcrhk error handling is set up */ + ERR_load_HWCRHK_strings(); + return 1; + } + +static ENGINE *engine_ncipher(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_ncipher(); + if(!toadd) return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); } /* This is a process-global DSO handle used for loading and unloading @@ -321,30 +401,41 @@ ENGINE *ENGINE_ncipher() * implicitly. */ static DSO *hwcrhk_dso = NULL; static HWCryptoHook_ContextHandle hwcrhk_context = 0; -static int hndidx = -1; /* Index for KM handle. Not really used yet. */ +#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 = "nfhwcrhk"; +static const char def_HWCRHK_LIBNAME[] = "nfhwcrhk"; +static const char *HWCRHK_LIBNAME = def_HWCRHK_LIBNAME; 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 @@ -353,16 +444,17 @@ static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT"; * called, the checking and error handling is probably down there. */ /* utility function to obtain a context */ -static int get_context(HWCryptoHook_ContextHandle *hac) +static int get_context(HWCryptoHook_ContextHandle *hac, + HWCryptoHook_CallerContext *cac) { char tempbuf[1024]; HWCryptoHook_ErrMsgBuf rmsg; rmsg.buf = tempbuf; - rmsg.size = 1024; + rmsg.size = sizeof(tempbuf); *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg, - NULL); + cac); if (!*hac) return 0; return 1; @@ -374,30 +466,38 @@ static void release_context(HWCryptoHook_ContextHandle hac) p_hwcrhk_Finish(hac); } +/* Destructor (complements the "ENGINE_ncipher()" constructor) */ +static int hwcrhk_destroy(ENGINE *e) + { + ERR_unload_HWCRHK_strings(); + return 1; + } + /* (de)initialisation functions. */ -static int hwcrhk_init() +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) { - ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_ALREADY_LOADED); + HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_ALREADY_LOADED); goto err; } /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */ - hwcrhk_dso = DSO_load(NULL, HWCRHK_LIBNAME, NULL, - DSO_FLAG_NAME_TRANSLATION); + hwcrhk_dso = DSO_load(NULL, HWCRHK_LIBNAME, NULL, 0); if(hwcrhk_dso == NULL) { - ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_DSO_FAILURE); + HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE); goto err; } if(!(p1 = (HWCryptoHook_Init_t *) @@ -406,6 +506,7 @@ static int hwcrhk_init() 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 *) @@ -414,22 +515,25 @@ static int hwcrhk_init() 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))) { - ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_DSO_FAILURE); + 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; @@ -448,16 +552,18 @@ static int hwcrhk_init() /* Try and get a context - if not, we may have a DSO but no * accelerator! */ - if(!get_context(&hwcrhk_context)) + if(!get_context(&hwcrhk_context, &password_context)) { - ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_UNIT_FAILURE); + HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_UNIT_FAILURE); goto err; } /* Everything's fine. */ - if (hndidx == -1) - hndidx = RSA_get_ex_new_index(0, +#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) @@ -466,28 +572,30 @@ err: 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() +static int hwcrhk_finish(ENGINE *e) { int to_return = 1; if(hwcrhk_dso == NULL) { - ENGINEerr(ENGINE_F_HWCRHK_FINISH,ENGINE_R_NOT_LOADED); + HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_NOT_LOADED); to_return = 0; goto err; } release_context(hwcrhk_context); if(!DSO_free(hwcrhk_dso)) { - ENGINEerr(ENGINE_F_HWCRHK_FINISH,ENGINE_R_DSO_FAILURE); + HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_DSO_FAILURE); to_return = 0; goto err; } @@ -498,21 +606,36 @@ static int hwcrhk_finish() 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(int cmd, long i, void *p, void (*f)()) +static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) { 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; + } + HWCRHK_LIBNAME = (const char *)p; + return 1; case ENGINE_CTRL_SET_LOGSTREAM: { BIO *bio = (BIO *)p; @@ -526,18 +649,31 @@ static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)()) if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1) logstream = bio; else - ENGINEerr(ENGINE_F_HWCRHK_CTRL,ENGINE_R_BIO_WAS_FREED); + 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_callback = (pem_password_cb *)f; + 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 |= @@ -557,11 +693,16 @@ static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)()) 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: - ENGINEerr(ENGINE_F_HWCRHK_CTRL, - ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); + HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, + HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED); to_return = 0; break; } @@ -569,44 +710,62 @@ static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)()) return to_return; } -static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, - const char *passphrase) +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; +#endif + HWCryptoHook_PassphraseContext ppctx; + +#if !defined(OPENSSL_NO_RSA) + rmsg.buf = tempbuf; + rmsg.size = sizeof(tempbuf); +#endif if(!hwcrhk_context) { - ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, - ENGINE_R_NOT_INITIALISED); + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, + HWCRHK_R_NOT_INITIALISED); goto err; } +#ifndef OPENSSL_NO_RSA hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle)); if (!hptr) { - ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, + 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, NULL)) + &rmsg, &ppctx)) { - ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, - ENGINE_R_CHIL_ERROR); + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, + HWCRHK_R_CHIL_ERROR); ERR_add_error_data(1,rmsg.buf); goto err; } if (!*hptr) { - ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, - ENGINE_R_NO_KEY); + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, + HWCRHK_R_NO_KEY); goto err; } - rtmp = RSA_new_method(&engine_hwcrhk); - RSA_set_ex_data(rtmp, hndidx, (char *)hptr); +#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; @@ -615,11 +774,11 @@ static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg) != HWCRYPTOHOOK_ERROR_MPISIZE) { - ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY,ENGINE_R_CHIL_ERROR); + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,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); @@ -627,8 +786,8 @@ static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)) { - ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY, - ENGINE_R_CHIL_ERROR); + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY, + HWCRHK_R_CHIL_ERROR); ERR_add_error_data(1,rmsg.buf); goto err; } @@ -639,23 +798,37 @@ static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, res = EVP_PKEY_new(); EVP_PKEY_assign_RSA(res, rtmp); +#endif + + if (!res) + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY, + 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(const char *key_id, const char *passphrase) +static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, void *callback_data) { - EVP_PKEY *res = hwcrhk_load_privkey(key_id, passphrase); + 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; @@ -665,12 +838,16 @@ static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, const char *passphrase) 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: - ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY, - ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY, + HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED); goto err; } @@ -682,7 +859,7 @@ static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, const char *passphrase) } /* A little mod_exp */ -static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, +static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx) { char tempbuf[1024]; @@ -695,11 +872,11 @@ static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, to_return = 0; /* expect failure */ rmsg.buf = tempbuf; - rmsg.size = 1024; + rmsg.size = sizeof(tempbuf); if(!hwcrhk_context) { - ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_NOT_INITIALISED); + HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_NOT_INITIALISED); goto err; } /* Prepare the params */ @@ -723,11 +900,11 @@ static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, might be a good thing. */ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) { - ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_REQUEST_FALLBACK); + HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FALLBACK); } else { - ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_REQUEST_FAILED); + HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FAILED); } ERR_add_error_data(1,rmsg.buf); goto err; @@ -737,38 +914,39 @@ static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, err: return to_return; } - -static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa) + +#ifndef OPENSSL_NO_RSA +static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa) { char tempbuf[1024]; HWCryptoHook_ErrMsgBuf rmsg; HWCryptoHook_RSAKeyHandle *hptr; int to_return = 0, ret; + rmsg.buf = tempbuf; + rmsg.size = sizeof(tempbuf); + if(!hwcrhk_context) { - ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_NOT_INITIALISED); + HWCRHKerr(HWCRHK_F_HWCRHK_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)) + if ((hptr = (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx_rsa)) != NULL) { HWCryptoHook_MPI m_a, m_r; if(!rsa->n) { - ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP, - ENGINE_R_MISSING_KEY_COMPONENTS); + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_MISSING_KEY_COMPONENTS); goto err; } - rmsg.buf = tempbuf; - rmsg.size = 1024; - /* Prepare the params */ bn_expand2(r, rsa->n->top); /* Check for error !! */ BN2MPI(m_a, I); @@ -788,11 +966,13 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa) might be a good thing. */ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) { - ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FALLBACK); + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_REQUEST_FALLBACK); } else { - ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FAILED); + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_REQUEST_FAILED); } ERR_add_error_data(1,rmsg.buf); goto err; @@ -804,14 +984,11 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa) if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { - ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP, - ENGINE_R_MISSING_KEY_COMPONENTS); + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_MISSING_KEY_COMPONENTS); goto err; } - rmsg.buf = tempbuf; - rmsg.size = 1024; - /* Prepare the params */ bn_expand2(r, rsa->n->top); /* Check for error !! */ BN2MPI(m_a, I); @@ -837,11 +1014,13 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa) might be a good thing. */ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) { - ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FALLBACK); + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_REQUEST_FALLBACK); } else { - ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FAILED); + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_REQUEST_FAILED); } ERR_add_error_data(1,rmsg.buf); goto err; @@ -852,16 +1031,18 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa) err: return to_return; } +#endif /* This function is aliased to mod_exp (with the mont stuff dropped). */ -static int hwcrhk_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, +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); } /* This function is aliased to mod_exp (with the dh and mont dropped). */ -static int hwcrhk_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, +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); @@ -876,11 +1057,11 @@ static int hwcrhk_rand_bytes(unsigned char *buf, int num) int ret; rmsg.buf = tempbuf; - rmsg.size = 1024; + rmsg.size = sizeof(tempbuf); if(!hwcrhk_context) { - ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_NOT_INITIALISED); + HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,HWCRHK_R_NOT_INITIALISED); goto err; } @@ -892,11 +1073,13 @@ static int hwcrhk_rand_bytes(unsigned char *buf, int num) might be a good thing. */ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) { - ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_REQUEST_FALLBACK); + HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, + HWCRHK_R_REQUEST_FALLBACK); } else { - ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_REQUEST_FAILED); + HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, + HWCRHK_R_REQUEST_FAILED); } ERR_add_error_data(1,rmsg.buf); goto err; @@ -914,20 +1097,28 @@ static int hwcrhk_rand_status(void) /* This cleans up an RSA KM key, called when ex_data is freed */ static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, - int index,long argl, void *argp) + 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 = 1024; + rmsg.size = sizeof(tempbuf); +#ifndef OPENSSL_NO_RSA hptr = (HWCryptoHook_RSAKeyHandle *) item; - if(!hptr) return; - ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL); - OPENSSL_free(hptr); + if(hptr) + { + ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL); + OPENSSL_free(hptr); + } +#endif } /* Mutex calls: since the HWCryptoHook model closely follows the POSIX model @@ -939,17 +1130,17 @@ static int hwcrhk_mutex_init(HWCryptoHook_Mutex* mt, { mt->lockid = CRYPTO_get_new_dynlockid(); if (mt->lockid == 0) - return 0; - return 1; + return 1; /* failure */ + return 0; /* success */ } static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt) { CRYPTO_w_lock(mt->lockid); - return 1; + return 0; } -void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt) +static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt) { CRYPTO_w_unlock(mt->lockid); } @@ -964,50 +1155,146 @@ static int hwcrhk_get_pass(const char *prompt_info, HWCryptoHook_PassphraseContext *ppctx, HWCryptoHook_CallerContext *cactx) { - int l = 0; - char prompt[1024]; - - if (password_callback == NULL) - { - ENGINEerr(ENGINE_F_HWCRHK_GET_PASS,ENGINE_R_NO_CALLBACK); - return -1; - } - if (prompt_info) + 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) { - strncpy(prompt, "Card: \"", sizeof(prompt)); - l += 5; - strncpy(prompt + l, prompt_info, sizeof(prompt) - l); - l += strlen(prompt_info); - if (l + 2 < sizeof(prompt)) - { - strncpy(prompt + l, "\"\n", sizeof(prompt) - l); - l += 2; - } + if (ppctx->ui_method) + { + ui_method = ppctx->ui_method; + callback = NULL; + } + if (ppctx->callback_data) + callback_data = ppctx->callback_data; } - if (l < sizeof(prompt) - 1) + if (callback == NULL && ui_method == NULL) { - strncpy(prompt, "Enter Passphrase :", - sizeof(prompt) - l); - l += 35; + HWCRHKerr(HWCRHK_F_HWCRHK_GET_PASS,HWCRHK_R_NO_CALLBACK); + return -1; } - prompt[l] = '\0'; - /* I know, passing on the prompt instead of the user data *is* - a bad thing. However, that's all we have right now. - -- Richard Levitte */ - *len_io = password_callback(buf, *len_io, 0, prompt); + 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 void hwcrhk_log_message(void *logstream, const char *message) +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 or C 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 (logstream) - lstream=*(BIO **)logstream; + if (logstr) + lstream=*(BIO **)logstr; if (lstream) { BIO_write(lstream, message, strlen(message)); @@ -1015,5 +1302,20 @@ static void hwcrhk_log_message(void *logstream, const char *message) CRYPTO_w_unlock(CRYPTO_LOCK_BIO); } -#endif /* !NO_HW_NCIPHER */ -#endif /* !NO_HW */ +/* This stuff is needed if this ENGINE is being compiled into a self-contained + * shared-library. */ +#ifdef ENGINE_DYNAMIC_SUPPORT +static int bind_fn(ENGINE *e, const char *id) + { + if(id && (strcmp(id, engine_hwcrhk_id) != 0)) + return 0; + if(!bind_helper(e)) + return 0; + return 1; + } +IMPLEMENT_DYNAMIC_CHECK_FN() +IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) +#endif /* ENGINE_DYNAMIC_SUPPORT */ + +#endif /* !OPENSSL_NO_HW_NCIPHER */ +#endif /* !OPENSSL_NO_HW */ diff --git a/src/lib/libcrypto/engine/hw_ncipher_err.c b/src/lib/libcrypto/engine/hw_ncipher_err.c new file mode 100644 index 0000000000..24024cfc6f --- /dev/null +++ b/src/lib/libcrypto/engine/hw_ncipher_err.c @@ -0,0 +1,156 @@ +/* hw_ncipher_err.c */ +/* ==================================================================== + * 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 + * 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 +#include +#include "hw_ncipher_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR +static ERR_STRING_DATA HWCRHK_str_functs[]= + { +{ERR_PACK(0,HWCRHK_F_HWCRHK_CTRL,0), "HWCRHK_CTRL"}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_FINISH,0), "HWCRHK_FINISH"}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_GET_PASS,0), "HWCRHK_GET_PASS"}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_INIT,0), "HWCRHK_INIT"}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_INSERT_CARD,0), "HWCRHK_INSERT_CARD"}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_LOAD_PRIVKEY,0), "HWCRHK_LOAD_PRIVKEY"}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_LOAD_PUBKEY,0), "HWCRHK_LOAD_PUBKEY"}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_MOD_EXP,0), "HWCRHK_MOD_EXP"}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_RAND_BYTES,0), "HWCRHK_RAND_BYTES"}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_RSA_MOD_EXP,0), "HWCRHK_RSA_MOD_EXP"}, +{0,NULL} + }; + +static ERR_STRING_DATA HWCRHK_str_reasons[]= + { +{HWCRHK_R_ALREADY_LOADED ,"already loaded"}, +{HWCRHK_R_BIO_WAS_FREED ,"bio was freed"}, +{HWCRHK_R_CHIL_ERROR ,"chil error"}, +{HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"}, +{HWCRHK_R_DSO_FAILURE ,"dso failure"}, +{HWCRHK_R_MISSING_KEY_COMPONENTS ,"missing key components"}, +{HWCRHK_R_NOT_INITIALISED ,"not initialised"}, +{HWCRHK_R_NOT_LOADED ,"not loaded"}, +{HWCRHK_R_NO_CALLBACK ,"no callback"}, +{HWCRHK_R_NO_KEY ,"no key"}, +{HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED,"private key algorithms disabled"}, +{HWCRHK_R_REQUEST_FAILED ,"request failed"}, +{HWCRHK_R_REQUEST_FALLBACK ,"request fallback"}, +{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/src/lib/libcrypto/engine/hw_ncipher_err.h b/src/lib/libcrypto/engine/hw_ncipher_err.h new file mode 100644 index 0000000000..4d65b1d470 --- /dev/null +++ b/src/lib/libcrypto/engine/hw_ncipher_err.h @@ -0,0 +1,100 @@ +/* ==================================================================== + * 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 + +/* 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/src/lib/libcrypto/engine/hw_nuron.c b/src/lib/libcrypto/engine/hw_nuron.c new file mode 100644 index 0000000000..2672012154 --- /dev/null +++ b/src/lib/libcrypto/engine/hw_nuron.c @@ -0,0 +1,399 @@ +/* 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 +#include +#include "cryptlib.h" +#include +#include + + +#ifndef OPENSSL_NO_HW +#ifndef OPENSSL_NO_HW_NURON + +#define NURON_LIB_NAME "nuron engine" +#include "hw_nuron_err.c" + +static const char def_NURON_LIBNAME[] = "nuronssl"; +static const char *NURON_LIBNAME = def_NURON_LIBNAME; +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) + { + 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, 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) + { + 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)()) + { + 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; + } + NURON_LIBNAME = (const char *)p; + return 1; + 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) + { + return nuron_mod_exp(r0,I,rsa->d,rsa->n,NULL); + } +#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). */ +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); + } + +#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 + }; +#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 */ + }; +#endif + +#ifndef OPENSSL_NO_DH +static DH_METHOD nuron_dh = + { + "Nuron DH method", + NULL, + NULL, + nuron_mod_exp_dh, + NULL, + NULL, + 0, + 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; + } + +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(); + } + +/* This stuff is needed if this ENGINE is being compiled into a self-contained + * shared-library. */ +#ifdef ENGINE_DYNAMIC_SUPPORT +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 /* ENGINE_DYNAMIC_SUPPORT */ + +#endif /* !OPENSSL_NO_HW_NURON */ +#endif /* !OPENSSL_NO_HW */ diff --git a/src/lib/libcrypto/engine/hw_nuron_err.c b/src/lib/libcrypto/engine/hw_nuron_err.c new file mode 100644 index 0000000000..df9d7bde76 --- /dev/null +++ b/src/lib/libcrypto/engine/hw_nuron_err.c @@ -0,0 +1,142 @@ +/* hw_nuron_err.c */ +/* ==================================================================== + * 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 + * 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 +#include +#include "hw_nuron_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR +static ERR_STRING_DATA NURON_str_functs[]= + { +{ERR_PACK(0,NURON_F_NURON_CTRL,0), "NURON_CTRL"}, +{ERR_PACK(0,NURON_F_NURON_FINISH,0), "NURON_FINISH"}, +{ERR_PACK(0,NURON_F_NURON_INIT,0), "NURON_INIT"}, +{ERR_PACK(0,NURON_F_NURON_MOD_EXP,0), "NURON_MOD_EXP"}, +{0,NULL} + }; + +static ERR_STRING_DATA NURON_str_reasons[]= + { +{NURON_R_ALREADY_LOADED ,"already loaded"}, +{NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"}, +{NURON_R_DSO_FAILURE ,"dso failure"}, +{NURON_R_DSO_FUNCTION_NOT_FOUND ,"dso function not found"}, +{NURON_R_DSO_NOT_FOUND ,"dso not found"}, +{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/src/lib/libcrypto/engine/hw_nuron_err.h b/src/lib/libcrypto/engine/hw_nuron_err.h new file mode 100644 index 0000000000..a56bfdf303 --- /dev/null +++ b/src/lib/libcrypto/engine/hw_nuron_err.h @@ -0,0 +1,86 @@ +/* ==================================================================== + * 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 + +/* 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/src/lib/libcrypto/engine/hw_openbsd_dev_crypto.c b/src/lib/libcrypto/engine/hw_openbsd_dev_crypto.c new file mode 100644 index 0000000000..f946389b8a --- /dev/null +++ b/src/lib/libcrypto/engine/hw_openbsd_dev_crypto.c @@ -0,0 +1,594 @@ +/* Written by Ben Laurie August 2001 */ +/* ==================================================================== + * 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 +#include +#include "eng_int.h" +/* Maybe this is needed? ... */ +#ifdef FLAT_INC +#include "evp_locl.h" +#else +#include "../evp/evp_locl.h" +#endif +#include + +#ifndef OPENSSL_OPENBSD_DEV_CRYPTO + +void ENGINE_load_openbsd_dev_crypto(void) + { + /* This is a NOP unless OPENSSL_OPENBSD_DEV_CRYPTO is defined */ + return; + } + +#else /* OPENSSL_OPENBSD_DEV_CRYPTO */ + +#include +#include +#include +#include +#include +#include + +#include + +/****************************************************/ +/* Declare the normal generic ENGINE stuff here ... */ + +static int dev_crypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid); +static int dev_crypto_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid); + +static const char dev_crypto_id[] = "openbsd_dev_crypto"; +static const char dev_crypto_name[] = "OpenBSD /dev/crypto"; + +static long allow_misaligned; + +#define DEV_CRYPTO_CMD_ALLOW_MISALIGNED ENGINE_CMD_BASE +static const ENGINE_CMD_DEFN dev_crypto_cmd_defns[]= + { + { DEV_CRYPTO_CMD_ALLOW_MISALIGNED, + "allow_misaligned", + "Permit misaligned data to be used", + ENGINE_CMD_FLAG_NUMERIC }, + { 0, NULL, NULL, 0 } + }; + +static int dev_crypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) + { + switch(cmd) + { + case DEV_CRYPTO_CMD_ALLOW_MISALIGNED: + allow_misaligned=i; + printf("allow misaligned=%ld\n",allow_misaligned); + break; + } + + return 1; + } + +static ENGINE *engine_openbsd_dev_crypto(void) + { + ENGINE *engine=ENGINE_new(); + + if(!ENGINE_set_id(engine, dev_crypto_id) || + !ENGINE_set_name(engine, dev_crypto_name) || + !ENGINE_set_ciphers(engine, dev_crypto_ciphers) || + !ENGINE_set_digests(engine, dev_crypto_digests) || + !ENGINE_set_ctrl_function(engine, dev_crypto_ctrl) || + !ENGINE_set_cmd_defns(engine, dev_crypto_cmd_defns)) + { + ENGINE_free(engine); + return NULL; + } + + return engine; + } + +void ENGINE_load_openbsd_dev_crypto(void) + { + /* Copied from eng_[openssl|dyn].c */ + ENGINE *toadd = engine_openbsd_dev_crypto(); + if(!toadd) return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); + } + +/******************************************************************************/ +/* Clip in the stuff from crypto/evp/openbsd_hw.c here. NB: What has changed? */ +/* I've removed the exposed EVP_*** functions, they're accessed through the */ +/* "dev_crypto_[ciphers|digests]" handlers. I've also moved the EVP_CIPHER */ +/* and EVP_MD structures to the bottom where they are close to the handlers */ +/* that expose them. What should be done? The global data (file-descriptors, */ +/* etc) should be put into ENGINE's ex_data support, and per-context data */ +/* (also file-descriptors perhaps) should be put into the contexts. Also code */ +/* formatting, fprintf statements, and OpenSSL-style error handling should be */ +/* added (dynamically, like the other ENGINEs). Also, "dynamic" support */ +/* be added to this ENGINE once it's up and running so that it could be built */ +/* as a shared-library. What else? device initialisation should take place */ +/* inside an ENGINE 'init()' handler (and likewise 'finish()'). ciphers and */ +/* digests won't be used by the framework unless the ENGINE has been */ +/* successfully initialised (that's one of the things you get for free) so */ +/* initialisation, including returning failure if device setup fails, can be */ +/* handled quite cleanly. This could presumably handle the opening (and then */ +/* closing inside 'finish()') of the 'cryptodev_fd' file-descriptor). */ + +/* longest key supported in hardware */ +#define MAX_HW_KEY 24 +#define MAX_HW_IV 8 + +#define MD5_DIGEST_LENGTH 16 +#define MD5_CBLOCK 64 + +static int fd; +static int dev_failed; + +typedef struct session_op session_op; + +#define CDATA(ctx) EVP_C_DATA(session_op,ctx) + +static void err(const char *str) + { + fprintf(stderr,"%s: errno %d\n",str,errno); + } + +static int dev_crypto_init(session_op *ses) + { + if(dev_failed) + return 0; + if(!fd) + { + int cryptodev_fd; + + if ((cryptodev_fd=open("/dev/crypto",O_RDWR,0)) < 0) + { + err("/dev/crypto"); + dev_failed=1; + return 0; + } + if (ioctl(cryptodev_fd,CRIOGET,&fd) == -1) + { + err("CRIOGET failed"); + close(cryptodev_fd); + dev_failed=1; + return 0; + } + close(cryptodev_fd); + } + assert(ses); + memset(ses,'\0',sizeof *ses); + + return 1; + } + +static int dev_crypto_cleanup(EVP_CIPHER_CTX *ctx) + { + fprintf(stderr,"cleanup %d\n",CDATA(ctx)->ses); + if(ioctl(fd,CIOCFSESSION,&CDATA(ctx)->ses) == -1) + err("CIOCFSESSION failed"); + + OPENSSL_free(CDATA(ctx)->key); + + return 1; + } + +static int dev_crypto_init_key(EVP_CIPHER_CTX *ctx,int cipher, + const unsigned char *key,int klen) + { + if(!dev_crypto_init(CDATA(ctx))) + return 0; + + CDATA(ctx)->key=OPENSSL_malloc(MAX_HW_KEY); + + assert(ctx->cipher->iv_len <= MAX_HW_IV); + + memcpy(CDATA(ctx)->key,key,klen); + + CDATA(ctx)->cipher=cipher; + CDATA(ctx)->keylen=klen; + + if (ioctl(fd,CIOCGSESSION,CDATA(ctx)) == -1) + { + err("CIOCGSESSION failed"); + return 0; + } + return 1; + } + +static int dev_crypto_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out, + const unsigned char *in,unsigned int inl) + { + struct crypt_op cryp; + unsigned char lb[MAX_HW_IV]; + + if(!inl) + return 1; + + assert(CDATA(ctx)); + assert(!dev_failed); + + memset(&cryp,'\0',sizeof cryp); + cryp.ses=CDATA(ctx)->ses; + cryp.op=ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT; + cryp.flags=0; + cryp.len=inl; + assert((inl&(ctx->cipher->block_size-1)) == 0); + cryp.src=(caddr_t)in; + cryp.dst=(caddr_t)out; + cryp.mac=0; + if(ctx->cipher->iv_len) + cryp.iv=(caddr_t)ctx->iv; + + if(!ctx->encrypt) + memcpy(lb,&in[cryp.len-ctx->cipher->iv_len],ctx->cipher->iv_len); + + if(ioctl(fd, CIOCCRYPT, &cryp) == -1) + { + if(errno == EINVAL) /* buffers are misaligned */ + { + unsigned int cinl=0; + char *cin=NULL; + char *cout=NULL; + + /* NB: this can only make cinl != inl with stream ciphers */ + cinl=(inl+3)/4*4; + + if(((unsigned long)in&3) || cinl != inl) + { + cin=OPENSSL_malloc(cinl); + memcpy(cin,in,inl); + cryp.src=cin; + } + + if(((unsigned long)out&3) || cinl != inl) + { + cout=OPENSSL_malloc(cinl); + cryp.dst=cout; + } + + cryp.len=cinl; + + if(ioctl(fd, CIOCCRYPT, &cryp) == -1) + { + err("CIOCCRYPT(2) failed"); + printf("src=%p dst=%p\n",cryp.src,cryp.dst); + abort(); + return 0; + } + + if(cout) + { + memcpy(out,cout,inl); + OPENSSL_free(cout); + } + if(cin) + OPENSSL_free(cin); + } + else + { + err("CIOCCRYPT failed"); + abort(); + return 0; + } + } + + if(ctx->encrypt) + memcpy(ctx->iv,&out[cryp.len-ctx->cipher->iv_len],ctx->cipher->iv_len); + else + memcpy(ctx->iv,lb,ctx->cipher->iv_len); + + return 1; + } + +static int dev_crypto_des_ede3_init_key(EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, int enc) + { return dev_crypto_init_key(ctx,CRYPTO_3DES_CBC,key,24); } + +static int dev_crypto_rc4_init_key(EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, int enc) + { return dev_crypto_init_key(ctx,CRYPTO_ARC4,key,16); } + +typedef struct + { + session_op sess; + char *data; + int len; + unsigned char md[EVP_MAX_MD_SIZE]; + } MD_DATA; + +static int dev_crypto_init_digest(MD_DATA *md_data,int mac) + { + if(!dev_crypto_init(&md_data->sess)) + return 0; + + md_data->len=0; + md_data->data=NULL; + + md_data->sess.mac=mac; + + if (ioctl(fd,CIOCGSESSION,&md_data->sess) == -1) + { + err("CIOCGSESSION failed"); + return 0; + } + fprintf(stderr,"opened %d\n",md_data->sess.ses); + return 1; + } + +static int dev_crypto_cleanup_digest(MD_DATA *md_data) + { + fprintf(stderr,"cleanup %d\n",md_data->sess.ses); + if (ioctl(fd,CIOCFSESSION,&md_data->sess.ses) == -1) + { + err("CIOCFSESSION failed"); + return 0; + } + + return 1; + } + +/* FIXME: if device can do chained MACs, then don't accumulate */ +/* FIXME: move accumulation to the framework */ +static int dev_crypto_md5_init(EVP_MD_CTX *ctx) + { return dev_crypto_init_digest(ctx->md_data,CRYPTO_MD5); } + +static int do_digest(int ses,unsigned char *md,const void *data,int len) + { + struct crypt_op cryp; + static unsigned char md5zero[16]= + { + 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04, + 0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,0x7e + }; + + /* some cards can't do zero length */ + if(!len) + { + memcpy(md,md5zero,16); + return 1; + } + + memset(&cryp,'\0',sizeof cryp); + cryp.ses=ses; + cryp.op=COP_ENCRYPT;/* required to do the MAC rather than check it */ + cryp.len=len; + cryp.src=(caddr_t)data; + cryp.dst=(caddr_t)data; // FIXME!!! + cryp.mac=(caddr_t)md; + + if(ioctl(fd, CIOCCRYPT, &cryp) == -1) + { + if(errno == EINVAL && allow_misaligned) /* buffer is misaligned */ + { + char *dcopy; + + dcopy=OPENSSL_malloc(len); + memcpy(dcopy,data,len); + cryp.src=dcopy; + cryp.dst=cryp.src; // FIXME!!! + + if(ioctl(fd, CIOCCRYPT, &cryp) == -1) + { + err("CIOCCRYPT(MAC2) failed"); + abort(); + return 0; + } + OPENSSL_free(dcopy); + } + else + { + err("CIOCCRYPT(MAC) failed"); + abort(); + return 0; + } + } + // printf("done\n"); + + return 1; + } + +static int dev_crypto_md5_update(EVP_MD_CTX *ctx,const void *data, + unsigned long len) + { + MD_DATA *md_data=ctx->md_data; + + if(ctx->flags&EVP_MD_CTX_FLAG_ONESHOT) + return do_digest(md_data->sess.ses,md_data->md,data,len); + + md_data->data=OPENSSL_realloc(md_data->data,md_data->len+len); + memcpy(md_data->data+md_data->len,data,len); + md_data->len+=len; + + return 1; + } + +static int dev_crypto_md5_final(EVP_MD_CTX *ctx,unsigned char *md) + { + int ret; + MD_DATA *md_data=ctx->md_data; + + if(ctx->flags&EVP_MD_CTX_FLAG_ONESHOT) + { + memcpy(md,md_data->md,MD5_DIGEST_LENGTH); + ret=1; + } + else + { + ret=do_digest(md_data->sess.ses,md,md_data->data,md_data->len); + OPENSSL_free(md_data->data); + md_data->data=NULL; + md_data->len=0; + } + + return ret; + } + +static int dev_crypto_md5_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from) + { + const MD_DATA *from_md=from->md_data; + MD_DATA *to_md=to->md_data; + + // How do we copy sessions? + assert(from->digest->flags&EVP_MD_FLAG_ONESHOT); + + to_md->data=OPENSSL_malloc(from_md->len); + memcpy(to_md->data,from_md->data,from_md->len); + + return 1; + } + +static int dev_crypto_md5_cleanup(EVP_MD_CTX *ctx) + { + return dev_crypto_cleanup_digest(ctx->md_data); + } + +/**************************************************************************/ +/* Here are the moved declarations of the EVP_CIPHER and EVP_MD */ +/* implementations. They're down here to be within easy editor-distance */ +/* of the digests and ciphers handler functions. */ + +#define dev_crypto_des_ede3_cbc_cipher dev_crypto_cipher + +BLOCK_CIPHER_def_cbc(dev_crypto_des_ede3, session_op, NID_des_ede3, 8, 24, 8, + 0, dev_crypto_des_ede3_init_key, + dev_crypto_cleanup, + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL) + +static const EVP_CIPHER r4_cipher= + { + NID_rc4, + 1,16,0, /* FIXME: key should be up to 256 bytes */ + EVP_CIPH_VARIABLE_LENGTH, + dev_crypto_rc4_init_key, + dev_crypto_cipher, + dev_crypto_cleanup, + sizeof(session_op), + NULL, + NULL, + NULL + }; + +static const EVP_MD md5_md= + { + NID_md5, + NID_md5WithRSAEncryption, + MD5_DIGEST_LENGTH, + EVP_MD_FLAG_ONESHOT, // XXX: set according to device info... + dev_crypto_md5_init, + dev_crypto_md5_update, + dev_crypto_md5_final, + dev_crypto_md5_copy, + dev_crypto_md5_cleanup, + EVP_PKEY_RSA_method, + MD5_CBLOCK, + sizeof(MD_DATA), + }; + +/****************************************************************/ +/* Implement the dev_crypto_[ciphers|digests] handlers here ... */ + +static int cipher_nids[] = {NID_des_ede3_cbc, NID_rc4}; +static int cipher_nids_num = 2; +static int digest_nids[] = {NID_md5}; +static int digest_nids_num = 1; + +static int dev_crypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid) + { + if(!cipher) + { + /* We are returning a list of supported nids */ + *nids = cipher_nids; + return cipher_nids_num; + } + /* We are being asked for a specific cipher */ + if(nid == NID_rc4) + *cipher = &r4_cipher; + else if(nid == NID_des_ede3_cbc) + *cipher = &dev_crypto_des_ede3_cbc; + else + { + *cipher = NULL; + return 0; + } + return 1; + } + +static int dev_crypto_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid) + { + if(!digest) + { + /* We are returning a list of supported nids */ + *nids = digest_nids; + return digest_nids_num; + } + /* We are being asked for a specific digest */ + if(nid == NID_md5) + *digest = &md5_md; + else + { + *digest = NULL; + return 0; + } + return 1; + } + +#endif /* OPENSSL_OPENBSD_DEV_CRYPTO */ diff --git a/src/lib/libcrypto/engine/hw_sureware_err.c b/src/lib/libcrypto/engine/hw_sureware_err.c new file mode 100644 index 0000000000..69955dadbb --- /dev/null +++ b/src/lib/libcrypto/engine/hw_sureware_err.c @@ -0,0 +1,150 @@ +/* hw_sureware_err.c */ +/* ==================================================================== + * 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 + * 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 +#include +#include "hw_sureware_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR +static ERR_STRING_DATA SUREWARE_str_functs[]= + { +{ERR_PACK(0,SUREWARE_F_SUREWAREHK_CTRL,0), "SUREWAREHK_CTRL"}, +{ERR_PACK(0,SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,0), "SUREWAREHK_DSA_DO_SIGN"}, +{ERR_PACK(0,SUREWARE_F_SUREWAREHK_EX_FREE,0), "SUREWAREHK_EX_FREE"}, +{ERR_PACK(0,SUREWARE_F_SUREWAREHK_FINISH,0), "SUREWAREHK_FINISH"}, +{ERR_PACK(0,SUREWARE_F_SUREWAREHK_INIT,0), "SUREWAREHK_INIT"}, +{ERR_PACK(0,SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,0), "SUREWAREHK_LOAD_PRIVATE_KEY"}, +{ERR_PACK(0,SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,0), "SUREWAREHK_LOAD_PUBLIC_KEY"}, +{ERR_PACK(0,SUREWARE_F_SUREWAREHK_MOD_EXP,0), "SUREWAREHK_MOD_EXP"}, +{ERR_PACK(0,SUREWARE_F_SUREWAREHK_RAND_BYTES,0), "SUREWAREHK_RAND_BYTES"}, +{ERR_PACK(0,SUREWARE_F_SUREWAREHK_RAND_SEED,0), "SUREWAREHK_RAND_SEED"}, +{ERR_PACK(0,SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,0), "SUREWAREHK_RSA_PRIV_DEC"}, +{ERR_PACK(0,SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC,0), "SUREWAREHK_RSA_PRIV_ENC"}, +{0,NULL} + }; + +static ERR_STRING_DATA SUREWARE_str_reasons[]= + { +{SUREWARE_R_BIO_WAS_FREED ,"bio was freed"}, +{SUREWARE_R_MISSING_KEY_COMPONENTS ,"missing key components"}, +{SUREWARE_R_REQUEST_FAILED ,"request failed"}, +{SUREWARE_R_REQUEST_FALLBACK ,"request fallback"}, +{SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"}, +{SUREWARE_R_UNIT_FAILURE ,"unit failure"}, +{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/src/lib/libcrypto/engine/hw_sureware_err.h b/src/lib/libcrypto/engine/hw_sureware_err.h new file mode 100644 index 0000000000..bc52af5e05 --- /dev/null +++ b/src/lib/libcrypto/engine/hw_sureware_err.h @@ -0,0 +1,94 @@ +/* ==================================================================== + * 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 + +/* 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_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_PRIVATE_KEY 105 +#define SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY 106 +#define SUREWARE_F_SUREWAREHK_MOD_EXP 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_PRIV_ENC 111 + +/* Reason codes. */ +#define SUREWARE_R_BIO_WAS_FREED 100 +#define SUREWARE_R_MISSING_KEY_COMPONENTS 105 +#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 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/lib/libcrypto/engine/hw_ubsec.c b/src/lib/libcrypto/engine/hw_ubsec.c new file mode 100644 index 0000000000..743c06043c --- /dev/null +++ b/src/lib/libcrypto/engine/hw_ubsec.c @@ -0,0 +1,1041 @@ +/* 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 +#include +#include "cryptlib.h" +#include +#include + +#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 "hw_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)()); +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); +#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 +#if 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 + +#if 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 + }; +#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 */ + }; +#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 + }; +#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; + } + +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(); + } + +/* 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 = "ubsec"; +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) + { + 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, 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); + 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) + { + 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)()) + { + 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; + } + UBSEC_LIBNAME = (const char *)p; + return 1; + 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; + } + memset(r->d, 0, BN_num_bytes(m)); + + if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { + fd = 0; + UBSECerr(UBSEC_F_UBSEC_INIT, 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((ctx = BN_CTX_new()) == NULL) + goto err; + + 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); + } +err: + if(ctx) + BN_CTX_free(ctx); + 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, 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_RSA_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_INIT, 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, 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 +#if 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_SIGN, UBSEC_R_BN_EXPAND_FAIL); + goto err; + } + + if (BN_bin2bn(dgst,dlen,&m) == NULL) { + UBSECerr(UBSEC_F_UBSEC_DSA_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_INIT, 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_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_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; + + BN_init(&v); + + if(!bn_wexpand(&v, 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_INIT, 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; + ENGINEerr(UBSEC_F_UBSEC_INIT, 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; + ENGINEerr(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; + ENGINEerr(UBSEC_F_UBSEC_INIT, 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; + + ENGINEerr(UBSEC_F_UBSEC_DH_COMPUTE_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 + +#if 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; + ENGINEerr(UBSEC_F_UBSEC_INIT, 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; + + ENGINEerr(UBSEC_F_UBSEC_RNG_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. */ +#ifdef ENGINE_DYNAMIC_SUPPORT +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 /* ENGINE_DYNAMIC_SUPPORT */ + +#endif /* !OPENSSL_NO_HW_UBSEC */ +#endif /* !OPENSSL_NO_HW */ diff --git a/src/lib/libcrypto/engine/hw_ubsec_err.c b/src/lib/libcrypto/engine/hw_ubsec_err.c new file mode 100644 index 0000000000..d707331fc2 --- /dev/null +++ b/src/lib/libcrypto/engine/hw_ubsec_err.c @@ -0,0 +1,151 @@ +/* hw_ubsec_err.c */ +/* ==================================================================== + * 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 + * 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 +#include +#include "hw_ubsec_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR +static ERR_STRING_DATA UBSEC_str_functs[]= + { +{ERR_PACK(0,UBSEC_F_UBSEC_CTRL,0), "UBSEC_CTRL"}, +{ERR_PACK(0,UBSEC_F_UBSEC_DH_COMPUTE_KEY,0), "UBSEC_DH_COMPUTE_KEY"}, +{ERR_PACK(0,UBSEC_F_UBSEC_DSA_SIGN,0), "UBSEC_DSA_SIGN"}, +{ERR_PACK(0,UBSEC_F_UBSEC_DSA_VERIFY,0), "UBSEC_DSA_VERIFY"}, +{ERR_PACK(0,UBSEC_F_UBSEC_FINISH,0), "UBSEC_FINISH"}, +{ERR_PACK(0,UBSEC_F_UBSEC_INIT,0), "UBSEC_INIT"}, +{ERR_PACK(0,UBSEC_F_UBSEC_MOD_EXP,0), "UBSEC_MOD_EXP"}, +{ERR_PACK(0,UBSEC_F_UBSEC_RNG_BYTES,0), "UBSEC_RNG_BYTES"}, +{ERR_PACK(0,UBSEC_F_UBSEC_RSA_MOD_EXP,0), "UBSEC_RSA_MOD_EXP"}, +{ERR_PACK(0,UBSEC_F_UBSEC_RSA_MOD_EXP_CRT,0), "UBSEC_RSA_MOD_EXP_CRT"}, +{0,NULL} + }; + +static ERR_STRING_DATA UBSEC_str_reasons[]= + { +{UBSEC_R_ALREADY_LOADED ,"already loaded"}, +{UBSEC_R_BN_EXPAND_FAIL ,"bn expand fail"}, +{UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"}, +{UBSEC_R_DSO_FAILURE ,"dso failure"}, +{UBSEC_R_MISSING_KEY_COMPONENTS ,"missing key components"}, +{UBSEC_R_NOT_LOADED ,"not loaded"}, +{UBSEC_R_REQUEST_FAILED ,"request failed"}, +{UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"}, +{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/src/lib/libcrypto/engine/hw_ubsec_err.h b/src/lib/libcrypto/engine/hw_ubsec_err.h new file mode 100644 index 0000000000..023d3be771 --- /dev/null +++ b/src/lib/libcrypto/engine/hw_ubsec_err.h @@ -0,0 +1,95 @@ +/* ==================================================================== + * 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 + +/* 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_DSA_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_RNG_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/src/lib/libcrypto/engine/tb_cipher.c b/src/lib/libcrypto/engine/tb_cipher.c new file mode 100644 index 0000000000..c5a50fc910 --- /dev/null +++ b/src/lib/libcrypto/engine/tb_cipher.c @@ -0,0 +1,145 @@ +/* ==================================================================== + * Copyright (c) 2000 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 +#include +#include "eng_int.h" + +/* If this symbol is defined then ENGINE_get_cipher_engine(), the function that + * is used by EVP to hook in cipher code and cache defaults (etc), will display + * brief debugging summaries to stderr with the 'nid'. */ +/* #define ENGINE_CIPHER_DEBUG */ + +static ENGINE_TABLE *cipher_table = NULL; + +void ENGINE_unregister_ciphers(ENGINE *e) + { + engine_table_unregister(&cipher_table, e); + } + +static void engine_unregister_all_ciphers(void) + { + engine_table_cleanup(&cipher_table); + } + +int ENGINE_register_ciphers(ENGINE *e) + { + if(e->ciphers) + { + const int *nids; + int num_nids = e->ciphers(e, NULL, &nids, 0); + if(num_nids > 0) + return engine_table_register(&cipher_table, + &engine_unregister_all_ciphers, e, nids, + num_nids, 0); + } + return 1; + } + +void ENGINE_register_all_ciphers() + { + ENGINE *e; + + for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) + ENGINE_register_ciphers(e); + } + +int ENGINE_set_default_ciphers(ENGINE *e) + { + if(e->ciphers) + { + const int *nids; + int num_nids = e->ciphers(e, NULL, &nids, 0); + if(num_nids > 0) + return engine_table_register(&cipher_table, + &engine_unregister_all_ciphers, e, nids, + num_nids, 1); + } + return 1; + } + +/* Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references) for a given cipher 'nid' */ +ENGINE *ENGINE_get_cipher_engine(int nid) + { + return engine_table_select(&cipher_table, nid); + } + +/* Obtains a cipher implementation from an ENGINE functional reference */ +const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid) + { + const EVP_CIPHER *ret; + ENGINE_CIPHERS_PTR fn = ENGINE_get_ciphers(e); + if(!fn || !fn(e, &ret, NULL, nid)) + { + ENGINEerr(ENGINE_F_ENGINE_GET_CIPHER, + ENGINE_R_UNIMPLEMENTED_CIPHER); + return NULL; + } + return ret; + } + +/* Gets the cipher callback from an ENGINE structure */ +ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e) + { + return e->ciphers; + } + +/* Sets the cipher callback in an ENGINE structure */ +int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f) + { + e->ciphers = f; + return 1; + } diff --git a/src/lib/libcrypto/engine/tb_dh.c b/src/lib/libcrypto/engine/tb_dh.c new file mode 100644 index 0000000000..c9347235ea --- /dev/null +++ b/src/lib/libcrypto/engine/tb_dh.c @@ -0,0 +1,120 @@ +/* ==================================================================== + * Copyright (c) 2000 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 +#include +#include "eng_int.h" + +/* If this symbol is defined then ENGINE_get_default_DH(), the function that is + * used by DH to hook in implementation code and cache defaults (etc), will + * display brief debugging summaries to stderr with the 'nid'. */ +/* #define ENGINE_DH_DEBUG */ + +static ENGINE_TABLE *dh_table = NULL; +static const int dummy_nid = 1; + +void ENGINE_unregister_DH(ENGINE *e) + { + engine_table_unregister(&dh_table, e); + } + +static void engine_unregister_all_DH(void) + { + engine_table_cleanup(&dh_table); + } + +int ENGINE_register_DH(ENGINE *e) + { + if(e->dh_meth) + return engine_table_register(&dh_table, + &engine_unregister_all_DH, e, &dummy_nid, 1, 0); + return 1; + } + +void ENGINE_register_all_DH() + { + ENGINE *e; + + for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) + ENGINE_register_DH(e); + } + +int ENGINE_set_default_DH(ENGINE *e) + { + if(e->dh_meth) + return engine_table_register(&dh_table, + &engine_unregister_all_DH, e, &dummy_nid, 1, 1); + return 1; + } + +/* Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references). */ +ENGINE *ENGINE_get_default_DH(void) + { + return engine_table_select(&dh_table, dummy_nid); + } + +/* Obtains an DH implementation from an ENGINE functional reference */ +const DH_METHOD *ENGINE_get_DH(const ENGINE *e) + { + return e->dh_meth; + } + +/* Sets an DH implementation in an ENGINE structure */ +int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth) + { + e->dh_meth = dh_meth; + return 1; + } diff --git a/src/lib/libcrypto/engine/tb_digest.c b/src/lib/libcrypto/engine/tb_digest.c new file mode 100644 index 0000000000..2c4dd6f796 --- /dev/null +++ b/src/lib/libcrypto/engine/tb_digest.c @@ -0,0 +1,145 @@ +/* ==================================================================== + * Copyright (c) 2000 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 +#include +#include "eng_int.h" + +/* If this symbol is defined then ENGINE_get_digest_engine(), the function that + * is used by EVP to hook in digest code and cache defaults (etc), will display + * brief debugging summaries to stderr with the 'nid'. */ +/* #define ENGINE_DIGEST_DEBUG */ + +static ENGINE_TABLE *digest_table = NULL; + +void ENGINE_unregister_digests(ENGINE *e) + { + engine_table_unregister(&digest_table, e); + } + +static void engine_unregister_all_digests(void) + { + engine_table_cleanup(&digest_table); + } + +int ENGINE_register_digests(ENGINE *e) + { + if(e->digests) + { + const int *nids; + int num_nids = e->digests(e, NULL, &nids, 0); + if(num_nids > 0) + return engine_table_register(&digest_table, + &engine_unregister_all_digests, e, nids, + num_nids, 0); + } + return 1; + } + +void ENGINE_register_all_digests() + { + ENGINE *e; + + for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) + ENGINE_register_digests(e); + } + +int ENGINE_set_default_digests(ENGINE *e) + { + if(e->digests) + { + const int *nids; + int num_nids = e->digests(e, NULL, &nids, 0); + if(num_nids > 0) + return engine_table_register(&digest_table, + &engine_unregister_all_digests, e, nids, + num_nids, 1); + } + return 1; + } + +/* Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references) for a given digest 'nid' */ +ENGINE *ENGINE_get_digest_engine(int nid) + { + return engine_table_select(&digest_table, nid); + } + +/* Obtains a digest implementation from an ENGINE functional reference */ +const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid) + { + const EVP_MD *ret; + ENGINE_DIGESTS_PTR fn = ENGINE_get_digests(e); + if(!fn || !fn(e, &ret, NULL, nid)) + { + ENGINEerr(ENGINE_F_ENGINE_GET_DIGEST, + ENGINE_R_UNIMPLEMENTED_DIGEST); + return NULL; + } + return ret; + } + +/* Gets the digest callback from an ENGINE structure */ +ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e) + { + return e->digests; + } + +/* Sets the digest callback in an ENGINE structure */ +int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f) + { + e->digests = f; + return 1; + } diff --git a/src/lib/libcrypto/engine/tb_dsa.c b/src/lib/libcrypto/engine/tb_dsa.c new file mode 100644 index 0000000000..e9209476b8 --- /dev/null +++ b/src/lib/libcrypto/engine/tb_dsa.c @@ -0,0 +1,120 @@ +/* ==================================================================== + * Copyright (c) 2000 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 +#include +#include "eng_int.h" + +/* If this symbol is defined then ENGINE_get_default_DSA(), the function that is + * used by DSA to hook in implementation code and cache defaults (etc), will + * display brief debugging summaries to stderr with the 'nid'. */ +/* #define ENGINE_DSA_DEBUG */ + +static ENGINE_TABLE *dsa_table = NULL; +static const int dummy_nid = 1; + +void ENGINE_unregister_DSA(ENGINE *e) + { + engine_table_unregister(&dsa_table, e); + } + +static void engine_unregister_all_DSA(void) + { + engine_table_cleanup(&dsa_table); + } + +int ENGINE_register_DSA(ENGINE *e) + { + if(e->dsa_meth) + return engine_table_register(&dsa_table, + &engine_unregister_all_DSA, e, &dummy_nid, 1, 0); + return 1; + } + +void ENGINE_register_all_DSA() + { + ENGINE *e; + + for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) + ENGINE_register_DSA(e); + } + +int ENGINE_set_default_DSA(ENGINE *e) + { + if(e->dsa_meth) + return engine_table_register(&dsa_table, + &engine_unregister_all_DSA, e, &dummy_nid, 1, 0); + return 1; + } + +/* Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references). */ +ENGINE *ENGINE_get_default_DSA(void) + { + return engine_table_select(&dsa_table, dummy_nid); + } + +/* Obtains an DSA implementation from an ENGINE functional reference */ +const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e) + { + return e->dsa_meth; + } + +/* Sets an DSA implementation in an ENGINE structure */ +int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth) + { + e->dsa_meth = dsa_meth; + return 1; + } diff --git a/src/lib/libcrypto/engine/tb_rand.c b/src/lib/libcrypto/engine/tb_rand.c new file mode 100644 index 0000000000..0b1d031f1e --- /dev/null +++ b/src/lib/libcrypto/engine/tb_rand.c @@ -0,0 +1,120 @@ +/* ==================================================================== + * Copyright (c) 2000 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 +#include +#include "eng_int.h" + +/* If this symbol is defined then ENGINE_get_default_RAND(), the function that is + * used by RAND to hook in implementation code and cache defaults (etc), will + * display brief debugging summaries to stderr with the 'nid'. */ +/* #define ENGINE_RAND_DEBUG */ + +static ENGINE_TABLE *rand_table = NULL; +static const int dummy_nid = 1; + +void ENGINE_unregister_RAND(ENGINE *e) + { + engine_table_unregister(&rand_table, e); + } + +static void engine_unregister_all_RAND(void) + { + engine_table_cleanup(&rand_table); + } + +int ENGINE_register_RAND(ENGINE *e) + { + if(e->rand_meth) + return engine_table_register(&rand_table, + &engine_unregister_all_RAND, e, &dummy_nid, 1, 0); + return 1; + } + +void ENGINE_register_all_RAND() + { + ENGINE *e; + + for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) + ENGINE_register_RAND(e); + } + +int ENGINE_set_default_RAND(ENGINE *e) + { + if(e->rand_meth) + return engine_table_register(&rand_table, + &engine_unregister_all_RAND, e, &dummy_nid, 1, 1); + return 1; + } + +/* Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references). */ +ENGINE *ENGINE_get_default_RAND(void) + { + return engine_table_select(&rand_table, dummy_nid); + } + +/* Obtains an RAND implementation from an ENGINE functional reference */ +const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e) + { + return e->rand_meth; + } + +/* Sets an RAND implementation in an ENGINE structure */ +int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth) + { + e->rand_meth = rand_meth; + return 1; + } diff --git a/src/lib/libcrypto/engine/tb_rsa.c b/src/lib/libcrypto/engine/tb_rsa.c new file mode 100644 index 0000000000..f84fea3968 --- /dev/null +++ b/src/lib/libcrypto/engine/tb_rsa.c @@ -0,0 +1,120 @@ +/* ==================================================================== + * Copyright (c) 2000 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 +#include +#include "eng_int.h" + +/* If this symbol is defined then ENGINE_get_default_RSA(), the function that is + * used by RSA to hook in implementation code and cache defaults (etc), will + * display brief debugging summaries to stderr with the 'nid'. */ +/* #define ENGINE_RSA_DEBUG */ + +static ENGINE_TABLE *rsa_table = NULL; +static const int dummy_nid = 1; + +void ENGINE_unregister_RSA(ENGINE *e) + { + engine_table_unregister(&rsa_table, e); + } + +static void engine_unregister_all_RSA(void) + { + engine_table_cleanup(&rsa_table); + } + +int ENGINE_register_RSA(ENGINE *e) + { + if(e->rsa_meth) + return engine_table_register(&rsa_table, + &engine_unregister_all_RSA, e, &dummy_nid, 1, 0); + return 1; + } + +void ENGINE_register_all_RSA() + { + ENGINE *e; + + for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) + ENGINE_register_RSA(e); + } + +int ENGINE_set_default_RSA(ENGINE *e) + { + if(e->rsa_meth) + return engine_table_register(&rsa_table, + &engine_unregister_all_RSA, e, &dummy_nid, 1, 1); + return 1; + } + +/* Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references). */ +ENGINE *ENGINE_get_default_RSA(void) + { + return engine_table_select(&rsa_table, dummy_nid); + } + +/* Obtains an RSA implementation from an ENGINE functional reference */ +const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e) + { + return e->rsa_meth; + } + +/* Sets an RSA implementation in an ENGINE structure */ +int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth) + { + e->rsa_meth = rsa_meth; + return 1; + } diff --git a/src/lib/libcrypto/engine/vendor_defns/aep.h b/src/lib/libcrypto/engine/vendor_defns/aep.h new file mode 100644 index 0000000000..2b2792d2d6 --- /dev/null +++ b/src/lib/libcrypto/engine/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(); +typedef AEP_RV t_AEP_SetBNCallBacks(AEP_RV (*GetBigNumSizeFunc)(), + AEP_RV (*MakeAEPBigNumFunc)(), + AEP_RV (*ConverAEPBigNumFunc)()); + diff --git a/src/lib/libcrypto/engine/vendor_defns/atalla.h b/src/lib/libcrypto/engine/vendor_defns/atalla.h index 8111649c54..149970d441 100644 --- a/src/lib/libcrypto/engine/vendor_defns/atalla.h +++ b/src/lib/libcrypto/engine/vendor_defns/atalla.h @@ -46,16 +46,3 @@ typedef int tfnASI_RSAPrivateKeyOpFn(RSAPrivateKey * rsaKey, unsigned char *input, unsigned int modulus_len); -/* 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 = "atasi"; -static const char *ATALLA_F1 = "ASI_GetHardwareConfig"; -static const char *ATALLA_F2 = "ASI_RSAPrivateKeyOpFn"; -static const char *ATALLA_F3 = "ASI_GetPerformanceStatistics"; - diff --git a/src/lib/libcrypto/engine/vendor_defns/cswift.h b/src/lib/libcrypto/engine/vendor_defns/cswift.h index 0af14a1a92..60079326bb 100644 --- a/src/lib/libcrypto/engine/vendor_defns/cswift.h +++ b/src/lib/libcrypto/engine/vendor_defns/cswift.h @@ -32,12 +32,12 @@ typedef __uint32_t SW_U32; typedef unsigned long SW_U32; /* 32 bit integer */ #endif -#if defined(WIN32) +#if defined(OPENSSL_SYS_WIN32) typedef struct _SW_U64 { SW_U32 low32; SW_U32 high32; } SW_U64; /* 64 bit integer */ -#elif defined(MAC) +#elif defined(OPENSSL_SYS_MACINTOSH_CLASSIC) typedef longlong SW_U64 #else /* Unix variants */ typedef struct _SW_U64 { @@ -156,6 +156,27 @@ typedef struct _SW_LARGENUMBER { /* bytes in network (big endian) order */ } SW_LARGENUMBER; +#if defined(OPENSSL_SYS_WIN32) + #include + 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 */ @@ -196,16 +217,16 @@ 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 t_swAcquireAccContext(SW_CONTEXT_HANDLE *hac); -typedef SW_STATUS t_swAttachKeyParam(SW_CONTEXT_HANDLE hac, - SW_PARAM *key_params); -typedef SW_STATUS 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 t_swReleaseAccContext(SW_CONTEXT_HANDLE hac); +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 } diff --git a/src/lib/libcrypto/engine/vendor_defns/hw_4758_cca.h b/src/lib/libcrypto/engine/vendor_defns/hw_4758_cca.h new file mode 100644 index 0000000000..296636e81a --- /dev/null +++ b/src/lib/libcrypto/engine/vendor_defns/hw_4758_cca.h @@ -0,0 +1,149 @@ +/**********************************************************************/ +/* */ +/* Prototypes of the CCA verbs used by the 4758 CCA openssl driver */ +/* */ +/* Maurice Gittens */ +/* */ +/**********************************************************************/ + +#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 -- cgit v1.2.3-55-g6feb