1 /* $NetBSD: ubsec.c,v 1.23 2009/05/12 08:23:01 cegger 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 $ */
6 * Copyright (c) 2000 Jason L. Wright (jason@thought.net)
7 * Copyright (c) 2000 Theo de Raadt (deraadt@openbsd.org)
8 * Copyright (c) 2001 Patrik Lindergren (patrik@ipunplugged.com)
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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.
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.
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: ubsec.c,v 1.23 2009/05/12 08:23:01 cegger Exp $");
43 * uBsec 5[56]01, bcm580xx, bcm582x hardware crypto accelerator
46 #include <sys/param.h>
47 #include <sys/systm.h>
49 #include <sys/endian.h>
51 #define letoh16 htole16
52 #define letoh32 htole32
53 #define UBSEC_NO_RNG /* until statistically tested */
55 #include <sys/errno.h>
56 #include <sys/malloc.h>
57 #include <sys/kernel.h>
59 #include <sys/device.h>
60 #include <sys/queue.h>
62 #include <uvm/uvm_extern.h>
64 #include <opencrypto/cryptodev.h>
65 #include <opencrypto/xform.h>
67 #include <dev/rndvar.h>
75 #include <dev/pci/pcireg.h>
76 #include <dev/pci/pcivar.h>
77 #include <dev/pci/pcidevs.h>
79 #include <dev/pci/ubsecreg.h>
80 #include <dev/pci/ubsecvar.h>
83 * Prototypes and count for the pci_device structure
85 static int ubsec_probe(device_t
, cfdata_t
, void *);
86 static void ubsec_attach(device_t
, device_t
, void *);
87 static void ubsec_reset_board(struct ubsec_softc
*);
88 static void ubsec_init_board(struct ubsec_softc
*);
89 static void ubsec_init_pciregs(struct pci_attach_args
*pa
);
90 static void ubsec_cleanchip(struct ubsec_softc
*);
91 static void ubsec_totalreset(struct ubsec_softc
*);
92 static int ubsec_free_q(struct ubsec_softc
*, struct ubsec_q
*);
95 struct cfattach ubsec_ca
= {
96 sizeof(struct ubsec_softc
), ubsec_probe
, ubsec_attach
,
99 struct cfdriver ubsec_cd
= {
103 CFATTACH_DECL(ubsec
, sizeof(struct ubsec_softc
), ubsec_probe
, ubsec_attach
,
105 extern struct cfdriver ubsec_cd
;
110 extern int ubsec_debug
;
114 static int ubsec_intr(void *);
115 static int ubsec_newsession(void*, u_int32_t
*, struct cryptoini
*);
116 static int ubsec_freesession(void*, u_int64_t
);
117 static int ubsec_process(void*, struct cryptop
*, int hint
);
118 static void ubsec_callback(struct ubsec_softc
*, struct ubsec_q
*);
119 static void ubsec_feed(struct ubsec_softc
*);
120 static void ubsec_mcopy(struct mbuf
*, struct mbuf
*, int, int);
121 static void ubsec_callback2(struct ubsec_softc
*, struct ubsec_q2
*);
122 static void ubsec_feed2(struct ubsec_softc
*);
124 static void ubsec_rng(void *);
125 #endif /* UBSEC_NO_RNG */
126 static int ubsec_dma_malloc(struct ubsec_softc
*, bus_size_t
,
127 struct ubsec_dma_alloc
*, int);
128 static void ubsec_dma_free(struct ubsec_softc
*, struct ubsec_dma_alloc
*);
129 static int ubsec_dmamap_aligned(bus_dmamap_t
);
131 static int ubsec_kprocess(void*, struct cryptkop
*, int);
132 static int ubsec_kprocess_modexp_sw(struct ubsec_softc
*,
133 struct cryptkop
*, int);
134 static int ubsec_kprocess_modexp_hw(struct ubsec_softc
*,
135 struct cryptkop
*, int);
136 static int ubsec_kprocess_rsapriv(struct ubsec_softc
*,
137 struct cryptkop
*, int);
138 static void ubsec_kfree(struct ubsec_softc
*, struct ubsec_q2
*);
139 static int ubsec_ksigbits(struct crparam
*);
140 static void ubsec_kshift_r(u_int
, u_int8_t
*, u_int
, u_int8_t
*, u_int
);
141 static void ubsec_kshift_l(u_int
, u_int8_t
*, u_int
, u_int8_t
*, u_int
);
144 static void ubsec_dump_pb(volatile struct ubsec_pktbuf
*);
145 static void ubsec_dump_mcr(struct ubsec_mcr
*);
146 static void ubsec_dump_ctx2(volatile struct ubsec_ctx_keyop
*);
149 #define READ_REG(sc,r) \
150 bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (r))
152 #define WRITE_REG(sc,reg,val) \
153 bus_space_write_4((sc)->sc_st, (sc)->sc_sh, reg, val)
155 #define SWAP32(x) (x) = htole32(ntohl((x)))
157 #define HTOLE32(x) (x) = htole32(x)
160 struct ubsec_stats ubsecstats
;
163 * ubsec_maxbatch controls the number of crypto ops to voluntarily
164 * collect into one submission to the hardware. This batching happens
165 * when ops are dispatched from the crypto subsystem with a hint that
166 * more are to follow immediately. These ops must also not be marked
167 * with a ``no delay'' flag.
169 static int ubsec_maxbatch
= 1;
171 SYSCTL_INT(_kern
, OID_AUTO
, ubsec_maxbatch
, CTLFLAG_RW
, &ubsec_maxbatch
,
172 0, "Broadcom driver: max ops to batch w/o interrupt");
176 * ubsec_maxaggr controls the number of crypto ops to submit to the
177 * hardware as a unit. This aggregation reduces the number of interrupts
178 * to the host at the expense of increased latency (for all but the last
179 * operation). For network traffic setting this to one yields the highest
180 * performance but at the expense of more interrupt processing.
182 static int ubsec_maxaggr
= 1;
184 SYSCTL_INT(_kern
, OID_AUTO
, ubsec_maxaggr
, CTLFLAG_RW
, &ubsec_maxaggr
,
185 0, "Broadcom driver: max ops to aggregate under one interrupt");
188 static const struct ubsec_product
{
189 pci_vendor_id_t ubsec_vendor
;
190 pci_product_id_t ubsec_product
;
193 const char *ubsec_name
;
194 } ubsec_products
[] = {
195 { PCI_VENDOR_BLUESTEEL
, PCI_PRODUCT_BLUESTEEL_5501
,
197 BS_STAT_MCR1_DONE
| BS_STAT_DMAERR
,
200 { PCI_VENDOR_BLUESTEEL
, PCI_PRODUCT_BLUESTEEL_5601
,
201 UBS_FLAGS_KEY
| UBS_FLAGS_RNG
,
202 BS_STAT_MCR1_DONE
| BS_STAT_DMAERR
,
206 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_5801
,
208 BS_STAT_MCR1_DONE
| BS_STAT_DMAERR
,
212 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_5802
,
213 UBS_FLAGS_KEY
| UBS_FLAGS_RNG
,
214 BS_STAT_MCR1_DONE
| BS_STAT_DMAERR
,
218 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_5805
,
219 UBS_FLAGS_KEY
| UBS_FLAGS_RNG
,
220 BS_STAT_MCR1_DONE
| BS_STAT_DMAERR
,
224 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_5820
,
225 UBS_FLAGS_KEY
| UBS_FLAGS_RNG
| UBS_FLAGS_LONGCTX
|
226 UBS_FLAGS_HWNORM
| UBS_FLAGS_BIGKEY
,
227 BS_STAT_MCR1_DONE
| BS_STAT_DMAERR
,
231 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_5821
,
232 UBS_FLAGS_KEY
| UBS_FLAGS_RNG
| UBS_FLAGS_LONGCTX
|
233 UBS_FLAGS_HWNORM
| UBS_FLAGS_BIGKEY
,
234 BS_STAT_MCR1_DONE
| BS_STAT_DMAERR
|
235 BS_STAT_MCR1_ALLEMPTY
| BS_STAT_MCR2_ALLEMPTY
,
238 { PCI_VENDOR_SUN
, PCI_PRODUCT_SUN_SCA1K
,
239 UBS_FLAGS_KEY
| UBS_FLAGS_RNG
| UBS_FLAGS_LONGCTX
|
240 UBS_FLAGS_HWNORM
| UBS_FLAGS_BIGKEY
,
241 BS_STAT_MCR1_DONE
| BS_STAT_DMAERR
|
242 BS_STAT_MCR1_ALLEMPTY
| BS_STAT_MCR2_ALLEMPTY
,
243 "Sun Crypto Accelerator 1000"
245 { PCI_VENDOR_SUN
, PCI_PRODUCT_SUN_5821
,
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 "Broadcom BCM5821 (Sun)"
253 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_5822
,
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
,
261 { PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_5823
,
262 UBS_FLAGS_KEY
| UBS_FLAGS_RNG
| UBS_FLAGS_LONGCTX
|
263 UBS_FLAGS_HWNORM
| UBS_FLAGS_BIGKEY
,
264 BS_STAT_MCR1_DONE
| BS_STAT_DMAERR
|
265 BS_STAT_MCR1_ALLEMPTY
| BS_STAT_MCR2_ALLEMPTY
,
276 static const struct ubsec_product
*
277 ubsec_lookup(const struct pci_attach_args
*pa
)
279 const struct ubsec_product
*up
;
281 for (up
= ubsec_products
; up
->ubsec_name
!= NULL
; up
++) {
282 if (PCI_VENDOR(pa
->pa_id
) == up
->ubsec_vendor
&&
283 PCI_PRODUCT(pa
->pa_id
) == up
->ubsec_product
)
290 ubsec_probe(device_t parent
, cfdata_t match
, void *aux
)
292 struct pci_attach_args
*pa
= (struct pci_attach_args
*)aux
;
294 if (ubsec_lookup(pa
) != NULL
)
301 ubsec_attach(device_t parent
, device_t self
, void *aux
)
303 struct ubsec_softc
*sc
= device_private(self
);
304 struct pci_attach_args
*pa
= aux
;
305 const struct ubsec_product
*up
;
306 pci_chipset_tag_t pc
= pa
->pa_pc
;
307 pci_intr_handle_t ih
;
308 const char *intrstr
= NULL
;
309 struct ubsec_dma
*dmap
;
312 up
= ubsec_lookup(pa
);
315 panic("ubsec_attach: impossible");
318 aprint_naive(": Crypto processor\n");
319 aprint_normal(": %s, rev. %d\n", up
->ubsec_name
,
320 PCI_REVISION(pa
->pa_class
));
322 SIMPLEQ_INIT(&sc
->sc_queue
);
323 SIMPLEQ_INIT(&sc
->sc_qchip
);
324 SIMPLEQ_INIT(&sc
->sc_queue2
);
325 SIMPLEQ_INIT(&sc
->sc_qchip2
);
326 SIMPLEQ_INIT(&sc
->sc_q2free
);
328 sc
->sc_flags
= up
->ubsec_flags
;
329 sc
->sc_statmask
= up
->ubsec_statmask
;
331 cmd
= pci_conf_read(pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
);
332 cmd
|= PCI_COMMAND_MASTER_ENABLE
;
333 pci_conf_write(pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
, cmd
);
335 if (pci_mapreg_map(pa
, BS_BAR
, PCI_MAPREG_TYPE_MEM
, 0,
336 &sc
->sc_st
, &sc
->sc_sh
, NULL
, NULL
)) {
337 aprint_error_dev(&sc
->sc_dv
, "can't find mem space");
341 sc
->sc_dmat
= pa
->pa_dmat
;
343 if (pci_intr_map(pa
, &ih
)) {
344 aprint_error_dev(&sc
->sc_dv
, "couldn't map interrupt\n");
347 intrstr
= pci_intr_string(pc
, ih
);
348 sc
->sc_ih
= pci_intr_establish(pc
, ih
, IPL_NET
, ubsec_intr
, sc
);
349 if (sc
->sc_ih
== NULL
) {
350 aprint_error_dev(&sc
->sc_dv
, "couldn't establish interrupt");
352 aprint_error(" at %s", intrstr
);
356 aprint_normal_dev(&sc
->sc_dv
, "interrupting at %s\n", intrstr
);
358 sc
->sc_cid
= crypto_get_driverid(0);
359 if (sc
->sc_cid
< 0) {
360 aprint_error_dev(&sc
->sc_dv
, "couldn't get crypto driver id\n");
361 pci_intr_disestablish(pc
, sc
->sc_ih
);
365 SIMPLEQ_INIT(&sc
->sc_freequeue
);
367 for (i
= 0; i
< UBS_MAX_NQUEUE
; i
++, dmap
++) {
370 q
= (struct ubsec_q
*)malloc(sizeof(struct ubsec_q
),
373 aprint_error_dev(&sc
->sc_dv
, "can't allocate queue buffers\n");
377 if (ubsec_dma_malloc(sc
, sizeof(struct ubsec_dmachunk
),
378 &dmap
->d_alloc
, 0)) {
379 aprint_error_dev(&sc
->sc_dv
, "can't allocate dma buffers\n");
383 dmap
->d_dma
= (struct ubsec_dmachunk
*)dmap
->d_alloc
.dma_vaddr
;
386 sc
->sc_queuea
[i
] = q
;
388 SIMPLEQ_INSERT_TAIL(&sc
->sc_freequeue
, q
, q_next
);
391 crypto_register(sc
->sc_cid
, CRYPTO_3DES_CBC
, 0, 0,
392 ubsec_newsession
, ubsec_freesession
, ubsec_process
, sc
);
393 crypto_register(sc
->sc_cid
, CRYPTO_DES_CBC
, 0, 0,
394 ubsec_newsession
, ubsec_freesession
, ubsec_process
, sc
);
395 crypto_register(sc
->sc_cid
, CRYPTO_MD5_HMAC_96
, 0, 0,
396 ubsec_newsession
, ubsec_freesession
, ubsec_process
, sc
);
397 crypto_register(sc
->sc_cid
, CRYPTO_SHA1_HMAC_96
, 0, 0,
398 ubsec_newsession
, ubsec_freesession
, ubsec_process
, sc
);
401 * Reset Broadcom chip
403 ubsec_reset_board(sc
);
406 * Init Broadcom specific PCI settings
408 ubsec_init_pciregs(pa
);
413 ubsec_init_board(sc
);
416 if (sc
->sc_flags
& UBS_FLAGS_RNG
) {
417 sc
->sc_statmask
|= BS_STAT_MCR2_DONE
;
419 if (ubsec_dma_malloc(sc
, sizeof(struct ubsec_mcr
),
420 &sc
->sc_rng
.rng_q
.q_mcr
, 0))
423 if (ubsec_dma_malloc(sc
, sizeof(struct ubsec_ctx_rngbypass
),
424 &sc
->sc_rng
.rng_q
.q_ctx
, 0)) {
425 ubsec_dma_free(sc
, &sc
->sc_rng
.rng_q
.q_mcr
);
429 if (ubsec_dma_malloc(sc
, sizeof(u_int32_t
) *
430 UBSEC_RNG_BUFSIZ
, &sc
->sc_rng
.rng_buf
, 0)) {
431 ubsec_dma_free(sc
, &sc
->sc_rng
.rng_q
.q_ctx
);
432 ubsec_dma_free(sc
, &sc
->sc_rng
.rng_q
.q_mcr
);
437 sc
->sc_rnghz
= hz
/ 100;
441 timeout_set(&sc
->sc_rngto
, ubsec_rng
, sc
);
442 timeout_add(&sc
->sc_rngto
, sc
->sc_rnghz
);
444 callout_init(&sc
->sc_rngto
, 0);
445 callout_reset(&sc
->sc_rngto
, sc
->sc_rnghz
, ubsec_rng
, sc
);
449 aprint_normal_dev(&sc
->sc_dv
, "random number generator enabled\n");
451 aprint_error_dev(&sc
->sc_dv
, "WARNING: random number generator "
454 #endif /* UBSEC_NO_RNG */
456 if (sc
->sc_flags
& UBS_FLAGS_KEY
) {
457 sc
->sc_statmask
|= BS_STAT_MCR2_DONE
;
459 crypto_kregister(sc
->sc_cid
, CRK_MOD_EXP
, 0,
462 crypto_kregister(sc
->sc_cid
, CRK_MOD_EXP_CRT
, 0,
469 * UBSEC Interrupt routine
472 ubsec_intr(void *arg
)
474 struct ubsec_softc
*sc
= arg
;
475 volatile u_int32_t stat
;
477 struct ubsec_dma
*dmap
;
480 stat
= READ_REG(sc
, BS_STAT
);
481 stat
&= sc
->sc_statmask
;
486 WRITE_REG(sc
, BS_STAT
, stat
); /* IACK */
489 * Check to see if we have any packets waiting for us
491 if ((stat
& BS_STAT_MCR1_DONE
)) {
492 while (!SIMPLEQ_EMPTY(&sc
->sc_qchip
)) {
493 q
= SIMPLEQ_FIRST(&sc
->sc_qchip
);
496 if ((dmap
->d_dma
->d_mcr
.mcr_flags
& htole16(UBS_MCR_DONE
)) == 0)
499 q
= SIMPLEQ_FIRST(&sc
->sc_qchip
);
500 SIMPLEQ_REMOVE_HEAD(&sc
->sc_qchip
, /*q,*/ q_next
);
502 npkts
= q
->q_nstacked_mcrs
;
503 sc
->sc_nqchip
-= 1+npkts
;
505 * search for further sc_qchip ubsec_q's that share
506 * the same MCR, and complete them too, they must be
509 for (i
= 0; i
< npkts
; i
++) {
510 if(q
->q_stacked_mcr
[i
])
511 ubsec_callback(sc
, q
->q_stacked_mcr
[i
]);
515 ubsec_callback(sc
, q
);
519 * Don't send any more packet to chip if there has been
522 if (!(stat
& BS_STAT_DMAERR
))
527 * Check to see if we have any key setups/rng's waiting for us
529 if ((sc
->sc_flags
& (UBS_FLAGS_KEY
|UBS_FLAGS_RNG
)) &&
530 (stat
& BS_STAT_MCR2_DONE
)) {
532 struct ubsec_mcr
*mcr
;
534 while (!SIMPLEQ_EMPTY(&sc
->sc_qchip2
)) {
535 q2
= SIMPLEQ_FIRST(&sc
->sc_qchip2
);
537 bus_dmamap_sync(sc
->sc_dmat
, q2
->q_mcr
.dma_map
,
538 0, q2
->q_mcr
.dma_map
->dm_mapsize
,
539 BUS_DMASYNC_POSTREAD
|BUS_DMASYNC_POSTWRITE
);
541 mcr
= (struct ubsec_mcr
*)q2
->q_mcr
.dma_vaddr
;
542 if ((mcr
->mcr_flags
& htole16(UBS_MCR_DONE
)) == 0) {
543 bus_dmamap_sync(sc
->sc_dmat
,
544 q2
->q_mcr
.dma_map
, 0,
545 q2
->q_mcr
.dma_map
->dm_mapsize
,
546 BUS_DMASYNC_PREREAD
|BUS_DMASYNC_PREWRITE
);
549 q2
= SIMPLEQ_FIRST(&sc
->sc_qchip2
);
550 SIMPLEQ_REMOVE_HEAD(&sc
->sc_qchip2
, /*q2,*/ q_next
);
551 ubsec_callback2(sc
, q2
);
553 * Don't send any more packet to chip if there has been
556 if (!(stat
& BS_STAT_DMAERR
))
562 * Check to see if we got any DMA Error
564 if (stat
& BS_STAT_DMAERR
) {
567 volatile u_int32_t a
= READ_REG(sc
, BS_ERR
);
569 printf("%s: dmaerr %s@%08x\n", device_xname(&sc
->sc_dv
),
570 (a
& BS_ERR_READ
) ? "read" : "write",
573 #endif /* UBSEC_DEBUG */
574 ubsecstats
.hst_dmaerr
++;
575 ubsec_totalreset(sc
);
579 if (sc
->sc_needwakeup
) { /* XXX check high watermark */
580 int wkeup
= sc
->sc_needwakeup
& (CRYPTO_SYMQ
|CRYPTO_ASYMQ
);
583 printf("%s: wakeup crypto (%x)\n", device_xname(&sc
->sc_dv
),
585 #endif /* UBSEC_DEBUG */
586 sc
->sc_needwakeup
&= ~wkeup
;
587 crypto_unblock(sc
->sc_cid
, wkeup
);
593 * ubsec_feed() - aggregate and post requests to chip
595 * It is assumed that the caller set splnet()
598 ubsec_feed(struct ubsec_softc
*sc
)
600 struct ubsec_q
*q
, *q2
;
606 #endif /* UBSEC_DEBUG */
608 npkts
= sc
->sc_nqueue
;
609 if (npkts
> ubsecstats
.hst_maxqueue
)
610 ubsecstats
.hst_maxqueue
= npkts
;
615 * Decide how many ops to combine in a single MCR. We cannot
616 * aggregate more than UBS_MAX_AGGR because this is the number
617 * of slots defined in the data structure. Otherwise we clamp
618 * based on the tunable parameter ubsec_maxaggr. Note that
619 * aggregation can happen in two ways: either by batching ops
620 * from above or because the h/w backs up and throttles us.
621 * Aggregating ops reduces the number of interrupts to the host
622 * but also (potentially) increases the latency for processing
623 * completed ops as we only get an interrupt when all aggregated
624 * ops have completed.
626 if (npkts
> UBS_MAX_AGGR
)
627 npkts
= UBS_MAX_AGGR
;
628 if (npkts
> ubsec_maxaggr
)
629 npkts
= ubsec_maxaggr
;
630 if (npkts
> ubsecstats
.hst_maxbatch
)
631 ubsecstats
.hst_maxbatch
= npkts
;
634 ubsecstats
.hst_totbatch
+= npkts
-1;
636 if ((stat
= READ_REG(sc
, BS_STAT
)) & (BS_STAT_MCR1_FULL
| BS_STAT_DMAERR
)) {
637 if (stat
& BS_STAT_DMAERR
) {
638 ubsec_totalreset(sc
);
639 ubsecstats
.hst_dmaerr
++;
641 ubsecstats
.hst_mcr1full
++;
648 printf("merging %d records\n", npkts
);
649 /* XXX temporary aggregation statistics reporting code */
652 printf("%s: new max aggregate %d\n", device_xname(&sc
->sc_dv
), max
);
654 #endif /* UBSEC_DEBUG */
656 q
= SIMPLEQ_FIRST(&sc
->sc_queue
);
657 SIMPLEQ_REMOVE_HEAD(&sc
->sc_queue
, /*q,*/ q_next
);
660 bus_dmamap_sync(sc
->sc_dmat
, q
->q_src_map
,
661 0, q
->q_src_map
->dm_mapsize
, BUS_DMASYNC_PREWRITE
);
662 if (q
->q_dst_map
!= NULL
)
663 bus_dmamap_sync(sc
->sc_dmat
, q
->q_dst_map
,
664 0, q
->q_dst_map
->dm_mapsize
, BUS_DMASYNC_PREREAD
);
666 q
->q_nstacked_mcrs
= npkts
- 1; /* Number of packets stacked */
668 for (i
= 0; i
< q
->q_nstacked_mcrs
; i
++) {
669 q2
= SIMPLEQ_FIRST(&sc
->sc_queue
);
670 bus_dmamap_sync(sc
->sc_dmat
, q2
->q_src_map
,
671 0, q2
->q_src_map
->dm_mapsize
, BUS_DMASYNC_PREWRITE
);
672 if (q2
->q_dst_map
!= NULL
)
673 bus_dmamap_sync(sc
->sc_dmat
, q2
->q_dst_map
,
674 0, q2
->q_dst_map
->dm_mapsize
, BUS_DMASYNC_PREREAD
);
675 q2
= SIMPLEQ_FIRST(&sc
->sc_queue
);
676 SIMPLEQ_REMOVE_HEAD(&sc
->sc_queue
, /*q2,*/ q_next
);
679 v
= ((void *)&q2
->q_dma
->d_dma
->d_mcr
);
680 v
= (char*)v
+ (sizeof(struct ubsec_mcr
) -
681 sizeof(struct ubsec_mcr_add
));
682 memcpy(&q
->q_dma
->d_dma
->d_mcradd
[i
], v
, sizeof(struct ubsec_mcr_add
));
683 q
->q_stacked_mcr
[i
] = q2
;
685 q
->q_dma
->d_dma
->d_mcr
.mcr_pkts
= htole16(npkts
);
686 SIMPLEQ_INSERT_TAIL(&sc
->sc_qchip
, q
, q_next
);
687 sc
->sc_nqchip
+= npkts
;
688 if (sc
->sc_nqchip
> ubsecstats
.hst_maxqchip
)
689 ubsecstats
.hst_maxqchip
= sc
->sc_nqchip
;
690 bus_dmamap_sync(sc
->sc_dmat
, q
->q_dma
->d_alloc
.dma_map
,
691 0, q
->q_dma
->d_alloc
.dma_map
->dm_mapsize
,
692 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
693 WRITE_REG(sc
, BS_MCR1
, q
->q_dma
->d_alloc
.dma_paddr
+
694 offsetof(struct ubsec_dmachunk
, d_mcr
));
698 while (!SIMPLEQ_EMPTY(&sc
->sc_queue
)) {
699 if ((stat
= READ_REG(sc
, BS_STAT
)) & (BS_STAT_MCR1_FULL
| BS_STAT_DMAERR
)) {
700 if (stat
& BS_STAT_DMAERR
) {
701 ubsec_totalreset(sc
);
702 ubsecstats
.hst_dmaerr
++;
704 ubsecstats
.hst_mcr1full
++;
709 q
= SIMPLEQ_FIRST(&sc
->sc_queue
);
711 bus_dmamap_sync(sc
->sc_dmat
, q
->q_src_map
,
712 0, q
->q_src_map
->dm_mapsize
, BUS_DMASYNC_PREWRITE
);
713 if (q
->q_dst_map
!= NULL
)
714 bus_dmamap_sync(sc
->sc_dmat
, q
->q_dst_map
,
715 0, q
->q_dst_map
->dm_mapsize
, BUS_DMASYNC_PREREAD
);
716 bus_dmamap_sync(sc
->sc_dmat
, q
->q_dma
->d_alloc
.dma_map
,
717 0, q
->q_dma
->d_alloc
.dma_map
->dm_mapsize
,
718 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
720 WRITE_REG(sc
, BS_MCR1
, q
->q_dma
->d_alloc
.dma_paddr
+
721 offsetof(struct ubsec_dmachunk
, d_mcr
));
724 printf("feed: q->chip %p %08x stat %08x\n",
725 q
, (u_int32_t
)q
->q_dma
->d_alloc
.dma_paddr
,
727 #endif /* UBSEC_DEBUG */
728 q
= SIMPLEQ_FIRST(&sc
->sc_queue
);
729 SIMPLEQ_REMOVE_HEAD(&sc
->sc_queue
, /*q,*/ q_next
);
731 SIMPLEQ_INSERT_TAIL(&sc
->sc_qchip
, q
, q_next
);
734 if (sc
->sc_nqchip
> ubsecstats
.hst_maxqchip
)
735 ubsecstats
.hst_maxqchip
= sc
->sc_nqchip
;
739 * Allocate a new 'session' and return an encoded session id. 'sidp'
740 * contains our registration id, and should contain an encoded session
741 * id on successful allocation.
744 ubsec_newsession(void *arg
, u_int32_t
*sidp
, struct cryptoini
*cri
)
746 struct cryptoini
*c
, *encini
= NULL
, *macini
= NULL
;
747 struct ubsec_softc
*sc
;
748 struct ubsec_session
*ses
= NULL
;
754 KASSERT(sc
!= NULL
/*, ("ubsec_newsession: null softc")*/);
756 if (sidp
== NULL
|| cri
== NULL
|| sc
== NULL
)
759 for (c
= cri
; c
!= NULL
; c
= c
->cri_next
) {
760 if (c
->cri_alg
== CRYPTO_MD5_HMAC_96
||
761 c
->cri_alg
== CRYPTO_SHA1_HMAC_96
) {
765 } else if (c
->cri_alg
== CRYPTO_DES_CBC
||
766 c
->cri_alg
== CRYPTO_3DES_CBC
) {
773 if (encini
== NULL
&& macini
== NULL
)
776 if (sc
->sc_sessions
== NULL
) {
777 ses
= sc
->sc_sessions
= (struct ubsec_session
*)malloc(
778 sizeof(struct ubsec_session
), M_DEVBUF
, M_NOWAIT
);
782 sc
->sc_nsessions
= 1;
784 for (sesn
= 0; sesn
< sc
->sc_nsessions
; sesn
++) {
785 if (sc
->sc_sessions
[sesn
].ses_used
== 0) {
786 ses
= &sc
->sc_sessions
[sesn
];
792 sesn
= sc
->sc_nsessions
;
793 ses
= (struct ubsec_session
*)malloc((sesn
+ 1) *
794 sizeof(struct ubsec_session
), M_DEVBUF
, M_NOWAIT
);
797 memcpy(ses
, sc
->sc_sessions
, sesn
*
798 sizeof(struct ubsec_session
));
799 memset(sc
->sc_sessions
, 0, sesn
*
800 sizeof(struct ubsec_session
));
801 free(sc
->sc_sessions
, M_DEVBUF
);
802 sc
->sc_sessions
= ses
;
803 ses
= &sc
->sc_sessions
[sesn
];
808 memset(ses
, 0, sizeof(struct ubsec_session
));
811 /* get an IV, network byte order */
813 rnd_extract_data(ses
->ses_iv
,
814 sizeof(ses
->ses_iv
), RND_EXTRACT_ANY
);
816 get_random_bytes(ses
->ses_iv
, sizeof(ses
->ses_iv
));
819 /* Go ahead and compute key in ubsec's byte order */
820 if (encini
->cri_alg
== CRYPTO_DES_CBC
) {
821 memcpy(&ses
->ses_deskey
[0], encini
->cri_key
, 8);
822 memcpy(&ses
->ses_deskey
[2], encini
->cri_key
, 8);
823 memcpy(&ses
->ses_deskey
[4], encini
->cri_key
, 8);
825 memcpy(ses
->ses_deskey
, encini
->cri_key
, 24);
827 SWAP32(ses
->ses_deskey
[0]);
828 SWAP32(ses
->ses_deskey
[1]);
829 SWAP32(ses
->ses_deskey
[2]);
830 SWAP32(ses
->ses_deskey
[3]);
831 SWAP32(ses
->ses_deskey
[4]);
832 SWAP32(ses
->ses_deskey
[5]);
836 for (i
= 0; i
< macini
->cri_klen
/ 8; i
++)
837 macini
->cri_key
[i
] ^= HMAC_IPAD_VAL
;
839 if (macini
->cri_alg
== CRYPTO_MD5_HMAC_96
) {
841 MD5Update(&md5ctx
, macini
->cri_key
,
842 macini
->cri_klen
/ 8);
843 MD5Update(&md5ctx
, hmac_ipad_buffer
,
844 HMAC_BLOCK_LEN
- (macini
->cri_klen
/ 8));
845 memcpy(ses
->ses_hminner
, md5ctx
.state
,
846 sizeof(md5ctx
.state
));
849 SHA1Update(&sha1ctx
, macini
->cri_key
,
850 macini
->cri_klen
/ 8);
851 SHA1Update(&sha1ctx
, hmac_ipad_buffer
,
852 HMAC_BLOCK_LEN
- (macini
->cri_klen
/ 8));
853 memcpy(ses
->ses_hminner
, sha1ctx
.state
,
854 sizeof(sha1ctx
.state
));
857 for (i
= 0; i
< macini
->cri_klen
/ 8; i
++)
858 macini
->cri_key
[i
] ^= (HMAC_IPAD_VAL
^ HMAC_OPAD_VAL
);
860 if (macini
->cri_alg
== CRYPTO_MD5_HMAC_96
) {
862 MD5Update(&md5ctx
, macini
->cri_key
,
863 macini
->cri_klen
/ 8);
864 MD5Update(&md5ctx
, hmac_opad_buffer
,
865 HMAC_BLOCK_LEN
- (macini
->cri_klen
/ 8));
866 memcpy(ses
->ses_hmouter
, md5ctx
.state
,
867 sizeof(md5ctx
.state
));
870 SHA1Update(&sha1ctx
, macini
->cri_key
,
871 macini
->cri_klen
/ 8);
872 SHA1Update(&sha1ctx
, hmac_opad_buffer
,
873 HMAC_BLOCK_LEN
- (macini
->cri_klen
/ 8));
874 memcpy(ses
->ses_hmouter
, sha1ctx
.state
,
875 sizeof(sha1ctx
.state
));
878 for (i
= 0; i
< macini
->cri_klen
/ 8; i
++)
879 macini
->cri_key
[i
] ^= HMAC_OPAD_VAL
;
882 *sidp
= UBSEC_SID(device_unit(&sc
->sc_dv
), sesn
);
887 * Deallocate a session.
890 ubsec_freesession(void *arg
, u_int64_t tid
)
892 struct ubsec_softc
*sc
;
894 u_int32_t sid
= ((u_int32_t
) tid
) & 0xffffffff;
897 KASSERT(sc
!= NULL
/*, ("ubsec_freesession: null softc")*/);
899 session
= UBSEC_SESSION(sid
);
900 if (session
>= sc
->sc_nsessions
)
903 memset(&sc
->sc_sessions
[session
], 0, sizeof(sc
->sc_sessions
[session
]));
907 #ifdef __FreeBSD__ /* Ugly gratuitous changes to bus_dma */
909 ubsec_op_cb(void *arg
, bus_dma_segment_t
*seg
, int nsegs
, bus_size_t mapsize
, int error
)
911 struct ubsec_operand
*op
= arg
;
913 KASSERT(nsegs
<= UBS_MAX_SCATTER
914 /*, ("Too many DMA segments returned when mapping operand")*/);
917 printf("ubsec_op_cb: mapsize %u nsegs %d\n",
918 (u_int
) mapsize
, nsegs
);
920 op
->mapsize
= mapsize
;
922 memcpy(op
->segs
, seg
, nsegs
* sizeof (seg
[0]));
927 ubsec_process(void *arg
, struct cryptop
*crp
, int hint
)
929 struct ubsec_q
*q
= NULL
;
933 int err
= 0, i
, j
, s
, nicealign
;
934 struct ubsec_softc
*sc
;
935 struct cryptodesc
*crd1
, *crd2
, *maccrd
, *enccrd
;
936 int encoffset
= 0, macoffset
= 0, cpskip
, cpoffset
;
937 int sskip
, dskip
, stheend
, dtheend
;
939 struct ubsec_session
*ses
;
940 struct ubsec_pktctx ctx
;
941 struct ubsec_dma
*dmap
= NULL
;
944 KASSERT(sc
!= NULL
/*, ("ubsec_process: null softc")*/);
946 if (crp
== NULL
|| crp
->crp_callback
== NULL
|| sc
== NULL
) {
947 ubsecstats
.hst_invalid
++;
950 if (UBSEC_SESSION(crp
->crp_sid
) >= sc
->sc_nsessions
) {
951 ubsecstats
.hst_badsession
++;
957 if (SIMPLEQ_EMPTY(&sc
->sc_freequeue
)) {
958 ubsecstats
.hst_queuefull
++;
959 sc
->sc_needwakeup
|= CRYPTO_SYMQ
;
964 q
= SIMPLEQ_FIRST(&sc
->sc_freequeue
);
965 SIMPLEQ_REMOVE_HEAD(&sc
->sc_freequeue
, /*q,*/ q_next
);
968 dmap
= q
->q_dma
; /* Save dma pointer */
969 memset(q
, 0, sizeof(struct ubsec_q
));
970 memset(&ctx
, 0, sizeof(ctx
));
972 q
->q_sesn
= UBSEC_SESSION(crp
->crp_sid
);
974 ses
= &sc
->sc_sessions
[q
->q_sesn
];
976 if (crp
->crp_flags
& CRYPTO_F_IMBUF
) {
977 q
->q_src_m
= (struct mbuf
*)crp
->crp_buf
;
978 q
->q_dst_m
= (struct mbuf
*)crp
->crp_buf
;
979 } else if (crp
->crp_flags
& CRYPTO_F_IOV
) {
980 q
->q_src_io
= (struct uio
*)crp
->crp_buf
;
981 q
->q_dst_io
= (struct uio
*)crp
->crp_buf
;
983 ubsecstats
.hst_badflags
++;
985 goto errout
; /* XXX we don't handle contiguous blocks! */
988 memset(&dmap
->d_dma
->d_mcr
, 0, sizeof(struct ubsec_mcr
));
990 dmap
->d_dma
->d_mcr
.mcr_pkts
= htole16(1);
991 dmap
->d_dma
->d_mcr
.mcr_flags
= 0;
994 crd1
= crp
->crp_desc
;
996 ubsecstats
.hst_nodesc
++;
1000 crd2
= crd1
->crd_next
;
1003 if (crd1
->crd_alg
== CRYPTO_MD5_HMAC_96
||
1004 crd1
->crd_alg
== CRYPTO_SHA1_HMAC_96
) {
1007 } else if (crd1
->crd_alg
== CRYPTO_DES_CBC
||
1008 crd1
->crd_alg
== CRYPTO_3DES_CBC
) {
1012 ubsecstats
.hst_badalg
++;
1017 if ((crd1
->crd_alg
== CRYPTO_MD5_HMAC_96
||
1018 crd1
->crd_alg
== CRYPTO_SHA1_HMAC_96
) &&
1019 (crd2
->crd_alg
== CRYPTO_DES_CBC
||
1020 crd2
->crd_alg
== CRYPTO_3DES_CBC
) &&
1021 ((crd2
->crd_flags
& CRD_F_ENCRYPT
) == 0)) {
1024 } else if ((crd1
->crd_alg
== CRYPTO_DES_CBC
||
1025 crd1
->crd_alg
== CRYPTO_3DES_CBC
) &&
1026 (crd2
->crd_alg
== CRYPTO_MD5_HMAC_96
||
1027 crd2
->crd_alg
== CRYPTO_SHA1_HMAC_96
) &&
1028 (crd1
->crd_flags
& CRD_F_ENCRYPT
)) {
1033 * We cannot order the ubsec as requested
1035 ubsecstats
.hst_badalg
++;
1042 encoffset
= enccrd
->crd_skip
;
1043 ctx
.pc_flags
|= htole16(UBS_PKTCTX_ENC_3DES
);
1045 if (enccrd
->crd_flags
& CRD_F_ENCRYPT
) {
1046 q
->q_flags
|= UBSEC_QFLAGS_COPYOUTIV
;
1048 if (enccrd
->crd_flags
& CRD_F_IV_EXPLICIT
)
1049 memcpy(ctx
.pc_iv
, enccrd
->crd_iv
, 8);
1051 ctx
.pc_iv
[0] = ses
->ses_iv
[0];
1052 ctx
.pc_iv
[1] = ses
->ses_iv
[1];
1055 if ((enccrd
->crd_flags
& CRD_F_IV_PRESENT
) == 0) {
1056 if (crp
->crp_flags
& CRYPTO_F_IMBUF
)
1057 m_copyback(q
->q_src_m
,
1059 8, (void *)ctx
.pc_iv
);
1060 else if (crp
->crp_flags
& CRYPTO_F_IOV
)
1061 cuio_copyback(q
->q_src_io
,
1063 8, (void *)ctx
.pc_iv
);
1066 ctx
.pc_flags
|= htole16(UBS_PKTCTX_INBOUND
);
1068 if (enccrd
->crd_flags
& CRD_F_IV_EXPLICIT
)
1069 memcpy(ctx
.pc_iv
, enccrd
->crd_iv
, 8);
1070 else if (crp
->crp_flags
& CRYPTO_F_IMBUF
)
1071 m_copydata(q
->q_src_m
, enccrd
->crd_inject
,
1072 8, (void *)ctx
.pc_iv
);
1073 else if (crp
->crp_flags
& CRYPTO_F_IOV
)
1074 cuio_copydata(q
->q_src_io
,
1075 enccrd
->crd_inject
, 8,
1079 ctx
.pc_deskey
[0] = ses
->ses_deskey
[0];
1080 ctx
.pc_deskey
[1] = ses
->ses_deskey
[1];
1081 ctx
.pc_deskey
[2] = ses
->ses_deskey
[2];
1082 ctx
.pc_deskey
[3] = ses
->ses_deskey
[3];
1083 ctx
.pc_deskey
[4] = ses
->ses_deskey
[4];
1084 ctx
.pc_deskey
[5] = ses
->ses_deskey
[5];
1085 SWAP32(ctx
.pc_iv
[0]);
1086 SWAP32(ctx
.pc_iv
[1]);
1090 macoffset
= maccrd
->crd_skip
;
1092 if (maccrd
->crd_alg
== CRYPTO_MD5_HMAC_96
)
1093 ctx
.pc_flags
|= htole16(UBS_PKTCTX_AUTH_MD5
);
1095 ctx
.pc_flags
|= htole16(UBS_PKTCTX_AUTH_SHA1
);
1097 for (i
= 0; i
< 5; i
++) {
1098 ctx
.pc_hminner
[i
] = ses
->ses_hminner
[i
];
1099 ctx
.pc_hmouter
[i
] = ses
->ses_hmouter
[i
];
1101 HTOLE32(ctx
.pc_hminner
[i
]);
1102 HTOLE32(ctx
.pc_hmouter
[i
]);
1106 if (enccrd
&& maccrd
) {
1108 * ubsec cannot handle packets where the end of encryption
1109 * and authentication are not the same, or where the
1110 * encrypted part begins before the authenticated part.
1112 if ((encoffset
+ enccrd
->crd_len
) !=
1113 (macoffset
+ maccrd
->crd_len
)) {
1114 ubsecstats
.hst_lenmismatch
++;
1118 if (enccrd
->crd_skip
< maccrd
->crd_skip
) {
1119 ubsecstats
.hst_skipmismatch
++;
1123 sskip
= maccrd
->crd_skip
;
1124 cpskip
= dskip
= enccrd
->crd_skip
;
1125 stheend
= maccrd
->crd_len
;
1126 dtheend
= enccrd
->crd_len
;
1127 coffset
= enccrd
->crd_skip
- maccrd
->crd_skip
;
1128 cpoffset
= cpskip
+ dtheend
;
1131 printf("mac: skip %d, len %d, inject %d\n",
1132 maccrd
->crd_skip
, maccrd
->crd_len
, maccrd
->crd_inject
);
1133 printf("enc: skip %d, len %d, inject %d\n",
1134 enccrd
->crd_skip
, enccrd
->crd_len
, enccrd
->crd_inject
);
1135 printf("src: skip %d, len %d\n", sskip
, stheend
);
1136 printf("dst: skip %d, len %d\n", dskip
, dtheend
);
1137 printf("ubs: coffset %d, pktlen %d, cpskip %d, cpoffset %d\n",
1138 coffset
, stheend
, cpskip
, cpoffset
);
1142 cpskip
= dskip
= sskip
= macoffset
+ encoffset
;
1143 dtheend
= stheend
= (enccrd
)?enccrd
->crd_len
:maccrd
->crd_len
;
1144 cpoffset
= cpskip
+ dtheend
;
1147 ctx
.pc_offset
= htole16(coffset
>> 2);
1149 /* XXX FIXME: jonathan asks, what the heck's that 0xfff0? */
1150 if (bus_dmamap_create(sc
->sc_dmat
, 0xfff0, UBS_MAX_SCATTER
,
1151 0xfff0, 0, BUS_DMA_NOWAIT
, &q
->q_src_map
) != 0) {
1155 if (crp
->crp_flags
& CRYPTO_F_IMBUF
) {
1156 if (bus_dmamap_load_mbuf(sc
->sc_dmat
, q
->q_src_map
,
1157 q
->q_src_m
, BUS_DMA_NOWAIT
) != 0) {
1158 bus_dmamap_destroy(sc
->sc_dmat
, q
->q_src_map
);
1159 q
->q_src_map
= NULL
;
1160 ubsecstats
.hst_noload
++;
1164 } else if (crp
->crp_flags
& CRYPTO_F_IOV
) {
1165 if (bus_dmamap_load_uio(sc
->sc_dmat
, q
->q_src_map
,
1166 q
->q_src_io
, BUS_DMA_NOWAIT
) != 0) {
1167 bus_dmamap_destroy(sc
->sc_dmat
, q
->q_src_map
);
1168 q
->q_src_map
= NULL
;
1169 ubsecstats
.hst_noload
++;
1174 nicealign
= ubsec_dmamap_aligned(q
->q_src_map
);
1176 dmap
->d_dma
->d_mcr
.mcr_pktlen
= htole16(stheend
);
1180 printf("src skip: %d nicealign: %u\n", sskip
, nicealign
);
1182 for (i
= j
= 0; i
< q
->q_src_map
->dm_nsegs
; i
++) {
1183 struct ubsec_pktbuf
*pb
;
1184 bus_size_t packl
= q
->q_src_map
->dm_segs
[i
].ds_len
;
1185 bus_addr_t packp
= q
->q_src_map
->dm_segs
[i
].ds_addr
;
1187 if (sskip
>= packl
) {
1196 if (packl
> 0xfffc) {
1202 pb
= &dmap
->d_dma
->d_mcr
.mcr_ipktbuf
;
1204 pb
= &dmap
->d_dma
->d_sbuf
[j
- 1];
1206 pb
->pb_addr
= htole32(packp
);
1209 if (packl
> stheend
) {
1210 pb
->pb_len
= htole32(stheend
);
1213 pb
->pb_len
= htole32(packl
);
1217 pb
->pb_len
= htole32(packl
);
1219 if ((i
+ 1) == q
->q_src_map
->dm_nsegs
)
1222 pb
->pb_next
= htole32(dmap
->d_alloc
.dma_paddr
+
1223 offsetof(struct ubsec_dmachunk
, d_sbuf
[j
]));
1227 if (enccrd
== NULL
&& maccrd
!= NULL
) {
1228 dmap
->d_dma
->d_mcr
.mcr_opktbuf
.pb_addr
= 0;
1229 dmap
->d_dma
->d_mcr
.mcr_opktbuf
.pb_len
= 0;
1230 dmap
->d_dma
->d_mcr
.mcr_opktbuf
.pb_next
= htole32(dmap
->d_alloc
.dma_paddr
+
1231 offsetof(struct ubsec_dmachunk
, d_macbuf
[0]));
1234 printf("opkt: %x %x %x\n",
1235 dmap
->d_dma
->d_mcr
.mcr_opktbuf
.pb_addr
,
1236 dmap
->d_dma
->d_mcr
.mcr_opktbuf
.pb_len
,
1237 dmap
->d_dma
->d_mcr
.mcr_opktbuf
.pb_next
);
1241 if (crp
->crp_flags
& CRYPTO_F_IOV
) {
1243 ubsecstats
.hst_iovmisaligned
++;
1247 /* XXX: ``what the heck's that'' 0xfff0? */
1248 if (bus_dmamap_create(sc
->sc_dmat
, 0xfff0,
1249 UBS_MAX_SCATTER
, 0xfff0, 0, BUS_DMA_NOWAIT
,
1250 &q
->q_dst_map
) != 0) {
1251 ubsecstats
.hst_nomap
++;
1255 if (bus_dmamap_load_uio(sc
->sc_dmat
, q
->q_dst_map
,
1256 q
->q_dst_io
, BUS_DMA_NOWAIT
) != 0) {
1257 bus_dmamap_destroy(sc
->sc_dmat
, q
->q_dst_map
);
1258 q
->q_dst_map
= NULL
;
1259 ubsecstats
.hst_noload
++;
1263 } else if (crp
->crp_flags
& CRYPTO_F_IMBUF
) {
1265 q
->q_dst_m
= q
->q_src_m
;
1266 q
->q_dst_map
= q
->q_src_map
;
1269 struct mbuf
*m
, *top
, **mp
;
1271 ubsecstats
.hst_unaligned
++;
1272 totlen
= q
->q_src_map
->dm_mapsize
;
1273 if (q
->q_src_m
->m_flags
& M_PKTHDR
) {
1275 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
1276 /*XXX FIXME: m_dup_pkthdr */
1277 if (m
&& 1 /*!m_dup_pkthdr(m, q->q_src_m, M_DONTWAIT)*/) {
1283 MGET(m
, M_DONTWAIT
, MT_DATA
);
1286 ubsecstats
.hst_nombuf
++;
1287 err
= sc
->sc_nqueue
? ERESTART
: ENOMEM
;
1291 /*XXX was M_DUP_PKTHDR*/
1292 M_COPY_PKTHDR(m
, q
->q_src_m
);
1293 if (totlen
>= MINCLSIZE
) {
1294 MCLGET(m
, M_DONTWAIT
);
1295 if ((m
->m_flags
& M_EXT
) == 0) {
1297 ubsecstats
.hst_nomcl
++;
1298 err
= sc
->sc_nqueue
? ERESTART
: ENOMEM
;
1307 while (totlen
> 0) {
1309 MGET(m
, M_DONTWAIT
, MT_DATA
);
1312 ubsecstats
.hst_nombuf
++;
1313 err
= sc
->sc_nqueue
? ERESTART
: ENOMEM
;
1318 if (top
&& totlen
>= MINCLSIZE
) {
1319 MCLGET(m
, M_DONTWAIT
);
1320 if ((m
->m_flags
& M_EXT
) == 0) {
1323 ubsecstats
.hst_nomcl
++;
1324 err
= sc
->sc_nqueue
? ERESTART
: ENOMEM
;
1329 m
->m_len
= len
= min(totlen
, len
);
1335 ubsec_mcopy(q
->q_src_m
, q
->q_dst_m
,
1337 /* XXX again, what the heck is that 0xfff0? */
1338 if (bus_dmamap_create(sc
->sc_dmat
, 0xfff0,
1339 UBS_MAX_SCATTER
, 0xfff0, 0, BUS_DMA_NOWAIT
,
1340 &q
->q_dst_map
) != 0) {
1341 ubsecstats
.hst_nomap
++;
1345 if (bus_dmamap_load_mbuf(sc
->sc_dmat
,
1346 q
->q_dst_map
, q
->q_dst_m
,
1347 BUS_DMA_NOWAIT
) != 0) {
1348 bus_dmamap_destroy(sc
->sc_dmat
,
1350 q
->q_dst_map
= NULL
;
1351 ubsecstats
.hst_noload
++;
1357 ubsecstats
.hst_badflags
++;
1364 printf("dst skip: %d\n", dskip
);
1366 for (i
= j
= 0; i
< q
->q_dst_map
->dm_nsegs
; i
++) {
1367 struct ubsec_pktbuf
*pb
;
1368 bus_size_t packl
= q
->q_dst_map
->dm_segs
[i
].ds_len
;
1369 bus_addr_t packp
= q
->q_dst_map
->dm_segs
[i
].ds_addr
;
1371 if (dskip
>= packl
) {
1380 if (packl
> 0xfffc) {
1386 pb
= &dmap
->d_dma
->d_mcr
.mcr_opktbuf
;
1388 pb
= &dmap
->d_dma
->d_dbuf
[j
- 1];
1390 pb
->pb_addr
= htole32(packp
);
1393 if (packl
> dtheend
) {
1394 pb
->pb_len
= htole32(dtheend
);
1397 pb
->pb_len
= htole32(packl
);
1401 pb
->pb_len
= htole32(packl
);
1403 if ((i
+ 1) == q
->q_dst_map
->dm_nsegs
) {
1405 pb
->pb_next
= htole32(dmap
->d_alloc
.dma_paddr
+
1406 offsetof(struct ubsec_dmachunk
, d_macbuf
[0]));
1410 pb
->pb_next
= htole32(dmap
->d_alloc
.dma_paddr
+
1411 offsetof(struct ubsec_dmachunk
, d_dbuf
[j
]));
1416 dmap
->d_dma
->d_mcr
.mcr_cmdctxp
= htole32(dmap
->d_alloc
.dma_paddr
+
1417 offsetof(struct ubsec_dmachunk
, d_ctx
));
1419 if (sc
->sc_flags
& UBS_FLAGS_LONGCTX
) {
1420 struct ubsec_pktctx_long
*ctxl
;
1422 ctxl
= (struct ubsec_pktctx_long
*)((char *)dmap
->d_alloc
.dma_vaddr
+
1423 offsetof(struct ubsec_dmachunk
, d_ctx
));
1425 /* transform small context into long context */
1426 ctxl
->pc_len
= htole16(sizeof(struct ubsec_pktctx_long
));
1427 ctxl
->pc_type
= htole16(UBS_PKTCTX_TYPE_IPSEC
);
1428 ctxl
->pc_flags
= ctx
.pc_flags
;
1429 ctxl
->pc_offset
= ctx
.pc_offset
;
1430 for (i
= 0; i
< 6; i
++)
1431 ctxl
->pc_deskey
[i
] = ctx
.pc_deskey
[i
];
1432 for (i
= 0; i
< 5; i
++)
1433 ctxl
->pc_hminner
[i
] = ctx
.pc_hminner
[i
];
1434 for (i
= 0; i
< 5; i
++)
1435 ctxl
->pc_hmouter
[i
] = ctx
.pc_hmouter
[i
];
1436 ctxl
->pc_iv
[0] = ctx
.pc_iv
[0];
1437 ctxl
->pc_iv
[1] = ctx
.pc_iv
[1];
1439 memcpy((char *)dmap
->d_alloc
.dma_vaddr
+
1440 offsetof(struct ubsec_dmachunk
, d_ctx
), &ctx
,
1441 sizeof(struct ubsec_pktctx
));
1444 SIMPLEQ_INSERT_TAIL(&sc
->sc_queue
, q
, q_next
);
1446 ubsecstats
.hst_ipackets
++;
1447 ubsecstats
.hst_ibytes
+= dmap
->d_alloc
.dma_map
->dm_mapsize
;
1448 if ((hint
& CRYPTO_HINT_MORE
) == 0 || sc
->sc_nqueue
>= ubsec_maxbatch
)
1455 if ((q
->q_dst_m
!= NULL
) && (q
->q_src_m
!= q
->q_dst_m
))
1456 m_freem(q
->q_dst_m
);
1458 if (q
->q_dst_map
!= NULL
&& q
->q_dst_map
!= q
->q_src_map
) {
1459 bus_dmamap_unload(sc
->sc_dmat
, q
->q_dst_map
);
1460 bus_dmamap_destroy(sc
->sc_dmat
, q
->q_dst_map
);
1462 if (q
->q_src_map
!= NULL
) {
1463 bus_dmamap_unload(sc
->sc_dmat
, q
->q_src_map
);
1464 bus_dmamap_destroy(sc
->sc_dmat
, q
->q_src_map
);
1468 SIMPLEQ_INSERT_TAIL(&sc
->sc_freequeue
, q
, q_next
);
1471 #if 0 /* jonathan says: this openbsd code seems to be subsumed elsewhere */
1473 ubsecstats
.hst_invalid
++;
1475 ubsecstats
.hst_nomem
++;
1477 if (err
!= ERESTART
) {
1478 crp
->crp_etype
= err
;
1481 sc
->sc_needwakeup
|= CRYPTO_SYMQ
;
1487 ubsec_callback(struct ubsec_softc
*sc
, struct ubsec_q
*q
)
1489 struct cryptop
*crp
= (struct cryptop
*)q
->q_crp
;
1490 struct cryptodesc
*crd
;
1491 struct ubsec_dma
*dmap
= q
->q_dma
;
1493 ubsecstats
.hst_opackets
++;
1494 ubsecstats
.hst_obytes
+= dmap
->d_alloc
.dma_size
;
1496 bus_dmamap_sync(sc
->sc_dmat
, dmap
->d_alloc
.dma_map
, 0,
1497 dmap
->d_alloc
.dma_map
->dm_mapsize
,
1498 BUS_DMASYNC_POSTREAD
|BUS_DMASYNC_POSTWRITE
);
1499 if (q
->q_dst_map
!= NULL
&& q
->q_dst_map
!= q
->q_src_map
) {
1500 bus_dmamap_sync(sc
->sc_dmat
, q
->q_dst_map
,
1501 0, q
->q_dst_map
->dm_mapsize
, BUS_DMASYNC_POSTREAD
);
1502 bus_dmamap_unload(sc
->sc_dmat
, q
->q_dst_map
);
1503 bus_dmamap_destroy(sc
->sc_dmat
, q
->q_dst_map
);
1505 bus_dmamap_sync(sc
->sc_dmat
, q
->q_src_map
,
1506 0, q
->q_src_map
->dm_mapsize
, BUS_DMASYNC_POSTWRITE
);
1507 bus_dmamap_unload(sc
->sc_dmat
, q
->q_src_map
);
1508 bus_dmamap_destroy(sc
->sc_dmat
, q
->q_src_map
);
1510 if ((crp
->crp_flags
& CRYPTO_F_IMBUF
) && (q
->q_src_m
!= q
->q_dst_m
)) {
1511 m_freem(q
->q_src_m
);
1512 crp
->crp_buf
= (void *)q
->q_dst_m
;
1515 /* copy out IV for future use */
1516 if (q
->q_flags
& UBSEC_QFLAGS_COPYOUTIV
) {
1517 for (crd
= crp
->crp_desc
; crd
; crd
= crd
->crd_next
) {
1518 if (crd
->crd_alg
!= CRYPTO_DES_CBC
&&
1519 crd
->crd_alg
!= CRYPTO_3DES_CBC
)
1521 if (crp
->crp_flags
& CRYPTO_F_IMBUF
)
1522 m_copydata((struct mbuf
*)crp
->crp_buf
,
1523 crd
->crd_skip
+ crd
->crd_len
- 8, 8,
1524 (void *)sc
->sc_sessions
[q
->q_sesn
].ses_iv
);
1525 else if (crp
->crp_flags
& CRYPTO_F_IOV
) {
1526 cuio_copydata((struct uio
*)crp
->crp_buf
,
1527 crd
->crd_skip
+ crd
->crd_len
- 8, 8,
1528 (void *)sc
->sc_sessions
[q
->q_sesn
].ses_iv
);
1534 for (crd
= crp
->crp_desc
; crd
; crd
= crd
->crd_next
) {
1535 if (crd
->crd_alg
!= CRYPTO_MD5_HMAC_96
&&
1536 crd
->crd_alg
!= CRYPTO_SHA1_HMAC_96
)
1538 if (crp
->crp_flags
& CRYPTO_F_IMBUF
)
1539 m_copyback((struct mbuf
*)crp
->crp_buf
,
1540 crd
->crd_inject
, 12,
1541 (void *)dmap
->d_dma
->d_macbuf
);
1542 else if (crp
->crp_flags
& CRYPTO_F_IOV
&& crp
->crp_mac
)
1543 bcopy((void *)dmap
->d_dma
->d_macbuf
,
1547 SIMPLEQ_INSERT_TAIL(&sc
->sc_freequeue
, q
, q_next
);
1552 ubsec_mcopy(struct mbuf
*srcm
, struct mbuf
*dstm
, int hoffset
, int toffset
)
1554 int i
, j
, dlen
, slen
;
1558 sptr
= srcm
->m_data
;
1560 dptr
= dstm
->m_data
;
1564 for (i
= 0; i
< min(slen
, dlen
); i
++) {
1565 if (j
< hoffset
|| j
>= toffset
)
1572 srcm
= srcm
->m_next
;
1575 sptr
= srcm
->m_data
;
1579 dstm
= dstm
->m_next
;
1582 dptr
= dstm
->m_data
;
1589 * feed the key generator, must be called at splnet() or higher.
1592 ubsec_feed2(struct ubsec_softc
*sc
)
1596 while (!SIMPLEQ_EMPTY(&sc
->sc_queue2
)) {
1597 if (READ_REG(sc
, BS_STAT
) & BS_STAT_MCR2_FULL
)
1599 q
= SIMPLEQ_FIRST(&sc
->sc_queue2
);
1601 bus_dmamap_sync(sc
->sc_dmat
, q
->q_mcr
.dma_map
, 0,
1602 q
->q_mcr
.dma_map
->dm_mapsize
,
1603 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1604 bus_dmamap_sync(sc
->sc_dmat
, q
->q_ctx
.dma_map
, 0,
1605 q
->q_ctx
.dma_map
->dm_mapsize
,
1606 BUS_DMASYNC_PREWRITE
);
1608 WRITE_REG(sc
, BS_MCR2
, q
->q_mcr
.dma_paddr
);
1609 q
= SIMPLEQ_FIRST(&sc
->sc_queue2
);
1610 SIMPLEQ_REMOVE_HEAD(&sc
->sc_queue2
, /*q,*/ q_next
);
1612 SIMPLEQ_INSERT_TAIL(&sc
->sc_qchip2
, q
, q_next
);
1617 * Callback for handling random numbers
1620 ubsec_callback2(struct ubsec_softc
*sc
, struct ubsec_q2
*q
)
1622 struct cryptkop
*krp
;
1623 struct ubsec_ctx_keyop
*ctx
;
1625 ctx
= (struct ubsec_ctx_keyop
*)q
->q_ctx
.dma_vaddr
;
1626 bus_dmamap_sync(sc
->sc_dmat
, q
->q_ctx
.dma_map
, 0,
1627 q
->q_ctx
.dma_map
->dm_mapsize
, BUS_DMASYNC_POSTWRITE
);
1629 switch (q
->q_type
) {
1630 #ifndef UBSEC_NO_RNG
1631 case UBS_CTXOP_RNGSHA1
:
1632 case UBS_CTXOP_RNGBYPASS
: {
1633 struct ubsec_q2_rng
*rng
= (struct ubsec_q2_rng
*)q
;
1637 bus_dmamap_sync(sc
->sc_dmat
, rng
->rng_buf
.dma_map
, 0,
1638 rng
->rng_buf
.dma_map
->dm_mapsize
, BUS_DMASYNC_POSTREAD
);
1639 p
= (u_int32_t
*)rng
->rng_buf
.dma_vaddr
;
1641 for (i
= 0; i
< UBSEC_RNG_BUFSIZ
; p
++, i
++)
1642 add_true_randomness(letoh32(*p
));
1645 /* XXX NetBSD rnd subsystem too weak */
1646 i
= 0; (void)i
; /* shut off gcc warnings */
1649 timeout_add(&sc
->sc_rngto
, sc
->sc_rnghz
);
1651 callout_reset(&sc
->sc_rngto
, sc
->sc_rnghz
, ubsec_rng
, sc
);
1656 case UBS_CTXOP_MODEXP
: {
1657 struct ubsec_q2_modexp
*me
= (struct ubsec_q2_modexp
*)q
;
1661 rlen
= (me
->me_modbits
+ 7) / 8;
1662 clen
= (krp
->krp_param
[krp
->krp_iparams
].crp_nbits
+ 7) / 8;
1664 bus_dmamap_sync(sc
->sc_dmat
, me
->me_M
.dma_map
,
1665 0, me
->me_M
.dma_map
->dm_mapsize
, BUS_DMASYNC_POSTWRITE
);
1666 bus_dmamap_sync(sc
->sc_dmat
, me
->me_E
.dma_map
,
1667 0, me
->me_E
.dma_map
->dm_mapsize
, BUS_DMASYNC_POSTWRITE
);
1668 bus_dmamap_sync(sc
->sc_dmat
, me
->me_C
.dma_map
,
1669 0, me
->me_C
.dma_map
->dm_mapsize
, BUS_DMASYNC_POSTREAD
);
1670 bus_dmamap_sync(sc
->sc_dmat
, me
->me_epb
.dma_map
,
1671 0, me
->me_epb
.dma_map
->dm_mapsize
, BUS_DMASYNC_POSTWRITE
);
1674 krp
->krp_status
= E2BIG
;
1676 if (sc
->sc_flags
& UBS_FLAGS_HWNORM
) {
1677 memset(krp
->krp_param
[krp
->krp_iparams
].crp_p
, 0,
1678 (krp
->krp_param
[krp
->krp_iparams
].crp_nbits
1680 bcopy(me
->me_C
.dma_vaddr
,
1681 krp
->krp_param
[krp
->krp_iparams
].crp_p
,
1682 (me
->me_modbits
+ 7) / 8);
1684 ubsec_kshift_l(me
->me_shiftbits
,
1685 me
->me_C
.dma_vaddr
, me
->me_normbits
,
1686 krp
->krp_param
[krp
->krp_iparams
].crp_p
,
1687 krp
->krp_param
[krp
->krp_iparams
].crp_nbits
);
1692 /* bzero all potentially sensitive data */
1693 memset(me
->me_E
.dma_vaddr
, 0, me
->me_E
.dma_size
);
1694 memset(me
->me_M
.dma_vaddr
, 0, me
->me_M
.dma_size
);
1695 memset(me
->me_C
.dma_vaddr
, 0, me
->me_C
.dma_size
);
1696 memset(me
->me_q
.q_ctx
.dma_vaddr
, 0, me
->me_q
.q_ctx
.dma_size
);
1698 /* Can't free here, so put us on the free list. */
1699 SIMPLEQ_INSERT_TAIL(&sc
->sc_q2free
, &me
->me_q
, q_next
);
1702 case UBS_CTXOP_RSAPRIV
: {
1703 struct ubsec_q2_rsapriv
*rp
= (struct ubsec_q2_rsapriv
*)q
;
1707 bus_dmamap_sync(sc
->sc_dmat
, rp
->rpr_msgin
.dma_map
, 0,
1708 rp
->rpr_msgin
.dma_map
->dm_mapsize
, BUS_DMASYNC_POSTWRITE
);
1709 bus_dmamap_sync(sc
->sc_dmat
, rp
->rpr_msgout
.dma_map
, 0,
1710 rp
->rpr_msgout
.dma_map
->dm_mapsize
, BUS_DMASYNC_POSTREAD
);
1712 len
= (krp
->krp_param
[UBS_RSAPRIV_PAR_MSGOUT
].crp_nbits
+ 7) / 8;
1713 bcopy(rp
->rpr_msgout
.dma_vaddr
,
1714 krp
->krp_param
[UBS_RSAPRIV_PAR_MSGOUT
].crp_p
, len
);
1718 memset(rp
->rpr_msgin
.dma_vaddr
, 0, rp
->rpr_msgin
.dma_size
);
1719 memset(rp
->rpr_msgout
.dma_vaddr
, 0, rp
->rpr_msgout
.dma_size
);
1720 memset(rp
->rpr_q
.q_ctx
.dma_vaddr
, 0, rp
->rpr_q
.q_ctx
.dma_size
);
1722 /* Can't free here, so put us on the free list. */
1723 SIMPLEQ_INSERT_TAIL(&sc
->sc_q2free
, &rp
->rpr_q
, q_next
);
1727 printf("%s: unknown ctx op: %x\n", device_xname(&sc
->sc_dv
),
1728 letoh16(ctx
->ctx_op
));
1733 #ifndef UBSEC_NO_RNG
1735 ubsec_rng(void *vsc
)
1737 struct ubsec_softc
*sc
= vsc
;
1738 struct ubsec_q2_rng
*rng
= &sc
->sc_rng
;
1739 struct ubsec_mcr
*mcr
;
1740 struct ubsec_ctx_rngbypass
*ctx
;
1744 if (rng
->rng_used
) {
1749 if (sc
->sc_nqueue2
>= UBS_MAX_NQUEUE
)
1752 mcr
= (struct ubsec_mcr
*)rng
->rng_q
.q_mcr
.dma_vaddr
;
1753 ctx
= (struct ubsec_ctx_rngbypass
*)rng
->rng_q
.q_ctx
.dma_vaddr
;
1755 mcr
->mcr_pkts
= htole16(1);
1757 mcr
->mcr_cmdctxp
= htole32(rng
->rng_q
.q_ctx
.dma_paddr
);
1758 mcr
->mcr_ipktbuf
.pb_addr
= mcr
->mcr_ipktbuf
.pb_next
= 0;
1759 mcr
->mcr_ipktbuf
.pb_len
= 0;
1760 mcr
->mcr_reserved
= mcr
->mcr_pktlen
= 0;
1761 mcr
->mcr_opktbuf
.pb_addr
= htole32(rng
->rng_buf
.dma_paddr
);
1762 mcr
->mcr_opktbuf
.pb_len
= htole32(((sizeof(u_int32_t
) * UBSEC_RNG_BUFSIZ
)) &
1764 mcr
->mcr_opktbuf
.pb_next
= 0;
1766 ctx
->rbp_len
= htole16(sizeof(struct ubsec_ctx_rngbypass
));
1767 ctx
->rbp_op
= htole16(UBS_CTXOP_RNGSHA1
);
1768 rng
->rng_q
.q_type
= UBS_CTXOP_RNGSHA1
;
1770 bus_dmamap_sync(sc
->sc_dmat
, rng
->rng_buf
.dma_map
, 0,
1771 rng
->rng_buf
.dma_map
->dm_mapsize
, BUS_DMASYNC_PREREAD
);
1773 SIMPLEQ_INSERT_TAIL(&sc
->sc_queue2
, &rng
->rng_q
, q_next
);
1776 ubsecstats
.hst_rng
++;
1783 * Something weird happened, generate our own call back.
1788 timeout_add(&sc
->sc_rngto
, sc
->sc_rnghz
);
1790 callout_reset(&sc
->sc_rngto
, sc
->sc_rnghz
, ubsec_rng
, sc
);
1793 #endif /* UBSEC_NO_RNG */
1796 ubsec_dma_malloc(struct ubsec_softc
*sc
, bus_size_t size
,
1797 struct ubsec_dma_alloc
*dma
,int mapflags
)
1801 if ((r
= bus_dmamem_alloc(sc
->sc_dmat
, size
, PAGE_SIZE
, 0,
1802 &dma
->dma_seg
, 1, &dma
->dma_nseg
, BUS_DMA_NOWAIT
)) != 0)
1805 if ((r
= bus_dmamem_map(sc
->sc_dmat
, &dma
->dma_seg
, dma
->dma_nseg
,
1806 size
, &dma
->dma_vaddr
, mapflags
| BUS_DMA_NOWAIT
)) != 0)
1809 if ((r
= bus_dmamap_create(sc
->sc_dmat
, size
, 1, size
, 0,
1810 BUS_DMA_NOWAIT
, &dma
->dma_map
)) != 0)
1813 if ((r
= bus_dmamap_load(sc
->sc_dmat
, dma
->dma_map
, dma
->dma_vaddr
,
1814 size
, NULL
, BUS_DMA_NOWAIT
)) != 0)
1817 dma
->dma_paddr
= dma
->dma_map
->dm_segs
[0].ds_addr
;
1818 dma
->dma_size
= size
;
1822 bus_dmamap_destroy(sc
->sc_dmat
, dma
->dma_map
);
1824 bus_dmamem_unmap(sc
->sc_dmat
, dma
->dma_vaddr
, size
);
1826 bus_dmamem_free(sc
->sc_dmat
, &dma
->dma_seg
, dma
->dma_nseg
);
1828 dma
->dma_map
= NULL
;
1833 ubsec_dma_free(struct ubsec_softc
*sc
, struct ubsec_dma_alloc
*dma
)
1835 bus_dmamap_unload(sc
->sc_dmat
, dma
->dma_map
);
1836 bus_dmamem_unmap(sc
->sc_dmat
, dma
->dma_vaddr
, dma
->dma_size
);
1837 bus_dmamem_free(sc
->sc_dmat
, &dma
->dma_seg
, dma
->dma_nseg
);
1838 bus_dmamap_destroy(sc
->sc_dmat
, dma
->dma_map
);
1842 * Resets the board. Values in the regesters are left as is
1843 * from the reset (i.e. initial values are assigned elsewhere).
1846 ubsec_reset_board(struct ubsec_softc
*sc
)
1848 volatile u_int32_t ctrl
;
1850 ctrl
= READ_REG(sc
, BS_CTRL
);
1851 ctrl
|= BS_CTRL_RESET
;
1852 WRITE_REG(sc
, BS_CTRL
, ctrl
);
1855 * Wait aprox. 30 PCI clocks = 900 ns = 0.9 us
1861 * Init Broadcom registers
1864 ubsec_init_board(struct ubsec_softc
*sc
)
1868 ctrl
= READ_REG(sc
, BS_CTRL
);
1869 ctrl
&= ~(BS_CTRL_BE32
| BS_CTRL_BE64
);
1870 ctrl
|= BS_CTRL_LITTLE_ENDIAN
| BS_CTRL_MCR1INT
;
1873 * XXX: Sam Leffler's code has (UBS_FLAGS_KEY|UBS_FLAGS_RNG)).
1874 * anyone got hw docs?
1876 if (sc
->sc_flags
& UBS_FLAGS_KEY
)
1877 ctrl
|= BS_CTRL_MCR2INT
;
1879 ctrl
&= ~BS_CTRL_MCR2INT
;
1881 if (sc
->sc_flags
& UBS_FLAGS_HWNORM
)
1882 ctrl
&= ~BS_CTRL_SWNORM
;
1884 WRITE_REG(sc
, BS_CTRL
, ctrl
);
1888 * Init Broadcom PCI registers
1891 ubsec_init_pciregs(struct pci_attach_args
*pa
)
1893 pci_chipset_tag_t pc
= pa
->pa_pc
;
1897 * This will set the cache line size to 1, this will
1898 * force the BCM58xx chip just to do burst read/writes.
1899 * Cache line read/writes are to slow
1901 misc
= pci_conf_read(pc
, pa
->pa_tag
, PCI_BHLC_REG
);
1902 misc
= (misc
& ~(PCI_CACHELINE_MASK
<< PCI_CACHELINE_SHIFT
))
1903 | ((UBS_DEF_CACHELINE
& 0xff) << PCI_CACHELINE_SHIFT
);
1904 pci_conf_write(pc
, pa
->pa_tag
, PCI_BHLC_REG
, misc
);
1908 * Clean up after a chip crash.
1909 * It is assumed that the caller in splnet()
1912 ubsec_cleanchip(struct ubsec_softc
*sc
)
1916 while (!SIMPLEQ_EMPTY(&sc
->sc_qchip
)) {
1917 q
= SIMPLEQ_FIRST(&sc
->sc_qchip
);
1918 SIMPLEQ_REMOVE_HEAD(&sc
->sc_qchip
, /*q,*/ q_next
);
1919 ubsec_free_q(sc
, q
);
1926 * It is assumed that the caller is within splnet()
1929 ubsec_free_q(struct ubsec_softc
*sc
, struct ubsec_q
*q
)
1932 struct cryptop
*crp
;
1936 npkts
= q
->q_nstacked_mcrs
;
1938 for (i
= 0; i
< npkts
; i
++) {
1939 if(q
->q_stacked_mcr
[i
]) {
1940 q2
= q
->q_stacked_mcr
[i
];
1942 if ((q2
->q_dst_m
!= NULL
) && (q2
->q_src_m
!= q2
->q_dst_m
))
1943 m_freem(q2
->q_dst_m
);
1945 crp
= (struct cryptop
*)q2
->q_crp
;
1947 SIMPLEQ_INSERT_TAIL(&sc
->sc_freequeue
, q2
, q_next
);
1949 crp
->crp_etype
= EFAULT
;
1959 if ((q
->q_dst_m
!= NULL
) && (q
->q_src_m
!= q
->q_dst_m
))
1960 m_freem(q
->q_dst_m
);
1962 crp
= (struct cryptop
*)q
->q_crp
;
1964 SIMPLEQ_INSERT_TAIL(&sc
->sc_freequeue
, q
, q_next
);
1966 crp
->crp_etype
= EFAULT
;
1972 * Routine to reset the chip and clean up.
1973 * It is assumed that the caller is in splnet()
1976 ubsec_totalreset(struct ubsec_softc
*sc
)
1978 ubsec_reset_board(sc
);
1979 ubsec_init_board(sc
);
1980 ubsec_cleanchip(sc
);
1984 ubsec_dmamap_aligned(bus_dmamap_t map
)
1988 for (i
= 0; i
< map
->dm_nsegs
; i
++) {
1989 if (map
->dm_segs
[i
].ds_addr
& 3)
1991 if ((i
!= (map
->dm_nsegs
- 1)) &&
1992 (map
->dm_segs
[i
].ds_len
& 3))
1999 struct ubsec_softc
*
2000 ubsec_kfind(struct cryptkop
*krp
)
2002 struct ubsec_softc
*sc
;
2005 for (i
= 0; i
< ubsec_cd
.cd_ndevs
; i
++) {
2006 sc
= ubsec_cd
.cd_devs
[i
];
2009 if (sc
->sc_cid
== krp
->krp_hid
)
2017 ubsec_kfree(struct ubsec_softc
*sc
, struct ubsec_q2
*q
)
2019 switch (q
->q_type
) {
2020 case UBS_CTXOP_MODEXP
: {
2021 struct ubsec_q2_modexp
*me
= (struct ubsec_q2_modexp
*)q
;
2023 ubsec_dma_free(sc
, &me
->me_q
.q_mcr
);
2024 ubsec_dma_free(sc
, &me
->me_q
.q_ctx
);
2025 ubsec_dma_free(sc
, &me
->me_M
);
2026 ubsec_dma_free(sc
, &me
->me_E
);
2027 ubsec_dma_free(sc
, &me
->me_C
);
2028 ubsec_dma_free(sc
, &me
->me_epb
);
2032 case UBS_CTXOP_RSAPRIV
: {
2033 struct ubsec_q2_rsapriv
*rp
= (struct ubsec_q2_rsapriv
*)q
;
2035 ubsec_dma_free(sc
, &rp
->rpr_q
.q_mcr
);
2036 ubsec_dma_free(sc
, &rp
->rpr_q
.q_ctx
);
2037 ubsec_dma_free(sc
, &rp
->rpr_msgin
);
2038 ubsec_dma_free(sc
, &rp
->rpr_msgout
);
2043 printf("%s: invalid kfree 0x%x\n", device_xname(&sc
->sc_dv
),
2050 ubsec_kprocess(void *arg
, struct cryptkop
*krp
, int hint
)
2052 struct ubsec_softc
*sc
;
2055 if (krp
== NULL
|| krp
->krp_callback
== NULL
)
2058 if ((sc
= ubsec_kfind(krp
)) == NULL
)
2062 KASSERT(sc
!= NULL
/*, ("ubsec_kprocess: null softc")*/);
2065 while (!SIMPLEQ_EMPTY(&sc
->sc_q2free
)) {
2068 q
= SIMPLEQ_FIRST(&sc
->sc_q2free
);
2069 SIMPLEQ_REMOVE_HEAD(&sc
->sc_q2free
, /*q,*/ q_next
);
2073 switch (krp
->krp_op
) {
2075 if (sc
->sc_flags
& UBS_FLAGS_HWNORM
)
2076 r
= ubsec_kprocess_modexp_hw(sc
, krp
, hint
);
2078 r
= ubsec_kprocess_modexp_sw(sc
, krp
, hint
);
2080 case CRK_MOD_EXP_CRT
:
2081 r
= ubsec_kprocess_rsapriv(sc
, krp
, hint
);
2084 printf("%s: kprocess: invalid op 0x%x\n",
2085 device_xname(&sc
->sc_dv
), krp
->krp_op
);
2086 krp
->krp_status
= EOPNOTSUPP
;
2094 * Start computation of cr[C] = (cr[M] ^ cr[E]) mod cr[N] (sw normalization)
2097 ubsec_kprocess_modexp_sw(struct ubsec_softc
*sc
, struct cryptkop
*krp
,
2100 struct ubsec_q2_modexp
*me
;
2101 struct ubsec_mcr
*mcr
;
2102 struct ubsec_ctx_modexp
*ctx
;
2103 struct ubsec_pktbuf
*epb
;
2105 u_int nbits
, normbits
, mbits
, shiftbits
, ebits
;
2107 me
= (struct ubsec_q2_modexp
*)malloc(sizeof *me
, M_DEVBUF
, M_NOWAIT
);
2112 memset(me
, 0, sizeof *me
);
2114 me
->me_q
.q_type
= UBS_CTXOP_MODEXP
;
2116 nbits
= ubsec_ksigbits(&krp
->krp_param
[UBS_MODEXP_PAR_N
]);
2119 else if (nbits
<= 768)
2121 else if (nbits
<= 1024)
2123 else if (sc
->sc_flags
& UBS_FLAGS_BIGKEY
&& nbits
<= 1536)
2125 else if (sc
->sc_flags
& UBS_FLAGS_BIGKEY
&& nbits
<= 2048)
2132 shiftbits
= normbits
- nbits
;
2134 me
->me_modbits
= nbits
;
2135 me
->me_shiftbits
= shiftbits
;
2136 me
->me_normbits
= normbits
;
2138 /* Sanity check: result bits must be >= true modulus bits. */
2139 if (krp
->krp_param
[krp
->krp_iparams
].crp_nbits
< nbits
) {
2144 if (ubsec_dma_malloc(sc
, sizeof(struct ubsec_mcr
),
2145 &me
->me_q
.q_mcr
, 0)) {
2149 mcr
= (struct ubsec_mcr
*)me
->me_q
.q_mcr
.dma_vaddr
;
2151 if (ubsec_dma_malloc(sc
, sizeof(struct ubsec_ctx_modexp
),
2152 &me
->me_q
.q_ctx
, 0)) {
2157 mbits
= ubsec_ksigbits(&krp
->krp_param
[UBS_MODEXP_PAR_M
]);
2158 if (mbits
> nbits
) {
2162 if (ubsec_dma_malloc(sc
, normbits
/ 8, &me
->me_M
, 0)) {
2166 ubsec_kshift_r(shiftbits
,
2167 krp
->krp_param
[UBS_MODEXP_PAR_M
].crp_p
, mbits
,
2168 me
->me_M
.dma_vaddr
, normbits
);
2170 if (ubsec_dma_malloc(sc
, normbits
/ 8, &me
->me_C
, 0)) {
2174 memset(me
->me_C
.dma_vaddr
, 0, me
->me_C
.dma_size
);
2176 ebits
= ubsec_ksigbits(&krp
->krp_param
[UBS_MODEXP_PAR_E
]);
2177 if (ebits
> nbits
) {
2181 if (ubsec_dma_malloc(sc
, normbits
/ 8, &me
->me_E
, 0)) {
2185 ubsec_kshift_r(shiftbits
,
2186 krp
->krp_param
[UBS_MODEXP_PAR_E
].crp_p
, ebits
,
2187 me
->me_E
.dma_vaddr
, normbits
);
2189 if (ubsec_dma_malloc(sc
, sizeof(struct ubsec_pktbuf
),
2194 epb
= (struct ubsec_pktbuf
*)me
->me_epb
.dma_vaddr
;
2195 epb
->pb_addr
= htole32(me
->me_E
.dma_paddr
);
2197 epb
->pb_len
= htole32(normbits
/ 8);
2206 mcr
->mcr_pkts
= htole16(1);
2208 mcr
->mcr_cmdctxp
= htole32(me
->me_q
.q_ctx
.dma_paddr
);
2209 mcr
->mcr_reserved
= 0;
2210 mcr
->mcr_pktlen
= 0;
2212 mcr
->mcr_ipktbuf
.pb_addr
= htole32(me
->me_M
.dma_paddr
);
2213 mcr
->mcr_ipktbuf
.pb_len
= htole32(normbits
/ 8);
2214 mcr
->mcr_ipktbuf
.pb_next
= htole32(me
->me_epb
.dma_paddr
);
2216 mcr
->mcr_opktbuf
.pb_addr
= htole32(me
->me_C
.dma_paddr
);
2217 mcr
->mcr_opktbuf
.pb_next
= 0;
2218 mcr
->mcr_opktbuf
.pb_len
= htole32(normbits
/ 8);
2221 /* Misaligned output buffer will hang the chip. */
2222 if ((letoh32(mcr
->mcr_opktbuf
.pb_addr
) & 3) != 0)
2223 panic("%s: modexp invalid addr 0x%x",
2224 device_xname(&sc
->sc_dv
), letoh32(mcr
->mcr_opktbuf
.pb_addr
));
2225 if ((letoh32(mcr
->mcr_opktbuf
.pb_len
) & 3) != 0)
2226 panic("%s: modexp invalid len 0x%x",
2227 device_xname(&sc
->sc_dv
), letoh32(mcr
->mcr_opktbuf
.pb_len
));
2230 ctx
= (struct ubsec_ctx_modexp
*)me
->me_q
.q_ctx
.dma_vaddr
;
2231 memset(ctx
, 0, sizeof(*ctx
));
2232 ubsec_kshift_r(shiftbits
,
2233 krp
->krp_param
[UBS_MODEXP_PAR_N
].crp_p
, nbits
,
2234 ctx
->me_N
, normbits
);
2235 ctx
->me_len
= htole16((normbits
/ 8) + (4 * sizeof(u_int16_t
)));
2236 ctx
->me_op
= htole16(UBS_CTXOP_MODEXP
);
2237 ctx
->me_E_len
= htole16(nbits
);
2238 ctx
->me_N_len
= htole16(nbits
);
2242 ubsec_dump_mcr(mcr
);
2243 ubsec_dump_ctx2((struct ubsec_ctx_keyop
*)ctx
);
2248 * ubsec_feed2 will sync mcr and ctx, we just need to sync
2251 bus_dmamap_sync(sc
->sc_dmat
, me
->me_M
.dma_map
,
2252 0, me
->me_M
.dma_map
->dm_mapsize
, BUS_DMASYNC_PREWRITE
);
2253 bus_dmamap_sync(sc
->sc_dmat
, me
->me_E
.dma_map
,
2254 0, me
->me_E
.dma_map
->dm_mapsize
, BUS_DMASYNC_PREWRITE
);
2255 bus_dmamap_sync(sc
->sc_dmat
, me
->me_C
.dma_map
,
2256 0, me
->me_C
.dma_map
->dm_mapsize
, BUS_DMASYNC_PREREAD
);
2257 bus_dmamap_sync(sc
->sc_dmat
, me
->me_epb
.dma_map
,
2258 0, me
->me_epb
.dma_map
->dm_mapsize
, BUS_DMASYNC_PREWRITE
);
2260 /* Enqueue and we're done... */
2262 SIMPLEQ_INSERT_TAIL(&sc
->sc_queue2
, &me
->me_q
, q_next
);
2264 ubsecstats
.hst_modexp
++;
2271 if (me
->me_q
.q_mcr
.dma_map
!= NULL
)
2272 ubsec_dma_free(sc
, &me
->me_q
.q_mcr
);
2273 if (me
->me_q
.q_ctx
.dma_map
!= NULL
) {
2274 memset(me
->me_q
.q_ctx
.dma_vaddr
, 0, me
->me_q
.q_ctx
.dma_size
);
2275 ubsec_dma_free(sc
, &me
->me_q
.q_ctx
);
2277 if (me
->me_M
.dma_map
!= NULL
) {
2278 memset(me
->me_M
.dma_vaddr
, 0, me
->me_M
.dma_size
);
2279 ubsec_dma_free(sc
, &me
->me_M
);
2281 if (me
->me_E
.dma_map
!= NULL
) {
2282 memset(me
->me_E
.dma_vaddr
, 0, me
->me_E
.dma_size
);
2283 ubsec_dma_free(sc
, &me
->me_E
);
2285 if (me
->me_C
.dma_map
!= NULL
) {
2286 memset(me
->me_C
.dma_vaddr
, 0, me
->me_C
.dma_size
);
2287 ubsec_dma_free(sc
, &me
->me_C
);
2289 if (me
->me_epb
.dma_map
!= NULL
)
2290 ubsec_dma_free(sc
, &me
->me_epb
);
2293 krp
->krp_status
= err
;
2299 * Start computation of cr[C] = (cr[M] ^ cr[E]) mod cr[N] (hw normalization)
2302 ubsec_kprocess_modexp_hw(struct ubsec_softc
*sc
, struct cryptkop
*krp
,
2305 struct ubsec_q2_modexp
*me
;
2306 struct ubsec_mcr
*mcr
;
2307 struct ubsec_ctx_modexp
*ctx
;
2308 struct ubsec_pktbuf
*epb
;
2310 u_int nbits
, normbits
, mbits
, shiftbits
, ebits
;
2312 me
= (struct ubsec_q2_modexp
*)malloc(sizeof *me
, M_DEVBUF
, M_NOWAIT
);
2317 memset(me
, 0, sizeof *me
);
2319 me
->me_q
.q_type
= UBS_CTXOP_MODEXP
;
2321 nbits
= ubsec_ksigbits(&krp
->krp_param
[UBS_MODEXP_PAR_N
]);
2324 else if (nbits
<= 768)
2326 else if (nbits
<= 1024)
2328 else if (sc
->sc_flags
& UBS_FLAGS_BIGKEY
&& nbits
<= 1536)
2330 else if (sc
->sc_flags
& UBS_FLAGS_BIGKEY
&& nbits
<= 2048)
2337 shiftbits
= normbits
- nbits
;
2340 me
->me_modbits
= nbits
;
2341 me
->me_shiftbits
= shiftbits
;
2342 me
->me_normbits
= normbits
;
2344 /* Sanity check: result bits must be >= true modulus bits. */
2345 if (krp
->krp_param
[krp
->krp_iparams
].crp_nbits
< nbits
) {
2350 if (ubsec_dma_malloc(sc
, sizeof(struct ubsec_mcr
),
2351 &me
->me_q
.q_mcr
, 0)) {
2355 mcr
= (struct ubsec_mcr
*)me
->me_q
.q_mcr
.dma_vaddr
;
2357 if (ubsec_dma_malloc(sc
, sizeof(struct ubsec_ctx_modexp
),
2358 &me
->me_q
.q_ctx
, 0)) {
2363 mbits
= ubsec_ksigbits(&krp
->krp_param
[UBS_MODEXP_PAR_M
]);
2364 if (mbits
> nbits
) {
2368 if (ubsec_dma_malloc(sc
, normbits
/ 8, &me
->me_M
, 0)) {
2372 memset(me
->me_M
.dma_vaddr
, 0, normbits
/ 8);
2373 bcopy(krp
->krp_param
[UBS_MODEXP_PAR_M
].crp_p
,
2374 me
->me_M
.dma_vaddr
, (mbits
+ 7) / 8);
2376 if (ubsec_dma_malloc(sc
, normbits
/ 8, &me
->me_C
, 0)) {
2380 memset(me
->me_C
.dma_vaddr
, 0, me
->me_C
.dma_size
);
2382 ebits
= ubsec_ksigbits(&krp
->krp_param
[UBS_MODEXP_PAR_E
]);
2383 if (ebits
> nbits
) {
2387 if (ubsec_dma_malloc(sc
, normbits
/ 8, &me
->me_E
, 0)) {
2391 memset(me
->me_E
.dma_vaddr
, 0, normbits
/ 8);
2392 bcopy(krp
->krp_param
[UBS_MODEXP_PAR_E
].crp_p
,
2393 me
->me_E
.dma_vaddr
, (ebits
+ 7) / 8);
2395 if (ubsec_dma_malloc(sc
, sizeof(struct ubsec_pktbuf
),
2400 epb
= (struct ubsec_pktbuf
*)me
->me_epb
.dma_vaddr
;
2401 epb
->pb_addr
= htole32(me
->me_E
.dma_paddr
);
2403 epb
->pb_len
= htole32((ebits
+ 7) / 8);
2412 mcr
->mcr_pkts
= htole16(1);
2414 mcr
->mcr_cmdctxp
= htole32(me
->me_q
.q_ctx
.dma_paddr
);
2415 mcr
->mcr_reserved
= 0;
2416 mcr
->mcr_pktlen
= 0;
2418 mcr
->mcr_ipktbuf
.pb_addr
= htole32(me
->me_M
.dma_paddr
);
2419 mcr
->mcr_ipktbuf
.pb_len
= htole32(normbits
/ 8);
2420 mcr
->mcr_ipktbuf
.pb_next
= htole32(me
->me_epb
.dma_paddr
);
2422 mcr
->mcr_opktbuf
.pb_addr
= htole32(me
->me_C
.dma_paddr
);
2423 mcr
->mcr_opktbuf
.pb_next
= 0;
2424 mcr
->mcr_opktbuf
.pb_len
= htole32(normbits
/ 8);
2427 /* Misaligned output buffer will hang the chip. */
2428 if ((letoh32(mcr
->mcr_opktbuf
.pb_addr
) & 3) != 0)
2429 panic("%s: modexp invalid addr 0x%x",
2430 device_xname(&sc
->sc_dv
), letoh32(mcr
->mcr_opktbuf
.pb_addr
));
2431 if ((letoh32(mcr
->mcr_opktbuf
.pb_len
) & 3) != 0)
2432 panic("%s: modexp invalid len 0x%x",
2433 device_xname(&sc
->sc_dv
), letoh32(mcr
->mcr_opktbuf
.pb_len
));
2436 ctx
= (struct ubsec_ctx_modexp
*)me
->me_q
.q_ctx
.dma_vaddr
;
2437 memset(ctx
, 0, sizeof(*ctx
));
2438 memcpy(ctx
->me_N
, krp
->krp_param
[UBS_MODEXP_PAR_N
].crp_p
,
2440 ctx
->me_len
= htole16((normbits
/ 8) + (4 * sizeof(u_int16_t
)));
2441 ctx
->me_op
= htole16(UBS_CTXOP_MODEXP
);
2442 ctx
->me_E_len
= htole16(ebits
);
2443 ctx
->me_N_len
= htole16(nbits
);
2447 ubsec_dump_mcr(mcr
);
2448 ubsec_dump_ctx2((struct ubsec_ctx_keyop
*)ctx
);
2453 * ubsec_feed2 will sync mcr and ctx, we just need to sync
2456 bus_dmamap_sync(sc
->sc_dmat
, me
->me_M
.dma_map
,
2457 0, me
->me_M
.dma_map
->dm_mapsize
, BUS_DMASYNC_PREWRITE
);
2458 bus_dmamap_sync(sc
->sc_dmat
, me
->me_E
.dma_map
,
2459 0, me
->me_E
.dma_map
->dm_mapsize
, BUS_DMASYNC_PREWRITE
);
2460 bus_dmamap_sync(sc
->sc_dmat
, me
->me_C
.dma_map
,
2461 0, me
->me_C
.dma_map
->dm_mapsize
, BUS_DMASYNC_PREREAD
);
2462 bus_dmamap_sync(sc
->sc_dmat
, me
->me_epb
.dma_map
,
2463 0, me
->me_epb
.dma_map
->dm_mapsize
, BUS_DMASYNC_PREWRITE
);
2465 /* Enqueue and we're done... */
2467 SIMPLEQ_INSERT_TAIL(&sc
->sc_queue2
, &me
->me_q
, q_next
);
2475 if (me
->me_q
.q_mcr
.dma_map
!= NULL
)
2476 ubsec_dma_free(sc
, &me
->me_q
.q_mcr
);
2477 if (me
->me_q
.q_ctx
.dma_map
!= NULL
) {
2478 memset(me
->me_q
.q_ctx
.dma_vaddr
, 0, me
->me_q
.q_ctx
.dma_size
);
2479 ubsec_dma_free(sc
, &me
->me_q
.q_ctx
);
2481 if (me
->me_M
.dma_map
!= NULL
) {
2482 memset(me
->me_M
.dma_vaddr
, 0, me
->me_M
.dma_size
);
2483 ubsec_dma_free(sc
, &me
->me_M
);
2485 if (me
->me_E
.dma_map
!= NULL
) {
2486 memset(me
->me_E
.dma_vaddr
, 0, me
->me_E
.dma_size
);
2487 ubsec_dma_free(sc
, &me
->me_E
);
2489 if (me
->me_C
.dma_map
!= NULL
) {
2490 memset(me
->me_C
.dma_vaddr
, 0, me
->me_C
.dma_size
);
2491 ubsec_dma_free(sc
, &me
->me_C
);
2493 if (me
->me_epb
.dma_map
!= NULL
)
2494 ubsec_dma_free(sc
, &me
->me_epb
);
2497 krp
->krp_status
= err
;
2503 ubsec_kprocess_rsapriv(struct ubsec_softc
*sc
, struct cryptkop
*krp
,
2506 struct ubsec_q2_rsapriv
*rp
= NULL
;
2507 struct ubsec_mcr
*mcr
;
2508 struct ubsec_ctx_rsapriv
*ctx
;
2510 u_int padlen
, msglen
;
2512 msglen
= ubsec_ksigbits(&krp
->krp_param
[UBS_RSAPRIV_PAR_P
]);
2513 padlen
= ubsec_ksigbits(&krp
->krp_param
[UBS_RSAPRIV_PAR_Q
]);
2514 if (msglen
> padlen
)
2519 else if (padlen
<= 384)
2521 else if (padlen
<= 512)
2523 else if (sc
->sc_flags
& UBS_FLAGS_BIGKEY
&& padlen
<= 768)
2525 else if (sc
->sc_flags
& UBS_FLAGS_BIGKEY
&& padlen
<= 1024)
2532 if (ubsec_ksigbits(&krp
->krp_param
[UBS_RSAPRIV_PAR_DP
]) > padlen
) {
2537 if (ubsec_ksigbits(&krp
->krp_param
[UBS_RSAPRIV_PAR_DQ
]) > padlen
) {
2542 if (ubsec_ksigbits(&krp
->krp_param
[UBS_RSAPRIV_PAR_PINV
]) > padlen
) {
2547 rp
= malloc(sizeof *rp
, M_DEVBUF
, M_NOWAIT
|M_ZERO
);
2551 rp
->rpr_q
.q_type
= UBS_CTXOP_RSAPRIV
;
2553 if (ubsec_dma_malloc(sc
, sizeof(struct ubsec_mcr
),
2554 &rp
->rpr_q
.q_mcr
, 0)) {
2558 mcr
= (struct ubsec_mcr
*)rp
->rpr_q
.q_mcr
.dma_vaddr
;
2560 if (ubsec_dma_malloc(sc
, sizeof(struct ubsec_ctx_rsapriv
),
2561 &rp
->rpr_q
.q_ctx
, 0)) {
2565 ctx
= (struct ubsec_ctx_rsapriv
*)rp
->rpr_q
.q_ctx
.dma_vaddr
;
2566 memset(ctx
, 0, sizeof *ctx
);
2569 bcopy(krp
->krp_param
[UBS_RSAPRIV_PAR_P
].crp_p
,
2570 &ctx
->rpr_buf
[0 * (padlen
/ 8)],
2571 (krp
->krp_param
[UBS_RSAPRIV_PAR_P
].crp_nbits
+ 7) / 8);
2574 bcopy(krp
->krp_param
[UBS_RSAPRIV_PAR_Q
].crp_p
,
2575 &ctx
->rpr_buf
[1 * (padlen
/ 8)],
2576 (krp
->krp_param
[UBS_RSAPRIV_PAR_Q
].crp_nbits
+ 7) / 8);
2579 bcopy(krp
->krp_param
[UBS_RSAPRIV_PAR_DP
].crp_p
,
2580 &ctx
->rpr_buf
[2 * (padlen
/ 8)],
2581 (krp
->krp_param
[UBS_RSAPRIV_PAR_DP
].crp_nbits
+ 7) / 8);
2584 bcopy(krp
->krp_param
[UBS_RSAPRIV_PAR_DQ
].crp_p
,
2585 &ctx
->rpr_buf
[3 * (padlen
/ 8)],
2586 (krp
->krp_param
[UBS_RSAPRIV_PAR_DQ
].crp_nbits
+ 7) / 8);
2589 bcopy(krp
->krp_param
[UBS_RSAPRIV_PAR_PINV
].crp_p
,
2590 &ctx
->rpr_buf
[4 * (padlen
/ 8)],
2591 (krp
->krp_param
[UBS_RSAPRIV_PAR_PINV
].crp_nbits
+ 7) / 8);
2593 msglen
= padlen
* 2;
2595 /* Copy in input message (aligned buffer/length). */
2596 if (ubsec_ksigbits(&krp
->krp_param
[UBS_RSAPRIV_PAR_MSGIN
]) > msglen
) {
2597 /* Is this likely? */
2601 if (ubsec_dma_malloc(sc
, (msglen
+ 7) / 8, &rp
->rpr_msgin
, 0)) {
2605 memset(rp
->rpr_msgin
.dma_vaddr
, 0, (msglen
+ 7) / 8);
2606 bcopy(krp
->krp_param
[UBS_RSAPRIV_PAR_MSGIN
].crp_p
,
2607 rp
->rpr_msgin
.dma_vaddr
,
2608 (krp
->krp_param
[UBS_RSAPRIV_PAR_MSGIN
].crp_nbits
+ 7) / 8);
2610 /* Prepare space for output message (aligned buffer/length). */
2611 if (ubsec_ksigbits(&krp
->krp_param
[UBS_RSAPRIV_PAR_MSGOUT
]) < msglen
) {
2612 /* Is this likely? */
2616 if (ubsec_dma_malloc(sc
, (msglen
+ 7) / 8, &rp
->rpr_msgout
, 0)) {
2620 memset(rp
->rpr_msgout
.dma_vaddr
, 0, (msglen
+ 7) / 8);
2622 mcr
->mcr_pkts
= htole16(1);
2624 mcr
->mcr_cmdctxp
= htole32(rp
->rpr_q
.q_ctx
.dma_paddr
);
2625 mcr
->mcr_ipktbuf
.pb_addr
= htole32(rp
->rpr_msgin
.dma_paddr
);
2626 mcr
->mcr_ipktbuf
.pb_next
= 0;
2627 mcr
->mcr_ipktbuf
.pb_len
= htole32(rp
->rpr_msgin
.dma_size
);
2628 mcr
->mcr_reserved
= 0;
2629 mcr
->mcr_pktlen
= htole16(msglen
);
2630 mcr
->mcr_opktbuf
.pb_addr
= htole32(rp
->rpr_msgout
.dma_paddr
);
2631 mcr
->mcr_opktbuf
.pb_next
= 0;
2632 mcr
->mcr_opktbuf
.pb_len
= htole32(rp
->rpr_msgout
.dma_size
);
2635 if (rp
->rpr_msgin
.dma_paddr
& 3 || rp
->rpr_msgin
.dma_size
& 3) {
2636 panic("%s: rsapriv: invalid msgin 0x%lx(0x%lx)",
2637 device_xname(&sc
->sc_dv
), (u_long
) rp
->rpr_msgin
.dma_paddr
,
2638 (u_long
) rp
->rpr_msgin
.dma_size
);
2640 if (rp
->rpr_msgout
.dma_paddr
& 3 || rp
->rpr_msgout
.dma_size
& 3) {
2641 panic("%s: rsapriv: invalid msgout 0x%lx(0x%lx)",
2642 device_xname(&sc
->sc_dv
), (u_long
) rp
->rpr_msgout
.dma_paddr
,
2643 (u_long
) rp
->rpr_msgout
.dma_size
);
2647 ctx
->rpr_len
= (sizeof(u_int16_t
) * 4) + (5 * (padlen
/ 8));
2648 ctx
->rpr_op
= htole16(UBS_CTXOP_RSAPRIV
);
2649 ctx
->rpr_q_len
= htole16(padlen
);
2650 ctx
->rpr_p_len
= htole16(padlen
);
2653 * ubsec_feed2 will sync mcr and ctx, we just need to sync
2656 bus_dmamap_sync(sc
->sc_dmat
, rp
->rpr_msgin
.dma_map
,
2657 0, rp
->rpr_msgin
.dma_map
->dm_mapsize
, BUS_DMASYNC_PREWRITE
);
2658 bus_dmamap_sync(sc
->sc_dmat
, rp
->rpr_msgout
.dma_map
,
2659 0, rp
->rpr_msgout
.dma_map
->dm_mapsize
, BUS_DMASYNC_PREREAD
);
2661 /* Enqueue and we're done... */
2663 SIMPLEQ_INSERT_TAIL(&sc
->sc_queue2
, &rp
->rpr_q
, q_next
);
2665 ubsecstats
.hst_modexpcrt
++;
2671 if (rp
->rpr_q
.q_mcr
.dma_map
!= NULL
)
2672 ubsec_dma_free(sc
, &rp
->rpr_q
.q_mcr
);
2673 if (rp
->rpr_msgin
.dma_map
!= NULL
) {
2674 memset(rp
->rpr_msgin
.dma_vaddr
, 0, rp
->rpr_msgin
.dma_size
);
2675 ubsec_dma_free(sc
, &rp
->rpr_msgin
);
2677 if (rp
->rpr_msgout
.dma_map
!= NULL
) {
2678 memset(rp
->rpr_msgout
.dma_vaddr
, 0, rp
->rpr_msgout
.dma_size
);
2679 ubsec_dma_free(sc
, &rp
->rpr_msgout
);
2683 krp
->krp_status
= err
;
2690 ubsec_dump_pb(volatile struct ubsec_pktbuf
*pb
)
2692 printf("addr 0x%x (0x%x) next 0x%x\n",
2693 pb
->pb_addr
, pb
->pb_len
, pb
->pb_next
);
2697 ubsec_dump_ctx2(volatile struct ubsec_ctx_keyop
*c
)
2699 printf("CTX (0x%x):\n", c
->ctx_len
);
2700 switch (letoh16(c
->ctx_op
)) {
2701 case UBS_CTXOP_RNGBYPASS
:
2702 case UBS_CTXOP_RNGSHA1
:
2704 case UBS_CTXOP_MODEXP
:
2706 struct ubsec_ctx_modexp
*cx
= (void *)c
;
2709 printf(" Elen %u, Nlen %u\n",
2710 letoh16(cx
->me_E_len
), letoh16(cx
->me_N_len
));
2711 len
= (cx
->me_N_len
+ 7)/8;
2712 for (i
= 0; i
< len
; i
++)
2713 printf("%s%02x", (i
== 0) ? " N: " : ":", cx
->me_N
[i
]);
2718 printf("unknown context: %x\n", c
->ctx_op
);
2720 printf("END CTX\n");
2724 ubsec_dump_mcr(struct ubsec_mcr
*mcr
)
2726 volatile struct ubsec_mcr_add
*ma
;
2730 printf(" pkts: %u, flags 0x%x\n",
2731 letoh16(mcr
->mcr_pkts
), letoh16(mcr
->mcr_flags
));
2732 ma
= (volatile struct ubsec_mcr_add
*)&mcr
->mcr_cmdctxp
;
2733 for (i
= 0; i
< letoh16(mcr
->mcr_pkts
); i
++) {
2734 printf(" %d: ctx 0x%x len 0x%x rsvd 0x%x\n", i
,
2735 letoh32(ma
->mcr_cmdctxp
), letoh16(ma
->mcr_pktlen
),
2736 letoh16(ma
->mcr_reserved
));
2737 printf(" %d: ipkt ", i
);
2738 ubsec_dump_pb(&ma
->mcr_ipktbuf
);
2739 printf(" %d: opkt ", i
);
2740 ubsec_dump_pb(&ma
->mcr_opktbuf
);
2743 printf("END MCR\n");
2745 #endif /* UBSEC_DEBUG */
2748 * Return the number of significant bits of a big number.
2751 ubsec_ksigbits(struct crparam
*cr
)
2753 u_int plen
= (cr
->crp_nbits
+ 7) / 8;
2754 int i
, sig
= plen
* 8;
2755 u_int8_t c
, *p
= cr
->crp_p
;
2757 for (i
= plen
- 1; i
>= 0; i
--) {
2760 while ((c
& 0x80) == 0) {
2772 ubsec_kshift_r(u_int shiftbits
, u_int8_t
*src
, u_int srcbits
,
2773 u_int8_t
*dst
, u_int dstbits
)
2778 slen
= (srcbits
+ 7) / 8;
2779 dlen
= (dstbits
+ 7) / 8;
2781 for (i
= 0; i
< slen
; i
++)
2783 for (i
= 0; i
< dlen
- slen
; i
++)
2791 dst
[di
--] = dst
[si
--];
2798 for (i
= dlen
- 1; i
> 0; i
--)
2799 dst
[i
] = (dst
[i
] << n
) |
2800 (dst
[i
- 1] >> (8 - n
));
2801 dst
[0] = dst
[0] << n
;
2806 ubsec_kshift_l(u_int shiftbits
, u_int8_t
*src
, u_int srcbits
,
2807 u_int8_t
*dst
, u_int dstbits
)
2809 int slen
, dlen
, i
, n
;
2811 slen
= (srcbits
+ 7) / 8;
2812 dlen
= (dstbits
+ 7) / 8;
2815 for (i
= 0; i
< slen
; i
++)
2816 dst
[i
] = src
[i
+ n
];
2817 for (i
= 0; i
< dlen
- slen
; i
++)
2822 for (i
= 0; i
< (dlen
- 1); i
++)
2823 dst
[i
] = (dst
[i
] >> n
) | (dst
[i
+ 1] << (8 - n
));
2824 dst
[dlen
- 1] = dst
[dlen
- 1] >> n
;