aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/sec
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2020-03-27 18:25:23 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2020-03-27 18:25:23 +0000
commitc03414326909ed7a740be3ba63fbbef01fe513a8 (patch)
tree9067f28738df03bb4b685773c52ba32517468212 /sys/dev/sec
parent4d94781b4d9e03b8dbd6604d7e2280d342d3cf7e (diff)
Notes
Diffstat (limited to 'sys/dev/sec')
-rw-r--r--sys/dev/sec/sec.c540
-rw-r--r--sys/dev/sec/sec.h18
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