1 /* $NetBSD: ubsec.c,v 1.34 2013/11/17 23:20:18 bad Exp $ */ 2 /* $FreeBSD: src/sys/dev/ubsec/ubsec.c,v 1.6.2.6 2003/01/23 21:06:43 sam Exp $ */ 3 /* $OpenBSD: ubsec.c,v 1.127 2003/06/04 14:04:58 jason Exp $ */ 4 5 /* 6 * Copyright (c) 2000 Jason L. Wright (jason@thought.net) 7 * Copyright (c) 2000 Theo de Raadt (deraadt@openbsd.org) 8 * Copyright (c) 2001 Patrik Lindergren (patrik@ipunplugged.com) 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 * 31 * Effort sponsored in part by the Defense Advanced Research Projects 32 * Agency (DARPA) and Air Force Research Laboratory, Air Force 33 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 34 * 35 */ 36 37 #include <sys/cdefs.h> 38 __KERNEL_RCSID(0, "$NetBSD: ubsec.c,v 1.34 2013/11/17 23:20:18 bad Exp $"); 39 40 #undef UBSEC_DEBUG 41 42 /* 43 * uBsec 5[56]01, bcm580xx, bcm582x hardware crypto accelerator 44 */ 45 46 #include <sys/param.h> 47 #include <sys/systm.h> 48 #include <sys/proc.h> 49 #include <sys/endian.h> 50 #ifdef __NetBSD__ 51 #define UBSEC_NO_RNG /* hangs on attach */ 52 #define letoh16 htole16 53 #define letoh32 htole32 54 #endif 55 #include <sys/errno.h> 56 #include <sys/malloc.h> 57 #include <sys/kernel.h> 58 #include <sys/mbuf.h> 59 #include <sys/device.h> 60 #include <sys/module.h> 61 #include <sys/queue.h> 62 #include <sys/sysctl.h> 63 64 #include <opencrypto/cryptodev.h> 65 #include <opencrypto/xform.h> 66 #ifdef __OpenBSD__ 67 #include <dev/rndvar.h> 68 #include <sys/md5k.h> 69 #else 70 #include <sys/cprng.h> 71 #include <sys/md5.h> 72 #endif 73 #include <sys/sha1.h> 74 75 #include <dev/pci/pcireg.h> 76 #include <dev/pci/pcivar.h> 77 #include <dev/pci/pcidevs.h> 78 79 #include <dev/pci/ubsecreg.h> 80 #include <dev/pci/ubsecvar.h> 81 82 /* 83 * Prototypes and count for the pci_device structure 84 */ 85 static int ubsec_probe(device_t, cfdata_t, void *); 86 static void ubsec_attach(device_t, device_t, void *); 87 static int ubsec_detach(device_t, int); 88 static int ubsec_sysctl_init(void); 89 static void ubsec_reset_board(struct ubsec_softc *); 90 static void ubsec_init_board(struct ubsec_softc *); 91 static void ubsec_init_pciregs(struct pci_attach_args *pa); 92 static void ubsec_cleanchip(struct ubsec_softc *); 93 static void ubsec_totalreset(struct ubsec_softc *); 94 static int ubsec_free_q(struct ubsec_softc*, struct ubsec_q *); 95 96 #ifdef __OpenBSD__ 97 struct cfattach ubsec_ca = { 98 sizeof(struct ubsec_softc), ubsec_probe, ubsec_attach, 99 }; 100 101 struct cfdriver ubsec_cd = { 102 0, "ubsec", DV_DULL 103 }; 104 #else 105 CFATTACH_DECL_NEW(ubsec, sizeof(struct ubsec_softc), ubsec_probe, ubsec_attach, 106 ubsec_detach, NULL); 107 extern struct cfdriver ubsec_cd; 108 #endif 109 110 /* patchable */ 111 #ifdef UBSEC_DEBUG 112 extern int ubsec_debug; 113 int ubsec_debug=1; 114 #endif 115 116 static int ubsec_intr(void *); 117 static int ubsec_newsession(void*, u_int32_t *, struct cryptoini *); 118 static int ubsec_freesession(void*, u_int64_t); 119 static int ubsec_process(void*, struct cryptop *, int hint); 120 static void ubsec_callback(struct ubsec_softc *, struct ubsec_q *); 121 static void ubsec_feed(struct ubsec_softc *); 122 static void ubsec_mcopy(struct mbuf *, struct mbuf *, int, int); 123 static void ubsec_callback2(struct ubsec_softc *, struct ubsec_q2 *); 124 static void ubsec_feed2(struct ubsec_softc *); 125 static void ubsec_feed4(struct ubsec_softc *); 126 #ifndef UBSEC_NO_RNG 127 static void ubsec_rng(void *); 128 static void ubsec_rng_locked(void *); 129 static void ubsec_rng_get(size_t, void *); 130 #endif /* UBSEC_NO_RNG */ 131 static int ubsec_dma_malloc(struct ubsec_softc *, bus_size_t, 132 struct ubsec_dma_alloc *, int); 133 static void ubsec_dma_free(struct ubsec_softc *, struct ubsec_dma_alloc *); 134 static int ubsec_dmamap_aligned(bus_dmamap_t); 135 136 static int ubsec_kprocess(void*, struct cryptkop *, int); 137 static int ubsec_kprocess_modexp_sw(struct ubsec_softc *, 138 struct cryptkop *, int); 139 static int ubsec_kprocess_modexp_hw(struct ubsec_softc *, 140 struct cryptkop *, int); 141 static int ubsec_kprocess_rsapriv(struct ubsec_softc *, 142 struct cryptkop *, int); 143 static void ubsec_kfree(struct ubsec_softc *, struct ubsec_q2 *); 144 static int ubsec_ksigbits(struct crparam *); 145 static void ubsec_kshift_r(u_int, u_int8_t *, u_int, u_int8_t *, u_int); 146 static void ubsec_kshift_l(u_int, u_int8_t *, u_int, u_int8_t *, u_int); 147 148 #ifdef UBSEC_DEBUG 149 static void ubsec_dump_pb(volatile struct ubsec_pktbuf *); 150 static void ubsec_dump_mcr(struct ubsec_mcr *); 151 static void ubsec_dump_ctx2(volatile struct ubsec_ctx_keyop *); 152 #endif 153 154 #define READ_REG(sc,r) \ 155 bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (r)) 156 157 #define WRITE_REG(sc,reg,val) \ 158 bus_space_write_4((sc)->sc_st, (sc)->sc_sh, reg, val) 159 160 #define SWAP32(x) (x) = htole32(ntohl((x))) 161 #ifndef HTOLE32 162 #define HTOLE32(x) (x) = htole32(x) 163 #endif 164 165 struct ubsec_stats ubsecstats; 166 167 static struct sysctllog *ubsec_sysctllog; 168 169 /* 170 * ubsec_maxbatch controls the number of crypto ops to voluntarily 171 * collect into one submission to the hardware. This batching happens 172 * when ops are dispatched from the crypto subsystem with a hint that 173 * more are to follow immediately. These ops must also not be marked 174 * with a ``no delay'' flag. 175 */ 176 static int ubsec_maxbatch = 1; 177 178 /* 179 * ubsec_maxaggr controls the number of crypto ops to submit to the 180 * hardware as a unit. This aggregation reduces the number of interrupts 181 * to the host at the expense of increased latency (for all but the last 182 * operation). For network traffic setting this to one yields the highest 183 * performance but at the expense of more interrupt processing. 184 */ 185 static int ubsec_maxaggr = 1; 186 187 static const struct ubsec_product { 188 pci_vendor_id_t ubsec_vendor; 189 pci_product_id_t ubsec_product; 190 int ubsec_flags; 191 int ubsec_statmask; 192 int ubsec_maxaggr; 193 const char *ubsec_name; 194 } ubsec_products[] = { 195 { PCI_VENDOR_BLUESTEEL, PCI_PRODUCT_BLUESTEEL_5501, 196 0, 197 BS_STAT_MCR1_DONE | BS_STAT_DMAERR, 198 UBS_MIN_AGGR, 199 "Bluesteel 5501" 200 }, 201 { PCI_VENDOR_BLUESTEEL, PCI_PRODUCT_BLUESTEEL_5601, 202 UBS_FLAGS_KEY | UBS_FLAGS_RNG, 203 BS_STAT_MCR1_DONE | BS_STAT_DMAERR, 204 UBS_MIN_AGGR, 205 "Bluesteel 5601" 206 }, 207 208 { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5801, 209 0, 210 BS_STAT_MCR1_DONE | BS_STAT_DMAERR, 211 UBS_MIN_AGGR, 212 "Broadcom BCM5801" 213 }, 214 215 { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5802, 216 UBS_FLAGS_KEY | UBS_FLAGS_RNG, 217 BS_STAT_MCR1_DONE | BS_STAT_DMAERR, 218 UBS_MIN_AGGR, 219 "Broadcom BCM5802" 220 }, 221 222 { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5805, 223 UBS_FLAGS_KEY | UBS_FLAGS_RNG, 224 BS_STAT_MCR1_DONE | BS_STAT_DMAERR, 225 UBS_MIN_AGGR, 226 "Broadcom BCM5805" 227 }, 228 229 { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5820, 230 UBS_FLAGS_KEY | UBS_FLAGS_RNG | UBS_FLAGS_LONGCTX | 231 UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY, 232 BS_STAT_MCR1_DONE | BS_STAT_DMAERR, 233 UBS_MIN_AGGR, 234 "Broadcom BCM5820" 235 }, 236 237 { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5821, 238 UBS_FLAGS_KEY | UBS_FLAGS_RNG | UBS_FLAGS_LONGCTX | 239 UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY, 240 BS_STAT_MCR1_DONE | BS_STAT_DMAERR | 241 BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY, 242 UBS_MIN_AGGR, 243 "Broadcom BCM5821" 244 }, 245 { PCI_VENDOR_SUN, PCI_PRODUCT_SUN_SCA1K, 246 UBS_FLAGS_KEY | UBS_FLAGS_RNG | UBS_FLAGS_LONGCTX | 247 UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY, 248 BS_STAT_MCR1_DONE | BS_STAT_DMAERR | 249 BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY, 250 UBS_MIN_AGGR, 251 "Sun Crypto Accelerator 1000" 252 }, 253 { PCI_VENDOR_SUN, PCI_PRODUCT_SUN_5821, 254 UBS_FLAGS_KEY | UBS_FLAGS_RNG | UBS_FLAGS_LONGCTX | 255 UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY, 256 BS_STAT_MCR1_DONE | BS_STAT_DMAERR | 257 BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY, 258 UBS_MIN_AGGR, 259 "Broadcom BCM5821 (Sun)" 260 }, 261 262 { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5822, 263 UBS_FLAGS_KEY | UBS_FLAGS_RNG | UBS_FLAGS_LONGCTX | 264 UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY, 265 BS_STAT_MCR1_DONE | BS_STAT_DMAERR | 266 BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY, 267 UBS_MIN_AGGR, 268 "Broadcom BCM5822" 269 }, 270 271 { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5823, 272 UBS_FLAGS_KEY | UBS_FLAGS_RNG | UBS_FLAGS_LONGCTX | 273 UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY, 274 BS_STAT_MCR1_DONE | BS_STAT_DMAERR | 275 BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY, 276 UBS_MIN_AGGR, 277 "Broadcom BCM5823" 278 }, 279 280 { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5825, 281 UBS_FLAGS_KEY | UBS_FLAGS_RNG | UBS_FLAGS_LONGCTX | 282 UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY, 283 BS_STAT_MCR1_DONE | BS_STAT_DMAERR | 284 BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY, 285 UBS_MIN_AGGR, 286 "Broadcom BCM5825" 287 }, 288 289 { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5860, 290 UBS_FLAGS_MULTIMCR | UBS_FLAGS_HWNORM | 291 UBS_FLAGS_LONGCTX | 292 UBS_FLAGS_RNG | UBS_FLAGS_RNG4 | 293 UBS_FLAGS_KEY | UBS_FLAGS_BIGKEY, 294 BS_STAT_MCR1_DONE | BS_STAT_DMAERR | 295 BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY | 296 BS_STAT_MCR3_ALLEMPTY | BS_STAT_MCR4_ALLEMPTY, 297 UBS_MAX_AGGR, 298 "Broadcom BCM5860" 299 }, 300 301 { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5861, 302 UBS_FLAGS_MULTIMCR | UBS_FLAGS_HWNORM | 303 UBS_FLAGS_LONGCTX | 304 UBS_FLAGS_RNG | UBS_FLAGS_RNG4 | 305 UBS_FLAGS_KEY | UBS_FLAGS_BIGKEY, 306 BS_STAT_MCR1_DONE | BS_STAT_DMAERR | 307 BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY | 308 BS_STAT_MCR3_ALLEMPTY | BS_STAT_MCR4_ALLEMPTY, 309 UBS_MAX_AGGR, 310 "Broadcom BCM5861" 311 }, 312 313 { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_5862, 314 UBS_FLAGS_MULTIMCR | UBS_FLAGS_HWNORM | 315 UBS_FLAGS_LONGCTX | 316 UBS_FLAGS_RNG | UBS_FLAGS_RNG4 | 317 UBS_FLAGS_KEY | UBS_FLAGS_BIGKEY, 318 BS_STAT_MCR1_DONE | BS_STAT_DMAERR | 319 BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY | 320 BS_STAT_MCR3_ALLEMPTY | BS_STAT_MCR4_ALLEMPTY, 321 UBS_MAX_AGGR, 322 "Broadcom BCM5862" 323 }, 324 325 { 0, 0, 326 0, 327 0, 328 0, 329 NULL 330 } 331 }; 332 333 static const struct ubsec_product * 334 ubsec_lookup(const struct pci_attach_args *pa) 335 { 336 const struct ubsec_product *up; 337 338 for (up = ubsec_products; up->ubsec_name != NULL; up++) { 339 if (PCI_VENDOR(pa->pa_id) == up->ubsec_vendor && 340 PCI_PRODUCT(pa->pa_id) == up->ubsec_product) 341 return (up); 342 } 343 return (NULL); 344 } 345 346 static int 347 ubsec_probe(device_t parent, cfdata_t match, void *aux) 348 { 349 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 350 351 if (ubsec_lookup(pa) != NULL) 352 return (1); 353 354 return (0); 355 } 356 357 static void 358 ubsec_attach(device_t parent, device_t self, void *aux) 359 { 360 struct ubsec_softc *sc = device_private(self); 361 struct pci_attach_args *pa = aux; 362 const struct ubsec_product *up; 363 pci_chipset_tag_t pc = pa->pa_pc; 364 pci_intr_handle_t ih; 365 const char *intrstr = NULL; 366 pcireg_t memtype; 367 struct ubsec_dma *dmap; 368 u_int32_t cmd, i; 369 370 sc->sc_dev = self; 371 sc->sc_pct = pc; 372 373 up = ubsec_lookup(pa); 374 if (up == NULL) { 375 printf("\n"); 376 panic("ubsec_attach: impossible"); 377 } 378 379 pci_aprint_devinfo_fancy(pa, "Crypto processor", up->ubsec_name, 1); 380 381 SIMPLEQ_INIT(&sc->sc_queue); 382 SIMPLEQ_INIT(&sc->sc_qchip); 383 SIMPLEQ_INIT(&sc->sc_queue2); 384 SIMPLEQ_INIT(&sc->sc_qchip2); 385 SIMPLEQ_INIT(&sc->sc_queue4); 386 SIMPLEQ_INIT(&sc->sc_qchip4); 387 SIMPLEQ_INIT(&sc->sc_q2free); 388 389 sc->sc_flags = up->ubsec_flags; 390 sc->sc_statmask = up->ubsec_statmask; 391 sc->sc_maxaggr = up->ubsec_maxaggr; 392 393 cmd = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 394 cmd |= PCI_COMMAND_MASTER_ENABLE; 395 pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, cmd); 396 397 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BS_BAR); 398 if (pci_mapreg_map(pa, BS_BAR, memtype, 0, 399 &sc->sc_st, &sc->sc_sh, NULL, &sc->sc_memsize)) { 400 aprint_error_dev(self, "can't find mem space"); 401 return; 402 } 403 404 sc->sc_dmat = pa->pa_dmat; 405 406 if (pci_intr_map(pa, &ih)) { 407 aprint_error_dev(self, "couldn't map interrupt\n"); 408 return; 409 } 410 intrstr = pci_intr_string(pc, ih); 411 sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, ubsec_intr, sc); 412 if (sc->sc_ih == NULL) { 413 aprint_error_dev(self, "couldn't establish interrupt"); 414 if (intrstr != NULL) 415 aprint_error(" at %s", intrstr); 416 aprint_error("\n"); 417 return; 418 } 419 aprint_normal_dev(self, "interrupting at %s\n", intrstr); 420 421 sc->sc_cid = crypto_get_driverid(0); 422 if (sc->sc_cid < 0) { 423 aprint_error_dev(self, "couldn't get crypto driver id\n"); 424 pci_intr_disestablish(pc, sc->sc_ih); 425 return; 426 } 427 428 sc->sc_rng_need = RND_POOLBITS / NBBY; 429 mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_VM); 430 431 SIMPLEQ_INIT(&sc->sc_freequeue); 432 dmap = sc->sc_dmaa; 433 for (i = 0; i < UBS_MAX_NQUEUE; i++, dmap++) { 434 struct ubsec_q *q; 435 436 q = (struct ubsec_q *)malloc(sizeof(struct ubsec_q), 437 M_DEVBUF, M_NOWAIT); 438 if (q == NULL) { 439 aprint_error_dev(self, "can't allocate queue buffers\n"); 440 break; 441 } 442 443 if (ubsec_dma_malloc(sc, sizeof(struct ubsec_dmachunk), 444 &dmap->d_alloc, 0)) { 445 aprint_error_dev(self, "can't allocate dma buffers\n"); 446 free(q, M_DEVBUF); 447 break; 448 } 449 dmap->d_dma = (struct ubsec_dmachunk *)dmap->d_alloc.dma_vaddr; 450 451 q->q_dma = dmap; 452 sc->sc_queuea[i] = q; 453 454 SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q, q_next); 455 } 456 457 crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0, 458 ubsec_newsession, ubsec_freesession, ubsec_process, sc); 459 crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0, 460 ubsec_newsession, ubsec_freesession, ubsec_process, sc); 461 crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC_96, 0, 0, 462 ubsec_newsession, ubsec_freesession, ubsec_process, sc); 463 crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC_96, 0, 0, 464 ubsec_newsession, ubsec_freesession, ubsec_process, sc); 465 466 /* 467 * Reset Broadcom chip 468 */ 469 ubsec_reset_board(sc); 470 471 /* 472 * Init Broadcom specific PCI settings 473 */ 474 ubsec_init_pciregs(pa); 475 476 /* 477 * Init Broadcom chip 478 */ 479 ubsec_init_board(sc); 480 481 #ifndef UBSEC_NO_RNG 482 if (sc->sc_flags & UBS_FLAGS_RNG) { 483 if (sc->sc_flags & UBS_FLAGS_RNG4) 484 sc->sc_statmask |= BS_STAT_MCR4_DONE; 485 else 486 sc->sc_statmask |= BS_STAT_MCR2_DONE; 487 488 if (ubsec_dma_malloc(sc, sizeof(struct ubsec_mcr), 489 &sc->sc_rng.rng_q.q_mcr, 0)) 490 goto skip_rng; 491 492 if (ubsec_dma_malloc(sc, sizeof(struct ubsec_ctx_rngbypass), 493 &sc->sc_rng.rng_q.q_ctx, 0)) { 494 ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_mcr); 495 goto skip_rng; 496 } 497 498 if (ubsec_dma_malloc(sc, sizeof(u_int32_t) * 499 UBSEC_RNG_BUFSIZ, &sc->sc_rng.rng_buf, 0)) { 500 ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_ctx); 501 ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_mcr); 502 goto skip_rng; 503 } 504 505 rndsource_setcb(&sc->sc_rnd_source, ubsec_rng_get, sc); 506 rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dev), 507 RND_TYPE_RNG, 508 RND_FLAG_NO_ESTIMATE|RND_FLAG_HASCB); 509 if (hz >= 100) 510 sc->sc_rnghz = hz / 100; 511 else 512 sc->sc_rnghz = 1; 513 #ifdef __OpenBSD__ 514 timeout_set(&sc->sc_rngto, ubsec_rng, sc); 515 timeout_add(&sc->sc_rngto, sc->sc_rnghz); 516 #else 517 callout_init(&sc->sc_rngto, 0); 518 callout_setfunc(&sc->sc_rngto, ubsec_rng, sc); 519 callout_schedule(&sc->sc_rngto, sc->sc_rnghz); 520 #endif 521 skip_rng: 522 if (sc->sc_rnghz) 523 aprint_normal_dev(self, "random number generator enabled\n"); 524 else 525 aprint_error_dev(self, "WARNING: random number generator " 526 "disabled\n"); 527 } 528 #endif /* UBSEC_NO_RNG */ 529 530 if (sc->sc_flags & UBS_FLAGS_KEY) { 531 sc->sc_statmask |= BS_STAT_MCR2_DONE; 532 533 crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0, 534 ubsec_kprocess, sc); 535 #if 0 536 crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0, 537 ubsec_kprocess, sc); 538 #endif 539 } 540 } 541 542 static int 543 ubsec_detach(device_t self, int flags) 544 { 545 struct ubsec_softc *sc = device_private(self); 546 struct ubsec_q *q, *qtmp; 547 548 /* disable interrupts */ 549 /* XXX wait/abort current ops? where is DMAERR enabled? */ 550 WRITE_REG(sc, BS_CTRL, READ_REG(sc, BS_CTRL) &~ 551 (BS_CTRL_MCR2INT | BS_CTRL_MCR1INT | BS_CTRL_DMAERR)); 552 553 #ifndef UBSEC_NO_RNG 554 if (sc->sc_flags & UBS_FLAGS_RNG) { 555 callout_halt(&sc->sc_rngto, NULL); 556 ubsec_dma_free(sc, &sc->sc_rng.rng_buf); 557 ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_ctx); 558 ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_mcr); 559 rnd_detach_source(&sc->sc_rnd_source); 560 } 561 #endif /* UBSEC_NO_RNG */ 562 563 crypto_unregister_all(sc->sc_cid); 564 565 mutex_spin_enter(&sc->sc_mtx); 566 567 ubsec_totalreset(sc); /* XXX leaves the chip running */ 568 569 SIMPLEQ_FOREACH_SAFE(q, &sc->sc_freequeue, q_next, qtmp) { 570 ubsec_dma_free(sc, &q->q_dma->d_alloc); 571 free(q, M_DEVBUF); 572 } 573 574 mutex_spin_exit(&sc->sc_mtx); 575 576 if (sc->sc_ih != NULL) { 577 pci_intr_disestablish(sc->sc_pct, sc->sc_ih); 578 sc->sc_ih = NULL; 579 } 580 581 if (sc->sc_memsize != 0) { 582 bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_memsize); 583 sc->sc_memsize = 0; 584 } 585 586 return 0; 587 } 588 589 MODULE(MODULE_CLASS_DRIVER, ubsec, "pci"); 590 591 #ifdef _MODULE 592 #include "ioconf.c" 593 #endif 594 595 static int 596 ubsec_modcmd(modcmd_t cmd, void *data) 597 { 598 int error = 0; 599 600 switch (cmd) { 601 case MODULE_CMD_INIT: 602 #ifdef _MODULE 603 error = config_init_component(cfdriver_ioconf_ubsec, 604 cfattach_ioconf_ubsec, cfdata_ioconf_ubsec); 605 #endif 606 if (error == 0) 607 error = ubsec_sysctl_init(); 608 return error; 609 case MODULE_CMD_FINI: 610 if (ubsec_sysctllog != NULL) 611 sysctl_teardown(&ubsec_sysctllog); 612 #ifdef _MODULE 613 error = config_fini_component(cfdriver_ioconf_ubsec, 614 cfattach_ioconf_ubsec, cfdata_ioconf_ubsec); 615 #endif 616 return error; 617 default: 618 return ENOTTY; 619 } 620 } 621 622 static int 623 ubsec_sysctl_init(void) 624 { 625 const struct sysctlnode *node = NULL; 626 627 ubsec_sysctllog = NULL; 628 629 sysctl_createv(&ubsec_sysctllog, 0, NULL, NULL, 630 CTLFLAG_PERMANENT, 631 CTLTYPE_NODE, "hw", NULL, 632 NULL, 0, NULL, 0, 633 CTL_HW, CTL_EOL); 634 sysctl_createv(&ubsec_sysctllog, 0, NULL, &node, 635 CTLFLAG_PERMANENT, 636 CTLTYPE_NODE, "ubsec", 637 SYSCTL_DESCR("ubsec opetions"), 638 NULL, 0, NULL, 0, 639 CTL_HW, CTL_CREATE, CTL_EOL); 640 sysctl_createv(&ubsec_sysctllog, 0, &node, NULL, 641 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, 642 CTLTYPE_INT, "maxbatch", 643 SYSCTL_DESCR("max ops to batch w/o interrupt"), 644 NULL, 0, &ubsec_maxbatch, 0, 645 CTL_CREATE, CTL_EOL); 646 sysctl_createv(&ubsec_sysctllog, 0, &node, NULL, 647 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, 648 CTLTYPE_INT, "maxaggr", 649 SYSCTL_DESCR("max ops to aggregate under one interrupt"), 650 NULL, 0, &ubsec_maxaggr, 0, 651 CTL_CREATE, CTL_EOL); 652 653 return 0; 654 } 655 656 /* 657 * UBSEC Interrupt routine 658 */ 659 static int 660 ubsec_intr(void *arg) 661 { 662 struct ubsec_softc *sc = arg; 663 volatile u_int32_t stat; 664 struct ubsec_q *q; 665 struct ubsec_dma *dmap; 666 int flags; 667 int npkts = 0, i; 668 669 mutex_spin_enter(&sc->sc_mtx); 670 stat = READ_REG(sc, BS_STAT); 671 stat &= sc->sc_statmask; 672 if (stat == 0) { 673 mutex_spin_exit(&sc->sc_mtx); 674 return (0); 675 } 676 677 WRITE_REG(sc, BS_STAT, stat); /* IACK */ 678 679 /* 680 * Check to see if we have any packets waiting for us 681 */ 682 if ((stat & BS_STAT_MCR1_DONE)) { 683 while (!SIMPLEQ_EMPTY(&sc->sc_qchip)) { 684 q = SIMPLEQ_FIRST(&sc->sc_qchip); 685 dmap = q->q_dma; 686 687 if ((dmap->d_dma->d_mcr.mcr_flags & htole16(UBS_MCR_DONE)) == 0) 688 break; 689 690 q = SIMPLEQ_FIRST(&sc->sc_qchip); 691 SIMPLEQ_REMOVE_HEAD(&sc->sc_qchip, /*q,*/ q_next); 692 693 npkts = q->q_nstacked_mcrs; 694 sc->sc_nqchip -= 1+npkts; 695 /* 696 * search for further sc_qchip ubsec_q's that share 697 * the same MCR, and complete them too, they must be 698 * at the top. 699 */ 700 for (i = 0; i < npkts; i++) { 701 if(q->q_stacked_mcr[i]) 702 ubsec_callback(sc, q->q_stacked_mcr[i]); 703 else 704 break; 705 } 706 ubsec_callback(sc, q); 707 } 708 709 /* 710 * Don't send any more packet to chip if there has been 711 * a DMAERR. 712 */ 713 if (!(stat & BS_STAT_DMAERR)) 714 ubsec_feed(sc); 715 } 716 717 /* 718 * Check to see if we have any key setups/rng's waiting for us 719 */ 720 if ((sc->sc_flags & (UBS_FLAGS_KEY|UBS_FLAGS_RNG)) && 721 (stat & BS_STAT_MCR2_DONE)) { 722 struct ubsec_q2 *q2; 723 struct ubsec_mcr *mcr; 724 725 while (!SIMPLEQ_EMPTY(&sc->sc_qchip2)) { 726 q2 = SIMPLEQ_FIRST(&sc->sc_qchip2); 727 728 bus_dmamap_sync(sc->sc_dmat, q2->q_mcr.dma_map, 729 0, q2->q_mcr.dma_map->dm_mapsize, 730 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 731 732 mcr = (struct ubsec_mcr *)q2->q_mcr.dma_vaddr; 733 734 /* A bug in new devices requires to swap this field */ 735 if (sc->sc_flags & UBS_FLAGS_MULTIMCR) 736 flags = htole16(mcr->mcr_flags); 737 else 738 flags = mcr->mcr_flags; 739 if ((flags & htole16(UBS_MCR_DONE)) == 0) { 740 bus_dmamap_sync(sc->sc_dmat, 741 q2->q_mcr.dma_map, 0, 742 q2->q_mcr.dma_map->dm_mapsize, 743 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 744 break; 745 } 746 q2 = SIMPLEQ_FIRST(&sc->sc_qchip2); 747 SIMPLEQ_REMOVE_HEAD(&sc->sc_qchip2, /*q2,*/ q_next); 748 ubsec_callback2(sc, q2); 749 /* 750 * Don't send any more packet to chip if there has been 751 * a DMAERR. 752 */ 753 if (!(stat & BS_STAT_DMAERR)) 754 ubsec_feed2(sc); 755 } 756 } 757 if ((sc->sc_flags & UBS_FLAGS_RNG4) && (stat & BS_STAT_MCR4_DONE)) { 758 struct ubsec_q2 *q2; 759 struct ubsec_mcr *mcr; 760 761 while (!SIMPLEQ_EMPTY(&sc->sc_qchip4)) { 762 q2 = SIMPLEQ_FIRST(&sc->sc_qchip4); 763 764 bus_dmamap_sync(sc->sc_dmat, q2->q_mcr.dma_map, 765 0, q2->q_mcr.dma_map->dm_mapsize, 766 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 767 768 mcr = (struct ubsec_mcr *)q2->q_mcr.dma_vaddr; 769 770 /* A bug in new devices requires to swap this field */ 771 flags = htole16(mcr->mcr_flags); 772 773 if ((flags & htole16(UBS_MCR_DONE)) == 0) { 774 bus_dmamap_sync(sc->sc_dmat, 775 q2->q_mcr.dma_map, 0, 776 q2->q_mcr.dma_map->dm_mapsize, 777 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 778 break; 779 } 780 SIMPLEQ_REMOVE_HEAD(&sc->sc_qchip4, q_next); 781 ubsec_callback2(sc, q2); 782 /* 783 * Don't send any more packet to chip if there has been 784 * a DMAERR. 785 */ 786 if (!(stat & BS_STAT_DMAERR)) 787 ubsec_feed4(sc); 788 } 789 } 790 791 /* 792 * Check to see if we got any DMA Error 793 */ 794 if (stat & BS_STAT_DMAERR) { 795 #ifdef UBSEC_DEBUG 796 if (ubsec_debug) { 797 volatile u_int32_t a = READ_REG(sc, BS_ERR); 798 799 printf("%s: dmaerr %s@%08x\n", device_xname(sc->sc_dev), 800 (a & BS_ERR_READ) ? "read" : "write", 801 a & BS_ERR_ADDR); 802 } 803 #endif /* UBSEC_DEBUG */ 804 ubsecstats.hst_dmaerr++; 805 ubsec_totalreset(sc); 806 ubsec_feed(sc); 807 } 808 809 if (sc->sc_needwakeup) { /* XXX check high watermark */ 810 int wkeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ); 811 #ifdef UBSEC_DEBUG 812 if (ubsec_debug) 813 printf("%s: wakeup crypto (%x)\n", device_xname(sc->sc_dev), 814 sc->sc_needwakeup); 815 #endif /* UBSEC_DEBUG */ 816 sc->sc_needwakeup &= ~wkeup; 817 crypto_unblock(sc->sc_cid, wkeup); 818 } 819 mutex_spin_exit(&sc->sc_mtx); 820 return (1); 821 } 822 823 /* 824 * ubsec_feed() - aggregate and post requests to chip 825 * OpenBSD comments: 826 * It is assumed that the caller set splnet() 827 */ 828 static void 829 ubsec_feed(struct ubsec_softc *sc) 830 { 831 struct ubsec_q *q, *q2; 832 int npkts, i; 833 void *v; 834 u_int32_t stat; 835 #ifdef UBSEC_DEBUG 836 static int max; 837 #endif /* UBSEC_DEBUG */ 838 839 npkts = sc->sc_nqueue; 840 if (npkts > ubsecstats.hst_maxqueue) 841 ubsecstats.hst_maxqueue = npkts; 842 if (npkts < 2) 843 goto feed1; 844 845 /* 846 * Decide how many ops to combine in a single MCR. We cannot 847 * aggregate more than UBS_MAX_AGGR because this is the number 848 * of slots defined in the data structure. Otherwise we clamp 849 * based on the tunable parameter ubsec_maxaggr. Note that 850 * aggregation can happen in two ways: either by batching ops 851 * from above or because the h/w backs up and throttles us. 852 * Aggregating ops reduces the number of interrupts to the host 853 * but also (potentially) increases the latency for processing 854 * completed ops as we only get an interrupt when all aggregated 855 * ops have completed. 856 */ 857 if (npkts > sc->sc_maxaggr) 858 npkts = sc->sc_maxaggr; 859 if (npkts > ubsec_maxaggr) 860 npkts = ubsec_maxaggr; 861 if (npkts > ubsecstats.hst_maxbatch) 862 ubsecstats.hst_maxbatch = npkts; 863 if (npkts < 2) 864 goto feed1; 865 ubsecstats.hst_totbatch += npkts-1; 866 867 if ((stat = READ_REG(sc, BS_STAT)) & (BS_STAT_MCR1_FULL | BS_STAT_DMAERR)) { 868 if (stat & BS_STAT_DMAERR) { 869 ubsec_totalreset(sc); 870 ubsecstats.hst_dmaerr++; 871 } else { 872 ubsecstats.hst_mcr1full++; 873 } 874 return; 875 } 876 877 #ifdef UBSEC_DEBUG 878 if (ubsec_debug) 879 printf("merging %d records\n", npkts); 880 /* XXX temporary aggregation statistics reporting code */ 881 if (max < npkts) { 882 max = npkts; 883 printf("%s: new max aggregate %d\n", device_xname(sc->sc_dev), max); 884 } 885 #endif /* UBSEC_DEBUG */ 886 887 q = SIMPLEQ_FIRST(&sc->sc_queue); 888 SIMPLEQ_REMOVE_HEAD(&sc->sc_queue, /*q,*/ q_next); 889 --sc->sc_nqueue; 890 891 bus_dmamap_sync(sc->sc_dmat, q->q_src_map, 892 0, q->q_src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 893 if (q->q_dst_map != NULL) 894 bus_dmamap_sync(sc->sc_dmat, q->q_dst_map, 895 0, q->q_dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); 896 897 q->q_nstacked_mcrs = npkts - 1; /* Number of packets stacked */ 898 899 for (i = 0; i < q->q_nstacked_mcrs; i++) { 900 q2 = SIMPLEQ_FIRST(&sc->sc_queue); 901 bus_dmamap_sync(sc->sc_dmat, q2->q_src_map, 902 0, q2->q_src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 903 if (q2->q_dst_map != NULL) 904 bus_dmamap_sync(sc->sc_dmat, q2->q_dst_map, 905 0, q2->q_dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); 906 q2= SIMPLEQ_FIRST(&sc->sc_queue); 907 SIMPLEQ_REMOVE_HEAD(&sc->sc_queue, /*q2,*/ q_next); 908 --sc->sc_nqueue; 909 910 v = ((void *)&q2->q_dma->d_dma->d_mcr); 911 v = (char*)v + (sizeof(struct ubsec_mcr) - 912 sizeof(struct ubsec_mcr_add)); 913 memcpy(&q->q_dma->d_dma->d_mcradd[i], v, sizeof(struct ubsec_mcr_add)); 914 q->q_stacked_mcr[i] = q2; 915 } 916 q->q_dma->d_dma->d_mcr.mcr_pkts = htole16(npkts); 917 SIMPLEQ_INSERT_TAIL(&sc->sc_qchip, q, q_next); 918 sc->sc_nqchip += npkts; 919 if (sc->sc_nqchip > ubsecstats.hst_maxqchip) 920 ubsecstats.hst_maxqchip = sc->sc_nqchip; 921 bus_dmamap_sync(sc->sc_dmat, q->q_dma->d_alloc.dma_map, 922 0, q->q_dma->d_alloc.dma_map->dm_mapsize, 923 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 924 WRITE_REG(sc, BS_MCR1, q->q_dma->d_alloc.dma_paddr + 925 offsetof(struct ubsec_dmachunk, d_mcr)); 926 return; 927 928 feed1: 929 while (!SIMPLEQ_EMPTY(&sc->sc_queue)) { 930 if ((stat = READ_REG(sc, BS_STAT)) & (BS_STAT_MCR1_FULL | BS_STAT_DMAERR)) { 931 if (stat & BS_STAT_DMAERR) { 932 ubsec_totalreset(sc); 933 ubsecstats.hst_dmaerr++; 934 } else { 935 ubsecstats.hst_mcr1full++; 936 } 937 break; 938 } 939 940 q = SIMPLEQ_FIRST(&sc->sc_queue); 941 942 bus_dmamap_sync(sc->sc_dmat, q->q_src_map, 943 0, q->q_src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 944 if (q->q_dst_map != NULL) 945 bus_dmamap_sync(sc->sc_dmat, q->q_dst_map, 946 0, q->q_dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); 947 bus_dmamap_sync(sc->sc_dmat, q->q_dma->d_alloc.dma_map, 948 0, q->q_dma->d_alloc.dma_map->dm_mapsize, 949 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 950 951 WRITE_REG(sc, BS_MCR1, q->q_dma->d_alloc.dma_paddr + 952 offsetof(struct ubsec_dmachunk, d_mcr)); 953 #ifdef UBSEC_DEBUG 954 if (ubsec_debug) 955 printf("feed: q->chip %p %08x stat %08x\n", 956 q, (u_int32_t)q->q_dma->d_alloc.dma_paddr, 957 stat); 958 #endif /* UBSEC_DEBUG */ 959 q = SIMPLEQ_FIRST(&sc->sc_queue); 960 SIMPLEQ_REMOVE_HEAD(&sc->sc_queue, /*q,*/ q_next); 961 --sc->sc_nqueue; 962 SIMPLEQ_INSERT_TAIL(&sc->sc_qchip, q, q_next); 963 sc->sc_nqchip++; 964 } 965 if (sc->sc_nqchip > ubsecstats.hst_maxqchip) 966 ubsecstats.hst_maxqchip = sc->sc_nqchip; 967 } 968 969 /* 970 * Allocate a new 'session' and return an encoded session id. 'sidp' 971 * contains our registration id, and should contain an encoded session 972 * id on successful allocation. 973 */ 974 static int 975 ubsec_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) 976 { 977 struct cryptoini *c, *encini = NULL, *macini = NULL; 978 struct ubsec_softc *sc; 979 struct ubsec_session *ses = NULL; 980 MD5_CTX md5ctx; 981 SHA1_CTX sha1ctx; 982 int i, sesn; 983 984 sc = arg; 985 KASSERT(sc != NULL /*, ("ubsec_newsession: null softc")*/); 986 987 if (sidp == NULL || cri == NULL || sc == NULL) 988 return (EINVAL); 989 990 for (c = cri; c != NULL; c = c->cri_next) { 991 if (c->cri_alg == CRYPTO_MD5_HMAC_96 || 992 c->cri_alg == CRYPTO_SHA1_HMAC_96) { 993 if (macini) 994 return (EINVAL); 995 macini = c; 996 } else if (c->cri_alg == CRYPTO_DES_CBC || 997 c->cri_alg == CRYPTO_3DES_CBC) { 998 if (encini) 999 return (EINVAL); 1000 encini = c; 1001 } else 1002 return (EINVAL); 1003 } 1004 if (encini == NULL && macini == NULL) 1005 return (EINVAL); 1006 1007 if (sc->sc_sessions == NULL) { 1008 ses = sc->sc_sessions = (struct ubsec_session *)malloc( 1009 sizeof(struct ubsec_session), M_DEVBUF, M_NOWAIT); 1010 if (ses == NULL) 1011 return (ENOMEM); 1012 sesn = 0; 1013 sc->sc_nsessions = 1; 1014 } else { 1015 for (sesn = 0; sesn < sc->sc_nsessions; sesn++) { 1016 if (sc->sc_sessions[sesn].ses_used == 0) { 1017 ses = &sc->sc_sessions[sesn]; 1018 break; 1019 } 1020 } 1021 1022 if (ses == NULL) { 1023 sesn = sc->sc_nsessions; 1024 ses = (struct ubsec_session *)malloc((sesn + 1) * 1025 sizeof(struct ubsec_session), M_DEVBUF, M_NOWAIT); 1026 if (ses == NULL) 1027 return (ENOMEM); 1028 memcpy(ses, sc->sc_sessions, sesn * 1029 sizeof(struct ubsec_session)); 1030 memset(sc->sc_sessions, 0, sesn * 1031 sizeof(struct ubsec_session)); 1032 free(sc->sc_sessions, M_DEVBUF); 1033 sc->sc_sessions = ses; 1034 ses = &sc->sc_sessions[sesn]; 1035 sc->sc_nsessions++; 1036 } 1037 } 1038 1039 memset(ses, 0, sizeof(struct ubsec_session)); 1040 ses->ses_used = 1; 1041 if (encini) { 1042 /* get an IV, network byte order */ 1043 #ifdef __NetBSD__ 1044 cprng_fast(ses->ses_iv, sizeof(ses->ses_iv)); 1045 #else 1046 get_random_bytes(ses->ses_iv, sizeof(ses->ses_iv)); 1047 #endif 1048 1049 /* Go ahead and compute key in ubsec's byte order */ 1050 if (encini->cri_alg == CRYPTO_DES_CBC) { 1051 memcpy(&ses->ses_deskey[0], encini->cri_key, 8); 1052 memcpy(&ses->ses_deskey[2], encini->cri_key, 8); 1053 memcpy(&ses->ses_deskey[4], encini->cri_key, 8); 1054 } else 1055 memcpy(ses->ses_deskey, encini->cri_key, 24); 1056 1057 SWAP32(ses->ses_deskey[0]); 1058 SWAP32(ses->ses_deskey[1]); 1059 SWAP32(ses->ses_deskey[2]); 1060 SWAP32(ses->ses_deskey[3]); 1061 SWAP32(ses->ses_deskey[4]); 1062 SWAP32(ses->ses_deskey[5]); 1063 } 1064 1065 if (macini) { 1066 for (i = 0; i < macini->cri_klen / 8; i++) 1067 macini->cri_key[i] ^= HMAC_IPAD_VAL; 1068 1069 if (macini->cri_alg == CRYPTO_MD5_HMAC_96) { 1070 MD5Init(&md5ctx); 1071 MD5Update(&md5ctx, macini->cri_key, 1072 macini->cri_klen / 8); 1073 MD5Update(&md5ctx, hmac_ipad_buffer, 1074 HMAC_BLOCK_LEN - (macini->cri_klen / 8)); 1075 memcpy(ses->ses_hminner, md5ctx.state, 1076 sizeof(md5ctx.state)); 1077 } else { 1078 SHA1Init(&sha1ctx); 1079 SHA1Update(&sha1ctx, macini->cri_key, 1080 macini->cri_klen / 8); 1081 SHA1Update(&sha1ctx, hmac_ipad_buffer, 1082 HMAC_BLOCK_LEN - (macini->cri_klen / 8)); 1083 memcpy(ses->ses_hminner, sha1ctx.state, 1084 sizeof(sha1ctx.state)); 1085 } 1086 1087 for (i = 0; i < macini->cri_klen / 8; i++) 1088 macini->cri_key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); 1089 1090 if (macini->cri_alg == CRYPTO_MD5_HMAC_96) { 1091 MD5Init(&md5ctx); 1092 MD5Update(&md5ctx, macini->cri_key, 1093 macini->cri_klen / 8); 1094 MD5Update(&md5ctx, hmac_opad_buffer, 1095 HMAC_BLOCK_LEN - (macini->cri_klen / 8)); 1096 memcpy(ses->ses_hmouter, md5ctx.state, 1097 sizeof(md5ctx.state)); 1098 } else { 1099 SHA1Init(&sha1ctx); 1100 SHA1Update(&sha1ctx, macini->cri_key, 1101 macini->cri_klen / 8); 1102 SHA1Update(&sha1ctx, hmac_opad_buffer, 1103 HMAC_BLOCK_LEN - (macini->cri_klen / 8)); 1104 memcpy(ses->ses_hmouter, sha1ctx.state, 1105 sizeof(sha1ctx.state)); 1106 } 1107 1108 for (i = 0; i < macini->cri_klen / 8; i++) 1109 macini->cri_key[i] ^= HMAC_OPAD_VAL; 1110 } 1111 1112 *sidp = UBSEC_SID(device_unit(sc->sc_dev), sesn); 1113 return (0); 1114 } 1115 1116 /* 1117 * Deallocate a session. 1118 */ 1119 static int 1120 ubsec_freesession(void *arg, u_int64_t tid) 1121 { 1122 struct ubsec_softc *sc; 1123 int session; 1124 u_int32_t sid = ((u_int32_t) tid) & 0xffffffff; 1125 1126 sc = arg; 1127 KASSERT(sc != NULL /*, ("ubsec_freesession: null softc")*/); 1128 1129 session = UBSEC_SESSION(sid); 1130 if (session >= sc->sc_nsessions) 1131 return (EINVAL); 1132 1133 memset(&sc->sc_sessions[session], 0, sizeof(sc->sc_sessions[session])); 1134 return (0); 1135 } 1136 1137 #ifdef __FreeBSD__ /* Ugly gratuitous changes to bus_dma */ 1138 static void 1139 ubsec_op_cb(void *arg, bus_dma_segment_t *seg, int nsegs, bus_size_t mapsize, int error) 1140 { 1141 struct ubsec_operand *op = arg; 1142 1143 KASSERT(nsegs <= UBS_MAX_SCATTER 1144 /*, ("Too many DMA segments returned when mapping operand")*/); 1145 #ifdef UBSEC_DEBUG 1146 if (ubsec_debug) 1147 printf("ubsec_op_cb: mapsize %u nsegs %d\n", 1148 (u_int) mapsize, nsegs); 1149 #endif 1150 op->mapsize = mapsize; 1151 op->nsegs = nsegs; 1152 memcpy(op->segs, seg, nsegs * sizeof (seg[0])); 1153 } 1154 #endif 1155 1156 static int 1157 ubsec_process(void *arg, struct cryptop *crp, int hint) 1158 { 1159 struct ubsec_q *q = NULL; 1160 #ifdef __OpenBSD__ 1161 int card; 1162 #endif 1163 int err = 0, i, j, nicealign; 1164 struct ubsec_softc *sc; 1165 struct cryptodesc *crd1, *crd2, *maccrd, *enccrd; 1166 int encoffset = 0, macoffset = 0, cpskip, cpoffset; 1167 int sskip, dskip, stheend, dtheend; 1168 int16_t coffset; 1169 struct ubsec_session *ses; 1170 struct ubsec_pktctx ctx; 1171 struct ubsec_dma *dmap = NULL; 1172 1173 sc = arg; 1174 KASSERT(sc != NULL /*, ("ubsec_process: null softc")*/); 1175 1176 if (crp == NULL || crp->crp_callback == NULL || sc == NULL) { 1177 ubsecstats.hst_invalid++; 1178 return (EINVAL); 1179 } 1180 if (UBSEC_SESSION(crp->crp_sid) >= sc->sc_nsessions) { 1181 ubsecstats.hst_badsession++; 1182 return (EINVAL); 1183 } 1184 1185 mutex_spin_enter(&sc->sc_mtx); 1186 1187 if (SIMPLEQ_EMPTY(&sc->sc_freequeue)) { 1188 ubsecstats.hst_queuefull++; 1189 sc->sc_needwakeup |= CRYPTO_SYMQ; 1190 mutex_spin_exit(&sc->sc_mtx); 1191 return(ERESTART); 1192 } 1193 1194 q = SIMPLEQ_FIRST(&sc->sc_freequeue); 1195 SIMPLEQ_REMOVE_HEAD(&sc->sc_freequeue, /*q,*/ q_next); 1196 mutex_spin_exit(&sc->sc_mtx); 1197 1198 dmap = q->q_dma; /* Save dma pointer */ 1199 memset(q, 0, sizeof(struct ubsec_q)); 1200 memset(&ctx, 0, sizeof(ctx)); 1201 1202 q->q_sesn = UBSEC_SESSION(crp->crp_sid); 1203 q->q_dma = dmap; 1204 ses = &sc->sc_sessions[q->q_sesn]; 1205 1206 if (crp->crp_flags & CRYPTO_F_IMBUF) { 1207 q->q_src_m = (struct mbuf *)crp->crp_buf; 1208 q->q_dst_m = (struct mbuf *)crp->crp_buf; 1209 } else if (crp->crp_flags & CRYPTO_F_IOV) { 1210 q->q_src_io = (struct uio *)crp->crp_buf; 1211 q->q_dst_io = (struct uio *)crp->crp_buf; 1212 } else { 1213 ubsecstats.hst_badflags++; 1214 err = EINVAL; 1215 goto errout; /* XXX we don't handle contiguous blocks! */ 1216 } 1217 1218 memset(&dmap->d_dma->d_mcr, 0, sizeof(struct ubsec_mcr)); 1219 1220 dmap->d_dma->d_mcr.mcr_pkts = htole16(1); 1221 dmap->d_dma->d_mcr.mcr_flags = 0; 1222 q->q_crp = crp; 1223 1224 crd1 = crp->crp_desc; 1225 if (crd1 == NULL) { 1226 ubsecstats.hst_nodesc++; 1227 err = EINVAL; 1228 goto errout; 1229 } 1230 crd2 = crd1->crd_next; 1231 1232 if (crd2 == NULL) { 1233 if (crd1->crd_alg == CRYPTO_MD5_HMAC_96 || 1234 crd1->crd_alg == CRYPTO_SHA1_HMAC_96) { 1235 maccrd = crd1; 1236 enccrd = NULL; 1237 } else if (crd1->crd_alg == CRYPTO_DES_CBC || 1238 crd1->crd_alg == CRYPTO_3DES_CBC) { 1239 maccrd = NULL; 1240 enccrd = crd1; 1241 } else { 1242 ubsecstats.hst_badalg++; 1243 err = EINVAL; 1244 goto errout; 1245 } 1246 } else { 1247 if ((crd1->crd_alg == CRYPTO_MD5_HMAC_96 || 1248 crd1->crd_alg == CRYPTO_SHA1_HMAC_96) && 1249 (crd2->crd_alg == CRYPTO_DES_CBC || 1250 crd2->crd_alg == CRYPTO_3DES_CBC) && 1251 ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) { 1252 maccrd = crd1; 1253 enccrd = crd2; 1254 } else if ((crd1->crd_alg == CRYPTO_DES_CBC || 1255 crd1->crd_alg == CRYPTO_3DES_CBC) && 1256 (crd2->crd_alg == CRYPTO_MD5_HMAC_96 || 1257 crd2->crd_alg == CRYPTO_SHA1_HMAC_96) && 1258 (crd1->crd_flags & CRD_F_ENCRYPT)) { 1259 enccrd = crd1; 1260 maccrd = crd2; 1261 } else { 1262 /* 1263 * We cannot order the ubsec as requested 1264 */ 1265 ubsecstats.hst_badalg++; 1266 err = EINVAL; 1267 goto errout; 1268 } 1269 } 1270 1271 if (enccrd) { 1272 encoffset = enccrd->crd_skip; 1273 ctx.pc_flags |= htole16(UBS_PKTCTX_ENC_3DES); 1274 1275 if (enccrd->crd_flags & CRD_F_ENCRYPT) { 1276 q->q_flags |= UBSEC_QFLAGS_COPYOUTIV; 1277 1278 if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) 1279 memcpy(ctx.pc_iv, enccrd->crd_iv, 8); 1280 else { 1281 ctx.pc_iv[0] = ses->ses_iv[0]; 1282 ctx.pc_iv[1] = ses->ses_iv[1]; 1283 } 1284 1285 if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) { 1286 if (crp->crp_flags & CRYPTO_F_IMBUF) 1287 m_copyback(q->q_src_m, 1288 enccrd->crd_inject, 1289 8, (void *)ctx.pc_iv); 1290 else if (crp->crp_flags & CRYPTO_F_IOV) 1291 cuio_copyback(q->q_src_io, 1292 enccrd->crd_inject, 1293 8, (void *)ctx.pc_iv); 1294 } 1295 } else { 1296 ctx.pc_flags |= htole16(UBS_PKTCTX_INBOUND); 1297 1298 if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) 1299 memcpy(ctx.pc_iv, enccrd->crd_iv, 8); 1300 else if (crp->crp_flags & CRYPTO_F_IMBUF) 1301 m_copydata(q->q_src_m, enccrd->crd_inject, 1302 8, (void *)ctx.pc_iv); 1303 else if (crp->crp_flags & CRYPTO_F_IOV) 1304 cuio_copydata(q->q_src_io, 1305 enccrd->crd_inject, 8, 1306 (void *)ctx.pc_iv); 1307 } 1308 1309 ctx.pc_deskey[0] = ses->ses_deskey[0]; 1310 ctx.pc_deskey[1] = ses->ses_deskey[1]; 1311 ctx.pc_deskey[2] = ses->ses_deskey[2]; 1312 ctx.pc_deskey[3] = ses->ses_deskey[3]; 1313 ctx.pc_deskey[4] = ses->ses_deskey[4]; 1314 ctx.pc_deskey[5] = ses->ses_deskey[5]; 1315 SWAP32(ctx.pc_iv[0]); 1316 SWAP32(ctx.pc_iv[1]); 1317 } 1318 1319 if (maccrd) { 1320 macoffset = maccrd->crd_skip; 1321 1322 if (maccrd->crd_alg == CRYPTO_MD5_HMAC_96) 1323 ctx.pc_flags |= htole16(UBS_PKTCTX_AUTH_MD5); 1324 else 1325 ctx.pc_flags |= htole16(UBS_PKTCTX_AUTH_SHA1); 1326 1327 for (i = 0; i < 5; i++) { 1328 ctx.pc_hminner[i] = ses->ses_hminner[i]; 1329 ctx.pc_hmouter[i] = ses->ses_hmouter[i]; 1330 1331 HTOLE32(ctx.pc_hminner[i]); 1332 HTOLE32(ctx.pc_hmouter[i]); 1333 } 1334 } 1335 1336 if (enccrd && maccrd) { 1337 /* 1338 * ubsec cannot handle packets where the end of encryption 1339 * and authentication are not the same, or where the 1340 * encrypted part begins before the authenticated part. 1341 */ 1342 if ((encoffset + enccrd->crd_len) != 1343 (macoffset + maccrd->crd_len)) { 1344 ubsecstats.hst_lenmismatch++; 1345 err = EINVAL; 1346 goto errout; 1347 } 1348 if (enccrd->crd_skip < maccrd->crd_skip) { 1349 ubsecstats.hst_skipmismatch++; 1350 err = EINVAL; 1351 goto errout; 1352 } 1353 sskip = maccrd->crd_skip; 1354 cpskip = dskip = enccrd->crd_skip; 1355 stheend = maccrd->crd_len; 1356 dtheend = enccrd->crd_len; 1357 coffset = enccrd->crd_skip - maccrd->crd_skip; 1358 cpoffset = cpskip + dtheend; 1359 #ifdef UBSEC_DEBUG 1360 if (ubsec_debug) { 1361 printf("mac: skip %d, len %d, inject %d\n", 1362 maccrd->crd_skip, maccrd->crd_len, maccrd->crd_inject); 1363 printf("enc: skip %d, len %d, inject %d\n", 1364 enccrd->crd_skip, enccrd->crd_len, enccrd->crd_inject); 1365 printf("src: skip %d, len %d\n", sskip, stheend); 1366 printf("dst: skip %d, len %d\n", dskip, dtheend); 1367 printf("ubs: coffset %d, pktlen %d, cpskip %d, cpoffset %d\n", 1368 coffset, stheend, cpskip, cpoffset); 1369 } 1370 #endif 1371 } else { 1372 cpskip = dskip = sskip = macoffset + encoffset; 1373 dtheend = stheend = (enccrd)?enccrd->crd_len:maccrd->crd_len; 1374 cpoffset = cpskip + dtheend; 1375 coffset = 0; 1376 } 1377 ctx.pc_offset = htole16(coffset >> 2); 1378 1379 /* XXX FIXME: jonathan asks, what the heck's that 0xfff0? */ 1380 if (bus_dmamap_create(sc->sc_dmat, 0xfff0, UBS_MAX_SCATTER, 1381 0xfff0, 0, BUS_DMA_NOWAIT, &q->q_src_map) != 0) { 1382 err = ENOMEM; 1383 goto errout; 1384 } 1385 if (crp->crp_flags & CRYPTO_F_IMBUF) { 1386 if (bus_dmamap_load_mbuf(sc->sc_dmat, q->q_src_map, 1387 q->q_src_m, BUS_DMA_NOWAIT) != 0) { 1388 bus_dmamap_destroy(sc->sc_dmat, q->q_src_map); 1389 q->q_src_map = NULL; 1390 ubsecstats.hst_noload++; 1391 err = ENOMEM; 1392 goto errout; 1393 } 1394 } else if (crp->crp_flags & CRYPTO_F_IOV) { 1395 if (bus_dmamap_load_uio(sc->sc_dmat, q->q_src_map, 1396 q->q_src_io, BUS_DMA_NOWAIT) != 0) { 1397 bus_dmamap_destroy(sc->sc_dmat, q->q_src_map); 1398 q->q_src_map = NULL; 1399 ubsecstats.hst_noload++; 1400 err = ENOMEM; 1401 goto errout; 1402 } 1403 } 1404 nicealign = ubsec_dmamap_aligned(q->q_src_map); 1405 1406 dmap->d_dma->d_mcr.mcr_pktlen = htole16(stheend); 1407 1408 #ifdef UBSEC_DEBUG 1409 if (ubsec_debug) 1410 printf("src skip: %d nicealign: %u\n", sskip, nicealign); 1411 #endif 1412 for (i = j = 0; i < q->q_src_map->dm_nsegs; i++) { 1413 struct ubsec_pktbuf *pb; 1414 bus_size_t packl = q->q_src_map->dm_segs[i].ds_len; 1415 bus_addr_t packp = q->q_src_map->dm_segs[i].ds_addr; 1416 1417 if (sskip >= packl) { 1418 sskip -= packl; 1419 continue; 1420 } 1421 1422 packl -= sskip; 1423 packp += sskip; 1424 sskip = 0; 1425 1426 if (packl > 0xfffc) { 1427 err = EIO; 1428 goto errout; 1429 } 1430 1431 if (j == 0) 1432 pb = &dmap->d_dma->d_mcr.mcr_ipktbuf; 1433 else 1434 pb = &dmap->d_dma->d_sbuf[j - 1]; 1435 1436 pb->pb_addr = htole32(packp); 1437 1438 if (stheend) { 1439 if (packl > stheend) { 1440 pb->pb_len = htole32(stheend); 1441 stheend = 0; 1442 } else { 1443 pb->pb_len = htole32(packl); 1444 stheend -= packl; 1445 } 1446 } else 1447 pb->pb_len = htole32(packl); 1448 1449 if ((i + 1) == q->q_src_map->dm_nsegs) 1450 pb->pb_next = 0; 1451 else 1452 pb->pb_next = htole32(dmap->d_alloc.dma_paddr + 1453 offsetof(struct ubsec_dmachunk, d_sbuf[j])); 1454 j++; 1455 } 1456 1457 if (enccrd == NULL && maccrd != NULL) { 1458 dmap->d_dma->d_mcr.mcr_opktbuf.pb_addr = 0; 1459 dmap->d_dma->d_mcr.mcr_opktbuf.pb_len = 0; 1460 dmap->d_dma->d_mcr.mcr_opktbuf.pb_next = htole32(dmap->d_alloc.dma_paddr + 1461 offsetof(struct ubsec_dmachunk, d_macbuf[0])); 1462 #ifdef UBSEC_DEBUG 1463 if (ubsec_debug) 1464 printf("opkt: %x %x %x\n", 1465 dmap->d_dma->d_mcr.mcr_opktbuf.pb_addr, 1466 dmap->d_dma->d_mcr.mcr_opktbuf.pb_len, 1467 dmap->d_dma->d_mcr.mcr_opktbuf.pb_next); 1468 1469 #endif 1470 } else { 1471 if (crp->crp_flags & CRYPTO_F_IOV) { 1472 if (!nicealign) { 1473 ubsecstats.hst_iovmisaligned++; 1474 err = EINVAL; 1475 goto errout; 1476 } 1477 /* XXX: ``what the heck's that'' 0xfff0? */ 1478 if (bus_dmamap_create(sc->sc_dmat, 0xfff0, 1479 UBS_MAX_SCATTER, 0xfff0, 0, BUS_DMA_NOWAIT, 1480 &q->q_dst_map) != 0) { 1481 ubsecstats.hst_nomap++; 1482 err = ENOMEM; 1483 goto errout; 1484 } 1485 if (bus_dmamap_load_uio(sc->sc_dmat, q->q_dst_map, 1486 q->q_dst_io, BUS_DMA_NOWAIT) != 0) { 1487 bus_dmamap_destroy(sc->sc_dmat, q->q_dst_map); 1488 q->q_dst_map = NULL; 1489 ubsecstats.hst_noload++; 1490 err = ENOMEM; 1491 goto errout; 1492 } 1493 } else if (crp->crp_flags & CRYPTO_F_IMBUF) { 1494 if (nicealign) { 1495 q->q_dst_m = q->q_src_m; 1496 q->q_dst_map = q->q_src_map; 1497 } else { 1498 int totlen, len; 1499 struct mbuf *m, *top, **mp; 1500 1501 ubsecstats.hst_unaligned++; 1502 totlen = q->q_src_map->dm_mapsize; 1503 if (q->q_src_m->m_flags & M_PKTHDR) { 1504 len = MHLEN; 1505 MGETHDR(m, M_DONTWAIT, MT_DATA); 1506 /*XXX FIXME: m_dup_pkthdr */ 1507 if (m && 1 /*!m_dup_pkthdr(m, q->q_src_m, M_DONTWAIT)*/) { 1508 m_free(m); 1509 m = NULL; 1510 } 1511 } else { 1512 len = MLEN; 1513 MGET(m, M_DONTWAIT, MT_DATA); 1514 } 1515 if (m == NULL) { 1516 ubsecstats.hst_nombuf++; 1517 err = sc->sc_nqueue ? ERESTART : ENOMEM; 1518 goto errout; 1519 } 1520 if (len == MHLEN) 1521 /*XXX was M_DUP_PKTHDR*/ 1522 M_COPY_PKTHDR(m, q->q_src_m); 1523 if (totlen >= MINCLSIZE) { 1524 MCLGET(m, M_DONTWAIT); 1525 if ((m->m_flags & M_EXT) == 0) { 1526 m_free(m); 1527 ubsecstats.hst_nomcl++; 1528 err = sc->sc_nqueue ? ERESTART : ENOMEM; 1529 goto errout; 1530 } 1531 len = MCLBYTES; 1532 } 1533 m->m_len = len; 1534 top = NULL; 1535 mp = ⊤ 1536 1537 while (totlen > 0) { 1538 if (top) { 1539 MGET(m, M_DONTWAIT, MT_DATA); 1540 if (m == NULL) { 1541 m_freem(top); 1542 ubsecstats.hst_nombuf++; 1543 err = sc->sc_nqueue ? ERESTART : ENOMEM; 1544 goto errout; 1545 } 1546 len = MLEN; 1547 } 1548 if (top && totlen >= MINCLSIZE) { 1549 MCLGET(m, M_DONTWAIT); 1550 if ((m->m_flags & M_EXT) == 0) { 1551 *mp = m; 1552 m_freem(top); 1553 ubsecstats.hst_nomcl++; 1554 err = sc->sc_nqueue ? ERESTART : ENOMEM; 1555 goto errout; 1556 } 1557 len = MCLBYTES; 1558 } 1559 m->m_len = len = min(totlen, len); 1560 totlen -= len; 1561 *mp = m; 1562 mp = &m->m_next; 1563 } 1564 q->q_dst_m = top; 1565 ubsec_mcopy(q->q_src_m, q->q_dst_m, 1566 cpskip, cpoffset); 1567 /* XXX again, what the heck is that 0xfff0? */ 1568 if (bus_dmamap_create(sc->sc_dmat, 0xfff0, 1569 UBS_MAX_SCATTER, 0xfff0, 0, BUS_DMA_NOWAIT, 1570 &q->q_dst_map) != 0) { 1571 ubsecstats.hst_nomap++; 1572 err = ENOMEM; 1573 goto errout; 1574 } 1575 if (bus_dmamap_load_mbuf(sc->sc_dmat, 1576 q->q_dst_map, q->q_dst_m, 1577 BUS_DMA_NOWAIT) != 0) { 1578 bus_dmamap_destroy(sc->sc_dmat, 1579 q->q_dst_map); 1580 q->q_dst_map = NULL; 1581 ubsecstats.hst_noload++; 1582 err = ENOMEM; 1583 goto errout; 1584 } 1585 } 1586 } else { 1587 ubsecstats.hst_badflags++; 1588 err = EINVAL; 1589 goto errout; 1590 } 1591 1592 #ifdef UBSEC_DEBUG 1593 if (ubsec_debug) 1594 printf("dst skip: %d\n", dskip); 1595 #endif 1596 for (i = j = 0; i < q->q_dst_map->dm_nsegs; i++) { 1597 struct ubsec_pktbuf *pb; 1598 bus_size_t packl = q->q_dst_map->dm_segs[i].ds_len; 1599 bus_addr_t packp = q->q_dst_map->dm_segs[i].ds_addr; 1600 1601 if (dskip >= packl) { 1602 dskip -= packl; 1603 continue; 1604 } 1605 1606 packl -= dskip; 1607 packp += dskip; 1608 dskip = 0; 1609 1610 if (packl > 0xfffc) { 1611 err = EIO; 1612 goto errout; 1613 } 1614 1615 if (j == 0) 1616 pb = &dmap->d_dma->d_mcr.mcr_opktbuf; 1617 else 1618 pb = &dmap->d_dma->d_dbuf[j - 1]; 1619 1620 pb->pb_addr = htole32(packp); 1621 1622 if (dtheend) { 1623 if (packl > dtheend) { 1624 pb->pb_len = htole32(dtheend); 1625 dtheend = 0; 1626 } else { 1627 pb->pb_len = htole32(packl); 1628 dtheend -= packl; 1629 } 1630 } else 1631 pb->pb_len = htole32(packl); 1632 1633 if ((i + 1) == q->q_dst_map->dm_nsegs) { 1634 if (maccrd) 1635 pb->pb_next = htole32(dmap->d_alloc.dma_paddr + 1636 offsetof(struct ubsec_dmachunk, d_macbuf[0])); 1637 else 1638 pb->pb_next = 0; 1639 } else 1640 pb->pb_next = htole32(dmap->d_alloc.dma_paddr + 1641 offsetof(struct ubsec_dmachunk, d_dbuf[j])); 1642 j++; 1643 } 1644 } 1645 1646 dmap->d_dma->d_mcr.mcr_cmdctxp = htole32(dmap->d_alloc.dma_paddr + 1647 offsetof(struct ubsec_dmachunk, d_ctx)); 1648 1649 if (sc->sc_flags & UBS_FLAGS_LONGCTX) { 1650 struct ubsec_pktctx_long *ctxl; 1651 1652 ctxl = (struct ubsec_pktctx_long *)((char *)dmap->d_alloc.dma_vaddr + 1653 offsetof(struct ubsec_dmachunk, d_ctx)); 1654 1655 /* transform small context into long context */ 1656 ctxl->pc_len = htole16(sizeof(struct ubsec_pktctx_long)); 1657 ctxl->pc_type = htole16(UBS_PKTCTX_TYPE_IPSEC); 1658 ctxl->pc_flags = ctx.pc_flags; 1659 ctxl->pc_offset = ctx.pc_offset; 1660 for (i = 0; i < 6; i++) 1661 ctxl->pc_deskey[i] = ctx.pc_deskey[i]; 1662 for (i = 0; i < 5; i++) 1663 ctxl->pc_hminner[i] = ctx.pc_hminner[i]; 1664 for (i = 0; i < 5; i++) 1665 ctxl->pc_hmouter[i] = ctx.pc_hmouter[i]; 1666 ctxl->pc_iv[0] = ctx.pc_iv[0]; 1667 ctxl->pc_iv[1] = ctx.pc_iv[1]; 1668 } else 1669 memcpy((char *)dmap->d_alloc.dma_vaddr + 1670 offsetof(struct ubsec_dmachunk, d_ctx), &ctx, 1671 sizeof(struct ubsec_pktctx)); 1672 1673 mutex_spin_enter(&sc->sc_mtx); 1674 SIMPLEQ_INSERT_TAIL(&sc->sc_queue, q, q_next); 1675 sc->sc_nqueue++; 1676 ubsecstats.hst_ipackets++; 1677 ubsecstats.hst_ibytes += dmap->d_alloc.dma_map->dm_mapsize; 1678 if ((hint & CRYPTO_HINT_MORE) == 0 || sc->sc_nqueue >= ubsec_maxbatch) 1679 ubsec_feed(sc); 1680 mutex_spin_exit(&sc->sc_mtx); 1681 return (0); 1682 1683 errout: 1684 if (q != NULL) { 1685 if ((q->q_dst_m != NULL) && (q->q_src_m != q->q_dst_m)) 1686 m_freem(q->q_dst_m); 1687 1688 if (q->q_dst_map != NULL && q->q_dst_map != q->q_src_map) { 1689 bus_dmamap_unload(sc->sc_dmat, q->q_dst_map); 1690 bus_dmamap_destroy(sc->sc_dmat, q->q_dst_map); 1691 } 1692 if (q->q_src_map != NULL) { 1693 bus_dmamap_unload(sc->sc_dmat, q->q_src_map); 1694 bus_dmamap_destroy(sc->sc_dmat, q->q_src_map); 1695 } 1696 1697 mutex_spin_enter(&sc->sc_mtx); 1698 SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q, q_next); 1699 mutex_spin_exit(&sc->sc_mtx); 1700 } 1701 #if 0 /* jonathan says: this openbsd code seems to be subsumed elsewhere */ 1702 if (err == EINVAL) 1703 ubsecstats.hst_invalid++; 1704 else 1705 ubsecstats.hst_nomem++; 1706 #endif 1707 if (err != ERESTART) { 1708 crp->crp_etype = err; 1709 crypto_done(crp); 1710 } else { 1711 sc->sc_needwakeup |= CRYPTO_SYMQ; 1712 } 1713 return (err); 1714 } 1715 1716 static void 1717 ubsec_callback(struct ubsec_softc *sc, struct ubsec_q *q) 1718 { 1719 struct cryptop *crp = (struct cryptop *)q->q_crp; 1720 struct cryptodesc *crd; 1721 struct ubsec_dma *dmap = q->q_dma; 1722 1723 ubsecstats.hst_opackets++; 1724 ubsecstats.hst_obytes += dmap->d_alloc.dma_size; 1725 1726 bus_dmamap_sync(sc->sc_dmat, dmap->d_alloc.dma_map, 0, 1727 dmap->d_alloc.dma_map->dm_mapsize, 1728 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1729 if (q->q_dst_map != NULL && q->q_dst_map != q->q_src_map) { 1730 bus_dmamap_sync(sc->sc_dmat, q->q_dst_map, 1731 0, q->q_dst_map->dm_mapsize, BUS_DMASYNC_POSTREAD); 1732 bus_dmamap_unload(sc->sc_dmat, q->q_dst_map); 1733 bus_dmamap_destroy(sc->sc_dmat, q->q_dst_map); 1734 } 1735 bus_dmamap_sync(sc->sc_dmat, q->q_src_map, 1736 0, q->q_src_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1737 bus_dmamap_unload(sc->sc_dmat, q->q_src_map); 1738 bus_dmamap_destroy(sc->sc_dmat, q->q_src_map); 1739 1740 if ((crp->crp_flags & CRYPTO_F_IMBUF) && (q->q_src_m != q->q_dst_m)) { 1741 m_freem(q->q_src_m); 1742 crp->crp_buf = (void *)q->q_dst_m; 1743 } 1744 1745 /* copy out IV for future use */ 1746 if (q->q_flags & UBSEC_QFLAGS_COPYOUTIV) { 1747 for (crd = crp->crp_desc; crd; crd = crd->crd_next) { 1748 if (crd->crd_alg != CRYPTO_DES_CBC && 1749 crd->crd_alg != CRYPTO_3DES_CBC) 1750 continue; 1751 if (crp->crp_flags & CRYPTO_F_IMBUF) 1752 m_copydata((struct mbuf *)crp->crp_buf, 1753 crd->crd_skip + crd->crd_len - 8, 8, 1754 (void *)sc->sc_sessions[q->q_sesn].ses_iv); 1755 else if (crp->crp_flags & CRYPTO_F_IOV) { 1756 cuio_copydata((struct uio *)crp->crp_buf, 1757 crd->crd_skip + crd->crd_len - 8, 8, 1758 (void *)sc->sc_sessions[q->q_sesn].ses_iv); 1759 } 1760 break; 1761 } 1762 } 1763 1764 for (crd = crp->crp_desc; crd; crd = crd->crd_next) { 1765 if (crd->crd_alg != CRYPTO_MD5_HMAC_96 && 1766 crd->crd_alg != CRYPTO_SHA1_HMAC_96) 1767 continue; 1768 if (crp->crp_flags & CRYPTO_F_IMBUF) 1769 m_copyback((struct mbuf *)crp->crp_buf, 1770 crd->crd_inject, 12, 1771 (void *)dmap->d_dma->d_macbuf); 1772 else if (crp->crp_flags & CRYPTO_F_IOV && crp->crp_mac) 1773 bcopy((void *)dmap->d_dma->d_macbuf, 1774 crp->crp_mac, 12); 1775 break; 1776 } 1777 SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q, q_next); 1778 crypto_done(crp); 1779 } 1780 1781 static void 1782 ubsec_mcopy(struct mbuf *srcm, struct mbuf *dstm, int hoffset, int toffset) 1783 { 1784 int i, j, dlen, slen; 1785 char *dptr, *sptr; 1786 1787 j = 0; 1788 sptr = srcm->m_data; 1789 slen = srcm->m_len; 1790 dptr = dstm->m_data; 1791 dlen = dstm->m_len; 1792 1793 while (1) { 1794 for (i = 0; i < min(slen, dlen); i++) { 1795 if (j < hoffset || j >= toffset) 1796 *dptr++ = *sptr++; 1797 slen--; 1798 dlen--; 1799 j++; 1800 } 1801 if (slen == 0) { 1802 srcm = srcm->m_next; 1803 if (srcm == NULL) 1804 return; 1805 sptr = srcm->m_data; 1806 slen = srcm->m_len; 1807 } 1808 if (dlen == 0) { 1809 dstm = dstm->m_next; 1810 if (dstm == NULL) 1811 return; 1812 dptr = dstm->m_data; 1813 dlen = dstm->m_len; 1814 } 1815 } 1816 } 1817 1818 /* 1819 * feed the key generator, must be called at splnet() or higher. 1820 */ 1821 static void 1822 ubsec_feed2(struct ubsec_softc *sc) 1823 { 1824 struct ubsec_q2 *q; 1825 1826 while (!SIMPLEQ_EMPTY(&sc->sc_queue2)) { 1827 if (READ_REG(sc, BS_STAT) & BS_STAT_MCR2_FULL) 1828 break; 1829 q = SIMPLEQ_FIRST(&sc->sc_queue2); 1830 1831 bus_dmamap_sync(sc->sc_dmat, q->q_mcr.dma_map, 0, 1832 q->q_mcr.dma_map->dm_mapsize, 1833 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1834 bus_dmamap_sync(sc->sc_dmat, q->q_ctx.dma_map, 0, 1835 q->q_ctx.dma_map->dm_mapsize, 1836 BUS_DMASYNC_PREWRITE); 1837 1838 WRITE_REG(sc, BS_MCR2, q->q_mcr.dma_paddr); 1839 q = SIMPLEQ_FIRST(&sc->sc_queue2); 1840 SIMPLEQ_REMOVE_HEAD(&sc->sc_queue2, /*q,*/ q_next); 1841 --sc->sc_nqueue2; 1842 SIMPLEQ_INSERT_TAIL(&sc->sc_qchip2, q, q_next); 1843 } 1844 } 1845 1846 /* 1847 * feed the RNG (used instead of ubsec_feed2() on 5827+ devices) 1848 */ 1849 void 1850 ubsec_feed4(struct ubsec_softc *sc) 1851 { 1852 struct ubsec_q2 *q; 1853 1854 while (!SIMPLEQ_EMPTY(&sc->sc_queue4)) { 1855 if (READ_REG(sc, BS_STAT) & BS_STAT_MCR4_FULL) 1856 break; 1857 q = SIMPLEQ_FIRST(&sc->sc_queue4); 1858 1859 bus_dmamap_sync(sc->sc_dmat, q->q_mcr.dma_map, 0, 1860 q->q_mcr.dma_map->dm_mapsize, 1861 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1862 bus_dmamap_sync(sc->sc_dmat, q->q_ctx.dma_map, 0, 1863 q->q_ctx.dma_map->dm_mapsize, 1864 BUS_DMASYNC_PREWRITE); 1865 1866 WRITE_REG(sc, BS_MCR4, q->q_mcr.dma_paddr); 1867 SIMPLEQ_REMOVE_HEAD(&sc->sc_queue4, q_next); 1868 --sc->sc_nqueue4; 1869 SIMPLEQ_INSERT_TAIL(&sc->sc_qchip4, q, q_next); 1870 } 1871 } 1872 1873 /* 1874 * Callback for handling random numbers 1875 */ 1876 static void 1877 ubsec_callback2(struct ubsec_softc *sc, struct ubsec_q2 *q) 1878 { 1879 struct cryptkop *krp; 1880 struct ubsec_ctx_keyop *ctx; 1881 1882 ctx = (struct ubsec_ctx_keyop *)q->q_ctx.dma_vaddr; 1883 bus_dmamap_sync(sc->sc_dmat, q->q_ctx.dma_map, 0, 1884 q->q_ctx.dma_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1885 1886 switch (q->q_type) { 1887 #ifndef UBSEC_NO_RNG 1888 case UBS_CTXOP_RNGSHA1: 1889 case UBS_CTXOP_RNGBYPASS: { 1890 struct ubsec_q2_rng *rng = (struct ubsec_q2_rng *)q; 1891 u_int32_t *p; 1892 int i; 1893 1894 bus_dmamap_sync(sc->sc_dmat, rng->rng_buf.dma_map, 0, 1895 rng->rng_buf.dma_map->dm_mapsize, BUS_DMASYNC_POSTREAD); 1896 p = (u_int32_t *)rng->rng_buf.dma_vaddr; 1897 #ifndef __NetBSD__ 1898 for (i = 0; i < UBSEC_RNG_BUFSIZ; p++, i++) 1899 add_true_randomness(letoh32(*p)); 1900 #else 1901 i = UBSEC_RNG_BUFSIZ * sizeof(u_int32_t); 1902 rnd_add_data(&sc->sc_rnd_source, (char *)p, i, i * NBBY); 1903 sc->sc_rng_need -= i; 1904 #endif 1905 rng->rng_used = 0; 1906 #ifdef __OpenBSD__ 1907 timeout_add(&sc->sc_rngto, sc->sc_rnghz); 1908 #else 1909 if (sc->sc_rng_need > 0) { 1910 callout_schedule(&sc->sc_rngto, sc->sc_rnghz); 1911 } 1912 #endif 1913 break; 1914 } 1915 #endif 1916 case UBS_CTXOP_MODEXP: { 1917 struct ubsec_q2_modexp *me = (struct ubsec_q2_modexp *)q; 1918 u_int rlen, clen; 1919 1920 krp = me->me_krp; 1921 rlen = (me->me_modbits + 7) / 8; 1922 clen = (krp->krp_param[krp->krp_iparams].crp_nbits + 7) / 8; 1923 1924 bus_dmamap_sync(sc->sc_dmat, me->me_M.dma_map, 1925 0, me->me_M.dma_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1926 bus_dmamap_sync(sc->sc_dmat, me->me_E.dma_map, 1927 0, me->me_E.dma_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1928 bus_dmamap_sync(sc->sc_dmat, me->me_C.dma_map, 1929 0, me->me_C.dma_map->dm_mapsize, BUS_DMASYNC_POSTREAD); 1930 bus_dmamap_sync(sc->sc_dmat, me->me_epb.dma_map, 1931 0, me->me_epb.dma_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1932 1933 if (clen < rlen) 1934 krp->krp_status = E2BIG; 1935 else { 1936 if (sc->sc_flags & UBS_FLAGS_HWNORM) { 1937 memset(krp->krp_param[krp->krp_iparams].crp_p, 0, 1938 (krp->krp_param[krp->krp_iparams].crp_nbits 1939 + 7) / 8); 1940 bcopy(me->me_C.dma_vaddr, 1941 krp->krp_param[krp->krp_iparams].crp_p, 1942 (me->me_modbits + 7) / 8); 1943 } else 1944 ubsec_kshift_l(me->me_shiftbits, 1945 me->me_C.dma_vaddr, me->me_normbits, 1946 krp->krp_param[krp->krp_iparams].crp_p, 1947 krp->krp_param[krp->krp_iparams].crp_nbits); 1948 } 1949 1950 crypto_kdone(krp); 1951 1952 /* bzero all potentially sensitive data */ 1953 memset(me->me_E.dma_vaddr, 0, me->me_E.dma_size); 1954 memset(me->me_M.dma_vaddr, 0, me->me_M.dma_size); 1955 memset(me->me_C.dma_vaddr, 0, me->me_C.dma_size); 1956 memset(me->me_q.q_ctx.dma_vaddr, 0, me->me_q.q_ctx.dma_size); 1957 1958 /* Can't free here, so put us on the free list. */ 1959 SIMPLEQ_INSERT_TAIL(&sc->sc_q2free, &me->me_q, q_next); 1960 break; 1961 } 1962 case UBS_CTXOP_RSAPRIV: { 1963 struct ubsec_q2_rsapriv *rp = (struct ubsec_q2_rsapriv *)q; 1964 u_int len; 1965 1966 krp = rp->rpr_krp; 1967 bus_dmamap_sync(sc->sc_dmat, rp->rpr_msgin.dma_map, 0, 1968 rp->rpr_msgin.dma_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1969 bus_dmamap_sync(sc->sc_dmat, rp->rpr_msgout.dma_map, 0, 1970 rp->rpr_msgout.dma_map->dm_mapsize, BUS_DMASYNC_POSTREAD); 1971 1972 len = (krp->krp_param[UBS_RSAPRIV_PAR_MSGOUT].crp_nbits + 7) / 8; 1973 bcopy(rp->rpr_msgout.dma_vaddr, 1974 krp->krp_param[UBS_RSAPRIV_PAR_MSGOUT].crp_p, len); 1975 1976 crypto_kdone(krp); 1977 1978 memset(rp->rpr_msgin.dma_vaddr, 0, rp->rpr_msgin.dma_size); 1979 memset(rp->rpr_msgout.dma_vaddr, 0, rp->rpr_msgout.dma_size); 1980 memset(rp->rpr_q.q_ctx.dma_vaddr, 0, rp->rpr_q.q_ctx.dma_size); 1981 1982 /* Can't free here, so put us on the free list. */ 1983 SIMPLEQ_INSERT_TAIL(&sc->sc_q2free, &rp->rpr_q, q_next); 1984 break; 1985 } 1986 default: 1987 printf("%s: unknown ctx op: %x\n", device_xname(sc->sc_dev), 1988 letoh16(ctx->ctx_op)); 1989 break; 1990 } 1991 } 1992 1993 #ifndef UBSEC_NO_RNG 1994 1995 static void 1996 ubsec_rng_get(size_t bytes, void *vsc) 1997 { 1998 struct ubsec_softc *sc = vsc; 1999 2000 mutex_spin_enter(&sc->sc_mtx); 2001 sc->sc_rng_need = bytes; 2002 ubsec_rng_locked(sc); 2003 mutex_spin_exit(&sc->sc_mtx); 2004 2005 } 2006 2007 static void 2008 ubsec_rng(void *vsc) 2009 { 2010 struct ubsec_softc *sc = vsc; 2011 mutex_spin_enter(&sc->sc_mtx); 2012 ubsec_rng_locked(sc); 2013 mutex_spin_exit(&sc->sc_mtx); 2014 } 2015 2016 static void 2017 ubsec_rng_locked(void *vsc) 2018 { 2019 struct ubsec_softc *sc = vsc; 2020 struct ubsec_q2_rng *rng = &sc->sc_rng; 2021 struct ubsec_mcr *mcr; 2022 struct ubsec_ctx_rngbypass *ctx; 2023 int *nqueue; 2024 2025 /* Caller is responsible to lock and release sc_mtx. */ 2026 KASSERT(mutex_owned(&sc->sc_mtx)); 2027 2028 if (rng->rng_used) { 2029 return; 2030 } 2031 2032 if (sc->sc_rng_need < 1) { 2033 callout_stop(&sc->sc_rngto); 2034 return; 2035 } 2036 2037 if (sc->sc_flags & UBS_FLAGS_RNG4) 2038 nqueue = &sc->sc_nqueue4; 2039 else 2040 nqueue = &sc->sc_nqueue2; 2041 2042 (*nqueue)++; 2043 if (*nqueue >= UBS_MAX_NQUEUE) 2044 goto out; 2045 2046 mcr = (struct ubsec_mcr *)rng->rng_q.q_mcr.dma_vaddr; 2047 ctx = (struct ubsec_ctx_rngbypass *)rng->rng_q.q_ctx.dma_vaddr; 2048 2049 mcr->mcr_pkts = htole16(1); 2050 mcr->mcr_flags = 0; 2051 mcr->mcr_cmdctxp = htole32(rng->rng_q.q_ctx.dma_paddr); 2052 mcr->mcr_ipktbuf.pb_addr = mcr->mcr_ipktbuf.pb_next = 0; 2053 mcr->mcr_ipktbuf.pb_len = 0; 2054 mcr->mcr_reserved = mcr->mcr_pktlen = 0; 2055 mcr->mcr_opktbuf.pb_addr = htole32(rng->rng_buf.dma_paddr); 2056 mcr->mcr_opktbuf.pb_len = htole32(((sizeof(u_int32_t) * UBSEC_RNG_BUFSIZ)) & 2057 UBS_PKTBUF_LEN); 2058 mcr->mcr_opktbuf.pb_next = 0; 2059 2060 ctx->rbp_len = htole16(sizeof(struct ubsec_ctx_rngbypass)); 2061 ctx->rbp_op = htole16(UBS_CTXOP_RNGSHA1); 2062 rng->rng_q.q_type = UBS_CTXOP_RNGSHA1; 2063 2064 bus_dmamap_sync(sc->sc_dmat, rng->rng_buf.dma_map, 0, 2065 rng->rng_buf.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD); 2066 2067 if (sc->sc_flags & UBS_FLAGS_RNG4) { 2068 SIMPLEQ_INSERT_TAIL(&sc->sc_queue4, &rng->rng_q, q_next); 2069 ubsec_feed4(sc); 2070 } else { 2071 SIMPLEQ_INSERT_TAIL(&sc->sc_queue2, &rng->rng_q, q_next); 2072 ubsec_feed2(sc); 2073 } 2074 rng->rng_used = 1; 2075 ubsecstats.hst_rng++; 2076 2077 return; 2078 2079 out: 2080 /* 2081 * Something weird happened, generate our own call back. 2082 */ 2083 (*nqueue)--; 2084 #ifdef __OpenBSD__ 2085 timeout_add(&sc->sc_rngto, sc->sc_rnghz); 2086 #else 2087 callout_schedule(&sc->sc_rngto, sc->sc_rnghz); 2088 #endif 2089 } 2090 #endif /* UBSEC_NO_RNG */ 2091 2092 static int 2093 ubsec_dma_malloc(struct ubsec_softc *sc, bus_size_t size, 2094 struct ubsec_dma_alloc *dma,int mapflags) 2095 { 2096 int r; 2097 2098 if ((r = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, 2099 &dma->dma_seg, 1, &dma->dma_nseg, BUS_DMA_NOWAIT)) != 0) 2100 goto fail_0; 2101 2102 if ((r = bus_dmamem_map(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg, 2103 size, &dma->dma_vaddr, mapflags | BUS_DMA_NOWAIT)) != 0) 2104 goto fail_1; 2105 2106 if ((r = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, 2107 BUS_DMA_NOWAIT, &dma->dma_map)) != 0) 2108 goto fail_2; 2109 2110 if ((r = bus_dmamap_load(sc->sc_dmat, dma->dma_map, dma->dma_vaddr, 2111 size, NULL, BUS_DMA_NOWAIT)) != 0) 2112 goto fail_3; 2113 2114 dma->dma_paddr = dma->dma_map->dm_segs[0].ds_addr; 2115 dma->dma_size = size; 2116 return (0); 2117 2118 fail_3: 2119 bus_dmamap_destroy(sc->sc_dmat, dma->dma_map); 2120 fail_2: 2121 bus_dmamem_unmap(sc->sc_dmat, dma->dma_vaddr, size); 2122 fail_1: 2123 bus_dmamem_free(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg); 2124 fail_0: 2125 dma->dma_map = NULL; 2126 return (r); 2127 } 2128 2129 static void 2130 ubsec_dma_free(struct ubsec_softc *sc, struct ubsec_dma_alloc *dma) 2131 { 2132 bus_dmamap_unload(sc->sc_dmat, dma->dma_map); 2133 bus_dmamem_unmap(sc->sc_dmat, dma->dma_vaddr, dma->dma_size); 2134 bus_dmamem_free(sc->sc_dmat, &dma->dma_seg, dma->dma_nseg); 2135 bus_dmamap_destroy(sc->sc_dmat, dma->dma_map); 2136 } 2137 2138 /* 2139 * Resets the board. Values in the regesters are left as is 2140 * from the reset (i.e. initial values are assigned elsewhere). 2141 */ 2142 static void 2143 ubsec_reset_board(struct ubsec_softc *sc) 2144 { 2145 volatile u_int32_t ctrl; 2146 2147 ctrl = READ_REG(sc, BS_CTRL); 2148 ctrl |= BS_CTRL_RESET; 2149 WRITE_REG(sc, BS_CTRL, ctrl); 2150 2151 /* 2152 * Wait aprox. 30 PCI clocks = 900 ns = 0.9 us 2153 */ 2154 DELAY(10); 2155 2156 /* Enable RNG and interrupts on newer devices */ 2157 if (sc->sc_flags & UBS_FLAGS_MULTIMCR) { 2158 #ifndef UBSEC_NO_RNG 2159 WRITE_REG(sc, BS_CFG, BS_CFG_RNG); 2160 #endif 2161 WRITE_REG(sc, BS_INT, BS_INT_DMAINT); 2162 } 2163 } 2164 2165 /* 2166 * Init Broadcom registers 2167 */ 2168 static void 2169 ubsec_init_board(struct ubsec_softc *sc) 2170 { 2171 u_int32_t ctrl; 2172 2173 ctrl = READ_REG(sc, BS_CTRL); 2174 ctrl &= ~(BS_CTRL_BE32 | BS_CTRL_BE64); 2175 ctrl |= BS_CTRL_LITTLE_ENDIAN | BS_CTRL_MCR1INT; 2176 2177 /* 2178 * XXX: Sam Leffler's code has (UBS_FLAGS_KEY|UBS_FLAGS_RNG)). 2179 * anyone got hw docs? 2180 */ 2181 if (sc->sc_flags & UBS_FLAGS_KEY) 2182 ctrl |= BS_CTRL_MCR2INT; 2183 else 2184 ctrl &= ~BS_CTRL_MCR2INT; 2185 2186 if (sc->sc_flags & UBS_FLAGS_HWNORM) 2187 ctrl &= ~BS_CTRL_SWNORM; 2188 2189 if (sc->sc_flags & UBS_FLAGS_MULTIMCR) { 2190 ctrl |= BS_CTRL_BSIZE240; 2191 ctrl &= ~BS_CTRL_MCR3INT; /* MCR3 is reserved for SSL */ 2192 2193 if (sc->sc_flags & UBS_FLAGS_RNG4) 2194 ctrl |= BS_CTRL_MCR4INT; 2195 else 2196 ctrl &= ~BS_CTRL_MCR4INT; 2197 } 2198 2199 WRITE_REG(sc, BS_CTRL, ctrl); 2200 } 2201 2202 /* 2203 * Init Broadcom PCI registers 2204 */ 2205 static void 2206 ubsec_init_pciregs(struct pci_attach_args *pa) 2207 { 2208 pci_chipset_tag_t pc = pa->pa_pc; 2209 u_int32_t misc; 2210 2211 /* 2212 * This will set the cache line size to 1, this will 2213 * force the BCM58xx chip just to do burst read/writes. 2214 * Cache line read/writes are to slow 2215 */ 2216 misc = pci_conf_read(pc, pa->pa_tag, PCI_BHLC_REG); 2217 misc = (misc & ~(PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT)) 2218 | ((UBS_DEF_CACHELINE & 0xff) << PCI_CACHELINE_SHIFT); 2219 pci_conf_write(pc, pa->pa_tag, PCI_BHLC_REG, misc); 2220 } 2221 2222 /* 2223 * Clean up after a chip crash. 2224 * It is assumed that the caller in splnet() 2225 */ 2226 static void 2227 ubsec_cleanchip(struct ubsec_softc *sc) 2228 { 2229 struct ubsec_q *q; 2230 2231 while (!SIMPLEQ_EMPTY(&sc->sc_qchip)) { 2232 q = SIMPLEQ_FIRST(&sc->sc_qchip); 2233 SIMPLEQ_REMOVE_HEAD(&sc->sc_qchip, /*q,*/ q_next); 2234 ubsec_free_q(sc, q); 2235 } 2236 sc->sc_nqchip = 0; 2237 } 2238 2239 /* 2240 * free a ubsec_q 2241 * It is assumed that the caller is within splnet() 2242 */ 2243 static int 2244 ubsec_free_q(struct ubsec_softc *sc, struct ubsec_q *q) 2245 { 2246 struct ubsec_q *q2; 2247 struct cryptop *crp; 2248 int npkts; 2249 int i; 2250 2251 npkts = q->q_nstacked_mcrs; 2252 2253 for (i = 0; i < npkts; i++) { 2254 if(q->q_stacked_mcr[i]) { 2255 q2 = q->q_stacked_mcr[i]; 2256 2257 if ((q2->q_dst_m != NULL) && (q2->q_src_m != q2->q_dst_m)) 2258 m_freem(q2->q_dst_m); 2259 2260 crp = (struct cryptop *)q2->q_crp; 2261 2262 SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q2, q_next); 2263 2264 crp->crp_etype = EFAULT; 2265 crypto_done(crp); 2266 } else { 2267 break; 2268 } 2269 } 2270 2271 /* 2272 * Free header MCR 2273 */ 2274 if ((q->q_dst_m != NULL) && (q->q_src_m != q->q_dst_m)) 2275 m_freem(q->q_dst_m); 2276 2277 crp = (struct cryptop *)q->q_crp; 2278 2279 SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q, q_next); 2280 2281 crp->crp_etype = EFAULT; 2282 crypto_done(crp); 2283 return(0); 2284 } 2285 2286 /* 2287 * Routine to reset the chip and clean up. 2288 * It is assumed that the caller is in splnet() 2289 */ 2290 static void 2291 ubsec_totalreset(struct ubsec_softc *sc) 2292 { 2293 ubsec_reset_board(sc); 2294 ubsec_init_board(sc); 2295 ubsec_cleanchip(sc); 2296 } 2297 2298 static int 2299 ubsec_dmamap_aligned(bus_dmamap_t map) 2300 { 2301 int i; 2302 2303 for (i = 0; i < map->dm_nsegs; i++) { 2304 if (map->dm_segs[i].ds_addr & 3) 2305 return (0); 2306 if ((i != (map->dm_nsegs - 1)) && 2307 (map->dm_segs[i].ds_len & 3)) 2308 return (0); 2309 } 2310 return (1); 2311 } 2312 2313 #ifdef __OpenBSD__ 2314 struct ubsec_softc * 2315 ubsec_kfind(struct cryptkop *krp) 2316 { 2317 struct ubsec_softc *sc; 2318 int i; 2319 2320 for (i = 0; i < ubsec_cd.cd_ndevs; i++) { 2321 sc = ubsec_cd.cd_devs[i]; 2322 if (sc == NULL) 2323 continue; 2324 if (sc->sc_cid == krp->krp_hid) 2325 return (sc); 2326 } 2327 return (NULL); 2328 } 2329 #endif 2330 2331 static void 2332 ubsec_kfree(struct ubsec_softc *sc, struct ubsec_q2 *q) 2333 { 2334 switch (q->q_type) { 2335 case UBS_CTXOP_MODEXP: { 2336 struct ubsec_q2_modexp *me = (struct ubsec_q2_modexp *)q; 2337 2338 ubsec_dma_free(sc, &me->me_q.q_mcr); 2339 ubsec_dma_free(sc, &me->me_q.q_ctx); 2340 ubsec_dma_free(sc, &me->me_M); 2341 ubsec_dma_free(sc, &me->me_E); 2342 ubsec_dma_free(sc, &me->me_C); 2343 ubsec_dma_free(sc, &me->me_epb); 2344 free(me, M_DEVBUF); 2345 break; 2346 } 2347 case UBS_CTXOP_RSAPRIV: { 2348 struct ubsec_q2_rsapriv *rp = (struct ubsec_q2_rsapriv *)q; 2349 2350 ubsec_dma_free(sc, &rp->rpr_q.q_mcr); 2351 ubsec_dma_free(sc, &rp->rpr_q.q_ctx); 2352 ubsec_dma_free(sc, &rp->rpr_msgin); 2353 ubsec_dma_free(sc, &rp->rpr_msgout); 2354 free(rp, M_DEVBUF); 2355 break; 2356 } 2357 default: 2358 printf("%s: invalid kfree 0x%x\n", device_xname(sc->sc_dev), 2359 q->q_type); 2360 break; 2361 } 2362 } 2363 2364 static int 2365 ubsec_kprocess(void *arg, struct cryptkop *krp, int hint) 2366 { 2367 struct ubsec_softc *sc; 2368 int r; 2369 2370 if (krp == NULL || krp->krp_callback == NULL) 2371 return (EINVAL); 2372 #ifdef __OpenBSD__ 2373 if ((sc = ubsec_kfind(krp)) == NULL) 2374 return (EINVAL); 2375 #else 2376 sc = arg; 2377 KASSERT(sc != NULL /*, ("ubsec_kprocess: null softc")*/); 2378 #endif 2379 2380 while (!SIMPLEQ_EMPTY(&sc->sc_q2free)) { 2381 struct ubsec_q2 *q; 2382 2383 q = SIMPLEQ_FIRST(&sc->sc_q2free); 2384 SIMPLEQ_REMOVE_HEAD(&sc->sc_q2free, /*q,*/ q_next); 2385 ubsec_kfree(sc, q); 2386 } 2387 2388 switch (krp->krp_op) { 2389 case CRK_MOD_EXP: 2390 if (sc->sc_flags & UBS_FLAGS_HWNORM) 2391 r = ubsec_kprocess_modexp_hw(sc, krp, hint); 2392 else 2393 r = ubsec_kprocess_modexp_sw(sc, krp, hint); 2394 break; 2395 case CRK_MOD_EXP_CRT: 2396 r = ubsec_kprocess_rsapriv(sc, krp, hint); 2397 break; 2398 default: 2399 printf("%s: kprocess: invalid op 0x%x\n", 2400 device_xname(sc->sc_dev), krp->krp_op); 2401 krp->krp_status = EOPNOTSUPP; 2402 crypto_kdone(krp); 2403 r = 0; 2404 } 2405 return (r); 2406 } 2407 2408 /* 2409 * Start computation of cr[C] = (cr[M] ^ cr[E]) mod cr[N] (sw normalization) 2410 */ 2411 static int 2412 ubsec_kprocess_modexp_sw(struct ubsec_softc *sc, struct cryptkop *krp, 2413 int hint) 2414 { 2415 struct ubsec_q2_modexp *me; 2416 struct ubsec_mcr *mcr; 2417 struct ubsec_ctx_modexp *ctx; 2418 struct ubsec_pktbuf *epb; 2419 int err = 0; 2420 u_int nbits, normbits, mbits, shiftbits, ebits; 2421 2422 me = (struct ubsec_q2_modexp *)malloc(sizeof *me, M_DEVBUF, M_NOWAIT); 2423 if (me == NULL) { 2424 err = ENOMEM; 2425 goto errout; 2426 } 2427 memset(me, 0, sizeof *me); 2428 me->me_krp = krp; 2429 me->me_q.q_type = UBS_CTXOP_MODEXP; 2430 2431 nbits = ubsec_ksigbits(&krp->krp_param[UBS_MODEXP_PAR_N]); 2432 if (nbits <= 512) 2433 normbits = 512; 2434 else if (nbits <= 768) 2435 normbits = 768; 2436 else if (nbits <= 1024) 2437 normbits = 1024; 2438 else if (sc->sc_flags & UBS_FLAGS_BIGKEY && nbits <= 1536) 2439 normbits = 1536; 2440 else if (sc->sc_flags & UBS_FLAGS_BIGKEY && nbits <= 2048) 2441 normbits = 2048; 2442 else { 2443 err = E2BIG; 2444 goto errout; 2445 } 2446 2447 shiftbits = normbits - nbits; 2448 2449 me->me_modbits = nbits; 2450 me->me_shiftbits = shiftbits; 2451 me->me_normbits = normbits; 2452 2453 /* Sanity check: result bits must be >= true modulus bits. */ 2454 if (krp->krp_param[krp->krp_iparams].crp_nbits < nbits) { 2455 err = ERANGE; 2456 goto errout; 2457 } 2458 2459 if (ubsec_dma_malloc(sc, sizeof(struct ubsec_mcr), 2460 &me->me_q.q_mcr, 0)) { 2461 err = ENOMEM; 2462 goto errout; 2463 } 2464 mcr = (struct ubsec_mcr *)me->me_q.q_mcr.dma_vaddr; 2465 2466 if (ubsec_dma_malloc(sc, sizeof(struct ubsec_ctx_modexp), 2467 &me->me_q.q_ctx, 0)) { 2468 err = ENOMEM; 2469 goto errout; 2470 } 2471 2472 mbits = ubsec_ksigbits(&krp->krp_param[UBS_MODEXP_PAR_M]); 2473 if (mbits > nbits) { 2474 err = E2BIG; 2475 goto errout; 2476 } 2477 if (ubsec_dma_malloc(sc, normbits / 8, &me->me_M, 0)) { 2478 err = ENOMEM; 2479 goto errout; 2480 } 2481 ubsec_kshift_r(shiftbits, 2482 krp->krp_param[UBS_MODEXP_PAR_M].crp_p, mbits, 2483 me->me_M.dma_vaddr, normbits); 2484 2485 if (ubsec_dma_malloc(sc, normbits / 8, &me->me_C, 0)) { 2486 err = ENOMEM; 2487 goto errout; 2488 } 2489 memset(me->me_C.dma_vaddr, 0, me->me_C.dma_size); 2490 2491 ebits = ubsec_ksigbits(&krp->krp_param[UBS_MODEXP_PAR_E]); 2492 if (ebits > nbits) { 2493 err = E2BIG; 2494 goto errout; 2495 } 2496 if (ubsec_dma_malloc(sc, normbits / 8, &me->me_E, 0)) { 2497 err = ENOMEM; 2498 goto errout; 2499 } 2500 ubsec_kshift_r(shiftbits, 2501 krp->krp_param[UBS_MODEXP_PAR_E].crp_p, ebits, 2502 me->me_E.dma_vaddr, normbits); 2503 2504 if (ubsec_dma_malloc(sc, sizeof(struct ubsec_pktbuf), 2505 &me->me_epb, 0)) { 2506 err = ENOMEM; 2507 goto errout; 2508 } 2509 epb = (struct ubsec_pktbuf *)me->me_epb.dma_vaddr; 2510 epb->pb_addr = htole32(me->me_E.dma_paddr); 2511 epb->pb_next = 0; 2512 epb->pb_len = htole32(normbits / 8); 2513 2514 #ifdef UBSEC_DEBUG 2515 if (ubsec_debug) { 2516 printf("Epb "); 2517 ubsec_dump_pb(epb); 2518 } 2519 #endif 2520 2521 mcr->mcr_pkts = htole16(1); 2522 mcr->mcr_flags = 0; 2523 mcr->mcr_cmdctxp = htole32(me->me_q.q_ctx.dma_paddr); 2524 mcr->mcr_reserved = 0; 2525 mcr->mcr_pktlen = 0; 2526 2527 mcr->mcr_ipktbuf.pb_addr = htole32(me->me_M.dma_paddr); 2528 mcr->mcr_ipktbuf.pb_len = htole32(normbits / 8); 2529 mcr->mcr_ipktbuf.pb_next = htole32(me->me_epb.dma_paddr); 2530 2531 mcr->mcr_opktbuf.pb_addr = htole32(me->me_C.dma_paddr); 2532 mcr->mcr_opktbuf.pb_next = 0; 2533 mcr->mcr_opktbuf.pb_len = htole32(normbits / 8); 2534 2535 #ifdef DIAGNOSTIC 2536 /* Misaligned output buffer will hang the chip. */ 2537 if ((letoh32(mcr->mcr_opktbuf.pb_addr) & 3) != 0) 2538 panic("%s: modexp invalid addr 0x%x", 2539 device_xname(sc->sc_dev), letoh32(mcr->mcr_opktbuf.pb_addr)); 2540 if ((letoh32(mcr->mcr_opktbuf.pb_len) & 3) != 0) 2541 panic("%s: modexp invalid len 0x%x", 2542 device_xname(sc->sc_dev), letoh32(mcr->mcr_opktbuf.pb_len)); 2543 #endif 2544 2545 ctx = (struct ubsec_ctx_modexp *)me->me_q.q_ctx.dma_vaddr; 2546 memset(ctx, 0, sizeof(*ctx)); 2547 ubsec_kshift_r(shiftbits, 2548 krp->krp_param[UBS_MODEXP_PAR_N].crp_p, nbits, 2549 ctx->me_N, normbits); 2550 ctx->me_len = htole16((normbits / 8) + (4 * sizeof(u_int16_t))); 2551 ctx->me_op = htole16(UBS_CTXOP_MODEXP); 2552 ctx->me_E_len = htole16(nbits); 2553 ctx->me_N_len = htole16(nbits); 2554 2555 #ifdef UBSEC_DEBUG 2556 if (ubsec_debug) { 2557 ubsec_dump_mcr(mcr); 2558 ubsec_dump_ctx2((struct ubsec_ctx_keyop *)ctx); 2559 } 2560 #endif 2561 2562 /* 2563 * ubsec_feed2 will sync mcr and ctx, we just need to sync 2564 * everything else. 2565 */ 2566 bus_dmamap_sync(sc->sc_dmat, me->me_M.dma_map, 2567 0, me->me_M.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 2568 bus_dmamap_sync(sc->sc_dmat, me->me_E.dma_map, 2569 0, me->me_E.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 2570 bus_dmamap_sync(sc->sc_dmat, me->me_C.dma_map, 2571 0, me->me_C.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD); 2572 bus_dmamap_sync(sc->sc_dmat, me->me_epb.dma_map, 2573 0, me->me_epb.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 2574 2575 /* Enqueue and we're done... */ 2576 mutex_spin_enter(&sc->sc_mtx); 2577 SIMPLEQ_INSERT_TAIL(&sc->sc_queue2, &me->me_q, q_next); 2578 ubsec_feed2(sc); 2579 ubsecstats.hst_modexp++; 2580 mutex_spin_exit(&sc->sc_mtx); 2581 2582 return (0); 2583 2584 errout: 2585 if (me != NULL) { 2586 if (me->me_q.q_mcr.dma_map != NULL) 2587 ubsec_dma_free(sc, &me->me_q.q_mcr); 2588 if (me->me_q.q_ctx.dma_map != NULL) { 2589 memset(me->me_q.q_ctx.dma_vaddr, 0, me->me_q.q_ctx.dma_size); 2590 ubsec_dma_free(sc, &me->me_q.q_ctx); 2591 } 2592 if (me->me_M.dma_map != NULL) { 2593 memset(me->me_M.dma_vaddr, 0, me->me_M.dma_size); 2594 ubsec_dma_free(sc, &me->me_M); 2595 } 2596 if (me->me_E.dma_map != NULL) { 2597 memset(me->me_E.dma_vaddr, 0, me->me_E.dma_size); 2598 ubsec_dma_free(sc, &me->me_E); 2599 } 2600 if (me->me_C.dma_map != NULL) { 2601 memset(me->me_C.dma_vaddr, 0, me->me_C.dma_size); 2602 ubsec_dma_free(sc, &me->me_C); 2603 } 2604 if (me->me_epb.dma_map != NULL) 2605 ubsec_dma_free(sc, &me->me_epb); 2606 free(me, M_DEVBUF); 2607 } 2608 krp->krp_status = err; 2609 crypto_kdone(krp); 2610 return (0); 2611 } 2612 2613 /* 2614 * Start computation of cr[C] = (cr[M] ^ cr[E]) mod cr[N] (hw normalization) 2615 */ 2616 static int 2617 ubsec_kprocess_modexp_hw(struct ubsec_softc *sc, struct cryptkop *krp, 2618 int hint) 2619 { 2620 struct ubsec_q2_modexp *me; 2621 struct ubsec_mcr *mcr; 2622 struct ubsec_ctx_modexp *ctx; 2623 struct ubsec_pktbuf *epb; 2624 int err = 0; 2625 u_int nbits, normbits, mbits, shiftbits, ebits; 2626 2627 me = (struct ubsec_q2_modexp *)malloc(sizeof *me, M_DEVBUF, M_NOWAIT); 2628 if (me == NULL) { 2629 err = ENOMEM; 2630 goto errout; 2631 } 2632 memset(me, 0, sizeof *me); 2633 me->me_krp = krp; 2634 me->me_q.q_type = UBS_CTXOP_MODEXP; 2635 2636 nbits = ubsec_ksigbits(&krp->krp_param[UBS_MODEXP_PAR_N]); 2637 if (nbits <= 512) 2638 normbits = 512; 2639 else if (nbits <= 768) 2640 normbits = 768; 2641 else if (nbits <= 1024) 2642 normbits = 1024; 2643 else if (sc->sc_flags & UBS_FLAGS_BIGKEY && nbits <= 1536) 2644 normbits = 1536; 2645 else if (sc->sc_flags & UBS_FLAGS_BIGKEY && nbits <= 2048) 2646 normbits = 2048; 2647 else { 2648 err = E2BIG; 2649 goto errout; 2650 } 2651 2652 shiftbits = normbits - nbits; 2653 2654 /* XXX ??? */ 2655 me->me_modbits = nbits; 2656 me->me_shiftbits = shiftbits; 2657 me->me_normbits = normbits; 2658 2659 /* Sanity check: result bits must be >= true modulus bits. */ 2660 if (krp->krp_param[krp->krp_iparams].crp_nbits < nbits) { 2661 err = ERANGE; 2662 goto errout; 2663 } 2664 2665 if (ubsec_dma_malloc(sc, sizeof(struct ubsec_mcr), 2666 &me->me_q.q_mcr, 0)) { 2667 err = ENOMEM; 2668 goto errout; 2669 } 2670 mcr = (struct ubsec_mcr *)me->me_q.q_mcr.dma_vaddr; 2671 2672 if (ubsec_dma_malloc(sc, sizeof(struct ubsec_ctx_modexp), 2673 &me->me_q.q_ctx, 0)) { 2674 err = ENOMEM; 2675 goto errout; 2676 } 2677 2678 mbits = ubsec_ksigbits(&krp->krp_param[UBS_MODEXP_PAR_M]); 2679 if (mbits > nbits) { 2680 err = E2BIG; 2681 goto errout; 2682 } 2683 if (ubsec_dma_malloc(sc, normbits / 8, &me->me_M, 0)) { 2684 err = ENOMEM; 2685 goto errout; 2686 } 2687 memset(me->me_M.dma_vaddr, 0, normbits / 8); 2688 bcopy(krp->krp_param[UBS_MODEXP_PAR_M].crp_p, 2689 me->me_M.dma_vaddr, (mbits + 7) / 8); 2690 2691 if (ubsec_dma_malloc(sc, normbits / 8, &me->me_C, 0)) { 2692 err = ENOMEM; 2693 goto errout; 2694 } 2695 memset(me->me_C.dma_vaddr, 0, me->me_C.dma_size); 2696 2697 ebits = ubsec_ksigbits(&krp->krp_param[UBS_MODEXP_PAR_E]); 2698 if (ebits > nbits) { 2699 err = E2BIG; 2700 goto errout; 2701 } 2702 if (ubsec_dma_malloc(sc, normbits / 8, &me->me_E, 0)) { 2703 err = ENOMEM; 2704 goto errout; 2705 } 2706 memset(me->me_E.dma_vaddr, 0, normbits / 8); 2707 bcopy(krp->krp_param[UBS_MODEXP_PAR_E].crp_p, 2708 me->me_E.dma_vaddr, (ebits + 7) / 8); 2709 2710 if (ubsec_dma_malloc(sc, sizeof(struct ubsec_pktbuf), 2711 &me->me_epb, 0)) { 2712 err = ENOMEM; 2713 goto errout; 2714 } 2715 epb = (struct ubsec_pktbuf *)me->me_epb.dma_vaddr; 2716 epb->pb_addr = htole32(me->me_E.dma_paddr); 2717 epb->pb_next = 0; 2718 epb->pb_len = htole32((ebits + 7) / 8); 2719 2720 #ifdef UBSEC_DEBUG 2721 if (ubsec_debug) { 2722 printf("Epb "); 2723 ubsec_dump_pb(epb); 2724 } 2725 #endif 2726 2727 mcr->mcr_pkts = htole16(1); 2728 mcr->mcr_flags = 0; 2729 mcr->mcr_cmdctxp = htole32(me->me_q.q_ctx.dma_paddr); 2730 mcr->mcr_reserved = 0; 2731 mcr->mcr_pktlen = 0; 2732 2733 mcr->mcr_ipktbuf.pb_addr = htole32(me->me_M.dma_paddr); 2734 mcr->mcr_ipktbuf.pb_len = htole32(normbits / 8); 2735 mcr->mcr_ipktbuf.pb_next = htole32(me->me_epb.dma_paddr); 2736 2737 mcr->mcr_opktbuf.pb_addr = htole32(me->me_C.dma_paddr); 2738 mcr->mcr_opktbuf.pb_next = 0; 2739 mcr->mcr_opktbuf.pb_len = htole32(normbits / 8); 2740 2741 #ifdef DIAGNOSTIC 2742 /* Misaligned output buffer will hang the chip. */ 2743 if ((letoh32(mcr->mcr_opktbuf.pb_addr) & 3) != 0) 2744 panic("%s: modexp invalid addr 0x%x", 2745 device_xname(sc->sc_dev), letoh32(mcr->mcr_opktbuf.pb_addr)); 2746 if ((letoh32(mcr->mcr_opktbuf.pb_len) & 3) != 0) 2747 panic("%s: modexp invalid len 0x%x", 2748 device_xname(sc->sc_dev), letoh32(mcr->mcr_opktbuf.pb_len)); 2749 #endif 2750 2751 ctx = (struct ubsec_ctx_modexp *)me->me_q.q_ctx.dma_vaddr; 2752 memset(ctx, 0, sizeof(*ctx)); 2753 memcpy(ctx->me_N, krp->krp_param[UBS_MODEXP_PAR_N].crp_p, 2754 (nbits + 7) / 8); 2755 ctx->me_len = htole16((normbits / 8) + (4 * sizeof(u_int16_t))); 2756 ctx->me_op = htole16(UBS_CTXOP_MODEXP); 2757 ctx->me_E_len = htole16(ebits); 2758 ctx->me_N_len = htole16(nbits); 2759 2760 #ifdef UBSEC_DEBUG 2761 if (ubsec_debug) { 2762 ubsec_dump_mcr(mcr); 2763 ubsec_dump_ctx2((struct ubsec_ctx_keyop *)ctx); 2764 } 2765 #endif 2766 2767 /* 2768 * ubsec_feed2 will sync mcr and ctx, we just need to sync 2769 * everything else. 2770 */ 2771 bus_dmamap_sync(sc->sc_dmat, me->me_M.dma_map, 2772 0, me->me_M.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 2773 bus_dmamap_sync(sc->sc_dmat, me->me_E.dma_map, 2774 0, me->me_E.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 2775 bus_dmamap_sync(sc->sc_dmat, me->me_C.dma_map, 2776 0, me->me_C.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD); 2777 bus_dmamap_sync(sc->sc_dmat, me->me_epb.dma_map, 2778 0, me->me_epb.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 2779 2780 /* Enqueue and we're done... */ 2781 mutex_spin_enter(&sc->sc_mtx); 2782 SIMPLEQ_INSERT_TAIL(&sc->sc_queue2, &me->me_q, q_next); 2783 ubsec_feed2(sc); 2784 mutex_spin_exit(&sc->sc_mtx); 2785 2786 return (0); 2787 2788 errout: 2789 if (me != NULL) { 2790 if (me->me_q.q_mcr.dma_map != NULL) 2791 ubsec_dma_free(sc, &me->me_q.q_mcr); 2792 if (me->me_q.q_ctx.dma_map != NULL) { 2793 memset(me->me_q.q_ctx.dma_vaddr, 0, me->me_q.q_ctx.dma_size); 2794 ubsec_dma_free(sc, &me->me_q.q_ctx); 2795 } 2796 if (me->me_M.dma_map != NULL) { 2797 memset(me->me_M.dma_vaddr, 0, me->me_M.dma_size); 2798 ubsec_dma_free(sc, &me->me_M); 2799 } 2800 if (me->me_E.dma_map != NULL) { 2801 memset(me->me_E.dma_vaddr, 0, me->me_E.dma_size); 2802 ubsec_dma_free(sc, &me->me_E); 2803 } 2804 if (me->me_C.dma_map != NULL) { 2805 memset(me->me_C.dma_vaddr, 0, me->me_C.dma_size); 2806 ubsec_dma_free(sc, &me->me_C); 2807 } 2808 if (me->me_epb.dma_map != NULL) 2809 ubsec_dma_free(sc, &me->me_epb); 2810 free(me, M_DEVBUF); 2811 } 2812 krp->krp_status = err; 2813 crypto_kdone(krp); 2814 return (0); 2815 } 2816 2817 static int 2818 ubsec_kprocess_rsapriv(struct ubsec_softc *sc, struct cryptkop *krp, 2819 int hint) 2820 { 2821 struct ubsec_q2_rsapriv *rp = NULL; 2822 struct ubsec_mcr *mcr; 2823 struct ubsec_ctx_rsapriv *ctx; 2824 int err = 0; 2825 u_int padlen, msglen; 2826 2827 msglen = ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_P]); 2828 padlen = ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_Q]); 2829 if (msglen > padlen) 2830 padlen = msglen; 2831 2832 if (padlen <= 256) 2833 padlen = 256; 2834 else if (padlen <= 384) 2835 padlen = 384; 2836 else if (padlen <= 512) 2837 padlen = 512; 2838 else if (sc->sc_flags & UBS_FLAGS_BIGKEY && padlen <= 768) 2839 padlen = 768; 2840 else if (sc->sc_flags & UBS_FLAGS_BIGKEY && padlen <= 1024) 2841 padlen = 1024; 2842 else { 2843 err = E2BIG; 2844 goto errout; 2845 } 2846 2847 if (ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_DP]) > padlen) { 2848 err = E2BIG; 2849 goto errout; 2850 } 2851 2852 if (ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_DQ]) > padlen) { 2853 err = E2BIG; 2854 goto errout; 2855 } 2856 2857 if (ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_PINV]) > padlen) { 2858 err = E2BIG; 2859 goto errout; 2860 } 2861 2862 rp = malloc(sizeof *rp, M_DEVBUF, M_NOWAIT|M_ZERO); 2863 if (rp == NULL) 2864 return (ENOMEM); 2865 rp->rpr_krp = krp; 2866 rp->rpr_q.q_type = UBS_CTXOP_RSAPRIV; 2867 2868 if (ubsec_dma_malloc(sc, sizeof(struct ubsec_mcr), 2869 &rp->rpr_q.q_mcr, 0)) { 2870 err = ENOMEM; 2871 goto errout; 2872 } 2873 mcr = (struct ubsec_mcr *)rp->rpr_q.q_mcr.dma_vaddr; 2874 2875 if (ubsec_dma_malloc(sc, sizeof(struct ubsec_ctx_rsapriv), 2876 &rp->rpr_q.q_ctx, 0)) { 2877 err = ENOMEM; 2878 goto errout; 2879 } 2880 ctx = (struct ubsec_ctx_rsapriv *)rp->rpr_q.q_ctx.dma_vaddr; 2881 memset(ctx, 0, sizeof *ctx); 2882 2883 /* Copy in p */ 2884 bcopy(krp->krp_param[UBS_RSAPRIV_PAR_P].crp_p, 2885 &ctx->rpr_buf[0 * (padlen / 8)], 2886 (krp->krp_param[UBS_RSAPRIV_PAR_P].crp_nbits + 7) / 8); 2887 2888 /* Copy in q */ 2889 bcopy(krp->krp_param[UBS_RSAPRIV_PAR_Q].crp_p, 2890 &ctx->rpr_buf[1 * (padlen / 8)], 2891 (krp->krp_param[UBS_RSAPRIV_PAR_Q].crp_nbits + 7) / 8); 2892 2893 /* Copy in dp */ 2894 bcopy(krp->krp_param[UBS_RSAPRIV_PAR_DP].crp_p, 2895 &ctx->rpr_buf[2 * (padlen / 8)], 2896 (krp->krp_param[UBS_RSAPRIV_PAR_DP].crp_nbits + 7) / 8); 2897 2898 /* Copy in dq */ 2899 bcopy(krp->krp_param[UBS_RSAPRIV_PAR_DQ].crp_p, 2900 &ctx->rpr_buf[3 * (padlen / 8)], 2901 (krp->krp_param[UBS_RSAPRIV_PAR_DQ].crp_nbits + 7) / 8); 2902 2903 /* Copy in pinv */ 2904 bcopy(krp->krp_param[UBS_RSAPRIV_PAR_PINV].crp_p, 2905 &ctx->rpr_buf[4 * (padlen / 8)], 2906 (krp->krp_param[UBS_RSAPRIV_PAR_PINV].crp_nbits + 7) / 8); 2907 2908 msglen = padlen * 2; 2909 2910 /* Copy in input message (aligned buffer/length). */ 2911 if (ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_MSGIN]) > msglen) { 2912 /* Is this likely? */ 2913 err = E2BIG; 2914 goto errout; 2915 } 2916 if (ubsec_dma_malloc(sc, (msglen + 7) / 8, &rp->rpr_msgin, 0)) { 2917 err = ENOMEM; 2918 goto errout; 2919 } 2920 memset(rp->rpr_msgin.dma_vaddr, 0, (msglen + 7) / 8); 2921 bcopy(krp->krp_param[UBS_RSAPRIV_PAR_MSGIN].crp_p, 2922 rp->rpr_msgin.dma_vaddr, 2923 (krp->krp_param[UBS_RSAPRIV_PAR_MSGIN].crp_nbits + 7) / 8); 2924 2925 /* Prepare space for output message (aligned buffer/length). */ 2926 if (ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_MSGOUT]) < msglen) { 2927 /* Is this likely? */ 2928 err = E2BIG; 2929 goto errout; 2930 } 2931 if (ubsec_dma_malloc(sc, (msglen + 7) / 8, &rp->rpr_msgout, 0)) { 2932 err = ENOMEM; 2933 goto errout; 2934 } 2935 memset(rp->rpr_msgout.dma_vaddr, 0, (msglen + 7) / 8); 2936 2937 mcr->mcr_pkts = htole16(1); 2938 mcr->mcr_flags = 0; 2939 mcr->mcr_cmdctxp = htole32(rp->rpr_q.q_ctx.dma_paddr); 2940 mcr->mcr_ipktbuf.pb_addr = htole32(rp->rpr_msgin.dma_paddr); 2941 mcr->mcr_ipktbuf.pb_next = 0; 2942 mcr->mcr_ipktbuf.pb_len = htole32(rp->rpr_msgin.dma_size); 2943 mcr->mcr_reserved = 0; 2944 mcr->mcr_pktlen = htole16(msglen); 2945 mcr->mcr_opktbuf.pb_addr = htole32(rp->rpr_msgout.dma_paddr); 2946 mcr->mcr_opktbuf.pb_next = 0; 2947 mcr->mcr_opktbuf.pb_len = htole32(rp->rpr_msgout.dma_size); 2948 2949 #ifdef DIAGNOSTIC 2950 if (rp->rpr_msgin.dma_paddr & 3 || rp->rpr_msgin.dma_size & 3) { 2951 panic("%s: rsapriv: invalid msgin 0x%lx(0x%lx)", 2952 device_xname(sc->sc_dev), (u_long) rp->rpr_msgin.dma_paddr, 2953 (u_long) rp->rpr_msgin.dma_size); 2954 } 2955 if (rp->rpr_msgout.dma_paddr & 3 || rp->rpr_msgout.dma_size & 3) { 2956 panic("%s: rsapriv: invalid msgout 0x%lx(0x%lx)", 2957 device_xname(sc->sc_dev), (u_long) rp->rpr_msgout.dma_paddr, 2958 (u_long) rp->rpr_msgout.dma_size); 2959 } 2960 #endif 2961 2962 ctx->rpr_len = (sizeof(u_int16_t) * 4) + (5 * (padlen / 8)); 2963 ctx->rpr_op = htole16(UBS_CTXOP_RSAPRIV); 2964 ctx->rpr_q_len = htole16(padlen); 2965 ctx->rpr_p_len = htole16(padlen); 2966 2967 /* 2968 * ubsec_feed2 will sync mcr and ctx, we just need to sync 2969 * everything else. 2970 */ 2971 bus_dmamap_sync(sc->sc_dmat, rp->rpr_msgin.dma_map, 2972 0, rp->rpr_msgin.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 2973 bus_dmamap_sync(sc->sc_dmat, rp->rpr_msgout.dma_map, 2974 0, rp->rpr_msgout.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD); 2975 2976 /* Enqueue and we're done... */ 2977 mutex_spin_enter(&sc->sc_mtx); 2978 SIMPLEQ_INSERT_TAIL(&sc->sc_queue2, &rp->rpr_q, q_next); 2979 ubsec_feed2(sc); 2980 ubsecstats.hst_modexpcrt++; 2981 mutex_spin_exit(&sc->sc_mtx); 2982 return (0); 2983 2984 errout: 2985 if (rp != NULL) { 2986 if (rp->rpr_q.q_mcr.dma_map != NULL) 2987 ubsec_dma_free(sc, &rp->rpr_q.q_mcr); 2988 if (rp->rpr_msgin.dma_map != NULL) { 2989 memset(rp->rpr_msgin.dma_vaddr, 0, rp->rpr_msgin.dma_size); 2990 ubsec_dma_free(sc, &rp->rpr_msgin); 2991 } 2992 if (rp->rpr_msgout.dma_map != NULL) { 2993 memset(rp->rpr_msgout.dma_vaddr, 0, rp->rpr_msgout.dma_size); 2994 ubsec_dma_free(sc, &rp->rpr_msgout); 2995 } 2996 free(rp, M_DEVBUF); 2997 } 2998 krp->krp_status = err; 2999 crypto_kdone(krp); 3000 return (0); 3001 } 3002 3003 #ifdef UBSEC_DEBUG 3004 static void 3005 ubsec_dump_pb(volatile struct ubsec_pktbuf *pb) 3006 { 3007 printf("addr 0x%x (0x%x) next 0x%x\n", 3008 pb->pb_addr, pb->pb_len, pb->pb_next); 3009 } 3010 3011 static void 3012 ubsec_dump_ctx2(volatile struct ubsec_ctx_keyop *c) 3013 { 3014 printf("CTX (0x%x):\n", c->ctx_len); 3015 switch (letoh16(c->ctx_op)) { 3016 case UBS_CTXOP_RNGBYPASS: 3017 case UBS_CTXOP_RNGSHA1: 3018 break; 3019 case UBS_CTXOP_MODEXP: 3020 { 3021 struct ubsec_ctx_modexp *cx = (void *)c; 3022 int i, len; 3023 3024 printf(" Elen %u, Nlen %u\n", 3025 letoh16(cx->me_E_len), letoh16(cx->me_N_len)); 3026 len = (cx->me_N_len + 7)/8; 3027 for (i = 0; i < len; i++) 3028 printf("%s%02x", (i == 0) ? " N: " : ":", cx->me_N[i]); 3029 printf("\n"); 3030 break; 3031 } 3032 default: 3033 printf("unknown context: %x\n", c->ctx_op); 3034 } 3035 printf("END CTX\n"); 3036 } 3037 3038 static void 3039 ubsec_dump_mcr(struct ubsec_mcr *mcr) 3040 { 3041 volatile struct ubsec_mcr_add *ma; 3042 int i; 3043 3044 printf("MCR:\n"); 3045 printf(" pkts: %u, flags 0x%x\n", 3046 letoh16(mcr->mcr_pkts), letoh16(mcr->mcr_flags)); 3047 ma = (volatile struct ubsec_mcr_add *)&mcr->mcr_cmdctxp; 3048 for (i = 0; i < letoh16(mcr->mcr_pkts); i++) { 3049 printf(" %d: ctx 0x%x len 0x%x rsvd 0x%x\n", i, 3050 letoh32(ma->mcr_cmdctxp), letoh16(ma->mcr_pktlen), 3051 letoh16(ma->mcr_reserved)); 3052 printf(" %d: ipkt ", i); 3053 ubsec_dump_pb(&ma->mcr_ipktbuf); 3054 printf(" %d: opkt ", i); 3055 ubsec_dump_pb(&ma->mcr_opktbuf); 3056 ma++; 3057 } 3058 printf("END MCR\n"); 3059 } 3060 #endif /* UBSEC_DEBUG */ 3061 3062 /* 3063 * Return the number of significant bits of a big number. 3064 */ 3065 static int 3066 ubsec_ksigbits(struct crparam *cr) 3067 { 3068 u_int plen = (cr->crp_nbits + 7) / 8; 3069 int i, sig = plen * 8; 3070 u_int8_t c, *p = cr->crp_p; 3071 3072 for (i = plen - 1; i >= 0; i--) { 3073 c = p[i]; 3074 if (c != 0) { 3075 while ((c & 0x80) == 0) { 3076 sig--; 3077 c <<= 1; 3078 } 3079 break; 3080 } 3081 sig -= 8; 3082 } 3083 return (sig); 3084 } 3085 3086 static void 3087 ubsec_kshift_r(u_int shiftbits, u_int8_t *src, u_int srcbits, 3088 u_int8_t *dst, u_int dstbits) 3089 { 3090 u_int slen, dlen; 3091 int i, si, di, n; 3092 3093 slen = (srcbits + 7) / 8; 3094 dlen = (dstbits + 7) / 8; 3095 3096 for (i = 0; i < slen; i++) 3097 dst[i] = src[i]; 3098 for (i = 0; i < dlen - slen; i++) 3099 dst[slen + i] = 0; 3100 3101 n = shiftbits / 8; 3102 if (n != 0) { 3103 si = dlen - n - 1; 3104 di = dlen - 1; 3105 while (si >= 0) 3106 dst[di--] = dst[si--]; 3107 while (di >= 0) 3108 dst[di--] = 0; 3109 } 3110 3111 n = shiftbits % 8; 3112 if (n != 0) { 3113 for (i = dlen - 1; i > 0; i--) 3114 dst[i] = (dst[i] << n) | 3115 (dst[i - 1] >> (8 - n)); 3116 dst[0] = dst[0] << n; 3117 } 3118 } 3119 3120 static void 3121 ubsec_kshift_l(u_int shiftbits, u_int8_t *src, u_int srcbits, 3122 u_int8_t *dst, u_int dstbits) 3123 { 3124 int slen, dlen, i, n; 3125 3126 slen = (srcbits + 7) / 8; 3127 dlen = (dstbits + 7) / 8; 3128 3129 n = shiftbits / 8; 3130 for (i = 0; i < slen; i++) 3131 dst[i] = src[i + n]; 3132 for (i = 0; i < dlen - slen; i++) 3133 dst[slen + i] = 0; 3134 3135 n = shiftbits % 8; 3136 if (n != 0) { 3137 for (i = 0; i < (dlen - 1); i++) 3138 dst[i] = (dst[i] >> n) | (dst[i + 1] << (8 - n)); 3139 dst[dlen - 1] = dst[dlen - 1] >> n; 3140 } 3141 } 3142