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.c1340
1 files changed, 1340 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..0ca442af8a
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_cryptodev.c
@@ -0,0 +1,1340 @@
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, -1 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 *cnids = 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 *cnids = 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 if (value & C3_HAS_AES) {
748 cryptodev_aes_128_cbc.init = xcrypt_init_key;
749 cryptodev_aes_128_cbc.do_cipher = xcrypt_cipher;
750 cryptodev_aes_128_cbc.cleanup = xcrypt_cleanup;
751 cryptodev_aes_128_cbc.ctx_size = sizeof(AES_KEY);
752
753 cryptodev_aes_192_cbc.init = xcrypt_init_key;
754 cryptodev_aes_192_cbc.do_cipher = xcrypt_cipher;
755 cryptodev_aes_192_cbc.cleanup = xcrypt_cleanup;
756 cryptodev_aes_192_cbc.ctx_size = sizeof(AES_KEY);
757
758 cryptodev_aes_256_cbc.init = xcrypt_init_key;
759 cryptodev_aes_256_cbc.do_cipher = xcrypt_cipher;
760 cryptodev_aes_256_cbc.cleanup = xcrypt_cleanup;
761 cryptodev_aes_256_cbc.ctx_size = sizeof(AES_KEY);
762 }
763 return (value);
764}
765#endif /* __i386__ */
766
767/*
768 * Registered by the ENGINE when used to find out how to deal with
769 * a particular NID in the ENGINE. this says what we'll do at the
770 * top level - note, that list is restricted by what we answer with
771 */
772static int
773cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
774 const int **nids, int nid)
775{
776 if (!cipher)
777 return (cryptodev_usable_ciphers(nids));
778
779 switch (nid) {
780 case NID_des_ede3_cbc:
781 *cipher = &cryptodev_3des_cbc;
782 break;
783 case NID_des_cbc:
784 *cipher = &cryptodev_des_cbc;
785 break;
786 case NID_bf_cbc:
787 *cipher = &cryptodev_bf_cbc;
788 break;
789 case NID_cast5_cbc:
790 *cipher = &cryptodev_cast_cbc;
791 break;
792 case NID_aes_128_cbc:
793 *cipher = &cryptodev_aes_128_cbc;
794 break;
795 case NID_aes_192_cbc:
796 *cipher = &cryptodev_aes_192_cbc;
797 break;
798 case NID_aes_256_cbc:
799 *cipher = &cryptodev_aes_256_cbc;
800 break;
801 default:
802 *cipher = NULL;
803 break;
804 }
805 return (*cipher != NULL);
806}
807
808static int
809cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
810 const int **nids, int nid)
811{
812 if (!digest)
813 return (cryptodev_usable_digests(nids));
814
815 switch (nid) {
816 case NID_md5:
817 *digest = NULL; /* need to make a clean md5 critter */
818 break;
819 default:
820 *digest = NULL;
821 break;
822 }
823 return (*digest != NULL);
824}
825
826/*
827 * Convert a BIGNUM to the representation that /dev/crypto needs.
828 * Upon completion of use, the caller is responsible for freeing
829 * crp->crp_p.
830 */
831static int
832bn2crparam(const BIGNUM *a, struct crparam *crp)
833{
834 int i, j, k;
835 ssize_t words, bytes, bits;
836 u_char *b;
837
838 crp->crp_p = NULL;
839 crp->crp_nbits = 0;
840
841 bits = BN_num_bits(a);
842 bytes = (bits + 7) / 8;
843
844 b = malloc(bytes);
845 if (b == NULL)
846 return (1);
847
848 crp->crp_p = b;
849 crp->crp_nbits = bits;
850
851 for (i = 0, j = 0; i < a->top; i++) {
852 for (k = 0; k < BN_BITS2 / 8; k++) {
853 if ((j + k) >= bytes)
854 return (0);
855 b[j + k] = a->d[i] >> (k * 8);
856 }
857 j += BN_BITS2 / 8;
858 }
859 return (0);
860}
861
862/* Convert a /dev/crypto parameter to a BIGNUM */
863static int
864crparam2bn(struct crparam *crp, BIGNUM *a)
865{
866 u_int8_t *pd;
867 int i, bytes;
868
869 bytes = (crp->crp_nbits + 7) / 8;
870
871 if (bytes == 0)
872 return (-1);
873
874 if ((pd = (u_int8_t *) malloc(bytes)) == NULL)
875 return (-1);
876
877 for (i = 0; i < bytes; i++)
878 pd[i] = crp->crp_p[bytes - i - 1];
879
880 BN_bin2bn(pd, bytes, a);
881 free(pd);
882
883 return (0);
884}
885
886static void
887zapparams(struct crypt_kop *kop)
888{
889 int i;
890
891 for (i = 0; i <= kop->crk_iparams + kop->crk_oparams; i++) {
892 if (kop->crk_param[i].crp_p)
893 free(kop->crk_param[i].crp_p);
894 kop->crk_param[i].crp_p = NULL;
895 kop->crk_param[i].crp_nbits = 0;
896 }
897}
898
899static int
900cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s)
901{
902 int fd, ret = -1;
903
904 if ((fd = get_asym_dev_crypto()) < 0)
905 return (ret);
906
907 if (r) {
908 kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char));
909 kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8;
910 kop->crk_oparams++;
911 }
912 if (s) {
913 kop->crk_param[kop->crk_iparams+1].crp_p = calloc(slen, sizeof(char));
914 kop->crk_param[kop->crk_iparams+1].crp_nbits = slen * 8;
915 kop->crk_oparams++;
916 }
917
918 if (ioctl(fd, CIOCKEY, kop) == 0) {
919 if (r)
920 crparam2bn(&kop->crk_param[kop->crk_iparams], r);
921 if (s)
922 crparam2bn(&kop->crk_param[kop->crk_iparams+1], s);
923 ret = 0;
924 }
925
926 return (ret);
927}
928
929static int
930cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
931 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
932{
933 struct crypt_kop kop;
934 int ret = 1;
935
936 /* Currently, we know we can do mod exp iff we can do any
937 * asymmetric operations at all.
938 */
939 if (cryptodev_asymfeat == 0) {
940 ret = BN_mod_exp(r, a, p, m, ctx);
941 return (ret);
942 }
943
944 memset(&kop, 0, sizeof kop);
945 kop.crk_op = CRK_MOD_EXP;
946
947 /* inputs: a^p % m */
948 if (bn2crparam(a, &kop.crk_param[0]))
949 goto err;
950 if (bn2crparam(p, &kop.crk_param[1]))
951 goto err;
952 if (bn2crparam(m, &kop.crk_param[2]))
953 goto err;
954 kop.crk_iparams = 3;
955
956 if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL) == -1) {
957 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
958 ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
959 }
960err:
961 zapparams(&kop);
962 return (ret);
963}
964
965static int
966cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
967{
968 int r;
969 BN_CTX *ctx;
970
971 ctx = BN_CTX_new();
972 r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL);
973 BN_CTX_free(ctx);
974 return (r);
975}
976
977static int
978cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
979{
980 struct crypt_kop kop;
981 int ret = 1;
982
983 if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
984 /* XXX 0 means failure?? */
985 return (0);
986 }
987
988 memset(&kop, 0, sizeof kop);
989 kop.crk_op = CRK_MOD_EXP_CRT;
990 /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
991 if (bn2crparam(rsa->p, &kop.crk_param[0]))
992 goto err;
993 if (bn2crparam(rsa->q, &kop.crk_param[1]))
994 goto err;
995 if (bn2crparam(I, &kop.crk_param[2]))
996 goto err;
997 if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
998 goto err;
999 if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
1000 goto err;
1001 if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
1002 goto err;
1003 kop.crk_iparams = 6;
1004
1005 if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL) == -1) {
1006 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
1007 ret = (*meth->rsa_mod_exp)(r0, I, rsa);
1008 }
1009err:
1010 zapparams(&kop);
1011 return (ret);
1012}
1013
1014static RSA_METHOD cryptodev_rsa = {
1015 "cryptodev RSA method",
1016 NULL, /* rsa_pub_enc */
1017 NULL, /* rsa_pub_dec */
1018 NULL, /* rsa_priv_enc */
1019 NULL, /* rsa_priv_dec */
1020 NULL,
1021 NULL,
1022 NULL, /* init */
1023 NULL, /* finish */
1024 0, /* flags */
1025 NULL, /* app_data */
1026 NULL, /* rsa_sign */
1027 NULL /* rsa_verify */
1028};
1029
1030static int
1031cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
1032 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
1033{
1034 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
1035}
1036
1037static int
1038cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
1039 BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
1040 BN_CTX *ctx, BN_MONT_CTX *mont)
1041{
1042 BIGNUM t2;
1043 int ret = 0;
1044
1045 BN_init(&t2);
1046
1047 /* v = ( g^u1 * y^u2 mod p ) mod q */
1048 /* let t1 = g ^ u1 mod p */
1049 ret = 0;
1050
1051 if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont))
1052 goto err;
1053
1054 /* let t2 = y ^ u2 mod p */
1055 if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont))
1056 goto err;
1057 /* let u1 = t1 * t2 mod p */
1058 if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx))
1059 goto err;
1060
1061 BN_copy(t1,u1);
1062
1063 ret = 1;
1064err:
1065 BN_free(&t2);
1066 return(ret);
1067}
1068
1069static DSA_SIG *
1070cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
1071{
1072 struct crypt_kop kop;
1073 BIGNUM *r = NULL, *s = NULL;
1074 DSA_SIG *dsaret = NULL;
1075
1076 if ((r = BN_new()) == NULL)
1077 goto err;
1078 if ((s = BN_new()) == NULL) {
1079 BN_free(r);
1080 goto err;
1081 }
1082
1083 memset(&kop, 0, sizeof kop);
1084 kop.crk_op = CRK_DSA_SIGN;
1085
1086 /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
1087 kop.crk_param[0].crp_p = (caddr_t)dgst;
1088 kop.crk_param[0].crp_nbits = dlen * 8;
1089 if (bn2crparam(dsa->p, &kop.crk_param[1]))
1090 goto err;
1091 if (bn2crparam(dsa->q, &kop.crk_param[2]))
1092 goto err;
1093 if (bn2crparam(dsa->g, &kop.crk_param[3]))
1094 goto err;
1095 if (bn2crparam(dsa->priv_key, &kop.crk_param[4]))
1096 goto err;
1097 kop.crk_iparams = 5;
1098
1099 if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r,
1100 BN_num_bytes(dsa->q), s) == 0) {
1101 dsaret = DSA_SIG_new();
1102 dsaret->r = r;
1103 dsaret->s = s;
1104 } else {
1105 const DSA_METHOD *meth = DSA_OpenSSL();
1106 BN_free(r);
1107 BN_free(s);
1108 dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
1109 }
1110err:
1111 kop.crk_param[0].crp_p = NULL;
1112 zapparams(&kop);
1113 return (dsaret);
1114}
1115
1116static int
1117cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
1118 DSA_SIG *sig, DSA *dsa)
1119{
1120 struct crypt_kop kop;
1121 int dsaret = 1;
1122
1123 memset(&kop, 0, sizeof kop);
1124 kop.crk_op = CRK_DSA_VERIFY;
1125
1126 /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
1127 kop.crk_param[0].crp_p = (caddr_t)dgst;
1128 kop.crk_param[0].crp_nbits = dlen * 8;
1129 if (bn2crparam(dsa->p, &kop.crk_param[1]))
1130 goto err;
1131 if (bn2crparam(dsa->q, &kop.crk_param[2]))
1132 goto err;
1133 if (bn2crparam(dsa->g, &kop.crk_param[3]))
1134 goto err;
1135 if (bn2crparam(dsa->pub_key, &kop.crk_param[4]))
1136 goto err;
1137 if (bn2crparam(sig->r, &kop.crk_param[5]))
1138 goto err;
1139 if (bn2crparam(sig->s, &kop.crk_param[6]))
1140 goto err;
1141 kop.crk_iparams = 7;
1142
1143 if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
1144 dsaret = kop.crk_status;
1145 } else {
1146 const DSA_METHOD *meth = DSA_OpenSSL();
1147
1148 dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
1149 }
1150err:
1151 kop.crk_param[0].crp_p = NULL;
1152 zapparams(&kop);
1153 return (dsaret);
1154}
1155
1156static DSA_METHOD cryptodev_dsa = {
1157 "cryptodev DSA method",
1158 NULL,
1159 NULL, /* dsa_sign_setup */
1160 NULL,
1161 NULL, /* dsa_mod_exp */
1162 NULL,
1163 NULL, /* init */
1164 NULL, /* finish */
1165 0, /* flags */
1166 NULL /* app_data */
1167};
1168
1169static int
1170cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
1171 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
1172 BN_MONT_CTX *m_ctx)
1173{
1174 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
1175}
1176
1177static int
1178cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
1179{
1180 struct crypt_kop kop;
1181 int dhret = 1;
1182 int fd, keylen;
1183
1184 if ((fd = get_asym_dev_crypto()) < 0) {
1185 const DH_METHOD *meth = DH_OpenSSL();
1186
1187 return ((meth->compute_key)(key, pub_key, dh));
1188 }
1189
1190 keylen = BN_num_bits(dh->p);
1191
1192 memset(&kop, 0, sizeof kop);
1193 kop.crk_op = CRK_DH_COMPUTE_KEY;
1194
1195 /* inputs: dh->priv_key pub_key dh->p key */
1196 if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
1197 goto err;
1198 if (bn2crparam(pub_key, &kop.crk_param[1]))
1199 goto err;
1200 if (bn2crparam(dh->p, &kop.crk_param[2]))
1201 goto err;
1202 kop.crk_iparams = 3;
1203
1204 kop.crk_param[3].crp_p = key;
1205 kop.crk_param[3].crp_nbits = keylen * 8;
1206 kop.crk_oparams = 1;
1207
1208 if (ioctl(fd, CIOCKEY, &kop) == -1) {
1209 const DH_METHOD *meth = DH_OpenSSL();
1210
1211 dhret = (meth->compute_key)(key, pub_key, dh);
1212 }
1213err:
1214 kop.crk_param[3].crp_p = NULL;
1215 zapparams(&kop);
1216 return (dhret);
1217}
1218
1219static DH_METHOD cryptodev_dh = {
1220 "cryptodev DH method",
1221 NULL, /* cryptodev_dh_generate_key */
1222 NULL,
1223 NULL,
1224 NULL,
1225 NULL,
1226 0, /* flags */
1227 NULL /* app_data */
1228};
1229
1230/*
1231 * ctrl right now is just a wrapper that doesn't do much
1232 * but I expect we'll want some options soon.
1233 */
1234static int
1235cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
1236{
1237#ifdef HAVE_SYSLOG_R
1238 struct syslog_data sd = SYSLOG_DATA_INIT;
1239#endif
1240
1241 switch (cmd) {
1242 default:
1243#ifdef HAVE_SYSLOG_R
1244 syslog_r(LOG_ERR, &sd,
1245 "cryptodev_ctrl: unknown command %d", cmd);
1246#else
1247 syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd);
1248#endif
1249 break;
1250 }
1251 return (1);
1252}
1253
1254void
1255ENGINE_load_cryptodev(void)
1256{
1257 ENGINE *engine = ENGINE_new();
1258 int fd;
1259
1260 if (engine == NULL)
1261 return;
1262 if ((fd = get_dev_crypto()) < 0) {
1263 ENGINE_free(engine);
1264 return;
1265 }
1266
1267 /*
1268 * find out what asymmetric crypto algorithms we support
1269 */
1270 if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
1271 close(fd);
1272 ENGINE_free(engine);
1273 return;
1274 }
1275 close(fd);
1276
1277 if (!ENGINE_set_id(engine, "cryptodev") ||
1278 !ENGINE_set_name(engine, "BSD cryptodev engine") ||
1279 !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) ||
1280 !ENGINE_set_digests(engine, cryptodev_engine_digests) ||
1281 !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) ||
1282 !ENGINE_set_cmd_defns(engine, cryptodev_defns)) {
1283 ENGINE_free(engine);
1284 return;
1285 }
1286
1287 if (ENGINE_set_RSA(engine, &cryptodev_rsa)) {
1288 const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay();
1289
1290 cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp;
1291 cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp;
1292 cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc;
1293 cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec;
1294 cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc;
1295 cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec;
1296 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1297 cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp;
1298 if (cryptodev_asymfeat & CRF_MOD_EXP_CRT)
1299 cryptodev_rsa.rsa_mod_exp =
1300 cryptodev_rsa_mod_exp;
1301 else
1302 cryptodev_rsa.rsa_mod_exp =
1303 cryptodev_rsa_nocrt_mod_exp;
1304 }
1305 }
1306
1307 if (ENGINE_set_DSA(engine, &cryptodev_dsa)) {
1308 const DSA_METHOD *meth = DSA_OpenSSL();
1309
1310 memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
1311 if (cryptodev_asymfeat & CRF_DSA_SIGN)
1312 cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
1313 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1314 cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp;
1315 cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp;
1316 }
1317 if (cryptodev_asymfeat & CRF_DSA_VERIFY)
1318 cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
1319 }
1320
1321 if (ENGINE_set_DH(engine, &cryptodev_dh)){
1322 const DH_METHOD *dh_meth = DH_OpenSSL();
1323
1324 cryptodev_dh.generate_key = dh_meth->generate_key;
1325 cryptodev_dh.compute_key = dh_meth->compute_key;
1326 cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp;
1327 if (cryptodev_asymfeat & CRF_MOD_EXP) {
1328 cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh;
1329 if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
1330 cryptodev_dh.compute_key =
1331 cryptodev_dh_compute_key;
1332 }
1333 }
1334
1335 ENGINE_add(engine);
1336 ENGINE_free(engine);
1337 ERR_clear_error();
1338}
1339
1340#endif /* HAVE_CRYPTODEV */