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 default: 496 CRYPTDEB("invalid mac"); 497 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 498 return (EINVAL); 499 } 500 501 bzero(&crie, sizeof(crie)); 502 bzero(&cria, sizeof(cria)); 503 504 if (txform) { 505 crie.cri_alg = txform->type; 506 crie.cri_klen = sop->keylen * 8; 507 if (sop->keylen > txform->maxkey || 508 sop->keylen < txform->minkey) { 509 CRYPTDEB("invalid cipher parameters"); 510 error = EINVAL; 511 SDT_PROBE1(opencrypto, dev, ioctl, error, 512 __LINE__); 513 goto bail; 514 } 515 516 crie.cri_key = malloc(crie.cri_klen / 8, 517 M_XDATA, M_WAITOK); 518 if ((error = copyin(sop->key, crie.cri_key, 519 crie.cri_klen / 8))) { 520 CRYPTDEB("invalid key"); 521 SDT_PROBE1(opencrypto, dev, ioctl, error, 522 __LINE__); 523 goto bail; 524 } 525 if (thash) 526 crie.cri_next = &cria; 527 } 528 529 if (thash) { 530 cria.cri_alg = thash->type; 531 cria.cri_klen = sop->mackeylen * 8; 532 if (thash->keysize != 0 && 533 sop->mackeylen > thash->keysize) { 534 CRYPTDEB("invalid mac key length"); 535 error = EINVAL; 536 SDT_PROBE1(opencrypto, dev, ioctl, error, 537 __LINE__); 538 goto bail; 539 } 540 541 if (cria.cri_klen) { 542 cria.cri_key = malloc(cria.cri_klen / 8, 543 M_XDATA, M_WAITOK); 544 if ((error = copyin(sop->mackey, cria.cri_key, 545 cria.cri_klen / 8))) { 546 CRYPTDEB("invalid mac key"); 547 SDT_PROBE1(opencrypto, dev, ioctl, 548 error, __LINE__); 549 goto bail; 550 } 551 } 552 } 553 554 /* NB: CIOCGSESSION2 has the crid */ 555 if (cmd == CIOCGSESSION2 556 #ifdef COMPAT_FREEBSD32 557 || cmd == CIOCGSESSION232 558 #endif 559 ) { 560 crid = SES2(sop)->crid; 561 error = checkforsoftware(&crid); 562 if (error) { 563 CRYPTDEB("checkforsoftware"); 564 SDT_PROBE1(opencrypto, dev, ioctl, error, 565 __LINE__); 566 goto bail; 567 } 568 } else 569 crid = CRYPTOCAP_F_HARDWARE; 570 error = crypto_newsession(&sid, (txform ? &crie : &cria), crid); 571 if (error) { 572 CRYPTDEB("crypto_newsession"); 573 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 574 goto bail; 575 } 576 577 cse = csecreate(fcr, sid, crie.cri_key, crie.cri_klen, 578 cria.cri_key, cria.cri_klen, sop->cipher, sop->mac, txform, 579 thash); 580 581 if (cse == NULL) { 582 crypto_freesession(sid); 583 error = EINVAL; 584 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 585 CRYPTDEB("csecreate"); 586 goto bail; 587 } 588 sop->ses = cse->ses; 589 if (cmd == CIOCGSESSION2 590 #ifdef COMPAT_FREEBSD32 591 || cmd == CIOCGSESSION232 592 #endif 593 ) { 594 /* return hardware/driver id */ 595 SES2(sop)->crid = CRYPTO_SESID2HID(cse->sid); 596 } 597 bail: 598 if (error) { 599 if (crie.cri_key) 600 free(crie.cri_key, M_XDATA); 601 if (cria.cri_key) 602 free(cria.cri_key, M_XDATA); 603 } 604 #ifdef COMPAT_FREEBSD32 605 else { 606 if (cmd == CIOCGSESSION32) 607 session_op_to_32(sop, data); 608 else if (cmd == CIOCGSESSION232) 609 session2_op_to_32((struct session2_op *)sop, 610 data); 611 } 612 #endif 613 break; 614 case CIOCFSESSION: 615 ses = *(u_int32_t *)data; 616 cse = csefind(fcr, ses); 617 if (cse == NULL) { 618 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 619 return (EINVAL); 620 } 621 csedelete(fcr, cse); 622 error = csefree(cse); 623 break; 624 case CIOCCRYPT: 625 #ifdef COMPAT_FREEBSD32 626 case CIOCCRYPT32: 627 if (cmd == CIOCCRYPT32) { 628 cop = &copc; 629 crypt_op_from_32(data, cop); 630 } else 631 #endif 632 cop = (struct crypt_op *)data; 633 cse = csefind(fcr, cop->ses); 634 if (cse == NULL) { 635 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 636 return (EINVAL); 637 } 638 error = cryptodev_op(cse, cop, active_cred, td); 639 #ifdef COMPAT_FREEBSD32 640 if (error == 0 && cmd == CIOCCRYPT32) 641 crypt_op_to_32(cop, data); 642 #endif 643 break; 644 case CIOCKEY: 645 case CIOCKEY2: 646 #ifdef COMPAT_FREEBSD32 647 case CIOCKEY32: 648 case CIOCKEY232: 649 #endif 650 if (!crypto_userasymcrypto) { 651 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 652 return (EPERM); /* XXX compat? */ 653 } 654 #ifdef COMPAT_FREEBSD32 655 if (cmd == CIOCKEY32 || cmd == CIOCKEY232) { 656 kop = &kopc; 657 crypt_kop_from_32(data, kop); 658 } else 659 #endif 660 kop = (struct crypt_kop *)data; 661 if (cmd == CIOCKEY 662 #ifdef COMPAT_FREEBSD32 663 || cmd == CIOCKEY32 664 #endif 665 ) { 666 /* NB: crypto core enforces s/w driver use */ 667 kop->crk_crid = 668 CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE; 669 } 670 mtx_lock(&Giant); 671 error = cryptodev_key(kop); 672 mtx_unlock(&Giant); 673 #ifdef COMPAT_FREEBSD32 674 if (cmd == CIOCKEY32 || cmd == CIOCKEY232) 675 crypt_kop_to_32(kop, data); 676 #endif 677 break; 678 case CIOCASYMFEAT: 679 if (!crypto_userasymcrypto) { 680 /* 681 * NB: if user asym crypto operations are 682 * not permitted return "no algorithms" 683 * so well-behaved applications will just 684 * fallback to doing them in software. 685 */ 686 *(int *)data = 0; 687 } else { 688 error = crypto_getfeat((int *)data); 689 if (error) 690 SDT_PROBE1(opencrypto, dev, ioctl, error, 691 __LINE__); 692 } 693 break; 694 case CIOCFINDDEV: 695 error = cryptodev_find((struct crypt_find_op *)data); 696 break; 697 case CIOCCRYPTAEAD: 698 caead = (struct crypt_aead *)data; 699 cse = csefind(fcr, caead->ses); 700 if (cse == NULL) { 701 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 702 return (EINVAL); 703 } 704 error = cryptodev_aead(cse, caead, active_cred, td); 705 break; 706 default: 707 error = EINVAL; 708 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 709 break; 710 } 711 return (error); 712 #undef SES2 713 } 714 715 static int cryptodev_cb(struct cryptop *); 716 717 static struct cryptop_data * 718 cod_alloc(struct csession *cse, size_t len, struct thread *td) 719 { 720 struct cryptop_data *cod; 721 struct uio *uio; 722 723 cod = malloc(sizeof(struct cryptop_data), M_XDATA, M_WAITOK | M_ZERO); 724 725 cod->cse = cse; 726 uio = &cod->uio; 727 uio->uio_iov = cod->iovec; 728 uio->uio_iovcnt = 1; 729 uio->uio_resid = len; 730 uio->uio_segflg = UIO_SYSSPACE; 731 uio->uio_rw = UIO_WRITE; 732 uio->uio_td = td; 733 uio->uio_iov[0].iov_len = len; 734 uio->uio_iov[0].iov_base = malloc(len, M_XDATA, M_WAITOK); 735 return (cod); 736 } 737 738 static void 739 cod_free(struct cryptop_data *cod) 740 { 741 742 free(cod->uio.uio_iov[0].iov_base, M_XDATA); 743 free(cod, M_XDATA); 744 } 745 746 static int 747 cryptodev_op( 748 struct csession *cse, 749 struct crypt_op *cop, 750 struct ucred *active_cred, 751 struct thread *td) 752 { 753 struct cryptop_data *cod = NULL; 754 struct cryptop *crp = NULL; 755 struct cryptodesc *crde = NULL, *crda = NULL; 756 int error; 757 758 if (cop->len > 256*1024-4) { 759 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 760 return (E2BIG); 761 } 762 763 if (cse->txform) { 764 if (cop->len == 0 || (cop->len % cse->txform->blocksize) != 0) { 765 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 766 return (EINVAL); 767 } 768 } 769 770 if (cse->thash) 771 cod = cod_alloc(cse, cop->len + cse->thash->hashsize, td); 772 else 773 cod = cod_alloc(cse, cop->len, td); 774 775 crp = crypto_getreq((cse->txform != NULL) + (cse->thash != NULL)); 776 if (crp == NULL) { 777 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 778 error = ENOMEM; 779 goto bail; 780 } 781 782 if (cse->thash && cse->txform) { 783 if (cop->flags & COP_F_CIPHER_FIRST) { 784 crde = crp->crp_desc; 785 crda = crde->crd_next; 786 } else { 787 crda = crp->crp_desc; 788 crde = crda->crd_next; 789 } 790 } else if (cse->thash) { 791 crda = crp->crp_desc; 792 } else if (cse->txform) { 793 crde = crp->crp_desc; 794 } else { 795 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 796 error = EINVAL; 797 goto bail; 798 } 799 800 if ((error = copyin(cop->src, cod->uio.uio_iov[0].iov_base, 801 cop->len))) { 802 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 803 goto bail; 804 } 805 806 if (crda) { 807 crda->crd_skip = 0; 808 crda->crd_len = cop->len; 809 crda->crd_inject = cop->len; 810 811 crda->crd_alg = cse->mac; 812 crda->crd_key = cse->mackey; 813 crda->crd_klen = cse->mackeylen * 8; 814 } 815 816 if (crde) { 817 if (cop->op == COP_ENCRYPT) 818 crde->crd_flags |= CRD_F_ENCRYPT; 819 else 820 crde->crd_flags &= ~CRD_F_ENCRYPT; 821 crde->crd_len = cop->len; 822 crde->crd_inject = 0; 823 824 crde->crd_alg = cse->cipher; 825 crde->crd_key = cse->key; 826 crde->crd_klen = cse->keylen * 8; 827 } 828 829 crp->crp_ilen = cop->len; 830 crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM 831 | (cop->flags & COP_F_BATCH); 832 crp->crp_uio = &cod->uio; 833 crp->crp_callback = cryptodev_cb; 834 crp->crp_sid = cse->sid; 835 crp->crp_opaque = cod; 836 837 if (cop->iv) { 838 if (crde == NULL) { 839 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 840 error = EINVAL; 841 goto bail; 842 } 843 if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */ 844 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 845 error = EINVAL; 846 goto bail; 847 } 848 if ((error = copyin(cop->iv, crde->crd_iv, 849 cse->txform->blocksize))) { 850 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 851 goto bail; 852 } 853 crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; 854 crde->crd_skip = 0; 855 } else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */ 856 crde->crd_skip = 0; 857 } else if (crde) { 858 crde->crd_flags |= CRD_F_IV_PRESENT; 859 crde->crd_skip = cse->txform->blocksize; 860 crde->crd_len -= cse->txform->blocksize; 861 } 862 863 if (cop->mac && crda == NULL) { 864 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 865 error = EINVAL; 866 goto bail; 867 } 868 869 again: 870 /* 871 * Let the dispatch run unlocked, then, interlock against the 872 * callback before checking if the operation completed and going 873 * to sleep. This insures drivers don't inherit our lock which 874 * results in a lock order reversal between crypto_dispatch forced 875 * entry and the crypto_done callback into us. 876 */ 877 error = crypto_dispatch(crp); 878 if (error != 0) { 879 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 880 goto bail; 881 } 882 883 mtx_lock(&cse->lock); 884 while (!cod->done) 885 mtx_sleep(cod, &cse->lock, PWAIT, "crydev", 0); 886 mtx_unlock(&cse->lock); 887 888 if (crp->crp_etype == EAGAIN) { 889 crp->crp_etype = 0; 890 crp->crp_flags &= ~CRYPTO_F_DONE; 891 cod->done = false; 892 goto again; 893 } 894 895 if (crp->crp_etype != 0) { 896 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 897 error = crp->crp_etype; 898 goto bail; 899 } 900 901 if (cop->dst && 902 (error = copyout(cod->uio.uio_iov[0].iov_base, cop->dst, 903 cop->len))) { 904 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 905 goto bail; 906 } 907 908 if (cop->mac && 909 (error = copyout((caddr_t)cod->uio.uio_iov[0].iov_base + cop->len, 910 cop->mac, cse->thash->hashsize))) { 911 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 912 goto bail; 913 } 914 915 bail: 916 if (crp) 917 crypto_freereq(crp); 918 if (cod) 919 cod_free(cod); 920 921 return (error); 922 } 923 924 static int 925 cryptodev_aead( 926 struct csession *cse, 927 struct crypt_aead *caead, 928 struct ucred *active_cred, 929 struct thread *td) 930 { 931 struct cryptop_data *cod = NULL; 932 struct cryptop *crp = NULL; 933 struct cryptodesc *crde = NULL, *crda = NULL; 934 int error; 935 936 if (caead->len > 256*1024-4 || caead->aadlen > 256*1024-4) { 937 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 938 return (E2BIG); 939 } 940 941 if (cse->txform == NULL || cse->thash == NULL || caead->tag == NULL || 942 (caead->len % cse->txform->blocksize) != 0) { 943 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 944 return (EINVAL); 945 } 946 947 cod = cod_alloc(cse, caead->aadlen + caead->len + cse->thash->hashsize, 948 td); 949 950 crp = crypto_getreq(2); 951 if (crp == NULL) { 952 error = ENOMEM; 953 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 954 goto bail; 955 } 956 957 if (caead->flags & COP_F_CIPHER_FIRST) { 958 crde = crp->crp_desc; 959 crda = crde->crd_next; 960 } else { 961 crda = crp->crp_desc; 962 crde = crda->crd_next; 963 } 964 965 if ((error = copyin(caead->aad, cod->uio.uio_iov[0].iov_base, 966 caead->aadlen))) { 967 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 968 goto bail; 969 } 970 971 if ((error = copyin(caead->src, (char *)cod->uio.uio_iov[0].iov_base + 972 caead->aadlen, caead->len))) { 973 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 974 goto bail; 975 } 976 977 /* 978 * For GCM, crd_len covers only the AAD. For other ciphers 979 * chained with an HMAC, crd_len covers both the AAD and the 980 * cipher text. 981 */ 982 crda->crd_skip = 0; 983 if (cse->cipher == CRYPTO_AES_NIST_GCM_16) 984 crda->crd_len = caead->aadlen; 985 else 986 crda->crd_len = caead->aadlen + caead->len; 987 crda->crd_inject = caead->aadlen + caead->len; 988 989 crda->crd_alg = cse->mac; 990 crda->crd_key = cse->mackey; 991 crda->crd_klen = cse->mackeylen * 8; 992 993 if (caead->op == COP_ENCRYPT) 994 crde->crd_flags |= CRD_F_ENCRYPT; 995 else 996 crde->crd_flags &= ~CRD_F_ENCRYPT; 997 crde->crd_skip = caead->aadlen; 998 crde->crd_len = caead->len; 999 crde->crd_inject = caead->aadlen; 1000 1001 crde->crd_alg = cse->cipher; 1002 crde->crd_key = cse->key; 1003 crde->crd_klen = cse->keylen * 8; 1004 1005 crp->crp_ilen = caead->aadlen + caead->len; 1006 crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM 1007 | (caead->flags & COP_F_BATCH); 1008 crp->crp_uio = &cod->uio; 1009 crp->crp_callback = cryptodev_cb; 1010 crp->crp_sid = cse->sid; 1011 crp->crp_opaque = cod; 1012 1013 if (caead->iv) { 1014 if (caead->ivlen > sizeof(crde->crd_iv)) { 1015 error = EINVAL; 1016 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1017 goto bail; 1018 } 1019 1020 if ((error = copyin(caead->iv, crde->crd_iv, caead->ivlen))) { 1021 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1022 goto bail; 1023 } 1024 crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; 1025 } else { 1026 crde->crd_flags |= CRD_F_IV_PRESENT; 1027 crde->crd_skip += cse->txform->blocksize; 1028 crde->crd_len -= cse->txform->blocksize; 1029 } 1030 1031 if ((error = copyin(caead->tag, (caddr_t)cod->uio.uio_iov[0].iov_base + 1032 caead->len + caead->aadlen, cse->thash->hashsize))) { 1033 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1034 goto bail; 1035 } 1036 again: 1037 /* 1038 * Let the dispatch run unlocked, then, interlock against the 1039 * callback before checking if the operation completed and going 1040 * to sleep. This insures drivers don't inherit our lock which 1041 * results in a lock order reversal between crypto_dispatch forced 1042 * entry and the crypto_done callback into us. 1043 */ 1044 error = crypto_dispatch(crp); 1045 if (error != 0) { 1046 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1047 goto bail; 1048 } 1049 1050 mtx_lock(&cse->lock); 1051 while (!cod->done) 1052 mtx_sleep(cod, &cse->lock, PWAIT, "crydev", 0); 1053 mtx_unlock(&cse->lock); 1054 1055 if (crp->crp_etype == EAGAIN) { 1056 crp->crp_etype = 0; 1057 crp->crp_flags &= ~CRYPTO_F_DONE; 1058 cod->done = false; 1059 goto again; 1060 } 1061 1062 if (crp->crp_etype != 0) { 1063 error = crp->crp_etype; 1064 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1065 goto bail; 1066 } 1067 1068 if (caead->dst && (error = copyout( 1069 (caddr_t)cod->uio.uio_iov[0].iov_base + caead->aadlen, caead->dst, 1070 caead->len))) { 1071 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1072 goto bail; 1073 } 1074 1075 if ((error = copyout((caddr_t)cod->uio.uio_iov[0].iov_base + 1076 caead->aadlen + caead->len, caead->tag, cse->thash->hashsize))) { 1077 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1078 goto bail; 1079 } 1080 1081 bail: 1082 crypto_freereq(crp); 1083 if (cod) 1084 cod_free(cod); 1085 1086 return (error); 1087 } 1088 1089 static int 1090 cryptodev_cb(struct cryptop *crp) 1091 { 1092 struct cryptop_data *cod = crp->crp_opaque; 1093 1094 /* 1095 * Lock to ensure the wakeup() is not missed by the loops 1096 * waiting on cod->done in cryptodev_op() and 1097 * cryptodev_aead(). 1098 */ 1099 mtx_lock(&cod->cse->lock); 1100 cod->done = true; 1101 mtx_unlock(&cod->cse->lock); 1102 wakeup(cod); 1103 return (0); 1104 } 1105 1106 static int 1107 cryptodevkey_cb(void *op) 1108 { 1109 struct cryptkop *krp = (struct cryptkop *) op; 1110 1111 wakeup_one(krp); 1112 return (0); 1113 } 1114 1115 static int 1116 cryptodev_key(struct crypt_kop *kop) 1117 { 1118 struct cryptkop *krp = NULL; 1119 int error = EINVAL; 1120 int in, out, size, i; 1121 1122 if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) { 1123 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1124 return (EFBIG); 1125 } 1126 1127 in = kop->crk_iparams; 1128 out = kop->crk_oparams; 1129 switch (kop->crk_op) { 1130 case CRK_MOD_EXP: 1131 if (in == 3 && out == 1) 1132 break; 1133 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1134 return (EINVAL); 1135 case CRK_MOD_EXP_CRT: 1136 if (in == 6 && out == 1) 1137 break; 1138 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1139 return (EINVAL); 1140 case CRK_DSA_SIGN: 1141 if (in == 5 && out == 2) 1142 break; 1143 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1144 return (EINVAL); 1145 case CRK_DSA_VERIFY: 1146 if (in == 7 && out == 0) 1147 break; 1148 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1149 return (EINVAL); 1150 case CRK_DH_COMPUTE_KEY: 1151 if (in == 3 && out == 1) 1152 break; 1153 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1154 return (EINVAL); 1155 default: 1156 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1157 return (EINVAL); 1158 } 1159 1160 krp = (struct cryptkop *)malloc(sizeof *krp, M_XDATA, M_WAITOK|M_ZERO); 1161 if (!krp) { 1162 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1163 return (ENOMEM); 1164 } 1165 krp->krp_op = kop->crk_op; 1166 krp->krp_status = kop->crk_status; 1167 krp->krp_iparams = kop->crk_iparams; 1168 krp->krp_oparams = kop->crk_oparams; 1169 krp->krp_crid = kop->crk_crid; 1170 krp->krp_status = 0; 1171 krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb; 1172 1173 for (i = 0; i < CRK_MAXPARAM; i++) { 1174 if (kop->crk_param[i].crp_nbits > 65536) { 1175 /* Limit is the same as in OpenBSD */ 1176 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1177 goto fail; 1178 } 1179 krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits; 1180 } 1181 for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) { 1182 size = (krp->krp_param[i].crp_nbits + 7) / 8; 1183 if (size == 0) 1184 continue; 1185 krp->krp_param[i].crp_p = malloc(size, M_XDATA, M_WAITOK); 1186 if (i >= krp->krp_iparams) 1187 continue; 1188 error = copyin(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p, size); 1189 if (error) { 1190 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1191 goto fail; 1192 } 1193 } 1194 1195 error = crypto_kdispatch(krp); 1196 if (error) { 1197 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1198 goto fail; 1199 } 1200 error = tsleep(krp, PSOCK, "crydev", 0); 1201 if (error) { 1202 /* XXX can this happen? if so, how do we recover? */ 1203 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1204 goto fail; 1205 } 1206 1207 kop->crk_crid = krp->krp_crid; /* device that did the work */ 1208 if (krp->krp_status != 0) { 1209 error = krp->krp_status; 1210 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1211 goto fail; 1212 } 1213 1214 for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) { 1215 size = (krp->krp_param[i].crp_nbits + 7) / 8; 1216 if (size == 0) 1217 continue; 1218 error = copyout(krp->krp_param[i].crp_p, kop->crk_param[i].crp_p, size); 1219 if (error) { 1220 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1221 goto fail; 1222 } 1223 } 1224 1225 fail: 1226 if (krp) { 1227 kop->crk_status = krp->krp_status; 1228 for (i = 0; i < CRK_MAXPARAM; i++) { 1229 if (krp->krp_param[i].crp_p) 1230 free(krp->krp_param[i].crp_p, M_XDATA); 1231 } 1232 free(krp, M_XDATA); 1233 } 1234 return (error); 1235 } 1236 1237 static int 1238 cryptodev_find(struct crypt_find_op *find) 1239 { 1240 device_t dev; 1241 size_t fnlen = sizeof find->name; 1242 1243 if (find->crid != -1) { 1244 dev = crypto_find_device_byhid(find->crid); 1245 if (dev == NULL) 1246 return (ENOENT); 1247 strncpy(find->name, device_get_nameunit(dev), fnlen); 1248 find->name[fnlen - 1] = '\x0'; 1249 } else { 1250 find->name[fnlen - 1] = '\x0'; 1251 find->crid = crypto_find_driver(find->name); 1252 if (find->crid == -1) 1253 return (ENOENT); 1254 } 1255 return (0); 1256 } 1257 1258 /* ARGSUSED */ 1259 static int 1260 cryptof_stat( 1261 struct file *fp, 1262 struct stat *sb, 1263 struct ucred *active_cred, 1264 struct thread *td) 1265 { 1266 1267 return (EOPNOTSUPP); 1268 } 1269 1270 /* ARGSUSED */ 1271 static int 1272 cryptof_close(struct file *fp, struct thread *td) 1273 { 1274 struct fcrypt *fcr = fp->f_data; 1275 struct csession *cse; 1276 1277 while ((cse = TAILQ_FIRST(&fcr->csessions))) { 1278 TAILQ_REMOVE(&fcr->csessions, cse, next); 1279 (void)csefree(cse); 1280 } 1281 free(fcr, M_XDATA); 1282 fp->f_data = NULL; 1283 return 0; 1284 } 1285 1286 static int 1287 cryptof_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp) 1288 { 1289 1290 kif->kf_type = KF_TYPE_CRYPTO; 1291 return (0); 1292 } 1293 1294 static struct csession * 1295 csefind(struct fcrypt *fcr, u_int ses) 1296 { 1297 struct csession *cse; 1298 1299 TAILQ_FOREACH(cse, &fcr->csessions, next) 1300 if (cse->ses == ses) 1301 return (cse); 1302 return (NULL); 1303 } 1304 1305 static int 1306 csedelete(struct fcrypt *fcr, struct csession *cse_del) 1307 { 1308 struct csession *cse; 1309 1310 TAILQ_FOREACH(cse, &fcr->csessions, next) { 1311 if (cse == cse_del) { 1312 TAILQ_REMOVE(&fcr->csessions, cse, next); 1313 return (1); 1314 } 1315 } 1316 return (0); 1317 } 1318 1319 static struct csession * 1320 cseadd(struct fcrypt *fcr, struct csession *cse) 1321 { 1322 TAILQ_INSERT_TAIL(&fcr->csessions, cse, next); 1323 cse->ses = fcr->sesn++; 1324 return (cse); 1325 } 1326 1327 struct csession * 1328 csecreate(struct fcrypt *fcr, u_int64_t sid, caddr_t key, u_int64_t keylen, 1329 caddr_t mackey, u_int64_t mackeylen, u_int32_t cipher, u_int32_t mac, 1330 struct enc_xform *txform, struct auth_hash *thash) 1331 { 1332 struct csession *cse; 1333 1334 cse = malloc(sizeof(struct csession), M_XDATA, M_NOWAIT | M_ZERO); 1335 if (cse == NULL) 1336 return NULL; 1337 mtx_init(&cse->lock, "cryptodev", "crypto session lock", MTX_DEF); 1338 cse->key = key; 1339 cse->keylen = keylen/8; 1340 cse->mackey = mackey; 1341 cse->mackeylen = mackeylen/8; 1342 cse->sid = sid; 1343 cse->cipher = cipher; 1344 cse->mac = mac; 1345 cse->txform = txform; 1346 cse->thash = thash; 1347 cseadd(fcr, cse); 1348 return (cse); 1349 } 1350 1351 static int 1352 csefree(struct csession *cse) 1353 { 1354 int error; 1355 1356 error = crypto_freesession(cse->sid); 1357 mtx_destroy(&cse->lock); 1358 if (cse->key) 1359 free(cse->key, M_XDATA); 1360 if (cse->mackey) 1361 free(cse->mackey, M_XDATA); 1362 free(cse, M_XDATA); 1363 return (error); 1364 } 1365 1366 static int 1367 cryptoopen(struct cdev *dev, int oflags, int devtype, struct thread *td) 1368 { 1369 return (0); 1370 } 1371 1372 static int 1373 cryptoread(struct cdev *dev, struct uio *uio, int ioflag) 1374 { 1375 return (EIO); 1376 } 1377 1378 static int 1379 cryptowrite(struct cdev *dev, struct uio *uio, int ioflag) 1380 { 1381 return (EIO); 1382 } 1383 1384 static int 1385 cryptoioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) 1386 { 1387 struct file *f; 1388 struct fcrypt *fcr; 1389 int fd, error; 1390 1391 switch (cmd) { 1392 case CRIOGET: 1393 fcr = malloc(sizeof(struct fcrypt), M_XDATA, M_WAITOK); 1394 TAILQ_INIT(&fcr->csessions); 1395 fcr->sesn = 0; 1396 1397 error = falloc(td, &f, &fd, 0); 1398 1399 if (error) { 1400 free(fcr, M_XDATA); 1401 return (error); 1402 } 1403 /* falloc automatically provides an extra reference to 'f'. */ 1404 finit(f, FREAD | FWRITE, DTYPE_CRYPTO, fcr, &cryptofops); 1405 *(u_int32_t *)data = fd; 1406 fdrop(f, td); 1407 break; 1408 case CRIOFINDDEV: 1409 error = cryptodev_find((struct crypt_find_op *)data); 1410 break; 1411 case CRIOASYMFEAT: 1412 error = crypto_getfeat((int *)data); 1413 break; 1414 default: 1415 error = EINVAL; 1416 break; 1417 } 1418 return (error); 1419 } 1420 1421 static struct cdevsw crypto_cdevsw = { 1422 .d_version = D_VERSION, 1423 .d_flags = D_NEEDGIANT, 1424 .d_open = cryptoopen, 1425 .d_read = cryptoread, 1426 .d_write = cryptowrite, 1427 .d_ioctl = cryptoioctl, 1428 .d_name = "crypto", 1429 }; 1430 static struct cdev *crypto_dev; 1431 1432 /* 1433 * Initialization code, both for static and dynamic loading. 1434 */ 1435 static int 1436 cryptodev_modevent(module_t mod, int type, void *unused) 1437 { 1438 switch (type) { 1439 case MOD_LOAD: 1440 if (bootverbose) 1441 printf("crypto: <crypto device>\n"); 1442 crypto_dev = make_dev(&crypto_cdevsw, 0, 1443 UID_ROOT, GID_WHEEL, 0666, 1444 "crypto"); 1445 return 0; 1446 case MOD_UNLOAD: 1447 /*XXX disallow if active sessions */ 1448 destroy_dev(crypto_dev); 1449 return 0; 1450 } 1451 return EINVAL; 1452 } 1453 1454 static moduledata_t cryptodev_mod = { 1455 "cryptodev", 1456 cryptodev_modevent, 1457 0 1458 }; 1459 MODULE_VERSION(cryptodev, 1); 1460 DECLARE_MODULE(cryptodev, cryptodev_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 1461 MODULE_DEPEND(cryptodev, crypto, 1, 1, 1); 1462 MODULE_DEPEND(cryptodev, zlib, 1, 1, 1); 1463