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