xref: /freebsd/sys/opencrypto/cryptodev.c (revision 60fde7ce5d7bf5d94290720ea53db5701ab406a8)
1 /*	$OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $	*/
2 
3 /*-
4  * Copyright (c) 2001 Theo de Raadt
5  * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
6  * Copyright (c) 2014 The FreeBSD Foundation
7  * All rights reserved.
8  *
9  * Portions of this software were developed by John-Mark Gurney
10  * under sponsorship of the FreeBSD Foundation and
11  * Rubicon Communications, LLC (Netgate).
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  *
17  * 1. Redistributions of source code must retain the above copyright
18  *   notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *   notice, this list of conditions and the following disclaimer in the
21  *   documentation and/or other materials provided with the distribution.
22  * 3. The name of the author may not be used to endorse or promote products
23  *   derived from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  *
36  * Effort sponsored in part by the Defense Advanced Research Projects
37  * Agency (DARPA) and Air Force Research Laboratory, Air Force
38  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
39  */
40 
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
43 
44 #include "opt_compat.h"
45 
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/malloc.h>
49 #include <sys/mbuf.h>
50 #include <sys/lock.h>
51 #include <sys/mutex.h>
52 #include <sys/sysctl.h>
53 #include <sys/file.h>
54 #include <sys/filedesc.h>
55 #include <sys/errno.h>
56 #include <sys/uio.h>
57 #include <sys/random.h>
58 #include <sys/conf.h>
59 #include <sys/kernel.h>
60 #include <sys/module.h>
61 #include <sys/fcntl.h>
62 #include <sys/bus.h>
63 #include <sys/user.h>
64 #include <sys/sdt.h>
65 
66 #include <opencrypto/cryptodev.h>
67 #include <opencrypto/xform.h>
68 
69 SDT_PROVIDER_DECLARE(opencrypto);
70 
71 SDT_PROBE_DEFINE1(opencrypto, dev, ioctl, error, "int"/*line number*/);
72 
73 #ifdef COMPAT_FREEBSD32
74 #include <sys/mount.h>
75 #include <compat/freebsd32/freebsd32.h>
76 
77 struct session_op32 {
78 	u_int32_t	cipher;
79 	u_int32_t	mac;
80 	u_int32_t	keylen;
81 	u_int32_t	key;
82 	int		mackeylen;
83 	u_int32_t	mackey;
84 	u_int32_t	ses;
85 };
86 
87 struct session2_op32 {
88 	u_int32_t	cipher;
89 	u_int32_t	mac;
90 	u_int32_t	keylen;
91 	u_int32_t	key;
92 	int		mackeylen;
93 	u_int32_t	mackey;
94 	u_int32_t	ses;
95 	int		crid;
96 	int		pad[4];
97 };
98 
99 struct crypt_op32 {
100 	u_int32_t	ses;
101 	u_int16_t	op;
102 	u_int16_t	flags;
103 	u_int		len;
104 	u_int32_t	src, dst;
105 	u_int32_t	mac;
106 	u_int32_t	iv;
107 };
108 
109 struct crparam32 {
110 	u_int32_t	crp_p;
111 	u_int		crp_nbits;
112 };
113 
114 struct crypt_kop32 {
115 	u_int		crk_op;
116 	u_int		crk_status;
117 	u_short		crk_iparams;
118 	u_short		crk_oparams;
119 	u_int		crk_crid;
120 	struct crparam32	crk_param[CRK_MAXPARAM];
121 };
122 
123 struct cryptotstat32 {
124 	struct timespec32	acc;
125 	struct timespec32	min;
126 	struct timespec32	max;
127 	u_int32_t	count;
128 };
129 
130 struct cryptostats32 {
131 	u_int32_t	cs_ops;
132 	u_int32_t	cs_errs;
133 	u_int32_t	cs_kops;
134 	u_int32_t	cs_kerrs;
135 	u_int32_t	cs_intrs;
136 	u_int32_t	cs_rets;
137 	u_int32_t	cs_blocks;
138 	u_int32_t	cs_kblocks;
139 	struct cryptotstat32 cs_invoke;
140 	struct cryptotstat32 cs_done;
141 	struct cryptotstat32 cs_cb;
142 	struct cryptotstat32 cs_finis;
143 };
144 
145 #define	CIOCGSESSION32	_IOWR('c', 101, struct session_op32)
146 #define	CIOCCRYPT32	_IOWR('c', 103, struct crypt_op32)
147 #define	CIOCKEY32	_IOWR('c', 104, struct crypt_kop32)
148 #define	CIOCGSESSION232	_IOWR('c', 106, struct session2_op32)
149 #define	CIOCKEY232	_IOWR('c', 107, struct crypt_kop32)
150 
151 static void
152 session_op_from_32(const struct session_op32 *from, struct session_op *to)
153 {
154 
155 	CP(*from, *to, cipher);
156 	CP(*from, *to, mac);
157 	CP(*from, *to, keylen);
158 	PTRIN_CP(*from, *to, key);
159 	CP(*from, *to, mackeylen);
160 	PTRIN_CP(*from, *to, mackey);
161 	CP(*from, *to, ses);
162 }
163 
164 static void
165 session2_op_from_32(const struct session2_op32 *from, struct session2_op *to)
166 {
167 
168 	session_op_from_32((const struct session_op32 *)from,
169 	    (struct session_op *)to);
170 	CP(*from, *to, crid);
171 }
172 
173 static void
174 session_op_to_32(const struct session_op *from, struct session_op32 *to)
175 {
176 
177 	CP(*from, *to, cipher);
178 	CP(*from, *to, mac);
179 	CP(*from, *to, keylen);
180 	PTROUT_CP(*from, *to, key);
181 	CP(*from, *to, mackeylen);
182 	PTROUT_CP(*from, *to, mackey);
183 	CP(*from, *to, ses);
184 }
185 
186 static void
187 session2_op_to_32(const struct session2_op *from, struct session2_op32 *to)
188 {
189 
190 	session_op_to_32((const struct session_op *)from,
191 	    (struct session_op32 *)to);
192 	CP(*from, *to, crid);
193 }
194 
195 static void
196 crypt_op_from_32(const struct crypt_op32 *from, struct crypt_op *to)
197 {
198 
199 	CP(*from, *to, ses);
200 	CP(*from, *to, op);
201 	CP(*from, *to, flags);
202 	CP(*from, *to, len);
203 	PTRIN_CP(*from, *to, src);
204 	PTRIN_CP(*from, *to, dst);
205 	PTRIN_CP(*from, *to, mac);
206 	PTRIN_CP(*from, *to, iv);
207 }
208 
209 static void
210 crypt_op_to_32(const struct crypt_op *from, struct crypt_op32 *to)
211 {
212 
213 	CP(*from, *to, ses);
214 	CP(*from, *to, op);
215 	CP(*from, *to, flags);
216 	CP(*from, *to, len);
217 	PTROUT_CP(*from, *to, src);
218 	PTROUT_CP(*from, *to, dst);
219 	PTROUT_CP(*from, *to, mac);
220 	PTROUT_CP(*from, *to, iv);
221 }
222 
223 static void
224 crparam_from_32(const struct crparam32 *from, struct crparam *to)
225 {
226 
227 	PTRIN_CP(*from, *to, crp_p);
228 	CP(*from, *to, crp_nbits);
229 }
230 
231 static void
232 crparam_to_32(const struct crparam *from, struct crparam32 *to)
233 {
234 
235 	PTROUT_CP(*from, *to, crp_p);
236 	CP(*from, *to, crp_nbits);
237 }
238 
239 static void
240 crypt_kop_from_32(const struct crypt_kop32 *from, struct crypt_kop *to)
241 {
242 	int i;
243 
244 	CP(*from, *to, crk_op);
245 	CP(*from, *to, crk_status);
246 	CP(*from, *to, crk_iparams);
247 	CP(*from, *to, crk_oparams);
248 	CP(*from, *to, crk_crid);
249 	for (i = 0; i < CRK_MAXPARAM; i++)
250 		crparam_from_32(&from->crk_param[i], &to->crk_param[i]);
251 }
252 
253 static void
254 crypt_kop_to_32(const struct crypt_kop *from, struct crypt_kop32 *to)
255 {
256 	int i;
257 
258 	CP(*from, *to, crk_op);
259 	CP(*from, *to, crk_status);
260 	CP(*from, *to, crk_iparams);
261 	CP(*from, *to, crk_oparams);
262 	CP(*from, *to, crk_crid);
263 	for (i = 0; i < CRK_MAXPARAM; i++)
264 		crparam_to_32(&from->crk_param[i], &to->crk_param[i]);
265 }
266 #endif
267 
268 struct csession {
269 	TAILQ_ENTRY(csession) next;
270 	u_int64_t	sid;
271 	u_int32_t	ses;
272 	struct mtx	lock;		/* for op submission */
273 
274 	u_int32_t	cipher;
275 	struct enc_xform *txform;
276 	u_int32_t	mac;
277 	struct auth_hash *thash;
278 
279 	caddr_t		key;
280 	int		keylen;
281 
282 	caddr_t		mackey;
283 	int		mackeylen;
284 };
285 
286 struct cryptop_data {
287 	struct csession *cse;
288 
289 	struct iovec	iovec[1];
290 	struct uio	uio;
291 	bool		done;
292 };
293 
294 struct fcrypt {
295 	TAILQ_HEAD(csessionlist, csession) csessions;
296 	int		sesn;
297 };
298 
299 static	int cryptof_ioctl(struct file *, u_long, void *,
300 		    struct ucred *, struct thread *);
301 static	int cryptof_stat(struct file *, struct stat *,
302 		    struct ucred *, struct thread *);
303 static	int cryptof_close(struct file *, struct thread *);
304 static	int cryptof_fill_kinfo(struct file *, struct kinfo_file *,
305 		    struct filedesc *);
306 
307 static struct fileops cryptofops = {
308     .fo_read = invfo_rdwr,
309     .fo_write = invfo_rdwr,
310     .fo_truncate = invfo_truncate,
311     .fo_ioctl = cryptof_ioctl,
312     .fo_poll = invfo_poll,
313     .fo_kqfilter = invfo_kqfilter,
314     .fo_stat = cryptof_stat,
315     .fo_close = cryptof_close,
316     .fo_chmod = invfo_chmod,
317     .fo_chown = invfo_chown,
318     .fo_sendfile = invfo_sendfile,
319     .fo_fill_kinfo = cryptof_fill_kinfo,
320 };
321 
322 static struct csession *csefind(struct fcrypt *, u_int);
323 static int csedelete(struct fcrypt *, struct csession *);
324 static struct csession *cseadd(struct fcrypt *, struct csession *);
325 static struct csession *csecreate(struct fcrypt *, u_int64_t, caddr_t,
326     u_int64_t, caddr_t, u_int64_t, u_int32_t, u_int32_t, struct enc_xform *,
327     struct auth_hash *);
328 static int csefree(struct csession *);
329 
330 static	int cryptodev_op(struct csession *, struct crypt_op *,
331 			struct ucred *, struct thread *td);
332 static	int cryptodev_aead(struct csession *, struct crypt_aead *,
333 			struct ucred *, struct thread *);
334 static	int cryptodev_key(struct crypt_kop *);
335 static	int cryptodev_find(struct crypt_find_op *);
336 
337 /*
338  * Check a crypto identifier to see if it requested
339  * a software device/driver.  This can be done either
340  * by device name/class or through search constraints.
341  */
342 static int
343 checkforsoftware(int *cridp)
344 {
345 	int crid;
346 
347 	crid = *cridp;
348 
349 	if (!crypto_devallowsoft) {
350 		if (crid & CRYPTOCAP_F_SOFTWARE) {
351 			if (crid & CRYPTOCAP_F_HARDWARE) {
352 				*cridp = CRYPTOCAP_F_HARDWARE;
353 				return 0;
354 			}
355 			return EINVAL;
356 		}
357 		if ((crid & CRYPTOCAP_F_HARDWARE) == 0 &&
358 		    (crypto_getcaps(crid) & CRYPTOCAP_F_HARDWARE) == 0)
359 			return EINVAL;
360 	}
361 	return 0;
362 }
363 
364 /* ARGSUSED */
365 static int
366 cryptof_ioctl(
367 	struct file *fp,
368 	u_long cmd,
369 	void *data,
370 	struct ucred *active_cred,
371 	struct thread *td)
372 {
373 #define	SES2(p)	((struct session2_op *)p)
374 	struct cryptoini cria, crie;
375 	struct fcrypt *fcr = fp->f_data;
376 	struct csession *cse;
377 	struct session_op *sop;
378 	struct crypt_op *cop;
379 	struct crypt_aead *caead;
380 	struct enc_xform *txform = NULL;
381 	struct auth_hash *thash = NULL;
382 	struct crypt_kop *kop;
383 	u_int64_t sid;
384 	u_int32_t ses;
385 	int error = 0, crid;
386 #ifdef COMPAT_FREEBSD32
387 	struct session2_op sopc;
388 	struct crypt_op copc;
389 	struct crypt_kop kopc;
390 #endif
391 
392 	switch (cmd) {
393 	case CIOCGSESSION:
394 	case CIOCGSESSION2:
395 #ifdef COMPAT_FREEBSD32
396 	case CIOCGSESSION32:
397 	case CIOCGSESSION232:
398 		if (cmd == CIOCGSESSION32) {
399 			session_op_from_32(data, (struct session_op *)&sopc);
400 			sop = (struct session_op *)&sopc;
401 		} else if (cmd == CIOCGSESSION232) {
402 			session2_op_from_32(data, &sopc);
403 			sop = (struct session_op *)&sopc;
404 		} else
405 #endif
406 			sop = (struct session_op *)data;
407 		switch (sop->cipher) {
408 		case 0:
409 			break;
410 		case CRYPTO_DES_CBC:
411 			txform = &enc_xform_des;
412 			break;
413 		case CRYPTO_3DES_CBC:
414 			txform = &enc_xform_3des;
415 			break;
416 		case CRYPTO_BLF_CBC:
417 			txform = &enc_xform_blf;
418 			break;
419 		case CRYPTO_CAST_CBC:
420 			txform = &enc_xform_cast5;
421 			break;
422 		case CRYPTO_SKIPJACK_CBC:
423 			txform = &enc_xform_skipjack;
424 			break;
425 		case CRYPTO_AES_CBC:
426 			txform = &enc_xform_rijndael128;
427 			break;
428 		case CRYPTO_AES_XTS:
429 			txform = &enc_xform_aes_xts;
430 			break;
431 		case CRYPTO_NULL_CBC:
432 			txform = &enc_xform_null;
433 			break;
434 		case CRYPTO_ARC4:
435 			txform = &enc_xform_arc4;
436 			break;
437  		case CRYPTO_CAMELLIA_CBC:
438  			txform = &enc_xform_camellia;
439  			break;
440 		case CRYPTO_AES_ICM:
441 			txform = &enc_xform_aes_icm;
442  			break;
443 		case CRYPTO_AES_NIST_GCM_16:
444 			txform = &enc_xform_aes_nist_gcm;
445  			break;
446 
447 		default:
448 			CRYPTDEB("invalid cipher");
449 			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
450 			return (EINVAL);
451 		}
452 
453 		switch (sop->mac) {
454 		case 0:
455 			break;
456 		case CRYPTO_MD5_HMAC:
457 			thash = &auth_hash_hmac_md5;
458 			break;
459 		case CRYPTO_SHA1_HMAC:
460 			thash = &auth_hash_hmac_sha1;
461 			break;
462 		case CRYPTO_SHA2_256_HMAC:
463 			thash = &auth_hash_hmac_sha2_256;
464 			break;
465 		case CRYPTO_SHA2_384_HMAC:
466 			thash = &auth_hash_hmac_sha2_384;
467 			break;
468 		case CRYPTO_SHA2_512_HMAC:
469 			thash = &auth_hash_hmac_sha2_512;
470 			break;
471 		case CRYPTO_RIPEMD160_HMAC:
472 			thash = &auth_hash_hmac_ripemd_160;
473 			break;
474 		case CRYPTO_AES_128_NIST_GMAC:
475 			thash = &auth_hash_nist_gmac_aes_128;
476 			break;
477 		case CRYPTO_AES_192_NIST_GMAC:
478 			thash = &auth_hash_nist_gmac_aes_192;
479 			break;
480 		case CRYPTO_AES_256_NIST_GMAC:
481 			thash = &auth_hash_nist_gmac_aes_256;
482 			break;
483 
484 #ifdef notdef
485 		case CRYPTO_MD5:
486 			thash = &auth_hash_md5;
487 			break;
488 		case CRYPTO_SHA1:
489 			thash = &auth_hash_sha1;
490 			break;
491 #endif
492 		case CRYPTO_NULL_HMAC:
493 			thash = &auth_hash_null;
494 			break;
495 
496 		case CRYPTO_BLAKE2B:
497 			thash = &auth_hash_blake2b;
498 			break;
499 		case CRYPTO_BLAKE2S:
500 			thash = &auth_hash_blake2s;
501 			break;
502 
503 		default:
504 			CRYPTDEB("invalid mac");
505 			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
506 			return (EINVAL);
507 		}
508 
509 		bzero(&crie, sizeof(crie));
510 		bzero(&cria, sizeof(cria));
511 
512 		if (txform) {
513 			crie.cri_alg = txform->type;
514 			crie.cri_klen = sop->keylen * 8;
515 			if (sop->keylen > txform->maxkey ||
516 			    sop->keylen < txform->minkey) {
517 				CRYPTDEB("invalid cipher parameters");
518 				error = EINVAL;
519 				SDT_PROBE1(opencrypto, dev, ioctl, error,
520 				    __LINE__);
521 				goto bail;
522 			}
523 
524 			crie.cri_key = malloc(crie.cri_klen / 8,
525 			    M_XDATA, M_WAITOK);
526 			if ((error = copyin(sop->key, crie.cri_key,
527 			    crie.cri_klen / 8))) {
528 				CRYPTDEB("invalid key");
529 				SDT_PROBE1(opencrypto, dev, ioctl, error,
530 				    __LINE__);
531 				goto bail;
532 			}
533 			if (thash)
534 				crie.cri_next = &cria;
535 		}
536 
537 		if (thash) {
538 			cria.cri_alg = thash->type;
539 			cria.cri_klen = sop->mackeylen * 8;
540 			if (thash->keysize != 0 &&
541 			    sop->mackeylen > thash->keysize) {
542 				CRYPTDEB("invalid mac key length");
543 				error = EINVAL;
544 				SDT_PROBE1(opencrypto, dev, ioctl, error,
545 				    __LINE__);
546 				goto bail;
547 			}
548 
549 			if (cria.cri_klen) {
550 				cria.cri_key = malloc(cria.cri_klen / 8,
551 				    M_XDATA, M_WAITOK);
552 				if ((error = copyin(sop->mackey, cria.cri_key,
553 				    cria.cri_klen / 8))) {
554 					CRYPTDEB("invalid mac key");
555 					SDT_PROBE1(opencrypto, dev, ioctl,
556 					    error, __LINE__);
557 					goto bail;
558 				}
559 			}
560 		}
561 
562 		/* NB: CIOCGSESSION2 has the crid */
563 		if (cmd == CIOCGSESSION2
564 #ifdef COMPAT_FREEBSD32
565 		    || cmd == CIOCGSESSION232
566 #endif
567 			) {
568 			crid = SES2(sop)->crid;
569 			error = checkforsoftware(&crid);
570 			if (error) {
571 				CRYPTDEB("checkforsoftware");
572 				SDT_PROBE1(opencrypto, dev, ioctl, error,
573 				    __LINE__);
574 				goto bail;
575 			}
576 		} else
577 			crid = CRYPTOCAP_F_HARDWARE;
578 		error = crypto_newsession(&sid, (txform ? &crie : &cria), crid);
579 		if (error) {
580 			CRYPTDEB("crypto_newsession");
581 			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
582 			goto bail;
583 		}
584 
585 		cse = csecreate(fcr, sid, crie.cri_key, crie.cri_klen,
586 		    cria.cri_key, cria.cri_klen, sop->cipher, sop->mac, txform,
587 		    thash);
588 
589 		if (cse == NULL) {
590 			crypto_freesession(sid);
591 			error = EINVAL;
592 			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
593 			CRYPTDEB("csecreate");
594 			goto bail;
595 		}
596 		sop->ses = cse->ses;
597 		if (cmd == CIOCGSESSION2
598 #ifdef COMPAT_FREEBSD32
599 		    || cmd == CIOCGSESSION232
600 #endif
601 		    ) {
602 			/* return hardware/driver id */
603 			SES2(sop)->crid = CRYPTO_SESID2HID(cse->sid);
604 		}
605 bail:
606 		if (error) {
607 			if (crie.cri_key)
608 				free(crie.cri_key, M_XDATA);
609 			if (cria.cri_key)
610 				free(cria.cri_key, M_XDATA);
611 		}
612 #ifdef COMPAT_FREEBSD32
613 		else {
614 			if (cmd == CIOCGSESSION32)
615 				session_op_to_32(sop, data);
616 			else if (cmd == CIOCGSESSION232)
617 				session2_op_to_32((struct session2_op *)sop,
618 				    data);
619 		}
620 #endif
621 		break;
622 	case CIOCFSESSION:
623 		ses = *(u_int32_t *)data;
624 		cse = csefind(fcr, ses);
625 		if (cse == NULL) {
626 			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
627 			return (EINVAL);
628 		}
629 		csedelete(fcr, cse);
630 		error = csefree(cse);
631 		break;
632 	case CIOCCRYPT:
633 #ifdef COMPAT_FREEBSD32
634 	case CIOCCRYPT32:
635 		if (cmd == CIOCCRYPT32) {
636 			cop = &copc;
637 			crypt_op_from_32(data, cop);
638 		} else
639 #endif
640 			cop = (struct crypt_op *)data;
641 		cse = csefind(fcr, cop->ses);
642 		if (cse == NULL) {
643 			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
644 			return (EINVAL);
645 		}
646 		error = cryptodev_op(cse, cop, active_cred, td);
647 #ifdef COMPAT_FREEBSD32
648 		if (error == 0 && cmd == CIOCCRYPT32)
649 			crypt_op_to_32(cop, data);
650 #endif
651 		break;
652 	case CIOCKEY:
653 	case CIOCKEY2:
654 #ifdef COMPAT_FREEBSD32
655 	case CIOCKEY32:
656 	case CIOCKEY232:
657 #endif
658 		if (!crypto_userasymcrypto) {
659 			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
660 			return (EPERM);		/* XXX compat? */
661 		}
662 #ifdef COMPAT_FREEBSD32
663 		if (cmd == CIOCKEY32 || cmd == CIOCKEY232) {
664 			kop = &kopc;
665 			crypt_kop_from_32(data, kop);
666 		} else
667 #endif
668 			kop = (struct crypt_kop *)data;
669 		if (cmd == CIOCKEY
670 #ifdef COMPAT_FREEBSD32
671 		    || cmd == CIOCKEY32
672 #endif
673 		    ) {
674 			/* NB: crypto core enforces s/w driver use */
675 			kop->crk_crid =
676 			    CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
677 		}
678 		mtx_lock(&Giant);
679 		error = cryptodev_key(kop);
680 		mtx_unlock(&Giant);
681 #ifdef COMPAT_FREEBSD32
682 		if (cmd == CIOCKEY32 || cmd == CIOCKEY232)
683 			crypt_kop_to_32(kop, data);
684 #endif
685 		break;
686 	case CIOCASYMFEAT:
687 		if (!crypto_userasymcrypto) {
688 			/*
689 			 * NB: if user asym crypto operations are
690 			 * not permitted return "no algorithms"
691 			 * so well-behaved applications will just
692 			 * fallback to doing them in software.
693 			 */
694 			*(int *)data = 0;
695 		} else {
696 			error = crypto_getfeat((int *)data);
697 			if (error)
698 				SDT_PROBE1(opencrypto, dev, ioctl, error,
699 				    __LINE__);
700 		}
701 		break;
702 	case CIOCFINDDEV:
703 		error = cryptodev_find((struct crypt_find_op *)data);
704 		break;
705 	case CIOCCRYPTAEAD:
706 		caead = (struct crypt_aead *)data;
707 		cse = csefind(fcr, caead->ses);
708 		if (cse == NULL) {
709 			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
710 			return (EINVAL);
711 		}
712 		error = cryptodev_aead(cse, caead, active_cred, td);
713 		break;
714 	default:
715 		error = EINVAL;
716 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
717 		break;
718 	}
719 	return (error);
720 #undef SES2
721 }
722 
723 static int cryptodev_cb(struct cryptop *);
724 
725 static struct cryptop_data *
726 cod_alloc(struct csession *cse, size_t len, struct thread *td)
727 {
728 	struct cryptop_data *cod;
729 	struct uio *uio;
730 
731 	cod = malloc(sizeof(struct cryptop_data), M_XDATA, M_WAITOK | M_ZERO);
732 
733 	cod->cse = cse;
734 	uio = &cod->uio;
735 	uio->uio_iov = cod->iovec;
736 	uio->uio_iovcnt = 1;
737 	uio->uio_resid = len;
738 	uio->uio_segflg = UIO_SYSSPACE;
739 	uio->uio_rw = UIO_WRITE;
740 	uio->uio_td = td;
741 	uio->uio_iov[0].iov_len = len;
742 	uio->uio_iov[0].iov_base = malloc(len, M_XDATA, M_WAITOK);
743 	return (cod);
744 }
745 
746 static void
747 cod_free(struct cryptop_data *cod)
748 {
749 
750 	free(cod->uio.uio_iov[0].iov_base, M_XDATA);
751 	free(cod, M_XDATA);
752 }
753 
754 static int
755 cryptodev_op(
756 	struct csession *cse,
757 	struct crypt_op *cop,
758 	struct ucred *active_cred,
759 	struct thread *td)
760 {
761 	struct cryptop_data *cod = NULL;
762 	struct cryptop *crp = NULL;
763 	struct cryptodesc *crde = NULL, *crda = NULL;
764 	int error;
765 
766 	if (cop->len > 256*1024-4) {
767 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
768 		return (E2BIG);
769 	}
770 
771 	if (cse->txform) {
772 		if (cop->len == 0 || (cop->len % cse->txform->blocksize) != 0) {
773 			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
774 			return (EINVAL);
775 		}
776 	}
777 
778 	if (cse->thash)
779 		cod = cod_alloc(cse, cop->len + cse->thash->hashsize, td);
780 	else
781 		cod = cod_alloc(cse, cop->len, td);
782 
783 	crp = crypto_getreq((cse->txform != NULL) + (cse->thash != NULL));
784 	if (crp == NULL) {
785 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
786 		error = ENOMEM;
787 		goto bail;
788 	}
789 
790 	if (cse->thash && cse->txform) {
791 		if (cop->flags & COP_F_CIPHER_FIRST) {
792 			crde = crp->crp_desc;
793 			crda = crde->crd_next;
794 		} else {
795 			crda = crp->crp_desc;
796 			crde = crda->crd_next;
797 		}
798 	} else if (cse->thash) {
799 		crda = crp->crp_desc;
800 	} else if (cse->txform) {
801 		crde = crp->crp_desc;
802 	} else {
803 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
804 		error = EINVAL;
805 		goto bail;
806 	}
807 
808 	if ((error = copyin(cop->src, cod->uio.uio_iov[0].iov_base,
809 	    cop->len))) {
810 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
811 		goto bail;
812 	}
813 
814 	if (crda) {
815 		crda->crd_skip = 0;
816 		crda->crd_len = cop->len;
817 		crda->crd_inject = cop->len;
818 
819 		crda->crd_alg = cse->mac;
820 		crda->crd_key = cse->mackey;
821 		crda->crd_klen = cse->mackeylen * 8;
822 	}
823 
824 	if (crde) {
825 		if (cop->op == COP_ENCRYPT)
826 			crde->crd_flags |= CRD_F_ENCRYPT;
827 		else
828 			crde->crd_flags &= ~CRD_F_ENCRYPT;
829 		crde->crd_len = cop->len;
830 		crde->crd_inject = 0;
831 
832 		crde->crd_alg = cse->cipher;
833 		crde->crd_key = cse->key;
834 		crde->crd_klen = cse->keylen * 8;
835 	}
836 
837 	crp->crp_ilen = cop->len;
838 	crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM
839 		       | (cop->flags & COP_F_BATCH);
840 	crp->crp_uio = &cod->uio;
841 	crp->crp_callback = cryptodev_cb;
842 	crp->crp_sid = cse->sid;
843 	crp->crp_opaque = cod;
844 
845 	if (cop->iv) {
846 		if (crde == NULL) {
847 			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
848 			error = EINVAL;
849 			goto bail;
850 		}
851 		if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
852 			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
853 			error = EINVAL;
854 			goto bail;
855 		}
856 		if ((error = copyin(cop->iv, crde->crd_iv,
857 		    cse->txform->blocksize))) {
858 			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
859 			goto bail;
860 		}
861 		crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
862 		crde->crd_skip = 0;
863 	} else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
864 		crde->crd_skip = 0;
865 	} else if (crde) {
866 		crde->crd_flags |= CRD_F_IV_PRESENT;
867 		crde->crd_skip = cse->txform->blocksize;
868 		crde->crd_len -= cse->txform->blocksize;
869 	}
870 
871 	if (cop->mac && crda == NULL) {
872 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
873 		error = EINVAL;
874 		goto bail;
875 	}
876 
877 again:
878 	/*
879 	 * Let the dispatch run unlocked, then, interlock against the
880 	 * callback before checking if the operation completed and going
881 	 * to sleep.  This insures drivers don't inherit our lock which
882 	 * results in a lock order reversal between crypto_dispatch forced
883 	 * entry and the crypto_done callback into us.
884 	 */
885 	error = crypto_dispatch(crp);
886 	if (error != 0) {
887 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
888 		goto bail;
889 	}
890 
891 	mtx_lock(&cse->lock);
892 	while (!cod->done)
893 		mtx_sleep(cod, &cse->lock, PWAIT, "crydev", 0);
894 	mtx_unlock(&cse->lock);
895 
896 	if (crp->crp_etype == EAGAIN) {
897 		crp->crp_etype = 0;
898 		crp->crp_flags &= ~CRYPTO_F_DONE;
899 		cod->done = false;
900 		goto again;
901 	}
902 
903 	if (crp->crp_etype != 0) {
904 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
905 		error = crp->crp_etype;
906 		goto bail;
907 	}
908 
909 	if (cop->dst &&
910 	    (error = copyout(cod->uio.uio_iov[0].iov_base, cop->dst,
911 	    cop->len))) {
912 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
913 		goto bail;
914 	}
915 
916 	if (cop->mac &&
917 	    (error = copyout((caddr_t)cod->uio.uio_iov[0].iov_base + cop->len,
918 	    cop->mac, cse->thash->hashsize))) {
919 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
920 		goto bail;
921 	}
922 
923 bail:
924 	if (crp)
925 		crypto_freereq(crp);
926 	if (cod)
927 		cod_free(cod);
928 
929 	return (error);
930 }
931 
932 static int
933 cryptodev_aead(
934 	struct csession *cse,
935 	struct crypt_aead *caead,
936 	struct ucred *active_cred,
937 	struct thread *td)
938 {
939 	struct cryptop_data *cod = NULL;
940 	struct cryptop *crp = NULL;
941 	struct cryptodesc *crde = NULL, *crda = NULL;
942 	int error;
943 
944 	if (caead->len > 256*1024-4 || caead->aadlen > 256*1024-4) {
945 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
946 		return (E2BIG);
947 	}
948 
949 	if (cse->txform == NULL || cse->thash == NULL || caead->tag == NULL ||
950 	    (caead->len % cse->txform->blocksize) != 0) {
951 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
952 		return (EINVAL);
953 	}
954 
955 	cod = cod_alloc(cse, caead->aadlen + caead->len + cse->thash->hashsize,
956 	    td);
957 
958 	crp = crypto_getreq(2);
959 	if (crp == NULL) {
960 		error = ENOMEM;
961 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
962 		goto bail;
963 	}
964 
965 	if (caead->flags & COP_F_CIPHER_FIRST) {
966 		crde = crp->crp_desc;
967 		crda = crde->crd_next;
968 	} else {
969 		crda = crp->crp_desc;
970 		crde = crda->crd_next;
971 	}
972 
973 	if ((error = copyin(caead->aad, cod->uio.uio_iov[0].iov_base,
974 	    caead->aadlen))) {
975 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
976 		goto bail;
977 	}
978 
979 	if ((error = copyin(caead->src, (char *)cod->uio.uio_iov[0].iov_base +
980 	    caead->aadlen, caead->len))) {
981 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
982 		goto bail;
983 	}
984 
985 	/*
986 	 * For GCM, crd_len covers only the AAD.  For other ciphers
987 	 * chained with an HMAC, crd_len covers both the AAD and the
988 	 * cipher text.
989 	 */
990 	crda->crd_skip = 0;
991 	if (cse->cipher == CRYPTO_AES_NIST_GCM_16)
992 		crda->crd_len = caead->aadlen;
993 	else
994 		crda->crd_len = caead->aadlen + caead->len;
995 	crda->crd_inject = caead->aadlen + caead->len;
996 
997 	crda->crd_alg = cse->mac;
998 	crda->crd_key = cse->mackey;
999 	crda->crd_klen = cse->mackeylen * 8;
1000 
1001 	if (caead->op == COP_ENCRYPT)
1002 		crde->crd_flags |= CRD_F_ENCRYPT;
1003 	else
1004 		crde->crd_flags &= ~CRD_F_ENCRYPT;
1005 	crde->crd_skip = caead->aadlen;
1006 	crde->crd_len = caead->len;
1007 	crde->crd_inject = caead->aadlen;
1008 
1009 	crde->crd_alg = cse->cipher;
1010 	crde->crd_key = cse->key;
1011 	crde->crd_klen = cse->keylen * 8;
1012 
1013 	crp->crp_ilen = caead->aadlen + caead->len;
1014 	crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM
1015 		       | (caead->flags & COP_F_BATCH);
1016 	crp->crp_uio = &cod->uio;
1017 	crp->crp_callback = cryptodev_cb;
1018 	crp->crp_sid = cse->sid;
1019 	crp->crp_opaque = cod;
1020 
1021 	if (caead->iv) {
1022 		if (caead->ivlen > sizeof(crde->crd_iv)) {
1023 			error = EINVAL;
1024 			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1025 			goto bail;
1026 		}
1027 
1028 		if ((error = copyin(caead->iv, crde->crd_iv, caead->ivlen))) {
1029 			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1030 			goto bail;
1031 		}
1032 		crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
1033 	} else {
1034 		crde->crd_flags |= CRD_F_IV_PRESENT;
1035 		crde->crd_skip += cse->txform->blocksize;
1036 		crde->crd_len -= cse->txform->blocksize;
1037 	}
1038 
1039 	if ((error = copyin(caead->tag, (caddr_t)cod->uio.uio_iov[0].iov_base +
1040 	    caead->len + caead->aadlen, cse->thash->hashsize))) {
1041 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1042 		goto bail;
1043 	}
1044 again:
1045 	/*
1046 	 * Let the dispatch run unlocked, then, interlock against the
1047 	 * callback before checking if the operation completed and going
1048 	 * to sleep.  This insures drivers don't inherit our lock which
1049 	 * results in a lock order reversal between crypto_dispatch forced
1050 	 * entry and the crypto_done callback into us.
1051 	 */
1052 	error = crypto_dispatch(crp);
1053 	if (error != 0) {
1054 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1055 		goto bail;
1056 	}
1057 
1058 	mtx_lock(&cse->lock);
1059 	while (!cod->done)
1060 		mtx_sleep(cod, &cse->lock, PWAIT, "crydev", 0);
1061 	mtx_unlock(&cse->lock);
1062 
1063 	if (crp->crp_etype == EAGAIN) {
1064 		crp->crp_etype = 0;
1065 		crp->crp_flags &= ~CRYPTO_F_DONE;
1066 		cod->done = false;
1067 		goto again;
1068 	}
1069 
1070 	if (crp->crp_etype != 0) {
1071 		error = crp->crp_etype;
1072 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1073 		goto bail;
1074 	}
1075 
1076 	if (caead->dst && (error = copyout(
1077 	    (caddr_t)cod->uio.uio_iov[0].iov_base + caead->aadlen, caead->dst,
1078 	    caead->len))) {
1079 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1080 		goto bail;
1081 	}
1082 
1083 	if ((error = copyout((caddr_t)cod->uio.uio_iov[0].iov_base +
1084 	    caead->aadlen + caead->len, caead->tag, cse->thash->hashsize))) {
1085 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1086 		goto bail;
1087 	}
1088 
1089 bail:
1090 	crypto_freereq(crp);
1091 	if (cod)
1092 		cod_free(cod);
1093 
1094 	return (error);
1095 }
1096 
1097 static int
1098 cryptodev_cb(struct cryptop *crp)
1099 {
1100 	struct cryptop_data *cod = crp->crp_opaque;
1101 
1102 	/*
1103 	 * Lock to ensure the wakeup() is not missed by the loops
1104 	 * waiting on cod->done in cryptodev_op() and
1105 	 * cryptodev_aead().
1106 	 */
1107 	mtx_lock(&cod->cse->lock);
1108 	cod->done = true;
1109 	mtx_unlock(&cod->cse->lock);
1110 	wakeup(cod);
1111 	return (0);
1112 }
1113 
1114 static int
1115 cryptodevkey_cb(void *op)
1116 {
1117 	struct cryptkop *krp = (struct cryptkop *) op;
1118 
1119 	wakeup_one(krp);
1120 	return (0);
1121 }
1122 
1123 static int
1124 cryptodev_key(struct crypt_kop *kop)
1125 {
1126 	struct cryptkop *krp = NULL;
1127 	int error = EINVAL;
1128 	int in, out, size, i;
1129 
1130 	if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {
1131 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1132 		return (EFBIG);
1133 	}
1134 
1135 	in = kop->crk_iparams;
1136 	out = kop->crk_oparams;
1137 	switch (kop->crk_op) {
1138 	case CRK_MOD_EXP:
1139 		if (in == 3 && out == 1)
1140 			break;
1141 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1142 		return (EINVAL);
1143 	case CRK_MOD_EXP_CRT:
1144 		if (in == 6 && out == 1)
1145 			break;
1146 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1147 		return (EINVAL);
1148 	case CRK_DSA_SIGN:
1149 		if (in == 5 && out == 2)
1150 			break;
1151 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1152 		return (EINVAL);
1153 	case CRK_DSA_VERIFY:
1154 		if (in == 7 && out == 0)
1155 			break;
1156 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1157 		return (EINVAL);
1158 	case CRK_DH_COMPUTE_KEY:
1159 		if (in == 3 && out == 1)
1160 			break;
1161 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1162 		return (EINVAL);
1163 	default:
1164 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1165 		return (EINVAL);
1166 	}
1167 
1168 	krp = (struct cryptkop *)malloc(sizeof *krp, M_XDATA, M_WAITOK|M_ZERO);
1169 	if (!krp) {
1170 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1171 		return (ENOMEM);
1172 	}
1173 	krp->krp_op = kop->crk_op;
1174 	krp->krp_status = kop->crk_status;
1175 	krp->krp_iparams = kop->crk_iparams;
1176 	krp->krp_oparams = kop->crk_oparams;
1177 	krp->krp_crid = kop->crk_crid;
1178 	krp->krp_status = 0;
1179 	krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb;
1180 
1181 	for (i = 0; i < CRK_MAXPARAM; i++) {
1182 		if (kop->crk_param[i].crp_nbits > 65536) {
1183 			/* Limit is the same as in OpenBSD */
1184 			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1185 			goto fail;
1186 		}
1187 		krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
1188 	}
1189 	for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
1190 		size = (krp->krp_param[i].crp_nbits + 7) / 8;
1191 		if (size == 0)
1192 			continue;
1193 		krp->krp_param[i].crp_p = malloc(size, M_XDATA, M_WAITOK);
1194 		if (i >= krp->krp_iparams)
1195 			continue;
1196 		error = copyin(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p, size);
1197 		if (error) {
1198 			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1199 			goto fail;
1200 		}
1201 	}
1202 
1203 	error = crypto_kdispatch(krp);
1204 	if (error) {
1205 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1206 		goto fail;
1207 	}
1208 	error = tsleep(krp, PSOCK, "crydev", 0);
1209 	if (error) {
1210 		/* XXX can this happen?  if so, how do we recover? */
1211 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1212 		goto fail;
1213 	}
1214 
1215 	kop->crk_crid = krp->krp_crid;		/* device that did the work */
1216 	if (krp->krp_status != 0) {
1217 		error = krp->krp_status;
1218 		SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1219 		goto fail;
1220 	}
1221 
1222 	for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {
1223 		size = (krp->krp_param[i].crp_nbits + 7) / 8;
1224 		if (size == 0)
1225 			continue;
1226 		error = copyout(krp->krp_param[i].crp_p, kop->crk_param[i].crp_p, size);
1227 		if (error) {
1228 			SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1229 			goto fail;
1230 		}
1231 	}
1232 
1233 fail:
1234 	if (krp) {
1235 		kop->crk_status = krp->krp_status;
1236 		for (i = 0; i < CRK_MAXPARAM; i++) {
1237 			if (krp->krp_param[i].crp_p)
1238 				free(krp->krp_param[i].crp_p, M_XDATA);
1239 		}
1240 		free(krp, M_XDATA);
1241 	}
1242 	return (error);
1243 }
1244 
1245 static int
1246 cryptodev_find(struct crypt_find_op *find)
1247 {
1248 	device_t dev;
1249 	size_t fnlen = sizeof find->name;
1250 
1251 	if (find->crid != -1) {
1252 		dev = crypto_find_device_byhid(find->crid);
1253 		if (dev == NULL)
1254 			return (ENOENT);
1255 		strncpy(find->name, device_get_nameunit(dev), fnlen);
1256 		find->name[fnlen - 1] = '\x0';
1257 	} else {
1258 		find->name[fnlen - 1] = '\x0';
1259 		find->crid = crypto_find_driver(find->name);
1260 		if (find->crid == -1)
1261 			return (ENOENT);
1262 	}
1263 	return (0);
1264 }
1265 
1266 /* ARGSUSED */
1267 static int
1268 cryptof_stat(
1269 	struct file *fp,
1270 	struct stat *sb,
1271 	struct ucred *active_cred,
1272 	struct thread *td)
1273 {
1274 
1275 	return (EOPNOTSUPP);
1276 }
1277 
1278 /* ARGSUSED */
1279 static int
1280 cryptof_close(struct file *fp, struct thread *td)
1281 {
1282 	struct fcrypt *fcr = fp->f_data;
1283 	struct csession *cse;
1284 
1285 	while ((cse = TAILQ_FIRST(&fcr->csessions))) {
1286 		TAILQ_REMOVE(&fcr->csessions, cse, next);
1287 		(void)csefree(cse);
1288 	}
1289 	free(fcr, M_XDATA);
1290 	fp->f_data = NULL;
1291 	return 0;
1292 }
1293 
1294 static int
1295 cryptof_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
1296 {
1297 
1298 	kif->kf_type = KF_TYPE_CRYPTO;
1299 	return (0);
1300 }
1301 
1302 static struct csession *
1303 csefind(struct fcrypt *fcr, u_int ses)
1304 {
1305 	struct csession *cse;
1306 
1307 	TAILQ_FOREACH(cse, &fcr->csessions, next)
1308 		if (cse->ses == ses)
1309 			return (cse);
1310 	return (NULL);
1311 }
1312 
1313 static int
1314 csedelete(struct fcrypt *fcr, struct csession *cse_del)
1315 {
1316 	struct csession *cse;
1317 
1318 	TAILQ_FOREACH(cse, &fcr->csessions, next) {
1319 		if (cse == cse_del) {
1320 			TAILQ_REMOVE(&fcr->csessions, cse, next);
1321 			return (1);
1322 		}
1323 	}
1324 	return (0);
1325 }
1326 
1327 static struct csession *
1328 cseadd(struct fcrypt *fcr, struct csession *cse)
1329 {
1330 	TAILQ_INSERT_TAIL(&fcr->csessions, cse, next);
1331 	cse->ses = fcr->sesn++;
1332 	return (cse);
1333 }
1334 
1335 struct csession *
1336 csecreate(struct fcrypt *fcr, u_int64_t sid, caddr_t key, u_int64_t keylen,
1337     caddr_t mackey, u_int64_t mackeylen, u_int32_t cipher, u_int32_t mac,
1338     struct enc_xform *txform, struct auth_hash *thash)
1339 {
1340 	struct csession *cse;
1341 
1342 	cse = malloc(sizeof(struct csession), M_XDATA, M_NOWAIT | M_ZERO);
1343 	if (cse == NULL)
1344 		return NULL;
1345 	mtx_init(&cse->lock, "cryptodev", "crypto session lock", MTX_DEF);
1346 	cse->key = key;
1347 	cse->keylen = keylen/8;
1348 	cse->mackey = mackey;
1349 	cse->mackeylen = mackeylen/8;
1350 	cse->sid = sid;
1351 	cse->cipher = cipher;
1352 	cse->mac = mac;
1353 	cse->txform = txform;
1354 	cse->thash = thash;
1355 	cseadd(fcr, cse);
1356 	return (cse);
1357 }
1358 
1359 static int
1360 csefree(struct csession *cse)
1361 {
1362 	int error;
1363 
1364 	error = crypto_freesession(cse->sid);
1365 	mtx_destroy(&cse->lock);
1366 	if (cse->key)
1367 		free(cse->key, M_XDATA);
1368 	if (cse->mackey)
1369 		free(cse->mackey, M_XDATA);
1370 	free(cse, M_XDATA);
1371 	return (error);
1372 }
1373 
1374 static int
1375 cryptoopen(struct cdev *dev, int oflags, int devtype, struct thread *td)
1376 {
1377 	return (0);
1378 }
1379 
1380 static int
1381 cryptoread(struct cdev *dev, struct uio *uio, int ioflag)
1382 {
1383 	return (EIO);
1384 }
1385 
1386 static int
1387 cryptowrite(struct cdev *dev, struct uio *uio, int ioflag)
1388 {
1389 	return (EIO);
1390 }
1391 
1392 static int
1393 cryptoioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
1394 {
1395 	struct file *f;
1396 	struct fcrypt *fcr;
1397 	int fd, error;
1398 
1399 	switch (cmd) {
1400 	case CRIOGET:
1401 		fcr = malloc(sizeof(struct fcrypt), M_XDATA, M_WAITOK);
1402 		TAILQ_INIT(&fcr->csessions);
1403 		fcr->sesn = 0;
1404 
1405 		error = falloc(td, &f, &fd, 0);
1406 
1407 		if (error) {
1408 			free(fcr, M_XDATA);
1409 			return (error);
1410 		}
1411 		/* falloc automatically provides an extra reference to 'f'. */
1412 		finit(f, FREAD | FWRITE, DTYPE_CRYPTO, fcr, &cryptofops);
1413 		*(u_int32_t *)data = fd;
1414 		fdrop(f, td);
1415 		break;
1416 	case CRIOFINDDEV:
1417 		error = cryptodev_find((struct crypt_find_op *)data);
1418 		break;
1419 	case CRIOASYMFEAT:
1420 		error = crypto_getfeat((int *)data);
1421 		break;
1422 	default:
1423 		error = EINVAL;
1424 		break;
1425 	}
1426 	return (error);
1427 }
1428 
1429 static struct cdevsw crypto_cdevsw = {
1430 	.d_version =	D_VERSION,
1431 	.d_flags =	D_NEEDGIANT,
1432 	.d_open =	cryptoopen,
1433 	.d_read =	cryptoread,
1434 	.d_write =	cryptowrite,
1435 	.d_ioctl =	cryptoioctl,
1436 	.d_name =	"crypto",
1437 };
1438 static struct cdev *crypto_dev;
1439 
1440 /*
1441  * Initialization code, both for static and dynamic loading.
1442  */
1443 static int
1444 cryptodev_modevent(module_t mod, int type, void *unused)
1445 {
1446 	switch (type) {
1447 	case MOD_LOAD:
1448 		if (bootverbose)
1449 			printf("crypto: <crypto device>\n");
1450 		crypto_dev = make_dev(&crypto_cdevsw, 0,
1451 				      UID_ROOT, GID_WHEEL, 0666,
1452 				      "crypto");
1453 		return 0;
1454 	case MOD_UNLOAD:
1455 		/*XXX disallow if active sessions */
1456 		destroy_dev(crypto_dev);
1457 		return 0;
1458 	}
1459 	return EINVAL;
1460 }
1461 
1462 static moduledata_t cryptodev_mod = {
1463 	"cryptodev",
1464 	cryptodev_modevent,
1465 	0
1466 };
1467 MODULE_VERSION(cryptodev, 1);
1468 DECLARE_MODULE(cryptodev, cryptodev_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
1469 MODULE_DEPEND(cryptodev, crypto, 1, 1, 1);
1470 MODULE_DEPEND(cryptodev, zlib, 1, 1, 1);
1471