This source file includes following definitions.
- nofn_match
- nofn_attach
- nofn_intr
- nofn_rng_read
- nofn_rng_intr
- nofn_rng_tick
- nofn_rng_disable
- nofn_rng_enable
- nofn_pk_enable
- nofn_pk_feed
- nofn_pk_process
- nofn_pk_find
- nofn_pk_read_reg
- nofn_pk_write_reg
- nofn_pk_zero_reg
- nofn_modexp_start
- nofn_modexp_finish
- nofn_pk_sigbits
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/proc.h>
41 #include <sys/errno.h>
42 #include <sys/malloc.h>
43 #include <sys/kernel.h>
44 #include <sys/mbuf.h>
45 #include <sys/device.h>
46 #include <sys/queue.h>
47
48 #include <crypto/cryptodev.h>
49 #include <crypto/cryptosoft.h>
50 #include <dev/rndvar.h>
51 #include <crypto/md5.h>
52 #include <crypto/sha1.h>
53
54 #include <dev/pci/pcireg.h>
55 #include <dev/pci/pcivar.h>
56 #include <dev/pci/pcidevs.h>
57
58 #include <dev/pci/nofnreg.h>
59 #include <dev/pci/nofnvar.h>
60
61 int nofn_match(struct device *, void *, void *);
62 void nofn_attach(struct device *, struct device *, void *);
63 int nofn_intr(void *);
64
65 void nofn_rng_enable(struct nofn_softc *);
66 void nofn_rng_disable(struct nofn_softc *);
67 void nofn_rng_tick(void *);
68 int nofn_rng_intr(struct nofn_softc *);
69 int nofn_rng_read(struct nofn_softc *);
70
71 int nofn_pk_process(struct cryptkop *);
72 void nofn_pk_enable(struct nofn_softc *);
73 void nofn_pk_feed(struct nofn_softc *);
74 struct nofn_softc *nofn_pk_find(struct cryptkop *);
75 void nofn_pk_write_reg(struct nofn_softc *, int, union nofn_pk_reg *);
76 void nofn_pk_read_reg(struct nofn_softc *, int, union nofn_pk_reg *);
77 void nofn_pk_zero_reg(struct nofn_softc *, int);
78 int nofn_modexp_start(struct nofn_softc *, struct nofn_pk_q *);
79 void nofn_modexp_finish(struct nofn_softc *, struct nofn_pk_q *);
80 int nofn_pk_sigbits(const u_int8_t *, u_int);
81
82 struct cfattach nofn_ca = {
83 sizeof(struct nofn_softc), nofn_match, nofn_attach
84 };
85
86 struct cfdriver nofn_cd = {
87 0, "nofn", DV_DULL
88 };
89
90 int
91 nofn_match(parent, match, aux)
92 struct device *parent;
93 void *match, *aux;
94 {
95 struct pci_attach_args *pa = (struct pci_attach_args *)aux;
96
97 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_HIFN &&
98 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_78XX)
99 return (1);
100 return (0);
101 }
102
103 void
104 nofn_attach(parent, self, aux)
105 struct device *parent, *self;
106 void *aux;
107 {
108 struct nofn_softc *sc = (struct nofn_softc *)self;
109 struct pci_attach_args *pa = aux;
110 pci_chipset_tag_t pc = pa->pa_pc;
111 pci_intr_handle_t ih;
112 const char *intrstr = NULL;
113 bus_size_t bar0size = 0, bar3size = 0;
114
115 sc->sc_dmat = pa->pa_dmat;
116
117 if (pci_mapreg_map(pa, NOFN_BAR0_REGS, PCI_MAPREG_TYPE_MEM, 0,
118 &sc->sc_st, &sc->sc_sh, NULL, &bar0size, 0)) {
119 printf(": can't map bar0 regs\n");
120 goto fail;
121 }
122
123 if (pci_intr_map(pa, &ih)) {
124 printf(": couldn't map interrupt\n");
125 bus_space_unmap(sc->sc_st, sc->sc_sh, bar0size);
126 goto fail;
127 }
128
129 intrstr = pci_intr_string(pc, ih);
130 sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, nofn_intr, sc,
131 self->dv_xname);
132 if (sc->sc_ih == NULL) {
133 printf(": couldn't establish interrupt");
134 if (intrstr != NULL)
135 printf(" at %s", intrstr);
136 printf("\n");
137 goto fail;
138 }
139
140 sc->sc_revid = REG_READ_4(sc, NOFN_REVID);
141
142 switch (sc->sc_revid) {
143 case REVID_7814_7854_1:
144 case REVID_8154_1:
145 case REVID_8065_1:
146 case REVID_8165_1:
147 if (pci_mapreg_map(pa, NOFN_BAR3_PK, PCI_MAPREG_TYPE_MEM, 0,
148 &sc->sc_pk_t, &sc->sc_pk_h, NULL, &bar3size, 0)) {
149 printf(": can't map bar3 regs\n");
150 goto fail;
151 }
152 nofn_rng_enable(sc);
153 nofn_pk_enable(sc);
154 break;
155 case REVID_7851_1:
156 case REVID_7851_2:
157 break;
158 default:
159 printf(": unknown revid %x\n", sc->sc_revid);
160 break;
161 }
162
163 printf(":");
164 if (sc->sc_flags & NOFN_FLAGS_PK)
165 printf(" PK");
166 if (sc->sc_flags & NOFN_FLAGS_RNG)
167 printf(" RNG");
168 printf(", %s\n", intrstr);
169
170 REG_WRITE_4(sc, NOFN_PCI_INT_MASK, sc->sc_intrmask);
171
172 return;
173
174 fail:
175 if (bar3size != 0)
176 bus_space_unmap(sc->sc_pk_t, sc->sc_pk_h, bar3size);
177 if (bar0size != 0)
178 bus_space_unmap(sc->sc_st, sc->sc_sh, bar0size);
179 }
180
181 int
182 nofn_intr(vsc)
183 void *vsc;
184 {
185 struct nofn_softc *sc = vsc;
186 u_int32_t stat;
187 int r = 0;
188
189 stat = REG_READ_4(sc, NOFN_PCI_INT_STAT) & sc->sc_intrmask;
190
191 if (stat & PCIINTSTAT_RNGRDY)
192 r |= nofn_rng_intr(sc);
193
194 if (stat & PCIINTSTAT_PK) {
195 struct nofn_pk_q *q;
196 u_int32_t sr;
197
198 r = 1;
199 sr = PK_READ_4(sc, NOFN_PK_SR);
200 if (sr & PK_SR_DONE && sc->sc_pk_current != NULL) {
201 q = sc->sc_pk_current;
202 sc->sc_pk_current = NULL;
203 q->q_finish(sc, q);
204 free(q, M_DEVBUF);
205 nofn_pk_feed(sc);
206 }
207 }
208
209 return (r);
210 }
211
212 int
213 nofn_rng_read(sc)
214 struct nofn_softc *sc;
215 {
216 u_int32_t buf[8], reg;
217 int ret = 0, i;
218
219 for (;;) {
220 reg = PK_READ_4(sc, NOFN_PK_SR);
221 if (reg & PK_SR_UFLOW) {
222 ret = -1;
223 printf("%s: rng underflow, disabling.\n",
224 sc->sc_dev.dv_xname);
225 nofn_rng_disable(sc);
226 break;
227 }
228
229 if ((reg & PK_SR_RRDY) == 0)
230 break;
231
232 ret = 1;
233 bus_space_read_region_4(sc->sc_pk_t, sc->sc_pk_h,
234 NOFN_PK_RNGFIFO_BEGIN, buf, 8);
235 if (sc->sc_rngskip > 0)
236 sc->sc_rngskip -= 8;
237 else
238 for (i = 0; i < 8; i++)
239 add_true_randomness(buf[i]);
240 }
241
242 return (ret);
243 }
244
245 int
246 nofn_rng_intr(sc)
247 struct nofn_softc *sc;
248 {
249 int r;
250
251 r = nofn_rng_read(sc);
252 if (r == 0)
253 return (0);
254 return (1);
255 }
256
257 void
258 nofn_rng_tick(vsc)
259 void *vsc;
260 {
261 struct nofn_softc *sc = vsc;
262 int s, r;
263
264 s = splnet();
265 r = nofn_rng_read(sc);
266 if (r != -1)
267 timeout_add(&sc->sc_rngto, sc->sc_rngtick);
268 splx(s);
269 }
270
271 void
272 nofn_rng_disable(sc)
273 struct nofn_softc *sc;
274 {
275 u_int32_t r;
276
277
278 r = PK_READ_4(sc, NOFN_PK_CFG2);
279 r &= PK_CFG2_ALU_ENA;
280 PK_WRITE_4(sc, NOFN_PK_CFG2, r);
281
282 switch (sc->sc_revid) {
283 case REVID_7814_7854_1:
284 if (timeout_pending(&sc->sc_rngto))
285 timeout_del(&sc->sc_rngto);
286 break;
287 case REVID_8154_1:
288 case REVID_8065_1:
289 case REVID_8165_1:
290
291 r = PK_READ_4(sc, NOFN_PK_IER);
292 r &= PK_IER_DONE;
293 PK_WRITE_4(sc, NOFN_PK_IER, r);
294
295 sc->sc_intrmask &= ~PCIINTMASK_RNGRDY;
296 REG_WRITE_4(sc, NOFN_PCI_INT_MASK, sc->sc_intrmask);
297 break;
298 default:
299 printf("%s: nofn_rng_disable: unknown rev %x\n",
300 sc->sc_dev.dv_xname, sc->sc_revid);
301 break;
302 }
303
304 sc->sc_flags &= ~NOFN_FLAGS_RNG;
305 }
306
307 void
308 nofn_rng_enable(sc)
309 struct nofn_softc *sc;
310 {
311 u_int32_t r;
312
313
314 PK_WRITE_4(sc, NOFN_PK_RNC, PK_RNC_SCALER);
315
316
317 r = PK_READ_4(sc, NOFN_PK_CFG2);
318 r &= PK_CFG2_ALU_ENA;
319 r |= PK_CFG2_RNG_ENA;
320 PK_WRITE_4(sc, NOFN_PK_CFG2, r);
321
322
323 switch (sc->sc_revid) {
324 case REVID_7814_7854_1:
325 timeout_set(&sc->sc_rngto, nofn_rng_tick, sc);
326 if (hz < 100)
327 sc->sc_rngtick = 1;
328 else
329 sc->sc_rngtick = hz / 100;
330 timeout_add(&sc->sc_rngto, sc->sc_rngtick);
331 break;
332 case REVID_8154_1:
333 case REVID_8065_1:
334 case REVID_8165_1:
335
336 r = PK_READ_4(sc, NOFN_PK_IER);
337 r &= PK_IER_DONE;
338 r |= PK_IER_RRDY;
339 PK_WRITE_4(sc, NOFN_PK_IER, r);
340 sc->sc_intrmask |= PCIINTMASK_RNGRDY;
341 break;
342 default:
343 printf("%s: nofn_rng_enable: unknown rev %x\n",
344 sc->sc_dev.dv_xname, sc->sc_revid);
345 break;
346 }
347
348 sc->sc_flags |= NOFN_FLAGS_RNG;
349 }
350
351 void
352 nofn_pk_enable(sc)
353 struct nofn_softc *sc;
354 {
355 u_int32_t r;
356 int algs[CRK_ALGORITHM_MAX + 1];
357
358 if ((sc->sc_cid = crypto_get_driverid(0)) < 0) {
359 printf(": failed to register cid\n");
360 return;
361 }
362
363 SIMPLEQ_INIT(&sc->sc_pk_queue);
364 sc->sc_pk_current = NULL;
365
366 bzero(algs, sizeof(algs));
367 algs[CRK_MOD_EXP] = CRYPTO_ALG_FLAG_SUPPORTED;
368 crypto_kregister(sc->sc_cid, algs, nofn_pk_process);
369
370
371 r = PK_READ_4(sc, NOFN_PK_CFG2);
372 r &= PK_CFG2_RNG_ENA;
373 r |= PK_CFG2_ALU_ENA;
374 PK_WRITE_4(sc, NOFN_PK_CFG2, r);
375
376 sc->sc_intrmask |= PCIINTMASK_PK;
377 sc->sc_flags |= NOFN_FLAGS_PK;
378 }
379
380 void
381 nofn_pk_feed(sc)
382 struct nofn_softc *sc;
383 {
384 struct nofn_pk_q *q;
385 u_int32_t r;
386
387
388 if (SIMPLEQ_EMPTY(&sc->sc_pk_queue) &&
389 sc->sc_pk_current == NULL) {
390 r = PK_READ_4(sc, NOFN_PK_IER);
391 r &= PK_IER_RRDY;
392 PK_WRITE_4(sc, NOFN_PK_IER, r);
393 return;
394 }
395
396
397 if (sc->sc_pk_current != NULL)
398 return;
399
400 while (!SIMPLEQ_EMPTY(&sc->sc_pk_queue)) {
401 q = SIMPLEQ_FIRST(&sc->sc_pk_queue);
402 if (q->q_start(sc, q) == 0) {
403 sc->sc_pk_current = q;
404 SIMPLEQ_REMOVE_HEAD(&sc->sc_pk_queue, q_next);
405
406 r = PK_READ_4(sc, NOFN_PK_IER);
407 r &= PK_IER_RRDY;
408 r |= PK_IER_DONE;
409 PK_WRITE_4(sc, NOFN_PK_IER, r);
410 break;
411 } else {
412 SIMPLEQ_REMOVE_HEAD(&sc->sc_pk_queue, q_next);
413 free(q, M_DEVBUF);
414 }
415 }
416 }
417
418 int
419 nofn_pk_process(krp)
420 struct cryptkop *krp;
421 {
422 struct nofn_softc *sc;
423 struct nofn_pk_q *q;
424 int s;
425
426 if (krp == NULL || krp->krp_callback == NULL)
427 return (EINVAL);
428 if ((sc = nofn_pk_find(krp)) == NULL) {
429 krp->krp_status = EINVAL;
430 crypto_kdone(krp);
431 return (0);
432 }
433
434 q = (struct nofn_pk_q *)malloc(sizeof(*q), M_DEVBUF, M_NOWAIT);
435 if (q == NULL) {
436 krp->krp_status = ENOMEM;
437 crypto_kdone(krp);
438 return (0);
439 }
440
441 switch (krp->krp_op) {
442 case CRK_MOD_EXP:
443 q->q_start = nofn_modexp_start;
444 q->q_finish = nofn_modexp_finish;
445 q->q_krp = krp;
446 s = splnet();
447 SIMPLEQ_INSERT_TAIL(&sc->sc_pk_queue, q, q_next);
448 nofn_pk_feed(sc);
449 splx(s);
450 return (0);
451 default:
452 printf("%s: kprocess: invalid op 0x%x\n",
453 sc->sc_dev.dv_xname, krp->krp_op);
454 krp->krp_status = EOPNOTSUPP;
455 crypto_kdone(krp);
456 free(q, M_DEVBUF);
457 return (0);
458 }
459 }
460
461 struct nofn_softc *
462 nofn_pk_find(krp)
463 struct cryptkop *krp;
464 {
465 struct nofn_softc *sc;
466 int i;
467
468 for (i = 0; i < nofn_cd.cd_ndevs; i++) {
469 sc = nofn_cd.cd_devs[i];
470 if (sc == NULL)
471 continue;
472 if (sc->sc_cid == krp->krp_hid)
473 return (sc);
474 }
475 return (NULL);
476 }
477
478 void
479 nofn_pk_read_reg(sc, ridx, rp)
480 struct nofn_softc *sc;
481 int ridx;
482 union nofn_pk_reg *rp;
483 {
484 #if BYTE_ORDER == BIG_ENDIAN
485 bus_space_read_region_4(sc->sc_pk_t, sc->sc_pk_h,
486 NOFN_PK_REGADDR(NOFN_PK_WIN_0, ridx, 0), rp->w, 1024/32);
487 #else
488 bus_space_read_region_4(sc->sc_pk_t, sc->sc_pk_h,
489 NOFN_PK_REGADDR(NOFN_PK_WIN_2, ridx, 0), rp->w, 1024/32);
490 #endif
491 }
492
493 void
494 nofn_pk_write_reg(sc, ridx, rp)
495 struct nofn_softc *sc;
496 int ridx;
497 union nofn_pk_reg *rp;
498 {
499 #if BYTE_ORDER == BIG_ENDIAN
500 bus_space_write_region_4(sc->sc_pk_t, sc->sc_pk_h,
501 NOFN_PK_REGADDR(NOFN_PK_WIN_0, ridx, 0), rp->w, 1024/32);
502 #else
503 bus_space_write_region_4(sc->sc_pk_t, sc->sc_pk_h,
504 NOFN_PK_REGADDR(NOFN_PK_WIN_2, ridx, 0), rp->w, 1024/32);
505 #endif
506 }
507
508 void
509 nofn_pk_zero_reg(sc, ridx)
510 struct nofn_softc *sc;
511 int ridx;
512 {
513 nofn_pk_write_reg(sc, ridx, &sc->sc_pk_zero);
514 }
515
516 int
517 nofn_modexp_start(sc, q)
518 struct nofn_softc *sc;
519 struct nofn_pk_q *q;
520 {
521 struct cryptkop *krp = q->q_krp;
522 int ip = 0, err = 0;
523 int mshift, eshift, nshift;
524 int mbits, ebits, nbits;
525
526 if (krp->krp_param[NOFN_MODEXP_PAR_M].crp_nbits > 1024) {
527 err = ERANGE;
528 goto errout;
529 }
530
531
532 nofn_pk_zero_reg(sc, 0);
533 nofn_pk_zero_reg(sc, 1);
534 nofn_pk_zero_reg(sc, 2);
535 nofn_pk_zero_reg(sc, 3);
536
537
538 nbits = nofn_pk_sigbits(krp->krp_param[NOFN_MODEXP_PAR_N].crp_p,
539 krp->krp_param[NOFN_MODEXP_PAR_N].crp_nbits);
540 if (nbits > 1024) {
541 err = E2BIG;
542 goto errout;
543 }
544 if (nbits < 5) {
545 err = ERANGE;
546 goto errout;
547 }
548 bzero(&sc->sc_pk_tmp, sizeof(sc->sc_pk_tmp));
549 bcopy(krp->krp_param[NOFN_MODEXP_PAR_N].crp_p, &sc->sc_pk_tmp,
550 (nbits + 7) / 8);
551 nofn_pk_write_reg(sc, 2, &sc->sc_pk_tmp);
552
553 nshift = 1024 - nbits;
554 PK_WRITE_4(sc, NOFN_PK_LENADDR(2), 1024);
555 if (nshift != 0) {
556 PK_WRITE_4(sc, NOFN_PK_INSTR_BEGIN + ip,
557 NOFN_PK_INSTR2(0, PK_OPCODE_SL, 2, 2, nshift));
558 ip += 4;
559
560 PK_WRITE_4(sc, NOFN_PK_INSTR_BEGIN + ip,
561 NOFN_PK_INSTR2(0, PK_OPCODE_TAG, 2, 2, nbits));
562 ip += 4;
563 }
564
565
566 mbits = nofn_pk_sigbits(krp->krp_param[NOFN_MODEXP_PAR_M].crp_p,
567 krp->krp_param[NOFN_MODEXP_PAR_M].crp_nbits);
568 if (mbits > 1024 || mbits > nbits) {
569 err = E2BIG;
570 goto errout;
571 }
572 bzero(&sc->sc_pk_tmp, sizeof(sc->sc_pk_tmp));
573 bcopy(krp->krp_param[NOFN_MODEXP_PAR_M].crp_p, &sc->sc_pk_tmp,
574 (mbits + 7) / 8);
575 nofn_pk_write_reg(sc, 0, &sc->sc_pk_tmp);
576
577 mshift = 1024 - nbits;
578 PK_WRITE_4(sc, NOFN_PK_LENADDR(0), 1024);
579 if (mshift != 0) {
580 PK_WRITE_4(sc, NOFN_PK_INSTR_BEGIN + ip,
581 NOFN_PK_INSTR2(0, PK_OPCODE_SL, 0, 0, mshift));
582 ip += 4;
583
584 PK_WRITE_4(sc, NOFN_PK_INSTR_BEGIN + ip,
585 NOFN_PK_INSTR2(0, PK_OPCODE_TAG, 0, 0, nbits));
586 ip += 4;
587 }
588
589
590 ebits = nofn_pk_sigbits(krp->krp_param[NOFN_MODEXP_PAR_E].crp_p,
591 krp->krp_param[NOFN_MODEXP_PAR_E].crp_nbits);
592 if (ebits > 1024 || ebits > nbits) {
593 err = E2BIG;
594 goto errout;
595 }
596 if (ebits < 1) {
597 err = ERANGE;
598 goto errout;
599 }
600 bzero(&sc->sc_pk_tmp, sizeof(sc->sc_pk_tmp));
601 bcopy(krp->krp_param[NOFN_MODEXP_PAR_E].crp_p, &sc->sc_pk_tmp,
602 (ebits + 7) / 8);
603 nofn_pk_write_reg(sc, 1, &sc->sc_pk_tmp);
604
605 eshift = 1024 - nbits;
606 PK_WRITE_4(sc, NOFN_PK_LENADDR(1), 1024);
607 if (eshift != 0) {
608 PK_WRITE_4(sc, NOFN_PK_INSTR_BEGIN + ip,
609 NOFN_PK_INSTR2(0, PK_OPCODE_SL, 1, 1, eshift));
610 ip += 4;
611
612 PK_WRITE_4(sc, NOFN_PK_INSTR_BEGIN + ip,
613 NOFN_PK_INSTR2(0, PK_OPCODE_TAG, 1, 1, nbits));
614 ip += 4;
615 }
616
617 if (nshift == 0) {
618 PK_WRITE_4(sc, NOFN_PK_INSTR_BEGIN + ip,
619 NOFN_PK_INSTR(PK_OP_DONE, PK_OPCODE_MODEXP, 3, 0, 1, 2));
620 ip += 4;
621 } else {
622 PK_WRITE_4(sc, NOFN_PK_INSTR_BEGIN + ip,
623 NOFN_PK_INSTR(0, PK_OPCODE_MODEXP, 3, 0, 1, 2));
624 ip += 4;
625
626 PK_WRITE_4(sc, NOFN_PK_INSTR_BEGIN + ip,
627 NOFN_PK_INSTR2(0, PK_OPCODE_SR, 3, 3, nshift));
628 ip += 4;
629
630 PK_WRITE_4(sc, NOFN_PK_INSTR_BEGIN + ip,
631 NOFN_PK_INSTR2(PK_OP_DONE, PK_OPCODE_TAG, 3, 3, nbits));
632 ip += 4;
633 }
634
635
636 PK_WRITE_4(sc, NOFN_PK_CR, 0 << PK_CR_OFFSET_S);
637
638 return (0);
639
640 errout:
641 bzero(&sc->sc_pk_tmp, sizeof(sc->sc_pk_tmp));
642 nofn_pk_zero_reg(sc, 0);
643 nofn_pk_zero_reg(sc, 1);
644 nofn_pk_zero_reg(sc, 2);
645 nofn_pk_zero_reg(sc, 3);
646 krp->krp_status = err;
647 crypto_kdone(krp);
648 return (1);
649 }
650
651 void
652 nofn_modexp_finish(sc, q)
653 struct nofn_softc *sc;
654 struct nofn_pk_q *q;
655 {
656 struct cryptkop *krp = q->q_krp;
657 int reglen, crplen;
658
659 nofn_pk_read_reg(sc, 3, &sc->sc_pk_tmp);
660
661 reglen = ((PK_READ_4(sc, NOFN_PK_LENADDR(3)) & NOFN_PK_LENMASK) + 7)
662 / 8;
663 crplen = (krp->krp_param[krp->krp_iparams].crp_nbits + 7) / 8;
664
665 if (crplen <= reglen)
666 bcopy(sc->sc_pk_tmp.b, krp->krp_param[krp->krp_iparams].crp_p,
667 reglen);
668 else {
669 bcopy(sc->sc_pk_tmp.b, krp->krp_param[krp->krp_iparams].crp_p,
670 reglen);
671 bzero(krp->krp_param[krp->krp_iparams].crp_p + reglen,
672 crplen - reglen);
673 }
674 bzero(&sc->sc_pk_tmp, sizeof(sc->sc_pk_tmp));
675 nofn_pk_zero_reg(sc, 0);
676 nofn_pk_zero_reg(sc, 1);
677 nofn_pk_zero_reg(sc, 2);
678 nofn_pk_zero_reg(sc, 3);
679 crypto_kdone(krp);
680 }
681
682
683
684
685 int
686 nofn_pk_sigbits(p, pbits)
687 const u_int8_t *p;
688 u_int pbits;
689 {
690 u_int plen = (pbits + 7) / 8;
691 int i, sig = plen * 8;
692 u_int8_t c;
693
694 for (i = plen - 1; i >= 0; i--) {
695 c = p[i];
696 if (c != 0) {
697 while ((c & 0x80) == 0) {
698 sig--;
699 c <<= 1;
700 }
701 break;
702 }
703 sig -= 8;
704 }
705 return (sig);
706 }