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