cryptodev.c revision 329887
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: stable/11/sys/opencrypto/cryptodev.c 329887 2018-02-23 23:56:33Z jhb $"); 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 69SDT_PROVIDER_DECLARE(opencrypto); 70 71SDT_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 77struct 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 87struct 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 99struct 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 109struct crparam32 { 110 u_int32_t crp_p; 111 u_int crp_nbits; 112}; 113 114struct 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 123struct cryptotstat32 { 124 struct timespec32 acc; 125 struct timespec32 min; 126 struct timespec32 max; 127 u_int32_t count; 128}; 129 130struct 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 151static void 152session_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 164static void 165session2_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 173static void 174session_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 186static void 187session2_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 195static void 196crypt_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 209static void 210crypt_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 223static void 224crparam_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 231static void 232crparam_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 239static void 240crypt_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 253static void 254crypt_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 268struct 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 u_char tmp_iv[EALG_MAX_BLOCK_LEN]; 282 283 caddr_t mackey; 284 int mackeylen; 285 286 struct iovec iovec; 287 struct uio uio; 288 int error; 289}; 290 291struct fcrypt { 292 TAILQ_HEAD(csessionlist, csession) csessions; 293 int sesn; 294}; 295 296static int cryptof_ioctl(struct file *, u_long, void *, 297 struct ucred *, struct thread *); 298static int cryptof_stat(struct file *, struct stat *, 299 struct ucred *, struct thread *); 300static int cryptof_close(struct file *, struct thread *); 301static int cryptof_fill_kinfo(struct file *, struct kinfo_file *, 302 struct filedesc *); 303 304static struct fileops cryptofops = { 305 .fo_read = invfo_rdwr, 306 .fo_write = invfo_rdwr, 307 .fo_truncate = invfo_truncate, 308 .fo_ioctl = cryptof_ioctl, 309 .fo_poll = invfo_poll, 310 .fo_kqfilter = invfo_kqfilter, 311 .fo_stat = cryptof_stat, 312 .fo_close = cryptof_close, 313 .fo_chmod = invfo_chmod, 314 .fo_chown = invfo_chown, 315 .fo_sendfile = invfo_sendfile, 316 .fo_fill_kinfo = cryptof_fill_kinfo, 317}; 318 319static struct csession *csefind(struct fcrypt *, u_int); 320static int csedelete(struct fcrypt *, struct csession *); 321static struct csession *cseadd(struct fcrypt *, struct csession *); 322static struct csession *csecreate(struct fcrypt *, u_int64_t, caddr_t, 323 u_int64_t, caddr_t, u_int64_t, u_int32_t, u_int32_t, struct enc_xform *, 324 struct auth_hash *); 325static int csefree(struct csession *); 326 327static int cryptodev_op(struct csession *, struct crypt_op *, 328 struct ucred *, struct thread *td); 329static int cryptodev_aead(struct csession *, struct crypt_aead *, 330 struct ucred *, struct thread *); 331static int cryptodev_key(struct crypt_kop *); 332static int cryptodev_find(struct crypt_find_op *); 333 334/* 335 * Check a crypto identifier to see if it requested 336 * a software device/driver. This can be done either 337 * by device name/class or through search constraints. 338 */ 339static int 340checkforsoftware(int *cridp) 341{ 342 int crid; 343 344 crid = *cridp; 345 346 if (!crypto_devallowsoft) { 347 if (crid & CRYPTOCAP_F_SOFTWARE) { 348 if (crid & CRYPTOCAP_F_HARDWARE) { 349 *cridp = CRYPTOCAP_F_HARDWARE; 350 return 0; 351 } 352 return EINVAL; 353 } 354 if ((crid & CRYPTOCAP_F_HARDWARE) == 0 && 355 (crypto_getcaps(crid) & CRYPTOCAP_F_HARDWARE) == 0) 356 return EINVAL; 357 } 358 return 0; 359} 360 361/* ARGSUSED */ 362static int 363cryptof_ioctl( 364 struct file *fp, 365 u_long cmd, 366 void *data, 367 struct ucred *active_cred, 368 struct thread *td) 369{ 370#define SES2(p) ((struct session2_op *)p) 371 struct cryptoini cria, crie; 372 struct fcrypt *fcr = fp->f_data; 373 struct csession *cse; 374 struct session_op *sop; 375 struct crypt_op *cop; 376 struct crypt_aead *caead; 377 struct enc_xform *txform = NULL; 378 struct auth_hash *thash = NULL; 379 struct crypt_kop *kop; 380 u_int64_t sid; 381 u_int32_t ses; 382 int error = 0, crid; 383#ifdef COMPAT_FREEBSD32 384 struct session2_op sopc; 385 struct crypt_op copc; 386 struct crypt_kop kopc; 387#endif 388 389 switch (cmd) { 390 case CIOCGSESSION: 391 case CIOCGSESSION2: 392#ifdef COMPAT_FREEBSD32 393 case CIOCGSESSION32: 394 case CIOCGSESSION232: 395 if (cmd == CIOCGSESSION32) { 396 session_op_from_32(data, (struct session_op *)&sopc); 397 sop = (struct session_op *)&sopc; 398 } else if (cmd == CIOCGSESSION232) { 399 session2_op_from_32(data, &sopc); 400 sop = (struct session_op *)&sopc; 401 } else 402#endif 403 sop = (struct session_op *)data; 404 switch (sop->cipher) { 405 case 0: 406 break; 407 case CRYPTO_DES_CBC: 408 txform = &enc_xform_des; 409 break; 410 case CRYPTO_3DES_CBC: 411 txform = &enc_xform_3des; 412 break; 413 case CRYPTO_BLF_CBC: 414 txform = &enc_xform_blf; 415 break; 416 case CRYPTO_CAST_CBC: 417 txform = &enc_xform_cast5; 418 break; 419 case CRYPTO_SKIPJACK_CBC: 420 txform = &enc_xform_skipjack; 421 break; 422 case CRYPTO_AES_CBC: 423 txform = &enc_xform_rijndael128; 424 break; 425 case CRYPTO_AES_XTS: 426 txform = &enc_xform_aes_xts; 427 break; 428 case CRYPTO_NULL_CBC: 429 txform = &enc_xform_null; 430 break; 431 case CRYPTO_ARC4: 432 txform = &enc_xform_arc4; 433 break; 434 case CRYPTO_CAMELLIA_CBC: 435 txform = &enc_xform_camellia; 436 break; 437 case CRYPTO_AES_ICM: 438 txform = &enc_xform_aes_icm; 439 break; 440 case CRYPTO_AES_NIST_GCM_16: 441 txform = &enc_xform_aes_nist_gcm; 442 break; 443 444 default: 445 CRYPTDEB("invalid cipher"); 446 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 447 return (EINVAL); 448 } 449 450 switch (sop->mac) { 451 case 0: 452 break; 453 case CRYPTO_MD5_HMAC: 454 thash = &auth_hash_hmac_md5; 455 break; 456 case CRYPTO_SHA1_HMAC: 457 thash = &auth_hash_hmac_sha1; 458 break; 459 case CRYPTO_SHA2_256_HMAC: 460 thash = &auth_hash_hmac_sha2_256; 461 break; 462 case CRYPTO_SHA2_384_HMAC: 463 thash = &auth_hash_hmac_sha2_384; 464 break; 465 case CRYPTO_SHA2_512_HMAC: 466 thash = &auth_hash_hmac_sha2_512; 467 break; 468 case CRYPTO_RIPEMD160_HMAC: 469 thash = &auth_hash_hmac_ripemd_160; 470 break; 471 case CRYPTO_AES_128_NIST_GMAC: 472 thash = &auth_hash_nist_gmac_aes_128; 473 break; 474 case CRYPTO_AES_192_NIST_GMAC: 475 thash = &auth_hash_nist_gmac_aes_192; 476 break; 477 case CRYPTO_AES_256_NIST_GMAC: 478 thash = &auth_hash_nist_gmac_aes_256; 479 break; 480 481#ifdef notdef 482 case CRYPTO_MD5: 483 thash = &auth_hash_md5; 484 break; 485 case CRYPTO_SHA1: 486 thash = &auth_hash_sha1; 487 break; 488#endif 489 case CRYPTO_NULL_HMAC: 490 thash = &auth_hash_null; 491 break; 492 default: 493 CRYPTDEB("invalid mac"); 494 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 495 return (EINVAL); 496 } 497 498 bzero(&crie, sizeof(crie)); 499 bzero(&cria, sizeof(cria)); 500 501 if (txform) { 502 crie.cri_alg = txform->type; 503 crie.cri_klen = sop->keylen * 8; 504 if (sop->keylen > txform->maxkey || 505 sop->keylen < txform->minkey) { 506 CRYPTDEB("invalid cipher parameters"); 507 error = EINVAL; 508 SDT_PROBE1(opencrypto, dev, ioctl, error, 509 __LINE__); 510 goto bail; 511 } 512 513 crie.cri_key = malloc(crie.cri_klen / 8, 514 M_XDATA, M_WAITOK); 515 if ((error = copyin(sop->key, crie.cri_key, 516 crie.cri_klen / 8))) { 517 CRYPTDEB("invalid key"); 518 SDT_PROBE1(opencrypto, dev, ioctl, error, 519 __LINE__); 520 goto bail; 521 } 522 if (thash) 523 crie.cri_next = &cria; 524 } 525 526 if (thash) { 527 cria.cri_alg = thash->type; 528 cria.cri_klen = sop->mackeylen * 8; 529 if (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 } 593bail: 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 711static int cryptodev_cb(void *); 712 713 714static int 715cryptodev_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) { 760 crda = crp->crp_desc; 761 if (cse->txform) 762 crde = crda->crd_next; 763 } else { 764 if (cse->txform) 765 crde = crp->crp_desc; 766 else { 767 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 768 error = EINVAL; 769 goto bail; 770 } 771 } 772 773 if ((error = copyin(cop->src, cse->uio.uio_iov[0].iov_base, 774 cop->len))) { 775 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 776 goto bail; 777 } 778 779 if (crda) { 780 crda->crd_skip = 0; 781 crda->crd_len = cop->len; 782 crda->crd_inject = cop->len; 783 784 crda->crd_alg = cse->mac; 785 crda->crd_key = cse->mackey; 786 crda->crd_klen = cse->mackeylen * 8; 787 } 788 789 if (crde) { 790 if (cop->op == COP_ENCRYPT) 791 crde->crd_flags |= CRD_F_ENCRYPT; 792 else 793 crde->crd_flags &= ~CRD_F_ENCRYPT; 794 crde->crd_len = cop->len; 795 crde->crd_inject = 0; 796 797 crde->crd_alg = cse->cipher; 798 crde->crd_key = cse->key; 799 crde->crd_klen = cse->keylen * 8; 800 } 801 802 crp->crp_ilen = cop->len; 803 crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM 804 | (cop->flags & COP_F_BATCH); 805 crp->crp_buf = (caddr_t)&cse->uio; 806 crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb; 807 crp->crp_sid = cse->sid; 808 crp->crp_opaque = (void *)cse; 809 810 if (cop->iv) { 811 if (crde == NULL) { 812 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 813 error = EINVAL; 814 goto bail; 815 } 816 if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */ 817 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 818 error = EINVAL; 819 goto bail; 820 } 821 if ((error = copyin(cop->iv, cse->tmp_iv, 822 cse->txform->blocksize))) { 823 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 824 goto bail; 825 } 826 bcopy(cse->tmp_iv, crde->crd_iv, cse->txform->blocksize); 827 crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; 828 crde->crd_skip = 0; 829 } else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */ 830 crde->crd_skip = 0; 831 } else if (crde) { 832 crde->crd_flags |= CRD_F_IV_PRESENT; 833 crde->crd_skip = cse->txform->blocksize; 834 crde->crd_len -= cse->txform->blocksize; 835 } 836 837 if (cop->mac && crda == NULL) { 838 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 839 error = EINVAL; 840 goto bail; 841 } 842 843again: 844 /* 845 * Let the dispatch run unlocked, then, interlock against the 846 * callback before checking if the operation completed and going 847 * to sleep. This insures drivers don't inherit our lock which 848 * results in a lock order reversal between crypto_dispatch forced 849 * entry and the crypto_done callback into us. 850 */ 851 error = crypto_dispatch(crp); 852 mtx_lock(&cse->lock); 853 if (error == 0 && (crp->crp_flags & CRYPTO_F_DONE) == 0) 854 error = msleep(crp, &cse->lock, PWAIT, "crydev", 0); 855 mtx_unlock(&cse->lock); 856 857 if (error != 0) { 858 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 859 goto bail; 860 } 861 862 if (crp->crp_etype == EAGAIN) { 863 crp->crp_etype = 0; 864 crp->crp_flags &= ~CRYPTO_F_DONE; 865 goto again; 866 } 867 868 if (crp->crp_etype != 0) { 869 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 870 error = crp->crp_etype; 871 goto bail; 872 } 873 874 if (cse->error) { 875 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 876 error = cse->error; 877 goto bail; 878 } 879 880 if (cop->dst && 881 (error = copyout(cse->uio.uio_iov[0].iov_base, cop->dst, 882 cop->len))) { 883 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 884 goto bail; 885 } 886 887 if (cop->mac && 888 (error = copyout((caddr_t)cse->uio.uio_iov[0].iov_base + cop->len, 889 cop->mac, cse->thash->hashsize))) { 890 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 891 goto bail; 892 } 893 894bail: 895 if (crp) 896 crypto_freereq(crp); 897 if (cse->uio.uio_iov[0].iov_base) 898 free(cse->uio.uio_iov[0].iov_base, M_XDATA); 899 900 return (error); 901} 902 903static int 904cryptodev_aead( 905 struct csession *cse, 906 struct crypt_aead *caead, 907 struct ucred *active_cred, 908 struct thread *td) 909{ 910 struct uio *uio; 911 struct cryptop *crp = NULL; 912 struct cryptodesc *crde = NULL, *crda = NULL; 913 int error; 914 915 if (caead->len > 256*1024-4 || caead->aadlen > 256*1024-4) { 916 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 917 return (E2BIG); 918 } 919 920 if (cse->txform == NULL || cse->thash == NULL || caead->tag == NULL || 921 (caead->len % cse->txform->blocksize) != 0) { 922 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 923 return (EINVAL); 924 } 925 926 uio = &cse->uio; 927 uio->uio_iov = &cse->iovec; 928 uio->uio_iovcnt = 1; 929 uio->uio_offset = 0; 930 uio->uio_resid = caead->aadlen + caead->len + cse->thash->hashsize; 931 uio->uio_segflg = UIO_SYSSPACE; 932 uio->uio_rw = UIO_WRITE; 933 uio->uio_td = td; 934 uio->uio_iov[0].iov_len = uio->uio_resid; 935 936 uio->uio_iov[0].iov_base = malloc(uio->uio_iov[0].iov_len, 937 M_XDATA, M_WAITOK); 938 939 crp = crypto_getreq(2); 940 if (crp == NULL) { 941 error = ENOMEM; 942 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 943 goto bail; 944 } 945 946 crda = crp->crp_desc; 947 crde = crda->crd_next; 948 949 if ((error = copyin(caead->aad, cse->uio.uio_iov[0].iov_base, 950 caead->aadlen))) { 951 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 952 goto bail; 953 } 954 955 if ((error = copyin(caead->src, (char *)cse->uio.uio_iov[0].iov_base + 956 caead->aadlen, caead->len))) { 957 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 958 goto bail; 959 } 960 961 crda->crd_skip = 0; 962 crda->crd_len = caead->aadlen; 963 crda->crd_inject = caead->aadlen + caead->len; 964 965 crda->crd_alg = cse->mac; 966 crda->crd_key = cse->mackey; 967 crda->crd_klen = cse->mackeylen * 8; 968 969 if (caead->op == COP_ENCRYPT) 970 crde->crd_flags |= CRD_F_ENCRYPT; 971 else 972 crde->crd_flags &= ~CRD_F_ENCRYPT; 973 crde->crd_skip = caead->aadlen; 974 crde->crd_len = caead->len; 975 crde->crd_inject = caead->aadlen; 976 977 crde->crd_alg = cse->cipher; 978 crde->crd_key = cse->key; 979 crde->crd_klen = cse->keylen * 8; 980 981 crp->crp_ilen = caead->aadlen + caead->len; 982 crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM 983 | (caead->flags & COP_F_BATCH); 984 crp->crp_buf = (caddr_t)&cse->uio.uio_iov; 985 crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb; 986 crp->crp_sid = cse->sid; 987 crp->crp_opaque = (void *)cse; 988 989 if (caead->iv) { 990 if (caead->ivlen > sizeof cse->tmp_iv) { 991 error = EINVAL; 992 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 993 goto bail; 994 } 995 996 if ((error = copyin(caead->iv, cse->tmp_iv, caead->ivlen))) { 997 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 998 goto bail; 999 } 1000 bcopy(cse->tmp_iv, crde->crd_iv, caead->ivlen); 1001 crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; 1002 } else { 1003 crde->crd_flags |= CRD_F_IV_PRESENT; 1004 crde->crd_skip += cse->txform->blocksize; 1005 crde->crd_len -= cse->txform->blocksize; 1006 } 1007 1008 if ((error = copyin(caead->tag, (caddr_t)cse->uio.uio_iov[0].iov_base + 1009 caead->len + caead->aadlen, cse->thash->hashsize))) { 1010 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1011 goto bail; 1012 } 1013again: 1014 /* 1015 * Let the dispatch run unlocked, then, interlock against the 1016 * callback before checking if the operation completed and going 1017 * to sleep. This insures drivers don't inherit our lock which 1018 * results in a lock order reversal between crypto_dispatch forced 1019 * entry and the crypto_done callback into us. 1020 */ 1021 error = crypto_dispatch(crp); 1022 mtx_lock(&cse->lock); 1023 if (error == 0 && (crp->crp_flags & CRYPTO_F_DONE) == 0) 1024 error = msleep(crp, &cse->lock, PWAIT, "crydev", 0); 1025 mtx_unlock(&cse->lock); 1026 1027 if (error != 0) { 1028 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1029 goto bail; 1030 } 1031 1032 if (crp->crp_etype == EAGAIN) { 1033 crp->crp_etype = 0; 1034 crp->crp_flags &= ~CRYPTO_F_DONE; 1035 goto again; 1036 } 1037 1038 if (crp->crp_etype != 0) { 1039 error = crp->crp_etype; 1040 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1041 goto bail; 1042 } 1043 1044 if (cse->error) { 1045 error = cse->error; 1046 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1047 goto bail; 1048 } 1049 1050 if (caead->dst && (error = copyout( 1051 (caddr_t)cse->uio.uio_iov[0].iov_base + caead->aadlen, caead->dst, 1052 caead->len))) { 1053 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1054 goto bail; 1055 } 1056 1057 if ((error = copyout((caddr_t)cse->uio.uio_iov[0].iov_base + 1058 caead->aadlen + caead->len, caead->tag, cse->thash->hashsize))) { 1059 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1060 goto bail; 1061 } 1062 1063bail: 1064 crypto_freereq(crp); 1065 free(cse->uio.uio_iov[0].iov_base, M_XDATA); 1066 1067 return (error); 1068} 1069 1070static int 1071cryptodev_cb(void *op) 1072{ 1073 struct cryptop *crp = (struct cryptop *) op; 1074 struct csession *cse = (struct csession *)crp->crp_opaque; 1075 1076 mtx_lock(&cse->lock); 1077 cse->error = crp->crp_etype; 1078 wakeup_one(crp); 1079 mtx_unlock(&cse->lock); 1080 return (0); 1081} 1082 1083static int 1084cryptodevkey_cb(void *op) 1085{ 1086 struct cryptkop *krp = (struct cryptkop *) op; 1087 1088 wakeup_one(krp); 1089 return (0); 1090} 1091 1092static int 1093cryptodev_key(struct crypt_kop *kop) 1094{ 1095 struct cryptkop *krp = NULL; 1096 int error = EINVAL; 1097 int in, out, size, i; 1098 1099 if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) { 1100 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1101 return (EFBIG); 1102 } 1103 1104 in = kop->crk_iparams; 1105 out = kop->crk_oparams; 1106 switch (kop->crk_op) { 1107 case CRK_MOD_EXP: 1108 if (in == 3 && out == 1) 1109 break; 1110 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1111 return (EINVAL); 1112 case CRK_MOD_EXP_CRT: 1113 if (in == 6 && out == 1) 1114 break; 1115 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1116 return (EINVAL); 1117 case CRK_DSA_SIGN: 1118 if (in == 5 && out == 2) 1119 break; 1120 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1121 return (EINVAL); 1122 case CRK_DSA_VERIFY: 1123 if (in == 7 && out == 0) 1124 break; 1125 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1126 return (EINVAL); 1127 case CRK_DH_COMPUTE_KEY: 1128 if (in == 3 && out == 1) 1129 break; 1130 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1131 return (EINVAL); 1132 default: 1133 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1134 return (EINVAL); 1135 } 1136 1137 krp = (struct cryptkop *)malloc(sizeof *krp, M_XDATA, M_WAITOK|M_ZERO); 1138 if (!krp) { 1139 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1140 return (ENOMEM); 1141 } 1142 krp->krp_op = kop->crk_op; 1143 krp->krp_status = kop->crk_status; 1144 krp->krp_iparams = kop->crk_iparams; 1145 krp->krp_oparams = kop->crk_oparams; 1146 krp->krp_crid = kop->crk_crid; 1147 krp->krp_status = 0; 1148 krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb; 1149 1150 for (i = 0; i < CRK_MAXPARAM; i++) { 1151 if (kop->crk_param[i].crp_nbits > 65536) { 1152 /* Limit is the same as in OpenBSD */ 1153 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1154 goto fail; 1155 } 1156 krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits; 1157 } 1158 for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) { 1159 size = (krp->krp_param[i].crp_nbits + 7) / 8; 1160 if (size == 0) 1161 continue; 1162 krp->krp_param[i].crp_p = malloc(size, M_XDATA, M_WAITOK); 1163 if (i >= krp->krp_iparams) 1164 continue; 1165 error = copyin(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p, size); 1166 if (error) { 1167 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1168 goto fail; 1169 } 1170 } 1171 1172 error = crypto_kdispatch(krp); 1173 if (error) { 1174 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1175 goto fail; 1176 } 1177 error = tsleep(krp, PSOCK, "crydev", 0); 1178 if (error) { 1179 /* XXX can this happen? if so, how do we recover? */ 1180 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1181 goto fail; 1182 } 1183 1184 kop->crk_crid = krp->krp_crid; /* device that did the work */ 1185 if (krp->krp_status != 0) { 1186 error = krp->krp_status; 1187 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1188 goto fail; 1189 } 1190 1191 for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) { 1192 size = (krp->krp_param[i].crp_nbits + 7) / 8; 1193 if (size == 0) 1194 continue; 1195 error = copyout(krp->krp_param[i].crp_p, kop->crk_param[i].crp_p, size); 1196 if (error) { 1197 SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); 1198 goto fail; 1199 } 1200 } 1201 1202fail: 1203 if (krp) { 1204 kop->crk_status = krp->krp_status; 1205 for (i = 0; i < CRK_MAXPARAM; i++) { 1206 if (krp->krp_param[i].crp_p) 1207 free(krp->krp_param[i].crp_p, M_XDATA); 1208 } 1209 free(krp, M_XDATA); 1210 } 1211 return (error); 1212} 1213 1214static int 1215cryptodev_find(struct crypt_find_op *find) 1216{ 1217 device_t dev; 1218 size_t fnlen = sizeof find->name; 1219 1220 if (find->crid != -1) { 1221 dev = crypto_find_device_byhid(find->crid); 1222 if (dev == NULL) 1223 return (ENOENT); 1224 strncpy(find->name, device_get_nameunit(dev), fnlen); 1225 find->name[fnlen - 1] = '\x0'; 1226 } else { 1227 find->name[fnlen - 1] = '\x0'; 1228 find->crid = crypto_find_driver(find->name); 1229 if (find->crid == -1) 1230 return (ENOENT); 1231 } 1232 return (0); 1233} 1234 1235/* ARGSUSED */ 1236static int 1237cryptof_stat( 1238 struct file *fp, 1239 struct stat *sb, 1240 struct ucred *active_cred, 1241 struct thread *td) 1242{ 1243 1244 return (EOPNOTSUPP); 1245} 1246 1247/* ARGSUSED */ 1248static int 1249cryptof_close(struct file *fp, struct thread *td) 1250{ 1251 struct fcrypt *fcr = fp->f_data; 1252 struct csession *cse; 1253 1254 while ((cse = TAILQ_FIRST(&fcr->csessions))) { 1255 TAILQ_REMOVE(&fcr->csessions, cse, next); 1256 (void)csefree(cse); 1257 } 1258 free(fcr, M_XDATA); 1259 fp->f_data = NULL; 1260 return 0; 1261} 1262 1263static int 1264cryptof_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp) 1265{ 1266 1267 kif->kf_type = KF_TYPE_CRYPTO; 1268 return (0); 1269} 1270 1271static struct csession * 1272csefind(struct fcrypt *fcr, u_int ses) 1273{ 1274 struct csession *cse; 1275 1276 TAILQ_FOREACH(cse, &fcr->csessions, next) 1277 if (cse->ses == ses) 1278 return (cse); 1279 return (NULL); 1280} 1281 1282static int 1283csedelete(struct fcrypt *fcr, struct csession *cse_del) 1284{ 1285 struct csession *cse; 1286 1287 TAILQ_FOREACH(cse, &fcr->csessions, next) { 1288 if (cse == cse_del) { 1289 TAILQ_REMOVE(&fcr->csessions, cse, next); 1290 return (1); 1291 } 1292 } 1293 return (0); 1294} 1295 1296static struct csession * 1297cseadd(struct fcrypt *fcr, struct csession *cse) 1298{ 1299 TAILQ_INSERT_TAIL(&fcr->csessions, cse, next); 1300 cse->ses = fcr->sesn++; 1301 return (cse); 1302} 1303 1304struct csession * 1305csecreate(struct fcrypt *fcr, u_int64_t sid, caddr_t key, u_int64_t keylen, 1306 caddr_t mackey, u_int64_t mackeylen, u_int32_t cipher, u_int32_t mac, 1307 struct enc_xform *txform, struct auth_hash *thash) 1308{ 1309 struct csession *cse; 1310 1311 cse = malloc(sizeof(struct csession), M_XDATA, M_NOWAIT | M_ZERO); 1312 if (cse == NULL) 1313 return NULL; 1314 mtx_init(&cse->lock, "cryptodev", "crypto session lock", MTX_DEF); 1315 cse->key = key; 1316 cse->keylen = keylen/8; 1317 cse->mackey = mackey; 1318 cse->mackeylen = mackeylen/8; 1319 cse->sid = sid; 1320 cse->cipher = cipher; 1321 cse->mac = mac; 1322 cse->txform = txform; 1323 cse->thash = thash; 1324 cseadd(fcr, cse); 1325 return (cse); 1326} 1327 1328static int 1329csefree(struct csession *cse) 1330{ 1331 int error; 1332 1333 error = crypto_freesession(cse->sid); 1334 mtx_destroy(&cse->lock); 1335 if (cse->key) 1336 free(cse->key, M_XDATA); 1337 if (cse->mackey) 1338 free(cse->mackey, M_XDATA); 1339 free(cse, M_XDATA); 1340 return (error); 1341} 1342 1343static int 1344cryptoopen(struct cdev *dev, int oflags, int devtype, struct thread *td) 1345{ 1346 return (0); 1347} 1348 1349static int 1350cryptoread(struct cdev *dev, struct uio *uio, int ioflag) 1351{ 1352 return (EIO); 1353} 1354 1355static int 1356cryptowrite(struct cdev *dev, struct uio *uio, int ioflag) 1357{ 1358 return (EIO); 1359} 1360 1361static int 1362cryptoioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) 1363{ 1364 struct file *f; 1365 struct fcrypt *fcr; 1366 int fd, error; 1367 1368 switch (cmd) { 1369 case CRIOGET: 1370 fcr = malloc(sizeof(struct fcrypt), M_XDATA, M_WAITOK); 1371 TAILQ_INIT(&fcr->csessions); 1372 fcr->sesn = 0; 1373 1374 error = falloc(td, &f, &fd, 0); 1375 1376 if (error) { 1377 free(fcr, M_XDATA); 1378 return (error); 1379 } 1380 /* falloc automatically provides an extra reference to 'f'. */ 1381 finit(f, FREAD | FWRITE, DTYPE_CRYPTO, fcr, &cryptofops); 1382 *(u_int32_t *)data = fd; 1383 fdrop(f, td); 1384 break; 1385 case CRIOFINDDEV: 1386 error = cryptodev_find((struct crypt_find_op *)data); 1387 break; 1388 case CRIOASYMFEAT: 1389 error = crypto_getfeat((int *)data); 1390 break; 1391 default: 1392 error = EINVAL; 1393 break; 1394 } 1395 return (error); 1396} 1397 1398static struct cdevsw crypto_cdevsw = { 1399 .d_version = D_VERSION, 1400 .d_flags = D_NEEDGIANT, 1401 .d_open = cryptoopen, 1402 .d_read = cryptoread, 1403 .d_write = cryptowrite, 1404 .d_ioctl = cryptoioctl, 1405 .d_name = "crypto", 1406}; 1407static struct cdev *crypto_dev; 1408 1409/* 1410 * Initialization code, both for static and dynamic loading. 1411 */ 1412static int 1413cryptodev_modevent(module_t mod, int type, void *unused) 1414{ 1415 switch (type) { 1416 case MOD_LOAD: 1417 if (bootverbose) 1418 printf("crypto: <crypto device>\n"); 1419 crypto_dev = make_dev(&crypto_cdevsw, 0, 1420 UID_ROOT, GID_WHEEL, 0666, 1421 "crypto"); 1422 return 0; 1423 case MOD_UNLOAD: 1424 /*XXX disallow if active sessions */ 1425 destroy_dev(crypto_dev); 1426 return 0; 1427 } 1428 return EINVAL; 1429} 1430 1431static moduledata_t cryptodev_mod = { 1432 "cryptodev", 1433 cryptodev_modevent, 1434 0 1435}; 1436MODULE_VERSION(cryptodev, 1); 1437DECLARE_MODULE(cryptodev, cryptodev_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 1438MODULE_DEPEND(cryptodev, crypto, 1, 1, 1); 1439MODULE_DEPEND(cryptodev, zlib, 1, 1, 1); 1440