1 /* $NetBSD: cryptodev.c,v 1.16 2005/12/11 12:25:20 christos Exp $ */ 2 /* $FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.4.2.4 2003/06/03 00:09:02 sam Exp $ */ 3 /* $OpenBSD: cryptodev.c,v 1.53 2002/07/10 22:21:30 mickey 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/cdefs.h> 38 __KERNEL_RCSID(0, "$NetBSD: cryptodev.c,v 1.16 2005/12/11 12:25:20 christos Exp $"); 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/malloc.h> 43 #include <sys/mbuf.h> 44 #include <sys/sysctl.h> 45 #include <sys/file.h> 46 #include <sys/filedesc.h> 47 #include <sys/errno.h> 48 #include <sys/md5.h> 49 #include <sys/sha1.h> 50 #include <sys/conf.h> 51 #include <sys/device.h> 52 53 #include <opencrypto/cryptodev.h> 54 #include <opencrypto/xform.h> 55 56 #ifdef __NetBSD__ 57 #define splcrypto splnet 58 #endif 59 60 struct csession { 61 TAILQ_ENTRY(csession) next; 62 u_int64_t sid; 63 u_int32_t ses; 64 65 u_int32_t cipher; 66 struct enc_xform *txform; 67 u_int32_t mac; 68 struct auth_hash *thash; 69 70 caddr_t key; 71 int keylen; 72 u_char tmp_iv[EALG_MAX_BLOCK_LEN]; 73 74 caddr_t mackey; 75 int mackeylen; 76 u_char tmp_mac[CRYPTO_MAX_MAC_LEN]; 77 78 struct iovec iovec[IOV_MAX]; 79 struct uio uio; 80 int error; 81 }; 82 83 struct fcrypt { 84 TAILQ_HEAD(csessionlist, csession) csessions; 85 int sesn; 86 }; 87 88 89 /* Declaration of master device (fd-cloning/ctxt-allocating) entrypoints */ 90 static int cryptoopen(dev_t dev, int flag, int mode, struct lwp *l); 91 static int cryptoread(dev_t dev, struct uio *uio, int ioflag); 92 static int cryptowrite(dev_t dev, struct uio *uio, int ioflag); 93 static int cryptoioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct lwp *l); 94 static int cryptoselect(dev_t dev, int rw, struct lwp *l); 95 96 /* Declaration of cloned-device (per-ctxt) entrypoints */ 97 static int cryptof_read(struct file *, off_t *, struct uio *, struct ucred *, int); 98 static int cryptof_write(struct file *, off_t *, struct uio *, struct ucred *, int); 99 static int cryptof_ioctl(struct file *, u_long, void*, struct lwp *l); 100 static int cryptof_close(struct file *, struct lwp *); 101 102 static const struct fileops cryptofops = { 103 cryptof_read, 104 cryptof_write, 105 cryptof_ioctl, 106 fnullop_fcntl, 107 fnullop_poll, 108 fbadop_stat, 109 cryptof_close, 110 fnullop_kqfilter 111 }; 112 113 static struct csession *csefind(struct fcrypt *, u_int); 114 static int csedelete(struct fcrypt *, struct csession *); 115 static struct csession *cseadd(struct fcrypt *, struct csession *); 116 static struct csession *csecreate(struct fcrypt *, u_int64_t, caddr_t, u_int64_t, 117 caddr_t, u_int64_t, u_int32_t, u_int32_t, struct enc_xform *, 118 struct auth_hash *); 119 static int csefree(struct csession *); 120 121 static int cryptodev_op(struct csession *, struct crypt_op *, struct lwp *); 122 static int cryptodev_key(struct crypt_kop *); 123 int cryptodev_dokey(struct crypt_kop *kop, struct crparam kvp[]); 124 125 static int cryptodev_cb(void *); 126 static int cryptodevkey_cb(void *); 127 128 /* 129 * sysctl-able control variables for /dev/crypto now defined in crypto.c: 130 * crypto_usercrypto, crypto_userasmcrypto, crypto_devallowsoft. 131 */ 132 133 /* ARGSUSED */ 134 int 135 cryptof_read(struct file *fp, off_t *poff, struct uio *uio, 136 struct ucred *cred, int flags) 137 { 138 return (EIO); 139 } 140 141 /* ARGSUSED */ 142 int 143 cryptof_write(struct file *fp, off_t *poff, struct uio *uio, 144 struct ucred *cred, int flags) 145 { 146 return (EIO); 147 } 148 149 /* ARGSUSED */ 150 int 151 cryptof_ioctl(struct file *fp, u_long cmd, void* data, struct lwp *l) 152 { 153 struct cryptoini cria, crie; 154 struct fcrypt *fcr = (struct fcrypt *)fp->f_data; 155 struct csession *cse; 156 struct session_op *sop; 157 struct crypt_op *cop; 158 struct enc_xform *txform = NULL; 159 struct auth_hash *thash = NULL; 160 u_int64_t sid; 161 u_int32_t ses; 162 int error = 0; 163 164 switch (cmd) { 165 case CIOCGSESSION: 166 sop = (struct session_op *)data; 167 switch (sop->cipher) { 168 case 0: 169 break; 170 case CRYPTO_DES_CBC: 171 txform = &enc_xform_des; 172 break; 173 case CRYPTO_3DES_CBC: 174 txform = &enc_xform_3des; 175 break; 176 case CRYPTO_BLF_CBC: 177 txform = &enc_xform_blf; 178 break; 179 case CRYPTO_CAST_CBC: 180 txform = &enc_xform_cast5; 181 break; 182 case CRYPTO_SKIPJACK_CBC: 183 txform = &enc_xform_skipjack; 184 break; 185 case CRYPTO_AES_CBC: 186 txform = &enc_xform_rijndael128; 187 break; 188 case CRYPTO_NULL_CBC: 189 txform = &enc_xform_null; 190 break; 191 case CRYPTO_ARC4: 192 txform = &enc_xform_arc4; 193 break; 194 default: 195 return (EINVAL); 196 } 197 198 switch (sop->mac) { 199 case 0: 200 break; 201 case CRYPTO_MD5_HMAC: 202 thash = &auth_hash_hmac_md5_96; 203 break; 204 case CRYPTO_SHA1_HMAC: 205 thash = &auth_hash_hmac_sha1_96; 206 break; 207 case CRYPTO_SHA2_HMAC: 208 if (sop->mackeylen == auth_hash_hmac_sha2_256.keysize) 209 thash = &auth_hash_hmac_sha2_256; 210 else if (sop->mackeylen == auth_hash_hmac_sha2_384.keysize) 211 thash = &auth_hash_hmac_sha2_384; 212 else if (sop->mackeylen == auth_hash_hmac_sha2_512.keysize) 213 thash = &auth_hash_hmac_sha2_512; 214 else 215 return (EINVAL); 216 break; 217 case CRYPTO_RIPEMD160_HMAC: 218 thash = &auth_hash_hmac_ripemd_160_96; 219 break; 220 case CRYPTO_MD5: 221 thash = &auth_hash_md5; 222 break; 223 case CRYPTO_SHA1: 224 thash = &auth_hash_sha1; 225 break; 226 case CRYPTO_NULL_HMAC: 227 thash = &auth_hash_null; 228 break; 229 default: 230 return (EINVAL); 231 } 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), 272 crypto_devallowsoft); 273 if (error) { 274 #ifdef CRYPTO_DEBUG 275 printf("SIOCSESSION violates kernel parameters\n"); 276 #endif 277 goto bail; 278 } 279 280 cse = csecreate(fcr, sid, crie.cri_key, crie.cri_klen, 281 cria.cri_key, cria.cri_klen, sop->cipher, sop->mac, txform, 282 thash); 283 284 if (cse == NULL) { 285 crypto_freesession(sid); 286 error = EINVAL; 287 goto bail; 288 } 289 sop->ses = cse->ses; 290 291 bail: 292 if (error) { 293 if (crie.cri_key) 294 FREE(crie.cri_key, M_XDATA); 295 if (cria.cri_key) 296 FREE(cria.cri_key, M_XDATA); 297 } 298 break; 299 case CIOCFSESSION: 300 ses = *(u_int32_t *)data; 301 cse = csefind(fcr, ses); 302 if (cse == NULL) 303 return (EINVAL); 304 csedelete(fcr, cse); 305 error = csefree(cse); 306 break; 307 case CIOCCRYPT: 308 cop = (struct crypt_op *)data; 309 cse = csefind(fcr, cop->ses); 310 if (cse == NULL) 311 return (EINVAL); 312 error = cryptodev_op(cse, cop, l); 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 } 323 return (error); 324 } 325 326 static int 327 cryptodev_op(struct csession *cse, struct crypt_op *cop, struct lwp *l) 328 { 329 struct cryptop *crp = NULL; 330 struct cryptodesc *crde = NULL, *crda = NULL; 331 int i, error, s; 332 333 if (cop->len > 256*1024-4) 334 return (E2BIG); 335 336 if (cse->txform) { 337 if (cop->len == 0 || (cop->len % cse->txform->blocksize) != 0) 338 return (EINVAL); 339 } 340 341 bzero(&cse->uio, sizeof(cse->uio)); 342 cse->uio.uio_iovcnt = 1; 343 cse->uio.uio_resid = 0; 344 cse->uio.uio_segflg = UIO_SYSSPACE; 345 cse->uio.uio_rw = UIO_WRITE; 346 cse->uio.uio_lwp = NULL; 347 cse->uio.uio_iov = cse->iovec; 348 bzero(&cse->iovec, sizeof(cse->iovec)); 349 cse->uio.uio_iov[0].iov_len = cop->len; 350 cse->uio.uio_iov[0].iov_base = malloc(cop->len, M_XDATA, M_WAITOK); 351 for (i = 0; i < cse->uio.uio_iovcnt; i++) 352 cse->uio.uio_resid += cse->uio.uio_iov[0].iov_len; 353 354 crp = crypto_getreq((cse->txform != NULL) + (cse->thash != NULL)); 355 if (crp == NULL) { 356 error = ENOMEM; 357 goto bail; 358 } 359 360 if (cse->thash) { 361 crda = crp->crp_desc; 362 if (cse->txform) 363 crde = crda->crd_next; 364 } else { 365 if (cse->txform) 366 crde = crp->crp_desc; 367 else { 368 error = EINVAL; 369 goto bail; 370 } 371 } 372 373 if ((error = copyin(cop->src, cse->uio.uio_iov[0].iov_base, cop->len))) 374 goto bail; 375 376 if (crda) { 377 crda->crd_skip = 0; 378 crda->crd_len = cop->len; 379 crda->crd_inject = 0; /* ??? */ 380 381 crda->crd_alg = cse->mac; 382 crda->crd_key = cse->mackey; 383 crda->crd_klen = cse->mackeylen * 8; 384 } 385 386 if (crde) { 387 if (cop->op == COP_ENCRYPT) 388 crde->crd_flags |= CRD_F_ENCRYPT; 389 else 390 crde->crd_flags &= ~CRD_F_ENCRYPT; 391 crde->crd_len = cop->len; 392 crde->crd_inject = 0; 393 394 crde->crd_alg = cse->cipher; 395 crde->crd_key = cse->key; 396 crde->crd_klen = cse->keylen * 8; 397 } 398 399 crp->crp_ilen = cop->len; 400 crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM 401 | (cop->flags & COP_F_BATCH); 402 crp->crp_buf = (caddr_t)&cse->uio; 403 crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb; 404 crp->crp_sid = cse->sid; 405 crp->crp_opaque = (void *)cse; 406 407 if (cop->iv) { 408 if (crde == NULL) { 409 error = EINVAL; 410 goto bail; 411 } 412 if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */ 413 error = EINVAL; 414 goto bail; 415 } 416 if ((error = copyin(cop->iv, cse->tmp_iv, cse->txform->blocksize))) 417 goto bail; 418 bcopy(cse->tmp_iv, crde->crd_iv, cse->txform->blocksize); 419 crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; 420 crde->crd_skip = 0; 421 } else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */ 422 crde->crd_skip = 0; 423 } else if (crde) { 424 crde->crd_flags |= CRD_F_IV_PRESENT; 425 crde->crd_skip = cse->txform->blocksize; 426 crde->crd_len -= cse->txform->blocksize; 427 } 428 429 if (cop->mac) { 430 if (crda == NULL) { 431 error = EINVAL; 432 goto bail; 433 } 434 crp->crp_mac=cse->tmp_mac; 435 } 436 437 s = splcrypto(); /* NB: only needed with CRYPTO_F_CBIMM */ 438 error = crypto_dispatch(crp); 439 if (error == 0 && (crp->crp_flags & CRYPTO_F_DONE) == 0) 440 error = tsleep(crp, PSOCK, "crydev", 0); 441 splx(s); 442 if (error) { 443 goto bail; 444 } 445 446 if (crp->crp_etype != 0) { 447 error = crp->crp_etype; 448 goto bail; 449 } 450 451 if (cse->error) { 452 error = cse->error; 453 goto bail; 454 } 455 456 if (cop->dst && 457 (error = copyout(cse->uio.uio_iov[0].iov_base, cop->dst, cop->len))) 458 goto bail; 459 460 if (cop->mac && 461 (error = copyout(crp->crp_mac, cop->mac, cse->thash->authsize))) 462 goto bail; 463 464 bail: 465 if (crp) 466 crypto_freereq(crp); 467 if (cse->uio.uio_iov[0].iov_base) 468 free(cse->uio.uio_iov[0].iov_base, M_XDATA); 469 470 return (error); 471 } 472 473 static int 474 cryptodev_cb(void *op) 475 { 476 struct cryptop *crp = (struct cryptop *) op; 477 struct csession *cse = (struct csession *)crp->crp_opaque; 478 479 cse->error = crp->crp_etype; 480 if (crp->crp_etype == EAGAIN) 481 return crypto_dispatch(crp); 482 wakeup_one(crp); 483 return (0); 484 } 485 486 static int 487 cryptodevkey_cb(void *op) 488 { 489 struct cryptkop *krp = (struct cryptkop *) op; 490 491 wakeup_one(krp); 492 return (0); 493 } 494 495 static int 496 cryptodev_key(struct crypt_kop *kop) 497 { 498 struct cryptkop *krp = NULL; 499 int error = EINVAL; 500 int in, out, size, i; 501 502 if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) { 503 return (EFBIG); 504 } 505 506 in = kop->crk_iparams; 507 out = kop->crk_oparams; 508 switch (kop->crk_op) { 509 case CRK_MOD_EXP: 510 if (in == 3 && out == 1) 511 break; 512 return (EINVAL); 513 case CRK_MOD_EXP_CRT: 514 if (in == 6 && out == 1) 515 break; 516 return (EINVAL); 517 case CRK_DSA_SIGN: 518 if (in == 5 && out == 2) 519 break; 520 return (EINVAL); 521 case CRK_DSA_VERIFY: 522 if (in == 7 && out == 0) 523 break; 524 return (EINVAL); 525 case CRK_DH_COMPUTE_KEY: 526 if (in == 3 && out == 1) 527 break; 528 return (EINVAL); 529 default: 530 return (EINVAL); 531 } 532 533 krp = (struct cryptkop *)malloc(sizeof *krp, M_XDATA, M_WAITOK); 534 if (!krp) 535 return (ENOMEM); 536 bzero(krp, sizeof *krp); 537 krp->krp_op = kop->crk_op; 538 krp->krp_status = kop->crk_status; 539 krp->krp_iparams = kop->crk_iparams; 540 krp->krp_oparams = kop->crk_oparams; 541 krp->krp_status = 0; 542 krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb; 543 544 for (i = 0; i < CRK_MAXPARAM; i++) 545 krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits; 546 for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) { 547 size = (krp->krp_param[i].crp_nbits + 7) / 8; 548 if (size == 0) 549 continue; 550 MALLOC(krp->krp_param[i].crp_p, caddr_t, size, M_XDATA, M_WAITOK); 551 if (i >= krp->krp_iparams) 552 continue; 553 error = copyin(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p, size); 554 if (error) 555 goto fail; 556 } 557 558 error = crypto_kdispatch(krp); 559 if (error == 0) 560 error = tsleep(krp, PSOCK, "crydev", 0); 561 if (error) 562 goto fail; 563 564 if (krp->krp_status != 0) { 565 error = krp->krp_status; 566 goto fail; 567 } 568 569 for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) { 570 size = (krp->krp_param[i].crp_nbits + 7) / 8; 571 if (size == 0) 572 continue; 573 error = copyout(krp->krp_param[i].crp_p, kop->crk_param[i].crp_p, size); 574 if (error) 575 goto fail; 576 } 577 578 fail: 579 if (krp) { 580 kop->crk_status = krp->krp_status; 581 for (i = 0; i < CRK_MAXPARAM; i++) { 582 if (krp->krp_param[i].crp_p) 583 FREE(krp->krp_param[i].crp_p, M_XDATA); 584 } 585 free(krp, M_XDATA); 586 } 587 return (error); 588 } 589 590 /* ARGSUSED */ 591 static int 592 cryptof_close(struct file *fp, struct lwp *l) 593 { 594 struct fcrypt *fcr = (struct fcrypt *)fp->f_data; 595 struct csession *cse; 596 597 while ((cse = TAILQ_FIRST(&fcr->csessions))) { 598 TAILQ_REMOVE(&fcr->csessions, cse, next); 599 (void)csefree(cse); 600 } 601 FREE(fcr, M_XDATA); 602 603 /* close() stolen from sys/kern/kern_ktrace.c */ 604 605 fp->f_data = NULL; 606 #if 0 607 FILE_UNUSE(fp, l); /* release file */ 608 fdrelease(l, fd); /* release fd table slot */ 609 #endif 610 611 return 0; 612 } 613 614 static struct csession * 615 csefind(struct fcrypt *fcr, u_int ses) 616 { 617 struct csession *cse; 618 619 TAILQ_FOREACH(cse, &fcr->csessions, next) 620 if (cse->ses == ses) 621 return (cse); 622 return (NULL); 623 } 624 625 static int 626 csedelete(struct fcrypt *fcr, struct csession *cse_del) 627 { 628 struct csession *cse; 629 630 TAILQ_FOREACH(cse, &fcr->csessions, next) { 631 if (cse == cse_del) { 632 TAILQ_REMOVE(&fcr->csessions, cse, next); 633 return (1); 634 } 635 } 636 return (0); 637 } 638 639 static struct csession * 640 cseadd(struct fcrypt *fcr, struct csession *cse) 641 { 642 TAILQ_INSERT_TAIL(&fcr->csessions, cse, next); 643 cse->ses = fcr->sesn++; 644 return (cse); 645 } 646 647 static struct csession * 648 csecreate(struct fcrypt *fcr, u_int64_t sid, caddr_t key, u_int64_t keylen, 649 caddr_t mackey, u_int64_t mackeylen, u_int32_t cipher, u_int32_t mac, 650 struct enc_xform *txform, struct auth_hash *thash) 651 { 652 struct csession *cse; 653 654 MALLOC(cse, struct csession *, sizeof(struct csession), 655 M_XDATA, M_NOWAIT); 656 if (cse == NULL) 657 return NULL; 658 cse->key = key; 659 cse->keylen = keylen/8; 660 cse->mackey = mackey; 661 cse->mackeylen = mackeylen/8; 662 cse->sid = sid; 663 cse->cipher = cipher; 664 cse->mac = mac; 665 cse->txform = txform; 666 cse->thash = thash; 667 cseadd(fcr, cse); 668 return (cse); 669 } 670 671 static int 672 csefree(struct csession *cse) 673 { 674 int error; 675 676 error = crypto_freesession(cse->sid); 677 if (cse->key) 678 FREE(cse->key, M_XDATA); 679 if (cse->mackey) 680 FREE(cse->mackey, M_XDATA); 681 FREE(cse, M_XDATA); 682 return (error); 683 } 684 685 static int 686 cryptoopen(dev_t dev, int flag, int mode, struct lwp *l) 687 { 688 if (crypto_usercrypto == 0) 689 return (ENXIO); 690 return (0); 691 } 692 693 static int 694 cryptoread(dev_t dev, struct uio *uio, int ioflag) 695 { 696 return (EIO); 697 } 698 699 static int 700 cryptowrite(dev_t dev, struct uio *uio, int ioflag) 701 { 702 return (EIO); 703 } 704 705 static int 706 cryptoioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct lwp *l) 707 { 708 struct file *f; 709 struct fcrypt *fcr; 710 int fd, error; 711 712 switch (cmd) { 713 case CRIOGET: 714 MALLOC(fcr, struct fcrypt *, 715 sizeof(struct fcrypt), M_XDATA, M_WAITOK); 716 TAILQ_INIT(&fcr->csessions); 717 fcr->sesn = 0; 718 719 error = falloc(l->l_proc, &f, &fd); 720 if (error) { 721 FREE(fcr, M_XDATA); 722 return (error); 723 } 724 f->f_flag = FREAD | FWRITE; 725 f->f_type = DTYPE_CRYPTO; 726 f->f_ops = &cryptofops; 727 f->f_data = (caddr_t) fcr; 728 *(u_int32_t *)data = fd; 729 FILE_SET_MATURE(f); 730 FILE_UNUSE(f, l); 731 break; 732 default: 733 error = EINVAL; 734 break; 735 } 736 return (error); 737 } 738 739 int 740 cryptoselect(dev_t dev, int rw, struct lwp *l) 741 { 742 return (0); 743 } 744 745 /*static*/ 746 struct cdevsw crypto_cdevsw = { 747 /* open */ cryptoopen, 748 /* close */ nullclose, 749 /* read */ cryptoread, 750 /* write */ cryptowrite, 751 /* ioctl */ cryptoioctl, 752 /* ttstop?*/ nostop, 753 /* ??*/ notty, 754 /* poll */ cryptoselect /*nopoll*/, 755 /* mmap */ nommap, 756 /* kqfilter */ nokqfilter, 757 }; 758 759 #ifdef __NetBSD__ 760 /* 761 * Pseudo-device initialization routine for /dev/crypto 762 */ 763 void cryptoattach(int); 764 765 void 766 cryptoattach(int num) 767 { 768 769 /* nothing to do */ 770 } 771 #endif /* __NetBSD__ */ 772