summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/engine/eng_cryptodev.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/engine/eng_cryptodev.c')
-rw-r--r--src/lib/libcrypto/engine/eng_cryptodev.c1418
1 files changed, 1418 insertions, 0 deletions
diff --git a/src/lib/libcrypto/engine/eng_cryptodev.c b/src/lib/libcrypto/engine/eng_cryptodev.c
new file mode 100644
index 0000000000..10b3856b4e
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_cryptodev.c
@@ -0,0 +1,1418 @@
1/*
2 * Copyright (c) 2002 Bob Beck <beck@openbsd.org>
3 * Copyright (c) 2002 Theo de Raadt
4 * Copyright (c) 2002 Markus Friedl
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29#include <openssl/objects.h>
30#include <openssl/engine.h>
31#include <openssl/evp.h>
32#include <openssl/bn.h>
33
34#if (defined(__unix__) || defined(unix)) && !defined(USG) && \
35 (defined(__OpenBSD__) || defined(__FreeBSD__))
36#include <sys/param.h>
37# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041)
38# define HAVE_CRYPTODEV
39# endif
40# if (OpenBSD >= 200110)
41# define HAVE_SYSLOG_R
42# endif
43#endif
44
45#ifndef HAVE_CRYPTODEV
46
47void
48ENGINE_load_cryptodev(void)
49{
50 /* This is a NOP on platforms without /dev/crypto */
51 return;
52}
53
54#else
55
56#include <sys/types.h>
57#include <crypto/cryptodev.h>
58#include <crypto/dh/dh.h>
59#include <crypto/dsa/dsa.h>
60#include <crypto/err/err.h>
61#include <crypto/rsa/rsa.h>
62#include <sys/ioctl.h>
63#include <errno.h>
64#include <stdio.h>
65#include <unistd.h>
66#include <fcntl.h>
67#include <stdarg.h>
68#include <syslog.h>
69#include <errno.h>
70#include <string.h>
71
72struct dev_crypto_state {
73 struct session_op d_sess;
74 int d_fd;
75
76#ifdef USE_CRYPTODEV_DIGESTS
77 char dummy_mac_key[HASH_MAX_LEN];
78
79 unsigned char digest_res[HASH_MAX_LEN];
80 char *mac_data;
81 int mac_len;
82
83 int copy;
84#endif
85};
86
87static u_int32_t cryptodev_asymfeat = 0;
88
89static int get_asym_dev_crypto(void);
90static int open_dev_crypto(void);
91static int get_dev_crypto(void);
92static int get_cryptodev_ciphers(const int **cnids);
93#ifdef USE_CRYPTODEV_DIGESTS
94static int get_cryptodev_digests(const int **cnids);
95#endif
96static int cryptodev_usable_ciphers(const int **nids);
97static int cryptodev_usable_digests(const int **nids);
98static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
99 const unsigned char *in, size_t inl);
100static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
101 const unsigned char *iv, int enc);
102static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx);
103static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
104 const int **nids, int nid);
105static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
106 const int **nids, int nid);
107static int bn2crparam(const BIGNUM *a, struct crparam *crp);
108static int crparam2bn(struct crparam *crp, BIGNUM *a);
109static void zapparams(struct crypt_kop *kop);
110static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r,
111 int slen, BIGNUM *s);
112
113static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
114 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
115static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I,
116 RSA *rsa, BN_CTX *ctx);
117static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
118static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
119 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
120static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
121 BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
122 BN_CTX *ctx, BN_MONT_CTX *mont);
123static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst,
124 int dlen, DSA *dsa);
125static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
126 DSA_SIG *sig, DSA *dsa);
127static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
128 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
129 BN_MONT_CTX *m_ctx);
130static int cryptodev_dh_compute_key(unsigned char *key,
131 const BIGNUM *pub_key, DH *dh);
132static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p,
133 void (*f)(void));
134void ENGINE_load_cryptodev(void);
135
136static const ENGINE_CMD_DEFN cryptodev_defns[] = {
137 { 0, NULL, NULL, 0 }
138};
139
140static struct {
141 int id;
142 int nid;
143 int ivmax;
144 int keylen;
145} ciphers[] = {
146 { CRYPTO_ARC4, NID_rc4, 0, 16, },
147 { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, },
148 { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, },
149 { CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, },
150 { CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24, },
151 { CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32, },
152 { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, },
153 { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, },
154 { 0, NID_undef, 0, 0, },
155};
156
157#ifdef USE_CRYPTODEV_DIGESTS
158static struct {
159 int id;
160 int nid;
161 int keylen;
162} digests[] = {
163 { CRYPTO_MD5_HMAC, NID_hmacWithMD5, 16},
164 { CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, 20},
165 { CRYPTO_RIPEMD160_HMAC, NID_ripemd160, 16/*?*/},
166 { CRYPTO_MD5_KPDK, NID_undef, 0},
167 { CRYPTO_SHA1_KPDK, NID_undef, 0},
168 { CRYPTO_MD5, NID_md5, 16},
169 { CRYPTO_SHA1, NID_sha1, 20},
170 { 0, NID_undef, 0},
171};
172#endif
173
174/*
175 * Return a fd if /dev/crypto seems usable, 0 otherwise.
176 */
177static int
178open_dev_crypto(void)
179{
180 static int fd = -1;
181
182 if (fd == -1) {
183 if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1)
184 return (-1);
185 /* close on exec */
186 if (fcntl(fd, F_SETFD, 1) == -1) {
187 close(fd);
188 fd = -1;
189 return (-1);
190 }
191 }
192 return (fd);
193}
194
195static int
196get_dev_crypto(void)
197{
198 int fd, retfd;
199
200 if ((fd = open_dev_crypto()) == -1)
201 return (-1);
202 if (ioctl(fd, CRIOGET, &retfd) == -1)
203 return (-1);
204
205 /* close on exec */
206 if (fcntl(retfd, F_SETFD, 1) == -1) {
207 close(retfd);
208 return (-1);
209 }
210 return (retfd);
211}
212
213/* Caching version for asym operations */
214static int
215get_asym_dev_crypto(void)
216{
217 static int fd = -1;
218
219 if (fd == -1)
220 fd = get_dev_crypto();
221 return fd;
222}
223
224/*
225 * Find out what ciphers /dev/crypto will let us have a session for.
226 * XXX note, that some of these openssl doesn't deal with yet!
227 * returning them here is harmless, as long as we return NULL
228 * when asked for a handler in the cryptodev_engine_ciphers routine
229 */
230static int
231get_cryptodev_ciphers(const int **cnids)
232{
233 static int nids[CRYPTO_ALGORITHM_MAX];
234 struct session_op sess;
235 int fd, i, count = 0;
236
237 if ((fd = get_dev_crypto()) < 0) {
238 *cnids = NULL;
239 return (0);
240 }
241 memset(&sess, 0, sizeof(sess));
242 sess.key = (caddr_t)"123456789abcdefghijklmno";
243
244 for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
245 if (ciphers[i].nid == NID_undef)
246 continue;
247 sess.cipher = ciphers[i].id;
248 sess.keylen = ciphers[i].keylen;
249 sess.mac = 0;
250 if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
251 ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
252 nids[count++] = ciphers[i].nid;
253 }
254 close(fd);
255
256 if (count > 0)
257 *cnids = nids;
258 else
259 *cnids = NULL;
260 return (count);
261}
262
263#ifdef USE_CRYPTODEV_DIGESTS
264/*
265 * Find out what digests /dev/crypto will let us have a session for.
266 * XXX note, that some of these openssl doesn't deal with yet!
267 * returning them here is harmless, as long as we return NULL
268 * when asked for a handler in the cryptodev_engine_digests routine
269 */
270static int
271get_cryptodev_digests(const int **cnids)
272{
273 static int nids[CRYPTO_ALGORITHM_MAX];
274 struct session_op sess;
275 int fd, i, count = 0;
276
277 if ((fd = get_dev_crypto()) < 0) {
278 *cnids = NULL;
279 return (0);
280 }
281 memset(&sess, 0, sizeof(sess));
282 sess.mackey = (caddr_t)"123456789abcdefghijklmno";
283 for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
284 if (digests[i].nid == NID_undef)
285 continue;
286 sess.mac = digests[i].id;
287 sess.mackeylen = digests[i].keylen;
288 sess.cipher = 0;
289 if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
290 ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
291 nids[count++] = digests[i].nid;
292 }
293 close(fd);
294
295 if (count > 0)
296 *cnids = nids;
297 else
298 *cnids = NULL;
299 return (count);
300}
301#endif /* 0 */
302
303/*
304 * Find the useable ciphers|digests from dev/crypto - this is the first
305 * thing called by the engine init crud which determines what it
306 * can use for ciphers from this engine. We want to return
307 * only what we can do, anythine else is handled by software.
308 *
309 * If we can't initialize the device to do anything useful for
310 * any reason, we want to return a NULL array, and 0 length,
311 * which forces everything to be done is software. By putting
312 * the initalization of the device in here, we ensure we can
313 * use this engine as the default, and if for whatever reason
314 * /dev/crypto won't do what we want it will just be done in
315 * software
316 *
317 * This can (should) be greatly expanded to perhaps take into
318 * account speed of the device, and what we want to do.
319 * (although the disabling of particular alg's could be controlled
320 * by the device driver with sysctl's.) - this is where we
321 * want most of the decisions made about what we actually want
322 * to use from /dev/crypto.
323 */
324static int
325cryptodev_usable_ciphers(const int **nids)
326{
327 return (get_cryptodev_ciphers(nids));
328}
329
330static int
331cryptodev_usable_digests(const int **nids)
332{
333#ifdef USE_CRYPTODEV_DIGESTS
334 return (get_cryptodev_digests(nids));
335#else
336 /*
337 * XXXX just disable all digests for now, because it sucks.
338 * we need a better way to decide this - i.e. I may not
339 * want digests on slow cards like hifn on fast machines,
340 * but might want them on slow or loaded machines, etc.
341 * will also want them when using crypto cards that don't
342 * suck moose gonads - would be nice to be able to decide something
343 * as reasonable default without having hackery that's card dependent.
344 * of course, the default should probably be just do everything,
345 * with perhaps a sysctl to turn algoritms off (or have them off
346 * by default) on cards that generally suck like the hifn.
347 */
348 *nids = NULL;
349 return (0);
350#endif
351}
352
353static int
354cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
355 const unsigned char *in, size_t inl)
356{
357 struct crypt_op cryp;
358 struct dev_crypto_state *state = ctx->cipher_data;
359 struct session_op *sess = &state->d_sess;
360 const void *iiv;
361 unsigned char save_iv[EVP_MAX_IV_LENGTH];
362
363 if (state->d_fd < 0)
364 return (0);
365 if (!inl)
366 return (1);
367 if ((inl % ctx->cipher->block_size) != 0)
368 return (0);
369
370 memset(&cryp, 0, sizeof(cryp));
371
372 cryp.ses = sess->ses;
373 cryp.flags = 0;
374 cryp.len = inl;
375 cryp.src = (caddr_t) in;
376 cryp.dst = (caddr_t) out;
377 cryp.mac = 0;
378
379 cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
380
381 if (ctx->cipher->iv_len) {
382 cryp.iv = (caddr_t) ctx->iv;
383 if (!ctx->encrypt) {
384 iiv = in + inl - ctx->cipher->iv_len;
385 memcpy(save_iv, iiv, ctx->cipher->iv_len);
386 }
387 } else
388 cryp.iv = NULL;
389
390 if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) {
391 /* XXX need better errror handling
392 * this can fail for a number of different reasons.
393 */
394 return (0);
395 }
396
397 if (ctx->cipher->iv_len) {
398 if (ctx->encrypt)
399 iiv = out + inl - ctx->cipher->iv_len;
400 else
401 iiv = save_iv;
402 memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
403 }
404 return (1);
405}
406
407static int
408cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
409 const unsigned char *iv, int enc)
410{
411 struct dev_crypto_state *state = ctx->cipher_data;
412 struct session_op *sess = &state->d_sess;
413 int cipher = -1, i;
414
415 for (i = 0; ciphers[i].id; i++)
416 if (ctx->cipher->nid == ciphers[i].nid &&
417 ctx->cipher->iv_len <= ciphers[i].ivmax &&
418 ctx->key_len == ciphers[i].keylen) {
419 cipher = ciphers[i].id;
420 break;
421 }
422
423 if (!ciphers[i].id) {
424 state->d_fd = -1;
425 return (0);
426 }
427
428 memset(sess, 0, sizeof(struct session_op));
429
430 if ((state->d_fd = get_dev_crypto()) < 0)
431 return (0);
432
433 sess->key = (caddr_t)key;
434 sess->keylen = ctx->key_len;
435 sess->cipher = cipher;
436
437 if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
438 close(state->d_fd);
439 state->d_fd = -1;
440 return (0);
441 }
442 return (1);
443}
444
445/*
446 * free anything we allocated earlier when initting a
447 * session, and close the session.
448 */
449static int
450cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
451{
452 int ret = 0;
453 struct dev_crypto_state *state = ctx->cipher_data;
454 struct session_op *sess = &state->d_sess;
455
456 if (state->d_fd < 0)
457 return (0);
458
459 /* XXX if this ioctl fails, someting's wrong. the invoker
460 * may have called us with a bogus ctx, or we could
461 * have a device that for whatever reason just doesn't
462 * want to play ball - it's not clear what's right
463 * here - should this be an error? should it just
464 * increase a counter, hmm. For right now, we return
465 * 0 - I don't believe that to be "right". we could
466 * call the gorpy openssl lib error handlers that
467 * print messages to users of the library. hmm..
468 */
469
470 if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) {
471 ret = 0;
472 } else {
473 ret = 1;
474 }
475 close(state->d_fd);
476 state->d_fd = -1;
477
478 return (ret);
479}
480
481/*
482 * libcrypto EVP stuff - this is how we get wired to EVP so the engine
483 * gets called when libcrypto requests a cipher NID.
484 */
485
486/* RC4 */
487const EVP_CIPHER cryptodev_rc4 = {
488 NID_rc4,
489 1, 16, 0,
490 EVP_CIPH_VARIABLE_LENGTH,
491 cryptodev_init_key,
492 cryptodev_cipher,
493 cryptodev_cleanup,
494 sizeof(struct dev_crypto_state),
495 NULL,
496 NULL,
497 NULL
498};
499
500/* DES CBC EVP */
501const EVP_CIPHER cryptodev_des_cbc = {
502 NID_des_cbc,
503 8, 8, 8,
504 EVP_CIPH_CBC_MODE,
505 cryptodev_init_key,
506 cryptodev_cipher,
507 cryptodev_cleanup,
508 sizeof(struct dev_crypto_state),
509 EVP_CIPHER_set_asn1_iv,
510 EVP_CIPHER_get_asn1_iv,
511 NULL
512};
513
514/* 3DES CBC EVP */
515const EVP_CIPHER cryptodev_3des_cbc = {
516 NID_des_ede3_cbc,
517 8, 24, 8,
518 EVP_CIPH_CBC_MODE,
519 cryptodev_init_key,
520 cryptodev_cipher,
521 cryptodev_cleanup,
522 sizeof(struct dev_crypto_state),
523 EVP_CIPHER_set_asn1_iv,
524 EVP_CIPHER_get_asn1_iv,
525 NULL
526};
527
528const EVP_CIPHER cryptodev_bf_cbc = {
529 NID_bf_cbc,
530 8, 16, 8,
531 EVP_CIPH_CBC_MODE,
532 cryptodev_init_key,
533 cryptodev_cipher,
534 cryptodev_cleanup,
535 sizeof(struct dev_crypto_state),
536 EVP_CIPHER_set_asn1_iv,
537 EVP_CIPHER_get_asn1_iv,
538 NULL
539};
540
541const EVP_CIPHER cryptodev_cast_cbc = {
542 NID_cast5_cbc,
543 8, 16, 8,
544 EVP_CIPH_CBC_MODE,
545 cryptodev_init_key,
546 cryptodev_cipher,
547 cryptodev_cleanup,
548 sizeof(struct dev_crypto_state),
549 EVP_CIPHER_set_asn1_iv,
550 EVP_CIPHER_get_asn1_iv,
551 NULL
552};
553
554const EVP_CIPHER cryptodev_aes_cbc = {
555 NID_aes_128_cbc,
556 16, 16, 16,
557 EVP_CIPH_CBC_MODE,
558 cryptodev_init_key,
559 cryptodev_cipher,
560 cryptodev_cleanup,
561 sizeof(struct dev_crypto_state),
562 EVP_CIPHER_set_asn1_iv,
563 EVP_CIPHER_get_asn1_iv,
564 NULL
565};
566
567const EVP_CIPHER cryptodev_aes_192_cbc = {
568 NID_aes_192_cbc,
569 16, 24, 16,
570 EVP_CIPH_CBC_MODE,
571 cryptodev_init_key,
572 cryptodev_cipher,
573 cryptodev_cleanup,
574 sizeof(struct dev_crypto_state),
575 EVP_CIPHER_set_asn1_iv,
576 EVP_CIPHER_get_asn1_iv,
577 NULL
578};
579
580const EVP_CIPHER cryptodev_aes_256_cbc = {
581 NID_aes_256_cbc,
582 16, 32, 16,
583 EVP_CIPH_CBC_MODE,
584 cryptodev_init_key,
585 cryptodev_cipher,
586 cryptodev_cleanup,
587 sizeof(struct dev_crypto_state),
588 EVP_CIPHER_set_asn1_iv,
589 EVP_CIPHER_get_asn1_iv,
590 NULL
591};
592
593/*
594 * Registered by the ENGINE when used to find out how to deal with
595 * a particular NID in the ENGINE. this says what we'll do at the
596 * top level - note, that list is restricted by what we answer with
597 */
598static int
599cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
600 const int **nids, int nid)
601{
602 if (!cipher)
603 return (cryptodev_usable_ciphers(nids));
604
605 switch (nid) {
606 case NID_rc4:
607 *cipher = &cryptodev_rc4;
608 break;
609 case NID_des_ede3_cbc:
610 *cipher = &cryptodev_3des_cbc;
611 break;
612 case NID_des_cbc:
613 *cipher = &cryptodev_des_cbc;
614 break;
615 case NID_bf_cbc:
616 *cipher = &cryptodev_bf_cbc;
617 break;
618 case NID_cast5_cbc:
619 *cipher = &cryptodev_cast_cbc;
620 break;
621 case NID_aes_128_cbc:
622 *cipher = &cryptodev_aes_cbc;
623 break;
624 case NID_aes_192_cbc:
625 *cipher = &cryptodev_aes_192_cbc;
626 break;
627 case NID_aes_256_cbc:
628 *cipher = &cryptodev_aes_256_cbc;
629 break;
630 default:
631 *cipher = NULL;
632 break;
633 }
634 return (*cipher != NULL);
635}
636
637
638#ifdef USE_CRYPTODEV_DIGESTS
639
640/* convert digest type to cryptodev */
641static int
642digest_nid_to_cryptodev(int nid)
643{
644 int i;
645
646 for (i = 0; digests[i].id; i++)
647 if (digests[i].nid == nid)
648 return (digests[i].id);
649 return (0);
650}
651
652
653static int
654digest_key_length(int nid)
655{
656 int i;
657
658 for (i = 0; digests[i].id; i++)
659 if (digests[i].nid == nid)
660 return digests[i].keylen;
661 return (0);
662}
663
664
665static int cryptodev_digest_init(EVP_MD_CTX *ctx)
666{
667 struct dev_crypto_state *state = ctx->md_data;
668 struct session_op *sess = &state->d_sess;
669 int digest;
670
671 if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef){
672 printf("cryptodev_digest_init: Can't get digest \n");
673 return (0);
674 }
675
676 memset(state, 0, sizeof(struct dev_crypto_state));
677
678 if ((state->d_fd = get_dev_crypto()) < 0) {
679 printf("cryptodev_digest_init: Can't get Dev \n");
680 return (0);
681 }
682
683 sess->mackey = state->dummy_mac_key;
684 sess->mackeylen = digest_key_length(ctx->digest->type);
685 sess->mac = digest;
686
687 if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) {
688 close(state->d_fd);
689 state->d_fd = -1;
690 printf("cryptodev_digest_init: Open session failed\n");
691 return (0);
692 }
693
694 return (1);
695}
696
697static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data,
698 size_t count)
699{
700 struct crypt_op cryp;
701 struct dev_crypto_state *state = ctx->md_data;
702 struct session_op *sess = &state->d_sess;
703
704 if (!data || state->d_fd < 0) {
705 printf("cryptodev_digest_update: illegal inputs \n");
706 return (0);
707 }
708
709 if (!count) {
710 return (0);
711 }
712
713 if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) {
714 /* if application doesn't support one buffer */
715 state->mac_data = OPENSSL_realloc(state->mac_data, state->mac_len + count);
716
717 if (!state->mac_data) {
718 printf("cryptodev_digest_update: realloc failed\n");
719 return (0);
720 }
721
722 memcpy(state->mac_data + state->mac_len, data, count);
723 state->mac_len += count;
724
725 return (1);
726 }
727
728 memset(&cryp, 0, sizeof(cryp));
729
730 cryp.ses = sess->ses;
731 cryp.flags = 0;
732 cryp.len = count;
733 cryp.src = (caddr_t) data;
734 cryp.dst = NULL;
735 cryp.mac = (caddr_t) state->digest_res;
736 if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
737 printf("cryptodev_digest_update: digest failed\n");
738 return (0);
739 }
740 return (1);
741}
742
743
744static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
745{
746 struct crypt_op cryp;
747 struct dev_crypto_state *state = ctx->md_data;
748 struct session_op *sess = &state->d_sess;
749
750 int ret = 1;
751
752 if (!md || state->d_fd < 0) {
753 printf("cryptodev_digest_final: illegal input\n");
754 return(0);
755 }
756
757 if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) {
758 /* if application doesn't support one buffer */
759 memset(&cryp, 0, sizeof(cryp));
760
761 cryp.ses = sess->ses;
762 cryp.flags = 0;
763 cryp.len = state->mac_len;
764 cryp.src = state->mac_data;
765 cryp.dst = NULL;
766 cryp.mac = (caddr_t)md;
767
768 if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
769 printf("cryptodev_digest_final: digest failed\n");
770 return (0);
771 }
772
773 return 1;
774 }
775
776 memcpy(md, state->digest_res, ctx->digest->md_size);
777
778 return (ret);
779}
780
781
782static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
783{
784 int ret = 1;
785 struct dev_crypto_state *state = ctx->md_data;
786 struct session_op *sess = &state->d_sess;
787
788 if (state->d_fd < 0) {
789 printf("cryptodev_digest_cleanup: illegal input\n");
790 return (0);
791 }
792
793 if (state->mac_data) {
794 OPENSSL_free(state->mac_data);
795 state->mac_data = NULL;
796 state->mac_len = 0;
797 }
798
799 if (state->copy)
800 return 1;
801
802 if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
803 printf("cryptodev_digest_cleanup: failed to close session\n");
804 ret = 0;
805 } else {
806 ret = 1;
807 }
808 close(state->d_fd);
809 state->d_fd = -1;
810
811 return (ret);
812}
813
814static int cryptodev_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
815{
816 struct dev_crypto_state *fstate = from->md_data;
817 struct dev_crypto_state *dstate = to->md_data;
818
819 memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
820
821 if (fstate->mac_len != 0) {
822 dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
823 memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
824 }
825
826 dstate->copy = 1;
827
828 return 1;
829}
830
831
832const EVP_MD cryptodev_sha1 = {
833 NID_sha1,
834 NID_undef,
835 SHA_DIGEST_LENGTH,
836 EVP_MD_FLAG_ONESHOT,
837 cryptodev_digest_init,
838 cryptodev_digest_update,
839 cryptodev_digest_final,
840 cryptodev_digest_copy,
841 cryptodev_digest_cleanup,
842 EVP_PKEY_NULL_method,
843 SHA_CBLOCK,
844 sizeof(struct dev_crypto_state),
845};
846
847const EVP_MD cryptodev_md5 = {
848 NID_md5,
849 NID_undef,
850 16 /* MD5_DIGEST_LENGTH */,
851 EVP_MD_FLAG_ONESHOT,
852 cryptodev_digest_init,
853 cryptodev_digest_update,
854 cryptodev_digest_final,
855 cryptodev_digest_copy,
856 cryptodev_digest_cleanup,
857 EVP_PKEY_NULL_method,
858 64 /* MD5_CBLOCK */,
859 sizeof(struct dev_crypto_state),
860};
861
862#endif /* USE_CRYPTODEV_DIGESTS */
863
864
865static int
866cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
867 const int **nids, int nid)
868{
869 if (!digest)
870 return (cryptodev_usable_digests(nids));
871
872 switch (nid) {
873#ifdef USE_CRYPTODEV_DIGESTS
874 case NID_md5:
875 *digest = &cryptodev_md5;
876 break;
877 case NID_sha1:
878 *digest = &cryptodev_sha1;
879 break;
880 default:
881#endif /* USE_CRYPTODEV_DIGESTS */
882 *digest = NULL;
883 break;
884 }
885 return (*digest != NULL);
886}
887
888/*
889 * Convert a BIGNUM to the representation that /dev/crypto needs.
890 * Upon completion of use, the caller is responsible for freeing
891 * crp->crp_p.
892 */
893static int
894bn2crparam(const BIGNUM *a, struct crparam *crp)
895{
896 int i, j, k;
897 ssize_t bytes, bits;
898 u_char *b;
899
900 crp->crp_p = NULL;
901 crp->crp_nbits = 0;
902
903 bits = BN_num_bits(a);
904 bytes = (bits + 7) / 8;
905
906 b = malloc(bytes);
907 if (b == NULL)
908 return (1);
909 memset(b, 0, bytes);
910
911 crp->crp_p = (caddr_t) b;
912 crp->crp_nbits = bits;
913
914 for (i = 0, j = 0; i < a->top; i++) {
915 for (k = 0; k < BN_BITS2 / 8; k++) {
916 if ((j + k) >= bytes)
917 return (0);
918 b[j + k] = a->d[i] >> (k * 8);
919 }
920 j += BN_BITS2 / 8;
921 }
922 return (0);
923}
924
925/* Convert a /dev/crypto parameter to a BIGNUM */
926static int
927crparam2bn(struct crparam *crp, BIGNUM *a)
928{
929 u_int8_t *pd;
930 int i, bytes;
931
932 bytes = (crp->crp_nbits + 7) / 8;
933
934 if (bytes == 0)
935 return (-1);
936
937 if ((pd = (u_int8_t *) malloc(bytes)) == NULL)
938 return (-1);
939
940 for (i = 0; i < bytes; i++)
941 pd[i] = crp->crp_p[bytes - i - 1];
942
943 BN_bin2bn(pd, bytes, a);
944 free(pd);
945
946 return (0);
947}
948
949static void
950zapparams(struct crypt_kop *kop)
951{
952 int i;
953
954 for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) {
955 if (kop->crk_param[i].crp_p)
956 free(kop->crk_param[i].crp_p);
957 kop->crk_param[i].crp_p = NULL;
958 kop->crk_param[i].crp_nbits = 0;
959 }
960}
961
962static int
963cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s)
964{
965 int fd, ret = -1;
966
967 if ((fd = get_asym_dev_crypto()) < 0)
968 return (ret);
969
970 if (r) {
971 kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char));
972 kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8;
973 kop->crk_oparams++;
974 }
975 if (s) {
976 kop->crk_param[kop->crk_iparams+1].crp_p = calloc(slen, sizeof(char));
977 kop->crk_param[kop->crk_iparams+1].crp_nbits = slen * 8;
978 kop->crk_oparams++;
979 }
980
981 if (ioctl(fd, CIOCKEY, kop) == 0) {
982 if (r)
983 crparam2bn(&kop->crk_param[kop->crk_iparams], r);
984 if (s)
985 crparam2bn(&kop->crk_param[kop->crk_iparams+1], s);
986 ret = 0;
987 }
988
989 return (ret);
990}
991
992static int
993cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
994 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
995{
996 struct crypt_kop kop;
997 int ret = 1;
998
999 /* Currently, we know we can do mod exp iff we can do any
1000 * asymmetric operations at all.
1001 */
1002 if (cryptodev_asymfeat == 0) {
1003 ret = BN_mod_exp(r, a, p, m, ctx);
1004 return (ret);
1005 }
1006
1007 memset(&kop, 0, sizeof kop);
1008 kop.crk_op = CRK_MOD_EXP;
1009
1010 /* inputs: a^p % m */
1011 if (bn2crparam(a, &kop.crk_param[0]))
1012 goto err;
1013 if (bn2crparam(p, &kop.crk_param[1]))
1014 goto err;
1015 if (bn2crparam(m, &kop.crk_param[2]))
1016 goto err;
1017 kop.crk_iparams = 3;
1018
1019 if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) {
1020 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
1021 printf("OCF asym process failed, Running in software\n");
1022 ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
1023
1024 } else if (ECANCELED == kop.crk_status) {
1025 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
1026 printf("OCF hardware operation cancelled. Running in Software\n");
1027 ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
1028 }
1029 /* else cryptodev operation worked ok ==> ret = 1*/
1030
1031err:
1032 zapparams(&kop);
1033 return (ret);
1034}
1035
1036static int
1037cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
1038{
1039 int r;
1040 ctx = BN_CTX_new();
1041 r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL);
1042 BN_CTX_free(ctx);
1043 return (r);
1044}
1045
1046static int
1047cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
1048{
1049 struct crypt_kop kop;
1050 int ret = 1;
1051
1052 if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
1053 /* XXX 0 means failure?? */
1054 return (0);
1055 }
1056
1057 memset(&kop, 0, sizeof kop);
1058 kop.crk_op = CRK_MOD_EXP_CRT;
1059 /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
1060 if (bn2crparam(rsa->p, &kop.crk_param[0]))
1061 goto err;
1062 if (bn2crparam(rsa->q, &kop.crk_param[1]))
1063 goto err;
1064 if (bn2crparam(I, &kop.crk_param[2]))
1065 goto err;
1066 if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
1067 goto err;
1068 if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
1069 goto err;
1070 if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
1071 goto err;
1072 kop.crk_iparams = 6;
1073
1074 if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) {
1075 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
1076 printf("OCF asym process failed, running in Software\n");
1077 ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
1078
1079 } else if (ECANCELED == kop.crk_status) {
1080 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
1081 printf("OCF hardware operation cancelled. Running in Software\n");
1082 ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
1083 }
1084 /* else cryptodev operation worked ok ==> ret = 1*/
1085
1086err:
1087 zapparams(&kop);
1088 return (ret);
1089}
1090
1091static RSA_METHOD cryptodev_rsa = {
1092 "cryptodev RSA method",
1093 NULL, /* rsa_pub_enc */
1094 NULL, /* rsa_pub_dec */
1095 NULL, /* rsa_priv_enc */
1096 NULL, /* rsa_priv_dec */
1097 NULL,
1098 NULL,
1099 NULL, /* init */
1100 NULL, /* finish */
1101 0, /* flags */
1102 NULL, /* app_data */
1103 NULL, /* rsa_sign */
1104 NULL /* rsa_verify */
1105};
1106
1107static int
1108cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
1109 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
1110{
1111 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
1112}
1113
1114static int
1115cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
1116 BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
1117 BN_CTX *ctx, BN_MONT_CTX *mont)
1118{
1119 BIGNUM t2;
1120 int ret = 0;
1121
1122 BN_init(&t2);
1123
1124 /* v = ( g^u1 * y^u2 mod p ) mod q */
1125 /* let t1 = g ^ u1 mod p */
1126 ret = 0;
1127
1128 if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont))
1129 goto err;
1130
1131 /* let t2 = y ^ u2 mod p */
1132 if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont))
1133 goto err;
1134 /* let u1 = t1 * t2 mod p */
1135 if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx))
1136 goto err;
1137
1138 BN_copy(t1,u1);
1139
1140 ret = 1;
1141err:
1142 BN_free(&t2);
1143 return(ret);
1144}
1145
1146static DSA_SIG *
1147cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
1148{
1149 struct crypt_kop kop;
1150 BIGNUM *r = NULL, *s = NULL;
1151 DSA_SIG *dsaret = NULL;
1152
1153 if ((r = BN_new()) == NULL)
1154 goto err;
1155 if ((s = BN_new()) == NULL) {
1156 BN_free(r);
1157 goto err;
1158 }
1159
1160 memset(&kop, 0, sizeof kop);
1161 kop.crk_op = CRK_DSA_SIGN;
1162
1163 /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
1164 kop.crk_param[0].crp_p = (caddr_t)dgst;
1165 kop.crk_param[0].crp_nbits = dlen * 8;
1166 if (bn2crparam(dsa->p, &kop.crk_param[1]))
1167 goto err;
1168 if (bn2crparam(dsa->q, &kop.crk_param[2]))
1169 goto err;
1170 if (bn2crparam(dsa->g, &kop.crk_param[3]))
1171 goto err;
1172 if (bn2crparam(dsa->priv_key, &kop.crk_param[4]))
1173 goto err;
1174 kop.crk_iparams = 5;
1175
1176 if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r,
1177 BN_num_bytes(dsa->q), s) == 0) {
1178 dsaret = DSA_SIG_new();
1179 dsaret->r = r;
1180 dsaret->s = s;
1181 } else {
1182 const DSA_METHOD *meth = DSA_OpenSSL();
1183 BN_free(r);
1184 BN_free(s);
1185 dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
1186 }
1187err:
1188 kop.crk_param[0].crp_p = NULL;
1189 zapparams(&kop);
1190 return (dsaret);
1191}
1192
1193static int
1194cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
1195 DSA_SIG *sig, DSA *dsa)
1196{
1197 struct crypt_kop kop;
1198 int dsaret = 1;
1199
1200 memset(&kop, 0, sizeof kop);
1201 kop.crk_op = CRK_DSA_VERIFY;
1202
1203 /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
1204 kop.crk_param[0].crp_p = (caddr_t)dgst;
1205 kop.crk_param[0].crp_nbits = dlen * 8;
1206 if (bn2crparam(dsa->p, &kop.crk_param[1]))
1207 goto err;
1208 if (bn2crparam(dsa->q, &kop.crk_param[2]))
1209 goto err;
1210 if (bn2crparam(dsa->g, &kop.crk_param[3]))
1211 goto err;
1212 if (bn2crparam(dsa->pub_key, &kop.crk_param[4]))
1213 goto err;
1214 if (bn2crparam(sig->r, &kop.crk_param[5]))
1215 goto err;
1216 if (bn2crparam(sig->s, &kop.crk_param[6]))
1217 goto err;
1218 kop.crk_iparams = 7;
1219
1220 if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
1221/*OCF success value is 0, if not zero, change dsaret to fail*/
1222 if(0 != kop.crk_status) dsaret = 0;
1223 } else {
1224 const DSA_METHOD *meth = DSA_OpenSSL();
1225
1226 dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
1227 }
1228err:
1229 kop.crk_param[0].crp_p = NULL;
1230 zapparams(&kop);
1231 return (dsaret);
1232}
1233
1234static DSA_METHOD cryptodev_dsa = {
1235 "cryptodev DSA method",
1236 NULL,
1237 NULL, /* dsa_sign_setup */
1238 NULL,
1239 NULL, /* dsa_mod_exp */
1240 NULL,
1241 NULL, /* init */
1242 NULL, /* finish */
1243 0, /* flags */
1244 NULL /* app_data */
1245};
1246
1247static int
1248cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
1249 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
1250 BN_MONT_CTX *m_ctx)
1251{
1252 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
1253}
1254
1255static int
1256cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
1257{
1258 struct crypt_kop kop;
1259 int dhret = 1;
1260 int fd, keylen;
1261
1262 if ((fd = get_asym_dev_crypto()) < 0) {
1263 const DH_METHOD *meth = DH_OpenSSL();
1264
1265 return ((meth->compute_key)(key, pub_key, dh));
1266 }
1267
1268 keylen = BN_num_bits(dh->p);
1269
1270 memset(&kop, 0, sizeof kop);
1271 kop.crk_op = CRK_DH_COMPUTE_KEY;
1272
1273 /* inputs: dh->priv_key pub_key dh->p key */
1274 if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
1275 goto err;
1276 if (bn2crparam(pub_key, &kop.crk_param[1]))
1277 goto err;
1278 if (bn2crparam(dh->p, &kop.crk_param[2]))
1279 goto err;
1280 kop.crk_iparams = 3;
1281
1282 kop.crk_param[3].crp_p = (caddr_t) key;
1283 kop.crk_param[3].crp_nbits = keylen * 8;
1284 kop.crk_oparams = 1;
1285
1286 if (ioctl(fd, CIOCKEY, &kop) == -1) {
1287 const DH_METHOD *meth = DH_OpenSSL();
1288
1289 dhret = (meth->compute_key)(key, pub_key, dh);
1290 }
1291err:
1292 kop.crk_param[3].crp_p = NULL;
1293 zapparams(&kop);
1294 return (dhret);
1295}
1296
1297static DH_METHOD cryptodev_dh = {
1298 "cryptodev DH method",
1299 NULL, /* cryptodev_dh_generate_key */
1300 NULL,
1301 NULL,
1302 NULL,
1303 NULL,
1304 0, /* flags */
1305 NULL /* app_data */
1306};
1307
1308/*
1309 * ctrl right now is just a wrapper that doesn't do much
1310 * but I expect we'll want some options soon.
1311 */
1312static int
1313cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
1314{
1315#ifdef HAVE_SYSLOG_R
1316 struct syslog_data sd = SYSLOG_DATA_INIT;
1317#endif
1318
1319 switch (cmd) {
1320 default:
1321#ifdef HAVE_SYSLOG_R
1322 syslog_r(LOG_ERR, &sd,
1323 "cryptodev_ctrl: unknown command %d", cmd);
1324#else
1325 syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd);
1326#endif
1327 break;
1328 }
1329 return (1);
1330}
1331
1332void
1333ENGINE_load_cryptodev(void)
1334{
1335 ENGINE *engine = ENGINE_new();
1336 int fd;
1337
1338 if (engine == NULL)
1339 return;
1340 if ((fd = get_dev_crypto()) < 0) {
1341 ENGINE_free(engine);
1342 return;
1343 }
1344
1345 /*
1346 * find out what asymmetric crypto algorithms we support
1347 */
1348 if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
1349 close(fd);
1350 ENGINE_free(engine);
1351 return;
1352 }
1353 close(fd);
1354
1355 if (!ENGINE_set_id(engine, "cryptodev") ||
1356 !ENGINE_set_name(engine, "BSD cryptodev engine") ||
1357 !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) ||
1358 !ENGINE_set_digests(engine, cryptodev_engine_digests) ||
1359 !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) ||
1360 !ENGINE_set_cmd_defns(engine, cryptodev_defns)) {
1361 ENGINE_free(engine);
1362 return;
1363 }
1364
1365 if (ENGINE_set_RSA(engine, &cryptodev_rsa)) {
1366 const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay();
1367
1368 cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp;
1369 cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp;
1370 cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc;
1371 cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec;
1372 cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc;
1373 cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec;
1374 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1375 cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp;
1376 if (cryptodev_asymfeat & CRF_MOD_EXP_CRT)
1377 cryptodev_rsa.rsa_mod_exp =
1378 cryptodev_rsa_mod_exp;
1379 else
1380 cryptodev_rsa.rsa_mod_exp =
1381 cryptodev_rsa_nocrt_mod_exp;
1382 }
1383 }
1384
1385 if (ENGINE_set_DSA(engine, &cryptodev_dsa)) {
1386 const DSA_METHOD *meth = DSA_OpenSSL();
1387
1388 memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
1389 if (cryptodev_asymfeat & CRF_DSA_SIGN)
1390 cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
1391 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1392 cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp;
1393 cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp;
1394 }
1395 if (cryptodev_asymfeat & CRF_DSA_VERIFY)
1396 cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
1397 }
1398
1399 if (ENGINE_set_DH(engine, &cryptodev_dh)){
1400 const DH_METHOD *dh_meth = DH_OpenSSL();
1401
1402 cryptodev_dh.generate_key = dh_meth->generate_key;
1403 cryptodev_dh.compute_key = dh_meth->compute_key;
1404 cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp;
1405 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1406 cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh;
1407 if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
1408 cryptodev_dh.compute_key =
1409 cryptodev_dh_compute_key;
1410 }
1411 }
1412
1413 ENGINE_add(engine);
1414 ENGINE_free(engine);
1415 ERR_clear_error();
1416}
1417
1418#endif /* HAVE_CRYPTODEV */