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