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