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