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