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.ssl556
-rw-r--r--src/lib/libcrypto/engine/README211
-rw-r--r--src/lib/libcrypto/engine/eng_all.c119
-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.c460
-rw-r--r--src/lib/libcrypto/engine/eng_err.c165
-rw-r--r--src/lib/libcrypto/engine/eng_fat.c147
-rw-r--r--src/lib/libcrypto/engine/eng_init.c157
-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.h717
-rw-r--r--src/lib/libcrypto/engine/hw_4758_cca.c6
-rw-r--r--src/lib/libcrypto/engine/hw_cryptodev.c505
-rw-r--r--src/lib/libcrypto/engine/hw_openbsd_dev_crypto.c594
-rw-r--r--src/lib/libcrypto/engine/hw_ubsec.c8
-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
26 files changed, 6629 insertions, 169 deletions
diff --git a/src/lib/libcrypto/engine/Makefile.ssl b/src/lib/libcrypto/engine/Makefile.ssl
new file mode 100644
index 0000000000..8bc8985e02
--- /dev/null
+++ b/src/lib/libcrypto/engine/Makefile.ssl
@@ -0,0 +1,556 @@
1#
2# OpenSSL/crypto/engine/Makefile
3#
4
5DIR= engine
6TOP= ../..
7CC= cc
8INCLUDES= -I.. -I$(TOP) -I../../include
9CFLAG=-g
10INSTALL_PREFIX=
11OPENSSLDIR= /usr/local/ssl
12INSTALLTOP=/usr/local/ssl
13MAKE= make -f Makefile.ssl
14MAKEDEPPROG= makedepend
15MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
16MAKEFILE= Makefile.ssl
17AR= ar r
18
19CFLAGS= $(INCLUDES) $(CFLAG)
20
21GENERAL=Makefile
22TEST= enginetest.c
23APPS=
24
25LIB=$(TOP)/libcrypto.a
26LIBSRC= eng_err.c eng_lib.c eng_list.c eng_init.c eng_ctrl.c \
27 eng_table.c eng_pkey.c eng_fat.c eng_all.c \
28 tb_rsa.c tb_dsa.c tb_dh.c tb_rand.c tb_cipher.c tb_digest.c \
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_cryptodev.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_cryptodev.o hw_aep.o hw_sureware.o hw_4758_cca.o
38
39SRC= $(LIBSRC)
40
41EXHEADER= engine.h
42HEADER= $(EXHEADER)
43
44ALL= $(GENERAL) $(SRC) $(HEADER)
45
46top:
47 (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
48
49all: lib
50
51lib: $(LIBOBJ)
52 $(AR) $(LIB) $(LIBOBJ)
53 $(RANLIB) $(LIB)
54 @touch lib
55
56files:
57 $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO
58
59links:
60 @sh $(TOP)/util/point.sh Makefile.ssl Makefile
61 @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
62 @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
63 @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
64
65install:
66 @for i in $(EXHEADER) ; \
67 do \
68 (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
69 chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
70 done;
71
72tags:
73 ctags $(SRC)
74
75errors:
76 $(PERL) $(TOP)/util/mkerr.pl -conf hw.ec \
77 -nostatic -staticloader -write hw_*.c
78
79tests:
80
81lint:
82 lint -DLINT $(INCLUDES) $(SRC)>fluff
83
84depend:
85 $(MAKEDEPEND) $(CFLAG) $(INCLUDES) $(DEPFLAG) $(PROGS) $(LIBSRC)
86
87dclean:
88 $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
89 mv -f Makefile.new $(MAKEFILE)
90
91clean:
92 rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
93
94# DO NOT DELETE THIS LINE -- make depend depends on it.
95
96eng_all.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
97eng_all.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
98eng_all.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
99eng_all.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
100eng_all.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
101eng_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
102eng_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
103eng_all.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
104eng_all.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
105eng_all.o: ../../include/openssl/ui.h eng_all.c eng_int.h
106eng_cnf.o: ../../e_os.h ../../include/openssl/asn1.h
107eng_cnf.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
108eng_cnf.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
109eng_cnf.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
110eng_cnf.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
111eng_cnf.o: ../../include/openssl/engine.h ../../include/openssl/err.h
112eng_cnf.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
113eng_cnf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
114eng_cnf.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
115eng_cnf.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
116eng_cnf.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
117eng_cnf.o: ../cryptlib.h eng_cnf.c
118eng_ctrl.o: ../../e_os.h ../../include/openssl/asn1.h
119eng_ctrl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
120eng_ctrl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
121eng_ctrl.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
122eng_ctrl.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
123eng_ctrl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
124eng_ctrl.o: ../../include/openssl/opensslconf.h
125eng_ctrl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
126eng_ctrl.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
127eng_ctrl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
128eng_ctrl.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
129eng_ctrl.o: ../cryptlib.h eng_ctrl.c eng_int.h
130eng_dyn.o: ../../e_os.h ../../include/openssl/asn1.h
131eng_dyn.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
132eng_dyn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
133eng_dyn.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
134eng_dyn.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
135eng_dyn.o: ../../include/openssl/engine.h ../../include/openssl/err.h
136eng_dyn.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
137eng_dyn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
138eng_dyn.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
139eng_dyn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
140eng_dyn.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
141eng_dyn.o: ../cryptlib.h eng_dyn.c eng_int.h
142eng_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
143eng_err.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
144eng_err.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
145eng_err.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
146eng_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
147eng_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
148eng_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
149eng_err.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
150eng_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
151eng_err.o: ../../include/openssl/ui.h eng_err.c
152eng_fat.o: ../../e_os.h ../../include/openssl/asn1.h
153eng_fat.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
154eng_fat.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
155eng_fat.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
156eng_fat.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
157eng_fat.o: ../../include/openssl/engine.h ../../include/openssl/err.h
158eng_fat.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
159eng_fat.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
160eng_fat.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
161eng_fat.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
162eng_fat.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
163eng_fat.o: ../cryptlib.h eng_fat.c eng_int.h
164eng_init.o: ../../e_os.h ../../include/openssl/asn1.h
165eng_init.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
166eng_init.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
167eng_init.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
168eng_init.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
169eng_init.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
170eng_init.o: ../../include/openssl/opensslconf.h
171eng_init.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
172eng_init.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
173eng_init.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
174eng_init.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.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/aes.h
200eng_openssl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
201eng_openssl.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
202eng_openssl.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
203eng_openssl.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
204eng_openssl.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
205eng_openssl.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
206eng_openssl.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
207eng_openssl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
208eng_openssl.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
209eng_openssl.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
210eng_openssl.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
211eng_openssl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
212eng_openssl.o: ../../include/openssl/opensslconf.h
213eng_openssl.o: ../../include/openssl/opensslv.h
214eng_openssl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
215eng_openssl.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
216eng_openssl.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
217eng_openssl.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
218eng_openssl.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
219eng_openssl.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
220eng_openssl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
221eng_openssl.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
222eng_openssl.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
223eng_openssl.o: ../cryptlib.h eng_openssl.c
224eng_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
225eng_pkey.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
226eng_pkey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
227eng_pkey.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
228eng_pkey.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
229eng_pkey.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
230eng_pkey.o: ../../include/openssl/opensslconf.h
231eng_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
232eng_pkey.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
233eng_pkey.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
234eng_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
235eng_pkey.o: ../cryptlib.h eng_int.h eng_pkey.c
236eng_table.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
237eng_table.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
238eng_table.o: ../../include/openssl/bn.h ../../include/openssl/cast.h
239eng_table.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
240eng_table.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
241eng_table.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
242eng_table.o: ../../include/openssl/engine.h ../../include/openssl/err.h
243eng_table.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
244eng_table.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
245eng_table.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
246eng_table.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
247eng_table.o: ../../include/openssl/objects.h
248eng_table.o: ../../include/openssl/opensslconf.h
249eng_table.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
250eng_table.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
251eng_table.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
252eng_table.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
253eng_table.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
254eng_table.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
255eng_table.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
256eng_table.o: eng_int.h eng_table.c
257hw_4758_cca.o: ../../e_os.h ../../include/openssl/aes.h
258hw_4758_cca.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
259hw_4758_cca.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
260hw_4758_cca.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
261hw_4758_cca.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
262hw_4758_cca.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
263hw_4758_cca.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
264hw_4758_cca.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
265hw_4758_cca.o: ../../include/openssl/err.h ../../include/openssl/evp.h
266hw_4758_cca.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
267hw_4758_cca.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
268hw_4758_cca.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
269hw_4758_cca.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
270hw_4758_cca.o: ../../include/openssl/opensslconf.h
271hw_4758_cca.o: ../../include/openssl/opensslv.h
272hw_4758_cca.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
273hw_4758_cca.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
274hw_4758_cca.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
275hw_4758_cca.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
276hw_4758_cca.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
277hw_4758_cca.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
278hw_4758_cca.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
279hw_4758_cca.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
280hw_4758_cca.o: ../cryptlib.h hw_4758_cca.c hw_4758_cca_err.c hw_4758_cca_err.h
281hw_4758_cca.o: vendor_defns/hw_4758_cca.h
282hw_aep.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
283hw_aep.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
284hw_aep.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
285hw_aep.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
286hw_aep.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
287hw_aep.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
288hw_aep.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
289hw_aep.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
290hw_aep.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
291hw_aep.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
292hw_aep.o: ../../include/openssl/ui.h hw_aep.c hw_aep_err.c hw_aep_err.h
293hw_aep.o: vendor_defns/aep.h
294hw_atalla.o: ../../e_os.h ../../include/openssl/asn1.h
295hw_atalla.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
296hw_atalla.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
297hw_atalla.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
298hw_atalla.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
299hw_atalla.o: ../../include/openssl/engine.h ../../include/openssl/err.h
300hw_atalla.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
301hw_atalla.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
302hw_atalla.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
303hw_atalla.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
304hw_atalla.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
305hw_atalla.o: ../cryptlib.h hw_atalla.c hw_atalla_err.c hw_atalla_err.h
306hw_atalla.o: vendor_defns/atalla.h
307hw_cswift.o: ../../e_os.h ../../include/openssl/asn1.h
308hw_cswift.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
309hw_cswift.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
310hw_cswift.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
311hw_cswift.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
312hw_cswift.o: ../../include/openssl/engine.h ../../include/openssl/err.h
313hw_cswift.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
314hw_cswift.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
315hw_cswift.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
316hw_cswift.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
317hw_cswift.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
318hw_cswift.o: ../cryptlib.h hw_cswift.c hw_cswift_err.c hw_cswift_err.h
319hw_cswift.o: vendor_defns/cswift.h
320hw_ncipher.o: ../../e_os.h ../../include/openssl/aes.h
321hw_ncipher.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
322hw_ncipher.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
323hw_ncipher.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
324hw_ncipher.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
325hw_ncipher.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
326hw_ncipher.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
327hw_ncipher.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
328hw_ncipher.o: ../../include/openssl/err.h ../../include/openssl/evp.h
329hw_ncipher.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
330hw_ncipher.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
331hw_ncipher.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
332hw_ncipher.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
333hw_ncipher.o: ../../include/openssl/opensslconf.h
334hw_ncipher.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
335hw_ncipher.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
336hw_ncipher.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
337hw_ncipher.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
338hw_ncipher.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
339hw_ncipher.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
340hw_ncipher.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
341hw_ncipher.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
342hw_ncipher.o: ../../include/openssl/ui_compat.h ../../include/openssl/x509.h
343hw_ncipher.o: ../../include/openssl/x509_vfy.h ../cryptlib.h hw_ncipher.c
344hw_ncipher.o: hw_ncipher_err.c hw_ncipher_err.h vendor_defns/hwcryptohook.h
345hw_nuron.o: ../../e_os.h ../../include/openssl/asn1.h
346hw_nuron.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
347hw_nuron.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
348hw_nuron.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
349hw_nuron.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
350hw_nuron.o: ../../include/openssl/engine.h ../../include/openssl/err.h
351hw_nuron.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
352hw_nuron.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
353hw_nuron.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
354hw_nuron.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
355hw_nuron.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
356hw_nuron.o: ../cryptlib.h hw_nuron.c hw_nuron_err.c hw_nuron_err.h
357hw_cryptodev.o: ../../include/openssl/aes.h
358hw_cryptodev.o: ../../include/openssl/asn1.h
359hw_cryptodev.o: ../../include/openssl/bio.h
360hw_cryptodev.o: ../../include/openssl/blowfish.h
361hw_cryptodev.o: ../../include/openssl/bn.h
362hw_cryptodev.o: ../../include/openssl/cast.h
363hw_cryptodev.o: ../../include/openssl/conf.h
364hw_cryptodev.o: ../../include/openssl/crypto.h
365hw_cryptodev.o: ../../include/openssl/des.h
366hw_cryptodev.o: ../../include/openssl/des_old.h
367hw_cryptodev.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
368hw_cryptodev.o: ../../include/openssl/e_os2.h
369hw_cryptodev.o: ../../include/openssl/engine.h
370hw_cryptodev.o: ../../include/openssl/err.h
371hw_cryptodev.o: ../../include/openssl/evp.h
372hw_cryptodev.o: ../../include/openssl/idea.h
373hw_cryptodev.o: ../../include/openssl/lhash.h
374hw_cryptodev.o: ../../include/openssl/md2.h
375hw_cryptodev.o: ../../include/openssl/md4.h
376hw_cryptodev.o: ../../include/openssl/md5.h
377hw_cryptodev.o: ../../include/openssl/mdc2.h
378hw_cryptodev.o: ../../include/openssl/obj_mac.h
379hw_cryptodev.o: ../../include/openssl/objects.h
380hw_cryptodev.o: ../../include/openssl/opensslconf.h
381hw_cryptodev.o: ../../include/openssl/opensslv.h
382hw_cryptodev.o: ../../include/openssl/ossl_typ.h
383hw_cryptodev.o: ../../include/openssl/rand.h
384hw_cryptodev.o: ../../include/openssl/rc2.h
385hw_cryptodev.o: ../../include/openssl/rc4.h
386hw_cryptodev.o: ../../include/openssl/rc5.h
387hw_cryptodev.o: ../../include/openssl/ripemd.h
388hw_cryptodev.o: ../../include/openssl/rsa.h
389hw_cryptodev.o: ../../include/openssl/safestack.h
390hw_cryptodev.o: ../../include/openssl/sha.h
391hw_cryptodev.o: ../../include/openssl/stack.h
392hw_cryptodev.o: ../../include/openssl/symhacks.h
393hw_cryptodev.o: ../../include/openssl/ui.h
394hw_cryptodev.o: ../../include/openssl/ui_compat.h ../evp/evp_locl.h
395hw_cryptodev.o: eng_int.h hw_cryptodev.c
396hw_sureware.o: ../../e_os.h ../../include/openssl/aes.h
397hw_sureware.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
398hw_sureware.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
399hw_sureware.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
400hw_sureware.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
401hw_sureware.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
402hw_sureware.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
403hw_sureware.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
404hw_sureware.o: ../../include/openssl/err.h ../../include/openssl/evp.h
405hw_sureware.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
406hw_sureware.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
407hw_sureware.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
408hw_sureware.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
409hw_sureware.o: ../../include/openssl/opensslconf.h
410hw_sureware.o: ../../include/openssl/opensslv.h
411hw_sureware.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
412hw_sureware.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
413hw_sureware.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
414hw_sureware.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
415hw_sureware.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
416hw_sureware.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
417hw_sureware.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
418hw_sureware.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
419hw_sureware.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
420hw_sureware.o: ../cryptlib.h eng_int.h engine.h hw_sureware.c hw_sureware_err.c
421hw_sureware.o: hw_sureware_err.h vendor_defns/sureware.h
422hw_ubsec.o: ../../e_os.h ../../include/openssl/asn1.h
423hw_ubsec.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
424hw_ubsec.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
425hw_ubsec.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
426hw_ubsec.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
427hw_ubsec.o: ../../include/openssl/engine.h ../../include/openssl/err.h
428hw_ubsec.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
429hw_ubsec.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
430hw_ubsec.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
431hw_ubsec.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
432hw_ubsec.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
433hw_ubsec.o: ../cryptlib.h hw_ubsec.c hw_ubsec_err.c hw_ubsec_err.h
434hw_ubsec.o: vendor_defns/hw_ubsec.h
435tb_cipher.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
436tb_cipher.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
437tb_cipher.o: ../../include/openssl/bn.h ../../include/openssl/cast.h
438tb_cipher.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
439tb_cipher.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
440tb_cipher.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
441tb_cipher.o: ../../include/openssl/engine.h ../../include/openssl/err.h
442tb_cipher.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
443tb_cipher.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
444tb_cipher.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
445tb_cipher.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
446tb_cipher.o: ../../include/openssl/objects.h
447tb_cipher.o: ../../include/openssl/opensslconf.h
448tb_cipher.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
449tb_cipher.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
450tb_cipher.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
451tb_cipher.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
452tb_cipher.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
453tb_cipher.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
454tb_cipher.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
455tb_cipher.o: eng_int.h tb_cipher.c
456tb_dh.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
457tb_dh.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
458tb_dh.o: ../../include/openssl/bn.h ../../include/openssl/cast.h
459tb_dh.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
460tb_dh.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
461tb_dh.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
462tb_dh.o: ../../include/openssl/engine.h ../../include/openssl/err.h
463tb_dh.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
464tb_dh.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
465tb_dh.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
466tb_dh.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
467tb_dh.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
468tb_dh.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
469tb_dh.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
470tb_dh.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
471tb_dh.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
472tb_dh.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
473tb_dh.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
474tb_dh.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h eng_int.h
475tb_dh.o: tb_dh.c
476tb_digest.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
477tb_digest.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
478tb_digest.o: ../../include/openssl/bn.h ../../include/openssl/cast.h
479tb_digest.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
480tb_digest.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
481tb_digest.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
482tb_digest.o: ../../include/openssl/engine.h ../../include/openssl/err.h
483tb_digest.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
484tb_digest.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
485tb_digest.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
486tb_digest.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
487tb_digest.o: ../../include/openssl/objects.h
488tb_digest.o: ../../include/openssl/opensslconf.h
489tb_digest.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
490tb_digest.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
491tb_digest.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
492tb_digest.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
493tb_digest.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
494tb_digest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
495tb_digest.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
496tb_digest.o: eng_int.h tb_digest.c
497tb_dsa.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
498tb_dsa.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
499tb_dsa.o: ../../include/openssl/bn.h ../../include/openssl/cast.h
500tb_dsa.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
501tb_dsa.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
502tb_dsa.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
503tb_dsa.o: ../../include/openssl/engine.h ../../include/openssl/err.h
504tb_dsa.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
505tb_dsa.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
506tb_dsa.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
507tb_dsa.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
508tb_dsa.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
509tb_dsa.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
510tb_dsa.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
511tb_dsa.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
512tb_dsa.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
513tb_dsa.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
514tb_dsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
515tb_dsa.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
516tb_dsa.o: eng_int.h tb_dsa.c
517tb_rand.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
518tb_rand.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
519tb_rand.o: ../../include/openssl/bn.h ../../include/openssl/cast.h
520tb_rand.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
521tb_rand.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
522tb_rand.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
523tb_rand.o: ../../include/openssl/engine.h ../../include/openssl/err.h
524tb_rand.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
525tb_rand.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
526tb_rand.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
527tb_rand.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
528tb_rand.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
529tb_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
530tb_rand.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
531tb_rand.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
532tb_rand.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
533tb_rand.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
534tb_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
535tb_rand.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
536tb_rand.o: eng_int.h tb_rand.c
537tb_rsa.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
538tb_rsa.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
539tb_rsa.o: ../../include/openssl/bn.h ../../include/openssl/cast.h
540tb_rsa.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
541tb_rsa.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
542tb_rsa.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
543tb_rsa.o: ../../include/openssl/engine.h ../../include/openssl/err.h
544tb_rsa.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
545tb_rsa.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
546tb_rsa.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
547tb_rsa.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
548tb_rsa.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
549tb_rsa.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
550tb_rsa.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
551tb_rsa.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
552tb_rsa.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
553tb_rsa.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
554tb_rsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
555tb_rsa.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
556tb_rsa.o: eng_int.h tb_rsa.c
diff --git a/src/lib/libcrypto/engine/README b/src/lib/libcrypto/engine/README
new file mode 100644
index 0000000000..6b69b70f57
--- /dev/null
+++ b/src/lib/libcrypto/engine/README
@@ -0,0 +1,211 @@
1Notes: 2001-09-24
2-----------------
3
4This "description" (if one chooses to call it that) needed some major updating
5so here goes. This update addresses a change being made at the same time to
6OpenSSL, and it pretty much completely restructures the underlying mechanics of
7the "ENGINE" code. So it serves a double purpose of being a "ENGINE internals
8for masochists" document *and* a rather extensive commit log message. (I'd get
9lynched for sticking all this in CHANGES or the commit mails :-).
10
11ENGINE_TABLE underlies this restructuring, as described in the internal header
12"eng_int.h", implemented in eng_table.c, and used in each of the "class" files;
13tb_rsa.c, tb_dsa.c, etc.
14
15However, "EVP_CIPHER" underlies the motivation and design of ENGINE_TABLE so
16I'll mention a bit about that first. EVP_CIPHER (and most of this applies
17equally to EVP_MD for digests) is both a "method" and a algorithm/mode
18identifier that, in the current API, "lingers". These cipher description +
19implementation structures can be defined or obtained directly by applications,
20or can be loaded "en masse" into EVP storage so that they can be catalogued and
21searched in various ways, ie. two ways of encrypting with the "des_cbc"
22algorithm/mode pair are;
23
24(i) directly;
25 const EVP_CIPHER *cipher = EVP_des_cbc();
26 EVP_EncryptInit(&ctx, cipher, key, iv);
27 [ ... use EVP_EncryptUpdate() and EVP_EncryptFinal() ...]
28
29(ii) indirectly;
30 OpenSSL_add_all_ciphers();
31 cipher = EVP_get_cipherbyname("des_cbc");
32 EVP_EncryptInit(&ctx, cipher, key, iv);
33 [ ... etc ... ]
34
35The latter is more generally used because it also allows ciphers/digests to be
36looked up based on other identifiers which can be useful for automatic cipher
37selection, eg. in SSL/TLS, or by user-controllable configuration.
38
39The important point about this is that EVP_CIPHER definitions and structures are
40passed around with impunity and there is no safe way, without requiring massive
41rewrites of many applications, to assume that EVP_CIPHERs can be reference
42counted. One an EVP_CIPHER is exposed to the caller, neither it nor anything it
43comes from can "safely" be destroyed. Unless of course the way of getting to
44such ciphers is via entirely distinct API calls that didn't exist before.
45However existing API usage cannot be made to understand when an EVP_CIPHER
46pointer, that has been passed to the caller, is no longer being used.
47
48The other problem with the existing API w.r.t. to hooking EVP_CIPHER support
49into ENGINE is storage - the OBJ_NAME-based storage used by EVP to register
50ciphers simultaneously registers cipher *types* and cipher *implementations* -
51they are effectively the same thing, an "EVP_CIPHER" pointer. The problem with
52hooking in ENGINEs is that multiple ENGINEs may implement the same ciphers. The
53solution is necessarily that ENGINE-provided ciphers simply are not registered,
54stored, or exposed to the caller in the same manner as existing ciphers. This is
55especially necessary considering the fact ENGINE uses reference counts to allow
56for cleanup, modularity, and DSO support - yet EVP_CIPHERs, as exposed to
57callers in the current API, support no such controls.
58
59Another sticking point for integrating cipher support into ENGINE is linkage.
60Already there is a problem with the way ENGINE supports RSA, DSA, etc whereby
61they are available *because* they're part of a giant ENGINE called "openssl".
62Ie. all implementations *have* to come from an ENGINE, but we get round that by
63having a giant ENGINE with all the software support encapsulated. This creates
64linker hassles if nothing else - linking a 1-line application that calls 2 basic
65RSA functions (eg. "RSA_free(RSA_new());") will result in large quantities of
66ENGINE code being linked in *and* because of that DSA, DH, and RAND also. If we
67continue with this approach for EVP_CIPHER support (even if it *was* possible)
68we would lose our ability to link selectively by selectively loading certain
69implementations of certain functionality. Touching any part of any kind of
70crypto would result in massive static linkage of everything else. So the
71solution is to change the way ENGINE feeds existing "classes", ie. how the
72hooking to ENGINE works from RSA, DSA, DH, RAND, as well as adding new hooking
73for EVP_CIPHER, and EVP_MD.
74
75The way this is now being done is by mostly reverting back to how things used to
76work prior to ENGINE :-). Ie. RSA now has a "RSA_METHOD" pointer again - this
77was previously replaced by an "ENGINE" pointer and all RSA code that required
78the RSA_METHOD would call ENGINE_get_RSA() each time on its ENGINE handle to
79temporarily get and use the ENGINE's RSA implementation. Apart from being more
80efficient, switching back to each RSA having an RSA_METHOD pointer also allows
81us to conceivably operate with *no* ENGINE. As we'll see, this removes any need
82for a fallback ENGINE that encapsulates default implementations - we can simply
83have our RSA structure pointing its RSA_METHOD pointer to the software
84implementation and have its ENGINE pointer set to NULL.
85
86A look at the EVP_CIPHER hooking is most explanatory, the RSA, DSA (etc) cases
87turn out to be degenerate forms of the same thing. The EVP storage of ciphers,
88and the existing EVP API functions that return "software" implementations and
89descriptions remain untouched. However, the storage takes more meaning in terms
90of "cipher description" and less meaning in terms of "implementation". When an
91EVP_CIPHER_CTX is actually initialised with an EVP_CIPHER method and is about to
92begin en/decryption, the hooking to ENGINE comes into play. What happens is that
93cipher-specific ENGINE code is asked for an ENGINE pointer (a functional
94reference) for any ENGINE that is registered to perform the algo/mode that the
95provided EVP_CIPHER structure represents. Under normal circumstances, that
96ENGINE code will return NULL because no ENGINEs will have had any cipher
97implementations *registered*. As such, a NULL ENGINE pointer is stored in the
98EVP_CIPHER_CTX context, and the EVP_CIPHER structure is left hooked into the
99context and so is used as the implementation. Pretty much how things work now
100except we'd have a redundant ENGINE pointer set to NULL and doing nothing.
101
102Conversely, if an ENGINE *has* been registered to perform the algorithm/mode
103combination represented by the provided EVP_CIPHER, then a functional reference
104to that ENGINE will be returned to the EVP_CIPHER_CTX during initialisation.
105That functional reference will be stored in the context (and released on
106cleanup) - and having that reference provides a *safe* way to use an EVP_CIPHER
107definition that is private to the ENGINE. Ie. the EVP_CIPHER provided by the
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
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..bc50465422
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_all.c
@@ -0,0 +1,119 @@
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#ifndef OPENSSL_NO_HW_4758_CCA
100 ENGINE_load_4758cca();
101#endif
102#ifdef OPENSSL_OPENBSD_DEV_CRYPTO
103 ENGINE_load_openbsd_dev_crypto();
104#endif
105#ifdef __OpenBSD__
106 ENGINE_load_cryptodev();
107#endif
108#endif
109 }
110
111#ifdef __OpenBSD__
112void ENGINE_setup_openbsd(void) {
113 if (!openbsd_default_loaded) {
114 ENGINE_load_cryptodev();
115 ENGINE_register_all_complete();
116 }
117 openbsd_default_loaded=1;
118}
119#endif
diff --git a/src/lib/libcrypto/engine/eng_cnf.c b/src/lib/libcrypto/engine/eng_cnf.c
new file mode 100644
index 0000000000..cdf670901a
--- /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
95static int 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..4139a16e76
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_dyn.c
@@ -0,0 +1,460 @@
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 if(ctx->DYNAMIC_LIBNAME)
161 OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME);
162 if(ctx->engine_id)
163 OPENSSL_free((void*)ctx->engine_id);
164 OPENSSL_free(ctx);
165 }
166 }
167
168/* Construct the per-ENGINE context. We create it blindly and then use a lock to
169 * check for a race - if so, all but one of the threads "racing" will have
170 * wasted their time. The alternative involves creating everything inside the
171 * lock which is far worse. */
172static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
173 {
174 dynamic_data_ctx *c;
175 c = OPENSSL_malloc(sizeof(dynamic_data_ctx));
176 if(!c)
177 {
178 ENGINEerr(ENGINE_F_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
179 return 0;
180 }
181 memset(c, 0, sizeof(dynamic_data_ctx));
182 c->dynamic_dso = NULL;
183 c->v_check = NULL;
184 c->bind_engine = NULL;
185 c->DYNAMIC_LIBNAME = NULL;
186 c->no_vcheck = 0;
187 c->engine_id = NULL;
188 c->list_add_value = 0;
189 c->DYNAMIC_F1 = "v_check";
190 c->DYNAMIC_F2 = "bind_engine";
191 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
192 if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e,
193 dynamic_ex_data_idx)) == NULL)
194 {
195 /* Good, we're the first */
196 ENGINE_set_ex_data(e, dynamic_ex_data_idx, c);
197 *ctx = c;
198 c = NULL;
199 }
200 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
201 /* If we lost the race to set the context, c is non-NULL and *ctx is the
202 * context of the thread that won. */
203 if(c)
204 OPENSSL_free(c);
205 return 1;
206 }
207
208/* This function retrieves the context structure from an ENGINE's "ex_data", or
209 * if it doesn't exist yet, sets it up. */
210static dynamic_data_ctx *dynamic_get_data_ctx(ENGINE *e)
211 {
212 dynamic_data_ctx *ctx;
213 if(dynamic_ex_data_idx < 0)
214 {
215 /* Create and register the ENGINE ex_data, and associate our
216 * "free" function with it to ensure any allocated contexts get
217 * freed when an ENGINE goes underground. */
218 int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL,
219 dynamic_data_ctx_free_func);
220 if(new_idx == -1)
221 {
222 ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX,ENGINE_R_NO_INDEX);
223 return NULL;
224 }
225 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
226 /* Avoid a race by checking again inside this lock */
227 if(dynamic_ex_data_idx < 0)
228 {
229 /* Good, someone didn't beat us to it */
230 dynamic_ex_data_idx = new_idx;
231 new_idx = -1;
232 }
233 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
234 /* In theory we could "give back" the index here if
235 * (new_idx>-1), but it's not possible and wouldn't gain us much
236 * if it were. */
237 }
238 ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx);
239 /* Check if the context needs to be created */
240 if((ctx == NULL) && !dynamic_set_data_ctx(e, &ctx))
241 /* "set_data" will set errors if necessary */
242 return NULL;
243 return ctx;
244 }
245
246static ENGINE *engine_dynamic(void)
247 {
248 ENGINE *ret = ENGINE_new();
249 if(!ret)
250 return NULL;
251 if(!ENGINE_set_id(ret, engine_dynamic_id) ||
252 !ENGINE_set_name(ret, engine_dynamic_name) ||
253 !ENGINE_set_init_function(ret, dynamic_init) ||
254 !ENGINE_set_finish_function(ret, dynamic_finish) ||
255 !ENGINE_set_ctrl_function(ret, dynamic_ctrl) ||
256 !ENGINE_set_flags(ret, ENGINE_FLAGS_BY_ID_COPY) ||
257 !ENGINE_set_cmd_defns(ret, dynamic_cmd_defns))
258 {
259 ENGINE_free(ret);
260 return NULL;
261 }
262 return ret;
263 }
264
265void ENGINE_load_dynamic(void)
266 {
267 ENGINE *toadd = engine_dynamic();
268 if(!toadd) return;
269 ENGINE_add(toadd);
270 /* If the "add" worked, it gets a structural reference. So either way,
271 * we release our just-created reference. */
272 ENGINE_free(toadd);
273 /* If the "add" didn't work, it was probably a conflict because it was
274 * already added (eg. someone calling ENGINE_load_blah then calling
275 * ENGINE_load_builtin_engines() perhaps). */
276 ERR_clear_error();
277 }
278
279static int dynamic_init(ENGINE *e)
280 {
281 /* We always return failure - the "dyanamic" engine itself can't be used
282 * for anything. */
283 return 0;
284 }
285
286static int dynamic_finish(ENGINE *e)
287 {
288 /* This should never be called on account of "dynamic_init" always
289 * failing. */
290 return 0;
291 }
292
293static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
294 {
295 dynamic_data_ctx *ctx = dynamic_get_data_ctx(e);
296 int initialised;
297
298 if(!ctx)
299 {
300 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_NOT_LOADED);
301 return 0;
302 }
303 initialised = ((ctx->dynamic_dso == NULL) ? 0 : 1);
304 /* All our control commands require the ENGINE to be uninitialised */
305 if(initialised)
306 {
307 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
308 ENGINE_R_ALREADY_LOADED);
309 return 0;
310 }
311 switch(cmd)
312 {
313 case DYNAMIC_CMD_SO_PATH:
314 /* a NULL 'p' or a string of zero-length is the same thing */
315 if(p && (strlen((const char *)p) < 1))
316 p = NULL;
317 if(ctx->DYNAMIC_LIBNAME)
318 OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME);
319 if(p)
320 ctx->DYNAMIC_LIBNAME = BUF_strdup(p);
321 else
322 ctx->DYNAMIC_LIBNAME = NULL;
323 return (ctx->DYNAMIC_LIBNAME ? 1 : 0);
324 case DYNAMIC_CMD_NO_VCHECK:
325 ctx->no_vcheck = ((i == 0) ? 0 : 1);
326 return 1;
327 case DYNAMIC_CMD_ID:
328 /* a NULL 'p' or a string of zero-length is the same thing */
329 if(p && (strlen((const char *)p) < 1))
330 p = NULL;
331 if(ctx->engine_id)
332 OPENSSL_free((void*)ctx->engine_id);
333 if(p)
334 ctx->engine_id = BUF_strdup(p);
335 else
336 ctx->engine_id = NULL;
337 return (ctx->engine_id ? 1 : 0);
338 case DYNAMIC_CMD_LIST_ADD:
339 if((i < 0) || (i > 2))
340 {
341 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
342 ENGINE_R_INVALID_ARGUMENT);
343 return 0;
344 }
345 ctx->list_add_value = (int)i;
346 return 1;
347 case DYNAMIC_CMD_LOAD:
348 return dynamic_load(e, ctx);
349 default:
350 break;
351 }
352 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
353 return 0;
354 }
355
356static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
357 {
358 ENGINE cpy;
359 dynamic_fns fns;
360
361 if(!ctx->DYNAMIC_LIBNAME || ((ctx->dynamic_dso = DSO_load(NULL,
362 ctx->DYNAMIC_LIBNAME, NULL, 0)) == NULL))
363 {
364 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
365 ENGINE_R_DSO_NOT_FOUND);
366 return 0;
367 }
368 /* We have to find a bind function otherwise it'll always end badly */
369 if(!(ctx->bind_engine = (dynamic_bind_engine)DSO_bind_func(
370 ctx->dynamic_dso, ctx->DYNAMIC_F2)))
371 {
372 ctx->bind_engine = NULL;
373 DSO_free(ctx->dynamic_dso);
374 ctx->dynamic_dso = NULL;
375 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
376 ENGINE_R_DSO_FAILURE);
377 return 0;
378 }
379 /* Do we perform version checking? */
380 if(!ctx->no_vcheck)
381 {
382 unsigned long vcheck_res = 0;
383 /* Now we try to find a version checking function and decide how
384 * to cope with failure if/when it fails. */
385 ctx->v_check = (dynamic_v_check_fn)DSO_bind_func(
386 ctx->dynamic_dso, ctx->DYNAMIC_F1);
387 if(ctx->v_check)
388 vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION);
389 /* We fail if the version checker veto'd the load *or* if it is
390 * deferring to us (by returning its version) and we think it is
391 * too old. */
392 if(vcheck_res < OSSL_DYNAMIC_OLDEST)
393 {
394 /* Fail */
395 ctx->bind_engine = NULL;
396 ctx->v_check = NULL;
397 DSO_free(ctx->dynamic_dso);
398 ctx->dynamic_dso = NULL;
399 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
400 ENGINE_R_VERSION_INCOMPATIBILITY);
401 return 0;
402 }
403 }
404 /* First binary copy the ENGINE structure so that we can roll back if
405 * the hand-over fails */
406 memcpy(&cpy, e, sizeof(ENGINE));
407 /* Provide the ERR, "ex_data", memory, and locking callbacks so the
408 * loaded library uses our state rather than its own. FIXME: As noted in
409 * engine.h, much of this would be simplified if each area of code
410 * provided its own "summary" structure of all related callbacks. It
411 * would also increase opaqueness. */
412 fns.err_fns = ERR_get_implementation();
413 fns.ex_data_fns = CRYPTO_get_ex_data_implementation();
414 CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb,
415 &fns.mem_fns.realloc_cb,
416 &fns.mem_fns.free_cb);
417 fns.lock_fns.lock_locking_cb = CRYPTO_get_locking_callback();
418 fns.lock_fns.lock_add_lock_cb = CRYPTO_get_add_lock_callback();
419 fns.lock_fns.dynlock_create_cb = CRYPTO_get_dynlock_create_callback();
420 fns.lock_fns.dynlock_lock_cb = CRYPTO_get_dynlock_lock_callback();
421 fns.lock_fns.dynlock_destroy_cb = CRYPTO_get_dynlock_destroy_callback();
422 /* Now that we've loaded the dynamic engine, make sure no "dynamic"
423 * ENGINE elements will show through. */
424 engine_set_all_null(e);
425
426 /* Try to bind the ENGINE onto our own ENGINE structure */
427 if(!ctx->bind_engine(e, ctx->engine_id, &fns))
428 {
429 ctx->bind_engine = NULL;
430 ctx->v_check = NULL;
431 DSO_free(ctx->dynamic_dso);
432 ctx->dynamic_dso = NULL;
433 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,ENGINE_R_INIT_FAILED);
434 /* Copy the original ENGINE structure back */
435 memcpy(e, &cpy, sizeof(ENGINE));
436 return 0;
437 }
438 /* Do we try to add this ENGINE to the internal list too? */
439 if(ctx->list_add_value > 0)
440 {
441 if(!ENGINE_add(e))
442 {
443 /* Do we tolerate this or fail? */
444 if(ctx->list_add_value > 1)
445 {
446 /* Fail - NB: By this time, it's too late to
447 * rollback, and trying to do so allows the
448 * bind_engine() code to have created leaks. We
449 * just have to fail where we are, after the
450 * ENGINE has changed. */
451 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
452 ENGINE_R_CONFLICTING_ENGINE_ID);
453 return 0;
454 }
455 /* Tolerate */
456 ERR_clear_error();
457 }
458 }
459 return 1;
460 }
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..f7edb5ad32
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_fat.c
@@ -0,0 +1,147 @@
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
87static int 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 return 1;
147 }
diff --git a/src/lib/libcrypto/engine/eng_init.c b/src/lib/libcrypto/engine/eng_init.c
new file mode 100644
index 0000000000..170c1791b3
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_init.c
@@ -0,0 +1,157 @@
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 }
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..0c220558e7
--- /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
new file mode 100644
index 0000000000..fd17ff616d
--- /dev/null
+++ b/src/lib/libcrypto/engine/engine.h
@@ -0,0 +1,717 @@
1/* openssl/engine.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_H
60#define HEADER_ENGINE_H
61
62#include <openssl/ossl_typ.h>
63#include <openssl/bn.h>
64#ifndef OPENSSL_NO_RSA
65#include <openssl/rsa.h>
66#endif
67#ifndef OPENSSL_NO_DSA
68#include <openssl/dsa.h>
69#endif
70#ifndef OPENSSL_NO_DH
71#include <openssl/dh.h>
72#endif
73#include <openssl/rand.h>
74#include <openssl/ui.h>
75#include <openssl/symhacks.h>
76#include <openssl/err.h>
77
78#ifdef __cplusplus
79extern "C" {
80#endif
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
93/* These flags are used to control combinations of algorithm (methods)
94 * by bitwise "OR"ing. */
95#define ENGINE_METHOD_RSA (unsigned int)0x0001
96#define ENGINE_METHOD_DSA (unsigned int)0x0002
97#define ENGINE_METHOD_DH (unsigned int)0x0004
98#define ENGINE_METHOD_RAND (unsigned int)0x0008
99#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040
100#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080
101/* Obvious all-or-nothing cases. */
102#define ENGINE_METHOD_ALL (unsigned int)0xFFFF
103#define ENGINE_METHOD_NONE (unsigned int)0x0000
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
160/* These flags are used to tell the ctrl function what should be done.
161 * All command numbers are shared between all engines, even if some don't
162 * make sense to some engines. In such a case, they do nothing but return
163 * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */
164#define ENGINE_CTRL_SET_LOGSTREAM 1
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
227/* Flags specific to the nCipher "chil" engine */
228#define ENGINE_CTRL_CHIL_SET_FORKCHECK 100
229 /* Depending on the value of the (long)i argument, this sets or
230 * unsets the SimpleForkCheck flag in the CHIL API to enable or
231 * disable checking and workarounds for applications that fork().
232 */
233#define ENGINE_CTRL_CHIL_NO_LOCKING 101
234 /* This prevents the initialisation function from providing mutex
235 * callbacks to the nCipher library. */
236
237/* If an ENGINE supports its own specific control commands and wishes the
238 * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on its
239 * behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN entries
240 * to ENGINE_set_cmd_defns(). It should also implement a ctrl() handler that
241 * supports the stated commands (ie. the "cmd_num" entries as described by the
242 * array). NB: The array must be ordered in increasing order of cmd_num.
243 * "null-terminated" means that the last ENGINE_CMD_DEFN element has cmd_num set
244 * to zero and/or cmd_name set to NULL. */
245typedef struct ENGINE_CMD_DEFN_st
246 {
247 unsigned int cmd_num; /* The command number */
248 const char *cmd_name; /* The command name itself */
249 const char *cmd_desc; /* A short description of the command */
250 unsigned int cmd_flags; /* The input the command expects */
251 } ENGINE_CMD_DEFN;
252
253/* Generic function pointer */
254typedef int (*ENGINE_GEN_FUNC_PTR)();
255/* Generic function pointer taking no arguments */
256typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *);
257/* Specific control function pointer */
258typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, void (*f)());
259/* Generic load_key function pointer */
260typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
261 UI_METHOD *ui_method, void *callback_data);
262/* These callback types are for an ENGINE's handler for cipher and digest logic.
263 * These handlers have these prototypes;
264 * int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
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);
276
277/* STRUCTURE functions ... all of these functions deal with pointers to ENGINE
278 * structures where the pointers have a "structural reference". This means that
279 * their reference is to allowed access to the structure but it does not imply
280 * that the structure is functional. To simply increment or decrement the
281 * structural reference count, use ENGINE_by_id and ENGINE_free. NB: This is not
282 * required when iterating using ENGINE_get_next as it will automatically
283 * decrement the structural reference count of the "current" ENGINE and
284 * increment the structural reference count of the ENGINE it returns (unless it
285 * is NULL). */
286
287/* Get the first/last "ENGINE" type available. */
288ENGINE *ENGINE_get_first(void);
289ENGINE *ENGINE_get_last(void);
290/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
291ENGINE *ENGINE_get_next(ENGINE *e);
292ENGINE *ENGINE_get_prev(ENGINE *e);
293/* Add another "ENGINE" type into the array. */
294int ENGINE_add(ENGINE *e);
295/* Remove an existing "ENGINE" type from the array. */
296int ENGINE_remove(ENGINE *e);
297/* Retrieve an engine from the list by its unique "id" value. */
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);
320
321/* Manage registration of ENGINEs per "table". For each type, there are 3
322 * functions;
323 * ENGINE_register_***(e) - registers the implementation from 'e' (if it has one)
324 * ENGINE_unregister_***(e) - unregister the implementation from 'e'
325 * ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list
326 * Cleanup is automatically registered from each table when required, so
327 * ENGINE_cleanup() will reverse any "register" operations. */
328
329int ENGINE_register_RSA(ENGINE *e);
330void ENGINE_unregister_RSA(ENGINE *e);
331void ENGINE_register_all_RSA(void);
332
333int ENGINE_register_DSA(ENGINE *e);
334void ENGINE_unregister_DSA(ENGINE *e);
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! */
410ENGINE *ENGINE_new(void);
411int ENGINE_free(ENGINE *e);
412int ENGINE_set_id(ENGINE *e, const char *id);
413int ENGINE_set_name(ENGINE *e, const char *name);
414int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
415int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
416int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
417int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
418int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
419int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
420int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_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);
433
434/* This function cleans up anything that needs it. Eg. the ENGINE_add() function
435 * automatically ensures the list cleanup function is registered to be called
436 * from ENGINE_cleanup(). Similarly, all ENGINE_register_*** functions ensure
437 * ENGINE_cleanup() will clean up after them. */
438void ENGINE_cleanup(void);
439
440/* These return values from within the ENGINE structure. These can be useful
441 * with functional references as well as structural references - it depends
442 * which you obtained. Using the result for functional purposes if you only
443 * obtained a structural reference may be problematic! */
444const char *ENGINE_get_id(const ENGINE *e);
445const char *ENGINE_get_name(const ENGINE *e);
446const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
447const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
448const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
449const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
450ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
451ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
452ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
453ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
454ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
455ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
456ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
457ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
458const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
459const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
460const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
461int ENGINE_get_flags(const ENGINE *e);
462void *ENGINE_get_ex_data(const ENGINE *e, int idx);
463
464/* FUNCTIONAL functions. These functions deal with ENGINE structures
465 * that have (or will) be initialised for use. Broadly speaking, the
466 * structural functions are useful for iterating the list of available
467 * engine types, creating new engine types, and other "list" operations.
468 * These functions actually deal with ENGINEs that are to be used. As
469 * such these functions can fail (if applicable) when particular
470 * engines are unavailable - eg. if a hardware accelerator is not
471 * attached or not functioning correctly. Each ENGINE has 2 reference
472 * counts; structural and functional. Every time a functional reference
473 * is obtained or released, a corresponding structural reference is
474 * automatically obtained or released too. */
475
476/* Initialise a engine type for use (or up its reference count if it's
477 * already in use). This will fail if the engine is not currently
478 * operational and cannot initialise. */
479int ENGINE_init(ENGINE *e);
480/* Free a functional reference to a engine type. This does not require
481 * a corresponding call to ENGINE_free as it also releases a structural
482 * reference. */
483int ENGINE_finish(ENGINE *e);
484
485/* The following functions handle keys that are stored in some secondary
486 * location, handled by the engine. The storage may be on a card or
487 * whatever. */
488EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
489 UI_METHOD *ui_method, void *callback_data);
490EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
491 UI_METHOD *ui_method, void *callback_data);
492
493/* This returns a pointer for the current ENGINE structure that
494 * is (by default) performing any RSA operations. The value returned
495 * is an incremented reference, so it should be free'd (ENGINE_finish)
496 * before it is discarded. */
497ENGINE *ENGINE_get_default_RSA(void);
498/* Same for the other "methods" */
499ENGINE *ENGINE_get_default_DSA(void);
500ENGINE *ENGINE_get_default_DH(void);
501ENGINE *ENGINE_get_default_RAND(void);
502/* These functions can be used to get a functional reference to perform
503 * ciphering or digesting corresponding to "nid". */
504ENGINE *ENGINE_get_cipher_engine(int nid);
505ENGINE *ENGINE_get_digest_engine(int nid);
506
507/* This sets a new default ENGINE structure for performing RSA
508 * operations. If the result is non-zero (success) then the ENGINE
509 * structure will have had its reference count up'd so the caller
510 * should still free their own reference 'e'. */
511int ENGINE_set_default_RSA(ENGINE *e);
512int ENGINE_set_default_string(ENGINE *e, const char *list);
513/* Same for the other "methods" */
514int ENGINE_set_default_DSA(ENGINE *e);
515int ENGINE_set_default_DH(ENGINE *e);
516int ENGINE_set_default_RAND(ENGINE *e);
517int ENGINE_set_default_ciphers(ENGINE *e);
518int ENGINE_set_default_digests(ENGINE *e);
519
520/* The combination "set" - the flags are bitwise "OR"d from the
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. */
525int ENGINE_set_default(ENGINE *e, unsigned int flags);
526
527void ENGINE_add_conf_module(void);
528
529/* Deprecated functions ... */
530/* int ENGINE_clear_defaults(void); */
531
532/**************************/
533/* DYNAMIC ENGINE SUPPORT */
534/**************************/
535
536/* Binary/behaviour compatibility levels */
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; }
628
629/* BEGIN ERROR CODES */
630/* The following lines are auto generated by the script mkerr.pl. Any changes
631 * made after this point may be overwritten when the script is next run.
632 */
633void ERR_load_ENGINE_strings(void);
634
635/* Error codes for the ENGINE functions. */
636
637/* Function codes. */
638#define ENGINE_F_DYNAMIC_CTRL 180
639#define ENGINE_F_DYNAMIC_GET_DATA_CTX 181
640#define ENGINE_F_DYNAMIC_LOAD 182
641#define ENGINE_F_ENGINE_ADD 105
642#define ENGINE_F_ENGINE_BY_ID 106
643#define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170
644#define ENGINE_F_ENGINE_CTRL 142
645#define ENGINE_F_ENGINE_CTRL_CMD 178
646#define ENGINE_F_ENGINE_CTRL_CMD_STRING 171
647#define ENGINE_F_ENGINE_FINISH 107
648#define ENGINE_F_ENGINE_FREE 108
649#define ENGINE_F_ENGINE_GET_CIPHER 185
650#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177
651#define ENGINE_F_ENGINE_GET_DIGEST 186
652#define ENGINE_F_ENGINE_GET_NEXT 115
653#define ENGINE_F_ENGINE_GET_PREV 116
654#define ENGINE_F_ENGINE_INIT 119
655#define ENGINE_F_ENGINE_LIST_ADD 120
656#define ENGINE_F_ENGINE_LIST_REMOVE 121
657#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150
658#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151
659#define ENGINE_F_ENGINE_MODULE_INIT 187
660#define ENGINE_F_ENGINE_NEW 122
661#define ENGINE_F_ENGINE_REMOVE 123
662#define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189
663#define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126
664#define ENGINE_F_ENGINE_SET_ID 129
665#define ENGINE_F_ENGINE_SET_NAME 130
666#define ENGINE_F_ENGINE_TABLE_REGISTER 184
667#define ENGINE_F_ENGINE_UNLOAD_KEY 152
668#define ENGINE_F_INT_CTRL_HELPER 172
669#define ENGINE_F_INT_ENGINE_CONFIGURE 188
670#define ENGINE_F_LOG_MESSAGE 141
671#define ENGINE_F_SET_DATA_CTX 183
672
673/* Reason codes. */
674#define ENGINE_R_ALREADY_LOADED 100
675#define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER 133
676#define ENGINE_R_CMD_NOT_EXECUTABLE 134
677#define ENGINE_R_COMMAND_TAKES_INPUT 135
678#define ENGINE_R_COMMAND_TAKES_NO_INPUT 136
679#define ENGINE_R_CONFLICTING_ENGINE_ID 103
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
683#define ENGINE_R_DSO_FAILURE 104
684#define ENGINE_R_DSO_NOT_FOUND 132
685#define ENGINE_R_ENGINES_SECTION_ERROR 148
686#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105
687#define ENGINE_R_ENGINE_SECTION_ERROR 149
688#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128
689#define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129
690#define ENGINE_R_FINISH_FAILED 106
691#define ENGINE_R_GET_HANDLE_FAILED 107
692#define ENGINE_R_ID_OR_NAME_MISSING 108
693#define ENGINE_R_INIT_FAILED 109
694#define ENGINE_R_INTERNAL_LIST_ERROR 110
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
700#define ENGINE_R_NOT_INITIALISED 117
701#define ENGINE_R_NOT_LOADED 112
702#define ENGINE_R_NO_CONTROL_FUNCTION 120
703#define ENGINE_R_NO_INDEX 144
704#define ENGINE_R_NO_LOAD_FUNCTION 125
705#define ENGINE_R_NO_REFERENCE 130
706#define ENGINE_R_NO_SUCH_ENGINE 116
707#define ENGINE_R_NO_UNLOAD_FUNCTION 126
708#define ENGINE_R_PROVIDE_PARAMETERS 113
709#define ENGINE_R_RSA_NOT_IMPLEMENTED 141
710#define ENGINE_R_UNIMPLEMENTED_CIPHER 146
711#define ENGINE_R_UNIMPLEMENTED_DIGEST 147
712#define ENGINE_R_VERSION_INCOMPATIBILITY 145
713
714#ifdef __cplusplus
715}
716#endif
717#endif
diff --git a/src/lib/libcrypto/engine/hw_4758_cca.c b/src/lib/libcrypto/engine/hw_4758_cca.c
index bfb80968e2..f404b1a3b8 100644
--- a/src/lib/libcrypto/engine/hw_4758_cca.c
+++ b/src/lib/libcrypto/engine/hw_4758_cca.c
@@ -715,7 +715,7 @@ static int cca_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
715 715
716 if (type == NID_sha1 || type == NID_md5) 716 if (type == NID_sha1 || type == NID_md5)
717 { 717 {
718 memset(hashBuffer, keyLength+1, 0); 718 memset(hashBuffer, 0, keyLength+1);
719 OPENSSL_free(hashBuffer); 719 OPENSSL_free(hashBuffer);
720 } 720 }
721 721
@@ -838,7 +838,7 @@ static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
838 838
839 if (type == NID_sha1 || type == NID_md5) 839 if (type == NID_sha1 || type == NID_md5)
840 { 840 {
841 memset(hashBuffer, keyLength+1, 0); 841 memset(hashBuffer, 0, keyLength+1);
842 OPENSSL_free(hashBuffer); 842 OPENSSL_free(hashBuffer);
843 } 843 }
844 844
@@ -953,7 +953,7 @@ static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx,
953#ifdef ENGINE_DYNAMIC_SUPPORT 953#ifdef ENGINE_DYNAMIC_SUPPORT
954static int bind_fn(ENGINE *e, const char *id) 954static int bind_fn(ENGINE *e, const char *id)
955 { 955 {
956 if(id && (strcmp(id, engine_4758_cca_id) != 0)) 956 if(id && (strcmp(id, engine_cswift_id) != 0))
957 return 0; 957 return 0;
958 if(!bind_helper(e)) 958 if(!bind_helper(e))
959 return 0; 959 return 0;
diff --git a/src/lib/libcrypto/engine/hw_cryptodev.c b/src/lib/libcrypto/engine/hw_cryptodev.c
index 7c3728f395..954eb85207 100644
--- a/src/lib/libcrypto/engine/hw_cryptodev.c
+++ b/src/lib/libcrypto/engine/hw_cryptodev.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2002 Bob Beck <beck@openbsd.org> 2 * Copyright (c) 2002 Bob Beck <beck@openbsd.org>
3 * Copyright (c) 2002 Theo de Raadt 3 * Copyright (c) 2002 Theo de Raadt
4 * Copyright (c) 2002 Markus Friedl
4 * All rights reserved. 5 * All rights reserved.
5 * 6 *
6 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
@@ -36,25 +37,56 @@
36#include <stdio.h> 37#include <stdio.h>
37#include <unistd.h> 38#include <unistd.h>
38#include <fcntl.h> 39#include <fcntl.h>
39#include <syslog.h>
40#include <stdarg.h> 40#include <stdarg.h>
41#include <syslog.h>
41#include <ssl/objects.h> 42#include <ssl/objects.h>
42#include <ssl/engine.h> 43#include <ssl/engine.h>
43#include <ssl/evp.h> 44#include <ssl/evp.h>
45#include <errno.h>
46#include <string.h>
44 47
45static int cryptodev_fd = -1; 48struct dev_crypto_state {
46static int cryptodev_sessions = 0; 49 struct session_op d_sess;
47static u_int32_t cryptodev_symfeat = 0; 50 int d_fd;
51};
48 52
53static u_int32_t cryptodev_asymfeat = 0;
54
55static int get_asym_dev_crypto(void);
56static int open_dev_crypto(void);
57static int get_dev_crypto(void);
58static int cryptodev_max_iv(int cipher);
59static int cryptodev_key_length_valid(int cipher, int len);
60static int cipher_nid_to_cryptodev(int nid);
61static int get_cryptodev_ciphers(const int **cnids);
62static int get_cryptodev_digests(const int **cnids);
63static int cryptodev_usable_ciphers(const int **nids);
64static int cryptodev_usable_digests(const int **nids);
65static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
66 const unsigned char *in, unsigned int inl);
67static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
68 const unsigned char *iv, int enc);
69static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx);
70static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
71 const int **nids, int nid);
72static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
73 const int **nids, int nid);
49static int bn2crparam(const BIGNUM *a, struct crparam *crp); 74static int bn2crparam(const BIGNUM *a, struct crparam *crp);
50static int crparam2bn(struct crparam *crp, BIGNUM *a); 75static int crparam2bn(struct crparam *crp, BIGNUM *a);
51static void zapparams(struct crypt_kop *kop); 76static void zapparams(struct crypt_kop *kop);
77static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r,
78 int slen, BIGNUM *s);
52 79
53static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
54static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, 80static 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); 81 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
82static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I,
83 RSA *rsa);
84static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
56static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, 85static 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); 86 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
87static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
88 BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
89 BN_CTX *ctx, BN_MONT_CTX *mont);
58static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, 90static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst,
59 int dlen, DSA *dsa); 91 int dlen, DSA *dsa);
60static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len, 92static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
@@ -64,8 +96,15 @@ static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
64 BN_MONT_CTX *m_ctx); 96 BN_MONT_CTX *m_ctx);
65static int cryptodev_dh_compute_key(unsigned char *key, 97static int cryptodev_dh_compute_key(unsigned char *key,
66 const BIGNUM *pub_key, DH *dh); 98 const BIGNUM *pub_key, DH *dh);
99static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p,
100 void (*f)());
101void ENGINE_load_cryptodev(void);
67 102
68static const ENGINE_CMD_DEFN cryptodev_defns[] = { 103static const ENGINE_CMD_DEFN cryptodev_defns[] = {
104 {ENGINE_CMD_BASE,
105 "SO_PATH",
106 "Specifies the path to the some stupid shared library",
107 ENGINE_CMD_FLAG_STRING},
69 { 0, NULL, NULL, 0 } 108 { 0, NULL, NULL, 0 }
70}; 109};
71 110
@@ -77,11 +116,10 @@ static struct {
77} ciphers[] = { 116} ciphers[] = {
78 { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, }, 117 { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, },
79 { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, }, 118 { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, },
80 { CRYPTO_AES_CBC, NID_undef, 8, 24, }, 119 { CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, },
81 { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, }, 120 { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, },
82 { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 8, }, 121 { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, },
83 { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, }, 122 { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, },
84 { CRYPTO_ARC4, NID_rc4, 8, 16, },
85 { 0, NID_undef, 0, 0, }, 123 { 0, NID_undef, 0, 0, },
86}; 124};
87 125
@@ -99,33 +137,53 @@ static struct {
99}; 137};
100 138
101/* 139/*
102 * Return 1 if /dev/crypto seems usable, 0 otherwise , also 140 * Return a fd if /dev/crypto seems usable, 0 otherwise.
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 */ 141 */
106static int 142static int
107check_dev_crypto() 143open_dev_crypto(void)
108{ 144{
109 int fd; 145 static int fd = -1;
110 146
111 if (cryptodev_fd == -1) { 147 if (fd == -1) {
112 if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1) 148 if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1)
113 return (0); 149 return (-1);
114 if (ioctl(fd, CRIOGET, &cryptodev_fd) == -1) {
115 close(fd);
116 return (0);
117 }
118 close(fd);
119 /* close on exec */ 150 /* close on exec */
120 if (fcntl(cryptodev_fd, F_SETFD, 1) == -1) { 151 if (fcntl(fd, F_SETFD, 1) == -1) {
121 close(cryptodev_fd); 152 close(fd);
122 cryptodev_fd = -1; 153 fd = -1;
123 return (0); 154 return (-1);
124 } 155 }
125 } 156 }
126 ioctl(cryptodev_fd, CIOCSYMFEAT, &cryptodev_symfeat); 157 return (fd);
158}
127 159
128 return (1); 160static int
161get_dev_crypto(void)
162{
163 int fd, retfd;
164
165 if ((fd = open_dev_crypto()) == -1)
166 return (-1);
167 if (ioctl(fd, CRIOGET, &retfd) == -1)
168 return (-1);
169
170 /* close on exec */
171 if (fcntl(retfd, F_SETFD, 1) == -1) {
172 close(retfd);
173 return (-1);
174 }
175 return (retfd);
176}
177
178/* Caching version for asym operations */
179static int
180get_asym_dev_crypto(void)
181{
182 static int fd = -1;
183
184 if (fd == -1)
185 fd = get_dev_crypto();
186 return fd;
129} 187}
130 188
131/* 189/*
@@ -183,8 +241,12 @@ get_cryptodev_ciphers(const int **cnids)
183{ 241{
184 static int nids[CRYPTO_ALGORITHM_MAX]; 242 static int nids[CRYPTO_ALGORITHM_MAX];
185 struct session_op sess; 243 struct session_op sess;
186 int i, count = 0; 244 int fd, i, count = 0;
187 245
246 if ((fd = get_dev_crypto()) < 0) {
247 *nids = NULL;
248 return (0);
249 }
188 memset(&sess, 0, sizeof(sess)); 250 memset(&sess, 0, sizeof(sess));
189 sess.key = (caddr_t)"123456781234567812345678"; 251 sess.key = (caddr_t)"123456781234567812345678";
190 252
@@ -194,10 +256,12 @@ get_cryptodev_ciphers(const int **cnids)
194 sess.cipher = ciphers[i].id; 256 sess.cipher = ciphers[i].id;
195 sess.keylen = ciphers[i].keylen; 257 sess.keylen = ciphers[i].keylen;
196 sess.mac = 0; 258 sess.mac = 0;
197 if (ioctl(cryptodev_fd, CIOCGSESSION, &sess) != -1 && 259 if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
198 ioctl(cryptodev_fd, CIOCFSESSION, &sess.ses) != -1) 260 ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
199 nids[count++] = ciphers[i].nid; 261 nids[count++] = ciphers[i].nid;
200 } 262 }
263 close(fd);
264
201 if (count > 0) 265 if (count > 0)
202 *cnids = nids; 266 *cnids = nids;
203 else 267 else
@@ -216,18 +280,24 @@ get_cryptodev_digests(const int **cnids)
216{ 280{
217 static int nids[CRYPTO_ALGORITHM_MAX]; 281 static int nids[CRYPTO_ALGORITHM_MAX];
218 struct session_op sess; 282 struct session_op sess;
219 int i, count = 0; 283 int fd, i, count = 0;
220 284
285 if ((fd = get_dev_crypto()) < 0) {
286 *nids = NULL;
287 return (0);
288 }
221 memset(&sess, 0, sizeof(sess)); 289 memset(&sess, 0, sizeof(sess));
222 for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { 290 for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
223 if (digests[i].nid == NID_undef) 291 if (digests[i].nid == NID_undef)
224 continue; 292 continue;
225 sess.mac = digests[i].id; 293 sess.mac = digests[i].id;
226 sess.cipher = 0; 294 sess.cipher = 0;
227 if (ioctl(cryptodev_fd, CIOCGSESSION, &sess) != -1 && 295 if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
228 ioctl(cryptodev_fd, CIOCFSESSION, &sess.ses) != -1) 296 ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
229 nids[count++] = digests[i].nid; 297 nids[count++] = digests[i].nid;
230 } 298 }
299 close(fd);
300
231 if (count > 0) 301 if (count > 0)
232 *cnids = nids; 302 *cnids = nids;
233 else 303 else
@@ -256,25 +326,15 @@ get_cryptodev_digests(const int **cnids)
256 * want most of the decisions made about what we actually want 326 * want most of the decisions made about what we actually want
257 * to use from /dev/crypto. 327 * to use from /dev/crypto.
258 */ 328 */
259int 329static int
260cryptodev_usable_ciphers(const int **nids) 330cryptodev_usable_ciphers(const int **nids)
261{ 331{
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)); 332 return (get_cryptodev_ciphers(nids));
272} 333}
273 334
274int 335static int
275cryptodev_usable_digests(const int **nids) 336cryptodev_usable_digests(const int **nids)
276{ 337{
277#if 1
278 /* 338 /*
279 * XXXX just disable all digests for now, because it sucks. 339 * XXXX just disable all digests for now, because it sucks.
280 * we need a better way to decide this - i.e. I may not 340 * we need a better way to decide this - i.e. I may not
@@ -289,29 +349,19 @@ cryptodev_usable_digests(const int **nids)
289 */ 349 */
290 *nids = NULL; 350 *nids = NULL;
291 return (0); 351 return (0);
292#endif
293
294 if (!check_dev_crypto()) {
295 *nids = NULL;
296 return (0);
297 }
298 return (get_cryptodev_digests(nids));
299} 352}
300 353
301 354static int
302int
303cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 355cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
304 const unsigned char *in, unsigned int inl) 356 const unsigned char *in, unsigned int inl)
305{ 357{
306 struct crypt_op cryp; 358 struct crypt_op cryp;
307 struct session_op *sess = ctx->cipher_data; 359 struct dev_crypto_state *state = ctx->cipher_data;
360 struct session_op *sess = &state->d_sess;
308 void *iiv; 361 void *iiv;
309 unsigned char save_iv[EVP_MAX_IV_LENGTH]; 362 unsigned char save_iv[EVP_MAX_IV_LENGTH];
310 struct syslog_data sd = SYSLOG_DATA_INIT;
311 363
312 if (cryptodev_fd == -1) 364 if (state->d_fd < 0)
313 return (0);
314 if (sess == NULL)
315 return (0); 365 return (0);
316 if (!inl) 366 if (!inl)
317 return (1); 367 return (1);
@@ -338,11 +388,10 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
338 } else 388 } else
339 cryp.iv = NULL; 389 cryp.iv = NULL;
340 390
341 if (ioctl(cryptodev_fd, CIOCCRYPT, &cryp) == -1) { 391 if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) {
342 /* XXX need better errror handling 392 /* XXX need better errror handling
343 * this can fail for a number of different reasons. 393 * this can fail for a number of different reasons.
344 */ 394 */
345 syslog_r(LOG_ERR, &sd, "CIOCCRYPT failed (%m)");
346 return (0); 395 return (0);
347 } 396 }
348 397
@@ -356,20 +405,17 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
356 return (1); 405 return (1);
357} 406}
358 407
359int 408static int
360cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 409cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
361 const unsigned char *iv, int enc) 410 const unsigned char *iv, int enc)
362{ 411{
363 struct session_op *sess = ctx->cipher_data; 412 struct dev_crypto_state *state = ctx->cipher_data;
364 struct syslog_data sd = SYSLOG_DATA_INIT; 413 struct session_op *sess = &state->d_sess;
365 int cipher; 414 int cipher;
366 415
367 if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef) 416 if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef)
368 return (0); 417 return (0);
369 418
370 if (!check_dev_crypto())
371 return (0);
372
373 if (ctx->cipher->iv_len > cryptodev_max_iv(cipher)) 419 if (ctx->cipher->iv_len > cryptodev_max_iv(cipher))
374 return (0); 420 return (0);
375 421
@@ -378,15 +424,18 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
378 424
379 memset(sess, 0, sizeof(struct session_op)); 425 memset(sess, 0, sizeof(struct session_op));
380 426
427 if ((state->d_fd = get_dev_crypto()) < 0)
428 return (0);
429
381 sess->key = (unsigned char *)key; 430 sess->key = (unsigned char *)key;
382 sess->keylen = ctx->key_len; 431 sess->keylen = ctx->key_len;
383 sess->cipher = cipher; 432 sess->cipher = cipher;
384 433
385 if (ioctl(cryptodev_fd, CIOCGSESSION, sess) == -1) { 434 if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
386 syslog_r(LOG_ERR, &sd, "CIOCGSESSION failed (%m)"); 435 close(state->d_fd);
436 state->d_fd = -1;
387 return (0); 437 return (0);
388 } 438 }
389 cryptodev_sessions++;
390 return (1); 439 return (1);
391} 440}
392 441
@@ -394,14 +443,14 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
394 * free anything we allocated earlier when initting a 443 * free anything we allocated earlier when initting a
395 * session, and close the session. 444 * session, and close the session.
396 */ 445 */
397int 446static int
398cryptodev_cleanup(EVP_CIPHER_CTX *ctx) 447cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
399{ 448{
400 int ret = 0; 449 int ret = 0;
401 struct session_op *sess = ctx->cipher_data; 450 struct dev_crypto_state *state = ctx->cipher_data;
402 struct syslog_data sd = SYSLOG_DATA_INIT; 451 struct session_op *sess = &state->d_sess;
403 452
404 if (sess == NULL) 453 if (state->d_fd < 0)
405 return (0); 454 return (0);
406 455
407 /* XXX if this ioctl fails, someting's wrong. the invoker 456 /* XXX if this ioctl fails, someting's wrong. the invoker
@@ -415,17 +464,14 @@ cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
415 * print messages to users of the library. hmm.. 464 * print messages to users of the library. hmm..
416 */ 465 */
417 466
418 if (ioctl(cryptodev_fd, CIOCFSESSION, &sess->ses) == -1) { 467 if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) {
419 syslog_r(LOG_ERR, &sd, "CIOCFSESSION failed (%m)");
420 ret = 0; 468 ret = 0;
421 } else { 469 } else {
422 cryptodev_sessions--;
423 ret = 1; 470 ret = 1;
424 } 471 }
425 if (cryptodev_sessions == 0 && cryptodev_fd != -1 ) { 472 close(state->d_fd);
426 close(cryptodev_fd); /* XXX should this be closed? */ 473 state->d_fd = -1;
427 cryptodev_fd = -1; 474
428 }
429 return (ret); 475 return (ret);
430} 476}
431 477
@@ -434,20 +480,6 @@ cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
434 * gets called when libcrypto requests a cipher NID. 480 * gets called when libcrypto requests a cipher NID.
435 */ 481 */
436 482
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 */ 483/* DES CBC EVP */
452const EVP_CIPHER cryptodev_des_cbc = { 484const EVP_CIPHER cryptodev_des_cbc = {
453 NID_des_cbc, 485 NID_des_cbc,
@@ -456,7 +488,7 @@ const EVP_CIPHER cryptodev_des_cbc = {
456 cryptodev_init_key, 488 cryptodev_init_key,
457 cryptodev_cipher, 489 cryptodev_cipher,
458 cryptodev_cleanup, 490 cryptodev_cleanup,
459 sizeof(struct session_op), 491 sizeof(struct dev_crypto_state),
460 EVP_CIPHER_set_asn1_iv, 492 EVP_CIPHER_set_asn1_iv,
461 EVP_CIPHER_get_asn1_iv, 493 EVP_CIPHER_get_asn1_iv,
462 NULL 494 NULL
@@ -470,19 +502,57 @@ const EVP_CIPHER cryptodev_3des_cbc = {
470 cryptodev_init_key, 502 cryptodev_init_key,
471 cryptodev_cipher, 503 cryptodev_cipher,
472 cryptodev_cleanup, 504 cryptodev_cleanup,
473 sizeof(struct session_op), 505 sizeof(struct dev_crypto_state),
506 EVP_CIPHER_set_asn1_iv,
507 EVP_CIPHER_get_asn1_iv,
508 NULL
509};
510
511const EVP_CIPHER cryptodev_bf_cbc = {
512 NID_bf_cbc,
513 8, 16, 8,
514 EVP_CIPH_CBC_MODE,
515 cryptodev_init_key,
516 cryptodev_cipher,
517 cryptodev_cleanup,
518 sizeof(struct dev_crypto_state),
519 EVP_CIPHER_set_asn1_iv,
520 EVP_CIPHER_get_asn1_iv,
521 NULL
522};
523
524const EVP_CIPHER cryptodev_cast_cbc = {
525 NID_cast5_cbc,
526 8, 16, 8,
527 EVP_CIPH_CBC_MODE,
528 cryptodev_init_key,
529 cryptodev_cipher,
530 cryptodev_cleanup,
531 sizeof(struct dev_crypto_state),
474 EVP_CIPHER_set_asn1_iv, 532 EVP_CIPHER_set_asn1_iv,
475 EVP_CIPHER_get_asn1_iv, 533 EVP_CIPHER_get_asn1_iv,
476 NULL 534 NULL
477}; 535};
478 536
537const EVP_CIPHER cryptodev_aes_cbc = {
538 NID_aes_128_cbc,
539 16, 16, 16,
540 EVP_CIPH_CBC_MODE,
541 cryptodev_init_key,
542 cryptodev_cipher,
543 cryptodev_cleanup,
544 sizeof(struct dev_crypto_state),
545 EVP_CIPHER_set_asn1_iv,
546 EVP_CIPHER_get_asn1_iv,
547 NULL
548};
479 549
480/* 550/*
481 * Registered by the ENGINE when used to find out how to deal with 551 * 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 552 * 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 553 * top level - note, that list is restricted by what we answer with
484 */ 554 */
485int 555static int
486cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, 556cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
487 const int **nids, int nid) 557 const int **nids, int nid)
488{ 558{
@@ -490,15 +560,21 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
490 return (cryptodev_usable_ciphers(nids)); 560 return (cryptodev_usable_ciphers(nids));
491 561
492 switch (nid) { 562 switch (nid) {
493 case NID_rc4:
494 *cipher = &cryptodev_arc4_cipher;
495 break;
496 case NID_des_ede3_cbc: 563 case NID_des_ede3_cbc:
497 *cipher = &cryptodev_3des_cbc; 564 *cipher = &cryptodev_3des_cbc;
498 break; 565 break;
499 case NID_des_cbc: 566 case NID_des_cbc:
500 *cipher = &cryptodev_des_cbc; 567 *cipher = &cryptodev_des_cbc;
501 break; 568 break;
569 case NID_bf_cbc:
570 *cipher = &cryptodev_bf_cbc;
571 break;
572 case NID_cast5_cbc:
573 *cipher = &cryptodev_cast_cbc;
574 break;
575 case NID_aes_128_cbc:
576 *cipher = &cryptodev_aes_cbc;
577 break;
502 default: 578 default:
503 *cipher = NULL; 579 *cipher = NULL;
504 break; 580 break;
@@ -506,7 +582,7 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
506 return (*cipher != NULL); 582 return (*cipher != NULL);
507} 583}
508 584
509int 585static int
510cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, 586cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
511 const int **nids, int nid) 587 const int **nids, int nid)
512{ 588{
@@ -524,7 +600,6 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
524 return (*digest != NULL); 600 return (*digest != NULL);
525} 601}
526 602
527
528/* 603/*
529 * Convert a BIGNUM to the representation that /dev/crypto needs. 604 * Convert a BIGNUM to the representation that /dev/crypto needs.
530 * Upon completion of use, the caller is responsible for freeing 605 * Upon completion of use, the caller is responsible for freeing
@@ -533,7 +608,7 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
533static int 608static int
534bn2crparam(const BIGNUM *a, struct crparam *crp) 609bn2crparam(const BIGNUM *a, struct crparam *crp)
535{ 610{
536 int i, j, n; 611 int i, j, k;
537 ssize_t words, bytes, bits; 612 ssize_t words, bytes, bits;
538 u_char *b; 613 u_char *b;
539 614
@@ -550,17 +625,13 @@ bn2crparam(const BIGNUM *a, struct crparam *crp)
550 crp->crp_p = b; 625 crp->crp_p = b;
551 crp->crp_nbits = bits; 626 crp->crp_nbits = bits;
552 627
553 words = (bits + BN_BITS2 - 1) / BN_BITS2; 628 for (i = 0, j = 0; i < a->top; i++) {
554 629 for (k = 0; k < BN_BITS2 / 8; k++) {
555 n = 0; 630 if ((j + k) >= bytes)
556 for (i = 0; i < words && n < bytes; i++) { 631 return (0);
557 BN_ULONG word; 632 b[j + k] = a->d[i] >> (k * 8);
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 } 633 }
634 j += BN_BITS2 / 8;
564 } 635 }
565 return (0); 636 return (0);
566} 637}
@@ -569,15 +640,22 @@ bn2crparam(const BIGNUM *a, struct crparam *crp)
569static int 640static int
570crparam2bn(struct crparam *crp, BIGNUM *a) 641crparam2bn(struct crparam *crp, BIGNUM *a)
571{ 642{
643 u_int8_t *pd;
572 int i, bytes; 644 int i, bytes;
573 645
574 bytes = (crp->crp_nbits + 7)/8; 646 bytes = (crp->crp_nbits + 7) / 8;
575 647
576 BN_zero(a); 648 if (bytes == 0)
577 for (i = bytes - 1; i >= 0; i--) { 649 return (-1);
578 BN_lshift(a, a, 8); 650
579 BN_add_word(a, (u_char)crp->crp_p[i]); 651 if ((pd = (u_int8_t *) malloc(bytes)) == NULL)
580 } 652 return (-1);
653
654 for (i = 0; i < bytes; i++)
655 pd[i] = crp->crp_p[bytes - i - 1];
656
657 BN_bin2bn(pd, bytes, a);
658 free(pd);
581 659
582 return (0); 660 return (0);
583} 661}
@@ -596,25 +674,32 @@ zapparams(struct crypt_kop *kop)
596} 674}
597 675
598static int 676static int
599cryptodev_sym(struct crypt_kop *kop, BIGNUM *r, BIGNUM *s) 677cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s)
600{ 678{
601 int ret = -1; 679 int fd, ret = -1;
680
681 if ((fd = get_asym_dev_crypto()) < 0)
682 return (ret);
602 683
603 if (r) { 684 if (r) {
604 kop->crk_param[kop->crk_iparams].crp_p = malloc(256); 685 kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char));
605 kop->crk_param[kop->crk_iparams].crp_nbits = 256 * 8; 686 kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8;
606 kop->crk_oparams++; 687 kop->crk_oparams++;
607 } 688 }
608 if (s) { 689 if (s) {
609 kop->crk_param[kop->crk_iparams+1].crp_p = malloc(256); 690 kop->crk_param[kop->crk_iparams+1].crp_p = calloc(slen, sizeof(char));
610 kop->crk_param[kop->crk_iparams+1].crp_nbits = 256 * 8; 691 kop->crk_param[kop->crk_iparams+1].crp_nbits = slen * 8;
611 kop->crk_oparams++; 692 kop->crk_oparams++;
612 } 693 }
613 694
614 if (ioctl(cryptodev_fd, CIOCKEY, &kop) == 0) { 695 if (ioctl(fd, CIOCKEY, kop) == 0) {
615 crparam2bn(&kop->crk_param[3], r); 696 if (r)
697 crparam2bn(&kop->crk_param[kop->crk_iparams], r);
698 if (s)
699 crparam2bn(&kop->crk_param[kop->crk_iparams+1], s);
616 ret = 0; 700 ret = 0;
617 } 701 }
702
618 return (ret); 703 return (ret);
619} 704}
620 705
@@ -623,38 +708,58 @@ cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
623 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) 708 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
624{ 709{
625 struct crypt_kop kop; 710 struct crypt_kop kop;
626 int ret = 0; 711 int ret = 1;
712
713 /* Currently, we know we can do mod exp iff we can do any
714 * asymmetric operations at all.
715 */
716 if (cryptodev_asymfeat == 0) {
717 ret = BN_mod_exp(r, a, p, m, ctx);
718 return (ret);
719 }
627 720
628 memset(&kop, 0, sizeof kop); 721 memset(&kop, 0, sizeof kop);
629 kop.crk_op = CRK_MOD_EXP; 722 kop.crk_op = CRK_MOD_EXP;
630 723
631 /* inputs: a m p */ 724 /* inputs: a^p % m */
632 if (bn2crparam(a, &kop.crk_param[0])) 725 if (bn2crparam(a, &kop.crk_param[0]))
633 goto err; 726 goto err;
634 if (bn2crparam(m, &kop.crk_param[1])) 727 if (bn2crparam(p, &kop.crk_param[1]))
635 goto err; 728 goto err;
636 if (bn2crparam(p, &kop.crk_param[2])) 729 if (bn2crparam(m, &kop.crk_param[2]))
637 goto err; 730 goto err;
638 kop.crk_iparams = 3; 731 kop.crk_iparams = 3;
639 732
640 if (cryptodev_sym(&kop, r, NULL) == -1) { 733 if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL) == -1) {
641 ret = BN_mod_exp(r, a, p, m, ctx); 734 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
735 ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
642 } 736 }
643err: 737err:
644 zapparams(&kop); 738 zapparams(&kop);
645 return (ret); 739 return (ret);
646} 740}
647 741
742static int
743cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
744{
745 int r;
746 BN_CTX *ctx;
747
748 ctx = BN_CTX_new();
749 r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL);
750 BN_CTX_free(ctx);
751 return (r);
752}
648 753
649static int 754static int
650cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) 755cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
651{ 756{
652 struct crypt_kop kop; 757 struct crypt_kop kop;
653 int ret = 0; 758 int ret = 1;
654 759
655 if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { 760 if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
656 /* XXX 0 means failure?? */ 761 /* XXX 0 means failure?? */
657 goto err; 762 return (0);
658 } 763 }
659 764
660 memset(&kop, 0, sizeof kop); 765 memset(&kop, 0, sizeof kop);
@@ -674,9 +779,8 @@ cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
674 goto err; 779 goto err;
675 kop.crk_iparams = 6; 780 kop.crk_iparams = 6;
676 781
677 if (cryptodev_sym(&kop, r0, NULL) == -1) { 782 if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL) == -1) {
678 const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 783 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
679
680 ret = (*meth->rsa_mod_exp)(r0, I, rsa); 784 ret = (*meth->rsa_mod_exp)(r0, I, rsa);
681 } 785 }
682err: 786err:
@@ -690,8 +794,8 @@ static RSA_METHOD cryptodev_rsa = {
690 NULL, /* rsa_pub_dec */ 794 NULL, /* rsa_pub_dec */
691 NULL, /* rsa_priv_enc */ 795 NULL, /* rsa_priv_enc */
692 NULL, /* rsa_priv_dec */ 796 NULL, /* rsa_priv_dec */
693 cryptodev_rsa_mod_exp, /* rsa_mod_exp */ 797 NULL,
694 cryptodev_bn_mod_exp, /* bn_mod_exp */ 798 NULL,
695 NULL, /* init */ 799 NULL, /* init */
696 NULL, /* finish */ 800 NULL, /* finish */
697 0, /* flags */ 801 0, /* flags */
@@ -707,6 +811,38 @@ cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
707 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); 811 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
708} 812}
709 813
814static int
815cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
816 BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
817 BN_CTX *ctx, BN_MONT_CTX *mont)
818{
819 BIGNUM t2;
820 int ret = 0;
821
822 BN_init(&t2);
823
824 /* v = ( g^u1 * y^u2 mod p ) mod q */
825 /* let t1 = g ^ u1 mod p */
826 ret = 0;
827
828 if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont))
829 goto err;
830
831 /* let t2 = y ^ u2 mod p */
832 if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont))
833 goto err;
834 /* let u1 = t1 * t2 mod p */
835 if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx))
836 goto err;
837
838 BN_copy(t1,u1);
839
840 ret = 1;
841err:
842 BN_free(&t2);
843 return(ret);
844}
845
710static DSA_SIG * 846static DSA_SIG *
711cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) 847cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
712{ 848{
@@ -721,6 +857,7 @@ cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
721 goto err; 857 goto err;
722 } 858 }
723 859
860 printf("bar\n");
724 memset(&kop, 0, sizeof kop); 861 memset(&kop, 0, sizeof kop);
725 kop.crk_op = CRK_DSA_SIGN; 862 kop.crk_op = CRK_DSA_SIGN;
726 863
@@ -737,13 +874,13 @@ cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
737 goto err; 874 goto err;
738 kop.crk_iparams = 5; 875 kop.crk_iparams = 5;
739 876
740 if (cryptodev_sym(&kop, r, s) == 0) { 877 if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r,
878 BN_num_bytes(dsa->q), s) == 0) {
741 dsaret = DSA_SIG_new(); 879 dsaret = DSA_SIG_new();
742 dsaret->r = r; 880 dsaret->r = r;
743 dsaret->s = s; 881 dsaret->s = s;
744 } else { 882 } else {
745 const DSA_METHOD *meth = DSA_OpenSSL(); 883 const DSA_METHOD *meth = DSA_OpenSSL();
746
747 BN_free(r); 884 BN_free(r);
748 BN_free(s); 885 BN_free(s);
749 dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa); 886 dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
@@ -759,7 +896,7 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
759 DSA_SIG *sig, DSA *dsa) 896 DSA_SIG *sig, DSA *dsa)
760{ 897{
761 struct crypt_kop kop; 898 struct crypt_kop kop;
762 int dsaret = 0; 899 int dsaret = 1;
763 900
764 memset(&kop, 0, sizeof kop); 901 memset(&kop, 0, sizeof kop);
765 kop.crk_op = CRK_DSA_VERIFY; 902 kop.crk_op = CRK_DSA_VERIFY;
@@ -781,7 +918,7 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
781 goto err; 918 goto err;
782 kop.crk_iparams = 7; 919 kop.crk_iparams = 7;
783 920
784 if (cryptodev_sym(&kop, NULL, NULL) == 0) { 921 if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
785 dsaret = kop.crk_status; 922 dsaret = kop.crk_status;
786 } else { 923 } else {
787 const DSA_METHOD *meth = DSA_OpenSSL(); 924 const DSA_METHOD *meth = DSA_OpenSSL();
@@ -796,11 +933,11 @@ err:
796 933
797static DSA_METHOD cryptodev_dsa = { 934static DSA_METHOD cryptodev_dsa = {
798 "cryptodev DSA method", 935 "cryptodev DSA method",
799 cryptodev_dsa_do_sign, 936 NULL,
800 NULL, /* dsa_sign_setup */ 937 NULL, /* dsa_sign_setup */
801 cryptodev_dsa_verify, 938 NULL,
802 NULL, /* dsa_mod_exp */ 939 NULL, /* dsa_mod_exp */
803 cryptodev_dsa_bn_mod_exp, /* bn_mod_exp */ 940 NULL,
804 NULL, /* init */ 941 NULL, /* init */
805 NULL, /* finish */ 942 NULL, /* finish */
806 0, /* flags */ 943 0, /* flags */
@@ -819,8 +956,14 @@ static int
819cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) 956cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
820{ 957{
821 struct crypt_kop kop; 958 struct crypt_kop kop;
822 int dhret = 0; 959 int dhret = 1;
823 int keylen; 960 int fd, keylen;
961
962 if ((fd = get_asym_dev_crypto()) < 0) {
963 const DH_METHOD *meth = DH_OpenSSL();
964
965 return ((meth->compute_key)(key, pub_key, dh));
966 }
824 967
825 keylen = BN_num_bits(dh->p); 968 keylen = BN_num_bits(dh->p);
826 969
@@ -840,7 +983,7 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
840 kop.crk_param[3].crp_nbits = keylen * 8; 983 kop.crk_param[3].crp_nbits = keylen * 8;
841 kop.crk_oparams = 1; 984 kop.crk_oparams = 1;
842 985
843 if (ioctl(cryptodev_fd, CIOCKEY, &kop) == -1) { 986 if (ioctl(fd, CIOCKEY, &kop) == -1) {
844 const DH_METHOD *meth = DH_OpenSSL(); 987 const DH_METHOD *meth = DH_OpenSSL();
845 988
846 dhret = (meth->compute_key)(key, pub_key, dh); 989 dhret = (meth->compute_key)(key, pub_key, dh);
@@ -854,8 +997,8 @@ err:
854static DH_METHOD cryptodev_dh = { 997static DH_METHOD cryptodev_dh = {
855 "cryptodev DH method", 998 "cryptodev DH method",
856 NULL, /* cryptodev_dh_generate_key */ 999 NULL, /* cryptodev_dh_generate_key */
857 cryptodev_dh_compute_key, 1000 NULL,
858 cryptodev_mod_exp_dh, 1001 NULL,
859 NULL, 1002 NULL,
860 NULL, 1003 NULL,
861 0, /* flags */ 1004 0, /* flags */
@@ -884,11 +1027,21 @@ void
884ENGINE_load_cryptodev(void) 1027ENGINE_load_cryptodev(void)
885{ 1028{
886 ENGINE *engine = ENGINE_new(); 1029 ENGINE *engine = ENGINE_new();
887 const RSA_METHOD *rsa_meth; 1030 int fd;
888 const DH_METHOD *dh_meth;
889 1031
890 if (engine == NULL) 1032 if (engine == NULL)
891 return; 1033 return;
1034 if ((fd = get_dev_crypto()) < 0)
1035 return;
1036
1037 /*
1038 * find out what asymmetric crypto algorithms we support
1039 */
1040 if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
1041 close(fd);
1042 return;
1043 }
1044 close(fd);
892 1045
893 if (!ENGINE_set_id(engine, "cryptodev") || 1046 if (!ENGINE_set_id(engine, "cryptodev") ||
894 !ENGINE_set_name(engine, "OpenBSD cryptodev engine") || 1047 !ENGINE_set_name(engine, "OpenBSD cryptodev engine") ||
@@ -900,24 +1053,52 @@ ENGINE_load_cryptodev(void)
900 return; 1053 return;
901 } 1054 }
902 1055
903 if ((cryptodev_symfeat & CRSFEAT_RSA) && 1056 if (ENGINE_set_RSA(engine, &cryptodev_rsa)) {
904 ENGINE_set_RSA(engine, &cryptodev_rsa)) { 1057 const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay();
905 rsa_meth = RSA_PKCS1_SSLeay(); 1058
1059 cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp;
1060 cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp;
906 cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc; 1061 cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc;
907 cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec; 1062 cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec;
908 cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_dec; 1063 cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc;
909 cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec; 1064 cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec;
1065 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1066 cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp;
1067 if (cryptodev_asymfeat & CRF_MOD_EXP_CRT)
1068 cryptodev_rsa.rsa_mod_exp =
1069 cryptodev_rsa_mod_exp;
1070 else
1071 cryptodev_rsa.rsa_mod_exp =
1072 cryptodev_rsa_nocrt_mod_exp;
1073 }
910 } 1074 }
911 1075
912 if ((cryptodev_symfeat & CRSFEAT_DSA) && 1076 if (ENGINE_set_DSA(engine, &cryptodev_dsa)) {
913 ENGINE_set_DSA(engine, &cryptodev_dsa)) { 1077 const DSA_METHOD *meth = DSA_OpenSSL();
1078
1079 memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
1080 if (cryptodev_asymfeat & CRF_DSA_SIGN)
1081 cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
1082 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1083 cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp;
1084 cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp;
1085 }
1086 if (cryptodev_asymfeat & CRF_DSA_VERIFY)
1087 cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
914 } 1088 }
915 1089
916 if ((cryptodev_symfeat & CRSFEAT_DH) && 1090 if (ENGINE_set_DH(engine, &cryptodev_dh)){
917 ENGINE_set_DH(engine, &cryptodev_dh)) { 1091 const DH_METHOD *dh_meth = DH_OpenSSL();
918 dh_meth = DH_OpenSSL(); 1092
919 cryptodev_dh.generate_key = dh_meth->generate_key; 1093 cryptodev_dh.generate_key = dh_meth->generate_key;
920 cryptodev_dh.compute_key = dh_meth->compute_key; 1094 cryptodev_dh.compute_key = dh_meth->compute_key;
1095 cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp;
1096 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1097 cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh;
1098 if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
1099 cryptodev_dh.compute_key =
1100 cryptodev_dh_compute_key;
1101 }
921 } 1102 }
922 1103
923 ENGINE_add(engine); 1104 ENGINE_add(engine);
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_ubsec.c b/src/lib/libcrypto/engine/hw_ubsec.c
index ed8401ec16..63397f868c 100644
--- a/src/lib/libcrypto/engine/hw_ubsec.c
+++ b/src/lib/libcrypto/engine/hw_ubsec.c
@@ -93,7 +93,7 @@ static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
93static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 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); 94 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
95#ifndef OPENSSL_NO_DSA 95#ifndef OPENSSL_NO_DSA
96#ifdef NOT_USED 96#if NOT_USED
97static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, 97static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
98 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, 98 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
99 BN_CTX *ctx, BN_MONT_CTX *in_mont); 99 BN_CTX *ctx, BN_MONT_CTX *in_mont);
@@ -113,7 +113,7 @@ static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh)
113static int ubsec_dh_generate_key(DH *dh); 113static int ubsec_dh_generate_key(DH *dh);
114#endif 114#endif
115 115
116#ifdef NOT_USED 116#if NOT_USED
117static int ubsec_rand_bytes(unsigned char *buf, int num); 117static int ubsec_rand_bytes(unsigned char *buf, int num);
118static int ubsec_rand_status(void); 118static int ubsec_rand_status(void);
119#endif 119#endif
@@ -663,7 +663,7 @@ static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
663} 663}
664 664
665#ifndef OPENSSL_NO_DSA 665#ifndef OPENSSL_NO_DSA
666#ifdef NOT_USED 666#if NOT_USED
667static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, 667static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
668 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, 668 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
669 BN_CTX *ctx, BN_MONT_CTX *in_mont) 669 BN_CTX *ctx, BN_MONT_CTX *in_mont)
@@ -987,7 +987,7 @@ err:
987 } 987 }
988#endif 988#endif
989 989
990#ifdef NOT_USED 990#if NOT_USED
991static int ubsec_rand_bytes(unsigned char * buf, 991static int ubsec_rand_bytes(unsigned char * buf,
992 int num) 992 int num)
993 { 993 {
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 }