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/Makefile447
-rw-r--r--src/lib/libcrypto/engine/eng_aesni.c570
-rw-r--r--src/lib/libcrypto/engine/eng_all.c1
-rw-r--r--src/lib/libcrypto/engine/eng_cryptodev.c1449
-rw-r--r--src/lib/libcrypto/engine/eng_list.c1
-rw-r--r--src/lib/libcrypto/engine/eng_rdrand.c143
-rw-r--r--src/lib/libcrypto/engine/eng_rsax.c668
-rw-r--r--src/lib/libcrypto/engine/enginetest.c283
-rw-r--r--src/lib/libcrypto/engine/hw_cryptodev.c1367
9 files changed, 4928 insertions, 1 deletions
diff --git a/src/lib/libcrypto/engine/Makefile b/src/lib/libcrypto/engine/Makefile
new file mode 100644
index 0000000000..d29bdd09a0
--- /dev/null
+++ b/src/lib/libcrypto/engine/Makefile
@@ -0,0 +1,447 @@
1#
2# OpenSSL/crypto/engine/Makefile
3#
4
5DIR= engine
6TOP= ../..
7CC= cc
8INCLUDES= -I.. -I$(TOP) -I../../include
9CFLAG=-g
10MAKEFILE= Makefile
11AR= ar r
12
13CFLAGS= $(INCLUDES) $(CFLAG)
14
15GENERAL=Makefile
16TEST= enginetest.c
17APPS=
18
19LIB=$(TOP)/libcrypto.a
20LIBSRC= eng_err.c eng_lib.c eng_list.c eng_init.c eng_ctrl.c \
21 eng_table.c eng_pkey.c eng_fat.c eng_all.c \
22 tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
23 tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c \
24 eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c \
25 eng_rsax.c eng_rdrand.c
26LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
27 eng_table.o eng_pkey.o eng_fat.o eng_all.o \
28 tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
29 tb_cipher.o tb_digest.o tb_pkmeth.o tb_asnmth.o \
30 eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o \
31 eng_rsax.o eng_rdrand.o
32
33SRC= $(LIBSRC)
34
35EXHEADER= engine.h
36HEADER= $(EXHEADER)
37
38ALL= $(GENERAL) $(SRC) $(HEADER)
39
40top:
41 (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
42
43all: lib
44
45lib: $(LIBOBJ)
46 $(AR) $(LIB) $(LIBOBJ)
47 $(RANLIB) $(LIB) || echo Never mind.
48 @touch lib
49
50files:
51 $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
52
53links:
54 @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
55 @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
56 @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
57
58install:
59 @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
60 @headerlist="$(EXHEADER)"; for i in $$headerlist ; \
61 do \
62 (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
63 chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
64 done;
65
66tags:
67 ctags $(SRC)
68
69tests:
70
71lint:
72 lint -DLINT $(INCLUDES) $(SRC)>fluff
73
74depend:
75 @[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
76 $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
77
78dclean:
79 $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
80 mv -f Makefile.new $(MAKEFILE)
81
82clean:
83 rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
84
85# DO NOT DELETE THIS LINE -- make depend depends on it.
86
87eng_all.o: ../../e_os.h ../../include/openssl/asn1.h
88eng_all.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
89eng_all.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
90eng_all.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
91eng_all.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
92eng_all.o: ../../include/openssl/err.h ../../include/openssl/evp.h
93eng_all.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
94eng_all.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
95eng_all.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
96eng_all.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
97eng_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
98eng_all.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
99eng_all.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_all.c eng_int.h
100eng_cnf.o: ../../e_os.h ../../include/openssl/asn1.h
101eng_cnf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
102eng_cnf.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
103eng_cnf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
104eng_cnf.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
105eng_cnf.o: ../../include/openssl/engine.h ../../include/openssl/err.h
106eng_cnf.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
107eng_cnf.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
108eng_cnf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
109eng_cnf.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
110eng_cnf.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
111eng_cnf.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
112eng_cnf.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
113eng_cnf.o: ../cryptlib.h eng_cnf.c eng_int.h
114eng_cryptodev.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
115eng_cryptodev.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
116eng_cryptodev.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
117eng_cryptodev.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
118eng_cryptodev.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
119eng_cryptodev.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
120eng_cryptodev.o: ../../include/openssl/obj_mac.h
121eng_cryptodev.o: ../../include/openssl/objects.h
122eng_cryptodev.o: ../../include/openssl/opensslconf.h
123eng_cryptodev.o: ../../include/openssl/opensslv.h
124eng_cryptodev.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
125eng_cryptodev.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
126eng_cryptodev.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
127eng_cryptodev.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
128eng_cryptodev.o: eng_cryptodev.c
129eng_ctrl.o: ../../e_os.h ../../include/openssl/asn1.h
130eng_ctrl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
131eng_ctrl.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
132eng_ctrl.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
133eng_ctrl.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
134eng_ctrl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
135eng_ctrl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
136eng_ctrl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
137eng_ctrl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
138eng_ctrl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
139eng_ctrl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
140eng_ctrl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
141eng_ctrl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_ctrl.c eng_int.h
142eng_dyn.o: ../../e_os.h ../../include/openssl/asn1.h
143eng_dyn.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
144eng_dyn.o: ../../include/openssl/crypto.h ../../include/openssl/dso.h
145eng_dyn.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
146eng_dyn.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
147eng_dyn.o: ../../include/openssl/engine.h ../../include/openssl/err.h
148eng_dyn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
149eng_dyn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
150eng_dyn.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
151eng_dyn.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
152eng_dyn.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
153eng_dyn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
154eng_dyn.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
155eng_dyn.o: ../cryptlib.h eng_dyn.c eng_int.h
156eng_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
157eng_err.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
158eng_err.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
159eng_err.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
160eng_err.o: ../../include/openssl/engine.h ../../include/openssl/err.h
161eng_err.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
162eng_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
163eng_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
164eng_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
165eng_err.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
166eng_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
167eng_err.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
168eng_err.o: eng_err.c
169eng_fat.o: ../../e_os.h ../../include/openssl/asn1.h
170eng_fat.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
171eng_fat.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
172eng_fat.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
173eng_fat.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
174eng_fat.o: ../../include/openssl/engine.h ../../include/openssl/err.h
175eng_fat.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
176eng_fat.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
177eng_fat.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
178eng_fat.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
179eng_fat.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
180eng_fat.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
181eng_fat.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
182eng_fat.o: ../cryptlib.h eng_fat.c eng_int.h
183eng_init.o: ../../e_os.h ../../include/openssl/asn1.h
184eng_init.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
185eng_init.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
186eng_init.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
187eng_init.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
188eng_init.o: ../../include/openssl/err.h ../../include/openssl/evp.h
189eng_init.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
190eng_init.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
191eng_init.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
192eng_init.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
193eng_init.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
194eng_init.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
195eng_init.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_init.c eng_int.h
196eng_lib.o: ../../e_os.h ../../include/openssl/asn1.h
197eng_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
198eng_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
199eng_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
200eng_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
201eng_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
202eng_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
203eng_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
204eng_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
205eng_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
206eng_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
207eng_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
208eng_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
209eng_lib.o: ../cryptlib.h eng_int.h eng_lib.c
210eng_list.o: ../../e_os.h ../../include/openssl/asn1.h
211eng_list.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
212eng_list.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
213eng_list.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
214eng_list.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
215eng_list.o: ../../include/openssl/err.h ../../include/openssl/evp.h
216eng_list.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
217eng_list.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
218eng_list.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
219eng_list.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
220eng_list.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
221eng_list.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
222eng_list.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h eng_list.c
223eng_openssl.o: ../../e_os.h ../../include/openssl/asn1.h
224eng_openssl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
225eng_openssl.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
226eng_openssl.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
227eng_openssl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
228eng_openssl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
229eng_openssl.o: ../../include/openssl/engine.h ../../include/openssl/err.h
230eng_openssl.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
231eng_openssl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
232eng_openssl.o: ../../include/openssl/opensslconf.h
233eng_openssl.o: ../../include/openssl/opensslv.h
234eng_openssl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
235eng_openssl.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
236eng_openssl.o: ../../include/openssl/rand.h ../../include/openssl/rc4.h
237eng_openssl.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
238eng_openssl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
239eng_openssl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
240eng_openssl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_openssl.c
241eng_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
242eng_pkey.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
243eng_pkey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
244eng_pkey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
245eng_pkey.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
246eng_pkey.o: ../../include/openssl/err.h ../../include/openssl/evp.h
247eng_pkey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
248eng_pkey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
249eng_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
250eng_pkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
251eng_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
252eng_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
253eng_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h eng_pkey.c
254eng_rdrand.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
255eng_rdrand.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
256eng_rdrand.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
257eng_rdrand.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
258eng_rdrand.o: ../../include/openssl/engine.h ../../include/openssl/err.h
259eng_rdrand.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
260eng_rdrand.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
261eng_rdrand.o: ../../include/openssl/opensslconf.h
262eng_rdrand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
263eng_rdrand.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
264eng_rdrand.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
265eng_rdrand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
266eng_rdrand.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
267eng_rdrand.o: eng_rdrand.c
268eng_rsax.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
269eng_rsax.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
270eng_rsax.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
271eng_rsax.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
272eng_rsax.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
273eng_rsax.o: ../../include/openssl/err.h ../../include/openssl/evp.h
274eng_rsax.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
275eng_rsax.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
276eng_rsax.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
277eng_rsax.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
278eng_rsax.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
279eng_rsax.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
280eng_rsax.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
281eng_rsax.o: eng_rsax.c
282eng_table.o: ../../e_os.h ../../include/openssl/asn1.h
283eng_table.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
284eng_table.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
285eng_table.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
286eng_table.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
287eng_table.o: ../../include/openssl/err.h ../../include/openssl/evp.h
288eng_table.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
289eng_table.o: ../../include/openssl/objects.h
290eng_table.o: ../../include/openssl/opensslconf.h
291eng_table.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
292eng_table.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
293eng_table.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
294eng_table.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
295eng_table.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
296eng_table.o: eng_table.c
297tb_asnmth.o: ../../e_os.h ../../include/openssl/asn1.h
298tb_asnmth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
299tb_asnmth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
300tb_asnmth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
301tb_asnmth.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
302tb_asnmth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
303tb_asnmth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
304tb_asnmth.o: ../../include/openssl/objects.h
305tb_asnmth.o: ../../include/openssl/opensslconf.h
306tb_asnmth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
307tb_asnmth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
308tb_asnmth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
309tb_asnmth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
310tb_asnmth.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h
311tb_asnmth.o: eng_int.h tb_asnmth.c
312tb_cipher.o: ../../e_os.h ../../include/openssl/asn1.h
313tb_cipher.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
314tb_cipher.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
315tb_cipher.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
316tb_cipher.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
317tb_cipher.o: ../../include/openssl/err.h ../../include/openssl/evp.h
318tb_cipher.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
319tb_cipher.o: ../../include/openssl/objects.h
320tb_cipher.o: ../../include/openssl/opensslconf.h
321tb_cipher.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
322tb_cipher.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
323tb_cipher.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
324tb_cipher.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
325tb_cipher.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
326tb_cipher.o: tb_cipher.c
327tb_dh.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
328tb_dh.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
329tb_dh.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
330tb_dh.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
331tb_dh.o: ../../include/openssl/engine.h ../../include/openssl/err.h
332tb_dh.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
333tb_dh.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
334tb_dh.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
335tb_dh.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
336tb_dh.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
337tb_dh.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
338tb_dh.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
339tb_dh.o: ../cryptlib.h eng_int.h tb_dh.c
340tb_digest.o: ../../e_os.h ../../include/openssl/asn1.h
341tb_digest.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
342tb_digest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
343tb_digest.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
344tb_digest.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
345tb_digest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
346tb_digest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
347tb_digest.o: ../../include/openssl/objects.h
348tb_digest.o: ../../include/openssl/opensslconf.h
349tb_digest.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
350tb_digest.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
351tb_digest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
352tb_digest.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
353tb_digest.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
354tb_digest.o: tb_digest.c
355tb_dsa.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
356tb_dsa.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
357tb_dsa.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
358tb_dsa.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
359tb_dsa.o: ../../include/openssl/engine.h ../../include/openssl/err.h
360tb_dsa.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
361tb_dsa.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
362tb_dsa.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
363tb_dsa.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
364tb_dsa.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
365tb_dsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
366tb_dsa.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
367tb_dsa.o: ../cryptlib.h eng_int.h tb_dsa.c
368tb_ecdh.o: ../../e_os.h ../../include/openssl/asn1.h
369tb_ecdh.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
370tb_ecdh.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
371tb_ecdh.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
372tb_ecdh.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
373tb_ecdh.o: ../../include/openssl/err.h ../../include/openssl/evp.h
374tb_ecdh.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
375tb_ecdh.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
376tb_ecdh.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
377tb_ecdh.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
378tb_ecdh.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
379tb_ecdh.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
380tb_ecdh.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_ecdh.c
381tb_ecdsa.o: ../../e_os.h ../../include/openssl/asn1.h
382tb_ecdsa.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
383tb_ecdsa.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
384tb_ecdsa.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
385tb_ecdsa.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
386tb_ecdsa.o: ../../include/openssl/err.h ../../include/openssl/evp.h
387tb_ecdsa.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
388tb_ecdsa.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
389tb_ecdsa.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
390tb_ecdsa.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
391tb_ecdsa.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
392tb_ecdsa.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
393tb_ecdsa.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_ecdsa.c
394tb_pkmeth.o: ../../e_os.h ../../include/openssl/asn1.h
395tb_pkmeth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
396tb_pkmeth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
397tb_pkmeth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
398tb_pkmeth.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
399tb_pkmeth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
400tb_pkmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
401tb_pkmeth.o: ../../include/openssl/objects.h
402tb_pkmeth.o: ../../include/openssl/opensslconf.h
403tb_pkmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
404tb_pkmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
405tb_pkmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
406tb_pkmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
407tb_pkmeth.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
408tb_pkmeth.o: tb_pkmeth.c
409tb_rand.o: ../../e_os.h ../../include/openssl/asn1.h
410tb_rand.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
411tb_rand.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
412tb_rand.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
413tb_rand.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
414tb_rand.o: ../../include/openssl/err.h ../../include/openssl/evp.h
415tb_rand.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
416tb_rand.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
417tb_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
418tb_rand.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
419tb_rand.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
420tb_rand.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
421tb_rand.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_rand.c
422tb_rsa.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
423tb_rsa.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
424tb_rsa.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
425tb_rsa.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
426tb_rsa.o: ../../include/openssl/engine.h ../../include/openssl/err.h
427tb_rsa.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
428tb_rsa.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
429tb_rsa.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
430tb_rsa.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
431tb_rsa.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
432tb_rsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
433tb_rsa.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
434tb_rsa.o: ../cryptlib.h eng_int.h tb_rsa.c
435tb_store.o: ../../e_os.h ../../include/openssl/asn1.h
436tb_store.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
437tb_store.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
438tb_store.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
439tb_store.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
440tb_store.o: ../../include/openssl/err.h ../../include/openssl/evp.h
441tb_store.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
442tb_store.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
443tb_store.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
444tb_store.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
445tb_store.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
446tb_store.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
447tb_store.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_store.c
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
index 6093376df4..0ae5d672b1 100644
--- a/src/lib/libcrypto/engine/eng_all.c
+++ b/src/lib/libcrypto/engine/eng_all.c
@@ -73,6 +73,7 @@ void ENGINE_load_builtin_engines(void)
73#if !defined(OPENSSL_NO_HW) && (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)) 73#if !defined(OPENSSL_NO_HW) && (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
74 ENGINE_load_cryptodev(); 74 ENGINE_load_cryptodev();
75#endif 75#endif
76
76#ifndef OPENSSL_NO_RSAX 77#ifndef OPENSSL_NO_RSAX
77 ENGINE_load_rsax(); 78 ENGINE_load_rsax();
78#endif 79#endif
diff --git a/src/lib/libcrypto/engine/eng_cryptodev.c b/src/lib/libcrypto/engine/eng_cryptodev.c
new file mode 100644
index 0000000000..a7abac1a7b
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_cryptodev.c
@@ -0,0 +1,1449 @@
1/*
2 * Copyright (c) 2002 Bob Beck <beck@openbsd.org>
3 * Copyright (c) 2002 Theo de Raadt
4 * Copyright (c) 2002 Markus Friedl
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29#include <openssl/objects.h>
30#include <openssl/engine.h>
31#include <openssl/evp.h>
32#include <openssl/bn.h>
33
34#if (defined(__unix__) || defined(unix)) && !defined(USG) && \
35 (defined(__OpenBSD__) || defined(__FreeBSD__))
36#include <sys/param.h>
37# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041)
38# define HAVE_CRYPTODEV
39# endif
40# if (OpenBSD >= 200110)
41# define HAVE_SYSLOG_R
42# endif
43#endif
44
45#ifndef HAVE_CRYPTODEV
46
47void
48ENGINE_load_cryptodev(void)
49{
50 /* This is a NOP on platforms without /dev/crypto */
51 return;
52}
53
54#else
55
56#include <sys/types.h>
57#include <crypto/cryptodev.h>
58#include <crypto/dh/dh.h>
59#include <crypto/dsa/dsa.h>
60#include <crypto/err/err.h>
61#include <crypto/rsa/rsa.h>
62#include <sys/ioctl.h>
63#include <errno.h>
64#include <stdio.h>
65#include <unistd.h>
66#include <fcntl.h>
67#include <stdarg.h>
68#include <syslog.h>
69#include <errno.h>
70#include <string.h>
71
72struct dev_crypto_state {
73 struct session_op d_sess;
74 int d_fd;
75
76#ifdef USE_CRYPTODEV_DIGESTS
77 char dummy_mac_key[HASH_MAX_LEN];
78
79 unsigned char digest_res[HASH_MAX_LEN];
80 char *mac_data;
81 int mac_len;
82#endif
83};
84
85static u_int32_t cryptodev_asymfeat = 0;
86
87static int get_asym_dev_crypto(void);
88static int open_dev_crypto(void);
89static int get_dev_crypto(void);
90static int get_cryptodev_ciphers(const int **cnids);
91#ifdef USE_CRYPTODEV_DIGESTS
92static int get_cryptodev_digests(const int **cnids);
93#endif
94static int cryptodev_usable_ciphers(const int **nids);
95static int cryptodev_usable_digests(const int **nids);
96static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
97 const unsigned char *in, size_t inl);
98static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
99 const unsigned char *iv, int enc);
100static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx);
101static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
102 const int **nids, int nid);
103static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
104 const int **nids, int nid);
105static int bn2crparam(const BIGNUM *a, struct crparam *crp);
106static int crparam2bn(struct crparam *crp, BIGNUM *a);
107static void zapparams(struct crypt_kop *kop);
108static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r,
109 int slen, BIGNUM *s);
110
111static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
112 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
113static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I,
114 RSA *rsa, BN_CTX *ctx);
115static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
116static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
117 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
118static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
119 BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
120 BN_CTX *ctx, BN_MONT_CTX *mont);
121static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst,
122 int dlen, DSA *dsa);
123static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
124 DSA_SIG *sig, DSA *dsa);
125static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
126 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
127 BN_MONT_CTX *m_ctx);
128static int cryptodev_dh_compute_key(unsigned char *key,
129 const BIGNUM *pub_key, DH *dh);
130static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p,
131 void (*f)(void));
132void ENGINE_load_cryptodev(void);
133
134static const ENGINE_CMD_DEFN cryptodev_defns[] = {
135 { 0, NULL, NULL, 0 }
136};
137
138static struct {
139 int id;
140 int nid;
141 int ivmax;
142 int keylen;
143} ciphers[] = {
144 { CRYPTO_ARC4, NID_rc4, 0, 16, },
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#ifdef USE_CRYPTODEV_DIGESTS
156static struct {
157 int id;
158 int nid;
159 int keylen;
160} digests[] = {
161 { CRYPTO_MD5_HMAC, NID_hmacWithMD5, 16},
162 { CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, 20},
163 { CRYPTO_RIPEMD160_HMAC, NID_ripemd160, 16/*?*/},
164 { CRYPTO_MD5_KPDK, NID_undef, 0},
165 { CRYPTO_SHA1_KPDK, NID_undef, 0},
166 { CRYPTO_MD5, NID_md5, 16},
167 { CRYPTO_SHA1, NID_sha1, 20},
168 { 0, NID_undef, 0},
169};
170#endif
171
172/*
173 * Return a fd if /dev/crypto seems usable, 0 otherwise.
174 */
175static int
176open_dev_crypto(void)
177{
178 static int fd = -1;
179
180 if (fd == -1) {
181 if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1)
182 return (-1);
183 /* close on exec */
184 if (fcntl(fd, F_SETFD, 1) == -1) {
185 close(fd);
186 fd = -1;
187 return (-1);
188 }
189 }
190 return (fd);
191}
192
193static int
194get_dev_crypto(void)
195{
196 int fd, retfd;
197
198 if ((fd = open_dev_crypto()) == -1)
199 return (-1);
200#ifndef CRIOGET_NOT_NEEDED
201 if (ioctl(fd, CRIOGET, &retfd) == -1)
202 return (-1);
203
204 /* close on exec */
205 if (fcntl(retfd, F_SETFD, 1) == -1) {
206 close(retfd);
207 return (-1);
208 }
209#else
210 retfd = fd;
211#endif
212 return (retfd);
213}
214
215static void put_dev_crypto(int fd)
216{
217#ifndef CRIOGET_NOT_NEEDED
218 close(fd);
219#endif
220}
221
222/* Caching version for asym operations */
223static int
224get_asym_dev_crypto(void)
225{
226 static int fd = -1;
227
228 if (fd == -1)
229 fd = get_dev_crypto();
230 return fd;
231}
232
233/*
234 * Find out what ciphers /dev/crypto will let us have a session for.
235 * XXX note, that some of these openssl doesn't deal with yet!
236 * returning them here is harmless, as long as we return NULL
237 * when asked for a handler in the cryptodev_engine_ciphers routine
238 */
239static int
240get_cryptodev_ciphers(const int **cnids)
241{
242 static int nids[CRYPTO_ALGORITHM_MAX];
243 struct session_op sess;
244 int fd, i, count = 0;
245
246 if ((fd = get_dev_crypto()) < 0) {
247 *cnids = NULL;
248 return (0);
249 }
250 memset(&sess, 0, sizeof(sess));
251 sess.key = (caddr_t)"123456789abcdefghijklmno";
252
253 for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
254 if (ciphers[i].nid == NID_undef)
255 continue;
256 sess.cipher = ciphers[i].id;
257 sess.keylen = ciphers[i].keylen;
258 sess.mac = 0;
259 if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
260 ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
261 nids[count++] = ciphers[i].nid;
262 }
263 put_dev_crypto(fd);
264
265 if (count > 0)
266 *cnids = nids;
267 else
268 *cnids = NULL;
269 return (count);
270}
271
272#ifdef USE_CRYPTODEV_DIGESTS
273/*
274 * Find out what digests /dev/crypto will let us have a session for.
275 * XXX note, that some of these openssl doesn't deal with yet!
276 * returning them here is harmless, as long as we return NULL
277 * when asked for a handler in the cryptodev_engine_digests routine
278 */
279static int
280get_cryptodev_digests(const int **cnids)
281{
282 static int nids[CRYPTO_ALGORITHM_MAX];
283 struct session_op sess;
284 int fd, i, count = 0;
285
286 if ((fd = get_dev_crypto()) < 0) {
287 *cnids = NULL;
288 return (0);
289 }
290 memset(&sess, 0, sizeof(sess));
291 sess.mackey = (caddr_t)"123456789abcdefghijklmno";
292 for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
293 if (digests[i].nid == NID_undef)
294 continue;
295 sess.mac = digests[i].id;
296 sess.mackeylen = digests[i].keylen;
297 sess.cipher = 0;
298 if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
299 ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
300 nids[count++] = digests[i].nid;
301 }
302 put_dev_crypto(fd);
303
304 if (count > 0)
305 *cnids = nids;
306 else
307 *cnids = NULL;
308 return (count);
309}
310#endif /* 0 */
311
312/*
313 * Find the useable ciphers|digests from dev/crypto - this is the first
314 * thing called by the engine init crud which determines what it
315 * can use for ciphers from this engine. We want to return
316 * only what we can do, anythine else is handled by software.
317 *
318 * If we can't initialize the device to do anything useful for
319 * any reason, we want to return a NULL array, and 0 length,
320 * which forces everything to be done is software. By putting
321 * the initalization of the device in here, we ensure we can
322 * use this engine as the default, and if for whatever reason
323 * /dev/crypto won't do what we want it will just be done in
324 * software
325 *
326 * This can (should) be greatly expanded to perhaps take into
327 * account speed of the device, and what we want to do.
328 * (although the disabling of particular alg's could be controlled
329 * by the device driver with sysctl's.) - this is where we
330 * want most of the decisions made about what we actually want
331 * to use from /dev/crypto.
332 */
333static int
334cryptodev_usable_ciphers(const int **nids)
335{
336 return (get_cryptodev_ciphers(nids));
337}
338
339static int
340cryptodev_usable_digests(const int **nids)
341{
342#ifdef USE_CRYPTODEV_DIGESTS
343 return (get_cryptodev_digests(nids));
344#else
345 /*
346 * XXXX just disable all digests for now, because it sucks.
347 * we need a better way to decide this - i.e. I may not
348 * want digests on slow cards like hifn on fast machines,
349 * but might want them on slow or loaded machines, etc.
350 * will also want them when using crypto cards that don't
351 * suck moose gonads - would be nice to be able to decide something
352 * as reasonable default without having hackery that's card dependent.
353 * of course, the default should probably be just do everything,
354 * with perhaps a sysctl to turn algoritms off (or have them off
355 * by default) on cards that generally suck like the hifn.
356 */
357 *nids = NULL;
358 return (0);
359#endif
360}
361
362static int
363cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
364 const unsigned char *in, size_t inl)
365{
366 struct crypt_op cryp;
367 struct dev_crypto_state *state = ctx->cipher_data;
368 struct session_op *sess = &state->d_sess;
369 const void *iiv;
370 unsigned char save_iv[EVP_MAX_IV_LENGTH];
371
372 if (state->d_fd < 0)
373 return (0);
374 if (!inl)
375 return (1);
376 if ((inl % ctx->cipher->block_size) != 0)
377 return (0);
378
379 memset(&cryp, 0, sizeof(cryp));
380
381 cryp.ses = sess->ses;
382 cryp.flags = 0;
383 cryp.len = inl;
384 cryp.src = (caddr_t) in;
385 cryp.dst = (caddr_t) out;
386 cryp.mac = 0;
387
388 cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
389
390 if (ctx->cipher->iv_len) {
391 cryp.iv = (caddr_t) ctx->iv;
392 if (!ctx->encrypt) {
393 iiv = in + inl - ctx->cipher->iv_len;
394 memcpy(save_iv, iiv, ctx->cipher->iv_len);
395 }
396 } else
397 cryp.iv = NULL;
398
399 if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) {
400 /* XXX need better errror handling
401 * this can fail for a number of different reasons.
402 */
403 return (0);
404 }
405
406 if (ctx->cipher->iv_len) {
407 if (ctx->encrypt)
408 iiv = out + inl - ctx->cipher->iv_len;
409 else
410 iiv = save_iv;
411 memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
412 }
413 return (1);
414}
415
416static int
417cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
418 const unsigned char *iv, int enc)
419{
420 struct dev_crypto_state *state = ctx->cipher_data;
421 struct session_op *sess = &state->d_sess;
422 int cipher = -1, i;
423
424 for (i = 0; ciphers[i].id; i++)
425 if (ctx->cipher->nid == ciphers[i].nid &&
426 ctx->cipher->iv_len <= ciphers[i].ivmax &&
427 ctx->key_len == ciphers[i].keylen) {
428 cipher = ciphers[i].id;
429 break;
430 }
431
432 if (!ciphers[i].id) {
433 state->d_fd = -1;
434 return (0);
435 }
436
437 memset(sess, 0, sizeof(struct session_op));
438
439 if ((state->d_fd = get_dev_crypto()) < 0)
440 return (0);
441
442 sess->key = (caddr_t)key;
443 sess->keylen = ctx->key_len;
444 sess->cipher = cipher;
445
446 if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
447 put_dev_crypto(state->d_fd);
448 state->d_fd = -1;
449 return (0);
450 }
451 return (1);
452}
453
454/*
455 * free anything we allocated earlier when initting a
456 * session, and close the session.
457 */
458static int
459cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
460{
461 int ret = 0;
462 struct dev_crypto_state *state = ctx->cipher_data;
463 struct session_op *sess = &state->d_sess;
464
465 if (state->d_fd < 0)
466 return (0);
467
468 /* XXX if this ioctl fails, someting's wrong. the invoker
469 * may have called us with a bogus ctx, or we could
470 * have a device that for whatever reason just doesn't
471 * want to play ball - it's not clear what's right
472 * here - should this be an error? should it just
473 * increase a counter, hmm. For right now, we return
474 * 0 - I don't believe that to be "right". we could
475 * call the gorpy openssl lib error handlers that
476 * print messages to users of the library. hmm..
477 */
478
479 if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) {
480 ret = 0;
481 } else {
482 ret = 1;
483 }
484 put_dev_crypto(state->d_fd);
485 state->d_fd = -1;
486
487 return (ret);
488}
489
490/*
491 * libcrypto EVP stuff - this is how we get wired to EVP so the engine
492 * gets called when libcrypto requests a cipher NID.
493 */
494
495/* RC4 */
496const EVP_CIPHER cryptodev_rc4 = {
497 NID_rc4,
498 1, 16, 0,
499 EVP_CIPH_VARIABLE_LENGTH,
500 cryptodev_init_key,
501 cryptodev_cipher,
502 cryptodev_cleanup,
503 sizeof(struct dev_crypto_state),
504 NULL,
505 NULL,
506 NULL
507};
508
509/* DES CBC EVP */
510const EVP_CIPHER cryptodev_des_cbc = {
511 NID_des_cbc,
512 8, 8, 8,
513 EVP_CIPH_CBC_MODE,
514 cryptodev_init_key,
515 cryptodev_cipher,
516 cryptodev_cleanup,
517 sizeof(struct dev_crypto_state),
518 EVP_CIPHER_set_asn1_iv,
519 EVP_CIPHER_get_asn1_iv,
520 NULL
521};
522
523/* 3DES CBC EVP */
524const EVP_CIPHER cryptodev_3des_cbc = {
525 NID_des_ede3_cbc,
526 8, 24, 8,
527 EVP_CIPH_CBC_MODE,
528 cryptodev_init_key,
529 cryptodev_cipher,
530 cryptodev_cleanup,
531 sizeof(struct dev_crypto_state),
532 EVP_CIPHER_set_asn1_iv,
533 EVP_CIPHER_get_asn1_iv,
534 NULL
535};
536
537const EVP_CIPHER cryptodev_bf_cbc = {
538 NID_bf_cbc,
539 8, 16, 8,
540 EVP_CIPH_CBC_MODE,
541 cryptodev_init_key,
542 cryptodev_cipher,
543 cryptodev_cleanup,
544 sizeof(struct dev_crypto_state),
545 EVP_CIPHER_set_asn1_iv,
546 EVP_CIPHER_get_asn1_iv,
547 NULL
548};
549
550const EVP_CIPHER cryptodev_cast_cbc = {
551 NID_cast5_cbc,
552 8, 16, 8,
553 EVP_CIPH_CBC_MODE,
554 cryptodev_init_key,
555 cryptodev_cipher,
556 cryptodev_cleanup,
557 sizeof(struct dev_crypto_state),
558 EVP_CIPHER_set_asn1_iv,
559 EVP_CIPHER_get_asn1_iv,
560 NULL
561};
562
563const EVP_CIPHER cryptodev_aes_cbc = {
564 NID_aes_128_cbc,
565 16, 16, 16,
566 EVP_CIPH_CBC_MODE,
567 cryptodev_init_key,
568 cryptodev_cipher,
569 cryptodev_cleanup,
570 sizeof(struct dev_crypto_state),
571 EVP_CIPHER_set_asn1_iv,
572 EVP_CIPHER_get_asn1_iv,
573 NULL
574};
575
576const EVP_CIPHER cryptodev_aes_192_cbc = {
577 NID_aes_192_cbc,
578 16, 24, 16,
579 EVP_CIPH_CBC_MODE,
580 cryptodev_init_key,
581 cryptodev_cipher,
582 cryptodev_cleanup,
583 sizeof(struct dev_crypto_state),
584 EVP_CIPHER_set_asn1_iv,
585 EVP_CIPHER_get_asn1_iv,
586 NULL
587};
588
589const EVP_CIPHER cryptodev_aes_256_cbc = {
590 NID_aes_256_cbc,
591 16, 32, 16,
592 EVP_CIPH_CBC_MODE,
593 cryptodev_init_key,
594 cryptodev_cipher,
595 cryptodev_cleanup,
596 sizeof(struct dev_crypto_state),
597 EVP_CIPHER_set_asn1_iv,
598 EVP_CIPHER_get_asn1_iv,
599 NULL
600};
601
602/*
603 * Registered by the ENGINE when used to find out how to deal with
604 * a particular NID in the ENGINE. this says what we'll do at the
605 * top level - note, that list is restricted by what we answer with
606 */
607static int
608cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
609 const int **nids, int nid)
610{
611 if (!cipher)
612 return (cryptodev_usable_ciphers(nids));
613
614 switch (nid) {
615 case NID_rc4:
616 *cipher = &cryptodev_rc4;
617 break;
618 case NID_des_ede3_cbc:
619 *cipher = &cryptodev_3des_cbc;
620 break;
621 case NID_des_cbc:
622 *cipher = &cryptodev_des_cbc;
623 break;
624 case NID_bf_cbc:
625 *cipher = &cryptodev_bf_cbc;
626 break;
627 case NID_cast5_cbc:
628 *cipher = &cryptodev_cast_cbc;
629 break;
630 case NID_aes_128_cbc:
631 *cipher = &cryptodev_aes_cbc;
632 break;
633 case NID_aes_192_cbc:
634 *cipher = &cryptodev_aes_192_cbc;
635 break;
636 case NID_aes_256_cbc:
637 *cipher = &cryptodev_aes_256_cbc;
638 break;
639 default:
640 *cipher = NULL;
641 break;
642 }
643 return (*cipher != NULL);
644}
645
646
647#ifdef USE_CRYPTODEV_DIGESTS
648
649/* convert digest type to cryptodev */
650static int
651digest_nid_to_cryptodev(int nid)
652{
653 int i;
654
655 for (i = 0; digests[i].id; i++)
656 if (digests[i].nid == nid)
657 return (digests[i].id);
658 return (0);
659}
660
661
662static int
663digest_key_length(int nid)
664{
665 int i;
666
667 for (i = 0; digests[i].id; i++)
668 if (digests[i].nid == nid)
669 return digests[i].keylen;
670 return (0);
671}
672
673
674static int cryptodev_digest_init(EVP_MD_CTX *ctx)
675{
676 struct dev_crypto_state *state = ctx->md_data;
677 struct session_op *sess = &state->d_sess;
678 int digest;
679
680 if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef){
681 printf("cryptodev_digest_init: Can't get digest \n");
682 return (0);
683 }
684
685 memset(state, 0, sizeof(struct dev_crypto_state));
686
687 if ((state->d_fd = get_dev_crypto()) < 0) {
688 printf("cryptodev_digest_init: Can't get Dev \n");
689 return (0);
690 }
691
692 sess->mackey = state->dummy_mac_key;
693 sess->mackeylen = digest_key_length(ctx->digest->type);
694 sess->mac = digest;
695
696 if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) {
697 put_dev_crypto(state->d_fd);
698 state->d_fd = -1;
699 printf("cryptodev_digest_init: Open session failed\n");
700 return (0);
701 }
702
703 return (1);
704}
705
706static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data,
707 size_t count)
708{
709 struct crypt_op cryp;
710 struct dev_crypto_state *state = ctx->md_data;
711 struct session_op *sess = &state->d_sess;
712
713 if (!data || state->d_fd < 0) {
714 printf("cryptodev_digest_update: illegal inputs \n");
715 return (0);
716 }
717
718 if (!count) {
719 return (0);
720 }
721
722 if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) {
723 /* if application doesn't support one buffer */
724 state->mac_data = OPENSSL_realloc(state->mac_data, state->mac_len + count);
725
726 if (!state->mac_data) {
727 printf("cryptodev_digest_update: realloc failed\n");
728 return (0);
729 }
730
731 memcpy(state->mac_data + state->mac_len, data, count);
732 state->mac_len += count;
733
734 return (1);
735 }
736
737 memset(&cryp, 0, sizeof(cryp));
738
739 cryp.ses = sess->ses;
740 cryp.flags = 0;
741 cryp.len = count;
742 cryp.src = (caddr_t) data;
743 cryp.dst = NULL;
744 cryp.mac = (caddr_t) state->digest_res;
745 if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
746 printf("cryptodev_digest_update: digest failed\n");
747 return (0);
748 }
749 return (1);
750}
751
752
753static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
754{
755 struct crypt_op cryp;
756 struct dev_crypto_state *state = ctx->md_data;
757 struct session_op *sess = &state->d_sess;
758
759 int ret = 1;
760
761 if (!md || state->d_fd < 0) {
762 printf("cryptodev_digest_final: illegal input\n");
763 return(0);
764 }
765
766 if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) {
767 /* if application doesn't support one buffer */
768 memset(&cryp, 0, sizeof(cryp));
769 cryp.ses = sess->ses;
770 cryp.flags = 0;
771 cryp.len = state->mac_len;
772 cryp.src = state->mac_data;
773 cryp.dst = NULL;
774 cryp.mac = (caddr_t)md;
775 if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
776 printf("cryptodev_digest_final: digest failed\n");
777 return (0);
778 }
779
780 return 1;
781 }
782
783 memcpy(md, state->digest_res, ctx->digest->md_size);
784
785 return (ret);
786}
787
788
789static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
790{
791 int ret = 1;
792 struct dev_crypto_state *state = ctx->md_data;
793 struct session_op *sess = &state->d_sess;
794
795 if (state == NULL)
796 return 0;
797
798 if (state->d_fd < 0) {
799 printf("cryptodev_digest_cleanup: illegal input\n");
800 return (0);
801 }
802
803 if (state->mac_data) {
804 OPENSSL_free(state->mac_data);
805 state->mac_data = NULL;
806 state->mac_len = 0;
807 }
808
809 if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
810 printf("cryptodev_digest_cleanup: failed to close session\n");
811 ret = 0;
812 } else {
813 ret = 1;
814 }
815 put_dev_crypto(state->d_fd);
816 state->d_fd = -1;
817
818 return (ret);
819}
820
821static int cryptodev_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
822{
823 struct dev_crypto_state *fstate = from->md_data;
824 struct dev_crypto_state *dstate = to->md_data;
825 struct session_op *sess;
826 int digest;
827
828 if (dstate == NULL || fstate == NULL)
829 return 1;
830
831 memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
832
833 sess = &dstate->d_sess;
834
835 digest = digest_nid_to_cryptodev(to->digest->type);
836
837 sess->mackey = dstate->dummy_mac_key;
838 sess->mackeylen = digest_key_length(to->digest->type);
839 sess->mac = digest;
840
841 dstate->d_fd = get_dev_crypto();
842
843 if (ioctl(dstate->d_fd, CIOCGSESSION, sess) < 0) {
844 put_dev_crypto(dstate->d_fd);
845 dstate->d_fd = -1;
846 printf("cryptodev_digest_init: Open session failed\n");
847 return (0);
848 }
849
850 if (fstate->mac_len != 0) {
851 if (fstate->mac_data != NULL)
852 {
853 dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
854 memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
855 dstate->mac_len = fstate->mac_len;
856 }
857 }
858
859 return 1;
860}
861
862
863const EVP_MD cryptodev_sha1 = {
864 NID_sha1,
865 NID_undef,
866 SHA_DIGEST_LENGTH,
867 EVP_MD_FLAG_ONESHOT,
868 cryptodev_digest_init,
869 cryptodev_digest_update,
870 cryptodev_digest_final,
871 cryptodev_digest_copy,
872 cryptodev_digest_cleanup,
873 EVP_PKEY_NULL_method,
874 SHA_CBLOCK,
875 sizeof(struct dev_crypto_state),
876};
877
878const EVP_MD cryptodev_md5 = {
879 NID_md5,
880 NID_undef,
881 16 /* MD5_DIGEST_LENGTH */,
882 EVP_MD_FLAG_ONESHOT,
883 cryptodev_digest_init,
884 cryptodev_digest_update,
885 cryptodev_digest_final,
886 cryptodev_digest_copy,
887 cryptodev_digest_cleanup,
888 EVP_PKEY_NULL_method,
889 64 /* MD5_CBLOCK */,
890 sizeof(struct dev_crypto_state),
891};
892
893#endif /* USE_CRYPTODEV_DIGESTS */
894
895
896static int
897cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
898 const int **nids, int nid)
899{
900 if (!digest)
901 return (cryptodev_usable_digests(nids));
902
903 switch (nid) {
904#ifdef USE_CRYPTODEV_DIGESTS
905 case NID_md5:
906 *digest = &cryptodev_md5;
907 break;
908 case NID_sha1:
909 *digest = &cryptodev_sha1;
910 break;
911 default:
912#endif /* USE_CRYPTODEV_DIGESTS */
913 *digest = NULL;
914 break;
915 }
916 return (*digest != NULL);
917}
918
919/*
920 * Convert a BIGNUM to the representation that /dev/crypto needs.
921 * Upon completion of use, the caller is responsible for freeing
922 * crp->crp_p.
923 */
924static int
925bn2crparam(const BIGNUM *a, struct crparam *crp)
926{
927 int i, j, k;
928 ssize_t bytes, bits;
929 u_char *b;
930
931 crp->crp_p = NULL;
932 crp->crp_nbits = 0;
933
934 bits = BN_num_bits(a);
935 bytes = (bits + 7) / 8;
936
937 b = malloc(bytes);
938 if (b == NULL)
939 return (1);
940 memset(b, 0, bytes);
941
942 crp->crp_p = (caddr_t) b;
943 crp->crp_nbits = bits;
944
945 for (i = 0, j = 0; i < a->top; i++) {
946 for (k = 0; k < BN_BITS2 / 8; k++) {
947 if ((j + k) >= bytes)
948 return (0);
949 b[j + k] = a->d[i] >> (k * 8);
950 }
951 j += BN_BITS2 / 8;
952 }
953 return (0);
954}
955
956/* Convert a /dev/crypto parameter to a BIGNUM */
957static int
958crparam2bn(struct crparam *crp, BIGNUM *a)
959{
960 u_int8_t *pd;
961 int i, bytes;
962
963 bytes = (crp->crp_nbits + 7) / 8;
964
965 if (bytes == 0)
966 return (-1);
967
968 if ((pd = (u_int8_t *) malloc(bytes)) == NULL)
969 return (-1);
970
971 for (i = 0; i < bytes; i++)
972 pd[i] = crp->crp_p[bytes - i - 1];
973
974 BN_bin2bn(pd, bytes, a);
975 free(pd);
976
977 return (0);
978}
979
980static void
981zapparams(struct crypt_kop *kop)
982{
983 int i;
984
985 for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) {
986 if (kop->crk_param[i].crp_p)
987 free(kop->crk_param[i].crp_p);
988 kop->crk_param[i].crp_p = NULL;
989 kop->crk_param[i].crp_nbits = 0;
990 }
991}
992
993static int
994cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s)
995{
996 int fd, ret = -1;
997
998 if ((fd = get_asym_dev_crypto()) < 0)
999 return (ret);
1000
1001 if (r) {
1002 kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char));
1003 kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8;
1004 kop->crk_oparams++;
1005 }
1006 if (s) {
1007 kop->crk_param[kop->crk_iparams+1].crp_p = calloc(slen, sizeof(char));
1008 kop->crk_param[kop->crk_iparams+1].crp_nbits = slen * 8;
1009 kop->crk_oparams++;
1010 }
1011
1012 if (ioctl(fd, CIOCKEY, kop) == 0) {
1013 if (r)
1014 crparam2bn(&kop->crk_param[kop->crk_iparams], r);
1015 if (s)
1016 crparam2bn(&kop->crk_param[kop->crk_iparams+1], s);
1017 ret = 0;
1018 }
1019
1020 return (ret);
1021}
1022
1023static int
1024cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
1025 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
1026{
1027 struct crypt_kop kop;
1028 int ret = 1;
1029
1030 /* Currently, we know we can do mod exp iff we can do any
1031 * asymmetric operations at all.
1032 */
1033 if (cryptodev_asymfeat == 0) {
1034 ret = BN_mod_exp(r, a, p, m, ctx);
1035 return (ret);
1036 }
1037
1038 memset(&kop, 0, sizeof kop);
1039 kop.crk_op = CRK_MOD_EXP;
1040
1041 /* inputs: a^p % m */
1042 if (bn2crparam(a, &kop.crk_param[0]))
1043 goto err;
1044 if (bn2crparam(p, &kop.crk_param[1]))
1045 goto err;
1046 if (bn2crparam(m, &kop.crk_param[2]))
1047 goto err;
1048 kop.crk_iparams = 3;
1049
1050 if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) {
1051 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
1052 printf("OCF asym process failed, Running in software\n");
1053 ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
1054
1055 } else if (ECANCELED == kop.crk_status) {
1056 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
1057 printf("OCF hardware operation cancelled. Running in Software\n");
1058 ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
1059 }
1060 /* else cryptodev operation worked ok ==> ret = 1*/
1061
1062err:
1063 zapparams(&kop);
1064 return (ret);
1065}
1066
1067static int
1068cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
1069{
1070 int r;
1071 ctx = BN_CTX_new();
1072 r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL);
1073 BN_CTX_free(ctx);
1074 return (r);
1075}
1076
1077static int
1078cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
1079{
1080 struct crypt_kop kop;
1081 int ret = 1;
1082
1083 if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
1084 /* XXX 0 means failure?? */
1085 return (0);
1086 }
1087
1088 memset(&kop, 0, sizeof kop);
1089 kop.crk_op = CRK_MOD_EXP_CRT;
1090 /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
1091 if (bn2crparam(rsa->p, &kop.crk_param[0]))
1092 goto err;
1093 if (bn2crparam(rsa->q, &kop.crk_param[1]))
1094 goto err;
1095 if (bn2crparam(I, &kop.crk_param[2]))
1096 goto err;
1097 if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
1098 goto err;
1099 if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
1100 goto err;
1101 if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
1102 goto err;
1103 kop.crk_iparams = 6;
1104
1105 if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) {
1106 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
1107 printf("OCF asym process failed, running in Software\n");
1108 ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
1109
1110 } else if (ECANCELED == kop.crk_status) {
1111 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
1112 printf("OCF hardware operation cancelled. Running in Software\n");
1113 ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
1114 }
1115 /* else cryptodev operation worked ok ==> ret = 1*/
1116
1117err:
1118 zapparams(&kop);
1119 return (ret);
1120}
1121
1122static RSA_METHOD cryptodev_rsa = {
1123 "cryptodev RSA method",
1124 NULL, /* rsa_pub_enc */
1125 NULL, /* rsa_pub_dec */
1126 NULL, /* rsa_priv_enc */
1127 NULL, /* rsa_priv_dec */
1128 NULL,
1129 NULL,
1130 NULL, /* init */
1131 NULL, /* finish */
1132 0, /* flags */
1133 NULL, /* app_data */
1134 NULL, /* rsa_sign */
1135 NULL /* rsa_verify */
1136};
1137
1138static int
1139cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
1140 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
1141{
1142 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
1143}
1144
1145static int
1146cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
1147 BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
1148 BN_CTX *ctx, BN_MONT_CTX *mont)
1149{
1150 BIGNUM t2;
1151 int ret = 0;
1152
1153 BN_init(&t2);
1154
1155 /* v = ( g^u1 * y^u2 mod p ) mod q */
1156 /* let t1 = g ^ u1 mod p */
1157 ret = 0;
1158
1159 if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont))
1160 goto err;
1161
1162 /* let t2 = y ^ u2 mod p */
1163 if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont))
1164 goto err;
1165 /* let u1 = t1 * t2 mod p */
1166 if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx))
1167 goto err;
1168
1169 BN_copy(t1,u1);
1170
1171 ret = 1;
1172err:
1173 BN_free(&t2);
1174 return(ret);
1175}
1176
1177static DSA_SIG *
1178cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
1179{
1180 struct crypt_kop kop;
1181 BIGNUM *r = NULL, *s = NULL;
1182 DSA_SIG *dsaret = NULL;
1183
1184 if ((r = BN_new()) == NULL)
1185 goto err;
1186 if ((s = BN_new()) == NULL) {
1187 BN_free(r);
1188 goto err;
1189 }
1190
1191 memset(&kop, 0, sizeof kop);
1192 kop.crk_op = CRK_DSA_SIGN;
1193
1194 /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
1195 kop.crk_param[0].crp_p = (caddr_t)dgst;
1196 kop.crk_param[0].crp_nbits = dlen * 8;
1197 if (bn2crparam(dsa->p, &kop.crk_param[1]))
1198 goto err;
1199 if (bn2crparam(dsa->q, &kop.crk_param[2]))
1200 goto err;
1201 if (bn2crparam(dsa->g, &kop.crk_param[3]))
1202 goto err;
1203 if (bn2crparam(dsa->priv_key, &kop.crk_param[4]))
1204 goto err;
1205 kop.crk_iparams = 5;
1206
1207 if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r,
1208 BN_num_bytes(dsa->q), s) == 0) {
1209 dsaret = DSA_SIG_new();
1210 dsaret->r = r;
1211 dsaret->s = s;
1212 } else {
1213 const DSA_METHOD *meth = DSA_OpenSSL();
1214 BN_free(r);
1215 BN_free(s);
1216 dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
1217 }
1218err:
1219 kop.crk_param[0].crp_p = NULL;
1220 zapparams(&kop);
1221 return (dsaret);
1222}
1223
1224static int
1225cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
1226 DSA_SIG *sig, DSA *dsa)
1227{
1228 struct crypt_kop kop;
1229 int dsaret = 1;
1230
1231 memset(&kop, 0, sizeof kop);
1232 kop.crk_op = CRK_DSA_VERIFY;
1233
1234 /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
1235 kop.crk_param[0].crp_p = (caddr_t)dgst;
1236 kop.crk_param[0].crp_nbits = dlen * 8;
1237 if (bn2crparam(dsa->p, &kop.crk_param[1]))
1238 goto err;
1239 if (bn2crparam(dsa->q, &kop.crk_param[2]))
1240 goto err;
1241 if (bn2crparam(dsa->g, &kop.crk_param[3]))
1242 goto err;
1243 if (bn2crparam(dsa->pub_key, &kop.crk_param[4]))
1244 goto err;
1245 if (bn2crparam(sig->r, &kop.crk_param[5]))
1246 goto err;
1247 if (bn2crparam(sig->s, &kop.crk_param[6]))
1248 goto err;
1249 kop.crk_iparams = 7;
1250
1251 if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
1252/*OCF success value is 0, if not zero, change dsaret to fail*/
1253 if(0 != kop.crk_status) dsaret = 0;
1254 } else {
1255 const DSA_METHOD *meth = DSA_OpenSSL();
1256
1257 dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
1258 }
1259err:
1260 kop.crk_param[0].crp_p = NULL;
1261 zapparams(&kop);
1262 return (dsaret);
1263}
1264
1265static DSA_METHOD cryptodev_dsa = {
1266 "cryptodev DSA method",
1267 NULL,
1268 NULL, /* dsa_sign_setup */
1269 NULL,
1270 NULL, /* dsa_mod_exp */
1271 NULL,
1272 NULL, /* init */
1273 NULL, /* finish */
1274 0, /* flags */
1275 NULL /* app_data */
1276};
1277
1278static int
1279cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
1280 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
1281 BN_MONT_CTX *m_ctx)
1282{
1283 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
1284}
1285
1286static int
1287cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
1288{
1289 struct crypt_kop kop;
1290 int dhret = 1;
1291 int fd, keylen;
1292
1293 if ((fd = get_asym_dev_crypto()) < 0) {
1294 const DH_METHOD *meth = DH_OpenSSL();
1295
1296 return ((meth->compute_key)(key, pub_key, dh));
1297 }
1298
1299 keylen = BN_num_bits(dh->p);
1300
1301 memset(&kop, 0, sizeof kop);
1302 kop.crk_op = CRK_DH_COMPUTE_KEY;
1303
1304 /* inputs: dh->priv_key pub_key dh->p key */
1305 if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
1306 goto err;
1307 if (bn2crparam(pub_key, &kop.crk_param[1]))
1308 goto err;
1309 if (bn2crparam(dh->p, &kop.crk_param[2]))
1310 goto err;
1311 kop.crk_iparams = 3;
1312
1313 kop.crk_param[3].crp_p = (caddr_t) key;
1314 kop.crk_param[3].crp_nbits = keylen * 8;
1315 kop.crk_oparams = 1;
1316
1317 if (ioctl(fd, CIOCKEY, &kop) == -1) {
1318 const DH_METHOD *meth = DH_OpenSSL();
1319
1320 dhret = (meth->compute_key)(key, pub_key, dh);
1321 }
1322err:
1323 kop.crk_param[3].crp_p = NULL;
1324 zapparams(&kop);
1325 return (dhret);
1326}
1327
1328static DH_METHOD cryptodev_dh = {
1329 "cryptodev DH method",
1330 NULL, /* cryptodev_dh_generate_key */
1331 NULL,
1332 NULL,
1333 NULL,
1334 NULL,
1335 0, /* flags */
1336 NULL /* app_data */
1337};
1338
1339/*
1340 * ctrl right now is just a wrapper that doesn't do much
1341 * but I expect we'll want some options soon.
1342 */
1343static int
1344cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
1345{
1346#ifdef HAVE_SYSLOG_R
1347 struct syslog_data sd = SYSLOG_DATA_INIT;
1348#endif
1349
1350 switch (cmd) {
1351 default:
1352#ifdef HAVE_SYSLOG_R
1353 syslog_r(LOG_ERR, &sd,
1354 "cryptodev_ctrl: unknown command %d", cmd);
1355#else
1356 syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd);
1357#endif
1358 break;
1359 }
1360 return (1);
1361}
1362
1363void
1364ENGINE_load_cryptodev(void)
1365{
1366 ENGINE *engine = ENGINE_new();
1367 int fd;
1368
1369 if (engine == NULL)
1370 return;
1371 if ((fd = get_dev_crypto()) < 0) {
1372 ENGINE_free(engine);
1373 return;
1374 }
1375
1376 /*
1377 * find out what asymmetric crypto algorithms we support
1378 */
1379 if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
1380 put_dev_crypto(fd);
1381 ENGINE_free(engine);
1382 return;
1383 }
1384 put_dev_crypto(fd);
1385
1386 if (!ENGINE_set_id(engine, "cryptodev") ||
1387 !ENGINE_set_name(engine, "BSD cryptodev engine") ||
1388 !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) ||
1389 !ENGINE_set_digests(engine, cryptodev_engine_digests) ||
1390 !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) ||
1391 !ENGINE_set_cmd_defns(engine, cryptodev_defns)) {
1392 ENGINE_free(engine);
1393 return;
1394 }
1395
1396 if (ENGINE_set_RSA(engine, &cryptodev_rsa)) {
1397 const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay();
1398
1399 cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp;
1400 cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp;
1401 cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc;
1402 cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec;
1403 cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc;
1404 cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec;
1405 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1406 cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp;
1407 if (cryptodev_asymfeat & CRF_MOD_EXP_CRT)
1408 cryptodev_rsa.rsa_mod_exp =
1409 cryptodev_rsa_mod_exp;
1410 else
1411 cryptodev_rsa.rsa_mod_exp =
1412 cryptodev_rsa_nocrt_mod_exp;
1413 }
1414 }
1415
1416 if (ENGINE_set_DSA(engine, &cryptodev_dsa)) {
1417 const DSA_METHOD *meth = DSA_OpenSSL();
1418
1419 memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
1420 if (cryptodev_asymfeat & CRF_DSA_SIGN)
1421 cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
1422 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1423 cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp;
1424 cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp;
1425 }
1426 if (cryptodev_asymfeat & CRF_DSA_VERIFY)
1427 cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
1428 }
1429
1430 if (ENGINE_set_DH(engine, &cryptodev_dh)){
1431 const DH_METHOD *dh_meth = DH_OpenSSL();
1432
1433 cryptodev_dh.generate_key = dh_meth->generate_key;
1434 cryptodev_dh.compute_key = dh_meth->compute_key;
1435 cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp;
1436 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1437 cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh;
1438 if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
1439 cryptodev_dh.compute_key =
1440 cryptodev_dh_compute_key;
1441 }
1442 }
1443
1444 ENGINE_add(engine);
1445 ENGINE_free(engine);
1446 ERR_clear_error();
1447}
1448
1449#endif /* HAVE_CRYPTODEV */
diff --git a/src/lib/libcrypto/engine/eng_list.c b/src/lib/libcrypto/engine/eng_list.c
index 95c858960b..27846edb1e 100644
--- a/src/lib/libcrypto/engine/eng_list.c
+++ b/src/lib/libcrypto/engine/eng_list.c
@@ -408,7 +408,6 @@ ENGINE *ENGINE_by_id(const char *id)
408 !ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) || 408 !ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) ||
409 !ENGINE_ctrl_cmd_string(iterator, "DIR_ADD", 409 !ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
410 load_dir, 0) || 410 load_dir, 0) ||
411 !ENGINE_ctrl_cmd_string(iterator, "LIST_ADD", "1", 0) ||
412 !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0)) 411 !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
413 goto notfound; 412 goto notfound;
414 return iterator; 413 return iterator;
diff --git a/src/lib/libcrypto/engine/eng_rdrand.c b/src/lib/libcrypto/engine/eng_rdrand.c
new file mode 100644
index 0000000000..4e9e91d54b
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_rdrand.c
@@ -0,0 +1,143 @@
1/* ====================================================================
2 * Copyright (c) 2011 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
50#include <openssl/opensslconf.h>
51
52#include <stdio.h>
53#include <string.h>
54#include <openssl/engine.h>
55#include <openssl/rand.h>
56#include <openssl/err.h>
57
58#if (defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
59 defined(__x86_64) || defined(__x86_64__) || \
60 defined(_M_AMD64) || defined (_M_X64)) && defined(OPENSSL_CPUID_OBJ)
61
62size_t OPENSSL_ia32_rdrand(void);
63
64static int get_random_bytes (unsigned char *buf, int num)
65 {
66 size_t rnd;
67
68 while (num>=(int)sizeof(size_t)) {
69 if ((rnd = OPENSSL_ia32_rdrand()) == 0) return 0;
70
71 *((size_t *)buf) = rnd;
72 buf += sizeof(size_t);
73 num -= sizeof(size_t);
74 }
75 if (num) {
76 if ((rnd = OPENSSL_ia32_rdrand()) == 0) return 0;
77
78 memcpy (buf,&rnd,num);
79 }
80
81 return 1;
82 }
83
84static int random_status (void)
85{ return 1; }
86
87static RAND_METHOD rdrand_meth =
88 {
89 NULL, /* seed */
90 get_random_bytes,
91 NULL, /* cleanup */
92 NULL, /* add */
93 get_random_bytes,
94 random_status,
95 };
96
97static int rdrand_init(ENGINE *e)
98{ return 1; }
99
100static const char *engine_e_rdrand_id = "rdrand";
101static const char *engine_e_rdrand_name = "Intel RDRAND engine";
102
103static int bind_helper(ENGINE *e)
104 {
105 if (!ENGINE_set_id(e, engine_e_rdrand_id) ||
106 !ENGINE_set_name(e, engine_e_rdrand_name) ||
107 !ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL) ||
108 !ENGINE_set_init_function(e, rdrand_init) ||
109 !ENGINE_set_RAND(e, &rdrand_meth) )
110 return 0;
111
112 return 1;
113 }
114
115static ENGINE *ENGINE_rdrand(void)
116 {
117 ENGINE *ret = ENGINE_new();
118 if(!ret)
119 return NULL;
120 if(!bind_helper(ret))
121 {
122 ENGINE_free(ret);
123 return NULL;
124 }
125 return ret;
126 }
127
128void ENGINE_load_rdrand (void)
129 {
130 extern unsigned int OPENSSL_ia32cap_P[];
131
132 if (OPENSSL_ia32cap_P[1] & (1<<(62-32)))
133 {
134 ENGINE *toadd = ENGINE_rdrand();
135 if(!toadd) return;
136 ENGINE_add(toadd);
137 ENGINE_free(toadd);
138 ERR_clear_error();
139 }
140 }
141#else
142void ENGINE_load_rdrand (void) {}
143#endif
diff --git a/src/lib/libcrypto/engine/eng_rsax.c b/src/lib/libcrypto/engine/eng_rsax.c
new file mode 100644
index 0000000000..96e63477ee
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_rsax.c
@@ -0,0 +1,668 @@
1/* crypto/engine/eng_rsax.c */
2/* Copyright (c) 2010-2010 Intel Corp.
3 * Author: Vinodh.Gopal@intel.com
4 * Jim Guilford
5 * Erdinc.Ozturk@intel.com
6 * Maxim.Perminov@intel.com
7 * Ying.Huang@intel.com
8 *
9 * More information about algorithm used can be found at:
10 * http://www.cse.buffalo.edu/srds2009/escs2009_submission_Gopal.pdf
11 */
12/* ====================================================================
13 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 *
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 *
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in
24 * the documentation and/or other materials provided with the
25 * distribution.
26 *
27 * 3. All advertising materials mentioning features or use of this
28 * software must display the following acknowledgment:
29 * "This product includes software developed by the OpenSSL Project
30 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
31 *
32 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
33 * endorse or promote products derived from this software without
34 * prior written permission. For written permission, please contact
35 * licensing@OpenSSL.org.
36 *
37 * 5. Products derived from this software may not be called "OpenSSL"
38 * nor may "OpenSSL" appear in their names without prior written
39 * permission of the OpenSSL Project.
40 *
41 * 6. Redistributions of any form whatsoever must retain the following
42 * acknowledgment:
43 * "This product includes software developed by the OpenSSL Project
44 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
47 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
49 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
50 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
51 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
52 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
53 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
55 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
56 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
57 * OF THE POSSIBILITY OF SUCH DAMAGE.
58 * ====================================================================
59 *
60 * This product includes cryptographic software written by Eric Young
61 * (eay@cryptsoft.com). This product includes software written by Tim
62 * Hudson (tjh@cryptsoft.com).
63 */
64
65#include <openssl/opensslconf.h>
66
67#include <stdio.h>
68#include <string.h>
69#include <openssl/crypto.h>
70#include <openssl/buffer.h>
71#include <openssl/engine.h>
72#ifndef OPENSSL_NO_RSA
73#include <openssl/rsa.h>
74#endif
75#include <openssl/bn.h>
76#include <openssl/err.h>
77
78/* RSAX is available **ONLY* on x86_64 CPUs */
79#undef COMPILE_RSAX
80
81#if (defined(__x86_64) || defined(__x86_64__) || \
82 defined(_M_AMD64) || defined (_M_X64)) && !defined(OPENSSL_NO_ASM)
83#define COMPILE_RSAX
84static ENGINE *ENGINE_rsax (void);
85#endif
86
87void ENGINE_load_rsax (void)
88 {
89/* On non-x86 CPUs it just returns. */
90#ifdef COMPILE_RSAX
91 ENGINE *toadd = ENGINE_rsax();
92 if(!toadd) return;
93 ENGINE_add(toadd);
94 ENGINE_free(toadd);
95 ERR_clear_error();
96#endif
97 }
98
99#ifdef COMPILE_RSAX
100#define E_RSAX_LIB_NAME "rsax engine"
101
102static int e_rsax_destroy(ENGINE *e);
103static int e_rsax_init(ENGINE *e);
104static int e_rsax_finish(ENGINE *e);
105static int e_rsax_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
106
107#ifndef OPENSSL_NO_RSA
108/* RSA stuff */
109static int e_rsax_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
110static int e_rsax_rsa_finish(RSA *r);
111#endif
112
113static const ENGINE_CMD_DEFN e_rsax_cmd_defns[] = {
114 {0, NULL, NULL, 0}
115 };
116
117#ifndef OPENSSL_NO_RSA
118/* Our internal RSA_METHOD that we provide pointers to */
119static RSA_METHOD e_rsax_rsa =
120 {
121 "Intel RSA-X method",
122 NULL,
123 NULL,
124 NULL,
125 NULL,
126 e_rsax_rsa_mod_exp,
127 NULL,
128 NULL,
129 e_rsax_rsa_finish,
130 RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE,
131 NULL,
132 NULL,
133 NULL
134 };
135#endif
136
137/* Constants used when creating the ENGINE */
138static const char *engine_e_rsax_id = "rsax";
139static const char *engine_e_rsax_name = "RSAX engine support";
140
141/* This internal function is used by ENGINE_rsax() */
142static int bind_helper(ENGINE *e)
143 {
144#ifndef OPENSSL_NO_RSA
145 const RSA_METHOD *meth1;
146#endif
147 if(!ENGINE_set_id(e, engine_e_rsax_id) ||
148 !ENGINE_set_name(e, engine_e_rsax_name) ||
149#ifndef OPENSSL_NO_RSA
150 !ENGINE_set_RSA(e, &e_rsax_rsa) ||
151#endif
152 !ENGINE_set_destroy_function(e, e_rsax_destroy) ||
153 !ENGINE_set_init_function(e, e_rsax_init) ||
154 !ENGINE_set_finish_function(e, e_rsax_finish) ||
155 !ENGINE_set_ctrl_function(e, e_rsax_ctrl) ||
156 !ENGINE_set_cmd_defns(e, e_rsax_cmd_defns))
157 return 0;
158
159#ifndef OPENSSL_NO_RSA
160 meth1 = RSA_PKCS1_SSLeay();
161 e_rsax_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
162 e_rsax_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
163 e_rsax_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
164 e_rsax_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
165 e_rsax_rsa.bn_mod_exp = meth1->bn_mod_exp;
166#endif
167 return 1;
168 }
169
170static ENGINE *ENGINE_rsax(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
183#ifndef OPENSSL_NO_RSA
184/* Used to attach our own key-data to an RSA structure */
185static int rsax_ex_data_idx = -1;
186#endif
187
188static int e_rsax_destroy(ENGINE *e)
189 {
190 return 1;
191 }
192
193/* (de)initialisation functions. */
194static int e_rsax_init(ENGINE *e)
195 {
196#ifndef OPENSSL_NO_RSA
197 if (rsax_ex_data_idx == -1)
198 rsax_ex_data_idx = RSA_get_ex_new_index(0,
199 NULL,
200 NULL, NULL, NULL);
201#endif
202 if (rsax_ex_data_idx == -1)
203 return 0;
204 return 1;
205 }
206
207static int e_rsax_finish(ENGINE *e)
208 {
209 return 1;
210 }
211
212static int e_rsax_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
213 {
214 int to_return = 1;
215
216 switch(cmd)
217 {
218 /* The command isn't understood by this engine */
219 default:
220 to_return = 0;
221 break;
222 }
223
224 return to_return;
225 }
226
227
228#ifndef OPENSSL_NO_RSA
229
230#ifdef _WIN32
231typedef unsigned __int64 UINT64;
232#else
233typedef unsigned long long UINT64;
234#endif
235typedef unsigned short UINT16;
236
237/* Table t is interleaved in the following manner:
238 * The order in memory is t[0][0], t[0][1], ..., t[0][7], t[1][0], ...
239 * A particular 512-bit value is stored in t[][index] rather than the more
240 * normal t[index][]; i.e. the qwords of a particular entry in t are not
241 * adjacent in memory
242 */
243
244/* Init BIGNUM b from the interleaved UINT64 array */
245static int interleaved_array_to_bn_512(BIGNUM* b, UINT64 *array);
246
247/* Extract array elements from BIGNUM b
248 * To set the whole array from b, call with n=8
249 */
250static int bn_extract_to_array_512(const BIGNUM* b, unsigned int n, UINT64 *array);
251
252struct mod_ctx_512 {
253 UINT64 t[8][8];
254 UINT64 m[8];
255 UINT64 m1[8]; /* 2^278 % m */
256 UINT64 m2[8]; /* 2^640 % m */
257 UINT64 k1[2]; /* (- 1/m) % 2^128 */
258};
259
260static int mod_exp_pre_compute_data_512(UINT64 *m, struct mod_ctx_512 *data);
261
262void mod_exp_512(UINT64 *result, /* 512 bits, 8 qwords */
263 UINT64 *g, /* 512 bits, 8 qwords */
264 UINT64 *exp, /* 512 bits, 8 qwords */
265 struct mod_ctx_512 *data);
266
267typedef struct st_e_rsax_mod_ctx
268{
269 UINT64 type;
270 union {
271 struct mod_ctx_512 b512;
272 } ctx;
273
274} E_RSAX_MOD_CTX;
275
276static E_RSAX_MOD_CTX *e_rsax_get_ctx(RSA *rsa, int idx, BIGNUM* m)
277{
278 E_RSAX_MOD_CTX *hptr;
279
280 if (idx < 0 || idx > 2)
281 return NULL;
282
283 hptr = RSA_get_ex_data(rsa, rsax_ex_data_idx);
284 if (!hptr) {
285 hptr = OPENSSL_malloc(3*sizeof(E_RSAX_MOD_CTX));
286 if (!hptr) return NULL;
287 hptr[2].type = hptr[1].type= hptr[0].type = 0;
288 RSA_set_ex_data(rsa, rsax_ex_data_idx, hptr);
289 }
290
291 if (hptr[idx].type == (UINT64)BN_num_bits(m))
292 return hptr+idx;
293
294 if (BN_num_bits(m) == 512) {
295 UINT64 _m[8];
296 bn_extract_to_array_512(m, 8, _m);
297 memset( &hptr[idx].ctx.b512, 0, sizeof(struct mod_ctx_512));
298 mod_exp_pre_compute_data_512(_m, &hptr[idx].ctx.b512);
299 }
300
301 hptr[idx].type = BN_num_bits(m);
302 return hptr+idx;
303}
304
305static int e_rsax_rsa_finish(RSA *rsa)
306 {
307 E_RSAX_MOD_CTX *hptr = RSA_get_ex_data(rsa, rsax_ex_data_idx);
308 if(hptr)
309 {
310 OPENSSL_free(hptr);
311 RSA_set_ex_data(rsa, rsax_ex_data_idx, NULL);
312 }
313 if (rsa->_method_mod_n)
314 BN_MONT_CTX_free(rsa->_method_mod_n);
315 if (rsa->_method_mod_p)
316 BN_MONT_CTX_free(rsa->_method_mod_p);
317 if (rsa->_method_mod_q)
318 BN_MONT_CTX_free(rsa->_method_mod_q);
319 return 1;
320 }
321
322
323static int e_rsax_bn_mod_exp(BIGNUM *r, const BIGNUM *g, const BIGNUM *e,
324 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont, E_RSAX_MOD_CTX* rsax_mod_ctx )
325{
326 if (rsax_mod_ctx && BN_get_flags(e, BN_FLG_CONSTTIME) != 0) {
327 if (BN_num_bits(m) == 512) {
328 UINT64 _r[8];
329 UINT64 _g[8];
330 UINT64 _e[8];
331
332 /* Init the arrays from the BIGNUMs */
333 bn_extract_to_array_512(g, 8, _g);
334 bn_extract_to_array_512(e, 8, _e);
335
336 mod_exp_512(_r, _g, _e, &rsax_mod_ctx->ctx.b512);
337 /* Return the result in the BIGNUM */
338 interleaved_array_to_bn_512(r, _r);
339 return 1;
340 }
341 }
342
343 return BN_mod_exp_mont(r, g, e, m, ctx, in_mont);
344}
345
346/* Declares for the Intel CIAP 512-bit / CRT / 1024 bit RSA modular
347 * exponentiation routine precalculations and a structure to hold the
348 * necessary values. These files are meant to live in crypto/rsa/ in
349 * the target openssl.
350 */
351
352/*
353 * Local method: extracts a piece from a BIGNUM, to fit it into
354 * an array. Call with n=8 to extract an entire 512-bit BIGNUM
355 */
356static int bn_extract_to_array_512(const BIGNUM* b, unsigned int n, UINT64 *array)
357{
358 int i;
359 UINT64 tmp;
360 unsigned char bn_buff[64];
361 memset(bn_buff, 0, 64);
362 if (BN_num_bytes(b) > 64) {
363 printf ("Can't support this byte size\n");
364 return 0; }
365 if (BN_num_bytes(b)!=0) {
366 if (!BN_bn2bin(b, bn_buff+(64-BN_num_bytes(b)))) {
367 printf ("Error's in bn2bin\n");
368 /* We have to error, here */
369 return 0; } }
370 while (n-- > 0) {
371 array[n] = 0;
372 for (i=7; i>=0; i--) {
373 tmp = bn_buff[63-(n*8+i)];
374 array[n] |= tmp << (8*i); } }
375 return 1;
376}
377
378/* Init a 512-bit BIGNUM from the UINT64*_ (8 * 64) interleaved array */
379static int interleaved_array_to_bn_512(BIGNUM* b, UINT64 *array)
380{
381 unsigned char tmp[64];
382 int n=8;
383 int i;
384 while (n-- > 0) {
385 for (i = 7; i>=0; i--) {
386 tmp[63-(n*8+i)] = (unsigned char)(array[n]>>(8*i)); } }
387 BN_bin2bn(tmp, 64, b);
388 return 0;
389}
390
391
392/* The main 512bit precompute call */
393static int mod_exp_pre_compute_data_512(UINT64 *m, struct mod_ctx_512 *data)
394 {
395 BIGNUM two_768, two_640, two_128, two_512, tmp, _m, tmp2;
396
397 /* We need a BN_CTX for the modulo functions */
398 BN_CTX* ctx;
399 /* Some tmps */
400 UINT64 _t[8];
401 int i, j, ret = 0;
402
403 /* Init _m with m */
404 BN_init(&_m);
405 interleaved_array_to_bn_512(&_m, m);
406 memset(_t, 0, 64);
407
408 /* Inits */
409 BN_init(&two_768);
410 BN_init(&two_640);
411 BN_init(&two_128);
412 BN_init(&two_512);
413 BN_init(&tmp);
414 BN_init(&tmp2);
415
416 /* Create our context */
417 if ((ctx=BN_CTX_new()) == NULL) { goto err; }
418 BN_CTX_start(ctx);
419
420 /*
421 * For production, if you care, these only need to be set once,
422 * and may be made constants.
423 */
424 BN_lshift(&two_768, BN_value_one(), 768);
425 BN_lshift(&two_640, BN_value_one(), 640);
426 BN_lshift(&two_128, BN_value_one(), 128);
427 BN_lshift(&two_512, BN_value_one(), 512);
428
429 if (0 == (m[7] & 0x8000000000000000)) {
430 exit(1);
431 }
432 if (0 == (m[0] & 0x1)) { /* Odd modulus required for Mont */
433 exit(1);
434 }
435
436 /* Precompute m1 */
437 BN_mod(&tmp, &two_768, &_m, ctx);
438 if (!bn_extract_to_array_512(&tmp, 8, &data->m1[0])) {
439 goto err; }
440
441 /* Precompute m2 */
442 BN_mod(&tmp, &two_640, &_m, ctx);
443 if (!bn_extract_to_array_512(&tmp, 8, &data->m2[0])) {
444 goto err;
445 }
446
447 /*
448 * Precompute k1, a 128b number = ((-1)* m-1 ) mod 2128; k1 should
449 * be non-negative.
450 */
451 BN_mod_inverse(&tmp, &_m, &two_128, ctx);
452 if (!BN_is_zero(&tmp)) { BN_sub(&tmp, &two_128, &tmp); }
453 if (!bn_extract_to_array_512(&tmp, 2, &data->k1[0])) {
454 goto err; }
455
456 /* Precompute t */
457 for (i=0; i<8; i++) {
458 BN_zero(&tmp);
459 if (i & 1) { BN_add(&tmp, &two_512, &tmp); }
460 if (i & 2) { BN_add(&tmp, &two_512, &tmp); }
461 if (i & 4) { BN_add(&tmp, &two_640, &tmp); }
462
463 BN_nnmod(&tmp2, &tmp, &_m, ctx);
464 if (!bn_extract_to_array_512(&tmp2, 8, _t)) {
465 goto err; }
466 for (j=0; j<8; j++) data->t[j][i] = _t[j]; }
467
468 /* Precompute m */
469 for (i=0; i<8; i++) {
470 data->m[i] = m[i]; }
471
472 ret = 1;
473
474err:
475 /* Cleanup */
476 if (ctx != NULL) {
477 BN_CTX_end(ctx); BN_CTX_free(ctx); }
478 BN_free(&two_768);
479 BN_free(&two_640);
480 BN_free(&two_128);
481 BN_free(&two_512);
482 BN_free(&tmp);
483 BN_free(&tmp2);
484 BN_free(&_m);
485
486 return ret;
487}
488
489
490static int e_rsax_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
491 {
492 BIGNUM *r1,*m1,*vrfy;
493 BIGNUM local_dmp1,local_dmq1,local_c,local_r1;
494 BIGNUM *dmp1,*dmq1,*c,*pr1;
495 int ret=0;
496
497 BN_CTX_start(ctx);
498 r1 = BN_CTX_get(ctx);
499 m1 = BN_CTX_get(ctx);
500 vrfy = BN_CTX_get(ctx);
501
502 {
503 BIGNUM local_p, local_q;
504 BIGNUM *p = NULL, *q = NULL;
505 int error = 0;
506
507 /* Make sure BN_mod_inverse in Montgomery
508 * intialization uses the BN_FLG_CONSTTIME flag
509 * (unless RSA_FLAG_NO_CONSTTIME is set)
510 */
511 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
512 {
513 BN_init(&local_p);
514 p = &local_p;
515 BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
516
517 BN_init(&local_q);
518 q = &local_q;
519 BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME);
520 }
521 else
522 {
523 p = rsa->p;
524 q = rsa->q;
525 }
526
527 if (rsa->flags & RSA_FLAG_CACHE_PRIVATE)
528 {
529 if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p, CRYPTO_LOCK_RSA, p, ctx))
530 error = 1;
531 if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_q, CRYPTO_LOCK_RSA, q, ctx))
532 error = 1;
533 }
534
535 /* clean up */
536 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
537 {
538 BN_free(&local_p);
539 BN_free(&local_q);
540 }
541 if ( error )
542 goto err;
543 }
544
545 if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
546 if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
547 goto err;
548
549 /* compute I mod q */
550 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
551 {
552 c = &local_c;
553 BN_with_flags(c, I, BN_FLG_CONSTTIME);
554 if (!BN_mod(r1,c,rsa->q,ctx)) goto err;
555 }
556 else
557 {
558 if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
559 }
560
561 /* compute r1^dmq1 mod q */
562 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
563 {
564 dmq1 = &local_dmq1;
565 BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
566 }
567 else
568 dmq1 = rsa->dmq1;
569
570 if (!e_rsax_bn_mod_exp(m1,r1,dmq1,rsa->q,ctx,
571 rsa->_method_mod_q, e_rsax_get_ctx(rsa, 0, rsa->q) )) goto err;
572
573 /* compute I mod p */
574 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
575 {
576 c = &local_c;
577 BN_with_flags(c, I, BN_FLG_CONSTTIME);
578 if (!BN_mod(r1,c,rsa->p,ctx)) goto err;
579 }
580 else
581 {
582 if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
583 }
584
585 /* compute r1^dmp1 mod p */
586 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
587 {
588 dmp1 = &local_dmp1;
589 BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
590 }
591 else
592 dmp1 = rsa->dmp1;
593
594 if (!e_rsax_bn_mod_exp(r0,r1,dmp1,rsa->p,ctx,
595 rsa->_method_mod_p, e_rsax_get_ctx(rsa, 1, rsa->p) )) goto err;
596
597 if (!BN_sub(r0,r0,m1)) goto err;
598 /* This will help stop the size of r0 increasing, which does
599 * affect the multiply if it optimised for a power of 2 size */
600 if (BN_is_negative(r0))
601 if (!BN_add(r0,r0,rsa->p)) goto err;
602
603 if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err;
604
605 /* Turn BN_FLG_CONSTTIME flag on before division operation */
606 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
607 {
608 pr1 = &local_r1;
609 BN_with_flags(pr1, r1, BN_FLG_CONSTTIME);
610 }
611 else
612 pr1 = r1;
613 if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err;
614
615 /* If p < q it is occasionally possible for the correction of
616 * adding 'p' if r0 is negative above to leave the result still
617 * negative. This can break the private key operations: the following
618 * second correction should *always* correct this rare occurrence.
619 * This will *never* happen with OpenSSL generated keys because
620 * they ensure p > q [steve]
621 */
622 if (BN_is_negative(r0))
623 if (!BN_add(r0,r0,rsa->p)) goto err;
624 if (!BN_mul(r1,r0,rsa->q,ctx)) goto err;
625 if (!BN_add(r0,r1,m1)) goto err;
626
627 if (rsa->e && rsa->n)
628 {
629 if (!e_rsax_bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n, e_rsax_get_ctx(rsa, 2, rsa->n) ))
630 goto err;
631
632 /* If 'I' was greater than (or equal to) rsa->n, the operation
633 * will be equivalent to using 'I mod n'. However, the result of
634 * the verify will *always* be less than 'n' so we don't check
635 * for absolute equality, just congruency. */
636 if (!BN_sub(vrfy, vrfy, I)) goto err;
637 if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err;
638 if (BN_is_negative(vrfy))
639 if (!BN_add(vrfy, vrfy, rsa->n)) goto err;
640 if (!BN_is_zero(vrfy))
641 {
642 /* 'I' and 'vrfy' aren't congruent mod n. Don't leak
643 * miscalculated CRT output, just do a raw (slower)
644 * mod_exp and return that instead. */
645
646 BIGNUM local_d;
647 BIGNUM *d = NULL;
648
649 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
650 {
651 d = &local_d;
652 BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
653 }
654 else
655 d = rsa->d;
656 if (!e_rsax_bn_mod_exp(r0,I,d,rsa->n,ctx,
657 rsa->_method_mod_n, e_rsax_get_ctx(rsa, 2, rsa->n) )) goto err;
658 }
659 }
660 ret=1;
661
662err:
663 BN_CTX_end(ctx);
664
665 return ret;
666 }
667#endif /* !OPENSSL_NO_RSA */
668#endif /* !COMPILE_RSAX */
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 */