1 /* $FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.4.2.4 2003/06/03 00:09:02 sam Exp $ */ 2 /* $DragonFly: src/sys/opencrypto/cryptodev.c,v 1.17 2006/05/26 15:55:13 dillon Exp $ */ 3 /* $OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $ */ 4 5 /* 6 * Copyright (c) 2001 Theo de Raadt 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * 31 * Effort sponsored in part by the Defense Advanced Research Projects 32 * Agency (DARPA) and Air Force Research Laboratory, Air Force 33 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 34 * 35 */ 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/malloc.h> 40 #include <sys/mbuf.h> 41 #include <sys/sysctl.h> 42 #include <sys/file.h> 43 #include <sys/lock.h> 44 #include <sys/filedesc.h> 45 #include <sys/errno.h> 46 #include <sys/uio.h> 47 #include <sys/random.h> 48 #include <sys/conf.h> 49 #include <sys/kernel.h> 50 #include <sys/fcntl.h> 51 #include <sys/proc.h> 52 #include <sys/file2.h> 53 #include <sys/thread2.h> 54 55 #include <opencrypto/cryptodev.h> 56 #include <opencrypto/xform.h> 57 58 struct csession { 59 TAILQ_ENTRY(csession) next; 60 u_int64_t sid; 61 u_int32_t ses; 62 63 u_int32_t cipher; 64 struct enc_xform *txform; 65 u_int32_t mac; 66 struct auth_hash *thash; 67 68 caddr_t key; 69 int keylen; 70 u_char tmp_iv[EALG_MAX_BLOCK_LEN]; 71 72 caddr_t mackey; 73 int mackeylen; 74 u_char tmp_mac[CRYPTO_MAX_MAC_LEN]; 75 76 struct iovec iovec[UIO_MAXIOV]; 77 struct uio uio; 78 int error; 79 }; 80 81 struct fcrypt { 82 TAILQ_HEAD(csessionlist, csession) csessions; 83 int sesn; 84 }; 85 86 static int cryptof_rw(struct file *fp, struct uio *uio, 87 struct ucred *cred, int flags); 88 static int cryptof_ioctl(struct file *, u_long, caddr_t, struct ucred *); 89 static int cryptof_poll(struct file *, int, struct ucred *); 90 static int cryptof_kqfilter(struct file *, struct knote *); 91 static int cryptof_stat(struct file *, struct stat *, struct ucred *); 92 static int cryptof_close(struct file *); 93 94 static struct fileops cryptofops = { 95 NULL, /* port */ 96 NULL, /* clone */ 97 cryptof_rw, 98 cryptof_rw, 99 cryptof_ioctl, 100 cryptof_poll, 101 cryptof_kqfilter, 102 cryptof_stat, 103 cryptof_close, 104 nofo_shutdown 105 }; 106 107 static struct csession *csefind(struct fcrypt *, u_int); 108 static int csedelete(struct fcrypt *, struct csession *); 109 static struct csession *cseadd(struct fcrypt *, struct csession *); 110 static struct csession *csecreate(struct fcrypt *, u_int64_t, caddr_t, 111 u_int64_t, caddr_t, u_int64_t, u_int32_t, u_int32_t, struct enc_xform *, 112 struct auth_hash *); 113 static int csefree(struct csession *); 114 115 static int cryptodev_op(struct csession *, struct crypt_op *); 116 static int cryptodev_key(struct crypt_kop *); 117 118 /* 119 * MPSAFE 120 */ 121 static int 122 cryptof_rw( 123 struct file *fp, 124 struct uio *uio, 125 struct ucred *active_cred, 126 int flags) 127 { 128 return (EIO); 129 } 130 131 /* 132 * MPALMOSTSAFE - acquires mplock 133 */ 134 static int 135 cryptof_ioctl( 136 struct file *fp, 137 u_long cmd, 138 caddr_t data, 139 struct ucred *cred) 140 { 141 struct cryptoini cria, crie; 142 struct fcrypt *fcr; 143 struct csession *cse; 144 struct session_op *sop; 145 struct crypt_op *cop; 146 struct enc_xform *txform = NULL; 147 struct auth_hash *thash = NULL; 148 u_int64_t sid; 149 u_int32_t ses; 150 int error = 0; 151 152 get_mplock(); 153 fcr = (struct fcrypt *)fp->f_data; 154 155 switch (cmd) { 156 case CIOCGSESSION: 157 sop = (struct session_op *)data; 158 switch (sop->cipher) { 159 case 0: 160 break; 161 case CRYPTO_DES_CBC: 162 txform = &enc_xform_des; 163 break; 164 case CRYPTO_3DES_CBC: 165 txform = &enc_xform_3des; 166 break; 167 case CRYPTO_BLF_CBC: 168 txform = &enc_xform_blf; 169 break; 170 case CRYPTO_CAST_CBC: 171 txform = &enc_xform_cast5; 172 break; 173 case CRYPTO_SKIPJACK_CBC: 174 txform = &enc_xform_skipjack; 175 break; 176 case CRYPTO_AES_CBC: 177 txform = &enc_xform_rijndael128; 178 break; 179 case CRYPTO_NULL_CBC: 180 txform = &enc_xform_null; 181 break; 182 case CRYPTO_ARC4: 183 txform = &enc_xform_arc4; 184 break; 185 default: 186 error = EINVAL; 187 break; 188 } 189 if (error) 190 break; 191 192 switch (sop->mac) { 193 case 0: 194 break; 195 case CRYPTO_MD5_HMAC: 196 thash = &auth_hash_hmac_md5_96; 197 break; 198 case CRYPTO_SHA1_HMAC: 199 thash = &auth_hash_hmac_sha1_96; 200 break; 201 case CRYPTO_SHA2_HMAC: 202 if (sop->mackeylen == auth_hash_hmac_sha2_256.keysize) 203 thash = &auth_hash_hmac_sha2_256; 204 else if (sop->mackeylen == auth_hash_hmac_sha2_384.keysize) 205 thash = &auth_hash_hmac_sha2_384; 206 else if (sop->mackeylen == auth_hash_hmac_sha2_512.keysize) 207 thash = &auth_hash_hmac_sha2_512; 208 else { 209 error = EINVAL; 210 break; 211 } 212 break; 213 case CRYPTO_RIPEMD160_HMAC: 214 thash = &auth_hash_hmac_ripemd_160_96; 215 break; 216 #ifdef notdef 217 case CRYPTO_MD5: 218 thash = &auth_hash_md5; 219 break; 220 case CRYPTO_SHA1: 221 thash = &auth_hash_sha1; 222 break; 223 #endif 224 case CRYPTO_NULL_HMAC: 225 thash = &auth_hash_null; 226 break; 227 default: 228 error = EINVAL; 229 break; 230 } 231 if (error) 232 break; 233 234 bzero(&crie, sizeof(crie)); 235 bzero(&cria, sizeof(cria)); 236 237 if (txform) { 238 crie.cri_alg = txform->type; 239 crie.cri_klen = sop->keylen * 8; 240 if (sop->keylen > txform->maxkey || 241 sop->keylen < txform->minkey) { 242 error = EINVAL; 243 goto bail; 244 } 245 246 MALLOC(crie.cri_key, u_int8_t *, 247 crie.cri_klen / 8, M_XDATA, M_WAITOK); 248 if ((error = copyin(sop->key, crie.cri_key, 249 crie.cri_klen / 8))) 250 goto bail; 251 if (thash) 252 crie.cri_next = &cria; 253 } 254 255 if (thash) { 256 cria.cri_alg = thash->type; 257 cria.cri_klen = sop->mackeylen * 8; 258 if (sop->mackeylen != thash->keysize) { 259 error = EINVAL; 260 goto bail; 261 } 262 263 if (cria.cri_klen) { 264 MALLOC(cria.cri_key, u_int8_t *, 265 cria.cri_klen / 8, M_XDATA, M_WAITOK); 266 if ((error = copyin(sop->mackey, cria.cri_key, 267 cria.cri_klen / 8))) 268 goto bail; 269 } 270 } 271 272 error = crypto_newsession(&sid, (txform ? &crie : &cria), 1); 273 if (error) 274 goto bail; 275 276 cse = csecreate(fcr, sid, crie.cri_key, crie.cri_klen, 277 cria.cri_key, cria.cri_klen, sop->cipher, sop->mac, txform, 278 thash); 279 280 if (cse == NULL) { 281 crypto_freesession(sid); 282 error = EINVAL; 283 goto bail; 284 } 285 sop->ses = cse->ses; 286 287 bail: 288 if (error) { 289 if (crie.cri_key) 290 FREE(crie.cri_key, M_XDATA); 291 if (cria.cri_key) 292 FREE(cria.cri_key, M_XDATA); 293 } 294 break; 295 case CIOCFSESSION: 296 ses = *(u_int32_t *)data; 297 cse = csefind(fcr, ses); 298 if (cse == NULL) { 299 error = EINVAL; 300 break; 301 } 302 csedelete(fcr, cse); 303 error = csefree(cse); 304 break; 305 case CIOCCRYPT: 306 cop = (struct crypt_op *)data; 307 cse = csefind(fcr, cop->ses); 308 if (cse == NULL) { 309 error = EINVAL; 310 break; 311 } 312 error = cryptodev_op(cse, cop); 313 break; 314 case CIOCKEY: 315 error = cryptodev_key((struct crypt_kop *)data); 316 break; 317 case CIOCASYMFEAT: 318 error = crypto_getfeat((int *)data); 319 break; 320 default: 321 error = EINVAL; 322 break; 323 } 324 rel_mplock(); 325 return (error); 326 } 327 328 static int cryptodev_cb(void *); 329 330 331 static int 332 cryptodev_op(struct csession *cse, struct crypt_op *cop) 333 { 334 struct cryptop *crp = NULL; 335 struct cryptodesc *crde = NULL, *crda = NULL; 336 int i, error; 337 338 if (cop->len > 256*1024-4) 339 return (E2BIG); 340 341 if (cse->txform && (cop->len % cse->txform->blocksize) != 0) 342 return (EINVAL); 343 344 bzero(&cse->uio, sizeof(cse->uio)); 345 cse->uio.uio_iovcnt = 1; 346 cse->uio.uio_resid = 0; 347 cse->uio.uio_segflg = UIO_SYSSPACE; 348 cse->uio.uio_rw = UIO_WRITE; 349 cse->uio.uio_td = curthread; 350 cse->uio.uio_iov = cse->iovec; 351 bzero(&cse->iovec, sizeof(cse->iovec)); 352 cse->uio.uio_iov[0].iov_len = cop->len; 353 cse->uio.uio_iov[0].iov_base = malloc(cop->len, M_XDATA, M_WAITOK); 354 for (i = 0; i < cse->uio.uio_iovcnt; i++) 355 cse->uio.uio_resid += cse->uio.uio_iov[0].iov_len; 356 357 crp = crypto_getreq((cse->txform != NULL) + (cse->thash != NULL)); 358 if (crp == NULL) { 359 error = ENOMEM; 360 goto bail; 361 } 362 363 if (cse->thash) { 364 crda = crp->crp_desc; 365 if (cse->txform) 366 crde = crda->crd_next; 367 } else { 368 if (cse->txform) 369 crde = crp->crp_desc; 370 else { 371 error = EINVAL; 372 goto bail; 373 } 374 } 375 376 if ((error = copyin(cop->src, cse->uio.uio_iov[0].iov_base, cop->len))) 377 goto bail; 378 379 if (crda) { 380 crda->crd_skip = 0; 381 crda->crd_len = cop->len; 382 crda->crd_inject = 0; /* ??? */ 383 384 crda->crd_alg = cse->mac; 385 crda->crd_key = cse->mackey; 386 crda->crd_klen = cse->mackeylen * 8; 387 } 388 389 if (crde) { 390 if (cop->op == COP_ENCRYPT) 391 crde->crd_flags |= CRD_F_ENCRYPT; 392 else 393 crde->crd_flags &= ~CRD_F_ENCRYPT; 394 crde->crd_len = cop->len; 395 crde->crd_inject = 0; 396 397 crde->crd_alg = cse->cipher; 398 crde->crd_key = cse->key; 399 crde->crd_klen = cse->keylen * 8; 400 } 401 402 crp->crp_ilen = cop->len; 403 crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM 404 | (cop->flags & COP_F_BATCH); 405 crp->crp_buf = (caddr_t)&cse->uio; 406 crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb; 407 crp->crp_sid = cse->sid; 408 crp->crp_opaque = (void *)cse; 409 410 if (cop->iv) { 411 if (crde == NULL) { 412 error = EINVAL; 413 goto bail; 414 } 415 if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */ 416 error = EINVAL; 417 goto bail; 418 } 419 if ((error = copyin(cop->iv, cse->tmp_iv, cse->txform->blocksize))) 420 goto bail; 421 bcopy(cse->tmp_iv, crde->crd_iv, cse->txform->blocksize); 422 crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; 423 crde->crd_skip = 0; 424 } else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */ 425 crde->crd_skip = 0; 426 } else if (crde) { 427 crde->crd_flags |= CRD_F_IV_PRESENT; 428 crde->crd_skip = cse->txform->blocksize; 429 crde->crd_len -= cse->txform->blocksize; 430 } 431 432 if (cop->mac) { 433 if (crda == NULL) { 434 error = EINVAL; 435 goto bail; 436 } 437 crp->crp_mac=cse->tmp_mac; 438 } 439 440 crit_enter(); 441 error = crypto_dispatch(crp); 442 if (error == 0 && (crp->crp_flags & CRYPTO_F_DONE) == 0) 443 error = tsleep(crp, 0, "crydev", 0); 444 crit_exit(); 445 if (error) 446 goto bail; 447 448 if (crp->crp_etype != 0) { 449 error = crp->crp_etype; 450 goto bail; 451 } 452 453 if (cse->error) { 454 error = cse->error; 455 goto bail; 456 } 457 458 if (cop->dst && 459 (error = copyout(cse->uio.uio_iov[0].iov_base, cop->dst, cop->len))) 460 goto bail; 461 462 if (cop->mac && 463 (error = copyout(crp->crp_mac, cop->mac, cse->thash->authsize))) 464 goto bail; 465 466 bail: 467 if (crp) 468 crypto_freereq(crp); 469 if (cse->uio.uio_iov[0].iov_base) 470 free(cse->uio.uio_iov[0].iov_base, M_XDATA); 471 472 return (error); 473 } 474 475 static int 476 cryptodev_cb(void *op) 477 { 478 struct cryptop *crp = (struct cryptop *) op; 479 struct csession *cse = (struct csession *)crp->crp_opaque; 480 481 cse->error = crp->crp_etype; 482 if (crp->crp_etype == EAGAIN) 483 return crypto_dispatch(crp); 484 wakeup_one(crp); 485 return (0); 486 } 487 488 static int 489 cryptodevkey_cb(void *op) 490 { 491 struct cryptkop *krp = (struct cryptkop *) op; 492 493 wakeup_one(krp); 494 return (0); 495 } 496 497 static int 498 cryptodev_key(struct crypt_kop *kop) 499 { 500 struct cryptkop *krp = NULL; 501 int error = EINVAL; 502 int in, out, size, i; 503 504 if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) { 505 return (EFBIG); 506 } 507 508 in = kop->crk_iparams; 509 out = kop->crk_oparams; 510 switch (kop->crk_op) { 511 case CRK_MOD_EXP: 512 if (in == 3 && out == 1) 513 break; 514 return (EINVAL); 515 case CRK_MOD_EXP_CRT: 516 if (in == 6 && out == 1) 517 break; 518 return (EINVAL); 519 case CRK_DSA_SIGN: 520 if (in == 5 && out == 2) 521 break; 522 return (EINVAL); 523 case CRK_DSA_VERIFY: 524 if (in == 7 && out == 0) 525 break; 526 return (EINVAL); 527 case CRK_DH_COMPUTE_KEY: 528 if (in == 3 && out == 1) 529 break; 530 return (EINVAL); 531 default: 532 return (EINVAL); 533 } 534 535 krp = (struct cryptkop *)malloc(sizeof *krp, M_XDATA, M_WAITOK); 536 if (!krp) 537 return (ENOMEM); 538 bzero(krp, sizeof *krp); 539 krp->krp_op = kop->crk_op; 540 krp->krp_status = kop->crk_status; 541 krp->krp_iparams = kop->crk_iparams; 542 krp->krp_oparams = kop->crk_oparams; 543 krp->krp_status = 0; 544 krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb; 545 546 for (i = 0; i < CRK_MAXPARAM; i++) 547 krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits; 548 for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) { 549 size = (krp->krp_param[i].crp_nbits + 7) / 8; 550 if (size == 0) 551 continue; 552 MALLOC(krp->krp_param[i].crp_p, caddr_t, size, M_XDATA, M_WAITOK); 553 if (i >= krp->krp_iparams) 554 continue; 555 error = copyin(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p, size); 556 if (error) 557 goto fail; 558 } 559 560 error = crypto_kdispatch(krp); 561 if (error == 0) 562 error = tsleep(krp, 0, "crydev", 0); 563 if (error) 564 goto fail; 565 566 if (krp->krp_status != 0) { 567 error = krp->krp_status; 568 goto fail; 569 } 570 571 for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) { 572 size = (krp->krp_param[i].crp_nbits + 7) / 8; 573 if (size == 0) 574 continue; 575 error = copyout(krp->krp_param[i].crp_p, kop->crk_param[i].crp_p, size); 576 if (error) 577 goto fail; 578 } 579 580 fail: 581 if (krp) { 582 kop->crk_status = krp->krp_status; 583 for (i = 0; i < CRK_MAXPARAM; i++) { 584 if (krp->krp_param[i].crp_p) 585 FREE(krp->krp_param[i].crp_p, M_XDATA); 586 } 587 free(krp, M_XDATA); 588 } 589 return (error); 590 } 591 592 /* 593 * MPSAFE 594 */ 595 static int 596 cryptof_poll(struct file *fp, int events, struct ucred *active_cred) 597 { 598 return (0); 599 } 600 601 /* 602 * MPSAFE 603 */ 604 static int 605 cryptof_kqfilter(struct file *fp, struct knote *kn) 606 { 607 608 return (0); 609 } 610 611 /* 612 * MPSAFE 613 */ 614 static int 615 cryptof_stat(struct file *fp, struct stat *sb, struct ucred *cred) 616 { 617 return (EOPNOTSUPP); 618 } 619 620 /* 621 * MPALMOSTSAFE - acquires mplock 622 */ 623 static int 624 cryptof_close(struct file *fp) 625 { 626 struct fcrypt *fcr; 627 struct csession *cse; 628 629 get_mplock(); 630 fcr = (struct fcrypt *)fp->f_data; 631 while ((cse = TAILQ_FIRST(&fcr->csessions))) { 632 TAILQ_REMOVE(&fcr->csessions, cse, next); 633 (void)csefree(cse); 634 } 635 fp->f_data = NULL; 636 rel_mplock(); 637 638 FREE(fcr, M_XDATA); 639 return (0); 640 } 641 642 static struct csession * 643 csefind(struct fcrypt *fcr, u_int ses) 644 { 645 struct csession *cse; 646 647 TAILQ_FOREACH(cse, &fcr->csessions, next) 648 if (cse->ses == ses) 649 return (cse); 650 return (NULL); 651 } 652 653 static int 654 csedelete(struct fcrypt *fcr, struct csession *cse_del) 655 { 656 struct csession *cse; 657 658 TAILQ_FOREACH(cse, &fcr->csessions, next) { 659 if (cse == cse_del) { 660 TAILQ_REMOVE(&fcr->csessions, cse, next); 661 return (1); 662 } 663 } 664 return (0); 665 } 666 667 static struct csession * 668 cseadd(struct fcrypt *fcr, struct csession *cse) 669 { 670 TAILQ_INSERT_TAIL(&fcr->csessions, cse, next); 671 cse->ses = fcr->sesn++; 672 return (cse); 673 } 674 675 struct csession * 676 csecreate(struct fcrypt *fcr, u_int64_t sid, caddr_t key, u_int64_t keylen, 677 caddr_t mackey, u_int64_t mackeylen, u_int32_t cipher, u_int32_t mac, 678 struct enc_xform *txform, struct auth_hash *thash) 679 { 680 struct csession *cse; 681 682 MALLOC(cse, struct csession *, sizeof(struct csession), 683 M_XDATA, M_NOWAIT); 684 if (cse == NULL) 685 return NULL; 686 cse->key = key; 687 cse->keylen = keylen/8; 688 cse->mackey = mackey; 689 cse->mackeylen = mackeylen/8; 690 cse->sid = sid; 691 cse->cipher = cipher; 692 cse->mac = mac; 693 cse->txform = txform; 694 cse->thash = thash; 695 cseadd(fcr, cse); 696 return (cse); 697 } 698 699 static int 700 csefree(struct csession *cse) 701 { 702 int error; 703 704 error = crypto_freesession(cse->sid); 705 if (cse->key) 706 FREE(cse->key, M_XDATA); 707 if (cse->mackey) 708 FREE(cse->mackey, M_XDATA); 709 FREE(cse, M_XDATA); 710 return (error); 711 } 712 713 static int 714 cryptoopen(dev_t dev, int oflags, int devtype, struct thread *td) 715 { 716 if (crypto_usercrypto == 0) 717 return (ENXIO); 718 return (0); 719 } 720 721 static int 722 cryptoread(dev_t dev, struct uio *uio, int ioflag) 723 { 724 return (EIO); 725 } 726 727 static int 728 cryptowrite(dev_t dev, struct uio *uio, int ioflag) 729 { 730 return (EIO); 731 } 732 733 static int 734 cryptoioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td) 735 { 736 struct file *f; 737 struct fcrypt *fcr; 738 int fd, error; 739 switch (cmd) { 740 case CRIOGET: 741 MALLOC(fcr, struct fcrypt *, 742 sizeof(struct fcrypt), M_XDATA, M_WAITOK); 743 TAILQ_INIT(&fcr->csessions); 744 fcr->sesn = 0; 745 746 KKASSERT(td->td_proc); 747 error = falloc(td->td_proc, &f, &fd); 748 749 if (error) { 750 FREE(fcr, M_XDATA); 751 return (error); 752 } 753 f->f_type = DTYPE_CRYPTO; 754 f->f_flag = FREAD | FWRITE; 755 f->f_ops = &cryptofops; 756 f->f_data = fcr; 757 fsetfd(td->td_proc, f, fd); 758 *(u_int32_t *)data = fd; 759 fdrop(f); 760 break; 761 default: 762 error = EINVAL; 763 break; 764 } 765 return (error); 766 } 767 768 #define CRYPTO_MAJOR 70 /* from openbsd */ 769 static struct cdevsw crypto_cdevsw = { 770 /* dev name */ "crypto", 771 /* dev major */ CRYPTO_MAJOR, 772 /* flags */ 0, 773 /* port */ NULL, 774 /* clone */ NULL, 775 776 /* open */ cryptoopen, 777 /* close */ nullclose, 778 /* read */ cryptoread, 779 /* write */ cryptowrite, 780 /* ioctl */ cryptoioctl, 781 /* poll */ nopoll, 782 /* mmap */ nommap, 783 /* strategy */ nostrategy, 784 /* dump */ nodump, 785 /* psize */ nopsize, 786 /* kqfilter */ NULL 787 }; 788 789 /* 790 * Initialization code, both for static and dynamic loading. 791 */ 792 static int 793 cryptodev_modevent(module_t mod, int type, void *unused) 794 { 795 switch (type) { 796 case MOD_LOAD: 797 if (bootverbose) 798 printf("crypto: <crypto device>\n"); 799 cdevsw_add(&crypto_cdevsw, 0, 0); 800 make_dev(&crypto_cdevsw, 0, UID_ROOT, GID_WHEEL, 801 0666, "crypto"); 802 return 0; 803 case MOD_UNLOAD: 804 /*XXX disallow if active sessions */ 805 cdevsw_remove(&crypto_cdevsw, 0, 0); 806 return 0; 807 } 808 return EINVAL; 809 } 810 811 static moduledata_t cryptodev_mod = { 812 "cryptodev", 813 cryptodev_modevent, 814 0 815 }; 816 MODULE_VERSION(cryptodev, 1); 817 DECLARE_MODULE(cryptodev, cryptodev_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 818 #if 0 819 MODULE_DEPEND(cryptodev, crypto, 1, 1, 1); 820 #endif 821