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