]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/opencrypto/cryptodev.c
Merge commit 'bd136720030ebb0b31e6d5a2236b9d0ddac71b94'
[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         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         struct enc_xform *txform;
332         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                 crp->crp_iv_start = 0;
882                 crp->crp_payload_start += cse->ivsize;
883                 crp->crp_payload_length -= cse->ivsize;
884                 dst += cse->ivsize;
885         }
886
887         if (cop->mac != NULL && crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
888                 error = copyin(cop->mac, cod->buf + crp->crp_digest_start,
889                     cse->hashsize);
890                 if (error) {
891                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
892                         goto bail;
893                 }
894         }
895 again:
896         /*
897          * Let the dispatch run unlocked, then, interlock against the
898          * callback before checking if the operation completed and going
899          * to sleep.  This insures drivers don't inherit our lock which
900          * results in a lock order reversal between crypto_dispatch forced
901          * entry and the crypto_done callback into us.
902          */
903         error = crypto_dispatch(crp);
904         if (error != 0) {
905                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
906                 goto bail;
907         }
908
909         mtx_lock(&cse->lock);
910         while (!cod->done)
911                 mtx_sleep(cod, &cse->lock, PWAIT, "crydev", 0);
912         mtx_unlock(&cse->lock);
913
914         if (crp->crp_etype == EAGAIN) {
915                 crp->crp_etype = 0;
916                 crp->crp_flags &= ~CRYPTO_F_DONE;
917                 cod->done = false;
918                 goto again;
919         }
920
921         if (crp->crp_etype != 0) {
922                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
923                 error = crp->crp_etype;
924                 goto bail;
925         }
926
927         if (cop->dst != NULL) {
928                 error = copyout(cod->obuf != NULL ? cod->obuf :
929                     cod->buf + crp->crp_payload_start, dst,
930                     crp->crp_payload_length);
931                 if (error) {
932                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
933                         goto bail;
934                 }
935         }
936
937         if (cop->mac != NULL && (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) == 0) {
938                 error = copyout((cod->obuf != NULL ? cod->obuf : cod->buf) +
939                     crp->crp_digest_start, cop->mac, cse->hashsize);
940                 if (error) {
941                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
942                         goto bail;
943                 }
944         }
945
946 bail:
947         crypto_freereq(crp);
948         cod_free(cod);
949
950         return (error);
951 }
952
953 static int
954 cryptodev_aead(struct csession *cse, struct crypt_aead *caead)
955 {
956         struct cryptop_data *cod = NULL;
957         struct cryptop *crp = NULL;
958         char *dst;
959         int error;
960
961         if (caead->len > 256*1024-4 || caead->aadlen > 256*1024-4) {
962                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
963                 return (E2BIG);
964         }
965
966         if (cse->txform == NULL || cse->hashsize == 0 || caead->tag == NULL ||
967             (caead->len % cse->txform->blocksize) != 0) {
968                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
969                 return (EINVAL);
970         }
971
972         /*
973          * The COP_F_CIPHER_FIRST flag predates explicit session
974          * modes, but the only way it was used was for EtA so allow it
975          * as long as it is consistent with EtA.
976          */
977         if (caead->flags & COP_F_CIPHER_FIRST) {
978                 if (caead->op != COP_ENCRYPT) {
979                         SDT_PROBE1(opencrypto, dev, ioctl, error,  __LINE__);
980                         return (EINVAL);
981                 }
982         }
983
984         cod = cod_alloc(cse, caead->aadlen, caead->len + cse->hashsize);
985         dst = caead->dst;
986
987         crp = crypto_getreq(cse->cses, M_WAITOK);
988
989         if (cod->aad != NULL)
990                 error = copyin(caead->aad, cod->aad, caead->aadlen);
991         else
992                 error = copyin(caead->aad, cod->buf, caead->aadlen);
993         if (error) {
994                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
995                 goto bail;
996         }
997         crp->crp_aad = cod->aad;
998         crp->crp_aad_start = 0;
999         crp->crp_aad_length = caead->aadlen;
1000
1001         if (cod->aad != NULL)
1002                 crp->crp_payload_start = 0;
1003         else
1004                 crp->crp_payload_start = caead->aadlen;
1005         error = copyin(caead->src, cod->buf + crp->crp_payload_start,
1006             caead->len);
1007         if (error) {
1008                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1009                 goto bail;
1010         }
1011         crp->crp_payload_length = caead->len;
1012         if (caead->op == COP_ENCRYPT && cod->obuf != NULL)
1013                 crp->crp_digest_start = crp->crp_payload_output_start +
1014                     caead->len;
1015         else
1016                 crp->crp_digest_start = crp->crp_payload_start + caead->len;
1017
1018         switch (cse->mode) {
1019         case CSP_MODE_AEAD:
1020         case CSP_MODE_ETA:
1021                 switch (caead->op) {
1022                 case COP_ENCRYPT:
1023                         crp->crp_op = CRYPTO_OP_ENCRYPT |
1024                             CRYPTO_OP_COMPUTE_DIGEST;
1025                         break;
1026                 case COP_DECRYPT:
1027                         crp->crp_op = CRYPTO_OP_DECRYPT |
1028                             CRYPTO_OP_VERIFY_DIGEST;
1029                         break;
1030                 default:
1031                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1032                         error = EINVAL;
1033                         goto bail;
1034                 }
1035                 break;
1036         default:
1037                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1038                 error = EINVAL;
1039                 goto bail;
1040         }
1041
1042         crp->crp_flags = CRYPTO_F_CBIMM | (caead->flags & COP_F_BATCH);
1043         crypto_use_buf(crp, cod->buf, crp->crp_payload_start + caead->len +
1044             cse->hashsize);
1045         if (cod->obuf != NULL)
1046                 crypto_use_output_buf(crp, cod->obuf, caead->len +
1047                     cse->hashsize);
1048         crp->crp_callback = cryptodev_cb;
1049         crp->crp_opaque = cod;
1050
1051         if (caead->iv) {
1052                 /*
1053                  * Permit a 16-byte IV for AES-XTS, but only use the
1054                  * first 8 bytes as a block number.
1055                  */
1056                 if (cse->mode == CSP_MODE_ETA &&
1057                     caead->ivlen == AES_BLOCK_LEN &&
1058                     cse->ivsize == AES_XTS_IV_LEN)
1059                         caead->ivlen = AES_XTS_IV_LEN;
1060
1061                 if (caead->ivlen != cse->ivsize) {
1062                         error = EINVAL;
1063                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1064                         goto bail;
1065                 }
1066
1067                 error = copyin(caead->iv, crp->crp_iv, cse->ivsize);
1068                 if (error) {
1069                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1070                         goto bail;
1071                 }
1072                 crp->crp_flags |= CRYPTO_F_IV_SEPARATE;
1073         } else {
1074                 crp->crp_iv_start = crp->crp_payload_start;
1075                 crp->crp_payload_start += cse->ivsize;
1076                 crp->crp_payload_length -= cse->ivsize;
1077                 dst += cse->ivsize;
1078         }
1079
1080         if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
1081                 error = copyin(caead->tag, cod->buf + crp->crp_digest_start,
1082                     cse->hashsize);
1083                 if (error) {
1084                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1085                         goto bail;
1086                 }
1087         }
1088 again:
1089         /*
1090          * Let the dispatch run unlocked, then, interlock against the
1091          * callback before checking if the operation completed and going
1092          * to sleep.  This insures drivers don't inherit our lock which
1093          * results in a lock order reversal between crypto_dispatch forced
1094          * entry and the crypto_done callback into us.
1095          */
1096         error = crypto_dispatch(crp);
1097         if (error != 0) {
1098                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1099                 goto bail;
1100         }
1101
1102         mtx_lock(&cse->lock);
1103         while (!cod->done)
1104                 mtx_sleep(cod, &cse->lock, PWAIT, "crydev", 0);
1105         mtx_unlock(&cse->lock);
1106
1107         if (crp->crp_etype == EAGAIN) {
1108                 crp->crp_etype = 0;
1109                 crp->crp_flags &= ~CRYPTO_F_DONE;
1110                 cod->done = false;
1111                 goto again;
1112         }
1113
1114         if (crp->crp_etype != 0) {
1115                 error = crp->crp_etype;
1116                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1117                 goto bail;
1118         }
1119
1120         if (caead->dst != NULL) {
1121                 error = copyout(cod->obuf != NULL ? cod->obuf :
1122                     cod->buf + crp->crp_payload_start, dst,
1123                     crp->crp_payload_length);
1124                 if (error) {
1125                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1126                         goto bail;
1127                 }
1128         }
1129
1130         if ((crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) == 0) {
1131                 error = copyout((cod->obuf != NULL ? cod->obuf : cod->buf) +
1132                     crp->crp_digest_start, caead->tag, cse->hashsize);
1133                 if (error) {
1134                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1135                         goto bail;
1136                 }
1137         }
1138
1139 bail:
1140         crypto_freereq(crp);
1141         cod_free(cod);
1142
1143         return (error);
1144 }
1145
1146 static int
1147 cryptodev_find(struct crypt_find_op *find)
1148 {
1149         device_t dev;
1150         size_t fnlen = sizeof find->name;
1151
1152         if (find->crid != -1) {
1153                 dev = crypto_find_device_byhid(find->crid);
1154                 if (dev == NULL)
1155                         return (ENOENT);
1156                 strncpy(find->name, device_get_nameunit(dev), fnlen);
1157                 find->name[fnlen - 1] = '\x0';
1158         } else {
1159                 find->name[fnlen - 1] = '\x0';
1160                 find->crid = crypto_find_driver(find->name);
1161                 if (find->crid == -1)
1162                         return (ENOENT);
1163         }
1164         return (0);
1165 }
1166
1167 static void
1168 fcrypt_dtor(void *data)
1169 {
1170         struct fcrypt *fcr = data;
1171         struct csession *cse;
1172
1173         while ((cse = TAILQ_FIRST(&fcr->csessions))) {
1174                 TAILQ_REMOVE(&fcr->csessions, cse, next);
1175                 KASSERT(refcount_load(&cse->refs) == 1,
1176                     ("%s: crypto session %p with %d refs", __func__, cse,
1177                     refcount_load(&cse->refs)));
1178                 cse_free(cse);
1179         }
1180         mtx_destroy(&fcr->lock);
1181         free(fcr, M_XDATA);
1182 }
1183
1184 static int
1185 crypto_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
1186 {
1187         struct fcrypt *fcr;
1188         int error;
1189
1190         fcr = malloc(sizeof(struct fcrypt), M_XDATA, M_WAITOK | M_ZERO);
1191         TAILQ_INIT(&fcr->csessions);
1192         mtx_init(&fcr->lock, "fcrypt", NULL, MTX_DEF);
1193         error = devfs_set_cdevpriv(fcr, fcrypt_dtor);
1194         if (error)
1195                 fcrypt_dtor(fcr);
1196         return (error);
1197 }
1198
1199 static int
1200 crypto_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
1201     struct thread *td)
1202 {
1203         struct fcrypt *fcr;
1204         struct csession *cse;
1205         struct session2_op *sop;
1206         struct crypt_op *cop;
1207         struct crypt_aead *caead;
1208         uint32_t ses;
1209         int error = 0;
1210         union {
1211                 struct session2_op sopc;
1212 #ifdef COMPAT_FREEBSD32
1213                 struct crypt_op copc;
1214                 struct crypt_aead aeadc;
1215 #endif
1216         } thunk;
1217 #ifdef COMPAT_FREEBSD32
1218         u_long cmd32;
1219         void *data32;
1220
1221         cmd32 = 0;
1222         data32 = NULL;
1223         switch (cmd) {
1224         case CIOCGSESSION32:
1225                 cmd32 = cmd;
1226                 data32 = data;
1227                 cmd = CIOCGSESSION;
1228                 data = (void *)&thunk.sopc;
1229                 session_op_from_32((struct session_op32 *)data32, &thunk.sopc);
1230                 break;
1231         case CIOCGSESSION232:
1232                 cmd32 = cmd;
1233                 data32 = data;
1234                 cmd = CIOCGSESSION2;
1235                 data = (void *)&thunk.sopc;
1236                 session2_op_from_32((struct session2_op32 *)data32,
1237                     &thunk.sopc);
1238                 break;
1239         case CIOCCRYPT32:
1240                 cmd32 = cmd;
1241                 data32 = data;
1242                 cmd = CIOCCRYPT;
1243                 data = (void *)&thunk.copc;
1244                 crypt_op_from_32((struct crypt_op32 *)data32, &thunk.copc);
1245                 break;
1246         case CIOCCRYPTAEAD32:
1247                 cmd32 = cmd;
1248                 data32 = data;
1249                 cmd = CIOCCRYPTAEAD;
1250                 data = (void *)&thunk.aeadc;
1251                 crypt_aead_from_32((struct crypt_aead32 *)data32, &thunk.aeadc);
1252                 break;
1253         }
1254 #endif
1255
1256         devfs_get_cdevpriv((void **)&fcr);
1257
1258         switch (cmd) {
1259 #ifdef COMPAT_FREEBSD12
1260         case CRIOGET:
1261                 /*
1262                  * NB: This may fail in cases that the old
1263                  * implementation did not if the current process has
1264                  * restricted filesystem access (e.g. running in a
1265                  * jail that does not expose /dev/crypto or in
1266                  * capability mode).
1267                  */
1268                 error = kern_openat(td, AT_FDCWD, "/dev/crypto", UIO_SYSSPACE,
1269                     O_RDWR, 0);
1270                 if (error == 0)
1271                         *(uint32_t *)data = td->td_retval[0];
1272                 break;
1273 #endif
1274         case CIOCGSESSION:
1275         case CIOCGSESSION2:
1276                 if (cmd == CIOCGSESSION) {
1277                         session2_op_from_op((void *)data, &thunk.sopc);
1278                         sop = &thunk.sopc;
1279                 } else
1280                         sop = (struct session2_op *)data;
1281
1282                 error = cse_create(fcr, sop);
1283                 if (cmd == CIOCGSESSION && error == 0)
1284                         session2_op_to_op(sop, (void *)data);
1285                 break;
1286         case CIOCFSESSION:
1287                 ses = *(uint32_t *)data;
1288                 if (!cse_delete(fcr, ses)) {
1289                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1290                         return (EINVAL);
1291                 }
1292                 break;
1293         case CIOCCRYPT:
1294                 cop = (struct crypt_op *)data;
1295                 cse = cse_find(fcr, cop->ses);
1296                 if (cse == NULL) {
1297                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1298                         return (EINVAL);
1299                 }
1300                 error = cryptodev_op(cse, cop);
1301                 cse_free(cse);
1302                 break;
1303         case CIOCFINDDEV:
1304                 error = cryptodev_find((struct crypt_find_op *)data);
1305                 break;
1306         case CIOCCRYPTAEAD:
1307                 caead = (struct crypt_aead *)data;
1308                 cse = cse_find(fcr, caead->ses);
1309                 if (cse == NULL) {
1310                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1311                         return (EINVAL);
1312                 }
1313                 error = cryptodev_aead(cse, caead);
1314                 cse_free(cse);
1315                 break;
1316         default:
1317                 error = EINVAL;
1318                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1319                 break;
1320         }
1321
1322 #ifdef COMPAT_FREEBSD32
1323         switch (cmd32) {
1324         case CIOCGSESSION32:
1325                 if (error == 0)
1326                         session_op_to_32((void *)data, data32);
1327                 break;
1328         case CIOCGSESSION232:
1329                 if (error == 0)
1330                         session2_op_to_32((void *)data, data32);
1331                 break;
1332         case CIOCCRYPT32:
1333                 if (error == 0)
1334                         crypt_op_to_32((void *)data, data32);
1335                 break;
1336         case CIOCCRYPTAEAD32:
1337                 if (error == 0)
1338                         crypt_aead_to_32((void *)data, data32);
1339                 break;
1340         }
1341 #endif
1342         return (error);
1343 }
1344
1345 static struct cdevsw crypto_cdevsw = {
1346         .d_version =    D_VERSION,
1347         .d_open =       crypto_open,
1348         .d_ioctl =      crypto_ioctl,
1349         .d_name =       "crypto",
1350 };
1351 static struct cdev *crypto_dev;
1352
1353 /*
1354  * Initialization code, both for static and dynamic loading.
1355  */
1356 static int
1357 cryptodev_modevent(module_t mod, int type, void *unused)
1358 {
1359         switch (type) {
1360         case MOD_LOAD:
1361                 if (bootverbose)
1362                         printf("crypto: <crypto device>\n");
1363                 crypto_dev = make_dev(&crypto_cdevsw, 0, 
1364                                       UID_ROOT, GID_WHEEL, 0666,
1365                                       "crypto");
1366                 return 0;
1367         case MOD_UNLOAD:
1368                 /*XXX disallow if active sessions */
1369                 destroy_dev(crypto_dev);
1370                 return 0;
1371         }
1372         return EINVAL;
1373 }
1374
1375 static moduledata_t cryptodev_mod = {
1376         "cryptodev",
1377         cryptodev_modevent,
1378         0
1379 };
1380 MODULE_VERSION(cryptodev, 1);
1381 DECLARE_MODULE(cryptodev, cryptodev_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
1382 MODULE_DEPEND(cryptodev, crypto, 1, 1, 1);
1383 MODULE_DEPEND(cryptodev, zlib, 1, 1, 1);