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