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