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