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