]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/opencrypto/cryptodev.c
dma: import snapshot 2021-07-10
[FreeBSD/FreeBSD.git] / sys / opencrypto / cryptodev.c
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/proc.h>
51 #include <sys/sysctl.h>
52 #include <sys/errno.h>
53 #include <sys/random.h>
54 #include <sys/conf.h>
55 #include <sys/kernel.h>
56 #include <sys/module.h>
57 #include <sys/fcntl.h>
58 #include <sys/bus.h>
59 #include <sys/sdt.h>
60 #include <sys/syscallsubr.h>
61
62 #include <opencrypto/cryptodev.h>
63 #include <opencrypto/xform.h>
64
65 SDT_PROVIDER_DECLARE(opencrypto);
66
67 SDT_PROBE_DEFINE1(opencrypto, dev, ioctl, error, "int"/*line number*/);
68
69 #ifdef COMPAT_FREEBSD12
70 /*
71  * Previously, most ioctls were performed against a cloned descriptor
72  * of /dev/crypto obtained via CRIOGET.  Now all ioctls are performed
73  * against /dev/crypto directly.
74  */
75 #define CRIOGET         _IOWR('c', 100, uint32_t)
76 #endif
77
78 /* the following are done against the cloned descriptor */
79
80 #ifdef COMPAT_FREEBSD32
81 #include <sys/mount.h>
82 #include <compat/freebsd32/freebsd32.h>
83
84 struct session_op32 {
85         uint32_t        cipher;
86         uint32_t        mac;
87         uint32_t        keylen;
88         uint32_t        key;
89         int             mackeylen;
90         uint32_t        mackey;
91         uint32_t        ses;
92 };
93
94 struct session2_op32 {
95         uint32_t        cipher;
96         uint32_t        mac;
97         uint32_t        keylen;
98         uint32_t        key;
99         int             mackeylen;
100         uint32_t        mackey;
101         uint32_t        ses;
102         int             crid;
103         int             pad[4];
104 };
105
106 struct crypt_op32 {
107         uint32_t        ses;
108         uint16_t        op;
109         uint16_t        flags;
110         u_int           len;
111         uint32_t        src, dst;
112         uint32_t        mac;
113         uint32_t        iv;
114 };
115
116 struct crypt_aead32 {
117         uint32_t        ses;
118         uint16_t        op;
119         uint16_t        flags;
120         u_int           len;
121         u_int           aadlen;
122         u_int           ivlen;
123         uint32_t        src;
124         uint32_t        dst;
125         uint32_t        aad;
126         uint32_t        tag;
127         uint32_t        iv;
128 };
129
130 #define CIOCGSESSION32  _IOWR('c', 101, struct session_op32)
131 #define CIOCCRYPT32     _IOWR('c', 103, struct crypt_op32)
132 #define CIOCGSESSION232 _IOWR('c', 106, struct session2_op32)
133 #define CIOCCRYPTAEAD32 _IOWR('c', 109, struct crypt_aead32)
134
135 static void
136 session_op_from_32(const struct session_op32 *from, struct session2_op *to)
137 {
138
139         memset(to, 0, sizeof(*to));
140         CP(*from, *to, cipher);
141         CP(*from, *to, mac);
142         CP(*from, *to, keylen);
143         PTRIN_CP(*from, *to, key);
144         CP(*from, *to, mackeylen);
145         PTRIN_CP(*from, *to, mackey);
146         CP(*from, *to, ses);
147         to->crid = CRYPTOCAP_F_HARDWARE;
148 }
149
150 static void
151 session2_op_from_32(const struct session2_op32 *from, struct session2_op *to)
152 {
153
154         session_op_from_32((const struct session_op32 *)from, to);
155         CP(*from, *to, crid);
156 }
157
158 static void
159 session_op_to_32(const struct session2_op *from, struct session_op32 *to)
160 {
161
162         CP(*from, *to, cipher);
163         CP(*from, *to, mac);
164         CP(*from, *to, keylen);
165         PTROUT_CP(*from, *to, key);
166         CP(*from, *to, mackeylen);
167         PTROUT_CP(*from, *to, mackey);
168         CP(*from, *to, ses);
169 }
170
171 static void
172 session2_op_to_32(const struct session2_op *from, struct session2_op32 *to)
173 {
174
175         session_op_to_32(from, (struct session_op32 *)to);
176         CP(*from, *to, crid);
177 }
178
179 static void
180 crypt_op_from_32(const struct crypt_op32 *from, struct crypt_op *to)
181 {
182
183         CP(*from, *to, ses);
184         CP(*from, *to, op);
185         CP(*from, *to, flags);
186         CP(*from, *to, len);
187         PTRIN_CP(*from, *to, src);
188         PTRIN_CP(*from, *to, dst);
189         PTRIN_CP(*from, *to, mac);
190         PTRIN_CP(*from, *to, iv);
191 }
192
193 static void
194 crypt_op_to_32(const struct crypt_op *from, struct crypt_op32 *to)
195 {
196
197         CP(*from, *to, ses);
198         CP(*from, *to, op);
199         CP(*from, *to, flags);
200         CP(*from, *to, len);
201         PTROUT_CP(*from, *to, src);
202         PTROUT_CP(*from, *to, dst);
203         PTROUT_CP(*from, *to, mac);
204         PTROUT_CP(*from, *to, iv);
205 }
206
207 static void
208 crypt_aead_from_32(const struct crypt_aead32 *from, struct crypt_aead *to)
209 {
210
211         CP(*from, *to, ses);
212         CP(*from, *to, op);
213         CP(*from, *to, flags);
214         CP(*from, *to, len);
215         CP(*from, *to, aadlen);
216         CP(*from, *to, ivlen);
217         PTRIN_CP(*from, *to, src);
218         PTRIN_CP(*from, *to, dst);
219         PTRIN_CP(*from, *to, aad);
220         PTRIN_CP(*from, *to, tag);
221         PTRIN_CP(*from, *to, iv);
222 }
223
224 static void
225 crypt_aead_to_32(const struct crypt_aead *from, struct crypt_aead32 *to)
226 {
227
228         CP(*from, *to, ses);
229         CP(*from, *to, op);
230         CP(*from, *to, flags);
231         CP(*from, *to, len);
232         CP(*from, *to, aadlen);
233         CP(*from, *to, ivlen);
234         PTROUT_CP(*from, *to, src);
235         PTROUT_CP(*from, *to, dst);
236         PTROUT_CP(*from, *to, aad);
237         PTROUT_CP(*from, *to, tag);
238         PTROUT_CP(*from, *to, iv);
239 }
240 #endif
241
242 static void
243 session2_op_from_op(const struct session_op *from, struct session2_op *to)
244 {
245
246         memset(to, 0, sizeof(*to));
247         memcpy(to, from, sizeof(*from));
248         to->crid = CRYPTOCAP_F_HARDWARE;
249 }
250
251 static void
252 session2_op_to_op(const struct session2_op *from, struct session_op *to)
253 {
254
255         memcpy(to, from, sizeof(*to));
256 }
257
258 struct csession {
259         TAILQ_ENTRY(csession) next;
260         crypto_session_t cses;
261         volatile u_int  refs;
262         uint32_t        ses;
263         struct mtx      lock;           /* for op submission */
264
265         const struct enc_xform *txform;
266         int             hashsize;
267         int             ivsize;
268         int             mode;
269
270         void            *key;
271         void            *mackey;
272 };
273
274 struct cryptop_data {
275         struct csession *cse;
276
277         char            *buf;
278         char            *obuf;
279         char            *aad;
280         bool            done;
281 };
282
283 struct fcrypt {
284         TAILQ_HEAD(csessionlist, csession) csessions;
285         int             sesn;
286         struct mtx      lock;
287 };
288
289 static bool use_outputbuffers;
290 SYSCTL_BOOL(_kern_crypto, OID_AUTO, cryptodev_use_output, CTLFLAG_RW,
291     &use_outputbuffers, 0,
292     "Use separate output buffers for /dev/crypto requests.");
293
294 static bool use_separate_aad;
295 SYSCTL_BOOL(_kern_crypto, OID_AUTO, cryptodev_separate_aad, CTLFLAG_RW,
296     &use_separate_aad, 0,
297     "Use separate AAD buffer for /dev/crypto requests.");
298
299 /*
300  * Check a crypto identifier to see if it requested
301  * a software device/driver.  This can be done either
302  * by device name/class or through search constraints.
303  */
304 static int
305 checkforsoftware(int *cridp)
306 {
307         int crid;
308
309         crid = *cridp;
310
311         if (!crypto_devallowsoft) {
312                 if (crid & CRYPTOCAP_F_SOFTWARE) {
313                         if (crid & CRYPTOCAP_F_HARDWARE) {
314                                 *cridp = CRYPTOCAP_F_HARDWARE;
315                                 return 0;
316                         }
317                         return EINVAL;
318                 }
319                 if ((crid & CRYPTOCAP_F_HARDWARE) == 0 &&
320                     (crypto_getcaps(crid) & CRYPTOCAP_F_HARDWARE) == 0)
321                         return EINVAL;
322         }
323         return 0;
324 }
325
326 static int
327 cse_create(struct fcrypt *fcr, struct session2_op *sop)
328 {
329         struct crypto_session_params csp;
330         struct csession *cse;
331         const struct enc_xform *txform;
332         const struct auth_hash *thash;
333         void *key = NULL;
334         void *mackey = NULL;
335         crypto_session_t cses;
336         int crid, error;
337
338         switch (sop->cipher) {
339         case 0:
340                 txform = NULL;
341                 break;
342         case CRYPTO_AES_CBC:
343                 txform = &enc_xform_rijndael128;
344                 break;
345         case CRYPTO_AES_XTS:
346                 txform = &enc_xform_aes_xts;
347                 break;
348         case CRYPTO_NULL_CBC:
349                 txform = &enc_xform_null;
350                 break;
351         case CRYPTO_CAMELLIA_CBC:
352                 txform = &enc_xform_camellia;
353                 break;
354         case CRYPTO_AES_ICM:
355                 txform = &enc_xform_aes_icm;
356                 break;
357         case CRYPTO_AES_NIST_GCM_16:
358                 txform = &enc_xform_aes_nist_gcm;
359                 break;
360         case CRYPTO_CHACHA20:
361                 txform = &enc_xform_chacha20;
362                 break;
363         case CRYPTO_AES_CCM_16:
364                 txform = &enc_xform_ccm;
365                 break;
366         case CRYPTO_CHACHA20_POLY1305:
367                 txform = &enc_xform_chacha20_poly1305;
368                 break;
369         default:
370                 CRYPTDEB("invalid cipher");
371                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
372                 return (EINVAL);
373         }
374
375         switch (sop->mac) {
376         case 0:
377                 thash = NULL;
378                 break;
379         case CRYPTO_POLY1305:
380                 thash = &auth_hash_poly1305;
381                 break;
382         case CRYPTO_SHA1_HMAC:
383                 thash = &auth_hash_hmac_sha1;
384                 break;
385         case CRYPTO_SHA2_224_HMAC:
386                 thash = &auth_hash_hmac_sha2_224;
387                 break;
388         case CRYPTO_SHA2_256_HMAC:
389                 thash = &auth_hash_hmac_sha2_256;
390                 break;
391         case CRYPTO_SHA2_384_HMAC:
392                 thash = &auth_hash_hmac_sha2_384;
393                 break;
394         case CRYPTO_SHA2_512_HMAC:
395                 thash = &auth_hash_hmac_sha2_512;
396                 break;
397         case CRYPTO_RIPEMD160_HMAC:
398                 thash = &auth_hash_hmac_ripemd_160;
399                 break;
400 #ifdef COMPAT_FREEBSD12
401         case CRYPTO_AES_128_NIST_GMAC:
402         case CRYPTO_AES_192_NIST_GMAC:
403         case CRYPTO_AES_256_NIST_GMAC:
404                 /* Should always be paired with GCM. */
405                 if (sop->cipher != CRYPTO_AES_NIST_GCM_16) {
406                         CRYPTDEB("GMAC without GCM");
407                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
408                         return (EINVAL);
409                 }
410                 break;
411 #endif
412         case CRYPTO_AES_NIST_GMAC:
413                 switch (sop->mackeylen * 8) {
414                 case 128:
415                         thash = &auth_hash_nist_gmac_aes_128;
416                         break;
417                 case 192:
418                         thash = &auth_hash_nist_gmac_aes_192;
419                         break;
420                 case 256:
421                         thash = &auth_hash_nist_gmac_aes_256;
422                         break;
423                 default:
424                         CRYPTDEB("invalid GMAC key length");
425                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
426                         return (EINVAL);
427                 }
428                 break;
429         case CRYPTO_AES_CCM_CBC_MAC:
430                 switch (sop->mackeylen) {
431                 case 16:
432                         thash = &auth_hash_ccm_cbc_mac_128;
433                         break;
434                 case 24:
435                         thash = &auth_hash_ccm_cbc_mac_192;
436                         break;
437                 case 32:
438                         thash = &auth_hash_ccm_cbc_mac_256;
439                         break;
440                 default:
441                         CRYPTDEB("Invalid CBC MAC key size %d", sop->keylen);
442                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
443                         return (EINVAL);
444                 }
445                 break;
446         case CRYPTO_SHA1:
447                 thash = &auth_hash_sha1;
448                 break;
449         case CRYPTO_SHA2_224:
450                 thash = &auth_hash_sha2_224;
451                 break;
452         case CRYPTO_SHA2_256:
453                 thash = &auth_hash_sha2_256;
454                 break;
455         case CRYPTO_SHA2_384:
456                 thash = &auth_hash_sha2_384;
457                 break;
458         case CRYPTO_SHA2_512:
459                 thash = &auth_hash_sha2_512;
460                 break;
461
462         case CRYPTO_NULL_HMAC:
463                 thash = &auth_hash_null;
464                 break;
465
466         case CRYPTO_BLAKE2B:
467                 thash = &auth_hash_blake2b;
468                 break;
469         case CRYPTO_BLAKE2S:
470                 thash = &auth_hash_blake2s;
471                 break;
472
473         default:
474                 CRYPTDEB("invalid mac");
475                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
476                 return (EINVAL);
477         }
478
479         if (txform == NULL && thash == NULL) {
480                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
481                 return (EINVAL);
482         }
483
484         memset(&csp, 0, sizeof(csp));
485         if (use_outputbuffers)
486                 csp.csp_flags |= CSP_F_SEPARATE_OUTPUT;
487
488         if (sop->cipher == CRYPTO_AES_NIST_GCM_16) {
489                 switch (sop->mac) {
490 #ifdef COMPAT_FREEBSD12
491                 case CRYPTO_AES_128_NIST_GMAC:
492                 case CRYPTO_AES_192_NIST_GMAC:
493                 case CRYPTO_AES_256_NIST_GMAC:
494                         if (sop->keylen != sop->mackeylen) {
495                                 SDT_PROBE1(opencrypto, dev, ioctl, error,
496                                     __LINE__);
497                                 return (EINVAL);
498                         }
499                         break;
500 #endif
501                 case 0:
502                         break;
503                 default:
504                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
505                         return (EINVAL);
506                 }
507                 csp.csp_mode = CSP_MODE_AEAD;
508         } else if (sop->cipher == CRYPTO_AES_CCM_16) {
509                 switch (sop->mac) {
510 #ifdef COMPAT_FREEBSD12
511                 case CRYPTO_AES_CCM_CBC_MAC:
512                         if (sop->keylen != sop->mackeylen) {
513                                 SDT_PROBE1(opencrypto, dev, ioctl, error,
514                                     __LINE__);
515                                 return (EINVAL);
516                         }
517                         thash = NULL;
518                         break;
519 #endif
520                 case 0:
521                         break;
522                 default:
523                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
524                         return (EINVAL);
525                 }
526                 csp.csp_mode = CSP_MODE_AEAD;
527         } else if (sop->cipher == CRYPTO_CHACHA20_POLY1305) {
528                 if (sop->mac != 0) {
529                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
530                         return (EINVAL);
531                 }
532                 csp.csp_mode = CSP_MODE_AEAD;
533         } else if (txform != NULL && thash != NULL)
534                 csp.csp_mode = CSP_MODE_ETA;
535         else if (txform != NULL)
536                 csp.csp_mode = CSP_MODE_CIPHER;
537         else
538                 csp.csp_mode = CSP_MODE_DIGEST;
539
540         switch (csp.csp_mode) {
541         case CSP_MODE_AEAD:
542         case CSP_MODE_ETA:
543                 if (use_separate_aad)
544                         csp.csp_flags |= CSP_F_SEPARATE_AAD;
545                 break;
546         }
547
548         if (txform != NULL) {
549                 csp.csp_cipher_alg = txform->type;
550                 csp.csp_cipher_klen = sop->keylen;
551                 if (sop->keylen > txform->maxkey ||
552                     sop->keylen < txform->minkey) {
553                         CRYPTDEB("invalid cipher parameters");
554                         error = EINVAL;
555                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
556                         goto bail;
557                 }
558
559                 key = malloc(csp.csp_cipher_klen, M_XDATA, M_WAITOK);
560                 error = copyin(sop->key, key, csp.csp_cipher_klen);
561                 if (error) {
562                         CRYPTDEB("invalid key");
563                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
564                         goto bail;
565                 }
566                 csp.csp_cipher_key = key;
567                 csp.csp_ivlen = txform->ivsize;
568         }
569
570         if (thash != NULL) {
571                 csp.csp_auth_alg = thash->type;
572                 csp.csp_auth_klen = sop->mackeylen;
573                 if (sop->mackeylen > thash->keysize || sop->mackeylen < 0) {
574                         CRYPTDEB("invalid mac key length");
575                         error = EINVAL;
576                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
577                         goto bail;
578                 }
579
580                 if (csp.csp_auth_klen != 0) {
581                         mackey = malloc(csp.csp_auth_klen, M_XDATA, M_WAITOK);
582                         error = copyin(sop->mackey, mackey, csp.csp_auth_klen);
583                         if (error) {
584                                 CRYPTDEB("invalid mac key");
585                                 SDT_PROBE1(opencrypto, dev, ioctl, error,
586                                     __LINE__);
587                                 goto bail;
588                         }
589                         csp.csp_auth_key = mackey;
590                 }
591
592                 if (csp.csp_auth_alg == CRYPTO_AES_NIST_GMAC)
593                         csp.csp_ivlen = AES_GCM_IV_LEN;
594                 if (csp.csp_auth_alg == CRYPTO_AES_CCM_CBC_MAC)
595                         csp.csp_ivlen = AES_CCM_IV_LEN;
596         }
597
598         crid = sop->crid;
599         error = checkforsoftware(&crid);
600         if (error) {
601                 CRYPTDEB("checkforsoftware");
602                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
603                 goto bail;
604         }
605         error = crypto_newsession(&cses, &csp, crid);
606         if (error) {
607                 CRYPTDEB("crypto_newsession");
608                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
609                 goto bail;
610         }
611
612         cse = malloc(sizeof(struct csession), M_XDATA, M_WAITOK | M_ZERO);
613         mtx_init(&cse->lock, "cryptodev", "crypto session lock", MTX_DEF);
614         refcount_init(&cse->refs, 1);
615         cse->key = key;
616         cse->mackey = mackey;
617         cse->mode = csp.csp_mode;
618         cse->cses = cses;
619         cse->txform = txform;
620         if (thash != NULL)
621                 cse->hashsize = thash->hashsize;
622         else if (csp.csp_cipher_alg == CRYPTO_AES_NIST_GCM_16)
623                 cse->hashsize = AES_GMAC_HASH_LEN;
624         else if (csp.csp_cipher_alg == CRYPTO_AES_CCM_16)
625                 cse->hashsize = AES_CBC_MAC_HASH_LEN;
626         else if (csp.csp_cipher_alg == CRYPTO_CHACHA20_POLY1305)
627                 cse->hashsize = POLY1305_HASH_LEN;
628         cse->ivsize = csp.csp_ivlen;
629
630         mtx_lock(&fcr->lock);
631         TAILQ_INSERT_TAIL(&fcr->csessions, cse, next);
632         cse->ses = fcr->sesn++;
633         mtx_unlock(&fcr->lock);
634
635         sop->ses = cse->ses;
636
637         /* return hardware/driver id */
638         sop->crid = crypto_ses2hid(cse->cses);
639 bail:
640         if (error) {
641                 free(key, M_XDATA);
642                 free(mackey, M_XDATA);
643         }
644         return (error);
645 }
646
647 static struct csession *
648 cse_find(struct fcrypt *fcr, u_int ses)
649 {
650         struct csession *cse;
651
652         mtx_lock(&fcr->lock);
653         TAILQ_FOREACH(cse, &fcr->csessions, next) {
654                 if (cse->ses == ses) {
655                         refcount_acquire(&cse->refs);
656                         mtx_unlock(&fcr->lock);
657                         return (cse);
658                 }
659         }
660         mtx_unlock(&fcr->lock);
661         return (NULL);
662 }
663
664 static void
665 cse_free(struct csession *cse)
666 {
667
668         if (!refcount_release(&cse->refs))
669                 return;
670         crypto_freesession(cse->cses);
671         mtx_destroy(&cse->lock);
672         if (cse->key)
673                 free(cse->key, M_XDATA);
674         if (cse->mackey)
675                 free(cse->mackey, M_XDATA);
676         free(cse, M_XDATA);
677 }
678
679 static bool
680 cse_delete(struct fcrypt *fcr, u_int ses)
681 {
682         struct csession *cse;
683
684         mtx_lock(&fcr->lock);
685         TAILQ_FOREACH(cse, &fcr->csessions, next) {
686                 if (cse->ses == ses) {
687                         TAILQ_REMOVE(&fcr->csessions, cse, next);
688                         mtx_unlock(&fcr->lock);
689                         cse_free(cse);
690                         return (true);
691                 }
692         }
693         mtx_unlock(&fcr->lock);
694         return (false);
695 }
696
697 static struct cryptop_data *
698 cod_alloc(struct csession *cse, size_t aad_len, size_t len)
699 {
700         struct cryptop_data *cod;
701
702         cod = malloc(sizeof(struct cryptop_data), M_XDATA, M_WAITOK | M_ZERO);
703
704         cod->cse = cse;
705         if (crypto_get_params(cse->cses)->csp_flags & CSP_F_SEPARATE_AAD) {
706                 if (aad_len != 0)
707                         cod->aad = malloc(aad_len, M_XDATA, M_WAITOK);
708                 cod->buf = malloc(len, M_XDATA, M_WAITOK);
709         } else
710                 cod->buf = malloc(aad_len + len, M_XDATA, M_WAITOK);
711         if (crypto_get_params(cse->cses)->csp_flags & CSP_F_SEPARATE_OUTPUT)
712                 cod->obuf = malloc(len, M_XDATA, M_WAITOK);
713         return (cod);
714 }
715
716 static void
717 cod_free(struct cryptop_data *cod)
718 {
719
720         free(cod->aad, M_XDATA);
721         free(cod->obuf, M_XDATA);
722         free(cod->buf, M_XDATA);
723         free(cod, M_XDATA);
724 }
725
726 static int
727 cryptodev_cb(struct cryptop *crp)
728 {
729         struct cryptop_data *cod = crp->crp_opaque;
730
731         /*
732          * Lock to ensure the wakeup() is not missed by the loops
733          * waiting on cod->done in cryptodev_op() and
734          * cryptodev_aead().
735          */
736         mtx_lock(&cod->cse->lock);
737         cod->done = true;
738         mtx_unlock(&cod->cse->lock);
739         wakeup(cod);
740         return (0);
741 }
742
743 static int
744 cryptodev_op(struct csession *cse, const struct crypt_op *cop)
745 {
746         struct cryptop_data *cod = NULL;
747         struct cryptop *crp = NULL;
748         char *dst;
749         int error;
750
751         if (cop->len > 256*1024-4) {
752                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
753                 return (E2BIG);
754         }
755
756         if (cse->txform) {
757                 if (cop->len == 0 || (cop->len % cse->txform->blocksize) != 0) {
758                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
759                         return (EINVAL);
760                 }
761         }
762
763         if (cop->mac && cse->hashsize == 0) {
764                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
765                 return (EINVAL);
766         }
767
768         /*
769          * The COP_F_CIPHER_FIRST flag predates explicit session
770          * modes, but the only way it was used was for EtA so allow it
771          * as long as it is consistent with EtA.
772          */
773         if (cop->flags & COP_F_CIPHER_FIRST) {
774                 if (cop->op != COP_ENCRYPT) {
775                         SDT_PROBE1(opencrypto, dev, ioctl, error,  __LINE__);
776                         return (EINVAL);
777                 }
778         }
779
780         cod = cod_alloc(cse, 0, cop->len + cse->hashsize);
781         dst = cop->dst;
782
783         crp = crypto_getreq(cse->cses, M_WAITOK);
784
785         error = copyin(cop->src, cod->buf, cop->len);
786         if (error) {
787                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
788                 goto bail;
789         }
790         crp->crp_payload_start = 0;
791         crp->crp_payload_length = cop->len;
792         if (cse->hashsize)
793                 crp->crp_digest_start = cop->len;
794
795         switch (cse->mode) {
796         case CSP_MODE_COMPRESS:
797                 switch (cop->op) {
798                 case COP_ENCRYPT:
799                         crp->crp_op = CRYPTO_OP_COMPRESS;
800                         break;
801                 case COP_DECRYPT:
802                         crp->crp_op = CRYPTO_OP_DECOMPRESS;
803                         break;
804                 default:
805                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
806                         error = EINVAL;
807                         goto bail;
808                 }
809                 break;
810         case CSP_MODE_CIPHER:
811                 switch (cop->op) {
812                 case COP_ENCRYPT:
813                         crp->crp_op = CRYPTO_OP_ENCRYPT;
814                         break;
815                 case COP_DECRYPT:
816                         crp->crp_op = CRYPTO_OP_DECRYPT;
817                         break;
818                 default:
819                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
820                         error = EINVAL;
821                         goto bail;
822                 }
823                 break;
824         case CSP_MODE_DIGEST:
825                 switch (cop->op) {
826                 case 0:
827                 case COP_ENCRYPT:
828                 case COP_DECRYPT:
829                         crp->crp_op = CRYPTO_OP_COMPUTE_DIGEST;
830                         if (cod->obuf != NULL)
831                                 crp->crp_digest_start = 0;
832                         break;
833                 default:
834                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
835                         error = EINVAL;
836                         goto bail;
837                 }
838                 break;
839         case CSP_MODE_ETA:
840                 switch (cop->op) {
841                 case COP_ENCRYPT:
842                         crp->crp_op = CRYPTO_OP_ENCRYPT |
843                             CRYPTO_OP_COMPUTE_DIGEST;
844                         break;
845                 case COP_DECRYPT:
846                         crp->crp_op = CRYPTO_OP_DECRYPT |
847                             CRYPTO_OP_VERIFY_DIGEST;
848                         break;
849                 default:
850                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
851                         error = EINVAL;
852                         goto bail;
853                 }
854                 break;
855         default:
856                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
857                 error = EINVAL;
858                 goto bail;
859         }
860
861         crp->crp_flags = CRYPTO_F_CBIMM | (cop->flags & COP_F_BATCH);
862         crypto_use_buf(crp, cod->buf, cop->len + cse->hashsize);
863         if (cod->obuf)
864                 crypto_use_output_buf(crp, cod->obuf, cop->len + cse->hashsize);
865         crp->crp_callback = cryptodev_cb;
866         crp->crp_opaque = cod;
867
868         if (cop->iv) {
869                 if (cse->ivsize == 0) {
870                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
871                         error = EINVAL;
872                         goto bail;
873                 }
874                 error = copyin(cop->iv, crp->crp_iv, cse->ivsize);
875                 if (error) {
876                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
877                         goto bail;
878                 }
879                 crp->crp_flags |= CRYPTO_F_IV_SEPARATE;
880         } else if (cse->ivsize != 0) {
881                 if (crp->crp_payload_length < cse->ivsize) {
882                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
883                         error = EINVAL;
884                         goto bail;
885                 }
886                 crp->crp_iv_start = 0;
887                 crp->crp_payload_start += cse->ivsize;
888                 crp->crp_payload_length -= cse->ivsize;
889                 dst += cse->ivsize;
890         }
891
892         if (cop->mac != NULL && crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
893                 error = copyin(cop->mac, cod->buf + crp->crp_digest_start,
894                     cse->hashsize);
895                 if (error) {
896                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
897                         goto bail;
898                 }
899         }
900 again:
901         /*
902          * Let the dispatch run unlocked, then, interlock against the
903          * callback before checking if the operation completed and going
904          * to sleep.  This insures drivers don't inherit our lock which
905          * results in a lock order reversal between crypto_dispatch forced
906          * entry and the crypto_done callback into us.
907          */
908         error = crypto_dispatch(crp);
909         if (error != 0) {
910                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
911                 goto bail;
912         }
913
914         mtx_lock(&cse->lock);
915         while (!cod->done)
916                 mtx_sleep(cod, &cse->lock, PWAIT, "crydev", 0);
917         mtx_unlock(&cse->lock);
918
919         if (crp->crp_etype == EAGAIN) {
920                 crp->crp_etype = 0;
921                 crp->crp_flags &= ~CRYPTO_F_DONE;
922                 cod->done = false;
923                 goto again;
924         }
925
926         if (crp->crp_etype != 0) {
927                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
928                 error = crp->crp_etype;
929                 goto bail;
930         }
931
932         if (cop->dst != NULL) {
933                 error = copyout(cod->obuf != NULL ? cod->obuf :
934                     cod->buf + crp->crp_payload_start, dst,
935                     crp->crp_payload_length);
936                 if (error) {
937                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
938                         goto bail;
939                 }
940         }
941
942         if (cop->mac != NULL && (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) == 0) {
943                 error = copyout((cod->obuf != NULL ? cod->obuf : cod->buf) +
944                     crp->crp_digest_start, cop->mac, cse->hashsize);
945                 if (error) {
946                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
947                         goto bail;
948                 }
949         }
950
951 bail:
952         crypto_freereq(crp);
953         cod_free(cod);
954
955         return (error);
956 }
957
958 static int
959 cryptodev_aead(struct csession *cse, struct crypt_aead *caead)
960 {
961         struct cryptop_data *cod = NULL;
962         struct cryptop *crp = NULL;
963         char *dst;
964         int error;
965
966         if (caead->len > 256*1024-4 || caead->aadlen > 256*1024-4) {
967                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
968                 return (E2BIG);
969         }
970
971         if (cse->txform == NULL || cse->hashsize == 0 || caead->tag == NULL ||
972             (caead->len % cse->txform->blocksize) != 0) {
973                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
974                 return (EINVAL);
975         }
976
977         /*
978          * The COP_F_CIPHER_FIRST flag predates explicit session
979          * modes, but the only way it was used was for EtA so allow it
980          * as long as it is consistent with EtA.
981          */
982         if (caead->flags & COP_F_CIPHER_FIRST) {
983                 if (caead->op != COP_ENCRYPT) {
984                         SDT_PROBE1(opencrypto, dev, ioctl, error,  __LINE__);
985                         return (EINVAL);
986                 }
987         }
988
989         cod = cod_alloc(cse, caead->aadlen, caead->len + cse->hashsize);
990         dst = caead->dst;
991
992         crp = crypto_getreq(cse->cses, M_WAITOK);
993
994         if (cod->aad != NULL)
995                 error = copyin(caead->aad, cod->aad, caead->aadlen);
996         else
997                 error = copyin(caead->aad, cod->buf, caead->aadlen);
998         if (error) {
999                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1000                 goto bail;
1001         }
1002         crp->crp_aad = cod->aad;
1003         crp->crp_aad_start = 0;
1004         crp->crp_aad_length = caead->aadlen;
1005
1006         if (cod->aad != NULL)
1007                 crp->crp_payload_start = 0;
1008         else
1009                 crp->crp_payload_start = caead->aadlen;
1010         error = copyin(caead->src, cod->buf + crp->crp_payload_start,
1011             caead->len);
1012         if (error) {
1013                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1014                 goto bail;
1015         }
1016         crp->crp_payload_length = caead->len;
1017         if (caead->op == COP_ENCRYPT && cod->obuf != NULL)
1018                 crp->crp_digest_start = crp->crp_payload_output_start +
1019                     caead->len;
1020         else
1021                 crp->crp_digest_start = crp->crp_payload_start + caead->len;
1022
1023         switch (cse->mode) {
1024         case CSP_MODE_AEAD:
1025         case CSP_MODE_ETA:
1026                 switch (caead->op) {
1027                 case COP_ENCRYPT:
1028                         crp->crp_op = CRYPTO_OP_ENCRYPT |
1029                             CRYPTO_OP_COMPUTE_DIGEST;
1030                         break;
1031                 case COP_DECRYPT:
1032                         crp->crp_op = CRYPTO_OP_DECRYPT |
1033                             CRYPTO_OP_VERIFY_DIGEST;
1034                         break;
1035                 default:
1036                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1037                         error = EINVAL;
1038                         goto bail;
1039                 }
1040                 break;
1041         default:
1042                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1043                 error = EINVAL;
1044                 goto bail;
1045         }
1046
1047         crp->crp_flags = CRYPTO_F_CBIMM | (caead->flags & COP_F_BATCH);
1048         crypto_use_buf(crp, cod->buf, crp->crp_payload_start + caead->len +
1049             cse->hashsize);
1050         if (cod->obuf != NULL)
1051                 crypto_use_output_buf(crp, cod->obuf, caead->len +
1052                     cse->hashsize);
1053         crp->crp_callback = cryptodev_cb;
1054         crp->crp_opaque = cod;
1055
1056         if (caead->iv) {
1057                 /*
1058                  * Permit a 16-byte IV for AES-XTS, but only use the
1059                  * first 8 bytes as a block number.
1060                  */
1061                 if (cse->mode == CSP_MODE_ETA &&
1062                     caead->ivlen == AES_BLOCK_LEN &&
1063                     cse->ivsize == AES_XTS_IV_LEN)
1064                         caead->ivlen = AES_XTS_IV_LEN;
1065
1066                 if (cse->ivsize == 0) {
1067                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1068                         error = EINVAL;
1069                         goto bail;
1070                 }
1071                 if (caead->ivlen != cse->ivsize) {
1072                         error = EINVAL;
1073                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1074                         goto bail;
1075                 }
1076
1077                 error = copyin(caead->iv, crp->crp_iv, cse->ivsize);
1078                 if (error) {
1079                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1080                         goto bail;
1081                 }
1082                 crp->crp_flags |= CRYPTO_F_IV_SEPARATE;
1083         } else {
1084                 error = EINVAL;
1085                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1086                 goto bail;
1087         }
1088
1089         if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
1090                 error = copyin(caead->tag, cod->buf + crp->crp_digest_start,
1091                     cse->hashsize);
1092                 if (error) {
1093                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1094                         goto bail;
1095                 }
1096         }
1097 again:
1098         /*
1099          * Let the dispatch run unlocked, then, interlock against the
1100          * callback before checking if the operation completed and going
1101          * to sleep.  This insures drivers don't inherit our lock which
1102          * results in a lock order reversal between crypto_dispatch forced
1103          * entry and the crypto_done callback into us.
1104          */
1105         error = crypto_dispatch(crp);
1106         if (error != 0) {
1107                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1108                 goto bail;
1109         }
1110
1111         mtx_lock(&cse->lock);
1112         while (!cod->done)
1113                 mtx_sleep(cod, &cse->lock, PWAIT, "crydev", 0);
1114         mtx_unlock(&cse->lock);
1115
1116         if (crp->crp_etype == EAGAIN) {
1117                 crp->crp_etype = 0;
1118                 crp->crp_flags &= ~CRYPTO_F_DONE;
1119                 cod->done = false;
1120                 goto again;
1121         }
1122
1123         if (crp->crp_etype != 0) {
1124                 error = crp->crp_etype;
1125                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1126                 goto bail;
1127         }
1128
1129         if (caead->dst != NULL) {
1130                 error = copyout(cod->obuf != NULL ? cod->obuf :
1131                     cod->buf + crp->crp_payload_start, dst,
1132                     crp->crp_payload_length);
1133                 if (error) {
1134                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1135                         goto bail;
1136                 }
1137         }
1138
1139         if ((crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) == 0) {
1140                 error = copyout((cod->obuf != NULL ? cod->obuf : cod->buf) +
1141                     crp->crp_digest_start, caead->tag, cse->hashsize);
1142                 if (error) {
1143                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1144                         goto bail;
1145                 }
1146         }
1147
1148 bail:
1149         crypto_freereq(crp);
1150         cod_free(cod);
1151
1152         return (error);
1153 }
1154
1155 static int
1156 cryptodev_find(struct crypt_find_op *find)
1157 {
1158         device_t dev;
1159         size_t fnlen = sizeof find->name;
1160
1161         if (find->crid != -1) {
1162                 dev = crypto_find_device_byhid(find->crid);
1163                 if (dev == NULL)
1164                         return (ENOENT);
1165                 strncpy(find->name, device_get_nameunit(dev), fnlen);
1166                 find->name[fnlen - 1] = '\x0';
1167         } else {
1168                 find->name[fnlen - 1] = '\x0';
1169                 find->crid = crypto_find_driver(find->name);
1170                 if (find->crid == -1)
1171                         return (ENOENT);
1172         }
1173         return (0);
1174 }
1175
1176 static void
1177 fcrypt_dtor(void *data)
1178 {
1179         struct fcrypt *fcr = data;
1180         struct csession *cse;
1181
1182         while ((cse = TAILQ_FIRST(&fcr->csessions))) {
1183                 TAILQ_REMOVE(&fcr->csessions, cse, next);
1184                 KASSERT(refcount_load(&cse->refs) == 1,
1185                     ("%s: crypto session %p with %d refs", __func__, cse,
1186                     refcount_load(&cse->refs)));
1187                 cse_free(cse);
1188         }
1189         mtx_destroy(&fcr->lock);
1190         free(fcr, M_XDATA);
1191 }
1192
1193 static int
1194 crypto_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
1195 {
1196         struct fcrypt *fcr;
1197         int error;
1198
1199         fcr = malloc(sizeof(struct fcrypt), M_XDATA, M_WAITOK | M_ZERO);
1200         TAILQ_INIT(&fcr->csessions);
1201         mtx_init(&fcr->lock, "fcrypt", NULL, MTX_DEF);
1202         error = devfs_set_cdevpriv(fcr, fcrypt_dtor);
1203         if (error)
1204                 fcrypt_dtor(fcr);
1205         return (error);
1206 }
1207
1208 static int
1209 crypto_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
1210     struct thread *td)
1211 {
1212         struct fcrypt *fcr;
1213         struct csession *cse;
1214         struct session2_op *sop;
1215         struct crypt_op *cop;
1216         struct crypt_aead *caead;
1217         uint32_t ses;
1218         int error = 0;
1219         union {
1220                 struct session2_op sopc;
1221 #ifdef COMPAT_FREEBSD32
1222                 struct crypt_op copc;
1223                 struct crypt_aead aeadc;
1224 #endif
1225         } thunk;
1226 #ifdef COMPAT_FREEBSD32
1227         u_long cmd32;
1228         void *data32;
1229
1230         cmd32 = 0;
1231         data32 = NULL;
1232         switch (cmd) {
1233         case CIOCGSESSION32:
1234                 cmd32 = cmd;
1235                 data32 = data;
1236                 cmd = CIOCGSESSION;
1237                 data = (void *)&thunk.sopc;
1238                 session_op_from_32((struct session_op32 *)data32, &thunk.sopc);
1239                 break;
1240         case CIOCGSESSION232:
1241                 cmd32 = cmd;
1242                 data32 = data;
1243                 cmd = CIOCGSESSION2;
1244                 data = (void *)&thunk.sopc;
1245                 session2_op_from_32((struct session2_op32 *)data32,
1246                     &thunk.sopc);
1247                 break;
1248         case CIOCCRYPT32:
1249                 cmd32 = cmd;
1250                 data32 = data;
1251                 cmd = CIOCCRYPT;
1252                 data = (void *)&thunk.copc;
1253                 crypt_op_from_32((struct crypt_op32 *)data32, &thunk.copc);
1254                 break;
1255         case CIOCCRYPTAEAD32:
1256                 cmd32 = cmd;
1257                 data32 = data;
1258                 cmd = CIOCCRYPTAEAD;
1259                 data = (void *)&thunk.aeadc;
1260                 crypt_aead_from_32((struct crypt_aead32 *)data32, &thunk.aeadc);
1261                 break;
1262         }
1263 #endif
1264
1265         devfs_get_cdevpriv((void **)&fcr);
1266
1267         switch (cmd) {
1268 #ifdef COMPAT_FREEBSD12
1269         case CRIOGET:
1270                 /*
1271                  * NB: This may fail in cases that the old
1272                  * implementation did not if the current process has
1273                  * restricted filesystem access (e.g. running in a
1274                  * jail that does not expose /dev/crypto or in
1275                  * capability mode).
1276                  */
1277                 error = kern_openat(td, AT_FDCWD, "/dev/crypto", UIO_SYSSPACE,
1278                     O_RDWR, 0);
1279                 if (error == 0)
1280                         *(uint32_t *)data = td->td_retval[0];
1281                 break;
1282 #endif
1283         case CIOCGSESSION:
1284         case CIOCGSESSION2:
1285                 if (cmd == CIOCGSESSION) {
1286                         session2_op_from_op((void *)data, &thunk.sopc);
1287                         sop = &thunk.sopc;
1288                 } else
1289                         sop = (struct session2_op *)data;
1290
1291                 error = cse_create(fcr, sop);
1292                 if (cmd == CIOCGSESSION && error == 0)
1293                         session2_op_to_op(sop, (void *)data);
1294                 break;
1295         case CIOCFSESSION:
1296                 ses = *(uint32_t *)data;
1297                 if (!cse_delete(fcr, ses)) {
1298                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1299                         return (EINVAL);
1300                 }
1301                 break;
1302         case CIOCCRYPT:
1303                 cop = (struct crypt_op *)data;
1304                 cse = cse_find(fcr, cop->ses);
1305                 if (cse == NULL) {
1306                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1307                         return (EINVAL);
1308                 }
1309                 error = cryptodev_op(cse, cop);
1310                 cse_free(cse);
1311                 break;
1312         case CIOCFINDDEV:
1313                 error = cryptodev_find((struct crypt_find_op *)data);
1314                 break;
1315         case CIOCCRYPTAEAD:
1316                 caead = (struct crypt_aead *)data;
1317                 cse = cse_find(fcr, caead->ses);
1318                 if (cse == NULL) {
1319                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1320                         return (EINVAL);
1321                 }
1322                 error = cryptodev_aead(cse, caead);
1323                 cse_free(cse);
1324                 break;
1325         default:
1326                 error = EINVAL;
1327                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1328                 break;
1329         }
1330
1331 #ifdef COMPAT_FREEBSD32
1332         switch (cmd32) {
1333         case CIOCGSESSION32:
1334                 if (error == 0)
1335                         session_op_to_32((void *)data, data32);
1336                 break;
1337         case CIOCGSESSION232:
1338                 if (error == 0)
1339                         session2_op_to_32((void *)data, data32);
1340                 break;
1341         case CIOCCRYPT32:
1342                 if (error == 0)
1343                         crypt_op_to_32((void *)data, data32);
1344                 break;
1345         case CIOCCRYPTAEAD32:
1346                 if (error == 0)
1347                         crypt_aead_to_32((void *)data, data32);
1348                 break;
1349         }
1350 #endif
1351         return (error);
1352 }
1353
1354 static struct cdevsw crypto_cdevsw = {
1355         .d_version =    D_VERSION,
1356         .d_open =       crypto_open,
1357         .d_ioctl =      crypto_ioctl,
1358         .d_name =       "crypto",
1359 };
1360 static struct cdev *crypto_dev;
1361
1362 /*
1363  * Initialization code, both for static and dynamic loading.
1364  */
1365 static int
1366 cryptodev_modevent(module_t mod, int type, void *unused)
1367 {
1368         switch (type) {
1369         case MOD_LOAD:
1370                 if (bootverbose)
1371                         printf("crypto: <crypto device>\n");
1372                 crypto_dev = make_dev(&crypto_cdevsw, 0, 
1373                                       UID_ROOT, GID_WHEEL, 0666,
1374                                       "crypto");
1375                 return 0;
1376         case MOD_UNLOAD:
1377                 /*XXX disallow if active sessions */
1378                 destroy_dev(crypto_dev);
1379                 return 0;
1380         }
1381         return EINVAL;
1382 }
1383
1384 static moduledata_t cryptodev_mod = {
1385         "cryptodev",
1386         cryptodev_modevent,
1387         0
1388 };
1389 MODULE_VERSION(cryptodev, 1);
1390 DECLARE_MODULE(cryptodev, cryptodev_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
1391 MODULE_DEPEND(cryptodev, crypto, 1, 1, 1);
1392 MODULE_DEPEND(cryptodev, zlib, 1, 1, 1);