-/* $OpenBSD: ubsec.c,v 1.159 2014/07/13 23:10:23 deraadt Exp $ */
+/* $OpenBSD: ubsec.c,v 1.160 2014/08/15 15:37:51 mikeb Exp $ */
/*
* Copyright (c) 2000 Jason L. Wright (jason@thought.net)
void ubsec_dma_free(struct ubsec_softc *, struct ubsec_dma_alloc *);
int ubsec_dmamap_aligned(bus_dmamap_t);
-int ubsec_kprocess(struct cryptkop *);
-struct ubsec_softc *ubsec_kfind(struct cryptkop *);
-int ubsec_kprocess_modexp_sw(struct ubsec_softc *, struct cryptkop *);
-int ubsec_kprocess_modexp_hw(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_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 *);
-void ubsec_dump_mcr(struct ubsec_mcr *);
-void ubsec_dump_ctx2(struct ubsec_ctx_keyop *);
-
#define READ_REG(sc,r) \
bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (r))
bus_size_t iosize;
u_int32_t i;
int algs[CRYPTO_ALGORITHM_MAX + 1];
- int kalgs[CRK_ALGORITHM_MAX + 1];
SIMPLEQ_INIT(&sc->sc_queue);
SIMPLEQ_INIT(&sc->sc_qchip);
SIMPLEQ_INIT(&sc->sc_queue2);
SIMPLEQ_INIT(&sc->sc_qchip2);
- SIMPLEQ_INIT(&sc->sc_q2free);
SIMPLEQ_INIT(&sc->sc_queue4);
SIMPLEQ_INIT(&sc->sc_qchip4);
if (sc->sc_flags & UBS_FLAGS_KEY) {
sc->sc_statmask |= BS_STAT_MCR2_DONE;
-
- bzero(kalgs, sizeof(kalgs));
- kalgs[CRK_MOD_EXP] = CRYPTO_ALG_FLAG_SUPPORTED;
-#if 0
- kalgs[CRK_MOD_EXP_CRT] = CRYPTO_ALG_FLAG_SUPPORTED;
-#endif
-
- crypto_kregister(sc->sc_cid, kalgs, ubsec_kprocess);
- printf(" PK");
}
printf(", %s\n", intrstr);
void
ubsec_callback2(struct ubsec_softc *sc, struct ubsec_q2 *q)
{
- struct cryptkop *krp;
struct ubsec_ctx_keyop *ctx;
ctx = (struct ubsec_ctx_keyop *)q->q_ctx.dma_vaddr;
break;
}
#endif
- case UBS_CTXOP_MODEXP: {
- struct ubsec_q2_modexp *me = (struct ubsec_q2_modexp *)q;
- u_int rlen, clen;
-
- krp = me->me_krp;
- rlen = (me->me_modbits + 7) / 8;
- clen = (krp->krp_param[krp->krp_iparams].crp_nbits + 7) / 8;
-
- bus_dmamap_sync(sc->sc_dmat, me->me_M.dma_map,
- 0, me->me_M.dma_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
- bus_dmamap_sync(sc->sc_dmat, me->me_E.dma_map,
- 0, me->me_E.dma_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
- bus_dmamap_sync(sc->sc_dmat, me->me_C.dma_map,
- 0, me->me_C.dma_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
- bus_dmamap_sync(sc->sc_dmat, me->me_epb.dma_map,
- 0, me->me_epb.dma_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
-
- if (clen < rlen)
- krp->krp_status = E2BIG;
- 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);
-
- /* bzero all potentially sensitive data */
- explicit_bzero(me->me_E.dma_vaddr, me->me_E.dma_size);
- explicit_bzero(me->me_M.dma_vaddr, me->me_M.dma_size);
- explicit_bzero(me->me_C.dma_vaddr, me->me_C.dma_size);
- explicit_bzero(me->me_q.q_ctx.dma_vaddr, me->me_q.q_ctx.dma_size);
-
- /* Can't free here, so put us on the free list. */
- SIMPLEQ_INSERT_TAIL(&sc->sc_q2free, &me->me_q, q_next);
- break;
- }
- case UBS_CTXOP_RSAPRIV: {
- struct ubsec_q2_rsapriv *rp = (struct ubsec_q2_rsapriv *)q;
- u_int len;
-
- krp = rp->rpr_krp;
- bus_dmamap_sync(sc->sc_dmat, rp->rpr_msgin.dma_map, 0,
- rp->rpr_msgin.dma_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
- bus_dmamap_sync(sc->sc_dmat, rp->rpr_msgout.dma_map, 0,
- rp->rpr_msgout.dma_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
-
- len = (krp->krp_param[UBS_RSAPRIV_PAR_MSGOUT].crp_nbits + 7) / 8;
- bcopy(rp->rpr_msgout.dma_vaddr,
- krp->krp_param[UBS_RSAPRIV_PAR_MSGOUT].crp_p, len);
-
- crypto_kdone(krp);
-
- explicit_bzero(rp->rpr_msgin.dma_vaddr, rp->rpr_msgin.dma_size);
- explicit_bzero(rp->rpr_msgout.dma_vaddr, rp->rpr_msgout.dma_size);
- explicit_bzero(rp->rpr_q.q_ctx.dma_vaddr, rp->rpr_q.q_ctx.dma_size);
-
- /* Can't free here, so put us on the free list. */
- SIMPLEQ_INSERT_TAIL(&sc->sc_q2free, &rp->rpr_q, q_next);
- break;
- }
default:
printf("%s: unknown ctx op: %x\n", sc->sc_dv.dv_xname,
letoh16(ctx->ctx_op));
}
return (1);
}
-
-struct ubsec_softc *
-ubsec_kfind(struct cryptkop *krp)
-{
- struct ubsec_softc *sc;
- int i;
-
- for (i = 0; i < ubsec_cd.cd_ndevs; i++) {
- sc = ubsec_cd.cd_devs[i];
- if (sc == NULL)
- continue;
- if (sc->sc_cid == krp->krp_hid)
- return (sc);
- }
- return (NULL);
-}
-
-void
-ubsec_kfree(struct ubsec_softc *sc, struct ubsec_q2 *q)
-{
- switch (q->q_type) {
- case UBS_CTXOP_MODEXP: {
- struct ubsec_q2_modexp *me = (struct ubsec_q2_modexp *)q;
-
- ubsec_dma_free(sc, &me->me_q.q_mcr);
- ubsec_dma_free(sc, &me->me_q.q_ctx);
- ubsec_dma_free(sc, &me->me_M);
- ubsec_dma_free(sc, &me->me_E);
- ubsec_dma_free(sc, &me->me_C);
- ubsec_dma_free(sc, &me->me_epb);
- free(me, M_DEVBUF, 0);
- break;
- }
- case UBS_CTXOP_RSAPRIV: {
- struct ubsec_q2_rsapriv *rp = (struct ubsec_q2_rsapriv *)q;
-
- ubsec_dma_free(sc, &rp->rpr_q.q_mcr);
- ubsec_dma_free(sc, &rp->rpr_q.q_ctx);
- ubsec_dma_free(sc, &rp->rpr_msgin);
- ubsec_dma_free(sc, &rp->rpr_msgout);
- free(rp, M_DEVBUF, 0);
- break;
- }
- default:
- printf("%s: invalid kfree 0x%x\n", sc->sc_dv.dv_xname,
- q->q_type);
- break;
- }
-}
-
-int
-ubsec_kprocess(struct cryptkop *krp)
-{
- struct ubsec_softc *sc;
- int r;
-
- if (krp == NULL || krp->krp_callback == NULL)
- return (EINVAL);
- if ((sc = ubsec_kfind(krp)) == NULL)
- return (EINVAL);
-
- while (!SIMPLEQ_EMPTY(&sc->sc_q2free)) {
- struct ubsec_q2 *q;
-
- q = SIMPLEQ_FIRST(&sc->sc_q2free);
- SIMPLEQ_REMOVE_HEAD(&sc->sc_q2free, q_next);
- ubsec_kfree(sc, q);
- }
-
- switch (krp->krp_op) {
- case CRK_MOD_EXP:
- if (sc->sc_flags & UBS_FLAGS_HWNORM)
- r = ubsec_kprocess_modexp_hw(sc, krp);
- else
- r = ubsec_kprocess_modexp_sw(sc, krp);
- break;
- case CRK_MOD_EXP_CRT:
- r = ubsec_kprocess_rsapriv(sc, krp);
- break;
- default:
- printf("%s: kprocess: invalid op 0x%x\n",
- sc->sc_dv.dv_xname, krp->krp_op);
- krp->krp_status = EOPNOTSUPP;
- crypto_kdone(krp);
- r = 0;
- }
- return (r);
-}
-
-/*
- * Start computation of cr[C] = (cr[M] ^ cr[E]) mod cr[N] (sw normalization)
- */
-int
-ubsec_kprocess_modexp_sw(struct ubsec_softc *sc, struct cryptkop *krp)
-{
- struct ubsec_q2_modexp *me;
- struct ubsec_mcr *mcr;
- struct ubsec_ctx_modexp *ctx;
- struct ubsec_pktbuf *epb;
- int err = 0, s;
- u_int nbits, normbits, mbits, shiftbits, ebits;
-
- me = malloc(sizeof *me, M_DEVBUF, M_NOWAIT | M_ZERO);
- if (me == NULL) {
- err = ENOMEM;
- goto errout;
- }
- 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;
-
- 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;
- }
- 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, 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;
- }
- ubsec_kshift_r(shiftbits,
- krp->krp_param[UBS_MODEXP_PAR_E].crp_p, ebits,
- me->me_E.dma_vaddr, normbits);
-
- 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(normbits / 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",
- sc->sc_dv.dv_xname, letoh32(mcr->mcr_opktbuf.pb_addr));
- if ((letoh32(mcr->mcr_opktbuf.pb_len) & 3) != 0)
- panic("%s: modexp invalid len 0x%x",
- sc->sc_dv.dv_xname, letoh32(mcr->mcr_opktbuf.pb_len));
-#endif
-
- ctx = (struct ubsec_ctx_modexp *)me->me_q.q_ctx.dma_vaddr;
- bzero(ctx, sizeof(*ctx));
- 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(nbits);
- ctx->me_N_len = htole16(nbits);
-
-#ifdef 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,
- 0, me->me_M.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
- bus_dmamap_sync(sc->sc_dmat, me->me_E.dma_map,
- 0, me->me_E.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
- bus_dmamap_sync(sc->sc_dmat, me->me_C.dma_map,
- 0, me->me_C.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD);
- bus_dmamap_sync(sc->sc_dmat, me->me_epb.dma_map,
- 0, me->me_epb.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
-
- /* Enqueue and we're done... */
- s = splnet();
- SIMPLEQ_INSERT_TAIL(&sc->sc_queue2, &me->me_q, q_next);
- ubsec_feed2(sc);
- splx(s);
-
- 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) {
- explicit_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) {
- explicit_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) {
- explicit_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) {
- explicit_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, 0);
- }
- krp->krp_status = err;
- crypto_kdone(krp);
- 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)
-{
- struct ubsec_q2_modexp *me;
- struct ubsec_mcr *mcr;
- struct ubsec_ctx_modexp *ctx;
- struct ubsec_pktbuf *epb;
- int err = 0, s;
- u_int nbits, normbits, mbits, shiftbits, ebits;
-
- me = malloc(sizeof *me, M_DEVBUF, M_NOWAIT | M_ZERO);
- if (me == NULL) {
- err = ENOMEM;
- goto errout;
- }
- 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",
- sc->sc_dv.dv_xname, letoh32(mcr->mcr_opktbuf.pb_addr));
- if ((letoh32(mcr->mcr_opktbuf.pb_len) & 3) != 0)
- panic("%s: modexp invalid len 0x%x",
- sc->sc_dv.dv_xname, 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
- 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,
- 0, me->me_M.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
- bus_dmamap_sync(sc->sc_dmat, me->me_E.dma_map,
- 0, me->me_E.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
- bus_dmamap_sync(sc->sc_dmat, me->me_C.dma_map,
- 0, me->me_C.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD);
- bus_dmamap_sync(sc->sc_dmat, me->me_epb.dma_map,
- 0, me->me_epb.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
-
- /* Enqueue and we're done... */
- s = splnet();
- SIMPLEQ_INSERT_TAIL(&sc->sc_queue2, &me->me_q, q_next);
- ubsec_feed2(sc);
- splx(s);
-
- 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) {
- explicit_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) {
- explicit_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) {
- explicit_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) {
- explicit_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, 0);
- }
- krp->krp_status = err;
- crypto_kdone(krp);
- return (0);
-}
-
-int
-ubsec_kprocess_rsapriv(struct ubsec_softc *sc, struct cryptkop *krp)
-{
- struct ubsec_q2_rsapriv *rp = NULL;
- struct ubsec_mcr *mcr;
- struct ubsec_ctx_rsapriv *ctx;
- int err = 0, s;
- u_int padlen, msglen;
-
- 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;
-
- if (padlen <= 256)
- padlen = 256;
- else if (padlen <= 384)
- padlen = 384;
- else if (padlen <= 512)
- padlen = 512;
- else if (sc->sc_flags & UBS_FLAGS_BIGKEY && padlen <= 768)
- padlen = 768;
- else if (sc->sc_flags & UBS_FLAGS_BIGKEY && padlen <= 1024)
- padlen = 1024;
- else {
- err = E2BIG;
- goto errout;
- }
-
- if (ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_DP]) > padlen) {
- err = E2BIG;
- goto errout;
- }
-
- if (ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_DQ]) > padlen) {
- err = E2BIG;
- goto errout;
- }
-
- if (ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_PINV]) > padlen) {
- err = E2BIG;
- goto errout;
- }
-
- rp = malloc(sizeof *rp, M_DEVBUF, M_NOWAIT | M_ZERO);
- if (rp == NULL)
- return (ENOMEM);
- rp->rpr_krp = krp;
- rp->rpr_q.q_type = UBS_CTXOP_RSAPRIV;
-
- if (ubsec_dma_malloc(sc, sizeof(struct ubsec_mcr),
- &rp->rpr_q.q_mcr, 0)) {
- err = ENOMEM;
- goto errout;
- }
- mcr = (struct ubsec_mcr *)rp->rpr_q.q_mcr.dma_vaddr;
-
- if (ubsec_dma_malloc(sc, sizeof(struct ubsec_ctx_rsapriv),
- &rp->rpr_q.q_ctx, 0)) {
- err = ENOMEM;
- goto errout;
- }
- ctx = (struct ubsec_ctx_rsapriv *)rp->rpr_q.q_ctx.dma_vaddr;
- bzero(ctx, sizeof *ctx);
-
- /* Copy in p */
- bcopy(krp->krp_param[UBS_RSAPRIV_PAR_P].crp_p,
- &ctx->rpr_buf[0 * (padlen / 8)],
- (krp->krp_param[UBS_RSAPRIV_PAR_P].crp_nbits + 7) / 8);
-
- /* Copy in q */
- bcopy(krp->krp_param[UBS_RSAPRIV_PAR_Q].crp_p,
- &ctx->rpr_buf[1 * (padlen / 8)],
- (krp->krp_param[UBS_RSAPRIV_PAR_Q].crp_nbits + 7) / 8);
-
- /* Copy in dp */
- bcopy(krp->krp_param[UBS_RSAPRIV_PAR_DP].crp_p,
- &ctx->rpr_buf[2 * (padlen / 8)],
- (krp->krp_param[UBS_RSAPRIV_PAR_DP].crp_nbits + 7) / 8);
-
- /* Copy in dq */
- bcopy(krp->krp_param[UBS_RSAPRIV_PAR_DQ].crp_p,
- &ctx->rpr_buf[3 * (padlen / 8)],
- (krp->krp_param[UBS_RSAPRIV_PAR_DQ].crp_nbits + 7) / 8);
-
- /* Copy in pinv */
- bcopy(krp->krp_param[UBS_RSAPRIV_PAR_PINV].crp_p,
- &ctx->rpr_buf[4 * (padlen / 8)],
- (krp->krp_param[UBS_RSAPRIV_PAR_PINV].crp_nbits + 7) / 8);
-
- msglen = padlen * 2;
-
- /* Copy in input message (aligned buffer/length). */
- if (ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_MSGIN]) > msglen) {
- /* Is this likely? */
- err = E2BIG;
- goto errout;
- }
- if (ubsec_dma_malloc(sc, (msglen + 7) / 8, &rp->rpr_msgin, 0)) {
- err = ENOMEM;
- goto errout;
- }
- bzero(rp->rpr_msgin.dma_vaddr, (msglen + 7) / 8);
- bcopy(krp->krp_param[UBS_RSAPRIV_PAR_MSGIN].crp_p,
- rp->rpr_msgin.dma_vaddr,
- (krp->krp_param[UBS_RSAPRIV_PAR_MSGIN].crp_nbits + 7) / 8);
-
- /* Prepare space for output message (aligned buffer/length). */
- if (ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_MSGOUT]) < msglen) {
- /* Is this likely? */
- err = E2BIG;
- goto errout;
- }
- if (ubsec_dma_malloc(sc, (msglen + 7) / 8, &rp->rpr_msgout, 0)) {
- err = ENOMEM;
- goto errout;
- }
- bzero(rp->rpr_msgout.dma_vaddr, (msglen + 7) / 8);
-
- mcr->mcr_pkts = htole16(1);
- mcr->mcr_flags = 0;
- mcr->mcr_cmdctxp = htole32(rp->rpr_q.q_ctx.dma_paddr);
- mcr->mcr_ipktbuf.pb_addr = htole32(rp->rpr_msgin.dma_paddr);
- mcr->mcr_ipktbuf.pb_next = 0;
- mcr->mcr_ipktbuf.pb_len = htole32(rp->rpr_msgin.dma_size);
- mcr->mcr_reserved = 0;
- mcr->mcr_pktlen = htole16(msglen);
- mcr->mcr_opktbuf.pb_addr = htole32(rp->rpr_msgout.dma_paddr);
- mcr->mcr_opktbuf.pb_next = 0;
- mcr->mcr_opktbuf.pb_len = htole32(rp->rpr_msgout.dma_size);
-
-#ifdef DIAGNOSTIC
- if (rp->rpr_msgin.dma_paddr & 3 || rp->rpr_msgin.dma_size & 3) {
- panic("%s: rsapriv: invalid msgin %08x(0x%lx)",
- sc->sc_dv.dv_xname, rp->rpr_msgin.dma_paddr,
- rp->rpr_msgin.dma_size);
- }
- if (rp->rpr_msgout.dma_paddr & 3 || rp->rpr_msgout.dma_size & 3) {
- panic("%s: rsapriv: invalid msgout %08x(0x%lx)",
- sc->sc_dv.dv_xname, rp->rpr_msgout.dma_paddr,
- rp->rpr_msgout.dma_size);
- }
-#endif
-
- ctx->rpr_len = (sizeof(u_int16_t) * 4) + (5 * (padlen / 8));
- ctx->rpr_op = htole16(UBS_CTXOP_RSAPRIV);
- ctx->rpr_q_len = htole16(padlen);
- ctx->rpr_p_len = htole16(padlen);
-
- /*
- * ubsec_feed2 will sync mcr and ctx, we just need to sync
- * everything else.
- */
- bus_dmamap_sync(sc->sc_dmat, rp->rpr_msgin.dma_map,
- 0, rp->rpr_msgin.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
- bus_dmamap_sync(sc->sc_dmat, rp->rpr_msgout.dma_map,
- 0, rp->rpr_msgout.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD);
-
- /* Enqueue and we're done... */
- s = splnet();
- SIMPLEQ_INSERT_TAIL(&sc->sc_queue2, &rp->rpr_q, q_next);
- ubsec_feed2(sc);
- splx(s);
- return (0);
-
-errout:
- if (rp != NULL) {
- if (rp->rpr_q.q_mcr.dma_map != NULL)
- ubsec_dma_free(sc, &rp->rpr_q.q_mcr);
- if (rp->rpr_msgin.dma_map != NULL) {
- explicit_bzero(rp->rpr_msgin.dma_vaddr,
- rp->rpr_msgin.dma_size);
- ubsec_dma_free(sc, &rp->rpr_msgin);
- }
- if (rp->rpr_msgout.dma_map != NULL) {
- explicit_bzero(rp->rpr_msgout.dma_vaddr,
- rp->rpr_msgout.dma_size);
- ubsec_dma_free(sc, &rp->rpr_msgout);
- }
- free(rp, M_DEVBUF, 0);
- }
- krp->krp_status = err;
- crypto_kdone(krp);
- return (0);
-}
-
-void
-ubsec_dump_pb(struct ubsec_pktbuf *pb)
-{
- printf("addr 0x%x (0x%x) next 0x%x\n",
- pb->pb_addr, pb->pb_len, pb->pb_next);
-}
-
-void
-ubsec_dump_ctx2(struct ubsec_ctx_keyop *c)
-{
- printf("CTX (0x%x):\n", c->ctx_len);
- switch (letoh16(c->ctx_op)) {
- case UBS_CTXOP_RNGBYPASS:
- case UBS_CTXOP_RNGSHA1:
- break;
- case UBS_CTXOP_MODEXP:
- {
- struct ubsec_ctx_modexp *cx = (void *)c;
- int i, len;
-
- printf(" Elen %u, Nlen %u\n",
- letoh16(cx->me_E_len), letoh16(cx->me_N_len));
- len = (cx->me_N_len + 7)/8;
- for (i = 0; i < len; i++)
- printf("%s%02x", (i == 0) ? " N: " : ":", cx->me_N[i]);
- printf("\n");
- break;
- }
- default:
- printf("unknown context: %x\n", c->ctx_op);
- }
- printf("END CTX\n");
-}
-
-void
-ubsec_dump_mcr(struct ubsec_mcr *mcr)
-{
- struct ubsec_mcr_add *ma;
- int i;
-
- printf("MCR:\n");
- printf(" pkts: %u, flags 0x%x\n",
- letoh16(mcr->mcr_pkts), letoh16(mcr->mcr_flags));
- ma = (struct ubsec_mcr_add *)&mcr->mcr_cmdctxp;
- for (i = 0; i < letoh16(mcr->mcr_pkts); i++) {
- printf(" %d: ctx 0x%x len 0x%x rsvd 0x%x\n", i,
- letoh32(ma->mcr_cmdctxp), letoh16(ma->mcr_pktlen),
- letoh16(ma->mcr_reserved));
- printf(" %d: ipkt ", i);
- ubsec_dump_pb(&ma->mcr_ipktbuf);
- printf(" %d: opkt ", i);
- ubsec_dump_pb(&ma->mcr_opktbuf);
- ma++;
- }
- printf("END MCR\n");
-}
-
-/*
- * Return the number of significant bits of a big number.
- */
-int
-ubsec_ksigbits(struct crparam *cr)
-{
- u_int plen = (cr->crp_nbits + 7) / 8;
- int i, sig = plen * 8;
- u_int8_t c, *p = cr->crp_p;
-
- for (i = plen - 1; i >= 0; i--) {
- c = p[i];
- if (c != 0) {
- while ((c & 0x80) == 0) {
- sig--;
- c <<= 1;
- }
- break;
- }
- sig -= 8;
- }
- return (sig);
-}
-
-void
-ubsec_kshift_r(u_int shiftbits, u_int8_t *src, u_int srcbits,
- u_int8_t *dst, u_int dstbits)
-{
- 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(u_int shiftbits, u_int8_t *src, u_int srcbits,
- u_int8_t *dst, u_int dstbits)
-{
- 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;
- }
-}