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