summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto')
-rw-r--r--src/lib/libcrypto/engine/Makefile10
-rw-r--r--src/lib/libcrypto/engine/eng_cryptodev.c1449
-rw-r--r--src/lib/libcrypto/engine/eng_padlock.c38
-rw-r--r--src/lib/libcrypto/engine/eng_padlock.ec1
4 files changed, 38 insertions, 1460 deletions
diff --git a/src/lib/libcrypto/engine/Makefile b/src/lib/libcrypto/engine/Makefile
index 44900f0420..06e1bc7494 100644
--- a/src/lib/libcrypto/engine/Makefile
+++ b/src/lib/libcrypto/engine/Makefile
@@ -17,17 +17,18 @@ TEST= enginetest.c
17APPS= 17APPS=
18 18
19LIB=$(TOP)/libcrypto.a 19LIB=$(TOP)/libcrypto.a
20LIBNAMES= eng_padlock
20LIBSRC= eng_err.c eng_lib.c eng_list.c eng_init.c eng_ctrl.c \ 21LIBSRC= 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 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_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 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_openssl.c eng_cnf.c eng_dyn.c \
25 eng_rsax.c eng_rdrand.c 26 eng_rsax.c eng_rdrand.c
26LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \ 27LIBOBJ= 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 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_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 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_openssl.o eng_cnf.o eng_dyn.o \
31 eng_rsax.o eng_rdrand.o 32 eng_rsax.o eng_rdrand.o
32 33
33SRC= $(LIBSRC) 34SRC= $(LIBSRC)
@@ -66,6 +67,11 @@ install:
66tags: 67tags:
67 ctags $(SRC) 68 ctags $(SRC)
68 69
70errors:
71 set -e; for l in $(LIBNAMES); do \
72 $(PERL) ../../util/mkerr.pl -conf eng_$$l.ec \
73 -nostatic -staticloader -write eng_$$l.c; \
74 done
69tests: 75tests:
70 76
71lint: 77lint:
diff --git a/src/lib/libcrypto/engine/eng_cryptodev.c b/src/lib/libcrypto/engine/eng_cryptodev.c
deleted file mode 100644
index a7abac1a7b..0000000000
--- a/src/lib/libcrypto/engine/eng_cryptodev.c
+++ /dev/null
@@ -1,1449 +0,0 @@
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_padlock.c b/src/lib/libcrypto/engine/eng_padlock.c
index 743558ab33..9f7a85a8da 100644
--- a/src/lib/libcrypto/engine/eng_padlock.c
+++ b/src/lib/libcrypto/engine/eng_padlock.c
@@ -104,10 +104,14 @@
104# if (defined(__GNUC__) && (defined(__i386__) || defined(__i386))) || \ 104# if (defined(__GNUC__) && (defined(__i386__) || defined(__i386))) || \
105 (defined(_MSC_VER) && defined(_M_IX86)) 105 (defined(_MSC_VER) && defined(_M_IX86))
106# define COMPILE_HW_PADLOCK 106# define COMPILE_HW_PADLOCK
107static ENGINE *ENGINE_padlock (void);
108# endif 107# endif
109#endif 108#endif
110 109
110#ifdef OPENSSL_NO_DYNAMIC_ENGINE
111#ifdef COMPILE_HW_PADLOCK
112static ENGINE *ENGINE_padlock (void);
113#endif
114
111void ENGINE_load_padlock (void) 115void ENGINE_load_padlock (void)
112{ 116{
113/* On non-x86 CPUs it just returns. */ 117/* On non-x86 CPUs it just returns. */
@@ -120,17 +124,21 @@ void ENGINE_load_padlock (void)
120#endif 124#endif
121} 125}
122 126
127#endif
128
123#ifdef COMPILE_HW_PADLOCK 129#ifdef COMPILE_HW_PADLOCK
124/* We do these includes here to avoid header problems on platforms that 130/* We do these includes here to avoid header problems on platforms that
125 do not have the VIA padlock anyway... */ 131 do not have the VIA padlock anyway... */
126#ifdef _MSC_VER 132#include <stdlib.h>
133#ifdef _WIN32
127# include <malloc.h> 134# include <malloc.h>
128# define alloca _alloca 135# ifndef alloca
129#elif defined(NETWARE_CLIB) && defined(__GNUC__) 136# define alloca _alloca
130 void *alloca(size_t); 137# endif
131# define alloca(s) __builtin_alloca(s) 138#elif defined(__GNUC__)
132#else 139# ifndef alloca
133# include <stdlib.h> 140# define alloca(s) __builtin_alloca(s)
141# endif
134#endif 142#endif
135 143
136/* Function for ENGINE detection and control */ 144/* Function for ENGINE detection and control */
@@ -191,6 +199,8 @@ padlock_bind_helper(ENGINE *e)
191 return 1; 199 return 1;
192} 200}
193 201
202#ifdef OPENSSL_NO_DYNAMIC_ENGINE
203
194/* Constructor */ 204/* Constructor */
195static ENGINE * 205static ENGINE *
196ENGINE_padlock(void) 206ENGINE_padlock(void)
@@ -209,6 +219,8 @@ ENGINE_padlock(void)
209 return eng; 219 return eng;
210} 220}
211 221
222#endif
223
212/* Check availability of the engine */ 224/* Check availability of the engine */
213static int 225static int
214padlock_init(ENGINE *e) 226padlock_init(ENGINE *e)
@@ -234,7 +246,7 @@ padlock_bind_fn(ENGINE *e, const char *id)
234 return 1; 246 return 1;
235} 247}
236 248
237IMPLEMENT_DYNAMIC_CHECK_FN () 249IMPLEMENT_DYNAMIC_CHECK_FN()
238IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn) 250IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn)
239#endif /* DYNAMIC_ENGINE */ 251#endif /* DYNAMIC_ENGINE */
240 252
@@ -1213,6 +1225,14 @@ static RAND_METHOD padlock_rand = {
1213 padlock_rand_status, /* rand status */ 1225 padlock_rand_status, /* rand status */
1214}; 1226};
1215 1227
1228#else /* !COMPILE_HW_PADLOCK */
1229#ifndef OPENSSL_NO_DYNAMIC_ENGINE
1230OPENSSL_EXPORT
1231int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
1232OPENSSL_EXPORT
1233int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; }
1234IMPLEMENT_DYNAMIC_CHECK_FN()
1235#endif
1216#endif /* COMPILE_HW_PADLOCK */ 1236#endif /* COMPILE_HW_PADLOCK */
1217 1237
1218#endif /* !OPENSSL_NO_HW_PADLOCK */ 1238#endif /* !OPENSSL_NO_HW_PADLOCK */
diff --git a/src/lib/libcrypto/engine/eng_padlock.ec b/src/lib/libcrypto/engine/eng_padlock.ec
new file mode 100644
index 0000000000..a0e7cbd60d
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_padlock.ec
@@ -0,0 +1 @@
L PADLOCK eng_padlock_err.h eng_padlock_err.c