summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/engine')
-rw-r--r--src/lib/libcrypto/engine/Makefile.ssl507
-rw-r--r--src/lib/libcrypto/engine/README483
-rw-r--r--src/lib/libcrypto/engine/eng_all.c118
-rw-r--r--src/lib/libcrypto/engine/eng_cnf.c242
-rw-r--r--src/lib/libcrypto/engine/eng_ctrl.c387
-rw-r--r--src/lib/libcrypto/engine/eng_dyn.c446
-rw-r--r--src/lib/libcrypto/engine/eng_err.c165
-rw-r--r--src/lib/libcrypto/engine/eng_fat.c148
-rw-r--r--src/lib/libcrypto/engine/eng_init.c158
-rw-r--r--src/lib/libcrypto/engine/eng_int.h185
-rw-r--r--src/lib/libcrypto/engine/eng_lib.c321
-rw-r--r--src/lib/libcrypto/engine/eng_list.c383
-rw-r--r--src/lib/libcrypto/engine/eng_openssl.c347
-rw-r--r--src/lib/libcrypto/engine/eng_pkey.c157
-rw-r--r--src/lib/libcrypto/engine/eng_table.c361
-rw-r--r--src/lib/libcrypto/engine/engine.h653
-rw-r--r--src/lib/libcrypto/engine/enginetest.c45
-rw-r--r--src/lib/libcrypto/engine/hw.ec8
-rw-r--r--src/lib/libcrypto/engine/hw_4758_cca.c950
-rw-r--r--src/lib/libcrypto/engine/hw_4758_cca_err.c149
-rw-r--r--src/lib/libcrypto/engine/hw_4758_cca_err.h93
-rw-r--r--src/lib/libcrypto/engine/hw_aep.c1101
-rw-r--r--src/lib/libcrypto/engine/hw_aep_err.c157
-rw-r--r--src/lib/libcrypto/engine/hw_aep_err.h101
-rw-r--r--src/lib/libcrypto/engine/hw_atalla.c283
-rw-r--r--src/lib/libcrypto/engine/hw_atalla_err.c145
-rw-r--r--src/lib/libcrypto/engine/hw_atalla_err.h89
-rw-r--r--src/lib/libcrypto/engine/hw_cryptodev.c926
-rw-r--r--src/lib/libcrypto/engine/hw_cswift.c322
-rw-r--r--src/lib/libcrypto/engine/hw_cswift_err.c149
-rw-r--r--src/lib/libcrypto/engine/hw_cswift_err.h93
-rw-r--r--src/lib/libcrypto/engine/hw_ncipher.c662
-rw-r--r--src/lib/libcrypto/engine/hw_ncipher_err.c156
-rw-r--r--src/lib/libcrypto/engine/hw_ncipher_err.h100
-rw-r--r--src/lib/libcrypto/engine/hw_nuron.c399
-rw-r--r--src/lib/libcrypto/engine/hw_nuron_err.c142
-rw-r--r--src/lib/libcrypto/engine/hw_nuron_err.h86
-rw-r--r--src/lib/libcrypto/engine/hw_openbsd_dev_crypto.c594
-rw-r--r--src/lib/libcrypto/engine/hw_sureware_err.c150
-rw-r--r--src/lib/libcrypto/engine/hw_sureware_err.h94
-rw-r--r--src/lib/libcrypto/engine/hw_ubsec.c1041
-rw-r--r--src/lib/libcrypto/engine/hw_ubsec_err.c151
-rw-r--r--src/lib/libcrypto/engine/hw_ubsec_err.h95
-rw-r--r--src/lib/libcrypto/engine/tb_cipher.c145
-rw-r--r--src/lib/libcrypto/engine/tb_dh.c120
-rw-r--r--src/lib/libcrypto/engine/tb_digest.c145
-rw-r--r--src/lib/libcrypto/engine/tb_dsa.c120
-rw-r--r--src/lib/libcrypto/engine/tb_rand.c120
-rw-r--r--src/lib/libcrypto/engine/tb_rsa.c120
-rw-r--r--src/lib/libcrypto/engine/vendor_defns/aep.h178
-rw-r--r--src/lib/libcrypto/engine/vendor_defns/atalla.h13
-rw-r--r--src/lib/libcrypto/engine/vendor_defns/cswift.h45
-rw-r--r--src/lib/libcrypto/engine/vendor_defns/hw_4758_cca.h149
53 files changed, 13515 insertions, 982 deletions
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 @@
5DIR= engine 5DIR= engine
6TOP= ../.. 6TOP= ../..
7CC= cc 7CC= cc
8INCLUDES= -I.. -I../../include 8INCLUDES= -I.. -I$(TOP) -I../../include
9CFLAG=-g 9CFLAG=-g
10INSTALL_PREFIX= 10INSTALL_PREFIX=
11OPENSSLDIR= /usr/local/ssl 11OPENSSLDIR= /usr/local/ssl
12INSTALLTOP=/usr/local/ssl 12INSTALLTOP=/usr/local/ssl
13MAKE= make -f Makefile.ssl 13MAKE= make -f Makefile.ssl
14MAKEDEPEND= $(TOP)/util/domd $(TOP) 14MAKEDEPPROG= makedepend
15MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
15MAKEFILE= Makefile.ssl 16MAKEFILE= Makefile.ssl
16AR= ar r 17AR= ar r
17 18
@@ -22,10 +23,18 @@ TEST= enginetest.c
22APPS= 23APPS=
23 24
24LIB=$(TOP)/libcrypto.a 25LIB=$(TOP)/libcrypto.a
25LIBSRC= engine_err.c engine_lib.c engine_list.c engine_openssl.c \ 26LIBSRC= eng_err.c eng_lib.c eng_list.c eng_init.c eng_ctrl.c \
26 hw_atalla.c hw_cswift.c hw_ncipher.c 27 eng_table.c eng_pkey.c eng_fat.c eng_all.c \
27LIBOBJ= engine_err.o engine_lib.o engine_list.o engine_openssl.o \ 28 tb_rsa.c tb_dsa.c tb_dh.c tb_rand.c tb_cipher.c tb_digest.c \
28 hw_atalla.o hw_cswift.o hw_ncipher.o 29 eng_openssl.c eng_dyn.c eng_cnf.c \
30 hw_atalla.c hw_cswift.c hw_ncipher.c hw_nuron.c hw_ubsec.c \
31 hw_openbsd_dev_crypto.c hw_aep.c hw_sureware.c hw_4758_cca.c
32LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
33 eng_table.o eng_pkey.o eng_fat.o eng_all.o \
34 tb_rsa.o tb_dsa.o tb_dh.o tb_rand.o tb_cipher.o tb_digest.o \
35 eng_openssl.o eng_dyn.o eng_cnf.o \
36 hw_atalla.o hw_cswift.o hw_ncipher.o hw_nuron.o hw_ubsec.o \
37 hw_openbsd_dev_crypto.o hw_aep.o hw_sureware.o hw_4758_cca.o
29 38
30SRC= $(LIBSRC) 39SRC= $(LIBSRC)
31 40
@@ -48,7 +57,7 @@ files:
48 $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO 57 $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO
49 58
50links: 59links:
51 @$(SHELL) $(TOP)/util/point.sh Makefile.ssl Makefile 60 @$(TOP)/util/point.sh Makefile.ssl Makefile
52 @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) 61 @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
53 @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) 62 @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
54 @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) 63 @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
@@ -63,6 +72,10 @@ install:
63tags: 72tags:
64 ctags $(SRC) 73 ctags $(SRC)
65 74
75errors:
76 $(PERL) $(TOP)/util/mkerr.pl -conf hw.ec \
77 -nostatic -staticloader -write hw_*.c; \
78
66tests: 79tests:
67 80
68lint: 81lint:
@@ -80,141 +93,361 @@ clean:
80 93
81# DO NOT DELETE THIS LINE -- make depend depends on it. 94# DO NOT DELETE THIS LINE -- make depend depends on it.
82 95
83engine_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h 96eng_all.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
84engine_err.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h 97eng_all.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
85engine_err.o: ../../include/openssl/cast.h ../../include/openssl/crypto.h 98eng_all.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
86engine_err.o: ../../include/openssl/des.h ../../include/openssl/dh.h 99eng_all.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
87engine_err.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h 100eng_all.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
88engine_err.o: ../../include/openssl/engine.h ../../include/openssl/err.h 101eng_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
89engine_err.o: ../../include/openssl/evp.h ../../include/openssl/idea.h 102eng_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
90engine_err.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h 103eng_all.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
91engine_err.o: ../../include/openssl/md4.h ../../include/openssl/md5.h 104eng_all.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
92engine_err.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h 105eng_all.o: ../../include/openssl/ui.h eng_all.c eng_int.h
93engine_err.o: ../../include/openssl/objects.h 106eng_cnf.o: ../../e_os.h ../../include/openssl/asn1.h
94engine_err.o: ../../include/openssl/opensslconf.h 107eng_cnf.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
95engine_err.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h 108eng_cnf.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
96engine_err.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h 109eng_cnf.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
97engine_err.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h 110eng_cnf.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
98engine_err.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h 111eng_cnf.o: ../../include/openssl/engine.h ../../include/openssl/err.h
99engine_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h 112eng_cnf.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
100engine_err.o: ../../include/openssl/symhacks.h 113eng_cnf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
101engine_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h 114eng_cnf.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
102engine_lib.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h 115eng_cnf.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
103engine_lib.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h 116eng_cnf.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
104engine_lib.o: ../../include/openssl/crypto.h ../../include/openssl/des.h 117eng_cnf.o: ../cryptlib.h eng_cnf.c
105engine_lib.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h 118eng_ctrl.o: ../../e_os.h ../../include/openssl/asn1.h
106engine_lib.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h 119eng_ctrl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
107engine_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h 120eng_ctrl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
108engine_lib.o: ../../include/openssl/evp.h ../../include/openssl/idea.h 121eng_ctrl.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
109engine_lib.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h 122eng_ctrl.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
110engine_lib.o: ../../include/openssl/md4.h ../../include/openssl/md5.h 123eng_ctrl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
111engine_lib.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h 124eng_ctrl.o: ../../include/openssl/opensslconf.h
112engine_lib.o: ../../include/openssl/objects.h 125eng_ctrl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
113engine_lib.o: ../../include/openssl/opensslconf.h 126eng_ctrl.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
114engine_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h 127eng_ctrl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
115engine_lib.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h 128eng_ctrl.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
116engine_lib.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h 129eng_ctrl.o: ../cryptlib.h eng_ctrl.c eng_int.h
117engine_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h 130eng_dyn.o: ../../e_os.h ../../include/openssl/asn1.h
118engine_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h 131eng_dyn.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
119engine_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h 132eng_dyn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
120engine_list.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h 133eng_dyn.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
121engine_list.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h 134eng_dyn.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
122engine_list.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h 135eng_dyn.o: ../../include/openssl/engine.h ../../include/openssl/err.h
123engine_list.o: ../../include/openssl/crypto.h ../../include/openssl/des.h 136eng_dyn.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
124engine_list.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h 137eng_dyn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
125engine_list.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h 138eng_dyn.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
126engine_list.o: ../../include/openssl/engine.h ../../include/openssl/err.h 139eng_dyn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
127engine_list.o: ../../include/openssl/evp.h ../../include/openssl/idea.h 140eng_dyn.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
128engine_list.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h 141eng_dyn.o: ../cryptlib.h eng_dyn.c eng_int.h
129engine_list.o: ../../include/openssl/md4.h ../../include/openssl/md5.h 142eng_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
130engine_list.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h 143eng_err.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
131engine_list.o: ../../include/openssl/objects.h 144eng_err.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
132engine_list.o: ../../include/openssl/opensslconf.h 145eng_err.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
133engine_list.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h 146eng_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
134engine_list.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h 147eng_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
135engine_list.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h 148eng_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
136engine_list.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h 149eng_err.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
137engine_list.o: ../../include/openssl/sha.h ../../include/openssl/stack.h 150eng_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
138engine_list.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h 151eng_err.o: ../../include/openssl/ui.h eng_err.c
139engine_openssl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h 152eng_fat.o: ../../e_os.h ../../include/openssl/asn1.h
140engine_openssl.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h 153eng_fat.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
141engine_openssl.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h 154eng_fat.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
142engine_openssl.o: ../../include/openssl/crypto.h ../../include/openssl/des.h 155eng_fat.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
143engine_openssl.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h 156eng_fat.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
144engine_openssl.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h 157eng_fat.o: ../../include/openssl/engine.h ../../include/openssl/err.h
145engine_openssl.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h 158eng_fat.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
146engine_openssl.o: ../../include/openssl/err.h ../../include/openssl/evp.h 159eng_fat.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
147engine_openssl.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h 160eng_fat.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
148engine_openssl.o: ../../include/openssl/md2.h ../../include/openssl/md4.h 161eng_fat.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
149engine_openssl.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h 162eng_fat.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
150engine_openssl.o: ../../include/openssl/obj_mac.h 163eng_fat.o: ../cryptlib.h eng_fat.c eng_int.h
151engine_openssl.o: ../../include/openssl/objects.h 164eng_init.o: ../../e_os.h ../../include/openssl/asn1.h
152engine_openssl.o: ../../include/openssl/opensslconf.h 165eng_init.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
153engine_openssl.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h 166eng_init.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
154engine_openssl.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h 167eng_init.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
155engine_openssl.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h 168eng_init.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
156engine_openssl.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h 169eng_init.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
157engine_openssl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h 170eng_init.o: ../../include/openssl/opensslconf.h
158engine_openssl.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h 171eng_init.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
159hw_atalla.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h 172eng_init.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
160hw_atalla.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h 173eng_init.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
161hw_atalla.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h 174eng_init.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
162hw_atalla.o: ../../include/openssl/crypto.h ../../include/openssl/des.h 175eng_init.o: ../cryptlib.h eng_init.c eng_int.h
176eng_lib.o: ../../e_os.h ../../include/openssl/asn1.h
177eng_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
178eng_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
179eng_lib.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
180eng_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
181eng_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
182eng_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
183eng_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
184eng_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
185eng_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
186eng_lib.o: ../../include/openssl/ui.h ../cryptlib.h eng_int.h eng_lib.c
187eng_list.o: ../../e_os.h ../../include/openssl/asn1.h
188eng_list.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
189eng_list.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
190eng_list.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
191eng_list.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
192eng_list.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
193eng_list.o: ../../include/openssl/opensslconf.h
194eng_list.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
195eng_list.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
196eng_list.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
197eng_list.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
198eng_list.o: ../cryptlib.h eng_int.h eng_list.c
199eng_openssl.o: ../../e_os.h ../../include/openssl/asn1.h
200eng_openssl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
201eng_openssl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
202eng_openssl.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
203eng_openssl.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
204eng_openssl.o: ../../include/openssl/engine.h ../../include/openssl/err.h
205eng_openssl.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
206eng_openssl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
207eng_openssl.o: ../../include/openssl/opensslconf.h
208eng_openssl.o: ../../include/openssl/opensslv.h
209eng_openssl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
210eng_openssl.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
211eng_openssl.o: ../../include/openssl/rand.h ../../include/openssl/rc4.h
212eng_openssl.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
213eng_openssl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
214eng_openssl.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
215eng_openssl.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
216eng_openssl.o: ../cryptlib.h eng_openssl.c
217eng_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
218eng_pkey.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
219eng_pkey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
220eng_pkey.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
221eng_pkey.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
222eng_pkey.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
223eng_pkey.o: ../../include/openssl/opensslconf.h
224eng_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
225eng_pkey.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
226eng_pkey.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
227eng_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
228eng_pkey.o: ../cryptlib.h eng_int.h eng_pkey.c
229eng_table.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
230eng_table.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
231eng_table.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
232eng_table.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
233eng_table.o: ../../include/openssl/err.h ../../include/openssl/evp.h
234eng_table.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
235eng_table.o: ../../include/openssl/objects.h
236eng_table.o: ../../include/openssl/opensslconf.h
237eng_table.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
238eng_table.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
239eng_table.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
240eng_table.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
241eng_table.o: eng_int.h eng_table.c
242hw_4758_cca.o: ../../e_os.h ../../include/openssl/asn1.h
243hw_4758_cca.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
244hw_4758_cca.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
245hw_4758_cca.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
246hw_4758_cca.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
247hw_4758_cca.o: ../../include/openssl/engine.h ../../include/openssl/err.h
248hw_4758_cca.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
249hw_4758_cca.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
250hw_4758_cca.o: ../../include/openssl/opensslconf.h
251hw_4758_cca.o: ../../include/openssl/opensslv.h
252hw_4758_cca.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
253hw_4758_cca.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
254hw_4758_cca.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
255hw_4758_cca.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
256hw_4758_cca.o: ../../include/openssl/ui.h ../../include/openssl/x509.h
257hw_4758_cca.o: ../../include/openssl/x509_vfy.h ../cryptlib.h hw_4758_cca.c
258hw_4758_cca.o: hw_4758_cca_err.c hw_4758_cca_err.h vendor_defns/hw_4758_cca.h
259hw_aep.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
260hw_aep.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
261hw_aep.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
262hw_aep.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
263hw_aep.o: ../../include/openssl/engine.h ../../include/openssl/err.h
264hw_aep.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
265hw_aep.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
266hw_aep.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
267hw_aep.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
268hw_aep.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h hw_aep.c
269hw_aep.o: hw_aep_err.c hw_aep_err.h vendor_defns/aep.h
270hw_atalla.o: ../../e_os.h ../../include/openssl/asn1.h
271hw_atalla.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
272hw_atalla.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
163hw_atalla.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h 273hw_atalla.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
164hw_atalla.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h 274hw_atalla.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
165hw_atalla.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h 275hw_atalla.o: ../../include/openssl/engine.h ../../include/openssl/err.h
166hw_atalla.o: ../../include/openssl/err.h ../../include/openssl/evp.h 276hw_atalla.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
167hw_atalla.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h 277hw_atalla.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
168hw_atalla.o: ../../include/openssl/md2.h ../../include/openssl/md4.h 278hw_atalla.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
169hw_atalla.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h 279hw_atalla.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
170hw_atalla.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h 280hw_atalla.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
171hw_atalla.o: ../../include/openssl/opensslconf.h 281hw_atalla.o: ../cryptlib.h hw_atalla.c hw_atalla_err.c hw_atalla_err.h
172hw_atalla.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
173hw_atalla.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
174hw_atalla.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
175hw_atalla.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
176hw_atalla.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
177hw_atalla.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h
178hw_atalla.o: vendor_defns/atalla.h 282hw_atalla.o: vendor_defns/atalla.h
179hw_cswift.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h 283hw_cswift.o: ../../e_os.h ../../include/openssl/asn1.h
180hw_cswift.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h 284hw_cswift.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
181hw_cswift.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h 285hw_cswift.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
182hw_cswift.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
183hw_cswift.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h 286hw_cswift.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
184hw_cswift.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h 287hw_cswift.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
185hw_cswift.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h 288hw_cswift.o: ../../include/openssl/engine.h ../../include/openssl/err.h
186hw_cswift.o: ../../include/openssl/err.h ../../include/openssl/evp.h 289hw_cswift.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
187hw_cswift.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h 290hw_cswift.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
188hw_cswift.o: ../../include/openssl/md2.h ../../include/openssl/md4.h 291hw_cswift.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
189hw_cswift.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h 292hw_cswift.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
190hw_cswift.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h 293hw_cswift.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
191hw_cswift.o: ../../include/openssl/opensslconf.h 294hw_cswift.o: ../cryptlib.h hw_cswift.c hw_cswift_err.c hw_cswift_err.h
192hw_cswift.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
193hw_cswift.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
194hw_cswift.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
195hw_cswift.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
196hw_cswift.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
197hw_cswift.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h
198hw_cswift.o: vendor_defns/cswift.h 295hw_cswift.o: vendor_defns/cswift.h
199hw_ncipher.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h 296hw_ncipher.o: ../../e_os.h ../../include/openssl/asn1.h
200hw_ncipher.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h 297hw_ncipher.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
201hw_ncipher.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h 298hw_ncipher.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
202hw_ncipher.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
203hw_ncipher.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h 299hw_ncipher.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
204hw_ncipher.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h 300hw_ncipher.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
205hw_ncipher.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h 301hw_ncipher.o: ../../include/openssl/engine.h ../../include/openssl/err.h
206hw_ncipher.o: ../../include/openssl/err.h ../../include/openssl/evp.h 302hw_ncipher.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
207hw_ncipher.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
208hw_ncipher.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
209hw_ncipher.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
210hw_ncipher.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h 303hw_ncipher.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
211hw_ncipher.o: ../../include/openssl/opensslconf.h 304hw_ncipher.o: ../../include/openssl/opensslconf.h
212hw_ncipher.o: ../../include/openssl/opensslv.h ../../include/openssl/pem.h 305hw_ncipher.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
213hw_ncipher.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h 306hw_ncipher.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
214hw_ncipher.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h 307hw_ncipher.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
215hw_ncipher.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h 308hw_ncipher.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
216hw_ncipher.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h 309hw_ncipher.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
217hw_ncipher.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h 310hw_ncipher.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
218hw_ncipher.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
219hw_ncipher.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h 311hw_ncipher.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
220hw_ncipher.o: ../cryptlib.h engine_int.h vendor_defns/hwcryptohook.h 312hw_ncipher.o: ../cryptlib.h hw_ncipher.c hw_ncipher_err.c hw_ncipher_err.h
313hw_ncipher.o: vendor_defns/hwcryptohook.h
314hw_nuron.o: ../../e_os.h ../../include/openssl/asn1.h
315hw_nuron.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
316hw_nuron.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
317hw_nuron.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
318hw_nuron.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
319hw_nuron.o: ../../include/openssl/engine.h ../../include/openssl/err.h
320hw_nuron.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
321hw_nuron.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
322hw_nuron.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
323hw_nuron.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
324hw_nuron.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
325hw_nuron.o: ../cryptlib.h hw_nuron.c hw_nuron_err.c hw_nuron_err.h
326hw_openbsd_dev_crypto.o: ../../include/openssl/asn1.h
327hw_openbsd_dev_crypto.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
328hw_openbsd_dev_crypto.o: ../../include/openssl/conf.h
329hw_openbsd_dev_crypto.o: ../../include/openssl/crypto.h
330hw_openbsd_dev_crypto.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
331hw_openbsd_dev_crypto.o: ../../include/openssl/e_os2.h
332hw_openbsd_dev_crypto.o: ../../include/openssl/engine.h
333hw_openbsd_dev_crypto.o: ../../include/openssl/err.h
334hw_openbsd_dev_crypto.o: ../../include/openssl/evp.h
335hw_openbsd_dev_crypto.o: ../../include/openssl/lhash.h
336hw_openbsd_dev_crypto.o: ../../include/openssl/obj_mac.h
337hw_openbsd_dev_crypto.o: ../../include/openssl/objects.h
338hw_openbsd_dev_crypto.o: ../../include/openssl/opensslconf.h
339hw_openbsd_dev_crypto.o: ../../include/openssl/opensslv.h
340hw_openbsd_dev_crypto.o: ../../include/openssl/ossl_typ.h
341hw_openbsd_dev_crypto.o: ../../include/openssl/rand.h
342hw_openbsd_dev_crypto.o: ../../include/openssl/rsa.h
343hw_openbsd_dev_crypto.o: ../../include/openssl/safestack.h
344hw_openbsd_dev_crypto.o: ../../include/openssl/stack.h
345hw_openbsd_dev_crypto.o: ../../include/openssl/symhacks.h
346hw_openbsd_dev_crypto.o: ../../include/openssl/ui.h ../evp/evp_locl.h eng_int.h
347hw_openbsd_dev_crypto.o: hw_openbsd_dev_crypto.c
348hw_sureware.o: ../../e_os.h ../../include/openssl/asn1.h
349hw_sureware.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
350hw_sureware.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
351hw_sureware.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
352hw_sureware.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
353hw_sureware.o: ../../include/openssl/engine.h ../../include/openssl/err.h
354hw_sureware.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
355hw_sureware.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
356hw_sureware.o: ../../include/openssl/opensslconf.h
357hw_sureware.o: ../../include/openssl/opensslv.h
358hw_sureware.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
359hw_sureware.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
360hw_sureware.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
361hw_sureware.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
362hw_sureware.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
363hw_sureware.o: ../../include/openssl/ui.h ../../include/openssl/x509.h
364hw_sureware.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
365hw_sureware.o: engine.h hw_sureware.c hw_sureware_err.c hw_sureware_err.h
366hw_sureware.o: vendor_defns/sureware.h
367hw_ubsec.o: ../../e_os.h ../../include/openssl/asn1.h
368hw_ubsec.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
369hw_ubsec.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
370hw_ubsec.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
371hw_ubsec.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
372hw_ubsec.o: ../../include/openssl/engine.h ../../include/openssl/err.h
373hw_ubsec.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
374hw_ubsec.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
375hw_ubsec.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
376hw_ubsec.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
377hw_ubsec.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
378hw_ubsec.o: ../cryptlib.h hw_ubsec.c hw_ubsec_err.c hw_ubsec_err.h
379hw_ubsec.o: vendor_defns/hw_ubsec.h
380tb_cipher.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
381tb_cipher.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
382tb_cipher.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
383tb_cipher.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
384tb_cipher.o: ../../include/openssl/err.h ../../include/openssl/evp.h
385tb_cipher.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
386tb_cipher.o: ../../include/openssl/objects.h
387tb_cipher.o: ../../include/openssl/opensslconf.h
388tb_cipher.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
389tb_cipher.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
390tb_cipher.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
391tb_cipher.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
392tb_cipher.o: eng_int.h tb_cipher.c
393tb_dh.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
394tb_dh.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
395tb_dh.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
396tb_dh.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
397tb_dh.o: ../../include/openssl/err.h ../../include/openssl/evp.h
398tb_dh.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
399tb_dh.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
400tb_dh.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
401tb_dh.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
402tb_dh.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
403tb_dh.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h eng_int.h
404tb_dh.o: tb_dh.c
405tb_digest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
406tb_digest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
407tb_digest.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
408tb_digest.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
409tb_digest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
410tb_digest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
411tb_digest.o: ../../include/openssl/objects.h
412tb_digest.o: ../../include/openssl/opensslconf.h
413tb_digest.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
414tb_digest.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
415tb_digest.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
416tb_digest.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
417tb_digest.o: eng_int.h tb_digest.c
418tb_dsa.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
419tb_dsa.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
420tb_dsa.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
421tb_dsa.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
422tb_dsa.o: ../../include/openssl/err.h ../../include/openssl/evp.h
423tb_dsa.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
424tb_dsa.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
425tb_dsa.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
426tb_dsa.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
427tb_dsa.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
428tb_dsa.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h eng_int.h
429tb_dsa.o: tb_dsa.c
430tb_rand.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
431tb_rand.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
432tb_rand.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
433tb_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
434tb_rand.o: ../../include/openssl/err.h ../../include/openssl/evp.h
435tb_rand.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
436tb_rand.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
437tb_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
438tb_rand.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
439tb_rand.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
440tb_rand.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
441tb_rand.o: eng_int.h tb_rand.c
442tb_rsa.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
443tb_rsa.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
444tb_rsa.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
445tb_rsa.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
446tb_rsa.o: ../../include/openssl/err.h ../../include/openssl/evp.h
447tb_rsa.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
448tb_rsa.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
449tb_rsa.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
450tb_rsa.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
451tb_rsa.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
452tb_rsa.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h eng_int.h
453tb_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 @@
1NOTES, THOUGHTS, and EVERYTHING 1Notes: 2001-09-24
2-------------------------------
3
4(1) Concurrency and locking ... I made a change to the ENGINE_free code
5 because I spotted a potential hold-up in proceedings (doing too
6 much inside a lock including calling a callback), there may be
7 other bits like this. What do the speed/optimisation freaks think
8 of this aspect of the code and design? There's lots of locking for
9 manipulation functions and I need that to keep things nice and
10 solid, but this manipulation is mostly (de)initialisation, I would
11 think that most run-time locking is purely in the ENGINE_init and
12 ENGINE_finish calls that might be made when getting handles for
13 RSA (and friends') structures. These would be mostly reference
14 count operations as the functional references should always be 1
15 or greater at run-time to prevent init/deinit thrashing.
16
17(2) nCipher support, via the HWCryptoHook API, is now in the code.
18 Apparently this hasn't been tested too much yet, but it looks
19 good. :-) Atalla support has been added too, but shares a lot in
20 common with Ben's original hooks in bn_exp.c (although it has been
21 ENGINE-ified, and error handling wrapped around it) and it's also
22 had some low-volume testing, so it should be usable.
23
24(3) Of more concern, we need to work out (a) how to put together usable
25 RAND_METHODs for units that just have one "get n or less random
26 bytes" function, (b) we also need to determine how to hook the code
27 in crypto/rand/ to use the ENGINE defaults in a way similar to what
28 has been done in crypto/rsa/, crypto/dsa/, etc.
29
30(4) ENGINE should really grow to encompass more than 3 public key
31 algorithms and randomness gathering. The structure/data level of
32 the engine code is hidden from code outside the crypto/engine/
33 directory so change shouldn't be too viral. More important though
34 is how things should evolve ... this needs thought and discussion.
35
36
37-----------------------------------==*==-----------------------------------
38
39More notes 2000-08-01
40---------------------
41
42Geoff Thorpe, who designed the engine part, wrote a pretty good description
43of the thoughts he had when he built it, good enough to include verbatim here
44(with his permission) -- Richard Levitte
45
46
47Date: Tue, 1 Aug 2000 16:54:08 +0100 (BST)
48From: Geoff Thorpe
49Subject: Re: The thoughts to merge BRANCH_engine into the main trunk are
50 emerging
51
52Hi there,
53
54I'm going to try and do some justice to this, but I'm a little short on
55time and the there is an endless amount that could be discussed on this
56subject. sigh ... please bear with me :-)
57
58> The changes in BRANCH_engine dig deep into the core of OpenSSL, for example
59> into the RSA and RAND routines, adding a level of indirection which is needed
60> to keep the abstraction, as far as I understand. It would be a good thing if
61> those who do play with those things took a look at the changes that have been
62> done in the branch and say out loud how much (or hopefully little) we've made
63> fools of ourselves.
64
65The point here is that the code that has emerged in the BRANCH_engine
66branch was based on some initial requirements of mine that I went in and
67addressed, and Richard has picked up the ball and run with it too. It
68would be really useful to get some review of the approach we've taken, but
69first I think I need to describe as best I can the reasons behind what has
70been done so far, in particular what issues we have tried to address when
71doing this, and what issues we have intentionally (or necessarily) tried
72to avoid.
73
74methods, engines, and evps
75--------------------------
76
77There has been some dicussion, particularly with Steve, about where this
78ENGINE stuff might fit into the conceptual picture as/when we start to
79abstract algorithms a little bit to make the library more extensible. In
80particular, it would desirable to have algorithms (symmetric, hash, pkc,
81etc) abstracted in some way that allows them to be just objects sitting in
82a list (or database) ... it'll just happen that the "DSA" object doesn't
83support encryption whereas the "RSA" object does. This requires a lot of
84consideration to begin to know how to tackle it; in particular how
85encapsulated should these things be? If the objects also understand their
86own ASN1 encodings and what-not, then it would for example be possible to
87add support for elliptic-curve DSA in as a new algorithm and automatically
88have ECC-DSA certificates supported in SSL applications. Possible, but not
89easy. :-)
90
91Whatever, it seems that the way to go (if I've grok'd Steve's comments on
92this in the past) is to amalgamate these things in EVP as is already done
93(I think) for ciphers or hashes (Steve, please correct/elaborate). I
94certainly think something should be done in this direction because right
95now we have different source directories, types, functions, and methods
96for each algorithm - even when conceptually they are very much different
97feathers of the same bird. (This is certainly all true for the public-key
98stuff, and may be partially true for the other parts.)
99
100ENGINE was *not* conceived as a way of solving this, far from it. Nor was
101it conceived as a way of replacing the various "***_METHOD"s. It was
102conceived as an abstraction of a sort of "virtual crypto device". If we
103lived in a world where "EVP_ALGO"s (or something like them) encapsulated
104particular algorithms like RSA,DSA,MD5,RC4,etc, and "***_METHOD"s
105encapsulated interfaces to algorithms (eg. some algo's might support a
106PKC_METHOD, a HASH_METHOD, or a CIPHER_METHOD, who knows?), then I would
107think that ENGINE would encapsulate an implementation of arbitrarily many
108of those algorithms - perhaps as alternatives to existing algorithms
109and/or perhaps as new previously unimplemented algorithms. An ENGINE could
110be used to contain an alternative software implementation, a wrapper for a
111hardware acceleration and/or key-management unit, a comms-wrapper for
112distributing cryptographic operations to remote machines, or any other
113"devices" your imagination can dream up.
114
115However, what has been done in the ENGINE branch so far is nothing more
116than starting to get our toes wet. I had a couple of self-imposed
117requirements when putting the initial abstraction together, and I may have
118already posed these in one form or another on the list, but briefly;
119
120 (i) only bother with public key algorithms for now, and maybe RAND too
121 (motivated by the need to get hardware support going and the fact
122 this was a comparitively easy subset to address to begin with).
123
124 (ii) don't change (if at all possible) the existing crypto code, ie. the
125 implementations, the way the ***_METHODs work, etc.
126
127 (iii) ensure that if no function from the ENGINE code is ever called then
128 things work the way they always did, and there is no memory
129 allocation (otherwise the failure to cleanup would be a problem -
130 this is part of the reason no STACKs were used, the other part of
131 the reason being I found them inappropriate).
132
133 (iv) ensure that all the built-in crypto was encapsulated by one of
134 these "ENGINE"s and that this engine was automatically selected as
135 the default.
136
137 (v) provide the minimum hooking possible in the existing crypto code
138 so that global functions (eg. RSA_public_encrypt) do not need any
139 extra parameter, yet will use whatever the current default ENGINE
140 for that RSA key is, and that the default can be set "per-key"
141 and globally (new keys will assume the global default, and keys
142 without their own default will be operated on using the global
143 default). NB: Try and make (v) conflict as little as possible with
144 (ii). :-)
145
146 (vi) wrap the ENGINE code up in duct tape so you can't even see the
147 corners. Ie. expose no structures at all, just black-box pointers.
148
149 (v) maintain internally a list of ENGINEs on which a calling
150 application can iterate, interrogate, etc. Allow a calling
151 application to hook in new ENGINEs, remove ENGINEs from the list,
152 and enforce uniqueness within the global list of each ENGINE's
153 "unique id".
154
155 (vi) keep reference counts for everything - eg. this includes storing a
156 reference inside each RSA structure to the ENGINE that it uses.
157 This is freed when the RSA structure is destroyed, or has its
158 ENGINE explicitly changed. The net effect needs to be that at any
159 time, it is deterministic to know whether an ENGINE is in use or
160 can be safely removed (or unloaded in the case of the other type
161 of reference) without invalidating function pointers that may or
162 may not be used indavertently in the future. This was actually
163 one of the biggest problems to overcome in the existing OpenSSL
164 code - implementations had always been assumed to be ever-present,
165 so there was no trivial way to get round this.
166
167 (vii) distinguish between structural references and functional
168 references.
169
170A *little* detail
171----------------- 2-----------------
172 3
173While my mind is on it; I'll illustrate the bit in item (vii). This idea 4This "description" (if one chooses to call it that) needed some major updating
174turned out to be very handy - the ENGINEs themselves need to be operated 5so here goes. This update addresses a change being made at the same time to
175on and manipulated simply as objects without necessarily trying to 6OpenSSL, and it pretty much completely restructures the underlying mechanics of
176"enable" them for use. Eg. most host machines will not have the necessary 7the "ENGINE" code. So it serves a double purpose of being a "ENGINE internals
177hardware or software to support all the engines one might compile into 8for masochists" document *and* a rather extensive commit log message. (I'd get
178OpenSSL, yet it needs to be possible to iterate across the ENGINEs, 9lynched for sticking all this in CHANGES or the commit mails :-).
179querying their names, properties, etc - all happening in a thread-safe 10
180manner that uses reference counts (if you imagine two threads iterating 11ENGINE_TABLE underlies this restructuring, as described in the internal header
181through a list and one thread removing the ENGINE the other is currently 12"eng_int.h", implemented in eng_table.c, and used in each of the "class" files;
182looking at - you can see the gotcha waiting to happen). For all of this, 13tb_rsa.c, tb_dsa.c, etc.
183*structural references* are used and operate much like the other reference 14
184counts in OpenSSL. 15However, "EVP_CIPHER" underlies the motivation and design of ENGINE_TABLE so
185 16I'll mention a bit about that first. EVP_CIPHER (and most of this applies
186The other kind of reference count is for *functional* references - these 17equally to EVP_MD for digests) is both a "method" and a algorithm/mode
187indicate a reference on which the caller can actually assume the 18identifier that, in the current API, "lingers". These cipher description +
188particular ENGINE to be initialised and usable to perform the operations 19implementation structures can be defined or obtained directly by applications,
189it implements. Any increment or decrement of the functional reference 20or can be loaded "en masse" into EVP storage so that they can be catalogued and
190count automatically invokes a corresponding change in the structural 21searched in various ways, ie. two ways of encrypting with the "des_cbc"
191reference count, as it is fairly obvious that a functional reference is a 22algorithm/mode pair are;
192restricted case of a structural reference. So struct_ref >= funct_ref at 23
193all times. NB: functional references are usually obtained by a call to 24(i) directly;
194ENGINE_init(), but can also be created implicitly by calls that require a 25 const EVP_CIPHER *cipher = EVP_des_cbc();
195new functional reference to be created, eg. ENGINE_set_default(). Either 26 EVP_EncryptInit(&ctx, cipher, key, iv);
196way the only time the underlying ENGINE's "init" function is really called 27 [ ... use EVP_EncryptUpdate() and EVP_EncryptFinal() ...]
197is when the (functional) reference count increases to 1, similarly the 28
198underlying "finish" handler is only called as the count goes down to 0. 29(ii) indirectly;
199The effect of this, for example, is that if you set the default ENGINE for 30 OpenSSL_add_all_ciphers();
200RSA operations to be "cswift", then its functional reference count will 31 cipher = EVP_get_cipherbyname("des_cbc");
201already be at least 1 so the CryptoSwift shared-library and the card will 32 EVP_EncryptInit(&ctx, cipher, key, iv);
202stay loaded and initialised until such time as all RSA keys using the 33 [ ... etc ... ]
203cswift ENGINE are changed or destroyed and the default ENGINE for RSA 34
204operations has been changed. This prevents repeated thrashing of init and 35The latter is more generally used because it also allows ciphers/digests to be
205finish handling if the count keeps getting down as far as zero. 36looked up based on other identifiers which can be useful for automatic cipher
206 37selection, eg. in SSL/TLS, or by user-controllable configuration.
207Otherwise, the way the ENGINE code has been put together I think pretty 38
208much reflects the above points. The reason for the ENGINE structure having 39The important point about this is that EVP_CIPHER definitions and structures are
209individual RSA_METHOD, DSA_METHOD, etc pointers is simply that it was the 40passed around with impunity and there is no safe way, without requiring massive
210easiest way to go about things for now, to hook it all into the raw 41rewrites of many applications, to assume that EVP_CIPHERs can be reference
211RSA,DSA,etc code, and I was trying to the keep the structure invisible 42counted. One an EVP_CIPHER is exposed to the caller, neither it nor anything it
212anyway so that the way this is internally managed could be easily changed 43comes from can "safely" be destroyed. Unless of course the way of getting to
213later on when we start to work out what's to be done about these other 44such ciphers is via entirely distinct API calls that didn't exist before.
214abstractions. 45However existing API usage cannot be made to understand when an EVP_CIPHER
215 46pointer, that has been passed to the caller, is no longer being used.
216Down the line, if some EVP-based technique emerges for adequately 47
217encapsulating algorithms and all their various bits and pieces, then I can 48The other problem with the existing API w.r.t. to hooking EVP_CIPHER support
218imagine that "ENGINE" would turn into a reference-counting database of 49into ENGINE is storage - the OBJ_NAME-based storage used by EVP to register
219these EVP things, of which the default "openssl" ENGINE would be the 50ciphers simultaneously registers cipher *types* and cipher *implementations* -
220library's own object database of pre-built software implemented algorithms 51they are effectively the same thing, an "EVP_CIPHER" pointer. The problem with
221(and such). It would also be cool to see the idea of "METHOD"s detached 52hooking in ENGINEs is that multiple ENGINEs may implement the same ciphers. The
222from the algorithms themselves ... so RSA, DSA, ElGamal, etc can all 53solution is necessarily that ENGINE-provided ciphers simply are not registered,
223expose essentially the same METHOD (aka interface), which would include 54stored, or exposed to the caller in the same manner as existing ciphers. This is
224any querying/flagging stuff to identify what the algorithm can/can't do, 55especially necessary considering the fact ENGINE uses reference counts to allow
225its name, and other stuff like max/min block sizes, key sizes, etc. This 56for cleanup, modularity, and DSO support - yet EVP_CIPHERs, as exposed to
226would result in ENGINE similarly detaching its internal database of 57callers in the current API, support no such controls.
227algorithm implementations from the function definitions that return 58
228interfaces to them. I think ... 59Another sticking point for integrating cipher support into ENGINE is linkage.
229 60Already there is a problem with the way ENGINE supports RSA, DSA, etc whereby
230As for DSOs etc. Well the DSO code is pretty handy (but could be made much 61they are available *because* they're part of a giant ENGINE called "openssl".
231more so) for loading vendor's driver-libraries and talking to them in some 62Ie. all implementations *have* to come from an ENGINE, but we get round that by
232generic way, but right now there's still big problems associated with 63having a giant ENGINE with all the software support encapsulated. This creates
233actually putting OpenSSL code (ie. new ENGINEs, or anything else for that 64linker hassles if nothing else - linking a 1-line application that calls 2 basic
234matter) in dynamically loadable libraries. These problems won't go away in 65RSA functions (eg. "RSA_free(RSA_new());") will result in large quantities of
235a hurry so I don't think we should expect to have any kind of 66ENGINE code being linked in *and* because of that DSA, DH, and RAND also. If we
236shared-library extensions any time soon - but solving the problems is a 67continue with this approach for EVP_CIPHER support (even if it *was* possible)
237good thing to aim for, and would as a side-effect probably help make 68we would lose our ability to link selectively by selectively loading certain
238OpenSSL more usable as a shared-library itself (looking at the things 69implementations of certain functionality. Touching any part of any kind of
239needed to do this will show you why). 70crypto would result in massive static linkage of everything else. So the
240 71solution is to change the way ENGINE feeds existing "classes", ie. how the
241One of the problems is that if you look at any of the ENGINE 72hooking to ENGINE works from RSA, DSA, DH, RAND, as well as adding new hooking
242implementations, eg. hw_cswift.c or hw_ncipher.c, you'll see how it needs 73for EVP_CIPHER, and EVP_MD.
243a variety of functionality and definitions from various areas of OpenSSL, 74
244including crypto/bn/, crypto/err/, crypto/ itself (locking for example), 75The way this is now being done is by mostly reverting back to how things used to
245crypto/dso/, crypto/engine/, crypto/rsa, etc etc etc. So if similar code 76work prior to ENGINE :-). Ie. RSA now has a "RSA_METHOD" pointer again - this
246were to be suctioned off into shared libraries, the shared libraries would 77was previously replaced by an "ENGINE" pointer and all RSA code that required
247either have to duplicate all the definitions and code and avoid loader 78the RSA_METHOD would call ENGINE_get_RSA() each time on its ENGINE handle to
248conflicts, or OpenSSL would have to somehow expose all that functionality 79temporarily get and use the ENGINE's RSA implementation. Apart from being more
249to the shared-library. If this isn't a big enough problem, the issue of 80efficient, switching back to each RSA having an RSA_METHOD pointer also allows
250binary compatibility will be - anyone writing Apache modules can tell you 81us to conceivably operate with *no* ENGINE. As we'll see, this removes any need
251that (Ralf? Ben? :-). However, I don't think OpenSSL would need to be 82for a fallback ENGINE that encapsulates default implementations - we can simply
252quite so forgiving as Apache should be, so OpenSSL could simply tell its 83have our RSA structure pointing its RSA_METHOD pointer to the software
253version to the DSO and leave the DSO with the problem of deciding whether 84implementation and have its ENGINE pointer set to NULL.
254to proceed or bail out for fear of binary incompatibilities. 85
255 86A look at the EVP_CIPHER hooking is most explanatory, the RSA, DSA (etc) cases
256Certainly one thing that would go a long way to addressing this is to 87turn out to be degenerate forms of the same thing. The EVP storage of ciphers,
257embark on a bit of an opaqueness mission. I've set the ENGINE code up with 88and the existing EVP API functions that return "software" implementations and
258this in mind - it's so draconian that even to declare your own ENGINE, you 89descriptions remain untouched. However, the storage takes more meaning in terms
259have to get the engine code to create the underlying ENGINE structure, and 90of "cipher description" and less meaning in terms of "implementation". When an
260then feed in the new ENGINE's function/method pointers through various 91EVP_CIPHER_CTX is actually initialised with an EVP_CIPHER method and is about to
261"set" functions. The more of the code that takes on such a black-box 92begin en/decryption, the hooking to ENGINE comes into play. What happens is that
262approach, the more of the code that will be (a) easy to expose to shared 93cipher-specific ENGINE code is asked for an ENGINE pointer (a functional
263libraries that need it, and (b) easy to expose to applications wanting to 94reference) for any ENGINE that is registered to perform the algo/mode that the
264use OpenSSL itself as a shared-library. From my own explorations in 95provided EVP_CIPHER structure represents. Under normal circumstances, that
265OpenSSL, the biggest leviathan I've seen that is a problem in this respect 96ENGINE code will return NULL because no ENGINEs will have had any cipher
266is the BIGNUM code. Trying to "expose" the bignum code through any kind of 97implementations *registered*. As such, a NULL ENGINE pointer is stored in the
267organised "METHODs", let alone do all the necessary bignum operations 98EVP_CIPHER_CTX context, and the EVP_CIPHER structure is left hooked into the
268solely through functions rather than direct access to the structures and 99context and so is used as the implementation. Pretty much how things work now
269macros, will be a massive pain in the "r"s. 100except we'd have a redundant ENGINE pointer set to NULL and doing nothing.
270 101
271Anyway, I'm done for now - hope it was readable. Thoughts? 102Conversely, if an ENGINE *has* been registered to perform the algorithm/mode
272 103combination represented by the provided EVP_CIPHER, then a functional reference
273Cheers, 104to that ENGINE will be returned to the EVP_CIPHER_CTX during initialisation.
274Geoff 105That functional reference will be stored in the context (and released on
275 106cleanup) - and having that reference provides a *safe* way to use an EVP_CIPHER
276 107definition that is private to the ENGINE. Ie. the EVP_CIPHER provided by the
277-----------------------------------==*==----------------------------------- 108application will actually be replaced by an EVP_CIPHER from the registered
109ENGINE - it will support the same algorithm/mode as the original but will be a
110completely different implementation. Because this EVP_CIPHER isn't stored in the
111EVP storage, nor is it returned to applications from traditional API functions,
112there is no associated problem with it not having reference counts. And of
113course, when one of these "private" cipher implementations is hooked into
114EVP_CIPHER_CTX, it is done whilst the EVP_CIPHER_CTX holds a functional
115reference to the ENGINE that owns it, thus the use of the ENGINE's EVP_CIPHER is
116safe.
117
118The "cipher-specific ENGINE code" I mentioned is implemented in tb_cipher.c but
119in essence it is simply an instantiation of "ENGINE_TABLE" code for use by
120EVP_CIPHER code. tb_digest.c is virtually identical but, of course, it is for
121use by EVP_MD code. Ditto for tb_rsa.c, tb_dsa.c, etc. These instantiations of
122ENGINE_TABLE essentially provide linker-separation of the classes so that even
123if ENGINEs implement *all* possible algorithms, an application using only
124EVP_CIPHER code will link at most code relating to EVP_CIPHER, tb_cipher.c, core
125ENGINE code that is independant of class, and of course the ENGINE
126implementation that the application loaded. It will *not* however link any
127class-specific ENGINE code for digests, RSA, etc nor will it bleed over into
128other APIs, such as the RSA/DSA/etc library code.
129
130ENGINE_TABLE is a little more complicated than may seem necessary but this is
131mostly to avoid a lot of "init()"-thrashing on ENGINEs (that may have to load
132DSOs, and other expensive setup that shouldn't be thrashed unnecessarily) *and*
133to duplicate "default" behaviour. Basically an ENGINE_TABLE instantiation, for
134example tb_cipher.c, implements a hash-table keyed by integer "nid" values.
135These nids provide the uniquenness of an algorithm/mode - and each nid will hash
136to a potentially NULL "ENGINE_PILE". An ENGINE_PILE is essentially a list of
137pointers to ENGINEs that implement that particular 'nid'. Each "pile" uses some
138caching tricks such that requests on that 'nid' will be cached and all future
139requests will return immediately (well, at least with minimal operation) unless
140a change is made to the pile, eg. perhaps an ENGINE was unloaded. The reason is
141that an application could have support for 10 ENGINEs statically linked
142in, and the machine in question may not have any of the hardware those 10
143ENGINEs support. If each of those ENGINEs has a "des_cbc" implementation, we
144want to avoid every EVP_CIPHER_CTX setup from trying (and failing) to initialise
145each of those 10 ENGINEs. Instead, the first such request will try to do that
146and will either return (and cache) a NULL ENGINE pointer or will return a
147functional reference to the first that successfully initialised. In the latter
148case it will also cache an extra functional reference to the ENGINE as a
149"default" for that 'nid'. The caching is acknowledged by a 'uptodate' variable
150that is unset only if un/registration takes place on that pile. Ie. if
151implementations of "des_cbc" are added or removed. This behaviour can be
152tweaked; the ENGINE_TABLE_FLAG_NOINIT value can be passed to
153ENGINE_set_table_flags(), in which case the only ENGINEs that tb_cipher.c will
154try to initialise from the "pile" will be those that are already initialised
155(ie. it's simply an increment of the functional reference count, and no real
156"initialisation" will take place).
157
158RSA, DSA, DH, and RAND all have their own ENGINE_TABLE code as well, and the
159difference is that they all use an implicit 'nid' of 1. Whereas EVP_CIPHERs are
160actually qualitatively different depending on 'nid' (the "des_cbc" EVP_CIPHER is
161not an interoperable implementation of "aes_256_cbc"), RSA_METHODs are
162necessarily interoperable and don't have different flavours, only different
163implementations. In other words, the ENGINE_TABLE for RSA will either be empty,
164or will have a single ENGING_PILE hashed to by the 'nid' 1 and that pile
165represents ENGINEs that implement the single "type" of RSA there is.
166
167Cleanup - the registration and unregistration may pose questions about how
168cleanup works with the ENGINE_PILE doing all this caching nonsense (ie. when the
169application or EVP_CIPHER code releases its last reference to an ENGINE, the
170ENGINE_PILE code may still have references and thus those ENGINEs will stay
171hooked in forever). The way this is handled is via "unregistration". With these
172new ENGINE changes, an abstract ENGINE can be loaded and initialised, but that
173is an algorithm-agnostic process. Even if initialised, it will not have
174registered any of its implementations (to do so would link all class "table"
175code despite the fact the application may use only ciphers, for example). This
176is deliberately a distinct step. Moreover, registration and unregistration has
177nothing to do with whether an ENGINE is *functional* or not (ie. you can even
178register an ENGINE and its implementations without it being operational, you may
179not even have the drivers to make it operate). What actually happens with
180respect to cleanup is managed inside eng_lib.c with the "engine_cleanup_***"
181functions. These functions are internal-only and each part of ENGINE code that
182could require cleanup will, upon performing its first allocation, register a
183callback with the "engine_cleanup" code. The other part of this that makes it
184tick is that the ENGINE_TABLE instantiations (tb_***.c) use NULL as their
185initialised state. So if RSA code asks for an ENGINE and no ENGINE has
186registered an implementation, the code will simply return NULL and the tb_rsa.c
187state will be unchanged. Thus, no cleanup is required unless registration takes
188place. ENGINE_cleanup() will simply iterate across a list of registered cleanup
189callbacks calling each in turn, and will then internally delete its own storage
190(a STACK). When a cleanup callback is next registered (eg. if the cleanup() is
191part of a gracefull restart and the application wants to cleanup all state then
192start again), the internal STACK storage will be freshly allocated. This is much
193the same as the situation in the ENGINE_TABLE instantiations ... NULL is the
194initialised state, so only modification operations (not queries) will cause that
195code to have to register a cleanup.
196
197What else? The bignum callbacks and associated ENGINE functions have been
198removed for two obvious reasons; (i) there was no way to generalise them to the
199mechanism now used by RSA/DSA/..., because there's no such thing as a BIGNUM
200method, and (ii) because of (i), there was no meaningful way for library or
201application code to automatically hook and use ENGINE supplied bignum functions
202anyway. Also, ENGINE_cpy() has been removed (although an internal-only version
203exists) - the idea of providing an ENGINE_cpy() function probably wasn't a good
204one and now certainly doesn't make sense in any generalised way. Some of the
205RSA, DSA, DH, and RAND functions that were fiddled during the original ENGINE
206changes have now, as a consequence, been reverted back. This is because the
207hooking of ENGINE is now automatic (and passive, it can interally use a NULL
208ENGINE pointer to simply ignore ENGINE from then on).
209
210Hell, that should be enough for now ... comments welcome: geoff@openssl.org
278 211
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 @@
1/* crypto/engine/eng_all.c -*- mode: C; c-file-style: "eay" -*- */
2/* Written by Richard Levitte <richard@levitte.org> for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <openssl/err.h>
60#include <openssl/engine.h>
61#include "eng_int.h"
62
63#ifdef __OpenBSD__
64static int openbsd_default_loaded = 0;
65#endif
66
67void ENGINE_load_builtin_engines(void)
68 {
69 /* There's no longer any need for an "openssl" ENGINE unless, one day,
70 * it is the *only* way for standard builtin implementations to be be
71 * accessed (ie. it would be possible to statically link binaries with
72 * *no* builtin implementations). */
73#if 0
74 ENGINE_load_openssl();
75#endif
76 ENGINE_load_dynamic();
77#ifndef OPENSSL_NO_HW
78#ifndef OPENSSL_NO_HW_CSWIFT
79 ENGINE_load_cswift();
80#endif
81#ifndef OPENSSL_NO_HW_NCIPHER
82 ENGINE_load_chil();
83#endif
84#ifndef OPENSSL_NO_HW_ATALLA
85 ENGINE_load_atalla();
86#endif
87#ifndef OPENSSL_NO_HW_NURON
88 ENGINE_load_nuron();
89#endif
90#ifndef OPENSSL_NO_HW_UBSEC
91 ENGINE_load_ubsec();
92#endif
93#ifndef OPENSSL_NO_HW_AEP
94 ENGINE_load_aep();
95#endif
96#ifndef OPENSSL_NO_HW_SUREWARE
97 ENGINE_load_sureware();
98#endif
99#ifdef OPENSSL_OPENBSD_DEV_CRYPTO
100 ENGINE_load_openbsd_dev_crypto();
101#endif
102#ifdef __OpenBSD__
103 ENGINE_load_cryptodev();
104#endif
105#endif
106 }
107
108#ifdef __OpenBSD__
109void ENGINE_setup_openbsd(void) {
110 if (!openbsd_default_loaded) {
111 ENGINE_load_cryptodev();
112 ENGINE_register_all_complete();
113 }
114 openbsd_default_loaded=1;
115}
116#endif
117
118
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 @@
1/* eng_cnf.c */
2/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 2001.
4 */
5/* ====================================================================
6 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <openssl/crypto.h>
61#include "cryptlib.h"
62#include <openssl/conf.h>
63#include <openssl/engine.h>
64
65/* #define ENGINE_CONF_DEBUG */
66
67/* ENGINE config module */
68
69static char *skip_dot(char *name)
70 {
71 char *p;
72 p = strchr(name, '.');
73 if (p)
74 return p + 1;
75 return name;
76 }
77
78static STACK_OF(ENGINE) *initialized_engines = NULL;
79
80static int int_engine_init(ENGINE *e)
81 {
82 if (!ENGINE_init(e))
83 return 0;
84 if (!initialized_engines)
85 initialized_engines = sk_ENGINE_new_null();
86 if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e))
87 {
88 ENGINE_finish(e);
89 return 0;
90 }
91 return 1;
92 }
93
94
95int int_engine_configure(char *name, char *value, const CONF *cnf)
96 {
97 int i;
98 int ret = 0;
99 long do_init = -1;
100 STACK_OF(CONF_VALUE) *ecmds;
101 CONF_VALUE *ecmd;
102 char *ctrlname, *ctrlvalue;
103 ENGINE *e = NULL;
104 name = skip_dot(name);
105#ifdef ENGINE_CONF_DEBUG
106 fprintf(stderr, "Configuring engine %s\n", name);
107#endif
108 /* Value is a section containing ENGINE commands */
109 ecmds = NCONF_get_section(cnf, value);
110
111 if (!ecmds)
112 {
113 ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_SECTION_ERROR);
114 return 0;
115 }
116
117 for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++)
118 {
119 ecmd = sk_CONF_VALUE_value(ecmds, i);
120 ctrlname = skip_dot(ecmd->name);
121 ctrlvalue = ecmd->value;
122#ifdef ENGINE_CONF_DEBUG
123 fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname, ctrlvalue);
124#endif
125
126 /* First handle some special pseudo ctrls */
127
128 /* Override engine name to use */
129 if (!strcmp(ctrlname, "engine_id"))
130 name = ctrlvalue;
131 /* Load a dynamic ENGINE */
132 else if (!strcmp(ctrlname, "dynamic_path"))
133 {
134 e = ENGINE_by_id("dynamic");
135 if (!e)
136 goto err;
137 if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0))
138 goto err;
139 if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0))
140 goto err;
141 if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
142 goto err;
143 }
144 /* ... add other pseudos here ... */
145 else
146 {
147 /* At this point we need an ENGINE structural reference
148 * if we don't already have one.
149 */
150 if (!e)
151 {
152 e = ENGINE_by_id(name);
153 if (!e)
154 return 0;
155 }
156 /* Allow "EMPTY" to mean no value: this allows a valid
157 * "value" to be passed to ctrls of type NO_INPUT
158 */
159 if (!strcmp(ctrlvalue, "EMPTY"))
160 ctrlvalue = NULL;
161 else if (!strcmp(ctrlname, "init"))
162 {
163 if (!NCONF_get_number_e(cnf, value, "init", &do_init))
164 goto err;
165 if (do_init == 1)
166 {
167 if (!int_engine_init(e))
168 goto err;
169 }
170 else if (do_init != 0)
171 {
172 ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_INVALID_INIT_VALUE);
173 goto err;
174 }
175 }
176 else if (!strcmp(ctrlname, "default_algorithms"))
177 {
178 if (!ENGINE_set_default_string(e, ctrlvalue))
179 goto err;
180 }
181 else if (!ENGINE_ctrl_cmd_string(e,
182 ctrlname, ctrlvalue, 0))
183 return 0;
184 }
185
186
187
188 }
189 if (e && (do_init == -1) && !int_engine_init(e))
190 goto err;
191 ret = 1;
192 err:
193 if (e)
194 ENGINE_free(e);
195 return ret;
196 }
197
198
199static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf)
200 {
201 STACK_OF(CONF_VALUE) *elist;
202 CONF_VALUE *cval;
203 int i;
204#ifdef ENGINE_CONF_DEBUG
205 fprintf(stderr, "Called engine module: name %s, value %s\n",
206 CONF_imodule_get_name(md), CONF_imodule_get_value(md));
207#endif
208 /* Value is a section containing ENGINEs to configure */
209 elist = NCONF_get_section(cnf, CONF_imodule_get_value(md));
210
211 if (!elist)
212 {
213 ENGINEerr(ENGINE_F_ENGINE_MODULE_INIT, ENGINE_R_ENGINES_SECTION_ERROR);
214 return 0;
215 }
216
217 for (i = 0; i < sk_CONF_VALUE_num(elist); i++)
218 {
219 cval = sk_CONF_VALUE_value(elist, i);
220 if (!int_engine_configure(cval->name, cval->value, cnf))
221 return 0;
222 }
223
224 return 1;
225 }
226
227static void int_engine_module_finish(CONF_IMODULE *md)
228 {
229 ENGINE *e;
230 while ((e = sk_ENGINE_pop(initialized_engines)))
231 ENGINE_finish(e);
232 sk_ENGINE_free(initialized_engines);
233 initialized_engines = NULL;
234 }
235
236
237void ENGINE_add_conf_module(void)
238 {
239 CONF_module_add("engines",
240 int_engine_module_init,
241 int_engine_module_finish);
242 }
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 @@
1/* crypto/engine/eng_ctrl.c */
2/* ====================================================================
3 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * licensing@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include <openssl/crypto.h>
57#include "cryptlib.h"
58#include "eng_int.h"
59#include <openssl/engine.h>
60
61/* When querying a ENGINE-specific control command's 'description', this string
62 * is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. */
63static const char *int_no_description = "";
64
65/* These internal functions handle 'CMD'-related control commands when the
66 * ENGINE in question has asked us to take care of it (ie. the ENGINE did not
67 * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. */
68
69static int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn)
70 {
71 if((defn->cmd_num == 0) || (defn->cmd_name == NULL))
72 return 1;
73 return 0;
74 }
75
76static int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s)
77 {
78 int idx = 0;
79 while(!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0))
80 {
81 idx++;
82 defn++;
83 }
84 if(int_ctrl_cmd_is_null(defn))
85 /* The given name wasn't found */
86 return -1;
87 return idx;
88 }
89
90static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num)
91 {
92 int idx = 0;
93 /* NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So
94 * our searches don't need to take any longer than necessary. */
95 while(!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num))
96 {
97 idx++;
98 defn++;
99 }
100 if(defn->cmd_num == num)
101 return idx;
102 /* The given cmd_num wasn't found */
103 return -1;
104 }
105
106static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, void (*f)())
107 {
108 int idx;
109 char *s = (char *)p;
110 /* Take care of the easy one first (eg. it requires no searches) */
111 if(cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE)
112 {
113 if((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns))
114 return 0;
115 return e->cmd_defns->cmd_num;
116 }
117 /* One or two commands require that "p" be a valid string buffer */
118 if((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) ||
119 (cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) ||
120 (cmd == ENGINE_CTRL_GET_DESC_FROM_CMD))
121 {
122 if(s == NULL)
123 {
124 ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
125 ERR_R_PASSED_NULL_PARAMETER);
126 return -1;
127 }
128 }
129 /* Now handle cmd_name -> cmd_num conversion */
130 if(cmd == ENGINE_CTRL_GET_CMD_FROM_NAME)
131 {
132 if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_name(
133 e->cmd_defns, s)) < 0))
134 {
135 ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
136 ENGINE_R_INVALID_CMD_NAME);
137 return -1;
138 }
139 return e->cmd_defns[idx].cmd_num;
140 }
141 /* For the rest of the commands, the 'long' argument must specify a
142 * valie command number - so we need to conduct a search. */
143 if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns,
144 (unsigned int)i)) < 0))
145 {
146 ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
147 ENGINE_R_INVALID_CMD_NUMBER);
148 return -1;
149 }
150 /* Now the logic splits depending on command type */
151 switch(cmd)
152 {
153 case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
154 idx++;
155 if(int_ctrl_cmd_is_null(e->cmd_defns + idx))
156 /* end-of-list */
157 return 0;
158 else
159 return e->cmd_defns[idx].cmd_num;
160 case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
161 return strlen(e->cmd_defns[idx].cmd_name);
162 case ENGINE_CTRL_GET_NAME_FROM_CMD:
163 return sprintf(s, "%s", e->cmd_defns[idx].cmd_name);
164 case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
165 if(e->cmd_defns[idx].cmd_desc)
166 return strlen(e->cmd_defns[idx].cmd_desc);
167 return strlen(int_no_description);
168 case ENGINE_CTRL_GET_DESC_FROM_CMD:
169 if(e->cmd_defns[idx].cmd_desc)
170 return sprintf(s, "%s", e->cmd_defns[idx].cmd_desc);
171 return sprintf(s, "%s", int_no_description);
172 case ENGINE_CTRL_GET_CMD_FLAGS:
173 return e->cmd_defns[idx].cmd_flags;
174 }
175 /* Shouldn't really be here ... */
176 ENGINEerr(ENGINE_F_INT_CTRL_HELPER,ENGINE_R_INTERNAL_LIST_ERROR);
177 return -1;
178 }
179
180int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
181 {
182 int ctrl_exists, ref_exists;
183 if(e == NULL)
184 {
185 ENGINEerr(ENGINE_F_ENGINE_CTRL,ERR_R_PASSED_NULL_PARAMETER);
186 return 0;
187 }
188 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
189 ref_exists = ((e->struct_ref > 0) ? 1 : 0);
190 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
191 ctrl_exists = ((e->ctrl == NULL) ? 0 : 1);
192 if(!ref_exists)
193 {
194 ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_REFERENCE);
195 return 0;
196 }
197 /* Intercept any "root-level" commands before trying to hand them on to
198 * ctrl() handlers. */
199 switch(cmd)
200 {
201 case ENGINE_CTRL_HAS_CTRL_FUNCTION:
202 return ctrl_exists;
203 case ENGINE_CTRL_GET_FIRST_CMD_TYPE:
204 case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
205 case ENGINE_CTRL_GET_CMD_FROM_NAME:
206 case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
207 case ENGINE_CTRL_GET_NAME_FROM_CMD:
208 case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
209 case ENGINE_CTRL_GET_DESC_FROM_CMD:
210 case ENGINE_CTRL_GET_CMD_FLAGS:
211 if(ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL))
212 return int_ctrl_helper(e,cmd,i,p,f);
213 if(!ctrl_exists)
214 {
215 ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
216 /* For these cmd-related functions, failure is indicated
217 * by a -1 return value (because 0 is used as a valid
218 * return in some places). */
219 return -1;
220 }
221 default:
222 break;
223 }
224 /* Anything else requires a ctrl() handler to exist. */
225 if(!ctrl_exists)
226 {
227 ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
228 return 0;
229 }
230 return e->ctrl(e, cmd, i, p, f);
231 }
232
233int ENGINE_cmd_is_executable(ENGINE *e, int cmd)
234 {
235 int flags;
236 if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0)
237 {
238 ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE,
239 ENGINE_R_INVALID_CMD_NUMBER);
240 return 0;
241 }
242 if(!(flags & ENGINE_CMD_FLAG_NO_INPUT) &&
243 !(flags & ENGINE_CMD_FLAG_NUMERIC) &&
244 !(flags & ENGINE_CMD_FLAG_STRING))
245 return 0;
246 return 1;
247 }
248
249int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
250 long i, void *p, void (*f)(), int cmd_optional)
251 {
252 int num;
253
254 if((e == NULL) || (cmd_name == NULL))
255 {
256 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
257 ERR_R_PASSED_NULL_PARAMETER);
258 return 0;
259 }
260 if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
261 ENGINE_CTRL_GET_CMD_FROM_NAME,
262 0, (void *)cmd_name, NULL)) <= 0))
263 {
264 /* If the command didn't *have* to be supported, we fake
265 * success. This allows certain settings to be specified for
266 * multiple ENGINEs and only require a change of ENGINE id
267 * (without having to selectively apply settings). Eg. changing
268 * from a hardware device back to the regular software ENGINE
269 * without editing the config file, etc. */
270 if(cmd_optional)
271 {
272 ERR_clear_error();
273 return 1;
274 }
275 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
276 ENGINE_R_INVALID_CMD_NAME);
277 return 0;
278 }
279 /* Force the result of the control command to 0 or 1, for the reasons
280 * mentioned before. */
281 if (ENGINE_ctrl(e, num, i, p, f))
282 return 1;
283 return 0;
284 }
285
286int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
287 int cmd_optional)
288 {
289 int num, flags;
290 long l;
291 char *ptr;
292 if((e == NULL) || (cmd_name == NULL))
293 {
294 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
295 ERR_R_PASSED_NULL_PARAMETER);
296 return 0;
297 }
298 if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
299 ENGINE_CTRL_GET_CMD_FROM_NAME,
300 0, (void *)cmd_name, NULL)) <= 0))
301 {
302 /* If the command didn't *have* to be supported, we fake
303 * success. This allows certain settings to be specified for
304 * multiple ENGINEs and only require a change of ENGINE id
305 * (without having to selectively apply settings). Eg. changing
306 * from a hardware device back to the regular software ENGINE
307 * without editing the config file, etc. */
308 if(cmd_optional)
309 {
310 ERR_clear_error();
311 return 1;
312 }
313 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
314 ENGINE_R_INVALID_CMD_NAME);
315 return 0;
316 }
317 if(!ENGINE_cmd_is_executable(e, num))
318 {
319 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
320 ENGINE_R_CMD_NOT_EXECUTABLE);
321 return 0;
322 }
323 if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL)) < 0)
324 {
325 /* Shouldn't happen, given that ENGINE_cmd_is_executable()
326 * returned success. */
327 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
328 ENGINE_R_INTERNAL_LIST_ERROR);
329 return 0;
330 }
331 /* If the command takes no input, there must be no input. And vice
332 * versa. */
333 if(flags & ENGINE_CMD_FLAG_NO_INPUT)
334 {
335 if(arg != NULL)
336 {
337 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
338 ENGINE_R_COMMAND_TAKES_NO_INPUT);
339 return 0;
340 }
341 /* We deliberately force the result of ENGINE_ctrl() to 0 or 1
342 * rather than returning it as "return data". This is to ensure
343 * usage of these commands is consistent across applications and
344 * that certain applications don't understand it one way, and
345 * others another. */
346 if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL))
347 return 1;
348 return 0;
349 }
350 /* So, we require input */
351 if(arg == NULL)
352 {
353 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
354 ENGINE_R_COMMAND_TAKES_INPUT);
355 return 0;
356 }
357 /* If it takes string input, that's easy */
358 if(flags & ENGINE_CMD_FLAG_STRING)
359 {
360 /* Same explanation as above */
361 if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL))
362 return 1;
363 return 0;
364 }
365 /* If it doesn't take numeric either, then it is unsupported for use in
366 * a config-setting situation, which is what this function is for. This
367 * should never happen though, because ENGINE_cmd_is_executable() was
368 * used. */
369 if(!(flags & ENGINE_CMD_FLAG_NUMERIC))
370 {
371 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
372 ENGINE_R_INTERNAL_LIST_ERROR);
373 return 0;
374 }
375 l = strtol(arg, &ptr, 10);
376 if((arg == ptr) || (*ptr != '\0'))
377 {
378 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
379 ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER);
380 return 0;
381 }
382 /* Force the result of the control command to 0 or 1, for the reasons
383 * mentioned before. */
384 if(ENGINE_ctrl(e, num, l, NULL, NULL))
385 return 1;
386 return 0;
387 }
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 @@
1/* crypto/engine/eng_dyn.c */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2001.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59
60#include <stdio.h>
61#include <openssl/crypto.h>
62#include "cryptlib.h"
63#include "eng_int.h"
64#include <openssl/engine.h>
65#include <openssl/dso.h>
66
67/* Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE loader
68 * should implement the hook-up functions with the following prototypes. */
69
70/* Our ENGINE handlers */
71static int dynamic_init(ENGINE *e);
72static int dynamic_finish(ENGINE *e);
73static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
74/* Predeclare our context type */
75typedef struct st_dynamic_data_ctx dynamic_data_ctx;
76/* The implementation for the important control command */
77static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx);
78
79#define DYNAMIC_CMD_SO_PATH ENGINE_CMD_BASE
80#define DYNAMIC_CMD_NO_VCHECK (ENGINE_CMD_BASE + 1)
81#define DYNAMIC_CMD_ID (ENGINE_CMD_BASE + 2)
82#define DYNAMIC_CMD_LIST_ADD (ENGINE_CMD_BASE + 3)
83#define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 4)
84
85/* The constants used when creating the ENGINE */
86static const char *engine_dynamic_id = "dynamic";
87static const char *engine_dynamic_name = "Dynamic engine loading support";
88static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = {
89 {DYNAMIC_CMD_SO_PATH,
90 "SO_PATH",
91 "Specifies the path to the new ENGINE shared library",
92 ENGINE_CMD_FLAG_STRING},
93 {DYNAMIC_CMD_NO_VCHECK,
94 "NO_VCHECK",
95 "Specifies to continue even if version checking fails (boolean)",
96 ENGINE_CMD_FLAG_NUMERIC},
97 {DYNAMIC_CMD_ID,
98 "ID",
99 "Specifies an ENGINE id name for loading",
100 ENGINE_CMD_FLAG_STRING},
101 {DYNAMIC_CMD_LIST_ADD,
102 "LIST_ADD",
103 "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)",
104 ENGINE_CMD_FLAG_NUMERIC},
105 {DYNAMIC_CMD_LOAD,
106 "LOAD",
107 "Load up the ENGINE specified by other settings",
108 ENGINE_CMD_FLAG_NO_INPUT},
109 {0, NULL, NULL, 0}
110 };
111static const ENGINE_CMD_DEFN dynamic_cmd_defns_empty[] = {
112 {0, NULL, NULL, 0}
113 };
114
115/* Loading code stores state inside the ENGINE structure via the "ex_data"
116 * element. We load all our state into a single structure and use that as a
117 * single context in the "ex_data" stack. */
118struct st_dynamic_data_ctx
119 {
120 /* The DSO object we load that supplies the ENGINE code */
121 DSO *dynamic_dso;
122 /* The function pointer to the version checking shared library function */
123 dynamic_v_check_fn v_check;
124 /* The function pointer to the engine-binding shared library function */
125 dynamic_bind_engine bind_engine;
126 /* The default name/path for loading the shared library */
127 const char *DYNAMIC_LIBNAME;
128 /* Whether to continue loading on a version check failure */
129 int no_vcheck;
130 /* If non-NULL, stipulates the 'id' of the ENGINE to be loaded */
131 const char *engine_id;
132 /* If non-zero, a successfully loaded ENGINE should be added to the internal
133 * ENGINE list. If 2, the add must succeed or the entire load should fail. */
134 int list_add_value;
135 /* The symbol name for the version checking function */
136 const char *DYNAMIC_F1;
137 /* The symbol name for the "initialise ENGINE structure" function */
138 const char *DYNAMIC_F2;
139 };
140
141/* This is the "ex_data" index we obtain and reserve for use with our context
142 * structure. */
143static int dynamic_ex_data_idx = -1;
144
145/* Because our ex_data element may or may not get allocated depending on whether
146 * a "first-use" occurs before the ENGINE is freed, we have a memory leak
147 * problem to solve. We can't declare a "new" handler for the ex_data as we
148 * don't want a dynamic_data_ctx in *all* ENGINE structures of all types (this
149 * is a bug in the design of CRYPTO_EX_DATA). As such, we just declare a "free"
150 * handler and that will get called if an ENGINE is being destroyed and there
151 * was an ex_data element corresponding to our context type. */
152static void dynamic_data_ctx_free_func(void *parent, void *ptr,
153 CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
154 {
155 if(ptr)
156 {
157 dynamic_data_ctx *ctx = (dynamic_data_ctx *)ptr;
158 if(ctx->dynamic_dso)
159 DSO_free(ctx->dynamic_dso);
160 OPENSSL_free(ctx);
161 }
162 }
163
164/* Construct the per-ENGINE context. We create it blindly and then use a lock to
165 * check for a race - if so, all but one of the threads "racing" will have
166 * wasted their time. The alternative involves creating everything inside the
167 * lock which is far worse. */
168static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
169 {
170 dynamic_data_ctx *c;
171 c = OPENSSL_malloc(sizeof(dynamic_data_ctx));
172 if(!ctx)
173 {
174 ENGINEerr(ENGINE_F_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
175 return 0;
176 }
177 memset(c, 0, sizeof(dynamic_data_ctx));
178 c->dynamic_dso = NULL;
179 c->v_check = NULL;
180 c->bind_engine = NULL;
181 c->DYNAMIC_LIBNAME = NULL;
182 c->no_vcheck = 0;
183 c->engine_id = NULL;
184 c->list_add_value = 0;
185 c->DYNAMIC_F1 = "v_check";
186 c->DYNAMIC_F2 = "bind_engine";
187 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
188 if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e,
189 dynamic_ex_data_idx)) == NULL)
190 {
191 /* Good, we're the first */
192 ENGINE_set_ex_data(e, dynamic_ex_data_idx, c);
193 *ctx = c;
194 c = NULL;
195 }
196 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
197 /* If we lost the race to set the context, c is non-NULL and *ctx is the
198 * context of the thread that won. */
199 if(c)
200 OPENSSL_free(c);
201 return 1;
202 }
203
204/* This function retrieves the context structure from an ENGINE's "ex_data", or
205 * if it doesn't exist yet, sets it up. */
206static dynamic_data_ctx *dynamic_get_data_ctx(ENGINE *e)
207 {
208 dynamic_data_ctx *ctx;
209 if(dynamic_ex_data_idx < 0)
210 {
211 /* Create and register the ENGINE ex_data, and associate our
212 * "free" function with it to ensure any allocated contexts get
213 * freed when an ENGINE goes underground. */
214 int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL,
215 dynamic_data_ctx_free_func);
216 if(new_idx == -1)
217 {
218 ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX,ENGINE_R_NO_INDEX);
219 return NULL;
220 }
221 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
222 /* Avoid a race by checking again inside this lock */
223 if(dynamic_ex_data_idx < 0)
224 {
225 /* Good, someone didn't beat us to it */
226 dynamic_ex_data_idx = new_idx;
227 new_idx = -1;
228 }
229 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
230 /* In theory we could "give back" the index here if
231 * (new_idx>-1), but it's not possible and wouldn't gain us much
232 * if it were. */
233 }
234 ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx);
235 /* Check if the context needs to be created */
236 if((ctx == NULL) && !dynamic_set_data_ctx(e, &ctx))
237 /* "set_data" will set errors if necessary */
238 return NULL;
239 return ctx;
240 }
241
242static ENGINE *engine_dynamic(void)
243 {
244 ENGINE *ret = ENGINE_new();
245 if(!ret)
246 return NULL;
247 if(!ENGINE_set_id(ret, engine_dynamic_id) ||
248 !ENGINE_set_name(ret, engine_dynamic_name) ||
249 !ENGINE_set_init_function(ret, dynamic_init) ||
250 !ENGINE_set_finish_function(ret, dynamic_finish) ||
251 !ENGINE_set_ctrl_function(ret, dynamic_ctrl) ||
252 !ENGINE_set_flags(ret, ENGINE_FLAGS_BY_ID_COPY) ||
253 !ENGINE_set_cmd_defns(ret, dynamic_cmd_defns))
254 {
255 ENGINE_free(ret);
256 return NULL;
257 }
258 return ret;
259 }
260
261void ENGINE_load_dynamic(void)
262 {
263 ENGINE *toadd = engine_dynamic();
264 if(!toadd) return;
265 ENGINE_add(toadd);
266 /* If the "add" worked, it gets a structural reference. So either way,
267 * we release our just-created reference. */
268 ENGINE_free(toadd);
269 /* If the "add" didn't work, it was probably a conflict because it was
270 * already added (eg. someone calling ENGINE_load_blah then calling
271 * ENGINE_load_builtin_engines() perhaps). */
272 ERR_clear_error();
273 }
274
275static int dynamic_init(ENGINE *e)
276 {
277 /* We always return failure - the "dyanamic" engine itself can't be used
278 * for anything. */
279 return 0;
280 }
281
282static int dynamic_finish(ENGINE *e)
283 {
284 /* This should never be called on account of "dynamic_init" always
285 * failing. */
286 return 0;
287 }
288
289static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
290 {
291 dynamic_data_ctx *ctx = dynamic_get_data_ctx(e);
292 int initialised;
293
294 if(!ctx)
295 {
296 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_NOT_LOADED);
297 return 0;
298 }
299 initialised = ((ctx->dynamic_dso == NULL) ? 0 : 1);
300 /* All our control commands require the ENGINE to be uninitialised */
301 if(initialised)
302 {
303 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
304 ENGINE_R_ALREADY_LOADED);
305 return 0;
306 }
307 switch(cmd)
308 {
309 case DYNAMIC_CMD_SO_PATH:
310 /* a NULL 'p' or a string of zero-length is the same thing */
311 if(p && (strlen((const char *)p) < 1))
312 p = NULL;
313 ctx->DYNAMIC_LIBNAME = (const char *)p;
314 return 1;
315 case DYNAMIC_CMD_NO_VCHECK:
316 ctx->no_vcheck = ((i == 0) ? 0 : 1);
317 return 1;
318 case DYNAMIC_CMD_ID:
319 /* a NULL 'p' or a string of zero-length is the same thing */
320 if(p && (strlen((const char *)p) < 1))
321 p = NULL;
322 ctx->engine_id = (const char *)p;
323 return 1;
324 case DYNAMIC_CMD_LIST_ADD:
325 if((i < 0) || (i > 2))
326 {
327 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
328 ENGINE_R_INVALID_ARGUMENT);
329 return 0;
330 }
331 ctx->list_add_value = (int)i;
332 return 1;
333 case DYNAMIC_CMD_LOAD:
334 return dynamic_load(e, ctx);
335 default:
336 break;
337 }
338 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
339 return 0;
340 }
341
342static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
343 {
344 ENGINE cpy;
345 dynamic_fns fns;
346
347 if(!ctx->DYNAMIC_LIBNAME || ((ctx->dynamic_dso = DSO_load(NULL,
348 ctx->DYNAMIC_LIBNAME, NULL, 0)) == NULL))
349 {
350 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
351 ENGINE_R_DSO_NOT_FOUND);
352 return 0;
353 }
354 /* We have to find a bind function otherwise it'll always end badly */
355 if(!(ctx->bind_engine = (dynamic_bind_engine)DSO_bind_func(
356 ctx->dynamic_dso, ctx->DYNAMIC_F2)))
357 {
358 ctx->bind_engine = NULL;
359 DSO_free(ctx->dynamic_dso);
360 ctx->dynamic_dso = NULL;
361 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
362 ENGINE_R_DSO_FAILURE);
363 return 0;
364 }
365 /* Do we perform version checking? */
366 if(!ctx->no_vcheck)
367 {
368 unsigned long vcheck_res = 0;
369 /* Now we try to find a version checking function and decide how
370 * to cope with failure if/when it fails. */
371 ctx->v_check = (dynamic_v_check_fn)DSO_bind_func(
372 ctx->dynamic_dso, ctx->DYNAMIC_F1);
373 if(ctx->v_check)
374 vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION);
375 /* We fail if the version checker veto'd the load *or* if it is
376 * deferring to us (by returning its version) and we think it is
377 * too old. */
378 if(vcheck_res < OSSL_DYNAMIC_OLDEST)
379 {
380 /* Fail */
381 ctx->bind_engine = NULL;
382 ctx->v_check = NULL;
383 DSO_free(ctx->dynamic_dso);
384 ctx->dynamic_dso = NULL;
385 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
386 ENGINE_R_VERSION_INCOMPATIBILITY);
387 return 0;
388 }
389 }
390 /* First binary copy the ENGINE structure so that we can roll back if
391 * the hand-over fails */
392 memcpy(&cpy, e, sizeof(ENGINE));
393 /* Provide the ERR, "ex_data", memory, and locking callbacks so the
394 * loaded library uses our state rather than its own. FIXME: As noted in
395 * engine.h, much of this would be simplified if each area of code
396 * provided its own "summary" structure of all related callbacks. It
397 * would also increase opaqueness. */
398 fns.err_fns = ERR_get_implementation();
399 fns.ex_data_fns = CRYPTO_get_ex_data_implementation();
400 CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb,
401 &fns.mem_fns.realloc_cb,
402 &fns.mem_fns.free_cb);
403 fns.lock_fns.lock_locking_cb = CRYPTO_get_locking_callback();
404 fns.lock_fns.lock_add_lock_cb = CRYPTO_get_add_lock_callback();
405 fns.lock_fns.dynlock_create_cb = CRYPTO_get_dynlock_create_callback();
406 fns.lock_fns.dynlock_lock_cb = CRYPTO_get_dynlock_lock_callback();
407 fns.lock_fns.dynlock_destroy_cb = CRYPTO_get_dynlock_destroy_callback();
408 /* Now that we've loaded the dynamic engine, make sure no "dynamic"
409 * ENGINE elements will show through. */
410 engine_set_all_null(e);
411
412 /* Try to bind the ENGINE onto our own ENGINE structure */
413 if(!ctx->bind_engine(e, ctx->engine_id, &fns))
414 {
415 ctx->bind_engine = NULL;
416 ctx->v_check = NULL;
417 DSO_free(ctx->dynamic_dso);
418 ctx->dynamic_dso = NULL;
419 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,ENGINE_R_INIT_FAILED);
420 /* Copy the original ENGINE structure back */
421 memcpy(e, &cpy, sizeof(ENGINE));
422 return 0;
423 }
424 /* Do we try to add this ENGINE to the internal list too? */
425 if(ctx->list_add_value > 0)
426 {
427 if(!ENGINE_add(e))
428 {
429 /* Do we tolerate this or fail? */
430 if(ctx->list_add_value > 1)
431 {
432 /* Fail - NB: By this time, it's too late to
433 * rollback, and trying to do so allows the
434 * bind_engine() code to have created leaks. We
435 * just have to fail where we are, after the
436 * ENGINE has changed. */
437 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
438 ENGINE_R_CONFLICTING_ENGINE_ID);
439 return 0;
440 }
441 /* Tolerate */
442 ERR_clear_error();
443 }
444 }
445 return 1;
446 }
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 @@
1/* crypto/engine/eng_err.c */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include <openssl/engine.h>
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA ENGINE_str_functs[]=
68 {
69{ERR_PACK(0,ENGINE_F_DYNAMIC_CTRL,0), "DYNAMIC_CTRL"},
70{ERR_PACK(0,ENGINE_F_DYNAMIC_GET_DATA_CTX,0), "DYNAMIC_GET_DATA_CTX"},
71{ERR_PACK(0,ENGINE_F_DYNAMIC_LOAD,0), "DYNAMIC_LOAD"},
72{ERR_PACK(0,ENGINE_F_ENGINE_ADD,0), "ENGINE_add"},
73{ERR_PACK(0,ENGINE_F_ENGINE_BY_ID,0), "ENGINE_by_id"},
74{ERR_PACK(0,ENGINE_F_ENGINE_CMD_IS_EXECUTABLE,0), "ENGINE_cmd_is_executable"},
75{ERR_PACK(0,ENGINE_F_ENGINE_CTRL,0), "ENGINE_ctrl"},
76{ERR_PACK(0,ENGINE_F_ENGINE_CTRL_CMD,0), "ENGINE_ctrl_cmd"},
77{ERR_PACK(0,ENGINE_F_ENGINE_CTRL_CMD_STRING,0), "ENGINE_ctrl_cmd_string"},
78{ERR_PACK(0,ENGINE_F_ENGINE_FINISH,0), "ENGINE_finish"},
79{ERR_PACK(0,ENGINE_F_ENGINE_FREE,0), "ENGINE_free"},
80{ERR_PACK(0,ENGINE_F_ENGINE_GET_CIPHER,0), "ENGINE_get_cipher"},
81{ERR_PACK(0,ENGINE_F_ENGINE_GET_DEFAULT_TYPE,0), "ENGINE_GET_DEFAULT_TYPE"},
82{ERR_PACK(0,ENGINE_F_ENGINE_GET_DIGEST,0), "ENGINE_get_digest"},
83{ERR_PACK(0,ENGINE_F_ENGINE_GET_NEXT,0), "ENGINE_get_next"},
84{ERR_PACK(0,ENGINE_F_ENGINE_GET_PREV,0), "ENGINE_get_prev"},
85{ERR_PACK(0,ENGINE_F_ENGINE_INIT,0), "ENGINE_init"},
86{ERR_PACK(0,ENGINE_F_ENGINE_LIST_ADD,0), "ENGINE_LIST_ADD"},
87{ERR_PACK(0,ENGINE_F_ENGINE_LIST_REMOVE,0), "ENGINE_LIST_REMOVE"},
88{ERR_PACK(0,ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,0), "ENGINE_load_private_key"},
89{ERR_PACK(0,ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,0), "ENGINE_load_public_key"},
90{ERR_PACK(0,ENGINE_F_ENGINE_MODULE_INIT,0), "ENGINE_MODULE_INIT"},
91{ERR_PACK(0,ENGINE_F_ENGINE_NEW,0), "ENGINE_new"},
92{ERR_PACK(0,ENGINE_F_ENGINE_REMOVE,0), "ENGINE_remove"},
93{ERR_PACK(0,ENGINE_F_ENGINE_SET_DEFAULT_STRING,0), "ENGINE_set_default_string"},
94{ERR_PACK(0,ENGINE_F_ENGINE_SET_DEFAULT_TYPE,0), "ENGINE_SET_DEFAULT_TYPE"},
95{ERR_PACK(0,ENGINE_F_ENGINE_SET_ID,0), "ENGINE_set_id"},
96{ERR_PACK(0,ENGINE_F_ENGINE_SET_NAME,0), "ENGINE_set_name"},
97{ERR_PACK(0,ENGINE_F_ENGINE_TABLE_REGISTER,0), "ENGINE_TABLE_REGISTER"},
98{ERR_PACK(0,ENGINE_F_ENGINE_UNLOAD_KEY,0), "ENGINE_UNLOAD_KEY"},
99{ERR_PACK(0,ENGINE_F_INT_CTRL_HELPER,0), "INT_CTRL_HELPER"},
100{ERR_PACK(0,ENGINE_F_INT_ENGINE_CONFIGURE,0), "INT_ENGINE_CONFIGURE"},
101{ERR_PACK(0,ENGINE_F_LOG_MESSAGE,0), "LOG_MESSAGE"},
102{ERR_PACK(0,ENGINE_F_SET_DATA_CTX,0), "SET_DATA_CTX"},
103{0,NULL}
104 };
105
106static ERR_STRING_DATA ENGINE_str_reasons[]=
107 {
108{ENGINE_R_ALREADY_LOADED ,"already loaded"},
109{ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER ,"argument is not a number"},
110{ENGINE_R_CMD_NOT_EXECUTABLE ,"cmd not executable"},
111{ENGINE_R_COMMAND_TAKES_INPUT ,"command takes input"},
112{ENGINE_R_COMMAND_TAKES_NO_INPUT ,"command takes no input"},
113{ENGINE_R_CONFLICTING_ENGINE_ID ,"conflicting engine id"},
114{ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
115{ENGINE_R_DH_NOT_IMPLEMENTED ,"dh not implemented"},
116{ENGINE_R_DSA_NOT_IMPLEMENTED ,"dsa not implemented"},
117{ENGINE_R_DSO_FAILURE ,"DSO failure"},
118{ENGINE_R_DSO_NOT_FOUND ,"dso not found"},
119{ENGINE_R_ENGINES_SECTION_ERROR ,"engines section error"},
120{ENGINE_R_ENGINE_IS_NOT_IN_LIST ,"engine is not in the list"},
121{ENGINE_R_ENGINE_SECTION_ERROR ,"engine section error"},
122{ENGINE_R_FAILED_LOADING_PRIVATE_KEY ,"failed loading private key"},
123{ENGINE_R_FAILED_LOADING_PUBLIC_KEY ,"failed loading public key"},
124{ENGINE_R_FINISH_FAILED ,"finish failed"},
125{ENGINE_R_GET_HANDLE_FAILED ,"could not obtain hardware handle"},
126{ENGINE_R_ID_OR_NAME_MISSING ,"'id' or 'name' missing"},
127{ENGINE_R_INIT_FAILED ,"init failed"},
128{ENGINE_R_INTERNAL_LIST_ERROR ,"internal list error"},
129{ENGINE_R_INVALID_ARGUMENT ,"invalid argument"},
130{ENGINE_R_INVALID_CMD_NAME ,"invalid cmd name"},
131{ENGINE_R_INVALID_CMD_NUMBER ,"invalid cmd number"},
132{ENGINE_R_INVALID_INIT_VALUE ,"invalid init value"},
133{ENGINE_R_INVALID_STRING ,"invalid string"},
134{ENGINE_R_NOT_INITIALISED ,"not initialised"},
135{ENGINE_R_NOT_LOADED ,"not loaded"},
136{ENGINE_R_NO_CONTROL_FUNCTION ,"no control function"},
137{ENGINE_R_NO_INDEX ,"no index"},
138{ENGINE_R_NO_LOAD_FUNCTION ,"no load function"},
139{ENGINE_R_NO_REFERENCE ,"no reference"},
140{ENGINE_R_NO_SUCH_ENGINE ,"no such engine"},
141{ENGINE_R_NO_UNLOAD_FUNCTION ,"no unload function"},
142{ENGINE_R_PROVIDE_PARAMETERS ,"provide parameters"},
143{ENGINE_R_RSA_NOT_IMPLEMENTED ,"rsa not implemented"},
144{ENGINE_R_UNIMPLEMENTED_CIPHER ,"unimplemented cipher"},
145{ENGINE_R_UNIMPLEMENTED_DIGEST ,"unimplemented digest"},
146{ENGINE_R_VERSION_INCOMPATIBILITY ,"version incompatibility"},
147{0,NULL}
148 };
149
150#endif
151
152void ERR_load_ENGINE_strings(void)
153 {
154 static int init=1;
155
156 if (init)
157 {
158 init=0;
159#ifndef OPENSSL_NO_ERR
160 ERR_load_strings(ERR_LIB_ENGINE,ENGINE_str_functs);
161 ERR_load_strings(ERR_LIB_ENGINE,ENGINE_str_reasons);
162#endif
163
164 }
165 }
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 @@
1/* crypto/engine/eng_fat.c */
2/* ====================================================================
3 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * licensing@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include <openssl/crypto.h>
57#include "cryptlib.h"
58#include "eng_int.h"
59#include <openssl/engine.h>
60#include <openssl/conf.h>
61
62int ENGINE_set_default(ENGINE *e, unsigned int flags)
63 {
64 if((flags & ENGINE_METHOD_CIPHERS) && !ENGINE_set_default_ciphers(e))
65 return 0;
66 if((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e))
67 return 0;
68#ifndef OPENSSL_NO_RSA
69 if((flags & ENGINE_METHOD_RSA) & !ENGINE_set_default_RSA(e))
70 return 0;
71#endif
72#ifndef OPENSSL_NO_DSA
73 if((flags & ENGINE_METHOD_DSA) & !ENGINE_set_default_DSA(e))
74 return 0;
75#endif
76#ifndef OPENSSL_NO_DH
77 if((flags & ENGINE_METHOD_DH) & !ENGINE_set_default_DH(e))
78 return 0;
79#endif
80 if((flags & ENGINE_METHOD_RAND) & !ENGINE_set_default_RAND(e))
81 return 0;
82 return 1;
83 }
84
85/* Set default algorithms using a string */
86
87int int_def_cb(const char *alg, int len, void *arg)
88 {
89 unsigned int *pflags = arg;
90 if (!strncmp(alg, "ALL", len))
91 *pflags |= ENGINE_METHOD_ALL;
92 else if (!strncmp(alg, "RSA", len))
93 *pflags |= ENGINE_METHOD_RSA;
94 else if (!strncmp(alg, "DSA", len))
95 *pflags |= ENGINE_METHOD_DSA;
96 else if (!strncmp(alg, "DH", len))
97 *pflags |= ENGINE_METHOD_DH;
98 else if (!strncmp(alg, "RAND", len))
99 *pflags |= ENGINE_METHOD_RAND;
100 else if (!strncmp(alg, "CIPHERS", len))
101 *pflags |= ENGINE_METHOD_CIPHERS;
102 else if (!strncmp(alg, "DIGESTS", len))
103 *pflags |= ENGINE_METHOD_DIGESTS;
104 else
105 return 0;
106 return 1;
107 }
108
109
110int ENGINE_set_default_string(ENGINE *e, const char *list)
111 {
112 unsigned int flags = 0;
113 if (!CONF_parse_list(list, ',', 1, int_def_cb, &flags))
114 {
115 ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_STRING,
116 ENGINE_R_INVALID_STRING);
117 ERR_add_error_data(2, "str=",list);
118 return 0;
119 }
120 return ENGINE_set_default(e, flags);
121 }
122
123int ENGINE_register_complete(ENGINE *e)
124 {
125 ENGINE_register_ciphers(e);
126 ENGINE_register_digests(e);
127#ifndef OPENSSL_NO_RSA
128 ENGINE_register_RSA(e);
129#endif
130#ifndef OPENSSL_NO_DSA
131 ENGINE_register_DSA(e);
132#endif
133#ifndef OPENSSL_NO_DH
134 ENGINE_register_DH(e);
135#endif
136 ENGINE_register_RAND(e);
137 return 1;
138 }
139
140int ENGINE_register_all_complete(void)
141 {
142 ENGINE *e;
143
144 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) {
145 ENGINE_register_complete(e);
146 }
147 return 1;
148 }
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 @@
1/* crypto/engine/eng_init.c */
2/* ====================================================================
3 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * licensing@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include <openssl/crypto.h>
57#include "cryptlib.h"
58#include "eng_int.h"
59#include <openssl/engine.h>
60
61/* Initialise a engine type for use (or up its functional reference count
62 * if it's already in use). This version is only used internally. */
63int engine_unlocked_init(ENGINE *e)
64 {
65 int to_return = 1;
66
67 if((e->funct_ref == 0) && e->init)
68 /* This is the first functional reference and the engine
69 * requires initialisation so we do it now. */
70 to_return = e->init(e);
71 if(to_return)
72 {
73 /* OK, we return a functional reference which is also a
74 * structural reference. */
75 e->struct_ref++;
76 e->funct_ref++;
77 engine_ref_debug(e, 0, 1)
78 engine_ref_debug(e, 1, 1)
79 }
80 return to_return;
81 }
82
83/* Free a functional reference to a engine type. This version is only used
84 * internally. */
85int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers)
86 {
87 int to_return = 1;
88
89 /* Reduce the functional reference count here so if it's the terminating
90 * case, we can release the lock safely and call the finish() handler
91 * without risk of a race. We get a race if we leave the count until
92 * after and something else is calling "finish" at the same time -
93 * there's a chance that both threads will together take the count from
94 * 2 to 0 without either calling finish(). */
95 e->funct_ref--;
96 engine_ref_debug(e, 1, -1);
97 if((e->funct_ref == 0) && e->finish)
98 {
99 if(unlock_for_handlers)
100 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
101 to_return = e->finish(e);
102 if(unlock_for_handlers)
103 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
104 if(!to_return)
105 return 0;
106 }
107#ifdef REF_CHECK
108 if(e->funct_ref < 0)
109 {
110 fprintf(stderr,"ENGINE_finish, bad functional reference count\n");
111 abort();
112 }
113#endif
114 /* Release the structural reference too */
115 if(!engine_free_util(e, 0))
116 {
117 ENGINEerr(ENGINE_F_ENGINE_FINISH,ENGINE_R_FINISH_FAILED);
118 return 0;
119 }
120 return to_return;
121 }
122
123/* The API (locked) version of "init" */
124int ENGINE_init(ENGINE *e)
125 {
126 int ret;
127 if(e == NULL)
128 {
129 ENGINEerr(ENGINE_F_ENGINE_INIT,ERR_R_PASSED_NULL_PARAMETER);
130 return 0;
131 }
132 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
133 ret = engine_unlocked_init(e);
134 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
135 return ret;
136 }
137
138/* The API (locked) version of "finish" */
139int ENGINE_finish(ENGINE *e)
140 {
141 int to_return = 1;
142
143 if(e == NULL)
144 {
145 ENGINEerr(ENGINE_F_ENGINE_FINISH,ERR_R_PASSED_NULL_PARAMETER);
146 return 0;
147 }
148 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
149 to_return = engine_unlocked_finish(e, 1);
150 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
151 if(!to_return)
152 {
153 ENGINEerr(ENGINE_F_ENGINE_FINISH,ENGINE_R_FINISH_FAILED);
154 return 0;
155 }
156 return to_return;
157 }
158
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 @@
1/* crypto/engine/eng_int.h */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#ifndef HEADER_ENGINE_INT_H
60#define HEADER_ENGINE_INT_H
61
62/* Take public definitions from engine.h */
63#include <openssl/engine.h>
64
65#ifdef __cplusplus
66extern "C" {
67#endif
68
69/* If we compile with this symbol defined, then both reference counts in the
70 * ENGINE structure will be monitored with a line of output on stderr for each
71 * change. This prints the engine's pointer address (truncated to unsigned int),
72 * "struct" or "funct" to indicate the reference type, the before and after
73 * reference count, and the file:line-number pair. The "engine_ref_debug"
74 * statements must come *after* the change. */
75#ifdef ENGINE_REF_COUNT_DEBUG
76
77#define engine_ref_debug(e, isfunct, diff) \
78 fprintf(stderr, "engine: %08x %s from %d to %d (%s:%d)\n", \
79 (unsigned int)(e), (isfunct ? "funct" : "struct"), \
80 ((isfunct) ? ((e)->funct_ref - (diff)) : ((e)->struct_ref - (diff))), \
81 ((isfunct) ? (e)->funct_ref : (e)->struct_ref), \
82 (__FILE__), (__LINE__));
83
84#else
85
86#define engine_ref_debug(e, isfunct, diff)
87
88#endif
89
90/* Any code that will need cleanup operations should use these functions to
91 * register callbacks. ENGINE_cleanup() will call all registered callbacks in
92 * order. NB: both the "add" functions assume CRYPTO_LOCK_ENGINE to already be
93 * held (in "write" mode). */
94typedef void (ENGINE_CLEANUP_CB)(void);
95typedef struct st_engine_cleanup_item
96 {
97 ENGINE_CLEANUP_CB *cb;
98 } ENGINE_CLEANUP_ITEM;
99DECLARE_STACK_OF(ENGINE_CLEANUP_ITEM)
100void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb);
101void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb);
102
103/* We need stacks of ENGINEs for use in eng_table.c */
104DECLARE_STACK_OF(ENGINE)
105
106/* If this symbol is defined then engine_table_select(), the function that is
107 * used by RSA, DSA (etc) code to select registered ENGINEs, cache defaults and
108 * functional references (etc), will display debugging summaries to stderr. */
109/* #define ENGINE_TABLE_DEBUG */
110
111/* This represents an implementation table. Dependent code should instantiate it
112 * as a (ENGINE_TABLE *) pointer value set initially to NULL. */
113typedef struct st_engine_table ENGINE_TABLE;
114int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
115 ENGINE *e, const int *nids, int num_nids, int setdefault);
116void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e);
117void engine_table_cleanup(ENGINE_TABLE **table);
118#ifndef ENGINE_TABLE_DEBUG
119ENGINE *engine_table_select(ENGINE_TABLE **table, int nid);
120#else
121ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l);
122#define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__)
123#endif
124
125/* Internal versions of API functions that have control over locking. These are
126 * used between C files when functionality needs to be shared but the caller may
127 * already be controlling of the CRYPTO_LOCK_ENGINE lock. */
128int engine_unlocked_init(ENGINE *e);
129int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers);
130int engine_free_util(ENGINE *e, int locked);
131
132/* This function will reset all "set"able values in an ENGINE to NULL. This
133 * won't touch reference counts or ex_data, but is equivalent to calling all the
134 * ENGINE_set_***() functions with a NULL value. */
135void engine_set_all_null(ENGINE *e);
136
137/* NB: Bitwise OR-able values for the "flags" variable in ENGINE are now exposed
138 * in engine.h. */
139
140/* This is a structure for storing implementations of various crypto
141 * algorithms and functions. */
142struct engine_st
143 {
144 const char *id;
145 const char *name;
146 const RSA_METHOD *rsa_meth;
147 const DSA_METHOD *dsa_meth;
148 const DH_METHOD *dh_meth;
149 const RAND_METHOD *rand_meth;
150 /* Cipher handling is via this callback */
151 ENGINE_CIPHERS_PTR ciphers;
152 /* Digest handling is via this callback */
153 ENGINE_DIGESTS_PTR digests;
154
155
156 ENGINE_GEN_INT_FUNC_PTR destroy;
157
158 ENGINE_GEN_INT_FUNC_PTR init;
159 ENGINE_GEN_INT_FUNC_PTR finish;
160 ENGINE_CTRL_FUNC_PTR ctrl;
161 ENGINE_LOAD_KEY_PTR load_privkey;
162 ENGINE_LOAD_KEY_PTR load_pubkey;
163
164 const ENGINE_CMD_DEFN *cmd_defns;
165 int flags;
166 /* reference count on the structure itself */
167 int struct_ref;
168 /* reference count on usability of the engine type. NB: This
169 * controls the loading and initialisation of any functionlity
170 * required by this engine, whereas the previous count is
171 * simply to cope with (de)allocation of this structure. Hence,
172 * running_ref <= struct_ref at all times. */
173 int funct_ref;
174 /* A place to store per-ENGINE data */
175 CRYPTO_EX_DATA ex_data;
176 /* Used to maintain the linked-list of engines. */
177 struct engine_st *prev;
178 struct engine_st *next;
179 };
180
181#ifdef __cplusplus
182}
183#endif
184
185#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 @@
1/* crypto/engine/eng_lib.c */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <openssl/crypto.h>
60#include "cryptlib.h"
61#include "eng_int.h"
62#include <openssl/rand.h> /* FIXME: This shouldn't be needed */
63#include <openssl/engine.h>
64
65/* The "new"/"free" stuff first */
66
67ENGINE *ENGINE_new(void)
68 {
69 ENGINE *ret;
70
71 ret = (ENGINE *)OPENSSL_malloc(sizeof(ENGINE));
72 if(ret == NULL)
73 {
74 ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE);
75 return NULL;
76 }
77 memset(ret, 0, sizeof(ENGINE));
78 ret->struct_ref = 1;
79 engine_ref_debug(ret, 0, 1)
80 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data);
81 return ret;
82 }
83
84/* Placed here (close proximity to ENGINE_new) so that modifications to the
85 * elements of the ENGINE structure are more likely to be caught and changed
86 * here. */
87void engine_set_all_null(ENGINE *e)
88 {
89 e->id = NULL;
90 e->name = NULL;
91 e->rsa_meth = NULL;
92 e->dsa_meth = NULL;
93 e->dh_meth = NULL;
94 e->rand_meth = NULL;
95 e->ciphers = NULL;
96 e->digests = NULL;
97 e->destroy = NULL;
98 e->init = NULL;
99 e->finish = NULL;
100 e->ctrl = NULL;
101 e->load_privkey = NULL;
102 e->load_pubkey = NULL;
103 e->cmd_defns = NULL;
104 e->flags = 0;
105 }
106
107int engine_free_util(ENGINE *e, int locked)
108 {
109 int i;
110
111 if(e == NULL)
112 {
113 ENGINEerr(ENGINE_F_ENGINE_FREE,
114 ERR_R_PASSED_NULL_PARAMETER);
115 return 0;
116 }
117 if(locked)
118 i = CRYPTO_add(&e->struct_ref,-1,CRYPTO_LOCK_ENGINE);
119 else
120 i = --e->struct_ref;
121 engine_ref_debug(e, 0, -1)
122 if (i > 0) return 1;
123#ifdef REF_CHECK
124 if (i < 0)
125 {
126 fprintf(stderr,"ENGINE_free, bad structural reference count\n");
127 abort();
128 }
129#endif
130 /* Give the ENGINE a chance to do any structural cleanup corresponding
131 * to allocation it did in its constructor (eg. unload error strings) */
132 if(e->destroy)
133 e->destroy(e);
134 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ENGINE, e, &e->ex_data);
135 OPENSSL_free(e);
136 return 1;
137 }
138
139int ENGINE_free(ENGINE *e)
140 {
141 return engine_free_util(e, 1);
142 }
143
144/* Cleanup stuff */
145
146/* ENGINE_cleanup() is coded such that anything that does work that will need
147 * cleanup can register a "cleanup" callback here. That way we don't get linker
148 * bloat by referring to all *possible* cleanups, but any linker bloat into code
149 * "X" will cause X's cleanup function to end up here. */
150static STACK_OF(ENGINE_CLEANUP_ITEM) *cleanup_stack = NULL;
151static int int_cleanup_check(int create)
152 {
153 if(cleanup_stack) return 1;
154 if(!create) return 0;
155 cleanup_stack = sk_ENGINE_CLEANUP_ITEM_new_null();
156 return (cleanup_stack ? 1 : 0);
157 }
158static ENGINE_CLEANUP_ITEM *int_cleanup_item(ENGINE_CLEANUP_CB *cb)
159 {
160 ENGINE_CLEANUP_ITEM *item = OPENSSL_malloc(sizeof(
161 ENGINE_CLEANUP_ITEM));
162 if(!item) return NULL;
163 item->cb = cb;
164 return item;
165 }
166void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb)
167 {
168 ENGINE_CLEANUP_ITEM *item;
169 if(!int_cleanup_check(1)) return;
170 item = int_cleanup_item(cb);
171 if(item)
172 sk_ENGINE_CLEANUP_ITEM_insert(cleanup_stack, item, 0);
173 }
174void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb)
175 {
176 ENGINE_CLEANUP_ITEM *item;
177 if(!int_cleanup_check(1)) return;
178 item = int_cleanup_item(cb);
179 if(item)
180 sk_ENGINE_CLEANUP_ITEM_push(cleanup_stack, item);
181 }
182/* The API function that performs all cleanup */
183static void engine_cleanup_cb_free(ENGINE_CLEANUP_ITEM *item)
184 {
185 (*(item->cb))();
186 OPENSSL_free(item);
187 }
188void ENGINE_cleanup(void)
189 {
190 if(int_cleanup_check(0))
191 {
192 sk_ENGINE_CLEANUP_ITEM_pop_free(cleanup_stack,
193 engine_cleanup_cb_free);
194 cleanup_stack = NULL;
195 }
196 /* FIXME: This should be handled (somehow) through RAND, eg. by it
197 * registering a cleanup callback. */
198 RAND_set_rand_method(NULL);
199 }
200
201/* Now the "ex_data" support */
202
203int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
204 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
205 {
206 return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ENGINE, argl, argp,
207 new_func, dup_func, free_func);
208 }
209
210int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg)
211 {
212 return(CRYPTO_set_ex_data(&e->ex_data, idx, arg));
213 }
214
215void *ENGINE_get_ex_data(const ENGINE *e, int idx)
216 {
217 return(CRYPTO_get_ex_data(&e->ex_data, idx));
218 }
219
220/* Functions to get/set an ENGINE's elements - mainly to avoid exposing the
221 * ENGINE structure itself. */
222
223int ENGINE_set_id(ENGINE *e, const char *id)
224 {
225 if(id == NULL)
226 {
227 ENGINEerr(ENGINE_F_ENGINE_SET_ID,
228 ERR_R_PASSED_NULL_PARAMETER);
229 return 0;
230 }
231 e->id = id;
232 return 1;
233 }
234
235int ENGINE_set_name(ENGINE *e, const char *name)
236 {
237 if(name == NULL)
238 {
239 ENGINEerr(ENGINE_F_ENGINE_SET_NAME,
240 ERR_R_PASSED_NULL_PARAMETER);
241 return 0;
242 }
243 e->name = name;
244 return 1;
245 }
246
247int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f)
248 {
249 e->destroy = destroy_f;
250 return 1;
251 }
252
253int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f)
254 {
255 e->init = init_f;
256 return 1;
257 }
258
259int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f)
260 {
261 e->finish = finish_f;
262 return 1;
263 }
264
265int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f)
266 {
267 e->ctrl = ctrl_f;
268 return 1;
269 }
270
271int ENGINE_set_flags(ENGINE *e, int flags)
272 {
273 e->flags = flags;
274 return 1;
275 }
276
277int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns)
278 {
279 e->cmd_defns = defns;
280 return 1;
281 }
282
283const char *ENGINE_get_id(const ENGINE *e)
284 {
285 return e->id;
286 }
287
288const char *ENGINE_get_name(const ENGINE *e)
289 {
290 return e->name;
291 }
292
293ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e)
294 {
295 return e->destroy;
296 }
297
298ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e)
299 {
300 return e->init;
301 }
302
303ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e)
304 {
305 return e->finish;
306 }
307
308ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e)
309 {
310 return e->ctrl;
311 }
312
313int ENGINE_get_flags(const ENGINE *e)
314 {
315 return e->flags;
316 }
317
318const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e)
319 {
320 return e->cmd_defns;
321 }
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 @@
1/* crypto/engine/eng_list.c */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <openssl/crypto.h>
60#include "cryptlib.h"
61#include "eng_int.h"
62#include <openssl/engine.h>
63
64/* The linked-list of pointers to engine types. engine_list_head
65 * incorporates an implicit structural reference but engine_list_tail
66 * does not - the latter is a computational niceity and only points
67 * to something that is already pointed to by its predecessor in the
68 * list (or engine_list_head itself). In the same way, the use of the
69 * "prev" pointer in each ENGINE is to save excessive list iteration,
70 * it doesn't correspond to an extra structural reference. Hence,
71 * engine_list_head, and each non-null "next" pointer account for
72 * the list itself assuming exactly 1 structural reference on each
73 * list member. */
74static ENGINE *engine_list_head = NULL;
75static ENGINE *engine_list_tail = NULL;
76
77/* This cleanup function is only needed internally. If it should be called, we
78 * register it with the "ENGINE_cleanup()" stack to be called during cleanup. */
79
80static void engine_list_cleanup(void)
81 {
82 ENGINE *iterator = engine_list_head;
83
84 while(iterator != NULL)
85 {
86 ENGINE_remove(iterator);
87 iterator = engine_list_head;
88 }
89 return;
90 }
91
92/* These static functions starting with a lower case "engine_" always
93 * take place when CRYPTO_LOCK_ENGINE has been locked up. */
94static int engine_list_add(ENGINE *e)
95 {
96 int conflict = 0;
97 ENGINE *iterator = NULL;
98
99 if(e == NULL)
100 {
101 ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
102 ERR_R_PASSED_NULL_PARAMETER);
103 return 0;
104 }
105 iterator = engine_list_head;
106 while(iterator && !conflict)
107 {
108 conflict = (strcmp(iterator->id, e->id) == 0);
109 iterator = iterator->next;
110 }
111 if(conflict)
112 {
113 ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
114 ENGINE_R_CONFLICTING_ENGINE_ID);
115 return 0;
116 }
117 if(engine_list_head == NULL)
118 {
119 /* We are adding to an empty list. */
120 if(engine_list_tail)
121 {
122 ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
123 ENGINE_R_INTERNAL_LIST_ERROR);
124 return 0;
125 }
126 engine_list_head = e;
127 e->prev = NULL;
128 /* The first time the list allocates, we should register the
129 * cleanup. */
130 engine_cleanup_add_last(engine_list_cleanup);
131 }
132 else
133 {
134 /* We are adding to the tail of an existing list. */
135 if((engine_list_tail == NULL) ||
136 (engine_list_tail->next != NULL))
137 {
138 ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
139 ENGINE_R_INTERNAL_LIST_ERROR);
140 return 0;
141 }
142 engine_list_tail->next = e;
143 e->prev = engine_list_tail;
144 }
145 /* Having the engine in the list assumes a structural
146 * reference. */
147 e->struct_ref++;
148 engine_ref_debug(e, 0, 1)
149 /* However it came to be, e is the last item in the list. */
150 engine_list_tail = e;
151 e->next = NULL;
152 return 1;
153 }
154
155static int engine_list_remove(ENGINE *e)
156 {
157 ENGINE *iterator;
158
159 if(e == NULL)
160 {
161 ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
162 ERR_R_PASSED_NULL_PARAMETER);
163 return 0;
164 }
165 /* We need to check that e is in our linked list! */
166 iterator = engine_list_head;
167 while(iterator && (iterator != e))
168 iterator = iterator->next;
169 if(iterator == NULL)
170 {
171 ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
172 ENGINE_R_ENGINE_IS_NOT_IN_LIST);
173 return 0;
174 }
175 /* un-link e from the chain. */
176 if(e->next)
177 e->next->prev = e->prev;
178 if(e->prev)
179 e->prev->next = e->next;
180 /* Correct our head/tail if necessary. */
181 if(engine_list_head == e)
182 engine_list_head = e->next;
183 if(engine_list_tail == e)
184 engine_list_tail = e->prev;
185 engine_free_util(e, 0);
186 return 1;
187 }
188
189/* Get the first/last "ENGINE" type available. */
190ENGINE *ENGINE_get_first(void)
191 {
192 ENGINE *ret;
193
194 CRYPTO_r_lock(CRYPTO_LOCK_ENGINE);
195 ret = engine_list_head;
196 if(ret)
197 {
198 ret->struct_ref++;
199 engine_ref_debug(ret, 0, 1)
200 }
201 CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE);
202 return ret;
203 }
204
205ENGINE *ENGINE_get_last(void)
206 {
207 ENGINE *ret;
208
209 CRYPTO_r_lock(CRYPTO_LOCK_ENGINE);
210 ret = engine_list_tail;
211 if(ret)
212 {
213 ret->struct_ref++;
214 engine_ref_debug(ret, 0, 1)
215 }
216 CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE);
217 return ret;
218 }
219
220/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
221ENGINE *ENGINE_get_next(ENGINE *e)
222 {
223 ENGINE *ret = NULL;
224 if(e == NULL)
225 {
226 ENGINEerr(ENGINE_F_ENGINE_GET_NEXT,
227 ERR_R_PASSED_NULL_PARAMETER);
228 return 0;
229 }
230 CRYPTO_r_lock(CRYPTO_LOCK_ENGINE);
231 ret = e->next;
232 if(ret)
233 {
234 /* Return a valid structural refernce to the next ENGINE */
235 ret->struct_ref++;
236 engine_ref_debug(ret, 0, 1)
237 }
238 CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE);
239 /* Release the structural reference to the previous ENGINE */
240 ENGINE_free(e);
241 return ret;
242 }
243
244ENGINE *ENGINE_get_prev(ENGINE *e)
245 {
246 ENGINE *ret = NULL;
247 if(e == NULL)
248 {
249 ENGINEerr(ENGINE_F_ENGINE_GET_PREV,
250 ERR_R_PASSED_NULL_PARAMETER);
251 return 0;
252 }
253 CRYPTO_r_lock(CRYPTO_LOCK_ENGINE);
254 ret = e->prev;
255 if(ret)
256 {
257 /* Return a valid structural reference to the next ENGINE */
258 ret->struct_ref++;
259 engine_ref_debug(ret, 0, 1)
260 }
261 CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE);
262 /* Release the structural reference to the previous ENGINE */
263 ENGINE_free(e);
264 return ret;
265 }
266
267/* Add another "ENGINE" type into the list. */
268int ENGINE_add(ENGINE *e)
269 {
270 int to_return = 1;
271 if(e == NULL)
272 {
273 ENGINEerr(ENGINE_F_ENGINE_ADD,
274 ERR_R_PASSED_NULL_PARAMETER);
275 return 0;
276 }
277 if((e->id == NULL) || (e->name == NULL))
278 {
279 ENGINEerr(ENGINE_F_ENGINE_ADD,
280 ENGINE_R_ID_OR_NAME_MISSING);
281 }
282 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
283 if(!engine_list_add(e))
284 {
285 ENGINEerr(ENGINE_F_ENGINE_ADD,
286 ENGINE_R_INTERNAL_LIST_ERROR);
287 to_return = 0;
288 }
289 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
290 return to_return;
291 }
292
293/* Remove an existing "ENGINE" type from the array. */
294int ENGINE_remove(ENGINE *e)
295 {
296 int to_return = 1;
297 if(e == NULL)
298 {
299 ENGINEerr(ENGINE_F_ENGINE_REMOVE,
300 ERR_R_PASSED_NULL_PARAMETER);
301 return 0;
302 }
303 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
304 if(!engine_list_remove(e))
305 {
306 ENGINEerr(ENGINE_F_ENGINE_REMOVE,
307 ENGINE_R_INTERNAL_LIST_ERROR);
308 to_return = 0;
309 }
310 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
311 return to_return;
312 }
313
314static void engine_cpy(ENGINE *dest, const ENGINE *src)
315 {
316 dest->id = src->id;
317 dest->name = src->name;
318#ifndef OPENSSL_NO_RSA
319 dest->rsa_meth = src->rsa_meth;
320#endif
321#ifndef OPENSSL_NO_DSA
322 dest->dsa_meth = src->dsa_meth;
323#endif
324#ifndef OPENSSL_NO_DH
325 dest->dh_meth = src->dh_meth;
326#endif
327 dest->rand_meth = src->rand_meth;
328 dest->ciphers = src->ciphers;
329 dest->digests = src->digests;
330 dest->destroy = src->destroy;
331 dest->init = src->init;
332 dest->finish = src->finish;
333 dest->ctrl = src->ctrl;
334 dest->load_privkey = src->load_privkey;
335 dest->load_pubkey = src->load_pubkey;
336 dest->cmd_defns = src->cmd_defns;
337 dest->flags = src->flags;
338 }
339
340ENGINE *ENGINE_by_id(const char *id)
341 {
342 ENGINE *iterator;
343 if(id == NULL)
344 {
345 ENGINEerr(ENGINE_F_ENGINE_BY_ID,
346 ERR_R_PASSED_NULL_PARAMETER);
347 return NULL;
348 }
349 CRYPTO_r_lock(CRYPTO_LOCK_ENGINE);
350 iterator = engine_list_head;
351 while(iterator && (strcmp(id, iterator->id) != 0))
352 iterator = iterator->next;
353 if(iterator)
354 {
355 /* We need to return a structural reference. If this is an
356 * ENGINE type that returns copies, make a duplicate - otherwise
357 * increment the existing ENGINE's reference count. */
358 if(iterator->flags & ENGINE_FLAGS_BY_ID_COPY)
359 {
360 ENGINE *cp = ENGINE_new();
361 if(!cp)
362 iterator = NULL;
363 else
364 {
365 engine_cpy(cp, iterator);
366 iterator = cp;
367 }
368 }
369 else
370 {
371 iterator->struct_ref++;
372 engine_ref_debug(iterator, 0, 1)
373 }
374 }
375 CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE);
376 if(iterator == NULL)
377 {
378 ENGINEerr(ENGINE_F_ENGINE_BY_ID,
379 ENGINE_R_NO_SUCH_ENGINE);
380 ERR_add_error_data(2, "id=", id);
381 }
382 return iterator;
383 }
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 @@
1/* crypto/engine/eng_openssl.c */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59
60#include <stdio.h>
61#include <openssl/crypto.h>
62#include "cryptlib.h"
63#include <openssl/engine.h>
64#include <openssl/dso.h>
65#include <openssl/pem.h>
66
67/* This testing gunk is implemented (and explained) lower down. It also assumes
68 * the application explicitly calls "ENGINE_load_openssl()" because this is no
69 * longer automatic in ENGINE_load_builtin_engines(). */
70#define TEST_ENG_OPENSSL_RC4
71#define TEST_ENG_OPENSSL_PKEY
72/* #define TEST_ENG_OPENSSL_RC4_OTHERS */
73#define TEST_ENG_OPENSSL_RC4_P_INIT
74/* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */
75#define TEST_ENG_OPENSSL_SHA
76/* #define TEST_ENG_OPENSSL_SHA_OTHERS */
77/* #define TEST_ENG_OPENSSL_SHA_P_INIT */
78/* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */
79/* #define TEST_ENG_OPENSSL_SHA_P_FINAL */
80
81#ifdef TEST_ENG_OPENSSL_RC4
82static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
83 const int **nids, int nid);
84#endif
85#ifdef TEST_ENG_OPENSSL_SHA
86static int openssl_digests(ENGINE *e, const EVP_MD **digest,
87 const int **nids, int nid);
88#endif
89
90#ifdef TEST_ENG_OPENSSL_PKEY
91static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
92 UI_METHOD *ui_method, void *callback_data);
93#endif
94
95/* The constants used when creating the ENGINE */
96static const char *engine_openssl_id = "openssl";
97static const char *engine_openssl_name = "Software engine support";
98
99/* This internal function is used by ENGINE_openssl() and possibly by the
100 * "dynamic" ENGINE support too */
101static int bind_helper(ENGINE *e)
102 {
103 if(!ENGINE_set_id(e, engine_openssl_id)
104 || !ENGINE_set_name(e, engine_openssl_name)
105#ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS
106#ifndef OPENSSL_NO_RSA
107 || !ENGINE_set_RSA(e, RSA_get_default_method())
108#endif
109#ifndef OPENSSL_NO_DSA
110 || !ENGINE_set_DSA(e, DSA_get_default_method())
111#endif
112#ifndef OPENSSL_NO_DH
113 || !ENGINE_set_DH(e, DH_get_default_method())
114#endif
115 || !ENGINE_set_RAND(e, RAND_SSLeay())
116#ifdef TEST_ENG_OPENSSL_RC4
117 || !ENGINE_set_ciphers(e, openssl_ciphers)
118#endif
119#ifdef TEST_ENG_OPENSSL_SHA
120 || !ENGINE_set_digests(e, openssl_digests)
121#endif
122#endif
123#ifdef TEST_ENG_OPENSSL_PKEY
124 || !ENGINE_set_load_privkey_function(e, openssl_load_privkey)
125#endif
126 )
127 return 0;
128 /* If we add errors to this ENGINE, ensure the error handling is setup here */
129 /* openssl_load_error_strings(); */
130 return 1;
131 }
132
133static ENGINE *engine_openssl(void)
134 {
135 ENGINE *ret = ENGINE_new();
136 if(!ret)
137 return NULL;
138 if(!bind_helper(ret))
139 {
140 ENGINE_free(ret);
141 return NULL;
142 }
143 return ret;
144 }
145
146void ENGINE_load_openssl(void)
147 {
148 ENGINE *toadd = engine_openssl();
149 if(!toadd) return;
150 ENGINE_add(toadd);
151 /* If the "add" worked, it gets a structural reference. So either way,
152 * we release our just-created reference. */
153 ENGINE_free(toadd);
154 ERR_clear_error();
155 }
156
157/* This stuff is needed if this ENGINE is being compiled into a self-contained
158 * shared-library. */
159#ifdef ENGINE_DYNAMIC_SUPPORT
160static int bind_fn(ENGINE *e, const char *id)
161 {
162 if(id && (strcmp(id, engine_openssl_id) != 0))
163 return 0;
164 if(!bind_helper(e))
165 return 0;
166 return 1;
167 }
168IMPLEMENT_DYNAMIC_CHECK_FN()
169IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
170#endif /* ENGINE_DYNAMIC_SUPPORT */
171
172#ifdef TEST_ENG_OPENSSL_RC4
173/* This section of code compiles an "alternative implementation" of two modes of
174 * RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4"
175 * should under normal circumstances go via this support rather than the default
176 * EVP support. There are other symbols to tweak the testing;
177 * TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time
178 * we're asked for a cipher we don't support (should not happen).
179 * TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time
180 * the "init_key" handler is called.
181 * TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler.
182 */
183#include <openssl/evp.h>
184#include <openssl/rc4.h>
185#define TEST_RC4_KEY_SIZE 16
186static int test_cipher_nids[] = {NID_rc4,NID_rc4_40};
187static int test_cipher_nids_number = 2;
188typedef struct {
189 unsigned char key[TEST_RC4_KEY_SIZE];
190 RC4_KEY ks;
191 } TEST_RC4_KEY;
192#define test(ctx) ((TEST_RC4_KEY *)(ctx)->cipher_data)
193static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
194 const unsigned char *iv, int enc)
195 {
196#ifdef TEST_ENG_OPENSSL_RC4_P_INIT
197 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n");
198#endif
199 memcpy(&test(ctx)->key[0],key,EVP_CIPHER_CTX_key_length(ctx));
200 RC4_set_key(&test(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),
201 test(ctx)->key);
202 return 1;
203 }
204static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
205 const unsigned char *in, unsigned int inl)
206 {
207#ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
208 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
209#endif
210 RC4(&test(ctx)->ks,inl,in,out);
211 return 1;
212 }
213static const EVP_CIPHER test_r4_cipher=
214 {
215 NID_rc4,
216 1,TEST_RC4_KEY_SIZE,0,
217 EVP_CIPH_VARIABLE_LENGTH,
218 test_rc4_init_key,
219 test_rc4_cipher,
220 NULL,
221 sizeof(TEST_RC4_KEY),
222 NULL,
223 NULL,
224 NULL
225 };
226static const EVP_CIPHER test_r4_40_cipher=
227 {
228 NID_rc4_40,
229 1,5 /* 40 bit */,0,
230 EVP_CIPH_VARIABLE_LENGTH,
231 test_rc4_init_key,
232 test_rc4_cipher,
233 NULL,
234 sizeof(TEST_RC4_KEY),
235 NULL,
236 NULL,
237 NULL
238 };
239static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
240 const int **nids, int nid)
241 {
242 if(!cipher)
243 {
244 /* We are returning a list of supported nids */
245 *nids = test_cipher_nids;
246 return test_cipher_nids_number;
247 }
248 /* We are being asked for a specific cipher */
249 if(nid == NID_rc4)
250 *cipher = &test_r4_cipher;
251 else if(nid == NID_rc4_40)
252 *cipher = &test_r4_40_cipher;
253 else
254 {
255#ifdef TEST_ENG_OPENSSL_RC4_OTHERS
256 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) returning NULL for "
257 "nid %d\n", nid);
258#endif
259 *cipher = NULL;
260 return 0;
261 }
262 return 1;
263 }
264#endif
265
266#ifdef TEST_ENG_OPENSSL_SHA
267/* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */
268#include <openssl/evp.h>
269#include <openssl/sha.h>
270static int test_digest_nids[] = {NID_sha1};
271static int test_digest_nids_number = 1;
272static int test_sha1_init(EVP_MD_CTX *ctx)
273 {
274#ifdef TEST_ENG_OPENSSL_SHA_P_INIT
275 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n");
276#endif
277 return SHA1_Init(ctx->md_data);
278 }
279static int test_sha1_update(EVP_MD_CTX *ctx,const void *data,unsigned long count)
280 {
281#ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE
282 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n");
283#endif
284 return SHA1_Update(ctx->md_data,data,count);
285 }
286static int test_sha1_final(EVP_MD_CTX *ctx,unsigned char *md)
287 {
288#ifdef TEST_ENG_OPENSSL_SHA_P_FINAL
289 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n");
290#endif
291 return SHA1_Final(md,ctx->md_data);
292 }
293static const EVP_MD test_sha_md=
294 {
295 NID_sha1,
296 NID_sha1WithRSAEncryption,
297 SHA_DIGEST_LENGTH,
298 0,
299 test_sha1_init,
300 test_sha1_update,
301 test_sha1_final,
302 NULL,
303 NULL,
304 EVP_PKEY_RSA_method,
305 SHA_CBLOCK,
306 sizeof(EVP_MD *)+sizeof(SHA_CTX),
307 };
308static int openssl_digests(ENGINE *e, const EVP_MD **digest,
309 const int **nids, int nid)
310 {
311 if(!digest)
312 {
313 /* We are returning a list of supported nids */
314 *nids = test_digest_nids;
315 return test_digest_nids_number;
316 }
317 /* We are being asked for a specific digest */
318 if(nid == NID_sha1)
319 *digest = &test_sha_md;
320 else
321 {
322#ifdef TEST_ENG_OPENSSL_SHA_OTHERS
323 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for "
324 "nid %d\n", nid);
325#endif
326 *digest = NULL;
327 return 0;
328 }
329 return 1;
330 }
331#endif
332
333#ifdef TEST_ENG_OPENSSL_PKEY
334static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
335 UI_METHOD *ui_method, void *callback_data)
336 {
337 BIO *in;
338 EVP_PKEY *key;
339 fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n", key_id);
340 in = BIO_new_file(key_id, "r");
341 if (!in)
342 return NULL;
343 key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL);
344 BIO_free(in);
345 return key;
346 }
347#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 @@
1/* crypto/engine/eng_pkey.c */
2/* ====================================================================
3 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * licensing@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include <openssl/crypto.h>
57#include "cryptlib.h"
58#include "eng_int.h"
59#include <openssl/engine.h>
60
61/* Basic get/set stuff */
62
63int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f)
64 {
65 e->load_privkey = loadpriv_f;
66 return 1;
67 }
68
69int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f)
70 {
71 e->load_pubkey = loadpub_f;
72 return 1;
73 }
74
75ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e)
76 {
77 return e->load_privkey;
78 }
79
80ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e)
81 {
82 return e->load_pubkey;
83 }
84
85/* API functions to load public/private keys */
86
87EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
88 UI_METHOD *ui_method, void *callback_data)
89 {
90 EVP_PKEY *pkey;
91
92 if(e == NULL)
93 {
94 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
95 ERR_R_PASSED_NULL_PARAMETER);
96 return 0;
97 }
98 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
99 if(e->funct_ref == 0)
100 {
101 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
102 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
103 ENGINE_R_NOT_INITIALISED);
104 return 0;
105 }
106 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
107 if (!e->load_privkey)
108 {
109 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
110 ENGINE_R_NO_LOAD_FUNCTION);
111 return 0;
112 }
113 pkey = e->load_privkey(e, key_id, ui_method, callback_data);
114 if (!pkey)
115 {
116 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
117 ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
118 return 0;
119 }
120 return pkey;
121 }
122
123EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
124 UI_METHOD *ui_method, void *callback_data)
125 {
126 EVP_PKEY *pkey;
127
128 if(e == NULL)
129 {
130 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
131 ERR_R_PASSED_NULL_PARAMETER);
132 return 0;
133 }
134 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
135 if(e->funct_ref == 0)
136 {
137 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
138 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
139 ENGINE_R_NOT_INITIALISED);
140 return 0;
141 }
142 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
143 if (!e->load_pubkey)
144 {
145 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
146 ENGINE_R_NO_LOAD_FUNCTION);
147 return 0;
148 }
149 pkey = e->load_pubkey(e, key_id, ui_method, callback_data);
150 if (!pkey)
151 {
152 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
153 ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
154 return 0;
155 }
156 return pkey;
157 }
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 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h"
58
59/* This is the type of item in the 'implementation' table. Each 'nid' hashes to
60 * a (potentially NULL) ENGINE_PILE structure which contains a stack of ENGINE*
61 * pointers. These pointers aren't references, because they're inserted and
62 * removed during ENGINE creation and ENGINE destruction. They point to ENGINEs
63 * that *exist* (ie. have a structural reference count greater than zero) rather
64 * than ENGINEs that are *functional*. Each pointer in those stacks are to
65 * ENGINEs that implements the algorithm corresponding to each 'nid'. */
66
67/* The type of the items in the table */
68typedef struct st_engine_pile
69 {
70 /* The 'nid' of the algorithm/mode this ENGINE_PILE structure represents
71 * */
72 int nid;
73 /* A stack of ENGINE pointers for ENGINEs that support this
74 * algorithm/mode. In the event that 'funct' is NULL, the first entry in
75 * this stack that initialises will be set as 'funct' and assumed as the
76 * default for operations of this type. */
77 STACK_OF(ENGINE) *sk;
78 /* The default ENGINE to perform this algorithm/mode. */
79 ENGINE *funct;
80 /* This value optimises engine_table_select(). If it is called it sets
81 * this value to 1. Any changes to this ENGINE_PILE resets it to zero.
82 * As such, no ENGINE_init() thrashing is done unless ENGINEs
83 * continually register (and/or unregister). */
84 int uptodate;
85 } ENGINE_PILE;
86
87/* The type of the hash table of ENGINE_PILE structures such that each are
88 * unique and keyed by the 'nid' value. */
89struct st_engine_table
90 {
91 LHASH piles;
92 }; /* ENGINE_TABLE */
93
94/* This value stores global options controlling behaviour of (mostly) the
95 * engine_table_select() function. It's a bitmask of flag values of the form
96 * ENGINE_TABLE_FLAG_*** (as defined in engine.h) and is controlled by the
97 * ENGINE_[get|set]_table_flags() function. */
98static unsigned int table_flags = 0;
99
100/* API function manipulating 'table_flags' */
101unsigned int ENGINE_get_table_flags(void)
102 {
103 return table_flags;
104 }
105void ENGINE_set_table_flags(unsigned int flags)
106 {
107 table_flags = flags;
108 }
109
110/* Internal functions for the "piles" hash table */
111static unsigned long engine_pile_hash(const ENGINE_PILE *c)
112 {
113 return c->nid;
114 }
115static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b)
116 {
117 return a->nid - b->nid;
118 }
119static IMPLEMENT_LHASH_HASH_FN(engine_pile_hash, const ENGINE_PILE *)
120static IMPLEMENT_LHASH_COMP_FN(engine_pile_cmp, const ENGINE_PILE *)
121static int int_table_check(ENGINE_TABLE **t, int create)
122 {
123 LHASH *lh;
124 if(*t)
125 return 1;
126 if(!create)
127 return 0;
128 if((lh = lh_new(LHASH_HASH_FN(engine_pile_hash),
129 LHASH_COMP_FN(engine_pile_cmp))) == NULL)
130 return 0;
131 *t = (ENGINE_TABLE *)lh;
132 return 1;
133 }
134
135/* Privately exposed (via eng_int.h) functions for adding and/or removing
136 * ENGINEs from the implementation table */
137int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
138 ENGINE *e, const int *nids, int num_nids, int setdefault)
139 {
140 int ret = 0, added = 0;
141 ENGINE_PILE tmplate, *fnd;
142 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
143 if(!(*table))
144 added = 1;
145 if(!int_table_check(table, 1))
146 goto end;
147 if(added)
148 /* The cleanup callback needs to be added */
149 engine_cleanup_add_first(cleanup);
150 while(num_nids--)
151 {
152 tmplate.nid = *nids;
153 fnd = lh_retrieve(&(*table)->piles, &tmplate);
154 if(!fnd)
155 {
156 fnd = OPENSSL_malloc(sizeof(ENGINE_PILE));
157 if(!fnd)
158 goto end;
159 fnd->uptodate = 1;
160 fnd->nid = *nids;
161 fnd->sk = sk_ENGINE_new_null();
162 if(!fnd->sk)
163 {
164 OPENSSL_free(fnd);
165 goto end;
166 }
167 fnd->funct= NULL;
168 lh_insert(&(*table)->piles, fnd);
169 }
170 /* A registration shouldn't add duplciate entries */
171 sk_ENGINE_delete_ptr(fnd->sk, e);
172 /* if 'setdefault', this ENGINE goes to the head of the list */
173 if(!sk_ENGINE_push(fnd->sk, e))
174 goto end;
175 /* "touch" this ENGINE_PILE */
176 fnd->uptodate = 0;
177 if(setdefault)
178 {
179 if(!engine_unlocked_init(e))
180 {
181 ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER,
182 ENGINE_R_INIT_FAILED);
183 goto end;
184 }
185 if(fnd->funct)
186 engine_unlocked_finish(fnd->funct, 0);
187 fnd->funct = e;
188 }
189 nids++;
190 }
191 ret = 1;
192end:
193 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
194 return ret;
195 }
196static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e)
197 {
198 int n;
199 /* Iterate the 'c->sk' stack removing any occurance of 'e' */
200 while((n = sk_ENGINE_find(pile->sk, e)) >= 0)
201 {
202 sk_ENGINE_delete(pile->sk, n);
203 /* "touch" this ENGINE_CIPHER */
204 pile->uptodate = 0;
205 }
206 if(pile->funct == e)
207 {
208 engine_unlocked_finish(e, 0);
209 pile->funct = NULL;
210 }
211 }
212static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb,ENGINE_PILE *,ENGINE *)
213void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e)
214 {
215 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
216 if(int_table_check(table, 0))
217 lh_doall_arg(&(*table)->piles,
218 LHASH_DOALL_ARG_FN(int_unregister_cb), e);
219 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
220 }
221
222static void int_cleanup_cb(ENGINE_PILE *p)
223 {
224 sk_ENGINE_free(p->sk);
225 if(p->funct)
226 engine_unlocked_finish(p->funct, 0);
227 OPENSSL_free(p);
228 }
229static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb,ENGINE_PILE *)
230void engine_table_cleanup(ENGINE_TABLE **table)
231 {
232 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
233 if(*table)
234 {
235 lh_doall(&(*table)->piles, LHASH_DOALL_FN(int_cleanup_cb));
236 lh_free(&(*table)->piles);
237 *table = NULL;
238 }
239 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
240 }
241
242/* Exposed API function to get a functional reference from the implementation
243 * table (ie. try to get a functional reference from the tabled structural
244 * references) for a given cipher 'nid' */
245#ifndef ENGINE_TABLE_DEBUG
246ENGINE *engine_table_select(ENGINE_TABLE **table, int nid)
247#else
248ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l)
249#endif
250 {
251 ENGINE *ret = NULL;
252 ENGINE_PILE tmplate, *fnd=NULL;
253 int initres, loop = 0;
254
255 /* If 'engine_ciphers' is NULL, then it's absolutely *sure* that no
256 * ENGINEs have registered any implementations! */
257 if(!(*table))
258 {
259#ifdef ENGINE_TABLE_DEBUG
260 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no "
261 "registered for anything!\n", f, l, nid);
262#endif
263 return NULL;
264 }
265 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
266 /* Check again inside the lock otherwise we could race against cleanup
267 * operations. But don't worry about a fprintf(stderr). */
268 if(!int_table_check(table, 0))
269 goto end;
270 tmplate.nid = nid;
271 fnd = lh_retrieve(&(*table)->piles, &tmplate);
272 if(!fnd)
273 goto end;
274 if(fnd->funct && engine_unlocked_init(fnd->funct))
275 {
276#ifdef ENGINE_TABLE_DEBUG
277 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
278 "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id);
279#endif
280 ret = fnd->funct;
281 goto end;
282 }
283 if(fnd->uptodate)
284 {
285 ret = fnd->funct;
286 goto end;
287 }
288trynext:
289 ret = sk_ENGINE_value(fnd->sk, loop++);
290 if(!ret)
291 {
292#ifdef ENGINE_TABLE_DEBUG
293 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no "
294 "registered implementations would initialise\n",
295 f, l, nid);
296#endif
297 goto end;
298 }
299#if 0
300 /* Don't need to get a reference if we hold the lock. If the locking has
301 * to change in future, that would be different ... */
302 ret->struct_ref++; engine_ref_debug(ret, 0, 1)
303#endif
304 /* Try and initialise the ENGINE if it's already functional *or* if the
305 * ENGINE_TABLE_FLAG_NOINIT flag is not set. */
306 if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT))
307 initres = engine_unlocked_init(ret);
308 else
309 initres = 0;
310#if 0
311 /* Release the structural reference */
312 ret->struct_ref--; engine_ref_debug(ret, 0, -1);
313#endif
314 if(initres)
315 {
316 /* If we didn't have a default (functional reference) for this
317 * 'nid' (or we had one but for whatever reason we're now
318 * initialising a different one), use this opportunity to set
319 * 'funct'. */
320 if((fnd->funct != ret) && engine_unlocked_init(ret))
321 {
322 /* If there was a previous default we release it. */
323 if(fnd->funct)
324 engine_unlocked_finish(fnd->funct, 0);
325 /* We got an extra functional reference for the
326 * per-'nid' default */
327 fnd->funct = ret;
328#ifdef ENGINE_TABLE_DEBUG
329 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, "
330 "setting default to '%s'\n", f, l, nid, ret->id);
331#endif
332 }
333#ifdef ENGINE_TABLE_DEBUG
334 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
335 "newly initialised '%s'\n", f, l, nid, ret->id);
336#endif
337 goto end;
338 }
339 goto trynext;
340end:
341 /* Whatever happened - we should "untouch" our uptodate file seeing as
342 * we have tried our best to find a functional reference for 'nid'. If
343 * it failed, it is unlikely to succeed again until some future
344 * registrations (or unregistrations) have taken place that affect that
345 * 'nid'. */
346 if(fnd)
347 fnd->uptodate = 1;
348#ifdef ENGINE_TABLE_DEBUG
349 if(ret)
350 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
351 "ENGINE '%s'\n", f, l, nid, ret->id);
352 else
353 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
354 "'no matching ENGINE'\n", f, l, nid);
355#endif
356 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
357 /* Whatever happened, any failed init()s are not failures in this
358 * context, so clear our error state. */
359 ERR_clear_error();
360 return ret;
361 }
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 @@
3 * project 2000. 3 * project 2000.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -59,36 +59,171 @@
59#ifndef HEADER_ENGINE_H 59#ifndef HEADER_ENGINE_H
60#define HEADER_ENGINE_H 60#define HEADER_ENGINE_H
61 61
62#include <openssl/ossl_typ.h>
62#include <openssl/bn.h> 63#include <openssl/bn.h>
64#ifndef OPENSSL_NO_RSA
63#include <openssl/rsa.h> 65#include <openssl/rsa.h>
66#endif
67#ifndef OPENSSL_NO_DSA
64#include <openssl/dsa.h> 68#include <openssl/dsa.h>
69#endif
70#ifndef OPENSSL_NO_DH
65#include <openssl/dh.h> 71#include <openssl/dh.h>
72#endif
66#include <openssl/rand.h> 73#include <openssl/rand.h>
67#include <openssl/evp.h> 74#include <openssl/ui.h>
68#include <openssl/symhacks.h> 75#include <openssl/symhacks.h>
76#include <openssl/err.h>
69 77
70#ifdef __cplusplus 78#ifdef __cplusplus
71extern "C" { 79extern "C" {
72#endif 80#endif
73 81
82/* Fixups for missing algorithms */
83#ifdef OPENSSL_NO_RSA
84typedef void RSA_METHOD;
85#endif
86#ifdef OPENSSL_NO_DSA
87typedef void DSA_METHOD;
88#endif
89#ifdef OPENSSL_NO_DH
90typedef void DH_METHOD;
91#endif
92
74/* These flags are used to control combinations of algorithm (methods) 93/* These flags are used to control combinations of algorithm (methods)
75 * by bitwise "OR"ing. */ 94 * by bitwise "OR"ing. */
76#define ENGINE_METHOD_RSA (unsigned int)0x0001 95#define ENGINE_METHOD_RSA (unsigned int)0x0001
77#define ENGINE_METHOD_DSA (unsigned int)0x0002 96#define ENGINE_METHOD_DSA (unsigned int)0x0002
78#define ENGINE_METHOD_DH (unsigned int)0x0004 97#define ENGINE_METHOD_DH (unsigned int)0x0004
79#define ENGINE_METHOD_RAND (unsigned int)0x0008 98#define ENGINE_METHOD_RAND (unsigned int)0x0008
80#define ENGINE_METHOD_BN_MOD_EXP (unsigned int)0x0010 99#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040
81#define ENGINE_METHOD_BN_MOD_EXP_CRT (unsigned int)0x0020 100#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080
82/* Obvious all-or-nothing cases. */ 101/* Obvious all-or-nothing cases. */
83#define ENGINE_METHOD_ALL (unsigned int)0xFFFF 102#define ENGINE_METHOD_ALL (unsigned int)0xFFFF
84#define ENGINE_METHOD_NONE (unsigned int)0x0000 103#define ENGINE_METHOD_NONE (unsigned int)0x0000
85 104
105/* This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used
106 * internally to control registration of ENGINE implementations, and can be set
107 * by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to
108 * initialise registered ENGINEs if they are not already initialised. */
109#define ENGINE_TABLE_FLAG_NOINIT (unsigned int)0x0001
110
111/* ENGINE flags that can be set by ENGINE_set_flags(). */
112/* #define ENGINE_FLAGS_MALLOCED 0x0001 */ /* Not used */
113
114/* This flag is for ENGINEs that wish to handle the various 'CMD'-related
115 * control commands on their own. Without this flag, ENGINE_ctrl() handles these
116 * control commands on behalf of the ENGINE using their "cmd_defns" data. */
117#define ENGINE_FLAGS_MANUAL_CMD_CTRL (int)0x0002
118
119/* This flag is for ENGINEs who return new duplicate structures when found via
120 * "ENGINE_by_id()". When an ENGINE must store state (eg. if ENGINE_ctrl()
121 * commands are called in sequence as part of some stateful process like
122 * key-generation setup and execution), it can set this flag - then each attempt
123 * to obtain the ENGINE will result in it being copied into a new structure.
124 * Normally, ENGINEs don't declare this flag so ENGINE_by_id() just increments
125 * the existing ENGINE's structural reference count. */
126#define ENGINE_FLAGS_BY_ID_COPY (int)0x0004
127
128/* ENGINEs can support their own command types, and these flags are used in
129 * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input each
130 * command expects. Currently only numeric and string input is supported. If a
131 * control command supports none of the _NUMERIC, _STRING, or _NO_INPUT options,
132 * then it is regarded as an "internal" control command - and not for use in
133 * config setting situations. As such, they're not available to the
134 * ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() access. Changes to
135 * this list of 'command types' should be reflected carefully in
136 * ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). */
137
138/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */
139#define ENGINE_CMD_FLAG_NUMERIC (unsigned int)0x0001
140/* accepts string input (cast from 'void*' to 'const char *', 4th parameter to
141 * ENGINE_ctrl) */
142#define ENGINE_CMD_FLAG_STRING (unsigned int)0x0002
143/* Indicates that the control command takes *no* input. Ie. the control command
144 * is unparameterised. */
145#define ENGINE_CMD_FLAG_NO_INPUT (unsigned int)0x0004
146/* Indicates that the control command is internal. This control command won't
147 * be shown in any output, and is only usable through the ENGINE_ctrl_cmd()
148 * function. */
149#define ENGINE_CMD_FLAG_INTERNAL (unsigned int)0x0008
150
151/* NB: These 3 control commands are deprecated and should not be used. ENGINEs
152 * relying on these commands should compile conditional support for
153 * compatibility (eg. if these symbols are defined) but should also migrate the
154 * same functionality to their own ENGINE-specific control functions that can be
155 * "discovered" by calling applications. The fact these control commands
156 * wouldn't be "executable" (ie. usable by text-based config) doesn't change the
157 * fact that application code can find and use them without requiring per-ENGINE
158 * hacking. */
159
86/* These flags are used to tell the ctrl function what should be done. 160/* These flags are used to tell the ctrl function what should be done.
87 * All command numbers are shared between all engines, even if some don't 161 * All command numbers are shared between all engines, even if some don't
88 * make sense to some engines. In such a case, they do nothing but return 162 * make sense to some engines. In such a case, they do nothing but return
89 * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */ 163 * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */
90#define ENGINE_CTRL_SET_LOGSTREAM 1 164#define ENGINE_CTRL_SET_LOGSTREAM 1
91#define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2 165#define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2
166#define ENGINE_CTRL_HUP 3 /* Close and reinitialise any
167 handles/connections etc. */
168#define ENGINE_CTRL_SET_USER_INTERFACE 4 /* Alternative to callback */
169#define ENGINE_CTRL_SET_CALLBACK_DATA 5 /* User-specific data, used
170 when calling the password
171 callback and the user
172 interface */
173
174/* These control commands allow an application to deal with an arbitrary engine
175 * in a dynamic way. Warn: Negative return values indicate errors FOR THESE
176 * COMMANDS because zero is used to indicate 'end-of-list'. Other commands,
177 * including ENGINE-specific command types, return zero for an error.
178 *
179 * An ENGINE can choose to implement these ctrl functions, and can internally
180 * manage things however it chooses - it does so by setting the
181 * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise the
182 * ENGINE_ctrl() code handles this on the ENGINE's behalf using the cmd_defns
183 * data (set using ENGINE_set_cmd_defns()). This means an ENGINE's ctrl()
184 * handler need only implement its own commands - the above "meta" commands will
185 * be taken care of. */
186
187/* Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", then
188 * all the remaining control commands will return failure, so it is worth
189 * checking this first if the caller is trying to "discover" the engine's
190 * capabilities and doesn't want errors generated unnecessarily. */
191#define ENGINE_CTRL_HAS_CTRL_FUNCTION 10
192/* Returns a positive command number for the first command supported by the
193 * engine. Returns zero if no ctrl commands are supported. */
194#define ENGINE_CTRL_GET_FIRST_CMD_TYPE 11
195/* The 'long' argument specifies a command implemented by the engine, and the
196 * return value is the next command supported, or zero if there are no more. */
197#define ENGINE_CTRL_GET_NEXT_CMD_TYPE 12
198/* The 'void*' argument is a command name (cast from 'const char *'), and the
199 * return value is the command that corresponds to it. */
200#define ENGINE_CTRL_GET_CMD_FROM_NAME 13
201/* The next two allow a command to be converted into its corresponding string
202 * form. In each case, the 'long' argument supplies the command. In the NAME_LEN
203 * case, the return value is the length of the command name (not counting a
204 * trailing EOL). In the NAME case, the 'void*' argument must be a string buffer
205 * large enough, and it will be populated with the name of the command (WITH a
206 * trailing EOL). */
207#define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD 14
208#define ENGINE_CTRL_GET_NAME_FROM_CMD 15
209/* The next two are similar but give a "short description" of a command. */
210#define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD 16
211#define ENGINE_CTRL_GET_DESC_FROM_CMD 17
212/* With this command, the return value is the OR'd combination of
213 * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given
214 * engine-specific ctrl command expects. */
215#define ENGINE_CTRL_GET_CMD_FLAGS 18
216
217/* ENGINE implementations should start the numbering of their own control
218 * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). */
219#define ENGINE_CMD_BASE 200
220
221/* NB: These 2 nCipher "chil" control commands are deprecated, and their
222 * functionality is now available through ENGINE-specific control commands
223 * (exposed through the above-mentioned 'CMD'-handling). Code using these 2
224 * commands should be migrated to the more general command handling before these
225 * are removed. */
226
92/* Flags specific to the nCipher "chil" engine */ 227/* Flags specific to the nCipher "chil" engine */
93#define ENGINE_CTRL_CHIL_SET_FORKCHECK 100 228#define ENGINE_CTRL_CHIL_SET_FORKCHECK 100
94 /* Depending on the value of the (long)i argument, this sets or 229 /* Depending on the value of the (long)i argument, this sets or
@@ -99,45 +234,55 @@ extern "C" {
99 /* This prevents the initialisation function from providing mutex 234 /* This prevents the initialisation function from providing mutex
100 * callbacks to the nCipher library. */ 235 * callbacks to the nCipher library. */
101 236
102/* As we're missing a BIGNUM_METHOD, we need a couple of locally 237/* If an ENGINE supports its own specific control commands and wishes the
103 * defined function types that engines can implement. */ 238 * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on its
104 239 * behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN entries
105#ifndef HEADER_ENGINE_INT_H 240 * to ENGINE_set_cmd_defns(). It should also implement a ctrl() handler that
106/* mod_exp operation, calculates; r = a ^ p mod m 241 * supports the stated commands (ie. the "cmd_num" entries as described by the
107 * NB: ctx can be NULL, but if supplied, the implementation may use 242 * array). NB: The array must be ordered in increasing order of cmd_num.
108 * it if it wishes. */ 243 * "null-terminated" means that the last ENGINE_CMD_DEFN element has cmd_num set
109typedef int (*BN_MOD_EXP)(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 244 * to zero and/or cmd_name set to NULL. */
110 const BIGNUM *m, BN_CTX *ctx); 245typedef struct ENGINE_CMD_DEFN_st
111 246 {
112/* private key operation for RSA, provided seperately in case other 247 unsigned int cmd_num; /* The command number */
113 * RSA implementations wish to use it. */ 248 const char *cmd_name; /* The command name itself */
114typedef int (*BN_MOD_EXP_CRT)(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 249 const char *cmd_desc; /* A short description of the command */
115 const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1, 250 unsigned int cmd_flags; /* The input the command expects */
116 const BIGNUM *iqmp, BN_CTX *ctx); 251 } ENGINE_CMD_DEFN;
117 252
118/* Generic function pointer */ 253/* Generic function pointer */
119typedef void (*ENGINE_GEN_FUNC_PTR)(); 254typedef int (*ENGINE_GEN_FUNC_PTR)();
120/* Generic function pointer taking no arguments */ 255/* Generic function pointer taking no arguments */
121typedef void (*ENGINE_GEN_INT_FUNC_PTR)(void); 256typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *);
122/* Specific control function pointer */ 257/* Specific control function pointer */
123typedef int (*ENGINE_CTRL_FUNC_PTR)(int cmd, long i, void *p, void (*f)()); 258typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, void (*f)());
124 259/* Generic load_key function pointer */
125/* The list of "engine" types is a static array of (const ENGINE*) 260typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
126 * pointers (not dynamic because static is fine for now and we otherwise 261 UI_METHOD *ui_method, void *callback_data);
127 * have to hook an appropriate load/unload function in to initialise and 262/* These callback types are for an ENGINE's handler for cipher and digest logic.
128 * cleanup). */ 263 * These handlers have these prototypes;
129typedef struct engine_st ENGINE; 264 * int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
130#endif 265 * int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid);
266 * Looking at how to implement these handlers in the case of cipher support, if
267 * the framework wants the EVP_CIPHER for 'nid', it will call;
268 * foo(e, &p_evp_cipher, NULL, nid); (return zero for failure)
269 * If the framework wants a list of supported 'nid's, it will call;
270 * foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error)
271 */
272/* Returns to a pointer to the array of supported cipher 'nid's. If the second
273 * parameter is non-NULL it is set to the size of the returned array. */
274typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int);
275typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int);
131 276
132/* STRUCTURE functions ... all of these functions deal with pointers to 277/* STRUCTURE functions ... all of these functions deal with pointers to ENGINE
133 * ENGINE structures where the pointers have a "structural reference". 278 * structures where the pointers have a "structural reference". This means that
134 * This means that their reference is to allow access to the structure 279 * their reference is to allowed access to the structure but it does not imply
135 * but it does not imply that the structure is functional. To simply 280 * that the structure is functional. To simply increment or decrement the
136 * increment or decrement the structural reference count, use ENGINE_new 281 * structural reference count, use ENGINE_by_id and ENGINE_free. NB: This is not
137 * and ENGINE_free. NB: This is not required when iterating using 282 * required when iterating using ENGINE_get_next as it will automatically
138 * ENGINE_get_next as it will automatically decrement the structural 283 * decrement the structural reference count of the "current" ENGINE and
139 * reference count of the "current" ENGINE and increment the structural 284 * increment the structural reference count of the ENGINE it returns (unless it
140 * reference count of the ENGINE it returns (unless it is NULL). */ 285 * is NULL). */
141 286
142/* Get the first/last "ENGINE" type available. */ 287/* Get the first/last "ENGINE" type available. */
143ENGINE *ENGINE_get_first(void); 288ENGINE *ENGINE_get_first(void);
@@ -151,67 +296,170 @@ int ENGINE_add(ENGINE *e);
151int ENGINE_remove(ENGINE *e); 296int ENGINE_remove(ENGINE *e);
152/* Retrieve an engine from the list by its unique "id" value. */ 297/* Retrieve an engine from the list by its unique "id" value. */
153ENGINE *ENGINE_by_id(const char *id); 298ENGINE *ENGINE_by_id(const char *id);
299/* Add all the built-in engines. */
300void ENGINE_load_openssl(void);
301void ENGINE_load_dynamic(void);
302void ENGINE_load_cswift(void);
303void ENGINE_load_chil(void);
304void ENGINE_load_atalla(void);
305void ENGINE_load_nuron(void);
306void ENGINE_load_ubsec(void);
307void ENGINE_load_aep(void);
308void ENGINE_load_sureware(void);
309void ENGINE_load_4758cca(void);
310void ENGINE_load_openbsd_dev_crypto(void);
311void ENGINE_load_builtin_engines(void);
312#ifdef __OpenBSD__
313void ENGINE_load_cryptodev(void);
314#endif
315
316/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
317 * "registry" handling. */
318unsigned int ENGINE_get_table_flags(void);
319void ENGINE_set_table_flags(unsigned int flags);
154 320
155/* These functions are useful for manufacturing new ENGINE 321/* Manage registration of ENGINEs per "table". For each type, there are 3
156 * structures. They don't address reference counting at all - 322 * functions;
157 * one uses them to populate an ENGINE structure with personalised 323 * ENGINE_register_***(e) - registers the implementation from 'e' (if it has one)
158 * implementations of things prior to using it directly or adding 324 * ENGINE_unregister_***(e) - unregister the implementation from 'e'
159 * it to the builtin ENGINE list in OpenSSL. These are also here 325 * ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list
160 * so that the ENGINE structure doesn't have to be exposed and 326 * Cleanup is automatically registered from each table when required, so
161 * break binary compatibility! 327 * ENGINE_cleanup() will reverse any "register" operations. */
162 * 328
163 * NB: I'm changing ENGINE_new to force the ENGINE structure to 329int ENGINE_register_RSA(ENGINE *e);
164 * be allocated from within OpenSSL. See the comment for 330void ENGINE_unregister_RSA(ENGINE *e);
165 * ENGINE_get_struct_size(). 331void ENGINE_register_all_RSA(void);
166 */ 332
167#if 0 333int ENGINE_register_DSA(ENGINE *e);
168ENGINE *ENGINE_new(ENGINE *e); 334void ENGINE_unregister_DSA(ENGINE *e);
169#else 335void ENGINE_register_all_DSA(void);
336
337int ENGINE_register_DH(ENGINE *e);
338void ENGINE_unregister_DH(ENGINE *e);
339void ENGINE_register_all_DH(void);
340
341int ENGINE_register_RAND(ENGINE *e);
342void ENGINE_unregister_RAND(ENGINE *e);
343void ENGINE_register_all_RAND(void);
344
345int ENGINE_register_ciphers(ENGINE *e);
346void ENGINE_unregister_ciphers(ENGINE *e);
347void ENGINE_register_all_ciphers(void);
348
349int ENGINE_register_digests(ENGINE *e);
350void ENGINE_unregister_digests(ENGINE *e);
351void ENGINE_register_all_digests(void);
352
353/* These functions register all support from the above categories. Note, use of
354 * these functions can result in static linkage of code your application may not
355 * need. If you only need a subset of functionality, consider using more
356 * selective initialisation. */
357int ENGINE_register_complete(ENGINE *e);
358int ENGINE_register_all_complete(void);
359
360/* Send parametrised control commands to the engine. The possibilities to send
361 * down an integer, a pointer to data or a function pointer are provided. Any of
362 * the parameters may or may not be NULL, depending on the command number. In
363 * actuality, this function only requires a structural (rather than functional)
364 * reference to an engine, but many control commands may require the engine be
365 * functional. The caller should be aware of trying commands that require an
366 * operational ENGINE, and only use functional references in such situations. */
367int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
368
369/* This function tests if an ENGINE-specific command is usable as a "setting".
370 * Eg. in an application's config file that gets processed through
371 * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to
372 * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). */
373int ENGINE_cmd_is_executable(ENGINE *e, int cmd);
374
375/* This function works like ENGINE_ctrl() with the exception of taking a
376 * command name instead of a command number, and can handle optional commands.
377 * See the comment on ENGINE_ctrl_cmd_string() for an explanation on how to
378 * use the cmd_name and cmd_optional. */
379int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
380 long i, void *p, void (*f)(), int cmd_optional);
381
382/* This function passes a command-name and argument to an ENGINE. The cmd_name
383 * is converted to a command number and the control command is called using
384 * 'arg' as an argument (unless the ENGINE doesn't support such a command, in
385 * which case no control command is called). The command is checked for input
386 * flags, and if necessary the argument will be converted to a numeric value. If
387 * cmd_optional is non-zero, then if the ENGINE doesn't support the given
388 * cmd_name the return value will be success anyway. This function is intended
389 * for applications to use so that users (or config files) can supply
390 * engine-specific config data to the ENGINE at run-time to control behaviour of
391 * specific engines. As such, it shouldn't be used for calling ENGINE_ctrl()
392 * functions that return data, deal with binary data, or that are otherwise
393 * supposed to be used directly through ENGINE_ctrl() in application code. Any
394 * "return" data from an ENGINE_ctrl() operation in this function will be lost -
395 * the return value is interpreted as failure if the return value is zero,
396 * success otherwise, and this function returns a boolean value as a result. In
397 * other words, vendors of 'ENGINE'-enabled devices should write ENGINE
398 * implementations with parameterisations that work in this scheme, so that
399 * compliant ENGINE-based applications can work consistently with the same
400 * configuration for the same ENGINE-enabled devices, across applications. */
401int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
402 int cmd_optional);
403
404/* These functions are useful for manufacturing new ENGINE structures. They
405 * don't address reference counting at all - one uses them to populate an ENGINE
406 * structure with personalised implementations of things prior to using it
407 * directly or adding it to the builtin ENGINE list in OpenSSL. These are also
408 * here so that the ENGINE structure doesn't have to be exposed and break binary
409 * compatibility! */
170ENGINE *ENGINE_new(void); 410ENGINE *ENGINE_new(void);
171#endif
172int ENGINE_free(ENGINE *e); 411int ENGINE_free(ENGINE *e);
173int ENGINE_set_id(ENGINE *e, const char *id); 412int ENGINE_set_id(ENGINE *e, const char *id);
174int ENGINE_set_name(ENGINE *e, const char *name); 413int ENGINE_set_name(ENGINE *e, const char *name);
175int ENGINE_set_RSA(ENGINE *e, RSA_METHOD *rsa_meth); 414int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
176int ENGINE_set_DSA(ENGINE *e, DSA_METHOD *dsa_meth); 415int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
177int ENGINE_set_DH(ENGINE *e, DH_METHOD *dh_meth); 416int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
178int ENGINE_set_RAND(ENGINE *e, RAND_METHOD *rand_meth); 417int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
179int ENGINE_set_BN_mod_exp(ENGINE *e, BN_MOD_EXP bn_mod_exp); 418int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
180int ENGINE_set_BN_mod_exp_crt(ENGINE *e, BN_MOD_EXP_CRT bn_mod_exp_crt);
181int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f); 419int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
182int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); 420int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
183int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f); 421int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
422int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f);
423int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
424int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
425int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
426int ENGINE_set_flags(ENGINE *e, int flags);
427int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
428/* These functions (and the "get" function lower down) allow control over any
429 * per-structure ENGINE data. */
430int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
431 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
432int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
184 433
185/* These return values from within the ENGINE structure. These can 434/* This function cleans up anything that needs it. Eg. the ENGINE_add() function
186 * be useful with functional references as well as structural 435 * automatically ensures the list cleanup function is registered to be called
187 * references - it depends which you obtained. Using the result 436 * from ENGINE_cleanup(). Similarly, all ENGINE_register_*** functions ensure
188 * for functional purposes if you only obtained a structural 437 * ENGINE_cleanup() will clean up after them. */
189 * reference may be problematic! */ 438void ENGINE_cleanup(void);
190const char *ENGINE_get_id(ENGINE *e); 439
191const char *ENGINE_get_name(ENGINE *e); 440/* These return values from within the ENGINE structure. These can be useful
192RSA_METHOD *ENGINE_get_RSA(ENGINE *e); 441 * with functional references as well as structural references - it depends
193DSA_METHOD *ENGINE_get_DSA(ENGINE *e); 442 * which you obtained. Using the result for functional purposes if you only
194DH_METHOD *ENGINE_get_DH(ENGINE *e); 443 * obtained a structural reference may be problematic! */
195RAND_METHOD *ENGINE_get_RAND(ENGINE *e); 444const char *ENGINE_get_id(const ENGINE *e);
196BN_MOD_EXP ENGINE_get_BN_mod_exp(ENGINE *e); 445const char *ENGINE_get_name(const ENGINE *e);
197BN_MOD_EXP_CRT ENGINE_get_BN_mod_exp_crt(ENGINE *e); 446const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
198ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(ENGINE *e); 447const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
199ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(ENGINE *e); 448const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
200ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(ENGINE *e); 449const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
201 450ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
202/* ENGINE_new is normally passed a NULL in the first parameter because 451ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
203 * the calling code doesn't have access to the definition of the ENGINE 452ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
204 * structure (for good reason). However, if the caller wishes to use 453ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
205 * its own memory allocation or use a static array, the following call 454ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
206 * should be used to check the amount of memory the ENGINE structure 455ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
207 * will occupy. This will make the code more future-proof. 456ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
208 * 457ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
209 * NB: I'm "#if 0"-ing this out because it's better to force the use of 458const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
210 * internally allocated memory. See similar change in ENGINE_new(). 459const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
211 */ 460const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
212#if 0 461int ENGINE_get_flags(const ENGINE *e);
213int ENGINE_get_struct_size(void); 462void *ENGINE_get_ex_data(const ENGINE *e, int idx);
214#endif
215 463
216/* FUNCTIONAL functions. These functions deal with ENGINE structures 464/* FUNCTIONAL functions. These functions deal with ENGINE structures
217 * that have (or will) be initialised for use. Broadly speaking, the 465 * that have (or will) be initialised for use. Broadly speaking, the
@@ -233,20 +481,14 @@ int ENGINE_init(ENGINE *e);
233 * a corresponding call to ENGINE_free as it also releases a structural 481 * a corresponding call to ENGINE_free as it also releases a structural
234 * reference. */ 482 * reference. */
235int ENGINE_finish(ENGINE *e); 483int ENGINE_finish(ENGINE *e);
236/* Send control parametrised commands to the engine. The possibilities
237 * to send down an integer, a pointer to data or a function pointer are
238 * provided. Any of the parameters may or may not be NULL, depending
239 * on the command number */
240/* WARNING: This is currently experimental and may change radically! */
241int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
242 484
243/* The following functions handle keys that are stored in some secondary 485/* The following functions handle keys that are stored in some secondary
244 * location, handled by the engine. The storage may be on a card or 486 * location, handled by the engine. The storage may be on a card or
245 * whatever. */ 487 * whatever. */
246EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, 488EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
247 const char *passphrase); 489 UI_METHOD *ui_method, void *callback_data);
248EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, 490EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
249 const char *passphrase); 491 UI_METHOD *ui_method, void *callback_data);
250 492
251/* This returns a pointer for the current ENGINE structure that 493/* This returns a pointer for the current ENGINE structure that
252 * is (by default) performing any RSA operations. The value returned 494 * is (by default) performing any RSA operations. The value returned
@@ -257,117 +499,192 @@ ENGINE *ENGINE_get_default_RSA(void);
257ENGINE *ENGINE_get_default_DSA(void); 499ENGINE *ENGINE_get_default_DSA(void);
258ENGINE *ENGINE_get_default_DH(void); 500ENGINE *ENGINE_get_default_DH(void);
259ENGINE *ENGINE_get_default_RAND(void); 501ENGINE *ENGINE_get_default_RAND(void);
260ENGINE *ENGINE_get_default_BN_mod_exp(void); 502/* These functions can be used to get a functional reference to perform
261ENGINE *ENGINE_get_default_BN_mod_exp_crt(void); 503 * ciphering or digesting corresponding to "nid". */
504ENGINE *ENGINE_get_cipher_engine(int nid);
505ENGINE *ENGINE_get_digest_engine(int nid);
262 506
263/* This sets a new default ENGINE structure for performing RSA 507/* This sets a new default ENGINE structure for performing RSA
264 * operations. If the result is non-zero (success) then the ENGINE 508 * operations. If the result is non-zero (success) then the ENGINE
265 * structure will have had its reference count up'd so the caller 509 * structure will have had its reference count up'd so the caller
266 * should still free their own reference 'e'. */ 510 * should still free their own reference 'e'. */
267int ENGINE_set_default_RSA(ENGINE *e); 511int ENGINE_set_default_RSA(ENGINE *e);
512int ENGINE_set_default_string(ENGINE *e, const char *list);
268/* Same for the other "methods" */ 513/* Same for the other "methods" */
269int ENGINE_set_default_DSA(ENGINE *e); 514int ENGINE_set_default_DSA(ENGINE *e);
270int ENGINE_set_default_DH(ENGINE *e); 515int ENGINE_set_default_DH(ENGINE *e);
271int ENGINE_set_default_RAND(ENGINE *e); 516int ENGINE_set_default_RAND(ENGINE *e);
272int ENGINE_set_default_BN_mod_exp(ENGINE *e); 517int ENGINE_set_default_ciphers(ENGINE *e);
273int ENGINE_set_default_BN_mod_exp_crt(ENGINE *e); 518int ENGINE_set_default_digests(ENGINE *e);
274 519
275/* The combination "set" - the flags are bitwise "OR"d from the 520/* The combination "set" - the flags are bitwise "OR"d from the
276 * ENGINE_METHOD_*** defines above. */ 521 * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
522 * function, this function can result in unnecessary static linkage. If your
523 * application requires only specific functionality, consider using more
524 * selective functions. */
277int ENGINE_set_default(ENGINE *e, unsigned int flags); 525int ENGINE_set_default(ENGINE *e, unsigned int flags);
278 526
279/* Obligatory error function. */ 527void ENGINE_add_conf_module(void);
280void ERR_load_ENGINE_strings(void);
281 528
282/* 529/* Deprecated functions ... */
283 * Error codes for all engine functions. NB: We use "generic" 530/* int ENGINE_clear_defaults(void); */
284 * function names instead of per-implementation ones because this 531
285 * levels the playing field for externally implemented bootstrapped 532/**************************/
286 * support code. As the filename and line number is included, it's 533/* DYNAMIC ENGINE SUPPORT */
287 * more important to indicate the type of function, so that 534/**************************/
288 * bootstrapped code (that can't easily add its own errors in) can 535
289 * use the same error codes too. 536/* Binary/behaviour compatibility levels */
290 */ 537#define OSSL_DYNAMIC_VERSION (unsigned long)0x00010100
538/* Binary versions older than this are too old for us (whether we're a loader or
539 * a loadee) */
540#define OSSL_DYNAMIC_OLDEST (unsigned long)0x00010100
541
542/* When compiling an ENGINE entirely as an external shared library, loadable by
543 * the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' structure
544 * type provides the calling application's (or library's) error functionality
545 * and memory management function pointers to the loaded library. These should
546 * be used/set in the loaded library code so that the loading application's
547 * 'state' will be used/changed in all operations. */
548typedef void *(*dyn_MEM_malloc_cb)(size_t);
549typedef void *(*dyn_MEM_realloc_cb)(void *, size_t);
550typedef void (*dyn_MEM_free_cb)(void *);
551typedef struct st_dynamic_MEM_fns {
552 dyn_MEM_malloc_cb malloc_cb;
553 dyn_MEM_realloc_cb realloc_cb;
554 dyn_MEM_free_cb free_cb;
555 } dynamic_MEM_fns;
556/* FIXME: Perhaps the memory and locking code (crypto.h) should declare and use
557 * these types so we (and any other dependant code) can simplify a bit?? */
558typedef void (*dyn_lock_locking_cb)(int,int,const char *,int);
559typedef int (*dyn_lock_add_lock_cb)(int*,int,int,const char *,int);
560typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb)(
561 const char *,int);
562typedef void (*dyn_dynlock_lock_cb)(int,struct CRYPTO_dynlock_value *,
563 const char *,int);
564typedef void (*dyn_dynlock_destroy_cb)(struct CRYPTO_dynlock_value *,
565 const char *,int);
566typedef struct st_dynamic_LOCK_fns {
567 dyn_lock_locking_cb lock_locking_cb;
568 dyn_lock_add_lock_cb lock_add_lock_cb;
569 dyn_dynlock_create_cb dynlock_create_cb;
570 dyn_dynlock_lock_cb dynlock_lock_cb;
571 dyn_dynlock_destroy_cb dynlock_destroy_cb;
572 } dynamic_LOCK_fns;
573/* The top-level structure */
574typedef struct st_dynamic_fns {
575 const ERR_FNS *err_fns;
576 const CRYPTO_EX_DATA_IMPL *ex_data_fns;
577 dynamic_MEM_fns mem_fns;
578 dynamic_LOCK_fns lock_fns;
579 } dynamic_fns;
580
581/* The version checking function should be of this prototype. NB: The
582 * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading code.
583 * If this function returns zero, it indicates a (potential) version
584 * incompatibility and the loaded library doesn't believe it can proceed.
585 * Otherwise, the returned value is the (latest) version supported by the
586 * loading library. The loader may still decide that the loaded code's version
587 * is unsatisfactory and could veto the load. The function is expected to
588 * be implemented with the symbol name "v_check", and a default implementation
589 * can be fully instantiated with IMPLEMENT_DYNAMIC_CHECK_FN(). */
590typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version);
591#define IMPLEMENT_DYNAMIC_CHECK_FN() \
592 unsigned long v_check(unsigned long v) { \
593 if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \
594 return 0; }
595
596/* This function is passed the ENGINE structure to initialise with its own
597 * function and command settings. It should not adjust the structural or
598 * functional reference counts. If this function returns zero, (a) the load will
599 * be aborted, (b) the previous ENGINE state will be memcpy'd back onto the
600 * structure, and (c) the shared library will be unloaded. So implementations
601 * should do their own internal cleanup in failure circumstances otherwise they
602 * could leak. The 'id' parameter, if non-NULL, represents the ENGINE id that
603 * the loader is looking for. If this is NULL, the shared library can choose to
604 * return failure or to initialise a 'default' ENGINE. If non-NULL, the shared
605 * library must initialise only an ENGINE matching the passed 'id'. The function
606 * is expected to be implemented with the symbol name "bind_engine". A standard
607 * implementation can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where
608 * the parameter 'fn' is a callback function that populates the ENGINE structure
609 * and returns an int value (zero for failure). 'fn' should have prototype;
610 * [static] int fn(ENGINE *e, const char *id); */
611typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id,
612 const dynamic_fns *fns);
613#define IMPLEMENT_DYNAMIC_BIND_FN(fn) \
614 int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \
615 if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \
616 fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \
617 return 0; \
618 CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \
619 CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \
620 CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \
621 CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \
622 CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \
623 if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \
624 return 0; \
625 if(!ERR_set_implementation(fns->err_fns)) return 0; \
626 if(!fn(e,id)) return 0; \
627 return 1; }
291 628
292/* BEGIN ERROR CODES */ 629/* BEGIN ERROR CODES */
293/* The following lines are auto generated by the script mkerr.pl. Any changes 630/* The following lines are auto generated by the script mkerr.pl. Any changes
294 * made after this point may be overwritten when the script is next run. 631 * made after this point may be overwritten when the script is next run.
295 */ 632 */
633void ERR_load_ENGINE_strings(void);
296 634
297/* Error codes for the ENGINE functions. */ 635/* Error codes for the ENGINE functions. */
298 636
299/* Function codes. */ 637/* Function codes. */
300#define ENGINE_F_ATALLA_FINISH 135 638#define ENGINE_F_DYNAMIC_CTRL 180
301#define ENGINE_F_ATALLA_INIT 136 639#define ENGINE_F_DYNAMIC_GET_DATA_CTX 181
302#define ENGINE_F_ATALLA_MOD_EXP 137 640#define ENGINE_F_DYNAMIC_LOAD 182
303#define ENGINE_F_ATALLA_RSA_MOD_EXP 138
304#define ENGINE_F_CSWIFT_DSA_SIGN 133
305#define ENGINE_F_CSWIFT_DSA_VERIFY 134
306#define ENGINE_F_CSWIFT_FINISH 100
307#define ENGINE_F_CSWIFT_INIT 101
308#define ENGINE_F_CSWIFT_MOD_EXP 102
309#define ENGINE_F_CSWIFT_MOD_EXP_CRT 103
310#define ENGINE_F_CSWIFT_RSA_MOD_EXP 104
311#define ENGINE_F_ENGINE_ADD 105 641#define ENGINE_F_ENGINE_ADD 105
312#define ENGINE_F_ENGINE_BY_ID 106 642#define ENGINE_F_ENGINE_BY_ID 106
643#define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170
313#define ENGINE_F_ENGINE_CTRL 142 644#define ENGINE_F_ENGINE_CTRL 142
645#define ENGINE_F_ENGINE_CTRL_CMD 178
646#define ENGINE_F_ENGINE_CTRL_CMD_STRING 171
314#define ENGINE_F_ENGINE_FINISH 107 647#define ENGINE_F_ENGINE_FINISH 107
315#define ENGINE_F_ENGINE_FREE 108 648#define ENGINE_F_ENGINE_FREE 108
316#define ENGINE_F_ENGINE_GET_BN_MOD_EXP 109 649#define ENGINE_F_ENGINE_GET_CIPHER 185
317#define ENGINE_F_ENGINE_GET_BN_MOD_EXP_CRT 110 650#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177
318#define ENGINE_F_ENGINE_GET_CTRL_FUNCTION 144 651#define ENGINE_F_ENGINE_GET_DIGEST 186
319#define ENGINE_F_ENGINE_GET_DH 111
320#define ENGINE_F_ENGINE_GET_DSA 112
321#define ENGINE_F_ENGINE_GET_FINISH_FUNCTION 145
322#define ENGINE_F_ENGINE_GET_ID 113
323#define ENGINE_F_ENGINE_GET_INIT_FUNCTION 146
324#define ENGINE_F_ENGINE_GET_NAME 114
325#define ENGINE_F_ENGINE_GET_NEXT 115 652#define ENGINE_F_ENGINE_GET_NEXT 115
326#define ENGINE_F_ENGINE_GET_PREV 116 653#define ENGINE_F_ENGINE_GET_PREV 116
327#define ENGINE_F_ENGINE_GET_RAND 117
328#define ENGINE_F_ENGINE_GET_RSA 118
329#define ENGINE_F_ENGINE_INIT 119 654#define ENGINE_F_ENGINE_INIT 119
330#define ENGINE_F_ENGINE_LIST_ADD 120 655#define ENGINE_F_ENGINE_LIST_ADD 120
331#define ENGINE_F_ENGINE_LIST_REMOVE 121 656#define ENGINE_F_ENGINE_LIST_REMOVE 121
332#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 657#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150
333#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 658#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151
659#define ENGINE_F_ENGINE_MODULE_INIT 187
334#define ENGINE_F_ENGINE_NEW 122 660#define ENGINE_F_ENGINE_NEW 122
335#define ENGINE_F_ENGINE_REMOVE 123 661#define ENGINE_F_ENGINE_REMOVE 123
336#define ENGINE_F_ENGINE_SET_BN_MOD_EXP 124 662#define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189
337#define ENGINE_F_ENGINE_SET_BN_MOD_EXP_CRT 125
338#define ENGINE_F_ENGINE_SET_CTRL_FUNCTION 147
339#define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126 663#define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126
340#define ENGINE_F_ENGINE_SET_DH 127
341#define ENGINE_F_ENGINE_SET_DSA 128
342#define ENGINE_F_ENGINE_SET_FINISH_FUNCTION 148
343#define ENGINE_F_ENGINE_SET_ID 129 664#define ENGINE_F_ENGINE_SET_ID 129
344#define ENGINE_F_ENGINE_SET_INIT_FUNCTION 149
345#define ENGINE_F_ENGINE_SET_NAME 130 665#define ENGINE_F_ENGINE_SET_NAME 130
346#define ENGINE_F_ENGINE_SET_RAND 131 666#define ENGINE_F_ENGINE_TABLE_REGISTER 184
347#define ENGINE_F_ENGINE_SET_RSA 132
348#define ENGINE_F_ENGINE_UNLOAD_KEY 152 667#define ENGINE_F_ENGINE_UNLOAD_KEY 152
349#define ENGINE_F_HWCRHK_CTRL 143 668#define ENGINE_F_INT_CTRL_HELPER 172
350#define ENGINE_F_HWCRHK_FINISH 135 669#define ENGINE_F_INT_ENGINE_CONFIGURE 188
351#define ENGINE_F_HWCRHK_GET_PASS 155
352#define ENGINE_F_HWCRHK_INIT 136
353#define ENGINE_F_HWCRHK_LOAD_PRIVKEY 153
354#define ENGINE_F_HWCRHK_LOAD_PUBKEY 154
355#define ENGINE_F_HWCRHK_MOD_EXP 137
356#define ENGINE_F_HWCRHK_MOD_EXP_CRT 138
357#define ENGINE_F_HWCRHK_RAND_BYTES 139
358#define ENGINE_F_HWCRHK_RSA_MOD_EXP 140
359#define ENGINE_F_LOG_MESSAGE 141 670#define ENGINE_F_LOG_MESSAGE 141
671#define ENGINE_F_SET_DATA_CTX 183
360 672
361/* Reason codes. */ 673/* Reason codes. */
362#define ENGINE_R_ALREADY_LOADED 100 674#define ENGINE_R_ALREADY_LOADED 100
363#define ENGINE_R_BIO_WAS_FREED 121 675#define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER 133
364#define ENGINE_R_BN_CTX_FULL 101 676#define ENGINE_R_CMD_NOT_EXECUTABLE 134
365#define ENGINE_R_BN_EXPAND_FAIL 102 677#define ENGINE_R_COMMAND_TAKES_INPUT 135
366#define ENGINE_R_CHIL_ERROR 123 678#define ENGINE_R_COMMAND_TAKES_NO_INPUT 136
367#define ENGINE_R_CONFLICTING_ENGINE_ID 103 679#define ENGINE_R_CONFLICTING_ENGINE_ID 103
368#define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119 680#define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119
681#define ENGINE_R_DH_NOT_IMPLEMENTED 139
682#define ENGINE_R_DSA_NOT_IMPLEMENTED 140
369#define ENGINE_R_DSO_FAILURE 104 683#define ENGINE_R_DSO_FAILURE 104
684#define ENGINE_R_DSO_NOT_FOUND 132
685#define ENGINE_R_ENGINES_SECTION_ERROR 148
370#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105 686#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105
687#define ENGINE_R_ENGINE_SECTION_ERROR 149
371#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128 688#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128
372#define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129 689#define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129
373#define ENGINE_R_FINISH_FAILED 106 690#define ENGINE_R_FINISH_FAILED 106
@@ -375,24 +692,26 @@ void ERR_load_ENGINE_strings(void);
375#define ENGINE_R_ID_OR_NAME_MISSING 108 692#define ENGINE_R_ID_OR_NAME_MISSING 108
376#define ENGINE_R_INIT_FAILED 109 693#define ENGINE_R_INIT_FAILED 109
377#define ENGINE_R_INTERNAL_LIST_ERROR 110 694#define ENGINE_R_INTERNAL_LIST_ERROR 110
378#define ENGINE_R_MISSING_KEY_COMPONENTS 111 695#define ENGINE_R_INVALID_ARGUMENT 143
696#define ENGINE_R_INVALID_CMD_NAME 137
697#define ENGINE_R_INVALID_CMD_NUMBER 138
698#define ENGINE_R_INVALID_INIT_VALUE 151
699#define ENGINE_R_INVALID_STRING 150
379#define ENGINE_R_NOT_INITIALISED 117 700#define ENGINE_R_NOT_INITIALISED 117
380#define ENGINE_R_NOT_LOADED 112 701#define ENGINE_R_NOT_LOADED 112
381#define ENGINE_R_NO_CALLBACK 127
382#define ENGINE_R_NO_CONTROL_FUNCTION 120 702#define ENGINE_R_NO_CONTROL_FUNCTION 120
383#define ENGINE_R_NO_KEY 124 703#define ENGINE_R_NO_INDEX 144
384#define ENGINE_R_NO_LOAD_FUNCTION 125 704#define ENGINE_R_NO_LOAD_FUNCTION 125
385#define ENGINE_R_NO_REFERENCE 130 705#define ENGINE_R_NO_REFERENCE 130
386#define ENGINE_R_NO_SUCH_ENGINE 116 706#define ENGINE_R_NO_SUCH_ENGINE 116
387#define ENGINE_R_NO_UNLOAD_FUNCTION 126 707#define ENGINE_R_NO_UNLOAD_FUNCTION 126
388#define ENGINE_R_PROVIDE_PARAMETERS 113 708#define ENGINE_R_PROVIDE_PARAMETERS 113
389#define ENGINE_R_REQUEST_FAILED 114 709#define ENGINE_R_RSA_NOT_IMPLEMENTED 141
390#define ENGINE_R_REQUEST_FALLBACK 118 710#define ENGINE_R_UNIMPLEMENTED_CIPHER 146
391#define ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL 122 711#define ENGINE_R_UNIMPLEMENTED_DIGEST 147
392#define ENGINE_R_UNIT_FAILURE 115 712#define ENGINE_R_VERSION_INCOMPATIBILITY 145
393 713
394#ifdef __cplusplus 714#ifdef __cplusplus
395} 715}
396#endif 716#endif
397#endif 717#endif
398
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 @@
3 * project 2000. 3 * project 2000.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -56,8 +56,11 @@
56 * 56 *
57 */ 57 */
58 58
59#include <openssl/e_os2.h>
59#include <stdio.h> 60#include <stdio.h>
60#include <string.h> 61#include <string.h>
62#include <openssl/buffer.h>
63#include <openssl/crypto.h>
61#include <openssl/engine.h> 64#include <openssl/engine.h>
62#include <openssl/err.h> 65#include <openssl/err.h>
63 66
@@ -76,6 +79,9 @@ static void display_engine_list()
76 h = ENGINE_get_next(h); 79 h = ENGINE_get_next(h);
77 } 80 }
78 printf("end of list\n"); 81 printf("end of list\n");
82 /* ENGINE_get_first() increases the struct_ref counter, so we
83 must call ENGINE_free() to decrease it again */
84 ENGINE_free(h);
79 } 85 }
80 86
81int main(int argc, char *argv[]) 87int main(int argc, char *argv[])
@@ -91,6 +97,18 @@ int main(int argc, char *argv[])
91 ENGINE *new_h3 = NULL; 97 ENGINE *new_h3 = NULL;
92 ENGINE *new_h4 = NULL; 98 ENGINE *new_h4 = NULL;
93 99
100 /* enable memory leak checking unless explicitly disabled */
101 if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
102 {
103 CRYPTO_malloc_debug_init();
104 CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
105 }
106 else
107 {
108 /* OPENSSL_DEBUG_MEMORY=off */
109 CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
110 }
111 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
94 ERR_load_crypto_strings(); 112 ERR_load_crypto_strings();
95 113
96 memset(block, 0, 512 * sizeof(ENGINE *)); 114 memset(block, 0, 512 * sizeof(ENGINE *));
@@ -124,6 +142,8 @@ int main(int argc, char *argv[])
124 printf("Remove failed!\n"); 142 printf("Remove failed!\n");
125 goto end; 143 goto end;
126 } 144 }
145 if (ptr)
146 ENGINE_free(ptr);
127 display_engine_list(); 147 display_engine_list();
128 if(!ENGINE_add(new_h3) || !ENGINE_add(new_h2)) 148 if(!ENGINE_add(new_h3) || !ENGINE_add(new_h2))
129 { 149 {
@@ -158,12 +178,7 @@ int main(int argc, char *argv[])
158 } 178 }
159 else 179 else
160 printf("Remove that should fail did.\n"); 180 printf("Remove that should fail did.\n");
161 if(!ENGINE_remove(new_h1)) 181 ERR_clear_error();
162 {
163 printf("Remove failed!\n");
164 goto end;
165 }
166 display_engine_list();
167 if(!ENGINE_remove(new_h3)) 182 if(!ENGINE_remove(new_h3))
168 { 183 {
169 printf("Remove failed!\n"); 184 printf("Remove failed!\n");
@@ -183,6 +198,8 @@ int main(int argc, char *argv[])
183 if(!ENGINE_remove(ptr)) 198 if(!ENGINE_remove(ptr))
184 printf("Remove failed!i - probably no hardware " 199 printf("Remove failed!i - probably no hardware "
185 "support present.\n"); 200 "support present.\n");
201 if (ptr)
202 ENGINE_free(ptr);
186 display_engine_list(); 203 display_engine_list();
187 if(!ENGINE_add(new_h1) || !ENGINE_remove(new_h1)) 204 if(!ENGINE_add(new_h1) || !ENGINE_remove(new_h1))
188 { 205 {
@@ -195,9 +212,9 @@ int main(int argc, char *argv[])
195 for(loop = 0; loop < 512; loop++) 212 for(loop = 0; loop < 512; loop++)
196 { 213 {
197 sprintf(buf, "id%i", loop); 214 sprintf(buf, "id%i", loop);
198 id = strdup(buf); 215 id = BUF_strdup(buf);
199 sprintf(buf, "Fake engine type %i", loop); 216 sprintf(buf, "Fake engine type %i", loop);
200 name = strdup(buf); 217 name = BUF_strdup(buf);
201 if(((block[loop] = ENGINE_new()) == NULL) || 218 if(((block[loop] = ENGINE_new()) == NULL) ||
202 !ENGINE_set_id(block[loop], id) || 219 !ENGINE_set_id(block[loop], id) ||
203 !ENGINE_set_name(block[loop], name)) 220 !ENGINE_set_name(block[loop], name))
@@ -228,12 +245,13 @@ cleanup_loop:
228 printf("\nRemove failed!\n"); 245 printf("\nRemove failed!\n");
229 goto end; 246 goto end;
230 } 247 }
248 ENGINE_free(ptr);
231 printf("."); fflush(stdout); 249 printf("."); fflush(stdout);
232 } 250 }
233 for(loop = 0; loop < 512; loop++) 251 for(loop = 0; loop < 512; loop++)
234 { 252 {
235 free((char *)(ENGINE_get_id(block[loop]))); 253 OPENSSL_free((void *)ENGINE_get_id(block[loop]));
236 free((char *)(ENGINE_get_name(block[loop]))); 254 OPENSSL_free((void *)ENGINE_get_name(block[loop]));
237 } 255 }
238 printf("\nTests completed happily\n"); 256 printf("\nTests completed happily\n");
239 to_return = 0; 257 to_return = 0;
@@ -247,5 +265,10 @@ end:
247 for(loop = 0; loop < 512; loop++) 265 for(loop = 0; loop < 512; loop++)
248 if(block[loop]) 266 if(block[loop])
249 ENGINE_free(block[loop]); 267 ENGINE_free(block[loop]);
268 ENGINE_cleanup();
269 CRYPTO_cleanup_all_ex_data();
270 ERR_free_strings();
271 ERR_remove_state(0);
272 CRYPTO_mem_leaks_fp(stderr);
250 return to_return; 273 return to_return;
251 } 274 }
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 @@
1L AEPHK hw_aep_err.h hw_aep_err.c
2L ATALLA hw_atalla_err.h hw_atalla_err.c
3L CSWIFT hw_cswift_err.h hw_cswift_err.c
4L HWCRHK hw_ncipher_err.h hw_ncipher_err.c
5L NURON hw_nuron_err.h hw_nuron_err.c
6L SUREWARE hw_sureware_err.h hw_sureware_err.c
7L UBSEC hw_ubsec_err.h hw_ubsec_err.c
8L 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 @@
1/* Author: Maurice Gittens <maurice@gittens.nl> */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * licensing@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include <stdio.h>
57#include <openssl/crypto.h>
58/* #include <openssl/pem.h> */
59#include "cryptlib.h"
60#include <openssl/dso.h>
61#include <openssl/x509.h>
62#include <openssl/objects.h>
63#include <openssl/engine.h>
64
65#ifndef OPENSSL_NO_HW
66#ifndef OPENSSL_NO_HW_4758_CCA
67
68#ifdef FLAT_INC
69#include "hw_4758_cca.h"
70#else
71#include "vendor_defns/hw_4758_cca.h"
72#endif
73
74#include "hw_4758_cca_err.c"
75
76static int ibm_4758_cca_destroy(ENGINE *e);
77static int ibm_4758_cca_init(ENGINE *e);
78static int ibm_4758_cca_finish(ENGINE *e);
79static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
80
81/* rsa functions */
82/*---------------*/
83#ifndef OPENSSL_NO_RSA
84static int cca_rsa_pub_enc(int flen, const unsigned char *from,
85 unsigned char *to, RSA *rsa,int padding);
86static int cca_rsa_priv_dec(int flen, const unsigned char *from,
87 unsigned char *to, RSA *rsa,int padding);
88static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
89 unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
90static int cca_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
91 unsigned char *sigbuf, unsigned int siglen, const RSA *rsa);
92
93/* utility functions */
94/*-----------------------*/
95static EVP_PKEY *ibm_4758_load_privkey(ENGINE*, const char*,
96 UI_METHOD *ui_method, void *callback_data);
97static EVP_PKEY *ibm_4758_load_pubkey(ENGINE*, const char*,
98 UI_METHOD *ui_method, void *callback_data);
99
100static int getModulusAndExponent(const unsigned char *token, long *exponentLength,
101 unsigned char *exponent, long *modulusLength,
102 long *modulusFieldLength, unsigned char *modulus);
103#endif
104
105/* RAND number functions */
106/*-----------------------*/
107static int cca_get_random_bytes(unsigned char*, int );
108static int cca_random_status(void);
109
110static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
111 int idx,long argl, void *argp);
112
113/* Function pointers for CCA verbs */
114/*---------------------------------*/
115#ifndef OPENSSL_NO_RSA
116static F_KEYRECORDREAD keyRecordRead;
117static F_DIGITALSIGNATUREGENERATE digitalSignatureGenerate;
118static F_DIGITALSIGNATUREVERIFY digitalSignatureVerify;
119static F_PUBLICKEYEXTRACT publicKeyExtract;
120static F_PKAENCRYPT pkaEncrypt;
121static F_PKADECRYPT pkaDecrypt;
122#endif
123static F_RANDOMNUMBERGENERATE randomNumberGenerate;
124
125/* static variables */
126/*------------------*/
127static const char def_CCA4758_LIB_NAME[] = CCA_LIB_NAME;
128static const char *CCA4758_LIB_NAME = def_CCA4758_LIB_NAME;
129#ifndef OPENSSL_NO_RSA
130static const char* n_keyRecordRead = CSNDKRR;
131static const char* n_digitalSignatureGenerate = CSNDDSG;
132static const char* n_digitalSignatureVerify = CSNDDSV;
133static const char* n_publicKeyExtract = CSNDPKX;
134static const char* n_pkaEncrypt = CSNDPKE;
135static const char* n_pkaDecrypt = CSNDPKD;
136#endif
137static const char* n_randomNumberGenerate = CSNBRNG;
138
139static int hndidx = -1;
140static DSO *dso = NULL;
141
142/* openssl engine initialization structures */
143/*------------------------------------------*/
144
145#define CCA4758_CMD_SO_PATH ENGINE_CMD_BASE
146static const ENGINE_CMD_DEFN cca4758_cmd_defns[] = {
147 {CCA4758_CMD_SO_PATH,
148 "SO_PATH",
149 "Specifies the path to the '4758cca' shared library",
150 ENGINE_CMD_FLAG_STRING},
151 {0, NULL, NULL, 0}
152 };
153
154#ifndef OPENSSL_NO_RSA
155static RSA_METHOD ibm_4758_cca_rsa =
156 {
157 "IBM 4758 CCA RSA method",
158 cca_rsa_pub_enc,
159 NULL,
160 NULL,
161 cca_rsa_priv_dec,
162 NULL, /*rsa_mod_exp,*/
163 NULL, /*mod_exp_mont,*/
164 NULL, /* init */
165 NULL, /* finish */
166 RSA_FLAG_SIGN_VER, /* flags */
167 NULL, /* app_data */
168 cca_rsa_sign, /* rsa_sign */
169 cca_rsa_verify /* rsa_verify */
170 };
171#endif
172
173static RAND_METHOD ibm_4758_cca_rand =
174 {
175 /* "IBM 4758 RAND method", */
176 NULL, /* seed */
177 cca_get_random_bytes, /* get random bytes from the card */
178 NULL, /* cleanup */
179 NULL, /* add */
180 cca_get_random_bytes, /* pseudo rand */
181 cca_random_status, /* status */
182 };
183
184static const char *engine_4758_cca_id = "4758cca";
185static const char *engine_4758_cca_name = "IBM 4758 CCA hardware engine support";
186
187/* engine implementation */
188/*-----------------------*/
189static int bind_helper(ENGINE *e)
190 {
191 if(!ENGINE_set_id(e, engine_4758_cca_id) ||
192 !ENGINE_set_name(e, engine_4758_cca_name) ||
193#ifndef OPENSSL_NO_RSA
194 !ENGINE_set_RSA(e, &ibm_4758_cca_rsa) ||
195#endif
196 !ENGINE_set_RAND(e, &ibm_4758_cca_rand) ||
197 !ENGINE_set_destroy_function(e, ibm_4758_cca_destroy) ||
198 !ENGINE_set_init_function(e, ibm_4758_cca_init) ||
199 !ENGINE_set_finish_function(e, ibm_4758_cca_finish) ||
200 !ENGINE_set_ctrl_function(e, ibm_4758_cca_ctrl) ||
201 !ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) ||
202 !ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) ||
203 !ENGINE_set_cmd_defns(e, cca4758_cmd_defns))
204 return 0;
205 /* Ensure the error handling is set up */
206 ERR_load_CCA4758_strings();
207 return 1;
208 }
209
210static ENGINE *engine_4758_cca(void)
211 {
212 ENGINE *ret = ENGINE_new();
213 if(!ret)
214 return NULL;
215 if(!bind_helper(ret))
216 {
217 ENGINE_free(ret);
218 return NULL;
219 }
220 return ret;
221 }
222
223void ENGINE_load_4758cca(void)
224 {
225 ENGINE *e_4758 = engine_4758_cca();
226 if (!e_4758) return;
227 ENGINE_add(e_4758);
228 ENGINE_free(e_4758);
229 ERR_clear_error();
230 }
231
232static int ibm_4758_cca_destroy(ENGINE *e)
233 {
234 ERR_unload_CCA4758_strings();
235 return 1;
236 }
237
238static int ibm_4758_cca_init(ENGINE *e)
239 {
240 if(dso)
241 {
242 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_ALREADY_LOADED);
243 goto err;
244 }
245
246 dso = DSO_load(NULL, CCA4758_LIB_NAME , NULL, 0);
247 if(!dso)
248 {
249 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
250 goto err;
251 }
252
253#ifndef OPENSSL_NO_RSA
254 if(!(keyRecordRead = (F_KEYRECORDREAD)
255 DSO_bind_func(dso, n_keyRecordRead)) ||
256 !(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
257 DSO_bind_func(dso, n_randomNumberGenerate)) ||
258 !(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)
259 DSO_bind_func(dso, n_digitalSignatureGenerate)) ||
260 !(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)
261 DSO_bind_func(dso, n_digitalSignatureVerify)) ||
262 !(publicKeyExtract = (F_PUBLICKEYEXTRACT)
263 DSO_bind_func(dso, n_publicKeyExtract)) ||
264 !(pkaEncrypt = (F_PKAENCRYPT)
265 DSO_bind_func(dso, n_pkaEncrypt)) ||
266 !(pkaDecrypt = (F_PKADECRYPT)
267 DSO_bind_func(dso, n_pkaDecrypt)))
268 {
269 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
270 goto err;
271 }
272#else
273 if(!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
274 DSO_bind_func(dso, n_randomNumberGenerate)))
275 {
276 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
277 goto err;
278 }
279#endif
280
281 hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle",
282 NULL, NULL, cca_ex_free);
283
284 return 1;
285err:
286 if(dso)
287 DSO_free(dso);
288 dso = NULL;
289
290 keyRecordRead = (F_KEYRECORDREAD)NULL;
291 randomNumberGenerate = (F_RANDOMNUMBERGENERATE)NULL;
292 digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)NULL;
293 digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)NULL;
294 publicKeyExtract = (F_PUBLICKEYEXTRACT)NULL;
295 pkaEncrypt = (F_PKAENCRYPT)NULL;
296 pkaDecrypt = (F_PKADECRYPT)NULL;
297 return 0;
298 }
299
300static int ibm_4758_cca_finish(ENGINE *e)
301 {
302 if(dso)
303 {
304 CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
305 CCA4758_R_NOT_LOADED);
306 return 0;
307 }
308 if(!DSO_free(dso))
309 {
310 CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
311 CCA4758_R_UNIT_FAILURE);
312 return 0;
313 }
314 dso = NULL;
315 keyRecordRead = (F_KEYRECORDREAD)NULL;
316 randomNumberGenerate = (F_RANDOMNUMBERGENERATE)NULL;
317 digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)NULL;
318 digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)NULL;
319 publicKeyExtract = (F_PUBLICKEYEXTRACT)NULL;
320 pkaEncrypt = (F_PKAENCRYPT)NULL;
321 pkaDecrypt = (F_PKADECRYPT)NULL;
322 return 1;
323 }
324
325static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
326 {
327 int initialised = ((dso == NULL) ? 0 : 1);
328 switch(cmd)
329 {
330 case CCA4758_CMD_SO_PATH:
331 if(p == NULL)
332 {
333 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
334 ERR_R_PASSED_NULL_PARAMETER);
335 return 0;
336 }
337 if(initialised)
338 {
339 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
340 CCA4758_R_ALREADY_LOADED);
341 return 0;
342 }
343 CCA4758_LIB_NAME = (const char *)p;
344 return 1;
345 default:
346 break;
347 }
348 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
349 CCA4758_R_COMMAND_NOT_IMPLEMENTED);
350 return 0;
351 }
352
353#ifndef OPENSSL_NO_RSA
354
355#define MAX_CCA_PKA_TOKEN_SIZE 2500
356
357static EVP_PKEY *ibm_4758_load_privkey(ENGINE* e, const char* key_id,
358 UI_METHOD *ui_method, void *callback_data)
359 {
360 RSA *rtmp = NULL;
361 EVP_PKEY *res = NULL;
362 unsigned char* keyToken = NULL;
363 unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE];
364 long pubKeyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
365 long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
366 long returnCode;
367 long reasonCode;
368 long exitDataLength = 0;
369 long ruleArrayLength = 0;
370 unsigned char exitData[8];
371 unsigned char ruleArray[8];
372 unsigned char keyLabel[64];
373 long keyLabelLength = strlen(key_id);
374 unsigned char modulus[256];
375 long modulusFieldLength = sizeof(modulus);
376 long modulusLength = 0;
377 unsigned char exponent[256];
378 long exponentLength = sizeof(exponent);
379
380 if (keyLabelLength > sizeof(keyLabel))
381 {
382 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
383 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
384 return NULL;
385 }
386
387 memset(keyLabel,' ', sizeof(keyLabel));
388 memcpy(keyLabel, key_id, keyLabelLength);
389
390 keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
391 if (!keyToken)
392 {
393 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
394 ERR_R_MALLOC_FAILURE);
395 goto err;
396 }
397
398 keyRecordRead(&returnCode, &reasonCode, &exitDataLength,
399 exitData, &ruleArrayLength, ruleArray, keyLabel,
400 &keyTokenLength, keyToken+sizeof(long));
401
402 if (returnCode)
403 {
404 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
405 CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
406 goto err;
407 }
408
409 publicKeyExtract(&returnCode, &reasonCode, &exitDataLength,
410 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
411 keyToken+sizeof(long), &pubKeyTokenLength, pubKeyToken);
412
413 if (returnCode)
414 {
415 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
416 CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
417 goto err;
418 }
419
420 if (!getModulusAndExponent(pubKeyToken, &exponentLength,
421 exponent, &modulusLength, &modulusFieldLength,
422 modulus))
423 {
424 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
425 CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
426 goto err;
427 }
428
429 (*(long*)keyToken) = keyTokenLength;
430 rtmp = RSA_new_method(e);
431 RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
432
433 rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
434 rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
435 rtmp->flags |= RSA_FLAG_EXT_PKEY;
436
437 res = EVP_PKEY_new();
438 EVP_PKEY_assign_RSA(res, rtmp);
439
440 return res;
441err:
442 if (keyToken)
443 OPENSSL_free(keyToken);
444 if (res)
445 EVP_PKEY_free(res);
446 if (rtmp)
447 RSA_free(rtmp);
448 return NULL;
449 }
450
451static EVP_PKEY *ibm_4758_load_pubkey(ENGINE* e, const char* key_id,
452 UI_METHOD *ui_method, void *callback_data)
453 {
454 RSA *rtmp = NULL;
455 EVP_PKEY *res = NULL;
456 unsigned char* keyToken = NULL;
457 long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
458 long returnCode;
459 long reasonCode;
460 long exitDataLength = 0;
461 long ruleArrayLength = 0;
462 unsigned char exitData[8];
463 unsigned char ruleArray[8];
464 unsigned char keyLabel[64];
465 long keyLabelLength = strlen(key_id);
466 unsigned char modulus[512];
467 long modulusFieldLength = sizeof(modulus);
468 long modulusLength = 0;
469 unsigned char exponent[512];
470 long exponentLength = sizeof(exponent);
471
472 if (keyLabelLength > sizeof(keyLabel))
473 {
474 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
475 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
476 return NULL;
477 }
478
479 memset(keyLabel,' ', sizeof(keyLabel));
480 memcpy(keyLabel, key_id, keyLabelLength);
481
482 keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
483 if (!keyToken)
484 {
485 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PUBKEY,
486 ERR_R_MALLOC_FAILURE);
487 goto err;
488 }
489
490 keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData,
491 &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength,
492 keyToken+sizeof(long));
493
494 if (returnCode)
495 {
496 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
497 ERR_R_MALLOC_FAILURE);
498 goto err;
499 }
500
501 if (!getModulusAndExponent(keyToken+sizeof(long), &exponentLength,
502 exponent, &modulusLength, &modulusFieldLength, modulus))
503 {
504 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
505 CCA4758_R_FAILED_LOADING_PUBLIC_KEY);
506 goto err;
507 }
508
509 (*(long*)keyToken) = keyTokenLength;
510 rtmp = RSA_new_method(e);
511 RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
512 rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
513 rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
514 rtmp->flags |= RSA_FLAG_EXT_PKEY;
515 res = EVP_PKEY_new();
516 EVP_PKEY_assign_RSA(res, rtmp);
517
518 return res;
519err:
520 if (keyToken)
521 OPENSSL_free(keyToken);
522 if (res)
523 EVP_PKEY_free(res);
524 if (rtmp)
525 RSA_free(rtmp);
526 return NULL;
527 }
528
529static int cca_rsa_pub_enc(int flen, const unsigned char *from,
530 unsigned char *to, RSA *rsa,int padding)
531 {
532 long returnCode;
533 long reasonCode;
534 long lflen = flen;
535 long exitDataLength = 0;
536 unsigned char exitData[8];
537 long ruleArrayLength = 1;
538 unsigned char ruleArray[8] = "PKCS-1.2";
539 long dataStructureLength = 0;
540 unsigned char dataStructure[8];
541 long outputLength = RSA_size(rsa);
542 long keyTokenLength;
543 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
544
545 keyTokenLength = *(long*)keyToken;
546 keyToken+=sizeof(long);
547
548 pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
549 &ruleArrayLength, ruleArray, &lflen, (unsigned char*)from,
550 &dataStructureLength, dataStructure, &keyTokenLength,
551 keyToken, &outputLength, to);
552
553 if (returnCode || reasonCode)
554 return -(returnCode << 16 | reasonCode);
555 return outputLength;
556 }
557
558static int cca_rsa_priv_dec(int flen, const unsigned char *from,
559 unsigned char *to, RSA *rsa,int padding)
560 {
561 long returnCode;
562 long reasonCode;
563 long lflen = flen;
564 long exitDataLength = 0;
565 unsigned char exitData[8];
566 long ruleArrayLength = 1;
567 unsigned char ruleArray[8] = "PKCS-1.2";
568 long dataStructureLength = 0;
569 unsigned char dataStructure[8];
570 long outputLength = RSA_size(rsa);
571 long keyTokenLength;
572 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
573
574 keyTokenLength = *(long*)keyToken;
575 keyToken+=sizeof(long);
576
577 pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
578 &ruleArrayLength, ruleArray, &lflen, (unsigned char*)from,
579 &dataStructureLength, dataStructure, &keyTokenLength,
580 keyToken, &outputLength, to);
581
582 return (returnCode | reasonCode) ? 0 : 1;
583 }
584
585#define SSL_SIG_LEN 36
586
587static int cca_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
588 unsigned char *sigbuf, unsigned int siglen, const RSA *rsa)
589 {
590 long returnCode;
591 long reasonCode;
592 long lsiglen = siglen;
593 long exitDataLength = 0;
594 unsigned char exitData[8];
595 long ruleArrayLength = 1;
596 unsigned char ruleArray[8] = "PKCS-1.1";
597 long keyTokenLength;
598 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
599 long length = SSL_SIG_LEN;
600 long keyLength ;
601 unsigned char *hashBuffer = NULL;
602 X509_SIG sig;
603 ASN1_TYPE parameter;
604 X509_ALGOR algorithm;
605 ASN1_OCTET_STRING digest;
606
607 keyTokenLength = *(long*)keyToken;
608 keyToken+=sizeof(long);
609
610 if (type == NID_md5 || type == NID_sha1)
611 {
612 sig.algor = &algorithm;
613 algorithm.algorithm = OBJ_nid2obj(type);
614
615 if (!algorithm.algorithm)
616 {
617 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
618 CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
619 return 0;
620 }
621
622 if (!algorithm.algorithm->length)
623 {
624 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
625 CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
626 return 0;
627 }
628
629 parameter.type = V_ASN1_NULL;
630 parameter.value.ptr = NULL;
631 algorithm.parameter = &parameter;
632
633 sig.digest = &digest;
634 sig.digest->data = (unsigned char*)m;
635 sig.digest->length = m_len;
636
637 length = i2d_X509_SIG(&sig, NULL);
638 }
639
640 keyLength = RSA_size(rsa);
641
642 if (length - RSA_PKCS1_PADDING > keyLength)
643 {
644 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
645 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
646 return 0;
647 }
648
649 switch (type)
650 {
651 case NID_md5_sha1 :
652 if (m_len != SSL_SIG_LEN)
653 {
654 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
655 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
656 return 0;
657 }
658
659 hashBuffer = (unsigned char *)m;
660 length = m_len;
661 break;
662 case NID_md5 :
663 {
664 unsigned char *ptr;
665 ptr = hashBuffer = OPENSSL_malloc(
666 (unsigned int)keyLength+1);
667 if (!hashBuffer)
668 {
669 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
670 ERR_R_MALLOC_FAILURE);
671 return 0;
672 }
673
674 i2d_X509_SIG(&sig, &ptr);
675 }
676 break;
677 case NID_sha1 :
678 {
679 unsigned char *ptr;
680 ptr = hashBuffer = OPENSSL_malloc(
681 (unsigned int)keyLength+1);
682 if (!hashBuffer)
683 {
684 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
685 ERR_R_MALLOC_FAILURE);
686 return 0;
687 }
688 i2d_X509_SIG(&sig, &ptr);
689 }
690 break;
691 default:
692 return 0;
693 }
694
695 digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength,
696 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
697 keyToken, &length, hashBuffer, &lsiglen, sigbuf);
698
699 if (type == NID_sha1 || type == NID_md5)
700 {
701 memset(hashBuffer, keyLength+1, 0);
702 OPENSSL_free(hashBuffer);
703 }
704
705 return ((returnCode || reasonCode) ? 0 : 1);
706 }
707
708#define SSL_SIG_LEN 36
709
710static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
711 unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
712 {
713 long returnCode;
714 long reasonCode;
715 long exitDataLength = 0;
716 unsigned char exitData[8];
717 long ruleArrayLength = 1;
718 unsigned char ruleArray[8] = "PKCS-1.1";
719 long outputLength=256;
720 long outputBitLength;
721 long keyTokenLength;
722 unsigned char *hashBuffer = NULL;
723 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
724 long length = SSL_SIG_LEN;
725 long keyLength ;
726 X509_SIG sig;
727 ASN1_TYPE parameter;
728 X509_ALGOR algorithm;
729 ASN1_OCTET_STRING digest;
730
731 keyTokenLength = *(long*)keyToken;
732 keyToken+=sizeof(long);
733
734 if (type == NID_md5 || type == NID_sha1)
735 {
736 sig.algor = &algorithm;
737 algorithm.algorithm = OBJ_nid2obj(type);
738
739 if (!algorithm.algorithm)
740 {
741 CCA4758err(CCA4758_F_IBM_4758_CCA_SIGN,
742 CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
743 return 0;
744 }
745
746 if (!algorithm.algorithm->length)
747 {
748 CCA4758err(CCA4758_F_IBM_4758_CCA_SIGN,
749 CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
750 return 0;
751 }
752
753 parameter.type = V_ASN1_NULL;
754 parameter.value.ptr = NULL;
755 algorithm.parameter = &parameter;
756
757 sig.digest = &digest;
758 sig.digest->data = (unsigned char*)m;
759 sig.digest->length = m_len;
760
761 length = i2d_X509_SIG(&sig, NULL);
762 }
763
764 keyLength = RSA_size(rsa);
765
766 if (length - RSA_PKCS1_PADDING > keyLength)
767 {
768 CCA4758err(CCA4758_F_IBM_4758_CCA_SIGN,
769 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
770 return 0;
771 }
772
773 switch (type)
774 {
775 case NID_md5_sha1 :
776 if (m_len != SSL_SIG_LEN)
777 {
778 CCA4758err(CCA4758_F_IBM_4758_CCA_SIGN,
779 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
780 return 0;
781 }
782 hashBuffer = (unsigned char*)m;
783 length = m_len;
784 break;
785 case NID_md5 :
786 {
787 unsigned char *ptr;
788 ptr = hashBuffer = OPENSSL_malloc(
789 (unsigned int)keyLength+1);
790 if (!hashBuffer)
791 {
792 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
793 ERR_R_MALLOC_FAILURE);
794 return 0;
795 }
796 i2d_X509_SIG(&sig, &ptr);
797 }
798 break;
799 case NID_sha1 :
800 {
801 unsigned char *ptr;
802 ptr = hashBuffer = OPENSSL_malloc(
803 (unsigned int)keyLength+1);
804 if (!hashBuffer)
805 {
806 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
807 ERR_R_MALLOC_FAILURE);
808 return 0;
809 }
810 i2d_X509_SIG(&sig, &ptr);
811 }
812 break;
813 default:
814 return 0;
815 }
816
817 digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength,
818 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
819 keyToken, &length, hashBuffer, &outputLength, &outputBitLength,
820 sigret);
821
822 if (type == NID_sha1 || type == NID_md5)
823 {
824 memset(hashBuffer, keyLength+1, 0);
825 OPENSSL_free(hashBuffer);
826 }
827
828 *siglen = outputLength;
829
830 return ((returnCode || reasonCode) ? 0 : 1);
831 }
832
833static int getModulusAndExponent(const unsigned char*token, long *exponentLength,
834 unsigned char *exponent, long *modulusLength, long *modulusFieldLength,
835 unsigned char *modulus)
836 {
837 unsigned long len;
838
839 if (*token++ != (char)0x1E) /* internal PKA token? */
840 return 0;
841
842 if (*token++) /* token version must be zero */
843 return 0;
844
845 len = *token++;
846 len = len << 8;
847 len |= (unsigned char)*token++;
848
849 token += 4; /* skip reserved bytes */
850
851 if (*token++ == (char)0x04)
852 {
853 if (*token++) /* token version must be zero */
854 return 0;
855
856 len = *token++;
857 len = len << 8;
858 len |= (unsigned char)*token++;
859
860 token+=2; /* skip reserved section */
861
862 len = *token++;
863 len = len << 8;
864 len |= (unsigned char)*token++;
865
866 *exponentLength = len;
867
868 len = *token++;
869 len = len << 8;
870 len |= (unsigned char)*token++;
871
872 *modulusLength = len;
873
874 len = *token++;
875 len = len << 8;
876 len |= (unsigned char)*token++;
877
878 *modulusFieldLength = len;
879
880 memcpy(exponent, token, *exponentLength);
881 token+= *exponentLength;
882
883 memcpy(modulus, token, *modulusFieldLength);
884 return 1;
885 }
886 return 0;
887 }
888
889#endif /* OPENSSL_NO_RSA */
890
891static int cca_random_status(void)
892 {
893 return 1;
894 }
895
896static int cca_get_random_bytes(unsigned char* buf, int num)
897 {
898 long ret_code;
899 long reason_code;
900 long exit_data_length;
901 unsigned char exit_data[4];
902 unsigned char form[] = "RANDOM ";
903 unsigned char rand_buf[8];
904
905 while(num >= sizeof(rand_buf))
906 {
907 randomNumberGenerate(&ret_code, &reason_code, &exit_data_length,
908 exit_data, form, rand_buf);
909 if (ret_code)
910 return 0;
911 num -= sizeof(rand_buf);
912 memcpy(buf, rand_buf, sizeof(rand_buf));
913 buf += sizeof(rand_buf);
914 }
915
916 if (num)
917 {
918 randomNumberGenerate(&ret_code, &reason_code, NULL, NULL,
919 form, rand_buf);
920 if (ret_code)
921 return 0;
922 memcpy(buf, rand_buf, num);
923 }
924
925 return 1;
926 }
927
928static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx,
929 long argl, void *argp)
930 {
931 if (item)
932 OPENSSL_free(item);
933 }
934
935/* Goo to handle building as a dynamic engine */
936#ifdef ENGINE_DYNAMIC_SUPPORT
937static int bind_fn(ENGINE *e, const char *id)
938 {
939 if(id && (strcmp(id, engine_cswift_id) != 0))
940 return 0;
941 if(!bind_helper(e))
942 return 0;
943 return 1;
944 }
945IMPLEMENT_DYNAMIC_CHECK_FN()
946IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
947#endif /* ENGINE_DYNAMIC_SUPPORT */
948
949#endif /* !OPENSSL_NO_HW_4758_CCA */
950#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 @@
1/* hw_4758_cca_err.c */
2/* ====================================================================
3 * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include "hw_4758_cca_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA CCA4758_str_functs[]=
68 {
69{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_CTRL,0), "IBM_4758_CCA_CTRL"},
70{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_FINISH,0), "IBM_4758_CCA_FINISH"},
71{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_INIT,0), "IBM_4758_CCA_INIT"},
72{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,0), "IBM_4758_CCA_LOAD_PRIVKEY"},
73{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_LOAD_PUBKEY,0), "IBM_4758_CCA_LOAD_PUBKEY"},
74{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_SIGN,0), "IBM_4758_CCA_SIGN"},
75{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_VERIFY,0), "IBM_4758_CCA_VERIFY"},
76{0,NULL}
77 };
78
79static ERR_STRING_DATA CCA4758_str_reasons[]=
80 {
81{CCA4758_R_ALREADY_LOADED ,"already loaded"},
82{CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD ,"asn1 oid unknown for md"},
83{CCA4758_R_COMMAND_NOT_IMPLEMENTED ,"command not implemented"},
84{CCA4758_R_DSO_FAILURE ,"dso failure"},
85{CCA4758_R_FAILED_LOADING_PRIVATE_KEY ,"failed loading private key"},
86{CCA4758_R_FAILED_LOADING_PUBLIC_KEY ,"failed loading public key"},
87{CCA4758_R_NOT_LOADED ,"not loaded"},
88{CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"},
89{CCA4758_R_UNIT_FAILURE ,"unit failure"},
90{CCA4758_R_UNKNOWN_ALGORITHM_TYPE ,"unknown algorithm type"},
91{0,NULL}
92 };
93
94#endif
95
96#ifdef CCA4758_LIB_NAME
97static ERR_STRING_DATA CCA4758_lib_name[]=
98 {
99{0 ,CCA4758_LIB_NAME},
100{0,NULL}
101 };
102#endif
103
104
105static int CCA4758_lib_error_code=0;
106static int CCA4758_error_init=1;
107
108static void ERR_load_CCA4758_strings(void)
109 {
110 if (CCA4758_lib_error_code == 0)
111 CCA4758_lib_error_code=ERR_get_next_error_library();
112
113 if (CCA4758_error_init)
114 {
115 CCA4758_error_init=0;
116#ifndef OPENSSL_NO_ERR
117 ERR_load_strings(CCA4758_lib_error_code,CCA4758_str_functs);
118 ERR_load_strings(CCA4758_lib_error_code,CCA4758_str_reasons);
119#endif
120
121#ifdef CCA4758_LIB_NAME
122 CCA4758_lib_name->error = ERR_PACK(CCA4758_lib_error_code,0,0);
123 ERR_load_strings(0,CCA4758_lib_name);
124#endif
125 }
126 }
127
128static void ERR_unload_CCA4758_strings(void)
129 {
130 if (CCA4758_error_init == 0)
131 {
132#ifndef OPENSSL_NO_ERR
133 ERR_unload_strings(CCA4758_lib_error_code,CCA4758_str_functs);
134 ERR_unload_strings(CCA4758_lib_error_code,CCA4758_str_reasons);
135#endif
136
137#ifdef CCA4758_LIB_NAME
138 ERR_unload_strings(0,CCA4758_lib_name);
139#endif
140 CCA4758_error_init=1;
141 }
142 }
143
144static void ERR_CCA4758_error(int function, int reason, char *file, int line)
145 {
146 if (CCA4758_lib_error_code == 0)
147 CCA4758_lib_error_code=ERR_get_next_error_library();
148 ERR_PUT_error(CCA4758_lib_error_code,function,reason,file,line);
149 }
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 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#ifndef HEADER_CCA4758_ERR_H
56#define HEADER_CCA4758_ERR_H
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_CCA4758_strings(void);
63static void ERR_unload_CCA4758_strings(void);
64static void ERR_CCA4758_error(int function, int reason, char *file, int line);
65#define CCA4758err(f,r) ERR_CCA4758_error((f),(r),__FILE__,__LINE__)
66
67/* Error codes for the CCA4758 functions. */
68
69/* Function codes. */
70#define CCA4758_F_IBM_4758_CCA_CTRL 100
71#define CCA4758_F_IBM_4758_CCA_FINISH 101
72#define CCA4758_F_IBM_4758_CCA_INIT 102
73#define CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY 103
74#define CCA4758_F_IBM_4758_CCA_LOAD_PUBKEY 104
75#define CCA4758_F_IBM_4758_CCA_SIGN 105
76#define CCA4758_F_IBM_4758_CCA_VERIFY 106
77
78/* Reason codes. */
79#define CCA4758_R_ALREADY_LOADED 100
80#define CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD 101
81#define CCA4758_R_COMMAND_NOT_IMPLEMENTED 102
82#define CCA4758_R_DSO_FAILURE 103
83#define CCA4758_R_FAILED_LOADING_PRIVATE_KEY 104
84#define CCA4758_R_FAILED_LOADING_PUBLIC_KEY 105
85#define CCA4758_R_NOT_LOADED 106
86#define CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL 107
87#define CCA4758_R_UNIT_FAILURE 108
88#define CCA4758_R_UNKNOWN_ALGORITHM_TYPE 109
89
90#ifdef __cplusplus
91}
92#endif
93#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 @@
1/* crypto/engine/hw_aep.c */
2/*
3 */
4/* ====================================================================
5 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * licensing@OpenSSL.org.
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
55 *
56 */
57
58#include <stdio.h>
59#include <openssl/bn.h>
60#include <string.h>
61
62#include <openssl/e_os2.h>
63#ifndef OPENSSL_SYS_MSDOS
64#include <sys/types.h>
65#include <unistd.h>
66#else
67#include <process.h>
68typedef int pid_t;
69#endif
70
71#include <openssl/crypto.h>
72#include <openssl/dso.h>
73#include <openssl/engine.h>
74
75#ifndef OPENSSL_NO_HW
76#ifndef OPENSSL_NO_HW_AEP
77#ifdef FLAT_INC
78#include "aep.h"
79#else
80#include "vendor_defns/aep.h"
81#endif
82
83#define AEP_LIB_NAME "aep engine"
84#define FAIL_TO_SW 0x10101010
85
86#include "hw_aep_err.c"
87
88static int aep_init(ENGINE *e);
89static int aep_finish(ENGINE *e);
90static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
91static int aep_destroy(ENGINE *e);
92
93static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR hConnection);
94static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection);
95static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection);
96static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use);
97
98/* BIGNUM stuff */
99static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
100 const BIGNUM *m, BN_CTX *ctx);
101
102static AEP_RV aep_mod_exp_crt(BIGNUM *r,const BIGNUM *a, const BIGNUM *p,
103 const BIGNUM *q, const BIGNUM *dmp1,const BIGNUM *dmq1,
104 const BIGNUM *iqmp, BN_CTX *ctx);
105
106/* RSA stuff */
107#ifndef OPENSSL_NO_RSA
108static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
109#endif
110
111/* This function is aliased to mod_exp (with the mont stuff dropped). */
112static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
113 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
114
115/* DSA stuff */
116#ifndef OPENSSL_NO_DSA
117static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
118 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
119 BN_CTX *ctx, BN_MONT_CTX *in_mont);
120
121static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
122 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
123 BN_MONT_CTX *m_ctx);
124#endif
125
126/* DH stuff */
127/* This function is aliased to mod_exp (with the DH and mont dropped). */
128#ifndef OPENSSL_NO_DH
129static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
130 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
131#endif
132
133/* rand stuff */
134#ifdef AEPRAND
135static int aep_rand(unsigned char *buf, int num);
136static int aep_rand_status(void);
137#endif
138
139/* Bignum conversion stuff */
140static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize);
141static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
142 unsigned char* AEP_BigNum);
143static AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize,
144 unsigned char* AEP_BigNum);
145
146/* The definitions for control commands specific to this engine */
147#define AEP_CMD_SO_PATH ENGINE_CMD_BASE
148static const ENGINE_CMD_DEFN aep_cmd_defns[] =
149 {
150 { AEP_CMD_SO_PATH,
151 "SO_PATH",
152 "Specifies the path to the 'aep' shared library",
153 ENGINE_CMD_FLAG_STRING
154 },
155 {0, NULL, NULL, 0}
156 };
157
158#ifndef OPENSSL_NO_RSA
159/* Our internal RSA_METHOD that we provide pointers to */
160static RSA_METHOD aep_rsa =
161 {
162 "Aep RSA method",
163 NULL, /*rsa_pub_encrypt*/
164 NULL, /*rsa_pub_decrypt*/
165 NULL, /*rsa_priv_encrypt*/
166 NULL, /*rsa_priv_encrypt*/
167 aep_rsa_mod_exp, /*rsa_mod_exp*/
168 aep_mod_exp_mont, /*bn_mod_exp*/
169 NULL, /*init*/
170 NULL, /*finish*/
171 0, /*flags*/
172 NULL, /*app_data*/
173 NULL, /*rsa_sign*/
174 NULL /*rsa_verify*/
175 };
176#endif
177
178#ifndef OPENSSL_NO_DSA
179/* Our internal DSA_METHOD that we provide pointers to */
180static DSA_METHOD aep_dsa =
181 {
182 "Aep DSA method",
183 NULL, /* dsa_do_sign */
184 NULL, /* dsa_sign_setup */
185 NULL, /* dsa_do_verify */
186 aep_dsa_mod_exp, /* dsa_mod_exp */
187 aep_mod_exp_dsa, /* bn_mod_exp */
188 NULL, /* init */
189 NULL, /* finish */
190 0, /* flags */
191 NULL /* app_data */
192 };
193#endif
194
195#ifndef OPENSSL_NO_DH
196/* Our internal DH_METHOD that we provide pointers to */
197static DH_METHOD aep_dh =
198 {
199 "Aep DH method",
200 NULL,
201 NULL,
202 aep_mod_exp_dh,
203 NULL,
204 NULL,
205 0,
206 NULL
207 };
208#endif
209
210#ifdef AEPRAND
211/* our internal RAND_method that we provide pointers to */
212static RAND_METHOD aep_random =
213 {
214 /*"AEP RAND method", */
215 NULL,
216 aep_rand,
217 NULL,
218 NULL,
219 aep_rand,
220 aep_rand_status,
221 };
222#endif
223
224/*Define an array of structures to hold connections*/
225static AEP_CONNECTION_ENTRY aep_app_conn_table[MAX_PROCESS_CONNECTIONS];
226
227/*Used to determine if this is a new process*/
228static pid_t recorded_pid = 0;
229
230#ifdef AEPRAND
231static AEP_U8 rand_block[RAND_BLK_SIZE];
232static AEP_U32 rand_block_bytes = 0;
233#endif
234
235/* Constants used when creating the ENGINE */
236static const char *engine_aep_id = "aep";
237static const char *engine_aep_name = "Aep hardware engine support";
238
239static int max_key_len = 2176;
240
241
242/* This internal function is used by ENGINE_aep() and possibly by the
243 * "dynamic" ENGINE support too */
244static int bind_aep(ENGINE *e)
245 {
246#ifndef OPENSSL_NO_RSA
247 const RSA_METHOD *meth1;
248#endif
249#ifndef OPENSSL_NO_DSA
250 const DSA_METHOD *meth2;
251#endif
252#ifndef OPENSSL_NO_DH
253 const DH_METHOD *meth3;
254#endif
255
256 if(!ENGINE_set_id(e, engine_aep_id) ||
257 !ENGINE_set_name(e, engine_aep_name) ||
258#ifndef OPENSSL_NO_RSA
259 !ENGINE_set_RSA(e, &aep_rsa) ||
260#endif
261#ifndef OPENSSL_NO_DSA
262 !ENGINE_set_DSA(e, &aep_dsa) ||
263#endif
264#ifndef OPENSSL_NO_DH
265 !ENGINE_set_DH(e, &aep_dh) ||
266#endif
267#ifdef AEPRAND
268 !ENGINE_set_RAND(e, &aep_random) ||
269#endif
270 !ENGINE_set_init_function(e, aep_init) ||
271 !ENGINE_set_destroy_function(e, aep_destroy) ||
272 !ENGINE_set_finish_function(e, aep_finish) ||
273 !ENGINE_set_ctrl_function(e, aep_ctrl) ||
274 !ENGINE_set_cmd_defns(e, aep_cmd_defns))
275 return 0;
276
277#ifndef OPENSSL_NO_RSA
278 /* We know that the "PKCS1_SSLeay()" functions hook properly
279 * to the aep-specific mod_exp and mod_exp_crt so we use
280 * those functions. NB: We don't use ENGINE_openssl() or
281 * anything "more generic" because something like the RSAref
282 * code may not hook properly, and if you own one of these
283 * cards then you have the right to do RSA operations on it
284 * anyway! */
285 meth1 = RSA_PKCS1_SSLeay();
286 aep_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
287 aep_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
288 aep_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
289 aep_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
290#endif
291
292
293#ifndef OPENSSL_NO_DSA
294 /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
295 * bits. */
296 meth2 = DSA_OpenSSL();
297 aep_dsa.dsa_do_sign = meth2->dsa_do_sign;
298 aep_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
299 aep_dsa.dsa_do_verify = meth2->dsa_do_verify;
300
301 aep_dsa = *DSA_get_default_method();
302 aep_dsa.dsa_mod_exp = aep_dsa_mod_exp;
303 aep_dsa.bn_mod_exp = aep_mod_exp_dsa;
304#endif
305
306#ifndef OPENSSL_NO_DH
307 /* Much the same for Diffie-Hellman */
308 meth3 = DH_OpenSSL();
309 aep_dh.generate_key = meth3->generate_key;
310 aep_dh.compute_key = meth3->compute_key;
311 aep_dh.bn_mod_exp = meth3->bn_mod_exp;
312#endif
313
314 /* Ensure the aep error handling is set up */
315 ERR_load_AEPHK_strings();
316
317 return 1;
318}
319
320#ifdef ENGINE_DYNAMIC_SUPPORT
321static int bind_helper(ENGINE *e, const char *id)
322 {
323 if(id && (strcmp(id, engine_aep_id) != 0))
324 return 0;
325 if(!bind_aep(e))
326 return 0;
327 return 1;
328 }
329IMPLEMENT_DYNAMIC_CHECK_FN()
330IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
331#else
332static ENGINE *engine_aep(void)
333 {
334 ENGINE *ret = ENGINE_new();
335 if(!ret)
336 return NULL;
337 if(!bind_aep(ret))
338 {
339 ENGINE_free(ret);
340 return NULL;
341 }
342 return ret;
343 }
344
345void ENGINE_load_aep(void)
346 {
347 /* Copied from eng_[openssl|dyn].c */
348 ENGINE *toadd = engine_aep();
349 if(!toadd) return;
350 ENGINE_add(toadd);
351 ENGINE_free(toadd);
352 ERR_clear_error();
353 }
354#endif
355
356/* This is a process-global DSO handle used for loading and unloading
357 * the Aep library. NB: This is only set (or unset) during an
358 * init() or finish() call (reference counts permitting) and they're
359 * operating with global locks, so this should be thread-safe
360 * implicitly. */
361static DSO *aep_dso = NULL;
362
363/* These are the static string constants for the DSO file name and the function
364 * symbol names to bind to.
365*/
366static const char *AEP_LIBNAME = "aep";
367
368static const char *AEP_F1 = "AEP_ModExp";
369static const char *AEP_F2 = "AEP_ModExpCrt";
370#ifdef AEPRAND
371static const char *AEP_F3 = "AEP_GenRandom";
372#endif
373static const char *AEP_F4 = "AEP_Finalize";
374static const char *AEP_F5 = "AEP_Initialize";
375static const char *AEP_F6 = "AEP_OpenConnection";
376static const char *AEP_F7 = "AEP_SetBNCallBacks";
377static const char *AEP_F8 = "AEP_CloseConnection";
378
379/* These are the function pointers that are (un)set when the library has
380 * successfully (un)loaded. */
381static t_AEP_OpenConnection *p_AEP_OpenConnection = NULL;
382static t_AEP_CloseConnection *p_AEP_CloseConnection = NULL;
383static t_AEP_ModExp *p_AEP_ModExp = NULL;
384static t_AEP_ModExpCrt *p_AEP_ModExpCrt = NULL;
385#ifdef AEPRAND
386static t_AEP_GenRandom *p_AEP_GenRandom = NULL;
387#endif
388static t_AEP_Initialize *p_AEP_Initialize = NULL;
389static t_AEP_Finalize *p_AEP_Finalize = NULL;
390static t_AEP_SetBNCallBacks *p_AEP_SetBNCallBacks = NULL;
391
392/* (de)initialisation functions. */
393static int aep_init(ENGINE *e)
394 {
395 t_AEP_ModExp *p1;
396 t_AEP_ModExpCrt *p2;
397#ifdef AEPRAND
398 t_AEP_GenRandom *p3;
399#endif
400 t_AEP_Finalize *p4;
401 t_AEP_Initialize *p5;
402 t_AEP_OpenConnection *p6;
403 t_AEP_SetBNCallBacks *p7;
404 t_AEP_CloseConnection *p8;
405
406 int to_return = 0;
407
408 if(aep_dso != NULL)
409 {
410 AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_ALREADY_LOADED);
411 goto err;
412 }
413 /* Attempt to load libaep.so. */
414
415 aep_dso = DSO_load(NULL, AEP_LIBNAME, NULL, 0);
416
417 if(aep_dso == NULL)
418 {
419 AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
420 goto err;
421 }
422
423 if( !(p1 = (t_AEP_ModExp *) DSO_bind_func( aep_dso,AEP_F1)) ||
424 !(p2 = (t_AEP_ModExpCrt*) DSO_bind_func( aep_dso,AEP_F2)) ||
425#ifdef AEPRAND
426 !(p3 = (t_AEP_GenRandom*) DSO_bind_func( aep_dso,AEP_F3)) ||
427#endif
428 !(p4 = (t_AEP_Finalize*) DSO_bind_func( aep_dso,AEP_F4)) ||
429 !(p5 = (t_AEP_Initialize*) DSO_bind_func( aep_dso,AEP_F5)) ||
430 !(p6 = (t_AEP_OpenConnection*) DSO_bind_func( aep_dso,AEP_F6)) ||
431 !(p7 = (t_AEP_SetBNCallBacks*) DSO_bind_func( aep_dso,AEP_F7)) ||
432 !(p8 = (t_AEP_CloseConnection*) DSO_bind_func( aep_dso,AEP_F8)))
433 {
434 AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
435 goto err;
436 }
437
438 /* Copy the pointers */
439
440 p_AEP_ModExp = p1;
441 p_AEP_ModExpCrt = p2;
442#ifdef AEPRAND
443 p_AEP_GenRandom = p3;
444#endif
445 p_AEP_Finalize = p4;
446 p_AEP_Initialize = p5;
447 p_AEP_OpenConnection = p6;
448 p_AEP_SetBNCallBacks = p7;
449 p_AEP_CloseConnection = p8;
450
451 to_return = 1;
452
453 return to_return;
454
455 err:
456
457 if(aep_dso)
458 DSO_free(aep_dso);
459
460 p_AEP_OpenConnection = NULL;
461 p_AEP_ModExp = NULL;
462 p_AEP_ModExpCrt = NULL;
463#ifdef AEPRAND
464 p_AEP_GenRandom = NULL;
465#endif
466 p_AEP_Initialize = NULL;
467 p_AEP_Finalize = NULL;
468 p_AEP_SetBNCallBacks = NULL;
469 p_AEP_CloseConnection = NULL;
470
471 return to_return;
472 }
473
474/* Destructor (complements the "ENGINE_aep()" constructor) */
475static int aep_destroy(ENGINE *e)
476 {
477 ERR_unload_AEPHK_strings();
478 return 1;
479 }
480
481static int aep_finish(ENGINE *e)
482 {
483 int to_return = 0, in_use;
484 AEP_RV rv;
485
486 if(aep_dso == NULL)
487 {
488 AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_NOT_LOADED);
489 goto err;
490 }
491
492 rv = aep_close_all_connections(0, &in_use);
493 if (rv != AEP_R_OK)
494 {
495 AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CLOSE_HANDLES_FAILED);
496 goto err;
497 }
498 if (in_use)
499 {
500 AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CONNECTIONS_IN_USE);
501 goto err;
502 }
503
504 rv = p_AEP_Finalize();
505 if (rv != AEP_R_OK)
506 {
507 AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_FINALIZE_FAILED);
508 goto err;
509 }
510
511 if(!DSO_free(aep_dso))
512 {
513 AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_UNIT_FAILURE);
514 goto err;
515 }
516
517 aep_dso = NULL;
518 p_AEP_CloseConnection = NULL;
519 p_AEP_OpenConnection = NULL;
520 p_AEP_ModExp = NULL;
521 p_AEP_ModExpCrt = NULL;
522#ifdef AEPRAND
523 p_AEP_GenRandom = NULL;
524#endif
525 p_AEP_Initialize = NULL;
526 p_AEP_Finalize = NULL;
527 p_AEP_SetBNCallBacks = NULL;
528
529 to_return = 1;
530 err:
531 return to_return;
532 }
533
534static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
535 {
536 int initialised = ((aep_dso == NULL) ? 0 : 1);
537 switch(cmd)
538 {
539 case AEP_CMD_SO_PATH:
540 if(p == NULL)
541 {
542 AEPHKerr(AEPHK_F_AEP_CTRL,
543 ERR_R_PASSED_NULL_PARAMETER);
544 return 0;
545 }
546 if(initialised)
547 {
548 AEPHKerr(AEPHK_F_AEP_CTRL,
549 AEPHK_R_ALREADY_LOADED);
550 return 0;
551 }
552 AEP_LIBNAME = (const char *)p;
553 return 1;
554 default:
555 break;
556 }
557 AEPHKerr(AEPHK_F_AEP_CTRL,AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
558 return 0;
559 }
560
561static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
562 const BIGNUM *m, BN_CTX *ctx)
563 {
564 int to_return = 0;
565 int r_len = 0;
566 AEP_CONNECTION_HNDL hConnection;
567 AEP_RV rv;
568
569 r_len = BN_num_bits(m);
570
571 /* Perform in software if modulus is too large for hardware. */
572
573 if (r_len > max_key_len){
574 AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
575 return BN_mod_exp(r, a, p, m, ctx);
576 }
577
578 /*Grab a connection from the pool*/
579 rv = aep_get_connection(&hConnection);
580 if (rv != AEP_R_OK)
581 {
582 AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_GET_HANDLE_FAILED);
583 return BN_mod_exp(r, a, p, m, ctx);
584 }
585
586 /*To the card with the mod exp*/
587 rv = p_AEP_ModExp(hConnection,(void*)a, (void*)p,(void*)m, (void*)r,NULL);
588
589 if (rv != AEP_R_OK)
590 {
591 AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_MOD_EXP_FAILED);
592 rv = aep_close_connection(hConnection);
593 return BN_mod_exp(r, a, p, m, ctx);
594 }
595
596 /*Return the connection to the pool*/
597 rv = aep_return_connection(hConnection);
598 if (rv != AEP_R_OK)
599 {
600 AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED);
601 goto err;
602 }
603
604 to_return = 1;
605 err:
606 return to_return;
607 }
608
609static AEP_RV aep_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
610 const BIGNUM *q, const BIGNUM *dmp1,
611 const BIGNUM *dmq1,const BIGNUM *iqmp, BN_CTX *ctx)
612 {
613 AEP_RV rv = AEP_R_OK;
614 AEP_CONNECTION_HNDL hConnection;
615
616 /*Grab a connection from the pool*/
617 rv = aep_get_connection(&hConnection);
618 if (rv != AEP_R_OK)
619 {
620 AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_GET_HANDLE_FAILED);
621 return FAIL_TO_SW;
622 }
623
624 /*To the card with the mod exp*/
625 rv = p_AEP_ModExpCrt(hConnection,(void*)a, (void*)p, (void*)q, (void*)dmp1,(void*)dmq1,
626 (void*)iqmp,(void*)r,NULL);
627 if (rv != AEP_R_OK)
628 {
629 AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_MOD_EXP_CRT_FAILED);
630 rv = aep_close_connection(hConnection);
631 return FAIL_TO_SW;
632 }
633
634 /*Return the connection to the pool*/
635 rv = aep_return_connection(hConnection);
636 if (rv != AEP_R_OK)
637 {
638 AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED);
639 goto err;
640 }
641
642 err:
643 return rv;
644 }
645
646
647#ifdef AEPRAND
648static int aep_rand(unsigned char *buf,int len )
649 {
650 AEP_RV rv = AEP_R_OK;
651 AEP_CONNECTION_HNDL hConnection;
652
653 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
654
655 /*Can the request be serviced with what's already in the buffer?*/
656 if (len <= rand_block_bytes)
657 {
658 memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
659 rand_block_bytes -= len;
660 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
661 }
662 else
663 /*If not the get another block of random bytes*/
664 {
665 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
666
667 rv = aep_get_connection(&hConnection);
668 if (rv != AEP_R_OK)
669 {
670 AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_HANDLE_FAILED);
671 goto err_nounlock;
672 }
673
674 if (len > RAND_BLK_SIZE)
675 {
676 rv = p_AEP_GenRandom(hConnection, len, 2, buf, NULL);
677 if (rv != AEP_R_OK)
678 {
679 AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED);
680 goto err_nounlock;
681 }
682 }
683 else
684 {
685 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
686
687 rv = p_AEP_GenRandom(hConnection, RAND_BLK_SIZE, 2, &rand_block[0], NULL);
688 if (rv != AEP_R_OK)
689 {
690 AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED);
691
692 goto err;
693 }
694
695 rand_block_bytes = RAND_BLK_SIZE;
696
697 memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
698 rand_block_bytes -= len;
699
700 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
701 }
702
703 rv = aep_return_connection(hConnection);
704 if (rv != AEP_R_OK)
705 {
706 AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED);
707
708 goto err_nounlock;
709 }
710 }
711
712 return 1;
713 err:
714 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
715 err_nounlock:
716 return 0;
717 }
718
719static int aep_rand_status(void)
720{
721 return 1;
722}
723#endif
724
725#ifndef OPENSSL_NO_RSA
726static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
727 {
728 BN_CTX *ctx = NULL;
729 int to_return = 0;
730 AEP_RV rv = AEP_R_OK;
731
732 if ((ctx = BN_CTX_new()) == NULL)
733 goto err;
734
735 if (!aep_dso)
736 {
737 AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_NOT_LOADED);
738 goto err;
739 }
740
741 /*See if we have all the necessary bits for a crt*/
742 if (rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp)
743 {
744 rv = aep_mod_exp_crt(r0,I,rsa->p,rsa->q, rsa->dmp1,rsa->dmq1,rsa->iqmp,ctx);
745
746 if (rv == FAIL_TO_SW){
747 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
748 to_return = (*meth->rsa_mod_exp)(r0, I, rsa);
749 goto err;
750 }
751 else if (rv != AEP_R_OK)
752 goto err;
753 }
754 else
755 {
756 if (!rsa->d || !rsa->n)
757 {
758 AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_MISSING_KEY_COMPONENTS);
759 goto err;
760 }
761
762 rv = aep_mod_exp(r0,I,rsa->d,rsa->n,ctx);
763 if (rv != AEP_R_OK)
764 goto err;
765
766 }
767
768 to_return = 1;
769
770 err:
771 if(ctx)
772 BN_CTX_free(ctx);
773 return to_return;
774}
775#endif
776
777#ifndef OPENSSL_NO_DSA
778static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
779 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
780 BN_CTX *ctx, BN_MONT_CTX *in_mont)
781 {
782 BIGNUM t;
783 int to_return = 0;
784 BN_init(&t);
785
786 /* let rr = a1 ^ p1 mod m */
787 if (!aep_mod_exp(rr,a1,p1,m,ctx)) goto end;
788 /* let t = a2 ^ p2 mod m */
789 if (!aep_mod_exp(&t,a2,p2,m,ctx)) goto end;
790 /* let rr = rr * t mod m */
791 if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
792 to_return = 1;
793 end:
794 BN_free(&t);
795 return to_return;
796 }
797
798static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
799 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
800 BN_MONT_CTX *m_ctx)
801 {
802 return aep_mod_exp(r, a, p, m, ctx);
803 }
804#endif
805
806/* This function is aliased to mod_exp (with the mont stuff dropped). */
807static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
808 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
809 {
810 return aep_mod_exp(r, a, p, m, ctx);
811 }
812
813#ifndef OPENSSL_NO_DH
814/* This function is aliased to mod_exp (with the dh and mont dropped). */
815static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
816 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
817 BN_MONT_CTX *m_ctx)
818 {
819 return aep_mod_exp(r, a, p, m, ctx);
820 }
821#endif
822
823static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection)
824 {
825 int count;
826 AEP_RV rv = AEP_R_OK;
827
828 /*Get the current process id*/
829 pid_t curr_pid;
830
831 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
832
833 curr_pid = getpid();
834
835 /*Check if this is the first time this is being called from the current
836 process*/
837 if (recorded_pid != curr_pid)
838 {
839 /*Remember our pid so we can check if we're in a new process*/
840 recorded_pid = curr_pid;
841
842 /*Call Finalize to make sure we have not inherited some data
843 from a parent process*/
844 p_AEP_Finalize();
845
846 /*Initialise the AEP API*/
847 rv = p_AEP_Initialize(NULL);
848
849 if (rv != AEP_R_OK)
850 {
851 AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_INIT_FAILURE);
852 recorded_pid = 0;
853 goto end;
854 }
855
856 /*Set the AEP big num call back functions*/
857 rv = p_AEP_SetBNCallBacks(&GetBigNumSize, &MakeAEPBigNum,
858 &ConvertAEPBigNum);
859
860 if (rv != AEP_R_OK)
861 {
862 AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_SETBNCALLBACK_FAILURE);
863 recorded_pid = 0;
864 goto end;
865 }
866
867#ifdef AEPRAND
868 /*Reset the rand byte count*/
869 rand_block_bytes = 0;
870#endif
871
872 /*Init the structures*/
873 for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
874 {
875 aep_app_conn_table[count].conn_state = NotConnected;
876 aep_app_conn_table[count].conn_hndl = 0;
877 }
878
879 /*Open a connection*/
880 rv = p_AEP_OpenConnection(phConnection);
881
882 if (rv != AEP_R_OK)
883 {
884 AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
885 recorded_pid = 0;
886 goto end;
887 }
888
889 aep_app_conn_table[0].conn_state = InUse;
890 aep_app_conn_table[0].conn_hndl = *phConnection;
891 goto end;
892 }
893 /*Check the existing connections to see if we can find a free one*/
894 for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
895 {
896 if (aep_app_conn_table[count].conn_state == Connected)
897 {
898 aep_app_conn_table[count].conn_state = InUse;
899 *phConnection = aep_app_conn_table[count].conn_hndl;
900 goto end;
901 }
902 }
903 /*If no connections available, we're going to have to try
904 to open a new one*/
905 for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
906 {
907 if (aep_app_conn_table[count].conn_state == NotConnected)
908 {
909 /*Open a connection*/
910 rv = p_AEP_OpenConnection(phConnection);
911
912 if (rv != AEP_R_OK)
913 {
914 AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
915 goto end;
916 }
917
918 aep_app_conn_table[count].conn_state = InUse;
919 aep_app_conn_table[count].conn_hndl = *phConnection;
920 goto end;
921 }
922 }
923 rv = AEP_R_GENERAL_ERROR;
924 end:
925 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
926 return rv;
927 }
928
929
930static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection)
931 {
932 int count;
933
934 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
935
936 /*Find the connection item that matches this connection handle*/
937 for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
938 {
939 if (aep_app_conn_table[count].conn_hndl == hConnection)
940 {
941 aep_app_conn_table[count].conn_state = Connected;
942 break;
943 }
944 }
945
946 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
947
948 return AEP_R_OK;
949 }
950
951static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection)
952 {
953 int count;
954 AEP_RV rv = AEP_R_OK;
955
956 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
957
958 /*Find the connection item that matches this connection handle*/
959 for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
960 {
961 if (aep_app_conn_table[count].conn_hndl == hConnection)
962 {
963 rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
964 if (rv != AEP_R_OK)
965 goto end;
966 aep_app_conn_table[count].conn_state = NotConnected;
967 aep_app_conn_table[count].conn_hndl = 0;
968 break;
969 }
970 }
971
972 end:
973 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
974 return rv;
975 }
976
977static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use)
978 {
979 int count;
980 AEP_RV rv = AEP_R_OK;
981
982 *in_use = 0;
983 if (use_engine_lock) CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
984 for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
985 {
986 switch (aep_app_conn_table[count].conn_state)
987 {
988 case Connected:
989 rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
990 if (rv != AEP_R_OK)
991 goto end;
992 aep_app_conn_table[count].conn_state = NotConnected;
993 aep_app_conn_table[count].conn_hndl = 0;
994 break;
995 case InUse:
996 (*in_use)++;
997 break;
998 case NotConnected:
999 break;
1000 }
1001 }
1002 end:
1003 if (use_engine_lock) CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
1004 return rv;
1005 }
1006
1007/*BigNum call back functions, used to convert OpenSSL bignums into AEP bignums.
1008 Note only 32bit Openssl build support*/
1009
1010static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize)
1011 {
1012 BIGNUM* bn;
1013
1014 /*Cast the ArbBigNum pointer to our BIGNUM struct*/
1015 bn = (BIGNUM*) ArbBigNum;
1016
1017#ifdef SIXTY_FOUR_BIT_LONG
1018 *BigNumSize = bn->top << 3;
1019#else
1020 /*Size of the bignum in bytes is equal to the bn->top (no of 32 bit
1021 words) multiplies by 4*/
1022 *BigNumSize = bn->top << 2;
1023#endif
1024
1025 return AEP_R_OK;
1026 }
1027
1028static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
1029 unsigned char* AEP_BigNum)
1030 {
1031 BIGNUM* bn;
1032
1033#ifndef SIXTY_FOUR_BIT_LONG
1034 unsigned char* buf;
1035 int i;
1036#endif
1037
1038 /*Cast the ArbBigNum pointer to our BIGNUM struct*/
1039 bn = (BIGNUM*) ArbBigNum;
1040
1041#ifdef SIXTY_FOUR_BIT_LONG
1042 memcpy(AEP_BigNum, bn->d, BigNumSize);
1043#else
1044 /*Must copy data into a (monotone) least significant byte first format
1045 performing endian conversion if necessary*/
1046 for(i=0;i<bn->top;i++)
1047 {
1048 buf = (unsigned char*)&bn->d[i];
1049
1050 *((AEP_U32*)AEP_BigNum) = (AEP_U32)
1051 ((unsigned) buf[1] << 8 | buf[0]) |
1052 ((unsigned) buf[3] << 8 | buf[2]) << 16;
1053
1054 AEP_BigNum += 4;
1055 }
1056#endif
1057
1058 return AEP_R_OK;
1059 }
1060
1061/*Turn an AEP Big Num back to a user big num*/
1062static AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize,
1063 unsigned char* AEP_BigNum)
1064 {
1065 BIGNUM* bn;
1066#ifndef SIXTY_FOUR_BIT_LONG
1067 int i;
1068#endif
1069
1070 bn = (BIGNUM*)ArbBigNum;
1071
1072 /*Expand the result bn so that it can hold our big num.
1073 Size is in bits*/
1074 bn_expand(bn, (int)(BigNumSize << 3));
1075
1076#ifdef SIXTY_FOUR_BIT_LONG
1077 bn->top = BigNumSize >> 3;
1078
1079 if((BigNumSize & 7) != 0)
1080 bn->top++;
1081
1082 memset(bn->d, 0, bn->top << 3);
1083
1084 memcpy(bn->d, AEP_BigNum, BigNumSize);
1085#else
1086 bn->top = BigNumSize >> 2;
1087
1088 for(i=0;i<bn->top;i++)
1089 {
1090 bn->d[i] = (AEP_U32)
1091 ((unsigned) AEP_BigNum[3] << 8 | AEP_BigNum[2]) << 16 |
1092 ((unsigned) AEP_BigNum[1] << 8 | AEP_BigNum[0]);
1093 AEP_BigNum += 4;
1094 }
1095#endif
1096
1097 return AEP_R_OK;
1098}
1099
1100#endif /* !OPENSSL_NO_HW_AEP */
1101#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 @@
1/* hw_aep_err.c */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include "hw_aep_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA AEPHK_str_functs[]=
68 {
69{ERR_PACK(0,AEPHK_F_AEP_CTRL,0), "AEP_CTRL"},
70{ERR_PACK(0,AEPHK_F_AEP_FINISH,0), "AEP_FINISH"},
71{ERR_PACK(0,AEPHK_F_AEP_GET_CONNECTION,0), "AEP_GET_CONNECTION"},
72{ERR_PACK(0,AEPHK_F_AEP_INIT,0), "AEP_INIT"},
73{ERR_PACK(0,AEPHK_F_AEP_MOD_EXP,0), "AEP_MOD_EXP"},
74{ERR_PACK(0,AEPHK_F_AEP_MOD_EXP_CRT,0), "AEP_MOD_EXP_CRT"},
75{ERR_PACK(0,AEPHK_F_AEP_RAND,0), "AEP_RAND"},
76{ERR_PACK(0,AEPHK_F_AEP_RSA_MOD_EXP,0), "AEP_RSA_MOD_EXP"},
77{0,NULL}
78 };
79
80static ERR_STRING_DATA AEPHK_str_reasons[]=
81 {
82{AEPHK_R_ALREADY_LOADED ,"already loaded"},
83{AEPHK_R_CLOSE_HANDLES_FAILED ,"close handles failed"},
84{AEPHK_R_CONNECTIONS_IN_USE ,"connections in use"},
85{AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
86{AEPHK_R_FINALIZE_FAILED ,"finalize failed"},
87{AEPHK_R_GET_HANDLE_FAILED ,"get handle failed"},
88{AEPHK_R_GET_RANDOM_FAILED ,"get random failed"},
89{AEPHK_R_INIT_FAILURE ,"init failure"},
90{AEPHK_R_MISSING_KEY_COMPONENTS ,"missing key components"},
91{AEPHK_R_MOD_EXP_CRT_FAILED ,"mod exp crt failed"},
92{AEPHK_R_MOD_EXP_FAILED ,"mod exp failed"},
93{AEPHK_R_NOT_LOADED ,"not loaded"},
94{AEPHK_R_OK ,"ok"},
95{AEPHK_R_RETURN_CONNECTION_FAILED ,"return connection failed"},
96{AEPHK_R_SETBNCALLBACK_FAILURE ,"setbncallback failure"},
97{AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"},
98{AEPHK_R_UNIT_FAILURE ,"unit failure"},
99{0,NULL}
100 };
101
102#endif
103
104#ifdef AEPHK_LIB_NAME
105static ERR_STRING_DATA AEPHK_lib_name[]=
106 {
107{0 ,AEPHK_LIB_NAME},
108{0,NULL}
109 };
110#endif
111
112
113static int AEPHK_lib_error_code=0;
114static int AEPHK_error_init=1;
115
116static void ERR_load_AEPHK_strings(void)
117 {
118 if (AEPHK_lib_error_code == 0)
119 AEPHK_lib_error_code=ERR_get_next_error_library();
120
121 if (AEPHK_error_init)
122 {
123 AEPHK_error_init=0;
124#ifndef OPENSSL_NO_ERR
125 ERR_load_strings(AEPHK_lib_error_code,AEPHK_str_functs);
126 ERR_load_strings(AEPHK_lib_error_code,AEPHK_str_reasons);
127#endif
128
129#ifdef AEPHK_LIB_NAME
130 AEPHK_lib_name->error = ERR_PACK(AEPHK_lib_error_code,0,0);
131 ERR_load_strings(0,AEPHK_lib_name);
132#endif
133 }
134 }
135
136static void ERR_unload_AEPHK_strings(void)
137 {
138 if (AEPHK_error_init == 0)
139 {
140#ifndef OPENSSL_NO_ERR
141 ERR_unload_strings(AEPHK_lib_error_code,AEPHK_str_functs);
142 ERR_unload_strings(AEPHK_lib_error_code,AEPHK_str_reasons);
143#endif
144
145#ifdef AEPHK_LIB_NAME
146 ERR_unload_strings(0,AEPHK_lib_name);
147#endif
148 AEPHK_error_init=1;
149 }
150 }
151
152static void ERR_AEPHK_error(int function, int reason, char *file, int line)
153 {
154 if (AEPHK_lib_error_code == 0)
155 AEPHK_lib_error_code=ERR_get_next_error_library();
156 ERR_PUT_error(AEPHK_lib_error_code,function,reason,file,line);
157 }
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 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#ifndef HEADER_AEPHK_ERR_H
56#define HEADER_AEPHK_ERR_H
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_AEPHK_strings(void);
63static void ERR_unload_AEPHK_strings(void);
64static void ERR_AEPHK_error(int function, int reason, char *file, int line);
65#define AEPHKerr(f,r) ERR_AEPHK_error((f),(r),__FILE__,__LINE__)
66
67/* Error codes for the AEPHK functions. */
68
69/* Function codes. */
70#define AEPHK_F_AEP_CTRL 100
71#define AEPHK_F_AEP_FINISH 101
72#define AEPHK_F_AEP_GET_CONNECTION 102
73#define AEPHK_F_AEP_INIT 103
74#define AEPHK_F_AEP_MOD_EXP 104
75#define AEPHK_F_AEP_MOD_EXP_CRT 105
76#define AEPHK_F_AEP_RAND 106
77#define AEPHK_F_AEP_RSA_MOD_EXP 107
78
79/* Reason codes. */
80#define AEPHK_R_ALREADY_LOADED 100
81#define AEPHK_R_CLOSE_HANDLES_FAILED 101
82#define AEPHK_R_CONNECTIONS_IN_USE 102
83#define AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED 103
84#define AEPHK_R_FINALIZE_FAILED 104
85#define AEPHK_R_GET_HANDLE_FAILED 105
86#define AEPHK_R_GET_RANDOM_FAILED 106
87#define AEPHK_R_INIT_FAILURE 107
88#define AEPHK_R_MISSING_KEY_COMPONENTS 108
89#define AEPHK_R_MOD_EXP_CRT_FAILED 109
90#define AEPHK_R_MOD_EXP_FAILED 110
91#define AEPHK_R_NOT_LOADED 111
92#define AEPHK_R_OK 112
93#define AEPHK_R_RETURN_CONNECTION_FAILED 113
94#define AEPHK_R_SETBNCALLBACK_FAILURE 114
95#define AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL 116
96#define AEPHK_R_UNIT_FAILURE 115
97
98#ifdef __cplusplus
99}
100#endif
101#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 @@
3 * project 2000. 3 * project 2000.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -60,11 +60,10 @@
60#include <openssl/crypto.h> 60#include <openssl/crypto.h>
61#include "cryptlib.h" 61#include "cryptlib.h"
62#include <openssl/dso.h> 62#include <openssl/dso.h>
63#include "engine_int.h"
64#include <openssl/engine.h> 63#include <openssl/engine.h>
65 64
66#ifndef NO_HW 65#ifndef OPENSSL_NO_HW
67#ifndef NO_HW_ATALLA 66#ifndef OPENSSL_NO_HW_ATALLA
68 67
69#ifdef FLAT_INC 68#ifdef FLAT_INC
70#include "atalla.h" 69#include "atalla.h"
@@ -72,19 +71,27 @@
72#include "vendor_defns/atalla.h" 71#include "vendor_defns/atalla.h"
73#endif 72#endif
74 73
75static int atalla_init(void); 74#define ATALLA_LIB_NAME "atalla engine"
76static int atalla_finish(void); 75#include "hw_atalla_err.c"
76
77static int atalla_destroy(ENGINE *e);
78static int atalla_init(ENGINE *e);
79static int atalla_finish(ENGINE *e);
80static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
77 81
78/* BIGNUM stuff */ 82/* BIGNUM stuff */
79static int atalla_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 83static int atalla_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
80 const BIGNUM *m, BN_CTX *ctx); 84 const BIGNUM *m, BN_CTX *ctx);
81 85
86#ifndef OPENSSL_NO_RSA
82/* RSA stuff */ 87/* RSA stuff */
83static int atalla_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa); 88static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
89#endif
84/* This function is aliased to mod_exp (with the mont stuff dropped). */ 90/* This function is aliased to mod_exp (with the mont stuff dropped). */
85static int atalla_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 91static int atalla_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
86 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); 92 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
87 93
94#ifndef OPENSSL_NO_DSA
88/* DSA stuff */ 95/* DSA stuff */
89static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, 96static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
90 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, 97 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
@@ -92,13 +99,27 @@ static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
92static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, 99static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
93 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 100 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
94 BN_MONT_CTX *m_ctx); 101 BN_MONT_CTX *m_ctx);
102#endif
95 103
104#ifndef OPENSSL_NO_DH
96/* DH stuff */ 105/* DH stuff */
97/* This function is alised to mod_exp (with the DH and mont dropped). */ 106/* This function is alised to mod_exp (with the DH and mont dropped). */
98static int atalla_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, 107static int atalla_mod_exp_dh(const DH *dh, BIGNUM *r,
108 const BIGNUM *a, const BIGNUM *p,
99 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); 109 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
110#endif
100 111
112/* The definitions for control commands specific to this engine */
113#define ATALLA_CMD_SO_PATH ENGINE_CMD_BASE
114static const ENGINE_CMD_DEFN atalla_cmd_defns[] = {
115 {ATALLA_CMD_SO_PATH,
116 "SO_PATH",
117 "Specifies the path to the 'atasi' shared library",
118 ENGINE_CMD_FLAG_STRING},
119 {0, NULL, NULL, 0}
120 };
101 121
122#ifndef OPENSSL_NO_RSA
102/* Our internal RSA_METHOD that we provide pointers to */ 123/* Our internal RSA_METHOD that we provide pointers to */
103static RSA_METHOD atalla_rsa = 124static RSA_METHOD atalla_rsa =
104 { 125 {
@@ -116,7 +137,9 @@ static RSA_METHOD atalla_rsa =
116 NULL, 137 NULL,
117 NULL 138 NULL
118 }; 139 };
140#endif
119 141
142#ifndef OPENSSL_NO_DSA
120/* Our internal DSA_METHOD that we provide pointers to */ 143/* Our internal DSA_METHOD that we provide pointers to */
121static DSA_METHOD atalla_dsa = 144static DSA_METHOD atalla_dsa =
122 { 145 {
@@ -131,7 +154,9 @@ static DSA_METHOD atalla_dsa =
131 0, /* flags */ 154 0, /* flags */
132 NULL /* app_data */ 155 NULL /* app_data */
133 }; 156 };
157#endif
134 158
159#ifndef OPENSSL_NO_DH
135/* Our internal DH_METHOD that we provide pointers to */ 160/* Our internal DH_METHOD that we provide pointers to */
136static DH_METHOD atalla_dh = 161static DH_METHOD atalla_dh =
137 { 162 {
@@ -144,36 +169,44 @@ static DH_METHOD atalla_dh =
144 0, 169 0,
145 NULL 170 NULL
146 }; 171 };
172#endif
147 173
148/* Our ENGINE structure. */ 174/* Constants used when creating the ENGINE */
149static ENGINE engine_atalla = 175static const char *engine_atalla_id = "atalla";
150 { 176static const char *engine_atalla_name = "Atalla hardware engine support";
151 "atalla", 177
152 "Atalla hardware engine support", 178/* This internal function is used by ENGINE_atalla() and possibly by the
153 &atalla_rsa, 179 * "dynamic" ENGINE support too */
154 &atalla_dsa, 180static int bind_helper(ENGINE *e)
155 &atalla_dh,
156 NULL,
157 atalla_mod_exp,
158 NULL,
159 atalla_init,
160 atalla_finish,
161 NULL, /* no ctrl() */
162 NULL, /* no load_privkey() */
163 NULL, /* no load_pubkey() */
164 0, /* no flags */
165 0, 0, /* no references */
166 NULL, NULL /* unlinked */
167 };
168
169/* As this is only ever called once, there's no need for locking
170 * (indeed - the lock will already be held by our caller!!!) */
171ENGINE *ENGINE_atalla()
172 { 181 {
173 RSA_METHOD *meth1; 182#ifndef OPENSSL_NO_RSA
174 DSA_METHOD *meth2; 183 const RSA_METHOD *meth1;
175 DH_METHOD *meth3; 184#endif
185#ifndef OPENSSL_NO_DSA
186 const DSA_METHOD *meth2;
187#endif
188#ifndef OPENSSL_NO_DH
189 const DH_METHOD *meth3;
190#endif
191 if(!ENGINE_set_id(e, engine_atalla_id) ||
192 !ENGINE_set_name(e, engine_atalla_name) ||
193#ifndef OPENSSL_NO_RSA
194 !ENGINE_set_RSA(e, &atalla_rsa) ||
195#endif
196#ifndef OPENSSL_NO_DSA
197 !ENGINE_set_DSA(e, &atalla_dsa) ||
198#endif
199#ifndef OPENSSL_NO_DH
200 !ENGINE_set_DH(e, &atalla_dh) ||
201#endif
202 !ENGINE_set_destroy_function(e, atalla_destroy) ||
203 !ENGINE_set_init_function(e, atalla_init) ||
204 !ENGINE_set_finish_function(e, atalla_finish) ||
205 !ENGINE_set_ctrl_function(e, atalla_ctrl) ||
206 !ENGINE_set_cmd_defns(e, atalla_cmd_defns))
207 return 0;
176 208
209#ifndef OPENSSL_NO_RSA
177 /* We know that the "PKCS1_SSLeay()" functions hook properly 210 /* We know that the "PKCS1_SSLeay()" functions hook properly
178 * to the atalla-specific mod_exp and mod_exp_crt so we use 211 * to the atalla-specific mod_exp and mod_exp_crt so we use
179 * those functions. NB: We don't use ENGINE_openssl() or 212 * those functions. NB: We don't use ENGINE_openssl() or
@@ -186,19 +219,50 @@ ENGINE *ENGINE_atalla()
186 atalla_rsa.rsa_pub_dec = meth1->rsa_pub_dec; 219 atalla_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
187 atalla_rsa.rsa_priv_enc = meth1->rsa_priv_enc; 220 atalla_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
188 atalla_rsa.rsa_priv_dec = meth1->rsa_priv_dec; 221 atalla_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
222#endif
189 223
224#ifndef OPENSSL_NO_DSA
190 /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish 225 /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
191 * bits. */ 226 * bits. */
192 meth2 = DSA_OpenSSL(); 227 meth2 = DSA_OpenSSL();
193 atalla_dsa.dsa_do_sign = meth2->dsa_do_sign; 228 atalla_dsa.dsa_do_sign = meth2->dsa_do_sign;
194 atalla_dsa.dsa_sign_setup = meth2->dsa_sign_setup; 229 atalla_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
195 atalla_dsa.dsa_do_verify = meth2->dsa_do_verify; 230 atalla_dsa.dsa_do_verify = meth2->dsa_do_verify;
231#endif
196 232
233#ifndef OPENSSL_NO_DH
197 /* Much the same for Diffie-Hellman */ 234 /* Much the same for Diffie-Hellman */
198 meth3 = DH_OpenSSL(); 235 meth3 = DH_OpenSSL();
199 atalla_dh.generate_key = meth3->generate_key; 236 atalla_dh.generate_key = meth3->generate_key;
200 atalla_dh.compute_key = meth3->compute_key; 237 atalla_dh.compute_key = meth3->compute_key;
201 return &engine_atalla; 238#endif
239
240 /* Ensure the atalla error handling is set up */
241 ERR_load_ATALLA_strings();
242 return 1;
243 }
244
245static ENGINE *engine_atalla(void)
246 {
247 ENGINE *ret = ENGINE_new();
248 if(!ret)
249 return NULL;
250 if(!bind_helper(ret))
251 {
252 ENGINE_free(ret);
253 return NULL;
254 }
255 return ret;
256 }
257
258void ENGINE_load_atalla(void)
259 {
260 /* Copied from eng_[openssl|dyn].c */
261 ENGINE *toadd = engine_atalla();
262 if(!toadd) return;
263 ENGINE_add(toadd);
264 ENGINE_free(toadd);
265 ERR_clear_error();
202 } 266 }
203 267
204/* This is a process-global DSO handle used for loading and unloading 268/* This is a process-global DSO handle used for loading and unloading
@@ -214,8 +278,32 @@ static tfnASI_GetHardwareConfig *p_Atalla_GetHardwareConfig = NULL;
214static tfnASI_RSAPrivateKeyOpFn *p_Atalla_RSAPrivateKeyOpFn = NULL; 278static tfnASI_RSAPrivateKeyOpFn *p_Atalla_RSAPrivateKeyOpFn = NULL;
215static tfnASI_GetPerformanceStatistics *p_Atalla_GetPerformanceStatistics = NULL; 279static tfnASI_GetPerformanceStatistics *p_Atalla_GetPerformanceStatistics = NULL;
216 280
281/* These are the static string constants for the DSO file name and the function
282 * symbol names to bind to. Regrettably, the DSO name on *nix appears to be
283 * "atasi.so" rather than something more consistent like "libatasi.so". At the
284 * time of writing, I'm not sure what the file name on win32 is but clearly
285 * native name translation is not possible (eg libatasi.so on *nix, and
286 * atasi.dll on win32). For the purposes of testing, I have created a symbollic
287 * link called "libatasi.so" so that we can use native name-translation - a
288 * better solution will be needed. */
289static const char def_ATALLA_LIBNAME[] = "atasi";
290static const char *ATALLA_LIBNAME = def_ATALLA_LIBNAME;
291static const char *ATALLA_F1 = "ASI_GetHardwareConfig";
292static const char *ATALLA_F2 = "ASI_RSAPrivateKeyOpFn";
293static const char *ATALLA_F3 = "ASI_GetPerformanceStatistics";
294
295/* Destructor (complements the "ENGINE_atalla()" constructor) */
296static int atalla_destroy(ENGINE *e)
297 {
298 /* Unload the atalla error strings so any error state including our
299 * functs or reasons won't lead to a segfault (they simply get displayed
300 * without corresponding string data because none will be found). */
301 ERR_unload_ATALLA_strings();
302 return 1;
303 }
304
217/* (de)initialisation functions. */ 305/* (de)initialisation functions. */
218static int atalla_init() 306static int atalla_init(ENGINE *e)
219 { 307 {
220 tfnASI_GetHardwareConfig *p1; 308 tfnASI_GetHardwareConfig *p1;
221 tfnASI_RSAPrivateKeyOpFn *p2; 309 tfnASI_RSAPrivateKeyOpFn *p2;
@@ -226,7 +314,7 @@ static int atalla_init()
226 314
227 if(atalla_dso != NULL) 315 if(atalla_dso != NULL)
228 { 316 {
229 ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_ALREADY_LOADED); 317 ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_ALREADY_LOADED);
230 goto err; 318 goto err;
231 } 319 }
232 /* Attempt to load libatasi.so/atasi.dll/whatever. Needs to be 320 /* Attempt to load libatasi.so/atasi.dll/whatever. Needs to be
@@ -236,11 +324,10 @@ static int atalla_init()
236 * drivers really use - for now a symbollic link needs to be 324 * drivers really use - for now a symbollic link needs to be
237 * created on the host system from libatasi.so to atasi.so on 325 * created on the host system from libatasi.so to atasi.so on
238 * unix variants. */ 326 * unix variants. */
239 atalla_dso = DSO_load(NULL, ATALLA_LIBNAME, NULL, 327 atalla_dso = DSO_load(NULL, ATALLA_LIBNAME, NULL, 0);
240 DSO_FLAG_NAME_TRANSLATION);
241 if(atalla_dso == NULL) 328 if(atalla_dso == NULL)
242 { 329 {
243 ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_DSO_FAILURE); 330 ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_NOT_LOADED);
244 goto err; 331 goto err;
245 } 332 }
246 if(!(p1 = (tfnASI_GetHardwareConfig *)DSO_bind_func( 333 if(!(p1 = (tfnASI_GetHardwareConfig *)DSO_bind_func(
@@ -250,7 +337,7 @@ static int atalla_init()
250 !(p3 = (tfnASI_GetPerformanceStatistics *)DSO_bind_func( 337 !(p3 = (tfnASI_GetPerformanceStatistics *)DSO_bind_func(
251 atalla_dso, ATALLA_F3))) 338 atalla_dso, ATALLA_F3)))
252 { 339 {
253 ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_DSO_FAILURE); 340 ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_NOT_LOADED);
254 goto err; 341 goto err;
255 } 342 }
256 /* Copy the pointers */ 343 /* Copy the pointers */
@@ -261,7 +348,7 @@ static int atalla_init()
261 * running. */ 348 * running. */
262 if(p1(0L, config_buf) != 0) 349 if(p1(0L, config_buf) != 0)
263 { 350 {
264 ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_UNIT_FAILURE); 351 ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_UNIT_FAILURE);
265 goto err; 352 goto err;
266 } 353 }
267 /* Everything's fine. */ 354 /* Everything's fine. */
@@ -275,16 +362,16 @@ err:
275 return 0; 362 return 0;
276 } 363 }
277 364
278static int atalla_finish() 365static int atalla_finish(ENGINE *e)
279 { 366 {
280 if(atalla_dso == NULL) 367 if(atalla_dso == NULL)
281 { 368 {
282 ENGINEerr(ENGINE_F_ATALLA_FINISH,ENGINE_R_NOT_LOADED); 369 ATALLAerr(ATALLA_F_ATALLA_FINISH,ATALLA_R_NOT_LOADED);
283 return 0; 370 return 0;
284 } 371 }
285 if(!DSO_free(atalla_dso)) 372 if(!DSO_free(atalla_dso))
286 { 373 {
287 ENGINEerr(ENGINE_F_ATALLA_FINISH,ENGINE_R_DSO_FAILURE); 374 ATALLAerr(ATALLA_F_ATALLA_FINISH,ATALLA_R_UNIT_FAILURE);
288 return 0; 375 return 0;
289 } 376 }
290 atalla_dso = NULL; 377 atalla_dso = NULL;
@@ -294,7 +381,32 @@ static int atalla_finish()
294 return 1; 381 return 1;
295 } 382 }
296 383
297static int atalla_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 384static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
385 {
386 int initialised = ((atalla_dso == NULL) ? 0 : 1);
387 switch(cmd)
388 {
389 case ATALLA_CMD_SO_PATH:
390 if(p == NULL)
391 {
392 ATALLAerr(ATALLA_F_ATALLA_CTRL,ERR_R_PASSED_NULL_PARAMETER);
393 return 0;
394 }
395 if(initialised)
396 {
397 ATALLAerr(ATALLA_F_ATALLA_CTRL,ATALLA_R_ALREADY_LOADED);
398 return 0;
399 }
400 ATALLA_LIBNAME = (const char *)p;
401 return 1;
402 default:
403 break;
404 }
405 ATALLAerr(ATALLA_F_ATALLA_CTRL,ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED);
406 return 0;
407 }
408
409static int atalla_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
298 const BIGNUM *m, BN_CTX *ctx) 410 const BIGNUM *m, BN_CTX *ctx)
299 { 411 {
300 /* I need somewhere to store temporary serialised values for 412 /* 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,
313 to_return = 0; /* expect failure */ 425 to_return = 0; /* expect failure */
314 426
315 if(!atalla_dso) 427 if(!atalla_dso)
316 { 428 {
317 ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_NOT_LOADED); 429 ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_NOT_LOADED);
318 goto err; 430 goto err;
319 } 431 }
320 /* Prepare the params */ 432 /* Prepare the params */
433 BN_CTX_start(ctx);
321 modulus = BN_CTX_get(ctx); 434 modulus = BN_CTX_get(ctx);
322 exponent = BN_CTX_get(ctx); 435 exponent = BN_CTX_get(ctx);
323 argument = BN_CTX_get(ctx); 436 argument = BN_CTX_get(ctx);
324 result = BN_CTX_get(ctx); 437 result = BN_CTX_get(ctx);
325 if(!modulus || !exponent || !argument || !result) 438 if (!result)
326 { 439 {
327 ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_BN_CTX_FULL); 440 ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_BN_CTX_FULL);
328 goto err; 441 goto err;
329 } 442 }
330 if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, m->top) || 443 if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, m->top) ||
331 !bn_wexpand(argument, m->top) || !bn_wexpand(result, m->top)) 444 !bn_wexpand(argument, m->top) || !bn_wexpand(result, m->top))
332 { 445 {
333 ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_BN_EXPAND_FAIL); 446 ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_BN_EXPAND_FAIL);
334 goto err; 447 goto err;
335 } 448 }
336 /* Prepare the key-data */ 449 /* Prepare the key-data */
337 memset(&keydata, 0,sizeof keydata); 450 memset(&keydata, 0,sizeof keydata);
338 numbytes = BN_num_bytes(m); 451 numbytes = BN_num_bytes(m);
@@ -352,36 +465,34 @@ static int atalla_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
352 if(p_Atalla_RSAPrivateKeyOpFn(&keydata, (unsigned char *)result->d, 465 if(p_Atalla_RSAPrivateKeyOpFn(&keydata, (unsigned char *)result->d,
353 (unsigned char *)argument->d, 466 (unsigned char *)argument->d,
354 keydata.modulus.len) != 0) 467 keydata.modulus.len) != 0)
355 { 468 {
356 ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_REQUEST_FAILED); 469 ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_REQUEST_FAILED);
357 goto err; 470 goto err;
358 } 471 }
359 /* Convert the response */ 472 /* Convert the response */
360 BN_bin2bn((unsigned char *)result->d, numbytes, r); 473 BN_bin2bn((unsigned char *)result->d, numbytes, r);
361 to_return = 1; 474 to_return = 1;
362err: 475err:
363 if(modulus) ctx->tos--; 476 BN_CTX_end(ctx);
364 if(exponent) ctx->tos--;
365 if(argument) ctx->tos--;
366 if(result) ctx->tos--;
367 return to_return; 477 return to_return;
368 } 478 }
369 479
370static int atalla_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa) 480#ifndef OPENSSL_NO_RSA
481static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
371 { 482 {
372 BN_CTX *ctx = NULL; 483 BN_CTX *ctx = NULL;
373 int to_return = 0; 484 int to_return = 0;
374 485
375 if(!atalla_dso) 486 if(!atalla_dso)
376 { 487 {
377 ENGINEerr(ENGINE_F_ATALLA_RSA_MOD_EXP,ENGINE_R_NOT_LOADED); 488 ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP,ATALLA_R_NOT_LOADED);
378 goto err; 489 goto err;
379 } 490 }
380 if((ctx = BN_CTX_new()) == NULL) 491 if((ctx = BN_CTX_new()) == NULL)
381 goto err; 492 goto err;
382 if(!rsa->d || !rsa->n) 493 if(!rsa->d || !rsa->n)
383 { 494 {
384 ENGINEerr(ENGINE_F_ATALLA_RSA_MOD_EXP,ENGINE_R_MISSING_KEY_COMPONENTS); 495 ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP,ATALLA_R_MISSING_KEY_COMPONENTS);
385 goto err; 496 goto err;
386 } 497 }
387 to_return = atalla_mod_exp(r0, I, rsa->d, rsa->n, ctx); 498 to_return = atalla_mod_exp(r0, I, rsa->d, rsa->n, ctx);
@@ -390,7 +501,9 @@ err:
390 BN_CTX_free(ctx); 501 BN_CTX_free(ctx);
391 return to_return; 502 return to_return;
392 } 503 }
504#endif
393 505
506#ifndef OPENSSL_NO_DSA
394/* This code was liberated and adapted from the commented-out code in 507/* This code was liberated and adapted from the commented-out code in
395 * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration 508 * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration
396 * (it doesn't have a CRT form for RSA), this function means that an 509 * (it doesn't have a CRT form for RSA), this function means that an
@@ -418,27 +531,45 @@ end:
418 return to_return; 531 return to_return;
419 } 532 }
420 533
421
422static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, 534static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
423 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 535 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
424 BN_MONT_CTX *m_ctx) 536 BN_MONT_CTX *m_ctx)
425 { 537 {
426 return atalla_mod_exp(r, a, p, m, ctx); 538 return atalla_mod_exp(r, a, p, m, ctx);
427 } 539 }
540#endif
428 541
429/* This function is aliased to mod_exp (with the mont stuff dropped). */ 542/* This function is aliased to mod_exp (with the mont stuff dropped). */
430static int atalla_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 543static int atalla_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
431 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) 544 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
432 { 545 {
433 return atalla_mod_exp(r, a, p, m, ctx); 546 return atalla_mod_exp(r, a, p, m, ctx);
434 } 547 }
435 548
549#ifndef OPENSSL_NO_DH
436/* This function is aliased to mod_exp (with the dh and mont dropped). */ 550/* This function is aliased to mod_exp (with the dh and mont dropped). */
437static int atalla_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, 551static int atalla_mod_exp_dh(const DH *dh, BIGNUM *r,
552 const BIGNUM *a, const BIGNUM *p,
438 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) 553 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
439 { 554 {
440 return atalla_mod_exp(r, a, p, m, ctx); 555 return atalla_mod_exp(r, a, p, m, ctx);
441 } 556 }
557#endif
558
559/* This stuff is needed if this ENGINE is being compiled into a self-contained
560 * shared-library. */
561#ifdef ENGINE_DYNAMIC_SUPPORT
562static int bind_fn(ENGINE *e, const char *id)
563 {
564 if(id && (strcmp(id, engine_atalla_id) != 0))
565 return 0;
566 if(!bind_helper(e))
567 return 0;
568 return 1;
569 }
570IMPLEMENT_DYNAMIC_CHECK_FN()
571IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
572#endif /* ENGINE_DYNAMIC_SUPPORT */
442 573
443#endif /* !NO_HW_ATALLA */ 574#endif /* !OPENSSL_NO_HW_ATALLA */
444#endif /* !NO_HW */ 575#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 @@
1/* hw_atalla_err.c */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include "hw_atalla_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA ATALLA_str_functs[]=
68 {
69{ERR_PACK(0,ATALLA_F_ATALLA_CTRL,0), "ATALLA_CTRL"},
70{ERR_PACK(0,ATALLA_F_ATALLA_FINISH,0), "ATALLA_FINISH"},
71{ERR_PACK(0,ATALLA_F_ATALLA_INIT,0), "ATALLA_INIT"},
72{ERR_PACK(0,ATALLA_F_ATALLA_MOD_EXP,0), "ATALLA_MOD_EXP"},
73{ERR_PACK(0,ATALLA_F_ATALLA_RSA_MOD_EXP,0), "ATALLA_RSA_MOD_EXP"},
74{0,NULL}
75 };
76
77static ERR_STRING_DATA ATALLA_str_reasons[]=
78 {
79{ATALLA_R_ALREADY_LOADED ,"already loaded"},
80{ATALLA_R_BN_CTX_FULL ,"bn ctx full"},
81{ATALLA_R_BN_EXPAND_FAIL ,"bn expand fail"},
82{ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
83{ATALLA_R_MISSING_KEY_COMPONENTS ,"missing key components"},
84{ATALLA_R_NOT_LOADED ,"not loaded"},
85{ATALLA_R_REQUEST_FAILED ,"request failed"},
86{ATALLA_R_UNIT_FAILURE ,"unit failure"},
87{0,NULL}
88 };
89
90#endif
91
92#ifdef ATALLA_LIB_NAME
93static ERR_STRING_DATA ATALLA_lib_name[]=
94 {
95{0 ,ATALLA_LIB_NAME},
96{0,NULL}
97 };
98#endif
99
100
101static int ATALLA_lib_error_code=0;
102static int ATALLA_error_init=1;
103
104static void ERR_load_ATALLA_strings(void)
105 {
106 if (ATALLA_lib_error_code == 0)
107 ATALLA_lib_error_code=ERR_get_next_error_library();
108
109 if (ATALLA_error_init)
110 {
111 ATALLA_error_init=0;
112#ifndef OPENSSL_NO_ERR
113 ERR_load_strings(ATALLA_lib_error_code,ATALLA_str_functs);
114 ERR_load_strings(ATALLA_lib_error_code,ATALLA_str_reasons);
115#endif
116
117#ifdef ATALLA_LIB_NAME
118 ATALLA_lib_name->error = ERR_PACK(ATALLA_lib_error_code,0,0);
119 ERR_load_strings(0,ATALLA_lib_name);
120#endif
121 }
122 }
123
124static void ERR_unload_ATALLA_strings(void)
125 {
126 if (ATALLA_error_init == 0)
127 {
128#ifndef OPENSSL_NO_ERR
129 ERR_unload_strings(ATALLA_lib_error_code,ATALLA_str_functs);
130 ERR_unload_strings(ATALLA_lib_error_code,ATALLA_str_reasons);
131#endif
132
133#ifdef ATALLA_LIB_NAME
134 ERR_unload_strings(0,ATALLA_lib_name);
135#endif
136 ATALLA_error_init=1;
137 }
138 }
139
140static void ERR_ATALLA_error(int function, int reason, char *file, int line)
141 {
142 if (ATALLA_lib_error_code == 0)
143 ATALLA_lib_error_code=ERR_get_next_error_library();
144 ERR_PUT_error(ATALLA_lib_error_code,function,reason,file,line);
145 }
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 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#ifndef HEADER_ATALLA_ERR_H
56#define HEADER_ATALLA_ERR_H
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_ATALLA_strings(void);
63static void ERR_unload_ATALLA_strings(void);
64static void ERR_ATALLA_error(int function, int reason, char *file, int line);
65#define ATALLAerr(f,r) ERR_ATALLA_error((f),(r),__FILE__,__LINE__)
66
67/* Error codes for the ATALLA functions. */
68
69/* Function codes. */
70#define ATALLA_F_ATALLA_CTRL 100
71#define ATALLA_F_ATALLA_FINISH 101
72#define ATALLA_F_ATALLA_INIT 102
73#define ATALLA_F_ATALLA_MOD_EXP 103
74#define ATALLA_F_ATALLA_RSA_MOD_EXP 104
75
76/* Reason codes. */
77#define ATALLA_R_ALREADY_LOADED 100
78#define ATALLA_R_BN_CTX_FULL 101
79#define ATALLA_R_BN_EXPAND_FAIL 102
80#define ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED 103
81#define ATALLA_R_MISSING_KEY_COMPONENTS 104
82#define ATALLA_R_NOT_LOADED 105
83#define ATALLA_R_REQUEST_FAILED 106
84#define ATALLA_R_UNIT_FAILURE 107
85
86#ifdef __cplusplus
87}
88#endif
89#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 @@
1/*
2 * Copyright (c) 2002 Bob Beck <beck@openbsd.org>
3 * Copyright (c) 2002 Theo de Raadt
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the names of contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 */
30
31#include <sys/types.h>
32#include <sys/param.h>
33#include <crypto/cryptodev.h>
34#include <sys/ioctl.h>
35#include <errno.h>
36#include <stdio.h>
37#include <unistd.h>
38#include <fcntl.h>
39#include <syslog.h>
40#include <stdarg.h>
41#include <ssl/objects.h>
42#include <ssl/engine.h>
43#include <ssl/evp.h>
44
45static int cryptodev_fd = -1;
46static int cryptodev_sessions = 0;
47static u_int32_t cryptodev_symfeat = 0;
48
49static int bn2crparam(const BIGNUM *a, struct crparam *crp);
50static int crparam2bn(struct crparam *crp, BIGNUM *a);
51static void zapparams(struct crypt_kop *kop);
52
53static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
54static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
55 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
56static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
57 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
58static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst,
59 int dlen, DSA *dsa);
60static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
61 DSA_SIG *sig, DSA *dsa);
62static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
63 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
64 BN_MONT_CTX *m_ctx);
65static int cryptodev_dh_compute_key(unsigned char *key,
66 const BIGNUM *pub_key, DH *dh);
67
68static const ENGINE_CMD_DEFN cryptodev_defns[] = {
69 { 0, NULL, NULL, 0 }
70};
71
72static struct {
73 int id;
74 int nid;
75 int ivmax;
76 int keylen;
77} ciphers[] = {
78 { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, },
79 { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, },
80 { CRYPTO_AES_CBC, NID_undef, 8, 24, },
81 { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, },
82 { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 8, },
83 { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, },
84 { CRYPTO_ARC4, NID_rc4, 8, 16, },
85 { 0, NID_undef, 0, 0, },
86};
87
88static struct {
89 int id;
90 int nid;
91} digests[] = {
92 { CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, },
93 { CRYPTO_RIPEMD160_HMAC, NID_ripemd160, },
94 { CRYPTO_MD5_KPDK, NID_undef, },
95 { CRYPTO_SHA1_KPDK, NID_undef, },
96 { CRYPTO_MD5, NID_md5, },
97 { CRYPTO_SHA1, NID_undef, },
98 { 0, NID_undef, },
99};
100
101/*
102 * Return 1 if /dev/crypto seems usable, 0 otherwise , also
103 * does most of the work of initting the device, if not already
104 * done.. This should leave is with global fd initialized with CRIOGET.
105 */
106static int
107check_dev_crypto()
108{
109 int fd;
110
111 if (cryptodev_fd == -1) {
112 if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1)
113 return (0);
114 if (ioctl(fd, CRIOGET, &cryptodev_fd) == -1) {
115 close(fd);
116 return (0);
117 }
118 close(fd);
119 /* close on exec */
120 if (fcntl(cryptodev_fd, F_SETFD, 1) == -1) {
121 close(cryptodev_fd);
122 cryptodev_fd = -1;
123 return (0);
124 }
125 }
126 ioctl(cryptodev_fd, CIOCSYMFEAT, &cryptodev_symfeat);
127
128 return (1);
129}
130
131/*
132 * XXXX this needs to be set for each alg - and determined from
133 * a running card.
134 */
135static int
136cryptodev_max_iv(int cipher)
137{
138 int i;
139
140 for (i = 0; ciphers[i].id; i++)
141 if (ciphers[i].id == cipher)
142 return (ciphers[i].ivmax);
143 return (0);
144}
145
146/*
147 * XXXX this needs to be set for each alg - and determined from
148 * a running card. For now, fake it out - but most of these
149 * for real devices should return 1 for the supported key
150 * sizes the device can handle.
151 */
152static int
153cryptodev_key_length_valid(int cipher, int len)
154{
155 int i;
156
157 for (i = 0; ciphers[i].id; i++)
158 if (ciphers[i].id == cipher)
159 return (ciphers[i].keylen == len);
160 return (0);
161}
162
163/* convert libcrypto nids to cryptodev */
164static int
165cipher_nid_to_cryptodev(int nid)
166{
167 int i;
168
169 for (i = 0; ciphers[i].id; i++)
170 if (ciphers[i].nid == nid)
171 return (ciphers[i].id);
172 return (0);
173}
174
175/*
176 * Find out what ciphers /dev/crypto will let us have a session for.
177 * XXX note, that some of these openssl doesn't deal with yet!
178 * returning them here is harmless, as long as we return NULL
179 * when asked for a handler in the cryptodev_engine_ciphers routine
180 */
181static int
182get_cryptodev_ciphers(const int **cnids)
183{
184 static int nids[CRYPTO_ALGORITHM_MAX];
185 struct session_op sess;
186 int i, count = 0;
187
188 memset(&sess, 0, sizeof(sess));
189 sess.key = (caddr_t)"123456781234567812345678";
190
191 for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
192 if (ciphers[i].nid == NID_undef)
193 continue;
194 sess.cipher = ciphers[i].id;
195 sess.keylen = ciphers[i].keylen;
196 sess.mac = 0;
197 if (ioctl(cryptodev_fd, CIOCGSESSION, &sess) != -1 &&
198 ioctl(cryptodev_fd, CIOCFSESSION, &sess.ses) != -1)
199 nids[count++] = ciphers[i].nid;
200 }
201 if (count > 0)
202 *cnids = nids;
203 else
204 *cnids = NULL;
205 return (count);
206}
207
208/*
209 * Find out what digests /dev/crypto will let us have a session for.
210 * XXX note, that some of these openssl doesn't deal with yet!
211 * returning them here is harmless, as long as we return NULL
212 * when asked for a handler in the cryptodev_engine_digests routine
213 */
214static int
215get_cryptodev_digests(const int **cnids)
216{
217 static int nids[CRYPTO_ALGORITHM_MAX];
218 struct session_op sess;
219 int i, count = 0;
220
221 memset(&sess, 0, sizeof(sess));
222 for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
223 if (digests[i].nid == NID_undef)
224 continue;
225 sess.mac = digests[i].id;
226 sess.cipher = 0;
227 if (ioctl(cryptodev_fd, CIOCGSESSION, &sess) != -1 &&
228 ioctl(cryptodev_fd, CIOCFSESSION, &sess.ses) != -1)
229 nids[count++] = digests[i].nid;
230 }
231 if (count > 0)
232 *cnids = nids;
233 else
234 *cnids = NULL;
235 return (count);
236}
237
238/*
239 * Find the useable ciphers|digests from dev/crypto - this is the first
240 * thing called by the engine init crud which determines what it
241 * can use for ciphers from this engine. We want to return
242 * only what we can do, anythine else is handled by software.
243 *
244 * If we can't initialize the device to do anything useful for
245 * any reason, we want to return a NULL array, and 0 length,
246 * which forces everything to be done is software. By putting
247 * the initalization of the device in here, we ensure we can
248 * use this engine as the default, and if for whatever reason
249 * /dev/crypto won't do what we want it will just be done in
250 * software
251 *
252 * This can (should) be greatly expanded to perhaps take into
253 * account speed of the device, and what we want to do.
254 * (although the disabling of particular alg's could be controlled
255 * by the device driver with sysctl's.) - this is where we
256 * want most of the decisions made about what we actually want
257 * to use from /dev/crypto.
258 */
259int
260cryptodev_usable_ciphers(const int **nids)
261{
262 if (!check_dev_crypto()) {
263 *nids = NULL;
264 return (0);
265 }
266
267 /* find what the device can do. Unfortunately, we don't
268 * necessarily want all of these yet, because we aren't
269 * yet set up to do them
270 */
271 return (get_cryptodev_ciphers(nids));
272}
273
274int
275cryptodev_usable_digests(const int **nids)
276{
277#if 1
278 /*
279 * XXXX just disable all digests for now, because it sucks.
280 * we need a better way to decide this - i.e. I may not
281 * want digests on slow cards like hifn on fast machines,
282 * but might want them on slow or loaded machines, etc.
283 * will also want them when using crypto cards that don't
284 * suck moose gonads - would be nice to be able to decide something
285 * as reasonable default without having hackery that's card dependent.
286 * of course, the default should probably be just do everything,
287 * with perhaps a sysctl to turn algoritms off (or have them off
288 * by default) on cards that generally suck like the hifn.
289 */
290 *nids = NULL;
291 return (0);
292#endif
293
294 if (!check_dev_crypto()) {
295 *nids = NULL;
296 return (0);
297 }
298 return (get_cryptodev_digests(nids));
299}
300
301
302int
303cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
304 const unsigned char *in, unsigned int inl)
305{
306 struct crypt_op cryp;
307 struct session_op *sess = ctx->cipher_data;
308 void *iiv;
309 unsigned char save_iv[EVP_MAX_IV_LENGTH];
310 struct syslog_data sd = SYSLOG_DATA_INIT;
311
312 if (cryptodev_fd == -1)
313 return (0);
314 if (sess == NULL)
315 return (0);
316 if (!inl)
317 return (1);
318 if ((inl % ctx->cipher->block_size) != 0)
319 return (0);
320
321 memset(&cryp, 0, sizeof(cryp));
322
323 cryp.ses = sess->ses;
324 cryp.flags = 0;
325 cryp.len = inl;
326 cryp.src = (caddr_t) in;
327 cryp.dst = (caddr_t) out;
328 cryp.mac = 0;
329
330 cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
331
332 if (ctx->cipher->iv_len) {
333 cryp.iv = (caddr_t) ctx->iv;
334 if (!ctx->encrypt) {
335 iiv = (void *) in + inl - ctx->cipher->iv_len;
336 memcpy(save_iv, iiv, ctx->cipher->iv_len);
337 }
338 } else
339 cryp.iv = NULL;
340
341 if (ioctl(cryptodev_fd, CIOCCRYPT, &cryp) == -1) {
342 /* XXX need better errror handling
343 * this can fail for a number of different reasons.
344 */
345 syslog_r(LOG_ERR, &sd, "CIOCCRYPT failed (%m)");
346 return (0);
347 }
348
349 if (ctx->cipher->iv_len) {
350 if (ctx->encrypt)
351 iiv = (void *) out + inl - ctx->cipher->iv_len;
352 else
353 iiv = save_iv;
354 memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
355 }
356 return (1);
357}
358
359int
360cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
361 const unsigned char *iv, int enc)
362{
363 struct session_op *sess = ctx->cipher_data;
364 struct syslog_data sd = SYSLOG_DATA_INIT;
365 int cipher;
366
367 if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef)
368 return (0);
369
370 if (!check_dev_crypto())
371 return (0);
372
373 if (ctx->cipher->iv_len > cryptodev_max_iv(cipher))
374 return (0);
375
376 if (!cryptodev_key_length_valid(cipher, ctx->key_len))
377 return (0);
378
379 memset(sess, 0, sizeof(struct session_op));
380
381 sess->key = (unsigned char *)key;
382 sess->keylen = ctx->key_len;
383 sess->cipher = cipher;
384
385 if (ioctl(cryptodev_fd, CIOCGSESSION, sess) == -1) {
386 syslog_r(LOG_ERR, &sd, "CIOCGSESSION failed (%m)");
387 return (0);
388 }
389 cryptodev_sessions++;
390 return (1);
391}
392
393/*
394 * free anything we allocated earlier when initting a
395 * session, and close the session.
396 */
397int
398cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
399{
400 int ret = 0;
401 struct session_op *sess = ctx->cipher_data;
402 struct syslog_data sd = SYSLOG_DATA_INIT;
403
404 if (sess == NULL)
405 return (0);
406
407 /* XXX if this ioctl fails, someting's wrong. the invoker
408 * may have called us with a bogus ctx, or we could
409 * have a device that for whatever reason just doesn't
410 * want to play ball - it's not clear what's right
411 * here - should this be an error? should it just
412 * increase a counter, hmm. For right now, we return
413 * 0 - I don't believe that to be "right". we could
414 * call the gorpy openssl lib error handlers that
415 * print messages to users of the library. hmm..
416 */
417
418 if (ioctl(cryptodev_fd, CIOCFSESSION, &sess->ses) == -1) {
419 syslog_r(LOG_ERR, &sd, "CIOCFSESSION failed (%m)");
420 ret = 0;
421 } else {
422 cryptodev_sessions--;
423 ret = 1;
424 }
425 if (cryptodev_sessions == 0 && cryptodev_fd != -1 ) {
426 close(cryptodev_fd); /* XXX should this be closed? */
427 cryptodev_fd = -1;
428 }
429 return (ret);
430}
431
432/*
433 * libcrypto EVP stuff - this is how we get wired to EVP so the engine
434 * gets called when libcrypto requests a cipher NID.
435 */
436
437/* ARC4 (16 byte key) */
438const EVP_CIPHER cryptodev_arc4_cipher = {
439 NID_rc4,
440 1, 16, 0,
441 EVP_CIPH_VARIABLE_LENGTH,
442 cryptodev_init_key,
443 cryptodev_cipher,
444 cryptodev_cleanup,
445 sizeof(struct session_op),
446 NULL,
447 NULL,
448 NULL
449};
450
451/* DES CBC EVP */
452const EVP_CIPHER cryptodev_des_cbc = {
453 NID_des_cbc,
454 8, 8, 8,
455 EVP_CIPH_CBC_MODE,
456 cryptodev_init_key,
457 cryptodev_cipher,
458 cryptodev_cleanup,
459 sizeof(struct session_op),
460 EVP_CIPHER_set_asn1_iv,
461 EVP_CIPHER_get_asn1_iv,
462 NULL
463};
464
465/* 3DES CBC EVP */
466const EVP_CIPHER cryptodev_3des_cbc = {
467 NID_des_ede3_cbc,
468 8, 24, 8,
469 EVP_CIPH_CBC_MODE,
470 cryptodev_init_key,
471 cryptodev_cipher,
472 cryptodev_cleanup,
473 sizeof(struct session_op),
474 EVP_CIPHER_set_asn1_iv,
475 EVP_CIPHER_get_asn1_iv,
476 NULL
477};
478
479
480/*
481 * Registered by the ENGINE when used to find out how to deal with
482 * a particular NID in the ENGINE. this says what we'll do at the
483 * top level - note, that list is restricted by what we answer with
484 */
485int
486cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
487 const int **nids, int nid)
488{
489 if (!cipher)
490 return (cryptodev_usable_ciphers(nids));
491
492 switch (nid) {
493 case NID_rc4:
494 *cipher = &cryptodev_arc4_cipher;
495 break;
496 case NID_des_ede3_cbc:
497 *cipher = &cryptodev_3des_cbc;
498 break;
499 case NID_des_cbc:
500 *cipher = &cryptodev_des_cbc;
501 break;
502 default:
503 *cipher = NULL;
504 break;
505 }
506 return (*cipher != NULL);
507}
508
509int
510cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
511 const int **nids, int nid)
512{
513 if (!digest)
514 return (cryptodev_usable_digests(nids));
515
516 switch (nid) {
517 case NID_md5:
518 *digest = NULL; /* need to make a clean md5 critter */
519 break;
520 default:
521 *digest = NULL;
522 break;
523 }
524 return (*digest != NULL);
525}
526
527
528/*
529 * Convert a BIGNUM to the representation that /dev/crypto needs.
530 * Upon completion of use, the caller is responsible for freeing
531 * crp->crp_p.
532 */
533static int
534bn2crparam(const BIGNUM *a, struct crparam *crp)
535{
536 int i, j, n;
537 ssize_t words, bytes, bits;
538 u_char *b;
539
540 crp->crp_p = NULL;
541 crp->crp_nbits = 0;
542
543 bits = BN_num_bits(a);
544 bytes = (bits + 7) / 8;
545
546 b = malloc(bytes);
547 if (b == NULL)
548 return (1);
549
550 crp->crp_p = b;
551 crp->crp_nbits = bits;
552
553 words = (bits + BN_BITS2 - 1) / BN_BITS2;
554
555 n = 0;
556 for (i = 0; i < words && n < bytes; i++) {
557 BN_ULONG word;
558
559 word = a->d[i];
560 for (j = 0 ; j < BN_BYTES && n < bytes; j++, n++) {
561 *b++ = (word & 0xff);
562 word >>= 8;
563 }
564 }
565 return (0);
566}
567
568/* Convert a /dev/crypto parameter to a BIGNUM */
569static int
570crparam2bn(struct crparam *crp, BIGNUM *a)
571{
572 int i, bytes;
573
574 bytes = (crp->crp_nbits + 7)/8;
575
576 BN_zero(a);
577 for (i = bytes - 1; i >= 0; i--) {
578 BN_lshift(a, a, 8);
579 BN_add_word(a, (u_char)crp->crp_p[i]);
580 }
581
582 return (0);
583}
584
585static void
586zapparams(struct crypt_kop *kop)
587{
588 int i;
589
590 for (i = 0; i <= kop->crk_iparams + kop->crk_oparams; i++) {
591 if (kop->crk_param[i].crp_p)
592 free(kop->crk_param[i].crp_p);
593 kop->crk_param[i].crp_p = NULL;
594 kop->crk_param[i].crp_nbits = 0;
595 }
596}
597
598static int
599cryptodev_sym(struct crypt_kop *kop, BIGNUM *r, BIGNUM *s)
600{
601 int ret = -1;
602
603 if (r) {
604 kop->crk_param[kop->crk_iparams].crp_p = malloc(256);
605 kop->crk_param[kop->crk_iparams].crp_nbits = 256 * 8;
606 kop->crk_oparams++;
607 }
608 if (s) {
609 kop->crk_param[kop->crk_iparams+1].crp_p = malloc(256);
610 kop->crk_param[kop->crk_iparams+1].crp_nbits = 256 * 8;
611 kop->crk_oparams++;
612 }
613
614 if (ioctl(cryptodev_fd, CIOCKEY, &kop) == 0) {
615 crparam2bn(&kop->crk_param[3], r);
616 ret = 0;
617 }
618 return (ret);
619}
620
621static int
622cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
623 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
624{
625 struct crypt_kop kop;
626 int ret = 0;
627
628 memset(&kop, 0, sizeof kop);
629 kop.crk_op = CRK_MOD_EXP;
630
631 /* inputs: a m p */
632 if (bn2crparam(a, &kop.crk_param[0]))
633 goto err;
634 if (bn2crparam(m, &kop.crk_param[1]))
635 goto err;
636 if (bn2crparam(p, &kop.crk_param[2]))
637 goto err;
638 kop.crk_iparams = 3;
639
640 if (cryptodev_sym(&kop, r, NULL) == -1) {
641 ret = BN_mod_exp(r, a, p, m, ctx);
642 }
643err:
644 zapparams(&kop);
645 return (ret);
646}
647
648
649static int
650cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
651{
652 struct crypt_kop kop;
653 int ret = 0;
654
655 if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
656 /* XXX 0 means failure?? */
657 goto err;
658 }
659
660 memset(&kop, 0, sizeof kop);
661 kop.crk_op = CRK_MOD_EXP_CRT;
662 /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
663 if (bn2crparam(rsa->p, &kop.crk_param[0]))
664 goto err;
665 if (bn2crparam(rsa->q, &kop.crk_param[1]))
666 goto err;
667 if (bn2crparam(I, &kop.crk_param[2]))
668 goto err;
669 if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
670 goto err;
671 if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
672 goto err;
673 if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
674 goto err;
675 kop.crk_iparams = 6;
676
677 if (cryptodev_sym(&kop, r0, NULL) == -1) {
678 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
679
680 ret = (*meth->rsa_mod_exp)(r0, I, rsa);
681 }
682err:
683 zapparams(&kop);
684 return (ret);
685}
686
687static RSA_METHOD cryptodev_rsa = {
688 "cryptodev RSA method",
689 NULL, /* rsa_pub_enc */
690 NULL, /* rsa_pub_dec */
691 NULL, /* rsa_priv_enc */
692 NULL, /* rsa_priv_dec */
693 cryptodev_rsa_mod_exp, /* rsa_mod_exp */
694 cryptodev_bn_mod_exp, /* bn_mod_exp */
695 NULL, /* init */
696 NULL, /* finish */
697 0, /* flags */
698 NULL, /* app_data */
699 NULL, /* rsa_sign */
700 NULL /* rsa_verify */
701};
702
703static int
704cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
705 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
706{
707 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
708}
709
710static DSA_SIG *
711cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
712{
713 struct crypt_kop kop;
714 BIGNUM *r = NULL, *s = NULL;
715 DSA_SIG *dsaret = NULL;
716
717 if ((r = BN_new()) == NULL)
718 goto err;
719 if ((s = BN_new()) == NULL) {
720 BN_free(r);
721 goto err;
722 }
723
724 memset(&kop, 0, sizeof kop);
725 kop.crk_op = CRK_DSA_SIGN;
726
727 /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
728 kop.crk_param[0].crp_p = (caddr_t)dgst;
729 kop.crk_param[0].crp_nbits = dlen * 8;
730 if (bn2crparam(dsa->p, &kop.crk_param[1]))
731 goto err;
732 if (bn2crparam(dsa->q, &kop.crk_param[2]))
733 goto err;
734 if (bn2crparam(dsa->g, &kop.crk_param[3]))
735 goto err;
736 if (bn2crparam(dsa->priv_key, &kop.crk_param[4]))
737 goto err;
738 kop.crk_iparams = 5;
739
740 if (cryptodev_sym(&kop, r, s) == 0) {
741 dsaret = DSA_SIG_new();
742 dsaret->r = r;
743 dsaret->s = s;
744 } else {
745 const DSA_METHOD *meth = DSA_OpenSSL();
746
747 BN_free(r);
748 BN_free(s);
749 dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
750 }
751err:
752 kop.crk_param[0].crp_p = NULL;
753 zapparams(&kop);
754 return (dsaret);
755}
756
757static int
758cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
759 DSA_SIG *sig, DSA *dsa)
760{
761 struct crypt_kop kop;
762 int dsaret = 0;
763
764 memset(&kop, 0, sizeof kop);
765 kop.crk_op = CRK_DSA_VERIFY;
766
767 /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
768 kop.crk_param[0].crp_p = (caddr_t)dgst;
769 kop.crk_param[0].crp_nbits = dlen * 8;
770 if (bn2crparam(dsa->p, &kop.crk_param[1]))
771 goto err;
772 if (bn2crparam(dsa->q, &kop.crk_param[2]))
773 goto err;
774 if (bn2crparam(dsa->g, &kop.crk_param[3]))
775 goto err;
776 if (bn2crparam(dsa->pub_key, &kop.crk_param[4]))
777 goto err;
778 if (bn2crparam(sig->r, &kop.crk_param[5]))
779 goto err;
780 if (bn2crparam(sig->s, &kop.crk_param[6]))
781 goto err;
782 kop.crk_iparams = 7;
783
784 if (cryptodev_sym(&kop, NULL, NULL) == 0) {
785 dsaret = kop.crk_status;
786 } else {
787 const DSA_METHOD *meth = DSA_OpenSSL();
788
789 dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
790 }
791err:
792 kop.crk_param[0].crp_p = NULL;
793 zapparams(&kop);
794 return (dsaret);
795}
796
797static DSA_METHOD cryptodev_dsa = {
798 "cryptodev DSA method",
799 cryptodev_dsa_do_sign,
800 NULL, /* dsa_sign_setup */
801 cryptodev_dsa_verify,
802 NULL, /* dsa_mod_exp */
803 cryptodev_dsa_bn_mod_exp, /* bn_mod_exp */
804 NULL, /* init */
805 NULL, /* finish */
806 0, /* flags */
807 NULL /* app_data */
808};
809
810static int
811cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
812 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
813 BN_MONT_CTX *m_ctx)
814{
815 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
816}
817
818static int
819cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
820{
821 struct crypt_kop kop;
822 int dhret = 0;
823 int keylen;
824
825 keylen = BN_num_bits(dh->p);
826
827 memset(&kop, 0, sizeof kop);
828 kop.crk_op = CRK_DH_COMPUTE_KEY;
829
830 /* inputs: dh->priv_key pub_key dh->p key */
831 if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
832 goto err;
833 if (bn2crparam(pub_key, &kop.crk_param[1]))
834 goto err;
835 if (bn2crparam(dh->p, &kop.crk_param[2]))
836 goto err;
837 kop.crk_iparams = 3;
838
839 kop.crk_param[3].crp_p = key;
840 kop.crk_param[3].crp_nbits = keylen * 8;
841 kop.crk_oparams = 1;
842
843 if (ioctl(cryptodev_fd, CIOCKEY, &kop) == -1) {
844 const DH_METHOD *meth = DH_OpenSSL();
845
846 dhret = (meth->compute_key)(key, pub_key, dh);
847 }
848err:
849 kop.crk_param[3].crp_p = NULL;
850 zapparams(&kop);
851 return (dhret);
852}
853
854static DH_METHOD cryptodev_dh = {
855 "cryptodev DH method",
856 NULL, /* cryptodev_dh_generate_key */
857 cryptodev_dh_compute_key,
858 cryptodev_mod_exp_dh,
859 NULL,
860 NULL,
861 0, /* flags */
862 NULL /* app_data */
863};
864
865/*
866 * ctrl right now is just a wrapper that doesn't do much
867 * but I expect we'll want some options soon.
868 */
869static int
870cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
871{
872 struct syslog_data sd = SYSLOG_DATA_INIT;
873
874 switch (cmd) {
875 default:
876 syslog_r(LOG_ERR, &sd,
877 "cryptodev_ctrl: unknown command %d", cmd);
878 break;
879 }
880 return (1);
881}
882
883void
884ENGINE_load_cryptodev(void)
885{
886 ENGINE *engine = ENGINE_new();
887 const RSA_METHOD *rsa_meth;
888 const DH_METHOD *dh_meth;
889
890 if (engine == NULL)
891 return;
892
893 if (!ENGINE_set_id(engine, "cryptodev") ||
894 !ENGINE_set_name(engine, "OpenBSD cryptodev engine") ||
895 !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) ||
896 !ENGINE_set_digests(engine, cryptodev_engine_digests) ||
897 !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) ||
898 !ENGINE_set_cmd_defns(engine, cryptodev_defns)) {
899 ENGINE_free(engine);
900 return;
901 }
902
903 if ((cryptodev_symfeat & CRSFEAT_RSA) &&
904 ENGINE_set_RSA(engine, &cryptodev_rsa)) {
905 rsa_meth = RSA_PKCS1_SSLeay();
906 cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc;
907 cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec;
908 cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_dec;
909 cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec;
910 }
911
912 if ((cryptodev_symfeat & CRSFEAT_DSA) &&
913 ENGINE_set_DSA(engine, &cryptodev_dsa)) {
914 }
915
916 if ((cryptodev_symfeat & CRSFEAT_DH) &&
917 ENGINE_set_DH(engine, &cryptodev_dh)) {
918 dh_meth = DH_OpenSSL();
919 cryptodev_dh.generate_key = dh_meth->generate_key;
920 cryptodev_dh.compute_key = dh_meth->compute_key;
921 }
922
923 ENGINE_add(engine);
924 ENGINE_free(engine);
925 ERR_clear_error();
926}
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 @@
3 * project 2000. 3 * project 2000.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -60,11 +60,10 @@
60#include <openssl/crypto.h> 60#include <openssl/crypto.h>
61#include "cryptlib.h" 61#include "cryptlib.h"
62#include <openssl/dso.h> 62#include <openssl/dso.h>
63#include "engine_int.h"
64#include <openssl/engine.h> 63#include <openssl/engine.h>
65 64
66#ifndef NO_HW 65#ifndef OPENSSL_NO_HW
67#ifndef NO_HW_CSWIFT 66#ifndef OPENSSL_NO_HW_CSWIFT
68 67
69/* Attribution notice: Rainbow have generously allowed me to reproduce 68/* Attribution notice: Rainbow have generously allowed me to reproduce
70 * the necessary definitions here from their API. This means the support 69 * the necessary definitions here from their API. This means the support
@@ -84,33 +83,55 @@
84#include "vendor_defns/cswift.h" 83#include "vendor_defns/cswift.h"
85#endif 84#endif
86 85
87static int cswift_init(void); 86#define CSWIFT_LIB_NAME "cswift engine"
88static int cswift_finish(void); 87#include "hw_cswift_err.c"
88
89static int cswift_destroy(ENGINE *e);
90static int cswift_init(ENGINE *e);
91static int cswift_finish(ENGINE *e);
92static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
89 93
90/* BIGNUM stuff */ 94/* BIGNUM stuff */
91static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 95static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
92 const BIGNUM *m, BN_CTX *ctx); 96 const BIGNUM *m, BN_CTX *ctx);
93static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 97static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
94 const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1, 98 const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
95 const BIGNUM *iqmp, BN_CTX *ctx); 99 const BIGNUM *iqmp, BN_CTX *ctx);
96 100
101#ifndef OPENSSL_NO_RSA
97/* RSA stuff */ 102/* RSA stuff */
98static int cswift_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa); 103static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
104#endif
99/* This function is aliased to mod_exp (with the mont stuff dropped). */ 105/* This function is aliased to mod_exp (with the mont stuff dropped). */
100static int cswift_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 106static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
101 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); 107 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
102 108
109#ifndef OPENSSL_NO_DSA
103/* DSA stuff */ 110/* DSA stuff */
104static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa); 111static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
105static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len, 112static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
106 DSA_SIG *sig, DSA *dsa); 113 DSA_SIG *sig, DSA *dsa);
114#endif
107 115
116#ifndef OPENSSL_NO_DH
108/* DH stuff */ 117/* DH stuff */
109/* This function is alised to mod_exp (with the DH and mont dropped). */ 118/* This function is alised to mod_exp (with the DH and mont dropped). */
110static int cswift_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, 119static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
120 const BIGNUM *a, const BIGNUM *p,
111 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); 121 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
122#endif
112 123
124/* The definitions for control commands specific to this engine */
125#define CSWIFT_CMD_SO_PATH ENGINE_CMD_BASE
126static const ENGINE_CMD_DEFN cswift_cmd_defns[] = {
127 {CSWIFT_CMD_SO_PATH,
128 "SO_PATH",
129 "Specifies the path to the 'cswift' shared library",
130 ENGINE_CMD_FLAG_STRING},
131 {0, NULL, NULL, 0}
132 };
113 133
134#ifndef OPENSSL_NO_RSA
114/* Our internal RSA_METHOD that we provide pointers to */ 135/* Our internal RSA_METHOD that we provide pointers to */
115static RSA_METHOD cswift_rsa = 136static RSA_METHOD cswift_rsa =
116 { 137 {
@@ -128,7 +149,9 @@ static RSA_METHOD cswift_rsa =
128 NULL, 149 NULL,
129 NULL 150 NULL
130 }; 151 };
152#endif
131 153
154#ifndef OPENSSL_NO_DSA
132/* Our internal DSA_METHOD that we provide pointers to */ 155/* Our internal DSA_METHOD that we provide pointers to */
133static DSA_METHOD cswift_dsa = 156static DSA_METHOD cswift_dsa =
134 { 157 {
@@ -143,7 +166,9 @@ static DSA_METHOD cswift_dsa =
143 0, /* flags */ 166 0, /* flags */
144 NULL /* app_data */ 167 NULL /* app_data */
145 }; 168 };
169#endif
146 170
171#ifndef OPENSSL_NO_DH
147/* Our internal DH_METHOD that we provide pointers to */ 172/* Our internal DH_METHOD that we provide pointers to */
148static DH_METHOD cswift_dh = 173static DH_METHOD cswift_dh =
149 { 174 {
@@ -156,35 +181,41 @@ static DH_METHOD cswift_dh =
156 0, 181 0,
157 NULL 182 NULL
158 }; 183 };
184#endif
159 185
160/* Our ENGINE structure. */ 186/* Constants used when creating the ENGINE */
161static ENGINE engine_cswift = 187static const char *engine_cswift_id = "cswift";
162 { 188static const char *engine_cswift_name = "CryptoSwift hardware engine support";
163 "cswift", 189
164 "CryptoSwift hardware engine support", 190/* This internal function is used by ENGINE_cswift() and possibly by the
165 &cswift_rsa, 191 * "dynamic" ENGINE support too */
166 &cswift_dsa, 192static int bind_helper(ENGINE *e)
167 &cswift_dh,
168 NULL,
169 cswift_mod_exp,
170 cswift_mod_exp_crt,
171 cswift_init,
172 cswift_finish,
173 NULL, /* no ctrl() */
174 NULL, /* no load_privkey() */
175 NULL, /* no load_pubkey() */
176 0, /* no flags */
177 0, 0, /* no references */
178 NULL, NULL /* unlinked */
179 };
180
181/* As this is only ever called once, there's no need for locking
182 * (indeed - the lock will already be held by our caller!!!) */
183ENGINE *ENGINE_cswift()
184 { 193 {
185 RSA_METHOD *meth1; 194#ifndef OPENSSL_NO_RSA
186 DH_METHOD *meth2; 195 const RSA_METHOD *meth1;
196#endif
197#ifndef OPENSSL_NO_DH
198 const DH_METHOD *meth2;
199#endif
200 if(!ENGINE_set_id(e, engine_cswift_id) ||
201 !ENGINE_set_name(e, engine_cswift_name) ||
202#ifndef OPENSSL_NO_RSA
203 !ENGINE_set_RSA(e, &cswift_rsa) ||
204#endif
205#ifndef OPENSSL_NO_DSA
206 !ENGINE_set_DSA(e, &cswift_dsa) ||
207#endif
208#ifndef OPENSSL_NO_DH
209 !ENGINE_set_DH(e, &cswift_dh) ||
210#endif
211 !ENGINE_set_destroy_function(e, cswift_destroy) ||
212 !ENGINE_set_init_function(e, cswift_init) ||
213 !ENGINE_set_finish_function(e, cswift_finish) ||
214 !ENGINE_set_ctrl_function(e, cswift_ctrl) ||
215 !ENGINE_set_cmd_defns(e, cswift_cmd_defns))
216 return 0;
187 217
218#ifndef OPENSSL_NO_RSA
188 /* We know that the "PKCS1_SSLeay()" functions hook properly 219 /* We know that the "PKCS1_SSLeay()" functions hook properly
189 * to the cswift-specific mod_exp and mod_exp_crt so we use 220 * to the cswift-specific mod_exp and mod_exp_crt so we use
190 * those functions. NB: We don't use ENGINE_openssl() or 221 * those functions. NB: We don't use ENGINE_openssl() or
@@ -197,12 +228,41 @@ ENGINE *ENGINE_cswift()
197 cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec; 228 cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
198 cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc; 229 cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
199 cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec; 230 cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
231#endif
200 232
233#ifndef OPENSSL_NO_DH
201 /* Much the same for Diffie-Hellman */ 234 /* Much the same for Diffie-Hellman */
202 meth2 = DH_OpenSSL(); 235 meth2 = DH_OpenSSL();
203 cswift_dh.generate_key = meth2->generate_key; 236 cswift_dh.generate_key = meth2->generate_key;
204 cswift_dh.compute_key = meth2->compute_key; 237 cswift_dh.compute_key = meth2->compute_key;
205 return &engine_cswift; 238#endif
239
240 /* Ensure the cswift error handling is set up */
241 ERR_load_CSWIFT_strings();
242 return 1;
243 }
244
245static ENGINE *engine_cswift(void)
246 {
247 ENGINE *ret = ENGINE_new();
248 if(!ret)
249 return NULL;
250 if(!bind_helper(ret))
251 {
252 ENGINE_free(ret);
253 return NULL;
254 }
255 return ret;
256 }
257
258void ENGINE_load_cswift(void)
259 {
260 /* Copied from eng_[openssl|dyn].c */
261 ENGINE *toadd = engine_cswift();
262 if(!toadd) return;
263 ENGINE_add(toadd);
264 ENGINE_free(toadd);
265 ERR_clear_error();
206 } 266 }
207 267
208/* This is a process-global DSO handle used for loading and unloading 268/* This is a process-global DSO handle used for loading and unloading
@@ -220,7 +280,8 @@ t_swSimpleRequest *p_CSwift_SimpleRequest = NULL;
220t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL; 280t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL;
221 281
222/* Used in the DSO operations. */ 282/* Used in the DSO operations. */
223static const char *CSWIFT_LIBNAME = "swift"; 283static const char def_CSWIFT_LIBNAME[] = "swift";
284static const char *CSWIFT_LIBNAME = def_CSWIFT_LIBNAME;
224static const char *CSWIFT_F1 = "swAcquireAccContext"; 285static const char *CSWIFT_F1 = "swAcquireAccContext";
225static const char *CSWIFT_F2 = "swAttachKeyParam"; 286static const char *CSWIFT_F2 = "swAttachKeyParam";
226static const char *CSWIFT_F3 = "swSimpleRequest"; 287static const char *CSWIFT_F3 = "swSimpleRequest";
@@ -249,8 +310,15 @@ static void release_context(SW_CONTEXT_HANDLE hac)
249 p_CSwift_ReleaseAccContext(hac); 310 p_CSwift_ReleaseAccContext(hac);
250 } 311 }
251 312
313/* Destructor (complements the "ENGINE_cswift()" constructor) */
314static int cswift_destroy(ENGINE *e)
315 {
316 ERR_unload_CSWIFT_strings();
317 return 1;
318 }
319
252/* (de)initialisation functions. */ 320/* (de)initialisation functions. */
253static int cswift_init() 321static int cswift_init(ENGINE *e)
254 { 322 {
255 SW_CONTEXT_HANDLE hac; 323 SW_CONTEXT_HANDLE hac;
256 t_swAcquireAccContext *p1; 324 t_swAcquireAccContext *p1;
@@ -260,15 +328,14 @@ static int cswift_init()
260 328
261 if(cswift_dso != NULL) 329 if(cswift_dso != NULL)
262 { 330 {
263 ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_ALREADY_LOADED); 331 CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_ALREADY_LOADED);
264 goto err; 332 goto err;
265 } 333 }
266 /* Attempt to load libswift.so/swift.dll/whatever. */ 334 /* Attempt to load libswift.so/swift.dll/whatever. */
267 cswift_dso = DSO_load(NULL, CSWIFT_LIBNAME, NULL, 335 cswift_dso = DSO_load(NULL, CSWIFT_LIBNAME, NULL, 0);
268 DSO_FLAG_NAME_TRANSLATION);
269 if(cswift_dso == NULL) 336 if(cswift_dso == NULL)
270 { 337 {
271 ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_DSO_FAILURE); 338 CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
272 goto err; 339 goto err;
273 } 340 }
274 if(!(p1 = (t_swAcquireAccContext *) 341 if(!(p1 = (t_swAcquireAccContext *)
@@ -280,7 +347,7 @@ static int cswift_init()
280 !(p4 = (t_swReleaseAccContext *) 347 !(p4 = (t_swReleaseAccContext *)
281 DSO_bind_func(cswift_dso, CSWIFT_F4))) 348 DSO_bind_func(cswift_dso, CSWIFT_F4)))
282 { 349 {
283 ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_DSO_FAILURE); 350 CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
284 goto err; 351 goto err;
285 } 352 }
286 /* Copy the pointers */ 353 /* Copy the pointers */
@@ -292,7 +359,7 @@ static int cswift_init()
292 * accelerator! */ 359 * accelerator! */
293 if(!get_context(&hac)) 360 if(!get_context(&hac))
294 { 361 {
295 ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_UNIT_FAILURE); 362 CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_UNIT_FAILURE);
296 goto err; 363 goto err;
297 } 364 }
298 release_context(hac); 365 release_context(hac);
@@ -308,16 +375,16 @@ err:
308 return 0; 375 return 0;
309 } 376 }
310 377
311static int cswift_finish() 378static int cswift_finish(ENGINE *e)
312 { 379 {
313 if(cswift_dso == NULL) 380 if(cswift_dso == NULL)
314 { 381 {
315 ENGINEerr(ENGINE_F_CSWIFT_FINISH,ENGINE_R_NOT_LOADED); 382 CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_NOT_LOADED);
316 return 0; 383 return 0;
317 } 384 }
318 if(!DSO_free(cswift_dso)) 385 if(!DSO_free(cswift_dso))
319 { 386 {
320 ENGINEerr(ENGINE_F_CSWIFT_FINISH,ENGINE_R_DSO_FAILURE); 387 CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_UNIT_FAILURE);
321 return 0; 388 return 0;
322 } 389 }
323 cswift_dso = NULL; 390 cswift_dso = NULL;
@@ -328,8 +395,33 @@ static int cswift_finish()
328 return 1; 395 return 1;
329 } 396 }
330 397
398static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
399 {
400 int initialised = ((cswift_dso == NULL) ? 0 : 1);
401 switch(cmd)
402 {
403 case CSWIFT_CMD_SO_PATH:
404 if(p == NULL)
405 {
406 CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,ERR_R_PASSED_NULL_PARAMETER);
407 return 0;
408 }
409 if(initialised)
410 {
411 CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_ALREADY_LOADED);
412 return 0;
413 }
414 CSWIFT_LIBNAME = (const char *)p;
415 return 1;
416 default:
417 break;
418 }
419 CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED);
420 return 0;
421 }
422
331/* Un petit mod_exp */ 423/* Un petit mod_exp */
332static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 424static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
333 const BIGNUM *m, BN_CTX *ctx) 425 const BIGNUM *m, BN_CTX *ctx)
334 { 426 {
335 /* I need somewhere to store temporary serialised values for 427 /* 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,
353 445
354 if(!get_context(&hac)) 446 if(!get_context(&hac))
355 { 447 {
356 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_GET_HANDLE_FAILED); 448 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_UNIT_FAILURE);
357 goto err; 449 goto err;
358 } 450 }
359 acquired = 1; 451 acquired = 1;
360 /* Prepare the params */ 452 /* Prepare the params */
453 BN_CTX_start(ctx);
361 modulus = BN_CTX_get(ctx); 454 modulus = BN_CTX_get(ctx);
362 exponent = BN_CTX_get(ctx); 455 exponent = BN_CTX_get(ctx);
363 argument = BN_CTX_get(ctx); 456 argument = BN_CTX_get(ctx);
364 result = BN_CTX_get(ctx); 457 result = BN_CTX_get(ctx);
365 if(!modulus || !exponent || !argument || !result) 458 if(!result)
366 { 459 {
367 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_BN_CTX_FULL); 460 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_CTX_FULL);
368 goto err; 461 goto err;
369 } 462 }
370 if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) || 463 if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) ||
371 !bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top)) 464 !bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top))
372 { 465 {
373 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_BN_EXPAND_FAIL); 466 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_EXPAND_FAIL);
374 goto err; 467 goto err;
375 } 468 }
376 sw_param.type = SW_ALG_EXP; 469 sw_param.type = SW_ALG_EXP;
@@ -387,13 +480,12 @@ static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
387 case SW_OK: 480 case SW_OK:
388 break; 481 break;
389 case SW_ERR_INPUT_SIZE: 482 case SW_ERR_INPUT_SIZE:
390 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP, 483 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BAD_KEY_SIZE);
391 ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
392 goto err; 484 goto err;
393 default: 485 default:
394 { 486 {
395 char tmpbuf[20]; 487 char tmpbuf[20];
396 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_REQUEST_FAILED); 488 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
397 sprintf(tmpbuf, "%ld", sw_status); 489 sprintf(tmpbuf, "%ld", sw_status);
398 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); 490 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
399 } 491 }
@@ -410,7 +502,7 @@ static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
410 &res, 1)) != SW_OK) 502 &res, 1)) != SW_OK)
411 { 503 {
412 char tmpbuf[20]; 504 char tmpbuf[20];
413 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_REQUEST_FAILED); 505 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
414 sprintf(tmpbuf, "%ld", sw_status); 506 sprintf(tmpbuf, "%ld", sw_status);
415 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); 507 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
416 goto err; 508 goto err;
@@ -421,15 +513,12 @@ static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
421err: 513err:
422 if(acquired) 514 if(acquired)
423 release_context(hac); 515 release_context(hac);
424 if(modulus) ctx->tos--; 516 BN_CTX_end(ctx);
425 if(exponent) ctx->tos--;
426 if(argument) ctx->tos--;
427 if(result) ctx->tos--;
428 return to_return; 517 return to_return;
429 } 518 }
430 519
431/* Un petit mod_exp chinois */ 520/* Un petit mod_exp chinois */
432static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 521static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
433 const BIGNUM *q, const BIGNUM *dmp1, 522 const BIGNUM *q, const BIGNUM *dmp1,
434 const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx) 523 const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx)
435 { 524 {
@@ -449,11 +538,12 @@ static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
449 538
450 if(!get_context(&hac)) 539 if(!get_context(&hac))
451 { 540 {
452 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_GET_HANDLE_FAILED); 541 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_UNIT_FAILURE);
453 goto err; 542 goto err;
454 } 543 }
455 acquired = 1; 544 acquired = 1;
456 /* Prepare the params */ 545 /* Prepare the params */
546 BN_CTX_start(ctx);
457 rsa_p = BN_CTX_get(ctx); 547 rsa_p = BN_CTX_get(ctx);
458 rsa_q = BN_CTX_get(ctx); 548 rsa_q = BN_CTX_get(ctx);
459 rsa_dmp1 = BN_CTX_get(ctx); 549 rsa_dmp1 = BN_CTX_get(ctx);
@@ -461,10 +551,9 @@ static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
461 rsa_iqmp = BN_CTX_get(ctx); 551 rsa_iqmp = BN_CTX_get(ctx);
462 argument = BN_CTX_get(ctx); 552 argument = BN_CTX_get(ctx);
463 result = BN_CTX_get(ctx); 553 result = BN_CTX_get(ctx);
464 if(!rsa_p || !rsa_q || !rsa_dmp1 || !rsa_dmq1 || !rsa_iqmp || 554 if(!result)
465 !argument || !result)
466 { 555 {
467 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_BN_CTX_FULL); 556 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_CTX_FULL);
468 goto err; 557 goto err;
469 } 558 }
470 if(!bn_wexpand(rsa_p, p->top) || !bn_wexpand(rsa_q, q->top) || 559 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,
474 !bn_wexpand(argument, a->top) || 563 !bn_wexpand(argument, a->top) ||
475 !bn_wexpand(result, p->top + q->top)) 564 !bn_wexpand(result, p->top + q->top))
476 { 565 {
477 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_BN_EXPAND_FAIL); 566 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
478 goto err; 567 goto err;
479 } 568 }
480 sw_param.type = SW_ALG_CRT; 569 sw_param.type = SW_ALG_CRT;
@@ -498,13 +587,12 @@ static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
498 case SW_OK: 587 case SW_OK:
499 break; 588 break;
500 case SW_ERR_INPUT_SIZE: 589 case SW_ERR_INPUT_SIZE:
501 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT, 590 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BAD_KEY_SIZE);
502 ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
503 goto err; 591 goto err;
504 default: 592 default:
505 { 593 {
506 char tmpbuf[20]; 594 char tmpbuf[20];
507 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_REQUEST_FAILED); 595 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
508 sprintf(tmpbuf, "%ld", sw_status); 596 sprintf(tmpbuf, "%ld", sw_status);
509 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); 597 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
510 } 598 }
@@ -521,7 +609,7 @@ static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
521 &res, 1)) != SW_OK) 609 &res, 1)) != SW_OK)
522 { 610 {
523 char tmpbuf[20]; 611 char tmpbuf[20];
524 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_REQUEST_FAILED); 612 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
525 sprintf(tmpbuf, "%ld", sw_status); 613 sprintf(tmpbuf, "%ld", sw_status);
526 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); 614 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
527 goto err; 615 goto err;
@@ -532,17 +620,12 @@ static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
532err: 620err:
533 if(acquired) 621 if(acquired)
534 release_context(hac); 622 release_context(hac);
535 if(rsa_p) ctx->tos--; 623 BN_CTX_end(ctx);
536 if(rsa_q) ctx->tos--;
537 if(rsa_dmp1) ctx->tos--;
538 if(rsa_dmq1) ctx->tos--;
539 if(rsa_iqmp) ctx->tos--;
540 if(argument) ctx->tos--;
541 if(result) ctx->tos--;
542 return to_return; 624 return to_return;
543 } 625 }
544 626
545static int cswift_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa) 627#ifndef OPENSSL_NO_RSA
628static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
546 { 629 {
547 BN_CTX *ctx; 630 BN_CTX *ctx;
548 int to_return = 0; 631 int to_return = 0;
@@ -551,7 +634,7 @@ static int cswift_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa)
551 goto err; 634 goto err;
552 if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) 635 if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
553 { 636 {
554 ENGINEerr(ENGINE_F_CSWIFT_RSA_MOD_EXP,ENGINE_R_MISSING_KEY_COMPONENTS); 637 CSWIFTerr(CSWIFT_F_CSWIFT_RSA_MOD_EXP,CSWIFT_R_MISSING_KEY_COMPONENTS);
555 goto err; 638 goto err;
556 } 639 }
557 to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1, 640 to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
@@ -561,14 +644,16 @@ err:
561 BN_CTX_free(ctx); 644 BN_CTX_free(ctx);
562 return to_return; 645 return to_return;
563 } 646 }
647#endif
564 648
565/* This function is aliased to mod_exp (with the mont stuff dropped). */ 649/* This function is aliased to mod_exp (with the mont stuff dropped). */
566static int cswift_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 650static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
567 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) 651 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
568 { 652 {
569 return cswift_mod_exp(r, a, p, m, ctx); 653 return cswift_mod_exp(r, a, p, m, ctx);
570 } 654 }
571 655
656#ifndef OPENSSL_NO_DSA
572static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa) 657static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
573 { 658 {
574 SW_CONTEXT_HANDLE hac; 659 SW_CONTEXT_HANDLE hac;
@@ -589,19 +674,20 @@ static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
589 goto err; 674 goto err;
590 if(!get_context(&hac)) 675 if(!get_context(&hac))
591 { 676 {
592 ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_GET_HANDLE_FAILED); 677 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_UNIT_FAILURE);
593 goto err; 678 goto err;
594 } 679 }
595 acquired = 1; 680 acquired = 1;
596 /* Prepare the params */ 681 /* Prepare the params */
682 BN_CTX_start(ctx);
597 dsa_p = BN_CTX_get(ctx); 683 dsa_p = BN_CTX_get(ctx);
598 dsa_q = BN_CTX_get(ctx); 684 dsa_q = BN_CTX_get(ctx);
599 dsa_g = BN_CTX_get(ctx); 685 dsa_g = BN_CTX_get(ctx);
600 dsa_key = BN_CTX_get(ctx); 686 dsa_key = BN_CTX_get(ctx);
601 result = BN_CTX_get(ctx); 687 result = BN_CTX_get(ctx);
602 if(!dsa_p || !dsa_q || !dsa_g || !dsa_key || !result) 688 if(!result)
603 { 689 {
604 ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_BN_CTX_FULL); 690 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_CTX_FULL);
605 goto err; 691 goto err;
606 } 692 }
607 if(!bn_wexpand(dsa_p, dsa->p->top) || 693 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)
610 !bn_wexpand(dsa_key, dsa->priv_key->top) || 696 !bn_wexpand(dsa_key, dsa->priv_key->top) ||
611 !bn_wexpand(result, dsa->p->top)) 697 !bn_wexpand(result, dsa->p->top))
612 { 698 {
613 ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_BN_EXPAND_FAIL); 699 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_EXPAND_FAIL);
614 goto err; 700 goto err;
615 } 701 }
616 sw_param.type = SW_ALG_DSA; 702 sw_param.type = SW_ALG_DSA;
@@ -633,13 +719,12 @@ static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
633 case SW_OK: 719 case SW_OK:
634 break; 720 break;
635 case SW_ERR_INPUT_SIZE: 721 case SW_ERR_INPUT_SIZE:
636 ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN, 722 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BAD_KEY_SIZE);
637 ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
638 goto err; 723 goto err;
639 default: 724 default:
640 { 725 {
641 char tmpbuf[20]; 726 char tmpbuf[20];
642 ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_REQUEST_FAILED); 727 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
643 sprintf(tmpbuf, "%ld", sw_status); 728 sprintf(tmpbuf, "%ld", sw_status);
644 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); 729 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
645 } 730 }
@@ -657,7 +742,7 @@ static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
657 if(sw_status != SW_OK) 742 if(sw_status != SW_OK)
658 { 743 {
659 char tmpbuf[20]; 744 char tmpbuf[20];
660 ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_REQUEST_FAILED); 745 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
661 sprintf(tmpbuf, "%ld", sw_status); 746 sprintf(tmpbuf, "%ld", sw_status);
662 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); 747 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
663 goto err; 748 goto err;
@@ -672,13 +757,11 @@ static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
672err: 757err:
673 if(acquired) 758 if(acquired)
674 release_context(hac); 759 release_context(hac);
675 if(dsa_p) ctx->tos--;
676 if(dsa_q) ctx->tos--;
677 if(dsa_g) ctx->tos--;
678 if(dsa_key) ctx->tos--;
679 if(result) ctx->tos--;
680 if(ctx) 760 if(ctx)
761 {
762 BN_CTX_end(ctx);
681 BN_CTX_free(ctx); 763 BN_CTX_free(ctx);
764 }
682 return to_return; 765 return to_return;
683 } 766 }
684 767
@@ -703,19 +786,20 @@ static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
703 goto err; 786 goto err;
704 if(!get_context(&hac)) 787 if(!get_context(&hac))
705 { 788 {
706 ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_GET_HANDLE_FAILED); 789 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_UNIT_FAILURE);
707 goto err; 790 goto err;
708 } 791 }
709 acquired = 1; 792 acquired = 1;
710 /* Prepare the params */ 793 /* Prepare the params */
794 BN_CTX_start(ctx);
711 dsa_p = BN_CTX_get(ctx); 795 dsa_p = BN_CTX_get(ctx);
712 dsa_q = BN_CTX_get(ctx); 796 dsa_q = BN_CTX_get(ctx);
713 dsa_g = BN_CTX_get(ctx); 797 dsa_g = BN_CTX_get(ctx);
714 dsa_key = BN_CTX_get(ctx); 798 dsa_key = BN_CTX_get(ctx);
715 argument = BN_CTX_get(ctx); 799 argument = BN_CTX_get(ctx);
716 if(!dsa_p || !dsa_q || !dsa_g || !dsa_key || !argument) 800 if(!argument)
717 { 801 {
718 ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_BN_CTX_FULL); 802 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_CTX_FULL);
719 goto err; 803 goto err;
720 } 804 }
721 if(!bn_wexpand(dsa_p, dsa->p->top) || 805 if(!bn_wexpand(dsa_p, dsa->p->top) ||
@@ -724,7 +808,7 @@ static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
724 !bn_wexpand(dsa_key, dsa->pub_key->top) || 808 !bn_wexpand(dsa_key, dsa->pub_key->top) ||
725 !bn_wexpand(argument, 40)) 809 !bn_wexpand(argument, 40))
726 { 810 {
727 ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_BN_EXPAND_FAIL); 811 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_EXPAND_FAIL);
728 goto err; 812 goto err;
729 } 813 }
730 sw_param.type = SW_ALG_DSA; 814 sw_param.type = SW_ALG_DSA;
@@ -747,13 +831,12 @@ static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
747 case SW_OK: 831 case SW_OK:
748 break; 832 break;
749 case SW_ERR_INPUT_SIZE: 833 case SW_ERR_INPUT_SIZE:
750 ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY, 834 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BAD_KEY_SIZE);
751 ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
752 goto err; 835 goto err;
753 default: 836 default:
754 { 837 {
755 char tmpbuf[20]; 838 char tmpbuf[20];
756 ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_REQUEST_FAILED); 839 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
757 sprintf(tmpbuf, "%ld", sw_status); 840 sprintf(tmpbuf, "%ld", sw_status);
758 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); 841 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
759 } 842 }
@@ -775,7 +858,7 @@ static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
775 if(sw_status != SW_OK) 858 if(sw_status != SW_OK)
776 { 859 {
777 char tmpbuf[20]; 860 char tmpbuf[20];
778 ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_REQUEST_FAILED); 861 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
779 sprintf(tmpbuf, "%ld", sw_status); 862 sprintf(tmpbuf, "%ld", sw_status);
780 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); 863 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
781 goto err; 864 goto err;
@@ -786,22 +869,39 @@ static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
786err: 869err:
787 if(acquired) 870 if(acquired)
788 release_context(hac); 871 release_context(hac);
789 if(dsa_p) ctx->tos--;
790 if(dsa_q) ctx->tos--;
791 if(dsa_g) ctx->tos--;
792 if(dsa_key) ctx->tos--;
793 if(argument) ctx->tos--;
794 if(ctx) 872 if(ctx)
873 {
874 BN_CTX_end(ctx);
795 BN_CTX_free(ctx); 875 BN_CTX_free(ctx);
876 }
796 return to_return; 877 return to_return;
797 } 878 }
879#endif
798 880
881#ifndef OPENSSL_NO_DH
799/* This function is aliased to mod_exp (with the dh and mont dropped). */ 882/* This function is aliased to mod_exp (with the dh and mont dropped). */
800static int cswift_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, 883static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
884 const BIGNUM *a, const BIGNUM *p,
801 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) 885 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
802 { 886 {
803 return cswift_mod_exp(r, a, p, m, ctx); 887 return cswift_mod_exp(r, a, p, m, ctx);
804 } 888 }
889#endif
890
891/* This stuff is needed if this ENGINE is being compiled into a self-contained
892 * shared-library. */
893#ifdef ENGINE_DYNAMIC_SUPPORT
894static int bind_fn(ENGINE *e, const char *id)
895 {
896 if(id && (strcmp(id, engine_cswift_id) != 0))
897 return 0;
898 if(!bind_helper(e))
899 return 0;
900 return 1;
901 }
902IMPLEMENT_DYNAMIC_CHECK_FN()
903IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
904#endif /* ENGINE_DYNAMIC_SUPPORT */
805 905
806#endif /* !NO_HW_CSWIFT */ 906#endif /* !OPENSSL_NO_HW_CSWIFT */
807#endif /* !NO_HW */ 907#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 @@
1/* hw_cswift_err.c */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include "hw_cswift_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA CSWIFT_str_functs[]=
68 {
69{ERR_PACK(0,CSWIFT_F_CSWIFT_CTRL,0), "CSWIFT_CTRL"},
70{ERR_PACK(0,CSWIFT_F_CSWIFT_DSA_SIGN,0), "CSWIFT_DSA_SIGN"},
71{ERR_PACK(0,CSWIFT_F_CSWIFT_DSA_VERIFY,0), "CSWIFT_DSA_VERIFY"},
72{ERR_PACK(0,CSWIFT_F_CSWIFT_FINISH,0), "CSWIFT_FINISH"},
73{ERR_PACK(0,CSWIFT_F_CSWIFT_INIT,0), "CSWIFT_INIT"},
74{ERR_PACK(0,CSWIFT_F_CSWIFT_MOD_EXP,0), "CSWIFT_MOD_EXP"},
75{ERR_PACK(0,CSWIFT_F_CSWIFT_MOD_EXP_CRT,0), "CSWIFT_MOD_EXP_CRT"},
76{ERR_PACK(0,CSWIFT_F_CSWIFT_RSA_MOD_EXP,0), "CSWIFT_RSA_MOD_EXP"},
77{0,NULL}
78 };
79
80static ERR_STRING_DATA CSWIFT_str_reasons[]=
81 {
82{CSWIFT_R_ALREADY_LOADED ,"already loaded"},
83{CSWIFT_R_BAD_KEY_SIZE ,"bad key size"},
84{CSWIFT_R_BN_CTX_FULL ,"bn ctx full"},
85{CSWIFT_R_BN_EXPAND_FAIL ,"bn expand fail"},
86{CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
87{CSWIFT_R_MISSING_KEY_COMPONENTS ,"missing key components"},
88{CSWIFT_R_NOT_LOADED ,"not loaded"},
89{CSWIFT_R_REQUEST_FAILED ,"request failed"},
90{CSWIFT_R_UNIT_FAILURE ,"unit failure"},
91{0,NULL}
92 };
93
94#endif
95
96#ifdef CSWIFT_LIB_NAME
97static ERR_STRING_DATA CSWIFT_lib_name[]=
98 {
99{0 ,CSWIFT_LIB_NAME},
100{0,NULL}
101 };
102#endif
103
104
105static int CSWIFT_lib_error_code=0;
106static int CSWIFT_error_init=1;
107
108static void ERR_load_CSWIFT_strings(void)
109 {
110 if (CSWIFT_lib_error_code == 0)
111 CSWIFT_lib_error_code=ERR_get_next_error_library();
112
113 if (CSWIFT_error_init)
114 {
115 CSWIFT_error_init=0;
116#ifndef OPENSSL_NO_ERR
117 ERR_load_strings(CSWIFT_lib_error_code,CSWIFT_str_functs);
118 ERR_load_strings(CSWIFT_lib_error_code,CSWIFT_str_reasons);
119#endif
120
121#ifdef CSWIFT_LIB_NAME
122 CSWIFT_lib_name->error = ERR_PACK(CSWIFT_lib_error_code,0,0);
123 ERR_load_strings(0,CSWIFT_lib_name);
124#endif
125 }
126 }
127
128static void ERR_unload_CSWIFT_strings(void)
129 {
130 if (CSWIFT_error_init == 0)
131 {
132#ifndef OPENSSL_NO_ERR
133 ERR_unload_strings(CSWIFT_lib_error_code,CSWIFT_str_functs);
134 ERR_unload_strings(CSWIFT_lib_error_code,CSWIFT_str_reasons);
135#endif
136
137#ifdef CSWIFT_LIB_NAME
138 ERR_unload_strings(0,CSWIFT_lib_name);
139#endif
140 CSWIFT_error_init=1;
141 }
142 }
143
144static void ERR_CSWIFT_error(int function, int reason, char *file, int line)
145 {
146 if (CSWIFT_lib_error_code == 0)
147 CSWIFT_lib_error_code=ERR_get_next_error_library();
148 ERR_PUT_error(CSWIFT_lib_error_code,function,reason,file,line);
149 }
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 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#ifndef HEADER_CSWIFT_ERR_H
56#define HEADER_CSWIFT_ERR_H
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_CSWIFT_strings(void);
63static void ERR_unload_CSWIFT_strings(void);
64static void ERR_CSWIFT_error(int function, int reason, char *file, int line);
65#define CSWIFTerr(f,r) ERR_CSWIFT_error((f),(r),__FILE__,__LINE__)
66
67/* Error codes for the CSWIFT functions. */
68
69/* Function codes. */
70#define CSWIFT_F_CSWIFT_CTRL 100
71#define CSWIFT_F_CSWIFT_DSA_SIGN 101
72#define CSWIFT_F_CSWIFT_DSA_VERIFY 102
73#define CSWIFT_F_CSWIFT_FINISH 103
74#define CSWIFT_F_CSWIFT_INIT 104
75#define CSWIFT_F_CSWIFT_MOD_EXP 105
76#define CSWIFT_F_CSWIFT_MOD_EXP_CRT 106
77#define CSWIFT_F_CSWIFT_RSA_MOD_EXP 107
78
79/* Reason codes. */
80#define CSWIFT_R_ALREADY_LOADED 100
81#define CSWIFT_R_BAD_KEY_SIZE 101
82#define CSWIFT_R_BN_CTX_FULL 102
83#define CSWIFT_R_BN_EXPAND_FAIL 103
84#define CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED 104
85#define CSWIFT_R_MISSING_KEY_COMPONENTS 105
86#define CSWIFT_R_NOT_LOADED 106
87#define CSWIFT_R_REQUEST_FAILED 107
88#define CSWIFT_R_UNIT_FAILURE 108
89
90#ifdef __cplusplus
91}
92#endif
93#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 @@
4 * for the OpenSSL project 2000. 4 * for the OpenSSL project 2000.
5 */ 5 */
6/* ==================================================================== 6/* ====================================================================
7 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 7 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
@@ -58,15 +58,16 @@
58 */ 58 */
59 59
60#include <stdio.h> 60#include <stdio.h>
61#include <string.h>
61#include <openssl/crypto.h> 62#include <openssl/crypto.h>
62#include <openssl/pem.h> 63#include <openssl/pem.h>
63#include "cryptlib.h" 64#include "cryptlib.h"
64#include <openssl/dso.h> 65#include <openssl/dso.h>
65#include "engine_int.h"
66#include <openssl/engine.h> 66#include <openssl/engine.h>
67#include <openssl/ui.h>
67 68
68#ifndef NO_HW 69#ifndef OPENSSL_NO_HW
69#ifndef NO_HW_NCIPHER 70#ifndef OPENSSL_NO_HW_NCIPHER
70 71
71/* Attribution notice: nCipher have said several times that it's OK for 72/* Attribution notice: nCipher have said several times that it's OK for
72 * us to implement a general interface to their boxes, and recently declared 73 * us to implement a general interface to their boxes, and recently declared
@@ -82,9 +83,13 @@
82#include "vendor_defns/hwcryptohook.h" 83#include "vendor_defns/hwcryptohook.h"
83#endif 84#endif
84 85
85static int hwcrhk_init(void); 86#define HWCRHK_LIB_NAME "hwcrhk engine"
86static int hwcrhk_finish(void); 87#include "hw_ncipher_err.c"
87static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)()); 88
89static int hwcrhk_destroy(ENGINE *e);
90static int hwcrhk_init(ENGINE *e);
91static int hwcrhk_finish(ENGINE *e);
92static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
88 93
89/* Functions to handle mutexes */ 94/* Functions to handle mutexes */
90static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*); 95static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*);
@@ -93,39 +98,77 @@ static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex*);
93static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*); 98static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*);
94 99
95/* BIGNUM stuff */ 100/* BIGNUM stuff */
96static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 101static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
97 const BIGNUM *m, BN_CTX *ctx); 102 const BIGNUM *m, BN_CTX *ctx);
98 103
104#ifndef OPENSSL_NO_RSA
99/* RSA stuff */ 105/* RSA stuff */
100static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa); 106static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa);
107#endif
101/* This function is aliased to mod_exp (with the mont stuff dropped). */ 108/* This function is aliased to mod_exp (with the mont stuff dropped). */
102static int hwcrhk_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 109static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
103 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); 110 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
104 111
105/* DH stuff */ 112/* DH stuff */
106/* This function is alised to mod_exp (with the DH and mont dropped). */ 113/* This function is alised to mod_exp (with the DH and mont dropped). */
107static int hwcrhk_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, 114static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
108 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); 115 const BIGNUM *a, const BIGNUM *p,
116 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
109 117
110/* RAND stuff */ 118/* RAND stuff */
111static int hwcrhk_rand_bytes(unsigned char *buf, int num); 119static int hwcrhk_rand_bytes(unsigned char *buf, int num);
112static int hwcrhk_rand_status(void); 120static int hwcrhk_rand_status(void);
113 121
114/* KM stuff */ 122/* KM stuff */
115static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, 123static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
116 const char *passphrase); 124 UI_METHOD *ui_method, void *callback_data);
117static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, 125static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
118 const char *passphrase); 126 UI_METHOD *ui_method, void *callback_data);
119static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, 127static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
120 int index,long argl, void *argp); 128 int ind,long argl, void *argp);
121 129
122/* Interaction stuff */ 130/* Interaction stuff */
131static int hwcrhk_insert_card(const char *prompt_info,
132 const char *wrong_info,
133 HWCryptoHook_PassphraseContext *ppctx,
134 HWCryptoHook_CallerContext *cactx);
123static int hwcrhk_get_pass(const char *prompt_info, 135static int hwcrhk_get_pass(const char *prompt_info,
124 int *len_io, char *buf, 136 int *len_io, char *buf,
125 HWCryptoHook_PassphraseContext *ppctx, 137 HWCryptoHook_PassphraseContext *ppctx,
126 HWCryptoHook_CallerContext *cactx); 138 HWCryptoHook_CallerContext *cactx);
127static void hwcrhk_log_message(void *logstream, const char *message); 139static void hwcrhk_log_message(void *logstr, const char *message);
140
141/* The definitions for control commands specific to this engine */
142#define HWCRHK_CMD_SO_PATH ENGINE_CMD_BASE
143#define HWCRHK_CMD_FORK_CHECK (ENGINE_CMD_BASE + 1)
144#define HWCRHK_CMD_THREAD_LOCKING (ENGINE_CMD_BASE + 2)
145#define HWCRHK_CMD_SET_USER_INTERFACE (ENGINE_CMD_BASE + 3)
146#define HWCRHK_CMD_SET_CALLBACK_DATA (ENGINE_CMD_BASE + 4)
147static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = {
148 {HWCRHK_CMD_SO_PATH,
149 "SO_PATH",
150 "Specifies the path to the 'hwcrhk' shared library",
151 ENGINE_CMD_FLAG_STRING},
152 {HWCRHK_CMD_FORK_CHECK,
153 "FORK_CHECK",
154 "Turns fork() checking on or off (boolean)",
155 ENGINE_CMD_FLAG_NUMERIC},
156 {HWCRHK_CMD_THREAD_LOCKING,
157 "THREAD_LOCKING",
158 "Turns thread-safe locking on or off (boolean)",
159 ENGINE_CMD_FLAG_NUMERIC},
160 {HWCRHK_CMD_SET_USER_INTERFACE,
161 "SET_USER_INTERFACE",
162 "Set the global user interface (internal)",
163 ENGINE_CMD_FLAG_INTERNAL},
164 {HWCRHK_CMD_SET_CALLBACK_DATA,
165 "SET_CALLBACK_DATA",
166 "Set the global user interface extra data (internal)",
167 ENGINE_CMD_FLAG_INTERNAL},
168 {0, NULL, NULL, 0}
169 };
128 170
171#ifndef OPENSSL_NO_RSA
129/* Our internal RSA_METHOD that we provide pointers to */ 172/* Our internal RSA_METHOD that we provide pointers to */
130static RSA_METHOD hwcrhk_rsa = 173static RSA_METHOD hwcrhk_rsa =
131 { 174 {
@@ -143,7 +186,9 @@ static RSA_METHOD hwcrhk_rsa =
143 NULL, 186 NULL,
144 NULL 187 NULL
145 }; 188 };
189#endif
146 190
191#ifndef OPENSSL_NO_DH
147/* Our internal DH_METHOD that we provide pointers to */ 192/* Our internal DH_METHOD that we provide pointers to */
148static DH_METHOD hwcrhk_dh = 193static DH_METHOD hwcrhk_dh =
149 { 194 {
@@ -156,6 +201,7 @@ static DH_METHOD hwcrhk_dh =
156 0, 201 0,
157 NULL 202 NULL
158 }; 203 };
204#endif
159 205
160static RAND_METHOD hwcrhk_rand = 206static RAND_METHOD hwcrhk_rand =
161 { 207 {
@@ -168,26 +214,9 @@ static RAND_METHOD hwcrhk_rand =
168 hwcrhk_rand_status, 214 hwcrhk_rand_status,
169 }; 215 };
170 216
171/* Our ENGINE structure. */ 217/* Constants used when creating the ENGINE */
172static ENGINE engine_hwcrhk = 218static const char *engine_hwcrhk_id = "chil";
173 { 219static const char *engine_hwcrhk_name = "nCipher hardware engine support";
174 "chil",
175 "nCipher hardware engine support",
176 &hwcrhk_rsa,
177 NULL,
178 &hwcrhk_dh,
179 &hwcrhk_rand,
180 hwcrhk_mod_exp,
181 NULL,
182 hwcrhk_init,
183 hwcrhk_finish,
184 hwcrhk_ctrl,
185 hwcrhk_load_privkey,
186 hwcrhk_load_pubkey,
187 0, /* no flags */
188 0, 0, /* no references */
189 NULL, NULL /* unlinked */
190 };
191 220
192/* Internal stuff for HWCryptoHook */ 221/* Internal stuff for HWCryptoHook */
193 222
@@ -204,7 +233,8 @@ struct HWCryptoHook_MutexValue
204 into HWCryptoHook_PassphraseContext */ 233 into HWCryptoHook_PassphraseContext */
205struct HWCryptoHook_PassphraseContextValue 234struct HWCryptoHook_PassphraseContextValue
206 { 235 {
207 void *any; 236 UI_METHOD *ui_method;
237 void *callback_data;
208 }; 238 };
209 239
210/* hwcryptohook.h has some typedefs that turn 240/* hwcryptohook.h has some typedefs that turn
@@ -212,7 +242,10 @@ struct HWCryptoHook_PassphraseContextValue
212 into HWCryptoHook_CallerContext */ 242 into HWCryptoHook_CallerContext */
213struct HWCryptoHook_CallerContextValue 243struct HWCryptoHook_CallerContextValue
214 { 244 {
215 void *any; 245 pem_password_cb *password_callback; /* Deprecated! Only present for
246 backward compatibility! */
247 UI_METHOD *ui_method;
248 void *callback_data;
216 }; 249 };
217 250
218/* The MPI structure in HWCryptoHook is pretty compatible with OpenSSL 251/* The MPI structure in HWCryptoHook is pretty compatible with OpenSSL
@@ -222,31 +255,27 @@ struct HWCryptoHook_CallerContextValue
222#define MPI2BN(bn, mp) \ 255#define MPI2BN(bn, mp) \
223 {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;} 256 {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
224 257
225#if 0 /* Card and password management is not yet supported */
226/* HWCryptoHook callbacks. insert_card() and get_pass() are not yet
227 defined, because we haven't quite decided on the proper form yet.
228 log_message() just adds an entry in the error stack. I don't know
229 if that's good or bad... */
230static int insert_card(const char *prompt_info,
231 const char *wrong_info,
232 HWCryptoHook_PassphraseContext *ppctx,
233 HWCryptoHook_CallerContext *cactx);
234static int get_pass(const char *prompt_info,
235 int *len_io, char *buf,
236 HWCryptoHook_PassphraseContext *ppctx,
237 HWCryptoHook_CallerContext *cactx);
238#endif
239
240static BIO *logstream = NULL; 258static BIO *logstream = NULL;
241static pem_password_cb *password_callback = NULL;
242#if 0
243static void *password_callback_userdata = NULL;
244#endif
245static int disable_mutex_callbacks = 0; 259static int disable_mutex_callbacks = 0;
246 260
261/* One might wonder why these are needed, since one can pass down at least
262 a UI_METHOD and a pointer to callback data to the key-loading functions.
263 The thing is that the ModExp and RSAImmed functions can load keys as well,
264 if the data they get is in a special, nCipher-defined format (hint: if you
265 look at the private exponent of the RSA data as a string, you'll see this
266 string: "nCipher KM tool key id", followed by some bytes, followed a key
267 identity string, followed by more bytes. This happens when you use "embed"
268 keys instead of "hwcrhk" keys). Unfortunately, those functions do not take
269 any passphrase or caller context, and our functions can't really take any
270 callback data either. Still, the "insert_card" and "get_passphrase"
271 callbacks may be called down the line, and will need to know what user
272 interface callbacks to call, and having callback data from the application
273 may be a nice thing as well, so we need to keep track of that globally. */
274static HWCryptoHook_CallerContext password_context = { NULL, NULL, NULL };
275
247/* Stuff to pass to the HWCryptoHook library */ 276/* Stuff to pass to the HWCryptoHook library */
248static HWCryptoHook_InitInfo hwcrhk_globals = { 277static HWCryptoHook_InitInfo hwcrhk_globals = {
249 0, /* Flags */ 278 HWCryptoHook_InitFlags_SimpleForkCheck, /* Flags */
250 &logstream, /* logstream */ 279 &logstream, /* logstream */
251 sizeof(BN_ULONG), /* limbsize */ 280 sizeof(BN_ULONG), /* limbsize */
252 0, /* mslimb first: false for BNs */ 281 0, /* mslimb first: false for BNs */
@@ -280,20 +309,42 @@ static HWCryptoHook_InitInfo hwcrhk_globals = {
280 0, /* hwcrhk_cv_destroy, */ 309 0, /* hwcrhk_cv_destroy, */
281 310
282 hwcrhk_get_pass, /* pass phrase */ 311 hwcrhk_get_pass, /* pass phrase */
283 0, /* insert_card, */ /* insert a card */ 312 hwcrhk_insert_card, /* insert a card */
284 hwcrhk_log_message /* Log message */ 313 hwcrhk_log_message /* Log message */
285}; 314};
286 315
287 316
288/* Now, to our own code */ 317/* Now, to our own code */
289 318
290/* As this is only ever called once, there's no need for locking 319/* This internal function is used by ENGINE_ncipher() and possibly by the
291 * (indeed - the lock will already be held by our caller!!!) */ 320 * "dynamic" ENGINE support too */
292ENGINE *ENGINE_ncipher() 321static int bind_helper(ENGINE *e)
293 { 322 {
294 RSA_METHOD *meth1; 323#ifndef OPENSSL_NO_RSA
295 DH_METHOD *meth2; 324 const RSA_METHOD *meth1;
325#endif
326#ifndef OPENSSL_NO_DH
327 const DH_METHOD *meth2;
328#endif
329 if(!ENGINE_set_id(e, engine_hwcrhk_id) ||
330 !ENGINE_set_name(e, engine_hwcrhk_name) ||
331#ifndef OPENSSL_NO_RSA
332 !ENGINE_set_RSA(e, &hwcrhk_rsa) ||
333#endif
334#ifndef OPENSSL_NO_DH
335 !ENGINE_set_DH(e, &hwcrhk_dh) ||
336#endif
337 !ENGINE_set_RAND(e, &hwcrhk_rand) ||
338 !ENGINE_set_destroy_function(e, hwcrhk_destroy) ||
339 !ENGINE_set_init_function(e, hwcrhk_init) ||
340 !ENGINE_set_finish_function(e, hwcrhk_finish) ||
341 !ENGINE_set_ctrl_function(e, hwcrhk_ctrl) ||
342 !ENGINE_set_load_privkey_function(e, hwcrhk_load_privkey) ||
343 !ENGINE_set_load_pubkey_function(e, hwcrhk_load_pubkey) ||
344 !ENGINE_set_cmd_defns(e, hwcrhk_cmd_defns))
345 return 0;
296 346
347#ifndef OPENSSL_NO_RSA
297 /* We know that the "PKCS1_SSLeay()" functions hook properly 348 /* We know that the "PKCS1_SSLeay()" functions hook properly
298 * to the cswift-specific mod_exp and mod_exp_crt so we use 349 * to the cswift-specific mod_exp and mod_exp_crt so we use
299 * those functions. NB: We don't use ENGINE_openssl() or 350 * those functions. NB: We don't use ENGINE_openssl() or
@@ -306,12 +357,41 @@ ENGINE *ENGINE_ncipher()
306 hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec; 357 hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
307 hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc; 358 hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
308 hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec; 359 hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
360#endif
309 361
362#ifndef OPENSSL_NO_DH
310 /* Much the same for Diffie-Hellman */ 363 /* Much the same for Diffie-Hellman */
311 meth2 = DH_OpenSSL(); 364 meth2 = DH_OpenSSL();
312 hwcrhk_dh.generate_key = meth2->generate_key; 365 hwcrhk_dh.generate_key = meth2->generate_key;
313 hwcrhk_dh.compute_key = meth2->compute_key; 366 hwcrhk_dh.compute_key = meth2->compute_key;
314 return &engine_hwcrhk; 367#endif
368
369 /* Ensure the hwcrhk error handling is set up */
370 ERR_load_HWCRHK_strings();
371 return 1;
372 }
373
374static ENGINE *engine_ncipher(void)
375 {
376 ENGINE *ret = ENGINE_new();
377 if(!ret)
378 return NULL;
379 if(!bind_helper(ret))
380 {
381 ENGINE_free(ret);
382 return NULL;
383 }
384 return ret;
385 }
386
387void ENGINE_load_chil(void)
388 {
389 /* Copied from eng_[openssl|dyn].c */
390 ENGINE *toadd = engine_ncipher();
391 if(!toadd) return;
392 ENGINE_add(toadd);
393 ENGINE_free(toadd);
394 ERR_clear_error();
315 } 395 }
316 396
317/* This is a process-global DSO handle used for loading and unloading 397/* This is a process-global DSO handle used for loading and unloading
@@ -321,30 +401,41 @@ ENGINE *ENGINE_ncipher()
321 * implicitly. */ 401 * implicitly. */
322static DSO *hwcrhk_dso = NULL; 402static DSO *hwcrhk_dso = NULL;
323static HWCryptoHook_ContextHandle hwcrhk_context = 0; 403static HWCryptoHook_ContextHandle hwcrhk_context = 0;
324static int hndidx = -1; /* Index for KM handle. Not really used yet. */ 404#ifndef OPENSSL_NO_RSA
405static int hndidx_rsa = -1; /* Index for KM handle. Not really used yet. */
406#endif
325 407
326/* These are the function pointers that are (un)set when the library has 408/* These are the function pointers that are (un)set when the library has
327 * successfully (un)loaded. */ 409 * successfully (un)loaded. */
328static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL; 410static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL;
329static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL; 411static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL;
330static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL; 412static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL;
413#ifndef OPENSSL_NO_RSA
331static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL; 414static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL;
415#endif
332static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL; 416static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL;
417#ifndef OPENSSL_NO_RSA
333static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL; 418static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL;
334static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL; 419static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL;
335static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL; 420static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL;
421#endif
336static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL; 422static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL;
337 423
338/* Used in the DSO operations. */ 424/* Used in the DSO operations. */
339static const char *HWCRHK_LIBNAME = "nfhwcrhk"; 425static const char def_HWCRHK_LIBNAME[] = "nfhwcrhk";
426static const char *HWCRHK_LIBNAME = def_HWCRHK_LIBNAME;
340static const char *n_hwcrhk_Init = "HWCryptoHook_Init"; 427static const char *n_hwcrhk_Init = "HWCryptoHook_Init";
341static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish"; 428static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish";
342static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp"; 429static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp";
430#ifndef OPENSSL_NO_RSA
343static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA"; 431static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA";
432#endif
344static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes"; 433static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes";
434#ifndef OPENSSL_NO_RSA
345static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey"; 435static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey";
346static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey"; 436static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey";
347static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey"; 437static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey";
438#endif
348static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT"; 439static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT";
349 440
350/* HWCryptoHook library functions and mechanics - these are used by the 441/* HWCryptoHook library functions and mechanics - these are used by the
@@ -353,16 +444,17 @@ static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT";
353 * called, the checking and error handling is probably down there. */ 444 * called, the checking and error handling is probably down there. */
354 445
355/* utility function to obtain a context */ 446/* utility function to obtain a context */
356static int get_context(HWCryptoHook_ContextHandle *hac) 447static int get_context(HWCryptoHook_ContextHandle *hac,
448 HWCryptoHook_CallerContext *cac)
357 { 449 {
358 char tempbuf[1024]; 450 char tempbuf[1024];
359 HWCryptoHook_ErrMsgBuf rmsg; 451 HWCryptoHook_ErrMsgBuf rmsg;
360 452
361 rmsg.buf = tempbuf; 453 rmsg.buf = tempbuf;
362 rmsg.size = 1024; 454 rmsg.size = sizeof(tempbuf);
363 455
364 *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg, 456 *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg,
365 NULL); 457 cac);
366 if (!*hac) 458 if (!*hac)
367 return 0; 459 return 0;
368 return 1; 460 return 1;
@@ -374,30 +466,38 @@ static void release_context(HWCryptoHook_ContextHandle hac)
374 p_hwcrhk_Finish(hac); 466 p_hwcrhk_Finish(hac);
375 } 467 }
376 468
469/* Destructor (complements the "ENGINE_ncipher()" constructor) */
470static int hwcrhk_destroy(ENGINE *e)
471 {
472 ERR_unload_HWCRHK_strings();
473 return 1;
474 }
475
377/* (de)initialisation functions. */ 476/* (de)initialisation functions. */
378static int hwcrhk_init() 477static int hwcrhk_init(ENGINE *e)
379 { 478 {
380 HWCryptoHook_Init_t *p1; 479 HWCryptoHook_Init_t *p1;
381 HWCryptoHook_Finish_t *p2; 480 HWCryptoHook_Finish_t *p2;
382 HWCryptoHook_ModExp_t *p3; 481 HWCryptoHook_ModExp_t *p3;
482#ifndef OPENSSL_NO_RSA
383 HWCryptoHook_RSA_t *p4; 483 HWCryptoHook_RSA_t *p4;
384 HWCryptoHook_RSALoadKey_t *p5; 484 HWCryptoHook_RSALoadKey_t *p5;
385 HWCryptoHook_RSAGetPublicKey_t *p6; 485 HWCryptoHook_RSAGetPublicKey_t *p6;
386 HWCryptoHook_RSAUnloadKey_t *p7; 486 HWCryptoHook_RSAUnloadKey_t *p7;
487#endif
387 HWCryptoHook_RandomBytes_t *p8; 488 HWCryptoHook_RandomBytes_t *p8;
388 HWCryptoHook_ModExpCRT_t *p9; 489 HWCryptoHook_ModExpCRT_t *p9;
389 490
390 if(hwcrhk_dso != NULL) 491 if(hwcrhk_dso != NULL)
391 { 492 {
392 ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_ALREADY_LOADED); 493 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_ALREADY_LOADED);
393 goto err; 494 goto err;
394 } 495 }
395 /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */ 496 /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */
396 hwcrhk_dso = DSO_load(NULL, HWCRHK_LIBNAME, NULL, 497 hwcrhk_dso = DSO_load(NULL, HWCRHK_LIBNAME, NULL, 0);
397 DSO_FLAG_NAME_TRANSLATION);
398 if(hwcrhk_dso == NULL) 498 if(hwcrhk_dso == NULL)
399 { 499 {
400 ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_DSO_FAILURE); 500 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE);
401 goto err; 501 goto err;
402 } 502 }
403 if(!(p1 = (HWCryptoHook_Init_t *) 503 if(!(p1 = (HWCryptoHook_Init_t *)
@@ -406,6 +506,7 @@ static int hwcrhk_init()
406 DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) || 506 DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) ||
407 !(p3 = (HWCryptoHook_ModExp_t *) 507 !(p3 = (HWCryptoHook_ModExp_t *)
408 DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) || 508 DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) ||
509#ifndef OPENSSL_NO_RSA
409 !(p4 = (HWCryptoHook_RSA_t *) 510 !(p4 = (HWCryptoHook_RSA_t *)
410 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) || 511 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) ||
411 !(p5 = (HWCryptoHook_RSALoadKey_t *) 512 !(p5 = (HWCryptoHook_RSALoadKey_t *)
@@ -414,22 +515,25 @@ static int hwcrhk_init()
414 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAGetPublicKey)) || 515 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAGetPublicKey)) ||
415 !(p7 = (HWCryptoHook_RSAUnloadKey_t *) 516 !(p7 = (HWCryptoHook_RSAUnloadKey_t *)
416 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAUnloadKey)) || 517 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAUnloadKey)) ||
518#endif
417 !(p8 = (HWCryptoHook_RandomBytes_t *) 519 !(p8 = (HWCryptoHook_RandomBytes_t *)
418 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) || 520 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) ||
419 !(p9 = (HWCryptoHook_ModExpCRT_t *) 521 !(p9 = (HWCryptoHook_ModExpCRT_t *)
420 DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT))) 522 DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT)))
421 { 523 {
422 ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_DSO_FAILURE); 524 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE);
423 goto err; 525 goto err;
424 } 526 }
425 /* Copy the pointers */ 527 /* Copy the pointers */
426 p_hwcrhk_Init = p1; 528 p_hwcrhk_Init = p1;
427 p_hwcrhk_Finish = p2; 529 p_hwcrhk_Finish = p2;
428 p_hwcrhk_ModExp = p3; 530 p_hwcrhk_ModExp = p3;
531#ifndef OPENSSL_NO_RSA
429 p_hwcrhk_RSA = p4; 532 p_hwcrhk_RSA = p4;
430 p_hwcrhk_RSALoadKey = p5; 533 p_hwcrhk_RSALoadKey = p5;
431 p_hwcrhk_RSAGetPublicKey = p6; 534 p_hwcrhk_RSAGetPublicKey = p6;
432 p_hwcrhk_RSAUnloadKey = p7; 535 p_hwcrhk_RSAUnloadKey = p7;
536#endif
433 p_hwcrhk_RandomBytes = p8; 537 p_hwcrhk_RandomBytes = p8;
434 p_hwcrhk_ModExpCRT = p9; 538 p_hwcrhk_ModExpCRT = p9;
435 539
@@ -448,16 +552,18 @@ static int hwcrhk_init()
448 552
449 /* Try and get a context - if not, we may have a DSO but no 553 /* Try and get a context - if not, we may have a DSO but no
450 * accelerator! */ 554 * accelerator! */
451 if(!get_context(&hwcrhk_context)) 555 if(!get_context(&hwcrhk_context, &password_context))
452 { 556 {
453 ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_UNIT_FAILURE); 557 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_UNIT_FAILURE);
454 goto err; 558 goto err;
455 } 559 }
456 /* Everything's fine. */ 560 /* Everything's fine. */
457 if (hndidx == -1) 561#ifndef OPENSSL_NO_RSA
458 hndidx = RSA_get_ex_new_index(0, 562 if (hndidx_rsa == -1)
563 hndidx_rsa = RSA_get_ex_new_index(0,
459 "nFast HWCryptoHook RSA key handle", 564 "nFast HWCryptoHook RSA key handle",
460 NULL, NULL, hwcrhk_ex_free); 565 NULL, NULL, hwcrhk_ex_free);
566#endif
461 return 1; 567 return 1;
462err: 568err:
463 if(hwcrhk_dso) 569 if(hwcrhk_dso)
@@ -466,28 +572,30 @@ err:
466 p_hwcrhk_Init = NULL; 572 p_hwcrhk_Init = NULL;
467 p_hwcrhk_Finish = NULL; 573 p_hwcrhk_Finish = NULL;
468 p_hwcrhk_ModExp = NULL; 574 p_hwcrhk_ModExp = NULL;
575#ifndef OPENSSL_NO_RSA
469 p_hwcrhk_RSA = NULL; 576 p_hwcrhk_RSA = NULL;
470 p_hwcrhk_RSALoadKey = NULL; 577 p_hwcrhk_RSALoadKey = NULL;
471 p_hwcrhk_RSAGetPublicKey = NULL; 578 p_hwcrhk_RSAGetPublicKey = NULL;
472 p_hwcrhk_RSAUnloadKey = NULL; 579 p_hwcrhk_RSAUnloadKey = NULL;
580#endif
473 p_hwcrhk_ModExpCRT = NULL; 581 p_hwcrhk_ModExpCRT = NULL;
474 p_hwcrhk_RandomBytes = NULL; 582 p_hwcrhk_RandomBytes = NULL;
475 return 0; 583 return 0;
476 } 584 }
477 585
478static int hwcrhk_finish() 586static int hwcrhk_finish(ENGINE *e)
479 { 587 {
480 int to_return = 1; 588 int to_return = 1;
481 if(hwcrhk_dso == NULL) 589 if(hwcrhk_dso == NULL)
482 { 590 {
483 ENGINEerr(ENGINE_F_HWCRHK_FINISH,ENGINE_R_NOT_LOADED); 591 HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_NOT_LOADED);
484 to_return = 0; 592 to_return = 0;
485 goto err; 593 goto err;
486 } 594 }
487 release_context(hwcrhk_context); 595 release_context(hwcrhk_context);
488 if(!DSO_free(hwcrhk_dso)) 596 if(!DSO_free(hwcrhk_dso))
489 { 597 {
490 ENGINEerr(ENGINE_F_HWCRHK_FINISH,ENGINE_R_DSO_FAILURE); 598 HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_DSO_FAILURE);
491 to_return = 0; 599 to_return = 0;
492 goto err; 600 goto err;
493 } 601 }
@@ -498,21 +606,36 @@ static int hwcrhk_finish()
498 p_hwcrhk_Init = NULL; 606 p_hwcrhk_Init = NULL;
499 p_hwcrhk_Finish = NULL; 607 p_hwcrhk_Finish = NULL;
500 p_hwcrhk_ModExp = NULL; 608 p_hwcrhk_ModExp = NULL;
609#ifndef OPENSSL_NO_RSA
501 p_hwcrhk_RSA = NULL; 610 p_hwcrhk_RSA = NULL;
502 p_hwcrhk_RSALoadKey = NULL; 611 p_hwcrhk_RSALoadKey = NULL;
503 p_hwcrhk_RSAGetPublicKey = NULL; 612 p_hwcrhk_RSAGetPublicKey = NULL;
504 p_hwcrhk_RSAUnloadKey = NULL; 613 p_hwcrhk_RSAUnloadKey = NULL;
614#endif
505 p_hwcrhk_ModExpCRT = NULL; 615 p_hwcrhk_ModExpCRT = NULL;
506 p_hwcrhk_RandomBytes = NULL; 616 p_hwcrhk_RandomBytes = NULL;
507 return to_return; 617 return to_return;
508 } 618 }
509 619
510static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)()) 620static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
511 { 621 {
512 int to_return = 1; 622 int to_return = 1;
513 623
514 switch(cmd) 624 switch(cmd)
515 { 625 {
626 case HWCRHK_CMD_SO_PATH:
627 if(hwcrhk_dso)
628 {
629 HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_ALREADY_LOADED);
630 return 0;
631 }
632 if(p == NULL)
633 {
634 HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,ERR_R_PASSED_NULL_PARAMETER);
635 return 0;
636 }
637 HWCRHK_LIBNAME = (const char *)p;
638 return 1;
516 case ENGINE_CTRL_SET_LOGSTREAM: 639 case ENGINE_CTRL_SET_LOGSTREAM:
517 { 640 {
518 BIO *bio = (BIO *)p; 641 BIO *bio = (BIO *)p;
@@ -526,18 +649,31 @@ static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)())
526 if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1) 649 if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1)
527 logstream = bio; 650 logstream = bio;
528 else 651 else
529 ENGINEerr(ENGINE_F_HWCRHK_CTRL,ENGINE_R_BIO_WAS_FREED); 652 HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_BIO_WAS_FREED);
530 } 653 }
531 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 654 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
532 break; 655 break;
533 case ENGINE_CTRL_SET_PASSWORD_CALLBACK: 656 case ENGINE_CTRL_SET_PASSWORD_CALLBACK:
534 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 657 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
535 password_callback = (pem_password_cb *)f; 658 password_context.password_callback = (pem_password_cb *)f;
659 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
660 break;
661 case ENGINE_CTRL_SET_USER_INTERFACE:
662 case HWCRHK_CMD_SET_USER_INTERFACE:
663 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
664 password_context.ui_method = (UI_METHOD *)p;
665 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
666 break;
667 case ENGINE_CTRL_SET_CALLBACK_DATA:
668 case HWCRHK_CMD_SET_CALLBACK_DATA:
669 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
670 password_context.callback_data = p;
536 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 671 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
537 break; 672 break;
538 /* this enables or disables the "SimpleForkCheck" flag used in the 673 /* this enables or disables the "SimpleForkCheck" flag used in the
539 * initialisation structure. */ 674 * initialisation structure. */
540 case ENGINE_CTRL_CHIL_SET_FORKCHECK: 675 case ENGINE_CTRL_CHIL_SET_FORKCHECK:
676 case HWCRHK_CMD_FORK_CHECK:
541 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 677 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
542 if(i) 678 if(i)
543 hwcrhk_globals.flags |= 679 hwcrhk_globals.flags |=
@@ -557,11 +693,16 @@ static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)())
557 disable_mutex_callbacks = 1; 693 disable_mutex_callbacks = 1;
558 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 694 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
559 break; 695 break;
696 case HWCRHK_CMD_THREAD_LOCKING:
697 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
698 disable_mutex_callbacks = ((i == 0) ? 0 : 1);
699 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
700 break;
560 701
561 /* The command isn't understood by this engine */ 702 /* The command isn't understood by this engine */
562 default: 703 default:
563 ENGINEerr(ENGINE_F_HWCRHK_CTRL, 704 HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,
564 ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); 705 HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
565 to_return = 0; 706 to_return = 0;
566 break; 707 break;
567 } 708 }
@@ -569,44 +710,62 @@ static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)())
569 return to_return; 710 return to_return;
570 } 711 }
571 712
572static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, 713static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
573 const char *passphrase) 714 UI_METHOD *ui_method, void *callback_data)
574 { 715 {
716#ifndef OPENSSL_NO_RSA
575 RSA *rtmp = NULL; 717 RSA *rtmp = NULL;
718#endif
576 EVP_PKEY *res = NULL; 719 EVP_PKEY *res = NULL;
720#ifndef OPENSSL_NO_RSA
577 HWCryptoHook_MPI e, n; 721 HWCryptoHook_MPI e, n;
578 HWCryptoHook_RSAKeyHandle *hptr; 722 HWCryptoHook_RSAKeyHandle *hptr;
723#endif
724#if !defined(OPENSSL_NO_RSA)
725 char tempbuf[1024];
579 HWCryptoHook_ErrMsgBuf rmsg; 726 HWCryptoHook_ErrMsgBuf rmsg;
727#endif
728 HWCryptoHook_PassphraseContext ppctx;
729
730#if !defined(OPENSSL_NO_RSA)
731 rmsg.buf = tempbuf;
732 rmsg.size = sizeof(tempbuf);
733#endif
580 734
581 if(!hwcrhk_context) 735 if(!hwcrhk_context)
582 { 736 {
583 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, 737 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
584 ENGINE_R_NOT_INITIALISED); 738 HWCRHK_R_NOT_INITIALISED);
585 goto err; 739 goto err;
586 } 740 }
741#ifndef OPENSSL_NO_RSA
587 hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle)); 742 hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle));
588 if (!hptr) 743 if (!hptr)
589 { 744 {
590 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, 745 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
591 ERR_R_MALLOC_FAILURE); 746 ERR_R_MALLOC_FAILURE);
592 goto err; 747 goto err;
593 } 748 }
749 ppctx.ui_method = ui_method;
750 ppctx.callback_data = callback_data;
594 if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr, 751 if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr,
595 &rmsg, NULL)) 752 &rmsg, &ppctx))
596 { 753 {
597 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, 754 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
598 ENGINE_R_CHIL_ERROR); 755 HWCRHK_R_CHIL_ERROR);
599 ERR_add_error_data(1,rmsg.buf); 756 ERR_add_error_data(1,rmsg.buf);
600 goto err; 757 goto err;
601 } 758 }
602 if (!*hptr) 759 if (!*hptr)
603 { 760 {
604 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, 761 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
605 ENGINE_R_NO_KEY); 762 HWCRHK_R_NO_KEY);
606 goto err; 763 goto err;
607 } 764 }
608 rtmp = RSA_new_method(&engine_hwcrhk); 765#endif
609 RSA_set_ex_data(rtmp, hndidx, (char *)hptr); 766#ifndef OPENSSL_NO_RSA
767 rtmp = RSA_new_method(eng);
768 RSA_set_ex_data(rtmp, hndidx_rsa, (char *)hptr);
610 rtmp->e = BN_new(); 769 rtmp->e = BN_new();
611 rtmp->n = BN_new(); 770 rtmp->n = BN_new();
612 rtmp->flags |= RSA_FLAG_EXT_PKEY; 771 rtmp->flags |= RSA_FLAG_EXT_PKEY;
@@ -615,11 +774,11 @@ static EVP_PKEY *hwcrhk_load_privkey(const char *key_id,
615 if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg) 774 if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)
616 != HWCRYPTOHOOK_ERROR_MPISIZE) 775 != HWCRYPTOHOOK_ERROR_MPISIZE)
617 { 776 {
618 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY,ENGINE_R_CHIL_ERROR); 777 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,HWCRHK_R_CHIL_ERROR);
619 ERR_add_error_data(1,rmsg.buf); 778 ERR_add_error_data(1,rmsg.buf);
620 goto err; 779 goto err;
621 } 780 }
622 781
623 bn_expand2(rtmp->e, e.size/sizeof(BN_ULONG)); 782 bn_expand2(rtmp->e, e.size/sizeof(BN_ULONG));
624 bn_expand2(rtmp->n, n.size/sizeof(BN_ULONG)); 783 bn_expand2(rtmp->n, n.size/sizeof(BN_ULONG));
625 MPI2BN(rtmp->e, e); 784 MPI2BN(rtmp->e, e);
@@ -627,8 +786,8 @@ static EVP_PKEY *hwcrhk_load_privkey(const char *key_id,
627 786
628 if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)) 787 if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg))
629 { 788 {
630 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY, 789 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,
631 ENGINE_R_CHIL_ERROR); 790 HWCRHK_R_CHIL_ERROR);
632 ERR_add_error_data(1,rmsg.buf); 791 ERR_add_error_data(1,rmsg.buf);
633 goto err; 792 goto err;
634 } 793 }
@@ -639,23 +798,37 @@ static EVP_PKEY *hwcrhk_load_privkey(const char *key_id,
639 798
640 res = EVP_PKEY_new(); 799 res = EVP_PKEY_new();
641 EVP_PKEY_assign_RSA(res, rtmp); 800 EVP_PKEY_assign_RSA(res, rtmp);
801#endif
802
803 if (!res)
804 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,
805 HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED);
642 806
643 return res; 807 return res;
644 err: 808 err:
645 if (res) 809 if (res)
646 EVP_PKEY_free(res); 810 EVP_PKEY_free(res);
811#ifndef OPENSSL_NO_RSA
647 if (rtmp) 812 if (rtmp)
648 RSA_free(rtmp); 813 RSA_free(rtmp);
814#endif
649 return NULL; 815 return NULL;
650 } 816 }
651 817
652static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, const char *passphrase) 818static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
819 UI_METHOD *ui_method, void *callback_data)
653 { 820 {
654 EVP_PKEY *res = hwcrhk_load_privkey(key_id, passphrase); 821 EVP_PKEY *res = NULL;
822
823#ifndef OPENSSL_NO_RSA
824 res = hwcrhk_load_privkey(eng, key_id,
825 ui_method, callback_data);
826#endif
655 827
656 if (res) 828 if (res)
657 switch(res->type) 829 switch(res->type)
658 { 830 {
831#ifndef OPENSSL_NO_RSA
659 case EVP_PKEY_RSA: 832 case EVP_PKEY_RSA:
660 { 833 {
661 RSA *rsa = NULL; 834 RSA *rsa = NULL;
@@ -665,12 +838,16 @@ static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, const char *passphrase)
665 res->pkey.rsa = RSA_new(); 838 res->pkey.rsa = RSA_new();
666 res->pkey.rsa->n = rsa->n; 839 res->pkey.rsa->n = rsa->n;
667 res->pkey.rsa->e = rsa->e; 840 res->pkey.rsa->e = rsa->e;
841 rsa->n = NULL;
842 rsa->e = NULL;
668 CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY); 843 CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
669 RSA_free(rsa); 844 RSA_free(rsa);
670 } 845 }
846 break;
847#endif
671 default: 848 default:
672 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY, 849 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,
673 ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); 850 HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
674 goto err; 851 goto err;
675 } 852 }
676 853
@@ -682,7 +859,7 @@ static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, const char *passphrase)
682 } 859 }
683 860
684/* A little mod_exp */ 861/* A little mod_exp */
685static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 862static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
686 const BIGNUM *m, BN_CTX *ctx) 863 const BIGNUM *m, BN_CTX *ctx)
687 { 864 {
688 char tempbuf[1024]; 865 char tempbuf[1024];
@@ -695,11 +872,11 @@ static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
695 872
696 to_return = 0; /* expect failure */ 873 to_return = 0; /* expect failure */
697 rmsg.buf = tempbuf; 874 rmsg.buf = tempbuf;
698 rmsg.size = 1024; 875 rmsg.size = sizeof(tempbuf);
699 876
700 if(!hwcrhk_context) 877 if(!hwcrhk_context)
701 { 878 {
702 ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_NOT_INITIALISED); 879 HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_NOT_INITIALISED);
703 goto err; 880 goto err;
704 } 881 }
705 /* Prepare the params */ 882 /* Prepare the params */
@@ -723,11 +900,11 @@ static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
723 might be a good thing. */ 900 might be a good thing. */
724 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) 901 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
725 { 902 {
726 ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_REQUEST_FALLBACK); 903 HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FALLBACK);
727 } 904 }
728 else 905 else
729 { 906 {
730 ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_REQUEST_FAILED); 907 HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FAILED);
731 } 908 }
732 ERR_add_error_data(1,rmsg.buf); 909 ERR_add_error_data(1,rmsg.buf);
733 goto err; 910 goto err;
@@ -737,38 +914,39 @@ static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
737err: 914err:
738 return to_return; 915 return to_return;
739 } 916 }
740 917
741static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa) 918#ifndef OPENSSL_NO_RSA
919static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa)
742 { 920 {
743 char tempbuf[1024]; 921 char tempbuf[1024];
744 HWCryptoHook_ErrMsgBuf rmsg; 922 HWCryptoHook_ErrMsgBuf rmsg;
745 HWCryptoHook_RSAKeyHandle *hptr; 923 HWCryptoHook_RSAKeyHandle *hptr;
746 int to_return = 0, ret; 924 int to_return = 0, ret;
747 925
926 rmsg.buf = tempbuf;
927 rmsg.size = sizeof(tempbuf);
928
748 if(!hwcrhk_context) 929 if(!hwcrhk_context)
749 { 930 {
750 ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_NOT_INITIALISED); 931 HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_NOT_INITIALISED);
751 goto err; 932 goto err;
752 } 933 }
753 934
754 /* This provides support for nForce keys. Since that's opaque data 935 /* This provides support for nForce keys. Since that's opaque data
755 all we do is provide a handle to the proper key and let HWCryptoHook 936 all we do is provide a handle to the proper key and let HWCryptoHook
756 take care of the rest. */ 937 take care of the rest. */
757 if ((hptr = (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx)) 938 if ((hptr = (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx_rsa))
758 != NULL) 939 != NULL)
759 { 940 {
760 HWCryptoHook_MPI m_a, m_r; 941 HWCryptoHook_MPI m_a, m_r;
761 942
762 if(!rsa->n) 943 if(!rsa->n)
763 { 944 {
764 ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP, 945 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
765 ENGINE_R_MISSING_KEY_COMPONENTS); 946 HWCRHK_R_MISSING_KEY_COMPONENTS);
766 goto err; 947 goto err;
767 } 948 }
768 949
769 rmsg.buf = tempbuf;
770 rmsg.size = 1024;
771
772 /* Prepare the params */ 950 /* Prepare the params */
773 bn_expand2(r, rsa->n->top); /* Check for error !! */ 951 bn_expand2(r, rsa->n->top); /* Check for error !! */
774 BN2MPI(m_a, I); 952 BN2MPI(m_a, I);
@@ -788,11 +966,13 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa)
788 might be a good thing. */ 966 might be a good thing. */
789 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) 967 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
790 { 968 {
791 ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FALLBACK); 969 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
970 HWCRHK_R_REQUEST_FALLBACK);
792 } 971 }
793 else 972 else
794 { 973 {
795 ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FAILED); 974 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
975 HWCRHK_R_REQUEST_FAILED);
796 } 976 }
797 ERR_add_error_data(1,rmsg.buf); 977 ERR_add_error_data(1,rmsg.buf);
798 goto err; 978 goto err;
@@ -804,14 +984,11 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa)
804 984
805 if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) 985 if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
806 { 986 {
807 ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP, 987 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
808 ENGINE_R_MISSING_KEY_COMPONENTS); 988 HWCRHK_R_MISSING_KEY_COMPONENTS);
809 goto err; 989 goto err;
810 } 990 }
811 991
812 rmsg.buf = tempbuf;
813 rmsg.size = 1024;
814
815 /* Prepare the params */ 992 /* Prepare the params */
816 bn_expand2(r, rsa->n->top); /* Check for error !! */ 993 bn_expand2(r, rsa->n->top); /* Check for error !! */
817 BN2MPI(m_a, I); 994 BN2MPI(m_a, I);
@@ -837,11 +1014,13 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa)
837 might be a good thing. */ 1014 might be a good thing. */
838 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) 1015 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
839 { 1016 {
840 ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FALLBACK); 1017 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
1018 HWCRHK_R_REQUEST_FALLBACK);
841 } 1019 }
842 else 1020 else
843 { 1021 {
844 ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FAILED); 1022 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
1023 HWCRHK_R_REQUEST_FAILED);
845 } 1024 }
846 ERR_add_error_data(1,rmsg.buf); 1025 ERR_add_error_data(1,rmsg.buf);
847 goto err; 1026 goto err;
@@ -852,16 +1031,18 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa)
852err: 1031err:
853 return to_return; 1032 return to_return;
854 } 1033 }
1034#endif
855 1035
856/* This function is aliased to mod_exp (with the mont stuff dropped). */ 1036/* This function is aliased to mod_exp (with the mont stuff dropped). */
857static int hwcrhk_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 1037static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
858 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) 1038 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
859 { 1039 {
860 return hwcrhk_mod_exp(r, a, p, m, ctx); 1040 return hwcrhk_mod_exp(r, a, p, m, ctx);
861 } 1041 }
862 1042
863/* This function is aliased to mod_exp (with the dh and mont dropped). */ 1043/* This function is aliased to mod_exp (with the dh and mont dropped). */
864static int hwcrhk_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, 1044static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
1045 const BIGNUM *a, const BIGNUM *p,
865 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) 1046 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
866 { 1047 {
867 return hwcrhk_mod_exp(r, a, p, m, ctx); 1048 return hwcrhk_mod_exp(r, a, p, m, ctx);
@@ -876,11 +1057,11 @@ static int hwcrhk_rand_bytes(unsigned char *buf, int num)
876 int ret; 1057 int ret;
877 1058
878 rmsg.buf = tempbuf; 1059 rmsg.buf = tempbuf;
879 rmsg.size = 1024; 1060 rmsg.size = sizeof(tempbuf);
880 1061
881 if(!hwcrhk_context) 1062 if(!hwcrhk_context)
882 { 1063 {
883 ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_NOT_INITIALISED); 1064 HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,HWCRHK_R_NOT_INITIALISED);
884 goto err; 1065 goto err;
885 } 1066 }
886 1067
@@ -892,11 +1073,13 @@ static int hwcrhk_rand_bytes(unsigned char *buf, int num)
892 might be a good thing. */ 1073 might be a good thing. */
893 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) 1074 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
894 { 1075 {
895 ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_REQUEST_FALLBACK); 1076 HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,
1077 HWCRHK_R_REQUEST_FALLBACK);
896 } 1078 }
897 else 1079 else
898 { 1080 {
899 ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_REQUEST_FAILED); 1081 HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,
1082 HWCRHK_R_REQUEST_FAILED);
900 } 1083 }
901 ERR_add_error_data(1,rmsg.buf); 1084 ERR_add_error_data(1,rmsg.buf);
902 goto err; 1085 goto err;
@@ -914,20 +1097,28 @@ static int hwcrhk_rand_status(void)
914/* This cleans up an RSA KM key, called when ex_data is freed */ 1097/* This cleans up an RSA KM key, called when ex_data is freed */
915 1098
916static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, 1099static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
917 int index,long argl, void *argp) 1100 int ind,long argl, void *argp)
918{ 1101{
919 char tempbuf[1024]; 1102 char tempbuf[1024];
920 HWCryptoHook_ErrMsgBuf rmsg; 1103 HWCryptoHook_ErrMsgBuf rmsg;
1104#ifndef OPENSSL_NO_RSA
921 HWCryptoHook_RSAKeyHandle *hptr; 1105 HWCryptoHook_RSAKeyHandle *hptr;
1106#endif
1107#if !defined(OPENSSL_NO_RSA)
922 int ret; 1108 int ret;
1109#endif
923 1110
924 rmsg.buf = tempbuf; 1111 rmsg.buf = tempbuf;
925 rmsg.size = 1024; 1112 rmsg.size = sizeof(tempbuf);
926 1113
1114#ifndef OPENSSL_NO_RSA
927 hptr = (HWCryptoHook_RSAKeyHandle *) item; 1115 hptr = (HWCryptoHook_RSAKeyHandle *) item;
928 if(!hptr) return; 1116 if(hptr)
929 ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL); 1117 {
930 OPENSSL_free(hptr); 1118 ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL);
1119 OPENSSL_free(hptr);
1120 }
1121#endif
931} 1122}
932 1123
933/* Mutex calls: since the HWCryptoHook model closely follows the POSIX model 1124/* Mutex calls: since the HWCryptoHook model closely follows the POSIX model
@@ -939,17 +1130,17 @@ static int hwcrhk_mutex_init(HWCryptoHook_Mutex* mt,
939 { 1130 {
940 mt->lockid = CRYPTO_get_new_dynlockid(); 1131 mt->lockid = CRYPTO_get_new_dynlockid();
941 if (mt->lockid == 0) 1132 if (mt->lockid == 0)
942 return 0; 1133 return 1; /* failure */
943 return 1; 1134 return 0; /* success */
944 } 1135 }
945 1136
946static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt) 1137static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt)
947 { 1138 {
948 CRYPTO_w_lock(mt->lockid); 1139 CRYPTO_w_lock(mt->lockid);
949 return 1; 1140 return 0;
950 } 1141 }
951 1142
952void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt) 1143static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt)
953 { 1144 {
954 CRYPTO_w_unlock(mt->lockid); 1145 CRYPTO_w_unlock(mt->lockid);
955 } 1146 }
@@ -964,50 +1155,146 @@ static int hwcrhk_get_pass(const char *prompt_info,
964 HWCryptoHook_PassphraseContext *ppctx, 1155 HWCryptoHook_PassphraseContext *ppctx,
965 HWCryptoHook_CallerContext *cactx) 1156 HWCryptoHook_CallerContext *cactx)
966 { 1157 {
967 int l = 0; 1158 pem_password_cb *callback = NULL;
968 char prompt[1024]; 1159 void *callback_data = NULL;
969 1160 UI_METHOD *ui_method = NULL;
970 if (password_callback == NULL) 1161
971 { 1162 if (cactx)
972 ENGINEerr(ENGINE_F_HWCRHK_GET_PASS,ENGINE_R_NO_CALLBACK); 1163 {
973 return -1; 1164 if (cactx->ui_method)
974 } 1165 ui_method = cactx->ui_method;
975 if (prompt_info) 1166 if (cactx->password_callback)
1167 callback = cactx->password_callback;
1168 if (cactx->callback_data)
1169 callback_data = cactx->callback_data;
1170 }
1171 if (ppctx)
976 { 1172 {
977 strncpy(prompt, "Card: \"", sizeof(prompt)); 1173 if (ppctx->ui_method)
978 l += 5; 1174 {
979 strncpy(prompt + l, prompt_info, sizeof(prompt) - l); 1175 ui_method = ppctx->ui_method;
980 l += strlen(prompt_info); 1176 callback = NULL;
981 if (l + 2 < sizeof(prompt)) 1177 }
982 { 1178 if (ppctx->callback_data)
983 strncpy(prompt + l, "\"\n", sizeof(prompt) - l); 1179 callback_data = ppctx->callback_data;
984 l += 2;
985 }
986 } 1180 }
987 if (l < sizeof(prompt) - 1) 1181 if (callback == NULL && ui_method == NULL)
988 { 1182 {
989 strncpy(prompt, "Enter Passphrase <enter to cancel>:", 1183 HWCRHKerr(HWCRHK_F_HWCRHK_GET_PASS,HWCRHK_R_NO_CALLBACK);
990 sizeof(prompt) - l); 1184 return -1;
991 l += 35;
992 } 1185 }
993 prompt[l] = '\0';
994 1186
995 /* I know, passing on the prompt instead of the user data *is* 1187 if (ui_method)
996 a bad thing. However, that's all we have right now. 1188 {
997 -- Richard Levitte */ 1189 UI *ui = UI_new_method(ui_method);
998 *len_io = password_callback(buf, *len_io, 0, prompt); 1190 if (ui)
1191 {
1192 int ok;
1193 char *prompt = UI_construct_prompt(ui,
1194 "pass phrase", prompt_info);
1195
1196 ok = UI_add_input_string(ui,prompt,
1197 UI_INPUT_FLAG_DEFAULT_PWD,
1198 buf,0,(*len_io) - 1);
1199 UI_add_user_data(ui, callback_data);
1200 UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
1201
1202 if (ok >= 0)
1203 do
1204 {
1205 ok=UI_process(ui);
1206 }
1207 while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
1208
1209 if (ok >= 0)
1210 *len_io = strlen(buf);
1211
1212 UI_free(ui);
1213 OPENSSL_free(prompt);
1214 }
1215 }
1216 else
1217 {
1218 *len_io = callback(buf, *len_io, 0, callback_data);
1219 }
999 if(!*len_io) 1220 if(!*len_io)
1000 return -1; 1221 return -1;
1001 return 0; 1222 return 0;
1002 } 1223 }
1003 1224
1004static void hwcrhk_log_message(void *logstream, const char *message) 1225static int hwcrhk_insert_card(const char *prompt_info,
1226 const char *wrong_info,
1227 HWCryptoHook_PassphraseContext *ppctx,
1228 HWCryptoHook_CallerContext *cactx)
1229 {
1230 int ok = -1;
1231 UI *ui;
1232 void *callback_data = NULL;
1233 UI_METHOD *ui_method = NULL;
1234
1235 if (cactx)
1236 {
1237 if (cactx->ui_method)
1238 ui_method = cactx->ui_method;
1239 if (cactx->callback_data)
1240 callback_data = cactx->callback_data;
1241 }
1242 if (ppctx)
1243 {
1244 if (ppctx->ui_method)
1245 ui_method = ppctx->ui_method;
1246 if (ppctx->callback_data)
1247 callback_data = ppctx->callback_data;
1248 }
1249 if (ui_method == NULL)
1250 {
1251 HWCRHKerr(HWCRHK_F_HWCRHK_INSERT_CARD,
1252 HWCRHK_R_NO_CALLBACK);
1253 return -1;
1254 }
1255
1256 ui = UI_new_method(ui_method);
1257
1258 if (ui)
1259 {
1260 char answer;
1261 char buf[BUFSIZ];
1262
1263 if (wrong_info)
1264 BIO_snprintf(buf, sizeof(buf)-1,
1265 "Current card: \"%s\"\n", wrong_info);
1266 ok = UI_dup_info_string(ui, buf);
1267 if (ok >= 0 && prompt_info)
1268 {
1269 BIO_snprintf(buf, sizeof(buf)-1,
1270 "Insert card \"%s\"", prompt_info);
1271 ok = UI_dup_input_boolean(ui, buf,
1272 "\n then hit <enter> or C<enter> to cancel\n",
1273 "\r\n", "Cc", UI_INPUT_FLAG_ECHO, &answer);
1274 }
1275 UI_add_user_data(ui, callback_data);
1276
1277 if (ok >= 0)
1278 ok = UI_process(ui);
1279 UI_free(ui);
1280
1281 if (ok == -2 || (ok >= 0 && answer == 'C'))
1282 ok = 1;
1283 else if (ok < 0)
1284 ok = -1;
1285 else
1286 ok = 0;
1287 }
1288 return ok;
1289 }
1290
1291static void hwcrhk_log_message(void *logstr, const char *message)
1005 { 1292 {
1006 BIO *lstream = NULL; 1293 BIO *lstream = NULL;
1007 1294
1008 CRYPTO_w_lock(CRYPTO_LOCK_BIO); 1295 CRYPTO_w_lock(CRYPTO_LOCK_BIO);
1009 if (logstream) 1296 if (logstr)
1010 lstream=*(BIO **)logstream; 1297 lstream=*(BIO **)logstr;
1011 if (lstream) 1298 if (lstream)
1012 { 1299 {
1013 BIO_write(lstream, message, strlen(message)); 1300 BIO_write(lstream, message, strlen(message));
@@ -1015,5 +1302,20 @@ static void hwcrhk_log_message(void *logstream, const char *message)
1015 CRYPTO_w_unlock(CRYPTO_LOCK_BIO); 1302 CRYPTO_w_unlock(CRYPTO_LOCK_BIO);
1016 } 1303 }
1017 1304
1018#endif /* !NO_HW_NCIPHER */ 1305/* This stuff is needed if this ENGINE is being compiled into a self-contained
1019#endif /* !NO_HW */ 1306 * shared-library. */
1307#ifdef ENGINE_DYNAMIC_SUPPORT
1308static int bind_fn(ENGINE *e, const char *id)
1309 {
1310 if(id && (strcmp(id, engine_hwcrhk_id) != 0))
1311 return 0;
1312 if(!bind_helper(e))
1313 return 0;
1314 return 1;
1315 }
1316IMPLEMENT_DYNAMIC_CHECK_FN()
1317IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
1318#endif /* ENGINE_DYNAMIC_SUPPORT */
1319
1320#endif /* !OPENSSL_NO_HW_NCIPHER */
1321#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 @@
1/* hw_ncipher_err.c */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include "hw_ncipher_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA HWCRHK_str_functs[]=
68 {
69{ERR_PACK(0,HWCRHK_F_HWCRHK_CTRL,0), "HWCRHK_CTRL"},
70{ERR_PACK(0,HWCRHK_F_HWCRHK_FINISH,0), "HWCRHK_FINISH"},
71{ERR_PACK(0,HWCRHK_F_HWCRHK_GET_PASS,0), "HWCRHK_GET_PASS"},
72{ERR_PACK(0,HWCRHK_F_HWCRHK_INIT,0), "HWCRHK_INIT"},
73{ERR_PACK(0,HWCRHK_F_HWCRHK_INSERT_CARD,0), "HWCRHK_INSERT_CARD"},
74{ERR_PACK(0,HWCRHK_F_HWCRHK_LOAD_PRIVKEY,0), "HWCRHK_LOAD_PRIVKEY"},
75{ERR_PACK(0,HWCRHK_F_HWCRHK_LOAD_PUBKEY,0), "HWCRHK_LOAD_PUBKEY"},
76{ERR_PACK(0,HWCRHK_F_HWCRHK_MOD_EXP,0), "HWCRHK_MOD_EXP"},
77{ERR_PACK(0,HWCRHK_F_HWCRHK_RAND_BYTES,0), "HWCRHK_RAND_BYTES"},
78{ERR_PACK(0,HWCRHK_F_HWCRHK_RSA_MOD_EXP,0), "HWCRHK_RSA_MOD_EXP"},
79{0,NULL}
80 };
81
82static ERR_STRING_DATA HWCRHK_str_reasons[]=
83 {
84{HWCRHK_R_ALREADY_LOADED ,"already loaded"},
85{HWCRHK_R_BIO_WAS_FREED ,"bio was freed"},
86{HWCRHK_R_CHIL_ERROR ,"chil error"},
87{HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
88{HWCRHK_R_DSO_FAILURE ,"dso failure"},
89{HWCRHK_R_MISSING_KEY_COMPONENTS ,"missing key components"},
90{HWCRHK_R_NOT_INITIALISED ,"not initialised"},
91{HWCRHK_R_NOT_LOADED ,"not loaded"},
92{HWCRHK_R_NO_CALLBACK ,"no callback"},
93{HWCRHK_R_NO_KEY ,"no key"},
94{HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED,"private key algorithms disabled"},
95{HWCRHK_R_REQUEST_FAILED ,"request failed"},
96{HWCRHK_R_REQUEST_FALLBACK ,"request fallback"},
97{HWCRHK_R_UNIT_FAILURE ,"unit failure"},
98{0,NULL}
99 };
100
101#endif
102
103#ifdef HWCRHK_LIB_NAME
104static ERR_STRING_DATA HWCRHK_lib_name[]=
105 {
106{0 ,HWCRHK_LIB_NAME},
107{0,NULL}
108 };
109#endif
110
111
112static int HWCRHK_lib_error_code=0;
113static int HWCRHK_error_init=1;
114
115static void ERR_load_HWCRHK_strings(void)
116 {
117 if (HWCRHK_lib_error_code == 0)
118 HWCRHK_lib_error_code=ERR_get_next_error_library();
119
120 if (HWCRHK_error_init)
121 {
122 HWCRHK_error_init=0;
123#ifndef OPENSSL_NO_ERR
124 ERR_load_strings(HWCRHK_lib_error_code,HWCRHK_str_functs);
125 ERR_load_strings(HWCRHK_lib_error_code,HWCRHK_str_reasons);
126#endif
127
128#ifdef HWCRHK_LIB_NAME
129 HWCRHK_lib_name->error = ERR_PACK(HWCRHK_lib_error_code,0,0);
130 ERR_load_strings(0,HWCRHK_lib_name);
131#endif
132 }
133 }
134
135static void ERR_unload_HWCRHK_strings(void)
136 {
137 if (HWCRHK_error_init == 0)
138 {
139#ifndef OPENSSL_NO_ERR
140 ERR_unload_strings(HWCRHK_lib_error_code,HWCRHK_str_functs);
141 ERR_unload_strings(HWCRHK_lib_error_code,HWCRHK_str_reasons);
142#endif
143
144#ifdef HWCRHK_LIB_NAME
145 ERR_unload_strings(0,HWCRHK_lib_name);
146#endif
147 HWCRHK_error_init=1;
148 }
149 }
150
151static void ERR_HWCRHK_error(int function, int reason, char *file, int line)
152 {
153 if (HWCRHK_lib_error_code == 0)
154 HWCRHK_lib_error_code=ERR_get_next_error_library();
155 ERR_PUT_error(HWCRHK_lib_error_code,function,reason,file,line);
156 }
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 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#ifndef HEADER_HWCRHK_ERR_H
56#define HEADER_HWCRHK_ERR_H
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_HWCRHK_strings(void);
63static void ERR_unload_HWCRHK_strings(void);
64static void ERR_HWCRHK_error(int function, int reason, char *file, int line);
65#define HWCRHKerr(f,r) ERR_HWCRHK_error((f),(r),__FILE__,__LINE__)
66
67/* Error codes for the HWCRHK functions. */
68
69/* Function codes. */
70#define HWCRHK_F_HWCRHK_CTRL 100
71#define HWCRHK_F_HWCRHK_FINISH 101
72#define HWCRHK_F_HWCRHK_GET_PASS 102
73#define HWCRHK_F_HWCRHK_INIT 103
74#define HWCRHK_F_HWCRHK_INSERT_CARD 104
75#define HWCRHK_F_HWCRHK_LOAD_PRIVKEY 105
76#define HWCRHK_F_HWCRHK_LOAD_PUBKEY 106
77#define HWCRHK_F_HWCRHK_MOD_EXP 107
78#define HWCRHK_F_HWCRHK_RAND_BYTES 108
79#define HWCRHK_F_HWCRHK_RSA_MOD_EXP 109
80
81/* Reason codes. */
82#define HWCRHK_R_ALREADY_LOADED 100
83#define HWCRHK_R_BIO_WAS_FREED 101
84#define HWCRHK_R_CHIL_ERROR 102
85#define HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED 103
86#define HWCRHK_R_DSO_FAILURE 104
87#define HWCRHK_R_MISSING_KEY_COMPONENTS 105
88#define HWCRHK_R_NOT_INITIALISED 106
89#define HWCRHK_R_NOT_LOADED 107
90#define HWCRHK_R_NO_CALLBACK 108
91#define HWCRHK_R_NO_KEY 109
92#define HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED 110
93#define HWCRHK_R_REQUEST_FAILED 111
94#define HWCRHK_R_REQUEST_FALLBACK 112
95#define HWCRHK_R_UNIT_FAILURE 113
96
97#ifdef __cplusplus
98}
99#endif
100#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 @@
1/* crypto/engine/hw_nuron.c */
2/* Written by Ben Laurie for the OpenSSL Project, leaning heavily on Geoff
3 * Thorpe's Atalla implementation.
4 */
5/* ====================================================================
6 * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <openssl/crypto.h>
61#include "cryptlib.h"
62#include <openssl/dso.h>
63#include <openssl/engine.h>
64
65
66#ifndef OPENSSL_NO_HW
67#ifndef OPENSSL_NO_HW_NURON
68
69#define NURON_LIB_NAME "nuron engine"
70#include "hw_nuron_err.c"
71
72static const char def_NURON_LIBNAME[] = "nuronssl";
73static const char *NURON_LIBNAME = def_NURON_LIBNAME;
74static const char *NURON_F1 = "nuron_mod_exp";
75
76/* The definitions for control commands specific to this engine */
77#define NURON_CMD_SO_PATH ENGINE_CMD_BASE
78static const ENGINE_CMD_DEFN nuron_cmd_defns[] = {
79 {NURON_CMD_SO_PATH,
80 "SO_PATH",
81 "Specifies the path to the 'nuronssl' shared library",
82 ENGINE_CMD_FLAG_STRING},
83 {0, NULL, NULL, 0}
84 };
85
86typedef int tfnModExp(BIGNUM *r,const BIGNUM *a,const BIGNUM *p,const BIGNUM *m);
87static tfnModExp *pfnModExp = NULL;
88
89static DSO *pvDSOHandle = NULL;
90
91static int nuron_destroy(ENGINE *e)
92 {
93 ERR_unload_NURON_strings();
94 return 1;
95 }
96
97static int nuron_init(ENGINE *e)
98 {
99 if(pvDSOHandle != NULL)
100 {
101 NURONerr(NURON_F_NURON_INIT,NURON_R_ALREADY_LOADED);
102 return 0;
103 }
104
105 pvDSOHandle = DSO_load(NULL, NURON_LIBNAME, NULL,
106 DSO_FLAG_NAME_TRANSLATION_EXT_ONLY);
107 if(!pvDSOHandle)
108 {
109 NURONerr(NURON_F_NURON_INIT,NURON_R_DSO_NOT_FOUND);
110 return 0;
111 }
112
113 pfnModExp = (tfnModExp *)DSO_bind_func(pvDSOHandle, NURON_F1);
114 if(!pfnModExp)
115 {
116 NURONerr(NURON_F_NURON_INIT,NURON_R_DSO_FUNCTION_NOT_FOUND);
117 return 0;
118 }
119
120 return 1;
121 }
122
123static int nuron_finish(ENGINE *e)
124 {
125 if(pvDSOHandle == NULL)
126 {
127 NURONerr(NURON_F_NURON_FINISH,NURON_R_NOT_LOADED);
128 return 0;
129 }
130 if(!DSO_free(pvDSOHandle))
131 {
132 NURONerr(NURON_F_NURON_FINISH,NURON_R_DSO_FAILURE);
133 return 0;
134 }
135 pvDSOHandle=NULL;
136 pfnModExp=NULL;
137 return 1;
138 }
139
140static int nuron_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
141 {
142 int initialised = ((pvDSOHandle == NULL) ? 0 : 1);
143 switch(cmd)
144 {
145 case NURON_CMD_SO_PATH:
146 if(p == NULL)
147 {
148 NURONerr(NURON_F_NURON_CTRL,ERR_R_PASSED_NULL_PARAMETER);
149 return 0;
150 }
151 if(initialised)
152 {
153 NURONerr(NURON_F_NURON_CTRL,NURON_R_ALREADY_LOADED);
154 return 0;
155 }
156 NURON_LIBNAME = (const char *)p;
157 return 1;
158 default:
159 break;
160 }
161 NURONerr(NURON_F_NURON_CTRL,NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED);
162 return 0;
163}
164
165static int nuron_mod_exp(BIGNUM *r,const BIGNUM *a,const BIGNUM *p,
166 const BIGNUM *m,BN_CTX *ctx)
167 {
168 if(!pvDSOHandle)
169 {
170 NURONerr(NURON_F_NURON_MOD_EXP,NURON_R_NOT_LOADED);
171 return 0;
172 }
173 return pfnModExp(r,a,p,m);
174 }
175
176#ifndef OPENSSL_NO_RSA
177static int nuron_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
178 {
179 return nuron_mod_exp(r0,I,rsa->d,rsa->n,NULL);
180 }
181#endif
182
183#ifndef OPENSSL_NO_DSA
184/* This code was liberated and adapted from the commented-out code in
185 * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration
186 * (it doesn't have a CRT form for RSA), this function means that an
187 * Atalla system running with a DSA server certificate can handshake
188 * around 5 or 6 times faster/more than an equivalent system running with
189 * RSA. Just check out the "signs" statistics from the RSA and DSA parts
190 * of "openssl speed -engine atalla dsa1024 rsa1024". */
191static int nuron_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
192 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
193 BN_CTX *ctx, BN_MONT_CTX *in_mont)
194 {
195 BIGNUM t;
196 int to_return = 0;
197
198 BN_init(&t);
199 /* let rr = a1 ^ p1 mod m */
200 if (!nuron_mod_exp(rr,a1,p1,m,ctx))
201 goto end;
202 /* let t = a2 ^ p2 mod m */
203 if (!nuron_mod_exp(&t,a2,p2,m,ctx))
204 goto end;
205 /* let rr = rr * t mod m */
206 if (!BN_mod_mul(rr,rr,&t,m,ctx))
207 goto end;
208 to_return = 1;
209end:
210 BN_free(&t);
211 return to_return;
212 }
213
214
215static int nuron_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
216 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
217 BN_MONT_CTX *m_ctx)
218 {
219 return nuron_mod_exp(r, a, p, m, ctx);
220 }
221#endif
222
223/* This function is aliased to mod_exp (with the mont stuff dropped). */
224static int nuron_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
225 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
226 {
227 return nuron_mod_exp(r, a, p, m, ctx);
228 }
229
230#ifndef OPENSSL_NO_DH
231/* This function is aliased to mod_exp (with the dh and mont dropped). */
232static int nuron_mod_exp_dh(const DH *dh, BIGNUM *r,
233 const BIGNUM *a, const BIGNUM *p,
234 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
235 {
236 return nuron_mod_exp(r, a, p, m, ctx);
237 }
238#endif
239
240#ifndef OPENSSL_NO_RSA
241static RSA_METHOD nuron_rsa =
242 {
243 "Nuron RSA method",
244 NULL,
245 NULL,
246 NULL,
247 NULL,
248 nuron_rsa_mod_exp,
249 nuron_mod_exp_mont,
250 NULL,
251 NULL,
252 0,
253 NULL,
254 NULL,
255 NULL
256 };
257#endif
258
259#ifndef OPENSSL_NO_DSA
260static DSA_METHOD nuron_dsa =
261 {
262 "Nuron DSA method",
263 NULL, /* dsa_do_sign */
264 NULL, /* dsa_sign_setup */
265 NULL, /* dsa_do_verify */
266 nuron_dsa_mod_exp, /* dsa_mod_exp */
267 nuron_mod_exp_dsa, /* bn_mod_exp */
268 NULL, /* init */
269 NULL, /* finish */
270 0, /* flags */
271 NULL /* app_data */
272 };
273#endif
274
275#ifndef OPENSSL_NO_DH
276static DH_METHOD nuron_dh =
277 {
278 "Nuron DH method",
279 NULL,
280 NULL,
281 nuron_mod_exp_dh,
282 NULL,
283 NULL,
284 0,
285 NULL
286 };
287#endif
288
289/* Constants used when creating the ENGINE */
290static const char *engine_nuron_id = "nuron";
291static const char *engine_nuron_name = "Nuron hardware engine support";
292
293/* This internal function is used by ENGINE_nuron() and possibly by the
294 * "dynamic" ENGINE support too */
295static int bind_helper(ENGINE *e)
296 {
297#ifndef OPENSSL_NO_RSA
298 const RSA_METHOD *meth1;
299#endif
300#ifndef OPENSSL_NO_DSA
301 const DSA_METHOD *meth2;
302#endif
303#ifndef OPENSSL_NO_DH
304 const DH_METHOD *meth3;
305#endif
306 if(!ENGINE_set_id(e, engine_nuron_id) ||
307 !ENGINE_set_name(e, engine_nuron_name) ||
308#ifndef OPENSSL_NO_RSA
309 !ENGINE_set_RSA(e, &nuron_rsa) ||
310#endif
311#ifndef OPENSSL_NO_DSA
312 !ENGINE_set_DSA(e, &nuron_dsa) ||
313#endif
314#ifndef OPENSSL_NO_DH
315 !ENGINE_set_DH(e, &nuron_dh) ||
316#endif
317 !ENGINE_set_destroy_function(e, nuron_destroy) ||
318 !ENGINE_set_init_function(e, nuron_init) ||
319 !ENGINE_set_finish_function(e, nuron_finish) ||
320 !ENGINE_set_ctrl_function(e, nuron_ctrl) ||
321 !ENGINE_set_cmd_defns(e, nuron_cmd_defns))
322 return 0;
323
324#ifndef OPENSSL_NO_RSA
325 /* We know that the "PKCS1_SSLeay()" functions hook properly
326 * to the nuron-specific mod_exp and mod_exp_crt so we use
327 * those functions. NB: We don't use ENGINE_openssl() or
328 * anything "more generic" because something like the RSAref
329 * code may not hook properly, and if you own one of these
330 * cards then you have the right to do RSA operations on it
331 * anyway! */
332 meth1=RSA_PKCS1_SSLeay();
333 nuron_rsa.rsa_pub_enc=meth1->rsa_pub_enc;
334 nuron_rsa.rsa_pub_dec=meth1->rsa_pub_dec;
335 nuron_rsa.rsa_priv_enc=meth1->rsa_priv_enc;
336 nuron_rsa.rsa_priv_dec=meth1->rsa_priv_dec;
337#endif
338
339#ifndef OPENSSL_NO_DSA
340 /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
341 * bits. */
342 meth2=DSA_OpenSSL();
343 nuron_dsa.dsa_do_sign=meth2->dsa_do_sign;
344 nuron_dsa.dsa_sign_setup=meth2->dsa_sign_setup;
345 nuron_dsa.dsa_do_verify=meth2->dsa_do_verify;
346#endif
347
348#ifndef OPENSSL_NO_DH
349 /* Much the same for Diffie-Hellman */
350 meth3=DH_OpenSSL();
351 nuron_dh.generate_key=meth3->generate_key;
352 nuron_dh.compute_key=meth3->compute_key;
353#endif
354
355 /* Ensure the nuron error handling is set up */
356 ERR_load_NURON_strings();
357 return 1;
358 }
359
360static ENGINE *engine_nuron(void)
361 {
362 ENGINE *ret = ENGINE_new();
363 if(!ret)
364 return NULL;
365 if(!bind_helper(ret))
366 {
367 ENGINE_free(ret);
368 return NULL;
369 }
370 return ret;
371 }
372
373void ENGINE_load_nuron(void)
374 {
375 /* Copied from eng_[openssl|dyn].c */
376 ENGINE *toadd = engine_nuron();
377 if(!toadd) return;
378 ENGINE_add(toadd);
379 ENGINE_free(toadd);
380 ERR_clear_error();
381 }
382
383/* This stuff is needed if this ENGINE is being compiled into a self-contained
384 * shared-library. */
385#ifdef ENGINE_DYNAMIC_SUPPORT
386static int bind_fn(ENGINE *e, const char *id)
387 {
388 if(id && (strcmp(id, engine_nuron_id) != 0))
389 return 0;
390 if(!bind_helper(e))
391 return 0;
392 return 1;
393 }
394IMPLEMENT_DYNAMIC_CHECK_FN()
395IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
396#endif /* ENGINE_DYNAMIC_SUPPORT */
397
398#endif /* !OPENSSL_NO_HW_NURON */
399#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 @@
1/* hw_nuron_err.c */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include "hw_nuron_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA NURON_str_functs[]=
68 {
69{ERR_PACK(0,NURON_F_NURON_CTRL,0), "NURON_CTRL"},
70{ERR_PACK(0,NURON_F_NURON_FINISH,0), "NURON_FINISH"},
71{ERR_PACK(0,NURON_F_NURON_INIT,0), "NURON_INIT"},
72{ERR_PACK(0,NURON_F_NURON_MOD_EXP,0), "NURON_MOD_EXP"},
73{0,NULL}
74 };
75
76static ERR_STRING_DATA NURON_str_reasons[]=
77 {
78{NURON_R_ALREADY_LOADED ,"already loaded"},
79{NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
80{NURON_R_DSO_FAILURE ,"dso failure"},
81{NURON_R_DSO_FUNCTION_NOT_FOUND ,"dso function not found"},
82{NURON_R_DSO_NOT_FOUND ,"dso not found"},
83{NURON_R_NOT_LOADED ,"not loaded"},
84{0,NULL}
85 };
86
87#endif
88
89#ifdef NURON_LIB_NAME
90static ERR_STRING_DATA NURON_lib_name[]=
91 {
92{0 ,NURON_LIB_NAME},
93{0,NULL}
94 };
95#endif
96
97
98static int NURON_lib_error_code=0;
99static int NURON_error_init=1;
100
101static void ERR_load_NURON_strings(void)
102 {
103 if (NURON_lib_error_code == 0)
104 NURON_lib_error_code=ERR_get_next_error_library();
105
106 if (NURON_error_init)
107 {
108 NURON_error_init=0;
109#ifndef OPENSSL_NO_ERR
110 ERR_load_strings(NURON_lib_error_code,NURON_str_functs);
111 ERR_load_strings(NURON_lib_error_code,NURON_str_reasons);
112#endif
113
114#ifdef NURON_LIB_NAME
115 NURON_lib_name->error = ERR_PACK(NURON_lib_error_code,0,0);
116 ERR_load_strings(0,NURON_lib_name);
117#endif
118 }
119 }
120
121static void ERR_unload_NURON_strings(void)
122 {
123 if (NURON_error_init == 0)
124 {
125#ifndef OPENSSL_NO_ERR
126 ERR_unload_strings(NURON_lib_error_code,NURON_str_functs);
127 ERR_unload_strings(NURON_lib_error_code,NURON_str_reasons);
128#endif
129
130#ifdef NURON_LIB_NAME
131 ERR_unload_strings(0,NURON_lib_name);
132#endif
133 NURON_error_init=1;
134 }
135 }
136
137static void ERR_NURON_error(int function, int reason, char *file, int line)
138 {
139 if (NURON_lib_error_code == 0)
140 NURON_lib_error_code=ERR_get_next_error_library();
141 ERR_PUT_error(NURON_lib_error_code,function,reason,file,line);
142 }
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 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#ifndef HEADER_NURON_ERR_H
56#define HEADER_NURON_ERR_H
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_NURON_strings(void);
63static void ERR_unload_NURON_strings(void);
64static void ERR_NURON_error(int function, int reason, char *file, int line);
65#define NURONerr(f,r) ERR_NURON_error((f),(r),__FILE__,__LINE__)
66
67/* Error codes for the NURON functions. */
68
69/* Function codes. */
70#define NURON_F_NURON_CTRL 100
71#define NURON_F_NURON_FINISH 101
72#define NURON_F_NURON_INIT 102
73#define NURON_F_NURON_MOD_EXP 103
74
75/* Reason codes. */
76#define NURON_R_ALREADY_LOADED 100
77#define NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED 101
78#define NURON_R_DSO_FAILURE 102
79#define NURON_R_DSO_FUNCTION_NOT_FOUND 103
80#define NURON_R_DSO_NOT_FOUND 104
81#define NURON_R_NOT_LOADED 105
82
83#ifdef __cplusplus
84}
85#endif
86#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 @@
1/* Written by Ben Laurie <ben@algroup.co.uk> August 2001 */
2/* ====================================================================
3 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * licensing@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include <openssl/engine.h>
57#include <openssl/evp.h>
58#include "eng_int.h"
59/* Maybe this is needed? ... */
60#ifdef FLAT_INC
61#include "evp_locl.h"
62#else
63#include "../evp/evp_locl.h"
64#endif
65#include <openssl/conf.h>
66
67#ifndef OPENSSL_OPENBSD_DEV_CRYPTO
68
69void ENGINE_load_openbsd_dev_crypto(void)
70 {
71 /* This is a NOP unless OPENSSL_OPENBSD_DEV_CRYPTO is defined */
72 return;
73 }
74
75#else /* OPENSSL_OPENBSD_DEV_CRYPTO */
76
77#include <fcntl.h>
78#include <stdio.h>
79#include <errno.h>
80#include <assert.h>
81#include <unistd.h>
82#include <sys/ioctl.h>
83
84#include <crypto/cryptodev.h>
85
86/****************************************************/
87/* Declare the normal generic ENGINE stuff here ... */
88
89static int dev_crypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
90 const int **nids, int nid);
91static int dev_crypto_digests(ENGINE *e, const EVP_MD **digest,
92 const int **nids, int nid);
93
94static const char dev_crypto_id[] = "openbsd_dev_crypto";
95static const char dev_crypto_name[] = "OpenBSD /dev/crypto";
96
97static long allow_misaligned;
98
99#define DEV_CRYPTO_CMD_ALLOW_MISALIGNED ENGINE_CMD_BASE
100static const ENGINE_CMD_DEFN dev_crypto_cmd_defns[]=
101 {
102 { DEV_CRYPTO_CMD_ALLOW_MISALIGNED,
103 "allow_misaligned",
104 "Permit misaligned data to be used",
105 ENGINE_CMD_FLAG_NUMERIC },
106 { 0, NULL, NULL, 0 }
107 };
108
109static int dev_crypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
110 {
111 switch(cmd)
112 {
113 case DEV_CRYPTO_CMD_ALLOW_MISALIGNED:
114 allow_misaligned=i;
115 printf("allow misaligned=%ld\n",allow_misaligned);
116 break;
117 }
118
119 return 1;
120 }
121
122static ENGINE *engine_openbsd_dev_crypto(void)
123 {
124 ENGINE *engine=ENGINE_new();
125
126 if(!ENGINE_set_id(engine, dev_crypto_id) ||
127 !ENGINE_set_name(engine, dev_crypto_name) ||
128 !ENGINE_set_ciphers(engine, dev_crypto_ciphers) ||
129 !ENGINE_set_digests(engine, dev_crypto_digests) ||
130 !ENGINE_set_ctrl_function(engine, dev_crypto_ctrl) ||
131 !ENGINE_set_cmd_defns(engine, dev_crypto_cmd_defns))
132 {
133 ENGINE_free(engine);
134 return NULL;
135 }
136
137 return engine;
138 }
139
140void ENGINE_load_openbsd_dev_crypto(void)
141 {
142 /* Copied from eng_[openssl|dyn].c */
143 ENGINE *toadd = engine_openbsd_dev_crypto();
144 if(!toadd) return;
145 ENGINE_add(toadd);
146 ENGINE_free(toadd);
147 ERR_clear_error();
148 }
149
150/******************************************************************************/
151/* Clip in the stuff from crypto/evp/openbsd_hw.c here. NB: What has changed? */
152/* I've removed the exposed EVP_*** functions, they're accessed through the */
153/* "dev_crypto_[ciphers|digests]" handlers. I've also moved the EVP_CIPHER */
154/* and EVP_MD structures to the bottom where they are close to the handlers */
155/* that expose them. What should be done? The global data (file-descriptors, */
156/* etc) should be put into ENGINE's ex_data support, and per-context data */
157/* (also file-descriptors perhaps) should be put into the contexts. Also code */
158/* formatting, fprintf statements, and OpenSSL-style error handling should be */
159/* added (dynamically, like the other ENGINEs). Also, "dynamic" support */
160/* be added to this ENGINE once it's up and running so that it could be built */
161/* as a shared-library. What else? device initialisation should take place */
162/* inside an ENGINE 'init()' handler (and likewise 'finish()'). ciphers and */
163/* digests won't be used by the framework unless the ENGINE has been */
164/* successfully initialised (that's one of the things you get for free) so */
165/* initialisation, including returning failure if device setup fails, can be */
166/* handled quite cleanly. This could presumably handle the opening (and then */
167/* closing inside 'finish()') of the 'cryptodev_fd' file-descriptor). */
168
169/* longest key supported in hardware */
170#define MAX_HW_KEY 24
171#define MAX_HW_IV 8
172
173#define MD5_DIGEST_LENGTH 16
174#define MD5_CBLOCK 64
175
176static int fd;
177static int dev_failed;
178
179typedef struct session_op session_op;
180
181#define CDATA(ctx) EVP_C_DATA(session_op,ctx)
182
183static void err(const char *str)
184 {
185 fprintf(stderr,"%s: errno %d\n",str,errno);
186 }
187
188static int dev_crypto_init(session_op *ses)
189 {
190 if(dev_failed)
191 return 0;
192 if(!fd)
193 {
194 int cryptodev_fd;
195
196 if ((cryptodev_fd=open("/dev/crypto",O_RDWR,0)) < 0)
197 {
198 err("/dev/crypto");
199 dev_failed=1;
200 return 0;
201 }
202 if (ioctl(cryptodev_fd,CRIOGET,&fd) == -1)
203 {
204 err("CRIOGET failed");
205 close(cryptodev_fd);
206 dev_failed=1;
207 return 0;
208 }
209 close(cryptodev_fd);
210 }
211 assert(ses);
212 memset(ses,'\0',sizeof *ses);
213
214 return 1;
215 }
216
217static int dev_crypto_cleanup(EVP_CIPHER_CTX *ctx)
218 {
219 fprintf(stderr,"cleanup %d\n",CDATA(ctx)->ses);
220 if(ioctl(fd,CIOCFSESSION,&CDATA(ctx)->ses) == -1)
221 err("CIOCFSESSION failed");
222
223 OPENSSL_free(CDATA(ctx)->key);
224
225 return 1;
226 }
227
228static int dev_crypto_init_key(EVP_CIPHER_CTX *ctx,int cipher,
229 const unsigned char *key,int klen)
230 {
231 if(!dev_crypto_init(CDATA(ctx)))
232 return 0;
233
234 CDATA(ctx)->key=OPENSSL_malloc(MAX_HW_KEY);
235
236 assert(ctx->cipher->iv_len <= MAX_HW_IV);
237
238 memcpy(CDATA(ctx)->key,key,klen);
239
240 CDATA(ctx)->cipher=cipher;
241 CDATA(ctx)->keylen=klen;
242
243 if (ioctl(fd,CIOCGSESSION,CDATA(ctx)) == -1)
244 {
245 err("CIOCGSESSION failed");
246 return 0;
247 }
248 return 1;
249 }
250
251static int dev_crypto_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
252 const unsigned char *in,unsigned int inl)
253 {
254 struct crypt_op cryp;
255 unsigned char lb[MAX_HW_IV];
256
257 if(!inl)
258 return 1;
259
260 assert(CDATA(ctx));
261 assert(!dev_failed);
262
263 memset(&cryp,'\0',sizeof cryp);
264 cryp.ses=CDATA(ctx)->ses;
265 cryp.op=ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
266 cryp.flags=0;
267 cryp.len=inl;
268 assert((inl&(ctx->cipher->block_size-1)) == 0);
269 cryp.src=(caddr_t)in;
270 cryp.dst=(caddr_t)out;
271 cryp.mac=0;
272 if(ctx->cipher->iv_len)
273 cryp.iv=(caddr_t)ctx->iv;
274
275 if(!ctx->encrypt)
276 memcpy(lb,&in[cryp.len-ctx->cipher->iv_len],ctx->cipher->iv_len);
277
278 if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
279 {
280 if(errno == EINVAL) /* buffers are misaligned */
281 {
282 unsigned int cinl=0;
283 char *cin=NULL;
284 char *cout=NULL;
285
286 /* NB: this can only make cinl != inl with stream ciphers */
287 cinl=(inl+3)/4*4;
288
289 if(((unsigned long)in&3) || cinl != inl)
290 {
291 cin=OPENSSL_malloc(cinl);
292 memcpy(cin,in,inl);
293 cryp.src=cin;
294 }
295
296 if(((unsigned long)out&3) || cinl != inl)
297 {
298 cout=OPENSSL_malloc(cinl);
299 cryp.dst=cout;
300 }
301
302 cryp.len=cinl;
303
304 if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
305 {
306 err("CIOCCRYPT(2) failed");
307 printf("src=%p dst=%p\n",cryp.src,cryp.dst);
308 abort();
309 return 0;
310 }
311
312 if(cout)
313 {
314 memcpy(out,cout,inl);
315 OPENSSL_free(cout);
316 }
317 if(cin)
318 OPENSSL_free(cin);
319 }
320 else
321 {
322 err("CIOCCRYPT failed");
323 abort();
324 return 0;
325 }
326 }
327
328 if(ctx->encrypt)
329 memcpy(ctx->iv,&out[cryp.len-ctx->cipher->iv_len],ctx->cipher->iv_len);
330 else
331 memcpy(ctx->iv,lb,ctx->cipher->iv_len);
332
333 return 1;
334 }
335
336static int dev_crypto_des_ede3_init_key(EVP_CIPHER_CTX *ctx,
337 const unsigned char *key,
338 const unsigned char *iv, int enc)
339 { return dev_crypto_init_key(ctx,CRYPTO_3DES_CBC,key,24); }
340
341static int dev_crypto_rc4_init_key(EVP_CIPHER_CTX *ctx,
342 const unsigned char *key,
343 const unsigned char *iv, int enc)
344 { return dev_crypto_init_key(ctx,CRYPTO_ARC4,key,16); }
345
346typedef struct
347 {
348 session_op sess;
349 char *data;
350 int len;
351 unsigned char md[EVP_MAX_MD_SIZE];
352 } MD_DATA;
353
354static int dev_crypto_init_digest(MD_DATA *md_data,int mac)
355 {
356 if(!dev_crypto_init(&md_data->sess))
357 return 0;
358
359 md_data->len=0;
360 md_data->data=NULL;
361
362 md_data->sess.mac=mac;
363
364 if (ioctl(fd,CIOCGSESSION,&md_data->sess) == -1)
365 {
366 err("CIOCGSESSION failed");
367 return 0;
368 }
369 fprintf(stderr,"opened %d\n",md_data->sess.ses);
370 return 1;
371 }
372
373static int dev_crypto_cleanup_digest(MD_DATA *md_data)
374 {
375 fprintf(stderr,"cleanup %d\n",md_data->sess.ses);
376 if (ioctl(fd,CIOCFSESSION,&md_data->sess.ses) == -1)
377 {
378 err("CIOCFSESSION failed");
379 return 0;
380 }
381
382 return 1;
383 }
384
385/* FIXME: if device can do chained MACs, then don't accumulate */
386/* FIXME: move accumulation to the framework */
387static int dev_crypto_md5_init(EVP_MD_CTX *ctx)
388 { return dev_crypto_init_digest(ctx->md_data,CRYPTO_MD5); }
389
390static int do_digest(int ses,unsigned char *md,const void *data,int len)
391 {
392 struct crypt_op cryp;
393 static unsigned char md5zero[16]=
394 {
395 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,
396 0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,0x7e
397 };
398
399 /* some cards can't do zero length */
400 if(!len)
401 {
402 memcpy(md,md5zero,16);
403 return 1;
404 }
405
406 memset(&cryp,'\0',sizeof cryp);
407 cryp.ses=ses;
408 cryp.op=COP_ENCRYPT;/* required to do the MAC rather than check it */
409 cryp.len=len;
410 cryp.src=(caddr_t)data;
411 cryp.dst=(caddr_t)data; // FIXME!!!
412 cryp.mac=(caddr_t)md;
413
414 if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
415 {
416 if(errno == EINVAL && allow_misaligned) /* buffer is misaligned */
417 {
418 char *dcopy;
419
420 dcopy=OPENSSL_malloc(len);
421 memcpy(dcopy,data,len);
422 cryp.src=dcopy;
423 cryp.dst=cryp.src; // FIXME!!!
424
425 if(ioctl(fd, CIOCCRYPT, &cryp) == -1)
426 {
427 err("CIOCCRYPT(MAC2) failed");
428 abort();
429 return 0;
430 }
431 OPENSSL_free(dcopy);
432 }
433 else
434 {
435 err("CIOCCRYPT(MAC) failed");
436 abort();
437 return 0;
438 }
439 }
440 // printf("done\n");
441
442 return 1;
443 }
444
445static int dev_crypto_md5_update(EVP_MD_CTX *ctx,const void *data,
446 unsigned long len)
447 {
448 MD_DATA *md_data=ctx->md_data;
449
450 if(ctx->flags&EVP_MD_CTX_FLAG_ONESHOT)
451 return do_digest(md_data->sess.ses,md_data->md,data,len);
452
453 md_data->data=OPENSSL_realloc(md_data->data,md_data->len+len);
454 memcpy(md_data->data+md_data->len,data,len);
455 md_data->len+=len;
456
457 return 1;
458 }
459
460static int dev_crypto_md5_final(EVP_MD_CTX *ctx,unsigned char *md)
461 {
462 int ret;
463 MD_DATA *md_data=ctx->md_data;
464
465 if(ctx->flags&EVP_MD_CTX_FLAG_ONESHOT)
466 {
467 memcpy(md,md_data->md,MD5_DIGEST_LENGTH);
468 ret=1;
469 }
470 else
471 {
472 ret=do_digest(md_data->sess.ses,md,md_data->data,md_data->len);
473 OPENSSL_free(md_data->data);
474 md_data->data=NULL;
475 md_data->len=0;
476 }
477
478 return ret;
479 }
480
481static int dev_crypto_md5_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
482 {
483 const MD_DATA *from_md=from->md_data;
484 MD_DATA *to_md=to->md_data;
485
486 // How do we copy sessions?
487 assert(from->digest->flags&EVP_MD_FLAG_ONESHOT);
488
489 to_md->data=OPENSSL_malloc(from_md->len);
490 memcpy(to_md->data,from_md->data,from_md->len);
491
492 return 1;
493 }
494
495static int dev_crypto_md5_cleanup(EVP_MD_CTX *ctx)
496 {
497 return dev_crypto_cleanup_digest(ctx->md_data);
498 }
499
500/**************************************************************************/
501/* Here are the moved declarations of the EVP_CIPHER and EVP_MD */
502/* implementations. They're down here to be within easy editor-distance */
503/* of the digests and ciphers handler functions. */
504
505#define dev_crypto_des_ede3_cbc_cipher dev_crypto_cipher
506
507BLOCK_CIPHER_def_cbc(dev_crypto_des_ede3, session_op, NID_des_ede3, 8, 24, 8,
508 0, dev_crypto_des_ede3_init_key,
509 dev_crypto_cleanup,
510 EVP_CIPHER_set_asn1_iv,
511 EVP_CIPHER_get_asn1_iv,
512 NULL)
513
514static const EVP_CIPHER r4_cipher=
515 {
516 NID_rc4,
517 1,16,0, /* FIXME: key should be up to 256 bytes */
518 EVP_CIPH_VARIABLE_LENGTH,
519 dev_crypto_rc4_init_key,
520 dev_crypto_cipher,
521 dev_crypto_cleanup,
522 sizeof(session_op),
523 NULL,
524 NULL,
525 NULL
526 };
527
528static const EVP_MD md5_md=
529 {
530 NID_md5,
531 NID_md5WithRSAEncryption,
532 MD5_DIGEST_LENGTH,
533 EVP_MD_FLAG_ONESHOT, // XXX: set according to device info...
534 dev_crypto_md5_init,
535 dev_crypto_md5_update,
536 dev_crypto_md5_final,
537 dev_crypto_md5_copy,
538 dev_crypto_md5_cleanup,
539 EVP_PKEY_RSA_method,
540 MD5_CBLOCK,
541 sizeof(MD_DATA),
542 };
543
544/****************************************************************/
545/* Implement the dev_crypto_[ciphers|digests] handlers here ... */
546
547static int cipher_nids[] = {NID_des_ede3_cbc, NID_rc4};
548static int cipher_nids_num = 2;
549static int digest_nids[] = {NID_md5};
550static int digest_nids_num = 1;
551
552static int dev_crypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
553 const int **nids, int nid)
554 {
555 if(!cipher)
556 {
557 /* We are returning a list of supported nids */
558 *nids = cipher_nids;
559 return cipher_nids_num;
560 }
561 /* We are being asked for a specific cipher */
562 if(nid == NID_rc4)
563 *cipher = &r4_cipher;
564 else if(nid == NID_des_ede3_cbc)
565 *cipher = &dev_crypto_des_ede3_cbc;
566 else
567 {
568 *cipher = NULL;
569 return 0;
570 }
571 return 1;
572 }
573
574static int dev_crypto_digests(ENGINE *e, const EVP_MD **digest,
575 const int **nids, int nid)
576 {
577 if(!digest)
578 {
579 /* We are returning a list of supported nids */
580 *nids = digest_nids;
581 return digest_nids_num;
582 }
583 /* We are being asked for a specific digest */
584 if(nid == NID_md5)
585 *digest = &md5_md;
586 else
587 {
588 *digest = NULL;
589 return 0;
590 }
591 return 1;
592 }
593
594#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 @@
1/* hw_sureware_err.c */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include "hw_sureware_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA SUREWARE_str_functs[]=
68 {
69{ERR_PACK(0,SUREWARE_F_SUREWAREHK_CTRL,0), "SUREWAREHK_CTRL"},
70{ERR_PACK(0,SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,0), "SUREWAREHK_DSA_DO_SIGN"},
71{ERR_PACK(0,SUREWARE_F_SUREWAREHK_EX_FREE,0), "SUREWAREHK_EX_FREE"},
72{ERR_PACK(0,SUREWARE_F_SUREWAREHK_FINISH,0), "SUREWAREHK_FINISH"},
73{ERR_PACK(0,SUREWARE_F_SUREWAREHK_INIT,0), "SUREWAREHK_INIT"},
74{ERR_PACK(0,SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,0), "SUREWAREHK_LOAD_PRIVATE_KEY"},
75{ERR_PACK(0,SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,0), "SUREWAREHK_LOAD_PUBLIC_KEY"},
76{ERR_PACK(0,SUREWARE_F_SUREWAREHK_MOD_EXP,0), "SUREWAREHK_MOD_EXP"},
77{ERR_PACK(0,SUREWARE_F_SUREWAREHK_RAND_BYTES,0), "SUREWAREHK_RAND_BYTES"},
78{ERR_PACK(0,SUREWARE_F_SUREWAREHK_RAND_SEED,0), "SUREWAREHK_RAND_SEED"},
79{ERR_PACK(0,SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,0), "SUREWAREHK_RSA_PRIV_DEC"},
80{ERR_PACK(0,SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC,0), "SUREWAREHK_RSA_PRIV_ENC"},
81{0,NULL}
82 };
83
84static ERR_STRING_DATA SUREWARE_str_reasons[]=
85 {
86{SUREWARE_R_BIO_WAS_FREED ,"bio was freed"},
87{SUREWARE_R_MISSING_KEY_COMPONENTS ,"missing key components"},
88{SUREWARE_R_REQUEST_FAILED ,"request failed"},
89{SUREWARE_R_REQUEST_FALLBACK ,"request fallback"},
90{SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"},
91{SUREWARE_R_UNIT_FAILURE ,"unit failure"},
92{0,NULL}
93 };
94
95#endif
96
97#ifdef SUREWARE_LIB_NAME
98static ERR_STRING_DATA SUREWARE_lib_name[]=
99 {
100{0 ,SUREWARE_LIB_NAME},
101{0,NULL}
102 };
103#endif
104
105
106static int SUREWARE_lib_error_code=0;
107static int SUREWARE_error_init=1;
108
109static void ERR_load_SUREWARE_strings(void)
110 {
111 if (SUREWARE_lib_error_code == 0)
112 SUREWARE_lib_error_code=ERR_get_next_error_library();
113
114 if (SUREWARE_error_init)
115 {
116 SUREWARE_error_init=0;
117#ifndef OPENSSL_NO_ERR
118 ERR_load_strings(SUREWARE_lib_error_code,SUREWARE_str_functs);
119 ERR_load_strings(SUREWARE_lib_error_code,SUREWARE_str_reasons);
120#endif
121
122#ifdef SUREWARE_LIB_NAME
123 SUREWARE_lib_name->error = ERR_PACK(SUREWARE_lib_error_code,0,0);
124 ERR_load_strings(0,SUREWARE_lib_name);
125#endif
126 }
127 }
128
129static void ERR_unload_SUREWARE_strings(void)
130 {
131 if (SUREWARE_error_init == 0)
132 {
133#ifndef OPENSSL_NO_ERR
134 ERR_unload_strings(SUREWARE_lib_error_code,SUREWARE_str_functs);
135 ERR_unload_strings(SUREWARE_lib_error_code,SUREWARE_str_reasons);
136#endif
137
138#ifdef SUREWARE_LIB_NAME
139 ERR_unload_strings(0,SUREWARE_lib_name);
140#endif
141 SUREWARE_error_init=1;
142 }
143 }
144
145static void ERR_SUREWARE_error(int function, int reason, char *file, int line)
146 {
147 if (SUREWARE_lib_error_code == 0)
148 SUREWARE_lib_error_code=ERR_get_next_error_library();
149 ERR_PUT_error(SUREWARE_lib_error_code,function,reason,file,line);
150 }
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 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#ifndef HEADER_SUREWARE_ERR_H
56#define HEADER_SUREWARE_ERR_H
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_SUREWARE_strings(void);
63static void ERR_unload_SUREWARE_strings(void);
64static void ERR_SUREWARE_error(int function, int reason, char *file, int line);
65#define SUREWAREerr(f,r) ERR_SUREWARE_error((f),(r),__FILE__,__LINE__)
66
67/* Error codes for the SUREWARE functions. */
68
69/* Function codes. */
70#define SUREWARE_F_SUREWAREHK_CTRL 100
71#define SUREWARE_F_SUREWAREHK_DSA_DO_SIGN 101
72#define SUREWARE_F_SUREWAREHK_EX_FREE 102
73#define SUREWARE_F_SUREWAREHK_FINISH 103
74#define SUREWARE_F_SUREWAREHK_INIT 104
75#define SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY 105
76#define SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY 106
77#define SUREWARE_F_SUREWAREHK_MOD_EXP 107
78#define SUREWARE_F_SUREWAREHK_RAND_BYTES 108
79#define SUREWARE_F_SUREWAREHK_RAND_SEED 109
80#define SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC 110
81#define SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC 111
82
83/* Reason codes. */
84#define SUREWARE_R_BIO_WAS_FREED 100
85#define SUREWARE_R_MISSING_KEY_COMPONENTS 105
86#define SUREWARE_R_REQUEST_FAILED 101
87#define SUREWARE_R_REQUEST_FALLBACK 102
88#define SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL 103
89#define SUREWARE_R_UNIT_FAILURE 104
90
91#ifdef __cplusplus
92}
93#endif
94#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 @@
1/* crypto/engine/hw_ubsec.c */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 *
5 * Cloned shamelessly by Joe Tardo.
6 */
7/* ====================================================================
8 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 *
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in
19 * the documentation and/or other materials provided with the
20 * distribution.
21 *
22 * 3. All advertising materials mentioning features or use of this
23 * software must display the following acknowledgment:
24 * "This product includes software developed by the OpenSSL Project
25 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
26 *
27 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
28 * endorse or promote products derived from this software without
29 * prior written permission. For written permission, please contact
30 * licensing@OpenSSL.org.
31 *
32 * 5. Products derived from this software may not be called "OpenSSL"
33 * nor may "OpenSSL" appear in their names without prior written
34 * permission of the OpenSSL Project.
35 *
36 * 6. Redistributions of any form whatsoever must retain the following
37 * acknowledgment:
38 * "This product includes software developed by the OpenSSL Project
39 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
42 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
44 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
50 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
51 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
52 * OF THE POSSIBILITY OF SUCH DAMAGE.
53 * ====================================================================
54 *
55 * This product includes cryptographic software written by Eric Young
56 * (eay@cryptsoft.com). This product includes software written by Tim
57 * Hudson (tjh@cryptsoft.com).
58 *
59 */
60
61#include <stdio.h>
62#include <openssl/crypto.h>
63#include "cryptlib.h"
64#include <openssl/dso.h>
65#include <openssl/engine.h>
66
67#ifndef OPENSSL_NO_HW
68#ifndef OPENSSL_NO_HW_UBSEC
69
70#ifdef FLAT_INC
71#include "hw_ubsec.h"
72#else
73#include "vendor_defns/hw_ubsec.h"
74#endif
75
76#define UBSEC_LIB_NAME "ubsec engine"
77#include "hw_ubsec_err.c"
78
79#define FAIL_TO_SOFTWARE -15
80
81static int ubsec_destroy(ENGINE *e);
82static int ubsec_init(ENGINE *e);
83static int ubsec_finish(ENGINE *e);
84static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
85static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
86 const BIGNUM *m, BN_CTX *ctx);
87static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
88 const BIGNUM *q, const BIGNUM *dp,
89 const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx);
90#ifndef OPENSSL_NO_RSA
91static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
92#endif
93static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
94 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
95#ifndef OPENSSL_NO_DSA
96#if NOT_USED
97static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
98 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
99 BN_CTX *ctx, BN_MONT_CTX *in_mont);
100static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
101 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
102 BN_MONT_CTX *m_ctx);
103#endif
104static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
105static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
106 DSA_SIG *sig, DSA *dsa);
107#endif
108#ifndef OPENSSL_NO_DH
109static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
110 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
111 BN_MONT_CTX *m_ctx);
112static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh);
113static int ubsec_dh_generate_key(DH *dh);
114#endif
115
116#if NOT_USED
117static int ubsec_rand_bytes(unsigned char *buf, int num);
118static int ubsec_rand_status(void);
119#endif
120
121#define UBSEC_CMD_SO_PATH ENGINE_CMD_BASE
122static const ENGINE_CMD_DEFN ubsec_cmd_defns[] = {
123 {UBSEC_CMD_SO_PATH,
124 "SO_PATH",
125 "Specifies the path to the 'ubsec' shared library",
126 ENGINE_CMD_FLAG_STRING},
127 {0, NULL, NULL, 0}
128 };
129
130#ifndef OPENSSL_NO_RSA
131/* Our internal RSA_METHOD that we provide pointers to */
132static RSA_METHOD ubsec_rsa =
133 {
134 "UBSEC RSA method",
135 NULL,
136 NULL,
137 NULL,
138 NULL,
139 ubsec_rsa_mod_exp,
140 ubsec_mod_exp_mont,
141 NULL,
142 NULL,
143 0,
144 NULL,
145 NULL,
146 NULL
147 };
148#endif
149
150#ifndef OPENSSL_NO_DSA
151/* Our internal DSA_METHOD that we provide pointers to */
152static DSA_METHOD ubsec_dsa =
153 {
154 "UBSEC DSA method",
155 ubsec_dsa_do_sign, /* dsa_do_sign */
156 NULL, /* dsa_sign_setup */
157 ubsec_dsa_verify, /* dsa_do_verify */
158 NULL, /* ubsec_dsa_mod_exp */ /* dsa_mod_exp */
159 NULL, /* ubsec_mod_exp_dsa */ /* bn_mod_exp */
160 NULL, /* init */
161 NULL, /* finish */
162 0, /* flags */
163 NULL /* app_data */
164 };
165#endif
166
167#ifndef OPENSSL_NO_DH
168/* Our internal DH_METHOD that we provide pointers to */
169static DH_METHOD ubsec_dh =
170 {
171 "UBSEC DH method",
172 ubsec_dh_generate_key,
173 ubsec_dh_compute_key,
174 ubsec_mod_exp_dh,
175 NULL,
176 NULL,
177 0,
178 NULL
179 };
180#endif
181
182/* Constants used when creating the ENGINE */
183static const char *engine_ubsec_id = "ubsec";
184static const char *engine_ubsec_name = "UBSEC hardware engine support";
185
186/* This internal function is used by ENGINE_ubsec() and possibly by the
187 * "dynamic" ENGINE support too */
188static int bind_helper(ENGINE *e)
189 {
190#ifndef OPENSSL_NO_RSA
191 const RSA_METHOD *meth1;
192#endif
193#ifndef OPENSSL_NO_DH
194#ifndef HAVE_UBSEC_DH
195 const DH_METHOD *meth3;
196#endif /* HAVE_UBSEC_DH */
197#endif
198 if(!ENGINE_set_id(e, engine_ubsec_id) ||
199 !ENGINE_set_name(e, engine_ubsec_name) ||
200#ifndef OPENSSL_NO_RSA
201 !ENGINE_set_RSA(e, &ubsec_rsa) ||
202#endif
203#ifndef OPENSSL_NO_DSA
204 !ENGINE_set_DSA(e, &ubsec_dsa) ||
205#endif
206#ifndef OPENSSL_NO_DH
207 !ENGINE_set_DH(e, &ubsec_dh) ||
208#endif
209 !ENGINE_set_destroy_function(e, ubsec_destroy) ||
210 !ENGINE_set_init_function(e, ubsec_init) ||
211 !ENGINE_set_finish_function(e, ubsec_finish) ||
212 !ENGINE_set_ctrl_function(e, ubsec_ctrl) ||
213 !ENGINE_set_cmd_defns(e, ubsec_cmd_defns))
214 return 0;
215
216#ifndef OPENSSL_NO_RSA
217 /* We know that the "PKCS1_SSLeay()" functions hook properly
218 * to the Broadcom-specific mod_exp and mod_exp_crt so we use
219 * those functions. NB: We don't use ENGINE_openssl() or
220 * anything "more generic" because something like the RSAref
221 * code may not hook properly, and if you own one of these
222 * cards then you have the right to do RSA operations on it
223 * anyway! */
224 meth1 = RSA_PKCS1_SSLeay();
225 ubsec_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
226 ubsec_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
227 ubsec_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
228 ubsec_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
229#endif
230
231#ifndef OPENSSL_NO_DH
232#ifndef HAVE_UBSEC_DH
233 /* Much the same for Diffie-Hellman */
234 meth3 = DH_OpenSSL();
235 ubsec_dh.generate_key = meth3->generate_key;
236 ubsec_dh.compute_key = meth3->compute_key;
237#endif /* HAVE_UBSEC_DH */
238#endif
239
240 /* Ensure the ubsec error handling is set up */
241 ERR_load_UBSEC_strings();
242 return 1;
243 }
244
245static ENGINE *engine_ubsec(void)
246 {
247 ENGINE *ret = ENGINE_new();
248 if(!ret)
249 return NULL;
250 if(!bind_helper(ret))
251 {
252 ENGINE_free(ret);
253 return NULL;
254 }
255 return ret;
256 }
257
258void ENGINE_load_ubsec(void)
259 {
260 /* Copied from eng_[openssl|dyn].c */
261 ENGINE *toadd = engine_ubsec();
262 if(!toadd) return;
263 ENGINE_add(toadd);
264 ENGINE_free(toadd);
265 ERR_clear_error();
266 }
267
268/* This is a process-global DSO handle used for loading and unloading
269 * the UBSEC library. NB: This is only set (or unset) during an
270 * init() or finish() call (reference counts permitting) and they're
271 * operating with global locks, so this should be thread-safe
272 * implicitly. */
273
274static DSO *ubsec_dso = NULL;
275
276/* These are the function pointers that are (un)set when the library has
277 * successfully (un)loaded. */
278
279static t_UBSEC_ubsec_bytes_to_bits *p_UBSEC_ubsec_bytes_to_bits = NULL;
280static t_UBSEC_ubsec_bits_to_bytes *p_UBSEC_ubsec_bits_to_bytes = NULL;
281static t_UBSEC_ubsec_open *p_UBSEC_ubsec_open = NULL;
282static t_UBSEC_ubsec_close *p_UBSEC_ubsec_close = NULL;
283#ifndef OPENSSL_NO_DH
284static t_UBSEC_diffie_hellman_generate_ioctl
285 *p_UBSEC_diffie_hellman_generate_ioctl = NULL;
286static t_UBSEC_diffie_hellman_agree_ioctl *p_UBSEC_diffie_hellman_agree_ioctl = NULL;
287#endif
288/* #ifndef OPENSSL_NO_RSA */
289static t_UBSEC_rsa_mod_exp_ioctl *p_UBSEC_rsa_mod_exp_ioctl = NULL;
290static t_UBSEC_rsa_mod_exp_crt_ioctl *p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
291/* #endif */
292#ifndef OPENSSL_NO_DSA
293static t_UBSEC_dsa_sign_ioctl *p_UBSEC_dsa_sign_ioctl = NULL;
294static t_UBSEC_dsa_verify_ioctl *p_UBSEC_dsa_verify_ioctl = NULL;
295#endif
296static t_UBSEC_math_accelerate_ioctl *p_UBSEC_math_accelerate_ioctl = NULL;
297static t_UBSEC_rng_ioctl *p_UBSEC_rng_ioctl = NULL;
298static t_UBSEC_max_key_len_ioctl *p_UBSEC_max_key_len_ioctl = NULL;
299
300static int max_key_len = 1024; /* ??? */
301
302/*
303 * These are the static string constants for the DSO file name and the function
304 * symbol names to bind to.
305 */
306
307static const char *UBSEC_LIBNAME = "ubsec";
308static const char *UBSEC_F1 = "ubsec_bytes_to_bits";
309static const char *UBSEC_F2 = "ubsec_bits_to_bytes";
310static const char *UBSEC_F3 = "ubsec_open";
311static const char *UBSEC_F4 = "ubsec_close";
312#ifndef OPENSSL_NO_DH
313static const char *UBSEC_F5 = "diffie_hellman_generate_ioctl";
314static const char *UBSEC_F6 = "diffie_hellman_agree_ioctl";
315#endif
316/* #ifndef OPENSSL_NO_RSA */
317static const char *UBSEC_F7 = "rsa_mod_exp_ioctl";
318static const char *UBSEC_F8 = "rsa_mod_exp_crt_ioctl";
319/* #endif */
320#ifndef OPENSSL_NO_DSA
321static const char *UBSEC_F9 = "dsa_sign_ioctl";
322static const char *UBSEC_F10 = "dsa_verify_ioctl";
323#endif
324static const char *UBSEC_F11 = "math_accelerate_ioctl";
325static const char *UBSEC_F12 = "rng_ioctl";
326static const char *UBSEC_F13 = "ubsec_max_key_len_ioctl";
327
328/* Destructor (complements the "ENGINE_ubsec()" constructor) */
329static int ubsec_destroy(ENGINE *e)
330 {
331 ERR_unload_UBSEC_strings();
332 return 1;
333 }
334
335/* (de)initialisation functions. */
336static int ubsec_init(ENGINE *e)
337 {
338 t_UBSEC_ubsec_bytes_to_bits *p1;
339 t_UBSEC_ubsec_bits_to_bytes *p2;
340 t_UBSEC_ubsec_open *p3;
341 t_UBSEC_ubsec_close *p4;
342#ifndef OPENSSL_NO_DH
343 t_UBSEC_diffie_hellman_generate_ioctl *p5;
344 t_UBSEC_diffie_hellman_agree_ioctl *p6;
345#endif
346/* #ifndef OPENSSL_NO_RSA */
347 t_UBSEC_rsa_mod_exp_ioctl *p7;
348 t_UBSEC_rsa_mod_exp_crt_ioctl *p8;
349/* #endif */
350#ifndef OPENSSL_NO_DSA
351 t_UBSEC_dsa_sign_ioctl *p9;
352 t_UBSEC_dsa_verify_ioctl *p10;
353#endif
354 t_UBSEC_math_accelerate_ioctl *p11;
355 t_UBSEC_rng_ioctl *p12;
356 t_UBSEC_max_key_len_ioctl *p13;
357 int fd = 0;
358
359 if(ubsec_dso != NULL)
360 {
361 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_ALREADY_LOADED);
362 goto err;
363 }
364 /*
365 * Attempt to load libubsec.so/ubsec.dll/whatever.
366 */
367 ubsec_dso = DSO_load(NULL, UBSEC_LIBNAME, NULL, 0);
368 if(ubsec_dso == NULL)
369 {
370 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
371 goto err;
372 }
373
374 if (
375 !(p1 = (t_UBSEC_ubsec_bytes_to_bits *) DSO_bind_func(ubsec_dso, UBSEC_F1)) ||
376 !(p2 = (t_UBSEC_ubsec_bits_to_bytes *) DSO_bind_func(ubsec_dso, UBSEC_F2)) ||
377 !(p3 = (t_UBSEC_ubsec_open *) DSO_bind_func(ubsec_dso, UBSEC_F3)) ||
378 !(p4 = (t_UBSEC_ubsec_close *) DSO_bind_func(ubsec_dso, UBSEC_F4)) ||
379#ifndef OPENSSL_NO_DH
380 !(p5 = (t_UBSEC_diffie_hellman_generate_ioctl *)
381 DSO_bind_func(ubsec_dso, UBSEC_F5)) ||
382 !(p6 = (t_UBSEC_diffie_hellman_agree_ioctl *)
383 DSO_bind_func(ubsec_dso, UBSEC_F6)) ||
384#endif
385/* #ifndef OPENSSL_NO_RSA */
386 !(p7 = (t_UBSEC_rsa_mod_exp_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F7)) ||
387 !(p8 = (t_UBSEC_rsa_mod_exp_crt_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F8)) ||
388/* #endif */
389#ifndef OPENSSL_NO_DSA
390 !(p9 = (t_UBSEC_dsa_sign_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F9)) ||
391 !(p10 = (t_UBSEC_dsa_verify_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F10)) ||
392#endif
393 !(p11 = (t_UBSEC_math_accelerate_ioctl *)
394 DSO_bind_func(ubsec_dso, UBSEC_F11)) ||
395 !(p12 = (t_UBSEC_rng_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F12)) ||
396 !(p13 = (t_UBSEC_max_key_len_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F13)))
397 {
398 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
399 goto err;
400 }
401
402 /* Copy the pointers */
403 p_UBSEC_ubsec_bytes_to_bits = p1;
404 p_UBSEC_ubsec_bits_to_bytes = p2;
405 p_UBSEC_ubsec_open = p3;
406 p_UBSEC_ubsec_close = p4;
407#ifndef OPENSSL_NO_DH
408 p_UBSEC_diffie_hellman_generate_ioctl = p5;
409 p_UBSEC_diffie_hellman_agree_ioctl = p6;
410#endif
411#ifndef OPENSSL_NO_RSA
412 p_UBSEC_rsa_mod_exp_ioctl = p7;
413 p_UBSEC_rsa_mod_exp_crt_ioctl = p8;
414#endif
415#ifndef OPENSSL_NO_DSA
416 p_UBSEC_dsa_sign_ioctl = p9;
417 p_UBSEC_dsa_verify_ioctl = p10;
418#endif
419 p_UBSEC_math_accelerate_ioctl = p11;
420 p_UBSEC_rng_ioctl = p12;
421 p_UBSEC_max_key_len_ioctl = p13;
422
423 /* Perform an open to see if there's actually any unit running. */
424 if (((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) > 0) && (p_UBSEC_max_key_len_ioctl(fd, &max_key_len) == 0))
425 {
426 p_UBSEC_ubsec_close(fd);
427 return 1;
428 }
429 else
430 {
431 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
432 }
433
434err:
435 if(ubsec_dso)
436 DSO_free(ubsec_dso);
437 p_UBSEC_ubsec_bytes_to_bits = NULL;
438 p_UBSEC_ubsec_bits_to_bytes = NULL;
439 p_UBSEC_ubsec_open = NULL;
440 p_UBSEC_ubsec_close = NULL;
441#ifndef OPENSSL_NO_DH
442 p_UBSEC_diffie_hellman_generate_ioctl = NULL;
443 p_UBSEC_diffie_hellman_agree_ioctl = NULL;
444#endif
445#ifndef OPENSSL_NO_RSA
446 p_UBSEC_rsa_mod_exp_ioctl = NULL;
447 p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
448#endif
449#ifndef OPENSSL_NO_DSA
450 p_UBSEC_dsa_sign_ioctl = NULL;
451 p_UBSEC_dsa_verify_ioctl = NULL;
452#endif
453 p_UBSEC_math_accelerate_ioctl = NULL;
454 p_UBSEC_rng_ioctl = NULL;
455 p_UBSEC_max_key_len_ioctl = NULL;
456
457 return 0;
458 }
459
460static int ubsec_finish(ENGINE *e)
461 {
462 if(ubsec_dso == NULL)
463 {
464 UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_NOT_LOADED);
465 return 0;
466 }
467 if(!DSO_free(ubsec_dso))
468 {
469 UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_DSO_FAILURE);
470 return 0;
471 }
472 ubsec_dso = NULL;
473 p_UBSEC_ubsec_bytes_to_bits = NULL;
474 p_UBSEC_ubsec_bits_to_bytes = NULL;
475 p_UBSEC_ubsec_open = NULL;
476 p_UBSEC_ubsec_close = NULL;
477#ifndef OPENSSL_NO_DH
478 p_UBSEC_diffie_hellman_generate_ioctl = NULL;
479 p_UBSEC_diffie_hellman_agree_ioctl = NULL;
480#endif
481#ifndef OPENSSL_NO_RSA
482 p_UBSEC_rsa_mod_exp_ioctl = NULL;
483 p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
484#endif
485#ifndef OPENSSL_NO_DSA
486 p_UBSEC_dsa_sign_ioctl = NULL;
487 p_UBSEC_dsa_verify_ioctl = NULL;
488#endif
489 p_UBSEC_math_accelerate_ioctl = NULL;
490 p_UBSEC_rng_ioctl = NULL;
491 p_UBSEC_max_key_len_ioctl = NULL;
492 return 1;
493 }
494
495static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
496 {
497 int initialised = ((ubsec_dso == NULL) ? 0 : 1);
498 switch(cmd)
499 {
500 case UBSEC_CMD_SO_PATH:
501 if(p == NULL)
502 {
503 UBSECerr(UBSEC_F_UBSEC_CTRL,ERR_R_PASSED_NULL_PARAMETER);
504 return 0;
505 }
506 if(initialised)
507 {
508 UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_ALREADY_LOADED);
509 return 0;
510 }
511 UBSEC_LIBNAME = (const char *)p;
512 return 1;
513 default:
514 break;
515 }
516 UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED);
517 return 0;
518 }
519
520static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
521 const BIGNUM *m, BN_CTX *ctx)
522 {
523 int y_len = 0;
524 int fd;
525
526 if(ubsec_dso == NULL)
527 {
528 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_NOT_LOADED);
529 return 0;
530 }
531
532 /* Check if hardware can't handle this argument. */
533 y_len = BN_num_bits(m);
534 if (y_len > max_key_len) {
535 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
536 return BN_mod_exp(r, a, p, m, ctx);
537 }
538
539 if(!bn_wexpand(r, m->top))
540 {
541 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_BN_EXPAND_FAIL);
542 return 0;
543 }
544 memset(r->d, 0, BN_num_bytes(m));
545
546 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
547 fd = 0;
548 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
549 return BN_mod_exp(r, a, p, m, ctx);
550 }
551
552 if (p_UBSEC_rsa_mod_exp_ioctl(fd, (unsigned char *)a->d, BN_num_bits(a),
553 (unsigned char *)m->d, BN_num_bits(m), (unsigned char *)p->d,
554 BN_num_bits(p), (unsigned char *)r->d, &y_len) != 0)
555 {
556 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED);
557 p_UBSEC_ubsec_close(fd);
558
559 return BN_mod_exp(r, a, p, m, ctx);
560 }
561
562 p_UBSEC_ubsec_close(fd);
563
564 r->top = (BN_num_bits(m)+BN_BITS2-1)/BN_BITS2;
565 return 1;
566 }
567
568#ifndef OPENSSL_NO_RSA
569static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
570 {
571 BN_CTX *ctx;
572 int to_return = 0;
573
574 if((ctx = BN_CTX_new()) == NULL)
575 goto err;
576
577 if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
578 {
579 UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP, UBSEC_R_MISSING_KEY_COMPONENTS);
580 goto err;
581 }
582
583 to_return = ubsec_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
584 rsa->dmq1, rsa->iqmp, ctx);
585 if (to_return == FAIL_TO_SOFTWARE)
586 {
587 /*
588 * Do in software as hardware failed.
589 */
590 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
591 to_return = (*meth->rsa_mod_exp)(r0, I, rsa);
592 }
593err:
594 if(ctx)
595 BN_CTX_free(ctx);
596 return to_return;
597 }
598#endif
599
600static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
601 const BIGNUM *q, const BIGNUM *dp,
602 const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx)
603 {
604 int y_len,
605 m_len,
606 fd;
607
608 m_len = BN_num_bytes(p) + BN_num_bytes(q) + 1;
609 y_len = BN_num_bits(p) + BN_num_bits(q);
610
611 /* Check if hardware can't handle this argument. */
612 if (y_len > max_key_len) {
613 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
614 return FAIL_TO_SOFTWARE;
615 }
616
617 if (!bn_wexpand(r, p->top + q->top + 1)) {
618 UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP_CRT, UBSEC_R_BN_EXPAND_FAIL);
619 return 0;
620 }
621
622 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
623 fd = 0;
624 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
625 return FAIL_TO_SOFTWARE;
626 }
627
628 if (p_UBSEC_rsa_mod_exp_crt_ioctl(fd,
629 (unsigned char *)a->d, BN_num_bits(a),
630 (unsigned char *)qinv->d, BN_num_bits(qinv),
631 (unsigned char *)dp->d, BN_num_bits(dp),
632 (unsigned char *)p->d, BN_num_bits(p),
633 (unsigned char *)dq->d, BN_num_bits(dq),
634 (unsigned char *)q->d, BN_num_bits(q),
635 (unsigned char *)r->d, &y_len) != 0) {
636 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED);
637 p_UBSEC_ubsec_close(fd);
638 return FAIL_TO_SOFTWARE;
639 }
640
641 p_UBSEC_ubsec_close(fd);
642
643 r->top = (BN_num_bits(p) + BN_num_bits(q) + BN_BITS2 - 1)/BN_BITS2;
644 return 1;
645}
646
647#ifndef OPENSSL_NO_DSA
648#if NOT_USED
649static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
650 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
651 BN_CTX *ctx, BN_MONT_CTX *in_mont)
652 {
653 BIGNUM t;
654 int to_return = 0;
655
656 BN_init(&t);
657 /* let rr = a1 ^ p1 mod m */
658 if (!ubsec_mod_exp(rr,a1,p1,m,ctx)) goto end;
659 /* let t = a2 ^ p2 mod m */
660 if (!ubsec_mod_exp(&t,a2,p2,m,ctx)) goto end;
661 /* let rr = rr * t mod m */
662 if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
663 to_return = 1;
664end:
665 BN_free(&t);
666 return to_return;
667 }
668
669static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
670 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
671 BN_MONT_CTX *m_ctx)
672 {
673 return ubsec_mod_exp(r, a, p, m, ctx);
674 }
675#endif
676#endif
677
678/*
679 * This function is aliased to mod_exp (with the mont stuff dropped).
680 */
681static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
682 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
683 {
684 int ret = 0;
685
686#ifndef OPENSSL_NO_RSA
687 /* Do in software if the key is too large for the hardware. */
688 if (BN_num_bits(m) > max_key_len)
689 {
690 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
691 ret = (*meth->bn_mod_exp)(r, a, p, m, ctx, m_ctx);
692 }
693 else
694#endif
695 {
696 ret = ubsec_mod_exp(r, a, p, m, ctx);
697 }
698
699 return ret;
700 }
701
702#ifndef OPENSSL_NO_DH
703/* This function is aliased to mod_exp (with the dh and mont dropped). */
704static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
705 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
706 BN_MONT_CTX *m_ctx)
707 {
708 return ubsec_mod_exp(r, a, p, m, ctx);
709 }
710#endif
711
712#ifndef OPENSSL_NO_DSA
713static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
714 {
715 DSA_SIG *to_return = NULL;
716 int s_len = 160, r_len = 160, d_len, fd;
717 BIGNUM m, *r=NULL, *s=NULL;
718
719 BN_init(&m);
720
721 s = BN_new();
722 r = BN_new();
723 if ((s == NULL) || (r==NULL))
724 goto err;
725
726 d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dlen);
727
728 if(!bn_wexpand(r, (160+BN_BITS2-1)/BN_BITS2) ||
729 (!bn_wexpand(s, (160+BN_BITS2-1)/BN_BITS2))) {
730 UBSECerr(UBSEC_F_UBSEC_DSA_SIGN, UBSEC_R_BN_EXPAND_FAIL);
731 goto err;
732 }
733
734 if (BN_bin2bn(dgst,dlen,&m) == NULL) {
735 UBSECerr(UBSEC_F_UBSEC_DSA_SIGN, UBSEC_R_BN_EXPAND_FAIL);
736 goto err;
737 }
738
739 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
740 const DSA_METHOD *meth;
741 fd = 0;
742 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
743 meth = DSA_OpenSSL();
744 to_return = meth->dsa_do_sign(dgst, dlen, dsa);
745 goto err;
746 }
747
748 if (p_UBSEC_dsa_sign_ioctl(fd, 0, /* compute hash before signing */
749 (unsigned char *)dgst, d_len,
750 NULL, 0, /* compute random value */
751 (unsigned char *)dsa->p->d, BN_num_bits(dsa->p),
752 (unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
753 (unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
754 (unsigned char *)dsa->priv_key->d, BN_num_bits(dsa->priv_key),
755 (unsigned char *)r->d, &r_len,
756 (unsigned char *)s->d, &s_len ) != 0) {
757 const DSA_METHOD *meth;
758
759 UBSECerr(UBSEC_F_UBSEC_DSA_SIGN, UBSEC_R_REQUEST_FAILED);
760 p_UBSEC_ubsec_close(fd);
761 meth = DSA_OpenSSL();
762 to_return = meth->dsa_do_sign(dgst, dlen, dsa);
763
764 goto err;
765 }
766
767 p_UBSEC_ubsec_close(fd);
768
769 r->top = (160+BN_BITS2-1)/BN_BITS2;
770 s->top = (160+BN_BITS2-1)/BN_BITS2;
771
772 to_return = DSA_SIG_new();
773 if(to_return == NULL) {
774 UBSECerr(UBSEC_F_UBSEC_DSA_SIGN, UBSEC_R_BN_EXPAND_FAIL);
775 goto err;
776 }
777
778 to_return->r = r;
779 to_return->s = s;
780
781err:
782 if (!to_return) {
783 if (r) BN_free(r);
784 if (s) BN_free(s);
785 }
786 BN_clear_free(&m);
787 return to_return;
788}
789
790static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
791 DSA_SIG *sig, DSA *dsa)
792 {
793 int v_len, d_len;
794 int to_return = 0;
795 int fd;
796 BIGNUM v;
797
798 BN_init(&v);
799
800 if(!bn_wexpand(&v, dsa->p->top)) {
801 UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY ,UBSEC_R_BN_EXPAND_FAIL);
802 goto err;
803 }
804
805 v_len = BN_num_bits(dsa->p);
806
807 d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dgst_len);
808
809 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
810 const DSA_METHOD *meth;
811 fd = 0;
812 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
813 meth = DSA_OpenSSL();
814 to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
815 goto err;
816 }
817
818 if (p_UBSEC_dsa_verify_ioctl(fd, 0, /* compute hash before signing */
819 (unsigned char *)dgst, d_len,
820 (unsigned char *)dsa->p->d, BN_num_bits(dsa->p),
821 (unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
822 (unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
823 (unsigned char *)dsa->pub_key->d, BN_num_bits(dsa->pub_key),
824 (unsigned char *)sig->r->d, BN_num_bits(sig->r),
825 (unsigned char *)sig->s->d, BN_num_bits(sig->s),
826 (unsigned char *)v.d, &v_len) != 0) {
827 const DSA_METHOD *meth;
828 UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY , UBSEC_R_REQUEST_FAILED);
829 p_UBSEC_ubsec_close(fd);
830
831 meth = DSA_OpenSSL();
832 to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
833
834 goto err;
835 }
836
837 p_UBSEC_ubsec_close(fd);
838
839 to_return = 1;
840err:
841 BN_clear_free(&v);
842 return to_return;
843 }
844#endif
845
846#ifndef OPENSSL_NO_DH
847static int ubsec_dh_compute_key (unsigned char *key,const BIGNUM *pub_key,DH *dh)
848 {
849 int ret = -1,
850 k_len,
851 fd;
852
853 k_len = BN_num_bits(dh->p);
854
855 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
856 {
857 const DH_METHOD *meth;
858 ENGINEerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
859 meth = DH_OpenSSL();
860 ret = meth->compute_key(key, pub_key, dh);
861 goto err;
862 }
863
864 if (p_UBSEC_diffie_hellman_agree_ioctl(fd,
865 (unsigned char *)dh->priv_key->d, BN_num_bits(dh->priv_key),
866 (unsigned char *)pub_key->d, BN_num_bits(pub_key),
867 (unsigned char *)dh->p->d, BN_num_bits(dh->p),
868 key, &k_len) != 0)
869 {
870 /* Hardware's a no go, failover to software */
871 const DH_METHOD *meth;
872 ENGINEerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_REQUEST_FAILED);
873 p_UBSEC_ubsec_close(fd);
874
875 meth = DH_OpenSSL();
876 ret = meth->compute_key(key, pub_key, dh);
877
878 goto err;
879 }
880
881 p_UBSEC_ubsec_close(fd);
882
883 ret = p_UBSEC_ubsec_bits_to_bytes(k_len);
884err:
885 return ret;
886 }
887
888static int ubsec_dh_generate_key (DH *dh)
889 {
890 int ret = 0,
891 random_bits = 0,
892 pub_key_len = 0,
893 priv_key_len = 0,
894 fd;
895 BIGNUM *pub_key = NULL;
896 BIGNUM *priv_key = NULL;
897
898 /*
899 * How many bits should Random x be? dh_key.c
900 * sets the range from 0 to num_bits(modulus) ???
901 */
902
903 if (dh->priv_key == NULL)
904 {
905 priv_key = BN_new();
906 if (priv_key == NULL) goto err;
907 priv_key_len = BN_num_bits(dh->p);
908 bn_wexpand(priv_key, dh->p->top);
909 do
910 if (!BN_rand_range(priv_key, dh->p)) goto err;
911 while (BN_is_zero(priv_key));
912 random_bits = BN_num_bits(priv_key);
913 }
914 else
915 {
916 priv_key = dh->priv_key;
917 }
918
919 if (dh->pub_key == NULL)
920 {
921 pub_key = BN_new();
922 pub_key_len = BN_num_bits(dh->p);
923 bn_wexpand(pub_key, dh->p->top);
924 if(pub_key == NULL) goto err;
925 }
926 else
927 {
928 pub_key = dh->pub_key;
929 }
930
931 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
932 {
933 const DH_METHOD *meth;
934 ENGINEerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
935 meth = DH_OpenSSL();
936 ret = meth->generate_key(dh);
937 goto err;
938 }
939
940 if (p_UBSEC_diffie_hellman_generate_ioctl(fd,
941 (unsigned char *)priv_key->d, &priv_key_len,
942 (unsigned char *)pub_key->d, &pub_key_len,
943 (unsigned char *)dh->g->d, BN_num_bits(dh->g),
944 (unsigned char *)dh->p->d, BN_num_bits(dh->p),
945 0, 0, random_bits) != 0)
946 {
947 /* Hardware's a no go, failover to software */
948 const DH_METHOD *meth;
949
950 ENGINEerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_REQUEST_FAILED);
951 p_UBSEC_ubsec_close(fd);
952
953 meth = DH_OpenSSL();
954 ret = meth->generate_key(dh);
955
956 goto err;
957 }
958
959 p_UBSEC_ubsec_close(fd);
960
961 dh->pub_key = pub_key;
962 dh->pub_key->top = (pub_key_len + BN_BITS2-1) / BN_BITS2;
963 dh->priv_key = priv_key;
964 dh->priv_key->top = (priv_key_len + BN_BITS2-1) / BN_BITS2;
965
966 ret = 1;
967err:
968 return ret;
969 }
970#endif
971
972#if NOT_USED
973static int ubsec_rand_bytes(unsigned char * buf,
974 int num)
975 {
976 int ret = 0,
977 fd;
978
979 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
980 {
981 const RAND_METHOD *meth;
982 ENGINEerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
983 num = p_UBSEC_ubsec_bits_to_bytes(num);
984 meth = RAND_SSLeay();
985 meth->seed(buf, num);
986 ret = meth->bytes(buf, num);
987 goto err;
988 }
989
990 num *= 8; /* bytes to bits */
991
992 if (p_UBSEC_rng_ioctl(fd,
993 UBSEC_RNG_DIRECT,
994 buf,
995 &num) != 0)
996 {
997 /* Hardware's a no go, failover to software */
998 const RAND_METHOD *meth;
999
1000 ENGINEerr(UBSEC_F_UBSEC_RNG_BYTES, UBSEC_R_REQUEST_FAILED);
1001 p_UBSEC_ubsec_close(fd);
1002
1003 num = p_UBSEC_ubsec_bits_to_bytes(num);
1004 meth = RAND_SSLeay();
1005 meth->seed(buf, num);
1006 ret = meth->bytes(buf, num);
1007
1008 goto err;
1009 }
1010
1011 p_UBSEC_ubsec_close(fd);
1012
1013 ret = 1;
1014err:
1015 return(ret);
1016 }
1017
1018
1019static int ubsec_rand_status(void)
1020 {
1021 return 0;
1022 }
1023#endif
1024
1025/* This stuff is needed if this ENGINE is being compiled into a self-contained
1026 * shared-library. */
1027#ifdef ENGINE_DYNAMIC_SUPPORT
1028static int bind_fn(ENGINE *e, const char *id)
1029 {
1030 if(id && (strcmp(id, engine_ubsec_id) != 0))
1031 return 0;
1032 if(!bind_helper(e))
1033 return 0;
1034 return 1;
1035 }
1036IMPLEMENT_DYNAMIC_CHECK_FN()
1037IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
1038#endif /* ENGINE_DYNAMIC_SUPPORT */
1039
1040#endif /* !OPENSSL_NO_HW_UBSEC */
1041#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 @@
1/* hw_ubsec_err.c */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include "hw_ubsec_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA UBSEC_str_functs[]=
68 {
69{ERR_PACK(0,UBSEC_F_UBSEC_CTRL,0), "UBSEC_CTRL"},
70{ERR_PACK(0,UBSEC_F_UBSEC_DH_COMPUTE_KEY,0), "UBSEC_DH_COMPUTE_KEY"},
71{ERR_PACK(0,UBSEC_F_UBSEC_DSA_SIGN,0), "UBSEC_DSA_SIGN"},
72{ERR_PACK(0,UBSEC_F_UBSEC_DSA_VERIFY,0), "UBSEC_DSA_VERIFY"},
73{ERR_PACK(0,UBSEC_F_UBSEC_FINISH,0), "UBSEC_FINISH"},
74{ERR_PACK(0,UBSEC_F_UBSEC_INIT,0), "UBSEC_INIT"},
75{ERR_PACK(0,UBSEC_F_UBSEC_MOD_EXP,0), "UBSEC_MOD_EXP"},
76{ERR_PACK(0,UBSEC_F_UBSEC_RNG_BYTES,0), "UBSEC_RNG_BYTES"},
77{ERR_PACK(0,UBSEC_F_UBSEC_RSA_MOD_EXP,0), "UBSEC_RSA_MOD_EXP"},
78{ERR_PACK(0,UBSEC_F_UBSEC_RSA_MOD_EXP_CRT,0), "UBSEC_RSA_MOD_EXP_CRT"},
79{0,NULL}
80 };
81
82static ERR_STRING_DATA UBSEC_str_reasons[]=
83 {
84{UBSEC_R_ALREADY_LOADED ,"already loaded"},
85{UBSEC_R_BN_EXPAND_FAIL ,"bn expand fail"},
86{UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
87{UBSEC_R_DSO_FAILURE ,"dso failure"},
88{UBSEC_R_MISSING_KEY_COMPONENTS ,"missing key components"},
89{UBSEC_R_NOT_LOADED ,"not loaded"},
90{UBSEC_R_REQUEST_FAILED ,"request failed"},
91{UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"},
92{UBSEC_R_UNIT_FAILURE ,"unit failure"},
93{0,NULL}
94 };
95
96#endif
97
98#ifdef UBSEC_LIB_NAME
99static ERR_STRING_DATA UBSEC_lib_name[]=
100 {
101{0 ,UBSEC_LIB_NAME},
102{0,NULL}
103 };
104#endif
105
106
107static int UBSEC_lib_error_code=0;
108static int UBSEC_error_init=1;
109
110static void ERR_load_UBSEC_strings(void)
111 {
112 if (UBSEC_lib_error_code == 0)
113 UBSEC_lib_error_code=ERR_get_next_error_library();
114
115 if (UBSEC_error_init)
116 {
117 UBSEC_error_init=0;
118#ifndef OPENSSL_NO_ERR
119 ERR_load_strings(UBSEC_lib_error_code,UBSEC_str_functs);
120 ERR_load_strings(UBSEC_lib_error_code,UBSEC_str_reasons);
121#endif
122
123#ifdef UBSEC_LIB_NAME
124 UBSEC_lib_name->error = ERR_PACK(UBSEC_lib_error_code,0,0);
125 ERR_load_strings(0,UBSEC_lib_name);
126#endif
127 }
128 }
129
130static void ERR_unload_UBSEC_strings(void)
131 {
132 if (UBSEC_error_init == 0)
133 {
134#ifndef OPENSSL_NO_ERR
135 ERR_unload_strings(UBSEC_lib_error_code,UBSEC_str_functs);
136 ERR_unload_strings(UBSEC_lib_error_code,UBSEC_str_reasons);
137#endif
138
139#ifdef UBSEC_LIB_NAME
140 ERR_unload_strings(0,UBSEC_lib_name);
141#endif
142 UBSEC_error_init=1;
143 }
144 }
145
146static void ERR_UBSEC_error(int function, int reason, char *file, int line)
147 {
148 if (UBSEC_lib_error_code == 0)
149 UBSEC_lib_error_code=ERR_get_next_error_library();
150 ERR_PUT_error(UBSEC_lib_error_code,function,reason,file,line);
151 }
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 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#ifndef HEADER_UBSEC_ERR_H
56#define HEADER_UBSEC_ERR_H
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_UBSEC_strings(void);
63static void ERR_unload_UBSEC_strings(void);
64static void ERR_UBSEC_error(int function, int reason, char *file, int line);
65#define UBSECerr(f,r) ERR_UBSEC_error((f),(r),__FILE__,__LINE__)
66
67/* Error codes for the UBSEC functions. */
68
69/* Function codes. */
70#define UBSEC_F_UBSEC_CTRL 100
71#define UBSEC_F_UBSEC_DH_COMPUTE_KEY 101
72#define UBSEC_F_UBSEC_DSA_SIGN 102
73#define UBSEC_F_UBSEC_DSA_VERIFY 103
74#define UBSEC_F_UBSEC_FINISH 104
75#define UBSEC_F_UBSEC_INIT 105
76#define UBSEC_F_UBSEC_MOD_EXP 106
77#define UBSEC_F_UBSEC_RNG_BYTES 107
78#define UBSEC_F_UBSEC_RSA_MOD_EXP 108
79#define UBSEC_F_UBSEC_RSA_MOD_EXP_CRT 109
80
81/* Reason codes. */
82#define UBSEC_R_ALREADY_LOADED 100
83#define UBSEC_R_BN_EXPAND_FAIL 101
84#define UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED 102
85#define UBSEC_R_DSO_FAILURE 103
86#define UBSEC_R_MISSING_KEY_COMPONENTS 104
87#define UBSEC_R_NOT_LOADED 105
88#define UBSEC_R_REQUEST_FAILED 106
89#define UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL 107
90#define UBSEC_R_UNIT_FAILURE 108
91
92#ifdef __cplusplus
93}
94#endif
95#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 @@
1/* ====================================================================
2 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h"
58
59/* If this symbol is defined then ENGINE_get_cipher_engine(), the function that
60 * is used by EVP to hook in cipher code and cache defaults (etc), will display
61 * brief debugging summaries to stderr with the 'nid'. */
62/* #define ENGINE_CIPHER_DEBUG */
63
64static ENGINE_TABLE *cipher_table = NULL;
65
66void ENGINE_unregister_ciphers(ENGINE *e)
67 {
68 engine_table_unregister(&cipher_table, e);
69 }
70
71static void engine_unregister_all_ciphers(void)
72 {
73 engine_table_cleanup(&cipher_table);
74 }
75
76int ENGINE_register_ciphers(ENGINE *e)
77 {
78 if(e->ciphers)
79 {
80 const int *nids;
81 int num_nids = e->ciphers(e, NULL, &nids, 0);
82 if(num_nids > 0)
83 return engine_table_register(&cipher_table,
84 &engine_unregister_all_ciphers, e, nids,
85 num_nids, 0);
86 }
87 return 1;
88 }
89
90void ENGINE_register_all_ciphers()
91 {
92 ENGINE *e;
93
94 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
95 ENGINE_register_ciphers(e);
96 }
97
98int ENGINE_set_default_ciphers(ENGINE *e)
99 {
100 if(e->ciphers)
101 {
102 const int *nids;
103 int num_nids = e->ciphers(e, NULL, &nids, 0);
104 if(num_nids > 0)
105 return engine_table_register(&cipher_table,
106 &engine_unregister_all_ciphers, e, nids,
107 num_nids, 1);
108 }
109 return 1;
110 }
111
112/* Exposed API function to get a functional reference from the implementation
113 * table (ie. try to get a functional reference from the tabled structural
114 * references) for a given cipher 'nid' */
115ENGINE *ENGINE_get_cipher_engine(int nid)
116 {
117 return engine_table_select(&cipher_table, nid);
118 }
119
120/* Obtains a cipher implementation from an ENGINE functional reference */
121const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid)
122 {
123 const EVP_CIPHER *ret;
124 ENGINE_CIPHERS_PTR fn = ENGINE_get_ciphers(e);
125 if(!fn || !fn(e, &ret, NULL, nid))
126 {
127 ENGINEerr(ENGINE_F_ENGINE_GET_CIPHER,
128 ENGINE_R_UNIMPLEMENTED_CIPHER);
129 return NULL;
130 }
131 return ret;
132 }
133
134/* Gets the cipher callback from an ENGINE structure */
135ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e)
136 {
137 return e->ciphers;
138 }
139
140/* Sets the cipher callback in an ENGINE structure */
141int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f)
142 {
143 e->ciphers = f;
144 return 1;
145 }
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 @@
1/* ====================================================================
2 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h"
58
59/* If this symbol is defined then ENGINE_get_default_DH(), the function that is
60 * used by DH to hook in implementation code and cache defaults (etc), will
61 * display brief debugging summaries to stderr with the 'nid'. */
62/* #define ENGINE_DH_DEBUG */
63
64static ENGINE_TABLE *dh_table = NULL;
65static const int dummy_nid = 1;
66
67void ENGINE_unregister_DH(ENGINE *e)
68 {
69 engine_table_unregister(&dh_table, e);
70 }
71
72static void engine_unregister_all_DH(void)
73 {
74 engine_table_cleanup(&dh_table);
75 }
76
77int ENGINE_register_DH(ENGINE *e)
78 {
79 if(e->dh_meth)
80 return engine_table_register(&dh_table,
81 &engine_unregister_all_DH, e, &dummy_nid, 1, 0);
82 return 1;
83 }
84
85void ENGINE_register_all_DH()
86 {
87 ENGINE *e;
88
89 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
90 ENGINE_register_DH(e);
91 }
92
93int ENGINE_set_default_DH(ENGINE *e)
94 {
95 if(e->dh_meth)
96 return engine_table_register(&dh_table,
97 &engine_unregister_all_DH, e, &dummy_nid, 1, 1);
98 return 1;
99 }
100
101/* Exposed API function to get a functional reference from the implementation
102 * table (ie. try to get a functional reference from the tabled structural
103 * references). */
104ENGINE *ENGINE_get_default_DH(void)
105 {
106 return engine_table_select(&dh_table, dummy_nid);
107 }
108
109/* Obtains an DH implementation from an ENGINE functional reference */
110const DH_METHOD *ENGINE_get_DH(const ENGINE *e)
111 {
112 return e->dh_meth;
113 }
114
115/* Sets an DH implementation in an ENGINE structure */
116int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth)
117 {
118 e->dh_meth = dh_meth;
119 return 1;
120 }
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 @@
1/* ====================================================================
2 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h"
58
59/* If this symbol is defined then ENGINE_get_digest_engine(), the function that
60 * is used by EVP to hook in digest code and cache defaults (etc), will display
61 * brief debugging summaries to stderr with the 'nid'. */
62/* #define ENGINE_DIGEST_DEBUG */
63
64static ENGINE_TABLE *digest_table = NULL;
65
66void ENGINE_unregister_digests(ENGINE *e)
67 {
68 engine_table_unregister(&digest_table, e);
69 }
70
71static void engine_unregister_all_digests(void)
72 {
73 engine_table_cleanup(&digest_table);
74 }
75
76int ENGINE_register_digests(ENGINE *e)
77 {
78 if(e->digests)
79 {
80 const int *nids;
81 int num_nids = e->digests(e, NULL, &nids, 0);
82 if(num_nids > 0)
83 return engine_table_register(&digest_table,
84 &engine_unregister_all_digests, e, nids,
85 num_nids, 0);
86 }
87 return 1;
88 }
89
90void ENGINE_register_all_digests()
91 {
92 ENGINE *e;
93
94 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
95 ENGINE_register_digests(e);
96 }
97
98int ENGINE_set_default_digests(ENGINE *e)
99 {
100 if(e->digests)
101 {
102 const int *nids;
103 int num_nids = e->digests(e, NULL, &nids, 0);
104 if(num_nids > 0)
105 return engine_table_register(&digest_table,
106 &engine_unregister_all_digests, e, nids,
107 num_nids, 1);
108 }
109 return 1;
110 }
111
112/* Exposed API function to get a functional reference from the implementation
113 * table (ie. try to get a functional reference from the tabled structural
114 * references) for a given digest 'nid' */
115ENGINE *ENGINE_get_digest_engine(int nid)
116 {
117 return engine_table_select(&digest_table, nid);
118 }
119
120/* Obtains a digest implementation from an ENGINE functional reference */
121const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid)
122 {
123 const EVP_MD *ret;
124 ENGINE_DIGESTS_PTR fn = ENGINE_get_digests(e);
125 if(!fn || !fn(e, &ret, NULL, nid))
126 {
127 ENGINEerr(ENGINE_F_ENGINE_GET_DIGEST,
128 ENGINE_R_UNIMPLEMENTED_DIGEST);
129 return NULL;
130 }
131 return ret;
132 }
133
134/* Gets the digest callback from an ENGINE structure */
135ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e)
136 {
137 return e->digests;
138 }
139
140/* Sets the digest callback in an ENGINE structure */
141int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f)
142 {
143 e->digests = f;
144 return 1;
145 }
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 @@
1/* ====================================================================
2 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h"
58
59/* If this symbol is defined then ENGINE_get_default_DSA(), the function that is
60 * used by DSA to hook in implementation code and cache defaults (etc), will
61 * display brief debugging summaries to stderr with the 'nid'. */
62/* #define ENGINE_DSA_DEBUG */
63
64static ENGINE_TABLE *dsa_table = NULL;
65static const int dummy_nid = 1;
66
67void ENGINE_unregister_DSA(ENGINE *e)
68 {
69 engine_table_unregister(&dsa_table, e);
70 }
71
72static void engine_unregister_all_DSA(void)
73 {
74 engine_table_cleanup(&dsa_table);
75 }
76
77int ENGINE_register_DSA(ENGINE *e)
78 {
79 if(e->dsa_meth)
80 return engine_table_register(&dsa_table,
81 &engine_unregister_all_DSA, e, &dummy_nid, 1, 0);
82 return 1;
83 }
84
85void ENGINE_register_all_DSA()
86 {
87 ENGINE *e;
88
89 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
90 ENGINE_register_DSA(e);
91 }
92
93int ENGINE_set_default_DSA(ENGINE *e)
94 {
95 if(e->dsa_meth)
96 return engine_table_register(&dsa_table,
97 &engine_unregister_all_DSA, e, &dummy_nid, 1, 0);
98 return 1;
99 }
100
101/* Exposed API function to get a functional reference from the implementation
102 * table (ie. try to get a functional reference from the tabled structural
103 * references). */
104ENGINE *ENGINE_get_default_DSA(void)
105 {
106 return engine_table_select(&dsa_table, dummy_nid);
107 }
108
109/* Obtains an DSA implementation from an ENGINE functional reference */
110const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e)
111 {
112 return e->dsa_meth;
113 }
114
115/* Sets an DSA implementation in an ENGINE structure */
116int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth)
117 {
118 e->dsa_meth = dsa_meth;
119 return 1;
120 }
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 @@
1/* ====================================================================
2 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h"
58
59/* If this symbol is defined then ENGINE_get_default_RAND(), the function that is
60 * used by RAND to hook in implementation code and cache defaults (etc), will
61 * display brief debugging summaries to stderr with the 'nid'. */
62/* #define ENGINE_RAND_DEBUG */
63
64static ENGINE_TABLE *rand_table = NULL;
65static const int dummy_nid = 1;
66
67void ENGINE_unregister_RAND(ENGINE *e)
68 {
69 engine_table_unregister(&rand_table, e);
70 }
71
72static void engine_unregister_all_RAND(void)
73 {
74 engine_table_cleanup(&rand_table);
75 }
76
77int ENGINE_register_RAND(ENGINE *e)
78 {
79 if(e->rand_meth)
80 return engine_table_register(&rand_table,
81 &engine_unregister_all_RAND, e, &dummy_nid, 1, 0);
82 return 1;
83 }
84
85void ENGINE_register_all_RAND()
86 {
87 ENGINE *e;
88
89 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
90 ENGINE_register_RAND(e);
91 }
92
93int ENGINE_set_default_RAND(ENGINE *e)
94 {
95 if(e->rand_meth)
96 return engine_table_register(&rand_table,
97 &engine_unregister_all_RAND, e, &dummy_nid, 1, 1);
98 return 1;
99 }
100
101/* Exposed API function to get a functional reference from the implementation
102 * table (ie. try to get a functional reference from the tabled structural
103 * references). */
104ENGINE *ENGINE_get_default_RAND(void)
105 {
106 return engine_table_select(&rand_table, dummy_nid);
107 }
108
109/* Obtains an RAND implementation from an ENGINE functional reference */
110const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e)
111 {
112 return e->rand_meth;
113 }
114
115/* Sets an RAND implementation in an ENGINE structure */
116int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth)
117 {
118 e->rand_meth = rand_meth;
119 return 1;
120 }
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 @@
1/* ====================================================================
2 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h"
58
59/* If this symbol is defined then ENGINE_get_default_RSA(), the function that is
60 * used by RSA to hook in implementation code and cache defaults (etc), will
61 * display brief debugging summaries to stderr with the 'nid'. */
62/* #define ENGINE_RSA_DEBUG */
63
64static ENGINE_TABLE *rsa_table = NULL;
65static const int dummy_nid = 1;
66
67void ENGINE_unregister_RSA(ENGINE *e)
68 {
69 engine_table_unregister(&rsa_table, e);
70 }
71
72static void engine_unregister_all_RSA(void)
73 {
74 engine_table_cleanup(&rsa_table);
75 }
76
77int ENGINE_register_RSA(ENGINE *e)
78 {
79 if(e->rsa_meth)
80 return engine_table_register(&rsa_table,
81 &engine_unregister_all_RSA, e, &dummy_nid, 1, 0);
82 return 1;
83 }
84
85void ENGINE_register_all_RSA()
86 {
87 ENGINE *e;
88
89 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
90 ENGINE_register_RSA(e);
91 }
92
93int ENGINE_set_default_RSA(ENGINE *e)
94 {
95 if(e->rsa_meth)
96 return engine_table_register(&rsa_table,
97 &engine_unregister_all_RSA, e, &dummy_nid, 1, 1);
98 return 1;
99 }
100
101/* Exposed API function to get a functional reference from the implementation
102 * table (ie. try to get a functional reference from the tabled structural
103 * references). */
104ENGINE *ENGINE_get_default_RSA(void)
105 {
106 return engine_table_select(&rsa_table, dummy_nid);
107 }
108
109/* Obtains an RSA implementation from an ENGINE functional reference */
110const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e)
111 {
112 return e->rsa_meth;
113 }
114
115/* Sets an RSA implementation in an ENGINE structure */
116int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth)
117 {
118 e->rsa_meth = rsa_meth;
119 return 1;
120 }
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 @@
1/* This header declares the necessary definitions for using the exponentiation
2 * acceleration capabilities, and rnd number generation of the AEP card.
3 *
4 */
5
6/*
7 *
8 * Some AEP defines
9 *
10 */
11
12/*Successful return value*/
13#define AEP_R_OK 0x00000000
14
15/*Miscelleanous unsuccessful return value*/
16#define AEP_R_GENERAL_ERROR 0x10000001
17
18/*Insufficient host memory*/
19#define AEP_R_HOST_MEMORY 0x10000002
20
21#define AEP_R_FUNCTION_FAILED 0x10000006
22
23/*Invalid arguments in function call*/
24#define AEP_R_ARGUMENTS_BAD 0x10020000
25
26#define AEP_R_NO_TARGET_RESOURCES 0x10030000
27
28/*Error occuring on socket operation*/
29#define AEP_R_SOCKERROR 0x10000010
30
31/*Socket has been closed from the other end*/
32#define AEP_R_SOCKEOF 0x10000011
33
34/*Invalid handles*/
35#define AEP_R_CONNECTION_HANDLE_INVALID 0x100000B3
36
37#define AEP_R_TRANSACTION_HANDLE_INVALID 0x10040000
38
39/*Transaction has not yet returned from accelerator*/
40#define AEP_R_TRANSACTION_NOT_READY 0x00010000
41
42/*There is already a thread waiting on this transaction*/
43#define AEP_R_TRANSACTION_CLAIMED 0x10050000
44
45/*The transaction timed out*/
46#define AEP_R_TIMED_OUT 0x10060000
47
48#define AEP_R_FXN_NOT_IMPLEMENTED 0x10070000
49
50#define AEP_R_TARGET_ERROR 0x10080000
51
52/*Error in the AEP daemon process*/
53#define AEP_R_DAEMON_ERROR 0x10090000
54
55/*Invalid ctx id*/
56#define AEP_R_INVALID_CTX_ID 0x10009000
57
58#define AEP_R_NO_KEY_MANAGER 0x1000a000
59
60/*Error obtaining a mutex*/
61#define AEP_R_MUTEX_BAD 0x000001A0
62
63/*Fxn call before AEP_Initialise ot after AEP_Finialise*/
64#define AEP_R_AEPAPI_NOT_INITIALIZED 0x10000190
65
66/*AEP_Initialise has already been called*/
67#define AEP_R_AEPAPI_ALREADY_INITIALIZED 0x10000191
68
69/*Maximum number of connections to daemon reached*/
70#define AEP_R_NO_MORE_CONNECTION_HNDLS 0x10000200
71
72/*
73 *
74 * Some AEP Type definitions
75 *
76 */
77
78/* an unsigned 8-bit value */
79typedef unsigned char AEP_U8;
80
81/* an unsigned 8-bit character */
82typedef char AEP_CHAR;
83
84/* a BYTE-sized Boolean flag */
85typedef AEP_U8 AEP_BBOOL;
86
87/*Unsigned value, at least 16 bits long*/
88typedef unsigned short AEP_U16;
89
90/* an unsigned value, at least 32 bits long */
91#ifdef SIXTY_FOUR_BIT_LONG
92typedef unsigned int AEP_U32;
93#else
94typedef unsigned long AEP_U32;
95#endif
96
97#ifdef SIXTY_FOUR_BIT_LONG
98typedef unsigned long AEP_U64;
99#else
100typedef struct { unsigned long l1, l2; } AEP_U64;
101#endif
102
103/* at least 32 bits; each bit is a Boolean flag */
104typedef AEP_U32 AEP_FLAGS;
105
106typedef AEP_U8 *AEP_U8_PTR;
107typedef AEP_CHAR *AEP_CHAR_PTR;
108typedef AEP_U32 *AEP_U32_PTR;
109typedef AEP_U64 *AEP_U64_PTR;
110typedef void *AEP_VOID_PTR;
111
112/* Pointer to a AEP_VOID_PTR-- i.e., pointer to pointer to void */
113typedef AEP_VOID_PTR *AEP_VOID_PTR_PTR;
114
115/*Used to identify an AEP connection handle*/
116typedef AEP_U32 AEP_CONNECTION_HNDL;
117
118/*Pointer to an AEP connection handle*/
119typedef AEP_CONNECTION_HNDL *AEP_CONNECTION_HNDL_PTR;
120
121/*Used by an application (in conjunction with the apps process id) to
122identify an individual transaction*/
123typedef AEP_U32 AEP_TRANSACTION_ID;
124
125/*Pointer to an applications transaction identifier*/
126typedef AEP_TRANSACTION_ID *AEP_TRANSACTION_ID_PTR;
127
128/*Return value type*/
129typedef AEP_U32 AEP_RV;
130
131#define MAX_PROCESS_CONNECTIONS 256
132
133#define RAND_BLK_SIZE 1024
134
135typedef enum{
136 NotConnected= 0,
137 Connected= 1,
138 InUse= 2
139} AEP_CONNECTION_STATE;
140
141
142typedef struct AEP_CONNECTION_ENTRY{
143 AEP_CONNECTION_STATE conn_state;
144 AEP_CONNECTION_HNDL conn_hndl;
145} AEP_CONNECTION_ENTRY;
146
147
148typedef AEP_RV t_AEP_OpenConnection(AEP_CONNECTION_HNDL_PTR phConnection);
149typedef AEP_RV t_AEP_CloseConnection(AEP_CONNECTION_HNDL hConnection);
150
151typedef AEP_RV t_AEP_ModExp(AEP_CONNECTION_HNDL hConnection,
152 AEP_VOID_PTR pA, AEP_VOID_PTR pP,
153 AEP_VOID_PTR pN,
154 AEP_VOID_PTR pResult,
155 AEP_TRANSACTION_ID* pidTransID);
156
157typedef AEP_RV t_AEP_ModExpCrt(AEP_CONNECTION_HNDL hConnection,
158 AEP_VOID_PTR pA, AEP_VOID_PTR pP,
159 AEP_VOID_PTR pQ,
160 AEP_VOID_PTR pDmp1, AEP_VOID_PTR pDmq1,
161 AEP_VOID_PTR pIqmp,
162 AEP_VOID_PTR pResult,
163 AEP_TRANSACTION_ID* pidTransID);
164
165#ifdef AEPRAND
166typedef AEP_RV t_AEP_GenRandom(AEP_CONNECTION_HNDL hConnection,
167 AEP_U32 Len,
168 AEP_U32 Type,
169 AEP_VOID_PTR pResult,
170 AEP_TRANSACTION_ID* pidTransID);
171#endif
172
173typedef AEP_RV t_AEP_Initialize(AEP_VOID_PTR pInitArgs);
174typedef AEP_RV t_AEP_Finalize();
175typedef AEP_RV t_AEP_SetBNCallBacks(AEP_RV (*GetBigNumSizeFunc)(),
176 AEP_RV (*MakeAEPBigNumFunc)(),
177 AEP_RV (*ConverAEPBigNumFunc)());
178
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,
46 unsigned char *input, 46 unsigned char *input,
47 unsigned int modulus_len); 47 unsigned int modulus_len);
48 48
49/* These are the static string constants for the DSO file name and the function
50 * symbol names to bind to. Regrettably, the DSO name on *nix appears to be
51 * "atasi.so" rather than something more consistent like "libatasi.so". At the
52 * time of writing, I'm not sure what the file name on win32 is but clearly
53 * native name translation is not possible (eg libatasi.so on *nix, and
54 * atasi.dll on win32). For the purposes of testing, I have created a symbollic
55 * link called "libatasi.so" so that we can use native name-translation - a
56 * better solution will be needed. */
57static const char *ATALLA_LIBNAME = "atasi";
58static const char *ATALLA_F1 = "ASI_GetHardwareConfig";
59static const char *ATALLA_F2 = "ASI_RSAPrivateKeyOpFn";
60static const char *ATALLA_F3 = "ASI_GetPerformanceStatistics";
61
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;
32typedef unsigned long SW_U32; /* 32 bit integer */ 32typedef unsigned long SW_U32; /* 32 bit integer */
33#endif 33#endif
34 34
35#if defined(WIN32) 35#if defined(OPENSSL_SYS_WIN32)
36 typedef struct _SW_U64 { 36 typedef struct _SW_U64 {
37 SW_U32 low32; 37 SW_U32 low32;
38 SW_U32 high32; 38 SW_U32 high32;
39 } SW_U64; /* 64 bit integer */ 39 } SW_U64; /* 64 bit integer */
40#elif defined(MAC) 40#elif defined(OPENSSL_SYS_MACINTOSH_CLASSIC)
41 typedef longlong SW_U64 41 typedef longlong SW_U64
42#else /* Unix variants */ 42#else /* Unix variants */
43 typedef struct _SW_U64 { 43 typedef struct _SW_U64 {
@@ -156,6 +156,27 @@ typedef struct _SW_LARGENUMBER {
156 /* bytes in network (big endian) order */ 156 /* bytes in network (big endian) order */
157} SW_LARGENUMBER; 157} SW_LARGENUMBER;
158 158
159#if defined(OPENSSL_SYS_WIN32)
160 #include <windows.h>
161 typedef HANDLE SW_OSHANDLE; /* handle to kernel object */
162 #define SW_OS_INVALID_HANDLE INVALID_HANDLE_VALUE
163 #define SW_CALLCONV _stdcall
164#elif defined(OPENSSL_SYS_MACINTOSH_CLASSIC)
165 /* async callback mechanisms */
166 /* swiftCallbackLevel */
167 #define SW_MAC_CALLBACK_LEVEL_NO 0
168 #define SW_MAC_CALLBACK_LEVEL_HARDWARE 1 /* from the hardware ISR */
169 #define SW_MAC_CALLBACK_LEVEL_SECONDARY 2 /* as secondary ISR */
170 typedef int SW_MAC_CALLBACK_LEVEL;
171 typedef int SW_OSHANDLE;
172 #define SW_OS_INVALID_HANDLE (-1)
173 #define SW_CALLCONV
174#else /* Unix variants */
175 typedef int SW_OSHANDLE; /* handle to driver */
176 #define SW_OS_INVALID_HANDLE (-1)
177 #define SW_CALLCONV
178#endif
179
159typedef struct _SW_CRT { 180typedef struct _SW_CRT {
160 SW_LARGENUMBER p; /* prime number p */ 181 SW_LARGENUMBER p; /* prime number p */
161 SW_LARGENUMBER q; /* prime number q */ 182 SW_LARGENUMBER q; /* prime number q */
@@ -196,16 +217,16 @@ typedef SW_U32 SW_CONTEXT_HANDLE; /* opaque context handle */
196 217
197/* Now the OpenSSL bits, these function types are the for the function 218/* Now the OpenSSL bits, these function types are the for the function
198 * pointers that will bound into the Rainbow shared libraries. */ 219 * pointers that will bound into the Rainbow shared libraries. */
199typedef SW_STATUS t_swAcquireAccContext(SW_CONTEXT_HANDLE *hac); 220typedef SW_STATUS SW_CALLCONV t_swAcquireAccContext(SW_CONTEXT_HANDLE *hac);
200typedef SW_STATUS t_swAttachKeyParam(SW_CONTEXT_HANDLE hac, 221typedef SW_STATUS SW_CALLCONV t_swAttachKeyParam(SW_CONTEXT_HANDLE hac,
201 SW_PARAM *key_params); 222 SW_PARAM *key_params);
202typedef SW_STATUS t_swSimpleRequest(SW_CONTEXT_HANDLE hac, 223typedef SW_STATUS SW_CALLCONV t_swSimpleRequest(SW_CONTEXT_HANDLE hac,
203 SW_COMMAND_CODE cmd, 224 SW_COMMAND_CODE cmd,
204 SW_LARGENUMBER pin[], 225 SW_LARGENUMBER pin[],
205 SW_U32 pin_count, 226 SW_U32 pin_count,
206 SW_LARGENUMBER pout[], 227 SW_LARGENUMBER pout[],
207 SW_U32 pout_count); 228 SW_U32 pout_count);
208typedef SW_STATUS t_swReleaseAccContext(SW_CONTEXT_HANDLE hac); 229typedef SW_STATUS SW_CALLCONV t_swReleaseAccContext(SW_CONTEXT_HANDLE hac);
209 230
210#ifdef __cplusplus 231#ifdef __cplusplus
211} 232}
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 @@
1/**********************************************************************/
2/* */
3/* Prototypes of the CCA verbs used by the 4758 CCA openssl driver */
4/* */
5/* Maurice Gittens <maurice@gittens.nl> */
6/* */
7/**********************************************************************/
8
9#ifndef __HW_4758_CCA__
10#define __HW_4758_CCA__
11
12/*
13 * Only WIN32 support for now
14 */
15#if defined(WIN32)
16
17 #define CCA_LIB_NAME "CSUNSAPI"
18
19 #define CSNDPKX "CSNDPKX_32"
20 #define CSNDKRR "CSNDKRR_32"
21 #define CSNDPKE "CSNDPKE_32"
22 #define CSNDPKD "CSNDPKD_32"
23 #define CSNDDSV "CSNDDSV_32"
24 #define CSNDDSG "CSNDDSG_32"
25 #define CSNBRNG "CSNBRNG_32"
26
27 #define SECURITYAPI __stdcall
28#else
29 /* Fixme!!
30 Find out the values of these constants for other platforms.
31 */
32 #define CCA_LIB_NAME "CSUNSAPI"
33
34 #define CSNDPKX "CSNDPKX"
35 #define CSNDKRR "CSNDKRR"
36 #define CSNDPKE "CSNDPKE"
37 #define CSNDPKD "CSNDPKD"
38 #define CSNDDSV "CSNDDSV"
39 #define CSNDDSG "CSNDDSG"
40 #define CSNBRNG "CSNBRNG"
41
42 #define SECURITYAPI
43#endif
44
45/*
46 * security API prototypes
47 */
48
49/* PKA Key Record Read */
50typedef void (SECURITYAPI *F_KEYRECORDREAD)
51 (long * return_code,
52 long * reason_code,
53 long * exit_data_length,
54 unsigned char * exit_data,
55 long * rule_array_count,
56 unsigned char * rule_array,
57 unsigned char * key_label,
58 long * key_token_length,
59 unsigned char * key_token);
60
61/* Random Number Generate */
62typedef void (SECURITYAPI *F_RANDOMNUMBERGENERATE)
63 (long * return_code,
64 long * reason_code,
65 long * exit_data_length,
66 unsigned char * exit_data,
67 unsigned char * form,
68 unsigned char * random_number);
69
70/* Digital Signature Generate */
71typedef void (SECURITYAPI *F_DIGITALSIGNATUREGENERATE)
72 (long * return_code,
73 long * reason_code,
74 long * exit_data_length,
75 unsigned char * exit_data,
76 long * rule_array_count,
77 unsigned char * rule_array,
78 long * PKA_private_key_id_length,
79 unsigned char * PKA_private_key_id,
80 long * hash_length,
81 unsigned char * hash,
82 long * signature_field_length,
83 long * signature_bit_length,
84 unsigned char * signature_field);
85
86/* Digital Signature Verify */
87typedef void (SECURITYAPI *F_DIGITALSIGNATUREVERIFY)(
88 long * return_code,
89 long * reason_code,
90 long * exit_data_length,
91 unsigned char * exit_data,
92 long * rule_array_count,
93 unsigned char * rule_array,
94 long * PKA_public_key_id_length,
95 unsigned char * PKA_public_key_id,
96 long * hash_length,
97 unsigned char * hash,
98 long * signature_field_length,
99 unsigned char * signature_field);
100
101/* PKA Public Key Extract */
102typedef void (SECURITYAPI *F_PUBLICKEYEXTRACT)(
103 long * return_code,
104 long * reason_code,
105 long * exit_data_length,
106 unsigned char * exit_data,
107 long * rule_array_count,
108 unsigned char * rule_array,
109 long * source_key_identifier_length,
110 unsigned char * source_key_identifier,
111 long * target_key_token_length,
112 unsigned char * target_key_token);
113
114/* PKA Encrypt */
115typedef void (SECURITYAPI *F_PKAENCRYPT)
116 (long * return_code,
117 long * reason_code,
118 long * exit_data_length,
119 unsigned char * exit_data,
120 long * rule_array_count,
121 unsigned char * rule_array,
122 long * key_value_length,
123 unsigned char * key_value,
124 long * data_struct_length,
125 unsigned char * data_struct,
126 long * RSA_public_key_length,
127 unsigned char * RSA_public_key,
128 long * RSA_encipher_length,
129 unsigned char * RSA_encipher );
130
131/* PKA Decrypt */
132typedef void (SECURITYAPI *F_PKADECRYPT)
133 (long * return_code,
134 long * reason_code,
135 long * exit_data_length,
136 unsigned char * exit_data,
137 long * rule_array_count,
138 unsigned char * rule_array,
139 long * enciphered_key_length,
140 unsigned char * enciphered_key,
141 long * data_struct_length,
142 unsigned char * data_struct,
143 long * RSA_private_key_length,
144 unsigned char * RSA_private_key,
145 long * key_value_length,
146 unsigned char * key_value );
147
148
149#endif