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/Makefile417
-rw-r--r--src/lib/libcrypto/engine/Makefile.ssl538
-rw-r--r--src/lib/libcrypto/engine/README211
-rw-r--r--src/lib/libcrypto/engine/eng_aesni.c570
-rw-r--r--src/lib/libcrypto/engine/eng_all.c131
-rw-r--r--src/lib/libcrypto/engine/eng_cnf.c259
-rw-r--r--src/lib/libcrypto/engine/eng_cryptodev.c1418
-rw-r--r--src/lib/libcrypto/engine/eng_ctrl.c389
-rw-r--r--src/lib/libcrypto/engine/eng_dyn.c548
-rw-r--r--src/lib/libcrypto/engine/eng_err.c173
-rw-r--r--src/lib/libcrypto/engine/eng_fat.c181
-rw-r--r--src/lib/libcrypto/engine/eng_init.c154
-rw-r--r--src/lib/libcrypto/engine/eng_int.h206
-rw-r--r--src/lib/libcrypto/engine/eng_lib.c332
-rw-r--r--src/lib/libcrypto/engine/eng_list.c433
-rw-r--r--src/lib/libcrypto/engine/eng_openssl.c384
-rw-r--r--src/lib/libcrypto/engine/eng_padlock.c1219
-rw-r--r--src/lib/libcrypto/engine/eng_pkey.c196
-rw-r--r--src/lib/libcrypto/engine/eng_table.c351
-rw-r--r--src/lib/libcrypto/engine/engine.h834
-rw-r--r--src/lib/libcrypto/engine/enginetest.c283
-rw-r--r--src/lib/libcrypto/engine/hw_cryptodev.c1367
-rw-r--r--src/lib/libcrypto/engine/hw_openbsd_dev_crypto.c594
-rw-r--r--src/lib/libcrypto/engine/tb_asnmth.c246
-rw-r--r--src/lib/libcrypto/engine/tb_cipher.c143
-rw-r--r--src/lib/libcrypto/engine/tb_dh.c118
-rw-r--r--src/lib/libcrypto/engine/tb_digest.c143
-rw-r--r--src/lib/libcrypto/engine/tb_dsa.c118
-rw-r--r--src/lib/libcrypto/engine/tb_ecdh.c133
-rw-r--r--src/lib/libcrypto/engine/tb_ecdsa.c118
-rw-r--r--src/lib/libcrypto/engine/tb_pkmeth.c167
-rw-r--r--src/lib/libcrypto/engine/tb_rand.c118
-rw-r--r--src/lib/libcrypto/engine/tb_rsa.c118
-rw-r--r--src/lib/libcrypto/engine/tb_store.c123
34 files changed, 11601 insertions, 1132 deletions
diff --git a/src/lib/libcrypto/engine/Makefile b/src/lib/libcrypto/engine/Makefile
new file mode 100644
index 0000000000..9c214824eb
--- /dev/null
+++ b/src/lib/libcrypto/engine/Makefile
@@ -0,0 +1,417 @@
1#
2# OpenSSL/crypto/engine/Makefile
3#
4
5DIR= engine
6TOP= ../..
7CC= cc
8INCLUDES= -I.. -I$(TOP) -I../../include
9CFLAG=-g
10MAKEFILE= Makefile
11AR= ar r
12
13CFLAGS= $(INCLUDES) $(CFLAG)
14
15GENERAL=Makefile
16TEST= enginetest.c
17APPS=
18
19LIB=$(TOP)/libcrypto.a
20LIBSRC= eng_err.c eng_lib.c eng_list.c eng_init.c eng_ctrl.c \
21 eng_table.c eng_pkey.c eng_fat.c eng_all.c \
22 tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
23 tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c \
24 eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c
25LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
26 eng_table.o eng_pkey.o eng_fat.o eng_all.o \
27 tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
28 tb_cipher.o tb_digest.o tb_pkmeth.o tb_asnmth.o \
29 eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o
30
31SRC= $(LIBSRC)
32
33EXHEADER= engine.h
34HEADER= $(EXHEADER)
35
36ALL= $(GENERAL) $(SRC) $(HEADER)
37
38top:
39 (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
40
41all: lib
42
43lib: $(LIBOBJ)
44 $(AR) $(LIB) $(LIBOBJ)
45 $(RANLIB) $(LIB) || echo Never mind.
46 @touch lib
47
48files:
49 $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
50
51links:
52 @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
53 @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
54 @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
55
56install:
57 @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
58 @headerlist="$(EXHEADER)"; for i in $$headerlist ; \
59 do \
60 (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
61 chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
62 done;
63
64tags:
65 ctags $(SRC)
66
67tests:
68
69lint:
70 lint -DLINT $(INCLUDES) $(SRC)>fluff
71
72depend:
73 @[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
74 $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
75
76dclean:
77 $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
78 mv -f Makefile.new $(MAKEFILE)
79
80clean:
81 rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
82
83# DO NOT DELETE THIS LINE -- make depend depends on it.
84
85eng_all.o: ../../e_os.h ../../include/openssl/asn1.h
86eng_all.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
87eng_all.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
88eng_all.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
89eng_all.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
90eng_all.o: ../../include/openssl/err.h ../../include/openssl/evp.h
91eng_all.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
92eng_all.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
93eng_all.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
94eng_all.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
95eng_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
96eng_all.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
97eng_all.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_all.c eng_int.h
98eng_cnf.o: ../../e_os.h ../../include/openssl/asn1.h
99eng_cnf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
100eng_cnf.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
101eng_cnf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
102eng_cnf.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
103eng_cnf.o: ../../include/openssl/engine.h ../../include/openssl/err.h
104eng_cnf.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
105eng_cnf.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
106eng_cnf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
107eng_cnf.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
108eng_cnf.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
109eng_cnf.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
110eng_cnf.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
111eng_cnf.o: ../cryptlib.h eng_cnf.c eng_int.h
112eng_cryptodev.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
113eng_cryptodev.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
114eng_cryptodev.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
115eng_cryptodev.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
116eng_cryptodev.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
117eng_cryptodev.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
118eng_cryptodev.o: ../../include/openssl/obj_mac.h
119eng_cryptodev.o: ../../include/openssl/objects.h
120eng_cryptodev.o: ../../include/openssl/opensslconf.h
121eng_cryptodev.o: ../../include/openssl/opensslv.h
122eng_cryptodev.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
123eng_cryptodev.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
124eng_cryptodev.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
125eng_cryptodev.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
126eng_cryptodev.o: eng_cryptodev.c
127eng_ctrl.o: ../../e_os.h ../../include/openssl/asn1.h
128eng_ctrl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
129eng_ctrl.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
130eng_ctrl.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
131eng_ctrl.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
132eng_ctrl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
133eng_ctrl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
134eng_ctrl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
135eng_ctrl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
136eng_ctrl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
137eng_ctrl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
138eng_ctrl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
139eng_ctrl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_ctrl.c eng_int.h
140eng_dyn.o: ../../e_os.h ../../include/openssl/asn1.h
141eng_dyn.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
142eng_dyn.o: ../../include/openssl/crypto.h ../../include/openssl/dso.h
143eng_dyn.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
144eng_dyn.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
145eng_dyn.o: ../../include/openssl/engine.h ../../include/openssl/err.h
146eng_dyn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
147eng_dyn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
148eng_dyn.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
149eng_dyn.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
150eng_dyn.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
151eng_dyn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
152eng_dyn.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
153eng_dyn.o: ../cryptlib.h eng_dyn.c eng_int.h
154eng_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
155eng_err.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
156eng_err.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
157eng_err.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
158eng_err.o: ../../include/openssl/engine.h ../../include/openssl/err.h
159eng_err.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
160eng_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
161eng_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
162eng_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
163eng_err.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
164eng_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
165eng_err.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
166eng_err.o: eng_err.c
167eng_fat.o: ../../e_os.h ../../include/openssl/asn1.h
168eng_fat.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
169eng_fat.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
170eng_fat.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
171eng_fat.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
172eng_fat.o: ../../include/openssl/engine.h ../../include/openssl/err.h
173eng_fat.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
174eng_fat.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
175eng_fat.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
176eng_fat.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
177eng_fat.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
178eng_fat.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
179eng_fat.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
180eng_fat.o: ../cryptlib.h eng_fat.c eng_int.h
181eng_init.o: ../../e_os.h ../../include/openssl/asn1.h
182eng_init.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
183eng_init.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
184eng_init.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
185eng_init.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
186eng_init.o: ../../include/openssl/err.h ../../include/openssl/evp.h
187eng_init.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
188eng_init.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
189eng_init.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
190eng_init.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
191eng_init.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
192eng_init.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
193eng_init.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_init.c eng_int.h
194eng_lib.o: ../../e_os.h ../../include/openssl/asn1.h
195eng_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
196eng_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
197eng_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
198eng_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
199eng_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
200eng_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
201eng_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
202eng_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
203eng_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
204eng_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
205eng_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
206eng_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
207eng_lib.o: ../cryptlib.h eng_int.h eng_lib.c
208eng_list.o: ../../e_os.h ../../include/openssl/asn1.h
209eng_list.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
210eng_list.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
211eng_list.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
212eng_list.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
213eng_list.o: ../../include/openssl/err.h ../../include/openssl/evp.h
214eng_list.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
215eng_list.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
216eng_list.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
217eng_list.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
218eng_list.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
219eng_list.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
220eng_list.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h eng_list.c
221eng_openssl.o: ../../e_os.h ../../include/openssl/asn1.h
222eng_openssl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
223eng_openssl.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
224eng_openssl.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
225eng_openssl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
226eng_openssl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
227eng_openssl.o: ../../include/openssl/engine.h ../../include/openssl/err.h
228eng_openssl.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
229eng_openssl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
230eng_openssl.o: ../../include/openssl/opensslconf.h
231eng_openssl.o: ../../include/openssl/opensslv.h
232eng_openssl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
233eng_openssl.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
234eng_openssl.o: ../../include/openssl/rand.h ../../include/openssl/rc4.h
235eng_openssl.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
236eng_openssl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
237eng_openssl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
238eng_openssl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_openssl.c
239eng_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
240eng_pkey.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
241eng_pkey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
242eng_pkey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
243eng_pkey.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
244eng_pkey.o: ../../include/openssl/err.h ../../include/openssl/evp.h
245eng_pkey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
246eng_pkey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
247eng_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
248eng_pkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
249eng_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
250eng_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
251eng_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h eng_pkey.c
252eng_table.o: ../../e_os.h ../../include/openssl/asn1.h
253eng_table.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
254eng_table.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
255eng_table.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
256eng_table.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
257eng_table.o: ../../include/openssl/err.h ../../include/openssl/evp.h
258eng_table.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
259eng_table.o: ../../include/openssl/objects.h
260eng_table.o: ../../include/openssl/opensslconf.h
261eng_table.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
262eng_table.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
263eng_table.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
264eng_table.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
265eng_table.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
266eng_table.o: eng_table.c
267tb_asnmth.o: ../../e_os.h ../../include/openssl/asn1.h
268tb_asnmth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
269tb_asnmth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
270tb_asnmth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
271tb_asnmth.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
272tb_asnmth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
273tb_asnmth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
274tb_asnmth.o: ../../include/openssl/objects.h
275tb_asnmth.o: ../../include/openssl/opensslconf.h
276tb_asnmth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
277tb_asnmth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
278tb_asnmth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
279tb_asnmth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
280tb_asnmth.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h
281tb_asnmth.o: eng_int.h tb_asnmth.c
282tb_cipher.o: ../../e_os.h ../../include/openssl/asn1.h
283tb_cipher.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
284tb_cipher.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
285tb_cipher.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
286tb_cipher.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
287tb_cipher.o: ../../include/openssl/err.h ../../include/openssl/evp.h
288tb_cipher.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
289tb_cipher.o: ../../include/openssl/objects.h
290tb_cipher.o: ../../include/openssl/opensslconf.h
291tb_cipher.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
292tb_cipher.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
293tb_cipher.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
294tb_cipher.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
295tb_cipher.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
296tb_cipher.o: tb_cipher.c
297tb_dh.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
298tb_dh.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
299tb_dh.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
300tb_dh.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
301tb_dh.o: ../../include/openssl/engine.h ../../include/openssl/err.h
302tb_dh.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
303tb_dh.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
304tb_dh.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
305tb_dh.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
306tb_dh.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
307tb_dh.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
308tb_dh.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
309tb_dh.o: ../cryptlib.h eng_int.h tb_dh.c
310tb_digest.o: ../../e_os.h ../../include/openssl/asn1.h
311tb_digest.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
312tb_digest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
313tb_digest.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
314tb_digest.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
315tb_digest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
316tb_digest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
317tb_digest.o: ../../include/openssl/objects.h
318tb_digest.o: ../../include/openssl/opensslconf.h
319tb_digest.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
320tb_digest.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
321tb_digest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
322tb_digest.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
323tb_digest.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
324tb_digest.o: tb_digest.c
325tb_dsa.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
326tb_dsa.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
327tb_dsa.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
328tb_dsa.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
329tb_dsa.o: ../../include/openssl/engine.h ../../include/openssl/err.h
330tb_dsa.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
331tb_dsa.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
332tb_dsa.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
333tb_dsa.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
334tb_dsa.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
335tb_dsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
336tb_dsa.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
337tb_dsa.o: ../cryptlib.h eng_int.h tb_dsa.c
338tb_ecdh.o: ../../e_os.h ../../include/openssl/asn1.h
339tb_ecdh.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
340tb_ecdh.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
341tb_ecdh.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
342tb_ecdh.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
343tb_ecdh.o: ../../include/openssl/err.h ../../include/openssl/evp.h
344tb_ecdh.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
345tb_ecdh.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
346tb_ecdh.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
347tb_ecdh.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
348tb_ecdh.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
349tb_ecdh.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
350tb_ecdh.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_ecdh.c
351tb_ecdsa.o: ../../e_os.h ../../include/openssl/asn1.h
352tb_ecdsa.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
353tb_ecdsa.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
354tb_ecdsa.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
355tb_ecdsa.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
356tb_ecdsa.o: ../../include/openssl/err.h ../../include/openssl/evp.h
357tb_ecdsa.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
358tb_ecdsa.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
359tb_ecdsa.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
360tb_ecdsa.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
361tb_ecdsa.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
362tb_ecdsa.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
363tb_ecdsa.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_ecdsa.c
364tb_pkmeth.o: ../../e_os.h ../../include/openssl/asn1.h
365tb_pkmeth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
366tb_pkmeth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
367tb_pkmeth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
368tb_pkmeth.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
369tb_pkmeth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
370tb_pkmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
371tb_pkmeth.o: ../../include/openssl/objects.h
372tb_pkmeth.o: ../../include/openssl/opensslconf.h
373tb_pkmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
374tb_pkmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
375tb_pkmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
376tb_pkmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
377tb_pkmeth.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
378tb_pkmeth.o: tb_pkmeth.c
379tb_rand.o: ../../e_os.h ../../include/openssl/asn1.h
380tb_rand.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
381tb_rand.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
382tb_rand.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
383tb_rand.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
384tb_rand.o: ../../include/openssl/err.h ../../include/openssl/evp.h
385tb_rand.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
386tb_rand.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
387tb_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
388tb_rand.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
389tb_rand.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
390tb_rand.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
391tb_rand.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_rand.c
392tb_rsa.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
393tb_rsa.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
394tb_rsa.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
395tb_rsa.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
396tb_rsa.o: ../../include/openssl/engine.h ../../include/openssl/err.h
397tb_rsa.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
398tb_rsa.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
399tb_rsa.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
400tb_rsa.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
401tb_rsa.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
402tb_rsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
403tb_rsa.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
404tb_rsa.o: ../cryptlib.h eng_int.h tb_rsa.c
405tb_store.o: ../../e_os.h ../../include/openssl/asn1.h
406tb_store.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
407tb_store.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
408tb_store.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
409tb_store.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
410tb_store.o: ../../include/openssl/err.h ../../include/openssl/evp.h
411tb_store.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
412tb_store.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
413tb_store.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
414tb_store.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
415tb_store.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
416tb_store.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
417tb_store.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_store.c
diff --git a/src/lib/libcrypto/engine/Makefile.ssl b/src/lib/libcrypto/engine/Makefile.ssl
deleted file mode 100644
index 30a4446ff9..0000000000
--- a/src/lib/libcrypto/engine/Makefile.ssl
+++ /dev/null
@@ -1,538 +0,0 @@
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) || echo Never mind.
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_cryptodev.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
308hw_cryptodev.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
309hw_cryptodev.o: ../../include/openssl/bn.h ../../include/openssl/cast.h
310hw_cryptodev.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
311hw_cryptodev.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
312hw_cryptodev.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
313hw_cryptodev.o: ../../include/openssl/engine.h ../../include/openssl/err.h
314hw_cryptodev.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
315hw_cryptodev.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
316hw_cryptodev.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
317hw_cryptodev.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
318hw_cryptodev.o: ../../include/openssl/objects.h
319hw_cryptodev.o: ../../include/openssl/opensslconf.h
320hw_cryptodev.o: ../../include/openssl/opensslv.h
321hw_cryptodev.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
322hw_cryptodev.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
323hw_cryptodev.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
324hw_cryptodev.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
325hw_cryptodev.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
326hw_cryptodev.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
327hw_cryptodev.o: ../../include/openssl/ui_compat.h hw_cryptodev.c
328hw_cswift.o: ../../e_os.h ../../include/openssl/asn1.h
329hw_cswift.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
330hw_cswift.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
331hw_cswift.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
332hw_cswift.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
333hw_cswift.o: ../../include/openssl/engine.h ../../include/openssl/err.h
334hw_cswift.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
335hw_cswift.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
336hw_cswift.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
337hw_cswift.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
338hw_cswift.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
339hw_cswift.o: ../cryptlib.h hw_cswift.c hw_cswift_err.c hw_cswift_err.h
340hw_cswift.o: vendor_defns/cswift.h
341hw_ncipher.o: ../../e_os.h ../../include/openssl/aes.h
342hw_ncipher.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
343hw_ncipher.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
344hw_ncipher.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
345hw_ncipher.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
346hw_ncipher.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
347hw_ncipher.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
348hw_ncipher.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
349hw_ncipher.o: ../../include/openssl/err.h ../../include/openssl/evp.h
350hw_ncipher.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
351hw_ncipher.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
352hw_ncipher.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
353hw_ncipher.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
354hw_ncipher.o: ../../include/openssl/opensslconf.h
355hw_ncipher.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
356hw_ncipher.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
357hw_ncipher.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
358hw_ncipher.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
359hw_ncipher.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
360hw_ncipher.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
361hw_ncipher.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
362hw_ncipher.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
363hw_ncipher.o: ../../include/openssl/ui_compat.h ../../include/openssl/x509.h
364hw_ncipher.o: ../../include/openssl/x509_vfy.h ../cryptlib.h hw_ncipher.c
365hw_ncipher.o: hw_ncipher_err.c hw_ncipher_err.h vendor_defns/hwcryptohook.h
366hw_nuron.o: ../../e_os.h ../../include/openssl/asn1.h
367hw_nuron.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
368hw_nuron.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
369hw_nuron.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
370hw_nuron.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
371hw_nuron.o: ../../include/openssl/engine.h ../../include/openssl/err.h
372hw_nuron.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
373hw_nuron.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
374hw_nuron.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
375hw_nuron.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
376hw_nuron.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
377hw_nuron.o: ../cryptlib.h hw_nuron.c hw_nuron_err.c hw_nuron_err.h
378hw_sureware.o: ../../e_os.h ../../include/openssl/aes.h
379hw_sureware.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
380hw_sureware.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
381hw_sureware.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
382hw_sureware.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
383hw_sureware.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
384hw_sureware.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
385hw_sureware.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
386hw_sureware.o: ../../include/openssl/err.h ../../include/openssl/evp.h
387hw_sureware.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
388hw_sureware.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
389hw_sureware.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
390hw_sureware.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
391hw_sureware.o: ../../include/openssl/opensslconf.h
392hw_sureware.o: ../../include/openssl/opensslv.h
393hw_sureware.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
394hw_sureware.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
395hw_sureware.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
396hw_sureware.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
397hw_sureware.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
398hw_sureware.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
399hw_sureware.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
400hw_sureware.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
401hw_sureware.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
402hw_sureware.o: ../cryptlib.h eng_int.h engine.h hw_sureware.c hw_sureware_err.c
403hw_sureware.o: hw_sureware_err.h vendor_defns/sureware.h
404hw_ubsec.o: ../../e_os.h ../../include/openssl/asn1.h
405hw_ubsec.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
406hw_ubsec.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
407hw_ubsec.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
408hw_ubsec.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
409hw_ubsec.o: ../../include/openssl/engine.h ../../include/openssl/err.h
410hw_ubsec.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
411hw_ubsec.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
412hw_ubsec.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
413hw_ubsec.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
414hw_ubsec.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
415hw_ubsec.o: ../cryptlib.h hw_ubsec.c hw_ubsec_err.c hw_ubsec_err.h
416hw_ubsec.o: vendor_defns/hw_ubsec.h
417tb_cipher.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
418tb_cipher.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
419tb_cipher.o: ../../include/openssl/bn.h ../../include/openssl/cast.h
420tb_cipher.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
421tb_cipher.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
422tb_cipher.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
423tb_cipher.o: ../../include/openssl/engine.h ../../include/openssl/err.h
424tb_cipher.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
425tb_cipher.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
426tb_cipher.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
427tb_cipher.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
428tb_cipher.o: ../../include/openssl/objects.h
429tb_cipher.o: ../../include/openssl/opensslconf.h
430tb_cipher.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
431tb_cipher.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
432tb_cipher.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
433tb_cipher.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
434tb_cipher.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
435tb_cipher.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
436tb_cipher.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
437tb_cipher.o: eng_int.h tb_cipher.c
438tb_dh.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
439tb_dh.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
440tb_dh.o: ../../include/openssl/bn.h ../../include/openssl/cast.h
441tb_dh.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
442tb_dh.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
443tb_dh.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
444tb_dh.o: ../../include/openssl/engine.h ../../include/openssl/err.h
445tb_dh.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
446tb_dh.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
447tb_dh.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
448tb_dh.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
449tb_dh.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
450tb_dh.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
451tb_dh.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
452tb_dh.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
453tb_dh.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
454tb_dh.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
455tb_dh.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
456tb_dh.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h eng_int.h
457tb_dh.o: tb_dh.c
458tb_digest.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
459tb_digest.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
460tb_digest.o: ../../include/openssl/bn.h ../../include/openssl/cast.h
461tb_digest.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
462tb_digest.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
463tb_digest.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
464tb_digest.o: ../../include/openssl/engine.h ../../include/openssl/err.h
465tb_digest.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
466tb_digest.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
467tb_digest.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
468tb_digest.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
469tb_digest.o: ../../include/openssl/objects.h
470tb_digest.o: ../../include/openssl/opensslconf.h
471tb_digest.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
472tb_digest.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
473tb_digest.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
474tb_digest.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
475tb_digest.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
476tb_digest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
477tb_digest.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
478tb_digest.o: eng_int.h tb_digest.c
479tb_dsa.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
480tb_dsa.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
481tb_dsa.o: ../../include/openssl/bn.h ../../include/openssl/cast.h
482tb_dsa.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
483tb_dsa.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
484tb_dsa.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
485tb_dsa.o: ../../include/openssl/engine.h ../../include/openssl/err.h
486tb_dsa.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
487tb_dsa.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
488tb_dsa.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
489tb_dsa.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
490tb_dsa.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
491tb_dsa.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
492tb_dsa.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
493tb_dsa.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
494tb_dsa.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
495tb_dsa.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
496tb_dsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
497tb_dsa.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
498tb_dsa.o: eng_int.h tb_dsa.c
499tb_rand.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
500tb_rand.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
501tb_rand.o: ../../include/openssl/bn.h ../../include/openssl/cast.h
502tb_rand.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
503tb_rand.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
504tb_rand.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
505tb_rand.o: ../../include/openssl/engine.h ../../include/openssl/err.h
506tb_rand.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
507tb_rand.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
508tb_rand.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
509tb_rand.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
510tb_rand.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
511tb_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
512tb_rand.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
513tb_rand.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
514tb_rand.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
515tb_rand.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
516tb_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
517tb_rand.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
518tb_rand.o: eng_int.h tb_rand.c
519tb_rsa.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
520tb_rsa.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
521tb_rsa.o: ../../include/openssl/bn.h ../../include/openssl/cast.h
522tb_rsa.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
523tb_rsa.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
524tb_rsa.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
525tb_rsa.o: ../../include/openssl/engine.h ../../include/openssl/err.h
526tb_rsa.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
527tb_rsa.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
528tb_rsa.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
529tb_rsa.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
530tb_rsa.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
531tb_rsa.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
532tb_rsa.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
533tb_rsa.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
534tb_rsa.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
535tb_rsa.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
536tb_rsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
537tb_rsa.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
538tb_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_aesni.c b/src/lib/libcrypto/engine/eng_aesni.c
new file mode 100644
index 0000000000..5fdb33bfde
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_aesni.c
@@ -0,0 +1,570 @@
1/*
2 * Support for Intel AES-NI intruction set
3 * Author: Huang Ying <ying.huang@intel.com>
4 *
5 * Intel AES-NI is a new set of Single Instruction Multiple Data
6 * (SIMD) instructions that are going to be introduced in the next
7 * generation of Intel processor, as of 2009. These instructions
8 * enable fast and secure data encryption and decryption, using the
9 * Advanced Encryption Standard (AES), defined by FIPS Publication
10 * number 197. The architecture introduces six instructions that
11 * offer full hardware support for AES. Four of them support high
12 * performance data encryption and decryption, and the other two
13 * instructions support the AES key expansion procedure.
14 *
15 * The white paper can be downloaded from:
16 * http://softwarecommunity.intel.com/isn/downloads/intelavx/AES-Instructions-Set_WP.pdf
17 *
18 * This file is based on engines/e_padlock.c
19 */
20
21/* ====================================================================
22 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
23 *
24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions
26 * are met:
27 *
28 * 1. Redistributions of source code must retain the above copyright
29 * notice, this list of conditions and the following disclaimer.
30 *
31 * 2. Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in
33 * the documentation and/or other materials provided with the
34 * distribution.
35 *
36 * 3. All advertising materials mentioning features or use of this
37 * software must display the following acknowledgment:
38 * "This product includes software developed by the OpenSSL Project
39 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
40 *
41 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
42 * endorse or promote products derived from this software without
43 * prior written permission. For written permission, please contact
44 * licensing@OpenSSL.org.
45 *
46 * 5. Products derived from this software may not be called "OpenSSL"
47 * nor may "OpenSSL" appear in their names without prior written
48 * permission of the OpenSSL Project.
49 *
50 * 6. Redistributions of any form whatsoever must retain the following
51 * acknowledgment:
52 * "This product includes software developed by the OpenSSL Project
53 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
54 *
55 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
56 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
58 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
59 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
60 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
61 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
64 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
65 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
66 * OF THE POSSIBILITY OF SUCH DAMAGE.
67 * ====================================================================
68 *
69 * This product includes cryptographic software written by Eric Young
70 * (eay@cryptsoft.com). This product includes software written by Tim
71 * Hudson (tjh@cryptsoft.com).
72 *
73 */
74
75
76#include <openssl/opensslconf.h>
77
78#if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_AES_NI) && !defined(OPENSSL_NO_AES)
79
80#include <stdio.h>
81#include <assert.h>
82#include "cryptlib.h"
83#include <openssl/dso.h>
84#include <openssl/engine.h>
85#include <openssl/evp.h>
86#include <openssl/aes.h>
87#include <openssl/err.h>
88
89/* AES-NI is available *ONLY* on some x86 CPUs. Not only that it
90 doesn't exist elsewhere, but it even can't be compiled on other
91 platforms! */
92#undef COMPILE_HW_AESNI
93#if (defined(__x86_64) || defined(__x86_64__) || \
94 defined(_M_AMD64) || defined(_M_X64) || \
95 defined(OPENSSL_IA32_SSE2)) && !defined(OPENSSL_NO_ASM) && !defined(__i386__)
96#define COMPILE_HW_AESNI
97#endif
98static ENGINE *ENGINE_aesni (void);
99
100void ENGINE_load_aesni (void)
101{
102/* On non-x86 CPUs it just returns. */
103#ifdef COMPILE_HW_AESNI
104 ENGINE *toadd = ENGINE_aesni();
105 if (!toadd) return;
106 ENGINE_add (toadd);
107 ENGINE_register_complete (toadd);
108 ENGINE_free (toadd);
109 ERR_clear_error ();
110#endif
111}
112
113#ifdef COMPILE_HW_AESNI
114int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
115 AES_KEY *key);
116int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
117 AES_KEY *key);
118
119void aesni_encrypt(const unsigned char *in, unsigned char *out,
120 const AES_KEY *key);
121void aesni_decrypt(const unsigned char *in, unsigned char *out,
122 const AES_KEY *key);
123
124void aesni_ecb_encrypt(const unsigned char *in,
125 unsigned char *out,
126 size_t length,
127 const AES_KEY *key,
128 int enc);
129void aesni_cbc_encrypt(const unsigned char *in,
130 unsigned char *out,
131 size_t length,
132 const AES_KEY *key,
133 unsigned char *ivec, int enc);
134
135/* Function for ENGINE detection and control */
136static int aesni_init(ENGINE *e);
137
138/* Cipher Stuff */
139static int aesni_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
140 const int **nids, int nid);
141
142#define AESNI_MIN_ALIGN 16
143#define AESNI_ALIGN(x) \
144 ((void *)(((unsigned long)(x)+AESNI_MIN_ALIGN-1)&~(AESNI_MIN_ALIGN-1)))
145
146/* Engine names */
147static const char aesni_id[] = "aesni",
148 aesni_name[] = "Intel AES-NI engine",
149 no_aesni_name[] = "Intel AES-NI engine (no-aesni)";
150
151
152/* The input and output encrypted as though 128bit cfb mode is being
153 * used. The extra state information to record how much of the
154 * 128bit block we have used is contained in *num;
155 */
156static void aesni_cfb128_encrypt(const unsigned char *in, unsigned char *out,
157 unsigned int len, const void *key,
158 unsigned char ivec[16], int *num,
159 int enc)
160{
161 unsigned int n;
162 size_t l = 0;
163
164 assert(in && out && key && ivec && num);
165
166 n = *num;
167
168 if (enc) {
169#if !defined(OPENSSL_SMALL_FOOTPRINT)
170 if (16%sizeof(size_t) == 0) do { /* always true actually */
171 while (n && len) {
172 *(out++) = ivec[n] ^= *(in++);
173 --len;
174 n = (n+1) % 16;
175 }
176 while (len>=16) {
177 aesni_encrypt(ivec, ivec, key);
178 for (n=0; n<16; n+=sizeof(size_t)) {
179 *(size_t*)(out+n) =
180 *(size_t*)(ivec+n) ^= *(size_t*)(in+n);
181 }
182 len -= 16;
183 out += 16;
184 in += 16;
185 }
186 n = 0;
187 if (len) {
188 aesni_encrypt(ivec, ivec, key);
189 while (len--) {
190 out[n] = ivec[n] ^= in[n];
191 ++n;
192 }
193 }
194 *num = n;
195 return;
196 } while (0);
197 /* the rest would be commonly eliminated by x86* compiler */
198#endif
199 while (l<len) {
200 if (n == 0) {
201 aesni_encrypt(ivec, ivec, key);
202 }
203 out[l] = ivec[n] ^= in[l];
204 ++l;
205 n = (n+1) % 16;
206 }
207 *num = n;
208 } else {
209#if !defined(OPENSSL_SMALL_FOOTPRINT)
210 if (16%sizeof(size_t) == 0) do { /* always true actually */
211 while (n && len) {
212 unsigned char c;
213 *(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c;
214 --len;
215 n = (n+1) % 16;
216 }
217 while (len>=16) {
218 aesni_encrypt(ivec, ivec, key);
219 for (n=0; n<16; n+=sizeof(size_t)) {
220 size_t t = *(size_t*)(in+n);
221 *(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t;
222 *(size_t*)(ivec+n) = t;
223 }
224 len -= 16;
225 out += 16;
226 in += 16;
227 }
228 n = 0;
229 if (len) {
230 aesni_encrypt(ivec, ivec, key);
231 while (len--) {
232 unsigned char c;
233 out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c;
234 ++n;
235 }
236 }
237 *num = n;
238 return;
239 } while (0);
240 /* the rest would be commonly eliminated by x86* compiler */
241#endif
242 while (l<len) {
243 unsigned char c;
244 if (n == 0) {
245 aesni_encrypt(ivec, ivec, key);
246 }
247 out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c;
248 ++l;
249 n = (n+1) % 16;
250 }
251 *num=n;
252 }
253}
254
255/* The input and output encrypted as though 128bit ofb mode is being
256 * used. The extra state information to record how much of the
257 * 128bit block we have used is contained in *num;
258 */
259static void aesni_ofb128_encrypt(const unsigned char *in, unsigned char *out,
260 unsigned int len, const void *key,
261 unsigned char ivec[16], int *num)
262{
263 unsigned int n;
264 size_t l=0;
265
266 assert(in && out && key && ivec && num);
267
268 n = *num;
269
270#if !defined(OPENSSL_SMALL_FOOTPRINT)
271 if (16%sizeof(size_t) == 0) do { /* always true actually */
272 while (n && len) {
273 *(out++) = *(in++) ^ ivec[n];
274 --len;
275 n = (n+1) % 16;
276 }
277 while (len>=16) {
278 aesni_encrypt(ivec, ivec, key);
279 for (n=0; n<16; n+=sizeof(size_t))
280 *(size_t*)(out+n) =
281 *(size_t*)(in+n) ^ *(size_t*)(ivec+n);
282 len -= 16;
283 out += 16;
284 in += 16;
285 }
286 n = 0;
287 if (len) {
288 aesni_encrypt(ivec, ivec, key);
289 while (len--) {
290 out[n] = in[n] ^ ivec[n];
291 ++n;
292 }
293 }
294 *num = n;
295 return;
296 } while(0);
297 /* the rest would be commonly eliminated by x86* compiler */
298#endif
299 while (l<len) {
300 if (n==0) {
301 aesni_encrypt(ivec, ivec, key);
302 }
303 out[l] = in[l] ^ ivec[n];
304 ++l;
305 n = (n+1) % 16;
306 }
307
308 *num=n;
309}
310/* ===== Engine "management" functions ===== */
311
312#if defined(_WIN32)
313typedef unsigned __int64 IA32CAP;
314#else
315typedef unsigned long long IA32CAP;
316#endif
317
318/* Prepare the ENGINE structure for registration */
319static int
320aesni_bind_helper(ENGINE *e)
321{
322 int engage;
323 if (sizeof(OPENSSL_ia32cap_P) > 4) {
324 engage = ((IA32CAP)OPENSSL_ia32cap_P >> 57) & 1;
325 } else {
326 IA32CAP OPENSSL_ia32_cpuid(void);
327 engage = (OPENSSL_ia32_cpuid() >> 57) & 1;
328 }
329
330 /* Register everything or return with an error */
331 if (!ENGINE_set_id(e, aesni_id) ||
332 !ENGINE_set_name(e, engage ? aesni_name : no_aesni_name) ||
333
334 !ENGINE_set_init_function(e, aesni_init) ||
335 (engage && !ENGINE_set_ciphers (e, aesni_ciphers))
336 )
337 return 0;
338
339 /* Everything looks good */
340 return 1;
341}
342
343/* Constructor */
344static ENGINE *
345ENGINE_aesni(void)
346{
347 ENGINE *eng = ENGINE_new();
348
349 if (!eng) {
350 return NULL;
351 }
352
353 if (!aesni_bind_helper(eng)) {
354 ENGINE_free(eng);
355 return NULL;
356 }
357
358 return eng;
359}
360
361/* Check availability of the engine */
362static int
363aesni_init(ENGINE *e)
364{
365 return 1;
366}
367
368#if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)
369#define NID_aes_128_cfb NID_aes_128_cfb128
370#endif
371
372#if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb)
373#define NID_aes_128_ofb NID_aes_128_ofb128
374#endif
375
376#if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb)
377#define NID_aes_192_cfb NID_aes_192_cfb128
378#endif
379
380#if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb)
381#define NID_aes_192_ofb NID_aes_192_ofb128
382#endif
383
384#if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb)
385#define NID_aes_256_cfb NID_aes_256_cfb128
386#endif
387
388#if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb)
389#define NID_aes_256_ofb NID_aes_256_ofb128
390#endif
391
392/* List of supported ciphers. */
393static int aesni_cipher_nids[] = {
394 NID_aes_128_ecb,
395 NID_aes_128_cbc,
396 NID_aes_128_cfb,
397 NID_aes_128_ofb,
398
399 NID_aes_192_ecb,
400 NID_aes_192_cbc,
401 NID_aes_192_cfb,
402 NID_aes_192_ofb,
403
404 NID_aes_256_ecb,
405 NID_aes_256_cbc,
406 NID_aes_256_cfb,
407 NID_aes_256_ofb,
408};
409static int aesni_cipher_nids_num =
410 (sizeof(aesni_cipher_nids)/sizeof(aesni_cipher_nids[0]));
411
412typedef struct
413{
414 AES_KEY ks;
415 unsigned int _pad1[3];
416} AESNI_KEY;
417
418static int
419aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *user_key,
420 const unsigned char *iv, int enc)
421{
422 int ret;
423 AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
424
425 if ((ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_CFB_MODE
426 || (ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_OFB_MODE
427 || enc)
428 ret=aesni_set_encrypt_key(user_key, ctx->key_len * 8, key);
429 else
430 ret=aesni_set_decrypt_key(user_key, ctx->key_len * 8, key);
431
432 if(ret < 0) {
433 EVPerr(EVP_F_AESNI_INIT_KEY,EVP_R_AES_KEY_SETUP_FAILED);
434 return 0;
435 }
436
437 return 1;
438}
439
440static int aesni_cipher_ecb(EVP_CIPHER_CTX *ctx, unsigned char *out,
441 const unsigned char *in, size_t inl)
442{ AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
443 aesni_ecb_encrypt(in, out, inl, key, ctx->encrypt);
444 return 1;
445}
446static int aesni_cipher_cbc(EVP_CIPHER_CTX *ctx, unsigned char *out,
447 const unsigned char *in, size_t inl)
448{ AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
449 aesni_cbc_encrypt(in, out, inl, key,
450 ctx->iv, ctx->encrypt);
451 return 1;
452}
453static int aesni_cipher_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
454 const unsigned char *in, size_t inl)
455{ AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
456
457 aesni_cfb128_encrypt(in, out, inl, key, ctx->iv,
458 &ctx->num, ctx->encrypt);
459 return 1;
460}
461static int aesni_cipher_ofb(EVP_CIPHER_CTX *ctx, unsigned char *out,
462 const unsigned char *in, size_t inl)
463{ AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
464 aesni_ofb128_encrypt(in, out, inl, key, ctx->iv, &ctx->num);
465 return 1;
466}
467
468#define AES_BLOCK_SIZE 16
469
470#define EVP_CIPHER_block_size_ECB AES_BLOCK_SIZE
471#define EVP_CIPHER_block_size_CBC AES_BLOCK_SIZE
472#define EVP_CIPHER_block_size_OFB 1
473#define EVP_CIPHER_block_size_CFB 1
474
475/* Declaring so many ciphers by hand would be a pain.
476 Instead introduce a bit of preprocessor magic :-) */
477#define DECLARE_AES_EVP(ksize,lmode,umode) \
478static const EVP_CIPHER aesni_##ksize##_##lmode = { \
479 NID_aes_##ksize##_##lmode, \
480 EVP_CIPHER_block_size_##umode, \
481 ksize / 8, \
482 AES_BLOCK_SIZE, \
483 0 | EVP_CIPH_##umode##_MODE, \
484 aesni_init_key, \
485 aesni_cipher_##lmode, \
486 NULL, \
487 sizeof(AESNI_KEY), \
488 EVP_CIPHER_set_asn1_iv, \
489 EVP_CIPHER_get_asn1_iv, \
490 NULL, \
491 NULL \
492}
493
494DECLARE_AES_EVP(128,ecb,ECB);
495DECLARE_AES_EVP(128,cbc,CBC);
496DECLARE_AES_EVP(128,cfb,CFB);
497DECLARE_AES_EVP(128,ofb,OFB);
498
499DECLARE_AES_EVP(192,ecb,ECB);
500DECLARE_AES_EVP(192,cbc,CBC);
501DECLARE_AES_EVP(192,cfb,CFB);
502DECLARE_AES_EVP(192,ofb,OFB);
503
504DECLARE_AES_EVP(256,ecb,ECB);
505DECLARE_AES_EVP(256,cbc,CBC);
506DECLARE_AES_EVP(256,cfb,CFB);
507DECLARE_AES_EVP(256,ofb,OFB);
508
509static int
510aesni_ciphers (ENGINE *e, const EVP_CIPHER **cipher,
511 const int **nids, int nid)
512{
513 /* No specific cipher => return a list of supported nids ... */
514 if (!cipher) {
515 *nids = aesni_cipher_nids;
516 return aesni_cipher_nids_num;
517 }
518
519 /* ... or the requested "cipher" otherwise */
520 switch (nid) {
521 case NID_aes_128_ecb:
522 *cipher = &aesni_128_ecb;
523 break;
524 case NID_aes_128_cbc:
525 *cipher = &aesni_128_cbc;
526 break;
527 case NID_aes_128_cfb:
528 *cipher = &aesni_128_cfb;
529 break;
530 case NID_aes_128_ofb:
531 *cipher = &aesni_128_ofb;
532 break;
533
534 case NID_aes_192_ecb:
535 *cipher = &aesni_192_ecb;
536 break;
537 case NID_aes_192_cbc:
538 *cipher = &aesni_192_cbc;
539 break;
540 case NID_aes_192_cfb:
541 *cipher = &aesni_192_cfb;
542 break;
543 case NID_aes_192_ofb:
544 *cipher = &aesni_192_ofb;
545 break;
546
547 case NID_aes_256_ecb:
548 *cipher = &aesni_256_ecb;
549 break;
550 case NID_aes_256_cbc:
551 *cipher = &aesni_256_cbc;
552 break;
553 case NID_aes_256_cfb:
554 *cipher = &aesni_256_cfb;
555 break;
556 case NID_aes_256_ofb:
557 *cipher = &aesni_256_ofb;
558 break;
559
560 default:
561 /* Sorry, we don't support this NID */
562 *cipher = NULL;
563 return 0;
564 }
565 return 1;
566}
567
568#endif /* COMPILE_HW_AESNI */
569#endif /* !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_AESNI) && !defined(OPENSSL_NO_AES) */
570
diff --git a/src/lib/libcrypto/engine/eng_all.c b/src/lib/libcrypto/engine/eng_all.c
new file mode 100644
index 0000000000..79d1f2beff
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_all.c
@@ -0,0 +1,131 @@
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 "cryptlib.h"
60#include "eng_int.h"
61
62void ENGINE_load_builtin_engines(void)
63 {
64#if 0
65 /* There's no longer any need for an "openssl" ENGINE unless, one day,
66 * it is the *only* way for standard builtin implementations to be be
67 * accessed (ie. it would be possible to statically link binaries with
68 * *no* builtin implementations). */
69 ENGINE_load_openssl();
70#endif
71#if !defined(OPENSSL_NO_HW) && (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
72 ENGINE_load_cryptodev();
73#endif
74
75#if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_AESNI)
76 ENGINE_load_aesni();
77#endif
78
79 ENGINE_load_dynamic();
80#ifndef OPENSSL_NO_STATIC_ENGINE
81#ifndef OPENSSL_NO_HW
82#ifndef OPENSSL_NO_HW_4758_CCA
83 ENGINE_load_4758cca();
84#endif
85#ifndef OPENSSL_NO_HW_AEP
86 ENGINE_load_aep();
87#endif
88#ifndef OPENSSL_NO_HW_ATALLA
89 ENGINE_load_atalla();
90#endif
91#ifndef OPENSSL_NO_HW_CSWIFT
92 ENGINE_load_cswift();
93#endif
94#ifndef OPENSSL_NO_HW_NCIPHER
95 ENGINE_load_chil();
96#endif
97#ifndef OPENSSL_NO_HW_NURON
98 ENGINE_load_nuron();
99#endif
100#ifndef OPENSSL_NO_HW_SUREWARE
101 ENGINE_load_sureware();
102#endif
103#ifndef OPENSSL_NO_HW_UBSEC
104 ENGINE_load_ubsec();
105#endif
106#ifndef OPENSSL_NO_HW_PADLOCK
107 ENGINE_load_padlock();
108#endif
109#endif
110#ifndef OPENSSL_NO_GOST
111 ENGINE_load_gost();
112#endif
113#ifndef OPENSSL_NO_GMP
114 ENGINE_load_gmp();
115#endif
116#if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
117 ENGINE_load_capi();
118#endif
119#endif
120 }
121
122#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
123void ENGINE_setup_bsd_cryptodev(void) {
124 static int bsd_cryptodev_default_loaded = 0;
125 if (!bsd_cryptodev_default_loaded) {
126 ENGINE_load_cryptodev();
127 ENGINE_register_all_complete();
128 }
129 bsd_cryptodev_default_loaded=1;
130}
131#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..95c4070015
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_cnf.c
@@ -0,0 +1,259 @@
1/* eng_cnf.c */
2/* Written by Stephen Henson (steve@openssl.org) 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 "eng_int.h"
60#include <openssl/conf.h>
61
62/* #define ENGINE_CONF_DEBUG */
63
64/* ENGINE config module */
65
66static char *skip_dot(char *name)
67 {
68 char *p;
69 p = strchr(name, '.');
70 if (p)
71 return p + 1;
72 return name;
73 }
74
75static STACK_OF(ENGINE) *initialized_engines = NULL;
76
77static int int_engine_init(ENGINE *e)
78 {
79 if (!ENGINE_init(e))
80 return 0;
81 if (!initialized_engines)
82 initialized_engines = sk_ENGINE_new_null();
83 if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e))
84 {
85 ENGINE_finish(e);
86 return 0;
87 }
88 return 1;
89 }
90
91
92static int int_engine_configure(char *name, char *value, const CONF *cnf)
93 {
94 int i;
95 int ret = 0;
96 long do_init = -1;
97 STACK_OF(CONF_VALUE) *ecmds;
98 CONF_VALUE *ecmd = NULL;
99 char *ctrlname, *ctrlvalue;
100 ENGINE *e = NULL;
101 int soft = 0;
102
103 name = skip_dot(name);
104#ifdef ENGINE_CONF_DEBUG
105 fprintf(stderr, "Configuring engine %s\n", name);
106#endif
107 /* Value is a section containing ENGINE commands */
108 ecmds = NCONF_get_section(cnf, value);
109
110 if (!ecmds)
111 {
112 ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_SECTION_ERROR);
113 return 0;
114 }
115
116 for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++)
117 {
118 ecmd = sk_CONF_VALUE_value(ecmds, i);
119 ctrlname = skip_dot(ecmd->name);
120 ctrlvalue = ecmd->value;
121#ifdef ENGINE_CONF_DEBUG
122 fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname, ctrlvalue);
123#endif
124
125 /* First handle some special pseudo ctrls */
126
127 /* Override engine name to use */
128 if (!strcmp(ctrlname, "engine_id"))
129 name = ctrlvalue;
130 else if (!strcmp(ctrlname, "soft_load"))
131 soft = 1;
132 /* Load a dynamic ENGINE */
133 else if (!strcmp(ctrlname, "dynamic_path"))
134 {
135 e = ENGINE_by_id("dynamic");
136 if (!e)
137 goto err;
138 if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0))
139 goto err;
140 if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0))
141 goto err;
142 if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
143 goto err;
144 }
145 /* ... add other pseudos here ... */
146 else
147 {
148 /* At this point we need an ENGINE structural reference
149 * if we don't already have one.
150 */
151 if (!e)
152 {
153 e = ENGINE_by_id(name);
154 if (!e && soft)
155 {
156 ERR_clear_error();
157 return 1;
158 }
159 if (!e)
160 goto err;
161 }
162 /* Allow "EMPTY" to mean no value: this allows a valid
163 * "value" to be passed to ctrls of type NO_INPUT
164 */
165 if (!strcmp(ctrlvalue, "EMPTY"))
166 ctrlvalue = NULL;
167 if (!strcmp(ctrlname, "init"))
168 {
169 if (!NCONF_get_number_e(cnf, value, "init", &do_init))
170 goto err;
171 if (do_init == 1)
172 {
173 if (!int_engine_init(e))
174 goto err;
175 }
176 else if (do_init != 0)
177 {
178 ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_INVALID_INIT_VALUE);
179 goto err;
180 }
181 }
182 else if (!strcmp(ctrlname, "default_algorithms"))
183 {
184 if (!ENGINE_set_default_string(e, ctrlvalue))
185 goto err;
186 }
187 else if (!ENGINE_ctrl_cmd_string(e,
188 ctrlname, ctrlvalue, 0))
189 goto err;
190 }
191
192
193
194 }
195 if (e && (do_init == -1) && !int_engine_init(e))
196 {
197 ecmd = NULL;
198 goto err;
199 }
200 ret = 1;
201 err:
202 if (ret != 1)
203 {
204 ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_CONFIGURATION_ERROR);
205 if (ecmd)
206 ERR_add_error_data(6, "section=", ecmd->section,
207 ", name=", ecmd->name,
208 ", value=", ecmd->value);
209 }
210 if (e)
211 ENGINE_free(e);
212 return ret;
213 }
214
215
216static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf)
217 {
218 STACK_OF(CONF_VALUE) *elist;
219 CONF_VALUE *cval;
220 int i;
221#ifdef ENGINE_CONF_DEBUG
222 fprintf(stderr, "Called engine module: name %s, value %s\n",
223 CONF_imodule_get_name(md), CONF_imodule_get_value(md));
224#endif
225 /* Value is a section containing ENGINEs to configure */
226 elist = NCONF_get_section(cnf, CONF_imodule_get_value(md));
227
228 if (!elist)
229 {
230 ENGINEerr(ENGINE_F_INT_ENGINE_MODULE_INIT, ENGINE_R_ENGINES_SECTION_ERROR);
231 return 0;
232 }
233
234 for (i = 0; i < sk_CONF_VALUE_num(elist); i++)
235 {
236 cval = sk_CONF_VALUE_value(elist, i);
237 if (!int_engine_configure(cval->name, cval->value, cnf))
238 return 0;
239 }
240
241 return 1;
242 }
243
244static void int_engine_module_finish(CONF_IMODULE *md)
245 {
246 ENGINE *e;
247 while ((e = sk_ENGINE_pop(initialized_engines)))
248 ENGINE_finish(e);
249 sk_ENGINE_free(initialized_engines);
250 initialized_engines = NULL;
251 }
252
253
254void ENGINE_add_conf_module(void)
255 {
256 CONF_module_add("engines",
257 int_engine_module_init,
258 int_engine_module_finish);
259 }
diff --git a/src/lib/libcrypto/engine/eng_cryptodev.c b/src/lib/libcrypto/engine/eng_cryptodev.c
new file mode 100644
index 0000000000..10b3856b4e
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_cryptodev.c
@@ -0,0 +1,1418 @@
1/*
2 * Copyright (c) 2002 Bob Beck <beck@openbsd.org>
3 * Copyright (c) 2002 Theo de Raadt
4 * Copyright (c) 2002 Markus Friedl
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29#include <openssl/objects.h>
30#include <openssl/engine.h>
31#include <openssl/evp.h>
32#include <openssl/bn.h>
33
34#if (defined(__unix__) || defined(unix)) && !defined(USG) && \
35 (defined(__OpenBSD__) || defined(__FreeBSD__))
36#include <sys/param.h>
37# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041)
38# define HAVE_CRYPTODEV
39# endif
40# if (OpenBSD >= 200110)
41# define HAVE_SYSLOG_R
42# endif
43#endif
44
45#ifndef HAVE_CRYPTODEV
46
47void
48ENGINE_load_cryptodev(void)
49{
50 /* This is a NOP on platforms without /dev/crypto */
51 return;
52}
53
54#else
55
56#include <sys/types.h>
57#include <crypto/cryptodev.h>
58#include <crypto/dh/dh.h>
59#include <crypto/dsa/dsa.h>
60#include <crypto/err/err.h>
61#include <crypto/rsa/rsa.h>
62#include <sys/ioctl.h>
63#include <errno.h>
64#include <stdio.h>
65#include <unistd.h>
66#include <fcntl.h>
67#include <stdarg.h>
68#include <syslog.h>
69#include <errno.h>
70#include <string.h>
71
72struct dev_crypto_state {
73 struct session_op d_sess;
74 int d_fd;
75
76#ifdef USE_CRYPTODEV_DIGESTS
77 char dummy_mac_key[HASH_MAX_LEN];
78
79 unsigned char digest_res[HASH_MAX_LEN];
80 char *mac_data;
81 int mac_len;
82
83 int copy;
84#endif
85};
86
87static u_int32_t cryptodev_asymfeat = 0;
88
89static int get_asym_dev_crypto(void);
90static int open_dev_crypto(void);
91static int get_dev_crypto(void);
92static int get_cryptodev_ciphers(const int **cnids);
93#ifdef USE_CRYPTODEV_DIGESTS
94static int get_cryptodev_digests(const int **cnids);
95#endif
96static int cryptodev_usable_ciphers(const int **nids);
97static int cryptodev_usable_digests(const int **nids);
98static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
99 const unsigned char *in, size_t inl);
100static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
101 const unsigned char *iv, int enc);
102static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx);
103static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
104 const int **nids, int nid);
105static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
106 const int **nids, int nid);
107static int bn2crparam(const BIGNUM *a, struct crparam *crp);
108static int crparam2bn(struct crparam *crp, BIGNUM *a);
109static void zapparams(struct crypt_kop *kop);
110static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r,
111 int slen, BIGNUM *s);
112
113static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
114 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
115static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I,
116 RSA *rsa, BN_CTX *ctx);
117static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
118static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
119 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
120static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
121 BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
122 BN_CTX *ctx, BN_MONT_CTX *mont);
123static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst,
124 int dlen, DSA *dsa);
125static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
126 DSA_SIG *sig, DSA *dsa);
127static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
128 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
129 BN_MONT_CTX *m_ctx);
130static int cryptodev_dh_compute_key(unsigned char *key,
131 const BIGNUM *pub_key, DH *dh);
132static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p,
133 void (*f)(void));
134void ENGINE_load_cryptodev(void);
135
136static const ENGINE_CMD_DEFN cryptodev_defns[] = {
137 { 0, NULL, NULL, 0 }
138};
139
140static struct {
141 int id;
142 int nid;
143 int ivmax;
144 int keylen;
145} ciphers[] = {
146 { CRYPTO_ARC4, NID_rc4, 0, 16, },
147 { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, },
148 { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, },
149 { CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, },
150 { CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24, },
151 { CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32, },
152 { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, },
153 { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, },
154 { 0, NID_undef, 0, 0, },
155};
156
157#ifdef USE_CRYPTODEV_DIGESTS
158static struct {
159 int id;
160 int nid;
161 int keylen;
162} digests[] = {
163 { CRYPTO_MD5_HMAC, NID_hmacWithMD5, 16},
164 { CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, 20},
165 { CRYPTO_RIPEMD160_HMAC, NID_ripemd160, 16/*?*/},
166 { CRYPTO_MD5_KPDK, NID_undef, 0},
167 { CRYPTO_SHA1_KPDK, NID_undef, 0},
168 { CRYPTO_MD5, NID_md5, 16},
169 { CRYPTO_SHA1, NID_sha1, 20},
170 { 0, NID_undef, 0},
171};
172#endif
173
174/*
175 * Return a fd if /dev/crypto seems usable, 0 otherwise.
176 */
177static int
178open_dev_crypto(void)
179{
180 static int fd = -1;
181
182 if (fd == -1) {
183 if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1)
184 return (-1);
185 /* close on exec */
186 if (fcntl(fd, F_SETFD, 1) == -1) {
187 close(fd);
188 fd = -1;
189 return (-1);
190 }
191 }
192 return (fd);
193}
194
195static int
196get_dev_crypto(void)
197{
198 int fd, retfd;
199
200 if ((fd = open_dev_crypto()) == -1)
201 return (-1);
202 if (ioctl(fd, CRIOGET, &retfd) == -1)
203 return (-1);
204
205 /* close on exec */
206 if (fcntl(retfd, F_SETFD, 1) == -1) {
207 close(retfd);
208 return (-1);
209 }
210 return (retfd);
211}
212
213/* Caching version for asym operations */
214static int
215get_asym_dev_crypto(void)
216{
217 static int fd = -1;
218
219 if (fd == -1)
220 fd = get_dev_crypto();
221 return fd;
222}
223
224/*
225 * Find out what ciphers /dev/crypto will let us have a session for.
226 * XXX note, that some of these openssl doesn't deal with yet!
227 * returning them here is harmless, as long as we return NULL
228 * when asked for a handler in the cryptodev_engine_ciphers routine
229 */
230static int
231get_cryptodev_ciphers(const int **cnids)
232{
233 static int nids[CRYPTO_ALGORITHM_MAX];
234 struct session_op sess;
235 int fd, i, count = 0;
236
237 if ((fd = get_dev_crypto()) < 0) {
238 *cnids = NULL;
239 return (0);
240 }
241 memset(&sess, 0, sizeof(sess));
242 sess.key = (caddr_t)"123456789abcdefghijklmno";
243
244 for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
245 if (ciphers[i].nid == NID_undef)
246 continue;
247 sess.cipher = ciphers[i].id;
248 sess.keylen = ciphers[i].keylen;
249 sess.mac = 0;
250 if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
251 ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
252 nids[count++] = ciphers[i].nid;
253 }
254 close(fd);
255
256 if (count > 0)
257 *cnids = nids;
258 else
259 *cnids = NULL;
260 return (count);
261}
262
263#ifdef USE_CRYPTODEV_DIGESTS
264/*
265 * Find out what digests /dev/crypto will let us have a session for.
266 * XXX note, that some of these openssl doesn't deal with yet!
267 * returning them here is harmless, as long as we return NULL
268 * when asked for a handler in the cryptodev_engine_digests routine
269 */
270static int
271get_cryptodev_digests(const int **cnids)
272{
273 static int nids[CRYPTO_ALGORITHM_MAX];
274 struct session_op sess;
275 int fd, i, count = 0;
276
277 if ((fd = get_dev_crypto()) < 0) {
278 *cnids = NULL;
279 return (0);
280 }
281 memset(&sess, 0, sizeof(sess));
282 sess.mackey = (caddr_t)"123456789abcdefghijklmno";
283 for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
284 if (digests[i].nid == NID_undef)
285 continue;
286 sess.mac = digests[i].id;
287 sess.mackeylen = digests[i].keylen;
288 sess.cipher = 0;
289 if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
290 ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
291 nids[count++] = digests[i].nid;
292 }
293 close(fd);
294
295 if (count > 0)
296 *cnids = nids;
297 else
298 *cnids = NULL;
299 return (count);
300}
301#endif /* 0 */
302
303/*
304 * Find the useable ciphers|digests from dev/crypto - this is the first
305 * thing called by the engine init crud which determines what it
306 * can use for ciphers from this engine. We want to return
307 * only what we can do, anythine else is handled by software.
308 *
309 * If we can't initialize the device to do anything useful for
310 * any reason, we want to return a NULL array, and 0 length,
311 * which forces everything to be done is software. By putting
312 * the initalization of the device in here, we ensure we can
313 * use this engine as the default, and if for whatever reason
314 * /dev/crypto won't do what we want it will just be done in
315 * software
316 *
317 * This can (should) be greatly expanded to perhaps take into
318 * account speed of the device, and what we want to do.
319 * (although the disabling of particular alg's could be controlled
320 * by the device driver with sysctl's.) - this is where we
321 * want most of the decisions made about what we actually want
322 * to use from /dev/crypto.
323 */
324static int
325cryptodev_usable_ciphers(const int **nids)
326{
327 return (get_cryptodev_ciphers(nids));
328}
329
330static int
331cryptodev_usable_digests(const int **nids)
332{
333#ifdef USE_CRYPTODEV_DIGESTS
334 return (get_cryptodev_digests(nids));
335#else
336 /*
337 * XXXX just disable all digests for now, because it sucks.
338 * we need a better way to decide this - i.e. I may not
339 * want digests on slow cards like hifn on fast machines,
340 * but might want them on slow or loaded machines, etc.
341 * will also want them when using crypto cards that don't
342 * suck moose gonads - would be nice to be able to decide something
343 * as reasonable default without having hackery that's card dependent.
344 * of course, the default should probably be just do everything,
345 * with perhaps a sysctl to turn algoritms off (or have them off
346 * by default) on cards that generally suck like the hifn.
347 */
348 *nids = NULL;
349 return (0);
350#endif
351}
352
353static int
354cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
355 const unsigned char *in, size_t inl)
356{
357 struct crypt_op cryp;
358 struct dev_crypto_state *state = ctx->cipher_data;
359 struct session_op *sess = &state->d_sess;
360 const void *iiv;
361 unsigned char save_iv[EVP_MAX_IV_LENGTH];
362
363 if (state->d_fd < 0)
364 return (0);
365 if (!inl)
366 return (1);
367 if ((inl % ctx->cipher->block_size) != 0)
368 return (0);
369
370 memset(&cryp, 0, sizeof(cryp));
371
372 cryp.ses = sess->ses;
373 cryp.flags = 0;
374 cryp.len = inl;
375 cryp.src = (caddr_t) in;
376 cryp.dst = (caddr_t) out;
377 cryp.mac = 0;
378
379 cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
380
381 if (ctx->cipher->iv_len) {
382 cryp.iv = (caddr_t) ctx->iv;
383 if (!ctx->encrypt) {
384 iiv = in + inl - ctx->cipher->iv_len;
385 memcpy(save_iv, iiv, ctx->cipher->iv_len);
386 }
387 } else
388 cryp.iv = NULL;
389
390 if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) {
391 /* XXX need better errror handling
392 * this can fail for a number of different reasons.
393 */
394 return (0);
395 }
396
397 if (ctx->cipher->iv_len) {
398 if (ctx->encrypt)
399 iiv = out + inl - ctx->cipher->iv_len;
400 else
401 iiv = save_iv;
402 memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
403 }
404 return (1);
405}
406
407static int
408cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
409 const unsigned char *iv, int enc)
410{
411 struct dev_crypto_state *state = ctx->cipher_data;
412 struct session_op *sess = &state->d_sess;
413 int cipher = -1, i;
414
415 for (i = 0; ciphers[i].id; i++)
416 if (ctx->cipher->nid == ciphers[i].nid &&
417 ctx->cipher->iv_len <= ciphers[i].ivmax &&
418 ctx->key_len == ciphers[i].keylen) {
419 cipher = ciphers[i].id;
420 break;
421 }
422
423 if (!ciphers[i].id) {
424 state->d_fd = -1;
425 return (0);
426 }
427
428 memset(sess, 0, sizeof(struct session_op));
429
430 if ((state->d_fd = get_dev_crypto()) < 0)
431 return (0);
432
433 sess->key = (caddr_t)key;
434 sess->keylen = ctx->key_len;
435 sess->cipher = cipher;
436
437 if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
438 close(state->d_fd);
439 state->d_fd = -1;
440 return (0);
441 }
442 return (1);
443}
444
445/*
446 * free anything we allocated earlier when initting a
447 * session, and close the session.
448 */
449static int
450cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
451{
452 int ret = 0;
453 struct dev_crypto_state *state = ctx->cipher_data;
454 struct session_op *sess = &state->d_sess;
455
456 if (state->d_fd < 0)
457 return (0);
458
459 /* XXX if this ioctl fails, someting's wrong. the invoker
460 * may have called us with a bogus ctx, or we could
461 * have a device that for whatever reason just doesn't
462 * want to play ball - it's not clear what's right
463 * here - should this be an error? should it just
464 * increase a counter, hmm. For right now, we return
465 * 0 - I don't believe that to be "right". we could
466 * call the gorpy openssl lib error handlers that
467 * print messages to users of the library. hmm..
468 */
469
470 if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) {
471 ret = 0;
472 } else {
473 ret = 1;
474 }
475 close(state->d_fd);
476 state->d_fd = -1;
477
478 return (ret);
479}
480
481/*
482 * libcrypto EVP stuff - this is how we get wired to EVP so the engine
483 * gets called when libcrypto requests a cipher NID.
484 */
485
486/* RC4 */
487const EVP_CIPHER cryptodev_rc4 = {
488 NID_rc4,
489 1, 16, 0,
490 EVP_CIPH_VARIABLE_LENGTH,
491 cryptodev_init_key,
492 cryptodev_cipher,
493 cryptodev_cleanup,
494 sizeof(struct dev_crypto_state),
495 NULL,
496 NULL,
497 NULL
498};
499
500/* DES CBC EVP */
501const EVP_CIPHER cryptodev_des_cbc = {
502 NID_des_cbc,
503 8, 8, 8,
504 EVP_CIPH_CBC_MODE,
505 cryptodev_init_key,
506 cryptodev_cipher,
507 cryptodev_cleanup,
508 sizeof(struct dev_crypto_state),
509 EVP_CIPHER_set_asn1_iv,
510 EVP_CIPHER_get_asn1_iv,
511 NULL
512};
513
514/* 3DES CBC EVP */
515const EVP_CIPHER cryptodev_3des_cbc = {
516 NID_des_ede3_cbc,
517 8, 24, 8,
518 EVP_CIPH_CBC_MODE,
519 cryptodev_init_key,
520 cryptodev_cipher,
521 cryptodev_cleanup,
522 sizeof(struct dev_crypto_state),
523 EVP_CIPHER_set_asn1_iv,
524 EVP_CIPHER_get_asn1_iv,
525 NULL
526};
527
528const EVP_CIPHER cryptodev_bf_cbc = {
529 NID_bf_cbc,
530 8, 16, 8,
531 EVP_CIPH_CBC_MODE,
532 cryptodev_init_key,
533 cryptodev_cipher,
534 cryptodev_cleanup,
535 sizeof(struct dev_crypto_state),
536 EVP_CIPHER_set_asn1_iv,
537 EVP_CIPHER_get_asn1_iv,
538 NULL
539};
540
541const EVP_CIPHER cryptodev_cast_cbc = {
542 NID_cast5_cbc,
543 8, 16, 8,
544 EVP_CIPH_CBC_MODE,
545 cryptodev_init_key,
546 cryptodev_cipher,
547 cryptodev_cleanup,
548 sizeof(struct dev_crypto_state),
549 EVP_CIPHER_set_asn1_iv,
550 EVP_CIPHER_get_asn1_iv,
551 NULL
552};
553
554const EVP_CIPHER cryptodev_aes_cbc = {
555 NID_aes_128_cbc,
556 16, 16, 16,
557 EVP_CIPH_CBC_MODE,
558 cryptodev_init_key,
559 cryptodev_cipher,
560 cryptodev_cleanup,
561 sizeof(struct dev_crypto_state),
562 EVP_CIPHER_set_asn1_iv,
563 EVP_CIPHER_get_asn1_iv,
564 NULL
565};
566
567const EVP_CIPHER cryptodev_aes_192_cbc = {
568 NID_aes_192_cbc,
569 16, 24, 16,
570 EVP_CIPH_CBC_MODE,
571 cryptodev_init_key,
572 cryptodev_cipher,
573 cryptodev_cleanup,
574 sizeof(struct dev_crypto_state),
575 EVP_CIPHER_set_asn1_iv,
576 EVP_CIPHER_get_asn1_iv,
577 NULL
578};
579
580const EVP_CIPHER cryptodev_aes_256_cbc = {
581 NID_aes_256_cbc,
582 16, 32, 16,
583 EVP_CIPH_CBC_MODE,
584 cryptodev_init_key,
585 cryptodev_cipher,
586 cryptodev_cleanup,
587 sizeof(struct dev_crypto_state),
588 EVP_CIPHER_set_asn1_iv,
589 EVP_CIPHER_get_asn1_iv,
590 NULL
591};
592
593/*
594 * Registered by the ENGINE when used to find out how to deal with
595 * a particular NID in the ENGINE. this says what we'll do at the
596 * top level - note, that list is restricted by what we answer with
597 */
598static int
599cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
600 const int **nids, int nid)
601{
602 if (!cipher)
603 return (cryptodev_usable_ciphers(nids));
604
605 switch (nid) {
606 case NID_rc4:
607 *cipher = &cryptodev_rc4;
608 break;
609 case NID_des_ede3_cbc:
610 *cipher = &cryptodev_3des_cbc;
611 break;
612 case NID_des_cbc:
613 *cipher = &cryptodev_des_cbc;
614 break;
615 case NID_bf_cbc:
616 *cipher = &cryptodev_bf_cbc;
617 break;
618 case NID_cast5_cbc:
619 *cipher = &cryptodev_cast_cbc;
620 break;
621 case NID_aes_128_cbc:
622 *cipher = &cryptodev_aes_cbc;
623 break;
624 case NID_aes_192_cbc:
625 *cipher = &cryptodev_aes_192_cbc;
626 break;
627 case NID_aes_256_cbc:
628 *cipher = &cryptodev_aes_256_cbc;
629 break;
630 default:
631 *cipher = NULL;
632 break;
633 }
634 return (*cipher != NULL);
635}
636
637
638#ifdef USE_CRYPTODEV_DIGESTS
639
640/* convert digest type to cryptodev */
641static int
642digest_nid_to_cryptodev(int nid)
643{
644 int i;
645
646 for (i = 0; digests[i].id; i++)
647 if (digests[i].nid == nid)
648 return (digests[i].id);
649 return (0);
650}
651
652
653static int
654digest_key_length(int nid)
655{
656 int i;
657
658 for (i = 0; digests[i].id; i++)
659 if (digests[i].nid == nid)
660 return digests[i].keylen;
661 return (0);
662}
663
664
665static int cryptodev_digest_init(EVP_MD_CTX *ctx)
666{
667 struct dev_crypto_state *state = ctx->md_data;
668 struct session_op *sess = &state->d_sess;
669 int digest;
670
671 if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef){
672 printf("cryptodev_digest_init: Can't get digest \n");
673 return (0);
674 }
675
676 memset(state, 0, sizeof(struct dev_crypto_state));
677
678 if ((state->d_fd = get_dev_crypto()) < 0) {
679 printf("cryptodev_digest_init: Can't get Dev \n");
680 return (0);
681 }
682
683 sess->mackey = state->dummy_mac_key;
684 sess->mackeylen = digest_key_length(ctx->digest->type);
685 sess->mac = digest;
686
687 if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) {
688 close(state->d_fd);
689 state->d_fd = -1;
690 printf("cryptodev_digest_init: Open session failed\n");
691 return (0);
692 }
693
694 return (1);
695}
696
697static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data,
698 size_t count)
699{
700 struct crypt_op cryp;
701 struct dev_crypto_state *state = ctx->md_data;
702 struct session_op *sess = &state->d_sess;
703
704 if (!data || state->d_fd < 0) {
705 printf("cryptodev_digest_update: illegal inputs \n");
706 return (0);
707 }
708
709 if (!count) {
710 return (0);
711 }
712
713 if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) {
714 /* if application doesn't support one buffer */
715 state->mac_data = OPENSSL_realloc(state->mac_data, state->mac_len + count);
716
717 if (!state->mac_data) {
718 printf("cryptodev_digest_update: realloc failed\n");
719 return (0);
720 }
721
722 memcpy(state->mac_data + state->mac_len, data, count);
723 state->mac_len += count;
724
725 return (1);
726 }
727
728 memset(&cryp, 0, sizeof(cryp));
729
730 cryp.ses = sess->ses;
731 cryp.flags = 0;
732 cryp.len = count;
733 cryp.src = (caddr_t) data;
734 cryp.dst = NULL;
735 cryp.mac = (caddr_t) state->digest_res;
736 if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
737 printf("cryptodev_digest_update: digest failed\n");
738 return (0);
739 }
740 return (1);
741}
742
743
744static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
745{
746 struct crypt_op cryp;
747 struct dev_crypto_state *state = ctx->md_data;
748 struct session_op *sess = &state->d_sess;
749
750 int ret = 1;
751
752 if (!md || state->d_fd < 0) {
753 printf("cryptodev_digest_final: illegal input\n");
754 return(0);
755 }
756
757 if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) {
758 /* if application doesn't support one buffer */
759 memset(&cryp, 0, sizeof(cryp));
760
761 cryp.ses = sess->ses;
762 cryp.flags = 0;
763 cryp.len = state->mac_len;
764 cryp.src = state->mac_data;
765 cryp.dst = NULL;
766 cryp.mac = (caddr_t)md;
767
768 if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
769 printf("cryptodev_digest_final: digest failed\n");
770 return (0);
771 }
772
773 return 1;
774 }
775
776 memcpy(md, state->digest_res, ctx->digest->md_size);
777
778 return (ret);
779}
780
781
782static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
783{
784 int ret = 1;
785 struct dev_crypto_state *state = ctx->md_data;
786 struct session_op *sess = &state->d_sess;
787
788 if (state->d_fd < 0) {
789 printf("cryptodev_digest_cleanup: illegal input\n");
790 return (0);
791 }
792
793 if (state->mac_data) {
794 OPENSSL_free(state->mac_data);
795 state->mac_data = NULL;
796 state->mac_len = 0;
797 }
798
799 if (state->copy)
800 return 1;
801
802 if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
803 printf("cryptodev_digest_cleanup: failed to close session\n");
804 ret = 0;
805 } else {
806 ret = 1;
807 }
808 close(state->d_fd);
809 state->d_fd = -1;
810
811 return (ret);
812}
813
814static int cryptodev_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
815{
816 struct dev_crypto_state *fstate = from->md_data;
817 struct dev_crypto_state *dstate = to->md_data;
818
819 memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
820
821 if (fstate->mac_len != 0) {
822 dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
823 memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
824 }
825
826 dstate->copy = 1;
827
828 return 1;
829}
830
831
832const EVP_MD cryptodev_sha1 = {
833 NID_sha1,
834 NID_undef,
835 SHA_DIGEST_LENGTH,
836 EVP_MD_FLAG_ONESHOT,
837 cryptodev_digest_init,
838 cryptodev_digest_update,
839 cryptodev_digest_final,
840 cryptodev_digest_copy,
841 cryptodev_digest_cleanup,
842 EVP_PKEY_NULL_method,
843 SHA_CBLOCK,
844 sizeof(struct dev_crypto_state),
845};
846
847const EVP_MD cryptodev_md5 = {
848 NID_md5,
849 NID_undef,
850 16 /* MD5_DIGEST_LENGTH */,
851 EVP_MD_FLAG_ONESHOT,
852 cryptodev_digest_init,
853 cryptodev_digest_update,
854 cryptodev_digest_final,
855 cryptodev_digest_copy,
856 cryptodev_digest_cleanup,
857 EVP_PKEY_NULL_method,
858 64 /* MD5_CBLOCK */,
859 sizeof(struct dev_crypto_state),
860};
861
862#endif /* USE_CRYPTODEV_DIGESTS */
863
864
865static int
866cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
867 const int **nids, int nid)
868{
869 if (!digest)
870 return (cryptodev_usable_digests(nids));
871
872 switch (nid) {
873#ifdef USE_CRYPTODEV_DIGESTS
874 case NID_md5:
875 *digest = &cryptodev_md5;
876 break;
877 case NID_sha1:
878 *digest = &cryptodev_sha1;
879 break;
880 default:
881#endif /* USE_CRYPTODEV_DIGESTS */
882 *digest = NULL;
883 break;
884 }
885 return (*digest != NULL);
886}
887
888/*
889 * Convert a BIGNUM to the representation that /dev/crypto needs.
890 * Upon completion of use, the caller is responsible for freeing
891 * crp->crp_p.
892 */
893static int
894bn2crparam(const BIGNUM *a, struct crparam *crp)
895{
896 int i, j, k;
897 ssize_t bytes, bits;
898 u_char *b;
899
900 crp->crp_p = NULL;
901 crp->crp_nbits = 0;
902
903 bits = BN_num_bits(a);
904 bytes = (bits + 7) / 8;
905
906 b = malloc(bytes);
907 if (b == NULL)
908 return (1);
909 memset(b, 0, bytes);
910
911 crp->crp_p = (caddr_t) b;
912 crp->crp_nbits = bits;
913
914 for (i = 0, j = 0; i < a->top; i++) {
915 for (k = 0; k < BN_BITS2 / 8; k++) {
916 if ((j + k) >= bytes)
917 return (0);
918 b[j + k] = a->d[i] >> (k * 8);
919 }
920 j += BN_BITS2 / 8;
921 }
922 return (0);
923}
924
925/* Convert a /dev/crypto parameter to a BIGNUM */
926static int
927crparam2bn(struct crparam *crp, BIGNUM *a)
928{
929 u_int8_t *pd;
930 int i, bytes;
931
932 bytes = (crp->crp_nbits + 7) / 8;
933
934 if (bytes == 0)
935 return (-1);
936
937 if ((pd = (u_int8_t *) malloc(bytes)) == NULL)
938 return (-1);
939
940 for (i = 0; i < bytes; i++)
941 pd[i] = crp->crp_p[bytes - i - 1];
942
943 BN_bin2bn(pd, bytes, a);
944 free(pd);
945
946 return (0);
947}
948
949static void
950zapparams(struct crypt_kop *kop)
951{
952 int i;
953
954 for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) {
955 if (kop->crk_param[i].crp_p)
956 free(kop->crk_param[i].crp_p);
957 kop->crk_param[i].crp_p = NULL;
958 kop->crk_param[i].crp_nbits = 0;
959 }
960}
961
962static int
963cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s)
964{
965 int fd, ret = -1;
966
967 if ((fd = get_asym_dev_crypto()) < 0)
968 return (ret);
969
970 if (r) {
971 kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char));
972 kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8;
973 kop->crk_oparams++;
974 }
975 if (s) {
976 kop->crk_param[kop->crk_iparams+1].crp_p = calloc(slen, sizeof(char));
977 kop->crk_param[kop->crk_iparams+1].crp_nbits = slen * 8;
978 kop->crk_oparams++;
979 }
980
981 if (ioctl(fd, CIOCKEY, kop) == 0) {
982 if (r)
983 crparam2bn(&kop->crk_param[kop->crk_iparams], r);
984 if (s)
985 crparam2bn(&kop->crk_param[kop->crk_iparams+1], s);
986 ret = 0;
987 }
988
989 return (ret);
990}
991
992static int
993cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
994 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
995{
996 struct crypt_kop kop;
997 int ret = 1;
998
999 /* Currently, we know we can do mod exp iff we can do any
1000 * asymmetric operations at all.
1001 */
1002 if (cryptodev_asymfeat == 0) {
1003 ret = BN_mod_exp(r, a, p, m, ctx);
1004 return (ret);
1005 }
1006
1007 memset(&kop, 0, sizeof kop);
1008 kop.crk_op = CRK_MOD_EXP;
1009
1010 /* inputs: a^p % m */
1011 if (bn2crparam(a, &kop.crk_param[0]))
1012 goto err;
1013 if (bn2crparam(p, &kop.crk_param[1]))
1014 goto err;
1015 if (bn2crparam(m, &kop.crk_param[2]))
1016 goto err;
1017 kop.crk_iparams = 3;
1018
1019 if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) {
1020 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
1021 printf("OCF asym process failed, Running in software\n");
1022 ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
1023
1024 } else if (ECANCELED == kop.crk_status) {
1025 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
1026 printf("OCF hardware operation cancelled. Running in Software\n");
1027 ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
1028 }
1029 /* else cryptodev operation worked ok ==> ret = 1*/
1030
1031err:
1032 zapparams(&kop);
1033 return (ret);
1034}
1035
1036static int
1037cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
1038{
1039 int r;
1040 ctx = BN_CTX_new();
1041 r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL);
1042 BN_CTX_free(ctx);
1043 return (r);
1044}
1045
1046static int
1047cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
1048{
1049 struct crypt_kop kop;
1050 int ret = 1;
1051
1052 if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
1053 /* XXX 0 means failure?? */
1054 return (0);
1055 }
1056
1057 memset(&kop, 0, sizeof kop);
1058 kop.crk_op = CRK_MOD_EXP_CRT;
1059 /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
1060 if (bn2crparam(rsa->p, &kop.crk_param[0]))
1061 goto err;
1062 if (bn2crparam(rsa->q, &kop.crk_param[1]))
1063 goto err;
1064 if (bn2crparam(I, &kop.crk_param[2]))
1065 goto err;
1066 if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
1067 goto err;
1068 if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
1069 goto err;
1070 if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
1071 goto err;
1072 kop.crk_iparams = 6;
1073
1074 if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) {
1075 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
1076 printf("OCF asym process failed, running in Software\n");
1077 ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
1078
1079 } else if (ECANCELED == kop.crk_status) {
1080 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
1081 printf("OCF hardware operation cancelled. Running in Software\n");
1082 ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
1083 }
1084 /* else cryptodev operation worked ok ==> ret = 1*/
1085
1086err:
1087 zapparams(&kop);
1088 return (ret);
1089}
1090
1091static RSA_METHOD cryptodev_rsa = {
1092 "cryptodev RSA method",
1093 NULL, /* rsa_pub_enc */
1094 NULL, /* rsa_pub_dec */
1095 NULL, /* rsa_priv_enc */
1096 NULL, /* rsa_priv_dec */
1097 NULL,
1098 NULL,
1099 NULL, /* init */
1100 NULL, /* finish */
1101 0, /* flags */
1102 NULL, /* app_data */
1103 NULL, /* rsa_sign */
1104 NULL /* rsa_verify */
1105};
1106
1107static int
1108cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
1109 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
1110{
1111 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
1112}
1113
1114static int
1115cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
1116 BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
1117 BN_CTX *ctx, BN_MONT_CTX *mont)
1118{
1119 BIGNUM t2;
1120 int ret = 0;
1121
1122 BN_init(&t2);
1123
1124 /* v = ( g^u1 * y^u2 mod p ) mod q */
1125 /* let t1 = g ^ u1 mod p */
1126 ret = 0;
1127
1128 if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont))
1129 goto err;
1130
1131 /* let t2 = y ^ u2 mod p */
1132 if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont))
1133 goto err;
1134 /* let u1 = t1 * t2 mod p */
1135 if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx))
1136 goto err;
1137
1138 BN_copy(t1,u1);
1139
1140 ret = 1;
1141err:
1142 BN_free(&t2);
1143 return(ret);
1144}
1145
1146static DSA_SIG *
1147cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
1148{
1149 struct crypt_kop kop;
1150 BIGNUM *r = NULL, *s = NULL;
1151 DSA_SIG *dsaret = NULL;
1152
1153 if ((r = BN_new()) == NULL)
1154 goto err;
1155 if ((s = BN_new()) == NULL) {
1156 BN_free(r);
1157 goto err;
1158 }
1159
1160 memset(&kop, 0, sizeof kop);
1161 kop.crk_op = CRK_DSA_SIGN;
1162
1163 /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
1164 kop.crk_param[0].crp_p = (caddr_t)dgst;
1165 kop.crk_param[0].crp_nbits = dlen * 8;
1166 if (bn2crparam(dsa->p, &kop.crk_param[1]))
1167 goto err;
1168 if (bn2crparam(dsa->q, &kop.crk_param[2]))
1169 goto err;
1170 if (bn2crparam(dsa->g, &kop.crk_param[3]))
1171 goto err;
1172 if (bn2crparam(dsa->priv_key, &kop.crk_param[4]))
1173 goto err;
1174 kop.crk_iparams = 5;
1175
1176 if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r,
1177 BN_num_bytes(dsa->q), s) == 0) {
1178 dsaret = DSA_SIG_new();
1179 dsaret->r = r;
1180 dsaret->s = s;
1181 } else {
1182 const DSA_METHOD *meth = DSA_OpenSSL();
1183 BN_free(r);
1184 BN_free(s);
1185 dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
1186 }
1187err:
1188 kop.crk_param[0].crp_p = NULL;
1189 zapparams(&kop);
1190 return (dsaret);
1191}
1192
1193static int
1194cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
1195 DSA_SIG *sig, DSA *dsa)
1196{
1197 struct crypt_kop kop;
1198 int dsaret = 1;
1199
1200 memset(&kop, 0, sizeof kop);
1201 kop.crk_op = CRK_DSA_VERIFY;
1202
1203 /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
1204 kop.crk_param[0].crp_p = (caddr_t)dgst;
1205 kop.crk_param[0].crp_nbits = dlen * 8;
1206 if (bn2crparam(dsa->p, &kop.crk_param[1]))
1207 goto err;
1208 if (bn2crparam(dsa->q, &kop.crk_param[2]))
1209 goto err;
1210 if (bn2crparam(dsa->g, &kop.crk_param[3]))
1211 goto err;
1212 if (bn2crparam(dsa->pub_key, &kop.crk_param[4]))
1213 goto err;
1214 if (bn2crparam(sig->r, &kop.crk_param[5]))
1215 goto err;
1216 if (bn2crparam(sig->s, &kop.crk_param[6]))
1217 goto err;
1218 kop.crk_iparams = 7;
1219
1220 if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
1221/*OCF success value is 0, if not zero, change dsaret to fail*/
1222 if(0 != kop.crk_status) dsaret = 0;
1223 } else {
1224 const DSA_METHOD *meth = DSA_OpenSSL();
1225
1226 dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
1227 }
1228err:
1229 kop.crk_param[0].crp_p = NULL;
1230 zapparams(&kop);
1231 return (dsaret);
1232}
1233
1234static DSA_METHOD cryptodev_dsa = {
1235 "cryptodev DSA method",
1236 NULL,
1237 NULL, /* dsa_sign_setup */
1238 NULL,
1239 NULL, /* dsa_mod_exp */
1240 NULL,
1241 NULL, /* init */
1242 NULL, /* finish */
1243 0, /* flags */
1244 NULL /* app_data */
1245};
1246
1247static int
1248cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
1249 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
1250 BN_MONT_CTX *m_ctx)
1251{
1252 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
1253}
1254
1255static int
1256cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
1257{
1258 struct crypt_kop kop;
1259 int dhret = 1;
1260 int fd, keylen;
1261
1262 if ((fd = get_asym_dev_crypto()) < 0) {
1263 const DH_METHOD *meth = DH_OpenSSL();
1264
1265 return ((meth->compute_key)(key, pub_key, dh));
1266 }
1267
1268 keylen = BN_num_bits(dh->p);
1269
1270 memset(&kop, 0, sizeof kop);
1271 kop.crk_op = CRK_DH_COMPUTE_KEY;
1272
1273 /* inputs: dh->priv_key pub_key dh->p key */
1274 if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
1275 goto err;
1276 if (bn2crparam(pub_key, &kop.crk_param[1]))
1277 goto err;
1278 if (bn2crparam(dh->p, &kop.crk_param[2]))
1279 goto err;
1280 kop.crk_iparams = 3;
1281
1282 kop.crk_param[3].crp_p = (caddr_t) key;
1283 kop.crk_param[3].crp_nbits = keylen * 8;
1284 kop.crk_oparams = 1;
1285
1286 if (ioctl(fd, CIOCKEY, &kop) == -1) {
1287 const DH_METHOD *meth = DH_OpenSSL();
1288
1289 dhret = (meth->compute_key)(key, pub_key, dh);
1290 }
1291err:
1292 kop.crk_param[3].crp_p = NULL;
1293 zapparams(&kop);
1294 return (dhret);
1295}
1296
1297static DH_METHOD cryptodev_dh = {
1298 "cryptodev DH method",
1299 NULL, /* cryptodev_dh_generate_key */
1300 NULL,
1301 NULL,
1302 NULL,
1303 NULL,
1304 0, /* flags */
1305 NULL /* app_data */
1306};
1307
1308/*
1309 * ctrl right now is just a wrapper that doesn't do much
1310 * but I expect we'll want some options soon.
1311 */
1312static int
1313cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
1314{
1315#ifdef HAVE_SYSLOG_R
1316 struct syslog_data sd = SYSLOG_DATA_INIT;
1317#endif
1318
1319 switch (cmd) {
1320 default:
1321#ifdef HAVE_SYSLOG_R
1322 syslog_r(LOG_ERR, &sd,
1323 "cryptodev_ctrl: unknown command %d", cmd);
1324#else
1325 syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd);
1326#endif
1327 break;
1328 }
1329 return (1);
1330}
1331
1332void
1333ENGINE_load_cryptodev(void)
1334{
1335 ENGINE *engine = ENGINE_new();
1336 int fd;
1337
1338 if (engine == NULL)
1339 return;
1340 if ((fd = get_dev_crypto()) < 0) {
1341 ENGINE_free(engine);
1342 return;
1343 }
1344
1345 /*
1346 * find out what asymmetric crypto algorithms we support
1347 */
1348 if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
1349 close(fd);
1350 ENGINE_free(engine);
1351 return;
1352 }
1353 close(fd);
1354
1355 if (!ENGINE_set_id(engine, "cryptodev") ||
1356 !ENGINE_set_name(engine, "BSD cryptodev engine") ||
1357 !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) ||
1358 !ENGINE_set_digests(engine, cryptodev_engine_digests) ||
1359 !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) ||
1360 !ENGINE_set_cmd_defns(engine, cryptodev_defns)) {
1361 ENGINE_free(engine);
1362 return;
1363 }
1364
1365 if (ENGINE_set_RSA(engine, &cryptodev_rsa)) {
1366 const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay();
1367
1368 cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp;
1369 cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp;
1370 cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc;
1371 cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec;
1372 cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc;
1373 cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec;
1374 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1375 cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp;
1376 if (cryptodev_asymfeat & CRF_MOD_EXP_CRT)
1377 cryptodev_rsa.rsa_mod_exp =
1378 cryptodev_rsa_mod_exp;
1379 else
1380 cryptodev_rsa.rsa_mod_exp =
1381 cryptodev_rsa_nocrt_mod_exp;
1382 }
1383 }
1384
1385 if (ENGINE_set_DSA(engine, &cryptodev_dsa)) {
1386 const DSA_METHOD *meth = DSA_OpenSSL();
1387
1388 memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
1389 if (cryptodev_asymfeat & CRF_DSA_SIGN)
1390 cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
1391 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1392 cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp;
1393 cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp;
1394 }
1395 if (cryptodev_asymfeat & CRF_DSA_VERIFY)
1396 cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
1397 }
1398
1399 if (ENGINE_set_DH(engine, &cryptodev_dh)){
1400 const DH_METHOD *dh_meth = DH_OpenSSL();
1401
1402 cryptodev_dh.generate_key = dh_meth->generate_key;
1403 cryptodev_dh.compute_key = dh_meth->compute_key;
1404 cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp;
1405 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1406 cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh;
1407 if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
1408 cryptodev_dh.compute_key =
1409 cryptodev_dh_compute_key;
1410 }
1411 }
1412
1413 ENGINE_add(engine);
1414 ENGINE_free(engine);
1415 ERR_clear_error();
1416}
1417
1418#endif /* HAVE_CRYPTODEV */
diff --git a/src/lib/libcrypto/engine/eng_ctrl.c b/src/lib/libcrypto/engine/eng_ctrl.c
new file mode 100644
index 0000000000..5ce25d92ec
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_ctrl.c
@@ -0,0 +1,389 @@
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 "eng_int.h"
57
58/* When querying a ENGINE-specific control command's 'description', this string
59 * is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. */
60static const char *int_no_description = "";
61
62/* These internal functions handle 'CMD'-related control commands when the
63 * ENGINE in question has asked us to take care of it (ie. the ENGINE did not
64 * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. */
65
66static int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn)
67 {
68 if((defn->cmd_num == 0) || (defn->cmd_name == NULL))
69 return 1;
70 return 0;
71 }
72
73static int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s)
74 {
75 int idx = 0;
76 while(!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0))
77 {
78 idx++;
79 defn++;
80 }
81 if(int_ctrl_cmd_is_null(defn))
82 /* The given name wasn't found */
83 return -1;
84 return idx;
85 }
86
87static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num)
88 {
89 int idx = 0;
90 /* NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So
91 * our searches don't need to take any longer than necessary. */
92 while(!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num))
93 {
94 idx++;
95 defn++;
96 }
97 if(defn->cmd_num == num)
98 return idx;
99 /* The given cmd_num wasn't found */
100 return -1;
101 }
102
103static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p,
104 void (*f)(void))
105 {
106 int idx;
107 char *s = (char *)p;
108 /* Take care of the easy one first (eg. it requires no searches) */
109 if(cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE)
110 {
111 if((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns))
112 return 0;
113 return e->cmd_defns->cmd_num;
114 }
115 /* One or two commands require that "p" be a valid string buffer */
116 if((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) ||
117 (cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) ||
118 (cmd == ENGINE_CTRL_GET_DESC_FROM_CMD))
119 {
120 if(s == NULL)
121 {
122 ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
123 ERR_R_PASSED_NULL_PARAMETER);
124 return -1;
125 }
126 }
127 /* Now handle cmd_name -> cmd_num conversion */
128 if(cmd == ENGINE_CTRL_GET_CMD_FROM_NAME)
129 {
130 if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_name(
131 e->cmd_defns, s)) < 0))
132 {
133 ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
134 ENGINE_R_INVALID_CMD_NAME);
135 return -1;
136 }
137 return e->cmd_defns[idx].cmd_num;
138 }
139 /* For the rest of the commands, the 'long' argument must specify a
140 * valie command number - so we need to conduct a search. */
141 if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns,
142 (unsigned int)i)) < 0))
143 {
144 ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
145 ENGINE_R_INVALID_CMD_NUMBER);
146 return -1;
147 }
148 /* Now the logic splits depending on command type */
149 switch(cmd)
150 {
151 case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
152 idx++;
153 if(int_ctrl_cmd_is_null(e->cmd_defns + idx))
154 /* end-of-list */
155 return 0;
156 else
157 return e->cmd_defns[idx].cmd_num;
158 case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
159 return strlen(e->cmd_defns[idx].cmd_name);
160 case ENGINE_CTRL_GET_NAME_FROM_CMD:
161 return BIO_snprintf(s,strlen(e->cmd_defns[idx].cmd_name) + 1,
162 "%s", e->cmd_defns[idx].cmd_name);
163 case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
164 if(e->cmd_defns[idx].cmd_desc)
165 return strlen(e->cmd_defns[idx].cmd_desc);
166 return strlen(int_no_description);
167 case ENGINE_CTRL_GET_DESC_FROM_CMD:
168 if(e->cmd_defns[idx].cmd_desc)
169 return BIO_snprintf(s,
170 strlen(e->cmd_defns[idx].cmd_desc) + 1,
171 "%s", e->cmd_defns[idx].cmd_desc);
172 return BIO_snprintf(s, strlen(int_no_description) + 1,"%s",
173 int_no_description);
174 case ENGINE_CTRL_GET_CMD_FLAGS:
175 return e->cmd_defns[idx].cmd_flags;
176 }
177 /* Shouldn't really be here ... */
178 ENGINEerr(ENGINE_F_INT_CTRL_HELPER,ENGINE_R_INTERNAL_LIST_ERROR);
179 return -1;
180 }
181
182int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
183 {
184 int ctrl_exists, ref_exists;
185 if(e == NULL)
186 {
187 ENGINEerr(ENGINE_F_ENGINE_CTRL,ERR_R_PASSED_NULL_PARAMETER);
188 return 0;
189 }
190 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
191 ref_exists = ((e->struct_ref > 0) ? 1 : 0);
192 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
193 ctrl_exists = ((e->ctrl == NULL) ? 0 : 1);
194 if(!ref_exists)
195 {
196 ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_REFERENCE);
197 return 0;
198 }
199 /* Intercept any "root-level" commands before trying to hand them on to
200 * ctrl() handlers. */
201 switch(cmd)
202 {
203 case ENGINE_CTRL_HAS_CTRL_FUNCTION:
204 return ctrl_exists;
205 case ENGINE_CTRL_GET_FIRST_CMD_TYPE:
206 case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
207 case ENGINE_CTRL_GET_CMD_FROM_NAME:
208 case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
209 case ENGINE_CTRL_GET_NAME_FROM_CMD:
210 case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
211 case ENGINE_CTRL_GET_DESC_FROM_CMD:
212 case ENGINE_CTRL_GET_CMD_FLAGS:
213 if(ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL))
214 return int_ctrl_helper(e,cmd,i,p,f);
215 if(!ctrl_exists)
216 {
217 ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
218 /* For these cmd-related functions, failure is indicated
219 * by a -1 return value (because 0 is used as a valid
220 * return in some places). */
221 return -1;
222 }
223 default:
224 break;
225 }
226 /* Anything else requires a ctrl() handler to exist. */
227 if(!ctrl_exists)
228 {
229 ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
230 return 0;
231 }
232 return e->ctrl(e, cmd, i, p, f);
233 }
234
235int ENGINE_cmd_is_executable(ENGINE *e, int cmd)
236 {
237 int flags;
238 if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0)
239 {
240 ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE,
241 ENGINE_R_INVALID_CMD_NUMBER);
242 return 0;
243 }
244 if(!(flags & ENGINE_CMD_FLAG_NO_INPUT) &&
245 !(flags & ENGINE_CMD_FLAG_NUMERIC) &&
246 !(flags & ENGINE_CMD_FLAG_STRING))
247 return 0;
248 return 1;
249 }
250
251int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
252 long i, void *p, void (*f)(void), int cmd_optional)
253 {
254 int num;
255
256 if((e == NULL) || (cmd_name == NULL))
257 {
258 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
259 ERR_R_PASSED_NULL_PARAMETER);
260 return 0;
261 }
262 if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
263 ENGINE_CTRL_GET_CMD_FROM_NAME,
264 0, (void *)cmd_name, NULL)) <= 0))
265 {
266 /* If the command didn't *have* to be supported, we fake
267 * success. This allows certain settings to be specified for
268 * multiple ENGINEs and only require a change of ENGINE id
269 * (without having to selectively apply settings). Eg. changing
270 * from a hardware device back to the regular software ENGINE
271 * without editing the config file, etc. */
272 if(cmd_optional)
273 {
274 ERR_clear_error();
275 return 1;
276 }
277 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
278 ENGINE_R_INVALID_CMD_NAME);
279 return 0;
280 }
281 /* Force the result of the control command to 0 or 1, for the reasons
282 * mentioned before. */
283 if (ENGINE_ctrl(e, num, i, p, f) > 0)
284 return 1;
285 return 0;
286 }
287
288int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
289 int cmd_optional)
290 {
291 int num, flags;
292 long l;
293 char *ptr;
294 if((e == NULL) || (cmd_name == NULL))
295 {
296 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
297 ERR_R_PASSED_NULL_PARAMETER);
298 return 0;
299 }
300 if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
301 ENGINE_CTRL_GET_CMD_FROM_NAME,
302 0, (void *)cmd_name, NULL)) <= 0))
303 {
304 /* If the command didn't *have* to be supported, we fake
305 * success. This allows certain settings to be specified for
306 * multiple ENGINEs and only require a change of ENGINE id
307 * (without having to selectively apply settings). Eg. changing
308 * from a hardware device back to the regular software ENGINE
309 * without editing the config file, etc. */
310 if(cmd_optional)
311 {
312 ERR_clear_error();
313 return 1;
314 }
315 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
316 ENGINE_R_INVALID_CMD_NAME);
317 return 0;
318 }
319 if(!ENGINE_cmd_is_executable(e, num))
320 {
321 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
322 ENGINE_R_CMD_NOT_EXECUTABLE);
323 return 0;
324 }
325 if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL)) < 0)
326 {
327 /* Shouldn't happen, given that ENGINE_cmd_is_executable()
328 * returned success. */
329 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
330 ENGINE_R_INTERNAL_LIST_ERROR);
331 return 0;
332 }
333 /* If the command takes no input, there must be no input. And vice
334 * versa. */
335 if(flags & ENGINE_CMD_FLAG_NO_INPUT)
336 {
337 if(arg != NULL)
338 {
339 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
340 ENGINE_R_COMMAND_TAKES_NO_INPUT);
341 return 0;
342 }
343 /* We deliberately force the result of ENGINE_ctrl() to 0 or 1
344 * rather than returning it as "return data". This is to ensure
345 * usage of these commands is consistent across applications and
346 * that certain applications don't understand it one way, and
347 * others another. */
348 if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
349 return 1;
350 return 0;
351 }
352 /* So, we require input */
353 if(arg == NULL)
354 {
355 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
356 ENGINE_R_COMMAND_TAKES_INPUT);
357 return 0;
358 }
359 /* If it takes string input, that's easy */
360 if(flags & ENGINE_CMD_FLAG_STRING)
361 {
362 /* Same explanation as above */
363 if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
364 return 1;
365 return 0;
366 }
367 /* If it doesn't take numeric either, then it is unsupported for use in
368 * a config-setting situation, which is what this function is for. This
369 * should never happen though, because ENGINE_cmd_is_executable() was
370 * used. */
371 if(!(flags & ENGINE_CMD_FLAG_NUMERIC))
372 {
373 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
374 ENGINE_R_INTERNAL_LIST_ERROR);
375 return 0;
376 }
377 l = strtol(arg, &ptr, 10);
378 if((arg == ptr) || (*ptr != '\0'))
379 {
380 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
381 ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER);
382 return 0;
383 }
384 /* Force the result of the control command to 0 or 1, for the reasons
385 * mentioned before. */
386 if(ENGINE_ctrl(e, num, l, NULL, NULL) > 0)
387 return 1;
388 return 0;
389 }
diff --git a/src/lib/libcrypto/engine/eng_dyn.c b/src/lib/libcrypto/engine/eng_dyn.c
new file mode 100644
index 0000000000..807da7a5eb
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_dyn.c
@@ -0,0 +1,548 @@
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 "eng_int.h"
61#include <openssl/dso.h>
62
63/* Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE loader
64 * should implement the hook-up functions with the following prototypes. */
65
66/* Our ENGINE handlers */
67static int dynamic_init(ENGINE *e);
68static int dynamic_finish(ENGINE *e);
69static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
70/* Predeclare our context type */
71typedef struct st_dynamic_data_ctx dynamic_data_ctx;
72/* The implementation for the important control command */
73static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx);
74
75#define DYNAMIC_CMD_SO_PATH ENGINE_CMD_BASE
76#define DYNAMIC_CMD_NO_VCHECK (ENGINE_CMD_BASE + 1)
77#define DYNAMIC_CMD_ID (ENGINE_CMD_BASE + 2)
78#define DYNAMIC_CMD_LIST_ADD (ENGINE_CMD_BASE + 3)
79#define DYNAMIC_CMD_DIR_LOAD (ENGINE_CMD_BASE + 4)
80#define DYNAMIC_CMD_DIR_ADD (ENGINE_CMD_BASE + 5)
81#define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 6)
82
83/* The constants used when creating the ENGINE */
84static const char *engine_dynamic_id = "dynamic";
85static const char *engine_dynamic_name = "Dynamic engine loading support";
86static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = {
87 {DYNAMIC_CMD_SO_PATH,
88 "SO_PATH",
89 "Specifies the path to the new ENGINE shared library",
90 ENGINE_CMD_FLAG_STRING},
91 {DYNAMIC_CMD_NO_VCHECK,
92 "NO_VCHECK",
93 "Specifies to continue even if version checking fails (boolean)",
94 ENGINE_CMD_FLAG_NUMERIC},
95 {DYNAMIC_CMD_ID,
96 "ID",
97 "Specifies an ENGINE id name for loading",
98 ENGINE_CMD_FLAG_STRING},
99 {DYNAMIC_CMD_LIST_ADD,
100 "LIST_ADD",
101 "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)",
102 ENGINE_CMD_FLAG_NUMERIC},
103 {DYNAMIC_CMD_DIR_LOAD,
104 "DIR_LOAD",
105 "Specifies whether to load from 'DIR_ADD' directories (0=no,1=yes,2=mandatory)",
106 ENGINE_CMD_FLAG_NUMERIC},
107 {DYNAMIC_CMD_DIR_ADD,
108 "DIR_ADD",
109 "Adds a directory from which ENGINEs can be loaded",
110 ENGINE_CMD_FLAG_STRING},
111 {DYNAMIC_CMD_LOAD,
112 "LOAD",
113 "Load up the ENGINE specified by other settings",
114 ENGINE_CMD_FLAG_NO_INPUT},
115 {0, NULL, NULL, 0}
116 };
117static const ENGINE_CMD_DEFN dynamic_cmd_defns_empty[] = {
118 {0, NULL, NULL, 0}
119 };
120
121/* Loading code stores state inside the ENGINE structure via the "ex_data"
122 * element. We load all our state into a single structure and use that as a
123 * single context in the "ex_data" stack. */
124struct st_dynamic_data_ctx
125 {
126 /* The DSO object we load that supplies the ENGINE code */
127 DSO *dynamic_dso;
128 /* The function pointer to the version checking shared library function */
129 dynamic_v_check_fn v_check;
130 /* The function pointer to the engine-binding shared library function */
131 dynamic_bind_engine bind_engine;
132 /* The default name/path for loading the shared library */
133 const char *DYNAMIC_LIBNAME;
134 /* Whether to continue loading on a version check failure */
135 int no_vcheck;
136 /* If non-NULL, stipulates the 'id' of the ENGINE to be loaded */
137 const char *engine_id;
138 /* If non-zero, a successfully loaded ENGINE should be added to the internal
139 * ENGINE list. If 2, the add must succeed or the entire load should fail. */
140 int list_add_value;
141 /* The symbol name for the version checking function */
142 const char *DYNAMIC_F1;
143 /* The symbol name for the "initialise ENGINE structure" function */
144 const char *DYNAMIC_F2;
145 /* Whether to never use 'dirs', use 'dirs' as a fallback, or only use
146 * 'dirs' for loading. Default is to use 'dirs' as a fallback. */
147 int dir_load;
148 /* A stack of directories from which ENGINEs could be loaded */
149 STACK_OF(OPENSSL_STRING) *dirs;
150 };
151
152/* This is the "ex_data" index we obtain and reserve for use with our context
153 * structure. */
154static int dynamic_ex_data_idx = -1;
155
156static void int_free_str(char *s) { OPENSSL_free(s); }
157/* Because our ex_data element may or may not get allocated depending on whether
158 * a "first-use" occurs before the ENGINE is freed, we have a memory leak
159 * problem to solve. We can't declare a "new" handler for the ex_data as we
160 * don't want a dynamic_data_ctx in *all* ENGINE structures of all types (this
161 * is a bug in the design of CRYPTO_EX_DATA). As such, we just declare a "free"
162 * handler and that will get called if an ENGINE is being destroyed and there
163 * was an ex_data element corresponding to our context type. */
164static void dynamic_data_ctx_free_func(void *parent, void *ptr,
165 CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
166 {
167 if(ptr)
168 {
169 dynamic_data_ctx *ctx = (dynamic_data_ctx *)ptr;
170 if(ctx->dynamic_dso)
171 DSO_free(ctx->dynamic_dso);
172 if(ctx->DYNAMIC_LIBNAME)
173 OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME);
174 if(ctx->engine_id)
175 OPENSSL_free((void*)ctx->engine_id);
176 if(ctx->dirs)
177 sk_OPENSSL_STRING_pop_free(ctx->dirs, int_free_str);
178 OPENSSL_free(ctx);
179 }
180 }
181
182/* Construct the per-ENGINE context. We create it blindly and then use a lock to
183 * check for a race - if so, all but one of the threads "racing" will have
184 * wasted their time. The alternative involves creating everything inside the
185 * lock which is far worse. */
186static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
187 {
188 dynamic_data_ctx *c;
189 c = OPENSSL_malloc(sizeof(dynamic_data_ctx));
190 if(!c)
191 {
192 ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
193 return 0;
194 }
195 memset(c, 0, sizeof(dynamic_data_ctx));
196 c->dynamic_dso = NULL;
197 c->v_check = NULL;
198 c->bind_engine = NULL;
199 c->DYNAMIC_LIBNAME = NULL;
200 c->no_vcheck = 0;
201 c->engine_id = NULL;
202 c->list_add_value = 0;
203 c->DYNAMIC_F1 = "v_check";
204 c->DYNAMIC_F2 = "bind_engine";
205 c->dir_load = 1;
206 c->dirs = sk_OPENSSL_STRING_new_null();
207 if(!c->dirs)
208 {
209 ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
210 OPENSSL_free(c);
211 return 0;
212 }
213 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
214 if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e,
215 dynamic_ex_data_idx)) == NULL)
216 {
217 /* Good, we're the first */
218 ENGINE_set_ex_data(e, dynamic_ex_data_idx, c);
219 *ctx = c;
220 c = NULL;
221 }
222 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
223 /* If we lost the race to set the context, c is non-NULL and *ctx is the
224 * context of the thread that won. */
225 if(c)
226 OPENSSL_free(c);
227 return 1;
228 }
229
230/* This function retrieves the context structure from an ENGINE's "ex_data", or
231 * if it doesn't exist yet, sets it up. */
232static dynamic_data_ctx *dynamic_get_data_ctx(ENGINE *e)
233 {
234 dynamic_data_ctx *ctx;
235 if(dynamic_ex_data_idx < 0)
236 {
237 /* Create and register the ENGINE ex_data, and associate our
238 * "free" function with it to ensure any allocated contexts get
239 * freed when an ENGINE goes underground. */
240 int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL,
241 dynamic_data_ctx_free_func);
242 if(new_idx == -1)
243 {
244 ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX,ENGINE_R_NO_INDEX);
245 return NULL;
246 }
247 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
248 /* Avoid a race by checking again inside this lock */
249 if(dynamic_ex_data_idx < 0)
250 {
251 /* Good, someone didn't beat us to it */
252 dynamic_ex_data_idx = new_idx;
253 new_idx = -1;
254 }
255 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
256 /* In theory we could "give back" the index here if
257 * (new_idx>-1), but it's not possible and wouldn't gain us much
258 * if it were. */
259 }
260 ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx);
261 /* Check if the context needs to be created */
262 if((ctx == NULL) && !dynamic_set_data_ctx(e, &ctx))
263 /* "set_data" will set errors if necessary */
264 return NULL;
265 return ctx;
266 }
267
268static ENGINE *engine_dynamic(void)
269 {
270 ENGINE *ret = ENGINE_new();
271 if(!ret)
272 return NULL;
273 if(!ENGINE_set_id(ret, engine_dynamic_id) ||
274 !ENGINE_set_name(ret, engine_dynamic_name) ||
275 !ENGINE_set_init_function(ret, dynamic_init) ||
276 !ENGINE_set_finish_function(ret, dynamic_finish) ||
277 !ENGINE_set_ctrl_function(ret, dynamic_ctrl) ||
278 !ENGINE_set_flags(ret, ENGINE_FLAGS_BY_ID_COPY) ||
279 !ENGINE_set_cmd_defns(ret, dynamic_cmd_defns))
280 {
281 ENGINE_free(ret);
282 return NULL;
283 }
284 return ret;
285 }
286
287void ENGINE_load_dynamic(void)
288 {
289 ENGINE *toadd = engine_dynamic();
290 if(!toadd) return;
291 ENGINE_add(toadd);
292 /* If the "add" worked, it gets a structural reference. So either way,
293 * we release our just-created reference. */
294 ENGINE_free(toadd);
295 /* If the "add" didn't work, it was probably a conflict because it was
296 * already added (eg. someone calling ENGINE_load_blah then calling
297 * ENGINE_load_builtin_engines() perhaps). */
298 ERR_clear_error();
299 }
300
301static int dynamic_init(ENGINE *e)
302 {
303 /* We always return failure - the "dyanamic" engine itself can't be used
304 * for anything. */
305 return 0;
306 }
307
308static int dynamic_finish(ENGINE *e)
309 {
310 /* This should never be called on account of "dynamic_init" always
311 * failing. */
312 return 0;
313 }
314
315static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
316 {
317 dynamic_data_ctx *ctx = dynamic_get_data_ctx(e);
318 int initialised;
319
320 if(!ctx)
321 {
322 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_NOT_LOADED);
323 return 0;
324 }
325 initialised = ((ctx->dynamic_dso == NULL) ? 0 : 1);
326 /* All our control commands require the ENGINE to be uninitialised */
327 if(initialised)
328 {
329 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
330 ENGINE_R_ALREADY_LOADED);
331 return 0;
332 }
333 switch(cmd)
334 {
335 case DYNAMIC_CMD_SO_PATH:
336 /* a NULL 'p' or a string of zero-length is the same thing */
337 if(p && (strlen((const char *)p) < 1))
338 p = NULL;
339 if(ctx->DYNAMIC_LIBNAME)
340 OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME);
341 if(p)
342 ctx->DYNAMIC_LIBNAME = BUF_strdup(p);
343 else
344 ctx->DYNAMIC_LIBNAME = NULL;
345 return (ctx->DYNAMIC_LIBNAME ? 1 : 0);
346 case DYNAMIC_CMD_NO_VCHECK:
347 ctx->no_vcheck = ((i == 0) ? 0 : 1);
348 return 1;
349 case DYNAMIC_CMD_ID:
350 /* a NULL 'p' or a string of zero-length is the same thing */
351 if(p && (strlen((const char *)p) < 1))
352 p = NULL;
353 if(ctx->engine_id)
354 OPENSSL_free((void*)ctx->engine_id);
355 if(p)
356 ctx->engine_id = BUF_strdup(p);
357 else
358 ctx->engine_id = NULL;
359 return (ctx->engine_id ? 1 : 0);
360 case DYNAMIC_CMD_LIST_ADD:
361 if((i < 0) || (i > 2))
362 {
363 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
364 ENGINE_R_INVALID_ARGUMENT);
365 return 0;
366 }
367 ctx->list_add_value = (int)i;
368 return 1;
369 case DYNAMIC_CMD_LOAD:
370 return dynamic_load(e, ctx);
371 case DYNAMIC_CMD_DIR_LOAD:
372 if((i < 0) || (i > 2))
373 {
374 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
375 ENGINE_R_INVALID_ARGUMENT);
376 return 0;
377 }
378 ctx->dir_load = (int)i;
379 return 1;
380 case DYNAMIC_CMD_DIR_ADD:
381 /* a NULL 'p' or a string of zero-length is the same thing */
382 if(!p || (strlen((const char *)p) < 1))
383 {
384 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
385 ENGINE_R_INVALID_ARGUMENT);
386 return 0;
387 }
388 {
389 char *tmp_str = BUF_strdup(p);
390 if(!tmp_str)
391 {
392 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
393 ERR_R_MALLOC_FAILURE);
394 return 0;
395 }
396 sk_OPENSSL_STRING_insert(ctx->dirs, tmp_str, -1);
397 }
398 return 1;
399 default:
400 break;
401 }
402 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
403 return 0;
404 }
405
406static int int_load(dynamic_data_ctx *ctx)
407 {
408 int num, loop;
409 /* Unless told not to, try a direct load */
410 if((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso,
411 ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL)
412 return 1;
413 /* If we're not allowed to use 'dirs' or we have none, fail */
414 if(!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1)
415 return 0;
416 for(loop = 0; loop < num; loop++)
417 {
418 const char *s = sk_OPENSSL_STRING_value(ctx->dirs, loop);
419 char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s);
420 if(!merge)
421 return 0;
422 if(DSO_load(ctx->dynamic_dso, merge, NULL, 0))
423 {
424 /* Found what we're looking for */
425 OPENSSL_free(merge);
426 return 1;
427 }
428 OPENSSL_free(merge);
429 }
430 return 0;
431 }
432
433static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
434 {
435 ENGINE cpy;
436 dynamic_fns fns;
437
438 if(!ctx->dynamic_dso)
439 ctx->dynamic_dso = DSO_new();
440 if(!ctx->DYNAMIC_LIBNAME)
441 {
442 if(!ctx->engine_id)
443 return 0;
444 ctx->DYNAMIC_LIBNAME =
445 DSO_convert_filename(ctx->dynamic_dso, ctx->engine_id);
446 }
447 if(!int_load(ctx))
448 {
449 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
450 ENGINE_R_DSO_NOT_FOUND);
451 DSO_free(ctx->dynamic_dso);
452 ctx->dynamic_dso = NULL;
453 return 0;
454 }
455 /* We have to find a bind function otherwise it'll always end badly */
456 if(!(ctx->bind_engine = (dynamic_bind_engine)DSO_bind_func(
457 ctx->dynamic_dso, ctx->DYNAMIC_F2)))
458 {
459 ctx->bind_engine = NULL;
460 DSO_free(ctx->dynamic_dso);
461 ctx->dynamic_dso = NULL;
462 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
463 ENGINE_R_DSO_FAILURE);
464 return 0;
465 }
466 /* Do we perform version checking? */
467 if(!ctx->no_vcheck)
468 {
469 unsigned long vcheck_res = 0;
470 /* Now we try to find a version checking function and decide how
471 * to cope with failure if/when it fails. */
472 ctx->v_check = (dynamic_v_check_fn)DSO_bind_func(
473 ctx->dynamic_dso, ctx->DYNAMIC_F1);
474 if(ctx->v_check)
475 vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION);
476 /* We fail if the version checker veto'd the load *or* if it is
477 * deferring to us (by returning its version) and we think it is
478 * too old. */
479 if(vcheck_res < OSSL_DYNAMIC_OLDEST)
480 {
481 /* Fail */
482 ctx->bind_engine = NULL;
483 ctx->v_check = NULL;
484 DSO_free(ctx->dynamic_dso);
485 ctx->dynamic_dso = NULL;
486 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
487 ENGINE_R_VERSION_INCOMPATIBILITY);
488 return 0;
489 }
490 }
491 /* First binary copy the ENGINE structure so that we can roll back if
492 * the hand-over fails */
493 memcpy(&cpy, e, sizeof(ENGINE));
494 /* Provide the ERR, "ex_data", memory, and locking callbacks so the
495 * loaded library uses our state rather than its own. FIXME: As noted in
496 * engine.h, much of this would be simplified if each area of code
497 * provided its own "summary" structure of all related callbacks. It
498 * would also increase opaqueness. */
499 fns.static_state = ENGINE_get_static_state();
500 fns.err_fns = ERR_get_implementation();
501 fns.ex_data_fns = CRYPTO_get_ex_data_implementation();
502 CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb,
503 &fns.mem_fns.realloc_cb,
504 &fns.mem_fns.free_cb);
505 fns.lock_fns.lock_locking_cb = CRYPTO_get_locking_callback();
506 fns.lock_fns.lock_add_lock_cb = CRYPTO_get_add_lock_callback();
507 fns.lock_fns.dynlock_create_cb = CRYPTO_get_dynlock_create_callback();
508 fns.lock_fns.dynlock_lock_cb = CRYPTO_get_dynlock_lock_callback();
509 fns.lock_fns.dynlock_destroy_cb = CRYPTO_get_dynlock_destroy_callback();
510 /* Now that we've loaded the dynamic engine, make sure no "dynamic"
511 * ENGINE elements will show through. */
512 engine_set_all_null(e);
513
514 /* Try to bind the ENGINE onto our own ENGINE structure */
515 if(!ctx->bind_engine(e, ctx->engine_id, &fns))
516 {
517 ctx->bind_engine = NULL;
518 ctx->v_check = NULL;
519 DSO_free(ctx->dynamic_dso);
520 ctx->dynamic_dso = NULL;
521 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,ENGINE_R_INIT_FAILED);
522 /* Copy the original ENGINE structure back */
523 memcpy(e, &cpy, sizeof(ENGINE));
524 return 0;
525 }
526 /* Do we try to add this ENGINE to the internal list too? */
527 if(ctx->list_add_value > 0)
528 {
529 if(!ENGINE_add(e))
530 {
531 /* Do we tolerate this or fail? */
532 if(ctx->list_add_value > 1)
533 {
534 /* Fail - NB: By this time, it's too late to
535 * rollback, and trying to do so allows the
536 * bind_engine() code to have created leaks. We
537 * just have to fail where we are, after the
538 * ENGINE has changed. */
539 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
540 ENGINE_R_CONFLICTING_ENGINE_ID);
541 return 0;
542 }
543 /* Tolerate */
544 ERR_clear_error();
545 }
546 }
547 return 1;
548 }
diff --git a/src/lib/libcrypto/engine/eng_err.c b/src/lib/libcrypto/engine/eng_err.c
new file mode 100644
index 0000000000..81c70acfa8
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_err.c
@@ -0,0 +1,173 @@
1/* crypto/engine/eng_err.c */
2/* ====================================================================
3 * Copyright (c) 1999-2010 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
67
68#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ENGINE,func,0)
69#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ENGINE,0,reason)
70
71static ERR_STRING_DATA ENGINE_str_functs[]=
72 {
73{ERR_FUNC(ENGINE_F_DYNAMIC_CTRL), "DYNAMIC_CTRL"},
74{ERR_FUNC(ENGINE_F_DYNAMIC_GET_DATA_CTX), "DYNAMIC_GET_DATA_CTX"},
75{ERR_FUNC(ENGINE_F_DYNAMIC_LOAD), "DYNAMIC_LOAD"},
76{ERR_FUNC(ENGINE_F_DYNAMIC_SET_DATA_CTX), "DYNAMIC_SET_DATA_CTX"},
77{ERR_FUNC(ENGINE_F_ENGINE_ADD), "ENGINE_add"},
78{ERR_FUNC(ENGINE_F_ENGINE_BY_ID), "ENGINE_by_id"},
79{ERR_FUNC(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE), "ENGINE_cmd_is_executable"},
80{ERR_FUNC(ENGINE_F_ENGINE_CTRL), "ENGINE_ctrl"},
81{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD), "ENGINE_ctrl_cmd"},
82{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD_STRING), "ENGINE_ctrl_cmd_string"},
83{ERR_FUNC(ENGINE_F_ENGINE_FINISH), "ENGINE_finish"},
84{ERR_FUNC(ENGINE_F_ENGINE_FREE_UTIL), "ENGINE_FREE_UTIL"},
85{ERR_FUNC(ENGINE_F_ENGINE_GET_CIPHER), "ENGINE_get_cipher"},
86{ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE), "ENGINE_GET_DEFAULT_TYPE"},
87{ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST), "ENGINE_get_digest"},
88{ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT), "ENGINE_get_next"},
89{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH), "ENGINE_get_pkey_asn1_meth"},
90{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_METH), "ENGINE_get_pkey_meth"},
91{ERR_FUNC(ENGINE_F_ENGINE_GET_PREV), "ENGINE_get_prev"},
92{ERR_FUNC(ENGINE_F_ENGINE_INIT), "ENGINE_init"},
93{ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD), "ENGINE_LIST_ADD"},
94{ERR_FUNC(ENGINE_F_ENGINE_LIST_REMOVE), "ENGINE_LIST_REMOVE"},
95{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY), "ENGINE_load_private_key"},
96{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY), "ENGINE_load_public_key"},
97{ERR_FUNC(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT), "ENGINE_load_ssl_client_cert"},
98{ERR_FUNC(ENGINE_F_ENGINE_NEW), "ENGINE_new"},
99{ERR_FUNC(ENGINE_F_ENGINE_REMOVE), "ENGINE_remove"},
100{ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_STRING), "ENGINE_set_default_string"},
101{ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_TYPE), "ENGINE_SET_DEFAULT_TYPE"},
102{ERR_FUNC(ENGINE_F_ENGINE_SET_ID), "ENGINE_set_id"},
103{ERR_FUNC(ENGINE_F_ENGINE_SET_NAME), "ENGINE_set_name"},
104{ERR_FUNC(ENGINE_F_ENGINE_TABLE_REGISTER), "ENGINE_TABLE_REGISTER"},
105{ERR_FUNC(ENGINE_F_ENGINE_UNLOAD_KEY), "ENGINE_UNLOAD_KEY"},
106{ERR_FUNC(ENGINE_F_ENGINE_UNLOCKED_FINISH), "ENGINE_UNLOCKED_FINISH"},
107{ERR_FUNC(ENGINE_F_ENGINE_UP_REF), "ENGINE_up_ref"},
108{ERR_FUNC(ENGINE_F_INT_CTRL_HELPER), "INT_CTRL_HELPER"},
109{ERR_FUNC(ENGINE_F_INT_ENGINE_CONFIGURE), "INT_ENGINE_CONFIGURE"},
110{ERR_FUNC(ENGINE_F_INT_ENGINE_MODULE_INIT), "INT_ENGINE_MODULE_INIT"},
111{ERR_FUNC(ENGINE_F_LOG_MESSAGE), "LOG_MESSAGE"},
112{0,NULL}
113 };
114
115static ERR_STRING_DATA ENGINE_str_reasons[]=
116 {
117{ERR_REASON(ENGINE_R_ALREADY_LOADED) ,"already loaded"},
118{ERR_REASON(ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER),"argument is not a number"},
119{ERR_REASON(ENGINE_R_CMD_NOT_EXECUTABLE) ,"cmd not executable"},
120{ERR_REASON(ENGINE_R_COMMAND_TAKES_INPUT),"command takes input"},
121{ERR_REASON(ENGINE_R_COMMAND_TAKES_NO_INPUT),"command takes no input"},
122{ERR_REASON(ENGINE_R_CONFLICTING_ENGINE_ID),"conflicting engine id"},
123{ERR_REASON(ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
124{ERR_REASON(ENGINE_R_DH_NOT_IMPLEMENTED) ,"dh not implemented"},
125{ERR_REASON(ENGINE_R_DSA_NOT_IMPLEMENTED),"dsa not implemented"},
126{ERR_REASON(ENGINE_R_DSO_FAILURE) ,"DSO failure"},
127{ERR_REASON(ENGINE_R_DSO_NOT_FOUND) ,"dso not found"},
128{ERR_REASON(ENGINE_R_ENGINES_SECTION_ERROR),"engines section error"},
129{ERR_REASON(ENGINE_R_ENGINE_CONFIGURATION_ERROR),"engine configuration error"},
130{ERR_REASON(ENGINE_R_ENGINE_IS_NOT_IN_LIST),"engine is not in the list"},
131{ERR_REASON(ENGINE_R_ENGINE_SECTION_ERROR),"engine section error"},
132{ERR_REASON(ENGINE_R_FAILED_LOADING_PRIVATE_KEY),"failed loading private key"},
133{ERR_REASON(ENGINE_R_FAILED_LOADING_PUBLIC_KEY),"failed loading public key"},
134{ERR_REASON(ENGINE_R_FINISH_FAILED) ,"finish failed"},
135{ERR_REASON(ENGINE_R_GET_HANDLE_FAILED) ,"could not obtain hardware handle"},
136{ERR_REASON(ENGINE_R_ID_OR_NAME_MISSING) ,"'id' or 'name' missing"},
137{ERR_REASON(ENGINE_R_INIT_FAILED) ,"init failed"},
138{ERR_REASON(ENGINE_R_INTERNAL_LIST_ERROR),"internal list error"},
139{ERR_REASON(ENGINE_R_INVALID_ARGUMENT) ,"invalid argument"},
140{ERR_REASON(ENGINE_R_INVALID_CMD_NAME) ,"invalid cmd name"},
141{ERR_REASON(ENGINE_R_INVALID_CMD_NUMBER) ,"invalid cmd number"},
142{ERR_REASON(ENGINE_R_INVALID_INIT_VALUE) ,"invalid init value"},
143{ERR_REASON(ENGINE_R_INVALID_STRING) ,"invalid string"},
144{ERR_REASON(ENGINE_R_NOT_INITIALISED) ,"not initialised"},
145{ERR_REASON(ENGINE_R_NOT_LOADED) ,"not loaded"},
146{ERR_REASON(ENGINE_R_NO_CONTROL_FUNCTION),"no control function"},
147{ERR_REASON(ENGINE_R_NO_INDEX) ,"no index"},
148{ERR_REASON(ENGINE_R_NO_LOAD_FUNCTION) ,"no load function"},
149{ERR_REASON(ENGINE_R_NO_REFERENCE) ,"no reference"},
150{ERR_REASON(ENGINE_R_NO_SUCH_ENGINE) ,"no such engine"},
151{ERR_REASON(ENGINE_R_NO_UNLOAD_FUNCTION) ,"no unload function"},
152{ERR_REASON(ENGINE_R_PROVIDE_PARAMETERS) ,"provide parameters"},
153{ERR_REASON(ENGINE_R_RSA_NOT_IMPLEMENTED),"rsa not implemented"},
154{ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER),"unimplemented cipher"},
155{ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST),"unimplemented digest"},
156{ERR_REASON(ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD),"unimplemented public key method"},
157{ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY),"version incompatibility"},
158{0,NULL}
159 };
160
161#endif
162
163void ERR_load_ENGINE_strings(void)
164 {
165#ifndef OPENSSL_NO_ERR
166
167 if (ERR_func_error_string(ENGINE_str_functs[0].error) == NULL)
168 {
169 ERR_load_strings(0,ENGINE_str_functs);
170 ERR_load_strings(0,ENGINE_str_reasons);
171 }
172#endif
173 }
diff --git a/src/lib/libcrypto/engine/eng_fat.c b/src/lib/libcrypto/engine/eng_fat.c
new file mode 100644
index 0000000000..db66e62350
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_fat.c
@@ -0,0 +1,181 @@
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 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
57 * ECDH support in OpenSSL originally developed by
58 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
59 */
60
61#include "eng_int.h"
62#include <openssl/conf.h>
63
64int ENGINE_set_default(ENGINE *e, unsigned int flags)
65 {
66 if((flags & ENGINE_METHOD_CIPHERS) && !ENGINE_set_default_ciphers(e))
67 return 0;
68 if((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e))
69 return 0;
70#ifndef OPENSSL_NO_RSA
71 if((flags & ENGINE_METHOD_RSA) && !ENGINE_set_default_RSA(e))
72 return 0;
73#endif
74#ifndef OPENSSL_NO_DSA
75 if((flags & ENGINE_METHOD_DSA) && !ENGINE_set_default_DSA(e))
76 return 0;
77#endif
78#ifndef OPENSSL_NO_DH
79 if((flags & ENGINE_METHOD_DH) && !ENGINE_set_default_DH(e))
80 return 0;
81#endif
82#ifndef OPENSSL_NO_ECDH
83 if((flags & ENGINE_METHOD_ECDH) && !ENGINE_set_default_ECDH(e))
84 return 0;
85#endif
86#ifndef OPENSSL_NO_ECDSA
87 if((flags & ENGINE_METHOD_ECDSA) && !ENGINE_set_default_ECDSA(e))
88 return 0;
89#endif
90 if((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e))
91 return 0;
92 if((flags & ENGINE_METHOD_PKEY_METHS)
93 && !ENGINE_set_default_pkey_meths(e))
94 return 0;
95 if((flags & ENGINE_METHOD_PKEY_ASN1_METHS)
96 && !ENGINE_set_default_pkey_asn1_meths(e))
97 return 0;
98 return 1;
99 }
100
101/* Set default algorithms using a string */
102
103static int int_def_cb(const char *alg, int len, void *arg)
104 {
105 unsigned int *pflags = arg;
106 if (!strncmp(alg, "ALL", len))
107 *pflags |= ENGINE_METHOD_ALL;
108 else if (!strncmp(alg, "RSA", len))
109 *pflags |= ENGINE_METHOD_RSA;
110 else if (!strncmp(alg, "DSA", len))
111 *pflags |= ENGINE_METHOD_DSA;
112 else if (!strncmp(alg, "ECDH", len))
113 *pflags |= ENGINE_METHOD_ECDH;
114 else if (!strncmp(alg, "ECDSA", len))
115 *pflags |= ENGINE_METHOD_ECDSA;
116 else if (!strncmp(alg, "DH", len))
117 *pflags |= ENGINE_METHOD_DH;
118 else if (!strncmp(alg, "RAND", len))
119 *pflags |= ENGINE_METHOD_RAND;
120 else if (!strncmp(alg, "CIPHERS", len))
121 *pflags |= ENGINE_METHOD_CIPHERS;
122 else if (!strncmp(alg, "DIGESTS", len))
123 *pflags |= ENGINE_METHOD_DIGESTS;
124 else if (!strncmp(alg, "PKEY", len))
125 *pflags |=
126 ENGINE_METHOD_PKEY_METHS|ENGINE_METHOD_PKEY_ASN1_METHS;
127 else if (!strncmp(alg, "PKEY_CRYPTO", len))
128 *pflags |= ENGINE_METHOD_PKEY_METHS;
129 else if (!strncmp(alg, "PKEY_ASN1", len))
130 *pflags |= ENGINE_METHOD_PKEY_ASN1_METHS;
131 else
132 return 0;
133 return 1;
134 }
135
136
137int ENGINE_set_default_string(ENGINE *e, const char *def_list)
138 {
139 unsigned int flags = 0;
140 if (!CONF_parse_list(def_list, ',', 1, int_def_cb, &flags))
141 {
142 ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_STRING,
143 ENGINE_R_INVALID_STRING);
144 ERR_add_error_data(2, "str=",def_list);
145 return 0;
146 }
147 return ENGINE_set_default(e, flags);
148 }
149
150int ENGINE_register_complete(ENGINE *e)
151 {
152 ENGINE_register_ciphers(e);
153 ENGINE_register_digests(e);
154#ifndef OPENSSL_NO_RSA
155 ENGINE_register_RSA(e);
156#endif
157#ifndef OPENSSL_NO_DSA
158 ENGINE_register_DSA(e);
159#endif
160#ifndef OPENSSL_NO_DH
161 ENGINE_register_DH(e);
162#endif
163#ifndef OPENSSL_NO_ECDH
164 ENGINE_register_ECDH(e);
165#endif
166#ifndef OPENSSL_NO_ECDSA
167 ENGINE_register_ECDSA(e);
168#endif
169 ENGINE_register_RAND(e);
170 ENGINE_register_pkey_meths(e);
171 return 1;
172 }
173
174int ENGINE_register_all_complete(void)
175 {
176 ENGINE *e;
177
178 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
179 ENGINE_register_complete(e);
180 return 1;
181 }
diff --git a/src/lib/libcrypto/engine/eng_init.c b/src/lib/libcrypto/engine/eng_init.c
new file mode 100644
index 0000000000..7633cf5f1d
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_init.c
@@ -0,0 +1,154 @@
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 "eng_int.h"
57
58/* Initialise a engine type for use (or up its functional reference count
59 * if it's already in use). This version is only used internally. */
60int engine_unlocked_init(ENGINE *e)
61 {
62 int to_return = 1;
63
64 if((e->funct_ref == 0) && e->init)
65 /* This is the first functional reference and the engine
66 * requires initialisation so we do it now. */
67 to_return = e->init(e);
68 if(to_return)
69 {
70 /* OK, we return a functional reference which is also a
71 * structural reference. */
72 e->struct_ref++;
73 e->funct_ref++;
74 engine_ref_debug(e, 0, 1)
75 engine_ref_debug(e, 1, 1)
76 }
77 return to_return;
78 }
79
80/* Free a functional reference to a engine type. This version is only used
81 * internally. */
82int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers)
83 {
84 int to_return = 1;
85
86 /* Reduce the functional reference count here so if it's the terminating
87 * case, we can release the lock safely and call the finish() handler
88 * without risk of a race. We get a race if we leave the count until
89 * after and something else is calling "finish" at the same time -
90 * there's a chance that both threads will together take the count from
91 * 2 to 0 without either calling finish(). */
92 e->funct_ref--;
93 engine_ref_debug(e, 1, -1);
94 if((e->funct_ref == 0) && e->finish)
95 {
96 if(unlock_for_handlers)
97 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
98 to_return = e->finish(e);
99 if(unlock_for_handlers)
100 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
101 if(!to_return)
102 return 0;
103 }
104#ifdef REF_CHECK
105 if(e->funct_ref < 0)
106 {
107 fprintf(stderr,"ENGINE_finish, bad functional reference count\n");
108 abort();
109 }
110#endif
111 /* Release the structural reference too */
112 if(!engine_free_util(e, 0))
113 {
114 ENGINEerr(ENGINE_F_ENGINE_UNLOCKED_FINISH,ENGINE_R_FINISH_FAILED);
115 return 0;
116 }
117 return to_return;
118 }
119
120/* The API (locked) version of "init" */
121int ENGINE_init(ENGINE *e)
122 {
123 int ret;
124 if(e == NULL)
125 {
126 ENGINEerr(ENGINE_F_ENGINE_INIT,ERR_R_PASSED_NULL_PARAMETER);
127 return 0;
128 }
129 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
130 ret = engine_unlocked_init(e);
131 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
132 return ret;
133 }
134
135/* The API (locked) version of "finish" */
136int ENGINE_finish(ENGINE *e)
137 {
138 int to_return = 1;
139
140 if(e == NULL)
141 {
142 ENGINEerr(ENGINE_F_ENGINE_FINISH,ERR_R_PASSED_NULL_PARAMETER);
143 return 0;
144 }
145 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
146 to_return = engine_unlocked_finish(e, 1);
147 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
148 if(!to_return)
149 {
150 ENGINEerr(ENGINE_F_ENGINE_FINISH,ENGINE_R_FINISH_FAILED);
151 return 0;
152 }
153 return to_return;
154 }
diff --git a/src/lib/libcrypto/engine/eng_int.h b/src/lib/libcrypto/engine/eng_int.h
new file mode 100644
index 0000000000..451ef8feb8
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_int.h
@@ -0,0 +1,206 @@
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 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * ECDH support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
63
64#ifndef HEADER_ENGINE_INT_H
65#define HEADER_ENGINE_INT_H
66
67#include "cryptlib.h"
68/* Take public definitions from engine.h */
69#include <openssl/engine.h>
70
71#ifdef __cplusplus
72extern "C" {
73#endif
74
75/* If we compile with this symbol defined, then both reference counts in the
76 * ENGINE structure will be monitored with a line of output on stderr for each
77 * change. This prints the engine's pointer address (truncated to unsigned int),
78 * "struct" or "funct" to indicate the reference type, the before and after
79 * reference count, and the file:line-number pair. The "engine_ref_debug"
80 * statements must come *after* the change. */
81#ifdef ENGINE_REF_COUNT_DEBUG
82
83#define engine_ref_debug(e, isfunct, diff) \
84 fprintf(stderr, "engine: %08x %s from %d to %d (%s:%d)\n", \
85 (unsigned int)(e), (isfunct ? "funct" : "struct"), \
86 ((isfunct) ? ((e)->funct_ref - (diff)) : ((e)->struct_ref - (diff))), \
87 ((isfunct) ? (e)->funct_ref : (e)->struct_ref), \
88 (__FILE__), (__LINE__));
89
90#else
91
92#define engine_ref_debug(e, isfunct, diff)
93
94#endif
95
96/* Any code that will need cleanup operations should use these functions to
97 * register callbacks. ENGINE_cleanup() will call all registered callbacks in
98 * order. NB: both the "add" functions assume CRYPTO_LOCK_ENGINE to already be
99 * held (in "write" mode). */
100typedef void (ENGINE_CLEANUP_CB)(void);
101typedef struct st_engine_cleanup_item
102 {
103 ENGINE_CLEANUP_CB *cb;
104 } ENGINE_CLEANUP_ITEM;
105DECLARE_STACK_OF(ENGINE_CLEANUP_ITEM)
106void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb);
107void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb);
108
109/* We need stacks of ENGINEs for use in eng_table.c */
110DECLARE_STACK_OF(ENGINE)
111
112/* If this symbol is defined then engine_table_select(), the function that is
113 * used by RSA, DSA (etc) code to select registered ENGINEs, cache defaults and
114 * functional references (etc), will display debugging summaries to stderr. */
115/* #define ENGINE_TABLE_DEBUG */
116
117/* This represents an implementation table. Dependent code should instantiate it
118 * as a (ENGINE_TABLE *) pointer value set initially to NULL. */
119typedef struct st_engine_table ENGINE_TABLE;
120int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
121 ENGINE *e, const int *nids, int num_nids, int setdefault);
122void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e);
123void engine_table_cleanup(ENGINE_TABLE **table);
124#ifndef ENGINE_TABLE_DEBUG
125ENGINE *engine_table_select(ENGINE_TABLE **table, int nid);
126#else
127ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l);
128#define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__)
129#endif
130typedef void (engine_table_doall_cb)(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg);
131void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, void *arg);
132
133/* Internal versions of API functions that have control over locking. These are
134 * used between C files when functionality needs to be shared but the caller may
135 * already be controlling of the CRYPTO_LOCK_ENGINE lock. */
136int engine_unlocked_init(ENGINE *e);
137int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers);
138int engine_free_util(ENGINE *e, int locked);
139
140/* This function will reset all "set"able values in an ENGINE to NULL. This
141 * won't touch reference counts or ex_data, but is equivalent to calling all the
142 * ENGINE_set_***() functions with a NULL value. */
143void engine_set_all_null(ENGINE *e);
144
145/* NB: Bitwise OR-able values for the "flags" variable in ENGINE are now exposed
146 * in engine.h. */
147
148/* Free up dynamically allocated public key methods associated with ENGINE */
149
150void engine_pkey_meths_free(ENGINE *e);
151void engine_pkey_asn1_meths_free(ENGINE *e);
152
153/* This is a structure for storing implementations of various crypto
154 * algorithms and functions. */
155struct engine_st
156 {
157 const char *id;
158 const char *name;
159 const RSA_METHOD *rsa_meth;
160 const DSA_METHOD *dsa_meth;
161 const DH_METHOD *dh_meth;
162 const ECDH_METHOD *ecdh_meth;
163 const ECDSA_METHOD *ecdsa_meth;
164 const RAND_METHOD *rand_meth;
165 const STORE_METHOD *store_meth;
166 /* Cipher handling is via this callback */
167 ENGINE_CIPHERS_PTR ciphers;
168 /* Digest handling is via this callback */
169 ENGINE_DIGESTS_PTR digests;
170 /* Public key handling via this callback */
171 ENGINE_PKEY_METHS_PTR pkey_meths;
172 /* ASN1 public key handling via this callback */
173 ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths;
174
175 ENGINE_GEN_INT_FUNC_PTR destroy;
176
177 ENGINE_GEN_INT_FUNC_PTR init;
178 ENGINE_GEN_INT_FUNC_PTR finish;
179 ENGINE_CTRL_FUNC_PTR ctrl;
180 ENGINE_LOAD_KEY_PTR load_privkey;
181 ENGINE_LOAD_KEY_PTR load_pubkey;
182
183 ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert;
184
185 const ENGINE_CMD_DEFN *cmd_defns;
186 int flags;
187 /* reference count on the structure itself */
188 int struct_ref;
189 /* reference count on usability of the engine type. NB: This
190 * controls the loading and initialisation of any functionlity
191 * required by this engine, whereas the previous count is
192 * simply to cope with (de)allocation of this structure. Hence,
193 * running_ref <= struct_ref at all times. */
194 int funct_ref;
195 /* A place to store per-ENGINE data */
196 CRYPTO_EX_DATA ex_data;
197 /* Used to maintain the linked-list of engines. */
198 struct engine_st *prev;
199 struct engine_st *next;
200 };
201
202#ifdef __cplusplus
203}
204#endif
205
206#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..18a6664645
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_lib.c
@@ -0,0 +1,332 @@
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 "eng_int.h"
60#include <openssl/rand.h>
61
62/* The "new"/"free" stuff first */
63
64ENGINE *ENGINE_new(void)
65 {
66 ENGINE *ret;
67
68 ret = (ENGINE *)OPENSSL_malloc(sizeof(ENGINE));
69 if(ret == NULL)
70 {
71 ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE);
72 return NULL;
73 }
74 memset(ret, 0, sizeof(ENGINE));
75 ret->struct_ref = 1;
76 engine_ref_debug(ret, 0, 1)
77 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data);
78 return ret;
79 }
80
81/* Placed here (close proximity to ENGINE_new) so that modifications to the
82 * elements of the ENGINE structure are more likely to be caught and changed
83 * here. */
84void engine_set_all_null(ENGINE *e)
85 {
86 e->id = NULL;
87 e->name = NULL;
88 e->rsa_meth = NULL;
89 e->dsa_meth = NULL;
90 e->dh_meth = NULL;
91 e->rand_meth = NULL;
92 e->store_meth = NULL;
93 e->ciphers = NULL;
94 e->digests = NULL;
95 e->destroy = NULL;
96 e->init = NULL;
97 e->finish = NULL;
98 e->ctrl = NULL;
99 e->load_privkey = NULL;
100 e->load_pubkey = NULL;
101 e->cmd_defns = NULL;
102 e->flags = 0;
103 }
104
105int engine_free_util(ENGINE *e, int locked)
106 {
107 int i;
108
109 if(e == NULL)
110 {
111 ENGINEerr(ENGINE_F_ENGINE_FREE_UTIL,
112 ERR_R_PASSED_NULL_PARAMETER);
113 return 0;
114 }
115 if(locked)
116 i = CRYPTO_add(&e->struct_ref,-1,CRYPTO_LOCK_ENGINE);
117 else
118 i = --e->struct_ref;
119 engine_ref_debug(e, 0, -1)
120 if (i > 0) return 1;
121#ifdef REF_CHECK
122 if (i < 0)
123 {
124 fprintf(stderr,"ENGINE_free, bad structural reference count\n");
125 abort();
126 }
127#endif
128 /* Free up any dynamically allocated public key methods */
129 engine_pkey_meths_free(e);
130 engine_pkey_asn1_meths_free(e);
131 /* Give the ENGINE a chance to do any structural cleanup corresponding
132 * to allocation it did in its constructor (eg. unload error strings) */
133 if(e->destroy)
134 e->destroy(e);
135 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ENGINE, e, &e->ex_data);
136 OPENSSL_free(e);
137 return 1;
138 }
139
140int ENGINE_free(ENGINE *e)
141 {
142 return engine_free_util(e, 1);
143 }
144
145/* Cleanup stuff */
146
147/* ENGINE_cleanup() is coded such that anything that does work that will need
148 * cleanup can register a "cleanup" callback here. That way we don't get linker
149 * bloat by referring to all *possible* cleanups, but any linker bloat into code
150 * "X" will cause X's cleanup function to end up here. */
151static STACK_OF(ENGINE_CLEANUP_ITEM) *cleanup_stack = NULL;
152static int int_cleanup_check(int create)
153 {
154 if(cleanup_stack) return 1;
155 if(!create) return 0;
156 cleanup_stack = sk_ENGINE_CLEANUP_ITEM_new_null();
157 return (cleanup_stack ? 1 : 0);
158 }
159static ENGINE_CLEANUP_ITEM *int_cleanup_item(ENGINE_CLEANUP_CB *cb)
160 {
161 ENGINE_CLEANUP_ITEM *item = OPENSSL_malloc(sizeof(
162 ENGINE_CLEANUP_ITEM));
163 if(!item) return NULL;
164 item->cb = cb;
165 return item;
166 }
167void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb)
168 {
169 ENGINE_CLEANUP_ITEM *item;
170 if(!int_cleanup_check(1)) return;
171 item = int_cleanup_item(cb);
172 if(item)
173 sk_ENGINE_CLEANUP_ITEM_insert(cleanup_stack, item, 0);
174 }
175void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb)
176 {
177 ENGINE_CLEANUP_ITEM *item;
178 if(!int_cleanup_check(1)) return;
179 item = int_cleanup_item(cb);
180 if(item)
181 sk_ENGINE_CLEANUP_ITEM_push(cleanup_stack, item);
182 }
183/* The API function that performs all cleanup */
184static void engine_cleanup_cb_free(ENGINE_CLEANUP_ITEM *item)
185 {
186 (*(item->cb))();
187 OPENSSL_free(item);
188 }
189void ENGINE_cleanup(void)
190 {
191 if(int_cleanup_check(0))
192 {
193 sk_ENGINE_CLEANUP_ITEM_pop_free(cleanup_stack,
194 engine_cleanup_cb_free);
195 cleanup_stack = NULL;
196 }
197 /* FIXME: This should be handled (somehow) through RAND, eg. by it
198 * registering a cleanup callback. */
199 RAND_set_rand_method(NULL);
200 }
201
202/* Now the "ex_data" support */
203
204int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
205 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
206 {
207 return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ENGINE, argl, argp,
208 new_func, dup_func, free_func);
209 }
210
211int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg)
212 {
213 return(CRYPTO_set_ex_data(&e->ex_data, idx, arg));
214 }
215
216void *ENGINE_get_ex_data(const ENGINE *e, int idx)
217 {
218 return(CRYPTO_get_ex_data(&e->ex_data, idx));
219 }
220
221/* Functions to get/set an ENGINE's elements - mainly to avoid exposing the
222 * ENGINE structure itself. */
223
224int ENGINE_set_id(ENGINE *e, const char *id)
225 {
226 if(id == NULL)
227 {
228 ENGINEerr(ENGINE_F_ENGINE_SET_ID,
229 ERR_R_PASSED_NULL_PARAMETER);
230 return 0;
231 }
232 e->id = id;
233 return 1;
234 }
235
236int ENGINE_set_name(ENGINE *e, const char *name)
237 {
238 if(name == NULL)
239 {
240 ENGINEerr(ENGINE_F_ENGINE_SET_NAME,
241 ERR_R_PASSED_NULL_PARAMETER);
242 return 0;
243 }
244 e->name = name;
245 return 1;
246 }
247
248int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f)
249 {
250 e->destroy = destroy_f;
251 return 1;
252 }
253
254int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f)
255 {
256 e->init = init_f;
257 return 1;
258 }
259
260int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f)
261 {
262 e->finish = finish_f;
263 return 1;
264 }
265
266int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f)
267 {
268 e->ctrl = ctrl_f;
269 return 1;
270 }
271
272int ENGINE_set_flags(ENGINE *e, int flags)
273 {
274 e->flags = flags;
275 return 1;
276 }
277
278int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns)
279 {
280 e->cmd_defns = defns;
281 return 1;
282 }
283
284const char *ENGINE_get_id(const ENGINE *e)
285 {
286 return e->id;
287 }
288
289const char *ENGINE_get_name(const ENGINE *e)
290 {
291 return e->name;
292 }
293
294ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e)
295 {
296 return e->destroy;
297 }
298
299ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e)
300 {
301 return e->init;
302 }
303
304ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e)
305 {
306 return e->finish;
307 }
308
309ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e)
310 {
311 return e->ctrl;
312 }
313
314int ENGINE_get_flags(const ENGINE *e)
315 {
316 return e->flags;
317 }
318
319const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e)
320 {
321 return e->cmd_defns;
322 }
323
324/* eng_lib.o is pretty much linked into anything that touches ENGINE already, so
325 * put the "static_state" hack here. */
326
327static int internal_static_hack = 0;
328
329void *ENGINE_get_static_state(void)
330 {
331 return &internal_static_hack;
332 }
diff --git a/src/lib/libcrypto/engine/eng_list.c b/src/lib/libcrypto/engine/eng_list.c
new file mode 100644
index 0000000000..27846edb1e
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_list.c
@@ -0,0 +1,433 @@
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 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * ECDH support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
63
64#include "eng_int.h"
65
66/* The linked-list of pointers to engine types. engine_list_head
67 * incorporates an implicit structural reference but engine_list_tail
68 * does not - the latter is a computational niceity and only points
69 * to something that is already pointed to by its predecessor in the
70 * list (or engine_list_head itself). In the same way, the use of the
71 * "prev" pointer in each ENGINE is to save excessive list iteration,
72 * it doesn't correspond to an extra structural reference. Hence,
73 * engine_list_head, and each non-null "next" pointer account for
74 * the list itself assuming exactly 1 structural reference on each
75 * list member. */
76static ENGINE *engine_list_head = NULL;
77static ENGINE *engine_list_tail = NULL;
78
79/* This cleanup function is only needed internally. If it should be called, we
80 * register it with the "ENGINE_cleanup()" stack to be called during cleanup. */
81
82static void engine_list_cleanup(void)
83 {
84 ENGINE *iterator = engine_list_head;
85
86 while(iterator != NULL)
87 {
88 ENGINE_remove(iterator);
89 iterator = engine_list_head;
90 }
91 return;
92 }
93
94/* These static functions starting with a lower case "engine_" always
95 * take place when CRYPTO_LOCK_ENGINE has been locked up. */
96static int engine_list_add(ENGINE *e)
97 {
98 int conflict = 0;
99 ENGINE *iterator = NULL;
100
101 if(e == NULL)
102 {
103 ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
104 ERR_R_PASSED_NULL_PARAMETER);
105 return 0;
106 }
107 iterator = engine_list_head;
108 while(iterator && !conflict)
109 {
110 conflict = (strcmp(iterator->id, e->id) == 0);
111 iterator = iterator->next;
112 }
113 if(conflict)
114 {
115 ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
116 ENGINE_R_CONFLICTING_ENGINE_ID);
117 return 0;
118 }
119 if(engine_list_head == NULL)
120 {
121 /* We are adding to an empty list. */
122 if(engine_list_tail)
123 {
124 ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
125 ENGINE_R_INTERNAL_LIST_ERROR);
126 return 0;
127 }
128 engine_list_head = e;
129 e->prev = NULL;
130 /* The first time the list allocates, we should register the
131 * cleanup. */
132 engine_cleanup_add_last(engine_list_cleanup);
133 }
134 else
135 {
136 /* We are adding to the tail of an existing list. */
137 if((engine_list_tail == NULL) ||
138 (engine_list_tail->next != NULL))
139 {
140 ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
141 ENGINE_R_INTERNAL_LIST_ERROR);
142 return 0;
143 }
144 engine_list_tail->next = e;
145 e->prev = engine_list_tail;
146 }
147 /* Having the engine in the list assumes a structural
148 * reference. */
149 e->struct_ref++;
150 engine_ref_debug(e, 0, 1)
151 /* However it came to be, e is the last item in the list. */
152 engine_list_tail = e;
153 e->next = NULL;
154 return 1;
155 }
156
157static int engine_list_remove(ENGINE *e)
158 {
159 ENGINE *iterator;
160
161 if(e == NULL)
162 {
163 ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
164 ERR_R_PASSED_NULL_PARAMETER);
165 return 0;
166 }
167 /* We need to check that e is in our linked list! */
168 iterator = engine_list_head;
169 while(iterator && (iterator != e))
170 iterator = iterator->next;
171 if(iterator == NULL)
172 {
173 ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
174 ENGINE_R_ENGINE_IS_NOT_IN_LIST);
175 return 0;
176 }
177 /* un-link e from the chain. */
178 if(e->next)
179 e->next->prev = e->prev;
180 if(e->prev)
181 e->prev->next = e->next;
182 /* Correct our head/tail if necessary. */
183 if(engine_list_head == e)
184 engine_list_head = e->next;
185 if(engine_list_tail == e)
186 engine_list_tail = e->prev;
187 engine_free_util(e, 0);
188 return 1;
189 }
190
191/* Get the first/last "ENGINE" type available. */
192ENGINE *ENGINE_get_first(void)
193 {
194 ENGINE *ret;
195
196 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
197 ret = engine_list_head;
198 if(ret)
199 {
200 ret->struct_ref++;
201 engine_ref_debug(ret, 0, 1)
202 }
203 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
204 return ret;
205 }
206
207ENGINE *ENGINE_get_last(void)
208 {
209 ENGINE *ret;
210
211 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
212 ret = engine_list_tail;
213 if(ret)
214 {
215 ret->struct_ref++;
216 engine_ref_debug(ret, 0, 1)
217 }
218 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
219 return ret;
220 }
221
222/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
223ENGINE *ENGINE_get_next(ENGINE *e)
224 {
225 ENGINE *ret = NULL;
226 if(e == NULL)
227 {
228 ENGINEerr(ENGINE_F_ENGINE_GET_NEXT,
229 ERR_R_PASSED_NULL_PARAMETER);
230 return 0;
231 }
232 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
233 ret = e->next;
234 if(ret)
235 {
236 /* Return a valid structural refernce to the next ENGINE */
237 ret->struct_ref++;
238 engine_ref_debug(ret, 0, 1)
239 }
240 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
241 /* Release the structural reference to the previous ENGINE */
242 ENGINE_free(e);
243 return ret;
244 }
245
246ENGINE *ENGINE_get_prev(ENGINE *e)
247 {
248 ENGINE *ret = NULL;
249 if(e == NULL)
250 {
251 ENGINEerr(ENGINE_F_ENGINE_GET_PREV,
252 ERR_R_PASSED_NULL_PARAMETER);
253 return 0;
254 }
255 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
256 ret = e->prev;
257 if(ret)
258 {
259 /* Return a valid structural reference to the next ENGINE */
260 ret->struct_ref++;
261 engine_ref_debug(ret, 0, 1)
262 }
263 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
264 /* Release the structural reference to the previous ENGINE */
265 ENGINE_free(e);
266 return ret;
267 }
268
269/* Add another "ENGINE" type into the list. */
270int ENGINE_add(ENGINE *e)
271 {
272 int to_return = 1;
273 if(e == NULL)
274 {
275 ENGINEerr(ENGINE_F_ENGINE_ADD,
276 ERR_R_PASSED_NULL_PARAMETER);
277 return 0;
278 }
279 if((e->id == NULL) || (e->name == NULL))
280 {
281 ENGINEerr(ENGINE_F_ENGINE_ADD,
282 ENGINE_R_ID_OR_NAME_MISSING);
283 }
284 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
285 if(!engine_list_add(e))
286 {
287 ENGINEerr(ENGINE_F_ENGINE_ADD,
288 ENGINE_R_INTERNAL_LIST_ERROR);
289 to_return = 0;
290 }
291 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
292 return to_return;
293 }
294
295/* Remove an existing "ENGINE" type from the array. */
296int ENGINE_remove(ENGINE *e)
297 {
298 int to_return = 1;
299 if(e == NULL)
300 {
301 ENGINEerr(ENGINE_F_ENGINE_REMOVE,
302 ERR_R_PASSED_NULL_PARAMETER);
303 return 0;
304 }
305 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
306 if(!engine_list_remove(e))
307 {
308 ENGINEerr(ENGINE_F_ENGINE_REMOVE,
309 ENGINE_R_INTERNAL_LIST_ERROR);
310 to_return = 0;
311 }
312 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
313 return to_return;
314 }
315
316static void engine_cpy(ENGINE *dest, const ENGINE *src)
317 {
318 dest->id = src->id;
319 dest->name = src->name;
320#ifndef OPENSSL_NO_RSA
321 dest->rsa_meth = src->rsa_meth;
322#endif
323#ifndef OPENSSL_NO_DSA
324 dest->dsa_meth = src->dsa_meth;
325#endif
326#ifndef OPENSSL_NO_DH
327 dest->dh_meth = src->dh_meth;
328#endif
329#ifndef OPENSSL_NO_ECDH
330 dest->ecdh_meth = src->ecdh_meth;
331#endif
332#ifndef OPENSSL_NO_ECDSA
333 dest->ecdsa_meth = src->ecdsa_meth;
334#endif
335 dest->rand_meth = src->rand_meth;
336 dest->store_meth = src->store_meth;
337 dest->ciphers = src->ciphers;
338 dest->digests = src->digests;
339 dest->pkey_meths = src->pkey_meths;
340 dest->destroy = src->destroy;
341 dest->init = src->init;
342 dest->finish = src->finish;
343 dest->ctrl = src->ctrl;
344 dest->load_privkey = src->load_privkey;
345 dest->load_pubkey = src->load_pubkey;
346 dest->cmd_defns = src->cmd_defns;
347 dest->flags = src->flags;
348 }
349
350ENGINE *ENGINE_by_id(const char *id)
351 {
352 ENGINE *iterator;
353 char *load_dir = NULL;
354 if(id == NULL)
355 {
356 ENGINEerr(ENGINE_F_ENGINE_BY_ID,
357 ERR_R_PASSED_NULL_PARAMETER);
358 return NULL;
359 }
360 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
361 iterator = engine_list_head;
362 while(iterator && (strcmp(id, iterator->id) != 0))
363 iterator = iterator->next;
364 if(iterator)
365 {
366 /* We need to return a structural reference. If this is an
367 * ENGINE type that returns copies, make a duplicate - otherwise
368 * increment the existing ENGINE's reference count. */
369 if(iterator->flags & ENGINE_FLAGS_BY_ID_COPY)
370 {
371 ENGINE *cp = ENGINE_new();
372 if(!cp)
373 iterator = NULL;
374 else
375 {
376 engine_cpy(cp, iterator);
377 iterator = cp;
378 }
379 }
380 else
381 {
382 iterator->struct_ref++;
383 engine_ref_debug(iterator, 0, 1)
384 }
385 }
386 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
387#if 0
388 if(iterator == NULL)
389 {
390 ENGINEerr(ENGINE_F_ENGINE_BY_ID,
391 ENGINE_R_NO_SUCH_ENGINE);
392 ERR_add_error_data(2, "id=", id);
393 }
394 return iterator;
395#else
396 /* EEK! Experimental code starts */
397 if(iterator) return iterator;
398 /* Prevent infinite recusrion if we're looking for the dynamic engine. */
399 if (strcmp(id, "dynamic"))
400 {
401#ifdef OPENSSL_SYS_VMS
402 if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = "SSLROOT:[ENGINES]";
403#else
404 if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = ENGINESDIR;
405#endif
406 iterator = ENGINE_by_id("dynamic");
407 if(!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) ||
408 !ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) ||
409 !ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
410 load_dir, 0) ||
411 !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
412 goto notfound;
413 return iterator;
414 }
415notfound:
416 ENGINE_free(iterator);
417 ENGINEerr(ENGINE_F_ENGINE_BY_ID,ENGINE_R_NO_SUCH_ENGINE);
418 ERR_add_error_data(2, "id=", id);
419 return NULL;
420 /* EEK! Experimental code ends */
421#endif
422 }
423
424int ENGINE_up_ref(ENGINE *e)
425 {
426 if (e == NULL)
427 {
428 ENGINEerr(ENGINE_F_ENGINE_UP_REF,ERR_R_PASSED_NULL_PARAMETER);
429 return 0;
430 }
431 CRYPTO_add(&e->struct_ref,1,CRYPTO_LOCK_ENGINE);
432 return 1;
433 }
diff --git a/src/lib/libcrypto/engine/eng_openssl.c b/src/lib/libcrypto/engine/eng_openssl.c
new file mode 100644
index 0000000000..9abb95cc22
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_openssl.c
@@ -0,0 +1,384 @@
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 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * ECDH support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
63
64
65#include <stdio.h>
66#include <openssl/crypto.h>
67#include "cryptlib.h"
68#include <openssl/engine.h>
69#include <openssl/dso.h>
70#include <openssl/pem.h>
71#include <openssl/evp.h>
72#include <openssl/rand.h>
73#ifndef OPENSSL_NO_RSA
74#include <openssl/rsa.h>
75#endif
76#ifndef OPENSSL_NO_DSA
77#include <openssl/dsa.h>
78#endif
79#ifndef OPENSSL_NO_DH
80#include <openssl/dh.h>
81#endif
82
83/* This testing gunk is implemented (and explained) lower down. It also assumes
84 * the application explicitly calls "ENGINE_load_openssl()" because this is no
85 * longer automatic in ENGINE_load_builtin_engines(). */
86#define TEST_ENG_OPENSSL_RC4
87#define TEST_ENG_OPENSSL_PKEY
88/* #define TEST_ENG_OPENSSL_RC4_OTHERS */
89#define TEST_ENG_OPENSSL_RC4_P_INIT
90/* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */
91#define TEST_ENG_OPENSSL_SHA
92/* #define TEST_ENG_OPENSSL_SHA_OTHERS */
93/* #define TEST_ENG_OPENSSL_SHA_P_INIT */
94/* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */
95/* #define TEST_ENG_OPENSSL_SHA_P_FINAL */
96
97/* Now check what of those algorithms are actually enabled */
98#ifdef OPENSSL_NO_RC4
99#undef TEST_ENG_OPENSSL_RC4
100#undef TEST_ENG_OPENSSL_RC4_OTHERS
101#undef TEST_ENG_OPENSSL_RC4_P_INIT
102#undef TEST_ENG_OPENSSL_RC4_P_CIPHER
103#endif
104#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA0) || defined(OPENSSL_NO_SHA1)
105#undef TEST_ENG_OPENSSL_SHA
106#undef TEST_ENG_OPENSSL_SHA_OTHERS
107#undef TEST_ENG_OPENSSL_SHA_P_INIT
108#undef TEST_ENG_OPENSSL_SHA_P_UPDATE
109#undef TEST_ENG_OPENSSL_SHA_P_FINAL
110#endif
111
112#ifdef TEST_ENG_OPENSSL_RC4
113static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
114 const int **nids, int nid);
115#endif
116#ifdef TEST_ENG_OPENSSL_SHA
117static int openssl_digests(ENGINE *e, const EVP_MD **digest,
118 const int **nids, int nid);
119#endif
120
121#ifdef TEST_ENG_OPENSSL_PKEY
122static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
123 UI_METHOD *ui_method, void *callback_data);
124#endif
125
126/* The constants used when creating the ENGINE */
127static const char *engine_openssl_id = "openssl";
128static const char *engine_openssl_name = "Software engine support";
129
130/* This internal function is used by ENGINE_openssl() and possibly by the
131 * "dynamic" ENGINE support too */
132static int bind_helper(ENGINE *e)
133 {
134 if(!ENGINE_set_id(e, engine_openssl_id)
135 || !ENGINE_set_name(e, engine_openssl_name)
136#ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS
137#ifndef OPENSSL_NO_RSA
138 || !ENGINE_set_RSA(e, RSA_get_default_method())
139#endif
140#ifndef OPENSSL_NO_DSA
141 || !ENGINE_set_DSA(e, DSA_get_default_method())
142#endif
143#ifndef OPENSSL_NO_ECDH
144 || !ENGINE_set_ECDH(e, ECDH_OpenSSL())
145#endif
146#ifndef OPENSSL_NO_ECDSA
147 || !ENGINE_set_ECDSA(e, ECDSA_OpenSSL())
148#endif
149#ifndef OPENSSL_NO_DH
150 || !ENGINE_set_DH(e, DH_get_default_method())
151#endif
152 || !ENGINE_set_RAND(e, RAND_SSLeay())
153#ifdef TEST_ENG_OPENSSL_RC4
154 || !ENGINE_set_ciphers(e, openssl_ciphers)
155#endif
156#ifdef TEST_ENG_OPENSSL_SHA
157 || !ENGINE_set_digests(e, openssl_digests)
158#endif
159#endif
160#ifdef TEST_ENG_OPENSSL_PKEY
161 || !ENGINE_set_load_privkey_function(e, openssl_load_privkey)
162#endif
163 )
164 return 0;
165 /* If we add errors to this ENGINE, ensure the error handling is setup here */
166 /* openssl_load_error_strings(); */
167 return 1;
168 }
169
170static ENGINE *engine_openssl(void)
171 {
172 ENGINE *ret = ENGINE_new();
173 if(!ret)
174 return NULL;
175 if(!bind_helper(ret))
176 {
177 ENGINE_free(ret);
178 return NULL;
179 }
180 return ret;
181 }
182
183void ENGINE_load_openssl(void)
184 {
185 ENGINE *toadd = engine_openssl();
186 if(!toadd) return;
187 ENGINE_add(toadd);
188 /* If the "add" worked, it gets a structural reference. So either way,
189 * we release our just-created reference. */
190 ENGINE_free(toadd);
191 ERR_clear_error();
192 }
193
194/* This stuff is needed if this ENGINE is being compiled into a self-contained
195 * shared-library. */
196#ifdef ENGINE_DYNAMIC_SUPPORT
197static int bind_fn(ENGINE *e, const char *id)
198 {
199 if(id && (strcmp(id, engine_openssl_id) != 0))
200 return 0;
201 if(!bind_helper(e))
202 return 0;
203 return 1;
204 }
205IMPLEMENT_DYNAMIC_CHECK_FN()
206IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
207#endif /* ENGINE_DYNAMIC_SUPPORT */
208
209#ifdef TEST_ENG_OPENSSL_RC4
210/* This section of code compiles an "alternative implementation" of two modes of
211 * RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4"
212 * should under normal circumstances go via this support rather than the default
213 * EVP support. There are other symbols to tweak the testing;
214 * TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time
215 * we're asked for a cipher we don't support (should not happen).
216 * TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time
217 * the "init_key" handler is called.
218 * TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler.
219 */
220#include <openssl/rc4.h>
221#define TEST_RC4_KEY_SIZE 16
222static int test_cipher_nids[] = {NID_rc4,NID_rc4_40};
223static int test_cipher_nids_number = 2;
224typedef struct {
225 unsigned char key[TEST_RC4_KEY_SIZE];
226 RC4_KEY ks;
227 } TEST_RC4_KEY;
228#define test(ctx) ((TEST_RC4_KEY *)(ctx)->cipher_data)
229static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
230 const unsigned char *iv, int enc)
231 {
232#ifdef TEST_ENG_OPENSSL_RC4_P_INIT
233 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n");
234#endif
235 memcpy(&test(ctx)->key[0],key,EVP_CIPHER_CTX_key_length(ctx));
236 RC4_set_key(&test(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),
237 test(ctx)->key);
238 return 1;
239 }
240static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
241 const unsigned char *in, size_t inl)
242 {
243#ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
244 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
245#endif
246 RC4(&test(ctx)->ks,inl,in,out);
247 return 1;
248 }
249static const EVP_CIPHER test_r4_cipher=
250 {
251 NID_rc4,
252 1,TEST_RC4_KEY_SIZE,0,
253 EVP_CIPH_VARIABLE_LENGTH,
254 test_rc4_init_key,
255 test_rc4_cipher,
256 NULL,
257 sizeof(TEST_RC4_KEY),
258 NULL,
259 NULL,
260 NULL,
261 NULL
262 };
263static const EVP_CIPHER test_r4_40_cipher=
264 {
265 NID_rc4_40,
266 1,5 /* 40 bit */,0,
267 EVP_CIPH_VARIABLE_LENGTH,
268 test_rc4_init_key,
269 test_rc4_cipher,
270 NULL,
271 sizeof(TEST_RC4_KEY),
272 NULL,
273 NULL,
274 NULL,
275 NULL
276 };
277static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
278 const int **nids, int nid)
279 {
280 if(!cipher)
281 {
282 /* We are returning a list of supported nids */
283 *nids = test_cipher_nids;
284 return test_cipher_nids_number;
285 }
286 /* We are being asked for a specific cipher */
287 if(nid == NID_rc4)
288 *cipher = &test_r4_cipher;
289 else if(nid == NID_rc4_40)
290 *cipher = &test_r4_40_cipher;
291 else
292 {
293#ifdef TEST_ENG_OPENSSL_RC4_OTHERS
294 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) returning NULL for "
295 "nid %d\n", nid);
296#endif
297 *cipher = NULL;
298 return 0;
299 }
300 return 1;
301 }
302#endif
303
304#ifdef TEST_ENG_OPENSSL_SHA
305/* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */
306#include <openssl/sha.h>
307static int test_digest_nids[] = {NID_sha1};
308static int test_digest_nids_number = 1;
309static int test_sha1_init(EVP_MD_CTX *ctx)
310 {
311#ifdef TEST_ENG_OPENSSL_SHA_P_INIT
312 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n");
313#endif
314 return SHA1_Init(ctx->md_data);
315 }
316static int test_sha1_update(EVP_MD_CTX *ctx,const void *data,size_t count)
317 {
318#ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE
319 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n");
320#endif
321 return SHA1_Update(ctx->md_data,data,count);
322 }
323static int test_sha1_final(EVP_MD_CTX *ctx,unsigned char *md)
324 {
325#ifdef TEST_ENG_OPENSSL_SHA_P_FINAL
326 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n");
327#endif
328 return SHA1_Final(md,ctx->md_data);
329 }
330static const EVP_MD test_sha_md=
331 {
332 NID_sha1,
333 NID_sha1WithRSAEncryption,
334 SHA_DIGEST_LENGTH,
335 0,
336 test_sha1_init,
337 test_sha1_update,
338 test_sha1_final,
339 NULL,
340 NULL,
341 EVP_PKEY_RSA_method,
342 SHA_CBLOCK,
343 sizeof(EVP_MD *)+sizeof(SHA_CTX),
344 };
345static int openssl_digests(ENGINE *e, const EVP_MD **digest,
346 const int **nids, int nid)
347 {
348 if(!digest)
349 {
350 /* We are returning a list of supported nids */
351 *nids = test_digest_nids;
352 return test_digest_nids_number;
353 }
354 /* We are being asked for a specific digest */
355 if(nid == NID_sha1)
356 *digest = &test_sha_md;
357 else
358 {
359#ifdef TEST_ENG_OPENSSL_SHA_OTHERS
360 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for "
361 "nid %d\n", nid);
362#endif
363 *digest = NULL;
364 return 0;
365 }
366 return 1;
367 }
368#endif
369
370#ifdef TEST_ENG_OPENSSL_PKEY
371static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
372 UI_METHOD *ui_method, void *callback_data)
373 {
374 BIO *in;
375 EVP_PKEY *key;
376 fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n", key_id);
377 in = BIO_new_file(key_id, "r");
378 if (!in)
379 return NULL;
380 key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL);
381 BIO_free(in);
382 return key;
383 }
384#endif
diff --git a/src/lib/libcrypto/engine/eng_padlock.c b/src/lib/libcrypto/engine/eng_padlock.c
new file mode 100644
index 0000000000..743558ab33
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_padlock.c
@@ -0,0 +1,1219 @@
1/*
2 * Support for VIA PadLock Advanced Cryptography Engine (ACE)
3 * Written by Michal Ludvig <michal@logix.cz>
4 * http://www.logix.cz/michal
5 *
6 * Big thanks to Andy Polyakov for a help with optimization,
7 * assembler fixes, port to MS Windows and a lot of other
8 * valuable work on this engine!
9 */
10
11/* ====================================================================
12 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in
23 * the documentation and/or other materials provided with the
24 * distribution.
25 *
26 * 3. All advertising materials mentioning features or use of this
27 * software must display the following acknowledgment:
28 * "This product includes software developed by the OpenSSL Project
29 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
30 *
31 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
32 * endorse or promote products derived from this software without
33 * prior written permission. For written permission, please contact
34 * licensing@OpenSSL.org.
35 *
36 * 5. Products derived from this software may not be called "OpenSSL"
37 * nor may "OpenSSL" appear in their names without prior written
38 * permission of the OpenSSL Project.
39 *
40 * 6. Redistributions of any form whatsoever must retain the following
41 * acknowledgment:
42 * "This product includes software developed by the OpenSSL Project
43 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
46 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
49 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
51 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
54 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
56 * OF THE POSSIBILITY OF SUCH DAMAGE.
57 * ====================================================================
58 *
59 * This product includes cryptographic software written by Eric Young
60 * (eay@cryptsoft.com). This product includes software written by Tim
61 * Hudson (tjh@cryptsoft.com).
62 *
63 */
64
65
66#include <stdio.h>
67#include <string.h>
68
69#include <openssl/opensslconf.h>
70#include <openssl/crypto.h>
71#include <openssl/dso.h>
72#include <openssl/engine.h>
73#include <openssl/evp.h>
74#ifndef OPENSSL_NO_AES
75#include <openssl/aes.h>
76#endif
77#include <openssl/rand.h>
78#include <openssl/err.h>
79
80#ifndef OPENSSL_NO_HW
81#ifndef OPENSSL_NO_HW_PADLOCK
82
83/* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */
84#if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
85# ifndef OPENSSL_NO_DYNAMIC_ENGINE
86# define DYNAMIC_ENGINE
87# endif
88#elif (OPENSSL_VERSION_NUMBER >= 0x00907000L)
89# ifdef ENGINE_DYNAMIC_SUPPORT
90# define DYNAMIC_ENGINE
91# endif
92#else
93# error "Only OpenSSL >= 0.9.7 is supported"
94#endif
95
96/* VIA PadLock AES is available *ONLY* on some x86 CPUs.
97 Not only that it doesn't exist elsewhere, but it
98 even can't be compiled on other platforms!
99
100 In addition, because of the heavy use of inline assembler,
101 compiler choice is limited to GCC and Microsoft C. */
102#undef COMPILE_HW_PADLOCK
103#if !defined(I386_ONLY) && !defined(OPENSSL_NO_INLINE_ASM)
104# if (defined(__GNUC__) && (defined(__i386__) || defined(__i386))) || \
105 (defined(_MSC_VER) && defined(_M_IX86))
106# define COMPILE_HW_PADLOCK
107static ENGINE *ENGINE_padlock (void);
108# endif
109#endif
110
111void ENGINE_load_padlock (void)
112{
113/* On non-x86 CPUs it just returns. */
114#ifdef COMPILE_HW_PADLOCK
115 ENGINE *toadd = ENGINE_padlock ();
116 if (!toadd) return;
117 ENGINE_add (toadd);
118 ENGINE_free (toadd);
119 ERR_clear_error ();
120#endif
121}
122
123#ifdef COMPILE_HW_PADLOCK
124/* We do these includes here to avoid header problems on platforms that
125 do not have the VIA padlock anyway... */
126#ifdef _MSC_VER
127# include <malloc.h>
128# define alloca _alloca
129#elif defined(NETWARE_CLIB) && defined(__GNUC__)
130 void *alloca(size_t);
131# define alloca(s) __builtin_alloca(s)
132#else
133# include <stdlib.h>
134#endif
135
136/* Function for ENGINE detection and control */
137static int padlock_available(void);
138static int padlock_init(ENGINE *e);
139
140/* RNG Stuff */
141static RAND_METHOD padlock_rand;
142
143/* Cipher Stuff */
144#ifndef OPENSSL_NO_AES
145static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
146#endif
147
148/* Engine names */
149static const char *padlock_id = "padlock";
150static char padlock_name[100];
151
152/* Available features */
153static int padlock_use_ace = 0; /* Advanced Cryptography Engine */
154static int padlock_use_rng = 0; /* Random Number Generator */
155#ifndef OPENSSL_NO_AES
156static int padlock_aes_align_required = 1;
157#endif
158
159/* ===== Engine "management" functions ===== */
160
161/* Prepare the ENGINE structure for registration */
162static int
163padlock_bind_helper(ENGINE *e)
164{
165 /* Check available features */
166 padlock_available();
167
168#if 1 /* disable RNG for now, see commentary in vicinity of RNG code */
169 padlock_use_rng=0;
170#endif
171
172 /* Generate a nice engine name with available features */
173 BIO_snprintf(padlock_name, sizeof(padlock_name),
174 "VIA PadLock (%s, %s)",
175 padlock_use_rng ? "RNG" : "no-RNG",
176 padlock_use_ace ? "ACE" : "no-ACE");
177
178 /* Register everything or return with an error */
179 if (!ENGINE_set_id(e, padlock_id) ||
180 !ENGINE_set_name(e, padlock_name) ||
181
182 !ENGINE_set_init_function(e, padlock_init) ||
183#ifndef OPENSSL_NO_AES
184 (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) ||
185#endif
186 (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) {
187 return 0;
188 }
189
190 /* Everything looks good */
191 return 1;
192}
193
194/* Constructor */
195static ENGINE *
196ENGINE_padlock(void)
197{
198 ENGINE *eng = ENGINE_new();
199
200 if (!eng) {
201 return NULL;
202 }
203
204 if (!padlock_bind_helper(eng)) {
205 ENGINE_free(eng);
206 return NULL;
207 }
208
209 return eng;
210}
211
212/* Check availability of the engine */
213static int
214padlock_init(ENGINE *e)
215{
216 return (padlock_use_rng || padlock_use_ace);
217}
218
219/* This stuff is needed if this ENGINE is being compiled into a self-contained
220 * shared-library.
221 */
222#ifdef DYNAMIC_ENGINE
223static int
224padlock_bind_fn(ENGINE *e, const char *id)
225{
226 if (id && (strcmp(id, padlock_id) != 0)) {
227 return 0;
228 }
229
230 if (!padlock_bind_helper(e)) {
231 return 0;
232 }
233
234 return 1;
235}
236
237IMPLEMENT_DYNAMIC_CHECK_FN ()
238IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn)
239#endif /* DYNAMIC_ENGINE */
240
241/* ===== Here comes the "real" engine ===== */
242
243#ifndef OPENSSL_NO_AES
244/* Some AES-related constants */
245#define AES_BLOCK_SIZE 16
246#define AES_KEY_SIZE_128 16
247#define AES_KEY_SIZE_192 24
248#define AES_KEY_SIZE_256 32
249
250/* Here we store the status information relevant to the
251 current context. */
252/* BIG FAT WARNING:
253 * Inline assembler in PADLOCK_XCRYPT_ASM()
254 * depends on the order of items in this structure.
255 * Don't blindly modify, reorder, etc!
256 */
257struct padlock_cipher_data
258{
259 unsigned char iv[AES_BLOCK_SIZE]; /* Initialization vector */
260 union { unsigned int pad[4];
261 struct {
262 int rounds:4;
263 int dgst:1; /* n/a in C3 */
264 int align:1; /* n/a in C3 */
265 int ciphr:1; /* n/a in C3 */
266 unsigned int keygen:1;
267 int interm:1;
268 unsigned int encdec:1;
269 int ksize:2;
270 } b;
271 } cword; /* Control word */
272 AES_KEY ks; /* Encryption key */
273};
274
275/*
276 * Essentially this variable belongs in thread local storage.
277 * Having this variable global on the other hand can only cause
278 * few bogus key reloads [if any at all on single-CPU system],
279 * so we accept the penatly...
280 */
281static volatile struct padlock_cipher_data *padlock_saved_context;
282#endif
283
284/*
285 * =======================================================
286 * Inline assembler section(s).
287 * =======================================================
288 * Order of arguments is chosen to facilitate Windows port
289 * using __fastcall calling convention. If you wish to add
290 * more routines, keep in mind that first __fastcall
291 * argument is passed in %ecx and second - in %edx.
292 * =======================================================
293 */
294#if defined(__GNUC__) && __GNUC__>=2
295/*
296 * As for excessive "push %ebx"/"pop %ebx" found all over.
297 * When generating position-independent code GCC won't let
298 * us use "b" in assembler templates nor even respect "ebx"
299 * in "clobber description." Therefore the trouble...
300 */
301
302/* Helper function - check if a CPUID instruction
303 is available on this CPU */
304static int
305padlock_insn_cpuid_available(void)
306{
307 int result = -1;
308
309 /* We're checking if the bit #21 of EFLAGS
310 can be toggled. If yes = CPUID is available. */
311 asm volatile (
312 "pushf\n"
313 "popl %%eax\n"
314 "xorl $0x200000, %%eax\n"
315 "movl %%eax, %%ecx\n"
316 "andl $0x200000, %%ecx\n"
317 "pushl %%eax\n"
318 "popf\n"
319 "pushf\n"
320 "popl %%eax\n"
321 "andl $0x200000, %%eax\n"
322 "xorl %%eax, %%ecx\n"
323 "movl %%ecx, %0\n"
324 : "=r" (result) : : "eax", "ecx");
325
326 return (result == 0);
327}
328
329/* Load supported features of the CPU to see if
330 the PadLock is available. */
331static int
332padlock_available(void)
333{
334 char vendor_string[16];
335 unsigned int eax, edx;
336
337 /* First check if the CPUID instruction is available at all... */
338 if (! padlock_insn_cpuid_available())
339 return 0;
340
341 /* Are we running on the Centaur (VIA) CPU? */
342 eax = 0x00000000;
343 vendor_string[12] = 0;
344 asm volatile (
345 "pushl %%ebx\n"
346 "cpuid\n"
347 "movl %%ebx,(%%edi)\n"
348 "movl %%edx,4(%%edi)\n"
349 "movl %%ecx,8(%%edi)\n"
350 "popl %%ebx"
351 : "+a"(eax) : "D"(vendor_string) : "ecx", "edx");
352 if (strcmp(vendor_string, "CentaurHauls") != 0)
353 return 0;
354
355 /* Check for Centaur Extended Feature Flags presence */
356 eax = 0xC0000000;
357 asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
358 : "+a"(eax) : : "ecx", "edx");
359 if (eax < 0xC0000001)
360 return 0;
361
362 /* Read the Centaur Extended Feature Flags */
363 eax = 0xC0000001;
364 asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
365 : "+a"(eax), "=d"(edx) : : "ecx");
366
367 /* Fill up some flags */
368 padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6));
369 padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2));
370
371 return padlock_use_ace + padlock_use_rng;
372}
373
374#ifndef OPENSSL_NO_AES
375/* Our own htonl()/ntohl() */
376static inline void
377padlock_bswapl(AES_KEY *ks)
378{
379 size_t i = sizeof(ks->rd_key)/sizeof(ks->rd_key[0]);
380 unsigned int *key = ks->rd_key;
381
382 while (i--) {
383 asm volatile ("bswapl %0" : "+r"(*key));
384 key++;
385 }
386}
387#endif
388
389/* Force key reload from memory to the CPU microcode.
390 Loading EFLAGS from the stack clears EFLAGS[30]
391 which does the trick. */
392static inline void
393padlock_reload_key(void)
394{
395 asm volatile ("pushfl; popfl");
396}
397
398#ifndef OPENSSL_NO_AES
399/*
400 * This is heuristic key context tracing. At first one
401 * believes that one should use atomic swap instructions,
402 * but it's not actually necessary. Point is that if
403 * padlock_saved_context was changed by another thread
404 * after we've read it and before we compare it with cdata,
405 * our key *shall* be reloaded upon thread context switch
406 * and we are therefore set in either case...
407 */
408static inline void
409padlock_verify_context(struct padlock_cipher_data *cdata)
410{
411 asm volatile (
412 "pushfl\n"
413" btl $30,(%%esp)\n"
414" jnc 1f\n"
415" cmpl %2,%1\n"
416" je 1f\n"
417" popfl\n"
418" subl $4,%%esp\n"
419"1: addl $4,%%esp\n"
420" movl %2,%0"
421 :"+m"(padlock_saved_context)
422 : "r"(padlock_saved_context), "r"(cdata) : "cc");
423}
424
425/* Template for padlock_xcrypt_* modes */
426/* BIG FAT WARNING:
427 * The offsets used with 'leal' instructions
428 * describe items of the 'padlock_cipher_data'
429 * structure.
430 */
431#define PADLOCK_XCRYPT_ASM(name,rep_xcrypt) \
432static inline void *name(size_t cnt, \
433 struct padlock_cipher_data *cdata, \
434 void *out, const void *inp) \
435{ void *iv; \
436 asm volatile ( "pushl %%ebx\n" \
437 " leal 16(%0),%%edx\n" \
438 " leal 32(%0),%%ebx\n" \
439 rep_xcrypt "\n" \
440 " popl %%ebx" \
441 : "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \
442 : "0"(cdata), "1"(cnt), "2"(out), "3"(inp) \
443 : "edx", "cc", "memory"); \
444 return iv; \
445}
446
447/* Generate all functions with appropriate opcodes */
448PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8") /* rep xcryptecb */
449PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0") /* rep xcryptcbc */
450PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0") /* rep xcryptcfb */
451PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8") /* rep xcryptofb */
452#endif
453
454/* The RNG call itself */
455static inline unsigned int
456padlock_xstore(void *addr, unsigned int edx_in)
457{
458 unsigned int eax_out;
459
460 asm volatile (".byte 0x0f,0xa7,0xc0" /* xstore */
461 : "=a"(eax_out),"=m"(*(unsigned *)addr)
462 : "D"(addr), "d" (edx_in)
463 );
464
465 return eax_out;
466}
467
468/* Why not inline 'rep movsd'? I failed to find information on what
469 * value in Direction Flag one can expect and consequently have to
470 * apply "better-safe-than-sorry" approach and assume "undefined."
471 * I could explicitly clear it and restore the original value upon
472 * return from padlock_aes_cipher, but it's presumably too much
473 * trouble for too little gain...
474 *
475 * In case you wonder 'rep xcrypt*' instructions above are *not*
476 * affected by the Direction Flag and pointers advance toward
477 * larger addresses unconditionally.
478 */
479static inline unsigned char *
480padlock_memcpy(void *dst,const void *src,size_t n)
481{
482 long *d=dst;
483 const long *s=src;
484
485 n /= sizeof(*d);
486 do { *d++ = *s++; } while (--n);
487
488 return dst;
489}
490
491#elif defined(_MSC_VER)
492/*
493 * Unlike GCC these are real functions. In order to minimize impact
494 * on performance we adhere to __fastcall calling convention in
495 * order to get two first arguments passed through %ecx and %edx.
496 * Which kind of suits very well, as instructions in question use
497 * both %ecx and %edx as input:-)
498 */
499#define REP_XCRYPT(code) \
500 _asm _emit 0xf3 \
501 _asm _emit 0x0f _asm _emit 0xa7 \
502 _asm _emit code
503
504/* BIG FAT WARNING:
505 * The offsets used with 'lea' instructions
506 * describe items of the 'padlock_cipher_data'
507 * structure.
508 */
509#define PADLOCK_XCRYPT_ASM(name,code) \
510static void * __fastcall \
511 name (size_t cnt, void *cdata, \
512 void *outp, const void *inp) \
513{ _asm mov eax,edx \
514 _asm lea edx,[eax+16] \
515 _asm lea ebx,[eax+32] \
516 _asm mov edi,outp \
517 _asm mov esi,inp \
518 REP_XCRYPT(code) \
519}
520
521PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb,0xc8)
522PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc,0xd0)
523PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb,0xe0)
524PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb,0xe8)
525
526static int __fastcall
527padlock_xstore(void *outp,unsigned int code)
528{ _asm mov edi,ecx
529 _asm _emit 0x0f _asm _emit 0xa7 _asm _emit 0xc0
530}
531
532static void __fastcall
533padlock_reload_key(void)
534{ _asm pushfd _asm popfd }
535
536static void __fastcall
537padlock_verify_context(void *cdata)
538{ _asm {
539 pushfd
540 bt DWORD PTR[esp],30
541 jnc skip
542 cmp ecx,padlock_saved_context
543 je skip
544 popfd
545 sub esp,4
546 skip: add esp,4
547 mov padlock_saved_context,ecx
548 }
549}
550
551static int
552padlock_available(void)
553{ _asm {
554 pushfd
555 pop eax
556 mov ecx,eax
557 xor eax,1<<21
558 push eax
559 popfd
560 pushfd
561 pop eax
562 xor eax,ecx
563 bt eax,21
564 jnc noluck
565 mov eax,0
566 cpuid
567 xor eax,eax
568 cmp ebx,'tneC'
569 jne noluck
570 cmp edx,'Hrua'
571 jne noluck
572 cmp ecx,'slua'
573 jne noluck
574 mov eax,0xC0000000
575 cpuid
576 mov edx,eax
577 xor eax,eax
578 cmp edx,0xC0000001
579 jb noluck
580 mov eax,0xC0000001
581 cpuid
582 xor eax,eax
583 bt edx,6
584 jnc skip_a
585 bt edx,7
586 jnc skip_a
587 mov padlock_use_ace,1
588 inc eax
589 skip_a: bt edx,2
590 jnc skip_r
591 bt edx,3
592 jnc skip_r
593 mov padlock_use_rng,1
594 inc eax
595 skip_r:
596 noluck:
597 }
598}
599
600static void __fastcall
601padlock_bswapl(void *key)
602{ _asm {
603 pushfd
604 cld
605 mov esi,ecx
606 mov edi,ecx
607 mov ecx,60
608 up: lodsd
609 bswap eax
610 stosd
611 loop up
612 popfd
613 }
614}
615
616/* MS actually specifies status of Direction Flag and compiler even
617 * manages to compile following as 'rep movsd' all by itself...
618 */
619#define padlock_memcpy(o,i,n) ((unsigned char *)memcpy((o),(i),(n)&~3U))
620#endif
621
622/* ===== AES encryption/decryption ===== */
623#ifndef OPENSSL_NO_AES
624
625#if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)
626#define NID_aes_128_cfb NID_aes_128_cfb128
627#endif
628
629#if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb)
630#define NID_aes_128_ofb NID_aes_128_ofb128
631#endif
632
633#if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb)
634#define NID_aes_192_cfb NID_aes_192_cfb128
635#endif
636
637#if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb)
638#define NID_aes_192_ofb NID_aes_192_ofb128
639#endif
640
641#if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb)
642#define NID_aes_256_cfb NID_aes_256_cfb128
643#endif
644
645#if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb)
646#define NID_aes_256_ofb NID_aes_256_ofb128
647#endif
648
649/* List of supported ciphers. */
650static int padlock_cipher_nids[] = {
651 NID_aes_128_ecb,
652 NID_aes_128_cbc,
653 NID_aes_128_cfb,
654 NID_aes_128_ofb,
655
656 NID_aes_192_ecb,
657 NID_aes_192_cbc,
658 NID_aes_192_cfb,
659 NID_aes_192_ofb,
660
661 NID_aes_256_ecb,
662 NID_aes_256_cbc,
663 NID_aes_256_cfb,
664 NID_aes_256_ofb,
665};
666static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/
667 sizeof(padlock_cipher_nids[0]));
668
669/* Function prototypes ... */
670static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
671 const unsigned char *iv, int enc);
672static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
673 const unsigned char *in, size_t nbytes);
674
675#define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) + \
676 ( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F ) )
677#define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\
678 NEAREST_ALIGNED(ctx->cipher_data))
679
680#define EVP_CIPHER_block_size_ECB AES_BLOCK_SIZE
681#define EVP_CIPHER_block_size_CBC AES_BLOCK_SIZE
682#define EVP_CIPHER_block_size_OFB 1
683#define EVP_CIPHER_block_size_CFB 1
684
685/* Declaring so many ciphers by hand would be a pain.
686 Instead introduce a bit of preprocessor magic :-) */
687#define DECLARE_AES_EVP(ksize,lmode,umode) \
688static const EVP_CIPHER padlock_aes_##ksize##_##lmode = { \
689 NID_aes_##ksize##_##lmode, \
690 EVP_CIPHER_block_size_##umode, \
691 AES_KEY_SIZE_##ksize, \
692 AES_BLOCK_SIZE, \
693 0 | EVP_CIPH_##umode##_MODE, \
694 padlock_aes_init_key, \
695 padlock_aes_cipher, \
696 NULL, \
697 sizeof(struct padlock_cipher_data) + 16, \
698 EVP_CIPHER_set_asn1_iv, \
699 EVP_CIPHER_get_asn1_iv, \
700 NULL, \
701 NULL \
702}
703
704DECLARE_AES_EVP(128,ecb,ECB);
705DECLARE_AES_EVP(128,cbc,CBC);
706DECLARE_AES_EVP(128,cfb,CFB);
707DECLARE_AES_EVP(128,ofb,OFB);
708
709DECLARE_AES_EVP(192,ecb,ECB);
710DECLARE_AES_EVP(192,cbc,CBC);
711DECLARE_AES_EVP(192,cfb,CFB);
712DECLARE_AES_EVP(192,ofb,OFB);
713
714DECLARE_AES_EVP(256,ecb,ECB);
715DECLARE_AES_EVP(256,cbc,CBC);
716DECLARE_AES_EVP(256,cfb,CFB);
717DECLARE_AES_EVP(256,ofb,OFB);
718
719static int
720padlock_ciphers (ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid)
721{
722 /* No specific cipher => return a list of supported nids ... */
723 if (!cipher) {
724 *nids = padlock_cipher_nids;
725 return padlock_cipher_nids_num;
726 }
727
728 /* ... or the requested "cipher" otherwise */
729 switch (nid) {
730 case NID_aes_128_ecb:
731 *cipher = &padlock_aes_128_ecb;
732 break;
733 case NID_aes_128_cbc:
734 *cipher = &padlock_aes_128_cbc;
735 break;
736 case NID_aes_128_cfb:
737 *cipher = &padlock_aes_128_cfb;
738 break;
739 case NID_aes_128_ofb:
740 *cipher = &padlock_aes_128_ofb;
741 break;
742
743 case NID_aes_192_ecb:
744 *cipher = &padlock_aes_192_ecb;
745 break;
746 case NID_aes_192_cbc:
747 *cipher = &padlock_aes_192_cbc;
748 break;
749 case NID_aes_192_cfb:
750 *cipher = &padlock_aes_192_cfb;
751 break;
752 case NID_aes_192_ofb:
753 *cipher = &padlock_aes_192_ofb;
754 break;
755
756 case NID_aes_256_ecb:
757 *cipher = &padlock_aes_256_ecb;
758 break;
759 case NID_aes_256_cbc:
760 *cipher = &padlock_aes_256_cbc;
761 break;
762 case NID_aes_256_cfb:
763 *cipher = &padlock_aes_256_cfb;
764 break;
765 case NID_aes_256_ofb:
766 *cipher = &padlock_aes_256_ofb;
767 break;
768
769 default:
770 /* Sorry, we don't support this NID */
771 *cipher = NULL;
772 return 0;
773 }
774
775 return 1;
776}
777
778/* Prepare the encryption key for PadLock usage */
779static int
780padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key,
781 const unsigned char *iv, int enc)
782{
783 struct padlock_cipher_data *cdata;
784 int key_len = EVP_CIPHER_CTX_key_length(ctx) * 8;
785
786 if (key==NULL) return 0; /* ERROR */
787
788 cdata = ALIGNED_CIPHER_DATA(ctx);
789 memset(cdata, 0, sizeof(struct padlock_cipher_data));
790
791 /* Prepare Control word. */
792 if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE)
793 cdata->cword.b.encdec = 0;
794 else
795 cdata->cword.b.encdec = (ctx->encrypt == 0);
796 cdata->cword.b.rounds = 10 + (key_len - 128) / 32;
797 cdata->cword.b.ksize = (key_len - 128) / 64;
798
799 switch(key_len) {
800 case 128:
801 /* PadLock can generate an extended key for
802 AES128 in hardware */
803 memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128);
804 cdata->cword.b.keygen = 0;
805 break;
806
807 case 192:
808 case 256:
809 /* Generate an extended AES key in software.
810 Needed for AES192/AES256 */
811 /* Well, the above applies to Stepping 8 CPUs
812 and is listed as hardware errata. They most
813 likely will fix it at some point and then
814 a check for stepping would be due here. */
815 if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE ||
816 EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE ||
817 enc)
818 AES_set_encrypt_key(key, key_len, &cdata->ks);
819 else
820 AES_set_decrypt_key(key, key_len, &cdata->ks);
821#ifndef AES_ASM
822 /* OpenSSL C functions use byte-swapped extended key. */
823 padlock_bswapl(&cdata->ks);
824#endif
825 cdata->cword.b.keygen = 1;
826 break;
827
828 default:
829 /* ERROR */
830 return 0;
831 }
832
833 /*
834 * This is done to cover for cases when user reuses the
835 * context for new key. The catch is that if we don't do
836 * this, padlock_eas_cipher might proceed with old key...
837 */
838 padlock_reload_key ();
839
840 return 1;
841}
842
843/*
844 * Simplified version of padlock_aes_cipher() used when
845 * 1) both input and output buffers are at aligned addresses.
846 * or when
847 * 2) running on a newer CPU that doesn't require aligned buffers.
848 */
849static int
850padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
851 const unsigned char *in_arg, size_t nbytes)
852{
853 struct padlock_cipher_data *cdata;
854 void *iv;
855
856 cdata = ALIGNED_CIPHER_DATA(ctx);
857 padlock_verify_context(cdata);
858
859 switch (EVP_CIPHER_CTX_mode(ctx)) {
860 case EVP_CIPH_ECB_MODE:
861 padlock_xcrypt_ecb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
862 break;
863
864 case EVP_CIPH_CBC_MODE:
865 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
866 iv = padlock_xcrypt_cbc(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
867 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
868 break;
869
870 case EVP_CIPH_CFB_MODE:
871 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
872 iv = padlock_xcrypt_cfb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
873 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
874 break;
875
876 case EVP_CIPH_OFB_MODE:
877 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
878 padlock_xcrypt_ofb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
879 memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
880 break;
881
882 default:
883 return 0;
884 }
885
886 memset(cdata->iv, 0, AES_BLOCK_SIZE);
887
888 return 1;
889}
890
891#ifndef PADLOCK_CHUNK
892# define PADLOCK_CHUNK 512 /* Must be a power of 2 larger than 16 */
893#endif
894#if PADLOCK_CHUNK<16 || PADLOCK_CHUNK&(PADLOCK_CHUNK-1)
895# error "insane PADLOCK_CHUNK..."
896#endif
897
898/* Re-align the arguments to 16-Bytes boundaries and run the
899 encryption function itself. This function is not AES-specific. */
900static int
901padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
902 const unsigned char *in_arg, size_t nbytes)
903{
904 struct padlock_cipher_data *cdata;
905 const void *inp;
906 unsigned char *out;
907 void *iv;
908 int inp_misaligned, out_misaligned, realign_in_loop;
909 size_t chunk, allocated=0;
910
911 /* ctx->num is maintained in byte-oriented modes,
912 such as CFB and OFB... */
913 if ((chunk = ctx->num)) { /* borrow chunk variable */
914 unsigned char *ivp=ctx->iv;
915
916 switch (EVP_CIPHER_CTX_mode(ctx)) {
917 case EVP_CIPH_CFB_MODE:
918 if (chunk >= AES_BLOCK_SIZE)
919 return 0; /* bogus value */
920
921 if (ctx->encrypt)
922 while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
923 ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk];
924 chunk++, nbytes--;
925 }
926 else while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
927 unsigned char c = *(in_arg++);
928 *(out_arg++) = c ^ ivp[chunk];
929 ivp[chunk++] = c, nbytes--;
930 }
931
932 ctx->num = chunk%AES_BLOCK_SIZE;
933 break;
934 case EVP_CIPH_OFB_MODE:
935 if (chunk >= AES_BLOCK_SIZE)
936 return 0; /* bogus value */
937
938 while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
939 *(out_arg++) = *(in_arg++) ^ ivp[chunk];
940 chunk++, nbytes--;
941 }
942
943 ctx->num = chunk%AES_BLOCK_SIZE;
944 break;
945 }
946 }
947
948 if (nbytes == 0)
949 return 1;
950#if 0
951 if (nbytes % AES_BLOCK_SIZE)
952 return 0; /* are we expected to do tail processing? */
953#else
954 /* nbytes is always multiple of AES_BLOCK_SIZE in ECB and CBC
955 modes and arbitrary value in byte-oriented modes, such as
956 CFB and OFB... */
957#endif
958
959 /* VIA promises CPUs that won't require alignment in the future.
960 For now padlock_aes_align_required is initialized to 1 and
961 the condition is never met... */
962 /* C7 core is capable to manage unaligned input in non-ECB[!]
963 mode, but performance penalties appear to be approximately
964 same as for software alignment below or ~3x. They promise to
965 improve it in the future, but for now we can just as well
966 pretend that it can only handle aligned input... */
967 if (!padlock_aes_align_required && (nbytes%AES_BLOCK_SIZE)==0)
968 return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
969
970 inp_misaligned = (((size_t)in_arg) & 0x0F);
971 out_misaligned = (((size_t)out_arg) & 0x0F);
972
973 /* Note that even if output is aligned and input not,
974 * I still prefer to loop instead of copy the whole
975 * input and then encrypt in one stroke. This is done
976 * in order to improve L1 cache utilization... */
977 realign_in_loop = out_misaligned|inp_misaligned;
978
979 if (!realign_in_loop && (nbytes%AES_BLOCK_SIZE)==0)
980 return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
981
982 /* this takes one "if" out of the loops */
983 chunk = nbytes;
984 chunk %= PADLOCK_CHUNK;
985 if (chunk==0) chunk = PADLOCK_CHUNK;
986
987 if (out_misaligned) {
988 /* optmize for small input */
989 allocated = (chunk<nbytes?PADLOCK_CHUNK:nbytes);
990 out = alloca(0x10 + allocated);
991 out = NEAREST_ALIGNED(out);
992 }
993 else
994 out = out_arg;
995
996 cdata = ALIGNED_CIPHER_DATA(ctx);
997 padlock_verify_context(cdata);
998
999 switch (EVP_CIPHER_CTX_mode(ctx)) {
1000 case EVP_CIPH_ECB_MODE:
1001 do {
1002 if (inp_misaligned)
1003 inp = padlock_memcpy(out, in_arg, chunk);
1004 else
1005 inp = in_arg;
1006 in_arg += chunk;
1007
1008 padlock_xcrypt_ecb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1009
1010 if (out_misaligned)
1011 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1012 else
1013 out = out_arg+=chunk;
1014
1015 nbytes -= chunk;
1016 chunk = PADLOCK_CHUNK;
1017 } while (nbytes);
1018 break;
1019
1020 case EVP_CIPH_CBC_MODE:
1021 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
1022 goto cbc_shortcut;
1023 do {
1024 if (iv != cdata->iv)
1025 memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
1026 chunk = PADLOCK_CHUNK;
1027 cbc_shortcut: /* optimize for small input */
1028 if (inp_misaligned)
1029 inp = padlock_memcpy(out, in_arg, chunk);
1030 else
1031 inp = in_arg;
1032 in_arg += chunk;
1033
1034 iv = padlock_xcrypt_cbc(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1035
1036 if (out_misaligned)
1037 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1038 else
1039 out = out_arg+=chunk;
1040
1041 } while (nbytes -= chunk);
1042 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
1043 break;
1044
1045 case EVP_CIPH_CFB_MODE:
1046 memcpy (iv = cdata->iv, ctx->iv, AES_BLOCK_SIZE);
1047 chunk &= ~(AES_BLOCK_SIZE-1);
1048 if (chunk) goto cfb_shortcut;
1049 else goto cfb_skiploop;
1050 do {
1051 if (iv != cdata->iv)
1052 memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
1053 chunk = PADLOCK_CHUNK;
1054 cfb_shortcut: /* optimize for small input */
1055 if (inp_misaligned)
1056 inp = padlock_memcpy(out, in_arg, chunk);
1057 else
1058 inp = in_arg;
1059 in_arg += chunk;
1060
1061 iv = padlock_xcrypt_cfb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1062
1063 if (out_misaligned)
1064 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1065 else
1066 out = out_arg+=chunk;
1067
1068 nbytes -= chunk;
1069 } while (nbytes >= AES_BLOCK_SIZE);
1070
1071 cfb_skiploop:
1072 if (nbytes) {
1073 unsigned char *ivp = cdata->iv;
1074
1075 if (iv != ivp) {
1076 memcpy(ivp, iv, AES_BLOCK_SIZE);
1077 iv = ivp;
1078 }
1079 ctx->num = nbytes;
1080 if (cdata->cword.b.encdec) {
1081 cdata->cword.b.encdec=0;
1082 padlock_reload_key();
1083 padlock_xcrypt_ecb(1,cdata,ivp,ivp);
1084 cdata->cword.b.encdec=1;
1085 padlock_reload_key();
1086 while(nbytes) {
1087 unsigned char c = *(in_arg++);
1088 *(out_arg++) = c ^ *ivp;
1089 *(ivp++) = c, nbytes--;
1090 }
1091 }
1092 else { padlock_reload_key();
1093 padlock_xcrypt_ecb(1,cdata,ivp,ivp);
1094 padlock_reload_key();
1095 while (nbytes) {
1096 *ivp = *(out_arg++) = *(in_arg++) ^ *ivp;
1097 ivp++, nbytes--;
1098 }
1099 }
1100 }
1101
1102 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
1103 break;
1104
1105 case EVP_CIPH_OFB_MODE:
1106 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
1107 chunk &= ~(AES_BLOCK_SIZE-1);
1108 if (chunk) do {
1109 if (inp_misaligned)
1110 inp = padlock_memcpy(out, in_arg, chunk);
1111 else
1112 inp = in_arg;
1113 in_arg += chunk;
1114
1115 padlock_xcrypt_ofb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1116
1117 if (out_misaligned)
1118 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1119 else
1120 out = out_arg+=chunk;
1121
1122 nbytes -= chunk;
1123 chunk = PADLOCK_CHUNK;
1124 } while (nbytes >= AES_BLOCK_SIZE);
1125
1126 if (nbytes) {
1127 unsigned char *ivp = cdata->iv;
1128
1129 ctx->num = nbytes;
1130 padlock_reload_key(); /* empirically found */
1131 padlock_xcrypt_ecb(1,cdata,ivp,ivp);
1132 padlock_reload_key(); /* empirically found */
1133 while (nbytes) {
1134 *(out_arg++) = *(in_arg++) ^ *ivp;
1135 ivp++, nbytes--;
1136 }
1137 }
1138
1139 memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
1140 break;
1141
1142 default:
1143 return 0;
1144 }
1145
1146 /* Clean the realign buffer if it was used */
1147 if (out_misaligned) {
1148 volatile unsigned long *p=(void *)out;
1149 size_t n = allocated/sizeof(*p);
1150 while (n--) *p++=0;
1151 }
1152
1153 memset(cdata->iv, 0, AES_BLOCK_SIZE);
1154
1155 return 1;
1156}
1157
1158#endif /* OPENSSL_NO_AES */
1159
1160/* ===== Random Number Generator ===== */
1161/*
1162 * This code is not engaged. The reason is that it does not comply
1163 * with recommendations for VIA RNG usage for secure applications
1164 * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it
1165 * provide meaningful error control...
1166 */
1167/* Wrapper that provides an interface between the API and
1168 the raw PadLock RNG */
1169static int
1170padlock_rand_bytes(unsigned char *output, int count)
1171{
1172 unsigned int eax, buf;
1173
1174 while (count >= 8) {
1175 eax = padlock_xstore(output, 0);
1176 if (!(eax&(1<<6))) return 0; /* RNG disabled */
1177 /* this ---vv--- covers DC bias, Raw Bits and String Filter */
1178 if (eax&(0x1F<<10)) return 0;
1179 if ((eax&0x1F)==0) continue; /* no data, retry... */
1180 if ((eax&0x1F)!=8) return 0; /* fatal failure... */
1181 output += 8;
1182 count -= 8;
1183 }
1184 while (count > 0) {
1185 eax = padlock_xstore(&buf, 3);
1186 if (!(eax&(1<<6))) return 0; /* RNG disabled */
1187 /* this ---vv--- covers DC bias, Raw Bits and String Filter */
1188 if (eax&(0x1F<<10)) return 0;
1189 if ((eax&0x1F)==0) continue; /* no data, retry... */
1190 if ((eax&0x1F)!=1) return 0; /* fatal failure... */
1191 *output++ = (unsigned char)buf;
1192 count--;
1193 }
1194 *(volatile unsigned int *)&buf=0;
1195
1196 return 1;
1197}
1198
1199/* Dummy but necessary function */
1200static int
1201padlock_rand_status(void)
1202{
1203 return 1;
1204}
1205
1206/* Prepare structure for registration */
1207static RAND_METHOD padlock_rand = {
1208 NULL, /* seed */
1209 padlock_rand_bytes, /* bytes */
1210 NULL, /* cleanup */
1211 NULL, /* add */
1212 padlock_rand_bytes, /* pseudorand */
1213 padlock_rand_status, /* rand status */
1214};
1215
1216#endif /* COMPILE_HW_PADLOCK */
1217
1218#endif /* !OPENSSL_NO_HW_PADLOCK */
1219#endif /* !OPENSSL_NO_HW */
diff --git a/src/lib/libcrypto/engine/eng_pkey.c b/src/lib/libcrypto/engine/eng_pkey.c
new file mode 100644
index 0000000000..1dfa2e3664
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_pkey.c
@@ -0,0 +1,196 @@
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 "eng_int.h"
57
58/* Basic get/set stuff */
59
60int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f)
61 {
62 e->load_privkey = loadpriv_f;
63 return 1;
64 }
65
66int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f)
67 {
68 e->load_pubkey = loadpub_f;
69 return 1;
70 }
71
72int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
73 ENGINE_SSL_CLIENT_CERT_PTR loadssl_f)
74 {
75 e->load_ssl_client_cert = loadssl_f;
76 return 1;
77 }
78
79ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e)
80 {
81 return e->load_privkey;
82 }
83
84ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e)
85 {
86 return e->load_pubkey;
87 }
88
89ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e)
90 {
91 return e->load_ssl_client_cert;
92 }
93
94/* API functions to load public/private keys */
95
96EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
97 UI_METHOD *ui_method, void *callback_data)
98 {
99 EVP_PKEY *pkey;
100
101 if(e == NULL)
102 {
103 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
104 ERR_R_PASSED_NULL_PARAMETER);
105 return 0;
106 }
107 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
108 if(e->funct_ref == 0)
109 {
110 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
111 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
112 ENGINE_R_NOT_INITIALISED);
113 return 0;
114 }
115 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
116 if (!e->load_privkey)
117 {
118 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
119 ENGINE_R_NO_LOAD_FUNCTION);
120 return 0;
121 }
122 pkey = e->load_privkey(e, key_id, ui_method, callback_data);
123 if (!pkey)
124 {
125 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
126 ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
127 return 0;
128 }
129 return pkey;
130 }
131
132EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
133 UI_METHOD *ui_method, void *callback_data)
134 {
135 EVP_PKEY *pkey;
136
137 if(e == NULL)
138 {
139 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
140 ERR_R_PASSED_NULL_PARAMETER);
141 return 0;
142 }
143 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
144 if(e->funct_ref == 0)
145 {
146 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
147 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
148 ENGINE_R_NOT_INITIALISED);
149 return 0;
150 }
151 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
152 if (!e->load_pubkey)
153 {
154 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
155 ENGINE_R_NO_LOAD_FUNCTION);
156 return 0;
157 }
158 pkey = e->load_pubkey(e, key_id, ui_method, callback_data);
159 if (!pkey)
160 {
161 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
162 ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
163 return 0;
164 }
165 return pkey;
166 }
167
168int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
169 STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey,
170 STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data)
171 {
172
173 if(e == NULL)
174 {
175 ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
176 ERR_R_PASSED_NULL_PARAMETER);
177 return 0;
178 }
179 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
180 if(e->funct_ref == 0)
181 {
182 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
183 ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
184 ENGINE_R_NOT_INITIALISED);
185 return 0;
186 }
187 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
188 if (!e->load_ssl_client_cert)
189 {
190 ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
191 ENGINE_R_NO_LOAD_FUNCTION);
192 return 0;
193 }
194 return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother,
195 ui_method, callback_data);
196 }
diff --git a/src/lib/libcrypto/engine/eng_table.c b/src/lib/libcrypto/engine/eng_table.c
new file mode 100644
index 0000000000..4fde948185
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_table.c
@@ -0,0 +1,351 @@
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 "cryptlib.h"
56#include <openssl/evp.h>
57#include <openssl/lhash.h>
58#include "eng_int.h"
59
60/* The type of the items in the table */
61typedef struct st_engine_pile
62 {
63 /* The 'nid' of this algorithm/mode */
64 int nid;
65 /* ENGINEs that implement this algorithm/mode. */
66 STACK_OF(ENGINE) *sk;
67 /* The default ENGINE to perform this algorithm/mode. */
68 ENGINE *funct;
69 /* Zero if 'sk' is newer than the cached 'funct', non-zero otherwise */
70 int uptodate;
71 } ENGINE_PILE;
72
73DECLARE_LHASH_OF(ENGINE_PILE);
74
75/* The type exposed in eng_int.h */
76struct st_engine_table
77 {
78 LHASH_OF(ENGINE_PILE) piles;
79 }; /* ENGINE_TABLE */
80
81
82typedef struct st_engine_pile_doall
83 {
84 engine_table_doall_cb *cb;
85 void *arg;
86 } ENGINE_PILE_DOALL;
87
88
89/* Global flags (ENGINE_TABLE_FLAG_***). */
90static unsigned int table_flags = 0;
91
92/* API function manipulating 'table_flags' */
93unsigned int ENGINE_get_table_flags(void)
94 {
95 return table_flags;
96 }
97
98void ENGINE_set_table_flags(unsigned int flags)
99 {
100 table_flags = flags;
101 }
102
103/* Internal functions for the "piles" hash table */
104static unsigned long engine_pile_hash(const ENGINE_PILE *c)
105 {
106 return c->nid;
107 }
108
109static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b)
110 {
111 return a->nid - b->nid;
112 }
113static IMPLEMENT_LHASH_HASH_FN(engine_pile, ENGINE_PILE)
114static IMPLEMENT_LHASH_COMP_FN(engine_pile, ENGINE_PILE)
115
116static int int_table_check(ENGINE_TABLE **t, int create)
117 {
118 LHASH_OF(ENGINE_PILE) *lh;
119
120 if(*t) return 1;
121 if(!create) return 0;
122 if((lh = lh_ENGINE_PILE_new()) == NULL)
123 return 0;
124 *t = (ENGINE_TABLE *)lh;
125 return 1;
126 }
127
128/* Privately exposed (via eng_int.h) functions for adding and/or removing
129 * ENGINEs from the implementation table */
130int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
131 ENGINE *e, const int *nids, int num_nids, int setdefault)
132 {
133 int ret = 0, added = 0;
134 ENGINE_PILE tmplate, *fnd;
135 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
136 if(!(*table))
137 added = 1;
138 if(!int_table_check(table, 1))
139 goto end;
140 if(added)
141 /* The cleanup callback needs to be added */
142 engine_cleanup_add_first(cleanup);
143 while(num_nids--)
144 {
145 tmplate.nid = *nids;
146 fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
147 if(!fnd)
148 {
149 fnd = OPENSSL_malloc(sizeof(ENGINE_PILE));
150 if(!fnd) goto end;
151 fnd->uptodate = 1;
152 fnd->nid = *nids;
153 fnd->sk = sk_ENGINE_new_null();
154 if(!fnd->sk)
155 {
156 OPENSSL_free(fnd);
157 goto end;
158 }
159 fnd->funct = NULL;
160 (void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd);
161 }
162 /* A registration shouldn't add duplciate entries */
163 (void)sk_ENGINE_delete_ptr(fnd->sk, e);
164 /* if 'setdefault', this ENGINE goes to the head of the list */
165 if(!sk_ENGINE_push(fnd->sk, e))
166 goto end;
167 /* "touch" this ENGINE_PILE */
168 fnd->uptodate = 0;
169 if(setdefault)
170 {
171 if(!engine_unlocked_init(e))
172 {
173 ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER,
174 ENGINE_R_INIT_FAILED);
175 goto end;
176 }
177 if(fnd->funct)
178 engine_unlocked_finish(fnd->funct, 0);
179 fnd->funct = e;
180 fnd->uptodate = 1;
181 }
182 nids++;
183 }
184 ret = 1;
185end:
186 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
187 return ret;
188 }
189static void int_unregister_cb_doall_arg(ENGINE_PILE *pile, ENGINE *e)
190 {
191 int n;
192 /* Iterate the 'c->sk' stack removing any occurance of 'e' */
193 while((n = sk_ENGINE_find(pile->sk, e)) >= 0)
194 {
195 (void)sk_ENGINE_delete(pile->sk, n);
196 pile->uptodate = 0;
197 }
198 if(pile->funct == e)
199 {
200 engine_unlocked_finish(e, 0);
201 pile->funct = NULL;
202 }
203 }
204static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb, ENGINE_PILE, ENGINE)
205
206void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e)
207 {
208 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
209 if(int_table_check(table, 0))
210 lh_ENGINE_PILE_doall_arg(&(*table)->piles,
211 LHASH_DOALL_ARG_FN(int_unregister_cb),
212 ENGINE, e);
213 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
214 }
215
216static void int_cleanup_cb_doall(ENGINE_PILE *p)
217 {
218 sk_ENGINE_free(p->sk);
219 if(p->funct)
220 engine_unlocked_finish(p->funct, 0);
221 OPENSSL_free(p);
222 }
223static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb, ENGINE_PILE)
224
225void engine_table_cleanup(ENGINE_TABLE **table)
226 {
227 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
228 if(*table)
229 {
230 lh_ENGINE_PILE_doall(&(*table)->piles,
231 LHASH_DOALL_FN(int_cleanup_cb));
232 lh_ENGINE_PILE_free(&(*table)->piles);
233 *table = NULL;
234 }
235 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
236 }
237
238/* return a functional reference for a given 'nid' */
239#ifndef ENGINE_TABLE_DEBUG
240ENGINE *engine_table_select(ENGINE_TABLE **table, int nid)
241#else
242ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l)
243#endif
244 {
245 ENGINE *ret = NULL;
246 ENGINE_PILE tmplate, *fnd=NULL;
247 int initres, loop = 0;
248
249 if(!(*table))
250 {
251#ifdef ENGINE_TABLE_DEBUG
252 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing "
253 "registered!\n", f, l, nid);
254#endif
255 return NULL;
256 }
257 ERR_set_mark();
258 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
259 /* Check again inside the lock otherwise we could race against cleanup
260 * operations. But don't worry about a fprintf(stderr). */
261 if(!int_table_check(table, 0)) goto end;
262 tmplate.nid = nid;
263 fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
264 if(!fnd) goto end;
265 if(fnd->funct && engine_unlocked_init(fnd->funct))
266 {
267#ifdef ENGINE_TABLE_DEBUG
268 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
269 "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id);
270#endif
271 ret = fnd->funct;
272 goto end;
273 }
274 if(fnd->uptodate)
275 {
276 ret = fnd->funct;
277 goto end;
278 }
279trynext:
280 ret = sk_ENGINE_value(fnd->sk, loop++);
281 if(!ret)
282 {
283#ifdef ENGINE_TABLE_DEBUG
284 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no "
285 "registered implementations would initialise\n",
286 f, l, nid);
287#endif
288 goto end;
289 }
290 /* Try to initialise the ENGINE? */
291 if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT))
292 initres = engine_unlocked_init(ret);
293 else
294 initres = 0;
295 if(initres)
296 {
297 /* Update 'funct' */
298 if((fnd->funct != ret) && engine_unlocked_init(ret))
299 {
300 /* If there was a previous default we release it. */
301 if(fnd->funct)
302 engine_unlocked_finish(fnd->funct, 0);
303 fnd->funct = ret;
304#ifdef ENGINE_TABLE_DEBUG
305 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, "
306 "setting default to '%s'\n", f, l, nid, ret->id);
307#endif
308 }
309#ifdef ENGINE_TABLE_DEBUG
310 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
311 "newly initialised '%s'\n", f, l, nid, ret->id);
312#endif
313 goto end;
314 }
315 goto trynext;
316end:
317 /* If it failed, it is unlikely to succeed again until some future
318 * registrations have taken place. In all cases, we cache. */
319 if(fnd) fnd->uptodate = 1;
320#ifdef ENGINE_TABLE_DEBUG
321 if(ret)
322 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
323 "ENGINE '%s'\n", f, l, nid, ret->id);
324 else
325 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
326 "'no matching ENGINE'\n", f, l, nid);
327#endif
328 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
329 /* Whatever happened, any failed init()s are not failures in this
330 * context, so clear our error state. */
331 ERR_pop_to_mark();
332 return ret;
333 }
334
335/* Table enumeration */
336
337static void int_cb_doall_arg(ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall)
338 {
339 dall->cb(pile->nid, pile->sk, pile->funct, dall->arg);
340 }
341static IMPLEMENT_LHASH_DOALL_ARG_FN(int_cb, ENGINE_PILE,ENGINE_PILE_DOALL)
342
343void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb,
344 void *arg)
345 {
346 ENGINE_PILE_DOALL dall;
347 dall.cb = cb;
348 dall.arg = arg;
349 lh_ENGINE_PILE_doall_arg(&table->piles, LHASH_DOALL_ARG_FN(int_cb),
350 ENGINE_PILE_DOALL, &dall);
351 }
diff --git a/src/lib/libcrypto/engine/engine.h b/src/lib/libcrypto/engine/engine.h
new file mode 100644
index 0000000000..9d73abac8e
--- /dev/null
+++ b/src/lib/libcrypto/engine/engine.h
@@ -0,0 +1,834 @@
1/* openssl/engine.h */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2004 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 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * ECDH support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
63
64#ifndef HEADER_ENGINE_H
65#define HEADER_ENGINE_H
66
67#include <openssl/opensslconf.h>
68
69#ifdef OPENSSL_NO_ENGINE
70#error ENGINE is disabled.
71#endif
72
73#ifndef OPENSSL_NO_DEPRECATED
74#include <openssl/bn.h>
75#ifndef OPENSSL_NO_RSA
76#include <openssl/rsa.h>
77#endif
78#ifndef OPENSSL_NO_DSA
79#include <openssl/dsa.h>
80#endif
81#ifndef OPENSSL_NO_DH
82#include <openssl/dh.h>
83#endif
84#ifndef OPENSSL_NO_ECDH
85#include <openssl/ecdh.h>
86#endif
87#ifndef OPENSSL_NO_ECDSA
88#include <openssl/ecdsa.h>
89#endif
90#include <openssl/rand.h>
91#include <openssl/ui.h>
92#include <openssl/err.h>
93#endif
94
95#include <openssl/ossl_typ.h>
96#include <openssl/symhacks.h>
97
98#include <openssl/x509.h>
99
100#ifdef __cplusplus
101extern "C" {
102#endif
103
104/* These flags are used to control combinations of algorithm (methods)
105 * by bitwise "OR"ing. */
106#define ENGINE_METHOD_RSA (unsigned int)0x0001
107#define ENGINE_METHOD_DSA (unsigned int)0x0002
108#define ENGINE_METHOD_DH (unsigned int)0x0004
109#define ENGINE_METHOD_RAND (unsigned int)0x0008
110#define ENGINE_METHOD_ECDH (unsigned int)0x0010
111#define ENGINE_METHOD_ECDSA (unsigned int)0x0020
112#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040
113#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080
114#define ENGINE_METHOD_STORE (unsigned int)0x0100
115#define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200
116#define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400
117/* Obvious all-or-nothing cases. */
118#define ENGINE_METHOD_ALL (unsigned int)0xFFFF
119#define ENGINE_METHOD_NONE (unsigned int)0x0000
120
121/* This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used
122 * internally to control registration of ENGINE implementations, and can be set
123 * by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to
124 * initialise registered ENGINEs if they are not already initialised. */
125#define ENGINE_TABLE_FLAG_NOINIT (unsigned int)0x0001
126
127/* ENGINE flags that can be set by ENGINE_set_flags(). */
128/* #define ENGINE_FLAGS_MALLOCED 0x0001 */ /* Not used */
129
130/* This flag is for ENGINEs that wish to handle the various 'CMD'-related
131 * control commands on their own. Without this flag, ENGINE_ctrl() handles these
132 * control commands on behalf of the ENGINE using their "cmd_defns" data. */
133#define ENGINE_FLAGS_MANUAL_CMD_CTRL (int)0x0002
134
135/* This flag is for ENGINEs who return new duplicate structures when found via
136 * "ENGINE_by_id()". When an ENGINE must store state (eg. if ENGINE_ctrl()
137 * commands are called in sequence as part of some stateful process like
138 * key-generation setup and execution), it can set this flag - then each attempt
139 * to obtain the ENGINE will result in it being copied into a new structure.
140 * Normally, ENGINEs don't declare this flag so ENGINE_by_id() just increments
141 * the existing ENGINE's structural reference count. */
142#define ENGINE_FLAGS_BY_ID_COPY (int)0x0004
143
144/* ENGINEs can support their own command types, and these flags are used in
145 * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input each
146 * command expects. Currently only numeric and string input is supported. If a
147 * control command supports none of the _NUMERIC, _STRING, or _NO_INPUT options,
148 * then it is regarded as an "internal" control command - and not for use in
149 * config setting situations. As such, they're not available to the
150 * ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() access. Changes to
151 * this list of 'command types' should be reflected carefully in
152 * ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). */
153
154/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */
155#define ENGINE_CMD_FLAG_NUMERIC (unsigned int)0x0001
156/* accepts string input (cast from 'void*' to 'const char *', 4th parameter to
157 * ENGINE_ctrl) */
158#define ENGINE_CMD_FLAG_STRING (unsigned int)0x0002
159/* Indicates that the control command takes *no* input. Ie. the control command
160 * is unparameterised. */
161#define ENGINE_CMD_FLAG_NO_INPUT (unsigned int)0x0004
162/* Indicates that the control command is internal. This control command won't
163 * be shown in any output, and is only usable through the ENGINE_ctrl_cmd()
164 * function. */
165#define ENGINE_CMD_FLAG_INTERNAL (unsigned int)0x0008
166
167/* NB: These 3 control commands are deprecated and should not be used. ENGINEs
168 * relying on these commands should compile conditional support for
169 * compatibility (eg. if these symbols are defined) but should also migrate the
170 * same functionality to their own ENGINE-specific control functions that can be
171 * "discovered" by calling applications. The fact these control commands
172 * wouldn't be "executable" (ie. usable by text-based config) doesn't change the
173 * fact that application code can find and use them without requiring per-ENGINE
174 * hacking. */
175
176/* These flags are used to tell the ctrl function what should be done.
177 * All command numbers are shared between all engines, even if some don't
178 * make sense to some engines. In such a case, they do nothing but return
179 * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */
180#define ENGINE_CTRL_SET_LOGSTREAM 1
181#define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2
182#define ENGINE_CTRL_HUP 3 /* Close and reinitialise any
183 handles/connections etc. */
184#define ENGINE_CTRL_SET_USER_INTERFACE 4 /* Alternative to callback */
185#define ENGINE_CTRL_SET_CALLBACK_DATA 5 /* User-specific data, used
186 when calling the password
187 callback and the user
188 interface */
189#define ENGINE_CTRL_LOAD_CONFIGURATION 6 /* Load a configuration, given
190 a string that represents a
191 file name or so */
192#define ENGINE_CTRL_LOAD_SECTION 7 /* Load data from a given
193 section in the already loaded
194 configuration */
195
196/* These control commands allow an application to deal with an arbitrary engine
197 * in a dynamic way. Warn: Negative return values indicate errors FOR THESE
198 * COMMANDS because zero is used to indicate 'end-of-list'. Other commands,
199 * including ENGINE-specific command types, return zero for an error.
200 *
201 * An ENGINE can choose to implement these ctrl functions, and can internally
202 * manage things however it chooses - it does so by setting the
203 * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise the
204 * ENGINE_ctrl() code handles this on the ENGINE's behalf using the cmd_defns
205 * data (set using ENGINE_set_cmd_defns()). This means an ENGINE's ctrl()
206 * handler need only implement its own commands - the above "meta" commands will
207 * be taken care of. */
208
209/* Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", then
210 * all the remaining control commands will return failure, so it is worth
211 * checking this first if the caller is trying to "discover" the engine's
212 * capabilities and doesn't want errors generated unnecessarily. */
213#define ENGINE_CTRL_HAS_CTRL_FUNCTION 10
214/* Returns a positive command number for the first command supported by the
215 * engine. Returns zero if no ctrl commands are supported. */
216#define ENGINE_CTRL_GET_FIRST_CMD_TYPE 11
217/* The 'long' argument specifies a command implemented by the engine, and the
218 * return value is the next command supported, or zero if there are no more. */
219#define ENGINE_CTRL_GET_NEXT_CMD_TYPE 12
220/* The 'void*' argument is a command name (cast from 'const char *'), and the
221 * return value is the command that corresponds to it. */
222#define ENGINE_CTRL_GET_CMD_FROM_NAME 13
223/* The next two allow a command to be converted into its corresponding string
224 * form. In each case, the 'long' argument supplies the command. In the NAME_LEN
225 * case, the return value is the length of the command name (not counting a
226 * trailing EOL). In the NAME case, the 'void*' argument must be a string buffer
227 * large enough, and it will be populated with the name of the command (WITH a
228 * trailing EOL). */
229#define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD 14
230#define ENGINE_CTRL_GET_NAME_FROM_CMD 15
231/* The next two are similar but give a "short description" of a command. */
232#define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD 16
233#define ENGINE_CTRL_GET_DESC_FROM_CMD 17
234/* With this command, the return value is the OR'd combination of
235 * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given
236 * engine-specific ctrl command expects. */
237#define ENGINE_CTRL_GET_CMD_FLAGS 18
238
239/* ENGINE implementations should start the numbering of their own control
240 * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). */
241#define ENGINE_CMD_BASE 200
242
243/* NB: These 2 nCipher "chil" control commands are deprecated, and their
244 * functionality is now available through ENGINE-specific control commands
245 * (exposed through the above-mentioned 'CMD'-handling). Code using these 2
246 * commands should be migrated to the more general command handling before these
247 * are removed. */
248
249/* Flags specific to the nCipher "chil" engine */
250#define ENGINE_CTRL_CHIL_SET_FORKCHECK 100
251 /* Depending on the value of the (long)i argument, this sets or
252 * unsets the SimpleForkCheck flag in the CHIL API to enable or
253 * disable checking and workarounds for applications that fork().
254 */
255#define ENGINE_CTRL_CHIL_NO_LOCKING 101
256 /* This prevents the initialisation function from providing mutex
257 * callbacks to the nCipher library. */
258
259/* If an ENGINE supports its own specific control commands and wishes the
260 * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on its
261 * behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN entries
262 * to ENGINE_set_cmd_defns(). It should also implement a ctrl() handler that
263 * supports the stated commands (ie. the "cmd_num" entries as described by the
264 * array). NB: The array must be ordered in increasing order of cmd_num.
265 * "null-terminated" means that the last ENGINE_CMD_DEFN element has cmd_num set
266 * to zero and/or cmd_name set to NULL. */
267typedef struct ENGINE_CMD_DEFN_st
268 {
269 unsigned int cmd_num; /* The command number */
270 const char *cmd_name; /* The command name itself */
271 const char *cmd_desc; /* A short description of the command */
272 unsigned int cmd_flags; /* The input the command expects */
273 } ENGINE_CMD_DEFN;
274
275/* Generic function pointer */
276typedef int (*ENGINE_GEN_FUNC_PTR)(void);
277/* Generic function pointer taking no arguments */
278typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *);
279/* Specific control function pointer */
280typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, void (*f)(void));
281/* Generic load_key function pointer */
282typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
283 UI_METHOD *ui_method, void *callback_data);
284typedef int (*ENGINE_SSL_CLIENT_CERT_PTR)(ENGINE *, SSL *ssl,
285 STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
286 STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data);
287/* These callback types are for an ENGINE's handler for cipher and digest logic.
288 * These handlers have these prototypes;
289 * int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
290 * int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid);
291 * Looking at how to implement these handlers in the case of cipher support, if
292 * the framework wants the EVP_CIPHER for 'nid', it will call;
293 * foo(e, &p_evp_cipher, NULL, nid); (return zero for failure)
294 * If the framework wants a list of supported 'nid's, it will call;
295 * foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error)
296 */
297/* Returns to a pointer to the array of supported cipher 'nid's. If the second
298 * parameter is non-NULL it is set to the size of the returned array. */
299typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int);
300typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int);
301typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, EVP_PKEY_METHOD **, const int **, int);
302typedef int (*ENGINE_PKEY_ASN1_METHS_PTR)(ENGINE *, EVP_PKEY_ASN1_METHOD **, const int **, int);
303/* STRUCTURE functions ... all of these functions deal with pointers to ENGINE
304 * structures where the pointers have a "structural reference". This means that
305 * their reference is to allowed access to the structure but it does not imply
306 * that the structure is functional. To simply increment or decrement the
307 * structural reference count, use ENGINE_by_id and ENGINE_free. NB: This is not
308 * required when iterating using ENGINE_get_next as it will automatically
309 * decrement the structural reference count of the "current" ENGINE and
310 * increment the structural reference count of the ENGINE it returns (unless it
311 * is NULL). */
312
313/* Get the first/last "ENGINE" type available. */
314ENGINE *ENGINE_get_first(void);
315ENGINE *ENGINE_get_last(void);
316/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
317ENGINE *ENGINE_get_next(ENGINE *e);
318ENGINE *ENGINE_get_prev(ENGINE *e);
319/* Add another "ENGINE" type into the array. */
320int ENGINE_add(ENGINE *e);
321/* Remove an existing "ENGINE" type from the array. */
322int ENGINE_remove(ENGINE *e);
323/* Retrieve an engine from the list by its unique "id" value. */
324ENGINE *ENGINE_by_id(const char *id);
325/* Add all the built-in engines. */
326void ENGINE_load_openssl(void);
327void ENGINE_load_dynamic(void);
328#ifndef OPENSSL_NO_STATIC_ENGINE
329void ENGINE_load_4758cca(void);
330void ENGINE_load_aep(void);
331void ENGINE_load_atalla(void);
332void ENGINE_load_chil(void);
333void ENGINE_load_cswift(void);
334void ENGINE_load_nuron(void);
335void ENGINE_load_sureware(void);
336void ENGINE_load_ubsec(void);
337void ENGINE_load_padlock(void);
338void ENGINE_load_capi(void);
339#ifndef OPENSSL_NO_GMP
340void ENGINE_load_gmp(void);
341#endif
342#ifndef OPENSSL_NO_GOST
343void ENGINE_load_gost(void);
344#endif
345#endif
346void ENGINE_load_cryptodev(void);
347void ENGINE_load_aesni(void);
348void ENGINE_load_builtin_engines(void);
349
350/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
351 * "registry" handling. */
352unsigned int ENGINE_get_table_flags(void);
353void ENGINE_set_table_flags(unsigned int flags);
354
355/* Manage registration of ENGINEs per "table". For each type, there are 3
356 * functions;
357 * ENGINE_register_***(e) - registers the implementation from 'e' (if it has one)
358 * ENGINE_unregister_***(e) - unregister the implementation from 'e'
359 * ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list
360 * Cleanup is automatically registered from each table when required, so
361 * ENGINE_cleanup() will reverse any "register" operations. */
362
363int ENGINE_register_RSA(ENGINE *e);
364void ENGINE_unregister_RSA(ENGINE *e);
365void ENGINE_register_all_RSA(void);
366
367int ENGINE_register_DSA(ENGINE *e);
368void ENGINE_unregister_DSA(ENGINE *e);
369void ENGINE_register_all_DSA(void);
370
371int ENGINE_register_ECDH(ENGINE *e);
372void ENGINE_unregister_ECDH(ENGINE *e);
373void ENGINE_register_all_ECDH(void);
374
375int ENGINE_register_ECDSA(ENGINE *e);
376void ENGINE_unregister_ECDSA(ENGINE *e);
377void ENGINE_register_all_ECDSA(void);
378
379int ENGINE_register_DH(ENGINE *e);
380void ENGINE_unregister_DH(ENGINE *e);
381void ENGINE_register_all_DH(void);
382
383int ENGINE_register_RAND(ENGINE *e);
384void ENGINE_unregister_RAND(ENGINE *e);
385void ENGINE_register_all_RAND(void);
386
387int ENGINE_register_STORE(ENGINE *e);
388void ENGINE_unregister_STORE(ENGINE *e);
389void ENGINE_register_all_STORE(void);
390
391int ENGINE_register_ciphers(ENGINE *e);
392void ENGINE_unregister_ciphers(ENGINE *e);
393void ENGINE_register_all_ciphers(void);
394
395int ENGINE_register_digests(ENGINE *e);
396void ENGINE_unregister_digests(ENGINE *e);
397void ENGINE_register_all_digests(void);
398
399int ENGINE_register_pkey_meths(ENGINE *e);
400void ENGINE_unregister_pkey_meths(ENGINE *e);
401void ENGINE_register_all_pkey_meths(void);
402
403int ENGINE_register_pkey_asn1_meths(ENGINE *e);
404void ENGINE_unregister_pkey_asn1_meths(ENGINE *e);
405void ENGINE_register_all_pkey_asn1_meths(void);
406
407/* These functions register all support from the above categories. Note, use of
408 * these functions can result in static linkage of code your application may not
409 * need. If you only need a subset of functionality, consider using more
410 * selective initialisation. */
411int ENGINE_register_complete(ENGINE *e);
412int ENGINE_register_all_complete(void);
413
414/* Send parametrised control commands to the engine. The possibilities to send
415 * down an integer, a pointer to data or a function pointer are provided. Any of
416 * the parameters may or may not be NULL, depending on the command number. In
417 * actuality, this function only requires a structural (rather than functional)
418 * reference to an engine, but many control commands may require the engine be
419 * functional. The caller should be aware of trying commands that require an
420 * operational ENGINE, and only use functional references in such situations. */
421int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
422
423/* This function tests if an ENGINE-specific command is usable as a "setting".
424 * Eg. in an application's config file that gets processed through
425 * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to
426 * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). */
427int ENGINE_cmd_is_executable(ENGINE *e, int cmd);
428
429/* This function works like ENGINE_ctrl() with the exception of taking a
430 * command name instead of a command number, and can handle optional commands.
431 * See the comment on ENGINE_ctrl_cmd_string() for an explanation on how to
432 * use the cmd_name and cmd_optional. */
433int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
434 long i, void *p, void (*f)(void), int cmd_optional);
435
436/* This function passes a command-name and argument to an ENGINE. The cmd_name
437 * is converted to a command number and the control command is called using
438 * 'arg' as an argument (unless the ENGINE doesn't support such a command, in
439 * which case no control command is called). The command is checked for input
440 * flags, and if necessary the argument will be converted to a numeric value. If
441 * cmd_optional is non-zero, then if the ENGINE doesn't support the given
442 * cmd_name the return value will be success anyway. This function is intended
443 * for applications to use so that users (or config files) can supply
444 * engine-specific config data to the ENGINE at run-time to control behaviour of
445 * specific engines. As such, it shouldn't be used for calling ENGINE_ctrl()
446 * functions that return data, deal with binary data, or that are otherwise
447 * supposed to be used directly through ENGINE_ctrl() in application code. Any
448 * "return" data from an ENGINE_ctrl() operation in this function will be lost -
449 * the return value is interpreted as failure if the return value is zero,
450 * success otherwise, and this function returns a boolean value as a result. In
451 * other words, vendors of 'ENGINE'-enabled devices should write ENGINE
452 * implementations with parameterisations that work in this scheme, so that
453 * compliant ENGINE-based applications can work consistently with the same
454 * configuration for the same ENGINE-enabled devices, across applications. */
455int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
456 int cmd_optional);
457
458/* These functions are useful for manufacturing new ENGINE structures. They
459 * don't address reference counting at all - one uses them to populate an ENGINE
460 * structure with personalised implementations of things prior to using it
461 * directly or adding it to the builtin ENGINE list in OpenSSL. These are also
462 * here so that the ENGINE structure doesn't have to be exposed and break binary
463 * compatibility! */
464ENGINE *ENGINE_new(void);
465int ENGINE_free(ENGINE *e);
466int ENGINE_up_ref(ENGINE *e);
467int ENGINE_set_id(ENGINE *e, const char *id);
468int ENGINE_set_name(ENGINE *e, const char *name);
469int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
470int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
471int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth);
472int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth);
473int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
474int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
475int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth);
476int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
477int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
478int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
479int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
480int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f);
481int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
482int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
483 ENGINE_SSL_CLIENT_CERT_PTR loadssl_f);
484int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
485int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
486int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f);
487int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f);
488int ENGINE_set_flags(ENGINE *e, int flags);
489int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
490/* These functions allow control over any per-structure ENGINE data. */
491int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
492 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
493int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
494void *ENGINE_get_ex_data(const ENGINE *e, int idx);
495
496/* This function cleans up anything that needs it. Eg. the ENGINE_add() function
497 * automatically ensures the list cleanup function is registered to be called
498 * from ENGINE_cleanup(). Similarly, all ENGINE_register_*** functions ensure
499 * ENGINE_cleanup() will clean up after them. */
500void ENGINE_cleanup(void);
501
502/* These return values from within the ENGINE structure. These can be useful
503 * with functional references as well as structural references - it depends
504 * which you obtained. Using the result for functional purposes if you only
505 * obtained a structural reference may be problematic! */
506const char *ENGINE_get_id(const ENGINE *e);
507const char *ENGINE_get_name(const ENGINE *e);
508const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
509const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
510const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e);
511const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e);
512const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
513const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
514const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e);
515ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
516ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
517ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
518ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
519ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
520ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
521ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e);
522ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
523ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
524ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e);
525ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e);
526const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
527const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
528const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
529const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
530const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
531 const char *str, int len);
532const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
533 const char *str, int len);
534const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
535int ENGINE_get_flags(const ENGINE *e);
536
537/* FUNCTIONAL functions. These functions deal with ENGINE structures
538 * that have (or will) be initialised for use. Broadly speaking, the
539 * structural functions are useful for iterating the list of available
540 * engine types, creating new engine types, and other "list" operations.
541 * These functions actually deal with ENGINEs that are to be used. As
542 * such these functions can fail (if applicable) when particular
543 * engines are unavailable - eg. if a hardware accelerator is not
544 * attached or not functioning correctly. Each ENGINE has 2 reference
545 * counts; structural and functional. Every time a functional reference
546 * is obtained or released, a corresponding structural reference is
547 * automatically obtained or released too. */
548
549/* Initialise a engine type for use (or up its reference count if it's
550 * already in use). This will fail if the engine is not currently
551 * operational and cannot initialise. */
552int ENGINE_init(ENGINE *e);
553/* Free a functional reference to a engine type. This does not require
554 * a corresponding call to ENGINE_free as it also releases a structural
555 * reference. */
556int ENGINE_finish(ENGINE *e);
557
558/* The following functions handle keys that are stored in some secondary
559 * location, handled by the engine. The storage may be on a card or
560 * whatever. */
561EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
562 UI_METHOD *ui_method, void *callback_data);
563EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
564 UI_METHOD *ui_method, void *callback_data);
565int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
566 STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey,
567 STACK_OF(X509) **pother,
568 UI_METHOD *ui_method, void *callback_data);
569
570/* This returns a pointer for the current ENGINE structure that
571 * is (by default) performing any RSA operations. The value returned
572 * is an incremented reference, so it should be free'd (ENGINE_finish)
573 * before it is discarded. */
574ENGINE *ENGINE_get_default_RSA(void);
575/* Same for the other "methods" */
576ENGINE *ENGINE_get_default_DSA(void);
577ENGINE *ENGINE_get_default_ECDH(void);
578ENGINE *ENGINE_get_default_ECDSA(void);
579ENGINE *ENGINE_get_default_DH(void);
580ENGINE *ENGINE_get_default_RAND(void);
581/* These functions can be used to get a functional reference to perform
582 * ciphering or digesting corresponding to "nid". */
583ENGINE *ENGINE_get_cipher_engine(int nid);
584ENGINE *ENGINE_get_digest_engine(int nid);
585ENGINE *ENGINE_get_pkey_meth_engine(int nid);
586ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid);
587
588/* This sets a new default ENGINE structure for performing RSA
589 * operations. If the result is non-zero (success) then the ENGINE
590 * structure will have had its reference count up'd so the caller
591 * should still free their own reference 'e'. */
592int ENGINE_set_default_RSA(ENGINE *e);
593int ENGINE_set_default_string(ENGINE *e, const char *def_list);
594/* Same for the other "methods" */
595int ENGINE_set_default_DSA(ENGINE *e);
596int ENGINE_set_default_ECDH(ENGINE *e);
597int ENGINE_set_default_ECDSA(ENGINE *e);
598int ENGINE_set_default_DH(ENGINE *e);
599int ENGINE_set_default_RAND(ENGINE *e);
600int ENGINE_set_default_ciphers(ENGINE *e);
601int ENGINE_set_default_digests(ENGINE *e);
602int ENGINE_set_default_pkey_meths(ENGINE *e);
603int ENGINE_set_default_pkey_asn1_meths(ENGINE *e);
604
605/* The combination "set" - the flags are bitwise "OR"d from the
606 * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
607 * function, this function can result in unnecessary static linkage. If your
608 * application requires only specific functionality, consider using more
609 * selective functions. */
610int ENGINE_set_default(ENGINE *e, unsigned int flags);
611
612void ENGINE_add_conf_module(void);
613
614/* Deprecated functions ... */
615/* int ENGINE_clear_defaults(void); */
616
617/**************************/
618/* DYNAMIC ENGINE SUPPORT */
619/**************************/
620
621/* Binary/behaviour compatibility levels */
622#define OSSL_DYNAMIC_VERSION (unsigned long)0x00020000
623/* Binary versions older than this are too old for us (whether we're a loader or
624 * a loadee) */
625#define OSSL_DYNAMIC_OLDEST (unsigned long)0x00020000
626
627/* When compiling an ENGINE entirely as an external shared library, loadable by
628 * the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' structure
629 * type provides the calling application's (or library's) error functionality
630 * and memory management function pointers to the loaded library. These should
631 * be used/set in the loaded library code so that the loading application's
632 * 'state' will be used/changed in all operations. The 'static_state' pointer
633 * allows the loaded library to know if it shares the same static data as the
634 * calling application (or library), and thus whether these callbacks need to be
635 * set or not. */
636typedef void *(*dyn_MEM_malloc_cb)(size_t);
637typedef void *(*dyn_MEM_realloc_cb)(void *, size_t);
638typedef void (*dyn_MEM_free_cb)(void *);
639typedef struct st_dynamic_MEM_fns {
640 dyn_MEM_malloc_cb malloc_cb;
641 dyn_MEM_realloc_cb realloc_cb;
642 dyn_MEM_free_cb free_cb;
643 } dynamic_MEM_fns;
644/* FIXME: Perhaps the memory and locking code (crypto.h) should declare and use
645 * these types so we (and any other dependant code) can simplify a bit?? */
646typedef void (*dyn_lock_locking_cb)(int,int,const char *,int);
647typedef int (*dyn_lock_add_lock_cb)(int*,int,int,const char *,int);
648typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb)(
649 const char *,int);
650typedef void (*dyn_dynlock_lock_cb)(int,struct CRYPTO_dynlock_value *,
651 const char *,int);
652typedef void (*dyn_dynlock_destroy_cb)(struct CRYPTO_dynlock_value *,
653 const char *,int);
654typedef struct st_dynamic_LOCK_fns {
655 dyn_lock_locking_cb lock_locking_cb;
656 dyn_lock_add_lock_cb lock_add_lock_cb;
657 dyn_dynlock_create_cb dynlock_create_cb;
658 dyn_dynlock_lock_cb dynlock_lock_cb;
659 dyn_dynlock_destroy_cb dynlock_destroy_cb;
660 } dynamic_LOCK_fns;
661/* The top-level structure */
662typedef struct st_dynamic_fns {
663 void *static_state;
664 const ERR_FNS *err_fns;
665 const CRYPTO_EX_DATA_IMPL *ex_data_fns;
666 dynamic_MEM_fns mem_fns;
667 dynamic_LOCK_fns lock_fns;
668 } dynamic_fns;
669
670/* The version checking function should be of this prototype. NB: The
671 * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading code.
672 * If this function returns zero, it indicates a (potential) version
673 * incompatibility and the loaded library doesn't believe it can proceed.
674 * Otherwise, the returned value is the (latest) version supported by the
675 * loading library. The loader may still decide that the loaded code's version
676 * is unsatisfactory and could veto the load. The function is expected to
677 * be implemented with the symbol name "v_check", and a default implementation
678 * can be fully instantiated with IMPLEMENT_DYNAMIC_CHECK_FN(). */
679typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version);
680#define IMPLEMENT_DYNAMIC_CHECK_FN() \
681 OPENSSL_EXPORT unsigned long v_check(unsigned long v); \
682 OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \
683 if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \
684 return 0; }
685
686/* This function is passed the ENGINE structure to initialise with its own
687 * function and command settings. It should not adjust the structural or
688 * functional reference counts. If this function returns zero, (a) the load will
689 * be aborted, (b) the previous ENGINE state will be memcpy'd back onto the
690 * structure, and (c) the shared library will be unloaded. So implementations
691 * should do their own internal cleanup in failure circumstances otherwise they
692 * could leak. The 'id' parameter, if non-NULL, represents the ENGINE id that
693 * the loader is looking for. If this is NULL, the shared library can choose to
694 * return failure or to initialise a 'default' ENGINE. If non-NULL, the shared
695 * library must initialise only an ENGINE matching the passed 'id'. The function
696 * is expected to be implemented with the symbol name "bind_engine". A standard
697 * implementation can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where
698 * the parameter 'fn' is a callback function that populates the ENGINE structure
699 * and returns an int value (zero for failure). 'fn' should have prototype;
700 * [static] int fn(ENGINE *e, const char *id); */
701typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id,
702 const dynamic_fns *fns);
703#define IMPLEMENT_DYNAMIC_BIND_FN(fn) \
704 OPENSSL_EXPORT \
705 int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \
706 OPENSSL_EXPORT \
707 int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \
708 if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \
709 if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \
710 fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \
711 return 0; \
712 CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \
713 CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \
714 CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \
715 CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \
716 CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \
717 if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \
718 return 0; \
719 if(!ERR_set_implementation(fns->err_fns)) return 0; \
720 skip_cbs: \
721 if(!fn(e,id)) return 0; \
722 return 1; }
723
724/* If the loading application (or library) and the loaded ENGINE library share
725 * the same static data (eg. they're both dynamically linked to the same
726 * libcrypto.so) we need a way to avoid trying to set system callbacks - this
727 * would fail, and for the same reason that it's unnecessary to try. If the
728 * loaded ENGINE has (or gets from through the loader) its own copy of the
729 * libcrypto static data, we will need to set the callbacks. The easiest way to
730 * detect this is to have a function that returns a pointer to some static data
731 * and let the loading application and loaded ENGINE compare their respective
732 * values. */
733void *ENGINE_get_static_state(void);
734
735#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
736void ENGINE_setup_bsd_cryptodev(void);
737#endif
738
739/* BEGIN ERROR CODES */
740/* The following lines are auto generated by the script mkerr.pl. Any changes
741 * made after this point may be overwritten when the script is next run.
742 */
743void ERR_load_ENGINE_strings(void);
744
745/* Error codes for the ENGINE functions. */
746
747/* Function codes. */
748#define ENGINE_F_DYNAMIC_CTRL 180
749#define ENGINE_F_DYNAMIC_GET_DATA_CTX 181
750#define ENGINE_F_DYNAMIC_LOAD 182
751#define ENGINE_F_DYNAMIC_SET_DATA_CTX 183
752#define ENGINE_F_ENGINE_ADD 105
753#define ENGINE_F_ENGINE_BY_ID 106
754#define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170
755#define ENGINE_F_ENGINE_CTRL 142
756#define ENGINE_F_ENGINE_CTRL_CMD 178
757#define ENGINE_F_ENGINE_CTRL_CMD_STRING 171
758#define ENGINE_F_ENGINE_FINISH 107
759#define ENGINE_F_ENGINE_FREE_UTIL 108
760#define ENGINE_F_ENGINE_GET_CIPHER 185
761#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177
762#define ENGINE_F_ENGINE_GET_DIGEST 186
763#define ENGINE_F_ENGINE_GET_NEXT 115
764#define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193
765#define ENGINE_F_ENGINE_GET_PKEY_METH 192
766#define ENGINE_F_ENGINE_GET_PREV 116
767#define ENGINE_F_ENGINE_INIT 119
768#define ENGINE_F_ENGINE_LIST_ADD 120
769#define ENGINE_F_ENGINE_LIST_REMOVE 121
770#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150
771#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151
772#define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194
773#define ENGINE_F_ENGINE_NEW 122
774#define ENGINE_F_ENGINE_REMOVE 123
775#define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189
776#define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126
777#define ENGINE_F_ENGINE_SET_ID 129
778#define ENGINE_F_ENGINE_SET_NAME 130
779#define ENGINE_F_ENGINE_TABLE_REGISTER 184
780#define ENGINE_F_ENGINE_UNLOAD_KEY 152
781#define ENGINE_F_ENGINE_UNLOCKED_FINISH 191
782#define ENGINE_F_ENGINE_UP_REF 190
783#define ENGINE_F_INT_CTRL_HELPER 172
784#define ENGINE_F_INT_ENGINE_CONFIGURE 188
785#define ENGINE_F_INT_ENGINE_MODULE_INIT 187
786#define ENGINE_F_LOG_MESSAGE 141
787
788/* Reason codes. */
789#define ENGINE_R_ALREADY_LOADED 100
790#define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER 133
791#define ENGINE_R_CMD_NOT_EXECUTABLE 134
792#define ENGINE_R_COMMAND_TAKES_INPUT 135
793#define ENGINE_R_COMMAND_TAKES_NO_INPUT 136
794#define ENGINE_R_CONFLICTING_ENGINE_ID 103
795#define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119
796#define ENGINE_R_DH_NOT_IMPLEMENTED 139
797#define ENGINE_R_DSA_NOT_IMPLEMENTED 140
798#define ENGINE_R_DSO_FAILURE 104
799#define ENGINE_R_DSO_NOT_FOUND 132
800#define ENGINE_R_ENGINES_SECTION_ERROR 148
801#define ENGINE_R_ENGINE_CONFIGURATION_ERROR 102
802#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105
803#define ENGINE_R_ENGINE_SECTION_ERROR 149
804#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128
805#define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129
806#define ENGINE_R_FINISH_FAILED 106
807#define ENGINE_R_GET_HANDLE_FAILED 107
808#define ENGINE_R_ID_OR_NAME_MISSING 108
809#define ENGINE_R_INIT_FAILED 109
810#define ENGINE_R_INTERNAL_LIST_ERROR 110
811#define ENGINE_R_INVALID_ARGUMENT 143
812#define ENGINE_R_INVALID_CMD_NAME 137
813#define ENGINE_R_INVALID_CMD_NUMBER 138
814#define ENGINE_R_INVALID_INIT_VALUE 151
815#define ENGINE_R_INVALID_STRING 150
816#define ENGINE_R_NOT_INITIALISED 117
817#define ENGINE_R_NOT_LOADED 112
818#define ENGINE_R_NO_CONTROL_FUNCTION 120
819#define ENGINE_R_NO_INDEX 144
820#define ENGINE_R_NO_LOAD_FUNCTION 125
821#define ENGINE_R_NO_REFERENCE 130
822#define ENGINE_R_NO_SUCH_ENGINE 116
823#define ENGINE_R_NO_UNLOAD_FUNCTION 126
824#define ENGINE_R_PROVIDE_PARAMETERS 113
825#define ENGINE_R_RSA_NOT_IMPLEMENTED 141
826#define ENGINE_R_UNIMPLEMENTED_CIPHER 146
827#define ENGINE_R_UNIMPLEMENTED_DIGEST 147
828#define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101
829#define ENGINE_R_VERSION_INCOMPATIBILITY 145
830
831#ifdef __cplusplus
832}
833#endif
834#endif
diff --git a/src/lib/libcrypto/engine/enginetest.c b/src/lib/libcrypto/engine/enginetest.c
new file mode 100644
index 0000000000..f4d70e7e0a
--- /dev/null
+++ b/src/lib/libcrypto/engine/enginetest.c
@@ -0,0 +1,283 @@
1/* crypto/engine/enginetest.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 <stdio.h>
60#include <string.h>
61#include <openssl/e_os2.h>
62
63#ifdef OPENSSL_NO_ENGINE
64int main(int argc, char *argv[])
65{
66 printf("No ENGINE support\n");
67 return(0);
68}
69#else
70#include <openssl/buffer.h>
71#include <openssl/crypto.h>
72#include <openssl/engine.h>
73#include <openssl/err.h>
74
75static void display_engine_list(void)
76 {
77 ENGINE *h;
78 int loop;
79
80 h = ENGINE_get_first();
81 loop = 0;
82 printf("listing available engine types\n");
83 while(h)
84 {
85 printf("engine %i, id = \"%s\", name = \"%s\"\n",
86 loop++, ENGINE_get_id(h), ENGINE_get_name(h));
87 h = ENGINE_get_next(h);
88 }
89 printf("end of list\n");
90 /* ENGINE_get_first() increases the struct_ref counter, so we
91 must call ENGINE_free() to decrease it again */
92 ENGINE_free(h);
93 }
94
95int main(int argc, char *argv[])
96 {
97 ENGINE *block[512];
98 char buf[256];
99 const char *id, *name;
100 ENGINE *ptr;
101 int loop;
102 int to_return = 1;
103 ENGINE *new_h1 = NULL;
104 ENGINE *new_h2 = NULL;
105 ENGINE *new_h3 = NULL;
106 ENGINE *new_h4 = NULL;
107
108 /* enable memory leak checking unless explicitly disabled */
109 if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
110 {
111 CRYPTO_malloc_debug_init();
112 CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
113 }
114 else
115 {
116 /* OPENSSL_DEBUG_MEMORY=off */
117 CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
118 }
119 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
120 ERR_load_crypto_strings();
121
122 memset(block, 0, 512 * sizeof(ENGINE *));
123 if(((new_h1 = ENGINE_new()) == NULL) ||
124 !ENGINE_set_id(new_h1, "test_id0") ||
125 !ENGINE_set_name(new_h1, "First test item") ||
126 ((new_h2 = ENGINE_new()) == NULL) ||
127 !ENGINE_set_id(new_h2, "test_id1") ||
128 !ENGINE_set_name(new_h2, "Second test item") ||
129 ((new_h3 = ENGINE_new()) == NULL) ||
130 !ENGINE_set_id(new_h3, "test_id2") ||
131 !ENGINE_set_name(new_h3, "Third test item") ||
132 ((new_h4 = ENGINE_new()) == NULL) ||
133 !ENGINE_set_id(new_h4, "test_id3") ||
134 !ENGINE_set_name(new_h4, "Fourth test item"))
135 {
136 printf("Couldn't set up test ENGINE structures\n");
137 goto end;
138 }
139 printf("\nenginetest beginning\n\n");
140 display_engine_list();
141 if(!ENGINE_add(new_h1))
142 {
143 printf("Add failed!\n");
144 goto end;
145 }
146 display_engine_list();
147 ptr = ENGINE_get_first();
148 if(!ENGINE_remove(ptr))
149 {
150 printf("Remove failed!\n");
151 goto end;
152 }
153 if (ptr)
154 ENGINE_free(ptr);
155 display_engine_list();
156 if(!ENGINE_add(new_h3) || !ENGINE_add(new_h2))
157 {
158 printf("Add failed!\n");
159 goto end;
160 }
161 display_engine_list();
162 if(!ENGINE_remove(new_h2))
163 {
164 printf("Remove failed!\n");
165 goto end;
166 }
167 display_engine_list();
168 if(!ENGINE_add(new_h4))
169 {
170 printf("Add failed!\n");
171 goto end;
172 }
173 display_engine_list();
174 if(ENGINE_add(new_h3))
175 {
176 printf("Add *should* have failed but didn't!\n");
177 goto end;
178 }
179 else
180 printf("Add that should fail did.\n");
181 ERR_clear_error();
182 if(ENGINE_remove(new_h2))
183 {
184 printf("Remove *should* have failed but didn't!\n");
185 goto end;
186 }
187 else
188 printf("Remove that should fail did.\n");
189 ERR_clear_error();
190 if(!ENGINE_remove(new_h3))
191 {
192 printf("Remove failed!\n");
193 goto end;
194 }
195 display_engine_list();
196 if(!ENGINE_remove(new_h4))
197 {
198 printf("Remove failed!\n");
199 goto end;
200 }
201 display_engine_list();
202 /* Depending on whether there's any hardware support compiled
203 * in, this remove may be destined to fail. */
204 ptr = ENGINE_get_first();
205 if(ptr)
206 if(!ENGINE_remove(ptr))
207 printf("Remove failed!i - probably no hardware "
208 "support present.\n");
209 if (ptr)
210 ENGINE_free(ptr);
211 display_engine_list();
212 if(!ENGINE_add(new_h1) || !ENGINE_remove(new_h1))
213 {
214 printf("Couldn't add and remove to an empty list!\n");
215 goto end;
216 }
217 else
218 printf("Successfully added and removed to an empty list!\n");
219 printf("About to beef up the engine-type list\n");
220 for(loop = 0; loop < 512; loop++)
221 {
222 sprintf(buf, "id%i", loop);
223 id = BUF_strdup(buf);
224 sprintf(buf, "Fake engine type %i", loop);
225 name = BUF_strdup(buf);
226 if(((block[loop] = ENGINE_new()) == NULL) ||
227 !ENGINE_set_id(block[loop], id) ||
228 !ENGINE_set_name(block[loop], name))
229 {
230 printf("Couldn't create block of ENGINE structures.\n"
231 "I'll probably also core-dump now, damn.\n");
232 goto end;
233 }
234 }
235 for(loop = 0; loop < 512; loop++)
236 {
237 if(!ENGINE_add(block[loop]))
238 {
239 printf("\nAdding stopped at %i, (%s,%s)\n",
240 loop, ENGINE_get_id(block[loop]),
241 ENGINE_get_name(block[loop]));
242 goto cleanup_loop;
243 }
244 else
245 printf("."); fflush(stdout);
246 }
247cleanup_loop:
248 printf("\nAbout to empty the engine-type list\n");
249 while((ptr = ENGINE_get_first()) != NULL)
250 {
251 if(!ENGINE_remove(ptr))
252 {
253 printf("\nRemove failed!\n");
254 goto end;
255 }
256 ENGINE_free(ptr);
257 printf("."); fflush(stdout);
258 }
259 for(loop = 0; loop < 512; loop++)
260 {
261 OPENSSL_free((void *)ENGINE_get_id(block[loop]));
262 OPENSSL_free((void *)ENGINE_get_name(block[loop]));
263 }
264 printf("\nTests completed happily\n");
265 to_return = 0;
266end:
267 if(to_return)
268 ERR_print_errors_fp(stderr);
269 if(new_h1) ENGINE_free(new_h1);
270 if(new_h2) ENGINE_free(new_h2);
271 if(new_h3) ENGINE_free(new_h3);
272 if(new_h4) ENGINE_free(new_h4);
273 for(loop = 0; loop < 512; loop++)
274 if(block[loop])
275 ENGINE_free(block[loop]);
276 ENGINE_cleanup();
277 CRYPTO_cleanup_all_ex_data();
278 ERR_free_strings();
279 ERR_remove_thread_state(NULL);
280 CRYPTO_mem_leaks_fp(stderr);
281 return to_return;
282 }
283#endif
diff --git a/src/lib/libcrypto/engine/hw_cryptodev.c b/src/lib/libcrypto/engine/hw_cryptodev.c
new file mode 100644
index 0000000000..0e80ca051a
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_cryptodev.c
@@ -0,0 +1,1367 @@
1/*
2 * Copyright (c) 2002-2004 Theo de Raadt
3 * Copyright (c) 2002 Bob Beck <beck@openbsd.org>
4 * Copyright (c) 2002 Markus Friedl
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29#include <openssl/objects.h>
30#include <openssl/engine.h>
31#include <openssl/evp.h>
32
33#if (defined(__unix__) || defined(unix)) && !defined(USG)
34#include <sys/param.h>
35# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041)
36# define HAVE_CRYPTODEV
37# endif
38# if (OpenBSD >= 200110)
39# define HAVE_SYSLOG_R
40# endif
41#endif
42
43#ifndef HAVE_CRYPTODEV
44
45void
46ENGINE_load_cryptodev(void)
47{
48 /* This is a NOP on platforms without /dev/crypto */
49 return;
50}
51
52#else
53
54#include <sys/types.h>
55#include <crypto/cryptodev.h>
56#include <sys/ioctl.h>
57
58#include <errno.h>
59#include <fcntl.h>
60#include <limits.h>
61#include <stdarg.h>
62#include <stdio.h>
63#include <string.h>
64#include <syslog.h>
65#include <unistd.h>
66
67#if defined(__i386__) || defined(__amd64__)
68#include <sys/sysctl.h>
69#include <machine/cpu.h>
70#include <machine/specialreg.h>
71
72#include <ssl/aes.h>
73
74static int check_viac3aes(void);
75#endif
76
77#define CRYPTO_VIAC3_MAX 3
78
79struct dev_crypto_state {
80 struct session_op d_sess;
81 int d_fd;
82};
83
84struct dev_crypto_cipher {
85 int c_id;
86 int c_nid;
87 int c_ivmax;
88 int c_keylen;
89};
90
91static u_int32_t cryptodev_asymfeat = 0;
92
93static int get_asym_dev_crypto(void);
94static int open_dev_crypto(void);
95static int get_dev_crypto(void);
96static struct dev_crypto_cipher *cipher_nid_to_cryptodev(int nid);
97static int get_cryptodev_ciphers(const int **cnids);
98/*static int get_cryptodev_digests(const int **cnids);*/
99static int cryptodev_usable_ciphers(const int **nids);
100static int cryptodev_usable_digests(const int **nids);
101static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
102 const unsigned char *in, size_t inl);
103static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
104 const unsigned char *iv, int enc);
105static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx);
106static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
107 const int **nids, int nid);
108static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
109 const int **nids, int nid);
110static int bn2crparam(const BIGNUM *a, struct crparam *crp);
111static int crparam2bn(struct crparam *crp, BIGNUM *a);
112static void zapparams(struct crypt_kop *kop);
113static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r,
114 int slen, BIGNUM *s);
115
116static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
117 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
118static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I,
119 RSA *rsa, BN_CTX *ctx);
120static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
121 BN_CTX *ctx);
122static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
123 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
124static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
125 BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
126 BN_CTX *ctx, BN_MONT_CTX *mont);
127static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst,
128 int dlen, DSA *dsa);
129static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
130 DSA_SIG *sig, DSA *dsa);
131static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
132 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
133 BN_MONT_CTX *m_ctx);
134static int cryptodev_dh_compute_key(unsigned char *key,
135 const BIGNUM *pub_key, DH *dh);
136static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p,
137 void (*f)());
138void ENGINE_load_cryptodev(void);
139
140static const ENGINE_CMD_DEFN cryptodev_defns[] = {
141 { 0, NULL, NULL, 0 }
142};
143
144static struct dev_crypto_cipher ciphers[] = {
145 { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, },
146 { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, },
147 { CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, },
148 { CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24, },
149 { CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32, },
150 { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, },
151 { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, },
152 { 0, NID_undef, 0, 0, },
153};
154
155#if 0 /* UNUSED */
156static struct {
157 int id;
158 int nid;
159} digests[] = {
160 { CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, },
161 { CRYPTO_RIPEMD160_HMAC, NID_ripemd160, },
162 { CRYPTO_MD5_KPDK, NID_undef, },
163 { CRYPTO_SHA1_KPDK, NID_undef, },
164 { CRYPTO_MD5, NID_md5, },
165 { CRYPTO_SHA1, NID_undef, },
166 { 0, NID_undef, },
167};
168#endif
169
170/*
171 * Return a fd if /dev/crypto seems usable, -1 otherwise.
172 */
173static int
174open_dev_crypto(void)
175{
176 static int fd = -1;
177
178 if (fd == -1) {
179 if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1)
180 return (-1);
181 /* close on exec */
182 if (fcntl(fd, F_SETFD, 1) == -1) {
183 close(fd);
184 fd = -1;
185 return (-1);
186 }
187 }
188 return (fd);
189}
190
191static int
192get_dev_crypto(void)
193{
194 int fd, retfd;
195
196 if ((fd = open_dev_crypto()) == -1)
197 return (-1);
198 if (ioctl(fd, CRIOGET, &retfd) == -1) {
199 close(fd);
200 return (-1);
201 }
202
203 /* close on exec */
204 if (fcntl(retfd, F_SETFD, 1) == -1) {
205 close(retfd);
206 return (-1);
207 }
208 return (retfd);
209}
210
211/* Caching version for asym operations */
212static int
213get_asym_dev_crypto(void)
214{
215 static int fd = -1;
216
217 if (fd == -1)
218 fd = get_dev_crypto();
219 return fd;
220}
221
222/* convert libcrypto nids to cryptodev */
223static struct dev_crypto_cipher *
224cipher_nid_to_cryptodev(int nid)
225{
226 int i;
227
228 for (i = 0; ciphers[i].c_id; i++)
229 if (ciphers[i].c_nid == nid)
230 return (&ciphers[i]);
231 return (NULL);
232}
233
234/*
235 * Find out what ciphers /dev/crypto will let us have a session for.
236 * XXX note, that some of these openssl doesn't deal with yet!
237 * returning them here is harmless, as long as we return NULL
238 * when asked for a handler in the cryptodev_engine_ciphers routine
239 */
240static int
241get_cryptodev_ciphers(const int **cnids)
242{
243 static int nids[CRYPTO_ALGORITHM_MAX + CRYPTO_VIAC3_MAX + 1];
244 struct session_op sess;
245 int fd, i, count = 0;
246
247 if ((fd = get_dev_crypto()) < 0) {
248 *cnids = NULL;
249 return (0);
250 }
251 memset(&sess, 0, sizeof(sess));
252 sess.key = (caddr_t)"123456781234567812345678";
253
254 for (i = 0; ciphers[i].c_id && count <= CRYPTO_ALGORITHM_MAX; i++) {
255 if (ciphers[i].c_nid == NID_undef)
256 continue;
257 sess.cipher = ciphers[i].c_id;
258 sess.keylen = ciphers[i].c_keylen;
259 sess.mac = 0;
260 if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
261 ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
262 nids[count++] = ciphers[i].c_nid;
263 }
264 close(fd);
265
266#if defined(__i386__) || defined(__amd64__)
267 /*
268 * Always check for the VIA C3 AES instructions;
269 * even if /dev/crypto is disabled.
270 */
271 if (check_viac3aes() >= 1) {
272 int have_NID_aes_128_cbc = 0;
273 int have_NID_aes_192_cbc = 0;
274 int have_NID_aes_256_cbc = 0;
275
276 for (i = 0; i < count; i++) {
277 if (nids[i] == NID_aes_128_cbc)
278 have_NID_aes_128_cbc = 1;
279 if (nids[i] == NID_aes_192_cbc)
280 have_NID_aes_192_cbc = 1;
281 if (nids[i] == NID_aes_256_cbc)
282 have_NID_aes_256_cbc = 1;
283 }
284 if (!have_NID_aes_128_cbc)
285 nids[count++] = NID_aes_128_cbc;
286 if (!have_NID_aes_192_cbc)
287 nids[count++] = NID_aes_192_cbc;
288 if (!have_NID_aes_256_cbc)
289 nids[count++] = NID_aes_256_cbc;
290 }
291#endif
292
293 if (count > 0)
294 *cnids = nids;
295 else
296 *cnids = NULL;
297 return (count);
298}
299
300/*
301 * Find out what digests /dev/crypto will let us have a session for.
302 * XXX note, that some of these openssl doesn't deal with yet!
303 * returning them here is harmless, as long as we return NULL
304 * when asked for a handler in the cryptodev_engine_digests routine
305 */
306#if 0 /* UNUSED */
307static int
308get_cryptodev_digests(const int **cnids)
309{
310 static int nids[CRYPTO_ALGORITHM_MAX];
311 struct session_op sess;
312 int fd, i, count = 0;
313
314 if ((fd = get_dev_crypto()) < 0) {
315 *cnids = NULL;
316 return (0);
317 }
318 memset(&sess, 0, sizeof(sess));
319 for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
320 if (digests[i].nid == NID_undef)
321 continue;
322 sess.mac = digests[i].id;
323 sess.cipher = 0;
324 if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
325 ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
326 nids[count++] = digests[i].nid;
327 }
328 close(fd);
329
330 if (count > 0)
331 *cnids = nids;
332 else
333 *cnids = NULL;
334 return (count);
335}
336#endif
337
338/*
339 * Find the useable ciphers|digests from dev/crypto - this is the first
340 * thing called by the engine init crud which determines what it
341 * can use for ciphers from this engine. We want to return
342 * only what we can do, anythine else is handled by software.
343 *
344 * If we can't initialize the device to do anything useful for
345 * any reason, we want to return a NULL array, and 0 length,
346 * which forces everything to be done is software. By putting
347 * the initalization of the device in here, we ensure we can
348 * use this engine as the default, and if for whatever reason
349 * /dev/crypto won't do what we want it will just be done in
350 * software
351 *
352 * This can (should) be greatly expanded to perhaps take into
353 * account speed of the device, and what we want to do.
354 * (although the disabling of particular alg's could be controlled
355 * by the device driver with sysctl's.) - this is where we
356 * want most of the decisions made about what we actually want
357 * to use from /dev/crypto.
358 */
359static int
360cryptodev_usable_ciphers(const int **nids)
361{
362 return (get_cryptodev_ciphers(nids));
363}
364
365static int
366cryptodev_usable_digests(const int **nids)
367{
368 /*
369 * XXXX just disable all digests for now, because it sucks.
370 * we need a better way to decide this - i.e. I may not
371 * want digests on slow cards like hifn on fast machines,
372 * but might want them on slow or loaded machines, etc.
373 * will also want them when using crypto cards that don't
374 * suck moose gonads - would be nice to be able to decide something
375 * as reasonable default without having hackery that's card dependent.
376 * of course, the default should probably be just do everything,
377 * with perhaps a sysctl to turn algoritms off (or have them off
378 * by default) on cards that generally suck like the hifn.
379 */
380 *nids = NULL;
381 return (0);
382}
383
384static int
385cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
386 const unsigned char *in, size_t inl)
387{
388 struct crypt_op cryp;
389 struct dev_crypto_state *state = ctx->cipher_data;
390 struct session_op *sess = &state->d_sess;
391 void *iiv;
392 unsigned char save_iv[EVP_MAX_IV_LENGTH];
393
394 if (state->d_fd < 0)
395 return (0);
396 if (!inl)
397 return (1);
398 if ((inl % ctx->cipher->block_size) != 0)
399 return (0);
400
401 memset(&cryp, 0, sizeof(cryp));
402
403 cryp.ses = sess->ses;
404 cryp.flags = 0;
405 cryp.len = inl;
406 cryp.src = (caddr_t) in;
407 cryp.dst = (caddr_t) out;
408 cryp.mac = 0;
409
410 cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
411
412 if (ctx->cipher->iv_len) {
413 cryp.iv = (caddr_t) ctx->iv;
414 if (!ctx->encrypt) {
415 iiv = (void *) in + inl - ctx->cipher->iv_len;
416 memcpy(save_iv, iiv, ctx->cipher->iv_len);
417 }
418 } else
419 cryp.iv = NULL;
420
421 if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) {
422 /* XXX need better errror handling
423 * this can fail for a number of different reasons.
424 */
425 return (0);
426 }
427
428 if (ctx->cipher->iv_len) {
429 if (ctx->encrypt)
430 iiv = (void *) out + inl - ctx->cipher->iv_len;
431 else
432 iiv = save_iv;
433 memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
434 }
435 return (1);
436}
437
438static int
439cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
440 const unsigned char *iv, int enc)
441{
442 struct dev_crypto_state *state = ctx->cipher_data;
443 struct session_op *sess = &state->d_sess;
444 struct dev_crypto_cipher *cipher;
445
446 if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NULL)
447 return (0);
448
449 if (ctx->cipher->iv_len > cipher->c_ivmax)
450 return (0);
451
452 if (ctx->key_len != cipher->c_keylen)
453 return (0);
454
455 memset(sess, 0, sizeof(struct session_op));
456
457 if ((state->d_fd = get_dev_crypto()) < 0)
458 return (0);
459
460 sess->key = (unsigned char *)key;
461 sess->keylen = ctx->key_len;
462 sess->cipher = cipher->c_id;
463
464 if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
465 close(state->d_fd);
466 state->d_fd = -1;
467 return (0);
468 }
469 return (1);
470}
471
472/*
473 * free anything we allocated earlier when initting a
474 * session, and close the session.
475 */
476static int
477cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
478{
479 int ret = 0;
480 struct dev_crypto_state *state = ctx->cipher_data;
481 struct session_op *sess = &state->d_sess;
482
483 if (state->d_fd < 0)
484 return (0);
485
486 /* XXX if this ioctl fails, someting's wrong. the invoker
487 * may have called us with a bogus ctx, or we could
488 * have a device that for whatever reason just doesn't
489 * want to play ball - it's not clear what's right
490 * here - should this be an error? should it just
491 * increase a counter, hmm. For right now, we return
492 * 0 - I don't believe that to be "right". we could
493 * call the gorpy openssl lib error handlers that
494 * print messages to users of the library. hmm..
495 */
496
497 if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) {
498 ret = 0;
499 } else {
500 ret = 1;
501 }
502 close(state->d_fd);
503 state->d_fd = -1;
504
505 return (ret);
506}
507
508/*
509 * libcrypto EVP stuff - this is how we get wired to EVP so the engine
510 * gets called when libcrypto requests a cipher NID.
511 */
512
513/* DES CBC EVP */
514const EVP_CIPHER cryptodev_des_cbc = {
515 NID_des_cbc,
516 8, 8, 8,
517 EVP_CIPH_CBC_MODE,
518 cryptodev_init_key,
519 cryptodev_cipher,
520 cryptodev_cleanup,
521 sizeof(struct dev_crypto_state),
522 EVP_CIPHER_set_asn1_iv,
523 EVP_CIPHER_get_asn1_iv,
524 NULL
525};
526
527/* 3DES CBC EVP */
528const EVP_CIPHER cryptodev_3des_cbc = {
529 NID_des_ede3_cbc,
530 8, 24, 8,
531 EVP_CIPH_CBC_MODE,
532 cryptodev_init_key,
533 cryptodev_cipher,
534 cryptodev_cleanup,
535 sizeof(struct dev_crypto_state),
536 EVP_CIPHER_set_asn1_iv,
537 EVP_CIPHER_get_asn1_iv,
538 NULL
539};
540
541const EVP_CIPHER cryptodev_bf_cbc = {
542 NID_bf_cbc,
543 8, 16, 8,
544 EVP_CIPH_CBC_MODE,
545 cryptodev_init_key,
546 cryptodev_cipher,
547 cryptodev_cleanup,
548 sizeof(struct dev_crypto_state),
549 EVP_CIPHER_set_asn1_iv,
550 EVP_CIPHER_get_asn1_iv,
551 NULL
552};
553
554const EVP_CIPHER cryptodev_cast_cbc = {
555 NID_cast5_cbc,
556 8, 16, 8,
557 EVP_CIPH_CBC_MODE,
558 cryptodev_init_key,
559 cryptodev_cipher,
560 cryptodev_cleanup,
561 sizeof(struct dev_crypto_state),
562 EVP_CIPHER_set_asn1_iv,
563 EVP_CIPHER_get_asn1_iv,
564 NULL
565};
566
567EVP_CIPHER cryptodev_aes_128_cbc = {
568 NID_aes_128_cbc,
569 16, 16, 16,
570 EVP_CIPH_CBC_MODE,
571 cryptodev_init_key,
572 cryptodev_cipher,
573 cryptodev_cleanup,
574 sizeof(struct dev_crypto_state),
575 EVP_CIPHER_set_asn1_iv,
576 EVP_CIPHER_get_asn1_iv,
577 NULL
578};
579
580EVP_CIPHER cryptodev_aes_192_cbc = {
581 NID_aes_192_cbc,
582 16, 24, 16,
583 EVP_CIPH_CBC_MODE,
584 cryptodev_init_key,
585 cryptodev_cipher,
586 cryptodev_cleanup,
587 sizeof(struct dev_crypto_state),
588 EVP_CIPHER_set_asn1_iv,
589 EVP_CIPHER_get_asn1_iv,
590 NULL
591};
592
593EVP_CIPHER cryptodev_aes_256_cbc = {
594 NID_aes_256_cbc,
595 16, 32, 16,
596 EVP_CIPH_CBC_MODE,
597 cryptodev_init_key,
598 cryptodev_cipher,
599 cryptodev_cleanup,
600 sizeof(struct dev_crypto_state),
601 EVP_CIPHER_set_asn1_iv,
602 EVP_CIPHER_get_asn1_iv,
603 NULL
604};
605
606#if defined(__i386__) || defined(__amd64__)
607
608static inline void
609viac3_xcrypt_cbc(int *cw, const void *src, void *dst, void *key, int rep,
610 void *iv)
611{
612#ifdef notdef
613 printf("cw %p[%x %x %x %x] src %p dst %p key %p rep %x iv %p\n",
614 cw, cw[0], cw[1], cw[2], cw[3],
615 src, dst, key, rep, iv);
616#endif
617#if defined(__i386__)
618
619 /*
620 * Clear bit 30 of EFLAGS.
621 */
622 __asm __volatile("pushfl; popfl");
623
624 /*
625 * Cannot simply place key into "b" register, since the compiler
626 * -pic mode uses that register; so instead we must dance a little.
627 */
628 __asm __volatile("pushl %%ebx; movl %0, %%ebx; rep xcrypt-cbc; popl %%ebx" :
629 : "m" (key), "a" (iv), "c" (rep), "d" (cw), "S" (src), "D" (dst)
630 : "memory", "cc");
631#else
632
633 /*
634 * Clear bit 30 of EFLAGS.
635 */
636 __asm __volatile("pushfq; popfq");
637 __asm __volatile("rep xcrypt-cbc" :
638 : "b" (key), "a" (iv), "c" (rep), "d" (cw), "S" (src), "D" (dst)
639 : "memory", "cc");
640#endif
641
642}
643
644#define ISUNALIGNED(x) ((long)(x)) & 15
645#define DOALIGN(v) ((void *)(((long)(v) + 15) & ~15))
646
647static int
648xcrypt_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
649 const unsigned char *in, size_t inl)
650{
651 unsigned char *save_iv_store[EVP_MAX_IV_LENGTH + 15];
652 unsigned char *save_iv = DOALIGN(save_iv_store);
653 unsigned char *ivs_store[EVP_MAX_IV_LENGTH + 15];
654 unsigned char *ivs = DOALIGN(ivs_store);
655 void *iiv, *iv = NULL, *ivp = NULL;
656 const void *usein = in;
657 void *useout = out, *spare;
658 int cws[4 + 3], *cw = DOALIGN(cws);
659
660 if (!inl)
661 return (1);
662 if ((inl % ctx->cipher->block_size) != 0)
663 return (0);
664 if (inl > UINT_MAX)
665 return (0);
666
667 if (ISUNALIGNED(in) || ISUNALIGNED(out)) {
668 spare = malloc(inl);
669 if (spare == NULL)
670 return (0);
671
672 if (ISUNALIGNED(in)) {
673 bcopy(in, spare, inl);
674 usein = spare;
675 }
676 if (ISUNALIGNED(out))
677 useout = spare;
678 }
679
680 cw[0] = C3_CRYPT_CWLO_ALG_AES | C3_CRYPT_CWLO_KEYGEN_SW |
681 C3_CRYPT_CWLO_NORMAL;
682 cw[0] |= ctx->encrypt ? C3_CRYPT_CWLO_ENCRYPT : C3_CRYPT_CWLO_DECRYPT;
683 cw[1] = cw[2] = cw[3] = 0;
684
685 switch (ctx->key_len * 8) {
686 case 128:
687 cw[0] |= C3_CRYPT_CWLO_KEY128;
688 break;
689 case 192:
690 cw[0] |= C3_CRYPT_CWLO_KEY192;
691 break;
692 case 256:
693 cw[0] |= C3_CRYPT_CWLO_KEY256;
694 break;
695 }
696
697 if (ctx->cipher->iv_len) {
698 iv = (caddr_t) ctx->iv;
699 if (!ctx->encrypt) {
700 iiv = (void *) in + inl - ctx->cipher->iv_len;
701 memcpy(save_iv, iiv, ctx->cipher->iv_len);
702 }
703 }
704
705 ivp = iv;
706 if (ISUNALIGNED(iv)) {
707 bcopy(iv, ivs, ctx->cipher->iv_len);
708 ivp = ivs;
709 }
710
711 viac3_xcrypt_cbc(cw, usein, useout, ctx->cipher_data, inl / 16, ivp);
712
713 if (ISUNALIGNED(in) || ISUNALIGNED(out)) {
714 if (ISUNALIGNED(out))
715 bcopy(spare, out, inl);
716 free(spare);
717 }
718
719 if (ivp == ivs)
720 bcopy(ivp, iv, ctx->cipher->iv_len);
721
722 if (ctx->cipher->iv_len) {
723 if (ctx->encrypt)
724 iiv = (void *) out + inl - ctx->cipher->iv_len;
725 else
726 iiv = save_iv;
727 memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
728 }
729 return (1);
730}
731
732static int
733xcrypt_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
734 const unsigned char *iv, int enc)
735{
736 AES_KEY *k = ctx->cipher_data;
737#ifndef AES_ASM
738 int i;
739#endif
740
741 bzero(k, sizeof *k);
742 if (enc)
743 AES_set_encrypt_key(key, ctx->key_len * 8, k);
744 else
745 AES_set_decrypt_key(key, ctx->key_len * 8, k);
746
747#ifndef AES_ASM
748 /*
749 * XXX Damn OpenSSL byte swaps the expanded key!!
750 *
751 * XXX But only if we're using the C implementation of AES
752 */
753 for (i = 0; i < 4 * (AES_MAXNR + 1); i++)
754 k->rd_key[i] = htonl(k->rd_key[i]);
755#endif
756
757 return (1);
758}
759
760static int
761xcrypt_cleanup(EVP_CIPHER_CTX *ctx)
762{
763 bzero(ctx->cipher_data, ctx->cipher->ctx_size);
764 return (1);
765}
766
767static int
768check_viac3aes(void)
769{
770 int mib[2] = { CTL_MACHDEP, CPU_XCRYPT }, value;
771 size_t size = sizeof(value);
772
773 if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &value, &size,
774 NULL, 0) < 0)
775 return (0);
776 if (value == 0)
777 return (0);
778
779 if (value & C3_HAS_AES) {
780 cryptodev_aes_128_cbc.init = xcrypt_init_key;
781 cryptodev_aes_128_cbc.do_cipher = xcrypt_cipher;
782 cryptodev_aes_128_cbc.cleanup = xcrypt_cleanup;
783 cryptodev_aes_128_cbc.ctx_size = sizeof(AES_KEY);
784
785 cryptodev_aes_192_cbc.init = xcrypt_init_key;
786 cryptodev_aes_192_cbc.do_cipher = xcrypt_cipher;
787 cryptodev_aes_192_cbc.cleanup = xcrypt_cleanup;
788 cryptodev_aes_192_cbc.ctx_size = sizeof(AES_KEY);
789
790 cryptodev_aes_256_cbc.init = xcrypt_init_key;
791 cryptodev_aes_256_cbc.do_cipher = xcrypt_cipher;
792 cryptodev_aes_256_cbc.cleanup = xcrypt_cleanup;
793 cryptodev_aes_256_cbc.ctx_size = sizeof(AES_KEY);
794 }
795 return (value);
796}
797#endif /* __i386__ || __amd64__ */
798
799/*
800 * Registered by the ENGINE when used to find out how to deal with
801 * a particular NID in the ENGINE. this says what we'll do at the
802 * top level - note, that list is restricted by what we answer with
803 */
804static int
805cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
806 const int **nids, int nid)
807{
808 if (!cipher)
809 return (cryptodev_usable_ciphers(nids));
810
811 switch (nid) {
812 case NID_des_ede3_cbc:
813 *cipher = &cryptodev_3des_cbc;
814 break;
815 case NID_des_cbc:
816 *cipher = &cryptodev_des_cbc;
817 break;
818 case NID_bf_cbc:
819 *cipher = &cryptodev_bf_cbc;
820 break;
821 case NID_cast5_cbc:
822 *cipher = &cryptodev_cast_cbc;
823 break;
824 case NID_aes_128_cbc:
825 *cipher = &cryptodev_aes_128_cbc;
826 break;
827 case NID_aes_192_cbc:
828 *cipher = &cryptodev_aes_192_cbc;
829 break;
830 case NID_aes_256_cbc:
831 *cipher = &cryptodev_aes_256_cbc;
832 break;
833 default:
834 *cipher = NULL;
835 break;
836 }
837 return (*cipher != NULL);
838}
839
840static int
841cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
842 const int **nids, int nid)
843{
844 if (!digest)
845 return (cryptodev_usable_digests(nids));
846
847 switch (nid) {
848 case NID_md5:
849 *digest = NULL; /* need to make a clean md5 critter */
850 break;
851 default:
852 *digest = NULL;
853 break;
854 }
855 return (*digest != NULL);
856}
857
858/*
859 * Convert a BIGNUM to the representation that /dev/crypto needs.
860 * Upon completion of use, the caller is responsible for freeing
861 * crp->crp_p.
862 */
863static int
864bn2crparam(const BIGNUM *a, struct crparam *crp)
865{
866 int i, j, k;
867 ssize_t bytes, bits;
868 u_char *b;
869
870 crp->crp_p = NULL;
871 crp->crp_nbits = 0;
872
873 bits = BN_num_bits(a);
874 bytes = (bits + 7) / 8;
875
876 b = malloc(bytes);
877 if (b == NULL)
878 return (1);
879
880 crp->crp_p = b;
881 crp->crp_nbits = bits;
882
883 for (i = 0, j = 0; i < a->top; i++) {
884 for (k = 0; k < BN_BITS2 / 8; k++) {
885 if ((j + k) >= bytes)
886 return (0);
887 b[j + k] = a->d[i] >> (k * 8);
888 }
889 j += BN_BITS2 / 8;
890 }
891 return (0);
892}
893
894/* Convert a /dev/crypto parameter to a BIGNUM */
895static int
896crparam2bn(struct crparam *crp, BIGNUM *a)
897{
898 u_int8_t *pd;
899 int i, bytes;
900
901 bytes = (crp->crp_nbits + 7) / 8;
902
903 if (bytes == 0)
904 return (-1);
905
906 if ((pd = (u_int8_t *) malloc(bytes)) == NULL)
907 return (-1);
908
909 for (i = 0; i < bytes; i++)
910 pd[i] = crp->crp_p[bytes - i - 1];
911
912 BN_bin2bn(pd, bytes, a);
913 free(pd);
914
915 return (0);
916}
917
918static void
919zapparams(struct crypt_kop *kop)
920{
921 int i;
922
923 for (i = 0; i <= kop->crk_iparams + kop->crk_oparams; i++) {
924 if (kop->crk_param[i].crp_p)
925 free(kop->crk_param[i].crp_p);
926 kop->crk_param[i].crp_p = NULL;
927 kop->crk_param[i].crp_nbits = 0;
928 }
929}
930
931static int
932cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s)
933{
934 int fd, ret = -1;
935
936 if ((fd = get_asym_dev_crypto()) < 0)
937 return (ret);
938
939 if (r) {
940 kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char));
941 kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8;
942 kop->crk_oparams++;
943 }
944 if (s) {
945 kop->crk_param[kop->crk_iparams+1].crp_p = calloc(slen, sizeof(char));
946 kop->crk_param[kop->crk_iparams+1].crp_nbits = slen * 8;
947 kop->crk_oparams++;
948 }
949
950 if (ioctl(fd, CIOCKEY, kop) == 0) {
951 if (r)
952 crparam2bn(&kop->crk_param[kop->crk_iparams], r);
953 if (s)
954 crparam2bn(&kop->crk_param[kop->crk_iparams+1], s);
955 ret = 0;
956 }
957
958 return (ret);
959}
960
961static int
962cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
963 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
964{
965 struct crypt_kop kop;
966 int ret = 1;
967
968 /* Currently, we know we can do mod exp iff we can do any
969 * asymmetric operations at all.
970 */
971 if (cryptodev_asymfeat == 0) {
972 ret = BN_mod_exp(r, a, p, m, ctx);
973 return (ret);
974 }
975
976 memset(&kop, 0, sizeof kop);
977 kop.crk_op = CRK_MOD_EXP;
978
979 /* inputs: a^p % m */
980 if (bn2crparam(a, &kop.crk_param[0]))
981 goto err;
982 if (bn2crparam(p, &kop.crk_param[1]))
983 goto err;
984 if (bn2crparam(m, &kop.crk_param[2]))
985 goto err;
986 kop.crk_iparams = 3;
987
988 if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL) == -1) {
989 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
990 ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
991 }
992err:
993 zapparams(&kop);
994 return (ret);
995}
996
997static int
998cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
999 BN_CTX *ctx)
1000{
1001 return (RSA_PKCS1_SSLeay()->rsa_mod_exp)(r0, I, rsa, ctx);
1002}
1003
1004static int
1005cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
1006{
1007 struct crypt_kop kop;
1008 int ret = 1;
1009
1010 if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
1011 /* XXX 0 means failure?? */
1012 return (0);
1013 }
1014
1015 memset(&kop, 0, sizeof kop);
1016 kop.crk_op = CRK_MOD_EXP_CRT;
1017 /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
1018 if (bn2crparam(rsa->p, &kop.crk_param[0]))
1019 goto err;
1020 if (bn2crparam(rsa->q, &kop.crk_param[1]))
1021 goto err;
1022 if (bn2crparam(I, &kop.crk_param[2]))
1023 goto err;
1024 if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
1025 goto err;
1026 if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
1027 goto err;
1028 if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
1029 goto err;
1030 kop.crk_iparams = 6;
1031
1032 if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL) == -1) {
1033 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
1034 ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
1035 }
1036err:
1037 zapparams(&kop);
1038 return (ret);
1039}
1040
1041static RSA_METHOD cryptodev_rsa = {
1042 "cryptodev RSA method",
1043 NULL, /* rsa_pub_enc */
1044 NULL, /* rsa_pub_dec */
1045 NULL, /* rsa_priv_enc */
1046 NULL, /* rsa_priv_dec */
1047 NULL,
1048 NULL,
1049 NULL, /* init */
1050 NULL, /* finish */
1051 0, /* flags */
1052 NULL, /* app_data */
1053 NULL, /* rsa_sign */
1054 NULL /* rsa_verify */
1055};
1056
1057static int
1058cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
1059 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
1060{
1061 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
1062}
1063
1064static int
1065cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
1066 BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
1067 BN_CTX *ctx, BN_MONT_CTX *mont)
1068{
1069 BIGNUM t2;
1070 int ret = 0;
1071
1072 BN_init(&t2);
1073
1074 /* v = ( g^u1 * y^u2 mod p ) mod q */
1075 /* let t1 = g ^ u1 mod p */
1076 ret = 0;
1077
1078 if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont))
1079 goto err;
1080
1081 /* let t2 = y ^ u2 mod p */
1082 if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont))
1083 goto err;
1084 /* let u1 = t1 * t2 mod p */
1085 if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx))
1086 goto err;
1087
1088 BN_copy(t1,u1);
1089
1090 ret = 1;
1091err:
1092 BN_free(&t2);
1093 return(ret);
1094}
1095
1096static DSA_SIG *
1097cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
1098{
1099 struct crypt_kop kop;
1100 BIGNUM *r = NULL, *s = NULL;
1101 DSA_SIG *dsaret = NULL;
1102
1103 if ((r = BN_new()) == NULL)
1104 goto err;
1105 if ((s = BN_new()) == NULL) {
1106 BN_free(r);
1107 goto err;
1108 }
1109
1110 memset(&kop, 0, sizeof kop);
1111 kop.crk_op = CRK_DSA_SIGN;
1112
1113 /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
1114 kop.crk_param[0].crp_p = (caddr_t)dgst;
1115 kop.crk_param[0].crp_nbits = dlen * 8;
1116 if (bn2crparam(dsa->p, &kop.crk_param[1]))
1117 goto err;
1118 if (bn2crparam(dsa->q, &kop.crk_param[2]))
1119 goto err;
1120 if (bn2crparam(dsa->g, &kop.crk_param[3]))
1121 goto err;
1122 if (bn2crparam(dsa->priv_key, &kop.crk_param[4]))
1123 goto err;
1124 kop.crk_iparams = 5;
1125
1126 if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r,
1127 BN_num_bytes(dsa->q), s) == 0) {
1128 dsaret = DSA_SIG_new();
1129 dsaret->r = r;
1130 dsaret->s = s;
1131 } else {
1132 const DSA_METHOD *meth = DSA_OpenSSL();
1133 BN_free(r);
1134 BN_free(s);
1135 dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
1136 }
1137err:
1138 kop.crk_param[0].crp_p = NULL;
1139 zapparams(&kop);
1140 return (dsaret);
1141}
1142
1143static int
1144cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
1145 DSA_SIG *sig, DSA *dsa)
1146{
1147 struct crypt_kop kop;
1148 int dsaret = 1;
1149
1150 memset(&kop, 0, sizeof kop);
1151 kop.crk_op = CRK_DSA_VERIFY;
1152
1153 /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
1154 kop.crk_param[0].crp_p = (caddr_t)dgst;
1155 kop.crk_param[0].crp_nbits = dlen * 8;
1156 if (bn2crparam(dsa->p, &kop.crk_param[1]))
1157 goto err;
1158 if (bn2crparam(dsa->q, &kop.crk_param[2]))
1159 goto err;
1160 if (bn2crparam(dsa->g, &kop.crk_param[3]))
1161 goto err;
1162 if (bn2crparam(dsa->pub_key, &kop.crk_param[4]))
1163 goto err;
1164 if (bn2crparam(sig->r, &kop.crk_param[5]))
1165 goto err;
1166 if (bn2crparam(sig->s, &kop.crk_param[6]))
1167 goto err;
1168 kop.crk_iparams = 7;
1169
1170 if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
1171 dsaret = kop.crk_status;
1172 } else {
1173 const DSA_METHOD *meth = DSA_OpenSSL();
1174
1175 dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
1176 }
1177err:
1178 kop.crk_param[0].crp_p = NULL;
1179 zapparams(&kop);
1180 return (dsaret);
1181}
1182
1183static DSA_METHOD cryptodev_dsa = {
1184 "cryptodev DSA method",
1185 NULL,
1186 NULL, /* dsa_sign_setup */
1187 NULL,
1188 NULL, /* dsa_mod_exp */
1189 NULL,
1190 NULL, /* init */
1191 NULL, /* finish */
1192 0, /* flags */
1193 NULL /* app_data */
1194};
1195
1196static int
1197cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
1198 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
1199 BN_MONT_CTX *m_ctx)
1200{
1201 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
1202}
1203
1204static int
1205cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
1206{
1207 struct crypt_kop kop;
1208 int dhret = 1;
1209 int fd, keylen;
1210
1211 if ((fd = get_asym_dev_crypto()) < 0) {
1212 const DH_METHOD *meth = DH_OpenSSL();
1213
1214 return ((meth->compute_key)(key, pub_key, dh));
1215 }
1216
1217 keylen = BN_num_bits(dh->p);
1218
1219 memset(&kop, 0, sizeof kop);
1220 kop.crk_op = CRK_DH_COMPUTE_KEY;
1221
1222 /* inputs: dh->priv_key pub_key dh->p key */
1223 if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
1224 goto err;
1225 if (bn2crparam(pub_key, &kop.crk_param[1]))
1226 goto err;
1227 if (bn2crparam(dh->p, &kop.crk_param[2]))
1228 goto err;
1229 kop.crk_iparams = 3;
1230
1231 kop.crk_param[3].crp_p = key;
1232 kop.crk_param[3].crp_nbits = keylen * 8;
1233 kop.crk_oparams = 1;
1234
1235 if (ioctl(fd, CIOCKEY, &kop) == -1) {
1236 const DH_METHOD *meth = DH_OpenSSL();
1237
1238 dhret = (meth->compute_key)(key, pub_key, dh);
1239 }
1240err:
1241 kop.crk_param[3].crp_p = NULL;
1242 zapparams(&kop);
1243 return (dhret);
1244}
1245
1246static DH_METHOD cryptodev_dh = {
1247 "cryptodev DH method",
1248 NULL, /* cryptodev_dh_generate_key */
1249 NULL,
1250 NULL,
1251 NULL,
1252 NULL,
1253 0, /* flags */
1254 NULL /* app_data */
1255};
1256
1257/*
1258 * ctrl right now is just a wrapper that doesn't do much
1259 * but I expect we'll want some options soon.
1260 */
1261static int
1262cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
1263{
1264#ifdef HAVE_SYSLOG_R
1265 struct syslog_data sd = SYSLOG_DATA_INIT;
1266#endif
1267
1268 switch (cmd) {
1269 default:
1270#ifdef HAVE_SYSLOG_R
1271 syslog_r(LOG_ERR, &sd,
1272 "cryptodev_ctrl: unknown command %d", cmd);
1273#else
1274 syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd);
1275#endif
1276 break;
1277 }
1278 return (1);
1279}
1280
1281void
1282ENGINE_load_cryptodev(void)
1283{
1284 ENGINE *engine = ENGINE_new();
1285 int fd;
1286
1287 if (engine == NULL)
1288 return;
1289 if ((fd = get_dev_crypto()) < 0) {
1290 ENGINE_free(engine);
1291 return;
1292 }
1293
1294 /*
1295 * find out what asymmetric crypto algorithms we support
1296 */
1297 if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
1298 close(fd);
1299 ENGINE_free(engine);
1300 return;
1301 }
1302 close(fd);
1303
1304 if (!ENGINE_set_id(engine, "cryptodev") ||
1305 !ENGINE_set_name(engine, "BSD cryptodev engine") ||
1306 !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) ||
1307 !ENGINE_set_digests(engine, cryptodev_engine_digests) ||
1308 !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) ||
1309 !ENGINE_set_cmd_defns(engine, cryptodev_defns)) {
1310 ENGINE_free(engine);
1311 return;
1312 }
1313
1314 if (ENGINE_set_RSA(engine, &cryptodev_rsa)) {
1315 const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay();
1316
1317 cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp;
1318 cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp;
1319 cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc;
1320 cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec;
1321 cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc;
1322 cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec;
1323 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1324 cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp;
1325 if (cryptodev_asymfeat & CRF_MOD_EXP_CRT)
1326 cryptodev_rsa.rsa_mod_exp =
1327 cryptodev_rsa_mod_exp;
1328 else
1329 cryptodev_rsa.rsa_mod_exp =
1330 cryptodev_rsa_nocrt_mod_exp;
1331 }
1332 }
1333
1334 if (ENGINE_set_DSA(engine, &cryptodev_dsa)) {
1335 const DSA_METHOD *meth = DSA_OpenSSL();
1336
1337 memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
1338 if (cryptodev_asymfeat & CRF_DSA_SIGN)
1339 cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
1340 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1341 cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp;
1342 cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp;
1343 }
1344 if (cryptodev_asymfeat & CRF_DSA_VERIFY)
1345 cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
1346 }
1347
1348 if (ENGINE_set_DH(engine, &cryptodev_dh)){
1349 const DH_METHOD *dh_meth = DH_OpenSSL();
1350
1351 cryptodev_dh.generate_key = dh_meth->generate_key;
1352 cryptodev_dh.compute_key = dh_meth->compute_key;
1353 cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp;
1354 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1355 cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh;
1356 if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
1357 cryptodev_dh.compute_key =
1358 cryptodev_dh_compute_key;
1359 }
1360 }
1361
1362 ENGINE_add(engine);
1363 ENGINE_free(engine);
1364 ERR_clear_error();
1365}
1366
1367#endif /* HAVE_CRYPTODEV */
diff --git a/src/lib/libcrypto/engine/hw_openbsd_dev_crypto.c b/src/lib/libcrypto/engine/hw_openbsd_dev_crypto.c
deleted file mode 100644
index b8aab545db..0000000000
--- a/src/lib/libcrypto/engine/hw_openbsd_dev_crypto.c
+++ /dev/null
@@ -1,594 +0,0 @@
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/tb_asnmth.c b/src/lib/libcrypto/engine/tb_asnmth.c
new file mode 100644
index 0000000000..75090339f7
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_asnmth.c
@@ -0,0 +1,246 @@
1/* ====================================================================
2 * Copyright (c) 2006 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 "eng_int.h"
56#include "asn1_locl.h"
57#include <openssl/evp.h>
58
59/* If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the
60 * function that is used by EVP to hook in pkey_asn1_meth code and cache
61 * defaults (etc), will display brief debugging summaries to stderr with the
62 * 'nid'. */
63/* #define ENGINE_PKEY_ASN1_METH_DEBUG */
64
65static ENGINE_TABLE *pkey_asn1_meth_table = NULL;
66
67void ENGINE_unregister_pkey_asn1_meths(ENGINE *e)
68 {
69 engine_table_unregister(&pkey_asn1_meth_table, e);
70 }
71
72static void engine_unregister_all_pkey_asn1_meths(void)
73 {
74 engine_table_cleanup(&pkey_asn1_meth_table);
75 }
76
77int ENGINE_register_pkey_asn1_meths(ENGINE *e)
78 {
79 if(e->pkey_asn1_meths)
80 {
81 const int *nids;
82 int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
83 if(num_nids > 0)
84 return engine_table_register(&pkey_asn1_meth_table,
85 engine_unregister_all_pkey_asn1_meths, e, nids,
86 num_nids, 0);
87 }
88 return 1;
89 }
90
91void ENGINE_register_all_pkey_asn1_meths(void)
92 {
93 ENGINE *e;
94
95 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
96 ENGINE_register_pkey_asn1_meths(e);
97 }
98
99int ENGINE_set_default_pkey_asn1_meths(ENGINE *e)
100 {
101 if(e->pkey_asn1_meths)
102 {
103 const int *nids;
104 int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
105 if(num_nids > 0)
106 return engine_table_register(&pkey_asn1_meth_table,
107 engine_unregister_all_pkey_asn1_meths, e, nids,
108 num_nids, 1);
109 }
110 return 1;
111 }
112
113/* Exposed API function to get a functional reference from the implementation
114 * table (ie. try to get a functional reference from the tabled structural
115 * references) for a given pkey_asn1_meth 'nid' */
116ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid)
117 {
118 return engine_table_select(&pkey_asn1_meth_table, nid);
119 }
120
121/* Obtains a pkey_asn1_meth implementation from an ENGINE functional reference */
122const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid)
123 {
124 EVP_PKEY_ASN1_METHOD *ret;
125 ENGINE_PKEY_ASN1_METHS_PTR fn = ENGINE_get_pkey_asn1_meths(e);
126 if(!fn || !fn(e, &ret, NULL, nid))
127 {
128 ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH,
129 ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
130 return NULL;
131 }
132 return ret;
133 }
134
135/* Gets the pkey_asn1_meth callback from an ENGINE structure */
136ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e)
137 {
138 return e->pkey_asn1_meths;
139 }
140
141/* Sets the pkey_asn1_meth callback in an ENGINE structure */
142int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f)
143 {
144 e->pkey_asn1_meths = f;
145 return 1;
146 }
147
148/* Internal function to free up EVP_PKEY_ASN1_METHOD structures before an
149 * ENGINE is destroyed
150 */
151
152void engine_pkey_asn1_meths_free(ENGINE *e)
153 {
154 int i;
155 EVP_PKEY_ASN1_METHOD *pkm;
156 if (e->pkey_asn1_meths)
157 {
158 const int *pknids;
159 int npknids;
160 npknids = e->pkey_asn1_meths(e, NULL, &pknids, 0);
161 for (i = 0; i < npknids; i++)
162 {
163 if (e->pkey_asn1_meths(e, &pkm, NULL, pknids[i]))
164 {
165 EVP_PKEY_asn1_free(pkm);
166 }
167 }
168 }
169 }
170
171/* Find a method based on a string. This does a linear search through
172 * all implemented algorithms. This is OK in practice because only
173 * a small number of algorithms are likely to be implemented in an engine
174 * and it is not used for speed critical operations.
175 */
176
177const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
178 const char *str, int len)
179 {
180 int i, nidcount;
181 const int *nids;
182 EVP_PKEY_ASN1_METHOD *ameth;
183 if (!e->pkey_asn1_meths)
184 return NULL;
185 if (len == -1)
186 len = strlen(str);
187 nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0);
188 for (i = 0; i < nidcount; i++)
189 {
190 e->pkey_asn1_meths(e, &ameth, NULL, nids[i]);
191 if (((int)strlen(ameth->pem_str) == len) &&
192 !strncasecmp(ameth->pem_str, str, len))
193 return ameth;
194 }
195 return NULL;
196 }
197
198typedef struct
199 {
200 ENGINE *e;
201 const EVP_PKEY_ASN1_METHOD *ameth;
202 const char *str;
203 int len;
204 } ENGINE_FIND_STR;
205
206static void look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg)
207 {
208 ENGINE_FIND_STR *lk = arg;
209 int i;
210 if (lk->ameth)
211 return;
212 for (i = 0; i < sk_ENGINE_num(sk); i++)
213 {
214 ENGINE *e = sk_ENGINE_value(sk, i);
215 EVP_PKEY_ASN1_METHOD *ameth;
216 e->pkey_asn1_meths(e, &ameth, NULL, nid);
217 if (((int)strlen(ameth->pem_str) == lk->len) &&
218 !strncasecmp(ameth->pem_str, lk->str, lk->len))
219 {
220 lk->e = e;
221 lk->ameth = ameth;
222 return;
223 }
224 }
225 }
226
227const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
228 const char *str, int len)
229 {
230 ENGINE_FIND_STR fstr;
231 fstr.e = NULL;
232 fstr.ameth = NULL;
233 fstr.str = str;
234 fstr.len = len;
235 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
236 engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr);
237 /* If found obtain a structural reference to engine */
238 if (fstr.e)
239 {
240 fstr.e->struct_ref++;
241 engine_ref_debug(fstr.e, 0, 1)
242 }
243 *pe = fstr.e;
244 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
245 return fstr.ameth;
246 }
diff --git a/src/lib/libcrypto/engine/tb_cipher.c b/src/lib/libcrypto/engine/tb_cipher.c
new file mode 100644
index 0000000000..177fc1fb73
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_cipher.c
@@ -0,0 +1,143 @@
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 "eng_int.h"
56
57/* If this symbol is defined then ENGINE_get_cipher_engine(), the function that
58 * is used by EVP to hook in cipher code and cache defaults (etc), will display
59 * brief debugging summaries to stderr with the 'nid'. */
60/* #define ENGINE_CIPHER_DEBUG */
61
62static ENGINE_TABLE *cipher_table = NULL;
63
64void ENGINE_unregister_ciphers(ENGINE *e)
65 {
66 engine_table_unregister(&cipher_table, e);
67 }
68
69static void engine_unregister_all_ciphers(void)
70 {
71 engine_table_cleanup(&cipher_table);
72 }
73
74int ENGINE_register_ciphers(ENGINE *e)
75 {
76 if(e->ciphers)
77 {
78 const int *nids;
79 int num_nids = e->ciphers(e, NULL, &nids, 0);
80 if(num_nids > 0)
81 return engine_table_register(&cipher_table,
82 engine_unregister_all_ciphers, e, nids,
83 num_nids, 0);
84 }
85 return 1;
86 }
87
88void ENGINE_register_all_ciphers()
89 {
90 ENGINE *e;
91
92 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
93 ENGINE_register_ciphers(e);
94 }
95
96int ENGINE_set_default_ciphers(ENGINE *e)
97 {
98 if(e->ciphers)
99 {
100 const int *nids;
101 int num_nids = e->ciphers(e, NULL, &nids, 0);
102 if(num_nids > 0)
103 return engine_table_register(&cipher_table,
104 engine_unregister_all_ciphers, e, nids,
105 num_nids, 1);
106 }
107 return 1;
108 }
109
110/* Exposed API function to get a functional reference from the implementation
111 * table (ie. try to get a functional reference from the tabled structural
112 * references) for a given cipher 'nid' */
113ENGINE *ENGINE_get_cipher_engine(int nid)
114 {
115 return engine_table_select(&cipher_table, nid);
116 }
117
118/* Obtains a cipher implementation from an ENGINE functional reference */
119const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid)
120 {
121 const EVP_CIPHER *ret;
122 ENGINE_CIPHERS_PTR fn = ENGINE_get_ciphers(e);
123 if(!fn || !fn(e, &ret, NULL, nid))
124 {
125 ENGINEerr(ENGINE_F_ENGINE_GET_CIPHER,
126 ENGINE_R_UNIMPLEMENTED_CIPHER);
127 return NULL;
128 }
129 return ret;
130 }
131
132/* Gets the cipher callback from an ENGINE structure */
133ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e)
134 {
135 return e->ciphers;
136 }
137
138/* Sets the cipher callback in an ENGINE structure */
139int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f)
140 {
141 e->ciphers = f;
142 return 1;
143 }
diff --git a/src/lib/libcrypto/engine/tb_dh.c b/src/lib/libcrypto/engine/tb_dh.c
new file mode 100644
index 0000000000..6e9d428761
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_dh.c
@@ -0,0 +1,118 @@
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 "eng_int.h"
56
57/* If this symbol is defined then ENGINE_get_default_DH(), the function that is
58 * used by DH to hook in implementation code and cache defaults (etc), will
59 * display brief debugging summaries to stderr with the 'nid'. */
60/* #define ENGINE_DH_DEBUG */
61
62static ENGINE_TABLE *dh_table = NULL;
63static const int dummy_nid = 1;
64
65void ENGINE_unregister_DH(ENGINE *e)
66 {
67 engine_table_unregister(&dh_table, e);
68 }
69
70static void engine_unregister_all_DH(void)
71 {
72 engine_table_cleanup(&dh_table);
73 }
74
75int ENGINE_register_DH(ENGINE *e)
76 {
77 if(e->dh_meth)
78 return engine_table_register(&dh_table,
79 engine_unregister_all_DH, e, &dummy_nid, 1, 0);
80 return 1;
81 }
82
83void ENGINE_register_all_DH()
84 {
85 ENGINE *e;
86
87 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
88 ENGINE_register_DH(e);
89 }
90
91int ENGINE_set_default_DH(ENGINE *e)
92 {
93 if(e->dh_meth)
94 return engine_table_register(&dh_table,
95 engine_unregister_all_DH, e, &dummy_nid, 1, 1);
96 return 1;
97 }
98
99/* Exposed API function to get a functional reference from the implementation
100 * table (ie. try to get a functional reference from the tabled structural
101 * references). */
102ENGINE *ENGINE_get_default_DH(void)
103 {
104 return engine_table_select(&dh_table, dummy_nid);
105 }
106
107/* Obtains an DH implementation from an ENGINE functional reference */
108const DH_METHOD *ENGINE_get_DH(const ENGINE *e)
109 {
110 return e->dh_meth;
111 }
112
113/* Sets an DH implementation in an ENGINE structure */
114int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth)
115 {
116 e->dh_meth = dh_meth;
117 return 1;
118 }
diff --git a/src/lib/libcrypto/engine/tb_digest.c b/src/lib/libcrypto/engine/tb_digest.c
new file mode 100644
index 0000000000..d3f4bb2747
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_digest.c
@@ -0,0 +1,143 @@
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 "eng_int.h"
56
57/* If this symbol is defined then ENGINE_get_digest_engine(), the function that
58 * is used by EVP to hook in digest code and cache defaults (etc), will display
59 * brief debugging summaries to stderr with the 'nid'. */
60/* #define ENGINE_DIGEST_DEBUG */
61
62static ENGINE_TABLE *digest_table = NULL;
63
64void ENGINE_unregister_digests(ENGINE *e)
65 {
66 engine_table_unregister(&digest_table, e);
67 }
68
69static void engine_unregister_all_digests(void)
70 {
71 engine_table_cleanup(&digest_table);
72 }
73
74int ENGINE_register_digests(ENGINE *e)
75 {
76 if(e->digests)
77 {
78 const int *nids;
79 int num_nids = e->digests(e, NULL, &nids, 0);
80 if(num_nids > 0)
81 return engine_table_register(&digest_table,
82 engine_unregister_all_digests, e, nids,
83 num_nids, 0);
84 }
85 return 1;
86 }
87
88void ENGINE_register_all_digests()
89 {
90 ENGINE *e;
91
92 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
93 ENGINE_register_digests(e);
94 }
95
96int ENGINE_set_default_digests(ENGINE *e)
97 {
98 if(e->digests)
99 {
100 const int *nids;
101 int num_nids = e->digests(e, NULL, &nids, 0);
102 if(num_nids > 0)
103 return engine_table_register(&digest_table,
104 engine_unregister_all_digests, e, nids,
105 num_nids, 1);
106 }
107 return 1;
108 }
109
110/* Exposed API function to get a functional reference from the implementation
111 * table (ie. try to get a functional reference from the tabled structural
112 * references) for a given digest 'nid' */
113ENGINE *ENGINE_get_digest_engine(int nid)
114 {
115 return engine_table_select(&digest_table, nid);
116 }
117
118/* Obtains a digest implementation from an ENGINE functional reference */
119const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid)
120 {
121 const EVP_MD *ret;
122 ENGINE_DIGESTS_PTR fn = ENGINE_get_digests(e);
123 if(!fn || !fn(e, &ret, NULL, nid))
124 {
125 ENGINEerr(ENGINE_F_ENGINE_GET_DIGEST,
126 ENGINE_R_UNIMPLEMENTED_DIGEST);
127 return NULL;
128 }
129 return ret;
130 }
131
132/* Gets the digest callback from an ENGINE structure */
133ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e)
134 {
135 return e->digests;
136 }
137
138/* Sets the digest callback in an ENGINE structure */
139int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f)
140 {
141 e->digests = f;
142 return 1;
143 }
diff --git a/src/lib/libcrypto/engine/tb_dsa.c b/src/lib/libcrypto/engine/tb_dsa.c
new file mode 100644
index 0000000000..e4674f5f07
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_dsa.c
@@ -0,0 +1,118 @@
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 "eng_int.h"
56
57/* If this symbol is defined then ENGINE_get_default_DSA(), the function that is
58 * used by DSA to hook in implementation code and cache defaults (etc), will
59 * display brief debugging summaries to stderr with the 'nid'. */
60/* #define ENGINE_DSA_DEBUG */
61
62static ENGINE_TABLE *dsa_table = NULL;
63static const int dummy_nid = 1;
64
65void ENGINE_unregister_DSA(ENGINE *e)
66 {
67 engine_table_unregister(&dsa_table, e);
68 }
69
70static void engine_unregister_all_DSA(void)
71 {
72 engine_table_cleanup(&dsa_table);
73 }
74
75int ENGINE_register_DSA(ENGINE *e)
76 {
77 if(e->dsa_meth)
78 return engine_table_register(&dsa_table,
79 engine_unregister_all_DSA, e, &dummy_nid, 1, 0);
80 return 1;
81 }
82
83void ENGINE_register_all_DSA()
84 {
85 ENGINE *e;
86
87 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
88 ENGINE_register_DSA(e);
89 }
90
91int ENGINE_set_default_DSA(ENGINE *e)
92 {
93 if(e->dsa_meth)
94 return engine_table_register(&dsa_table,
95 engine_unregister_all_DSA, e, &dummy_nid, 1, 1);
96 return 1;
97 }
98
99/* Exposed API function to get a functional reference from the implementation
100 * table (ie. try to get a functional reference from the tabled structural
101 * references). */
102ENGINE *ENGINE_get_default_DSA(void)
103 {
104 return engine_table_select(&dsa_table, dummy_nid);
105 }
106
107/* Obtains an DSA implementation from an ENGINE functional reference */
108const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e)
109 {
110 return e->dsa_meth;
111 }
112
113/* Sets an DSA implementation in an ENGINE structure */
114int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth)
115 {
116 e->dsa_meth = dsa_meth;
117 return 1;
118 }
diff --git a/src/lib/libcrypto/engine/tb_ecdh.c b/src/lib/libcrypto/engine/tb_ecdh.c
new file mode 100644
index 0000000000..c8ec7812c5
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_ecdh.c
@@ -0,0 +1,133 @@
1/* crypto/engine/tb_ecdh.c */
2/* ====================================================================
3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
4 *
5 * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
6 * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
7 * to the OpenSSL project.
8 *
9 * The ECC Code is licensed pursuant to the OpenSSL open source
10 * license provided below.
11 *
12 * The ECDH engine software is originally written by Nils Gura and
13 * Douglas Stebila of Sun Microsystems Laboratories.
14 *
15 */
16/* ====================================================================
17 * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 *
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 *
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in
28 * the documentation and/or other materials provided with the
29 * distribution.
30 *
31 * 3. All advertising materials mentioning features or use of this
32 * software must display the following acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
35 *
36 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
37 * endorse or promote products derived from this software without
38 * prior written permission. For written permission, please contact
39 * licensing@OpenSSL.org.
40 *
41 * 5. Products derived from this software may not be called "OpenSSL"
42 * nor may "OpenSSL" appear in their names without prior written
43 * permission of the OpenSSL Project.
44 *
45 * 6. Redistributions of any form whatsoever must retain the following
46 * acknowledgment:
47 * "This product includes software developed by the OpenSSL Project
48 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
51 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
54 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
56 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
59 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
61 * OF THE POSSIBILITY OF SUCH DAMAGE.
62 * ====================================================================
63 *
64 * This product includes cryptographic software written by Eric Young
65 * (eay@cryptsoft.com). This product includes software written by Tim
66 * Hudson (tjh@cryptsoft.com).
67 *
68 */
69
70#include "eng_int.h"
71
72/* If this symbol is defined then ENGINE_get_default_ECDH(), the function that is
73 * used by ECDH to hook in implementation code and cache defaults (etc), will
74 * display brief debugging summaries to stderr with the 'nid'. */
75/* #define ENGINE_ECDH_DEBUG */
76
77static ENGINE_TABLE *ecdh_table = NULL;
78static const int dummy_nid = 1;
79
80void ENGINE_unregister_ECDH(ENGINE *e)
81 {
82 engine_table_unregister(&ecdh_table, e);
83 }
84
85static void engine_unregister_all_ECDH(void)
86 {
87 engine_table_cleanup(&ecdh_table);
88 }
89
90int ENGINE_register_ECDH(ENGINE *e)
91 {
92 if(e->ecdh_meth)
93 return engine_table_register(&ecdh_table,
94 engine_unregister_all_ECDH, e, &dummy_nid, 1, 0);
95 return 1;
96 }
97
98void ENGINE_register_all_ECDH()
99 {
100 ENGINE *e;
101
102 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
103 ENGINE_register_ECDH(e);
104 }
105
106int ENGINE_set_default_ECDH(ENGINE *e)
107 {
108 if(e->ecdh_meth)
109 return engine_table_register(&ecdh_table,
110 engine_unregister_all_ECDH, e, &dummy_nid, 1, 1);
111 return 1;
112 }
113
114/* Exposed API function to get a functional reference from the implementation
115 * table (ie. try to get a functional reference from the tabled structural
116 * references). */
117ENGINE *ENGINE_get_default_ECDH(void)
118 {
119 return engine_table_select(&ecdh_table, dummy_nid);
120 }
121
122/* Obtains an ECDH implementation from an ENGINE functional reference */
123const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e)
124 {
125 return e->ecdh_meth;
126 }
127
128/* Sets an ECDH implementation in an ENGINE structure */
129int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth)
130 {
131 e->ecdh_meth = ecdh_meth;
132 return 1;
133 }
diff --git a/src/lib/libcrypto/engine/tb_ecdsa.c b/src/lib/libcrypto/engine/tb_ecdsa.c
new file mode 100644
index 0000000000..005ecb622c
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_ecdsa.c
@@ -0,0 +1,118 @@
1/* ====================================================================
2 * Copyright (c) 2000-2002 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 "eng_int.h"
56
57/* If this symbol is defined then ENGINE_get_default_ECDSA(), the function that is
58 * used by ECDSA to hook in implementation code and cache defaults (etc), will
59 * display brief debugging summaries to stderr with the 'nid'. */
60/* #define ENGINE_ECDSA_DEBUG */
61
62static ENGINE_TABLE *ecdsa_table = NULL;
63static const int dummy_nid = 1;
64
65void ENGINE_unregister_ECDSA(ENGINE *e)
66 {
67 engine_table_unregister(&ecdsa_table, e);
68 }
69
70static void engine_unregister_all_ECDSA(void)
71 {
72 engine_table_cleanup(&ecdsa_table);
73 }
74
75int ENGINE_register_ECDSA(ENGINE *e)
76 {
77 if(e->ecdsa_meth)
78 return engine_table_register(&ecdsa_table,
79 engine_unregister_all_ECDSA, e, &dummy_nid, 1, 0);
80 return 1;
81 }
82
83void ENGINE_register_all_ECDSA()
84 {
85 ENGINE *e;
86
87 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
88 ENGINE_register_ECDSA(e);
89 }
90
91int ENGINE_set_default_ECDSA(ENGINE *e)
92 {
93 if(e->ecdsa_meth)
94 return engine_table_register(&ecdsa_table,
95 engine_unregister_all_ECDSA, e, &dummy_nid, 1, 1);
96 return 1;
97 }
98
99/* Exposed API function to get a functional reference from the implementation
100 * table (ie. try to get a functional reference from the tabled structural
101 * references). */
102ENGINE *ENGINE_get_default_ECDSA(void)
103 {
104 return engine_table_select(&ecdsa_table, dummy_nid);
105 }
106
107/* Obtains an ECDSA implementation from an ENGINE functional reference */
108const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e)
109 {
110 return e->ecdsa_meth;
111 }
112
113/* Sets an ECDSA implementation in an ENGINE structure */
114int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth)
115 {
116 e->ecdsa_meth = ecdsa_meth;
117 return 1;
118 }
diff --git a/src/lib/libcrypto/engine/tb_pkmeth.c b/src/lib/libcrypto/engine/tb_pkmeth.c
new file mode 100644
index 0000000000..1cdb967f25
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_pkmeth.c
@@ -0,0 +1,167 @@
1/* ====================================================================
2 * Copyright (c) 2006 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 "eng_int.h"
56#include <openssl/evp.h>
57
58/* If this symbol is defined then ENGINE_get_pkey_meth_engine(), the function
59 * that is used by EVP to hook in pkey_meth code and cache defaults (etc), will
60 * display brief debugging summaries to stderr with the 'nid'. */
61/* #define ENGINE_PKEY_METH_DEBUG */
62
63static ENGINE_TABLE *pkey_meth_table = NULL;
64
65void ENGINE_unregister_pkey_meths(ENGINE *e)
66 {
67 engine_table_unregister(&pkey_meth_table, e);
68 }
69
70static void engine_unregister_all_pkey_meths(void)
71 {
72 engine_table_cleanup(&pkey_meth_table);
73 }
74
75int ENGINE_register_pkey_meths(ENGINE *e)
76 {
77 if(e->pkey_meths)
78 {
79 const int *nids;
80 int num_nids = e->pkey_meths(e, NULL, &nids, 0);
81 if(num_nids > 0)
82 return engine_table_register(&pkey_meth_table,
83 engine_unregister_all_pkey_meths, e, nids,
84 num_nids, 0);
85 }
86 return 1;
87 }
88
89void ENGINE_register_all_pkey_meths()
90 {
91 ENGINE *e;
92
93 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
94 ENGINE_register_pkey_meths(e);
95 }
96
97int ENGINE_set_default_pkey_meths(ENGINE *e)
98 {
99 if(e->pkey_meths)
100 {
101 const int *nids;
102 int num_nids = e->pkey_meths(e, NULL, &nids, 0);
103 if(num_nids > 0)
104 return engine_table_register(&pkey_meth_table,
105 engine_unregister_all_pkey_meths, e, nids,
106 num_nids, 1);
107 }
108 return 1;
109 }
110
111/* Exposed API function to get a functional reference from the implementation
112 * table (ie. try to get a functional reference from the tabled structural
113 * references) for a given pkey_meth 'nid' */
114ENGINE *ENGINE_get_pkey_meth_engine(int nid)
115 {
116 return engine_table_select(&pkey_meth_table, nid);
117 }
118
119/* Obtains a pkey_meth implementation from an ENGINE functional reference */
120const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid)
121 {
122 EVP_PKEY_METHOD *ret;
123 ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e);
124 if(!fn || !fn(e, &ret, NULL, nid))
125 {
126 ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_METH,
127 ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
128 return NULL;
129 }
130 return ret;
131 }
132
133/* Gets the pkey_meth callback from an ENGINE structure */
134ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e)
135 {
136 return e->pkey_meths;
137 }
138
139/* Sets the pkey_meth callback in an ENGINE structure */
140int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f)
141 {
142 e->pkey_meths = f;
143 return 1;
144 }
145
146/* Internal function to free up EVP_PKEY_METHOD structures before an
147 * ENGINE is destroyed
148 */
149
150void engine_pkey_meths_free(ENGINE *e)
151 {
152 int i;
153 EVP_PKEY_METHOD *pkm;
154 if (e->pkey_meths)
155 {
156 const int *pknids;
157 int npknids;
158 npknids = e->pkey_meths(e, NULL, &pknids, 0);
159 for (i = 0; i < npknids; i++)
160 {
161 if (e->pkey_meths(e, &pkm, NULL, pknids[i]))
162 {
163 EVP_PKEY_meth_free(pkm);
164 }
165 }
166 }
167 }
diff --git a/src/lib/libcrypto/engine/tb_rand.c b/src/lib/libcrypto/engine/tb_rand.c
new file mode 100644
index 0000000000..f36f67c0f6
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_rand.c
@@ -0,0 +1,118 @@
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 "eng_int.h"
56
57/* If this symbol is defined then ENGINE_get_default_RAND(), the function that is
58 * used by RAND to hook in implementation code and cache defaults (etc), will
59 * display brief debugging summaries to stderr with the 'nid'. */
60/* #define ENGINE_RAND_DEBUG */
61
62static ENGINE_TABLE *rand_table = NULL;
63static const int dummy_nid = 1;
64
65void ENGINE_unregister_RAND(ENGINE *e)
66 {
67 engine_table_unregister(&rand_table, e);
68 }
69
70static void engine_unregister_all_RAND(void)
71 {
72 engine_table_cleanup(&rand_table);
73 }
74
75int ENGINE_register_RAND(ENGINE *e)
76 {
77 if(e->rand_meth)
78 return engine_table_register(&rand_table,
79 engine_unregister_all_RAND, e, &dummy_nid, 1, 0);
80 return 1;
81 }
82
83void ENGINE_register_all_RAND()
84 {
85 ENGINE *e;
86
87 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
88 ENGINE_register_RAND(e);
89 }
90
91int ENGINE_set_default_RAND(ENGINE *e)
92 {
93 if(e->rand_meth)
94 return engine_table_register(&rand_table,
95 engine_unregister_all_RAND, e, &dummy_nid, 1, 1);
96 return 1;
97 }
98
99/* Exposed API function to get a functional reference from the implementation
100 * table (ie. try to get a functional reference from the tabled structural
101 * references). */
102ENGINE *ENGINE_get_default_RAND(void)
103 {
104 return engine_table_select(&rand_table, dummy_nid);
105 }
106
107/* Obtains an RAND implementation from an ENGINE functional reference */
108const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e)
109 {
110 return e->rand_meth;
111 }
112
113/* Sets an RAND implementation in an ENGINE structure */
114int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth)
115 {
116 e->rand_meth = rand_meth;
117 return 1;
118 }
diff --git a/src/lib/libcrypto/engine/tb_rsa.c b/src/lib/libcrypto/engine/tb_rsa.c
new file mode 100644
index 0000000000..fbc707fd26
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_rsa.c
@@ -0,0 +1,118 @@
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 "eng_int.h"
56
57/* If this symbol is defined then ENGINE_get_default_RSA(), the function that is
58 * used by RSA to hook in implementation code and cache defaults (etc), will
59 * display brief debugging summaries to stderr with the 'nid'. */
60/* #define ENGINE_RSA_DEBUG */
61
62static ENGINE_TABLE *rsa_table = NULL;
63static const int dummy_nid = 1;
64
65void ENGINE_unregister_RSA(ENGINE *e)
66 {
67 engine_table_unregister(&rsa_table, e);
68 }
69
70static void engine_unregister_all_RSA(void)
71 {
72 engine_table_cleanup(&rsa_table);
73 }
74
75int ENGINE_register_RSA(ENGINE *e)
76 {
77 if(e->rsa_meth)
78 return engine_table_register(&rsa_table,
79 engine_unregister_all_RSA, e, &dummy_nid, 1, 0);
80 return 1;
81 }
82
83void ENGINE_register_all_RSA()
84 {
85 ENGINE *e;
86
87 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
88 ENGINE_register_RSA(e);
89 }
90
91int ENGINE_set_default_RSA(ENGINE *e)
92 {
93 if(e->rsa_meth)
94 return engine_table_register(&rsa_table,
95 engine_unregister_all_RSA, e, &dummy_nid, 1, 1);
96 return 1;
97 }
98
99/* Exposed API function to get a functional reference from the implementation
100 * table (ie. try to get a functional reference from the tabled structural
101 * references). */
102ENGINE *ENGINE_get_default_RSA(void)
103 {
104 return engine_table_select(&rsa_table, dummy_nid);
105 }
106
107/* Obtains an RSA implementation from an ENGINE functional reference */
108const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e)
109 {
110 return e->rsa_meth;
111 }
112
113/* Sets an RSA implementation in an ENGINE structure */
114int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth)
115 {
116 e->rsa_meth = rsa_meth;
117 return 1;
118 }
diff --git a/src/lib/libcrypto/engine/tb_store.c b/src/lib/libcrypto/engine/tb_store.c
new file mode 100644
index 0000000000..8cc435c935
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_store.c
@@ -0,0 +1,123 @@
1/* ====================================================================
2 * Copyright (c) 2003 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 "eng_int.h"
56
57/* If this symbol is defined then ENGINE_get_default_STORE(), the function that is
58 * used by STORE to hook in implementation code and cache defaults (etc), will
59 * display brief debugging summaries to stderr with the 'nid'. */
60/* #define ENGINE_STORE_DEBUG */
61
62static ENGINE_TABLE *store_table = NULL;
63static const int dummy_nid = 1;
64
65void ENGINE_unregister_STORE(ENGINE *e)
66 {
67 engine_table_unregister(&store_table, e);
68 }
69
70static void engine_unregister_all_STORE(void)
71 {
72 engine_table_cleanup(&store_table);
73 }
74
75int ENGINE_register_STORE(ENGINE *e)
76 {
77 if(e->store_meth)
78 return engine_table_register(&store_table,
79 engine_unregister_all_STORE, e, &dummy_nid, 1, 0);
80 return 1;
81 }
82
83void ENGINE_register_all_STORE()
84 {
85 ENGINE *e;
86
87 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
88 ENGINE_register_STORE(e);
89 }
90
91/* The following two functions are removed because they're useless. */
92#if 0
93int ENGINE_set_default_STORE(ENGINE *e)
94 {
95 if(e->store_meth)
96 return engine_table_register(&store_table,
97 engine_unregister_all_STORE, e, &dummy_nid, 1, 1);
98 return 1;
99 }
100#endif
101
102#if 0
103/* Exposed API function to get a functional reference from the implementation
104 * table (ie. try to get a functional reference from the tabled structural
105 * references). */
106ENGINE *ENGINE_get_default_STORE(void)
107 {
108 return engine_table_select(&store_table, dummy_nid);
109 }
110#endif
111
112/* Obtains an STORE implementation from an ENGINE functional reference */
113const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e)
114 {
115 return e->store_meth;
116 }
117
118/* Sets an STORE implementation in an ENGINE structure */
119int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth)
120 {
121 e->store_meth = store_meth;
122 return 1;
123 }