summaryrefslogtreecommitdiffstats
path: root/sys/dev/ubsec
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2002-10-07 20:02:34 +0000
committersam <sam@FreeBSD.org>2002-10-07 20:02:34 +0000
commitee6c62e3fe91046d73b33ed1081c46c0e7f58ea0 (patch)
tree7ebc3a43bea2929701830f397b9330dd7877f3d1 /sys/dev/ubsec
parent6bb1507f12d490730bbfe3406fff9c62ff193f91 (diff)
downloadFreeBSD-src-ee6c62e3fe91046d73b33ed1081c46c0e7f58ea0.zip
FreeBSD-src-ee6c62e3fe91046d73b33ed1081c46c0e7f58ea0.tar.gz
Track openbsd changes that don't affect us yet (PK supoprt is
currently disabled): o Don't use constants for the output parameter, use the iparam count as a pointer to the first result location. o Fix bits vs bytes counting problems. o Split out the hardware and software normalization versions of modexp. o Enable hardware normalization for chips that support it. o On reset, disable hardware normalization for 582x and make sure the chip is in little endian mode. o Since sw normalization is now the only option, simplify normalization handling. Also fix RNG harvesting: disabling PK support (for the moment) had disabled the MCR2 interrupt; consider both KEY support and RNG support when deciding whether or not to enable it. Obtained from: openbsd
Diffstat (limited to 'sys/dev/ubsec')
-rw-r--r--sys/dev/ubsec/ubsec.c271
-rw-r--r--sys/dev/ubsec/ubsecreg.h12
-rw-r--r--sys/dev/ubsec/ubsecvar.h3
3 files changed, 258 insertions, 28 deletions
diff --git a/sys/dev/ubsec/ubsec.c b/sys/dev/ubsec/ubsec.c
index 9d13681..415bd49 100644
--- a/sys/dev/ubsec/ubsec.c
+++ b/sys/dev/ubsec/ubsec.c
@@ -1,5 +1,5 @@
/* $FreeBSD$ */
-/* $OpenBSD: ubsec.c,v 1.103 2002/06/17 08:05:47 deraadt Exp $ */
+/* $OpenBSD: ubsec.c,v 1.115 2002/09/24 18:33:26 jason Exp $ */
/*
* Copyright (c) 2000 Jason L. Wright (jason@thought.net)
@@ -148,7 +148,8 @@ static void ubsec_totalreset(struct ubsec_softc *sc);
static int ubsec_free_q(struct ubsec_softc *sc, struct ubsec_q *q);
static int ubsec_kprocess(void*, struct cryptkop *, int);
-static int ubsec_kprocess_modexp(struct ubsec_softc *, struct cryptkop *, int);
+static int ubsec_kprocess_modexp_hw(struct ubsec_softc *, struct cryptkop *, int);
+static int ubsec_kprocess_modexp_sw(struct ubsec_softc *, struct cryptkop *, int);
static int ubsec_kprocess_rsapriv(struct ubsec_softc *, struct cryptkop *, int);
static void ubsec_kfree(struct ubsec_softc *, struct ubsec_q2 *);
static int ubsec_ksigbits(struct crparam *);
@@ -437,8 +438,10 @@ skip_rng:
crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0,
ubsec_kprocess, sc);
+#if 0
crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0,
ubsec_kprocess, sc);
+#endif
}
return (0);
bad:
@@ -1618,7 +1621,7 @@ ubsec_callback2(struct ubsec_softc *sc, struct ubsec_q2 *q)
krp = me->me_krp;
rlen = (me->me_modbits + 7) / 8;
- clen = (krp->krp_param[UBS_MODEXP_PAR_C].crp_nbits + 7) / 8;
+ clen = (krp->krp_param[krp->krp_iparams].crp_nbits + 7) / 8;
bus_dmamap_sync(sc->sc_dmat, me->me_M.dma_map,
BUS_DMASYNC_POSTWRITE);
@@ -1631,11 +1634,20 @@ ubsec_callback2(struct ubsec_softc *sc, struct ubsec_q2 *q)
if (clen < rlen)
krp->krp_status = E2BIG;
- else
- ubsec_kshift_l(me->me_shiftbits,
- me->me_C.dma_vaddr, me->me_modbits,
- krp->krp_param[UBS_MODEXP_PAR_C].crp_p,
- krp->krp_param[UBS_MODEXP_PAR_C].crp_nbits);
+ else {
+ if (sc->sc_flags & UBS_FLAGS_HWNORM) {
+ bzero(krp->krp_param[krp->krp_iparams].crp_p,
+ (krp->krp_param[krp->krp_iparams].crp_nbits
+ + 7) / 8);
+ bcopy(me->me_C.dma_vaddr,
+ krp->krp_param[krp->krp_iparams].crp_p,
+ (me->me_modbits + 7) / 8);
+ } else
+ ubsec_kshift_l(me->me_shiftbits,
+ me->me_C.dma_vaddr, me->me_normbits,
+ krp->krp_param[krp->krp_iparams].crp_p,
+ krp->krp_param[krp->krp_iparams].crp_nbits);
+ }
crypto_kdone(krp);
@@ -1816,9 +1828,21 @@ ubsec_reset_board(struct ubsec_softc *sc)
static void
ubsec_init_board(struct ubsec_softc *sc)
{
- WRITE_REG(sc, BS_CTRL,
- READ_REG(sc, BS_CTRL) | BS_CTRL_MCR1INT | BS_CTRL_DMAERR |
- ((sc->sc_flags & UBS_FLAGS_KEY) ? BS_CTRL_MCR2INT : 0));
+ u_int32_t ctrl;
+
+ ctrl = READ_REG(sc, BS_CTRL);
+ ctrl &= ~(BS_CTRL_BE32 | BS_CTRL_BE64);
+ ctrl |= BS_CTRL_LITTLE_ENDIAN | BS_CTRL_MCR1INT;
+
+ if (sc->sc_flags & (UBS_FLAGS_KEY|UBS_FLAGS_RNG))
+ ctrl |= BS_CTRL_MCR2INT;
+ else
+ ctrl &= ~BS_CTRL_MCR2INT;
+
+ if (sc->sc_flags & UBS_FLAGS_HWNORM)
+ ctrl &= ~BS_CTRL_SWNORM;
+
+ WRITE_REG(sc, BS_CTRL, ctrl);
}
/*
@@ -1972,6 +1996,7 @@ static int
ubsec_kprocess(void *arg, struct cryptkop *krp, int hint)
{
struct ubsec_softc *sc = arg;
+ int r;
if (krp == NULL || krp->krp_callback == NULL)
return (EINVAL);
@@ -1986,7 +2011,11 @@ ubsec_kprocess(void *arg, struct cryptkop *krp, int hint)
switch (krp->krp_op) {
case CRK_MOD_EXP:
- return (ubsec_kprocess_modexp(sc, krp, hint));
+ if (sc->sc_flags & UBS_FLAGS_HWNORM)
+ r = ubsec_kprocess_modexp_hw(sc, krp, hint);
+ else
+ r = ubsec_kprocess_modexp_sw(sc, krp, hint);
+ break;
case CRK_MOD_EXP_CRT:
return (ubsec_kprocess_rsapriv(sc, krp, hint));
default:
@@ -1996,13 +2025,14 @@ ubsec_kprocess(void *arg, struct cryptkop *krp, int hint)
crypto_kdone(krp);
return (0);
}
+ return (0); /* silence compiler */
}
/*
- * Start computation of cr[C] = (cr[M] ^ cr[E]) mod cr[N]
+ * Start computation of cr[C] = (cr[M] ^ cr[E]) mod cr[N] (sw normalization)
*/
static int
-ubsec_kprocess_modexp(struct ubsec_softc *sc, struct cryptkop *krp, int hint)
+ubsec_kprocess_modexp_sw(struct ubsec_softc *sc, struct cryptkop *krp, int hint)
{
struct ubsec_q2_modexp *me;
struct ubsec_mcr *mcr;
@@ -2036,16 +2066,14 @@ ubsec_kprocess_modexp(struct ubsec_softc *sc, struct cryptkop *krp, int hint)
goto errout;
}
- if (sc->sc_flags & UBS_FLAGS_HWNORM)
- shiftbits = 0;
- else
- shiftbits = normbits - nbits;
+ shiftbits = normbits - nbits;
- me->me_modbits = normbits;
+ me->me_modbits = nbits;
me->me_shiftbits = shiftbits;
+ me->me_normbits = normbits;
/* Sanity check: result bits must be >= true modulus bits. */
- if (krp->krp_param[UBS_MODEXP_PAR_C].crp_nbits < nbits) {
+ if (krp->krp_param[krp->krp_iparams].crp_nbits < nbits) {
err = ERANGE;
goto errout;
}
@@ -2145,8 +2173,8 @@ ubsec_kprocess_modexp(struct ubsec_softc *sc, struct cryptkop *krp, int hint)
ctx->me_N, normbits);
ctx->me_len = htole16((normbits / 8) + (4 * sizeof(u_int16_t)));
ctx->me_op = htole16(UBS_CTXOP_MODEXP);
- ctx->me_E_len = htole16(normbits - shiftbits);
- ctx->me_N_len = htole16(normbits - shiftbits);
+ ctx->me_E_len = htole16(nbits);
+ ctx->me_N_len = htole16(nbits);
#ifdef UBSEC_DEBUG
if (ubsec_debug) {
@@ -2202,6 +2230,205 @@ errout:
return (0);
}
+/*
+ * Start computation of cr[C] = (cr[M] ^ cr[E]) mod cr[N] (hw normalization)
+ */
+int
+ubsec_kprocess_modexp_hw(struct ubsec_softc *sc, struct cryptkop *krp, int hint)
+{
+ struct ubsec_q2_modexp *me;
+ struct ubsec_mcr *mcr;
+ struct ubsec_ctx_modexp *ctx;
+ struct ubsec_pktbuf *epb;
+ int err = 0;
+ u_int nbits, normbits, mbits, shiftbits, ebits;
+
+ me = (struct ubsec_q2_modexp *)malloc(sizeof *me, M_DEVBUF, M_NOWAIT);
+ if (me == NULL) {
+ err = ENOMEM;
+ goto errout;
+ }
+ bzero(me, sizeof *me);
+ me->me_krp = krp;
+ me->me_q.q_type = UBS_CTXOP_MODEXP;
+
+ nbits = ubsec_ksigbits(&krp->krp_param[UBS_MODEXP_PAR_N]);
+ if (nbits <= 512)
+ normbits = 512;
+ else if (nbits <= 768)
+ normbits = 768;
+ else if (nbits <= 1024)
+ normbits = 1024;
+ else if (sc->sc_flags & UBS_FLAGS_BIGKEY && nbits <= 1536)
+ normbits = 1536;
+ else if (sc->sc_flags & UBS_FLAGS_BIGKEY && nbits <= 2048)
+ normbits = 2048;
+ else {
+ err = E2BIG;
+ goto errout;
+ }
+
+ shiftbits = normbits - nbits;
+
+ /* XXX ??? */
+ me->me_modbits = nbits;
+ me->me_shiftbits = shiftbits;
+ me->me_normbits = normbits;
+
+ /* Sanity check: result bits must be >= true modulus bits. */
+ if (krp->krp_param[krp->krp_iparams].crp_nbits < nbits) {
+ err = ERANGE;
+ goto errout;
+ }
+
+ if (ubsec_dma_malloc(sc, sizeof(struct ubsec_mcr),
+ &me->me_q.q_mcr, 0)) {
+ err = ENOMEM;
+ goto errout;
+ }
+ mcr = (struct ubsec_mcr *)me->me_q.q_mcr.dma_vaddr;
+
+ if (ubsec_dma_malloc(sc, sizeof(struct ubsec_ctx_modexp),
+ &me->me_q.q_ctx, 0)) {
+ err = ENOMEM;
+ goto errout;
+ }
+
+ mbits = ubsec_ksigbits(&krp->krp_param[UBS_MODEXP_PAR_M]);
+ if (mbits > nbits) {
+ err = E2BIG;
+ goto errout;
+ }
+ if (ubsec_dma_malloc(sc, normbits / 8, &me->me_M, 0)) {
+ err = ENOMEM;
+ goto errout;
+ }
+ bzero(me->me_M.dma_vaddr, normbits / 8);
+ bcopy(krp->krp_param[UBS_MODEXP_PAR_M].crp_p,
+ me->me_M.dma_vaddr, (mbits + 7) / 8);
+
+ if (ubsec_dma_malloc(sc, normbits / 8, &me->me_C, 0)) {
+ err = ENOMEM;
+ goto errout;
+ }
+ bzero(me->me_C.dma_vaddr, me->me_C.dma_size);
+
+ ebits = ubsec_ksigbits(&krp->krp_param[UBS_MODEXP_PAR_E]);
+ if (ebits > nbits) {
+ err = E2BIG;
+ goto errout;
+ }
+ if (ubsec_dma_malloc(sc, normbits / 8, &me->me_E, 0)) {
+ err = ENOMEM;
+ goto errout;
+ }
+ bzero(me->me_E.dma_vaddr, normbits / 8);
+ bcopy(krp->krp_param[UBS_MODEXP_PAR_E].crp_p,
+ me->me_E.dma_vaddr, (ebits + 7) / 8);
+
+ if (ubsec_dma_malloc(sc, sizeof(struct ubsec_pktbuf),
+ &me->me_epb, 0)) {
+ err = ENOMEM;
+ goto errout;
+ }
+ epb = (struct ubsec_pktbuf *)me->me_epb.dma_vaddr;
+ epb->pb_addr = htole32(me->me_E.dma_paddr);
+ epb->pb_next = 0;
+ epb->pb_len = htole32((ebits + 7) / 8);
+
+#ifdef UBSEC_DEBUG
+ printf("Epb ");
+ ubsec_dump_pb(epb);
+#endif
+
+ mcr->mcr_pkts = htole16(1);
+ mcr->mcr_flags = 0;
+ mcr->mcr_cmdctxp = htole32(me->me_q.q_ctx.dma_paddr);
+ mcr->mcr_reserved = 0;
+ mcr->mcr_pktlen = 0;
+
+ mcr->mcr_ipktbuf.pb_addr = htole32(me->me_M.dma_paddr);
+ mcr->mcr_ipktbuf.pb_len = htole32(normbits / 8);
+ mcr->mcr_ipktbuf.pb_next = htole32(me->me_epb.dma_paddr);
+
+ mcr->mcr_opktbuf.pb_addr = htole32(me->me_C.dma_paddr);
+ mcr->mcr_opktbuf.pb_next = 0;
+ mcr->mcr_opktbuf.pb_len = htole32(normbits / 8);
+
+#ifdef DIAGNOSTIC
+ /* Misaligned output buffer will hang the chip. */
+ if ((letoh32(mcr->mcr_opktbuf.pb_addr) & 3) != 0)
+ panic("%s: modexp invalid addr 0x%x\n",
+ device_get_nameunit(sc->sc_dev),
+ letoh32(mcr->mcr_opktbuf.pb_addr));
+ if ((letoh32(mcr->mcr_opktbuf.pb_len) & 3) != 0)
+ panic("%s: modexp invalid len 0x%x\n",
+ device_get_nameunit(sc->sc_dev),
+ letoh32(mcr->mcr_opktbuf.pb_len));
+#endif
+
+ ctx = (struct ubsec_ctx_modexp *)me->me_q.q_ctx.dma_vaddr;
+ bzero(ctx, sizeof(*ctx));
+ bcopy(krp->krp_param[UBS_MODEXP_PAR_N].crp_p, ctx->me_N,
+ (nbits + 7) / 8);
+ ctx->me_len = htole16((normbits / 8) + (4 * sizeof(u_int16_t)));
+ ctx->me_op = htole16(UBS_CTXOP_MODEXP);
+ ctx->me_E_len = htole16(ebits);
+ ctx->me_N_len = htole16(nbits);
+
+#ifdef UBSEC_DEBUG
+ if (ubsec_debug) {
+ ubsec_dump_mcr(mcr);
+ ubsec_dump_ctx2((struct ubsec_ctx_keyop *)ctx);
+ }
+#endif
+
+ /*
+ * ubsec_feed2 will sync mcr and ctx, we just need to sync
+ * everything else.
+ */
+ bus_dmamap_sync(sc->sc_dmat, me->me_M.dma_map, BUS_DMASYNC_PREWRITE);
+ bus_dmamap_sync(sc->sc_dmat, me->me_E.dma_map, BUS_DMASYNC_PREWRITE);
+ bus_dmamap_sync(sc->sc_dmat, me->me_C.dma_map, BUS_DMASYNC_PREREAD);
+ bus_dmamap_sync(sc->sc_dmat, me->me_epb.dma_map, BUS_DMASYNC_PREWRITE);
+
+ /* Enqueue and we're done... */
+ UBSEC_LOCK(sc);
+ SIMPLEQ_INSERT_TAIL(&sc->sc_queue2, &me->me_q, q_next);
+ ubsec_feed2(sc);
+ UBSEC_UNLOCK(sc);
+
+ return (0);
+
+errout:
+ if (me != NULL) {
+ if (me->me_q.q_mcr.dma_map != NULL)
+ ubsec_dma_free(sc, &me->me_q.q_mcr);
+ if (me->me_q.q_ctx.dma_map != NULL) {
+ bzero(me->me_q.q_ctx.dma_vaddr, me->me_q.q_ctx.dma_size);
+ ubsec_dma_free(sc, &me->me_q.q_ctx);
+ }
+ if (me->me_M.dma_map != NULL) {
+ bzero(me->me_M.dma_vaddr, me->me_M.dma_size);
+ ubsec_dma_free(sc, &me->me_M);
+ }
+ if (me->me_E.dma_map != NULL) {
+ bzero(me->me_E.dma_vaddr, me->me_E.dma_size);
+ ubsec_dma_free(sc, &me->me_E);
+ }
+ if (me->me_C.dma_map != NULL) {
+ bzero(me->me_C.dma_vaddr, me->me_C.dma_size);
+ ubsec_dma_free(sc, &me->me_C);
+ }
+ if (me->me_epb.dma_map != NULL)
+ ubsec_dma_free(sc, &me->me_epb);
+ free(me, M_DEVBUF);
+ }
+ krp->krp_status = err;
+ crypto_kdone(krp);
+ return (0);
+}
+
static int
ubsec_kprocess_rsapriv(struct ubsec_softc *sc, struct cryptkop *krp, int hint)
{
diff --git a/sys/dev/ubsec/ubsecreg.h b/sys/dev/ubsec/ubsecreg.h
index ee8c79a..bd23352 100644
--- a/sys/dev/ubsec/ubsecreg.h
+++ b/sys/dev/ubsec/ubsecreg.h
@@ -1,5 +1,5 @@
/* $FreeBSD$ */
-/* $OpenBSD: ubsecreg.h,v 1.23 2002/05/08 23:05:28 jason Exp $ */
+/* $OpenBSD: ubsecreg.h,v 1.27 2002/09/11 22:40:31 jason Exp $ */
/*
* Copyright (c) 2000 Theo de Raadt
@@ -86,12 +86,14 @@
#define BS_CTRL_BE32 0x08000000 /* big-endian, 32bit bytes */
#define BS_CTRL_BE64 0x04000000 /* big-endian, 64bit bytes */
#define BS_CTRL_DMAERR 0x02000000 /* enable intr DMA error */
-#define BS_CTRL_RNG_M 0x01800000 /* RND mode */
+#define BS_CTRL_RNG_M 0x01800000 /* RNG mode */
#define BS_CTRL_RNG_1 0x00000000 /* 1bit rn/one slow clock */
#define BS_CTRL_RNG_4 0x00800000 /* 1bit rn/four slow clocks */
#define BS_CTRL_RNG_8 0x01000000 /* 1bit rn/eight slow clocks */
#define BS_CTRL_RNG_16 0x01800000 /* 1bit rn/16 slow clocks */
+#define BS_CTRL_SWNORM 0x00400000 /* 582[01], sw normalization */
#define BS_CTRL_FRAG_M 0x0000ffff /* output fragment size mask */
+#define BS_CTRL_LITTLE_ENDIAN (BS_CTRL_BE32 | BS_CTRL_BE64)
/* BS_STAT - DMA Status */
#define BS_STAT_MCR1_BUSY 0x80000000 /* MCR1 is busy */
@@ -100,8 +102,8 @@
#define BS_STAT_DMAERR 0x10000000 /* DMA error */
#define BS_STAT_MCR2_FULL 0x08000000 /* MCR2 is full */
#define BS_STAT_MCR2_DONE 0x04000000 /* MCR2 is done */
-#define BS_STAT_MCR1_ALLEMPTY 0x02000000 /* MCR1 is completely empty */
-#define BS_STAT_MCR2_ALLEMPTY 0x01000000 /* MCR2 is completely empty */
+#define BS_STAT_MCR1_ALLEMPTY 0x02000000 /* 5821, MCR1 is empty */
+#define BS_STAT_MCR2_ALLEMPTY 0x01000000 /* 5821, MCR2 is empty */
/* BS_ERR - DMA Error Address */
#define BS_ERR_ADDR 0xfffffffc /* error address mask */
@@ -196,7 +198,7 @@ struct ubsec_ctx_modexp {
volatile u_int16_t me_op; /* modexp, 0x47 */
volatile u_int16_t me_E_len; /* E (bits) */
volatile u_int16_t me_N_len; /* N (bits) */
- u_int8_t me_N[1024/8]; /* N */
+ u_int8_t me_N[2048/8]; /* N */
};
struct ubsec_ctx_rsapriv {
diff --git a/sys/dev/ubsec/ubsecvar.h b/sys/dev/ubsec/ubsecvar.h
index fa55288..991fb52 100644
--- a/sys/dev/ubsec/ubsecvar.h
+++ b/sys/dev/ubsec/ubsecvar.h
@@ -1,5 +1,5 @@
/* $FreeBSD$ */
-/* $OpenBSD: ubsecvar.h,v 1.33 2002/05/15 15:15:42 jason Exp $ */
+/* $OpenBSD: ubsecvar.h,v 1.35 2002/09/24 18:33:26 jason Exp $ */
/*
* Copyright (c) 2000 Theo de Raadt
@@ -89,6 +89,7 @@ struct ubsec_q2_modexp {
struct ubsec_dma_alloc me_epb;
int me_modbits;
int me_shiftbits;
+ int me_normbits;
};
#define UBS_RSAPRIV_PAR_P 0
OpenPOWER on IntegriCloud