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.23 2008/01/06 16:55:53 swildner 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/device.h> 50 #include <sys/kernel.h> 51 #include <sys/fcntl.h> 52 #include <sys/proc.h> 53 #include <sys/file2.h> 54 #include <sys/thread2.h> 55 56 #include <opencrypto/cryptodev.h> 57 #include <opencrypto/xform.h> 58 59 struct csession { 60 TAILQ_ENTRY(csession) next; 61 u_int64_t sid; 62 u_int32_t ses; 63 64 u_int32_t cipher; 65 struct enc_xform *txform; 66 u_int32_t mac; 67 struct auth_hash *thash; 68 69 caddr_t key; 70 int keylen; 71 u_char tmp_iv[EALG_MAX_BLOCK_LEN]; 72 73 caddr_t mackey; 74 int mackeylen; 75 u_char tmp_mac[CRYPTO_MAX_MAC_LEN]; 76 77 struct iovec iovec[UIO_MAXIOV]; 78 struct uio uio; 79 int error; 80 }; 81 82 struct fcrypt { 83 TAILQ_HEAD(csessionlist, csession) csessions; 84 int sesn; 85 }; 86 87 static int cryptof_rw(struct file *fp, struct uio *uio, 88 struct ucred *cred, int flags); 89 static int cryptof_ioctl(struct file *, u_long, caddr_t, struct ucred *); 90 static int cryptof_poll(struct file *, int, struct ucred *); 91 static int cryptof_kqfilter(struct file *, struct knote *); 92 static int cryptof_stat(struct file *, struct stat *, struct ucred *); 93 static int cryptof_close(struct file *); 94 95 static struct fileops cryptofops = { 96 .fo_read = cryptof_rw, 97 .fo_write = cryptof_rw, 98 .fo_ioctl = cryptof_ioctl, 99 .fo_poll = cryptof_poll, 100 .fo_kqfilter = cryptof_kqfilter, 101 .fo_stat = cryptof_stat, 102 .fo_close = cryptof_close, 103 .fo_shutdown = nofo_shutdown 104 }; 105 106 static struct csession *csefind(struct fcrypt *, u_int); 107 static int csedelete(struct fcrypt *, struct csession *); 108 static struct csession *cseadd(struct fcrypt *, struct csession *); 109 static struct csession *csecreate(struct fcrypt *, u_int64_t, caddr_t, 110 u_int64_t, caddr_t, u_int64_t, u_int32_t, u_int32_t, struct enc_xform *, 111 struct auth_hash *); 112 static int csefree(struct csession *); 113 114 static int cryptodev_op(struct csession *, struct crypt_op *); 115 static int cryptodev_key(struct crypt_kop *); 116 117 /* 118 * MPSAFE 119 */ 120 static int 121 cryptof_rw( 122 struct file *fp, 123 struct uio *uio, 124 struct ucred *active_cred, 125 int flags) 126 { 127 return (EIO); 128 } 129 130 /* 131 * MPALMOSTSAFE - acquires mplock 132 */ 133 static int 134 cryptof_ioctl( 135 struct file *fp, 136 u_long cmd, 137 caddr_t data, 138 struct ucred *cred) 139 { 140 struct cryptoini cria, crie; 141 struct fcrypt *fcr; 142 struct csession *cse; 143 struct session_op *sop; 144 struct crypt_op *cop; 145 struct enc_xform *txform = NULL; 146 struct auth_hash *thash = NULL; 147 u_int64_t sid; 148 u_int32_t ses; 149 int error = 0; 150 151 get_mplock(); 152 fcr = (struct fcrypt *)fp->f_data; 153 154 switch (cmd) { 155 case CIOCGSESSION: 156 sop = (struct session_op *)data; 157 switch (sop->cipher) { 158 case 0: 159 break; 160 case CRYPTO_DES_CBC: 161 txform = &enc_xform_des; 162 break; 163 case CRYPTO_3DES_CBC: 164 txform = &enc_xform_3des; 165 break; 166 case CRYPTO_BLF_CBC: 167 txform = &enc_xform_blf; 168 break; 169 case CRYPTO_CAST_CBC: 170 txform = &enc_xform_cast5; 171 break; 172 case CRYPTO_SKIPJACK_CBC: 173 txform = &enc_xform_skipjack; 174 break; 175 case CRYPTO_AES_CBC: 176 txform = &enc_xform_rijndael128; 177 break; 178 case CRYPTO_NULL_CBC: 179 txform = &enc_xform_null; 180 break; 181 case CRYPTO_ARC4: 182 txform = &enc_xform_arc4; 183 break; 184 default: 185 error = EINVAL; 186 break; 187 } 188 if (error) 189 break; 190 191 switch (sop->mac) { 192 case 0: 193 break; 194 case CRYPTO_MD5_HMAC: 195 thash = &auth_hash_hmac_md5_96; 196 break; 197 case CRYPTO_SHA1_HMAC: 198 thash = &auth_hash_hmac_sha1_96; 199 break; 200 case CRYPTO_SHA2_HMAC: 201 if (sop->mackeylen == auth_hash_hmac_sha2_256.keysize) 202 thash = &auth_hash_hmac_sha2_256; 203 else if (sop->mackeylen == auth_hash_hmac_sha2_384.keysize) 204 thash = &auth_hash_hmac_sha2_384; 205 else if (sop->mackeylen == auth_hash_hmac_sha2_512.keysize) 206 thash = &auth_hash_hmac_sha2_512; 207 else { 208 error = EINVAL; 209 break; 210 } 211 break; 212 case CRYPTO_RIPEMD160_HMAC: 213 thash = &auth_hash_hmac_ripemd_160_96; 214 break; 215 #ifdef notdef 216 case CRYPTO_MD5: 217 thash = &auth_hash_md5; 218 break; 219 case CRYPTO_SHA1: 220 thash = &auth_hash_sha1; 221 break; 222 #endif 223 case CRYPTO_NULL_HMAC: 224 thash = &auth_hash_null; 225 break; 226 default: 227 error = EINVAL; 228 break; 229 } 230 if (error) 231 break; 232 233 bzero(&crie, sizeof(crie)); 234 bzero(&cria, sizeof(cria)); 235 236 if (txform) { 237 crie.cri_alg = txform->type; 238 crie.cri_klen = sop->keylen * 8; 239 if (sop->keylen > txform->maxkey || 240 sop->keylen < txform->minkey) { 241 error = EINVAL; 242 goto bail; 243 } 244 245 MALLOC(crie.cri_key, u_int8_t *, 246 crie.cri_klen / 8, M_XDATA, M_WAITOK); 247 if ((error = copyin(sop->key, crie.cri_key, 248 crie.cri_klen / 8))) 249 goto bail; 250 if (thash) 251 crie.cri_next = &cria; 252 } 253 254 if (thash) { 255 cria.cri_alg = thash->type; 256 cria.cri_klen = sop->mackeylen * 8; 257 if (sop->mackeylen != thash->keysize) { 258 error = EINVAL; 259 goto bail; 260 } 261 262 if (cria.cri_klen) { 263 MALLOC(cria.cri_key, u_int8_t *, 264 cria.cri_klen / 8, M_XDATA, M_WAITOK); 265 if ((error = copyin(sop->mackey, cria.cri_key, 266 cria.cri_klen / 8))) 267 goto bail; 268 } 269 } 270 271 error = crypto_newsession(&sid, (txform ? &crie : &cria), 1); 272 if (error) 273 goto bail; 274 275 cse = csecreate(fcr, sid, crie.cri_key, crie.cri_klen, 276 cria.cri_key, cria.cri_klen, sop->cipher, sop->mac, txform, 277 thash); 278 279 if (cse == NULL) { 280 crypto_freesession(sid); 281 error = EINVAL; 282 goto bail; 283 } 284 sop->ses = cse->ses; 285 286 bail: 287 if (error) { 288 if (crie.cri_key) 289 FREE(crie.cri_key, M_XDATA); 290 if (cria.cri_key) 291 FREE(cria.cri_key, M_XDATA); 292 } 293 break; 294 case CIOCFSESSION: 295 ses = *(u_int32_t *)data; 296 cse = csefind(fcr, ses); 297 if (cse == NULL) { 298 error = EINVAL; 299 break; 300 } 301 csedelete(fcr, cse); 302 error = csefree(cse); 303 break; 304 case CIOCCRYPT: 305 cop = (struct crypt_op *)data; 306 cse = csefind(fcr, cop->ses); 307 if (cse == NULL) { 308 error = EINVAL; 309 break; 310 } 311 error = cryptodev_op(cse, cop); 312 break; 313 case CIOCKEY: 314 error = cryptodev_key((struct crypt_kop *)data); 315 break; 316 case CIOCASYMFEAT: 317 error = crypto_getfeat((int *)data); 318 break; 319 default: 320 error = EINVAL; 321 break; 322 } 323 rel_mplock(); 324 return (error); 325 } 326 327 static int cryptodev_cb(void *); 328 329 330 static int 331 cryptodev_op(struct csession *cse, struct crypt_op *cop) 332 { 333 struct cryptop *crp = NULL; 334 struct cryptodesc *crde = NULL, *crda = NULL; 335 int i, error; 336 337 if (cop->len > 256*1024-4) 338 return (E2BIG); 339 340 if (cse->txform && (cop->len % cse->txform->blocksize) != 0) 341 return (EINVAL); 342 343 bzero(&cse->uio, sizeof(cse->uio)); 344 cse->uio.uio_iovcnt = 1; 345 cse->uio.uio_resid = 0; 346 cse->uio.uio_segflg = UIO_SYSSPACE; 347 cse->uio.uio_rw = UIO_WRITE; 348 cse->uio.uio_td = curthread; 349 cse->uio.uio_iov = cse->iovec; 350 bzero(&cse->iovec, sizeof(cse->iovec)); 351 cse->uio.uio_iov[0].iov_len = cop->len; 352 cse->uio.uio_iov[0].iov_base = kmalloc(cop->len, M_XDATA, M_WAITOK); 353 for (i = 0; i < cse->uio.uio_iovcnt; i++) 354 cse->uio.uio_resid += cse->uio.uio_iov[0].iov_len; 355 356 crp = crypto_getreq((cse->txform != NULL) + (cse->thash != NULL)); 357 if (crp == NULL) { 358 error = ENOMEM; 359 goto bail; 360 } 361 362 if (cse->thash) { 363 crda = crp->crp_desc; 364 if (cse->txform) 365 crde = crda->crd_next; 366 } else { 367 if (cse->txform) 368 crde = crp->crp_desc; 369 else { 370 error = EINVAL; 371 goto bail; 372 } 373 } 374 375 if ((error = copyin(cop->src, cse->uio.uio_iov[0].iov_base, cop->len))) 376 goto bail; 377 378 if (crda) { 379 crda->crd_skip = 0; 380 crda->crd_len = cop->len; 381 crda->crd_inject = 0; /* ??? */ 382 383 crda->crd_alg = cse->mac; 384 crda->crd_key = cse->mackey; 385 crda->crd_klen = cse->mackeylen * 8; 386 } 387 388 if (crde) { 389 if (cop->op == COP_ENCRYPT) 390 crde->crd_flags |= CRD_F_ENCRYPT; 391 else 392 crde->crd_flags &= ~CRD_F_ENCRYPT; 393 crde->crd_len = cop->len; 394 crde->crd_inject = 0; 395 396 crde->crd_alg = cse->cipher; 397 crde->crd_key = cse->key; 398 crde->crd_klen = cse->keylen * 8; 399 } 400 401 crp->crp_ilen = cop->len; 402 crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM 403 | (cop->flags & COP_F_BATCH); 404 crp->crp_buf = (caddr_t)&cse->uio; 405 crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb; 406 crp->crp_sid = cse->sid; 407 crp->crp_opaque = (void *)cse; 408 409 if (cop->iv) { 410 if (crde == NULL) { 411 error = EINVAL; 412 goto bail; 413 } 414 if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */ 415 error = EINVAL; 416 goto bail; 417 } 418 if ((error = copyin(cop->iv, cse->tmp_iv, cse->txform->blocksize))) 419 goto bail; 420 bcopy(cse->tmp_iv, crde->crd_iv, cse->txform->blocksize); 421 crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; 422 crde->crd_skip = 0; 423 } else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */ 424 crde->crd_skip = 0; 425 } else if (crde) { 426 crde->crd_flags |= CRD_F_IV_PRESENT; 427 crde->crd_skip = cse->txform->blocksize; 428 crde->crd_len -= cse->txform->blocksize; 429 } 430 431 if (cop->mac) { 432 if (crda == NULL) { 433 error = EINVAL; 434 goto bail; 435 } 436 crp->crp_mac=cse->tmp_mac; 437 } 438 439 crit_enter(); 440 error = crypto_dispatch(crp); 441 if (error == 0 && (crp->crp_flags & CRYPTO_F_DONE) == 0) 442 error = tsleep(crp, 0, "crydev", 0); 443 crit_exit(); 444 if (error) 445 goto bail; 446 447 if (crp->crp_etype != 0) { 448 error = crp->crp_etype; 449 goto bail; 450 } 451 452 if (cse->error) { 453 error = cse->error; 454 goto bail; 455 } 456 457 if (cop->dst && 458 (error = copyout(cse->uio.uio_iov[0].iov_base, cop->dst, cop->len))) 459 goto bail; 460 461 if (cop->mac && 462 (error = copyout(crp->crp_mac, cop->mac, cse->thash->authsize))) 463 goto bail; 464 465 bail: 466 if (crp) 467 crypto_freereq(crp); 468 if (cse->uio.uio_iov[0].iov_base) 469 kfree(cse->uio.uio_iov[0].iov_base, M_XDATA); 470 471 return (error); 472 } 473 474 static int 475 cryptodev_cb(void *op) 476 { 477 struct cryptop *crp = (struct cryptop *) op; 478 struct csession *cse = (struct csession *)crp->crp_opaque; 479 480 cse->error = crp->crp_etype; 481 if (crp->crp_etype == EAGAIN) 482 return crypto_dispatch(crp); 483 wakeup_one(crp); 484 return (0); 485 } 486 487 static int 488 cryptodevkey_cb(void *op) 489 { 490 struct cryptkop *krp = (struct cryptkop *) op; 491 492 wakeup_one(krp); 493 return (0); 494 } 495 496 static int 497 cryptodev_key(struct crypt_kop *kop) 498 { 499 struct cryptkop *krp = NULL; 500 int error = EINVAL; 501 int in, out, size, i; 502 503 if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) { 504 return (EFBIG); 505 } 506 507 in = kop->crk_iparams; 508 out = kop->crk_oparams; 509 switch (kop->crk_op) { 510 case CRK_MOD_EXP: 511 if (in == 3 && out == 1) 512 break; 513 return (EINVAL); 514 case CRK_MOD_EXP_CRT: 515 if (in == 6 && out == 1) 516 break; 517 return (EINVAL); 518 case CRK_DSA_SIGN: 519 if (in == 5 && out == 2) 520 break; 521 return (EINVAL); 522 case CRK_DSA_VERIFY: 523 if (in == 7 && out == 0) 524 break; 525 return (EINVAL); 526 case CRK_DH_COMPUTE_KEY: 527 if (in == 3 && out == 1) 528 break; 529 return (EINVAL); 530 default: 531 return (EINVAL); 532 } 533 534 krp = (struct cryptkop *)kmalloc(sizeof *krp, M_XDATA, M_WAITOK | M_ZERO); 535 krp->krp_op = kop->crk_op; 536 krp->krp_status = kop->crk_status; 537 krp->krp_iparams = kop->crk_iparams; 538 krp->krp_oparams = kop->crk_oparams; 539 krp->krp_status = 0; 540 krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb; 541 542 for (i = 0; i < CRK_MAXPARAM; i++) 543 krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits; 544 for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) { 545 size = (krp->krp_param[i].crp_nbits + 7) / 8; 546 if (size == 0) 547 continue; 548 MALLOC(krp->krp_param[i].crp_p, caddr_t, size, M_XDATA, M_WAITOK); 549 if (i >= krp->krp_iparams) 550 continue; 551 error = copyin(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p, size); 552 if (error) 553 goto fail; 554 } 555 556 error = crypto_kdispatch(krp); 557 if (error == 0) 558 error = tsleep(krp, 0, "crydev", 0); 559 if (error) 560 goto fail; 561 562 if (krp->krp_status != 0) { 563 error = krp->krp_status; 564 goto fail; 565 } 566 567 for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) { 568 size = (krp->krp_param[i].crp_nbits + 7) / 8; 569 if (size == 0) 570 continue; 571 error = copyout(krp->krp_param[i].crp_p, kop->crk_param[i].crp_p, size); 572 if (error) 573 goto fail; 574 } 575 576 fail: 577 if (krp) { 578 kop->crk_status = krp->krp_status; 579 for (i = 0; i < CRK_MAXPARAM; i++) { 580 if (krp->krp_param[i].crp_p) 581 FREE(krp->krp_param[i].crp_p, M_XDATA); 582 } 583 kfree(krp, M_XDATA); 584 } 585 return (error); 586 } 587 588 /* 589 * MPSAFE 590 */ 591 static int 592 cryptof_poll(struct file *fp, int events, struct ucred *active_cred) 593 { 594 return (0); 595 } 596 597 /* 598 * MPSAFE 599 */ 600 static int 601 cryptof_kqfilter(struct file *fp, struct knote *kn) 602 { 603 604 return (0); 605 } 606 607 /* 608 * MPSAFE 609 */ 610 static int 611 cryptof_stat(struct file *fp, struct stat *sb, struct ucred *cred) 612 { 613 return (EOPNOTSUPP); 614 } 615 616 /* 617 * MPALMOSTSAFE - acquires mplock 618 */ 619 static int 620 cryptof_close(struct file *fp) 621 { 622 struct fcrypt *fcr; 623 struct csession *cse; 624 625 get_mplock(); 626 fcr = (struct fcrypt *)fp->f_data; 627 while ((cse = TAILQ_FIRST(&fcr->csessions))) { 628 TAILQ_REMOVE(&fcr->csessions, cse, next); 629 (void)csefree(cse); 630 } 631 fp->f_data = NULL; 632 rel_mplock(); 633 634 FREE(fcr, M_XDATA); 635 return (0); 636 } 637 638 static struct csession * 639 csefind(struct fcrypt *fcr, u_int ses) 640 { 641 struct csession *cse; 642 643 TAILQ_FOREACH(cse, &fcr->csessions, next) 644 if (cse->ses == ses) 645 return (cse); 646 return (NULL); 647 } 648 649 static int 650 csedelete(struct fcrypt *fcr, struct csession *cse_del) 651 { 652 struct csession *cse; 653 654 TAILQ_FOREACH(cse, &fcr->csessions, next) { 655 if (cse == cse_del) { 656 TAILQ_REMOVE(&fcr->csessions, cse, next); 657 return (1); 658 } 659 } 660 return (0); 661 } 662 663 static struct csession * 664 cseadd(struct fcrypt *fcr, struct csession *cse) 665 { 666 TAILQ_INSERT_TAIL(&fcr->csessions, cse, next); 667 cse->ses = fcr->sesn++; 668 return (cse); 669 } 670 671 struct csession * 672 csecreate(struct fcrypt *fcr, u_int64_t sid, caddr_t key, u_int64_t keylen, 673 caddr_t mackey, u_int64_t mackeylen, u_int32_t cipher, u_int32_t mac, 674 struct enc_xform *txform, struct auth_hash *thash) 675 { 676 struct csession *cse; 677 678 MALLOC(cse, struct csession *, sizeof(struct csession), 679 M_XDATA, M_NOWAIT); 680 if (cse == NULL) 681 return NULL; 682 cse->key = key; 683 cse->keylen = keylen/8; 684 cse->mackey = mackey; 685 cse->mackeylen = mackeylen/8; 686 cse->sid = sid; 687 cse->cipher = cipher; 688 cse->mac = mac; 689 cse->txform = txform; 690 cse->thash = thash; 691 cseadd(fcr, cse); 692 return (cse); 693 } 694 695 static int 696 csefree(struct csession *cse) 697 { 698 int error; 699 700 error = crypto_freesession(cse->sid); 701 if (cse->key) 702 FREE(cse->key, M_XDATA); 703 if (cse->mackey) 704 FREE(cse->mackey, M_XDATA); 705 FREE(cse, M_XDATA); 706 return (error); 707 } 708 709 static int 710 cryptoopen(struct dev_open_args *ap) 711 { 712 if (crypto_usercrypto == 0) 713 return (ENXIO); 714 return (0); 715 } 716 717 static int 718 cryptoread(struct dev_read_args *ap) 719 { 720 return (EIO); 721 } 722 723 static int 724 cryptowrite(struct dev_write_args *ap) 725 { 726 return (EIO); 727 } 728 729 static int 730 cryptoioctl(struct dev_ioctl_args *ap) 731 { 732 struct file *f; 733 struct fcrypt *fcr; 734 int fd, error; 735 736 switch (ap->a_cmd) { 737 case CRIOGET: 738 MALLOC(fcr, struct fcrypt *, 739 sizeof(struct fcrypt), M_XDATA, M_WAITOK); 740 TAILQ_INIT(&fcr->csessions); 741 fcr->sesn = 0; 742 743 KKASSERT(curproc); 744 error = falloc(curproc, &f, &fd); 745 746 if (error) { 747 FREE(fcr, M_XDATA); 748 return (error); 749 } 750 f->f_type = DTYPE_CRYPTO; 751 f->f_flag = FREAD | FWRITE; 752 f->f_ops = &cryptofops; 753 f->f_data = fcr; 754 fsetfd(curproc, f, fd); 755 *(u_int32_t *)ap->a_data = fd; 756 fdrop(f); 757 break; 758 default: 759 error = EINVAL; 760 break; 761 } 762 return (error); 763 } 764 765 #define CRYPTO_MAJOR 70 /* from openbsd */ 766 static struct dev_ops crypto_ops = { 767 { "crypto", CRYPTO_MAJOR, 0 }, 768 .d_open = cryptoopen, 769 .d_close = nullclose, 770 .d_read = cryptoread, 771 .d_write = cryptowrite, 772 .d_ioctl = cryptoioctl, 773 }; 774 775 /* 776 * Initialization code, both for static and dynamic loading. 777 */ 778 static int 779 cryptodev_modevent(module_t mod, int type, void *unused) 780 { 781 switch (type) { 782 case MOD_LOAD: 783 if (bootverbose) 784 kprintf("crypto: <crypto device>\n"); 785 dev_ops_add(&crypto_ops, 0, 0); 786 make_dev(&crypto_ops, 0, UID_ROOT, GID_WHEEL, 787 0666, "crypto"); 788 return 0; 789 case MOD_UNLOAD: 790 /*XXX disallow if active sessions */ 791 dev_ops_remove(&crypto_ops, 0, 0); 792 return 0; 793 } 794 return EINVAL; 795 } 796 797 static moduledata_t cryptodev_mod = { 798 "cryptodev", 799 cryptodev_modevent, 800 0 801 }; 802 MODULE_VERSION(cryptodev, 1); 803 DECLARE_MODULE(cryptodev, cryptodev_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 804 #if 0 805 MODULE_DEPEND(cryptodev, crypto, 1, 1, 1); 806 #endif 807