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