1 /* $NetBSD: cryptodev.c,v 1.133 2026/05/19 19:00:00 riastradh 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) 2008 The NetBSD Foundation, Inc. 7 * All rights reserved. 8 * 9 * This code is derived from software contributed to The NetBSD Foundation 10 * by Coyote Point Systems, Inc. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * Copyright (c) 2001 Theo de Raadt 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 3. The name of the author may not be used to endorse or promote products 47 * derived from this software without specific prior written permission. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 50 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 51 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 52 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 53 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 54 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 55 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 56 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 57 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 58 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 59 * 60 * Effort sponsored in part by the Defense Advanced Research Projects 61 * Agency (DARPA) and Air Force Research Laboratory, Air Force 62 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 63 * 64 */ 65 66 #include <sys/cdefs.h> 67 __KERNEL_RCSID(0, "$NetBSD: cryptodev.c,v 1.133 2026/05/19 19:00:00 riastradh Exp $"); 68 69 #include <sys/param.h> 70 #include <sys/systm.h> 71 #include <sys/kmem.h> 72 #include <sys/malloc.h> 73 #include <sys/mbuf.h> 74 #include <sys/pool.h> 75 #include <sys/sysctl.h> 76 #include <sys/file.h> 77 #include <sys/filedesc.h> 78 #include <sys/errno.h> 79 #include <sys/md5.h> 80 #include <sys/sha1.h> 81 #include <sys/conf.h> 82 #include <sys/device.h> 83 #include <sys/kauth.h> 84 #include <sys/select.h> 85 #include <sys/poll.h> 86 #include <sys/atomic.h> 87 #include <sys/stat.h> 88 #include <sys/module.h> 89 #include <sys/compat_stub.h> 90 91 #include "ioconf.h" 92 93 #ifdef _KERNEL_OPT 94 #include "opt_ocf.h" 95 #include "opt_compat_netbsd.h" 96 #endif 97 98 #include <opencrypto/cryptodev.h> 99 #include <opencrypto/ocryptodev.h> 100 #include <opencrypto/cryptodev_internal.h> 101 #include <opencrypto/xform.h> 102 103 #include "ioconf.h" 104 105 static kmutex_t cryptodev_mtx; 106 107 struct csession { 108 TAILQ_ENTRY(csession) next; 109 kmutex_t lock; 110 uint64_t sid; 111 uint32_t ses; 112 volatile uint32_t refcnt; 113 114 uint32_t cipher; /* note: shares name space in crd_alg */ 115 const struct enc_xform *txform; 116 uint32_t mac; /* note: shares name space in crd_alg */ 117 const struct auth_hash *thash; 118 uint32_t comp_alg; /* note: shares name space in crd_alg */ 119 const struct comp_algo *tcomp; 120 121 void * key; 122 int keylen; 123 124 void * mackey; 125 int mackeylen; 126 }; 127 128 struct fcrypt { 129 TAILQ_HEAD(csessionlist, csession) csessions; 130 TAILQ_HEAD(crprethead, cryptop) crp_ret_mq; 131 TAILQ_HEAD(krprethead, cryptkop) crp_ret_mkq; 132 uint32_t sesn; 133 struct selinfo sinfo; 134 uint32_t requestid; 135 struct timespec atime; 136 struct timespec mtime; 137 struct timespec btime; 138 kmutex_t lock; 139 }; 140 141 /* For our fixed-size allocations */ 142 static struct pool fcrpl; 143 static struct pool csepl; 144 145 /* Declaration of master device (fd-cloning/ctxt-allocating) entrypoints */ 146 static int cryptoopen(dev_t dev, int flag, int mode, struct lwp *l); 147 static int cryptoread(dev_t dev, struct uio *uio, int ioflag); 148 static int cryptowrite(dev_t dev, struct uio *uio, int ioflag); 149 static int cryptoselect(dev_t dev, int rw, struct lwp *l); 150 151 static bool crypto_detaching = false; 152 static int crypto_refcount = 0; /* Prevent detaching while in use */ 153 154 static int 155 crypto_refcount_get(void) 156 { 157 int error; 158 159 mutex_enter(&cryptodev_mtx); 160 if (crypto_detaching) { 161 error = ENXIO; 162 } else if (crypto_refcount == INT_MAX) { 163 error = EBUSY; 164 } else { 165 crypto_refcount++; 166 error = 0; 167 } 168 mutex_exit(&cryptodev_mtx); 169 170 return error; 171 } 172 173 static void 174 crypto_refcount_put(void) 175 { 176 177 mutex_enter(&cryptodev_mtx); 178 KASSERT(crypto_refcount > 0); 179 crypto_refcount--; 180 mutex_exit(&cryptodev_mtx); 181 } 182 183 /* Declaration of cloned-device (per-ctxt) entrypoints */ 184 static int cryptof_read(struct file *, off_t *, struct uio *, 185 kauth_cred_t, int); 186 static int cryptof_write(struct file *, off_t *, struct uio *, 187 kauth_cred_t, int); 188 static int cryptof_ioctl(struct file *, u_long, void *); 189 static int cryptof_close(struct file *); 190 static int cryptof_poll(struct file *, int); 191 static int cryptof_stat(struct file *, struct stat *); 192 193 static const struct fileops cryptofops = { 194 .fo_name = "cryptof", 195 .fo_read = cryptof_read, 196 .fo_write = cryptof_write, 197 .fo_ioctl = cryptof_ioctl, 198 .fo_fcntl = fnullop_fcntl, 199 .fo_poll = cryptof_poll, 200 .fo_stat = cryptof_stat, 201 .fo_close = cryptof_close, 202 .fo_kqfilter = fnullop_kqfilter, 203 .fo_restart = fnullop_restart, 204 }; 205 206 static struct csession *cse_find(struct fcrypt *, uint32_t); 207 static int cse_delete(struct fcrypt *, uint32_t); 208 static struct csession *cse_add(struct fcrypt *, struct csession *); 209 static struct csession *cse_create(struct fcrypt *, uint64_t, void *, 210 uint64_t, void *, uint64_t, uint32_t, uint32_t, uint32_t, 211 const struct enc_xform *, const struct auth_hash *, 212 const struct comp_algo *); 213 static void cse_free(struct csession *); 214 215 static int cryptodev_key(struct crypt_kop *); 216 static int cryptodev_mkey(struct fcrypt *, struct crypt_n_kop *, size_t); 217 static void cryptodev_msessionfin(struct fcrypt *, size_t, uint32_t *); 218 219 static void cryptodev_cb(struct cryptop *); 220 static void cryptodevkey_cb(struct cryptkop *); 221 222 static void cryptodev_mcb(struct cryptop *); 223 static void cryptodevkey_mcb(struct cryptkop *); 224 225 static int cryptodev_getmstatus(struct fcrypt *, struct crypt_result *, 226 int); 227 static int cryptodev_getstatus(struct fcrypt *, struct crypt_result *); 228 229 static struct cryptop_data * 230 cod_ctor(struct cryptop_data *cod, struct csession *cse, size_t iov_len) 231 { 232 memset(cod, 0, sizeof(*cod)); 233 cod->cse = cse; 234 cod->iov_len = iov_len; 235 cod->uio.uio_iovcnt = 1; 236 cod->uio.uio_resid = 0; 237 cod->uio.uio_rw = UIO_WRITE; 238 cod->uio.uio_iov = cod->iovec; 239 UIO_SETUP_SYSSPACE(&cod->uio); 240 241 /* the iov needs to be big enough to handle the uncompressed data.... */ 242 cod->uio.uio_iov[0].iov_len = cod->iov_len; 243 if (cod->iov_len > 0) 244 cod->uio.uio_iov[0].iov_base = kmem_zalloc(iov_len, KM_SLEEP); 245 cod->uio.uio_resid = cod->uio.uio_iov[0].iov_len; 246 DPRINTF("lid[%u]: uio.iov_base %p malloced %zu bytes\n", 247 CRYPTO_SESID2LID(cse->sid), 248 cod->uio.uio_iov[0].iov_base, cod->iov_len); 249 return cod; 250 } 251 252 static void 253 cod_dtor(struct cryptop_data *cod) 254 { 255 DPRINTF("lid[%u]: uio.iov_base %p freeing %zu bytes\n", 256 CRYPTO_SESID2LID(cod->cse->sid), 257 cod->uio.uio_iov[0].iov_base, cod->iov_len); 258 if (cod->iov_len && cod->uio.uio_iov[0].iov_base) { 259 kmem_free(cod->uio.uio_iov[0].iov_base, cod->iov_len); 260 cod->uio.uio_iov[0].iov_base = NULL; 261 } 262 } 263 264 static void 265 fcrypt_settime(struct fcrypt *fcr) 266 { 267 mutex_enter(&fcr->lock); 268 fcr->mtime = fcr->atime; 269 mutex_exit(&fcr->lock); 270 } 271 272 static struct fcrypt * 273 fcrypt_ctor(void) 274 { 275 struct fcrypt *fcr; 276 277 fcr = pool_get(&fcrpl, PR_WAITOK); 278 getnanotime(&fcr->btime); 279 fcr->atime = fcr->mtime = fcr->btime; 280 TAILQ_INIT(&fcr->csessions); 281 TAILQ_INIT(&fcr->crp_ret_mq); 282 TAILQ_INIT(&fcr->crp_ret_mkq); 283 selinit(&fcr->sinfo); 284 /* 285 * Don't ever return session 0, to allow detection of 286 * failed creation attempts with multi-create ioctl. 287 */ 288 fcr->sesn = 1; 289 fcr->requestid = 1; 290 mutex_init(&fcr->lock, MUTEX_DEFAULT, IPL_NONE); 291 292 return fcr; 293 } 294 295 static void 296 fcrypt_dtor(struct fcrypt *fcr) 297 { 298 struct csession *cse; 299 300 while ((cse = TAILQ_FIRST(&fcr->csessions))) { 301 TAILQ_REMOVE(&fcr->csessions, cse, next); 302 KASSERT(atomic_load_relaxed(&cse->refcnt) == 1); 303 cse_free(cse); 304 } 305 seldestroy(&fcr->sinfo); 306 mutex_destroy(&fcr->lock); 307 308 pool_put(&fcrpl, fcr); 309 } 310 311 /* 312 * sysctl-able control variables for /dev/crypto now defined in crypto.c: 313 * crypto_usercrypto, crypto_userasymcrypto, crypto_devallowsoft. 314 */ 315 316 /* ARGSUSED */ 317 int 318 cryptof_read(file_t *fp, off_t *poff, 319 struct uio *uio, kauth_cred_t cred, int flags) 320 { 321 return EIO; 322 } 323 324 /* ARGSUSED */ 325 int 326 cryptof_write(file_t *fp, off_t *poff, 327 struct uio *uio, kauth_cred_t cred, int flags) 328 { 329 return EIO; 330 } 331 332 /* ARGSUSED */ 333 int 334 cryptof_ioctl(struct file *fp, u_long cmd, void *data) 335 { 336 struct fcrypt *fcr = fp->f_fcrypt; 337 struct csession *cse; 338 struct session_op *sop; 339 struct session_n_op *snop; 340 struct crypt_op *cop; 341 struct crypt_mop *mop; 342 struct crypt_mkop *mkop; 343 struct crypt_n_op *cnop; 344 struct crypt_n_kop *knop; 345 struct crypt_sgop *sgop; 346 struct crypt_sfop *sfop; 347 struct cryptret *crypt_ret; 348 struct crypt_result *crypt_res; 349 uint32_t ses; 350 uint32_t *sesid; 351 int error = 0; 352 size_t count, len; 353 354 /* backwards compatibility */ 355 file_t *criofp; 356 struct fcrypt *criofcr; 357 int criofd; 358 359 mutex_enter(&fcr->lock); 360 getnanotime(&fcr->atime); 361 mutex_exit(&fcr->lock); 362 363 switch (cmd) { 364 case CRIOGET: /* XXX deprecated, remove after 5.0 */ 365 error = crypto_refcount_get(); 366 if (error) 367 return error; 368 if ((error = fd_allocfile(&criofp, &criofd)) != 0) { 369 crypto_refcount_put(); 370 return error; 371 } 372 criofcr = fcrypt_ctor(); 373 error = fd_clone(criofp, criofd, (FREAD|FWRITE), 374 &cryptofops, criofcr); 375 KASSERTMSG(error == EMOVEFD, "error=%d", error); 376 *(uint32_t *)data = criofd; 377 return 0; 378 case CIOCGSESSION: 379 sop = (struct session_op *)data; 380 error = cryptodev_session(fcr, sop); 381 DPRINTF("create(%#x) error = %d\n", sop->ses, error); 382 break; 383 case CIOCNGSESSION: 384 sgop = (struct crypt_sgop *)data; 385 if (sgop->count <= 0 || sgop->count > 386 MIN(CRYPTODEV_OPS_MAX, SIZE_MAX/sizeof(*snop))) { 387 error = EINVAL; 388 break; 389 } 390 len = sgop->count * sizeof(*snop); 391 snop = kmem_alloc(len, KM_SLEEP); 392 error = copyin(sgop->sessions, snop, len); 393 if (!error) { 394 fcrypt_settime(fcr); 395 error = cryptodev_msession(fcr, snop, sgop->count); 396 if (!error) { 397 error = copyout(snop, sgop->sessions, len); 398 } 399 } 400 kmem_free(snop, len); 401 break; 402 case CIOCFSESSION: 403 fcrypt_settime(fcr); 404 ses = *(uint32_t *)data; 405 mutex_enter(&fcr->lock); 406 error = cse_delete(fcr, ses); 407 mutex_exit(&fcr->lock); 408 DPRINTF("destroy(%#x) error = %d\n", ses, error); 409 break; 410 case CIOCNFSESSION: 411 fcrypt_settime(fcr); 412 sfop = (struct crypt_sfop *)data; 413 if (sfop->count <= 0 || sfop->count > 414 MIN(CRYPTODEV_OPS_MAX, SIZE_MAX/sizeof(*sesid))) { 415 error = EINVAL; 416 break; 417 } 418 len = sfop->count * sizeof(*sesid); 419 sesid = kmem_alloc(len, KM_SLEEP); 420 error = copyin(sfop->sesid, sesid, len); 421 if (!error) { 422 cryptodev_msessionfin(fcr, sfop->count, sesid); 423 } 424 kmem_free(sesid, len); 425 break; 426 case CIOCCRYPT: 427 fcrypt_settime(fcr); 428 cop = (struct crypt_op *)data; 429 cse = cse_find(fcr, cop->ses); 430 if (cse == NULL) { 431 DPRINTF("cse_find failed %#x\n", cop->ses); 432 return EINVAL; 433 } 434 error = cryptodev_op(cse, cop, curlwp); 435 cse_free(cse); 436 DPRINTF("cryptodev_op error = %d\n", error); 437 break; 438 case CIOCNCRYPTM: 439 fcrypt_settime(fcr); 440 mop = (struct crypt_mop *)data; 441 if (mop->count <= 0 || mop->count > 442 MIN(CRYPTODEV_OPS_MAX, SIZE_MAX/sizeof(*cnop))) { 443 error = EINVAL; 444 break; 445 } 446 len = mop->count * sizeof(*cnop); 447 cnop = kmem_alloc(len, KM_SLEEP); 448 error = copyin(mop->reqs, cnop, len); 449 if (!error) { 450 error = cryptodev_mop(fcr, cnop, mop->count, curlwp); 451 if (!error) { 452 error = copyout(cnop, mop->reqs, len); 453 } 454 } 455 kmem_free(cnop, len); 456 break; 457 case CIOCKEY: 458 error = cryptodev_key((struct crypt_kop *)data); 459 DPRINTF("cryptodev_key error = %d\n", error); 460 break; 461 case CIOCNFKEYM: 462 fcrypt_settime(fcr); 463 mkop = (struct crypt_mkop *)data; 464 if (mkop->count <= 0 || mkop->count > 465 MIN(CRYPTODEV_OPS_MAX, SIZE_MAX/sizeof(*knop))) { 466 error = EINVAL; 467 break; 468 } 469 len = mkop->count * sizeof(*knop); 470 knop = kmem_alloc(len, KM_SLEEP); 471 error = copyin(mkop->reqs, knop, len); 472 if (!error) { 473 error = cryptodev_mkey(fcr, knop, mkop->count); 474 if (!error) 475 error = copyout(knop, mkop->reqs, len); 476 } 477 kmem_free(knop, len); 478 break; 479 case CIOCASYMFEAT: 480 error = crypto_getfeat((int *)data); 481 break; 482 case CIOCNCRYPTRETM: 483 fcrypt_settime(fcr); 484 crypt_ret = (struct cryptret *)data; 485 if (crypt_ret->count <= 0 || crypt_ret->count > 486 MIN(CRYPTODEV_OPS_MAX, SIZE_MAX/sizeof(*crypt_res))) { 487 error = EINVAL; 488 break; 489 } 490 len = crypt_ret->count * sizeof(*crypt_res); 491 crypt_res = kmem_alloc(len, KM_SLEEP); 492 error = copyin(crypt_ret->results, crypt_res, len); 493 if (error) 494 goto reterr; 495 count = crypt_ret->count; 496 crypt_ret->count = cryptodev_getmstatus(fcr, crypt_res, 497 crypt_ret->count); 498 /* sanity check count */ 499 if (crypt_ret->count > count) { 500 printf("%s.%d: error returned count %zd > original " 501 " count %zd\n", 502 __FILE__, __LINE__, crypt_ret->count, count); 503 crypt_ret->count = count; 504 505 } 506 error = copyout(crypt_res, crypt_ret->results, len); 507 reterr: 508 kmem_free(crypt_res, len); 509 break; 510 case CIOCNCRYPTRET: 511 error = cryptodev_getstatus(fcr, (struct crypt_result *)data); 512 break; 513 default: 514 /* Check for backward compatible commands */ 515 516 MODULE_HOOK_CALL(ocryptof_50_hook, (fp, cmd, data), 517 enosys(), error); 518 if (error == ENOSYS) 519 error = EINVAL; 520 return error; 521 } 522 return error; 523 } 524 525 int 526 cryptodev_op(struct csession *cse, struct crypt_op *cop, struct lwp *l) 527 { 528 struct cryptop *crp = NULL; 529 struct cryptop_data *cod = NULL; 530 struct cryptodesc *crde = NULL, *crda = NULL, *crdc = NULL; 531 int error; 532 size_t iov_len = cop->len; 533 int flags=0; 534 size_t dst_len; /* copyout size */ 535 536 if (cop->len > 256*1024-4) 537 return E2BIG; 538 539 if (cse->txform) { 540 if (cop->len < cse->txform->blocksize 541 + (cop->iv ? 0 : cse->txform->ivsize) || 542 (cop->len - (cop->iv ? 0 : cse->txform->ivsize)) 543 % cse->txform->blocksize != 0) 544 return EINVAL; 545 } 546 547 if (cse->tcomp == NULL && cse->txform == NULL && cse->thash == NULL) 548 return EINVAL; 549 550 DPRINTF("[%u]: iov_len %zu\n", 551 CRYPTO_SESID2LID(cse->sid), iov_len); 552 if ((cse->tcomp) && cop->dst_len) { 553 if (iov_len < cop->dst_len) { 554 /* Need larger iov to deal with decompress */ 555 iov_len = cop->dst_len; 556 } 557 DPRINTF("iov_len -> %zu for decompress\n", iov_len); 558 } 559 560 561 crp = crypto_getreq((cse->tcomp != NULL) 562 + (cse->txform != NULL) + (cse->thash != NULL)); 563 if (crp == NULL) { 564 error = ENOMEM; 565 goto bail; 566 } 567 cod = cod_ctor(&crp->cod, cse, iov_len); 568 DPRINTF("lid[%u]: crp %p\n", CRYPTO_SESID2LID(cse->sid), crp); 569 570 /* crds are always ordered tcomp, thash, then txform */ 571 /* with optional missing links */ 572 573 /* XXX: If we're going to compress then hash or encrypt, we need 574 * to be able to pass on the new size of the data. 575 */ 576 577 if (cse->tcomp) { 578 crdc = crp->crp_desc; 579 } 580 581 if (cse->thash) { 582 crda = crdc ? crdc->crd_next : crp->crp_desc; 583 if (cse->txform && crda) 584 crde = crda->crd_next; 585 } else { 586 if (cse->txform) { 587 crde = crdc ? crdc->crd_next : crp->crp_desc; 588 } else if (!cse->tcomp) { 589 error = EINVAL; 590 goto bail; 591 } 592 } 593 594 DPRINTF("ocf[%u]: iov_len %zu, cop->len %u\n", 595 CRYPTO_SESID2LID(cse->sid), 596 cod->uio.uio_iov[0].iov_len, 597 cop->len); 598 599 if ((error = copyin(cop->src, cod->uio.uio_iov[0].iov_base, cop->len))) 600 { 601 printf("copyin failed %s %d \n", (char *)cop->src, error); 602 goto bail; 603 } 604 605 if (crdc) { 606 switch (cop->op) { 607 case COP_COMP: 608 crdc->crd_flags |= CRD_F_COMP; 609 break; 610 case COP_DECOMP: 611 crdc->crd_flags &= ~CRD_F_COMP; 612 break; 613 default: 614 break; 615 } 616 /* more data to follow? */ 617 if (cop->flags & COP_F_MORE) { 618 flags |= CRYPTO_F_MORE; 619 } 620 crdc->crd_len = cop->len; 621 crdc->crd_inject = 0; 622 623 crdc->crd_alg = cse->comp_alg; 624 crdc->crd_key = NULL; 625 crdc->crd_klen = 0; 626 DPRINTF("lid[%u]: crdc setup for comp_alg %d.\n", 627 CRYPTO_SESID2LID(cse->sid), crdc->crd_alg); 628 } 629 630 if (crda) { 631 crda->crd_skip = 0; 632 crda->crd_len = cop->len; 633 crda->crd_inject = 0; /* ??? */ 634 635 crda->crd_alg = cse->mac; 636 crda->crd_key = cse->mackey; 637 crda->crd_klen = cse->mackeylen * 8; 638 DPRINTF("crda setup for mac %d.\n", crda->crd_alg); 639 } 640 641 if (crde) { 642 switch (cop->op) { 643 case COP_ENCRYPT: 644 crde->crd_flags |= CRD_F_ENCRYPT; 645 break; 646 case COP_DECRYPT: 647 crde->crd_flags &= ~CRD_F_ENCRYPT; 648 break; 649 default: 650 break; 651 } 652 crde->crd_len = cop->len; 653 crde->crd_inject = 0; 654 655 if (cse->cipher == CRYPTO_AES_GCM_16 && crda) 656 crda->crd_len = 0; 657 else if (cse->cipher == CRYPTO_AES_GMAC) 658 crde->crd_len = 0; 659 660 crde->crd_alg = cse->cipher; 661 crde->crd_key = cse->key; 662 crde->crd_klen = cse->keylen * 8; 663 DPRINTF("crde setup for cipher %d.\n", crde->crd_alg); 664 } 665 666 667 crp->crp_ilen = cop->len; 668 crp->crp_flags = CRYPTO_F_IOV | (cop->flags & COP_F_BATCH) | flags; 669 crp->crp_buf = (void *)&cod->uio; 670 crp->crp_callback = cryptodev_cb; 671 crp->crp_sid = cse->sid; 672 crp->crp_opaque = cod; 673 674 if (cop->iv) { 675 if (crde == NULL) { 676 error = EINVAL; 677 goto bail; 678 } 679 if (cse->txform->ivsize == 0) { 680 error = EINVAL; 681 goto bail; 682 } 683 if ((error = copyin(cop->iv, crp->tmp_iv, 684 cse->txform->ivsize))) 685 goto bail; 686 (void)memcpy(crde->crd_iv, crp->tmp_iv, cse->txform->ivsize); 687 crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; 688 crde->crd_skip = 0; 689 } else if (crde) { 690 if (cse->txform->ivsize == 0) { 691 crde->crd_skip = 0; 692 } else { 693 if (!(crde->crd_flags & CRD_F_ENCRYPT)) 694 crde->crd_flags |= CRD_F_IV_PRESENT; 695 crde->crd_skip = cse->txform->ivsize; 696 crde->crd_len -= cse->txform->ivsize; 697 } 698 } 699 700 if (cop->mac) { 701 if (crda == NULL) { 702 error = EINVAL; 703 goto bail; 704 } 705 crp->crp_mac = crp->tmp_mac; 706 } 707 708 cv_init(&crp->crp_cv, "crydev"); 709 crypto_dispatch(crp); 710 mutex_enter(&cse->lock); 711 while (!(crp->crp_devflags & CRYPTODEV_F_RET)) { 712 DPRINTF("cse->sid[%u]: sleeping on cv %p for crp %p\n", 713 (uint32_t)cse->sid, &crp->crp_cv, crp); 714 cv_wait(&crp->crp_cv, &cse->lock); /* XXX cv_wait_sig? */ 715 } 716 mutex_exit(&cse->lock); 717 cv_destroy(&crp->crp_cv); 718 719 if (crp->crp_etype != 0) { 720 DPRINTF("crp_etype %d\n", crp->crp_etype); 721 error = crp->crp_etype; 722 goto bail; 723 } 724 725 dst_len = crp->crp_ilen; 726 /* let the user know how much data was returned */ 727 if (crp->crp_olen) { 728 if (crp->crp_olen > (cop->dst_len ? cop->dst_len : cop->len)) { 729 error = ENOSPC; 730 goto bail; 731 } 732 dst_len = cop->dst_len = crp->crp_olen; 733 } 734 735 if (cop->dst) { 736 DPRINTF("copyout %zu bytes to %p\n", dst_len, cop->dst); 737 } 738 if (cop->dst && 739 (error = copyout(cod->uio.uio_iov[0].iov_base, cop->dst, dst_len))) 740 { 741 DPRINTF("copyout error %d\n", error); 742 goto bail; 743 } 744 745 if (cop->mac && 746 (error = copyout(crp->crp_mac, cop->mac, cse->thash->authsize))) { 747 DPRINTF("mac copyout error %d\n", error); 748 goto bail; 749 } 750 751 752 bail: 753 if (cod) 754 cod_dtor(cod); 755 if (crp) 756 crypto_freereq(crp); 757 return error; 758 } 759 760 static void 761 cryptodev_cb(struct cryptop *crp) 762 { 763 struct cryptop_data *cod = crp->crp_opaque; 764 DPRINTF("cod = %p\n", cod); 765 766 mutex_enter(&cod->cse->lock); 767 crp->crp_devflags |= CRYPTODEV_F_RET; 768 cv_signal(&crp->crp_cv); 769 mutex_exit(&cod->cse->lock); 770 } 771 772 static void 773 cryptodev_mcb(struct cryptop *crp) 774 { 775 struct cryptop_data *cod = crp->crp_opaque; 776 777 mutex_enter(&cod->cse->lock); 778 TAILQ_INSERT_TAIL(&crp->fcrp->crp_ret_mq, crp, crp_next); 779 selnotify(&crp->fcrp->sinfo, 0, 0); 780 mutex_exit(&cod->cse->lock); 781 } 782 783 static void 784 cryptodevkey_cb(struct cryptkop *krp) 785 { 786 787 mutex_enter(&krp->krp_lock); 788 krp->krp_devflags |= CRYPTODEV_F_RET; 789 cv_signal(&krp->krp_cv); 790 mutex_exit(&krp->krp_lock); 791 } 792 793 static void 794 cryptodevkey_mcb(struct cryptkop *krp) 795 { 796 797 mutex_enter(&krp->krp_lock); 798 cv_signal(&krp->krp_cv); 799 TAILQ_INSERT_TAIL(&krp->fcrp->crp_ret_mkq, krp, krp_next); 800 selnotify(&krp->fcrp->sinfo, 0, 0); 801 mutex_exit(&krp->krp_lock); 802 } 803 804 static int 805 cryptodev_key(struct crypt_kop *kop) 806 { 807 struct cryptkop *krp = NULL; 808 int error = EINVAL; 809 size_t in, out, size, i; 810 811 if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) 812 return EFBIG; 813 814 in = kop->crk_iparams; 815 out = kop->crk_oparams; 816 switch (kop->crk_op) { 817 case CRK_MOD_EXP: 818 if (in == 3 && out == 1) 819 break; 820 return EINVAL; 821 case CRK_MOD_EXP_CRT: 822 if (in == 6 && out == 1) 823 break; 824 return EINVAL; 825 case CRK_DSA_SIGN: 826 if (in == 5 && out == 2) 827 break; 828 return EINVAL; 829 case CRK_DSA_VERIFY: 830 if (in == 7 && out == 0) 831 break; 832 return EINVAL; 833 case CRK_DH_COMPUTE_KEY: 834 if (in == 3 && out == 1) 835 break; 836 return EINVAL; 837 case CRK_MOD_ADD: 838 if (in == 3 && out == 1) 839 break; 840 return EINVAL; 841 case CRK_MOD_ADDINV: 842 if (in == 2 && out == 1) 843 break; 844 return EINVAL; 845 case CRK_MOD_SUB: 846 if (in == 3 && out == 1) 847 break; 848 return EINVAL; 849 case CRK_MOD_MULT: 850 if (in == 3 && out == 1) 851 break; 852 return EINVAL; 853 case CRK_MOD_MULTINV: 854 if (in == 2 && out == 1) 855 break; 856 return EINVAL; 857 case CRK_MOD: 858 if (in == 2 && out == 1) 859 break; 860 return EINVAL; 861 default: 862 return EINVAL; 863 } 864 865 krp = crypto_kgetreq(1, PR_WAITOK); 866 if (krp == NULL) { 867 /* limited by opencrypto.crypto_ret_kq.maxlen */ 868 return ENOMEM; 869 } 870 (void)memset(krp, 0, sizeof *krp); 871 cv_init(&krp->krp_cv, "crykdev"); 872 mutex_init(&krp->krp_lock, MUTEX_DEFAULT, IPL_NONE); 873 krp->krp_op = kop->crk_op; 874 krp->krp_status = kop->crk_status; 875 krp->krp_iparams = kop->crk_iparams; 876 krp->krp_oparams = kop->crk_oparams; 877 krp->krp_status = 0; 878 krp->krp_callback = cryptodevkey_cb; 879 880 for (i = 0; i < CRK_MAXPARAM; i++) 881 krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits; 882 for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) { 883 size = (krp->krp_param[i].crp_nbits + 7) / 8; 884 if (size == 0) 885 continue; 886 krp->krp_param[i].crp_p = kmem_alloc(size, KM_SLEEP); 887 if (i >= krp->krp_iparams) 888 continue; 889 error = copyin(kop->crk_param[i].crp_p, 890 krp->krp_param[i].crp_p, size); 891 if (error) 892 goto fail; 893 } 894 895 crypto_kdispatch(krp); 896 897 mutex_enter(&krp->krp_lock); 898 while (!(krp->krp_devflags & CRYPTODEV_F_RET)) { 899 cv_wait(&krp->krp_cv, &krp->krp_lock); /* XXX cv_wait_sig? */ 900 } 901 mutex_exit(&krp->krp_lock); 902 903 if (krp->krp_status != 0) { 904 DPRINTF("krp->krp_status 0x%08x\n", krp->krp_status); 905 error = krp->krp_status; 906 goto fail; 907 } 908 909 for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; 910 i++) { 911 size = (krp->krp_param[i].crp_nbits + 7) / 8; 912 if (size == 0) 913 continue; 914 error = copyout(krp->krp_param[i].crp_p, 915 kop->crk_param[i].crp_p, size); 916 if (error) { 917 DPRINTF("copyout oparam %zu failed, " 918 "error=%d\n", i-krp->krp_iparams, error); 919 goto fail; 920 } 921 } 922 923 fail: 924 kop->crk_status = krp->krp_status; 925 for (i = 0; i < CRK_MAXPARAM; i++) { 926 struct crparam *kp = &(krp->krp_param[i]); 927 if (krp->krp_param[i].crp_p) { 928 size = (kp->crp_nbits + 7) / 8; 929 KASSERT(size > 0); 930 (void)memset(kp->crp_p, 0, size); 931 kmem_free(kp->crp_p, size); 932 } 933 } 934 cv_destroy(&krp->krp_cv); 935 crypto_kfreereq(krp); 936 DPRINTF("error=0x%08x\n", error); 937 return error; 938 } 939 940 941 /* ARGSUSED */ 942 static int 943 cryptof_close(struct file *fp) 944 { 945 struct fcrypt *fcr = fp->f_fcrypt; 946 947 fp->f_fcrypt = NULL; 948 fcrypt_dtor(fcr); 949 crypto_refcount_put(); 950 return 0; 951 } 952 953 /* needed for compatibility module */ 954 struct csession * 955 cryptodev_cse_find(struct fcrypt *fcr, uint32_t ses) 956 { 957 return cse_find(fcr, ses); 958 } 959 960 /* needed for compatibility module */ 961 void 962 cryptodev_cse_free(struct csession *cse) 963 { 964 cse_free(cse); 965 } 966 967 static struct csession * 968 cse_find(struct fcrypt *fcr, uint32_t ses) 969 { 970 struct csession *cse, *cnext; 971 972 mutex_enter(&fcr->lock); 973 TAILQ_FOREACH_SAFE(cse, &fcr->csessions, next, cnext) 974 if (cse->ses == ses) { 975 if (atomic_inc_uint_nv(&cse->refcnt) == UINT_MAX) { 976 atomic_dec_uint(&cse->refcnt); 977 cse = NULL; 978 } 979 mutex_exit(&fcr->lock); 980 return cse; 981 } 982 mutex_exit(&fcr->lock); 983 984 return NULL; 985 } 986 987 static int 988 cse_delete(struct fcrypt *fcr, uint32_t ses) 989 { 990 struct csession *cse, *cnext; 991 992 TAILQ_FOREACH_SAFE(cse, &fcr->csessions, next, cnext) { 993 if (cse->ses == ses) { 994 if (atomic_load_relaxed(&cse->refcnt) != 1) 995 return EBUSY; 996 TAILQ_REMOVE(&fcr->csessions, cse, next); 997 cse_free(cse); 998 return 0; 999 } 1000 } 1001 return EINVAL; 1002 } 1003 1004 static struct csession * 1005 cse_add(struct fcrypt *fcr, struct csession *cse) 1006 { 1007 mutex_enter(&fcr->lock); 1008 /* don't let session ID wrap! */ 1009 if (fcr->sesn + 1 == 0) { 1010 mutex_exit(&fcr->lock); 1011 return NULL; 1012 } 1013 TAILQ_INSERT_TAIL(&fcr->csessions, cse, next); 1014 cse->ses = fcr->sesn++; 1015 mutex_exit(&fcr->lock); 1016 return cse; 1017 } 1018 1019 static struct csession * 1020 cse_create(struct fcrypt *fcr, uint64_t sid, void *key, uint64_t keylen, 1021 void *mackey, uint64_t mackeylen, uint32_t cipher, uint32_t mac, 1022 uint32_t comp_alg, const struct enc_xform *txform, 1023 const struct auth_hash *thash, const struct comp_algo *tcomp) 1024 { 1025 struct csession *cse; 1026 1027 cse = pool_get(&csepl, PR_NOWAIT); 1028 if (cse == NULL) 1029 return NULL; 1030 cse->key = key; 1031 mutex_init(&cse->lock, MUTEX_DEFAULT, IPL_NONE); 1032 cse->refcnt = 1; 1033 cse->keylen = keylen/8; 1034 cse->mackey = mackey; 1035 cse->mackeylen = mackeylen/8; 1036 cse->sid = sid; 1037 cse->cipher = cipher; 1038 cse->mac = mac; 1039 cse->comp_alg = comp_alg; 1040 cse->txform = txform; 1041 cse->thash = thash; 1042 cse->tcomp = tcomp; 1043 if (cse_add(fcr, cse)) { 1044 DPRINTF("created %p\n", cse); 1045 return cse; 1046 } 1047 1048 mutex_destroy(&cse->lock); 1049 pool_put(&csepl, cse); 1050 return NULL; 1051 } 1052 1053 static void 1054 cse_free(struct csession *cse) 1055 { 1056 1057 DPRINTF("destroying %p %d\n", cse, atomic_load_relaxed(&cse->refcnt)); 1058 membar_release(); 1059 if (atomic_dec_uint_nv(&cse->refcnt) > 0) 1060 return; 1061 membar_acquire(); 1062 mutex_destroy(&cse->lock); 1063 crypto_freesession(cse->sid); 1064 if (cse->key) 1065 free(cse->key, M_XDATA); 1066 if (cse->mackey) 1067 free(cse->mackey, M_XDATA); 1068 pool_put(&csepl, cse); 1069 } 1070 1071 static int 1072 cryptoopen(dev_t dev, int flag, int mode, 1073 struct lwp *l) 1074 { 1075 file_t *fp; 1076 struct fcrypt *fcr; 1077 int fd, error; 1078 1079 if (crypto_usercrypto == 0) 1080 return ENXIO; 1081 1082 if ((error = crypto_refcount_get()) != 0) 1083 return error; 1084 1085 if ((error = fd_allocfile(&fp, &fd)) != 0) { 1086 crypto_refcount_put(); 1087 return error; 1088 } 1089 1090 fcr = fcrypt_ctor(); 1091 error = fd_clone(fp, fd, flag, &cryptofops, fcr); 1092 KASSERTMSG(error == EMOVEFD, "error=%d", error); 1093 return error; 1094 } 1095 1096 static int 1097 cryptoread(dev_t dev, struct uio *uio, int ioflag) 1098 { 1099 return EIO; 1100 } 1101 1102 static int 1103 cryptowrite(dev_t dev, struct uio *uio, int ioflag) 1104 { 1105 return EIO; 1106 } 1107 1108 int 1109 cryptoselect(dev_t dev, int rw, struct lwp *l) 1110 { 1111 return 0; 1112 } 1113 1114 /*static*/ 1115 struct cdevsw crypto_cdevsw = { 1116 .d_open = cryptoopen, 1117 .d_close = noclose, 1118 .d_read = cryptoread, 1119 .d_write = cryptowrite, 1120 .d_ioctl = noioctl, 1121 .d_stop = nostop, 1122 .d_tty = notty, 1123 .d_poll = cryptoselect /*nopoll*/, 1124 .d_mmap = nommap, 1125 .d_kqfilter = nokqfilter, 1126 .d_discard = nodiscard, 1127 .d_flag = D_OTHER 1128 }; 1129 1130 int 1131 cryptodev_mop(struct fcrypt *fcr, 1132 struct crypt_n_op * cnop, 1133 size_t count, struct lwp *l) 1134 { 1135 struct cryptop *crp = NULL; 1136 struct cryptop_data *cod = NULL; 1137 struct cryptodesc *crde = NULL, *crda = NULL, *crdc = NULL; 1138 int error = 0; 1139 struct csession *cse; 1140 int flags=0; 1141 size_t req, iov_len; 1142 1143 1144 for (req = 0; req < count; req++) { 1145 cse = cse_find(fcr, cnop[req].ses); 1146 if (cse == NULL) { 1147 DPRINTF("cse_find failed %#x\n", cnop[req].ses); 1148 cnop[req].status = EINVAL; 1149 continue; 1150 } 1151 1152 if (cnop[req].len > 256*1024-4) { 1153 DPRINTF("length failed\n"); 1154 cnop[req].status = EINVAL; 1155 continue; 1156 } 1157 if (cse->txform) { 1158 if (cnop[req].len < cse->txform->blocksize - 1159 (cnop[req].iv ? 0 : cse->txform->ivsize) || 1160 (cnop[req].len - 1161 (cnop[req].iv ? 0 : cse->txform->ivsize)) 1162 % cse->txform->blocksize) { 1163 cnop[req].status = EINVAL; 1164 continue; 1165 } 1166 } 1167 1168 if (cse->txform == NULL && 1169 cse->thash == NULL && 1170 cse->tcomp == NULL) { 1171 cnop[req].status = EINVAL; 1172 goto bail; 1173 } 1174 1175 /* sanitize */ 1176 if (cnop[req].len <= 0) { 1177 cnop[req].status = ENOMEM; 1178 goto bail; 1179 } 1180 1181 crp = crypto_getreq((cse->txform != NULL) + 1182 (cse->thash != NULL) + 1183 (cse->tcomp != NULL)); 1184 if (crp == NULL) { 1185 cnop[req].status = ENOMEM; 1186 goto bail; 1187 } 1188 1189 iov_len = cnop[req].len; 1190 /* got a compression/decompression max size? */ 1191 if ((cse->tcomp) && cnop[req].dst_len) { 1192 if (iov_len < cnop[req].dst_len) { 1193 /* Need larger iov to deal with decompress */ 1194 iov_len = cnop[req].dst_len; 1195 } 1196 DPRINTF("iov_len -> %zu for decompress\n", iov_len); 1197 } 1198 1199 cod = cod_ctor(&crp->cod, cse, iov_len); 1200 1201 if (cse->tcomp) { 1202 crdc = crp->crp_desc; 1203 } 1204 1205 if (cse->thash) { 1206 crda = crdc ? crdc->crd_next : crp->crp_desc; 1207 if (cse->txform && crda) 1208 crde = crda->crd_next; 1209 } else { 1210 if (cse->txform) { 1211 crde = crdc ? crdc->crd_next : crp->crp_desc; 1212 } else if (!cse->tcomp) { 1213 error = EINVAL; 1214 goto bail; 1215 } 1216 } 1217 1218 if ((copyin(cnop[req].src, 1219 cod->uio.uio_iov[0].iov_base, cnop[req].len))) { 1220 cnop[req].status = EINVAL; 1221 goto bail; 1222 } 1223 1224 if (crdc) { 1225 switch (cnop[req].op) { 1226 case COP_COMP: 1227 crdc->crd_flags |= CRD_F_COMP; 1228 break; 1229 case COP_DECOMP: 1230 crdc->crd_flags &= ~CRD_F_COMP; 1231 break; 1232 default: 1233 break; 1234 } 1235 /* more data to follow? */ 1236 if (cnop[req].flags & COP_F_MORE) { 1237 flags |= CRYPTO_F_MORE; 1238 } 1239 crdc->crd_len = cnop[req].len; 1240 crdc->crd_inject = 0; 1241 1242 crdc->crd_alg = cse->comp_alg; 1243 crdc->crd_key = NULL; 1244 crdc->crd_klen = 0; 1245 DPRINTF("cse->sid[%d]: crdc setup for comp_alg %d" 1246 " len %d.\n", 1247 (uint32_t)cse->sid, crdc->crd_alg, 1248 crdc->crd_len); 1249 } 1250 1251 if (crda) { 1252 crda->crd_skip = 0; 1253 crda->crd_len = cnop[req].len; 1254 crda->crd_inject = 0; /* ??? */ 1255 1256 crda->crd_alg = cse->mac; 1257 crda->crd_key = cse->mackey; 1258 crda->crd_klen = cse->mackeylen * 8; 1259 } 1260 1261 if (crde) { 1262 if (cnop[req].op == COP_ENCRYPT) 1263 crde->crd_flags |= CRD_F_ENCRYPT; 1264 else 1265 crde->crd_flags &= ~CRD_F_ENCRYPT; 1266 crde->crd_len = cnop[req].len; 1267 crde->crd_inject = 0; 1268 1269 crde->crd_alg = cse->cipher; 1270 #ifdef notyet /* XXX must notify h/w driver new key, drain */ 1271 if(cnop[req].key && cnop[req].keylen) { 1272 crde->crd_key = malloc(cnop[req].keylen, 1273 M_XDATA, M_WAITOK); 1274 if((error = copyin(cnop[req].key, 1275 crde->crd_key, cnop[req].keylen))) { 1276 cnop[req].status = EINVAL; 1277 goto bail; 1278 } 1279 crde->crd_klen = cnop[req].keylen * 8; 1280 } else { ... } 1281 #endif 1282 crde->crd_key = cse->key; 1283 crde->crd_klen = cse->keylen * 8; 1284 } 1285 1286 crp->crp_ilen = cnop[req].len; 1287 crp->crp_flags = CRYPTO_F_IOV | 1288 (cnop[req].flags & COP_F_BATCH) | flags; 1289 crp->crp_buf = (void *)&cod->uio; 1290 crp->crp_callback = cryptodev_mcb; 1291 crp->crp_sid = cse->sid; 1292 crp->crp_opaque = cod; 1293 crp->fcrp = fcr; 1294 crp->dst = cnop[req].dst; 1295 crp->len = cnop[req].len; /* input len, iov may be larger */ 1296 crp->mac = cnop[req].mac; 1297 DPRINTF("iov_base %p dst %p len %d mac %p\n", 1298 cod->uio.uio_iov[0].iov_base, crp->dst, crp->len, 1299 crp->mac); 1300 1301 if (cnop[req].iv) { 1302 if (crde == NULL) { 1303 cnop[req].status = EINVAL; 1304 goto bail; 1305 } 1306 if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */ 1307 cnop[req].status = EINVAL; 1308 goto bail; 1309 } 1310 if ((error = copyin(cnop[req].iv, crp->tmp_iv, 1311 cse->txform->ivsize))) { 1312 cnop[req].status = EINVAL; 1313 goto bail; 1314 } 1315 (void)memcpy(crde->crd_iv, crp->tmp_iv, 1316 cse->txform->ivsize); 1317 crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; 1318 crde->crd_skip = 0; 1319 } else if (crde) { 1320 if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */ 1321 crde->crd_skip = 0; 1322 } else { 1323 if (!(crde->crd_flags & CRD_F_ENCRYPT)) 1324 crde->crd_flags |= CRD_F_IV_PRESENT; 1325 crde->crd_skip = cse->txform->ivsize; 1326 crde->crd_len -= cse->txform->ivsize; 1327 } 1328 } 1329 1330 if (cnop[req].mac) { 1331 if (crda == NULL) { 1332 cnop[req].status = EINVAL; 1333 goto bail; 1334 } 1335 crp->crp_mac = crp->tmp_mac; 1336 } 1337 cnop[req].reqid = atomic_inc_32_nv(&(fcr->requestid)); 1338 crp->crp_reqid = cnop[req].reqid; 1339 crp->crp_usropaque = cnop[req].opaque; 1340 cv_init(&crp->crp_cv, "crydev"); 1341 crypto_dispatch(crp); 1342 cnop[req].status = 0; 1343 cv_destroy(&crp->crp_cv); 1344 bail: 1345 if (cnop[req].status) { 1346 DPRINTF("%zu status %d\n", req, cnop[req].status); 1347 cse_free(cse); 1348 if (cod) 1349 cod_dtor(cod); 1350 if (crp) 1351 crypto_freereq(crp); 1352 error = 0; 1353 } 1354 } 1355 return error; 1356 } 1357 1358 static int 1359 cryptodev_mkey(struct fcrypt *fcr, struct crypt_n_kop *kop, size_t count) 1360 { 1361 struct cryptkop *krp = NULL; 1362 int error = EINVAL; 1363 size_t in, out, size, i, req; 1364 1365 for (req = 0; req < count; req++) { 1366 if (kop[req].crk_iparams + kop[req].crk_oparams > CRK_MAXPARAM) 1367 return EFBIG; 1368 1369 in = kop[req].crk_iparams; 1370 out = kop[req].crk_oparams; 1371 switch (kop[req].crk_op) { 1372 case CRK_MOD_EXP: 1373 if (in == 3 && out == 1) 1374 break; 1375 kop[req].crk_status = EINVAL; 1376 continue; 1377 case CRK_MOD_EXP_CRT: 1378 if (in == 6 && out == 1) 1379 break; 1380 kop[req].crk_status = EINVAL; 1381 continue; 1382 case CRK_DSA_SIGN: 1383 if (in == 5 && out == 2) 1384 break; 1385 kop[req].crk_status = EINVAL; 1386 continue; 1387 case CRK_DSA_VERIFY: 1388 if (in == 7 && out == 0) 1389 break; 1390 kop[req].crk_status = EINVAL; 1391 continue; 1392 case CRK_DH_COMPUTE_KEY: 1393 if (in == 3 && out == 1) 1394 break; 1395 kop[req].crk_status = EINVAL; 1396 continue; 1397 case CRK_MOD_ADD: 1398 if (in == 3 && out == 1) 1399 break; 1400 kop[req].crk_status = EINVAL; 1401 continue; 1402 case CRK_MOD_ADDINV: 1403 if (in == 2 && out == 1) 1404 break; 1405 kop[req].crk_status = EINVAL; 1406 continue; 1407 case CRK_MOD_SUB: 1408 if (in == 3 && out == 1) 1409 break; 1410 kop[req].crk_status = EINVAL; 1411 continue; 1412 case CRK_MOD_MULT: 1413 if (in == 3 && out == 1) 1414 break; 1415 kop[req].crk_status = EINVAL; 1416 continue; 1417 case CRK_MOD_MULTINV: 1418 if (in == 2 && out == 1) 1419 break; 1420 kop[req].crk_status = EINVAL; 1421 continue; 1422 case CRK_MOD: 1423 if (in == 2 && out == 1) 1424 break; 1425 kop[req].crk_status = EINVAL; 1426 continue; 1427 default: 1428 kop[req].crk_status = EINVAL; 1429 continue; 1430 } 1431 1432 krp = crypto_kgetreq(1, PR_WAITOK); 1433 if (krp == NULL) { 1434 /* limited by opencrypto.crypto_ret_kq.maxlen */ 1435 continue; 1436 } 1437 (void)memset(krp, 0, sizeof *krp); 1438 cv_init(&krp->krp_cv, "crykdev"); 1439 krp->krp_op = kop[req].crk_op; 1440 krp->krp_status = kop[req].crk_status; 1441 krp->krp_iparams = kop[req].crk_iparams; 1442 krp->krp_oparams = kop[req].crk_oparams; 1443 krp->krp_status = 0; 1444 krp->krp_callback = cryptodevkey_mcb; 1445 (void)memcpy(krp->crk_param, kop[req].crk_param, 1446 sizeof(kop[req].crk_param)); 1447 1448 krp->krp_flags = 0; 1449 1450 for (i = 0; i < CRK_MAXPARAM; i++) 1451 krp->krp_param[i].crp_nbits = 1452 kop[req].crk_param[i].crp_nbits; 1453 for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) { 1454 size = (krp->krp_param[i].crp_nbits + 7) / 8; 1455 if (size == 0) 1456 continue; 1457 krp->krp_param[i].crp_p = 1458 kmem_alloc(size, KM_SLEEP); 1459 if (i >= krp->krp_iparams) 1460 continue; 1461 kop[req].crk_status = 1462 copyin(kop[req].crk_param[i].crp_p, 1463 krp->krp_param[i].crp_p, size); 1464 if (kop[req].crk_status) 1465 goto fail; 1466 } 1467 krp->fcrp = fcr; 1468 1469 kop[req].crk_reqid = atomic_inc_32_nv(&(fcr->requestid)); 1470 krp->krp_reqid = kop[req].crk_reqid; 1471 krp->krp_usropaque = kop[req].crk_opaque; 1472 1473 crypto_kdispatch(krp); 1474 kop[req].crk_status = 0; 1475 fail: 1476 if (kop[req].crk_status) { 1477 if (krp) { 1478 kop[req].crk_status = krp->krp_status; 1479 for (i = 0; i < CRK_MAXPARAM; i++) { 1480 struct crparam *kp = 1481 &(krp->krp_param[i]); 1482 if (kp->crp_p) { 1483 size = (kp->crp_nbits + 7) / 8; 1484 KASSERT(size > 0); 1485 memset(kp->crp_p, 0, size); 1486 kmem_free(kp->crp_p, size); 1487 } 1488 } 1489 cv_destroy(&krp->krp_cv); 1490 crypto_kfreereq(krp); 1491 } 1492 } 1493 error = 0; 1494 } 1495 DPRINTF("error=0x%08x\n", error); 1496 return error; 1497 } 1498 1499 int 1500 cryptodev_session(struct fcrypt *fcr, struct session_op *sop) 1501 { 1502 struct cryptoini cria, crie; 1503 struct cryptoini cric; /* compressor */ 1504 struct cryptoini *crihead = NULL; 1505 const struct enc_xform *txform = NULL; 1506 const struct auth_hash *thash = NULL; 1507 const struct comp_algo *tcomp = NULL; 1508 struct csession *cse; 1509 uint64_t sid; 1510 int error = 0; 1511 1512 DPRINTF("cipher=%d, mac=%d\n", sop->cipher, sop->mac); 1513 1514 /* XXX there must be a way to not embed the list of xforms here */ 1515 switch (sop->cipher) { 1516 case 0: 1517 break; 1518 case CRYPTO_DES_CBC: 1519 txform = &enc_xform_des; 1520 break; 1521 case CRYPTO_3DES_CBC: 1522 txform = &enc_xform_3des; 1523 break; 1524 case CRYPTO_BLF_CBC: 1525 txform = &enc_xform_blf; 1526 break; 1527 case CRYPTO_CAST_CBC: 1528 txform = &enc_xform_cast5; 1529 break; 1530 case CRYPTO_SKIPJACK_CBC: 1531 txform = &enc_xform_skipjack; 1532 break; 1533 case CRYPTO_AES_CBC: 1534 txform = &enc_xform_aes; 1535 break; 1536 case CRYPTO_CAMELLIA_CBC: 1537 txform = &enc_xform_camellia; 1538 break; 1539 case CRYPTO_AES_CTR: 1540 txform = &enc_xform_aes_ctr; 1541 break; 1542 case CRYPTO_AES_GCM_16: 1543 txform = &enc_xform_aes_gcm; 1544 break; 1545 case CRYPTO_AES_GMAC: 1546 txform = &enc_xform_aes_gmac; 1547 break; 1548 case CRYPTO_NULL_CBC: 1549 txform = &enc_xform_null; 1550 break; 1551 case CRYPTO_ARC4: 1552 txform = &enc_xform_arc4; 1553 break; 1554 default: 1555 DPRINTF("Invalid cipher %d\n", sop->cipher); 1556 return EINVAL; 1557 } 1558 1559 switch (sop->comp_alg) { 1560 case 0: 1561 break; 1562 case CRYPTO_DEFLATE_COMP: 1563 tcomp = &comp_algo_deflate; 1564 break; 1565 case CRYPTO_GZIP_COMP: 1566 tcomp = &comp_algo_gzip; 1567 DPRINTF("tcomp for GZIP\n"); 1568 break; 1569 default: 1570 DPRINTF("Invalid compression alg %d\n", sop->comp_alg); 1571 return EINVAL; 1572 } 1573 1574 switch (sop->mac) { 1575 case 0: 1576 break; 1577 case CRYPTO_MD5_HMAC: 1578 thash = &auth_hash_hmac_md5; 1579 break; 1580 case CRYPTO_SHA1_HMAC: 1581 thash = &auth_hash_hmac_sha1; 1582 break; 1583 case CRYPTO_MD5_HMAC_96: 1584 thash = &auth_hash_hmac_md5_96; 1585 break; 1586 case CRYPTO_SHA1_HMAC_96: 1587 thash = &auth_hash_hmac_sha1_96; 1588 break; 1589 case CRYPTO_SHA2_HMAC: 1590 /* XXX switching on key length seems questionable */ 1591 if (sop->mackeylen == auth_hash_hmac_sha2_256.keysize) { 1592 thash = &auth_hash_hmac_sha2_256; 1593 } else if (sop->mackeylen == auth_hash_hmac_sha2_384.keysize) { 1594 thash = &auth_hash_hmac_sha2_384; 1595 } else if (sop->mackeylen == auth_hash_hmac_sha2_512.keysize) { 1596 thash = &auth_hash_hmac_sha2_512; 1597 } else { 1598 DPRINTF("Invalid mackeylen %d\n", sop->mackeylen); 1599 return EINVAL; 1600 } 1601 break; 1602 case CRYPTO_SHA2_384_HMAC: 1603 thash = &auth_hash_hmac_sha2_384; 1604 break; 1605 case CRYPTO_SHA2_512_HMAC: 1606 thash = &auth_hash_hmac_sha2_512; 1607 break; 1608 case CRYPTO_RIPEMD160_HMAC: 1609 thash = &auth_hash_hmac_ripemd_160; 1610 break; 1611 case CRYPTO_RIPEMD160_HMAC_96: 1612 thash = &auth_hash_hmac_ripemd_160_96; 1613 break; 1614 case CRYPTO_MD5: 1615 thash = &auth_hash_md5; 1616 break; 1617 case CRYPTO_SHA1: 1618 thash = &auth_hash_sha1; 1619 break; 1620 case CRYPTO_AES_XCBC_MAC_96: 1621 thash = &auth_hash_aes_xcbc_mac_96; 1622 break; 1623 case CRYPTO_AES_128_GMAC: 1624 thash = &auth_hash_gmac_aes_128; 1625 break; 1626 case CRYPTO_AES_192_GMAC: 1627 thash = &auth_hash_gmac_aes_192; 1628 break; 1629 case CRYPTO_AES_256_GMAC: 1630 thash = &auth_hash_gmac_aes_256; 1631 break; 1632 case CRYPTO_NULL_HMAC: 1633 thash = &auth_hash_null; 1634 break; 1635 default: 1636 DPRINTF("Invalid mac %d\n", sop->mac); 1637 return EINVAL; 1638 } 1639 1640 memset(&crie, 0, sizeof(crie)); 1641 memset(&cria, 0, sizeof(cria)); 1642 memset(&cric, 0, sizeof(cric)); 1643 1644 if (tcomp) { 1645 cric.cri_alg = tcomp->type; 1646 cric.cri_klen = 0; 1647 DPRINTF("tcomp->type = %d\n", tcomp->type); 1648 1649 crihead = &cric; 1650 if (txform) { 1651 cric.cri_next = &crie; 1652 } else if (thash) { 1653 cric.cri_next = &cria; 1654 } 1655 } 1656 1657 if (txform) { 1658 crie.cri_alg = txform->type; 1659 crie.cri_klen = sop->keylen * 8; 1660 if (sop->keylen > txform->maxkey || 1661 sop->keylen < txform->minkey) { 1662 DPRINTF("keylen %d not in [%d,%d]\n", 1663 sop->keylen, txform->minkey, txform->maxkey); 1664 error = EINVAL; 1665 goto bail; 1666 } 1667 1668 crie.cri_key = malloc(crie.cri_klen / 8, M_XDATA, M_WAITOK); 1669 if ((error = copyin(sop->key, crie.cri_key, crie.cri_klen / 8))) 1670 goto bail; 1671 if (!crihead) { 1672 crihead = &crie; 1673 } 1674 if (thash) 1675 crie.cri_next = &cria; 1676 } 1677 1678 if (thash) { 1679 cria.cri_alg = thash->type; 1680 cria.cri_klen = sop->mackeylen * 8; 1681 if (sop->mackeylen != thash->keysize) { 1682 DPRINTF("mackeylen %d != keysize %d\n", 1683 sop->mackeylen, thash->keysize); 1684 error = EINVAL; 1685 goto bail; 1686 } 1687 if (cria.cri_klen) { 1688 cria.cri_key = malloc(cria.cri_klen / 8, M_XDATA, 1689 M_WAITOK); 1690 if ((error = copyin(sop->mackey, cria.cri_key, 1691 cria.cri_klen / 8))) { 1692 goto bail; 1693 } 1694 } 1695 if (!crihead) { 1696 crihead = &cria; 1697 } 1698 } 1699 1700 error = crypto_newsession(&sid, crihead, crypto_devallowsoft); 1701 if (!error) { 1702 DPRINTF("got session %d\n", (uint32_t)sid); 1703 cse = cse_create(fcr, sid, crie.cri_key, crie.cri_klen, 1704 cria.cri_key, cria.cri_klen, (txform ? sop->cipher : 0), sop->mac, 1705 (tcomp ? sop->comp_alg : 0), txform, thash, tcomp); 1706 if (cse != NULL) { 1707 sop->ses = cse->ses; 1708 } else { 1709 DPRINTF("csecreate failed\n"); 1710 crypto_freesession(sid); 1711 error = EINVAL; 1712 } 1713 } else { 1714 DPRINTF("SIOCSESSION violates kernel parameters %d\n", error); 1715 } 1716 bail: 1717 if (error) { 1718 if (crie.cri_key) { 1719 memset(crie.cri_key, 0, crie.cri_klen / 8); 1720 free(crie.cri_key, M_XDATA); 1721 } 1722 if (cria.cri_key) { 1723 memset(cria.cri_key, 0, cria.cri_klen / 8); 1724 free(cria.cri_key, M_XDATA); 1725 } 1726 } 1727 return error; 1728 } 1729 1730 int 1731 cryptodev_msession(struct fcrypt *fcr, struct session_n_op *sn_ops, 1732 size_t count) 1733 { 1734 size_t i; 1735 1736 for (i = 0; i < count; i++, sn_ops++) { 1737 struct session_op s_op; 1738 s_op.cipher = sn_ops->cipher; 1739 s_op.mac = sn_ops->mac; 1740 s_op.comp_alg = sn_ops->comp_alg; 1741 s_op.keylen = sn_ops->keylen; 1742 s_op.key = sn_ops->key; 1743 s_op.mackeylen = sn_ops->mackeylen; 1744 s_op.mackey = sn_ops->mackey; 1745 s_op.ses = ~0; 1746 1747 sn_ops->status = cryptodev_session(fcr, &s_op); 1748 if (sn_ops->status) { 1749 DPRINTF("%zu: create failed %d\n", i, sn_ops->status); 1750 } 1751 sn_ops->ses = s_op.ses; 1752 } 1753 1754 return 0; 1755 } 1756 1757 static void 1758 cryptodev_msessionfin(struct fcrypt *fcr, size_t count, uint32_t *sesid) 1759 { 1760 mutex_enter(&fcr->lock); 1761 for (size_t req = 0; req < count; req++) { 1762 // XXX: What to do if busy? 1763 cse_delete(fcr, sesid[req]); 1764 } 1765 mutex_exit(&fcr->lock); 1766 } 1767 1768 /* 1769 * collect as many completed requests as are available, or count completed 1770 * requests, whichever is less. 1771 * return the number of requests. 1772 */ 1773 static int 1774 cryptodev_getmstatus(struct fcrypt *fcr, struct crypt_result *crypt_res, 1775 int count) 1776 { 1777 struct cryptop *crp = NULL; 1778 struct cryptkop *krp = NULL; 1779 int i, size, req = 0; 1780 int completed=0; 1781 1782 /* On queue so nobody else can grab them 1783 * and copyout can be delayed-- no locking */ 1784 TAILQ_HEAD(, cryptop) crp_delfree_q = 1785 TAILQ_HEAD_INITIALIZER(crp_delfree_q); 1786 TAILQ_HEAD(, cryptkop) krp_delfree_q = 1787 TAILQ_HEAD_INITIALIZER(krp_delfree_q); 1788 1789 /* at this point we do not know which response user is requesting for 1790 * (symmetric or asymmetric) so we copyout one from each i.e if the 1791 * count is 2 then 1 from symmetric and 1 from asymmetric queue and 1792 * if 3 then 2 symmetric and 1 asymmetric and so on */ 1793 1794 /* pull off a list of requests while protected from changes */ 1795 mutex_enter(&fcr->lock); 1796 while (req < count) { 1797 crp = TAILQ_FIRST(&fcr->crp_ret_mq); 1798 if (crp) { 1799 TAILQ_REMOVE(&fcr->crp_ret_mq, crp, crp_next); 1800 TAILQ_INSERT_TAIL(&crp_delfree_q, crp, crp_next); 1801 crypt_res[req].status = 0; 1802 req++; 1803 } 1804 if (req < count) { 1805 crypt_res[req].status = 0; 1806 krp = TAILQ_FIRST(&fcr->crp_ret_mkq); 1807 if (krp) { 1808 TAILQ_REMOVE(&fcr->crp_ret_mkq, krp, krp_next); 1809 TAILQ_INSERT_TAIL(&krp_delfree_q, krp, krp_next); 1810 req++; 1811 } 1812 } 1813 } 1814 mutex_exit(&fcr->lock); 1815 1816 /* now do all the work outside the mutex */ 1817 for(req=0; req < count ;) { 1818 crp = TAILQ_FIRST(&crp_delfree_q); 1819 if (crp) { 1820 struct cryptop_data *cod = crp->crp_opaque; 1821 if (crypt_res[req].status != 0) { 1822 /* cse_find failed during collection */ 1823 goto bail; 1824 } 1825 crypt_res[req].reqid = crp->crp_reqid; 1826 crypt_res[req].opaque = crp->crp_usropaque; 1827 completed++; 1828 1829 if (crp->crp_etype != 0) { 1830 crypt_res[req].status = crp->crp_etype; 1831 goto bail; 1832 } 1833 1834 if (crp->dst && (crypt_res[req].status = 1835 copyout(cod->uio.uio_iov[0].iov_base, crp->dst, 1836 crp->len))) 1837 goto bail; 1838 1839 if (crp->mac && (crypt_res[req].status = 1840 copyout(crp->crp_mac, crp->mac, 1841 cod->cse->thash->authsize))) 1842 goto bail; 1843 1844 bail: 1845 TAILQ_REMOVE(&crp_delfree_q, crp, crp_next); 1846 cse_free(cod->cse); 1847 cod_dtor(cod); 1848 crypto_freereq(crp); 1849 req++; 1850 } 1851 1852 if (req < count) { 1853 krp = TAILQ_FIRST(&krp_delfree_q); 1854 if (krp) { 1855 crypt_res[req].reqid = krp->krp_reqid; 1856 crypt_res[req].opaque = krp->krp_usropaque; 1857 completed++; 1858 if (krp->krp_status != 0) { 1859 DPRINTF("krp->krp_status 0x%08x\n", 1860 krp->krp_status); 1861 crypt_res[req].status = krp->krp_status; 1862 goto fail; 1863 } 1864 1865 for (i = krp->krp_iparams; i < krp->krp_iparams 1866 + krp->krp_oparams; i++) { 1867 size = (krp->krp_param[i].crp_nbits 1868 + 7) / 8; 1869 if (size == 0) 1870 continue; 1871 crypt_res[req].status = copyout 1872 (krp->krp_param[i].crp_p, 1873 krp->crk_param[i].crp_p, size); 1874 if (crypt_res[req].status) { 1875 DPRINTF("copyout oparam %d failed, " 1876 "error=%d\n", 1877 i - krp->krp_iparams, 1878 crypt_res[req].status); 1879 goto fail; 1880 } 1881 } 1882 fail: 1883 TAILQ_REMOVE(&krp_delfree_q, krp, krp_next); 1884 /* not sure what to do for this */ 1885 /* kop[req].crk_status = krp->krp_status; */ 1886 for (i = 0; i < CRK_MAXPARAM; i++) { 1887 struct crparam *kp = &(krp->krp_param[i]); 1888 if (kp->crp_p) { 1889 size = (kp->crp_nbits + 7) / 8; 1890 KASSERT(size > 0); 1891 (void)memset(kp->crp_p, 0, size); 1892 kmem_free(kp->crp_p, size); 1893 } 1894 } 1895 cv_destroy(&krp->krp_cv); 1896 crypto_kfreereq(krp); 1897 req++; 1898 } 1899 } 1900 } 1901 1902 return completed; 1903 } 1904 1905 static int 1906 cryptodev_getstatus (struct fcrypt *fcr, struct crypt_result *crypt_res) 1907 { 1908 struct cryptop *crp = NULL, *cnext; 1909 struct cryptkop *krp = NULL, *knext; 1910 int i, size, req = 0; 1911 1912 mutex_enter(&fcr->lock); 1913 /* Here we dont know for which request the user is requesting the 1914 * response so checking in both the queues */ 1915 TAILQ_FOREACH_SAFE(crp, &fcr->crp_ret_mq, crp_next, cnext) { 1916 if(crp && (crp->crp_reqid == crypt_res->reqid)) { 1917 struct cryptop_data *cod = crp->crp_opaque; 1918 crypt_res->opaque = crp->crp_usropaque; 1919 if (crp->crp_etype != 0) { 1920 crypt_res->status = crp->crp_etype; 1921 goto bail; 1922 } 1923 1924 if (crp->dst && (crypt_res->status = 1925 copyout(cod->uio.uio_iov[0].iov_base, 1926 crp->dst, crp->len))) 1927 goto bail; 1928 1929 if (crp->mac && (crypt_res->status = 1930 copyout(crp->crp_mac, crp->mac, 1931 cod->cse->thash->authsize))) 1932 goto bail; 1933 bail: 1934 TAILQ_REMOVE(&fcr->crp_ret_mq, crp, crp_next); 1935 mutex_exit(&fcr->lock); 1936 cse_free(cod->cse); 1937 cod_dtor(cod); 1938 crypto_freereq(crp); 1939 return 0; 1940 } 1941 } 1942 1943 TAILQ_FOREACH_SAFE(krp, &fcr->crp_ret_mkq, krp_next, knext) { 1944 if(krp && (krp->krp_reqid == crypt_res->reqid)) { 1945 crypt_res[req].opaque = krp->krp_usropaque; 1946 if (krp->krp_status != 0) { 1947 DPRINTF("krp->krp_status 0x%08x\n", 1948 krp->krp_status); 1949 crypt_res[req].status = krp->krp_status; 1950 goto fail; 1951 } 1952 1953 for (i = krp->krp_iparams; i < krp->krp_iparams + 1954 krp->krp_oparams; i++) { 1955 size = (krp->krp_param[i].crp_nbits + 7) / 8; 1956 if (size == 0) 1957 continue; 1958 crypt_res[req].status = copyout( 1959 krp->krp_param[i].crp_p, 1960 krp->crk_param[i].crp_p, size); 1961 if (crypt_res[req].status) { 1962 DPRINTF("copyout oparam " 1963 "%d failed, error=%d\n", 1964 i - krp->krp_iparams, 1965 crypt_res[req].status); 1966 goto fail; 1967 } 1968 } 1969 fail: 1970 TAILQ_REMOVE(&fcr->crp_ret_mkq, krp, krp_next); 1971 mutex_exit(&fcr->lock); 1972 /* not sure what to do for this */ 1973 /* kop[req].crk_status = krp->krp_status; */ 1974 for (i = 0; i < CRK_MAXPARAM; i++) { 1975 struct crparam *kp = &(krp->krp_param[i]); 1976 if (kp->crp_p) { 1977 size = (kp->crp_nbits + 7) / 8; 1978 KASSERT(size > 0); 1979 memset(kp->crp_p, 0, size); 1980 kmem_free(kp->crp_p, size); 1981 } 1982 } 1983 cv_destroy(&krp->krp_cv); 1984 crypto_kfreereq(krp); 1985 return 0; 1986 } 1987 } 1988 mutex_exit(&fcr->lock); 1989 return EINPROGRESS; 1990 } 1991 1992 static int 1993 cryptof_stat(struct file *fp, struct stat *st) 1994 { 1995 struct fcrypt *fcr = fp->f_fcrypt; 1996 1997 (void)memset(st, 0, sizeof(*st)); 1998 1999 mutex_enter(&fcr->lock); 2000 st->st_dev = makedev(cdevsw_lookup_major(&crypto_cdevsw), fcr->sesn); 2001 st->st_atimespec = fcr->atime; 2002 st->st_mtimespec = fcr->mtime; 2003 st->st_ctimespec = st->st_birthtimespec = fcr->btime; 2004 st->st_uid = kauth_cred_geteuid(fp->f_cred); 2005 st->st_gid = kauth_cred_getegid(fp->f_cred); 2006 mutex_exit(&fcr->lock); 2007 2008 return 0; 2009 } 2010 2011 static int 2012 cryptof_poll(struct file *fp, int events) 2013 { 2014 struct fcrypt *fcr = fp->f_fcrypt; 2015 int revents = 0; 2016 2017 if (!(events & (POLLIN | POLLRDNORM))) { 2018 /* only support read and POLLIN */ 2019 return 0; 2020 } 2021 2022 mutex_enter(&fcr->lock); 2023 if (TAILQ_EMPTY(&fcr->crp_ret_mq) && TAILQ_EMPTY(&fcr->crp_ret_mkq)) { 2024 /* no completed requests pending, save the poll for later */ 2025 selrecord(curlwp, &fcr->sinfo); 2026 } else { 2027 /* let the app(s) know that there are completed requests */ 2028 revents = events & (POLLIN | POLLRDNORM); 2029 } 2030 mutex_exit(&fcr->lock); 2031 2032 return revents; 2033 } 2034 2035 static void 2036 cryptodev_init(void) 2037 { 2038 2039 mutex_init(&cryptodev_mtx, MUTEX_DEFAULT, IPL_NONE); 2040 2041 pool_init(&fcrpl, sizeof(struct fcrypt), 0, 0, 0, "fcrpl", 2042 NULL, IPL_NONE); 2043 pool_init(&csepl, sizeof(struct csession), 0, 0, 0, "csepl", 2044 NULL, IPL_NONE); 2045 2046 /* 2047 * Preallocate space for 64 users, with 5 sessions each. 2048 * (consider that a TLS protocol session requires at least 2049 * 3DES, MD5, and SHA1 (both hashes are used in the PRF) for 2050 * the negotiation, plus HMAC_SHA1 for the actual SSL records, 2051 * consuming one session here for each algorithm. 2052 */ 2053 pool_prime(&fcrpl, 64); 2054 pool_prime(&csepl, 64 * 5); 2055 } 2056 2057 static void 2058 cryptodev_fini(void) 2059 { 2060 2061 KASSERTMSG(crypto_refcount == 0, 2062 "crypto_refcount=%d", crypto_refcount); 2063 2064 pool_destroy(&csepl); 2065 pool_destroy(&fcrpl); 2066 2067 mutex_destroy(&cryptodev_mtx); 2068 } 2069 2070 /* 2071 * Pseudo-device initialization routine for /dev/crypto 2072 */ 2073 void 2074 cryptoattach(int num) 2075 { 2076 #ifndef _MODULE 2077 crypto_init(); 2078 cryptodev_init(); 2079 #endif 2080 } 2081 2082 MODULE(MODULE_CLASS_DRIVER, crypto, "opencrypto"); 2083 2084 static int 2085 crypto_modcmd(modcmd_t cmd, void *arg) 2086 { 2087 #ifdef _MODULE 2088 int error = 0; 2089 devmajor_t cmajor = NODEVMAJOR, bmajor = NODEVMAJOR; 2090 #endif 2091 2092 switch (cmd) { 2093 case MODULE_CMD_INIT: 2094 #ifdef _MODULE 2095 cryptodev_init(); 2096 error = devsw_attach("crypto", NULL, &bmajor, 2097 &crypto_cdevsw, &cmajor); 2098 if (error) { 2099 aprint_error("crypto: unable to register devsw," 2100 " error %d\n", error); 2101 cryptodev_fini(); 2102 return error; 2103 } 2104 #endif 2105 return 0; 2106 case MODULE_CMD_FINI: 2107 /* 2108 * Can't unload safely because there is no way to wait 2109 * for all files with a given struct fileops to be 2110 * closed. 2111 */ 2112 return ENOTTY; 2113 2114 mutex_enter(&cryptodev_mtx); 2115 if (crypto_refcount != 0) { 2116 mutex_exit(&cryptodev_mtx); 2117 return EBUSY; 2118 } 2119 crypto_detaching = true; 2120 mutex_exit(&cryptodev_mtx); 2121 devsw_detach(NULL, &crypto_cdevsw); 2122 cryptodev_fini(); 2123 return 0; 2124 default: 2125 return ENOTTY; 2126 } 2127 } 2128