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