summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>2002-05-15 15:15:43 +0000
committerJason Wright <jason@cvs.openbsd.org>2002-05-15 15:15:43 +0000
commitf42af0c450d69bd07595da4883d4a7bbd148562f (patch)
tree135d9b859cca9de2c73ffb93a5be3e1adb4ea37a
parent89699e6bc100cb4df9bfc78e5c2dbbae49bc0a53 (diff)
Rework MODEXP:
5805 (and 5601) require the modulus and base to be normalized to the right of one of several different register lengths. The result is also normalized to the same length. Provide functions for shifting the bits back and forth as appropriate. Note: for consistencies sake the exponent is NOT normalized.
-rw-r--r--sys/dev/pci/ubsec.c251
-rw-r--r--sys/dev/pci/ubsecvar.h3
2 files changed, 141 insertions, 113 deletions
diff --git a/sys/dev/pci/ubsec.c b/sys/dev/pci/ubsec.c
index 82766cc9db6..a8e2ebec4b7 100644
--- a/sys/dev/pci/ubsec.c
+++ b/sys/dev/pci/ubsec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ubsec.c,v 1.99 2002/05/13 22:28:56 jason Exp $ */
+/* $OpenBSD: ubsec.c,v 1.100 2002/05/15 15:15:41 jason Exp $ */
/*
* Copyright (c) 2000 Jason L. Wright (jason@thought.net)
@@ -110,8 +110,9 @@ struct ubsec_softc *ubsec_kfind(struct cryptkop *);
int ubsec_kprocess_modexp(struct ubsec_softc *, struct cryptkop *);
int ubsec_kprocess_rsapriv(struct ubsec_softc *, struct cryptkop *);
void ubsec_kfree(struct ubsec_softc *, struct ubsec_q2 *);
-int ubsec_kcopyin(struct crparam *, caddr_t, u_int, u_int *);
-int ubsec_norm_sigbits(const u_int8_t *, u_int);
+int ubsec_ksigbits(struct crparam *);
+void ubsec_kshift_r(u_int, u_int8_t *, u_int, u_int8_t *, u_int);
+void ubsec_kshift_l(u_int, u_int8_t *, u_int, u_int8_t *, u_int);
/* DEBUG crap... */
void ubsec_dump_pb(struct ubsec_pktbuf *);
@@ -387,7 +388,8 @@ ubsec_intr(arg)
/*
* Check to see if we have any key setups/rng's waiting for us
*/
- if ((sc->sc_flags & UBS_FLAGS_KEY) && (stat & BS_STAT_MCR2_DONE)) {
+ if ((sc->sc_flags & (UBS_FLAGS_KEY|UBS_FLAGS_RNG)) &&
+ (stat & BS_STAT_MCR2_DONE)) {
struct ubsec_q2 *q2;
struct ubsec_mcr *mcr;
@@ -1403,14 +1405,11 @@ ubsec_callback2(sc, q)
if (clen < rlen)
krp->krp_status = E2BIG;
- else {
- caddr_t dst;
-
- krp->krp_status = 0;
- dst = krp->krp_param[UBS_MODEXP_PAR_C].crp_p;
- bcopy(me->me_C.dma_vaddr, dst, rlen);
- bzero(dst + rlen, clen - rlen);
- }
+ 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);
crypto_kdone(krp);
@@ -1812,45 +1811,52 @@ ubsec_kprocess_modexp(sc, krp)
struct ubsec_softc *sc;
struct cryptkop *krp;
{
- struct ubsec_q2_modexp *me = NULL;
+ struct ubsec_q2_modexp *me;
struct ubsec_mcr *mcr;
struct ubsec_ctx_modexp *ctx;
struct ubsec_pktbuf *epb;
int err = 0, s;
- u_int len;
- u_int modbits;
-
- modbits = krp->krp_param[UBS_MODEXP_PAR_N].crp_nbits;
- if (modbits <= 512)
- modbits = 512;
- else if (modbits <= 768)
- modbits = 768;
- else if (modbits <= 1024)
- modbits = 1024;
- else if (sc->sc_flags & UBS_FLAGS_LONGCTX && modbits <= 1536)
- modbits = 1536;
- else if (sc->sc_flags & UBS_FLAGS_LONGCTX && modbits <= 2048)
- modbits = 2048;
+ 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;
}
+ if (sc->sc_flags & UBS_FLAGS_HWNORM)
+ shiftbits = 0;
+ else
+ shiftbits = normbits - nbits;
+
+ me->me_modbits = normbits;
+ me->me_shiftbits = shiftbits;
+
/* Sanity check: result bits must be >= true modulus bits. */
- if (krp->krp_param[UBS_MODEXP_PAR_C].crp_nbits <
- krp->krp_param[UBS_MODEXP_PAR_N].crp_nbits) {
+ if (krp->krp_param[UBS_MODEXP_PAR_C].crp_nbits < nbits) {
err = ERANGE;
goto errout;
}
- me = (struct ubsec_q2_modexp *)malloc(sizeof *me, M_DEVBUF, M_NOWAIT);
- if (me == NULL)
- return (ENOMEM);
- bzero(me, sizeof *me);
- me->me_krp = krp;
- me->me_q.q_type = UBS_CTXOP_MODEXP;
- me->me_modbits = modbits;
-
if (ubsec_dma_malloc(sc, sizeof(struct ubsec_mcr),
&me->me_q.q_mcr, 0)) {
err = ENOMEM;
@@ -1864,17 +1870,25 @@ ubsec_kprocess_modexp(sc, krp)
goto errout;
}
- if (ubsec_dma_malloc(sc, 2048 / 8, &me->me_M, 0)) {
+ 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;
}
+ ubsec_kshift_r(shiftbits,
+ krp->krp_param[UBS_MODEXP_PAR_M].crp_p, mbits,
+ me->me_M.dma_vaddr, normbits);
if (ubsec_dma_malloc(sc, 2048 / 8, &me->me_E, 0)) {
err = ENOMEM;
goto errout;
}
- if (ubsec_dma_malloc(sc, modbits / 8, &me->me_C, 0)) {
+ if (ubsec_dma_malloc(sc, normbits / 8, &me->me_C, 0)) {
err = ENOMEM;
goto errout;
}
@@ -1887,15 +1901,17 @@ ubsec_kprocess_modexp(sc, krp)
}
epb = (struct ubsec_pktbuf *)me->me_epb.dma_vaddr;
- len = (krp->krp_param[UBS_MODEXP_PAR_E].crp_nbits + 7) / 8;
- if (len > me->me_E.dma_size) {
- err = EOPNOTSUPP;
+ ebits = ubsec_ksigbits(&krp->krp_param[UBS_MODEXP_PAR_E]);
+ if (ebits > nbits) {
+ err = E2BIG;
goto errout;
}
- bcopy(krp->krp_param[UBS_MODEXP_PAR_E].crp_p, me->me_E.dma_vaddr, len);
+ bcopy(krp->krp_param[UBS_MODEXP_PAR_E].crp_p,
+ me->me_E.dma_vaddr, (ebits + 7) / 8);
epb->pb_addr = htole32(me->me_E.dma_paddr);
epb->pb_next = 0;
- epb->pb_len = htole32(len);
+ epb->pb_len = htole32((ebits + 7) / 8);
+
#ifdef UBSEC_DEBUG
printf("Epb ");
ubsec_dump_pb(epb);
@@ -1907,18 +1923,13 @@ ubsec_kprocess_modexp(sc, krp)
mcr->mcr_reserved = 0;
mcr->mcr_pktlen = 0;
- if (ubsec_kcopyin(&krp->krp_param[UBS_MODEXP_PAR_M], me->me_M.dma_vaddr,
- 1024 / 8, &len)) {
- err = EOPNOTSUPP;
- goto errout;
- }
mcr->mcr_ipktbuf.pb_addr = htole32(me->me_M.dma_paddr);
- mcr->mcr_ipktbuf.pb_len = htole32(len);
+ 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(modbits / 8);
+ mcr->mcr_opktbuf.pb_len = htole32(normbits / 8);
#ifdef DIAGNOSTIC
/* Misaligned output buffer will hang the chip. */
@@ -1932,19 +1943,13 @@ ubsec_kprocess_modexp(sc, krp)
ctx = (struct ubsec_ctx_modexp *)me->me_q.q_ctx.dma_vaddr;
bzero(ctx, sizeof(*ctx));
- if (ubsec_kcopyin(&krp->krp_param[UBS_MODEXP_PAR_N], ctx->me_N,
- 1024 / 8, &len)) {
- err = EOPNOTSUPP;
- goto errout;
- }
- len = ((krp->krp_param[UBS_MODEXP_PAR_N].crp_nbits + 31) / 32) * 32;
- if (len < 512)
- len = 512;
- ctx->me_len = htole16((len / 8) + (4 * sizeof(u_int16_t)));
+ ubsec_kshift_r(shiftbits,
+ krp->krp_param[UBS_MODEXP_PAR_N].crp_p, nbits,
+ 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(((krp->krp_param[UBS_MODEXP_PAR_E].crp_nbits + 7) / 8) * 8);
- ctx->me_N_len = htole16(len);
+ ctx->me_E_len = htole16(ebits);
+ ctx->me_N_len = htole16(normbits - shiftbits);
#ifdef UBSEC_DEBUG
ubsec_dump_mcr(mcr);
@@ -2012,10 +2017,8 @@ ubsec_kprocess_rsapriv(sc, krp)
int err = 0, s;
u_int padlen, msglen;
- msglen = ubsec_norm_sigbits(krp->krp_param[UBS_RSAPRIV_PAR_P].crp_p,
- krp->krp_param[UBS_RSAPRIV_PAR_P].crp_nbits);
- padlen = ubsec_norm_sigbits(krp->krp_param[UBS_RSAPRIV_PAR_Q].crp_p,
- krp->krp_param[UBS_RSAPRIV_PAR_Q].crp_nbits);
+ msglen = ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_P]);
+ padlen = ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_Q]);
if (msglen > padlen)
padlen = msglen;
@@ -2025,9 +2028,9 @@ ubsec_kprocess_rsapriv(sc, krp)
padlen = 384;
else if (padlen <= 512)
padlen = 512;
- else if (sc->sc_flags & UBS_FLAGS_LONGCTX && padlen <= 768)
+ else if (sc->sc_flags & UBS_FLAGS_BIGKEY && padlen <= 768)
padlen = 768;
- else if (sc->sc_flags & UBS_FLAGS_LONGCTX && padlen <= 1024)
+ else if (sc->sc_flags & UBS_FLAGS_BIGKEY && padlen <= 1024)
padlen = 1024;
else {
err = E2BIG;
@@ -2035,22 +2038,19 @@ ubsec_kprocess_rsapriv(sc, krp)
goto errout;
}
- if (ubsec_norm_sigbits(krp->krp_param[UBS_RSAPRIV_PAR_DP].crp_p,
- krp->krp_param[UBS_RSAPRIV_PAR_DP].crp_nbits) > padlen) {
+ if (ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_DP]) > padlen) {
err = E2BIG;
printf("bad p\n");
goto errout;
}
- if (ubsec_norm_sigbits(krp->krp_param[UBS_RSAPRIV_PAR_DQ].crp_p,
- krp->krp_param[UBS_RSAPRIV_PAR_DQ].crp_nbits) > padlen) {
+ if (ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_DQ]) > padlen) {
err = E2BIG;
printf("bad q\n");
goto errout;
}
- if (ubsec_norm_sigbits(krp->krp_param[UBS_RSAPRIV_PAR_PINV].crp_p,
- krp->krp_param[UBS_RSAPRIV_PAR_PINV].crp_nbits) > padlen) {
+ if (ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_PINV]) > padlen) {
err = E2BIG;
printf("bad pinv\n");
goto errout;
@@ -2106,8 +2106,7 @@ ubsec_kprocess_rsapriv(sc, krp)
msglen = padlen * 2;
/* Copy in input message (aligned buffer/length). */
- if (ubsec_norm_sigbits(krp->krp_param[UBS_RSAPRIV_PAR_MSGIN].crp_p,
- krp->krp_param[UBS_RSAPRIV_PAR_MSGIN].crp_nbits) > msglen) {
+ if (ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_MSGIN]) > msglen) {
/* Is this likely? */
printf("msginbuf...\n");
err = E2BIG;
@@ -2123,8 +2122,7 @@ ubsec_kprocess_rsapriv(sc, krp)
(krp->krp_param[UBS_RSAPRIV_PAR_MSGIN].crp_nbits + 7) / 8);
/* Prepare space for output message (aligned buffer/length). */
- if (ubsec_norm_sigbits(krp->krp_param[UBS_RSAPRIV_PAR_MSGOUT].crp_p,
- krp->krp_param[UBS_RSAPRIV_PAR_MSGOUT].crp_nbits) < msglen) {
+ if (ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_MSGOUT]) < msglen) {
printf("msgoutbuf\n");
/* Is this likely? */
err = E2BIG;
@@ -2201,34 +2199,6 @@ errout:
return (0);
}
-/*
- * Copy a key into a ubsec dma buffer, round up to multiple of 32 bits.
- */
-int
-ubsec_kcopyin(crpar, buf, bufsiz, reslen)
- struct crparam *crpar;
- caddr_t buf;
- u_int bufsiz, *reslen;
-{
- u_int nbytes, npad;
-
- nbytes = (crpar->crp_nbits + 7) / 8;
- if ((nbytes & 3) != 0)
- npad = 4 - (nbytes & 3);
- else
- npad = 0;
-
- if ((bufsiz & 3) != 0)
- panic("ubsec_kcopyin: bad len");
- if ((nbytes + npad) > bufsiz)
- return (-1);
-
- bcopy(crpar->crp_p, buf, nbytes);
- bzero(buf + nbytes, npad);
- *reslen = nbytes + npad;
- return (0);
-}
-
void
ubsec_dump_pb(struct ubsec_pktbuf *pb)
{
@@ -2290,13 +2260,12 @@ ubsec_dump_mcr(struct ubsec_mcr *mcr)
* Return the number of significant bits of a big number.
*/
int
-ubsec_norm_sigbits(p, pbits)
- const u_int8_t *p;
- u_int pbits;
+ubsec_ksigbits(cr)
+ struct crparam *cr;
{
- u_int plen = (pbits + 7) / 8;
+ u_int plen = (cr->crp_nbits + 7) / 8;
int i, sig = plen * 8;
- u_int8_t c;
+ u_int8_t c, *p = cr->crp_p;
for (i = plen - 1; i >= 0; i--) {
c = p[i];
@@ -2312,3 +2281,61 @@ ubsec_norm_sigbits(p, pbits)
return (sig);
}
+void
+ubsec_kshift_r(shiftbits, src, srcbits, dst, dstbits)
+ u_int shiftbits, srcbits, dstbits;
+ u_int8_t *src, *dst;
+{
+ u_int slen, dlen;
+ int i, si, di, n;
+
+ slen = (srcbits + 7) / 8;
+ dlen = (dstbits + 7) / 8;
+
+ for (i = 0; i < slen; i++)
+ dst[i] = src[i];
+ for (i = 0; i < dlen - slen; i++)
+ dst[slen + i] = 0;
+
+ n = shiftbits / 8;
+ if (n != 0) {
+ si = dlen - n - 1;
+ di = dlen - 1;
+ while (si >= 0)
+ dst[di--] = dst[si--];
+ while (di >= 0)
+ dst[di--] = 0;
+ }
+
+ n = shiftbits % 8;
+ if (n != 0) {
+ for (i = dlen - 1; i > 0; i--)
+ dst[i] = (dst[i] << n) |
+ (dst[i - 1] >> (8 - n));
+ dst[0] = dst[0] << n;
+ }
+}
+
+void
+ubsec_kshift_l(shiftbits, src, srcbits, dst, dstbits)
+ u_int shiftbits, srcbits, dstbits;
+ u_int8_t *src, *dst;
+{
+ int slen, dlen, i, n;
+
+ slen = (srcbits + 7) / 8;
+ dlen = (dstbits + 7) / 8;
+
+ n = shiftbits / 8;
+ for (i = 0; i < slen; i++)
+ dst[i] = src[i + n];
+ for (i = 0; i < dlen - slen; i++)
+ dst[slen + i] = 0;
+
+ n = shiftbits % 8;
+ if (n != 0) {
+ for (i = 0; i < (dlen - 1); i++)
+ dst[i] = (dst[i] >> n) | (dst[i + 1] << (8 - n));
+ dst[dlen - 1] = dst[dlen - 1] >> n;
+ }
+}
diff --git a/sys/dev/pci/ubsecvar.h b/sys/dev/pci/ubsecvar.h
index 818c7a55fb3..fb861fa5e6d 100644
--- a/sys/dev/pci/ubsecvar.h
+++ b/sys/dev/pci/ubsecvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ubsecvar.h,v 1.32 2002/05/13 22:28:56 jason Exp $ */
+/* $OpenBSD: ubsecvar.h,v 1.33 2002/05/15 15:15:42 jason Exp $ */
/*
* Copyright (c) 2000 Theo de Raadt
@@ -87,6 +87,7 @@ struct ubsec_q2_modexp {
struct ubsec_dma_alloc me_C;
struct ubsec_dma_alloc me_epb;
int me_modbits;
+ int me_shiftbits;
};
#define UBS_RSAPRIV_PAR_P 0