ubsec.c revision 1.26 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 (at) thought.net)
7 * Copyright (c) 2000 Theo de Raadt (deraadt (at) openbsd.org)
8 * Copyright (c) 2001 Patrik Lindergren (patrik (at) 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 = ⊤
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