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