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