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