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