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