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