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