1 /** $MirOS: src/sys/dev/pci/ises.c,v 1.3 2011/11/20 18:54:47 tg Exp $ */
2 /* $OpenBSD: ises.c,v 1.27 2004/05/07 14:42:26 millert Exp $ */
3
4 /*
5 * Copyright (c) 2000, 2001 H�kan Olsson (ho@crt.se)
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /*
31 * PCC-ISES hardware crypto accelerator
32 */
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/proc.h>
37 #include <sys/errno.h>
38 #include <sys/malloc.h>
39 #include <sys/kernel.h>
40 #include <sys/mbuf.h>
41 #include <sys/timeout.h>
42 #include <sys/device.h>
43 #include <sys/queue.h>
44
45 #include <crypto/cryptodev.h>
46 #include <crypto/cryptosoft.h>
47 #include <dev/rndvar.h>
48 #include <syskern/md5.h>
49 #include <crypto/sha1.h>
50 #include <crypto/rmd160.h>
51
52 #include <dev/pci/pcireg.h>
53 #include <dev/pci/pcivar.h>
54 #include <dev/pci/pcidevs.h>
55
56 #include <dev/pci/isesreg.h>
57 #include <dev/pci/isesvar.h>
58 #include <dev/microcode/ises/ises_fw.h>
59
60 /*
61 * Prototypes and count for the pci_device structure
62 */
63 int ises_match(struct device *, void *, void *);
64 void ises_attach(struct device *, struct device *, void *);
65
66 void ises_initstate(void *);
67 void ises_hrng_init(struct ises_softc *);
68 void ises_hrng(void *);
69 void ises_process_oqueue(struct ises_softc *);
70 int ises_queue_cmd(struct ises_softc *, u_int32_t, u_int32_t *,
71 u_int32_t (*)(struct ises_softc *, struct ises_cmd *));
72 u_int32_t ises_get_fwversion(struct ises_softc *);
73 int ises_assert_cmd_mode(struct ises_softc *);
74
75 int ises_intr(void *);
76 int ises_newsession(u_int32_t *, struct cryptoini *);
77 int ises_freesession(u_int64_t);
78 int ises_process(struct cryptop *);
79 void ises_callback(struct ises_q *);
80 int ises_feed(struct ises_softc *);
81 int ises_bchu_switch_session(struct ises_softc *,
82 struct ises_session *, int);
83 u_int32_t ises_bchu_switch_final(struct ises_softc *, struct ises_cmd *);
84
85 void ises_read_dma(struct ises_softc *);
86
87 #define READ_REG(sc,r) \
88 bus_space_read_4((sc)->sc_memt, (sc)->sc_memh,r)
89
90 #define WRITE_REG(sc,reg,val) \
91 bus_space_write_4((sc)->sc_memt, (sc)->sc_memh, reg, val)
92
93 /* XXX This should probably be (x) = htole32((x)) */
94 #define SWAP32(x) ((x) = swap32((x)))
95
96 #ifdef ISESDEBUG
97 # define DPRINTF(x) printf x
98 #else
99 # define DPRINTF(x)
100 #endif
101
102 #ifdef ISESDEBUG
103 void ises_debug_init(struct ises_softc *);
104 void ises_debug_2(void);
105 void ises_debug_loop(void *);
106 void ises_showreg(void);
107 void ises_debug_parse_omr(struct ises_softc *);
108 void ises_debug_simple_cmd(struct ises_softc *, u_int32_t, u_int32_t);
109 struct ises_softc *ises_sc;
110 struct timeout ises_db_timeout;
111 int ises_db;
112 #endif
113
114 /* For HRNG entropy collection, these values gather 1600 bytes/s */
115 #ifndef ISESRNGBITS
116 #define ISESRNGBITS 128 /* Bits per iteration (mult. of 32) */
117 #define ISESRNGIPS 100 /* Iterations per second */
118 #endif
119
120 /* XXX Disable HRNG while debugging. */
121 #define ISES_HRNG_DISABLED
122
123 /* Maximum number of times we try to download the firmware. */
124 #define ISES_MAX_DOWNLOAD_RETRIES 3
125
126 struct cfattach ises_ca = {
127 sizeof(struct ises_softc), ises_match, ises_attach,
128 };
129
130 struct cfdriver ises_cd = {
131 0, "ises", DV_DULL
132 };
133
134 struct ises_stats {
135 u_int64_t ibytes;
136 u_int64_t obytes;
137 u_int32_t ipkts;
138 u_int32_t opkts;
139 u_int32_t invalid;
140 u_int32_t nomem;
141 } isesstats;
142
143 int
ises_match(struct device * parent,void * match,void * aux)144 ises_match(struct device *parent, void *match, void *aux)
145 {
146 struct pci_attach_args *pa = (struct pci_attach_args *)aux;
147
148 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_PIJNENBURG &&
149 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_PIJNENBURG_PCC_ISES)
150 return (1);
151
152 return (0);
153 }
154
155 void
ises_attach(struct device * parent,struct device * self,void * aux)156 ises_attach(struct device *parent, struct device *self, void *aux)
157 {
158 struct ises_softc *sc = (struct ises_softc *)self;
159 struct pci_attach_args *pa = aux;
160 pci_chipset_tag_t pc = pa->pa_pc;
161 pci_intr_handle_t ih;
162 const char *intrstr = NULL;
163 bus_size_t memsize;
164 u_int32_t cmd;
165
166 bus_dma_segment_t seg;
167 int nsegs, error, state;
168
169 SIMPLEQ_INIT(&sc->sc_queue);
170 SIMPLEQ_INIT(&sc->sc_qchip);
171 SIMPLEQ_INIT(&sc->sc_cmdq);
172 state = 0;
173
174 /* Verify PCI space */
175 cmd = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
176 cmd |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE;
177 pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, cmd);
178 cmd = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
179
180 if (!(cmd & PCI_COMMAND_MEM_ENABLE)) {
181 printf(": failed to enable memory mapping\n");
182 return;
183 }
184
185 if (!(cmd & PCI_COMMAND_MASTER_ENABLE)) {
186 printf(": failed to enable bus mastering\n");
187 return;
188 }
189
190 /* Map control/status registers. */
191 if (pci_mapreg_map(pa, PCI_MAPREG_START,
192 PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->sc_memt,
193 &sc->sc_memh, NULL, &memsize, 0)) {
194 printf(": can't find mem space\n");
195 return;
196 }
197 state++;
198
199 /* Map interrupt. */
200 if (pci_intr_map(pa, &ih)) {
201 printf(": couldn't map interrupt\n");
202 goto fail;
203 }
204 state++;
205
206 intrstr = pci_intr_string(pc, ih);
207 sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, ises_intr, sc,
208 self->dv_xname);
209 if (sc->sc_ih == NULL) {
210 printf(": couldn't establish interrupt\n");
211 if (intrstr != NULL)
212 printf(" at %s", intrstr);
213 printf("\n");
214 goto fail;
215 }
216
217 /* Initialize DMA map */
218 sc->sc_dmat = pa->pa_dmat;
219 error = bus_dmamap_create(sc->sc_dmat, 1 << PGSHIFT, 1, 1 << PGSHIFT,
220 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_dmamap);
221 if (error) {
222 printf(": cannot create dma map (%d)\n", error);
223 goto fail;
224 }
225 state++;
226
227 /* Allocate in DMAable memory. */
228 if (bus_dmamem_alloc(sc->sc_dmat, ISES_B_DATASIZE, 1, 0, &seg, 1,
229 &nsegs, BUS_DMA_NOWAIT)) {
230 printf(": can't alloc dma buffer space\n");
231 goto fail;
232 }
233 state++;
234
235 if (bus_dmamem_map(sc->sc_dmat, &seg, nsegs, ISES_B_DATASIZE,
236 &sc->sc_dma_data, 0)) {
237 printf(": can't map dma buffer space\n");
238 goto fail;
239 }
240 state++;
241
242 printf(": %s\n", intrstr);
243
244 bzero(&isesstats, sizeof(isesstats));
245
246 sc->sc_cid = crypto_get_driverid(0);
247
248 if (sc->sc_cid < 0)
249 goto fail;
250
251 /*
252 * Since none of the initialization steps generate interrupts
253 * for example, the hardware reset, we use a number of timeouts
254 * (or init states) to do the rest of the chip initialization.
255 */
256
257 sc->sc_initstate = 0;
258 startuphook_establish(ises_initstate, sc);
259
260 #ifdef ISESDEBUG
261 ises_debug_init(sc);
262 #endif
263 return;
264
265 fail:
266 switch (state) { /* Always fallthrough here. */
267 case 5:
268 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)&sc->sc_dma_data,
269 sizeof sc->sc_dma_data);
270 case 4:
271 bus_dmamem_free(sc->sc_dmat, &seg, nsegs);
272 case 3:
273 bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap);
274 case 2:
275 pci_intr_disestablish(pc, sc->sc_ih);
276 case 1:
277 bus_space_unmap(sc->sc_memt, sc->sc_memh, memsize);
278 default: /* 0 */
279 break;
280 }
281 return;
282 }
283
284 void
ises_initstate(void * v)285 ises_initstate(void *v)
286 {
287 /*
288 * Step through chip initialization.
289 * sc->sc_initstate tells us what to do.
290 */
291 extern int hz;
292 struct ises_softc *sc = v;
293 char *dv = sc->sc_dv.dv_xname;
294 u_int32_t stat;
295 int p, ticks, algs[CRYPTO_ALGORITHM_MAX + 1];
296 static int retry_count = 0; /* XXX Should be in softc */
297
298 ticks = hz * 3 / 2; /* 1.5s */
299
300 p = ISES_STAT_IDP_STATE(READ_REG(sc, ISES_A_STAT));
301 DPRINTF(("%s: initstate %d, IDP state is %d \"%s\"\n", dv,
302 sc->sc_initstate, p, ises_idp_state[p]));
303
304 switch (sc->sc_initstate) {
305 case 0:
306 /* Called by dostartuphooks(9). */
307 timeout_set(&sc->sc_timeout, ises_initstate, sc);
308
309 /* FALLTHROUGH */
310 sc->sc_initstate++;
311 case 1:
312 /* Power up the chip (clear powerdown bit) */
313 stat = READ_REG(sc, ISES_BO_STAT);
314 if (stat & ISES_BO_STAT_POWERDOWN) {
315 stat &= ~ISES_BO_STAT_POWERDOWN;
316 WRITE_REG(sc, ISES_BO_STAT, stat);
317 /* Selftests will take 1 second. */
318 break;
319 }
320 #if 1
321 else {
322 /* Power down the chip for sane init, then rerun. */
323 stat |= ISES_BO_STAT_POWERDOWN;
324 WRITE_REG(sc, ISES_BO_STAT, stat);
325 sc->sc_initstate--; /* Rerun state 1. */
326 break;
327 }
328 #else
329 /* FALLTHROUGH (chip is already powered up) */
330 sc->sc_initstate++;
331 #endif
332
333 case 2:
334 /* Perform a hardware reset */
335 stat = 0;
336
337 printf ("%s: initializing...\n", dv);
338
339 /* Clear all possible bypass bits. */
340 for (p = 0; p < 128; p++)
341 WRITE_REG(sc, ISES_B_BDATAOUT, 0L);
342
343 stat |= ISES_BO_STAT_HWRESET;
344 WRITE_REG(sc, ISES_BO_STAT, stat);
345 stat &= ~ISES_BO_STAT_HWRESET;
346 WRITE_REG(sc, ISES_BO_STAT, stat);
347 /* Again, selftests will take 1 second. */
348 break;
349
350 case 3:
351 /* Set AConf to zero, i.e 32-bits access to A-int. */
352 stat = READ_REG(sc, ISES_BO_STAT);
353 stat &= ~ISES_BO_STAT_ACONF;
354 WRITE_REG(sc, ISES_BO_STAT, stat);
355
356 /* Is the firmware already loaded? */
357 if (READ_REG(sc, ISES_A_STAT) & ISES_STAT_HW_DA) {
358 /* Yes it is, jump ahead a bit */
359 ticks = 1;
360 sc->sc_initstate += 3; /* Next step --> 7 */
361 break;
362 }
363
364 /*
365 * Download the Basic Functionality firmware.
366 */
367
368 p = ISES_STAT_IDP_STATE(READ_REG(sc, ISES_A_STAT));
369 if (p == ISES_IDP_WFPL) {
370 /* We're ready to download. */
371 ticks = 1;
372 sc->sc_initstate += 2; /* Next step --> 6 */
373 break;
374 }
375
376 /*
377 * Prior to downloading we need to reset the NSRAM.
378 * Setting the tamper bit will erase the contents
379 * in 1 microsecond.
380 */
381 stat = READ_REG(sc, ISES_BO_STAT);
382 stat |= ISES_BO_STAT_TAMPER;
383 WRITE_REG(sc, ISES_BO_STAT, stat);
384 ticks = 1;
385 break;
386
387 case 4:
388 /* After tamper bit has been set, powerdown chip. */
389 stat = READ_REG(sc, ISES_BO_STAT);
390 stat |= ISES_BO_STAT_POWERDOWN;
391 WRITE_REG(sc, ISES_BO_STAT, stat);
392 /* Wait one second for power to dissipate. */
393 break;
394
395 case 5:
396 /* Clear tamper and powerdown bits. */
397 stat = READ_REG(sc, ISES_BO_STAT);
398 stat &= ~(ISES_BO_STAT_TAMPER | ISES_BO_STAT_POWERDOWN);
399 WRITE_REG(sc, ISES_BO_STAT, stat);
400 /* Again we need to wait a second for selftests. */
401 break;
402
403 case 6:
404 /*
405 * We'll need some space in the input queue (IQF)
406 * and we need to be in the 'waiting for program
407 * length' IDP state (0x4).
408 */
409 p = ISES_STAT_IDP_STATE(READ_REG(sc, ISES_A_STAT));
410 if (READ_REG(sc, ISES_A_IQF) < 4 || p != ISES_IDP_WFPL) {
411 if (retry_count++ < ISES_MAX_DOWNLOAD_RETRIES) {
412 /* Retry download. */
413 sc->sc_initstate -= 5; /* Next step --> 2 */
414 ticks = 1;
415 break;
416 }
417 retry_count = 0;
418 printf("%s: cannot download firmware, "
419 "IDP state is \"%s\"\n", dv, ises_idp_state[p]);
420 return;
421 }
422
423 /* Write firmware length */
424 WRITE_REG(sc, ISES_A_IQD, ISES_BF_IDPLEN);
425
426 /* Write firmware code */
427 for (p = 0; p < sizeof(ises_bf_fw)/sizeof(u_int32_t); p++) {
428 WRITE_REG(sc, ISES_A_IQD, ises_bf_fw[p]);
429 if (READ_REG(sc, ISES_A_IQF) < 4)
430 DELAY(10);
431 }
432
433 /* Write firmware CRC */
434 WRITE_REG(sc, ISES_A_IQD, ISES_BF_IDPCRC);
435
436 /* Wait 1s while chip resets and runs selftests */
437 break;
438
439 case 7:
440 /* Did the download succed? */
441 if (READ_REG(sc, ISES_A_STAT) & ISES_STAT_HW_DA) {
442 ticks = 1;
443 break;
444 }
445
446 /* We failed. */
447 goto fail;
448
449 case 8:
450 if (ises_assert_cmd_mode(sc) < 0)
451 goto fail;
452
453 /*
454 * Now that the basic functionality firmware should be
455 * up and running, try to get the firmware version.
456 */
457
458 stat = ises_get_fwversion(sc);
459 if (stat == 0)
460 goto fail;
461
462 printf("%s: firmware v%d.%d loaded (%d bytes)", dv,
463 stat & 0xffff, (stat >> 16) & 0xffff, ISES_BF_IDPLEN << 2);
464
465 /* We can use firmware versions 1.x & 2.x */
466 switch (stat & 0xffff) {
467 case 0:
468 printf(" diagnostic, %s disabled\n", dv);
469 goto fail;
470 case 1: /* Basic Func "base" firmware */
471 case 2: /* Basic Func "ipsec" firmware, no ADP code */
472 break;
473 default:
474 printf(" unknown, %s disabled\n", dv);
475 goto fail;
476 }
477
478 stat = READ_REG(sc, ISES_A_STAT);
479 DPRINTF((", mode %s",
480 ises_sw_mode[ISES_STAT_SW_MODE(stat)]));
481
482 /* Reuse the timeout for HRNG entropy collection. */
483 timeout_del(&sc->sc_timeout);
484 ises_hrng_init(sc);
485
486 /* Set the interrupt mask */
487 sc->sc_intrmask = ISES_STAT_BCHU_OAF | ISES_STAT_BCHU_ERR |
488 ISES_STAT_BCHU_OFHF | ISES_STAT_SW_OQSINC |
489 ISES_STAT_LNAU_BUSY_1 | ISES_STAT_LNAU_ERR_1 |
490 ISES_STAT_LNAU_BUSY_2 | ISES_STAT_LNAU_ERR_2;
491 #if 0
492 ISES_STAT_BCHU_ERR | ISES_STAT_BCHU_OAF |
493 ISES_STAT_BCHU_IFE | ISES_STAT_BCHU_IFHE |
494 ISES_STAT_BCHU_OFHF | ISES_STAT_BCHU_OFF;
495 #endif
496
497 WRITE_REG(sc, ISES_A_INTE, sc->sc_intrmask);
498
499 /* We're done. */
500 printf("\n");
501
502 /* Register ourselves with crypto framework. */
503 bzero(algs, sizeof(algs));
504
505 algs[CRYPTO_3DES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
506 algs[CRYPTO_DES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
507 algs[CRYPTO_MD5_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
508 algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
509 algs[CRYPTO_RIPEMD160_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
510
511 crypto_register(sc->sc_cid, algs,
512 ises_newsession, ises_freesession, ises_process);
513 return;
514
515 default:
516 printf("%s: entered unknown initstate %d\n", dv,
517 sc->sc_initstate);
518 goto fail;
519 }
520
521 /* Increment state counter and schedule next step in 'ticks' ticks. */
522 sc->sc_initstate++;
523 timeout_add(&sc->sc_timeout, ticks);
524 return;
525
526 fail:
527 printf("%s: firmware failure\n", dv);
528 timeout_del(&sc->sc_timeout);
529 return;
530 }
531
532 /* Put a command on the A-interface queue. */
533 int
ises_queue_cmd(struct ises_softc * sc,u_int32_t cmd,u_int32_t * data,u_int32_t (* callback)(struct ises_softc *,struct ises_cmd *))534 ises_queue_cmd(struct ises_softc *sc, u_int32_t cmd, u_int32_t *data,
535 u_int32_t (*callback)(struct ises_softc *, struct ises_cmd *))
536 {
537 struct ises_cmd *cq;
538 int p, len, s, code;
539
540 len = cmd >> 24;
541 code = (cmd >> 16) & 0xFF;
542
543 #ifdef ISESDEBUG
544 if (code != ISES_CMD_HBITS) /* ... since this happens 100 times/s */
545 DPRINTF(("%s: queueing cmd 0x%x len %d\n", sc->sc_dv.dv_xname,
546 code, len));
547 #endif
548
549 s = splnet();
550
551 if (len > READ_REG(sc, ISES_A_IQF)) {
552 splx(s);
553 return (EAGAIN); /* XXX ENOMEM ? */
554 }
555
556 cq = (struct ises_cmd *)
557 malloc(sizeof (struct ises_cmd), M_DEVBUF, M_NOWAIT);
558 if (cq == NULL) {
559 splx(s);
560 isesstats.nomem++;
561 return (ENOMEM);
562 }
563 bzero(cq, sizeof (struct ises_cmd));
564 cq->cmd_code = code;
565 cq->cmd_cb = callback;
566 cq->cmd_session = sc->sc_cursession;
567 SIMPLEQ_INSERT_TAIL(&sc->sc_cmdq, cq, cmd_next);
568
569 WRITE_REG(sc, ISES_A_IQD, cmd);
570
571 /* LNAU register data should be written in reverse order */
572 if ((code >= ISES_CMD_LW_A_1 && code <= ISES_CMD_LW_U_1) || /* LNAU1 */
573 (code >= ISES_CMD_LW_A_2 && code <= ISES_CMD_LW_U_2)) /* LNAU2 */
574 for (p = len - 1; p >= 0; p--)
575 WRITE_REG(sc, ISES_A_IQD, *(data + p));
576 else
577 for (p = 0; p < len; p++)
578 WRITE_REG(sc, ISES_A_IQD, *(data + p));
579
580 /* Signal 'command ready'. */
581 WRITE_REG(sc, ISES_A_IQS, 0);
582
583 splx(s);
584 return (0);
585 }
586
587 /* Process all completed responses in the output queue. */
588 void
ises_process_oqueue(struct ises_softc * sc)589 ises_process_oqueue(struct ises_softc *sc)
590 {
591 #ifdef ISESDEBUG
592 char *dv = sc->sc_dv.dv_xname;
593 #endif
594 struct ises_cmd *cq;
595 struct ises_session *ses;
596 u_int32_t oqs, r, d;
597 int cmd, len, c, s;
598
599 r = READ_REG(sc, ISES_A_OQS);
600 if (r > 1)
601 DPRINTF(("%s:process_oqueue: OQS=%d\n", dv, r));
602
603 /* OQS gives us the number of responses we have to process. */
604 while ((oqs = READ_REG(sc, ISES_A_OQS)) > 0) {
605 /* Read command response. [ len(8) | cmd(8) | rc(16) ] */
606 r = READ_REG(sc, ISES_A_OQD);
607 len = (r >> 24);
608 cmd = (r >> 16) & 0xff;
609 r = r & 0xffff;
610
611 s = splnet();
612 if (!SIMPLEQ_EMPTY(&sc->sc_cmdq)) {
613 cq = SIMPLEQ_FIRST(&sc->sc_cmdq);
614 SIMPLEQ_REMOVE_HEAD(&sc->sc_cmdq, cmd_next);
615 cq->cmd_rlen = len;
616 } else {
617 cq = NULL;
618 DPRINTF(("%s:process_oqueue: cmd queue empty!\n", dv));
619 }
620 splx(s);
621
622 if (r) {
623 /* Ouch. This command generated an error */
624 DPRINTF(("%s:process_oqueue: cmd 0x%x err %d\n", dv,
625 cmd, (r & ISES_RC_MASK)));
626 /* Abort any running session switch to force a retry.*/
627 sc->sc_switching = 0;
628 /* Return to CMD mode. This will reset all queues. */
629 (void)ises_assert_cmd_mode(sc);
630 } else {
631 /* Use specified callback, if any */
632 if (cq && cq->cmd_cb) {
633 if (cmd == cq->cmd_code) {
634 cq->cmd_cb(sc, cq);
635 cmd = ISES_CMD_NONE;
636 } else {
637 DPRINTF(("%s:process_oqueue: expected"
638 " cmd 0x%x, got 0x%x\n", dv,
639 cq->cmd_code, cmd));
640 /* XXX Some error handling here? */
641 }
642 }
643
644 switch (cmd) {
645 case ISES_CMD_NONE:
646 break;
647
648 case ISES_CMD_HBITS:
649 /* XXX How about increasing the pool size? */
650 /* XXX Use add_entropy_words instead? */
651 /* XXX ... at proper spl */
652 /* Cmd generated by ises_rng() via timeouts */
653 while (len--) {
654 d = READ_REG(sc, ISES_A_OQD);
655 add_true_randomness(d);
656 }
657 break;
658
659 case ISES_CMD_LUPLOAD_1:
660 /* Get result of LNAU 1 operation. */
661 DPRINTF(("%s:process_oqueue: LNAU 1 result "
662 "upload (len=%d)\n", dv, len));
663 sc->sc_lnau1_rlen = len;
664 bzero(sc->sc_lnau1_r, 2048 / 8);
665 while (len--) {
666 /* first word is LSW */
667 sc->sc_lnau1_r[len] =
668 READ_REG(sc, ISES_A_OQD);
669 }
670 break;
671
672 case ISES_CMD_LUPLOAD_2:
673 /* Get result of LNAU 1 operation. */
674 DPRINTF(("%s:process_oqueue: LNAU 2 result "
675 "upload (len=%d)\n", dv, len));
676 sc->sc_lnau2_rlen = len;
677 bzero(sc->sc_lnau1_r, 2048 / 8);
678 while (len--) {
679 /* first word is LSW */
680 sc->sc_lnau2_r[len] =
681 READ_REG(sc, ISES_A_OQD);
682 }
683 break;
684
685 case ISES_CMD_BR_OMR:
686 ses = &sc->sc_sessions[cq->cmd_session];
687 ses->omr = READ_REG(sc, ISES_A_OQD);
688 DPRINTF(("%s:process_oqueue: read OMR[%08x]\n",
689 dv, ses->omr));
690 #ifdef ISESDEBUG
691 ises_debug_parse_omr(sc);
692 #endif
693 break;
694
695 case ISES_CMD_BSWITCH:
696 /* XXX Currently BSWITCH does not work. */
697 DPRINTF(("%s:process_oqueue: BCHU_SWITCH\n"));
698 /* Put switched BCHU session in cur session. */
699 ses = &sc->sc_sessions[cq->cmd_session];
700 for(c = 0; len > 0; len--, c++)
701 #if 0 /* Don't store the key, just drain the data */
702 *((u_int32_t *)&ses + c) =
703 #endif
704 READ_REG(sc, ISES_A_OQD);
705
706 sc->sc_switching = 0;
707 ises_feed (sc);
708 break;
709
710 case ISES_CMD_BW_HMLR:
711 /* XXX Obsoleted by ises_bchu_switch_final */
712 DPRINTF(("%s:process_oqueue: CMD_BW_HMLR !?\n",
713 dv));
714 break;
715
716 default:
717 /* All other are ok (no response data) */
718 DPRINTF(("%s:process_oqueue cmd 0x%x len %d\n",
719 dv, cmd, len));
720 if (cq && cq->cmd_cb)
721 len -= cq->cmd_cb(sc, cq);
722 }
723 }
724
725 if (cq)
726 free(cq, M_DEVBUF);
727
728 /* This will drain any remaining data and ACK this reponse. */
729 while (len-- > 0)
730 d = READ_REG(sc, ISES_A_OQD);
731 WRITE_REG(sc, ISES_A_OQS, 0);
732 if (oqs > 1)
733 DELAY(1); /* Wait for fw to decrement OQS (8 clocks) */
734 }
735 }
736
737 int
ises_intr(void * arg)738 ises_intr(void *arg)
739 {
740 struct ises_softc *sc = arg;
741 u_int32_t ints, dma_status, cmd;
742 char *dv = sc->sc_dv.dv_xname;
743
744 dma_status = READ_REG(sc, ISES_DMA_STATUS);
745
746 if (!(dma_status & (ISES_DMA_STATUS_R_ERR | ISES_DMA_STATUS_W_ERR))) {
747 if ((sc->sc_dma_mask & ISES_DMA_STATUS_R_RUN) != 0 &&
748 (dma_status & ISES_DMA_STATUS_R_RUN) == 0) {
749 DPRINTF(("%s: DMA read complete\n", dv));
750
751 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0,
752 sc->sc_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
753
754 /* XXX Pick up and return the data.*/
755
756 WRITE_REG(sc, ISES_DMA_RESET, 0);
757 }
758 if ((sc->sc_dma_mask & ISES_DMA_STATUS_W_RUN) != 0 &&
759 (dma_status & ISES_DMA_STATUS_W_RUN) == 0) {
760 DPRINTF(("%s: DMA write complete\n", dv));
761
762 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0,
763 sc->sc_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
764
765 WRITE_REG(sc, ISES_DMA_RESET, 0);
766 ises_feed(sc);
767 }
768 } else {
769 printf ("%s: DMA error\n", dv);
770 WRITE_REG(sc, ISES_DMA_RESET, 0);
771 }
772
773 ints = READ_REG(sc, ISES_A_INTS);
774 if (!(ints & sc->sc_intrmask)) {
775 DPRINTF (("%s: other intr mask [%08x]\n", ints));
776 return (0); /* Not our interrupt. */
777 }
778
779 /* Clear all set intr bits. */
780 WRITE_REG(sc, ISES_A_INTS, ints);
781
782 #if 0
783 /* Check it we've got room for more data. */
784 if (READ_REG(sc, ISES_A_STAT) &
785 (ISES_STAT_BCHU_IFE | ISES_STAT_BCHU_IFHE))
786 ises_feed(sc);
787 #endif
788
789 /* Does the A-intf output queue have data we need to process? */
790 if (ints & ISES_STAT_SW_OQSINC)
791 ises_process_oqueue(sc);
792
793 if (ints & ISES_STAT_LNAU_BUSY_1) {
794 DPRINTF(("%s:ises_intr: LNAU 1 job complete\n", dv));
795 /* upload LNAU 1 result (into sc->sc_lnau1_r) */
796 cmd = ISES_MKCMD(ISES_CMD_LUPLOAD_1, 0);
797 ises_queue_cmd(sc, cmd, NULL, NULL);
798 }
799
800 if (ints & ISES_STAT_LNAU_BUSY_2) {
801 DPRINTF(("%s:ises_intr: LNAU 2 job complete\n", dv));
802 /* upload LNAU 2 result (into sc->sc_lnau2_r) */
803 cmd = ISES_MKCMD(ISES_CMD_LUPLOAD_2, 0);
804 ises_queue_cmd(sc, cmd, NULL, NULL);
805 }
806
807 if (ints & ISES_STAT_LNAU_ERR_1) {
808 DPRINTF(("%s:ises_intr: LNAU 1 error\n", dv));
809 sc->sc_lnau1_rlen = -1;
810 }
811
812 if (ints & ISES_STAT_LNAU_ERR_2) {
813 DPRINTF(("%s:ises_intr: LNAU 2 error\n", dv));
814 sc->sc_lnau2_rlen = -1;
815 }
816
817 if (ints & ISES_STAT_BCHU_OAF) { /* output data available */
818 DPRINTF(("%s:ises_intr: BCHU_OAF bit set\n", dv));
819 /* Read DMA data from B-interface. */
820 ises_read_dma (sc);
821 }
822
823 if (ints & ISES_STAT_BCHU_ERR) { /* We got a BCHU error */
824 DPRINTF(("%s:ises_intr: BCHU error\n", dv));
825 /* XXX Error handling */
826 }
827
828 if (ints & ISES_STAT_BCHU_OFHF) { /* Output is half full */
829 DPRINTF(("%s:ises_intr: BCHU output FIFO half full\n", dv));
830 /* XXX drain data? */
831 }
832
833 #if 0 /* XXX Useful? */
834 if (ints & ISES_STAT_BCHU_OFF) { /* Output is full */
835 /* XXX drain data / error handling? */
836 }
837 #endif
838 return (1);
839 }
840
841 int
ises_feed(struct ises_softc * sc)842 ises_feed(struct ises_softc *sc)
843 {
844 struct ises_q *q;
845 bus_dma_segment_t *ds = &sc->sc_dmamap->dm_segs[0];
846 u_int32_t dma_status;
847 int s;
848 #ifdef ISESDEBUG
849 char *dv = sc->sc_dv.dv_xname;
850 #endif
851
852 DPRINTF(("%s:ises_feed: called (sc = %p)\n", dv, sc));
853 DELAY(1000000);
854
855 s = splnet();
856 /* Anything to do? */
857 if (SIMPLEQ_EMPTY(&sc->sc_queue) ||
858 (READ_REG(sc, ISES_A_STAT) & ISES_STAT_BCHU_IFF)) {
859 splx(s);
860 return (0);
861 }
862
863 /* Pick the first */
864 q = SIMPLEQ_FIRST(&sc->sc_queue);
865 splx(s);
866
867 /* If we're currently switching sessions, we'll have to wait. */
868 if (sc->sc_switching != 0) {
869 DPRINTF(("%s:ises_feed: waiting for session switch\n", dv));
870 return (0);
871 }
872
873 /* If on-chip data is not correct for this data, switch session. */
874 if (sc->sc_cursession != q->q_sesn) {
875 /* Session switch required */
876 DPRINTF(("%s:ises_feed: initiating session switch\n", dv));
877 if (ises_bchu_switch_session (sc, &q->q_session, q->q_sesn))
878 sc->sc_cursession = q->q_sesn;
879 else
880 DPRINTF(("%s:ises_feed: session switch failed\n", dv));
881 return (0);
882 }
883
884 DPRINTF(("%s:ises_feed: feed to chip (q = %p)\n", dv, q));
885 DELAY(2000000);
886
887 s = splnet();
888 SIMPLEQ_REMOVE_HEAD(&sc->sc_queue, q_next);
889 SIMPLEQ_INSERT_TAIL(&sc->sc_qchip, q, q_next);
890 --sc->sc_nqueue;
891 splx(s);
892
893 if (q->q_crp->crp_flags & CRYPTO_F_IMBUF)
894 bus_dmamap_load_mbuf(sc->sc_dmat, sc->sc_dmamap,
895 q->q_src.mbuf, BUS_DMA_NOWAIT);
896 else if (q->q_crp->crp_flags & CRYPTO_F_IOV)
897 bus_dmamap_load_uio(sc->sc_dmat, sc->sc_dmamap, q->q_src.uio,
898 BUS_DMA_NOWAIT);
899 /* ... else */
900
901 /* Start writing data to the ises. */
902 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0,
903 sc->sc_dmamap->dm_mapsize, BUS_DMASYNC_PREWRITE);
904
905 DPRINTF(("%s:ises_feed: writing DMA\n", dv));
906 DELAY(1000000);
907
908 sc->sc_dma_mask |= ISES_DMA_STATUS_W_RUN;
909
910 WRITE_REG(sc, ISES_DMA_WRITE_START, ds->ds_addr);
911 WRITE_REG(sc, ISES_DMA_WRITE_COUNT, ISES_DMA_WCOUNT(ds->ds_len));
912
913 dma_status = READ_REG(sc, ISES_DMA_STATUS);
914 dma_status |= ISES_DMA_CTRL_ILT | ISES_DMA_CTRL_RLINE;
915 WRITE_REG(sc, ISES_DMA_CTRL, dma_status);
916
917 DPRINTF(("%s:ises_feed: done\n", dv));
918 return (0);
919 }
920
921 /*
922 * Allocate a new 'session' and return an encoded session id. 'sidp'
923 * contains our registration id, and should contain an encoded session
924 * id on successful allocation.
925 */
926 int
ises_newsession(u_int32_t * sidp,struct cryptoini * cri)927 ises_newsession(u_int32_t *sidp, struct cryptoini *cri)
928 {
929 struct cryptoini *c, *mac = NULL, *enc = NULL;
930 struct ises_softc *sc = NULL;
931 struct ises_session *ses;
932 MD5_CTX md5ctx;
933 SHA1_CTX sha1ctx;
934 RMD160_CTX rmd160ctx;
935 int i, sesn;
936 #ifdef ISESDEBUG
937 char *dv;
938 #endif
939
940 if (sidp == NULL || cri == NULL)
941 return (EINVAL);
942
943 for (i = 0; i < ises_cd.cd_ndevs; i++) {
944 sc = ises_cd.cd_devs[i];
945 if (sc == NULL || sc->sc_cid == (*sidp))
946 break;
947 }
948 if (sc == NULL)
949 return (EINVAL);
950 #ifdef ISESDEBUG
951 dv = sc->sc_dv.dv_xname;
952 #endif
953
954 DPRINTF(("%s:ises_newsession: start\n", dv));
955
956 for (c = cri; c != NULL; c = c->cri_next) {
957 if (c->cri_alg == CRYPTO_MD5_HMAC ||
958 c->cri_alg == CRYPTO_SHA1_HMAC ||
959 c->cri_alg == CRYPTO_RIPEMD160_HMAC) {
960 if (mac)
961 return (EINVAL);
962 mac = c;
963 } else if (c->cri_alg == CRYPTO_DES_CBC ||
964 c->cri_alg == CRYPTO_3DES_CBC) {
965 if (enc)
966 return (EINVAL);
967 enc = c;
968 } else
969 return (EINVAL);
970 }
971 if (mac == 0 && enc == 0)
972 return (EINVAL);
973
974 #ifdef ISESDEBUG
975 printf ("%s:ises_newsession: mac=%p(%d) enc=%p(%d)\n",
976 dv, mac, (mac ? mac->cri_alg : -1), enc, (enc ? enc->cri_alg : -1));
977 #endif
978
979 /* Allocate a new session */
980 if (sc->sc_sessions == NULL) {
981 ses = sc->sc_sessions = (struct ises_session *)
982 malloc(sizeof(struct ises_session), M_DEVBUF, M_NOWAIT);
983 if (ses == NULL) {
984 isesstats.nomem++;
985 return (ENOMEM);
986 }
987 sc->sc_cursession = -1;
988 sesn = 0;
989 sc->sc_nsessions = 1;
990 } else {
991 ses = NULL;
992 for (sesn = 0; sesn < sc->sc_nsessions; sesn++)
993 if (sc->sc_sessions[sesn].omr == 0) {
994 ses = &sc->sc_sessions[sesn];
995 sc->sc_cursession = sesn;
996 break;
997 }
998
999 if (ses == NULL) {
1000 i = sc->sc_nsessions * sizeof(struct ises_session);
1001 ses = (struct ises_session *)
1002 malloc(i + sizeof(struct ises_session), M_DEVBUF,
1003 M_NOWAIT);
1004 if (ses == NULL) {
1005 isesstats.nomem++;
1006 return (ENOMEM);
1007 }
1008
1009 bcopy(sc->sc_sessions, ses, i);
1010 bzero(sc->sc_sessions, i);
1011 free(sc->sc_sessions, M_DEVBUF);
1012 sc->sc_sessions = ses;
1013 ses = &sc->sc_sessions[sc->sc_nsessions];
1014 sc->sc_cursession = sc->sc_nsessions;
1015 sc->sc_nsessions++;
1016 }
1017 }
1018
1019 DPRINTF(("%s:ises_newsession: nsessions=%d cursession=%d\n", dv,
1020 sc->sc_nsessions, sc->sc_cursession));
1021
1022 bzero(ses, sizeof(struct ises_session));
1023
1024 /* Select data path through B-interface. */
1025 ses->omr |= ISES_SELR_BCHU_DIS;
1026
1027 if (enc) {
1028 /* get an IV, network byte order */
1029 /* XXX switch to using builtin HRNG ! */
1030 get_random_bytes(ses->sccr, sizeof(ses->sccr));
1031
1032 /* crypto key */
1033 if (enc->cri_alg == CRYPTO_DES_CBC) {
1034 bcopy(enc->cri_key, &ses->kr[0], 8);
1035 bcopy(enc->cri_key, &ses->kr[2], 8);
1036 bcopy(enc->cri_key, &ses->kr[4], 8);
1037 } else
1038 bcopy(enc->cri_key, &ses->kr[0], 24);
1039
1040 SWAP32(ses->kr[0]);
1041 SWAP32(ses->kr[1]);
1042 SWAP32(ses->kr[2]);
1043 SWAP32(ses->kr[3]);
1044 SWAP32(ses->kr[4]);
1045 SWAP32(ses->kr[5]);
1046 }
1047
1048 if (mac) {
1049 for (i = 0; i < mac->cri_klen / 8; i++)
1050 mac->cri_key[i] ^= HMAC_IPAD_VAL;
1051
1052 switch (mac->cri_alg) {
1053 case CRYPTO_MD5_HMAC:
1054 MD5Init(&md5ctx);
1055 MD5Update(&md5ctx, mac->cri_key, mac->cri_klen / 8);
1056 MD5Update(&md5ctx, hmac_ipad_buffer, HMAC_BLOCK_LEN -
1057 (mac->cri_klen / 8));
1058 MD5Final((u_int8_t *)&ses->cvr, &md5ctx);
1059 break;
1060 case CRYPTO_SHA1_HMAC:
1061 SHA1Init(&sha1ctx);
1062 SHA1Update(&sha1ctx, mac->cri_key, mac->cri_klen / 8);
1063 SHA1Update(&sha1ctx, hmac_ipad_buffer, HMAC_BLOCK_LEN -
1064 (mac->cri_klen / 8));
1065 SHA1Final((u_int8_t *)ses->cvr, &sha1ctx);
1066 break;
1067 case CRYPTO_RIPEMD160_HMAC:
1068 default:
1069 RMD160Init(&rmd160ctx);
1070 RMD160Update(&rmd160ctx, mac->cri_key,
1071 mac->cri_klen / 8);
1072 RMD160Update(&rmd160ctx, hmac_ipad_buffer,
1073 HMAC_BLOCK_LEN - (mac->cri_klen / 8));
1074 RMD160Final((u_int8_t *)ses->cvr, &rmd160ctx);
1075 break;
1076 }
1077
1078 for (i = 0; i < mac->cri_klen / 8; i++)
1079 mac->cri_key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
1080
1081 switch (mac->cri_alg) {
1082 case CRYPTO_MD5_HMAC:
1083 MD5Init(&md5ctx);
1084 MD5Update(&md5ctx, mac->cri_key, mac->cri_klen / 8);
1085 MD5Update(&md5ctx, hmac_opad_buffer, HMAC_BLOCK_LEN -
1086 (mac->cri_klen / 8));
1087 MD5Update(&md5ctx, (u_int8_t *)ses->cvr,
1088 sizeof(md5ctx.state));
1089 MD5Final((u_int8_t *)ses->cvr, &md5ctx);
1090 break;
1091 case CRYPTO_SHA1_HMAC:
1092 SHA1Init(&sha1ctx);
1093 SHA1Update(&sha1ctx, mac->cri_key, mac->cri_klen / 8);
1094 SHA1Update(&sha1ctx, hmac_opad_buffer, HMAC_BLOCK_LEN -
1095 (mac->cri_klen / 8));
1096 SHA1Update(&sha1ctx, (u_int8_t *)ses->cvr,
1097 sizeof(sha1ctx.state));
1098 SHA1Final((u_int8_t *)ses->cvr, &sha1ctx);
1099 break;
1100 case CRYPTO_RIPEMD160_HMAC:
1101 default:
1102 RMD160Init(&rmd160ctx);
1103 RMD160Update(&rmd160ctx, mac->cri_key,
1104 mac->cri_klen / 8);
1105 RMD160Update(&rmd160ctx, hmac_opad_buffer,
1106 HMAC_BLOCK_LEN - (mac->cri_klen / 8));
1107 RMD160Update(&rmd160ctx, (u_int8_t *)ses->cvr,
1108 sizeof(rmd160ctx.state));
1109 RMD160Final((u_int8_t *)ses->cvr, &rmd160ctx);
1110 break;
1111 }
1112
1113 for (i = 0; i < mac->cri_klen / 8; i++)
1114 mac->cri_key[i] ^= HMAC_OPAD_VAL;
1115 }
1116
1117 DPRINTF(("%s:ises_newsession: done\n", dv));
1118 *sidp = ISES_SID(sc->sc_dv.dv_unit, sesn);
1119 return (0);
1120 }
1121
1122 /* Deallocate a session. */
1123 int
ises_freesession(u_int64_t tsid)1124 ises_freesession(u_int64_t tsid)
1125 {
1126 struct ises_softc *sc;
1127 int card, sesn;
1128 u_int32_t sid = ((u_int32_t)tsid) & 0xffffffff;
1129
1130 card = ISES_CARD(sid);
1131 if (card >= ises_cd.cd_ndevs || ises_cd.cd_devs[card] == NULL)
1132 return (EINVAL);
1133
1134 sc = ises_cd.cd_devs[card];
1135 sesn = ISES_SESSION(sid);
1136
1137 DPRINTF(("%s:ises_freesession: freeing session %d\n",
1138 sc->sc_dv.dv_xname, sesn));
1139
1140 if (sc->sc_cursession == sesn)
1141 sc->sc_cursession = -1;
1142
1143 bzero(&sc->sc_sessions[sesn], sizeof(sc->sc_sessions[sesn]));
1144
1145 return (0);
1146 }
1147
1148 /* Called by the crypto framework, crypto(9). */
1149 int
ises_process(struct cryptop * crp)1150 ises_process(struct cryptop *crp)
1151 {
1152 struct ises_softc *sc;
1153 struct ises_q *q;
1154 struct cryptodesc *maccrd, *enccrd, *crd;
1155 struct ises_session *ses;
1156 int card, s, err = EINVAL;
1157 int encoffset, macoffset, cpskip, sskip, dskip, stheend, dtheend;
1158 int cpoffset, coffset;
1159 #if 0
1160 int nicealign;
1161 #endif
1162 #ifdef ISESDEBUG
1163 char *dv;
1164 #endif
1165
1166 if (crp == NULL || crp->crp_callback == NULL)
1167 return (EINVAL);
1168
1169 card = ISES_CARD(crp->crp_sid);
1170 if (card >= ises_cd.cd_ndevs || ises_cd.cd_devs[card] == NULL)
1171 goto errout;
1172
1173 sc = ises_cd.cd_devs[card];
1174 #ifdef ISESDEBUG
1175 dv = sc->sc_dv.dv_xname;
1176 #endif
1177
1178 DPRINTF(("%s:ises_process: start (crp = %p)\n", dv, crp));
1179
1180 s = splnet();
1181 if (sc->sc_nqueue == ISES_MAX_NQUEUE) {
1182 splx(s);
1183 goto memerr;
1184 }
1185 splx(s);
1186
1187 q = (struct ises_q *)malloc(sizeof(struct ises_q), M_DEVBUF, M_NOWAIT);
1188 if (q == NULL)
1189 goto memerr;
1190 bzero(q, sizeof(struct ises_q));
1191
1192 q->q_sesn = ISES_SESSION(crp->crp_sid);
1193 ses = &sc->sc_sessions[q->q_sesn];
1194
1195 DPRINTF(("%s:ises_process: session %d selected\n", dv, q->q_sesn));
1196
1197 q->q_sc = sc;
1198 q->q_crp = crp;
1199
1200 if (crp->crp_flags & CRYPTO_F_IMBUF) {
1201 q->q_src.mbuf = (struct mbuf *)crp->crp_buf;
1202 q->q_dst.mbuf = (struct mbuf *)crp->crp_buf;
1203 } else if (crp->crp_flags & CRYPTO_F_IOV) {
1204 q->q_src.uio = (struct uio *)crp->crp_buf;
1205 q->q_dst.uio = (struct uio *)crp->crp_buf;
1206 } else {
1207 /* XXX for now... */
1208 goto errout;
1209 }
1210
1211 /*
1212 * Check if the crypto descriptors are sane. We accept:
1213 * - just one crd; either auth or crypto
1214 * - two crds; must be one auth and one crypto, although now
1215 * for encryption we only want the first to be crypto, while
1216 * for decryption the second one should be crypto.
1217 */
1218 maccrd = enccrd = NULL;
1219 for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
1220 switch (crd->crd_alg) {
1221 case CRYPTO_MD5_HMAC:
1222 case CRYPTO_SHA1_HMAC:
1223 case CRYPTO_RIPEMD160_HMAC:
1224 if (maccrd || (enccrd &&
1225 (enccrd->crd_flags & CRD_F_ENCRYPT) == 0))
1226 goto errout;
1227 maccrd = crd;
1228 break;
1229 case CRYPTO_DES_CBC:
1230 case CRYPTO_3DES_CBC:
1231 if (enccrd ||
1232 (maccrd && (crd->crd_flags & CRD_F_ENCRYPT)))
1233 goto errout;
1234 enccrd = crd;
1235 break;
1236 default:
1237 goto errout;
1238 }
1239 }
1240 if (!maccrd && !enccrd)
1241 goto errout;
1242
1243 DPRINTF(("%s:ises_process: enc=%p mac=%p\n", dv, enccrd, maccrd));
1244
1245 /* Select data path through B-interface. */
1246 q->q_session.omr |= ISES_SELR_BCHU_DIS;
1247
1248 if (enccrd) {
1249 encoffset = enccrd->crd_skip;
1250
1251 /* Select algorithm */
1252 if (enccrd->crd_alg == CRYPTO_3DES_CBC)
1253 q->q_session.omr |= ISES_SOMR_BOMR_3DES;
1254 else
1255 q->q_session.omr |= ISES_SOMR_BOMR_DES;
1256
1257 /* Set CBC mode */
1258 q->q_session.omr |= ISES_SOMR_FMR_CBC;
1259
1260 if (enccrd->crd_flags & CRD_F_ENCRYPT) {
1261 /* Set encryption bit */
1262 q->q_session.omr |= ISES_SOMR_EDR;
1263
1264 if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
1265 bcopy(enccrd->crd_iv, q->q_session.sccr, 8);
1266 else {
1267 q->q_session.sccr[0] = ses->sccr[0];
1268 q->q_session.sccr[1] = ses->sccr[1];
1269 }
1270
1271 if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
1272 if (crp->crp_flags & CRYPTO_F_IMBUF)
1273 m_copyback(q->q_src.mbuf,
1274 enccrd->crd_inject, 8,
1275 (caddr_t)q->q_session.sccr);
1276 else if (crp->crp_flags & CRYPTO_F_IOV)
1277 cuio_copyback(q->q_src.uio,
1278 enccrd->crd_inject, 8,
1279 (caddr_t)q->q_session.sccr);
1280 /* XXX else ... */
1281 }
1282 } else {
1283 /* Clear encryption bit == decrypt mode */
1284 q->q_session.omr &= ~ISES_SOMR_EDR;
1285
1286 if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
1287 bcopy(enccrd->crd_iv, q->q_session.sccr, 8);
1288 else if (crp->crp_flags & CRYPTO_F_IMBUF)
1289 m_copydata(q->q_src.mbuf, enccrd->crd_inject,
1290 8, (caddr_t)q->q_session.sccr);
1291 else if (crp->crp_flags & CRYPTO_F_IOV)
1292 cuio_copydata(q->q_src.uio,
1293 enccrd->crd_inject, 8,
1294 (caddr_t)q->q_session.sccr);
1295 /* XXX else ... */
1296 }
1297
1298 q->q_session.kr[0] = ses->kr[0];
1299 q->q_session.kr[1] = ses->kr[1];
1300 q->q_session.kr[2] = ses->kr[2];
1301 q->q_session.kr[3] = ses->kr[3];
1302 q->q_session.kr[4] = ses->kr[4];
1303 q->q_session.kr[5] = ses->kr[5];
1304
1305 SWAP32(q->q_session.sccr[0]);
1306 SWAP32(q->q_session.sccr[1]);
1307 }
1308
1309 if (maccrd) {
1310 macoffset = maccrd->crd_skip;
1311
1312 /* Select algorithm */
1313 switch (crd->crd_alg) {
1314 case CRYPTO_MD5_HMAC:
1315 q->q_session.omr |= ISES_HOMR_HFR_MD5;
1316 break;
1317 case CRYPTO_SHA1_HMAC:
1318 q->q_session.omr |= ISES_HOMR_HFR_SHA1;
1319 break;
1320 case CRYPTO_RIPEMD160_HMAC:
1321 default:
1322 q->q_session.omr |= ISES_HOMR_HFR_RMD160;
1323 break;
1324 }
1325
1326 q->q_session.cvr[0] = ses->cvr[0];
1327 q->q_session.cvr[1] = ses->cvr[1];
1328 q->q_session.cvr[2] = ses->cvr[2];
1329 q->q_session.cvr[3] = ses->cvr[3];
1330 q->q_session.cvr[4] = ses->cvr[4];
1331 }
1332
1333 if (enccrd && maccrd) {
1334 /* XXX Check if ises handles differing end of auth/enc etc */
1335 /* XXX For now, assume not (same as ubsec). */
1336 if (((encoffset + enccrd->crd_len) !=
1337 (macoffset + maccrd->crd_len)) ||
1338 (enccrd->crd_skip < maccrd->crd_skip)) {
1339 goto errout;
1340 }
1341
1342 sskip = maccrd->crd_skip;
1343 cpskip = dskip = enccrd->crd_skip;
1344 stheend = maccrd->crd_len;
1345 dtheend = enccrd->crd_len;
1346 coffset = cpskip - sskip;
1347 cpoffset = cpskip + dtheend;
1348 /* XXX DEBUG ? */
1349 } else {
1350 cpskip = dskip = sskip = macoffset + encoffset;
1351 dtheend = enccrd ? enccrd->crd_len : maccrd->crd_len;
1352 stheend = dtheend;
1353 cpoffset = cpskip + dtheend;
1354 coffset = 0;
1355 }
1356 q->q_offset = coffset >> 2;
1357
1358 #if 0 /* XXX not sure about this, in bus_dma context */
1359
1360 if (crp->crp_flags & CRYPTO_F_IMBUF)
1361 q->q_src_l = mbuf2pages(q->q_src.mbuf, &q->q_src_npa,
1362 q->q_src_packp, q->q_src_packl, 1, &nicealign);
1363 else if (crp->crp_flags & CRYPTO_F_IOV)
1364 q->q_src_l = iov2pages(q->q_src.uio, &q->q_src_npa,
1365 q->q_src_packp, q->q_src_packl, 1, &nicealign);
1366 /* XXX else */
1367
1368 DPRINTF(("%s:ises_process: foo2pages called!\n", dv));
1369
1370 if (q->q_src_l == 0)
1371 goto memerr;
1372 else if (q->q_src_l > 0xfffc) {
1373 err = EIO;
1374 goto errout;
1375 }
1376
1377 /* XXX ... */
1378
1379 if (enccrd == NULL && maccrd != NULL) {
1380 /* XXX ... */
1381 } else {
1382 if (!nicealign && (crp->crp_flags & CRYPTO_F_IOV)) {
1383 goto errout;
1384 } else if (!nicealign && (crp->crp_flags & CRYPTO_F_IMBUF)) {
1385 int totlen, len;
1386 struct mbuf *m, *top, **mp;
1387
1388 totlen = q->q_dst_l = q->q_src_l;
1389 if (q->q_src.mbuf->m_flags & M_PKTHDR) {
1390 MGETHDR(m, M_DONTWAIT, MT_DATA);
1391 M_DUP_PKTHDR(m, q->q_src.mbuf);
1392 len = MHLEN;
1393 } else {
1394 MGET(m, M_DONTWAIT, MT_DATA);
1395 len = MLEN;
1396 }
1397 if (m == NULL)
1398 goto memerr;
1399 if (totlen >= MINCLSIZE) {
1400 MCLGET(m, M_DONTWAIT);
1401 if (m->m_flags & M_EXT)
1402 len = MCLBYTES;
1403 }
1404 m->m_len = len;
1405 top = NULL;
1406 mp = ⊤
1407
1408 while (totlen > 0) {
1409 if (top) {
1410 MGET(m, M_DONTWAIT, MT_DATA);
1411 if (m == NULL) {
1412 m_freem(top);
1413 goto memerr;
1414 }
1415 len = MLEN;
1416 }
1417 if (top && totlen >= MINCLSIZE) {
1418 MCLGET(m, M_DONTWAIT);
1419 if (m->m_flags & M_EXT)
1420 len = MCLBYTES;
1421 }
1422 m->m_len = len = min(totlen, len);
1423 totlen -= len;
1424 *mp = m;
1425
1426 mp = &m->m_next;
1427 }
1428 q->q_dst.mbuf = top;
1429 #if notyet
1430 ubsec_mcopy(q->q_src.mbuf, q->q_dst.mbuf, cpskip, cpoffset);
1431 #endif
1432 } else
1433 q->q_dst.mbuf = q->q_src.mbuf;
1434
1435 #if 0
1436 /* XXX ? */
1437 q->q_dst_l = mbuf2pages(q->q_dst.mbuf, &q->q_dst_npa,
1438 &q->q_dst_packp, &q->q_dst_packl, 1, NULL);
1439 #endif
1440 }
1441
1442 #endif /* XXX */
1443
1444 DPRINTF(("%s:ises_process: queueing request\n", dv));
1445
1446 s = splnet();
1447 SIMPLEQ_INSERT_TAIL(&sc->sc_queue, q, q_next);
1448 sc->sc_nqueue++;
1449 splx(s);
1450 ises_feed(sc);
1451
1452 return (0);
1453
1454 memerr:
1455 err = ENOMEM;
1456 isesstats.nomem++;
1457 errout:
1458 DPRINTF(("%s:ises_process: an error occurred, err=%d, q=%p\n", dv,
1459 err, q));
1460
1461 if (err == EINVAL)
1462 isesstats.invalid++;
1463
1464 if (q) {
1465 if (q->q_src.mbuf != q->q_dst.mbuf)
1466 m_freem(q->q_dst.mbuf);
1467 free(q, M_DEVBUF);
1468 }
1469 crp->crp_etype = err;
1470 crypto_done(crp);
1471 return (0);
1472 }
1473
1474 void
ises_callback(struct ises_q * q)1475 ises_callback(struct ises_q *q)
1476 {
1477 struct cryptop *crp = (struct cryptop *)q->q_crp;
1478 struct cryptodesc *crd;
1479 struct ises_softc *sc = q->q_sc;
1480 u_int8_t *sccr;
1481
1482 if ((crp->crp_flags & CRYPTO_F_IMBUF) &&
1483 (q->q_src.mbuf != q->q_dst.mbuf)) {
1484 m_freem(q->q_src.mbuf);
1485 crp->crp_buf = (caddr_t)q->q_dst.mbuf;
1486 }
1487
1488 if (q->q_session.omr & ISES_SOMR_EDR) {
1489 /* Copy out IV after encryption. */
1490 sccr = (u_int8_t *)&sc->sc_sessions[q->q_sesn].sccr;
1491 for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
1492 if (crd->crd_alg != CRYPTO_DES_CBC &&
1493 crd->crd_alg != CRYPTO_3DES_CBC)
1494 continue;
1495 if (crp->crp_flags & CRYPTO_F_IMBUF)
1496 m_copydata((struct mbuf *)crp->crp_buf,
1497 crd->crd_skip + crd->crd_len - 8, 8, sccr);
1498 else if (crp->crp_flags & CRYPTO_F_IOV)
1499 cuio_copydata((struct uio *)crp->crp_buf,
1500 crd->crd_skip + crd->crd_len - 8, 8, sccr);
1501 }
1502 }
1503
1504 for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
1505 if (crd->crd_alg != CRYPTO_MD5_HMAC &&
1506 crd->crd_alg != CRYPTO_SHA1_HMAC &&
1507 crd->crd_alg != CRYPTO_RIPEMD160_HMAC)
1508 continue;
1509 if (crp->crp_flags & CRYPTO_F_IMBUF)
1510 m_copyback((struct mbuf *)crp->crp_buf,
1511 crd->crd_inject, 12, (u_int8_t *)q->q_macbuf);
1512 else if (crp->crp_flags & CRYPTO_F_IOV)
1513 bcopy((u_int8_t *)q->q_macbuf, crp->crp_mac, 12);
1514 /* XXX else ... */
1515 break;
1516 }
1517
1518 free(q, M_DEVBUF);
1519 DPRINTF(("%s:ises_callback: calling crypto_done\n",
1520 sc->sc_dv.dv_xname));
1521 crypto_done(crp);
1522 }
1523
1524 /* Initilize the ISES hardware RNG, and set up timeouts. */
1525 void
ises_hrng_init(struct ises_softc * sc)1526 ises_hrng_init(struct ises_softc *sc)
1527 {
1528 u_int32_t cmd, r;
1529 int i;
1530 #ifdef ISESDEBUG
1531 struct timeval tv1, tv2;
1532 #endif
1533
1534 /* Asking for random data will seed LFSR and start the RBG */
1535 cmd = ISES_MKCMD(ISES_CMD_HBITS, 1);
1536 r = 8; /* 8 * 32 = 256 bits */
1537
1538 if (ises_queue_cmd(sc, cmd, &r, NULL))
1539 return;
1540
1541 /* Wait until response arrives. */
1542 for (i = 1000; i && READ_REG(sc, ISES_A_OQS) == 0; i--)
1543 DELAY(10);
1544
1545 if (!READ_REG(sc, ISES_A_OQS))
1546 return;
1547
1548 /* Drain cmd response and 8*32 bits data */
1549 for (i = 0; i <= r; i++)
1550 (void)READ_REG(sc, ISES_A_OQD);
1551
1552 /* ACK the response */
1553 WRITE_REG(sc, ISES_A_OQS, 0);
1554 DELAY(1);
1555 printf(", %s rng active", sc->sc_dv.dv_xname);
1556
1557 #ifdef ISESDEBUG
1558 /* Benchmark the HRNG. */
1559
1560 /*
1561 * XXX These values gets surprisingly large. Docs state the
1562 * HNRG produces > 1 mbit/s of random data. The values I'm seeing
1563 * are much higher, ca 2.7-2.8 mbit/s. AFAICT the algorithm is sound.
1564 * Compiler optimization issues, perhaps?
1565 */
1566
1567 #define ISES_WPR 250
1568 #define ISES_ROUNDS 100
1569 cmd = ISES_MKCMD(ISES_CMD_HBITS, 1);
1570 r = ISES_WPR;
1571
1572 /* Queue 100 cmds; each generate 250 32-bit words of rnd data. */
1573 microtime(&tv1);
1574 for (i = 0; i < ISES_ROUNDS; i++)
1575 ises_queue_cmd(sc, cmd, &r, NULL);
1576 for (i = 0; i < ISES_ROUNDS; i++) {
1577 while (READ_REG(sc, ISES_A_OQS) == 0) ; /* Wait for response */
1578
1579 (void)READ_REG(sc, ISES_A_OQD); /* read response */
1580 for (r = ISES_WPR; r--;)
1581 (void)READ_REG(sc, ISES_A_OQD); /* read data */
1582 WRITE_REG(sc, ISES_A_OQS, 0); /* ACK resp */
1583 DELAY(1); /* OQS needs 1us to decrement */
1584 }
1585 microtime(&tv2);
1586
1587 timersub(&tv2, &tv1, &tv1);
1588 tv1.tv_usec += 1000000 * tv1.tv_sec;
1589 printf(", %dKb/sec",
1590 ISES_WPR * ISES_ROUNDS * 32 / 1024 * 1000000 / tv1.tv_usec);
1591 #endif
1592
1593 timeout_set(&sc->sc_timeout, ises_hrng, sc);
1594 #ifndef ISES_HRNG_DISABLED
1595 ises_hrng(sc); /* Call first update */
1596 #endif
1597 }
1598
1599 /* Called by timeout (and once by ises_init_hrng()). */
1600 void
ises_hrng(void * v)1601 ises_hrng(void *v)
1602 {
1603 /*
1604 * Throw a HRNG read random bits command on the command queue.
1605 * The normal loop will manage the result and add it to the pool.
1606 */
1607 struct ises_softc *sc = v;
1608 u_int32_t cmd, n;
1609 extern int hz; /* from param.c */
1610
1611 timeout_add(&sc->sc_timeout, hz / ISESRNGIPS);
1612
1613 if (ises_assert_cmd_mode(sc) != 0)
1614 return;
1615
1616 cmd = ISES_MKCMD(ISES_CMD_HBITS, 1);
1617 n = (ISESRNGBITS >> 5) & 0xff; /* ask for N 32 bit words */
1618
1619 ises_queue_cmd(sc, cmd, &n, NULL);
1620 }
1621
1622 u_int32_t
ises_get_fwversion(struct ises_softc * sc)1623 ises_get_fwversion(struct ises_softc *sc)
1624 {
1625 u_int32_t r;
1626 int i;
1627
1628 r = ISES_MKCMD(ISES_CMD_CHIP_ID, 0);
1629 WRITE_REG(sc, ISES_A_IQD, r);
1630 WRITE_REG(sc, ISES_A_IQS, 0);
1631
1632 for (i = 100; i > 0 && READ_REG(sc, ISES_A_OQS) == 0; i--)
1633 DELAY(1);
1634
1635 if (i < 1)
1636 return (0); /* No response */
1637
1638 r = READ_REG(sc, ISES_A_OQD);
1639
1640 /* Check validity. On error drain reponse data. */
1641 if (((r >> 16) & 0xff) != ISES_CMD_CHIP_ID ||
1642 ((r >> 24) & 0xff) != 3 || (r & ISES_RC_MASK) != ISES_RC_SUCCESS) {
1643 if ((r & ISES_RC_MASK) == ISES_RC_SUCCESS)
1644 for (i = ((r >> 24) & 0xff); i; i--)
1645 (void)READ_REG(sc, ISES_A_OQD);
1646 r = 0;
1647 goto out;
1648 }
1649
1650 r = READ_REG(sc, ISES_A_OQD); /* read version */
1651 (void)READ_REG(sc, ISES_A_OQD); /* Discard 64bit "chip-id" */
1652 (void)READ_REG(sc, ISES_A_OQD);
1653 out:
1654 WRITE_REG(sc, ISES_A_OQS, 0); /* Ack the response */
1655 DELAY(1);
1656 return (r);
1657 }
1658
1659 /*
1660 * ises_assert_cmd_mode() returns
1661 * -1 for failure to go to cmd
1662 * 0 if mode already was cmd
1663 * >0 if mode was other (WFC/WFR) but now is cmd (this has reset the queues)
1664 */
1665 int
ises_assert_cmd_mode(struct ises_softc * sc)1666 ises_assert_cmd_mode(struct ises_softc *sc)
1667 {
1668 switch (ISES_STAT_SW_MODE(READ_REG(sc, ISES_A_STAT))) {
1669 case 0x0: /* Selftest. XXX This is a transient state. */
1670 DELAY(1000000);
1671 if (ISES_STAT_SW_MODE(READ_REG(sc, ISES_A_STAT)) == 0)
1672 return (-1);
1673 return (ises_assert_cmd_mode(sc));
1674 case 0x1: /* Command mode */
1675 return (0);
1676 case 0x2: /* Waiting For Continue / WFC */
1677 bus_space_write_2(sc->sc_memt, sc->sc_memh, ISES_A_CTRL,
1678 ISES_A_CTRL_CONTINUE);
1679 DELAY(1);
1680 return ((ISES_STAT_SW_MODE(READ_REG(sc, ISES_A_STAT)) == 0) ?
1681 1 : -1);
1682 case 0x3: /* Waiting For Reset / WFR */
1683 bus_space_write_2(sc->sc_memt, sc->sc_memh, ISES_A_CTRL,
1684 ISES_A_CTRL_RESET);
1685 DELAY(1000000);
1686 return ((ISES_STAT_SW_MODE(READ_REG(sc, ISES_A_STAT)) == 0) ?
1687 2 : -1);
1688 default:
1689 return (-1); /* Unknown mode */
1690 }
1691 }
1692
1693 int
ises_bchu_switch_session(struct ises_softc * sc,struct ises_session * ss,int new_session)1694 ises_bchu_switch_session (struct ises_softc *sc, struct ises_session *ss,
1695 int new_session)
1696 {
1697 /* It appears that the BCHU_SWITCH_SESSION command is broken. */
1698 /* We have to work around it. */
1699
1700 u_int32_t cmd;
1701
1702 /* Do we have enough in-queue space? Count cmds + data, 16bit words. */
1703 if ((8 * 2 + sizeof (*ss) / 2) > READ_REG(sc, ISES_A_IQF))
1704 return (0);
1705
1706 /* Mark 'switch' in progress. */
1707 sc->sc_switching = new_session + 1;
1708
1709 /* Write the key. */
1710 cmd = ISES_MKCMD(ISES_CMD_BW_KR0, 2);
1711 ises_queue_cmd(sc, cmd, &ss->kr[4], NULL);
1712 cmd = ISES_MKCMD(ISES_CMD_BW_KR1, 2);
1713 ises_queue_cmd(sc, cmd, &ss->kr[2], NULL);
1714 cmd = ISES_MKCMD(ISES_CMD_BW_KR2, 2);
1715 ises_queue_cmd(sc, cmd, &ss->kr[0], NULL);
1716
1717 /* Write OMR - Operation Method Register, clears SCCR+CVR+DBCR+HMLR */
1718 cmd = ISES_MKCMD(ISES_CMD_BW_OMR, 1);
1719 ises_queue_cmd(sc, cmd, &ss->omr, NULL);
1720
1721 /* Write SCCR - Symmetric Crypto Chaining Register (IV) */
1722 cmd = ISES_MKCMD(ISES_CMD_BW_SCCR, 2);
1723 ises_queue_cmd(sc, cmd, &ss->sccr[0], NULL);
1724
1725 /* Write CVR - Chaining Variables Register (hash state) */
1726 cmd = ISES_MKCMD(ISES_CMD_BW_CVR, 5);
1727 ises_queue_cmd(sc, cmd, &ss->cvr[0], NULL);
1728
1729 /* Write DBCR - Data Block Count Register */
1730 cmd = ISES_MKCMD(ISES_CMD_BW_DBCR, 2);
1731 ises_queue_cmd(sc, cmd, &ss->dbcr[0], NULL);
1732
1733 /* Write HMLR - Hash Message Length Register - last cmd in switch */
1734 cmd = ISES_MKCMD(ISES_CMD_BW_HMLR, 2);
1735 ises_queue_cmd(sc, cmd, &ss->hmlr[0], ises_bchu_switch_final);
1736
1737 return (1);
1738 }
1739
1740 u_int32_t
ises_bchu_switch_final(struct ises_softc * sc,struct ises_cmd * cmd)1741 ises_bchu_switch_final (struct ises_softc *sc, struct ises_cmd *cmd)
1742 {
1743 /* Session switch is complete. */
1744
1745 DPRINTF(("%s:ises_bchu_switch_final: switch complete\n",
1746 sc->sc_dv.dv_xname));
1747
1748 sc->sc_cursession = sc->sc_switching - 1;
1749 sc->sc_switching = 0;
1750
1751 /* Retry/restart feed. */
1752 ises_feed(sc);
1753
1754 return (0);
1755 }
1756
1757 /* XXX Currently unused. */
1758 void
ises_read_dma(struct ises_softc * sc)1759 ises_read_dma (struct ises_softc *sc)
1760 {
1761 bus_dma_segment_t *ds = &sc->sc_dmamap->dm_segs[0];
1762 u_int32_t dma_status;
1763
1764 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0,
1765 sc->sc_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
1766
1767 WRITE_REG(sc, ISES_DMA_READ_START, ds->ds_addr);
1768 WRITE_REG(sc, ISES_DMA_READ_START, ISES_DMA_RCOUNT(ds->ds_len));
1769
1770 dma_status = READ_REG(sc, ISES_DMA_STATUS);
1771 dma_status |= ISES_DMA_CTRL_ILT | ISES_DMA_CTRL_WRITE;
1772 WRITE_REG(sc, ISES_DMA_CTRL, dma_status);
1773 }
1774
1775 #ifdef ISESDEBUG
1776 /*
1777 * Development code section below here.
1778 */
1779
1780 void
ises_debug_init(struct ises_softc * sc)1781 ises_debug_init (struct ises_softc *sc)
1782 {
1783 ises_sc = sc;
1784 ises_db = 0;
1785 timeout_set (&ises_db_timeout, ises_debug_loop, sc);
1786 timeout_add (&ises_db_timeout, 100);
1787 printf ("ises0: ISESDEBUG active (ises_sc = %p)\n", ises_sc);
1788 }
1789
1790 void
ises_debug_2(void)1791 ises_debug_2 (void)
1792 {
1793 timeout_set (&ises_db_timeout, ises_debug_loop, ises_sc);
1794 timeout_add (&ises_db_timeout, 100);
1795 printf ("ises0: another debug timeout scheduled!\n");
1796 }
1797
1798 void
ises_debug_simple_cmd(struct ises_softc * sc,u_int32_t code,u_int32_t d)1799 ises_debug_simple_cmd (struct ises_softc *sc, u_int32_t code, u_int32_t d)
1800 {
1801 u_int32_t cmd, data;
1802
1803 cmd = ISES_MKCMD(code, (d ? 1 : 0));
1804 data = d;
1805 ises_queue_cmd(sc, cmd, &d, NULL);
1806 }
1807
1808 void
ises_debug_loop(void * v)1809 ises_debug_loop (void *v)
1810 {
1811 struct ises_softc *sc = (struct ises_softc *)v;
1812 struct ises_session ses;
1813 u_int32_t cmd, stat;
1814 int i;
1815
1816 if (ises_db)
1817 printf ("ises0: ises_db = %d sc = %p\n", ises_db, sc);
1818
1819 timeout_add (&ises_db_timeout, 300); /* Every 3 secs */
1820
1821 stat = READ_REG(sc, ISES_A_OQS);
1822 cmd = READ_REG(sc, ISES_A_IQS);
1823 if (stat || cmd)
1824 printf ("ises0: IQS=%d OQS=%d / IQF=%d OQF=%d\n",
1825 cmd, stat, READ_REG(sc, ISES_A_IQF),
1826 READ_REG(sc, ISES_A_OQF));
1827
1828 switch (ises_db) {
1829 default:
1830 /* 0 - do nothing (just loop) */
1831 break;
1832 case 1:
1833 /* Just dump register info */
1834 ises_showreg();
1835 break;
1836 case 2:
1837 /* Reset LNAU 1 registers */
1838 ises_debug_simple_cmd(sc, ISES_CMD_LRESET_1, 0);
1839
1840 /* Compute R = (141 * 5623) % 117 (R should be 51 (0x33)) */
1841 ises_debug_simple_cmd(sc, ISES_CMD_LW_A_1, 141);
1842 ises_debug_simple_cmd(sc, ISES_CMD_LW_B_1, 5623);
1843 ises_debug_simple_cmd(sc, ISES_CMD_LW_N_1, 117);
1844
1845 /* Launch LNAU operation. */
1846 ises_debug_simple_cmd(sc, ISES_CMD_LMULMOD_1, 0);
1847 break;
1848 case 3:
1849 /* Read result LNAU_1 R register (should not be necessary) */
1850 ises_debug_simple_cmd(sc, ISES_CMD_LUPLOAD_1, 0);
1851 break;
1852 case 4:
1853 /* Print result */
1854 printf ("LNAU_1 R length = %d\n", sc->sc_lnau1_rlen);
1855 for (i = 0; i < sc->sc_lnau1_rlen; i++)
1856 printf ("W%02d-[%08x]-(%u)\t%s", i, sc->sc_lnau1_r[i],
1857 sc->sc_lnau1_r[i], (i%4)==3 ? "\n" : "");
1858 printf ("%s", (i%4) ? "\n" : "");
1859 break;
1860 case 5:
1861 /* Crypto. */
1862
1863 /* Load BCHU session data */
1864 bzero(&ses, sizeof ses);
1865 ses.kr[0] = 0xD0;
1866 ses.kr[1] = 0xD1;
1867 ses.kr[2] = 0xD2;
1868 ses.kr[3] = 0xD3;
1869 ses.kr[4] = 0xD4;
1870 ses.kr[5] = 0xD5;
1871
1872 /* cipher data out is hash in, SHA1, 3DES, encrypt, ECB */
1873 ses.omr = ISES_SELR_BCHU_HISOF | ISES_HOMR_HFR_SHA1 |
1874 ISES_SOMR_BOMR_3DES | ISES_SOMR_EDR | ISES_SOMR_FMR_ECB;
1875
1876 #if 1
1877 printf ("Queueing home-cooked session switch\n");
1878 ises_bchu_switch_session(sc, &ses, 0);
1879 #else /* switch session does not appear to work - it never returns */
1880 printf ("Queueing BCHU session switch\n");
1881 cmd = ISES_MKCMD(ISES_CMD_BSWITCH, sizeof ses / 4);
1882 printf ("session is %d 32bit words (== 18 ?), cmd = [%08x]\n",
1883 sizeof ses / 4, cmd);
1884 ises_queue_cmd(sc, cmd, (u_int32_t *)&ses, NULL);
1885 #endif
1886
1887 break;
1888 case 96:
1889 printf ("Stopping HRNG data collection\n");
1890 timeout_del(&sc->sc_timeout);
1891 break;
1892 case 97:
1893 printf ("Restarting HRNG data collection\n");
1894 if (!timeout_pending(&sc->sc_timeout))
1895 timeout_add(&sc->sc_timeout, hz);
1896 break;
1897 case 98:
1898 printf ("Resetting (wait >1s before cont.)\n");
1899 stat = ISES_BO_STAT_HWRESET;
1900 WRITE_REG(sc, ISES_BO_STAT, stat);
1901 stat &= ~ISES_BO_STAT_HWRESET;
1902 WRITE_REG(sc, ISES_BO_STAT, stat);
1903 break;
1904 case 99:
1905 printf ("Resetting everything!\n");
1906 if (timeout_pending(&sc->sc_timeout))
1907 timeout_del(&sc->sc_timeout);
1908 timeout_set(&sc->sc_timeout, ises_initstate, sc);
1909 sc->sc_initstate = 0;
1910 ises_initstate(sc);
1911 break;
1912 }
1913
1914 ises_db = 0;
1915 }
1916
1917 void
ises_showreg(void)1918 ises_showreg (void)
1919 {
1920 struct ises_softc *sc = ises_sc;
1921 u_int32_t stat, cmd;
1922
1923 /* Board register */
1924
1925 printf ("Board register: ");
1926 stat = READ_REG(sc, ISES_BO_STAT);
1927
1928 if (stat & ISES_BO_STAT_LOOP)
1929 printf ("LoopMode ");
1930 if (stat & ISES_BO_STAT_TAMPER)
1931 printf ("Tamper ");
1932 if (stat & ISES_BO_STAT_POWERDOWN)
1933 printf ("PowerDown ");
1934 if (stat & ISES_BO_STAT_ACONF)
1935 printf ("16bitA-IF ");
1936 if (stat & ISES_BO_STAT_HWRESET)
1937 printf ("HWReset");
1938 if (stat & ISES_BO_STAT_AIRQ)
1939 printf ("A-IFintr");
1940 printf("\n");
1941
1942 /* A interface */
1943
1944 printf ("A Interface STAT register: \n\tLNAU-[");
1945 stat = READ_REG(sc, ISES_A_STAT);
1946 if (stat & ISES_STAT_LNAU_MASKED)
1947 printf ("masked");
1948 else {
1949 if (stat & ISES_STAT_LNAU_BUSY_1)
1950 printf ("busy1 ");
1951 if (stat & ISES_STAT_LNAU_ERR_1)
1952 printf ("err1 ");
1953 if (stat & ISES_STAT_LNAU_BUSY_2)
1954 printf ("busy2 ");
1955 if (stat & ISES_STAT_LNAU_ERR_2)
1956 printf ("err2 ");
1957 }
1958 printf ("]\n\tBCHU-[");
1959
1960 if (stat & ISES_STAT_BCHU_MASKED)
1961 printf ("masked");
1962 else {
1963 if (stat & ISES_STAT_BCHU_BUSY)
1964 printf ("busy ");
1965 if (stat & ISES_STAT_BCHU_ERR)
1966 printf ("err ");
1967 if (stat & ISES_STAT_BCHU_SCIF)
1968 printf ("cr-inop ");
1969 if (stat & ISES_STAT_BCHU_HIF)
1970 printf ("ha-inop ");
1971 if (stat & ISES_STAT_BCHU_DDB)
1972 printf ("dscd-data ");
1973 if (stat & ISES_STAT_BCHU_IRF)
1974 printf ("inp-req ");
1975 if (stat & ISES_STAT_BCHU_OAF)
1976 printf ("out-avail ");
1977 if (stat & ISES_STAT_BCHU_DIE)
1978 printf ("inp-enabled ");
1979 if (stat & ISES_STAT_BCHU_UE)
1980 printf ("ififo-empty ");
1981 if (stat & ISES_STAT_BCHU_IFE)
1982 printf ("ififo-half ");
1983 if (stat & ISES_STAT_BCHU_IFHE)
1984 printf ("ififo-full ");
1985 if (stat & ISES_STAT_BCHU_OFE)
1986 printf ("ofifo-empty ");
1987 if (stat & ISES_STAT_BCHU_OFHF)
1988 printf ("ofifo-half ");
1989 if (stat & ISES_STAT_BCHU_OFF)
1990 printf ("ofifo-full ");
1991 }
1992 printf ("] \n\tmisc-[");
1993
1994 if (stat & ISES_STAT_HW_DA)
1995 printf ("downloaded-appl ");
1996 if (stat & ISES_STAT_HW_ACONF)
1997 printf ("A-IF-conf ");
1998 if (stat & ISES_STAT_SW_WFOQ)
1999 printf ("OQ-wait ");
2000 if (stat & ISES_STAT_SW_OQSINC)
2001 printf ("OQS-increased ");
2002 printf ("]\n\t");
2003
2004 if (stat & ISES_STAT_HW_DA)
2005 printf ("SW-mode is \"%s\"",
2006 ises_sw_mode[ISES_STAT_SW_MODE(stat)]);
2007 else
2008 printf ("IDP-state is \"%s\"",
2009 ises_idp_state[ISES_STAT_IDP_STATE(stat)]);
2010 printf ("\n");
2011
2012 printf ("\tOQS = %d IQS = %d OQF = %d IQF = %d\n",
2013 READ_REG(sc, ISES_A_OQS), READ_REG(sc, ISES_A_IQS),
2014 READ_REG(sc, ISES_A_OQF), READ_REG(sc, ISES_A_IQF));
2015
2016 /* B interface */
2017
2018 printf ("B-interface status register contains [%08x]\n",
2019 READ_REG(sc, ISES_B_STAT));
2020
2021 /* DMA */
2022
2023 printf ("DMA read starts at 0x%x, length %d bytes\n",
2024 READ_REG(sc, ISES_DMA_READ_START),
2025 READ_REG(sc, ISES_DMA_READ_COUNT) >> 16);
2026
2027 printf ("DMA write starts at 0x%x, length %d bytes\n",
2028 READ_REG(sc, ISES_DMA_WRITE_START),
2029 READ_REG(sc, ISES_DMA_WRITE_COUNT) & 0x00ff);
2030
2031 stat = READ_REG(sc, ISES_DMA_STATUS);
2032 printf ("DMA status register contains [%08x]\n", stat);
2033
2034 if (stat & ISES_DMA_CTRL_ILT)
2035 printf (" -- Ignore latency timer\n");
2036 if (stat & 0x0C000000)
2037 printf (" -- PCI Read - multiple\n");
2038 else if (stat & 0x08000000)
2039 printf (" -- PCI Read - line\n");
2040
2041 if (stat & ISES_DMA_STATUS_R_RUN)
2042 printf (" -- PCI Read running/incomplete\n");
2043 else
2044 printf (" -- PCI Read complete\n");
2045 if (stat & ISES_DMA_STATUS_R_ERR)
2046 printf (" -- PCI Read DMA Error\n");
2047
2048 if (stat & ISES_DMA_STATUS_W_RUN)
2049 printf (" -- PCI Write running/incomplete\n");
2050 else
2051 printf (" -- PCI Write complete\n");
2052 if (stat & ISES_DMA_STATUS_W_ERR)
2053 printf (" -- PCI Write DMA Error\n");
2054
2055 /* OMR / HOMR / SOMR */
2056
2057 /*
2058 * All these means throwing a cmd on to the A-interface, and then
2059 * reading the result.
2060 *
2061 * Currently, put debug output in process_oqueue...
2062 */
2063
2064 printf ("Queueing Operation Method Register (OMR) READ cmd...\n");
2065 cmd = ISES_MKCMD(ISES_CMD_BR_OMR, 0);
2066 ises_queue_cmd(sc, cmd, NULL, NULL);
2067 }
2068
2069 void
ises_debug_parse_omr(struct ises_softc * sc)2070 ises_debug_parse_omr (struct ises_softc *sc)
2071 {
2072 u_int32_t omr = sc->sc_sessions[sc->sc_cursession].omr;
2073
2074 printf ("SELR : ");
2075 if (omr & ISES_SELR_BCHU_EH)
2076 printf ("cont-on-error ");
2077 else
2078 printf ("stop-on-error ");
2079
2080 if (omr & ISES_SELR_BCHU_HISOF)
2081 printf ("HU-input-is-SCU-output ");
2082
2083 if (omr & ISES_SELR_BCHU_DIS)
2084 printf ("data-interface-select=B ");
2085 else
2086 printf ("data-interface-select=DataIn/DataOut ");
2087
2088 printf ("\n");
2089
2090 printf ("HOMR : ");
2091 if (omr & ISES_HOMR_HMTR)
2092 printf ("expect-padded-hash-msg ");
2093 else
2094 printf ("expect-plaintext-hash-msg ");
2095
2096 printf ("ER=%d ", (omr & ISES_HOMR_ER) >> 20); /* ick */
2097
2098 printf ("HFR=");
2099 switch (omr & ISES_HOMR_HFR) {
2100 case ISES_HOMR_HFR_NOP:
2101 printf ("inactive ");
2102 break;
2103 case ISES_HOMR_HFR_MD5:
2104 printf ("MD5 ");
2105 break;
2106 case ISES_HOMR_HFR_RMD160:
2107 printf ("RMD160 ");
2108 break;
2109 case ISES_HOMR_HFR_RMD128:
2110 printf ("RMD128 ");
2111 break;
2112 case ISES_HOMR_HFR_SHA1:
2113 printf ("SHA-1 ");
2114 break;
2115 default:
2116 printf ("reserved! ");
2117 break;
2118 }
2119 printf ("\nSOMR : ");
2120
2121 switch (omr & ISES_SOMR_BOMR) {
2122 case ISES_SOMR_BOMR_NOP:
2123 printf ("NOP ");
2124 break;
2125 case ISES_SOMR_BOMR_TRANSPARENT:
2126 printf ("transparent ");
2127 break;
2128 case ISES_SOMR_BOMR_DES:
2129 printf ("DES ");
2130 break;
2131 case ISES_SOMR_BOMR_3DES2:
2132 printf ("3DES-2 ");
2133 break;
2134 case ISES_SOMR_BOMR_3DES:
2135 printf ("3DES-3 ");
2136 break;
2137 default:
2138 if (omr & ISES_SOMR_BOMR_SAFER)
2139 printf ("SAFER ");
2140 else
2141 printf ("reserved! ");
2142 break;
2143 }
2144
2145 if (omr & ISES_SOMR_EDR)
2146 printf ("mode=encrypt ");
2147 else
2148 printf ("mode=decrypt ");
2149
2150 switch (omr & ISES_SOMR_FMR) {
2151 case ISES_SOMR_FMR_ECB:
2152 printf ("ECB");
2153 break;
2154 case ISES_SOMR_FMR_CBC:
2155 printf ("CBC");
2156 break;
2157 case ISES_SOMR_FMR_CFB64:
2158 printf ("CFB64");
2159 break;
2160 case ISES_SOMR_FMR_OFB64:
2161 printf ("OFB64");
2162 break;
2163 default:
2164 /* Nada */
2165 }
2166 printf ("\n");
2167 }
2168
2169 #endif /* ISESDEBUG */
2170