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/Makefile91
-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.c105
-rw-r--r--src/lib/libcrypto/engine/eng_cnf.c259
-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.c182
-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.c434
-rw-r--r--src/lib/libcrypto/engine/eng_openssl.c384
-rw-r--r--src/lib/libcrypto/engine/eng_padlock.c1239
-rw-r--r--src/lib/libcrypto/engine/eng_padlock.ec1
-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.h813
-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, 9833 insertions, 1132 deletions
diff --git a/src/lib/libcrypto/engine/Makefile b/src/lib/libcrypto/engine/Makefile
new file mode 100644
index 0000000000..06e1bc7494
--- /dev/null
+++ b/src/lib/libcrypto/engine/Makefile
@@ -0,0 +1,91 @@
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
20LIBNAMES= eng_padlock
21LIBSRC= eng_err.c eng_lib.c eng_list.c eng_init.c eng_ctrl.c \
22 eng_table.c eng_pkey.c eng_fat.c eng_all.c \
23 tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
24 tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c \
25 eng_openssl.c eng_cnf.c eng_dyn.c \
26 eng_rsax.c eng_rdrand.c
27LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
28 eng_table.o eng_pkey.o eng_fat.o eng_all.o \
29 tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
30 tb_cipher.o tb_digest.o tb_pkmeth.o tb_asnmth.o \
31 eng_openssl.o eng_cnf.o eng_dyn.o \
32 eng_rsax.o eng_rdrand.o
33
34SRC= $(LIBSRC)
35
36EXHEADER= engine.h
37HEADER= $(EXHEADER)
38
39ALL= $(GENERAL) $(SRC) $(HEADER)
40
41top:
42 (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
43
44all: lib
45
46lib: $(LIBOBJ)
47 $(AR) $(LIB) $(LIBOBJ)
48 $(RANLIB) $(LIB) || echo Never mind.
49 @touch lib
50
51files:
52 $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
53
54links:
55 @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
56 @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
57 @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
58
59install:
60 @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
61 @headerlist="$(EXHEADER)"; for i in $$headerlist ; \
62 do \
63 (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
64 chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
65 done;
66
67tags:
68 ctags $(SRC)
69
70errors:
71 set -e; for l in $(LIBNAMES); do \
72 $(PERL) ../../util/mkerr.pl -conf eng_$$l.ec \
73 -nostatic -staticloader -write eng_$$l.c; \
74 done
75tests:
76
77lint:
78 lint -DLINT $(INCLUDES) $(SRC)>fluff
79
80depend:
81 @[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
82 $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
83
84dclean:
85 $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
86 mv -f Makefile.new $(MAKEFILE)
87
88clean:
89 rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
90
91# DO NOT DELETE THIS LINE -- make depend depends on it.
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..2fbfc448fd
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_all.c
@@ -0,0 +1,105 @@
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 /* Some ENGINEs need this */
65 OPENSSL_cpuid_setup();
66#if 0
67 /* There's no longer any need for an "openssl" ENGINE unless, one day,
68 * it is the *only* way for standard builtin implementations to be be
69 * accessed (ie. it would be possible to statically link binaries with
70 * *no* builtin implementations). */
71 ENGINE_load_openssl();
72#endif
73#if !defined(OPENSSL_NO_HW) && (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
74 ENGINE_load_cryptodev();
75#endif
76#ifndef OPENSSL_NO_RSAX
77 ENGINE_load_rsax();
78#endif
79#ifndef OPENSSL_NO_RDRAND
80 ENGINE_load_rdrand();
81#endif
82 ENGINE_load_dynamic();
83#ifndef OPENSSL_NO_STATIC_ENGINE
84#ifndef OPENSSL_NO_HW
85#ifndef OPENSSL_NO_HW_PADLOCK
86 ENGINE_load_padlock();
87#endif
88#endif
89#ifndef OPENSSL_NO_GOST
90 ENGINE_load_gost();
91#endif
92#endif
93 ENGINE_register_all_complete();
94 }
95
96#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
97void ENGINE_setup_bsd_cryptodev(void) {
98 static int bsd_cryptodev_default_loaded = 0;
99 if (!bsd_cryptodev_default_loaded) {
100 ENGINE_load_cryptodev();
101 ENGINE_register_all_complete();
102 }
103 bsd_cryptodev_default_loaded=1;
104}
105#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_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..789b8d57e5
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_fat.c
@@ -0,0 +1,182 @@
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 if (!(e->flags & ENGINE_FLAGS_NO_REGISTER_ALL))
180 ENGINE_register_complete(e);
181 return 1;
182 }
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..95c858960b
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_list.c
@@ -0,0 +1,434 @@
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, "LIST_ADD", "1", 0) ||
412 !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
413 goto notfound;
414 return iterator;
415 }
416notfound:
417 ENGINE_free(iterator);
418 ENGINEerr(ENGINE_F_ENGINE_BY_ID,ENGINE_R_NO_SUCH_ENGINE);
419 ERR_add_error_data(2, "id=", id);
420 return NULL;
421 /* EEK! Experimental code ends */
422#endif
423 }
424
425int ENGINE_up_ref(ENGINE *e)
426 {
427 if (e == NULL)
428 {
429 ENGINEerr(ENGINE_F_ENGINE_UP_REF,ERR_R_PASSED_NULL_PARAMETER);
430 return 0;
431 }
432 CRYPTO_add(&e->struct_ref,1,CRYPTO_LOCK_ENGINE);
433 return 1;
434 }
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..d1fc8d9315
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_padlock.c
@@ -0,0 +1,1239 @@
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
107# endif
108#endif
109
110#ifdef OPENSSL_NO_DYNAMIC_ENGINE
111#ifdef COMPILE_HW_PADLOCK
112static ENGINE *ENGINE_padlock (void);
113#endif
114
115void ENGINE_load_padlock (void)
116{
117/* On non-x86 CPUs it just returns. */
118#ifdef COMPILE_HW_PADLOCK
119 ENGINE *toadd = ENGINE_padlock ();
120 if (!toadd) return;
121 ENGINE_add (toadd);
122 ENGINE_free (toadd);
123 ERR_clear_error ();
124#endif
125}
126
127#endif
128
129#ifdef COMPILE_HW_PADLOCK
130/* We do these includes here to avoid header problems on platforms that
131 do not have the VIA padlock anyway... */
132#include <stdlib.h>
133#ifdef _WIN32
134# include <malloc.h>
135# ifndef alloca
136# define alloca _alloca
137# endif
138#elif defined(__GNUC__)
139# ifndef alloca
140# define alloca(s) __builtin_alloca(s)
141# endif
142#endif
143
144/* Function for ENGINE detection and control */
145static int padlock_available(void);
146static int padlock_init(ENGINE *e);
147
148/* RNG Stuff */
149static RAND_METHOD padlock_rand;
150
151/* Cipher Stuff */
152#ifndef OPENSSL_NO_AES
153static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
154#endif
155
156/* Engine names */
157static const char *padlock_id = "padlock";
158static char padlock_name[100];
159
160/* Available features */
161static int padlock_use_ace = 0; /* Advanced Cryptography Engine */
162static int padlock_use_rng = 0; /* Random Number Generator */
163#ifndef OPENSSL_NO_AES
164static int padlock_aes_align_required = 1;
165#endif
166
167/* ===== Engine "management" functions ===== */
168
169/* Prepare the ENGINE structure for registration */
170static int
171padlock_bind_helper(ENGINE *e)
172{
173 /* Check available features */
174 padlock_available();
175
176#if 1 /* disable RNG for now, see commentary in vicinity of RNG code */
177 padlock_use_rng=0;
178#endif
179
180 /* Generate a nice engine name with available features */
181 (void) snprintf(padlock_name, sizeof(padlock_name),
182 "VIA PadLock (%s, %s)",
183 padlock_use_rng ? "RNG" : "no-RNG",
184 padlock_use_ace ? "ACE" : "no-ACE");
185
186 /* Register everything or return with an error */
187 if (!ENGINE_set_id(e, padlock_id) ||
188 !ENGINE_set_name(e, padlock_name) ||
189
190 !ENGINE_set_init_function(e, padlock_init) ||
191#ifndef OPENSSL_NO_AES
192 (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) ||
193#endif
194 (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) {
195 return 0;
196 }
197
198 /* Everything looks good */
199 return 1;
200}
201
202#ifdef OPENSSL_NO_DYNAMIC_ENGINE
203
204/* Constructor */
205static ENGINE *
206ENGINE_padlock(void)
207{
208 ENGINE *eng = ENGINE_new();
209
210 if (!eng) {
211 return NULL;
212 }
213
214 if (!padlock_bind_helper(eng)) {
215 ENGINE_free(eng);
216 return NULL;
217 }
218
219 return eng;
220}
221
222#endif
223
224/* Check availability of the engine */
225static int
226padlock_init(ENGINE *e)
227{
228 return (padlock_use_rng || padlock_use_ace);
229}
230
231/* This stuff is needed if this ENGINE is being compiled into a self-contained
232 * shared-library.
233 */
234#ifdef DYNAMIC_ENGINE
235static int
236padlock_bind_fn(ENGINE *e, const char *id)
237{
238 if (id && (strcmp(id, padlock_id) != 0)) {
239 return 0;
240 }
241
242 if (!padlock_bind_helper(e)) {
243 return 0;
244 }
245
246 return 1;
247}
248
249IMPLEMENT_DYNAMIC_CHECK_FN()
250IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn)
251#endif /* DYNAMIC_ENGINE */
252
253/* ===== Here comes the "real" engine ===== */
254
255#ifndef OPENSSL_NO_AES
256/* Some AES-related constants */
257#define AES_BLOCK_SIZE 16
258#define AES_KEY_SIZE_128 16
259#define AES_KEY_SIZE_192 24
260#define AES_KEY_SIZE_256 32
261
262/* Here we store the status information relevant to the
263 current context. */
264/* BIG FAT WARNING:
265 * Inline assembler in PADLOCK_XCRYPT_ASM()
266 * depends on the order of items in this structure.
267 * Don't blindly modify, reorder, etc!
268 */
269struct padlock_cipher_data
270{
271 unsigned char iv[AES_BLOCK_SIZE]; /* Initialization vector */
272 union { unsigned int pad[4];
273 struct {
274 int rounds:4;
275 int dgst:1; /* n/a in C3 */
276 int align:1; /* n/a in C3 */
277 int ciphr:1; /* n/a in C3 */
278 unsigned int keygen:1;
279 int interm:1;
280 unsigned int encdec:1;
281 int ksize:2;
282 } b;
283 } cword; /* Control word */
284 AES_KEY ks; /* Encryption key */
285};
286
287/*
288 * Essentially this variable belongs in thread local storage.
289 * Having this variable global on the other hand can only cause
290 * few bogus key reloads [if any at all on single-CPU system],
291 * so we accept the penatly...
292 */
293static volatile struct padlock_cipher_data *padlock_saved_context;
294#endif
295
296/*
297 * =======================================================
298 * Inline assembler section(s).
299 * =======================================================
300 * Order of arguments is chosen to facilitate Windows port
301 * using __fastcall calling convention. If you wish to add
302 * more routines, keep in mind that first __fastcall
303 * argument is passed in %ecx and second - in %edx.
304 * =======================================================
305 */
306#if defined(__GNUC__) && __GNUC__>=2
307/*
308 * As for excessive "push %ebx"/"pop %ebx" found all over.
309 * When generating position-independent code GCC won't let
310 * us use "b" in assembler templates nor even respect "ebx"
311 * in "clobber description." Therefore the trouble...
312 */
313
314/* Helper function - check if a CPUID instruction
315 is available on this CPU */
316static int
317padlock_insn_cpuid_available(void)
318{
319 int result = -1;
320
321 /* We're checking if the bit #21 of EFLAGS
322 can be toggled. If yes = CPUID is available. */
323 asm volatile (
324 "pushf\n"
325 "popl %%eax\n"
326 "xorl $0x200000, %%eax\n"
327 "movl %%eax, %%ecx\n"
328 "andl $0x200000, %%ecx\n"
329 "pushl %%eax\n"
330 "popf\n"
331 "pushf\n"
332 "popl %%eax\n"
333 "andl $0x200000, %%eax\n"
334 "xorl %%eax, %%ecx\n"
335 "movl %%ecx, %0\n"
336 : "=r" (result) : : "eax", "ecx");
337
338 return (result == 0);
339}
340
341/* Load supported features of the CPU to see if
342 the PadLock is available. */
343static int
344padlock_available(void)
345{
346 char vendor_string[16];
347 unsigned int eax, edx;
348
349 /* First check if the CPUID instruction is available at all... */
350 if (! padlock_insn_cpuid_available())
351 return 0;
352
353 /* Are we running on the Centaur (VIA) CPU? */
354 eax = 0x00000000;
355 vendor_string[12] = 0;
356 asm volatile (
357 "pushl %%ebx\n"
358 "cpuid\n"
359 "movl %%ebx,(%%edi)\n"
360 "movl %%edx,4(%%edi)\n"
361 "movl %%ecx,8(%%edi)\n"
362 "popl %%ebx"
363 : "+a"(eax) : "D"(vendor_string) : "ecx", "edx");
364 if (strcmp(vendor_string, "CentaurHauls") != 0)
365 return 0;
366
367 /* Check for Centaur Extended Feature Flags presence */
368 eax = 0xC0000000;
369 asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
370 : "+a"(eax) : : "ecx", "edx");
371 if (eax < 0xC0000001)
372 return 0;
373
374 /* Read the Centaur Extended Feature Flags */
375 eax = 0xC0000001;
376 asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
377 : "+a"(eax), "=d"(edx) : : "ecx");
378
379 /* Fill up some flags */
380 padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6));
381 padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2));
382
383 return padlock_use_ace + padlock_use_rng;
384}
385
386#ifndef OPENSSL_NO_AES
387/* Our own htonl()/ntohl() */
388static inline void
389padlock_bswapl(AES_KEY *ks)
390{
391 size_t i = sizeof(ks->rd_key)/sizeof(ks->rd_key[0]);
392 unsigned int *key = ks->rd_key;
393
394 while (i--) {
395 asm volatile ("bswapl %0" : "+r"(*key));
396 key++;
397 }
398}
399#endif
400
401/* Force key reload from memory to the CPU microcode.
402 Loading EFLAGS from the stack clears EFLAGS[30]
403 which does the trick. */
404static inline void
405padlock_reload_key(void)
406{
407 asm volatile ("pushfl; popfl");
408}
409
410#ifndef OPENSSL_NO_AES
411/*
412 * This is heuristic key context tracing. At first one
413 * believes that one should use atomic swap instructions,
414 * but it's not actually necessary. Point is that if
415 * padlock_saved_context was changed by another thread
416 * after we've read it and before we compare it with cdata,
417 * our key *shall* be reloaded upon thread context switch
418 * and we are therefore set in either case...
419 */
420static inline void
421padlock_verify_context(struct padlock_cipher_data *cdata)
422{
423 asm volatile (
424 "pushfl\n"
425" btl $30,(%%esp)\n"
426" jnc 1f\n"
427" cmpl %2,%1\n"
428" je 1f\n"
429" popfl\n"
430" subl $4,%%esp\n"
431"1: addl $4,%%esp\n"
432" movl %2,%0"
433 :"+m"(padlock_saved_context)
434 : "r"(padlock_saved_context), "r"(cdata) : "cc");
435}
436
437/* Template for padlock_xcrypt_* modes */
438/* BIG FAT WARNING:
439 * The offsets used with 'leal' instructions
440 * describe items of the 'padlock_cipher_data'
441 * structure.
442 */
443#define PADLOCK_XCRYPT_ASM(name,rep_xcrypt) \
444static inline void *name(size_t cnt, \
445 struct padlock_cipher_data *cdata, \
446 void *out, const void *inp) \
447{ void *iv; \
448 asm volatile ( "pushl %%ebx\n" \
449 " leal 16(%0),%%edx\n" \
450 " leal 32(%0),%%ebx\n" \
451 rep_xcrypt "\n" \
452 " popl %%ebx" \
453 : "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \
454 : "0"(cdata), "1"(cnt), "2"(out), "3"(inp) \
455 : "edx", "cc", "memory"); \
456 return iv; \
457}
458
459/* Generate all functions with appropriate opcodes */
460PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8") /* rep xcryptecb */
461PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0") /* rep xcryptcbc */
462PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0") /* rep xcryptcfb */
463PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8") /* rep xcryptofb */
464#endif
465
466/* The RNG call itself */
467static inline unsigned int
468padlock_xstore(void *addr, unsigned int edx_in)
469{
470 unsigned int eax_out;
471
472 asm volatile (".byte 0x0f,0xa7,0xc0" /* xstore */
473 : "=a"(eax_out),"=m"(*(unsigned *)addr)
474 : "D"(addr), "d" (edx_in)
475 );
476
477 return eax_out;
478}
479
480/* Why not inline 'rep movsd'? I failed to find information on what
481 * value in Direction Flag one can expect and consequently have to
482 * apply "better-safe-than-sorry" approach and assume "undefined."
483 * I could explicitly clear it and restore the original value upon
484 * return from padlock_aes_cipher, but it's presumably too much
485 * trouble for too little gain...
486 *
487 * In case you wonder 'rep xcrypt*' instructions above are *not*
488 * affected by the Direction Flag and pointers advance toward
489 * larger addresses unconditionally.
490 */
491static inline unsigned char *
492padlock_memcpy(void *dst,const void *src,size_t n)
493{
494 long *d=dst;
495 const long *s=src;
496
497 n /= sizeof(*d);
498 do { *d++ = *s++; } while (--n);
499
500 return dst;
501}
502
503#elif defined(_MSC_VER)
504/*
505 * Unlike GCC these are real functions. In order to minimize impact
506 * on performance we adhere to __fastcall calling convention in
507 * order to get two first arguments passed through %ecx and %edx.
508 * Which kind of suits very well, as instructions in question use
509 * both %ecx and %edx as input:-)
510 */
511#define REP_XCRYPT(code) \
512 _asm _emit 0xf3 \
513 _asm _emit 0x0f _asm _emit 0xa7 \
514 _asm _emit code
515
516/* BIG FAT WARNING:
517 * The offsets used with 'lea' instructions
518 * describe items of the 'padlock_cipher_data'
519 * structure.
520 */
521#define PADLOCK_XCRYPT_ASM(name,code) \
522static void * __fastcall \
523 name (size_t cnt, void *cdata, \
524 void *outp, const void *inp) \
525{ _asm mov eax,edx \
526 _asm lea edx,[eax+16] \
527 _asm lea ebx,[eax+32] \
528 _asm mov edi,outp \
529 _asm mov esi,inp \
530 REP_XCRYPT(code) \
531}
532
533PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb,0xc8)
534PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc,0xd0)
535PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb,0xe0)
536PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb,0xe8)
537
538static int __fastcall
539padlock_xstore(void *outp,unsigned int code)
540{ _asm mov edi,ecx
541 _asm _emit 0x0f _asm _emit 0xa7 _asm _emit 0xc0
542}
543
544static void __fastcall
545padlock_reload_key(void)
546{ _asm pushfd _asm popfd }
547
548static void __fastcall
549padlock_verify_context(void *cdata)
550{ _asm {
551 pushfd
552 bt DWORD PTR[esp],30
553 jnc skip
554 cmp ecx,padlock_saved_context
555 je skip
556 popfd
557 sub esp,4
558 skip: add esp,4
559 mov padlock_saved_context,ecx
560 }
561}
562
563static int
564padlock_available(void)
565{ _asm {
566 pushfd
567 pop eax
568 mov ecx,eax
569 xor eax,1<<21
570 push eax
571 popfd
572 pushfd
573 pop eax
574 xor eax,ecx
575 bt eax,21
576 jnc noluck
577 mov eax,0
578 cpuid
579 xor eax,eax
580 cmp ebx,'tneC'
581 jne noluck
582 cmp edx,'Hrua'
583 jne noluck
584 cmp ecx,'slua'
585 jne noluck
586 mov eax,0xC0000000
587 cpuid
588 mov edx,eax
589 xor eax,eax
590 cmp edx,0xC0000001
591 jb noluck
592 mov eax,0xC0000001
593 cpuid
594 xor eax,eax
595 bt edx,6
596 jnc skip_a
597 bt edx,7
598 jnc skip_a
599 mov padlock_use_ace,1
600 inc eax
601 skip_a: bt edx,2
602 jnc skip_r
603 bt edx,3
604 jnc skip_r
605 mov padlock_use_rng,1
606 inc eax
607 skip_r:
608 noluck:
609 }
610}
611
612static void __fastcall
613padlock_bswapl(void *key)
614{ _asm {
615 pushfd
616 cld
617 mov esi,ecx
618 mov edi,ecx
619 mov ecx,60
620 up: lodsd
621 bswap eax
622 stosd
623 loop up
624 popfd
625 }
626}
627
628/* MS actually specifies status of Direction Flag and compiler even
629 * manages to compile following as 'rep movsd' all by itself...
630 */
631#define padlock_memcpy(o,i,n) ((unsigned char *)memcpy((o),(i),(n)&~3U))
632#endif
633
634/* ===== AES encryption/decryption ===== */
635#ifndef OPENSSL_NO_AES
636
637#if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)
638#define NID_aes_128_cfb NID_aes_128_cfb128
639#endif
640
641#if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb)
642#define NID_aes_128_ofb NID_aes_128_ofb128
643#endif
644
645#if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb)
646#define NID_aes_192_cfb NID_aes_192_cfb128
647#endif
648
649#if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb)
650#define NID_aes_192_ofb NID_aes_192_ofb128
651#endif
652
653#if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb)
654#define NID_aes_256_cfb NID_aes_256_cfb128
655#endif
656
657#if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb)
658#define NID_aes_256_ofb NID_aes_256_ofb128
659#endif
660
661/* List of supported ciphers. */
662static int padlock_cipher_nids[] = {
663 NID_aes_128_ecb,
664 NID_aes_128_cbc,
665 NID_aes_128_cfb,
666 NID_aes_128_ofb,
667
668 NID_aes_192_ecb,
669 NID_aes_192_cbc,
670 NID_aes_192_cfb,
671 NID_aes_192_ofb,
672
673 NID_aes_256_ecb,
674 NID_aes_256_cbc,
675 NID_aes_256_cfb,
676 NID_aes_256_ofb,
677};
678static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/
679 sizeof(padlock_cipher_nids[0]));
680
681/* Function prototypes ... */
682static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
683 const unsigned char *iv, int enc);
684static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
685 const unsigned char *in, size_t nbytes);
686
687#define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) + \
688 ( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F ) )
689#define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\
690 NEAREST_ALIGNED(ctx->cipher_data))
691
692#define EVP_CIPHER_block_size_ECB AES_BLOCK_SIZE
693#define EVP_CIPHER_block_size_CBC AES_BLOCK_SIZE
694#define EVP_CIPHER_block_size_OFB 1
695#define EVP_CIPHER_block_size_CFB 1
696
697/* Declaring so many ciphers by hand would be a pain.
698 Instead introduce a bit of preprocessor magic :-) */
699#define DECLARE_AES_EVP(ksize,lmode,umode) \
700static const EVP_CIPHER padlock_aes_##ksize##_##lmode = { \
701 NID_aes_##ksize##_##lmode, \
702 EVP_CIPHER_block_size_##umode, \
703 AES_KEY_SIZE_##ksize, \
704 AES_BLOCK_SIZE, \
705 0 | EVP_CIPH_##umode##_MODE, \
706 padlock_aes_init_key, \
707 padlock_aes_cipher, \
708 NULL, \
709 sizeof(struct padlock_cipher_data) + 16, \
710 EVP_CIPHER_set_asn1_iv, \
711 EVP_CIPHER_get_asn1_iv, \
712 NULL, \
713 NULL \
714}
715
716DECLARE_AES_EVP(128,ecb,ECB);
717DECLARE_AES_EVP(128,cbc,CBC);
718DECLARE_AES_EVP(128,cfb,CFB);
719DECLARE_AES_EVP(128,ofb,OFB);
720
721DECLARE_AES_EVP(192,ecb,ECB);
722DECLARE_AES_EVP(192,cbc,CBC);
723DECLARE_AES_EVP(192,cfb,CFB);
724DECLARE_AES_EVP(192,ofb,OFB);
725
726DECLARE_AES_EVP(256,ecb,ECB);
727DECLARE_AES_EVP(256,cbc,CBC);
728DECLARE_AES_EVP(256,cfb,CFB);
729DECLARE_AES_EVP(256,ofb,OFB);
730
731static int
732padlock_ciphers (ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid)
733{
734 /* No specific cipher => return a list of supported nids ... */
735 if (!cipher) {
736 *nids = padlock_cipher_nids;
737 return padlock_cipher_nids_num;
738 }
739
740 /* ... or the requested "cipher" otherwise */
741 switch (nid) {
742 case NID_aes_128_ecb:
743 *cipher = &padlock_aes_128_ecb;
744 break;
745 case NID_aes_128_cbc:
746 *cipher = &padlock_aes_128_cbc;
747 break;
748 case NID_aes_128_cfb:
749 *cipher = &padlock_aes_128_cfb;
750 break;
751 case NID_aes_128_ofb:
752 *cipher = &padlock_aes_128_ofb;
753 break;
754
755 case NID_aes_192_ecb:
756 *cipher = &padlock_aes_192_ecb;
757 break;
758 case NID_aes_192_cbc:
759 *cipher = &padlock_aes_192_cbc;
760 break;
761 case NID_aes_192_cfb:
762 *cipher = &padlock_aes_192_cfb;
763 break;
764 case NID_aes_192_ofb:
765 *cipher = &padlock_aes_192_ofb;
766 break;
767
768 case NID_aes_256_ecb:
769 *cipher = &padlock_aes_256_ecb;
770 break;
771 case NID_aes_256_cbc:
772 *cipher = &padlock_aes_256_cbc;
773 break;
774 case NID_aes_256_cfb:
775 *cipher = &padlock_aes_256_cfb;
776 break;
777 case NID_aes_256_ofb:
778 *cipher = &padlock_aes_256_ofb;
779 break;
780
781 default:
782 /* Sorry, we don't support this NID */
783 *cipher = NULL;
784 return 0;
785 }
786
787 return 1;
788}
789
790/* Prepare the encryption key for PadLock usage */
791static int
792padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key,
793 const unsigned char *iv, int enc)
794{
795 struct padlock_cipher_data *cdata;
796 int key_len = EVP_CIPHER_CTX_key_length(ctx) * 8;
797
798 if (key==NULL) return 0; /* ERROR */
799
800 cdata = ALIGNED_CIPHER_DATA(ctx);
801 memset(cdata, 0, sizeof(struct padlock_cipher_data));
802
803 /* Prepare Control word. */
804 if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE)
805 cdata->cword.b.encdec = 0;
806 else
807 cdata->cword.b.encdec = (ctx->encrypt == 0);
808 cdata->cword.b.rounds = 10 + (key_len - 128) / 32;
809 cdata->cword.b.ksize = (key_len - 128) / 64;
810
811 switch(key_len) {
812 case 128:
813 /* PadLock can generate an extended key for
814 AES128 in hardware */
815 memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128);
816 cdata->cword.b.keygen = 0;
817 break;
818
819 case 192:
820 case 256:
821 /* Generate an extended AES key in software.
822 Needed for AES192/AES256 */
823 /* Well, the above applies to Stepping 8 CPUs
824 and is listed as hardware errata. They most
825 likely will fix it at some point and then
826 a check for stepping would be due here. */
827 if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE ||
828 EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE ||
829 enc)
830 AES_set_encrypt_key(key, key_len, &cdata->ks);
831 else
832 AES_set_decrypt_key(key, key_len, &cdata->ks);
833#ifndef AES_ASM
834 /* OpenSSL C functions use byte-swapped extended key. */
835 padlock_bswapl(&cdata->ks);
836#endif
837 cdata->cword.b.keygen = 1;
838 break;
839
840 default:
841 /* ERROR */
842 return 0;
843 }
844
845 /*
846 * This is done to cover for cases when user reuses the
847 * context for new key. The catch is that if we don't do
848 * this, padlock_eas_cipher might proceed with old key...
849 */
850 padlock_reload_key ();
851
852 return 1;
853}
854
855/*
856 * Simplified version of padlock_aes_cipher() used when
857 * 1) both input and output buffers are at aligned addresses.
858 * or when
859 * 2) running on a newer CPU that doesn't require aligned buffers.
860 */
861static int
862padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
863 const unsigned char *in_arg, size_t nbytes)
864{
865 struct padlock_cipher_data *cdata;
866 void *iv;
867
868 cdata = ALIGNED_CIPHER_DATA(ctx);
869 padlock_verify_context(cdata);
870
871 switch (EVP_CIPHER_CTX_mode(ctx)) {
872 case EVP_CIPH_ECB_MODE:
873 padlock_xcrypt_ecb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
874 break;
875
876 case EVP_CIPH_CBC_MODE:
877 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
878 iv = padlock_xcrypt_cbc(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
879 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
880 break;
881
882 case EVP_CIPH_CFB_MODE:
883 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
884 iv = padlock_xcrypt_cfb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
885 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
886 break;
887
888 case EVP_CIPH_OFB_MODE:
889 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
890 padlock_xcrypt_ofb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
891 memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
892 break;
893
894 default:
895 return 0;
896 }
897
898 memset(cdata->iv, 0, AES_BLOCK_SIZE);
899
900 return 1;
901}
902
903#ifndef PADLOCK_CHUNK
904# define PADLOCK_CHUNK 512 /* Must be a power of 2 larger than 16 */
905#endif
906#if PADLOCK_CHUNK<16 || PADLOCK_CHUNK&(PADLOCK_CHUNK-1)
907# error "insane PADLOCK_CHUNK..."
908#endif
909
910/* Re-align the arguments to 16-Bytes boundaries and run the
911 encryption function itself. This function is not AES-specific. */
912static int
913padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
914 const unsigned char *in_arg, size_t nbytes)
915{
916 struct padlock_cipher_data *cdata;
917 const void *inp;
918 unsigned char *out;
919 void *iv;
920 int inp_misaligned, out_misaligned, realign_in_loop;
921 size_t chunk, allocated=0;
922
923 /* ctx->num is maintained in byte-oriented modes,
924 such as CFB and OFB... */
925 if ((chunk = ctx->num)) { /* borrow chunk variable */
926 unsigned char *ivp=ctx->iv;
927
928 switch (EVP_CIPHER_CTX_mode(ctx)) {
929 case EVP_CIPH_CFB_MODE:
930 if (chunk >= AES_BLOCK_SIZE)
931 return 0; /* bogus value */
932
933 if (ctx->encrypt)
934 while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
935 ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk];
936 chunk++, nbytes--;
937 }
938 else while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
939 unsigned char c = *(in_arg++);
940 *(out_arg++) = c ^ ivp[chunk];
941 ivp[chunk++] = c, nbytes--;
942 }
943
944 ctx->num = chunk%AES_BLOCK_SIZE;
945 break;
946 case EVP_CIPH_OFB_MODE:
947 if (chunk >= AES_BLOCK_SIZE)
948 return 0; /* bogus value */
949
950 while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
951 *(out_arg++) = *(in_arg++) ^ ivp[chunk];
952 chunk++, nbytes--;
953 }
954
955 ctx->num = chunk%AES_BLOCK_SIZE;
956 break;
957 }
958 }
959
960 if (nbytes == 0)
961 return 1;
962#if 0
963 if (nbytes % AES_BLOCK_SIZE)
964 return 0; /* are we expected to do tail processing? */
965#else
966 /* nbytes is always multiple of AES_BLOCK_SIZE in ECB and CBC
967 modes and arbitrary value in byte-oriented modes, such as
968 CFB and OFB... */
969#endif
970
971 /* VIA promises CPUs that won't require alignment in the future.
972 For now padlock_aes_align_required is initialized to 1 and
973 the condition is never met... */
974 /* C7 core is capable to manage unaligned input in non-ECB[!]
975 mode, but performance penalties appear to be approximately
976 same as for software alignment below or ~3x. They promise to
977 improve it in the future, but for now we can just as well
978 pretend that it can only handle aligned input... */
979 if (!padlock_aes_align_required && (nbytes%AES_BLOCK_SIZE)==0)
980 return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
981
982 inp_misaligned = (((size_t)in_arg) & 0x0F);
983 out_misaligned = (((size_t)out_arg) & 0x0F);
984
985 /* Note that even if output is aligned and input not,
986 * I still prefer to loop instead of copy the whole
987 * input and then encrypt in one stroke. This is done
988 * in order to improve L1 cache utilization... */
989 realign_in_loop = out_misaligned|inp_misaligned;
990
991 if (!realign_in_loop && (nbytes%AES_BLOCK_SIZE)==0)
992 return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
993
994 /* this takes one "if" out of the loops */
995 chunk = nbytes;
996 chunk %= PADLOCK_CHUNK;
997 if (chunk==0) chunk = PADLOCK_CHUNK;
998
999 if (out_misaligned) {
1000 /* optmize for small input */
1001 allocated = (chunk<nbytes?PADLOCK_CHUNK:nbytes);
1002 out = alloca(0x10 + allocated);
1003 out = NEAREST_ALIGNED(out);
1004 }
1005 else
1006 out = out_arg;
1007
1008 cdata = ALIGNED_CIPHER_DATA(ctx);
1009 padlock_verify_context(cdata);
1010
1011 switch (EVP_CIPHER_CTX_mode(ctx)) {
1012 case EVP_CIPH_ECB_MODE:
1013 do {
1014 if (inp_misaligned)
1015 inp = padlock_memcpy(out, in_arg, chunk);
1016 else
1017 inp = in_arg;
1018 in_arg += chunk;
1019
1020 padlock_xcrypt_ecb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1021
1022 if (out_misaligned)
1023 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1024 else
1025 out = out_arg+=chunk;
1026
1027 nbytes -= chunk;
1028 chunk = PADLOCK_CHUNK;
1029 } while (nbytes);
1030 break;
1031
1032 case EVP_CIPH_CBC_MODE:
1033 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
1034 goto cbc_shortcut;
1035 do {
1036 if (iv != cdata->iv)
1037 memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
1038 chunk = PADLOCK_CHUNK;
1039 cbc_shortcut: /* optimize for small input */
1040 if (inp_misaligned)
1041 inp = padlock_memcpy(out, in_arg, chunk);
1042 else
1043 inp = in_arg;
1044 in_arg += chunk;
1045
1046 iv = padlock_xcrypt_cbc(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1047
1048 if (out_misaligned)
1049 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1050 else
1051 out = out_arg+=chunk;
1052
1053 } while (nbytes -= chunk);
1054 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
1055 break;
1056
1057 case EVP_CIPH_CFB_MODE:
1058 memcpy (iv = cdata->iv, ctx->iv, AES_BLOCK_SIZE);
1059 chunk &= ~(AES_BLOCK_SIZE-1);
1060 if (chunk) goto cfb_shortcut;
1061 else goto cfb_skiploop;
1062 do {
1063 if (iv != cdata->iv)
1064 memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
1065 chunk = PADLOCK_CHUNK;
1066 cfb_shortcut: /* optimize for small input */
1067 if (inp_misaligned)
1068 inp = padlock_memcpy(out, in_arg, chunk);
1069 else
1070 inp = in_arg;
1071 in_arg += chunk;
1072
1073 iv = padlock_xcrypt_cfb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1074
1075 if (out_misaligned)
1076 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1077 else
1078 out = out_arg+=chunk;
1079
1080 nbytes -= chunk;
1081 } while (nbytes >= AES_BLOCK_SIZE);
1082
1083 cfb_skiploop:
1084 if (nbytes) {
1085 unsigned char *ivp = cdata->iv;
1086
1087 if (iv != ivp) {
1088 memcpy(ivp, iv, AES_BLOCK_SIZE);
1089 iv = ivp;
1090 }
1091 ctx->num = nbytes;
1092 if (cdata->cword.b.encdec) {
1093 cdata->cword.b.encdec=0;
1094 padlock_reload_key();
1095 padlock_xcrypt_ecb(1,cdata,ivp,ivp);
1096 cdata->cword.b.encdec=1;
1097 padlock_reload_key();
1098 while(nbytes) {
1099 unsigned char c = *(in_arg++);
1100 *(out_arg++) = c ^ *ivp;
1101 *(ivp++) = c, nbytes--;
1102 }
1103 }
1104 else { padlock_reload_key();
1105 padlock_xcrypt_ecb(1,cdata,ivp,ivp);
1106 padlock_reload_key();
1107 while (nbytes) {
1108 *ivp = *(out_arg++) = *(in_arg++) ^ *ivp;
1109 ivp++, nbytes--;
1110 }
1111 }
1112 }
1113
1114 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
1115 break;
1116
1117 case EVP_CIPH_OFB_MODE:
1118 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
1119 chunk &= ~(AES_BLOCK_SIZE-1);
1120 if (chunk) do {
1121 if (inp_misaligned)
1122 inp = padlock_memcpy(out, in_arg, chunk);
1123 else
1124 inp = in_arg;
1125 in_arg += chunk;
1126
1127 padlock_xcrypt_ofb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1128
1129 if (out_misaligned)
1130 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1131 else
1132 out = out_arg+=chunk;
1133
1134 nbytes -= chunk;
1135 chunk = PADLOCK_CHUNK;
1136 } while (nbytes >= AES_BLOCK_SIZE);
1137
1138 if (nbytes) {
1139 unsigned char *ivp = cdata->iv;
1140
1141 ctx->num = nbytes;
1142 padlock_reload_key(); /* empirically found */
1143 padlock_xcrypt_ecb(1,cdata,ivp,ivp);
1144 padlock_reload_key(); /* empirically found */
1145 while (nbytes) {
1146 *(out_arg++) = *(in_arg++) ^ *ivp;
1147 ivp++, nbytes--;
1148 }
1149 }
1150
1151 memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
1152 break;
1153
1154 default:
1155 return 0;
1156 }
1157
1158 /* Clean the realign buffer if it was used */
1159 if (out_misaligned) {
1160 volatile unsigned long *p=(void *)out;
1161 size_t n = allocated/sizeof(*p);
1162 while (n--) *p++=0;
1163 }
1164
1165 memset(cdata->iv, 0, AES_BLOCK_SIZE);
1166
1167 return 1;
1168}
1169
1170#endif /* OPENSSL_NO_AES */
1171
1172/* ===== Random Number Generator ===== */
1173/*
1174 * This code is not engaged. The reason is that it does not comply
1175 * with recommendations for VIA RNG usage for secure applications
1176 * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it
1177 * provide meaningful error control...
1178 */
1179/* Wrapper that provides an interface between the API and
1180 the raw PadLock RNG */
1181static int
1182padlock_rand_bytes(unsigned char *output, int count)
1183{
1184 unsigned int eax, buf;
1185
1186 while (count >= 8) {
1187 eax = padlock_xstore(output, 0);
1188 if (!(eax&(1<<6))) return 0; /* RNG disabled */
1189 /* this ---vv--- covers DC bias, Raw Bits and String Filter */
1190 if (eax&(0x1F<<10)) return 0;
1191 if ((eax&0x1F)==0) continue; /* no data, retry... */
1192 if ((eax&0x1F)!=8) return 0; /* fatal failure... */
1193 output += 8;
1194 count -= 8;
1195 }
1196 while (count > 0) {
1197 eax = padlock_xstore(&buf, 3);
1198 if (!(eax&(1<<6))) return 0; /* RNG disabled */
1199 /* this ---vv--- covers DC bias, Raw Bits and String Filter */
1200 if (eax&(0x1F<<10)) return 0;
1201 if ((eax&0x1F)==0) continue; /* no data, retry... */
1202 if ((eax&0x1F)!=1) return 0; /* fatal failure... */
1203 *output++ = (unsigned char)buf;
1204 count--;
1205 }
1206 *(volatile unsigned int *)&buf=0;
1207
1208 return 1;
1209}
1210
1211/* Dummy but necessary function */
1212static int
1213padlock_rand_status(void)
1214{
1215 return 1;
1216}
1217
1218/* Prepare structure for registration */
1219static RAND_METHOD padlock_rand = {
1220 NULL, /* seed */
1221 padlock_rand_bytes, /* bytes */
1222 NULL, /* cleanup */
1223 NULL, /* add */
1224 padlock_rand_bytes, /* pseudorand */
1225 padlock_rand_status, /* rand status */
1226};
1227
1228#else /* !COMPILE_HW_PADLOCK */
1229#ifndef OPENSSL_NO_DYNAMIC_ENGINE
1230OPENSSL_EXPORT
1231int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
1232OPENSSL_EXPORT
1233int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; }
1234IMPLEMENT_DYNAMIC_CHECK_FN()
1235#endif
1236#endif /* COMPILE_HW_PADLOCK */
1237
1238#endif /* !OPENSSL_NO_HW_PADLOCK */
1239#endif /* !OPENSSL_NO_HW */
diff --git a/src/lib/libcrypto/engine/eng_padlock.ec b/src/lib/libcrypto/engine/eng_padlock.ec
new file mode 100644
index 0000000000..a0e7cbd60d
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_padlock.ec
@@ -0,0 +1 @@
L PADLOCK eng_padlock_err.h eng_padlock_err.c
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..425720e988
--- /dev/null
+++ b/src/lib/libcrypto/engine/engine.h
@@ -0,0 +1,813 @@
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
97#include <openssl/x509.h>
98
99#ifdef __cplusplus
100extern "C" {
101#endif
102
103/* These flags are used to control combinations of algorithm (methods)
104 * by bitwise "OR"ing. */
105#define ENGINE_METHOD_RSA (unsigned int)0x0001
106#define ENGINE_METHOD_DSA (unsigned int)0x0002
107#define ENGINE_METHOD_DH (unsigned int)0x0004
108#define ENGINE_METHOD_RAND (unsigned int)0x0008
109#define ENGINE_METHOD_ECDH (unsigned int)0x0010
110#define ENGINE_METHOD_ECDSA (unsigned int)0x0020
111#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040
112#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080
113#define ENGINE_METHOD_STORE (unsigned int)0x0100
114#define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200
115#define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400
116/* Obvious all-or-nothing cases. */
117#define ENGINE_METHOD_ALL (unsigned int)0xFFFF
118#define ENGINE_METHOD_NONE (unsigned int)0x0000
119
120/* This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used
121 * internally to control registration of ENGINE implementations, and can be set
122 * by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to
123 * initialise registered ENGINEs if they are not already initialised. */
124#define ENGINE_TABLE_FLAG_NOINIT (unsigned int)0x0001
125
126/* ENGINE flags that can be set by ENGINE_set_flags(). */
127/* #define ENGINE_FLAGS_MALLOCED 0x0001 */ /* Not used */
128
129/* This flag is for ENGINEs that wish to handle the various 'CMD'-related
130 * control commands on their own. Without this flag, ENGINE_ctrl() handles these
131 * control commands on behalf of the ENGINE using their "cmd_defns" data. */
132#define ENGINE_FLAGS_MANUAL_CMD_CTRL (int)0x0002
133
134/* This flag is for ENGINEs who return new duplicate structures when found via
135 * "ENGINE_by_id()". When an ENGINE must store state (eg. if ENGINE_ctrl()
136 * commands are called in sequence as part of some stateful process like
137 * key-generation setup and execution), it can set this flag - then each attempt
138 * to obtain the ENGINE will result in it being copied into a new structure.
139 * Normally, ENGINEs don't declare this flag so ENGINE_by_id() just increments
140 * the existing ENGINE's structural reference count. */
141#define ENGINE_FLAGS_BY_ID_COPY (int)0x0004
142
143/* This flag if for an ENGINE that does not want its methods registered as
144 * part of ENGINE_register_all_complete() for example if the methods are
145 * not usable as default methods.
146 */
147
148#define ENGINE_FLAGS_NO_REGISTER_ALL (int)0x0008
149
150/* ENGINEs can support their own command types, and these flags are used in
151 * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input each
152 * command expects. Currently only numeric and string input is supported. If a
153 * control command supports none of the _NUMERIC, _STRING, or _NO_INPUT options,
154 * then it is regarded as an "internal" control command - and not for use in
155 * config setting situations. As such, they're not available to the
156 * ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() access. Changes to
157 * this list of 'command types' should be reflected carefully in
158 * ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). */
159
160/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */
161#define ENGINE_CMD_FLAG_NUMERIC (unsigned int)0x0001
162/* accepts string input (cast from 'void*' to 'const char *', 4th parameter to
163 * ENGINE_ctrl) */
164#define ENGINE_CMD_FLAG_STRING (unsigned int)0x0002
165/* Indicates that the control command takes *no* input. Ie. the control command
166 * is unparameterised. */
167#define ENGINE_CMD_FLAG_NO_INPUT (unsigned int)0x0004
168/* Indicates that the control command is internal. This control command won't
169 * be shown in any output, and is only usable through the ENGINE_ctrl_cmd()
170 * function. */
171#define ENGINE_CMD_FLAG_INTERNAL (unsigned int)0x0008
172
173/* NB: These 3 control commands are deprecated and should not be used. ENGINEs
174 * relying on these commands should compile conditional support for
175 * compatibility (eg. if these symbols are defined) but should also migrate the
176 * same functionality to their own ENGINE-specific control functions that can be
177 * "discovered" by calling applications. The fact these control commands
178 * wouldn't be "executable" (ie. usable by text-based config) doesn't change the
179 * fact that application code can find and use them without requiring per-ENGINE
180 * hacking. */
181
182/* These flags are used to tell the ctrl function what should be done.
183 * All command numbers are shared between all engines, even if some don't
184 * make sense to some engines. In such a case, they do nothing but return
185 * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */
186#define ENGINE_CTRL_SET_LOGSTREAM 1
187#define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2
188#define ENGINE_CTRL_HUP 3 /* Close and reinitialise any
189 handles/connections etc. */
190#define ENGINE_CTRL_SET_USER_INTERFACE 4 /* Alternative to callback */
191#define ENGINE_CTRL_SET_CALLBACK_DATA 5 /* User-specific data, used
192 when calling the password
193 callback and the user
194 interface */
195#define ENGINE_CTRL_LOAD_CONFIGURATION 6 /* Load a configuration, given
196 a string that represents a
197 file name or so */
198#define ENGINE_CTRL_LOAD_SECTION 7 /* Load data from a given
199 section in the already loaded
200 configuration */
201
202/* These control commands allow an application to deal with an arbitrary engine
203 * in a dynamic way. Warn: Negative return values indicate errors FOR THESE
204 * COMMANDS because zero is used to indicate 'end-of-list'. Other commands,
205 * including ENGINE-specific command types, return zero for an error.
206 *
207 * An ENGINE can choose to implement these ctrl functions, and can internally
208 * manage things however it chooses - it does so by setting the
209 * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise the
210 * ENGINE_ctrl() code handles this on the ENGINE's behalf using the cmd_defns
211 * data (set using ENGINE_set_cmd_defns()). This means an ENGINE's ctrl()
212 * handler need only implement its own commands - the above "meta" commands will
213 * be taken care of. */
214
215/* Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", then
216 * all the remaining control commands will return failure, so it is worth
217 * checking this first if the caller is trying to "discover" the engine's
218 * capabilities and doesn't want errors generated unnecessarily. */
219#define ENGINE_CTRL_HAS_CTRL_FUNCTION 10
220/* Returns a positive command number for the first command supported by the
221 * engine. Returns zero if no ctrl commands are supported. */
222#define ENGINE_CTRL_GET_FIRST_CMD_TYPE 11
223/* The 'long' argument specifies a command implemented by the engine, and the
224 * return value is the next command supported, or zero if there are no more. */
225#define ENGINE_CTRL_GET_NEXT_CMD_TYPE 12
226/* The 'void*' argument is a command name (cast from 'const char *'), and the
227 * return value is the command that corresponds to it. */
228#define ENGINE_CTRL_GET_CMD_FROM_NAME 13
229/* The next two allow a command to be converted into its corresponding string
230 * form. In each case, the 'long' argument supplies the command. In the NAME_LEN
231 * case, the return value is the length of the command name (not counting a
232 * trailing EOL). In the NAME case, the 'void*' argument must be a string buffer
233 * large enough, and it will be populated with the name of the command (WITH a
234 * trailing EOL). */
235#define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD 14
236#define ENGINE_CTRL_GET_NAME_FROM_CMD 15
237/* The next two are similar but give a "short description" of a command. */
238#define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD 16
239#define ENGINE_CTRL_GET_DESC_FROM_CMD 17
240/* With this command, the return value is the OR'd combination of
241 * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given
242 * engine-specific ctrl command expects. */
243#define ENGINE_CTRL_GET_CMD_FLAGS 18
244
245/* ENGINE implementations should start the numbering of their own control
246 * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). */
247#define ENGINE_CMD_BASE 200
248
249/* If an ENGINE supports its own specific control commands and wishes the
250 * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on its
251 * behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN entries
252 * to ENGINE_set_cmd_defns(). It should also implement a ctrl() handler that
253 * supports the stated commands (ie. the "cmd_num" entries as described by the
254 * array). NB: The array must be ordered in increasing order of cmd_num.
255 * "null-terminated" means that the last ENGINE_CMD_DEFN element has cmd_num set
256 * to zero and/or cmd_name set to NULL. */
257typedef struct ENGINE_CMD_DEFN_st
258 {
259 unsigned int cmd_num; /* The command number */
260 const char *cmd_name; /* The command name itself */
261 const char *cmd_desc; /* A short description of the command */
262 unsigned int cmd_flags; /* The input the command expects */
263 } ENGINE_CMD_DEFN;
264
265/* Generic function pointer */
266typedef int (*ENGINE_GEN_FUNC_PTR)(void);
267/* Generic function pointer taking no arguments */
268typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *);
269/* Specific control function pointer */
270typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, void (*f)(void));
271/* Generic load_key function pointer */
272typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
273 UI_METHOD *ui_method, void *callback_data);
274typedef int (*ENGINE_SSL_CLIENT_CERT_PTR)(ENGINE *, SSL *ssl,
275 STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
276 STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data);
277/* These callback types are for an ENGINE's handler for cipher and digest logic.
278 * These handlers have these prototypes;
279 * int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
280 * int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid);
281 * Looking at how to implement these handlers in the case of cipher support, if
282 * the framework wants the EVP_CIPHER for 'nid', it will call;
283 * foo(e, &p_evp_cipher, NULL, nid); (return zero for failure)
284 * If the framework wants a list of supported 'nid's, it will call;
285 * foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error)
286 */
287/* Returns to a pointer to the array of supported cipher 'nid's. If the second
288 * parameter is non-NULL it is set to the size of the returned array. */
289typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int);
290typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int);
291typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, EVP_PKEY_METHOD **, const int **, int);
292typedef int (*ENGINE_PKEY_ASN1_METHS_PTR)(ENGINE *, EVP_PKEY_ASN1_METHOD **, const int **, int);
293/* STRUCTURE functions ... all of these functions deal with pointers to ENGINE
294 * structures where the pointers have a "structural reference". This means that
295 * their reference is to allowed access to the structure but it does not imply
296 * that the structure is functional. To simply increment or decrement the
297 * structural reference count, use ENGINE_by_id and ENGINE_free. NB: This is not
298 * required when iterating using ENGINE_get_next as it will automatically
299 * decrement the structural reference count of the "current" ENGINE and
300 * increment the structural reference count of the ENGINE it returns (unless it
301 * is NULL). */
302
303/* Get the first/last "ENGINE" type available. */
304ENGINE *ENGINE_get_first(void);
305ENGINE *ENGINE_get_last(void);
306/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
307ENGINE *ENGINE_get_next(ENGINE *e);
308ENGINE *ENGINE_get_prev(ENGINE *e);
309/* Add another "ENGINE" type into the array. */
310int ENGINE_add(ENGINE *e);
311/* Remove an existing "ENGINE" type from the array. */
312int ENGINE_remove(ENGINE *e);
313/* Retrieve an engine from the list by its unique "id" value. */
314ENGINE *ENGINE_by_id(const char *id);
315/* Add all the built-in engines. */
316void ENGINE_load_openssl(void);
317void ENGINE_load_dynamic(void);
318#ifndef OPENSSL_NO_STATIC_ENGINE
319void ENGINE_load_padlock(void);
320#ifndef OPENSSL_NO_GOST
321void ENGINE_load_gost(void);
322#endif
323#endif
324void ENGINE_load_cryptodev(void);
325void ENGINE_load_rsax(void);
326void ENGINE_load_rdrand(void);
327void ENGINE_load_builtin_engines(void);
328
329/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
330 * "registry" handling. */
331unsigned int ENGINE_get_table_flags(void);
332void ENGINE_set_table_flags(unsigned int flags);
333
334/* Manage registration of ENGINEs per "table". For each type, there are 3
335 * functions;
336 * ENGINE_register_***(e) - registers the implementation from 'e' (if it has one)
337 * ENGINE_unregister_***(e) - unregister the implementation from 'e'
338 * ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list
339 * Cleanup is automatically registered from each table when required, so
340 * ENGINE_cleanup() will reverse any "register" operations. */
341
342int ENGINE_register_RSA(ENGINE *e);
343void ENGINE_unregister_RSA(ENGINE *e);
344void ENGINE_register_all_RSA(void);
345
346int ENGINE_register_DSA(ENGINE *e);
347void ENGINE_unregister_DSA(ENGINE *e);
348void ENGINE_register_all_DSA(void);
349
350int ENGINE_register_ECDH(ENGINE *e);
351void ENGINE_unregister_ECDH(ENGINE *e);
352void ENGINE_register_all_ECDH(void);
353
354int ENGINE_register_ECDSA(ENGINE *e);
355void ENGINE_unregister_ECDSA(ENGINE *e);
356void ENGINE_register_all_ECDSA(void);
357
358int ENGINE_register_DH(ENGINE *e);
359void ENGINE_unregister_DH(ENGINE *e);
360void ENGINE_register_all_DH(void);
361
362int ENGINE_register_RAND(ENGINE *e);
363void ENGINE_unregister_RAND(ENGINE *e);
364void ENGINE_register_all_RAND(void);
365
366int ENGINE_register_STORE(ENGINE *e);
367void ENGINE_unregister_STORE(ENGINE *e);
368void ENGINE_register_all_STORE(void);
369
370int ENGINE_register_ciphers(ENGINE *e);
371void ENGINE_unregister_ciphers(ENGINE *e);
372void ENGINE_register_all_ciphers(void);
373
374int ENGINE_register_digests(ENGINE *e);
375void ENGINE_unregister_digests(ENGINE *e);
376void ENGINE_register_all_digests(void);
377
378int ENGINE_register_pkey_meths(ENGINE *e);
379void ENGINE_unregister_pkey_meths(ENGINE *e);
380void ENGINE_register_all_pkey_meths(void);
381
382int ENGINE_register_pkey_asn1_meths(ENGINE *e);
383void ENGINE_unregister_pkey_asn1_meths(ENGINE *e);
384void ENGINE_register_all_pkey_asn1_meths(void);
385
386/* These functions register all support from the above categories. Note, use of
387 * these functions can result in static linkage of code your application may not
388 * need. If you only need a subset of functionality, consider using more
389 * selective initialisation. */
390int ENGINE_register_complete(ENGINE *e);
391int ENGINE_register_all_complete(void);
392
393/* Send parametrised control commands to the engine. The possibilities to send
394 * down an integer, a pointer to data or a function pointer are provided. Any of
395 * the parameters may or may not be NULL, depending on the command number. In
396 * actuality, this function only requires a structural (rather than functional)
397 * reference to an engine, but many control commands may require the engine be
398 * functional. The caller should be aware of trying commands that require an
399 * operational ENGINE, and only use functional references in such situations. */
400int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
401
402/* This function tests if an ENGINE-specific command is usable as a "setting".
403 * Eg. in an application's config file that gets processed through
404 * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to
405 * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). */
406int ENGINE_cmd_is_executable(ENGINE *e, int cmd);
407
408/* This function works like ENGINE_ctrl() with the exception of taking a
409 * command name instead of a command number, and can handle optional commands.
410 * See the comment on ENGINE_ctrl_cmd_string() for an explanation on how to
411 * use the cmd_name and cmd_optional. */
412int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
413 long i, void *p, void (*f)(void), int cmd_optional);
414
415/* This function passes a command-name and argument to an ENGINE. The cmd_name
416 * is converted to a command number and the control command is called using
417 * 'arg' as an argument (unless the ENGINE doesn't support such a command, in
418 * which case no control command is called). The command is checked for input
419 * flags, and if necessary the argument will be converted to a numeric value. If
420 * cmd_optional is non-zero, then if the ENGINE doesn't support the given
421 * cmd_name the return value will be success anyway. This function is intended
422 * for applications to use so that users (or config files) can supply
423 * engine-specific config data to the ENGINE at run-time to control behaviour of
424 * specific engines. As such, it shouldn't be used for calling ENGINE_ctrl()
425 * functions that return data, deal with binary data, or that are otherwise
426 * supposed to be used directly through ENGINE_ctrl() in application code. Any
427 * "return" data from an ENGINE_ctrl() operation in this function will be lost -
428 * the return value is interpreted as failure if the return value is zero,
429 * success otherwise, and this function returns a boolean value as a result. In
430 * other words, vendors of 'ENGINE'-enabled devices should write ENGINE
431 * implementations with parameterisations that work in this scheme, so that
432 * compliant ENGINE-based applications can work consistently with the same
433 * configuration for the same ENGINE-enabled devices, across applications. */
434int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
435 int cmd_optional);
436
437/* These functions are useful for manufacturing new ENGINE structures. They
438 * don't address reference counting at all - one uses them to populate an ENGINE
439 * structure with personalised implementations of things prior to using it
440 * directly or adding it to the builtin ENGINE list in OpenSSL. These are also
441 * here so that the ENGINE structure doesn't have to be exposed and break binary
442 * compatibility! */
443ENGINE *ENGINE_new(void);
444int ENGINE_free(ENGINE *e);
445int ENGINE_up_ref(ENGINE *e);
446int ENGINE_set_id(ENGINE *e, const char *id);
447int ENGINE_set_name(ENGINE *e, const char *name);
448int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
449int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
450int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth);
451int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth);
452int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
453int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
454int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth);
455int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
456int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
457int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
458int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
459int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f);
460int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
461int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
462 ENGINE_SSL_CLIENT_CERT_PTR loadssl_f);
463int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
464int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
465int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f);
466int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f);
467int ENGINE_set_flags(ENGINE *e, int flags);
468int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
469/* These functions allow control over any per-structure ENGINE data. */
470int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
471 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
472int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
473void *ENGINE_get_ex_data(const ENGINE *e, int idx);
474
475/* This function cleans up anything that needs it. Eg. the ENGINE_add() function
476 * automatically ensures the list cleanup function is registered to be called
477 * from ENGINE_cleanup(). Similarly, all ENGINE_register_*** functions ensure
478 * ENGINE_cleanup() will clean up after them. */
479void ENGINE_cleanup(void);
480
481/* These return values from within the ENGINE structure. These can be useful
482 * with functional references as well as structural references - it depends
483 * which you obtained. Using the result for functional purposes if you only
484 * obtained a structural reference may be problematic! */
485const char *ENGINE_get_id(const ENGINE *e);
486const char *ENGINE_get_name(const ENGINE *e);
487const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
488const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
489const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e);
490const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e);
491const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
492const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
493const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e);
494ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
495ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
496ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
497ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
498ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
499ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
500ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e);
501ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
502ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
503ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e);
504ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e);
505const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
506const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
507const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
508const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
509const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
510 const char *str, int len);
511const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
512 const char *str, int len);
513const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
514int ENGINE_get_flags(const ENGINE *e);
515
516/* FUNCTIONAL functions. These functions deal with ENGINE structures
517 * that have (or will) be initialised for use. Broadly speaking, the
518 * structural functions are useful for iterating the list of available
519 * engine types, creating new engine types, and other "list" operations.
520 * These functions actually deal with ENGINEs that are to be used. As
521 * such these functions can fail (if applicable) when particular
522 * engines are unavailable - eg. if a hardware accelerator is not
523 * attached or not functioning correctly. Each ENGINE has 2 reference
524 * counts; structural and functional. Every time a functional reference
525 * is obtained or released, a corresponding structural reference is
526 * automatically obtained or released too. */
527
528/* Initialise a engine type for use (or up its reference count if it's
529 * already in use). This will fail if the engine is not currently
530 * operational and cannot initialise. */
531int ENGINE_init(ENGINE *e);
532/* Free a functional reference to a engine type. This does not require
533 * a corresponding call to ENGINE_free as it also releases a structural
534 * reference. */
535int ENGINE_finish(ENGINE *e);
536
537/* The following functions handle keys that are stored in some secondary
538 * location, handled by the engine. The storage may be on a card or
539 * whatever. */
540EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
541 UI_METHOD *ui_method, void *callback_data);
542EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
543 UI_METHOD *ui_method, void *callback_data);
544int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
545 STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey,
546 STACK_OF(X509) **pother,
547 UI_METHOD *ui_method, void *callback_data);
548
549/* This returns a pointer for the current ENGINE structure that
550 * is (by default) performing any RSA operations. The value returned
551 * is an incremented reference, so it should be free'd (ENGINE_finish)
552 * before it is discarded. */
553ENGINE *ENGINE_get_default_RSA(void);
554/* Same for the other "methods" */
555ENGINE *ENGINE_get_default_DSA(void);
556ENGINE *ENGINE_get_default_ECDH(void);
557ENGINE *ENGINE_get_default_ECDSA(void);
558ENGINE *ENGINE_get_default_DH(void);
559ENGINE *ENGINE_get_default_RAND(void);
560/* These functions can be used to get a functional reference to perform
561 * ciphering or digesting corresponding to "nid". */
562ENGINE *ENGINE_get_cipher_engine(int nid);
563ENGINE *ENGINE_get_digest_engine(int nid);
564ENGINE *ENGINE_get_pkey_meth_engine(int nid);
565ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid);
566
567/* This sets a new default ENGINE structure for performing RSA
568 * operations. If the result is non-zero (success) then the ENGINE
569 * structure will have had its reference count up'd so the caller
570 * should still free their own reference 'e'. */
571int ENGINE_set_default_RSA(ENGINE *e);
572int ENGINE_set_default_string(ENGINE *e, const char *def_list);
573/* Same for the other "methods" */
574int ENGINE_set_default_DSA(ENGINE *e);
575int ENGINE_set_default_ECDH(ENGINE *e);
576int ENGINE_set_default_ECDSA(ENGINE *e);
577int ENGINE_set_default_DH(ENGINE *e);
578int ENGINE_set_default_RAND(ENGINE *e);
579int ENGINE_set_default_ciphers(ENGINE *e);
580int ENGINE_set_default_digests(ENGINE *e);
581int ENGINE_set_default_pkey_meths(ENGINE *e);
582int ENGINE_set_default_pkey_asn1_meths(ENGINE *e);
583
584/* The combination "set" - the flags are bitwise "OR"d from the
585 * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
586 * function, this function can result in unnecessary static linkage. If your
587 * application requires only specific functionality, consider using more
588 * selective functions. */
589int ENGINE_set_default(ENGINE *e, unsigned int flags);
590
591void ENGINE_add_conf_module(void);
592
593/* Deprecated functions ... */
594/* int ENGINE_clear_defaults(void); */
595
596/**************************/
597/* DYNAMIC ENGINE SUPPORT */
598/**************************/
599
600/* Binary/behaviour compatibility levels */
601#define OSSL_DYNAMIC_VERSION (unsigned long)0x00020000
602/* Binary versions older than this are too old for us (whether we're a loader or
603 * a loadee) */
604#define OSSL_DYNAMIC_OLDEST (unsigned long)0x00020000
605
606/* When compiling an ENGINE entirely as an external shared library, loadable by
607 * the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' structure
608 * type provides the calling application's (or library's) error functionality
609 * and memory management function pointers to the loaded library. These should
610 * be used/set in the loaded library code so that the loading application's
611 * 'state' will be used/changed in all operations. The 'static_state' pointer
612 * allows the loaded library to know if it shares the same static data as the
613 * calling application (or library), and thus whether these callbacks need to be
614 * set or not. */
615typedef void *(*dyn_MEM_malloc_cb)(size_t);
616typedef void *(*dyn_MEM_realloc_cb)(void *, size_t);
617typedef void (*dyn_MEM_free_cb)(void *);
618typedef struct st_dynamic_MEM_fns {
619 dyn_MEM_malloc_cb malloc_cb;
620 dyn_MEM_realloc_cb realloc_cb;
621 dyn_MEM_free_cb free_cb;
622 } dynamic_MEM_fns;
623/* FIXME: Perhaps the memory and locking code (crypto.h) should declare and use
624 * these types so we (and any other dependant code) can simplify a bit?? */
625typedef void (*dyn_lock_locking_cb)(int,int,const char *,int);
626typedef int (*dyn_lock_add_lock_cb)(int*,int,int,const char *,int);
627typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb)(
628 const char *,int);
629typedef void (*dyn_dynlock_lock_cb)(int,struct CRYPTO_dynlock_value *,
630 const char *,int);
631typedef void (*dyn_dynlock_destroy_cb)(struct CRYPTO_dynlock_value *,
632 const char *,int);
633typedef struct st_dynamic_LOCK_fns {
634 dyn_lock_locking_cb lock_locking_cb;
635 dyn_lock_add_lock_cb lock_add_lock_cb;
636 dyn_dynlock_create_cb dynlock_create_cb;
637 dyn_dynlock_lock_cb dynlock_lock_cb;
638 dyn_dynlock_destroy_cb dynlock_destroy_cb;
639 } dynamic_LOCK_fns;
640/* The top-level structure */
641typedef struct st_dynamic_fns {
642 void *static_state;
643 const ERR_FNS *err_fns;
644 const CRYPTO_EX_DATA_IMPL *ex_data_fns;
645 dynamic_MEM_fns mem_fns;
646 dynamic_LOCK_fns lock_fns;
647 } dynamic_fns;
648
649/* The version checking function should be of this prototype. NB: The
650 * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading code.
651 * If this function returns zero, it indicates a (potential) version
652 * incompatibility and the loaded library doesn't believe it can proceed.
653 * Otherwise, the returned value is the (latest) version supported by the
654 * loading library. The loader may still decide that the loaded code's version
655 * is unsatisfactory and could veto the load. The function is expected to
656 * be implemented with the symbol name "v_check", and a default implementation
657 * can be fully instantiated with IMPLEMENT_DYNAMIC_CHECK_FN(). */
658typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version);
659#define IMPLEMENT_DYNAMIC_CHECK_FN() \
660 OPENSSL_EXPORT unsigned long v_check(unsigned long v); \
661 OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \
662 if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \
663 return 0; }
664
665/* This function is passed the ENGINE structure to initialise with its own
666 * function and command settings. It should not adjust the structural or
667 * functional reference counts. If this function returns zero, (a) the load will
668 * be aborted, (b) the previous ENGINE state will be memcpy'd back onto the
669 * structure, and (c) the shared library will be unloaded. So implementations
670 * should do their own internal cleanup in failure circumstances otherwise they
671 * could leak. The 'id' parameter, if non-NULL, represents the ENGINE id that
672 * the loader is looking for. If this is NULL, the shared library can choose to
673 * return failure or to initialise a 'default' ENGINE. If non-NULL, the shared
674 * library must initialise only an ENGINE matching the passed 'id'. The function
675 * is expected to be implemented with the symbol name "bind_engine". A standard
676 * implementation can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where
677 * the parameter 'fn' is a callback function that populates the ENGINE structure
678 * and returns an int value (zero for failure). 'fn' should have prototype;
679 * [static] int fn(ENGINE *e, const char *id); */
680typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id,
681 const dynamic_fns *fns);
682#define IMPLEMENT_DYNAMIC_BIND_FN(fn) \
683 OPENSSL_EXPORT \
684 int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \
685 OPENSSL_EXPORT \
686 int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \
687 if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \
688 if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \
689 fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \
690 return 0; \
691 CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \
692 CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \
693 CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \
694 CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \
695 CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \
696 if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \
697 return 0; \
698 if(!ERR_set_implementation(fns->err_fns)) return 0; \
699 skip_cbs: \
700 if(!fn(e,id)) return 0; \
701 return 1; }
702
703/* If the loading application (or library) and the loaded ENGINE library share
704 * the same static data (eg. they're both dynamically linked to the same
705 * libcrypto.so) we need a way to avoid trying to set system callbacks - this
706 * would fail, and for the same reason that it's unnecessary to try. If the
707 * loaded ENGINE has (or gets from through the loader) its own copy of the
708 * libcrypto static data, we will need to set the callbacks. The easiest way to
709 * detect this is to have a function that returns a pointer to some static data
710 * and let the loading application and loaded ENGINE compare their respective
711 * values. */
712void *ENGINE_get_static_state(void);
713
714#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
715void ENGINE_setup_bsd_cryptodev(void);
716#endif
717
718/* BEGIN ERROR CODES */
719/* The following lines are auto generated by the script mkerr.pl. Any changes
720 * made after this point may be overwritten when the script is next run.
721 */
722void ERR_load_ENGINE_strings(void);
723
724/* Error codes for the ENGINE functions. */
725
726/* Function codes. */
727#define ENGINE_F_DYNAMIC_CTRL 180
728#define ENGINE_F_DYNAMIC_GET_DATA_CTX 181
729#define ENGINE_F_DYNAMIC_LOAD 182
730#define ENGINE_F_DYNAMIC_SET_DATA_CTX 183
731#define ENGINE_F_ENGINE_ADD 105
732#define ENGINE_F_ENGINE_BY_ID 106
733#define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170
734#define ENGINE_F_ENGINE_CTRL 142
735#define ENGINE_F_ENGINE_CTRL_CMD 178
736#define ENGINE_F_ENGINE_CTRL_CMD_STRING 171
737#define ENGINE_F_ENGINE_FINISH 107
738#define ENGINE_F_ENGINE_FREE_UTIL 108
739#define ENGINE_F_ENGINE_GET_CIPHER 185
740#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177
741#define ENGINE_F_ENGINE_GET_DIGEST 186
742#define ENGINE_F_ENGINE_GET_NEXT 115
743#define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193
744#define ENGINE_F_ENGINE_GET_PKEY_METH 192
745#define ENGINE_F_ENGINE_GET_PREV 116
746#define ENGINE_F_ENGINE_INIT 119
747#define ENGINE_F_ENGINE_LIST_ADD 120
748#define ENGINE_F_ENGINE_LIST_REMOVE 121
749#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150
750#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151
751#define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194
752#define ENGINE_F_ENGINE_NEW 122
753#define ENGINE_F_ENGINE_REMOVE 123
754#define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189
755#define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126
756#define ENGINE_F_ENGINE_SET_ID 129
757#define ENGINE_F_ENGINE_SET_NAME 130
758#define ENGINE_F_ENGINE_TABLE_REGISTER 184
759#define ENGINE_F_ENGINE_UNLOAD_KEY 152
760#define ENGINE_F_ENGINE_UNLOCKED_FINISH 191
761#define ENGINE_F_ENGINE_UP_REF 190
762#define ENGINE_F_INT_CTRL_HELPER 172
763#define ENGINE_F_INT_ENGINE_CONFIGURE 188
764#define ENGINE_F_INT_ENGINE_MODULE_INIT 187
765#define ENGINE_F_LOG_MESSAGE 141
766
767/* Reason codes. */
768#define ENGINE_R_ALREADY_LOADED 100
769#define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER 133
770#define ENGINE_R_CMD_NOT_EXECUTABLE 134
771#define ENGINE_R_COMMAND_TAKES_INPUT 135
772#define ENGINE_R_COMMAND_TAKES_NO_INPUT 136
773#define ENGINE_R_CONFLICTING_ENGINE_ID 103
774#define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119
775#define ENGINE_R_DH_NOT_IMPLEMENTED 139
776#define ENGINE_R_DSA_NOT_IMPLEMENTED 140
777#define ENGINE_R_DSO_FAILURE 104
778#define ENGINE_R_DSO_NOT_FOUND 132
779#define ENGINE_R_ENGINES_SECTION_ERROR 148
780#define ENGINE_R_ENGINE_CONFIGURATION_ERROR 102
781#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105
782#define ENGINE_R_ENGINE_SECTION_ERROR 149
783#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128
784#define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129
785#define ENGINE_R_FINISH_FAILED 106
786#define ENGINE_R_GET_HANDLE_FAILED 107
787#define ENGINE_R_ID_OR_NAME_MISSING 108
788#define ENGINE_R_INIT_FAILED 109
789#define ENGINE_R_INTERNAL_LIST_ERROR 110
790#define ENGINE_R_INVALID_ARGUMENT 143
791#define ENGINE_R_INVALID_CMD_NAME 137
792#define ENGINE_R_INVALID_CMD_NUMBER 138
793#define ENGINE_R_INVALID_INIT_VALUE 151
794#define ENGINE_R_INVALID_STRING 150
795#define ENGINE_R_NOT_INITIALISED 117
796#define ENGINE_R_NOT_LOADED 112
797#define ENGINE_R_NO_CONTROL_FUNCTION 120
798#define ENGINE_R_NO_INDEX 144
799#define ENGINE_R_NO_LOAD_FUNCTION 125
800#define ENGINE_R_NO_REFERENCE 130
801#define ENGINE_R_NO_SUCH_ENGINE 116
802#define ENGINE_R_NO_UNLOAD_FUNCTION 126
803#define ENGINE_R_PROVIDE_PARAMETERS 113
804#define ENGINE_R_RSA_NOT_IMPLEMENTED 141
805#define ENGINE_R_UNIMPLEMENTED_CIPHER 146
806#define ENGINE_R_UNIMPLEMENTED_DIGEST 147
807#define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101
808#define ENGINE_R_VERSION_INCOMPATIBILITY 145
809
810#ifdef __cplusplus
811}
812#endif
813#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..bc953872dd
--- /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 xcryptcbc; 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 xcryptcbc" :
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 }