]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/opencrypto/cryptodev.c
vmm: fix set but not used warnings
[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 struct crparam32 {
136         uint32_t        crp_p;
137         u_int           crp_nbits;
138 };
139
140 struct crypt_kop32 {
141         u_int           crk_op;
142         u_int           crk_status;
143         u_short         crk_iparams;
144         u_short         crk_oparams;
145         u_int           crk_crid;
146         struct crparam32        crk_param[CRK_MAXPARAM];
147 };
148
149 #define CIOCGSESSION32  _IOWR('c', 101, struct session_op32)
150 #define CIOCCRYPT32     _IOWR('c', 103, struct crypt_op32)
151 #define CIOCKEY32       _IOWR('c', 104, struct crypt_kop32)
152 #define CIOCGSESSION232 _IOWR('c', 106, struct session2_op32)
153 #define CIOCKEY232      _IOWR('c', 107, struct crypt_kop32)
154 #define CIOCCRYPTAEAD32 _IOWR('c', 109, struct crypt_aead32)
155
156 static void
157 session_op_from_32(const struct session_op32 *from, struct session2_op *to)
158 {
159
160         memset(to, 0, sizeof(*to));
161         CP(*from, *to, cipher);
162         CP(*from, *to, mac);
163         CP(*from, *to, keylen);
164         PTRIN_CP(*from, *to, key);
165         CP(*from, *to, mackeylen);
166         PTRIN_CP(*from, *to, mackey);
167         CP(*from, *to, ses);
168         to->crid = CRYPTOCAP_F_HARDWARE;
169 }
170
171 static void
172 session2_op_from_32(const struct session2_op32 *from, struct session2_op *to)
173 {
174
175         session_op_from_32((const struct session_op32 *)from, to);
176         CP(*from, *to, crid);
177         CP(*from, *to, ivlen);
178         CP(*from, *to, maclen);
179 }
180
181 static void
182 session_op_to_32(const struct session2_op *from, struct session_op32 *to)
183 {
184
185         CP(*from, *to, cipher);
186         CP(*from, *to, mac);
187         CP(*from, *to, keylen);
188         PTROUT_CP(*from, *to, key);
189         CP(*from, *to, mackeylen);
190         PTROUT_CP(*from, *to, mackey);
191         CP(*from, *to, ses);
192 }
193
194 static void
195 session2_op_to_32(const struct session2_op *from, struct session2_op32 *to)
196 {
197
198         session_op_to_32(from, (struct session_op32 *)to);
199         CP(*from, *to, crid);
200 }
201
202 static void
203 crypt_op_from_32(const struct crypt_op32 *from, struct crypt_op *to)
204 {
205
206         CP(*from, *to, ses);
207         CP(*from, *to, op);
208         CP(*from, *to, flags);
209         CP(*from, *to, len);
210         PTRIN_CP(*from, *to, src);
211         PTRIN_CP(*from, *to, dst);
212         PTRIN_CP(*from, *to, mac);
213         PTRIN_CP(*from, *to, iv);
214 }
215
216 static void
217 crypt_op_to_32(const struct crypt_op *from, struct crypt_op32 *to)
218 {
219
220         CP(*from, *to, ses);
221         CP(*from, *to, op);
222         CP(*from, *to, flags);
223         CP(*from, *to, len);
224         PTROUT_CP(*from, *to, src);
225         PTROUT_CP(*from, *to, dst);
226         PTROUT_CP(*from, *to, mac);
227         PTROUT_CP(*from, *to, iv);
228 }
229
230 static void
231 crypt_aead_from_32(const struct crypt_aead32 *from, struct crypt_aead *to)
232 {
233
234         CP(*from, *to, ses);
235         CP(*from, *to, op);
236         CP(*from, *to, flags);
237         CP(*from, *to, len);
238         CP(*from, *to, aadlen);
239         CP(*from, *to, ivlen);
240         PTRIN_CP(*from, *to, src);
241         PTRIN_CP(*from, *to, dst);
242         PTRIN_CP(*from, *to, aad);
243         PTRIN_CP(*from, *to, tag);
244         PTRIN_CP(*from, *to, iv);
245 }
246
247 static void
248 crypt_aead_to_32(const struct crypt_aead *from, struct crypt_aead32 *to)
249 {
250
251         CP(*from, *to, ses);
252         CP(*from, *to, op);
253         CP(*from, *to, flags);
254         CP(*from, *to, len);
255         CP(*from, *to, aadlen);
256         CP(*from, *to, ivlen);
257         PTROUT_CP(*from, *to, src);
258         PTROUT_CP(*from, *to, dst);
259         PTROUT_CP(*from, *to, aad);
260         PTROUT_CP(*from, *to, tag);
261         PTROUT_CP(*from, *to, iv);
262 }
263
264 static void
265 crparam_from_32(const struct crparam32 *from, struct crparam *to)
266 {
267
268         PTRIN_CP(*from, *to, crp_p);
269         CP(*from, *to, crp_nbits);
270 }
271
272 static void
273 crparam_to_32(const struct crparam *from, struct crparam32 *to)
274 {
275
276         PTROUT_CP(*from, *to, crp_p);
277         CP(*from, *to, crp_nbits);
278 }
279
280 static void
281 crypt_kop_from_32(const struct crypt_kop32 *from, struct crypt_kop *to)
282 {
283         int i;
284
285         CP(*from, *to, crk_op);
286         CP(*from, *to, crk_status);
287         CP(*from, *to, crk_iparams);
288         CP(*from, *to, crk_oparams);
289         CP(*from, *to, crk_crid);
290         for (i = 0; i < CRK_MAXPARAM; i++)
291                 crparam_from_32(&from->crk_param[i], &to->crk_param[i]);
292 }
293
294 static void
295 crypt_kop_to_32(const struct crypt_kop *from, struct crypt_kop32 *to)
296 {
297         int i;
298
299         CP(*from, *to, crk_op);
300         CP(*from, *to, crk_status);
301         CP(*from, *to, crk_iparams);
302         CP(*from, *to, crk_oparams);
303         CP(*from, *to, crk_crid);
304         for (i = 0; i < CRK_MAXPARAM; i++)
305                 crparam_to_32(&from->crk_param[i], &to->crk_param[i]);
306 }
307 #endif
308
309 static void
310 session2_op_from_op(const struct session_op *from, struct session2_op *to)
311 {
312
313         memset(to, 0, sizeof(*to));
314         memcpy(to, from, sizeof(*from));
315         to->crid = CRYPTOCAP_F_HARDWARE;
316 }
317
318 static void
319 session2_op_to_op(const struct session2_op *from, struct session_op *to)
320 {
321
322         memcpy(to, from, sizeof(*to));
323 }
324
325 struct csession {
326         TAILQ_ENTRY(csession) next;
327         crypto_session_t cses;
328         volatile u_int  refs;
329         uint32_t        ses;
330         struct mtx      lock;           /* for op submission */
331
332         struct enc_xform *txform;
333         int             hashsize;
334         int             ivsize;
335
336         void            *key;
337         void            *mackey;
338 };
339
340 struct cryptop_data {
341         struct csession *cse;
342
343         char            *buf;
344         char            *obuf;
345         char            *aad;
346         bool            done;
347 };
348
349 struct fcrypt {
350         TAILQ_HEAD(csessionlist, csession) csessions;
351         int             sesn;
352         struct mtx      lock;
353 };
354
355 static bool use_outputbuffers;
356 SYSCTL_BOOL(_kern_crypto, OID_AUTO, cryptodev_use_output, CTLFLAG_RW,
357     &use_outputbuffers, 0,
358     "Use separate output buffers for /dev/crypto requests.");
359
360 static bool use_separate_aad;
361 SYSCTL_BOOL(_kern_crypto, OID_AUTO, cryptodev_separate_aad, CTLFLAG_RW,
362     &use_separate_aad, 0,
363     "Use separate AAD buffer for /dev/crypto requests.");
364
365 static struct timeval warninterval = { .tv_sec = 60, .tv_usec = 0 };
366 SYSCTL_TIMEVAL_SEC(_kern, OID_AUTO, cryptodev_warn_interval, CTLFLAG_RW,
367     &warninterval,
368     "Delay in seconds between warnings of deprecated /dev/crypto algorithms");
369
370 static MALLOC_DEFINE(M_CRYPTODEV, "cryptodev", "/dev/crypto data buffers");
371
372 /*
373  * Check a crypto identifier to see if it requested
374  * a software device/driver.  This can be done either
375  * by device name/class or through search constraints.
376  */
377 static int
378 checkforsoftware(int *cridp)
379 {
380         int crid;
381
382         crid = *cridp;
383
384         if (!crypto_devallowsoft) {
385                 if (crid & CRYPTOCAP_F_SOFTWARE) {
386                         if (crid & CRYPTOCAP_F_HARDWARE) {
387                                 *cridp = CRYPTOCAP_F_HARDWARE;
388                                 return 0;
389                         }
390                         return EINVAL;
391                 }
392                 if ((crid & CRYPTOCAP_F_HARDWARE) == 0 &&
393                     (crypto_getcaps(crid) & CRYPTOCAP_F_HARDWARE) == 0)
394                         return EINVAL;
395         }
396         return 0;
397 }
398
399 static int
400 cse_create(struct fcrypt *fcr, struct session2_op *sop)
401 {
402         struct crypto_session_params csp;
403         struct csession *cse;
404         struct enc_xform *txform;
405         struct auth_hash *thash;
406         void *key = NULL;
407         void *mackey = NULL;
408         crypto_session_t cses;
409         int crid, error;
410
411         switch (sop->cipher) {
412         case 0:
413                 txform = NULL;
414                 break;
415         case CRYPTO_AES_CBC:
416                 txform = &enc_xform_rijndael128;
417                 break;
418         case CRYPTO_AES_XTS:
419                 txform = &enc_xform_aes_xts;
420                 break;
421         case CRYPTO_NULL_CBC:
422                 txform = &enc_xform_null;
423                 break;
424         case CRYPTO_CAMELLIA_CBC:
425                 txform = &enc_xform_camellia;
426                 break;
427         case CRYPTO_AES_ICM:
428                 txform = &enc_xform_aes_icm;
429                 break;
430         case CRYPTO_AES_NIST_GCM_16:
431                 txform = &enc_xform_aes_nist_gcm;
432                 break;
433         case CRYPTO_CHACHA20:
434                 txform = &enc_xform_chacha20;
435                 break;
436         case CRYPTO_AES_CCM_16:
437                 txform = &enc_xform_ccm;
438                 break;
439         case CRYPTO_CHACHA20_POLY1305:
440                 txform = &enc_xform_chacha20_poly1305;
441                 break;
442         default:
443                 CRYPTDEB("invalid cipher");
444                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
445                 return (EINVAL);
446         }
447
448         switch (sop->mac) {
449         case 0:
450                 thash = NULL;
451                 break;
452         case CRYPTO_POLY1305:
453                 thash = &auth_hash_poly1305;
454                 break;
455         case CRYPTO_SHA1_HMAC:
456                 thash = &auth_hash_hmac_sha1;
457                 break;
458         case CRYPTO_SHA2_224_HMAC:
459                 thash = &auth_hash_hmac_sha2_224;
460                 break;
461         case CRYPTO_SHA2_256_HMAC:
462                 thash = &auth_hash_hmac_sha2_256;
463                 break;
464         case CRYPTO_SHA2_384_HMAC:
465                 thash = &auth_hash_hmac_sha2_384;
466                 break;
467         case CRYPTO_SHA2_512_HMAC:
468                 thash = &auth_hash_hmac_sha2_512;
469                 break;
470         case CRYPTO_RIPEMD160_HMAC:
471                 thash = &auth_hash_hmac_ripemd_160;
472                 break;
473 #ifdef COMPAT_FREEBSD12
474         case CRYPTO_AES_128_NIST_GMAC:
475         case CRYPTO_AES_192_NIST_GMAC:
476         case CRYPTO_AES_256_NIST_GMAC:
477                 /* Should always be paired with GCM. */
478                 if (sop->cipher != CRYPTO_AES_NIST_GCM_16) {
479                         CRYPTDEB("GMAC without GCM");
480                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
481                         return (EINVAL);
482                 }
483                 break;
484 #endif
485         case CRYPTO_AES_NIST_GMAC:
486                 switch (sop->mackeylen * 8) {
487                 case 128:
488                         thash = &auth_hash_nist_gmac_aes_128;
489                         break;
490                 case 192:
491                         thash = &auth_hash_nist_gmac_aes_192;
492                         break;
493                 case 256:
494                         thash = &auth_hash_nist_gmac_aes_256;
495                         break;
496                 default:
497                         CRYPTDEB("invalid GMAC key length");
498                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
499                         return (EINVAL);
500                 }
501                 break;
502         case CRYPTO_AES_CCM_CBC_MAC:
503                 switch (sop->mackeylen) {
504                 case 16:
505                         thash = &auth_hash_ccm_cbc_mac_128;
506                         break;
507                 case 24:
508                         thash = &auth_hash_ccm_cbc_mac_192;
509                         break;
510                 case 32:
511                         thash = &auth_hash_ccm_cbc_mac_256;
512                         break;
513                 default:
514                         CRYPTDEB("Invalid CBC MAC key size %d", sop->keylen);
515                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
516                         return (EINVAL);
517                 }
518                 break;
519         case CRYPTO_SHA1:
520                 thash = &auth_hash_sha1;
521                 break;
522         case CRYPTO_SHA2_224:
523                 thash = &auth_hash_sha2_224;
524                 break;
525         case CRYPTO_SHA2_256:
526                 thash = &auth_hash_sha2_256;
527                 break;
528         case CRYPTO_SHA2_384:
529                 thash = &auth_hash_sha2_384;
530                 break;
531         case CRYPTO_SHA2_512:
532                 thash = &auth_hash_sha2_512;
533                 break;
534
535         case CRYPTO_NULL_HMAC:
536                 thash = &auth_hash_null;
537                 break;
538
539         case CRYPTO_BLAKE2B:
540                 thash = &auth_hash_blake2b;
541                 break;
542         case CRYPTO_BLAKE2S:
543                 thash = &auth_hash_blake2s;
544                 break;
545
546         default:
547                 CRYPTDEB("invalid mac");
548                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
549                 return (EINVAL);
550         }
551
552         if (txform == NULL && thash == NULL) {
553                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
554                 return (EINVAL);
555         }
556
557         memset(&csp, 0, sizeof(csp));
558         if (use_outputbuffers)
559                 csp.csp_flags |= CSP_F_SEPARATE_OUTPUT;
560
561         if (sop->cipher == CRYPTO_AES_NIST_GCM_16) {
562                 switch (sop->mac) {
563 #ifdef COMPAT_FREEBSD12
564                 case CRYPTO_AES_128_NIST_GMAC:
565                 case CRYPTO_AES_192_NIST_GMAC:
566                 case CRYPTO_AES_256_NIST_GMAC:
567                         if (sop->keylen != sop->mackeylen) {
568                                 SDT_PROBE1(opencrypto, dev, ioctl, error,
569                                     __LINE__);
570                                 return (EINVAL);
571                         }
572                         break;
573 #endif
574                 case 0:
575                         break;
576                 default:
577                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
578                         return (EINVAL);
579                 }
580                 csp.csp_mode = CSP_MODE_AEAD;
581         } else if (sop->cipher == CRYPTO_AES_CCM_16) {
582                 switch (sop->mac) {
583 #ifdef COMPAT_FREEBSD12
584                 case CRYPTO_AES_CCM_CBC_MAC:
585                         if (sop->keylen != sop->mackeylen) {
586                                 SDT_PROBE1(opencrypto, dev, ioctl, error,
587                                     __LINE__);
588                                 return (EINVAL);
589                         }
590                         thash = NULL;
591                         break;
592 #endif
593                 case 0:
594                         break;
595                 default:
596                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
597                         return (EINVAL);
598                 }
599                 csp.csp_mode = CSP_MODE_AEAD;
600         } else if (sop->cipher == CRYPTO_CHACHA20_POLY1305) {
601                 if (sop->mac != 0) {
602                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
603                         return (EINVAL);
604                 }
605                 csp.csp_mode = CSP_MODE_AEAD;
606         } else if (txform != NULL && thash != NULL)
607                 csp.csp_mode = CSP_MODE_ETA;
608         else if (txform != NULL)
609                 csp.csp_mode = CSP_MODE_CIPHER;
610         else
611                 csp.csp_mode = CSP_MODE_DIGEST;
612
613         switch (csp.csp_mode) {
614         case CSP_MODE_AEAD:
615         case CSP_MODE_ETA:
616                 if (use_separate_aad)
617                         csp.csp_flags |= CSP_F_SEPARATE_AAD;
618                 break;
619         }
620
621         if (txform != NULL) {
622                 csp.csp_cipher_alg = txform->type;
623                 csp.csp_cipher_klen = sop->keylen;
624                 if (sop->keylen > txform->maxkey ||
625                     sop->keylen < txform->minkey) {
626                         CRYPTDEB("invalid cipher parameters");
627                         error = EINVAL;
628                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
629                         goto bail;
630                 }
631
632                 key = malloc(csp.csp_cipher_klen, M_CRYPTODEV, M_WAITOK);
633                 error = copyin(sop->key, key, csp.csp_cipher_klen);
634                 if (error) {
635                         CRYPTDEB("invalid key");
636                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
637                         goto bail;
638                 }
639                 csp.csp_cipher_key = key;
640                 csp.csp_ivlen = txform->ivsize;
641         }
642
643         if (thash != NULL) {
644                 csp.csp_auth_alg = thash->type;
645                 csp.csp_auth_klen = sop->mackeylen;
646                 if (sop->mackeylen > thash->keysize || sop->mackeylen < 0) {
647                         CRYPTDEB("invalid mac key length");
648                         error = EINVAL;
649                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
650                         goto bail;
651                 }
652
653                 if (csp.csp_auth_klen != 0) {
654                         mackey = malloc(csp.csp_auth_klen, M_CRYPTODEV,
655                             M_WAITOK);
656                         error = copyin(sop->mackey, mackey, csp.csp_auth_klen);
657                         if (error) {
658                                 CRYPTDEB("invalid mac key");
659                                 SDT_PROBE1(opencrypto, dev, ioctl, error,
660                                     __LINE__);
661                                 goto bail;
662                         }
663                         csp.csp_auth_key = mackey;
664                 }
665
666                 if (csp.csp_auth_alg == CRYPTO_AES_NIST_GMAC)
667                         csp.csp_ivlen = AES_GCM_IV_LEN;
668                 if (csp.csp_auth_alg == CRYPTO_AES_CCM_CBC_MAC)
669                         csp.csp_ivlen = AES_CCM_IV_LEN;
670         }
671
672         if (sop->ivlen != 0) {
673                 if (csp.csp_ivlen == 0) {
674                         CRYPTDEB("does not support an IV");
675                         error = EINVAL;
676                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
677                         goto bail;
678                 }
679                 csp.csp_ivlen = sop->ivlen;
680         }
681         if (sop->maclen != 0) {
682                 if (!(thash != NULL || csp.csp_mode == CSP_MODE_AEAD)) {
683                         CRYPTDEB("does not support a MAC");
684                         error = EINVAL;
685                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
686                         goto bail;
687                 }
688                 csp.csp_auth_mlen = sop->maclen;
689         }
690
691         crid = sop->crid;
692         error = checkforsoftware(&crid);
693         if (error) {
694                 CRYPTDEB("checkforsoftware");
695                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
696                 goto bail;
697         }
698         error = crypto_newsession(&cses, &csp, crid);
699         if (error) {
700                 CRYPTDEB("crypto_newsession");
701                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
702                 goto bail;
703         }
704
705         cse = malloc(sizeof(struct csession), M_CRYPTODEV, M_WAITOK | M_ZERO);
706         mtx_init(&cse->lock, "cryptodev", "crypto session lock", MTX_DEF);
707         refcount_init(&cse->refs, 1);
708         cse->key = key;
709         cse->mackey = mackey;
710         cse->cses = cses;
711         cse->txform = txform;
712         if (sop->maclen != 0)
713                 cse->hashsize = sop->maclen;
714         else if (thash != NULL)
715                 cse->hashsize = thash->hashsize;
716         else if (csp.csp_cipher_alg == CRYPTO_AES_NIST_GCM_16)
717                 cse->hashsize = AES_GMAC_HASH_LEN;
718         else if (csp.csp_cipher_alg == CRYPTO_AES_CCM_16)
719                 cse->hashsize = AES_CBC_MAC_HASH_LEN;
720         else if (csp.csp_cipher_alg == CRYPTO_CHACHA20_POLY1305)
721                 cse->hashsize = POLY1305_HASH_LEN;
722         cse->ivsize = csp.csp_ivlen;
723
724         mtx_lock(&fcr->lock);
725         TAILQ_INSERT_TAIL(&fcr->csessions, cse, next);
726         cse->ses = fcr->sesn++;
727         mtx_unlock(&fcr->lock);
728
729         sop->ses = cse->ses;
730
731         /* return hardware/driver id */
732         sop->crid = crypto_ses2hid(cse->cses);
733 bail:
734         if (error) {
735                 free(key, M_CRYPTODEV);
736                 free(mackey, M_CRYPTODEV);
737         }
738         return (error);
739 }
740
741 static struct csession *
742 cse_find(struct fcrypt *fcr, u_int ses)
743 {
744         struct csession *cse;
745
746         mtx_lock(&fcr->lock);
747         TAILQ_FOREACH(cse, &fcr->csessions, next) {
748                 if (cse->ses == ses) {
749                         refcount_acquire(&cse->refs);
750                         mtx_unlock(&fcr->lock);
751                         return (cse);
752                 }
753         }
754         mtx_unlock(&fcr->lock);
755         return (NULL);
756 }
757
758 static void
759 cse_free(struct csession *cse)
760 {
761
762         if (!refcount_release(&cse->refs))
763                 return;
764         crypto_freesession(cse->cses);
765         mtx_destroy(&cse->lock);
766         if (cse->key)
767                 free(cse->key, M_CRYPTODEV);
768         if (cse->mackey)
769                 free(cse->mackey, M_CRYPTODEV);
770         free(cse, M_CRYPTODEV);
771 }
772
773 static bool
774 cse_delete(struct fcrypt *fcr, u_int ses)
775 {
776         struct csession *cse;
777
778         mtx_lock(&fcr->lock);
779         TAILQ_FOREACH(cse, &fcr->csessions, next) {
780                 if (cse->ses == ses) {
781                         TAILQ_REMOVE(&fcr->csessions, cse, next);
782                         mtx_unlock(&fcr->lock);
783                         cse_free(cse);
784                         return (true);
785                 }
786         }
787         mtx_unlock(&fcr->lock);
788         return (false);
789 }
790
791 static struct cryptop_data *
792 cod_alloc(struct csession *cse, size_t aad_len, size_t len)
793 {
794         struct cryptop_data *cod;
795
796         cod = malloc(sizeof(struct cryptop_data), M_CRYPTODEV, M_WAITOK |
797             M_ZERO);
798
799         cod->cse = cse;
800         if (crypto_get_params(cse->cses)->csp_flags & CSP_F_SEPARATE_AAD) {
801                 if (aad_len != 0)
802                         cod->aad = malloc(aad_len, M_CRYPTODEV, M_WAITOK);
803                 cod->buf = malloc(len, M_CRYPTODEV, M_WAITOK);
804         } else
805                 cod->buf = malloc(aad_len + len, M_CRYPTODEV, M_WAITOK);
806         if (crypto_get_params(cse->cses)->csp_flags & CSP_F_SEPARATE_OUTPUT)
807                 cod->obuf = malloc(len, M_CRYPTODEV, M_WAITOK);
808         return (cod);
809 }
810
811 static void
812 cod_free(struct cryptop_data *cod)
813 {
814
815         free(cod->aad, M_CRYPTODEV);
816         free(cod->obuf, M_CRYPTODEV);
817         free(cod->buf, M_CRYPTODEV);
818         free(cod, M_CRYPTODEV);
819 }
820
821 static int
822 cryptodev_cb(struct cryptop *crp)
823 {
824         struct cryptop_data *cod = crp->crp_opaque;
825
826         /*
827          * Lock to ensure the wakeup() is not missed by the loops
828          * waiting on cod->done in cryptodev_op() and
829          * cryptodev_aead().
830          */
831         mtx_lock(&cod->cse->lock);
832         cod->done = true;
833         mtx_unlock(&cod->cse->lock);
834         wakeup(cod);
835         return (0);
836 }
837
838 static int
839 cryptodev_op(struct csession *cse, const struct crypt_op *cop)
840 {
841         const struct crypto_session_params *csp;
842         struct cryptop_data *cod = NULL;
843         struct cryptop *crp = NULL;
844         char *dst;
845         int error;
846
847         if (cop->len > 256*1024-4) {
848                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
849                 return (E2BIG);
850         }
851
852         if (cse->txform) {
853                 if ((cop->len % cse->txform->blocksize) != 0) {
854                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
855                         return (EINVAL);
856                 }
857         }
858
859         if (cop->mac && cse->hashsize == 0) {
860                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
861                 return (EINVAL);
862         }
863
864         /*
865          * The COP_F_CIPHER_FIRST flag predates explicit session
866          * modes, but the only way it was used was for EtA so allow it
867          * as long as it is consistent with EtA.
868          */
869         if (cop->flags & COP_F_CIPHER_FIRST) {
870                 if (cop->op != COP_ENCRYPT) {
871                         SDT_PROBE1(opencrypto, dev, ioctl, error,  __LINE__);
872                         return (EINVAL);
873                 }
874         }
875
876         cod = cod_alloc(cse, 0, cop->len + cse->hashsize);
877         dst = cop->dst;
878
879         crp = crypto_getreq(cse->cses, M_WAITOK);
880
881         error = copyin(cop->src, cod->buf, cop->len);
882         if (error) {
883                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
884                 goto bail;
885         }
886         crp->crp_payload_start = 0;
887         crp->crp_payload_length = cop->len;
888         if (cse->hashsize)
889                 crp->crp_digest_start = cop->len;
890
891         csp = crypto_get_params(cse->cses);
892         switch (csp->csp_mode) {
893         case CSP_MODE_COMPRESS:
894                 switch (cop->op) {
895                 case COP_ENCRYPT:
896                         crp->crp_op = CRYPTO_OP_COMPRESS;
897                         break;
898                 case COP_DECRYPT:
899                         crp->crp_op = CRYPTO_OP_DECOMPRESS;
900                         break;
901                 default:
902                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
903                         error = EINVAL;
904                         goto bail;
905                 }
906                 break;
907         case CSP_MODE_CIPHER:
908                 if (cop->len == 0 ||
909                     (cop->iv == NULL && cop->len == cse->ivsize)) {
910                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
911                         error = EINVAL;
912                         goto bail;
913                 }
914                 switch (cop->op) {
915                 case COP_ENCRYPT:
916                         crp->crp_op = CRYPTO_OP_ENCRYPT;
917                         break;
918                 case COP_DECRYPT:
919                         crp->crp_op = CRYPTO_OP_DECRYPT;
920                         break;
921                 default:
922                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
923                         error = EINVAL;
924                         goto bail;
925                 }
926                 break;
927         case CSP_MODE_DIGEST:
928                 switch (cop->op) {
929                 case 0:
930                 case COP_ENCRYPT:
931                 case COP_DECRYPT:
932                         crp->crp_op = CRYPTO_OP_COMPUTE_DIGEST;
933                         if (cod->obuf != NULL)
934                                 crp->crp_digest_start = 0;
935                         break;
936                 default:
937                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
938                         error = EINVAL;
939                         goto bail;
940                 }
941                 break;
942         case CSP_MODE_AEAD:
943                 if (cse->ivsize != 0 && cop->iv == NULL) {
944                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
945                         error = EINVAL;
946                         goto bail;
947                 }
948                 /* FALLTHROUGH */
949         case CSP_MODE_ETA:
950                 switch (cop->op) {
951                 case COP_ENCRYPT:
952                         crp->crp_op = CRYPTO_OP_ENCRYPT |
953                             CRYPTO_OP_COMPUTE_DIGEST;
954                         break;
955                 case COP_DECRYPT:
956                         crp->crp_op = CRYPTO_OP_DECRYPT |
957                             CRYPTO_OP_VERIFY_DIGEST;
958                         break;
959                 default:
960                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
961                         error = EINVAL;
962                         goto bail;
963                 }
964                 break;
965         default:
966                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
967                 error = EINVAL;
968                 goto bail;
969         }
970
971         crp->crp_flags = CRYPTO_F_CBIMM | (cop->flags & COP_F_BATCH);
972         crypto_use_buf(crp, cod->buf, cop->len + cse->hashsize);
973         if (cod->obuf)
974                 crypto_use_output_buf(crp, cod->obuf, cop->len + cse->hashsize);
975         crp->crp_callback = cryptodev_cb;
976         crp->crp_opaque = cod;
977
978         if (cop->iv) {
979                 if (cse->ivsize == 0) {
980                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
981                         error = EINVAL;
982                         goto bail;
983                 }
984                 error = copyin(cop->iv, crp->crp_iv, cse->ivsize);
985                 if (error) {
986                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
987                         goto bail;
988                 }
989                 crp->crp_flags |= CRYPTO_F_IV_SEPARATE;
990         } else if (cse->ivsize != 0) {
991                 if (crp->crp_payload_length < cse->ivsize) {
992                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
993                         error = EINVAL;
994                         goto bail;
995                 }
996                 crp->crp_iv_start = 0;
997                 crp->crp_payload_length -= cse->ivsize;
998                 if (crp->crp_payload_length != 0)
999                         crp->crp_payload_start = cse->ivsize;
1000                 dst += cse->ivsize;
1001         }
1002
1003         if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
1004                 error = copyin(cop->mac, cod->buf + crp->crp_digest_start,
1005                     cse->hashsize);
1006                 if (error) {
1007                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1008                         goto bail;
1009                 }
1010         }
1011 again:
1012         /*
1013          * Let the dispatch run unlocked, then, interlock against the
1014          * callback before checking if the operation completed and going
1015          * to sleep.  This insures drivers don't inherit our lock which
1016          * results in a lock order reversal between crypto_dispatch forced
1017          * entry and the crypto_done callback into us.
1018          */
1019         error = crypto_dispatch(crp);
1020         if (error != 0) {
1021                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1022                 goto bail;
1023         }
1024
1025         mtx_lock(&cse->lock);
1026         while (!cod->done)
1027                 mtx_sleep(cod, &cse->lock, PWAIT, "crydev", 0);
1028         mtx_unlock(&cse->lock);
1029
1030         if (crp->crp_etype == EAGAIN) {
1031                 crp->crp_etype = 0;
1032                 crp->crp_flags &= ~CRYPTO_F_DONE;
1033                 cod->done = false;
1034                 goto again;
1035         }
1036
1037         if (crp->crp_etype != 0) {
1038                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1039                 error = crp->crp_etype;
1040                 goto bail;
1041         }
1042
1043         if (cop->dst != NULL) {
1044                 error = copyout(cod->obuf != NULL ? cod->obuf :
1045                     cod->buf + crp->crp_payload_start, dst,
1046                     crp->crp_payload_length);
1047                 if (error) {
1048                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1049                         goto bail;
1050                 }
1051         }
1052
1053         if (cop->mac != NULL && (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) == 0) {
1054                 error = copyout((cod->obuf != NULL ? cod->obuf : cod->buf) +
1055                     crp->crp_digest_start, cop->mac, cse->hashsize);
1056                 if (error) {
1057                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1058                         goto bail;
1059                 }
1060         }
1061
1062 bail:
1063         crypto_freereq(crp);
1064         cod_free(cod);
1065
1066         return (error);
1067 }
1068
1069 static int
1070 cryptodev_aead(struct csession *cse, struct crypt_aead *caead)
1071 {
1072         const struct crypto_session_params *csp;
1073         struct cryptop_data *cod = NULL;
1074         struct cryptop *crp = NULL;
1075         char *dst;
1076         int error;
1077
1078         if (caead->len > 256*1024-4 || caead->aadlen > 256*1024-4) {
1079                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1080                 return (E2BIG);
1081         }
1082
1083         if (cse->txform == NULL || cse->hashsize == 0 || caead->tag == NULL ||
1084             (caead->len % cse->txform->blocksize) != 0) {
1085                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1086                 return (EINVAL);
1087         }
1088
1089         /*
1090          * The COP_F_CIPHER_FIRST flag predates explicit session
1091          * modes, but the only way it was used was for EtA so allow it
1092          * as long as it is consistent with EtA.
1093          */
1094         if (caead->flags & COP_F_CIPHER_FIRST) {
1095                 if (caead->op != COP_ENCRYPT) {
1096                         SDT_PROBE1(opencrypto, dev, ioctl, error,  __LINE__);
1097                         return (EINVAL);
1098                 }
1099         }
1100
1101         cod = cod_alloc(cse, caead->aadlen, caead->len + cse->hashsize);
1102         dst = caead->dst;
1103
1104         crp = crypto_getreq(cse->cses, M_WAITOK);
1105
1106         if (cod->aad != NULL)
1107                 error = copyin(caead->aad, cod->aad, caead->aadlen);
1108         else
1109                 error = copyin(caead->aad, cod->buf, caead->aadlen);
1110         if (error) {
1111                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1112                 goto bail;
1113         }
1114         crp->crp_aad = cod->aad;
1115         crp->crp_aad_start = 0;
1116         crp->crp_aad_length = caead->aadlen;
1117
1118         if (cod->aad != NULL)
1119                 crp->crp_payload_start = 0;
1120         else
1121                 crp->crp_payload_start = caead->aadlen;
1122         error = copyin(caead->src, cod->buf + crp->crp_payload_start,
1123             caead->len);
1124         if (error) {
1125                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1126                 goto bail;
1127         }
1128         crp->crp_payload_length = caead->len;
1129         if (caead->op == COP_ENCRYPT && cod->obuf != NULL)
1130                 crp->crp_digest_start = crp->crp_payload_output_start +
1131                     caead->len;
1132         else
1133                 crp->crp_digest_start = crp->crp_payload_start + caead->len;
1134
1135         csp = crypto_get_params(cse->cses);
1136         switch (csp->csp_mode) {
1137         case CSP_MODE_AEAD:
1138         case CSP_MODE_ETA:
1139                 switch (caead->op) {
1140                 case COP_ENCRYPT:
1141                         crp->crp_op = CRYPTO_OP_ENCRYPT |
1142                             CRYPTO_OP_COMPUTE_DIGEST;
1143                         break;
1144                 case COP_DECRYPT:
1145                         crp->crp_op = CRYPTO_OP_DECRYPT |
1146                             CRYPTO_OP_VERIFY_DIGEST;
1147                         break;
1148                 default:
1149                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1150                         error = EINVAL;
1151                         goto bail;
1152                 }
1153                 break;
1154         default:
1155                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1156                 error = EINVAL;
1157                 goto bail;
1158         }
1159
1160         crp->crp_flags = CRYPTO_F_CBIMM | (caead->flags & COP_F_BATCH);
1161         crypto_use_buf(crp, cod->buf, crp->crp_payload_start + caead->len +
1162             cse->hashsize);
1163         if (cod->obuf != NULL)
1164                 crypto_use_output_buf(crp, cod->obuf, caead->len +
1165                     cse->hashsize);
1166         crp->crp_callback = cryptodev_cb;
1167         crp->crp_opaque = cod;
1168
1169         if (caead->iv) {
1170                 /*
1171                  * Permit a 16-byte IV for AES-XTS, but only use the
1172                  * first 8 bytes as a block number.
1173                  */
1174                 if (csp->csp_mode == CSP_MODE_ETA &&
1175                     csp->csp_cipher_alg == CRYPTO_AES_XTS &&
1176                     caead->ivlen == AES_BLOCK_LEN)
1177                         caead->ivlen = AES_XTS_IV_LEN;
1178
1179                 if (cse->ivsize == 0) {
1180                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1181                         error = EINVAL;
1182                         goto bail;
1183                 }
1184                 if (caead->ivlen != cse->ivsize) {
1185                         error = EINVAL;
1186                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1187                         goto bail;
1188                 }
1189
1190                 error = copyin(caead->iv, crp->crp_iv, cse->ivsize);
1191                 if (error) {
1192                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1193                         goto bail;
1194                 }
1195                 crp->crp_flags |= CRYPTO_F_IV_SEPARATE;
1196         } else {
1197                 error = EINVAL;
1198                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1199                 goto bail;
1200         }
1201
1202         if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
1203                 error = copyin(caead->tag, cod->buf + crp->crp_digest_start,
1204                     cse->hashsize);
1205                 if (error) {
1206                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1207                         goto bail;
1208                 }
1209         }
1210 again:
1211         /*
1212          * Let the dispatch run unlocked, then, interlock against the
1213          * callback before checking if the operation completed and going
1214          * to sleep.  This insures drivers don't inherit our lock which
1215          * results in a lock order reversal between crypto_dispatch forced
1216          * entry and the crypto_done callback into us.
1217          */
1218         error = crypto_dispatch(crp);
1219         if (error != 0) {
1220                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1221                 goto bail;
1222         }
1223
1224         mtx_lock(&cse->lock);
1225         while (!cod->done)
1226                 mtx_sleep(cod, &cse->lock, PWAIT, "crydev", 0);
1227         mtx_unlock(&cse->lock);
1228
1229         if (crp->crp_etype == EAGAIN) {
1230                 crp->crp_etype = 0;
1231                 crp->crp_flags &= ~CRYPTO_F_DONE;
1232                 cod->done = false;
1233                 goto again;
1234         }
1235
1236         if (crp->crp_etype != 0) {
1237                 error = crp->crp_etype;
1238                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1239                 goto bail;
1240         }
1241
1242         if (caead->dst != NULL) {
1243                 error = copyout(cod->obuf != NULL ? cod->obuf :
1244                     cod->buf + crp->crp_payload_start, dst,
1245                     crp->crp_payload_length);
1246                 if (error) {
1247                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1248                         goto bail;
1249                 }
1250         }
1251
1252         if ((crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) == 0) {
1253                 error = copyout((cod->obuf != NULL ? cod->obuf : cod->buf) +
1254                     crp->crp_digest_start, caead->tag, cse->hashsize);
1255                 if (error) {
1256                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1257                         goto bail;
1258                 }
1259         }
1260
1261 bail:
1262         crypto_freereq(crp);
1263         cod_free(cod);
1264
1265         return (error);
1266 }
1267
1268 static void
1269 cryptodevkey_cb(struct cryptkop *krp)
1270 {
1271
1272         wakeup_one(krp);
1273 }
1274
1275 static int
1276 cryptodev_key(struct crypt_kop *kop)
1277 {
1278         struct cryptkop *krp = NULL;
1279         int error = EINVAL;
1280         int in, out, size, i;
1281
1282         if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {
1283                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1284                 return (EFBIG);
1285         }
1286
1287         in = kop->crk_iparams;
1288         out = kop->crk_oparams;
1289         switch (kop->crk_op) {
1290         case CRK_MOD_EXP:
1291                 if (in == 3 && out == 1)
1292                         break;
1293                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1294                 return (EINVAL);
1295         case CRK_MOD_EXP_CRT:
1296                 if (in == 6 && out == 1)
1297                         break;
1298                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1299                 return (EINVAL);
1300         case CRK_DSA_SIGN:
1301                 if (in == 5 && out == 2)
1302                         break;
1303                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1304                 return (EINVAL);
1305         case CRK_DSA_VERIFY:
1306                 if (in == 7 && out == 0)
1307                         break;
1308                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1309                 return (EINVAL);
1310         case CRK_DH_COMPUTE_KEY:
1311                 if (in == 3 && out == 1)
1312                         break;
1313                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1314                 return (EINVAL);
1315         default:
1316                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1317                 return (EINVAL);
1318         }
1319
1320         krp = malloc(sizeof(*krp), M_CRYPTODEV, M_WAITOK | M_ZERO);
1321         krp->krp_op = kop->crk_op;
1322         krp->krp_status = kop->crk_status;
1323         krp->krp_iparams = kop->crk_iparams;
1324         krp->krp_oparams = kop->crk_oparams;
1325         krp->krp_crid = kop->crk_crid;
1326         krp->krp_status = 0;
1327         krp->krp_callback = cryptodevkey_cb;
1328
1329         for (i = 0; i < CRK_MAXPARAM; i++) {
1330                 if (kop->crk_param[i].crp_nbits > 65536) {
1331                         /* Limit is the same as in OpenBSD */
1332                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1333                         goto fail;
1334                 }
1335                 krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
1336         }
1337         for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
1338                 size = (krp->krp_param[i].crp_nbits + 7) / 8;
1339                 if (size == 0)
1340                         continue;
1341                 krp->krp_param[i].crp_p = malloc(size, M_CRYPTODEV, M_WAITOK);
1342                 if (i >= krp->krp_iparams)
1343                         continue;
1344                 error = copyin(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p, size);
1345                 if (error) {
1346                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1347                         goto fail;
1348                 }
1349         }
1350
1351         error = crypto_kdispatch(krp);
1352         if (error) {
1353                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1354                 goto fail;
1355         }
1356         error = tsleep(krp, PSOCK, "crydev", 0);
1357         if (error) {
1358                 /* XXX can this happen?  if so, how do we recover? */
1359                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1360                 goto fail;
1361         }
1362         
1363         kop->crk_crid = krp->krp_hid;           /* device that did the work */
1364         if (krp->krp_status != 0) {
1365                 error = krp->krp_status;
1366                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1367                 goto fail;
1368         }
1369
1370         for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {
1371                 size = (krp->krp_param[i].crp_nbits + 7) / 8;
1372                 if (size == 0)
1373                         continue;
1374                 error = copyout(krp->krp_param[i].crp_p, kop->crk_param[i].crp_p, size);
1375                 if (error) {
1376                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1377                         goto fail;
1378                 }
1379         }
1380
1381 fail:
1382         if (krp) {
1383                 kop->crk_status = krp->krp_status;
1384                 for (i = 0; i < CRK_MAXPARAM; i++) {
1385                         if (krp->krp_param[i].crp_p)
1386                                 free(krp->krp_param[i].crp_p, M_CRYPTODEV);
1387                 }
1388                 free(krp, M_CRYPTODEV);
1389         }
1390         return (error);
1391 }
1392
1393 static int
1394 cryptodev_find(struct crypt_find_op *find)
1395 {
1396         device_t dev;
1397         size_t fnlen = sizeof find->name;
1398
1399         if (find->crid != -1) {
1400                 dev = crypto_find_device_byhid(find->crid);
1401                 if (dev == NULL)
1402                         return (ENOENT);
1403                 strncpy(find->name, device_get_nameunit(dev), fnlen);
1404                 find->name[fnlen - 1] = '\x0';
1405         } else {
1406                 find->name[fnlen - 1] = '\x0';
1407                 find->crid = crypto_find_driver(find->name);
1408                 if (find->crid == -1)
1409                         return (ENOENT);
1410         }
1411         return (0);
1412 }
1413
1414 static void
1415 fcrypt_dtor(void *data)
1416 {
1417         struct fcrypt *fcr = data;
1418         struct csession *cse;
1419
1420         while ((cse = TAILQ_FIRST(&fcr->csessions))) {
1421                 TAILQ_REMOVE(&fcr->csessions, cse, next);
1422                 KASSERT(refcount_load(&cse->refs) == 1,
1423                     ("%s: crypto session %p with %d refs", __func__, cse,
1424                     refcount_load(&cse->refs)));
1425                 cse_free(cse);
1426         }
1427         mtx_destroy(&fcr->lock);
1428         free(fcr, M_CRYPTODEV);
1429 }
1430
1431 static int
1432 crypto_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
1433 {
1434         struct fcrypt *fcr;
1435         int error;
1436
1437         fcr = malloc(sizeof(struct fcrypt), M_CRYPTODEV, M_WAITOK | M_ZERO);
1438         TAILQ_INIT(&fcr->csessions);
1439         mtx_init(&fcr->lock, "fcrypt", NULL, MTX_DEF);
1440         error = devfs_set_cdevpriv(fcr, fcrypt_dtor);
1441         if (error)
1442                 fcrypt_dtor(fcr);
1443         return (error);
1444 }
1445
1446 static int
1447 crypto_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
1448     struct thread *td)
1449 {
1450         static struct timeval keywarn, featwarn;
1451         struct fcrypt *fcr;
1452         struct csession *cse;
1453         struct session2_op *sop;
1454         struct crypt_op *cop;
1455         struct crypt_aead *caead;
1456         struct crypt_kop *kop;
1457         uint32_t ses;
1458         int error = 0;
1459         union {
1460                 struct session2_op sopc;
1461 #ifdef COMPAT_FREEBSD32
1462                 struct crypt_op copc;
1463                 struct crypt_aead aeadc;
1464                 struct crypt_kop kopc;
1465 #endif
1466         } thunk;
1467 #ifdef COMPAT_FREEBSD32
1468         u_long cmd32;
1469         void *data32;
1470
1471         cmd32 = 0;
1472         data32 = NULL;
1473         switch (cmd) {
1474         case CIOCGSESSION32:
1475                 cmd32 = cmd;
1476                 data32 = data;
1477                 cmd = CIOCGSESSION;
1478                 data = (void *)&thunk.sopc;
1479                 session_op_from_32((struct session_op32 *)data32, &thunk.sopc);
1480                 break;
1481         case CIOCGSESSION232:
1482                 cmd32 = cmd;
1483                 data32 = data;
1484                 cmd = CIOCGSESSION2;
1485                 data = (void *)&thunk.sopc;
1486                 session2_op_from_32((struct session2_op32 *)data32,
1487                     &thunk.sopc);
1488                 break;
1489         case CIOCCRYPT32:
1490                 cmd32 = cmd;
1491                 data32 = data;
1492                 cmd = CIOCCRYPT;
1493                 data = (void *)&thunk.copc;
1494                 crypt_op_from_32((struct crypt_op32 *)data32, &thunk.copc);
1495                 break;
1496         case CIOCCRYPTAEAD32:
1497                 cmd32 = cmd;
1498                 data32 = data;
1499                 cmd = CIOCCRYPTAEAD;
1500                 data = (void *)&thunk.aeadc;
1501                 crypt_aead_from_32((struct crypt_aead32 *)data32, &thunk.aeadc);
1502                 break;
1503         case CIOCKEY32:
1504         case CIOCKEY232:
1505                 cmd32 = cmd;
1506                 data32 = data;
1507                 if (cmd == CIOCKEY32)
1508                         cmd = CIOCKEY;
1509                 else
1510                         cmd = CIOCKEY2;
1511                 data = (void *)&thunk.kopc;
1512                 crypt_kop_from_32((struct crypt_kop32 *)data32, &thunk.kopc);
1513                 break;
1514         }
1515 #endif
1516
1517         devfs_get_cdevpriv((void **)&fcr);
1518
1519         switch (cmd) {
1520 #ifdef COMPAT_FREEBSD12
1521         case CRIOGET:
1522                 /*
1523                  * NB: This may fail in cases that the old
1524                  * implementation did not if the current process has
1525                  * restricted filesystem access (e.g. running in a
1526                  * jail that does not expose /dev/crypto or in
1527                  * capability mode).
1528                  */
1529                 error = kern_openat(td, AT_FDCWD, "/dev/crypto", UIO_SYSSPACE,
1530                     O_RDWR, 0);
1531                 if (error == 0)
1532                         *(uint32_t *)data = td->td_retval[0];
1533                 break;
1534 #endif
1535         case CIOCGSESSION:
1536         case CIOCGSESSION2:
1537                 if (cmd == CIOCGSESSION) {
1538                         session2_op_from_op((void *)data, &thunk.sopc);
1539                         sop = &thunk.sopc;
1540                 } else
1541                         sop = (struct session2_op *)data;
1542
1543                 error = cse_create(fcr, sop);
1544                 if (cmd == CIOCGSESSION && error == 0)
1545                         session2_op_to_op(sop, (void *)data);
1546                 break;
1547         case CIOCFSESSION:
1548                 ses = *(uint32_t *)data;
1549                 if (!cse_delete(fcr, ses)) {
1550                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1551                         return (EINVAL);
1552                 }
1553                 break;
1554         case CIOCCRYPT:
1555                 cop = (struct crypt_op *)data;
1556                 cse = cse_find(fcr, cop->ses);
1557                 if (cse == NULL) {
1558                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1559                         return (EINVAL);
1560                 }
1561                 error = cryptodev_op(cse, cop);
1562                 cse_free(cse);
1563                 break;
1564         case CIOCKEY:
1565         case CIOCKEY2:
1566                 if (ratecheck(&keywarn, &warninterval))
1567                         gone_in(14,
1568                             "Asymmetric crypto operations via /dev/crypto");
1569
1570                 if (!crypto_userasymcrypto) {
1571                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1572                         return (EPERM);         /* XXX compat? */
1573                 }
1574                 kop = (struct crypt_kop *)data;
1575                 if (cmd == CIOCKEY) {
1576                         /* NB: crypto core enforces s/w driver use */
1577                         kop->crk_crid =
1578                             CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
1579                 }
1580                 mtx_lock(&Giant);
1581                 error = cryptodev_key(kop);
1582                 mtx_unlock(&Giant);
1583                 break;
1584         case CIOCASYMFEAT:
1585                 if (ratecheck(&featwarn, &warninterval))
1586                         gone_in(14,
1587                             "Asymmetric crypto features via /dev/crypto");
1588
1589                 if (!crypto_userasymcrypto) {
1590                         /*
1591                          * NB: if user asym crypto operations are
1592                          * not permitted return "no algorithms"
1593                          * so well-behaved applications will just
1594                          * fallback to doing them in software.
1595                          */
1596                         *(int *)data = 0;
1597                 } else {
1598                         error = crypto_getfeat((int *)data);
1599                         if (error)
1600                                 SDT_PROBE1(opencrypto, dev, ioctl, error,
1601                                     __LINE__);
1602                 }
1603                 break;
1604         case CIOCFINDDEV:
1605                 error = cryptodev_find((struct crypt_find_op *)data);
1606                 break;
1607         case CIOCCRYPTAEAD:
1608                 caead = (struct crypt_aead *)data;
1609                 cse = cse_find(fcr, caead->ses);
1610                 if (cse == NULL) {
1611                         SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1612                         return (EINVAL);
1613                 }
1614                 error = cryptodev_aead(cse, caead);
1615                 cse_free(cse);
1616                 break;
1617         default:
1618                 error = EINVAL;
1619                 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
1620                 break;
1621         }
1622
1623 #ifdef COMPAT_FREEBSD32
1624         switch (cmd32) {
1625         case CIOCGSESSION32:
1626                 if (error == 0)
1627                         session_op_to_32((void *)data, data32);
1628                 break;
1629         case CIOCGSESSION232:
1630                 if (error == 0)
1631                         session2_op_to_32((void *)data, data32);
1632                 break;
1633         case CIOCCRYPT32:
1634                 if (error == 0)
1635                         crypt_op_to_32((void *)data, data32);
1636                 break;
1637         case CIOCCRYPTAEAD32:
1638                 if (error == 0)
1639                         crypt_aead_to_32((void *)data, data32);
1640                 break;
1641         case CIOCKEY32:
1642         case CIOCKEY232:
1643                 crypt_kop_to_32((void *)data, data32);
1644                 break;
1645         }
1646 #endif
1647         return (error);
1648 }
1649
1650 static struct cdevsw crypto_cdevsw = {
1651         .d_version =    D_VERSION,
1652         .d_open =       crypto_open,
1653         .d_ioctl =      crypto_ioctl,
1654         .d_name =       "crypto",
1655 };
1656 static struct cdev *crypto_dev;
1657
1658 /*
1659  * Initialization code, both for static and dynamic loading.
1660  */
1661 static int
1662 cryptodev_modevent(module_t mod, int type, void *unused)
1663 {
1664         switch (type) {
1665         case MOD_LOAD:
1666                 if (bootverbose)
1667                         printf("crypto: <crypto device>\n");
1668                 crypto_dev = make_dev(&crypto_cdevsw, 0, 
1669                                       UID_ROOT, GID_WHEEL, 0666,
1670                                       "crypto");
1671                 return 0;
1672         case MOD_UNLOAD:
1673                 /*XXX disallow if active sessions */
1674                 destroy_dev(crypto_dev);
1675                 return 0;
1676         }
1677         return EINVAL;
1678 }
1679
1680 static moduledata_t cryptodev_mod = {
1681         "cryptodev",
1682         cryptodev_modevent,
1683         0
1684 };
1685 MODULE_VERSION(cryptodev, 1);
1686 DECLARE_MODULE(cryptodev, cryptodev_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
1687 MODULE_DEPEND(cryptodev, crypto, 1, 1, 1);
1688 MODULE_DEPEND(cryptodev, zlib, 1, 1, 1);