diff options
| author | John Baldwin <jhb@FreeBSD.org> | 2020-03-27 18:25:23 +0000 |
|---|---|---|
| committer | John Baldwin <jhb@FreeBSD.org> | 2020-03-27 18:25:23 +0000 |
| commit | c03414326909ed7a740be3ba63fbbef01fe513a8 (patch) | |
| tree | 9067f28738df03bb4b685773c52ba32517468212 /sys/dev/sec | |
| parent | 4d94781b4d9e03b8dbd6604d7e2280d342d3cf7e (diff) | |
Notes
Diffstat (limited to 'sys/dev/sec')
| -rw-r--r-- | sys/dev/sec/sec.c | 540 | ||||
| -rw-r--r-- | sys/dev/sec/sec.h | 18 |
2 files changed, 218 insertions, 340 deletions
diff --git a/sys/dev/sec/sec.c b/sys/dev/sec/sec.c index 76f808757845..3b3ea0018060 100644 --- a/sys/dev/sec/sec.c +++ b/sys/dev/sec/sec.c @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include <machine/resource.h> #include <opencrypto/cryptodev.h> +#include <opencrypto/xform_auth.h> #include "cryptodev_if.h" #include <dev/ofw/ofw_bus_subr.h> @@ -74,7 +75,7 @@ static int sec_init(struct sec_softc *sc); static int sec_alloc_dma_mem(struct sec_softc *sc, struct sec_dma_mem *dma_mem, bus_size_t size); static int sec_desc_map_dma(struct sec_softc *sc, - struct sec_dma_mem *dma_mem, void *mem, bus_size_t size, int type, + struct sec_dma_mem *dma_mem, struct cryptop *crp, bus_size_t size, struct sec_desc_map_info *sdmi); static void sec_free_dma_mem(struct sec_dma_mem *dma_mem); static void sec_enqueue(struct sec_softc *sc); @@ -82,48 +83,43 @@ static int sec_enqueue_desc(struct sec_softc *sc, struct sec_desc *desc, int channel); static int sec_eu_channel(struct sec_softc *sc, int eu); static int sec_make_pointer(struct sec_softc *sc, struct sec_desc *desc, - u_int n, void *data, bus_size_t doffset, bus_size_t dsize, int dtype); + u_int n, struct cryptop *crp, bus_size_t doffset, bus_size_t dsize); static int sec_make_pointer_direct(struct sec_softc *sc, struct sec_desc *desc, u_int n, bus_addr_t data, bus_size_t dsize); +static int sec_probesession(device_t dev, + const struct crypto_session_params *csp); static int sec_newsession(device_t dev, crypto_session_t cses, - struct cryptoini *cri); + const struct crypto_session_params *csp); static int sec_process(device_t dev, struct cryptop *crp, int hint); -static int sec_split_cri(struct cryptoini *cri, struct cryptoini **enc, - struct cryptoini **mac); -static int sec_split_crp(struct cryptop *crp, struct cryptodesc **enc, - struct cryptodesc **mac); static int sec_build_common_ns_desc(struct sec_softc *sc, - struct sec_desc *desc, struct sec_session *ses, struct cryptop *crp, - struct cryptodesc *enc, int buftype); + struct sec_desc *desc, const struct crypto_session_params *csp, + struct cryptop *crp); static int sec_build_common_s_desc(struct sec_softc *sc, - struct sec_desc *desc, struct sec_session *ses, struct cryptop *crp, - struct cryptodesc *enc, struct cryptodesc *mac, int buftype); + struct sec_desc *desc, const struct crypto_session_params *csp, + struct cryptop *crp); static struct sec_desc *sec_find_desc(struct sec_softc *sc, bus_addr_t paddr); /* AESU */ -static int sec_aesu_newsession(struct sec_softc *sc, - struct sec_session *ses, struct cryptoini *enc, struct cryptoini *mac); +static bool sec_aesu_newsession(const struct crypto_session_params *csp); static int sec_aesu_make_desc(struct sec_softc *sc, - struct sec_session *ses, struct sec_desc *desc, struct cryptop *crp, - int buftype); + const struct crypto_session_params *csp, struct sec_desc *desc, + struct cryptop *crp); /* DEU */ -static int sec_deu_newsession(struct sec_softc *sc, - struct sec_session *ses, struct cryptoini *enc, struct cryptoini *mac); +static bool sec_deu_newsession(const struct crypto_session_params *csp); static int sec_deu_make_desc(struct sec_softc *sc, - struct sec_session *ses, struct sec_desc *desc, struct cryptop *crp, - int buftype); + const struct crypto_session_params *csp, struct sec_desc *desc, + struct cryptop *crp); /* MDEU */ -static int sec_mdeu_can_handle(u_int alg); -static int sec_mdeu_config(struct cryptodesc *crd, +static bool sec_mdeu_can_handle(u_int alg); +static int sec_mdeu_config(const struct crypto_session_params *csp, u_int *eu, u_int *mode, u_int *hashlen); -static int sec_mdeu_newsession(struct sec_softc *sc, - struct sec_session *ses, struct cryptoini *enc, struct cryptoini *mac); +static bool sec_mdeu_newsession(const struct crypto_session_params *csp); static int sec_mdeu_make_desc(struct sec_softc *sc, - struct sec_session *ses, struct sec_desc *desc, struct cryptop *crp, - int buftype); + const struct crypto_session_params *csp, struct sec_desc *desc, + struct cryptop *crp); static device_method_t sec_methods[] = { /* Device interface */ @@ -136,6 +132,7 @@ static device_method_t sec_methods[] = { DEVMETHOD(device_shutdown, sec_shutdown), /* Crypto methods */ + DEVMETHOD(cryptodev_probesession, sec_probesession), DEVMETHOD(cryptodev_newsession, sec_newsession), DEVMETHOD(cryptodev_process, sec_process), @@ -362,24 +359,6 @@ sec_attach(device_t dev) if (error) goto fail6; - /* Register in OCF (AESU) */ - crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0); - - /* Register in OCF (DEU) */ - crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0); - crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0); - - /* Register in OCF (MDEU) */ - crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0); - crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0); - crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0); - crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0); - crypto_register(sc->sc_cid, CRYPTO_SHA2_256_HMAC, 0, 0); - if (sc->sc_version >= 3) { - crypto_register(sc->sc_cid, CRYPTO_SHA2_384_HMAC, 0, 0); - crypto_register(sc->sc_cid, CRYPTO_SHA2_512_HMAC, 0, 0); - } - return (0); fail6: @@ -545,9 +524,12 @@ sec_release_intr(struct sec_softc *sc, struct resource *ires, void *ihand, static void sec_primary_intr(void *arg) { + struct sec_session *ses; struct sec_softc *sc = arg; struct sec_desc *desc; + struct cryptop *crp; uint64_t isr; + uint8_t hash[HASH_MAX_LEN]; int i, wakeup = 0; SEC_LOCK(sc, controller); @@ -595,7 +577,26 @@ sec_primary_intr(void *arg) SEC_DESC_SYNC_POINTERS(desc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - desc->sd_crp->crp_etype = desc->sd_error; + crp = desc->sd_crp; + crp->crp_etype = desc->sd_error; + if (crp->crp_etype == 0) { + ses = crypto_get_driver_session(crp->crp_session); + if (ses->ss_mlen != 0) { + if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) { + crypto_copydata(crp, + crp->crp_digest_start, + ses->ss_mlen, hash); + if (timingsafe_bcmp( + desc->sd_desc->shd_digest, + hash, ses->ss_mlen) != 0) + crp->crp_etype = EBADMSG; + } else + crypto_copyback(crp, + crp->crp_digest_start, + ses->ss_mlen, + desc->sd_desc->shd_digest); + } + } crypto_done(desc->sd_crp); SEC_DESC_FREE_POINTERS(desc); @@ -786,14 +787,6 @@ sec_dma_map_desc_cb(void *arg, bus_dma_segment_t *segs, int nseg, sdmi->sdmi_lt_last = lt; } -static void -sec_dma_map_desc_cb2(void *arg, bus_dma_segment_t *segs, int nseg, - bus_size_t size, int error) -{ - - sec_dma_map_desc_cb(arg, segs, nseg, error); -} - static int sec_alloc_dma_mem(struct sec_softc *sc, struct sec_dma_mem *dma_mem, bus_size_t size) @@ -851,22 +844,22 @@ err1: } static int -sec_desc_map_dma(struct sec_softc *sc, struct sec_dma_mem *dma_mem, void *mem, - bus_size_t size, int type, struct sec_desc_map_info *sdmi) +sec_desc_map_dma(struct sec_softc *sc, struct sec_dma_mem *dma_mem, + struct cryptop *crp, bus_size_t size, struct sec_desc_map_info *sdmi) { int error; if (dma_mem->dma_vaddr != NULL) return (EBUSY); - switch (type) { - case SEC_MEMORY: + switch (crp->crp_buf_type) { + case CRYPTO_BUF_CONTIG: break; - case SEC_UIO: + case CRYPTO_BUF_UIO: size = SEC_FREE_LT_CNT(sc) * SEC_MAX_DMA_BLOCK_SIZE; break; - case SEC_MBUF: - size = m_length((struct mbuf*)mem, NULL); + case CRYPTO_BUF_MBUF: + size = m_length(crp->crp_mbuf, NULL); break; default: return (EINVAL); @@ -899,20 +892,8 @@ sec_desc_map_dma(struct sec_softc *sc, struct sec_dma_mem *dma_mem, void *mem, return (error); } - switch (type) { - case SEC_MEMORY: - error = bus_dmamap_load(dma_mem->dma_tag, dma_mem->dma_map, - mem, size, sec_dma_map_desc_cb, sdmi, BUS_DMA_NOWAIT); - break; - case SEC_UIO: - error = bus_dmamap_load_uio(dma_mem->dma_tag, dma_mem->dma_map, - mem, sec_dma_map_desc_cb2, sdmi, BUS_DMA_NOWAIT); - break; - case SEC_MBUF: - error = bus_dmamap_load_mbuf(dma_mem->dma_tag, dma_mem->dma_map, - mem, sec_dma_map_desc_cb2, sdmi, BUS_DMA_NOWAIT); - break; - } + error = bus_dmamap_load_crp(dma_mem->dma_tag, dma_mem->dma_map, crp, + sec_dma_map_desc_cb, sdmi, BUS_DMA_NOWAIT); if (error) { device_printf(sc->sc_dev, "cannot get address of the DMA" @@ -923,7 +904,7 @@ sec_desc_map_dma(struct sec_softc *sc, struct sec_dma_mem *dma_mem, void *mem, } dma_mem->dma_is_map = 1; - dma_mem->dma_vaddr = mem; + dma_mem->dma_vaddr = crp; return (0); } @@ -1130,7 +1111,7 @@ sec_make_pointer_direct(struct sec_softc *sc, struct sec_desc *desc, u_int n, static int sec_make_pointer(struct sec_softc *sc, struct sec_desc *desc, - u_int n, void *data, bus_size_t doffset, bus_size_t dsize, int dtype) + u_int n, struct cryptop *crp, bus_size_t doffset, bus_size_t dsize) { struct sec_desc_map_info sdmi = { sc, dsize, doffset, NULL, NULL, 0 }; struct sec_hw_desc_ptr *ptr; @@ -1138,14 +1119,8 @@ sec_make_pointer(struct sec_softc *sc, struct sec_desc *desc, SEC_LOCK_ASSERT(sc, descriptors); - /* For flat memory map only requested region */ - if (dtype == SEC_MEMORY) { - data = (uint8_t*)(data) + doffset; - sdmi.sdmi_offset = 0; - } - - error = sec_desc_map_dma(sc, &(desc->sd_ptr_dmem[n]), data, dsize, - dtype, &sdmi); + error = sec_desc_map_dma(sc, &(desc->sd_ptr_dmem[n]), crp, dsize, + &sdmi); if (error) return (error); @@ -1162,115 +1137,116 @@ sec_make_pointer(struct sec_softc *sc, struct sec_desc *desc, return (0); } -static int -sec_split_cri(struct cryptoini *cri, struct cryptoini **enc, - struct cryptoini **mac) +static bool +sec_cipher_supported(const struct crypto_session_params *csp) { - struct cryptoini *e, *m; - - e = cri; - m = cri->cri_next; - /* We can haldle only two operations */ - if (m && m->cri_next) - return (EINVAL); - - if (sec_mdeu_can_handle(e->cri_alg)) { - cri = m; - m = e; - e = cri; + switch (csp->csp_cipher_alg) { + case CRYPTO_AES_CBC: + /* AESU */ + if (csp->csp_ivlen != AES_BLOCK_LEN) + return (false); + break; + case CRYPTO_DES_CBC: + case CRYPTO_3DES_CBC: + /* DEU */ + if (csp->csp_ivlen != DES_BLOCK_LEN) + return (false); + break; + default: + return (false); } - if (m && !sec_mdeu_can_handle(m->cri_alg)) - return (EINVAL); + if (csp->csp_cipher_klen == 0 || csp->csp_cipher_klen > SEC_MAX_KEY_LEN) + return (false); - *enc = e; - *mac = m; + return (true); +} - return (0); +static bool +sec_auth_supported(struct sec_softc *sc, + const struct crypto_session_params *csp) +{ + + switch (csp->csp_auth_alg) { + case CRYPTO_SHA2_384_HMAC: + case CRYPTO_SHA2_512_HMAC: + if (sc->sc_version < 3) + return (false); + /* FALLTHROUGH */ + case CRYPTO_MD5_HMAC: + case CRYPTO_SHA1_HMAC: + case CRYPTO_SHA2_256_HMAC: + if (csp->csp_auth_klen > SEC_MAX_KEY_LEN) + return (false); + break; + case CRYPTO_MD5: + case CRYPTO_SHA1: + break; + default: + return (false); + } + return (true); } static int -sec_split_crp(struct cryptop *crp, struct cryptodesc **enc, - struct cryptodesc **mac) +sec_probesession(device_t dev, const struct crypto_session_params *csp) { - struct cryptodesc *e, *m, *t; - - e = crp->crp_desc; - m = e->crd_next; + struct sec_softc *sc = device_get_softc(dev); - /* We can haldle only two operations */ - if (m && m->crd_next) + if (csp->csp_flags != 0) return (EINVAL); - - if (sec_mdeu_can_handle(e->crd_alg)) { - t = m; - m = e; - e = t; - } - - if (m && !sec_mdeu_can_handle(m->crd_alg)) + switch (csp->csp_mode) { + case CSP_MODE_DIGEST: + if (!sec_auth_supported(sc, csp)) + return (EINVAL); + break; + case CSP_MODE_CIPHER: + if (!sec_cipher_supported(csp)) + return (EINVAL); + break; + case CSP_MODE_ETA: + if (!sec_auth_supported(sc, csp) || !sec_cipher_supported(csp)) + return (EINVAL); + break; + default: return (EINVAL); - - *enc = e; - *mac = m; - - return (0); + } + return (CRYPTODEV_PROBE_HARDWARE); } static int -sec_newsession(device_t dev, crypto_session_t cses, struct cryptoini *cri) +sec_newsession(device_t dev, crypto_session_t cses, + const struct crypto_session_params *csp) { - struct sec_softc *sc = device_get_softc(dev); struct sec_eu_methods *eu = sec_eus; - struct cryptoini *enc = NULL; - struct cryptoini *mac = NULL; struct sec_session *ses; - int error = -1; - - error = sec_split_cri(cri, &enc, &mac); - if (error) - return (error); - - /* Check key lengths */ - if (enc && enc->cri_key && (enc->cri_klen / 8) > SEC_MAX_KEY_LEN) - return (E2BIG); - - if (mac && mac->cri_key && (mac->cri_klen / 8) > SEC_MAX_KEY_LEN) - return (E2BIG); - - /* Only SEC 3.0 supports digests larger than 256 bits */ - if (sc->sc_version < 3 && mac && mac->cri_klen > 256) - return (E2BIG); ses = crypto_get_driver_session(cses); /* Find EU for this session */ while (eu->sem_make_desc != NULL) { - error = eu->sem_newsession(sc, ses, enc, mac); - if (error >= 0) + if (eu->sem_newsession(csp)) break; - eu++; } - - /* If not found, return EINVAL */ - if (error < 0) - return (EINVAL); + KASSERT(eu->sem_make_desc != NULL, ("failed to find eu for session")); /* Save cipher key */ - if (enc && enc->cri_key) { - ses->ss_klen = enc->cri_klen / 8; - memcpy(ses->ss_key, enc->cri_key, ses->ss_klen); - } + if (csp->csp_cipher_key != NULL) + memcpy(ses->ss_key, csp->csp_cipher_key, csp->csp_cipher_klen); /* Save digest key */ - if (mac && mac->cri_key) { - ses->ss_mklen = mac->cri_klen / 8; - memcpy(ses->ss_mkey, mac->cri_key, ses->ss_mklen); + if (csp->csp_auth_key != NULL) + memcpy(ses->ss_mkey, csp->csp_auth_key, csp->csp_auth_klen); + + if (csp->csp_auth_alg != 0) { + if (csp->csp_auth_mlen == 0) + ses->ss_mlen = crypto_auth_hash(csp)->hashsize; + else + ses->ss_mlen = csp->csp_auth_mlen; } - ses->ss_eu = eu; return (0); } @@ -1279,11 +1255,12 @@ sec_process(device_t dev, struct cryptop *crp, int hint) { struct sec_softc *sc = device_get_softc(dev); struct sec_desc *desc = NULL; - struct cryptodesc *mac, *enc; + const struct crypto_session_params *csp; struct sec_session *ses; - int buftype, error = 0; + int error = 0; ses = crypto_get_driver_session(crp->crp_session); + csp = crypto_get_params(crp->crp_session); /* Check for input length */ if (crp->crp_ilen > SEC_MAX_DMA_BLOCK_SIZE) { @@ -1292,13 +1269,6 @@ sec_process(device_t dev, struct cryptop *crp, int hint) return (0); } - /* Get descriptors */ - if (sec_split_crp(crp, &enc, &mac)) { - crp->crp_etype = EINVAL; - crypto_done(crp); - return (0); - } - SEC_LOCK(sc, descriptors); SEC_DESC_SYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); @@ -1315,56 +1285,29 @@ sec_process(device_t dev, struct cryptop *crp, int hint) desc->sd_error = 0; desc->sd_crp = crp; - if (crp->crp_flags & CRYPTO_F_IOV) - buftype = SEC_UIO; - else if (crp->crp_flags & CRYPTO_F_IMBUF) - buftype = SEC_MBUF; - else - buftype = SEC_MEMORY; - - if (enc && enc->crd_flags & CRD_F_ENCRYPT) { - if (enc->crd_flags & CRD_F_IV_EXPLICIT) - memcpy(desc->sd_desc->shd_iv, enc->crd_iv, - ses->ss_ivlen); - else - arc4rand(desc->sd_desc->shd_iv, ses->ss_ivlen, 0); - - if ((enc->crd_flags & CRD_F_IV_PRESENT) == 0) - crypto_copyback(crp->crp_flags, crp->crp_buf, - enc->crd_inject, ses->ss_ivlen, + if (csp->csp_cipher_alg != 0) { + if (crp->crp_flags & CRYPTO_F_IV_GENERATE) { + arc4rand(desc->sd_desc->shd_iv, csp->csp_ivlen, 0); + crypto_copyback(crp, crp->crp_iv_start, csp->csp_ivlen, desc->sd_desc->shd_iv); - } else if (enc) { - if (enc->crd_flags & CRD_F_IV_EXPLICIT) - memcpy(desc->sd_desc->shd_iv, enc->crd_iv, - ses->ss_ivlen); + } else if (crp->crp_flags & CRYPTO_F_IV_SEPARATE) + memcpy(desc->sd_desc->shd_iv, crp->crp_iv, + csp->csp_ivlen); else - crypto_copydata(crp->crp_flags, crp->crp_buf, - enc->crd_inject, ses->ss_ivlen, + crypto_copydata(crp, crp->crp_iv_start, csp->csp_ivlen, desc->sd_desc->shd_iv); } - if (enc && enc->crd_flags & CRD_F_KEY_EXPLICIT) { - if ((enc->crd_klen / 8) <= SEC_MAX_KEY_LEN) { - ses->ss_klen = enc->crd_klen / 8; - memcpy(ses->ss_key, enc->crd_key, ses->ss_klen); - } else - error = E2BIG; - } + if (crp->crp_cipher_key != NULL) + memcpy(ses->ss_key, crp->crp_cipher_key, csp->csp_cipher_klen); - if (!error && mac && mac->crd_flags & CRD_F_KEY_EXPLICIT) { - if ((mac->crd_klen / 8) <= SEC_MAX_KEY_LEN) { - ses->ss_mklen = mac->crd_klen / 8; - memcpy(ses->ss_mkey, mac->crd_key, ses->ss_mklen); - } else - error = E2BIG; - } + if (crp->crp_auth_key != NULL) + memcpy(ses->ss_mkey, crp->crp_auth_key, csp->csp_auth_klen); - if (!error) { - memcpy(desc->sd_desc->shd_key, ses->ss_key, ses->ss_klen); - memcpy(desc->sd_desc->shd_mkey, ses->ss_mkey, ses->ss_mklen); + memcpy(desc->sd_desc->shd_key, ses->ss_key, csp->csp_cipher_klen); + memcpy(desc->sd_desc->shd_mkey, ses->ss_mkey, csp->csp_auth_klen); - error = ses->ss_eu->sem_make_desc(sc, ses, desc, crp, buftype); - } + error = ses->ss_eu->sem_make_desc(sc, csp, desc, crp); if (error) { SEC_DESC_FREE_POINTERS(desc); @@ -1400,8 +1343,7 @@ sec_process(device_t dev, struct cryptop *crp, int hint) static int sec_build_common_ns_desc(struct sec_softc *sc, struct sec_desc *desc, - struct sec_session *ses, struct cryptop *crp, struct cryptodesc *enc, - int buftype) + const struct crypto_session_params *csp, struct cryptop *crp) { struct sec_hw_desc *hd = desc->sd_desc; int error; @@ -1417,25 +1359,25 @@ sec_build_common_ns_desc(struct sec_softc *sc, struct sec_desc *desc, /* Pointer 1: IV IN */ error = sec_make_pointer_direct(sc, desc, 1, desc->sd_desc_paddr + - offsetof(struct sec_hw_desc, shd_iv), ses->ss_ivlen); + offsetof(struct sec_hw_desc, shd_iv), csp->csp_ivlen); if (error) return (error); /* Pointer 2: Cipher Key */ error = sec_make_pointer_direct(sc, desc, 2, desc->sd_desc_paddr + - offsetof(struct sec_hw_desc, shd_key), ses->ss_klen); + offsetof(struct sec_hw_desc, shd_key), csp->csp_cipher_klen); if (error) return (error); /* Pointer 3: Data IN */ - error = sec_make_pointer(sc, desc, 3, crp->crp_buf, enc->crd_skip, - enc->crd_len, buftype); + error = sec_make_pointer(sc, desc, 3, crp, crp->crp_payload_start, + crp->crp_payload_length); if (error) return (error); /* Pointer 4: Data OUT */ - error = sec_make_pointer(sc, desc, 4, crp->crp_buf, enc->crd_skip, - enc->crd_len, buftype); + error = sec_make_pointer(sc, desc, 4, crp, crp->crp_payload_start, + crp->crp_payload_length); if (error) return (error); @@ -1452,20 +1394,13 @@ sec_build_common_ns_desc(struct sec_softc *sc, struct sec_desc *desc, static int sec_build_common_s_desc(struct sec_softc *sc, struct sec_desc *desc, - struct sec_session *ses, struct cryptop *crp, struct cryptodesc *enc, - struct cryptodesc *mac, int buftype) + const struct crypto_session_params *csp, struct cryptop *crp) { struct sec_hw_desc *hd = desc->sd_desc; u_int eu, mode, hashlen; int error; - if (mac->crd_len < enc->crd_len) - return (EINVAL); - - if (mac->crd_skip + mac->crd_len != enc->crd_skip + enc->crd_len) - return (EINVAL); - - error = sec_mdeu_config(mac, &eu, &mode, &hashlen); + error = sec_mdeu_config(csp, &eu, &mode, &hashlen); if (error) return (error); @@ -1475,144 +1410,107 @@ sec_build_common_s_desc(struct sec_softc *sc, struct sec_desc *desc, /* Pointer 0: HMAC Key */ error = sec_make_pointer_direct(sc, desc, 0, desc->sd_desc_paddr + - offsetof(struct sec_hw_desc, shd_mkey), ses->ss_mklen); + offsetof(struct sec_hw_desc, shd_mkey), csp->csp_auth_klen); if (error) return (error); /* Pointer 1: HMAC-Only Data IN */ - error = sec_make_pointer(sc, desc, 1, crp->crp_buf, mac->crd_skip, - mac->crd_len - enc->crd_len, buftype); + error = sec_make_pointer(sc, desc, 1, crp, crp->crp_aad_start, + crp->crp_aad_length); if (error) return (error); /* Pointer 2: Cipher Key */ error = sec_make_pointer_direct(sc, desc, 2, desc->sd_desc_paddr + - offsetof(struct sec_hw_desc, shd_key), ses->ss_klen); + offsetof(struct sec_hw_desc, shd_key), csp->csp_cipher_klen); if (error) return (error); /* Pointer 3: IV IN */ error = sec_make_pointer_direct(sc, desc, 3, desc->sd_desc_paddr + - offsetof(struct sec_hw_desc, shd_iv), ses->ss_ivlen); + offsetof(struct sec_hw_desc, shd_iv), csp->csp_ivlen); if (error) return (error); /* Pointer 4: Data IN */ - error = sec_make_pointer(sc, desc, 4, crp->crp_buf, enc->crd_skip, - enc->crd_len, buftype); + error = sec_make_pointer(sc, desc, 4, crp, crp->crp_payload_start, + crp->crp_payload_length); if (error) return (error); /* Pointer 5: Data OUT */ - error = sec_make_pointer(sc, desc, 5, crp->crp_buf, enc->crd_skip, - enc->crd_len, buftype); + error = sec_make_pointer(sc, desc, 5, crp, crp->crp_payload_start, + crp->crp_payload_length); if (error) return (error); /* Pointer 6: HMAC OUT */ - error = sec_make_pointer(sc, desc, 6, crp->crp_buf, mac->crd_inject, - hashlen, buftype); + error = sec_make_pointer_direct(sc, desc, 6, desc->sd_desc_paddr + + offsetof(struct sec_hw_desc, shd_digest), hashlen); return (error); } /* AESU */ -static int -sec_aesu_newsession(struct sec_softc *sc, struct sec_session *ses, - struct cryptoini *enc, struct cryptoini *mac) +static bool +sec_aesu_newsession(const struct crypto_session_params *csp) { - if (enc == NULL) - return (-1); - - if (enc->cri_alg != CRYPTO_AES_CBC) - return (-1); - - ses->ss_ivlen = AES_BLOCK_LEN; - - return (0); + return (csp->csp_cipher_alg == CRYPTO_AES_CBC); } static int -sec_aesu_make_desc(struct sec_softc *sc, struct sec_session *ses, - struct sec_desc *desc, struct cryptop *crp, int buftype) +sec_aesu_make_desc(struct sec_softc *sc, + const struct crypto_session_params *csp, struct sec_desc *desc, + struct cryptop *crp) { struct sec_hw_desc *hd = desc->sd_desc; - struct cryptodesc *enc, *mac; int error; - error = sec_split_crp(crp, &enc, &mac); - if (error) - return (error); - - if (!enc) - return (EINVAL); - hd->shd_eu_sel0 = SEC_EU_AESU; hd->shd_mode0 = SEC_AESU_MODE_CBC; - if (enc->crd_alg != CRYPTO_AES_CBC) - return (EINVAL); - - if (enc->crd_flags & CRD_F_ENCRYPT) { + if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { hd->shd_mode0 |= SEC_AESU_MODE_ED; hd->shd_dir = 0; } else hd->shd_dir = 1; - if (mac) - error = sec_build_common_s_desc(sc, desc, ses, crp, enc, mac, - buftype); + if (csp->csp_mode == CSP_MODE_ETA) + error = sec_build_common_s_desc(sc, desc, csp, crp); else - error = sec_build_common_ns_desc(sc, desc, ses, crp, enc, - buftype); + error = sec_build_common_ns_desc(sc, desc, csp, crp); return (error); } /* DEU */ -static int -sec_deu_newsession(struct sec_softc *sc, struct sec_session *ses, - struct cryptoini *enc, struct cryptoini *mac) +static bool +sec_deu_newsession(const struct crypto_session_params *csp) { - if (enc == NULL) - return (-1); - - switch (enc->cri_alg) { + switch (csp->csp_cipher_alg) { case CRYPTO_DES_CBC: case CRYPTO_3DES_CBC: - break; + return (true); default: - return (-1); + return (false); } - - ses->ss_ivlen = DES_BLOCK_LEN; - - return (0); } static int -sec_deu_make_desc(struct sec_softc *sc, struct sec_session *ses, - struct sec_desc *desc, struct cryptop *crp, int buftype) +sec_deu_make_desc(struct sec_softc *sc, const struct crypto_session_params *csp, + struct sec_desc *desc, struct cryptop *crp) { struct sec_hw_desc *hd = desc->sd_desc; - struct cryptodesc *enc, *mac; int error; - error = sec_split_crp(crp, &enc, &mac); - if (error) - return (error); - - if (!enc) - return (EINVAL); - hd->shd_eu_sel0 = SEC_EU_DEU; hd->shd_mode0 = SEC_DEU_MODE_CBC; - switch (enc->crd_alg) { + switch (csp->csp_cipher_alg) { case CRYPTO_3DES_CBC: hd->shd_mode0 |= SEC_DEU_MODE_TS; break; @@ -1622,25 +1520,23 @@ sec_deu_make_desc(struct sec_softc *sc, struct sec_session *ses, return (EINVAL); } - if (enc->crd_flags & CRD_F_ENCRYPT) { + if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { hd->shd_mode0 |= SEC_DEU_MODE_ED; hd->shd_dir = 0; } else hd->shd_dir = 1; - if (mac) - error = sec_build_common_s_desc(sc, desc, ses, crp, enc, mac, - buftype); + if (csp->csp_mode == CSP_MODE_ETA) + error = sec_build_common_s_desc(sc, desc, csp, crp); else - error = sec_build_common_ns_desc(sc, desc, ses, crp, enc, - buftype); + error = sec_build_common_ns_desc(sc, desc, csp, crp); return (error); } /* MDEU */ -static int +static bool sec_mdeu_can_handle(u_int alg) { switch (alg) { @@ -1651,20 +1547,21 @@ sec_mdeu_can_handle(u_int alg) case CRYPTO_SHA2_256_HMAC: case CRYPTO_SHA2_384_HMAC: case CRYPTO_SHA2_512_HMAC: - return (1); + return (true); default: - return (0); + return (false); } } static int -sec_mdeu_config(struct cryptodesc *crd, u_int *eu, u_int *mode, u_int *hashlen) +sec_mdeu_config(const struct crypto_session_params *csp, u_int *eu, u_int *mode, + u_int *hashlen) { *mode = SEC_MDEU_MODE_PD | SEC_MDEU_MODE_INIT; *eu = SEC_EU_NONE; - switch (crd->crd_alg) { + switch (csp->csp_auth_alg) { case CRYPTO_MD5_HMAC: *mode |= SEC_MDEU_MODE_HMAC; /* FALLTHROUGH */ @@ -1703,34 +1600,23 @@ sec_mdeu_config(struct cryptodesc *crd, u_int *eu, u_int *mode, u_int *hashlen) return (0); } -static int -sec_mdeu_newsession(struct sec_softc *sc, struct sec_session *ses, - struct cryptoini *enc, struct cryptoini *mac) +static bool +sec_mdeu_newsession(const struct crypto_session_params *csp) { - if (mac && sec_mdeu_can_handle(mac->cri_alg)) - return (0); - - return (-1); + return (sec_mdeu_can_handle(csp->csp_auth_alg)); } static int -sec_mdeu_make_desc(struct sec_softc *sc, struct sec_session *ses, - struct sec_desc *desc, struct cryptop *crp, int buftype) +sec_mdeu_make_desc(struct sec_softc *sc, + const struct crypto_session_params *csp, + struct sec_desc *desc, struct cryptop *crp) { - struct cryptodesc *enc, *mac; struct sec_hw_desc *hd = desc->sd_desc; u_int eu, mode, hashlen; int error; - error = sec_split_crp(crp, &enc, &mac); - if (error) - return (error); - - if (enc) - return (EINVAL); - - error = sec_mdeu_config(mac, &eu, &mode, &hashlen); + error = sec_mdeu_config(csp, &eu, &mode, &hashlen); if (error) return (error); @@ -1754,7 +1640,7 @@ sec_mdeu_make_desc(struct sec_softc *sc, struct sec_session *ses, if (hd->shd_mode0 & SEC_MDEU_MODE_HMAC) error = sec_make_pointer_direct(sc, desc, 2, desc->sd_desc_paddr + offsetof(struct sec_hw_desc, - shd_mkey), ses->ss_mklen); + shd_mkey), csp->csp_auth_klen); else error = sec_make_pointer_direct(sc, desc, 2, 0, 0); @@ -1762,8 +1648,8 @@ sec_mdeu_make_desc(struct sec_softc *sc, struct sec_session *ses, return (error); /* Pointer 3: Input Data */ - error = sec_make_pointer(sc, desc, 3, crp->crp_buf, mac->crd_skip, - mac->crd_len, buftype); + error = sec_make_pointer(sc, desc, 3, crp, crp->crp_payload_start, + crp->crp_payload_length); if (error) return (error); @@ -1773,8 +1659,8 @@ sec_mdeu_make_desc(struct sec_softc *sc, struct sec_session *ses, return (error); /* Pointer 5: Hash out */ - error = sec_make_pointer(sc, desc, 5, crp->crp_buf, - mac->crd_inject, hashlen, buftype); + error = sec_make_pointer_direct(sc, desc, 5, desc->sd_desc_paddr + + offsetof(struct sec_hw_desc, shd_digest), hashlen); if (error) return (error); diff --git a/sys/dev/sec/sec.h b/sys/dev/sec/sec.h index 05b15039ad64..6ad482316a54 100644 --- a/sys/dev/sec/sec.h +++ b/sys/dev/sec/sec.h @@ -98,6 +98,7 @@ struct sec_hw_desc { uint8_t shd_iv[SEC_MAX_IV_LEN]; uint8_t shd_key[SEC_MAX_KEY_LEN]; uint8_t shd_mkey[SEC_MAX_KEY_LEN]; + uint8_t shd_digest[HASH_MAX_LEN]; } __packed__; #define shd_eu_sel0 shd_control.request.eu_sel0 @@ -144,21 +145,17 @@ struct sec_lt { }; struct sec_eu_methods { - int (*sem_newsession)(struct sec_softc *sc, - struct sec_session *ses, struct cryptoini *enc, - struct cryptoini *mac); + bool (*sem_newsession)(const struct crypto_session_params *csp); int (*sem_make_desc)(struct sec_softc *sc, - struct sec_session *ses, struct sec_desc *desc, - struct cryptop *crp, int buftype); + const struct crypto_session_params *csp, struct sec_desc *desc, + struct cryptop *crp); }; struct sec_session { struct sec_eu_methods *ss_eu; uint8_t ss_key[SEC_MAX_KEY_LEN]; uint8_t ss_mkey[SEC_MAX_KEY_LEN]; - u_int ss_klen; - u_int ss_mklen; - u_int ss_ivlen; + int ss_mlen; }; struct sec_desc_map_info { @@ -319,11 +316,6 @@ struct sec_softc { (((sc)->sc_lt_free_cnt - (sc)->sc_lt_alloc_cnt - 1) \ & (SEC_LT_ENTRIES - 1)) -/* DMA Maping defines */ -#define SEC_MEMORY 0 -#define SEC_UIO 1 -#define SEC_MBUF 2 - /* Size of SEC registers area */ #define SEC_IO_SIZE 0x10000 |
