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