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