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 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Effort sponsored in part by the Defense Advanced Research Projects 31 * Agency (DARPA) and Air Force Research Laboratory, Air Force 32 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 33 */ 34 35 #include <sys/cdefs.h> 36 __FBSDID("$FreeBSD$"); 37 38 #include "opt_compat.h" 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/malloc.h> 43 #include <sys/mbuf.h> 44 #include <sys/lock.h> 45 #include <sys/mutex.h> 46 #include <sys/sysctl.h> 47 #include <sys/file.h> 48 #include <sys/filedesc.h> 49 #include <sys/errno.h> 50 #include <sys/uio.h> 51 #include <sys/random.h> 52 #include <sys/conf.h> 53 #include <sys/kernel.h> 54 #include <sys/module.h> 55 #include <sys/fcntl.h> 56 #include <sys/bus.h> 57 58 #include <opencrypto/cryptodev.h> 59 #include <opencrypto/xform.h> 60 61 #ifdef COMPAT_FREEBSD32 62 #include <sys/mount.h> 63 #include <compat/freebsd32/freebsd32.h> 64 65 struct session_op32 { 66 u_int32_t cipher; 67 u_int32_t mac; 68 u_int32_t keylen; 69 u_int32_t key; 70 int mackeylen; 71 u_int32_t mackey; 72 u_int32_t ses; 73 }; 74 75 struct session2_op32 { 76 u_int32_t cipher; 77 u_int32_t mac; 78 u_int32_t keylen; 79 u_int32_t key; 80 int mackeylen; 81 u_int32_t mackey; 82 u_int32_t ses; 83 int crid; 84 int pad[4]; 85 }; 86 87 struct crypt_op32 { 88 u_int32_t ses; 89 u_int16_t op; 90 u_int16_t flags; 91 u_int len; 92 u_int32_t src, dst; 93 u_int32_t mac; 94 u_int32_t iv; 95 }; 96 97 struct crparam32 { 98 u_int32_t crp_p; 99 u_int crp_nbits; 100 }; 101 102 struct crypt_kop32 { 103 u_int crk_op; 104 u_int crk_status; 105 u_short crk_iparams; 106 u_short crk_oparams; 107 u_int crk_crid; 108 struct crparam32 crk_param[CRK_MAXPARAM]; 109 }; 110 111 struct cryptotstat32 { 112 struct timespec32 acc; 113 struct timespec32 min; 114 struct timespec32 max; 115 u_int32_t count; 116 }; 117 118 struct cryptostats32 { 119 u_int32_t cs_ops; 120 u_int32_t cs_errs; 121 u_int32_t cs_kops; 122 u_int32_t cs_kerrs; 123 u_int32_t cs_intrs; 124 u_int32_t cs_rets; 125 u_int32_t cs_blocks; 126 u_int32_t cs_kblocks; 127 struct cryptotstat32 cs_invoke; 128 struct cryptotstat32 cs_done; 129 struct cryptotstat32 cs_cb; 130 struct cryptotstat32 cs_finis; 131 }; 132 133 #define CIOCGSESSION32 _IOWR('c', 101, struct session_op32) 134 #define CIOCCRYPT32 _IOWR('c', 103, struct crypt_op32) 135 #define CIOCKEY32 _IOWR('c', 104, struct crypt_kop32) 136 #define CIOCGSESSION232 _IOWR('c', 106, struct session2_op32) 137 #define CIOCKEY232 _IOWR('c', 107, struct crypt_kop32) 138 139 static void 140 session_op_from_32(const struct session_op32 *from, struct session_op *to) 141 { 142 143 CP(*from, *to, cipher); 144 CP(*from, *to, mac); 145 CP(*from, *to, keylen); 146 PTRIN_CP(*from, *to, key); 147 CP(*from, *to, mackeylen); 148 PTRIN_CP(*from, *to, mackey); 149 CP(*from, *to, ses); 150 } 151 152 static void 153 session2_op_from_32(const struct session2_op32 *from, struct session2_op *to) 154 { 155 156 session_op_from_32((const struct session_op32 *)from, 157 (struct session_op *)to); 158 CP(*from, *to, crid); 159 } 160 161 static void 162 session_op_to_32(const struct session_op *from, struct session_op32 *to) 163 { 164 165 CP(*from, *to, cipher); 166 CP(*from, *to, mac); 167 CP(*from, *to, keylen); 168 PTROUT_CP(*from, *to, key); 169 CP(*from, *to, mackeylen); 170 PTROUT_CP(*from, *to, mackey); 171 CP(*from, *to, ses); 172 } 173 174 static void 175 session2_op_to_32(const struct session2_op *from, struct session2_op32 *to) 176 { 177 178 session_op_to_32((const struct session_op *)from, 179 (struct session_op32 *)to); 180 CP(*from, *to, crid); 181 } 182 183 static void 184 crypt_op_from_32(const struct crypt_op32 *from, struct crypt_op *to) 185 { 186 187 CP(*from, *to, ses); 188 CP(*from, *to, op); 189 CP(*from, *to, flags); 190 CP(*from, *to, len); 191 PTRIN_CP(*from, *to, src); 192 PTRIN_CP(*from, *to, dst); 193 PTRIN_CP(*from, *to, mac); 194 PTRIN_CP(*from, *to, iv); 195 } 196 197 static void 198 crypt_op_to_32(const struct crypt_op *from, struct crypt_op32 *to) 199 { 200 201 CP(*from, *to, ses); 202 CP(*from, *to, op); 203 CP(*from, *to, flags); 204 CP(*from, *to, len); 205 PTROUT_CP(*from, *to, src); 206 PTROUT_CP(*from, *to, dst); 207 PTROUT_CP(*from, *to, mac); 208 PTROUT_CP(*from, *to, iv); 209 } 210 211 static void 212 crparam_from_32(const struct crparam32 *from, struct crparam *to) 213 { 214 215 PTRIN_CP(*from, *to, crp_p); 216 CP(*from, *to, crp_nbits); 217 } 218 219 static void 220 crparam_to_32(const struct crparam *from, struct crparam32 *to) 221 { 222 223 PTROUT_CP(*from, *to, crp_p); 224 CP(*from, *to, crp_nbits); 225 } 226 227 static void 228 crypt_kop_from_32(const struct crypt_kop32 *from, struct crypt_kop *to) 229 { 230 int i; 231 232 CP(*from, *to, crk_op); 233 CP(*from, *to, crk_status); 234 CP(*from, *to, crk_iparams); 235 CP(*from, *to, crk_oparams); 236 CP(*from, *to, crk_crid); 237 for (i = 0; i < CRK_MAXPARAM; i++) 238 crparam_from_32(&from->crk_param[i], &to->crk_param[i]); 239 } 240 241 static void 242 crypt_kop_to_32(const struct crypt_kop *from, struct crypt_kop32 *to) 243 { 244 int i; 245 246 CP(*from, *to, crk_op); 247 CP(*from, *to, crk_status); 248 CP(*from, *to, crk_iparams); 249 CP(*from, *to, crk_oparams); 250 CP(*from, *to, crk_crid); 251 for (i = 0; i < CRK_MAXPARAM; i++) 252 crparam_to_32(&from->crk_param[i], &to->crk_param[i]); 253 } 254 #endif 255 256 struct csession { 257 TAILQ_ENTRY(csession) next; 258 u_int64_t sid; 259 u_int32_t ses; 260 struct mtx lock; /* for op submission */ 261 262 u_int32_t cipher; 263 struct enc_xform *txform; 264 u_int32_t mac; 265 struct auth_hash *thash; 266 267 caddr_t key; 268 int keylen; 269 u_char tmp_iv[EALG_MAX_BLOCK_LEN]; 270 271 caddr_t mackey; 272 int mackeylen; 273 274 struct iovec iovec; 275 struct uio uio; 276 int error; 277 }; 278 279 struct fcrypt { 280 TAILQ_HEAD(csessionlist, csession) csessions; 281 int sesn; 282 }; 283 284 static int cryptof_ioctl(struct file *, u_long, void *, 285 struct ucred *, struct thread *); 286 static int cryptof_stat(struct file *, struct stat *, 287 struct ucred *, struct thread *); 288 static int cryptof_close(struct file *, struct thread *); 289 290 static struct fileops cryptofops = { 291 .fo_read = invfo_rdwr, 292 .fo_write = invfo_rdwr, 293 .fo_truncate = invfo_truncate, 294 .fo_ioctl = cryptof_ioctl, 295 .fo_poll = invfo_poll, 296 .fo_kqfilter = invfo_kqfilter, 297 .fo_stat = cryptof_stat, 298 .fo_close = cryptof_close, 299 .fo_chmod = invfo_chmod, 300 .fo_chown = invfo_chown, 301 .fo_sendfile = invfo_sendfile, 302 }; 303 304 static struct csession *csefind(struct fcrypt *, u_int); 305 static int csedelete(struct fcrypt *, struct csession *); 306 static struct csession *cseadd(struct fcrypt *, struct csession *); 307 static struct csession *csecreate(struct fcrypt *, u_int64_t, caddr_t, 308 u_int64_t, caddr_t, u_int64_t, u_int32_t, u_int32_t, struct enc_xform *, 309 struct auth_hash *); 310 static int csefree(struct csession *); 311 312 static int cryptodev_op(struct csession *, struct crypt_op *, 313 struct ucred *, struct thread *td); 314 static int cryptodev_key(struct crypt_kop *); 315 static int cryptodev_find(struct crypt_find_op *); 316 317 /* 318 * Check a crypto identifier to see if it requested 319 * a software device/driver. This can be done either 320 * by device name/class or through search constraints. 321 */ 322 static int 323 checkforsoftware(int crid) 324 { 325 326 if (!crypto_devallowsoft) { 327 if (crid & CRYPTOCAP_F_SOFTWARE) 328 return EINVAL; /* XXX */ 329 if ((crid & CRYPTOCAP_F_HARDWARE) == 0 && 330 (crypto_getcaps(crid) & CRYPTOCAP_F_HARDWARE) == 0) 331 return EINVAL; /* XXX */ 332 } 333 return 0; 334 } 335 336 /* ARGSUSED */ 337 static int 338 cryptof_ioctl( 339 struct file *fp, 340 u_long cmd, 341 void *data, 342 struct ucred *active_cred, 343 struct thread *td) 344 { 345 #define SES2(p) ((struct session2_op *)p) 346 struct cryptoini cria, crie; 347 struct fcrypt *fcr = fp->f_data; 348 struct csession *cse; 349 struct session_op *sop; 350 struct crypt_op *cop; 351 struct enc_xform *txform = NULL; 352 struct auth_hash *thash = NULL; 353 struct crypt_kop *kop; 354 u_int64_t sid; 355 u_int32_t ses; 356 int error = 0, crid; 357 #ifdef COMPAT_FREEBSD32 358 struct session2_op sopc; 359 struct crypt_op copc; 360 struct crypt_kop kopc; 361 #endif 362 363 switch (cmd) { 364 case CIOCGSESSION: 365 case CIOCGSESSION2: 366 #ifdef COMPAT_FREEBSD32 367 case CIOCGSESSION32: 368 case CIOCGSESSION232: 369 if (cmd == CIOCGSESSION32) { 370 session_op_from_32(data, (struct session_op *)&sopc); 371 sop = (struct session_op *)&sopc; 372 } else if (cmd == CIOCGSESSION232) { 373 session2_op_from_32(data, &sopc); 374 sop = (struct session_op *)&sopc; 375 } else 376 #endif 377 sop = (struct session_op *)data; 378 switch (sop->cipher) { 379 case 0: 380 break; 381 case CRYPTO_DES_CBC: 382 txform = &enc_xform_des; 383 break; 384 case CRYPTO_3DES_CBC: 385 txform = &enc_xform_3des; 386 break; 387 case CRYPTO_BLF_CBC: 388 txform = &enc_xform_blf; 389 break; 390 case CRYPTO_CAST_CBC: 391 txform = &enc_xform_cast5; 392 break; 393 case CRYPTO_SKIPJACK_CBC: 394 txform = &enc_xform_skipjack; 395 break; 396 case CRYPTO_AES_CBC: 397 txform = &enc_xform_rijndael128; 398 break; 399 case CRYPTO_AES_XTS: 400 txform = &enc_xform_aes_xts; 401 break; 402 case CRYPTO_NULL_CBC: 403 txform = &enc_xform_null; 404 break; 405 case CRYPTO_ARC4: 406 txform = &enc_xform_arc4; 407 break; 408 case CRYPTO_CAMELLIA_CBC: 409 txform = &enc_xform_camellia; 410 break; 411 default: 412 return (EINVAL); 413 } 414 415 switch (sop->mac) { 416 case 0: 417 break; 418 case CRYPTO_MD5_HMAC: 419 thash = &auth_hash_hmac_md5; 420 break; 421 case CRYPTO_SHA1_HMAC: 422 thash = &auth_hash_hmac_sha1; 423 break; 424 case CRYPTO_SHA2_256_HMAC: 425 thash = &auth_hash_hmac_sha2_256; 426 break; 427 case CRYPTO_SHA2_384_HMAC: 428 thash = &auth_hash_hmac_sha2_384; 429 break; 430 case CRYPTO_SHA2_512_HMAC: 431 thash = &auth_hash_hmac_sha2_512; 432 break; 433 case CRYPTO_RIPEMD160_HMAC: 434 thash = &auth_hash_hmac_ripemd_160; 435 break; 436 #ifdef notdef 437 case CRYPTO_MD5: 438 thash = &auth_hash_md5; 439 break; 440 case CRYPTO_SHA1: 441 thash = &auth_hash_sha1; 442 break; 443 #endif 444 case CRYPTO_NULL_HMAC: 445 thash = &auth_hash_null; 446 break; 447 default: 448 return (EINVAL); 449 } 450 451 bzero(&crie, sizeof(crie)); 452 bzero(&cria, sizeof(cria)); 453 454 if (txform) { 455 crie.cri_alg = txform->type; 456 crie.cri_klen = sop->keylen * 8; 457 if (sop->keylen > txform->maxkey || 458 sop->keylen < txform->minkey) { 459 error = EINVAL; 460 goto bail; 461 } 462 463 crie.cri_key = malloc(crie.cri_klen / 8, 464 M_XDATA, M_WAITOK); 465 if ((error = copyin(sop->key, crie.cri_key, 466 crie.cri_klen / 8))) 467 goto bail; 468 if (thash) 469 crie.cri_next = &cria; 470 } 471 472 if (thash) { 473 cria.cri_alg = thash->type; 474 cria.cri_klen = sop->mackeylen * 8; 475 if (sop->mackeylen != thash->keysize) { 476 error = EINVAL; 477 goto bail; 478 } 479 480 if (cria.cri_klen) { 481 cria.cri_key = malloc(cria.cri_klen / 8, 482 M_XDATA, M_WAITOK); 483 if ((error = copyin(sop->mackey, cria.cri_key, 484 cria.cri_klen / 8))) 485 goto bail; 486 } 487 } 488 489 /* NB: CIOCGSESSION2 has the crid */ 490 if (cmd == CIOCGSESSION2 491 #ifdef COMPAT_FREEBSD32 492 || cmd == CIOCGSESSION232 493 #endif 494 ) { 495 crid = SES2(sop)->crid; 496 error = checkforsoftware(crid); 497 if (error) 498 goto bail; 499 } else 500 crid = CRYPTOCAP_F_HARDWARE; 501 error = crypto_newsession(&sid, (txform ? &crie : &cria), crid); 502 if (error) 503 goto bail; 504 505 cse = csecreate(fcr, sid, crie.cri_key, crie.cri_klen, 506 cria.cri_key, cria.cri_klen, sop->cipher, sop->mac, txform, 507 thash); 508 509 if (cse == NULL) { 510 crypto_freesession(sid); 511 error = EINVAL; 512 goto bail; 513 } 514 sop->ses = cse->ses; 515 if (cmd == CIOCGSESSION2 516 #ifdef COMPAT_FREEBSD32 517 || cmd == CIOCGSESSION232 518 #endif 519 ) { 520 /* return hardware/driver id */ 521 SES2(sop)->crid = CRYPTO_SESID2HID(cse->sid); 522 } 523 bail: 524 if (error) { 525 if (crie.cri_key) 526 free(crie.cri_key, M_XDATA); 527 if (cria.cri_key) 528 free(cria.cri_key, M_XDATA); 529 } 530 #ifdef COMPAT_FREEBSD32 531 else { 532 if (cmd == CIOCGSESSION32) 533 session_op_to_32(sop, data); 534 else if (cmd == CIOCGSESSION232) 535 session2_op_to_32((struct session2_op *)sop, 536 data); 537 } 538 #endif 539 break; 540 case CIOCFSESSION: 541 ses = *(u_int32_t *)data; 542 cse = csefind(fcr, ses); 543 if (cse == NULL) 544 return (EINVAL); 545 csedelete(fcr, cse); 546 error = csefree(cse); 547 break; 548 case CIOCCRYPT: 549 #ifdef COMPAT_FREEBSD32 550 case CIOCCRYPT32: 551 if (cmd == CIOCCRYPT32) { 552 cop = &copc; 553 crypt_op_from_32(data, cop); 554 } else 555 #endif 556 cop = (struct crypt_op *)data; 557 cse = csefind(fcr, cop->ses); 558 if (cse == NULL) 559 return (EINVAL); 560 error = cryptodev_op(cse, cop, active_cred, td); 561 #ifdef COMPAT_FREEBSD32 562 if (error == 0 && cmd == CIOCCRYPT32) 563 crypt_op_to_32(cop, data); 564 #endif 565 break; 566 case CIOCKEY: 567 case CIOCKEY2: 568 #ifdef COMPAT_FREEBSD32 569 case CIOCKEY32: 570 case CIOCKEY232: 571 #endif 572 if (!crypto_userasymcrypto) 573 return (EPERM); /* XXX compat? */ 574 #ifdef COMPAT_FREEBSD32 575 if (cmd == CIOCKEY32 || cmd == CIOCKEY232) { 576 kop = &kopc; 577 crypt_kop_from_32(data, kop); 578 } else 579 #endif 580 kop = (struct crypt_kop *)data; 581 if (cmd == CIOCKEY 582 #ifdef COMPAT_FREEBSD32 583 || cmd == CIOCKEY32 584 #endif 585 ) { 586 /* NB: crypto core enforces s/w driver use */ 587 kop->crk_crid = 588 CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE; 589 } 590 mtx_lock(&Giant); 591 error = cryptodev_key(kop); 592 mtx_unlock(&Giant); 593 #ifdef COMPAT_FREEBSD32 594 if (cmd == CIOCKEY32 || cmd == CIOCKEY232) 595 crypt_kop_to_32(kop, data); 596 #endif 597 break; 598 case CIOCASYMFEAT: 599 if (!crypto_userasymcrypto) { 600 /* 601 * NB: if user asym crypto operations are 602 * not permitted return "no algorithms" 603 * so well-behaved applications will just 604 * fallback to doing them in software. 605 */ 606 *(int *)data = 0; 607 } else 608 error = crypto_getfeat((int *)data); 609 break; 610 case CIOCFINDDEV: 611 error = cryptodev_find((struct crypt_find_op *)data); 612 break; 613 default: 614 error = EINVAL; 615 break; 616 } 617 return (error); 618 #undef SES2 619 } 620 621 static int cryptodev_cb(void *); 622 623 624 static int 625 cryptodev_op( 626 struct csession *cse, 627 struct crypt_op *cop, 628 struct ucred *active_cred, 629 struct thread *td) 630 { 631 struct cryptop *crp = NULL; 632 struct cryptodesc *crde = NULL, *crda = NULL; 633 int error; 634 635 if (cop->len > 256*1024-4) 636 return (E2BIG); 637 638 if (cse->txform) { 639 if (cop->len == 0 || (cop->len % cse->txform->blocksize) != 0) 640 return (EINVAL); 641 } 642 643 cse->uio.uio_iov = &cse->iovec; 644 cse->uio.uio_iovcnt = 1; 645 cse->uio.uio_offset = 0; 646 cse->uio.uio_resid = cop->len; 647 cse->uio.uio_segflg = UIO_SYSSPACE; 648 cse->uio.uio_rw = UIO_WRITE; 649 cse->uio.uio_td = td; 650 cse->uio.uio_iov[0].iov_len = cop->len; 651 if (cse->thash) { 652 cse->uio.uio_iov[0].iov_len += cse->thash->hashsize; 653 cse->uio.uio_resid += cse->thash->hashsize; 654 } 655 cse->uio.uio_iov[0].iov_base = malloc(cse->uio.uio_iov[0].iov_len, 656 M_XDATA, M_WAITOK); 657 658 crp = crypto_getreq((cse->txform != NULL) + (cse->thash != NULL)); 659 if (crp == NULL) { 660 error = ENOMEM; 661 goto bail; 662 } 663 664 if (cse->thash) { 665 crda = crp->crp_desc; 666 if (cse->txform) 667 crde = crda->crd_next; 668 } else { 669 if (cse->txform) 670 crde = crp->crp_desc; 671 else { 672 error = EINVAL; 673 goto bail; 674 } 675 } 676 677 if ((error = copyin(cop->src, cse->uio.uio_iov[0].iov_base, cop->len))) 678 goto bail; 679 680 if (crda) { 681 crda->crd_skip = 0; 682 crda->crd_len = cop->len; 683 crda->crd_inject = cop->len; 684 685 crda->crd_alg = cse->mac; 686 crda->crd_key = cse->mackey; 687 crda->crd_klen = cse->mackeylen * 8; 688 } 689 690 if (crde) { 691 if (cop->op == COP_ENCRYPT) 692 crde->crd_flags |= CRD_F_ENCRYPT; 693 else 694 crde->crd_flags &= ~CRD_F_ENCRYPT; 695 crde->crd_len = cop->len; 696 crde->crd_inject = 0; 697 698 crde->crd_alg = cse->cipher; 699 crde->crd_key = cse->key; 700 crde->crd_klen = cse->keylen * 8; 701 } 702 703 crp->crp_ilen = cop->len; 704 crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM 705 | (cop->flags & COP_F_BATCH); 706 crp->crp_buf = (caddr_t)&cse->uio; 707 crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb; 708 crp->crp_sid = cse->sid; 709 crp->crp_opaque = (void *)cse; 710 711 if (cop->iv) { 712 if (crde == NULL) { 713 error = EINVAL; 714 goto bail; 715 } 716 if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */ 717 error = EINVAL; 718 goto bail; 719 } 720 if ((error = copyin(cop->iv, cse->tmp_iv, cse->txform->blocksize))) 721 goto bail; 722 bcopy(cse->tmp_iv, crde->crd_iv, cse->txform->blocksize); 723 crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; 724 crde->crd_skip = 0; 725 } else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */ 726 crde->crd_skip = 0; 727 } else if (crde) { 728 crde->crd_flags |= CRD_F_IV_PRESENT; 729 crde->crd_skip = cse->txform->blocksize; 730 crde->crd_len -= cse->txform->blocksize; 731 } 732 733 if (cop->mac && crda == NULL) { 734 error = EINVAL; 735 goto bail; 736 } 737 738 again: 739 /* 740 * Let the dispatch run unlocked, then, interlock against the 741 * callback before checking if the operation completed and going 742 * to sleep. This insures drivers don't inherit our lock which 743 * results in a lock order reversal between crypto_dispatch forced 744 * entry and the crypto_done callback into us. 745 */ 746 error = crypto_dispatch(crp); 747 mtx_lock(&cse->lock); 748 if (error == 0 && (crp->crp_flags & CRYPTO_F_DONE) == 0) 749 error = msleep(crp, &cse->lock, PWAIT, "crydev", 0); 750 mtx_unlock(&cse->lock); 751 752 if (error != 0) 753 goto bail; 754 755 if (crp->crp_etype == EAGAIN) { 756 crp->crp_etype = 0; 757 crp->crp_flags &= ~CRYPTO_F_DONE; 758 goto again; 759 } 760 761 if (crp->crp_etype != 0) { 762 error = crp->crp_etype; 763 goto bail; 764 } 765 766 if (cse->error) { 767 error = cse->error; 768 goto bail; 769 } 770 771 if (cop->dst && 772 (error = copyout(cse->uio.uio_iov[0].iov_base, cop->dst, cop->len))) 773 goto bail; 774 775 if (cop->mac && 776 (error = copyout((caddr_t)cse->uio.uio_iov[0].iov_base + cop->len, 777 cop->mac, cse->thash->hashsize))) 778 goto bail; 779 780 bail: 781 if (crp) 782 crypto_freereq(crp); 783 if (cse->uio.uio_iov[0].iov_base) 784 free(cse->uio.uio_iov[0].iov_base, M_XDATA); 785 786 return (error); 787 } 788 789 static int 790 cryptodev_cb(void *op) 791 { 792 struct cryptop *crp = (struct cryptop *) op; 793 struct csession *cse = (struct csession *)crp->crp_opaque; 794 795 mtx_lock(&cse->lock); 796 cse->error = crp->crp_etype; 797 wakeup_one(crp); 798 mtx_unlock(&cse->lock); 799 return (0); 800 } 801 802 static int 803 cryptodevkey_cb(void *op) 804 { 805 struct cryptkop *krp = (struct cryptkop *) op; 806 807 wakeup_one(krp); 808 return (0); 809 } 810 811 static int 812 cryptodev_key(struct crypt_kop *kop) 813 { 814 struct cryptkop *krp = NULL; 815 int error = EINVAL; 816 int in, out, size, i; 817 818 if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) { 819 return (EFBIG); 820 } 821 822 in = kop->crk_iparams; 823 out = kop->crk_oparams; 824 switch (kop->crk_op) { 825 case CRK_MOD_EXP: 826 if (in == 3 && out == 1) 827 break; 828 return (EINVAL); 829 case CRK_MOD_EXP_CRT: 830 if (in == 6 && out == 1) 831 break; 832 return (EINVAL); 833 case CRK_DSA_SIGN: 834 if (in == 5 && out == 2) 835 break; 836 return (EINVAL); 837 case CRK_DSA_VERIFY: 838 if (in == 7 && out == 0) 839 break; 840 return (EINVAL); 841 case CRK_DH_COMPUTE_KEY: 842 if (in == 3 && out == 1) 843 break; 844 return (EINVAL); 845 default: 846 return (EINVAL); 847 } 848 849 krp = (struct cryptkop *)malloc(sizeof *krp, M_XDATA, M_WAITOK|M_ZERO); 850 if (!krp) 851 return (ENOMEM); 852 krp->krp_op = kop->crk_op; 853 krp->krp_status = kop->crk_status; 854 krp->krp_iparams = kop->crk_iparams; 855 krp->krp_oparams = kop->crk_oparams; 856 krp->krp_crid = kop->crk_crid; 857 krp->krp_status = 0; 858 krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb; 859 860 for (i = 0; i < CRK_MAXPARAM; i++) { 861 if (kop->crk_param[i].crp_nbits > 65536) 862 /* Limit is the same as in OpenBSD */ 863 goto fail; 864 krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits; 865 } 866 for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) { 867 size = (krp->krp_param[i].crp_nbits + 7) / 8; 868 if (size == 0) 869 continue; 870 krp->krp_param[i].crp_p = malloc(size, M_XDATA, M_WAITOK); 871 if (i >= krp->krp_iparams) 872 continue; 873 error = copyin(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p, size); 874 if (error) 875 goto fail; 876 } 877 878 error = crypto_kdispatch(krp); 879 if (error) 880 goto fail; 881 error = tsleep(krp, PSOCK, "crydev", 0); 882 if (error) { 883 /* XXX can this happen? if so, how do we recover? */ 884 goto fail; 885 } 886 887 kop->crk_crid = krp->krp_crid; /* device that did the work */ 888 if (krp->krp_status != 0) { 889 error = krp->krp_status; 890 goto fail; 891 } 892 893 for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) { 894 size = (krp->krp_param[i].crp_nbits + 7) / 8; 895 if (size == 0) 896 continue; 897 error = copyout(krp->krp_param[i].crp_p, kop->crk_param[i].crp_p, size); 898 if (error) 899 goto fail; 900 } 901 902 fail: 903 if (krp) { 904 kop->crk_status = krp->krp_status; 905 for (i = 0; i < CRK_MAXPARAM; i++) { 906 if (krp->krp_param[i].crp_p) 907 free(krp->krp_param[i].crp_p, M_XDATA); 908 } 909 free(krp, M_XDATA); 910 } 911 return (error); 912 } 913 914 static int 915 cryptodev_find(struct crypt_find_op *find) 916 { 917 device_t dev; 918 919 if (find->crid != -1) { 920 dev = crypto_find_device_byhid(find->crid); 921 if (dev == NULL) 922 return (ENOENT); 923 strlcpy(find->name, device_get_nameunit(dev), 924 sizeof(find->name)); 925 } else { 926 find->crid = crypto_find_driver(find->name); 927 if (find->crid == -1) 928 return (ENOENT); 929 } 930 return (0); 931 } 932 933 /* ARGSUSED */ 934 static int 935 cryptof_stat( 936 struct file *fp, 937 struct stat *sb, 938 struct ucred *active_cred, 939 struct thread *td) 940 { 941 942 return (EOPNOTSUPP); 943 } 944 945 /* ARGSUSED */ 946 static int 947 cryptof_close(struct file *fp, struct thread *td) 948 { 949 struct fcrypt *fcr = fp->f_data; 950 struct csession *cse; 951 952 while ((cse = TAILQ_FIRST(&fcr->csessions))) { 953 TAILQ_REMOVE(&fcr->csessions, cse, next); 954 (void)csefree(cse); 955 } 956 free(fcr, M_XDATA); 957 fp->f_data = NULL; 958 return 0; 959 } 960 961 static struct csession * 962 csefind(struct fcrypt *fcr, u_int ses) 963 { 964 struct csession *cse; 965 966 TAILQ_FOREACH(cse, &fcr->csessions, next) 967 if (cse->ses == ses) 968 return (cse); 969 return (NULL); 970 } 971 972 static int 973 csedelete(struct fcrypt *fcr, struct csession *cse_del) 974 { 975 struct csession *cse; 976 977 TAILQ_FOREACH(cse, &fcr->csessions, next) { 978 if (cse == cse_del) { 979 TAILQ_REMOVE(&fcr->csessions, cse, next); 980 return (1); 981 } 982 } 983 return (0); 984 } 985 986 static struct csession * 987 cseadd(struct fcrypt *fcr, struct csession *cse) 988 { 989 TAILQ_INSERT_TAIL(&fcr->csessions, cse, next); 990 cse->ses = fcr->sesn++; 991 return (cse); 992 } 993 994 struct csession * 995 csecreate(struct fcrypt *fcr, u_int64_t sid, caddr_t key, u_int64_t keylen, 996 caddr_t mackey, u_int64_t mackeylen, u_int32_t cipher, u_int32_t mac, 997 struct enc_xform *txform, struct auth_hash *thash) 998 { 999 struct csession *cse; 1000 1001 cse = malloc(sizeof(struct csession), M_XDATA, M_NOWAIT | M_ZERO); 1002 if (cse == NULL) 1003 return NULL; 1004 mtx_init(&cse->lock, "cryptodev", "crypto session lock", MTX_DEF); 1005 cse->key = key; 1006 cse->keylen = keylen/8; 1007 cse->mackey = mackey; 1008 cse->mackeylen = mackeylen/8; 1009 cse->sid = sid; 1010 cse->cipher = cipher; 1011 cse->mac = mac; 1012 cse->txform = txform; 1013 cse->thash = thash; 1014 cseadd(fcr, cse); 1015 return (cse); 1016 } 1017 1018 static int 1019 csefree(struct csession *cse) 1020 { 1021 int error; 1022 1023 error = crypto_freesession(cse->sid); 1024 mtx_destroy(&cse->lock); 1025 if (cse->key) 1026 free(cse->key, M_XDATA); 1027 if (cse->mackey) 1028 free(cse->mackey, M_XDATA); 1029 free(cse, M_XDATA); 1030 return (error); 1031 } 1032 1033 static int 1034 cryptoopen(struct cdev *dev, int oflags, int devtype, struct thread *td) 1035 { 1036 return (0); 1037 } 1038 1039 static int 1040 cryptoread(struct cdev *dev, struct uio *uio, int ioflag) 1041 { 1042 return (EIO); 1043 } 1044 1045 static int 1046 cryptowrite(struct cdev *dev, struct uio *uio, int ioflag) 1047 { 1048 return (EIO); 1049 } 1050 1051 static int 1052 cryptoioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) 1053 { 1054 struct file *f; 1055 struct fcrypt *fcr; 1056 int fd, error; 1057 1058 switch (cmd) { 1059 case CRIOGET: 1060 fcr = malloc(sizeof(struct fcrypt), M_XDATA, M_WAITOK); 1061 TAILQ_INIT(&fcr->csessions); 1062 fcr->sesn = 0; 1063 1064 error = falloc(td, &f, &fd, 0); 1065 1066 if (error) { 1067 free(fcr, M_XDATA); 1068 return (error); 1069 } 1070 /* falloc automatically provides an extra reference to 'f'. */ 1071 finit(f, FREAD | FWRITE, DTYPE_CRYPTO, fcr, &cryptofops); 1072 *(u_int32_t *)data = fd; 1073 fdrop(f, td); 1074 break; 1075 case CRIOFINDDEV: 1076 error = cryptodev_find((struct crypt_find_op *)data); 1077 break; 1078 case CRIOASYMFEAT: 1079 error = crypto_getfeat((int *)data); 1080 break; 1081 default: 1082 error = EINVAL; 1083 break; 1084 } 1085 return (error); 1086 } 1087 1088 static struct cdevsw crypto_cdevsw = { 1089 .d_version = D_VERSION, 1090 .d_flags = D_NEEDGIANT, 1091 .d_open = cryptoopen, 1092 .d_read = cryptoread, 1093 .d_write = cryptowrite, 1094 .d_ioctl = cryptoioctl, 1095 .d_name = "crypto", 1096 }; 1097 static struct cdev *crypto_dev; 1098 1099 /* 1100 * Initialization code, both for static and dynamic loading. 1101 */ 1102 static int 1103 cryptodev_modevent(module_t mod, int type, void *unused) 1104 { 1105 switch (type) { 1106 case MOD_LOAD: 1107 if (bootverbose) 1108 printf("crypto: <crypto device>\n"); 1109 crypto_dev = make_dev(&crypto_cdevsw, 0, 1110 UID_ROOT, GID_WHEEL, 0666, 1111 "crypto"); 1112 return 0; 1113 case MOD_UNLOAD: 1114 /*XXX disallow if active sessions */ 1115 destroy_dev(crypto_dev); 1116 return 0; 1117 } 1118 return EINVAL; 1119 } 1120 1121 static moduledata_t cryptodev_mod = { 1122 "cryptodev", 1123 cryptodev_modevent, 1124 0 1125 }; 1126 MODULE_VERSION(cryptodev, 1); 1127 DECLARE_MODULE(cryptodev, cryptodev_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 1128 MODULE_DEPEND(cryptodev, crypto, 1, 1, 1); 1129 MODULE_DEPEND(cryptodev, zlib, 1, 1, 1); 1130