From: Vakul Garg Date: Mon, 30 Sep 2019 14:40:42 +0000 (+0530) Subject: crypto/dpaax_sec: support PDCP U-Plane with integrity X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=2e4cbdb4b2c2;p=dpdk.git crypto/dpaax_sec: support PDCP U-Plane with integrity PDCP u-plane may optionally support integrity as well. This patch add support for supporting integrity along with confidentiality. Signed-off-by: Vakul Garg Acked-by: Akhil Goyal --- diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c index fae2168252..75a4fe0faf 100644 --- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c +++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c @@ -2591,6 +2591,7 @@ dpaa2_sec_set_pdcp_session(struct rte_cryptodev *dev, struct ctxt_priv *priv; struct dpaa2_sec_dev_private *dev_priv = dev->data->dev_private; struct alginfo authdata, cipherdata; + struct alginfo *p_authdata = NULL; int bufsize = -1; struct sec_flow_context *flc; #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN @@ -2693,39 +2694,32 @@ dpaa2_sec_set_pdcp_session(struct rte_cryptodev *dev, goto out; } - /* Auth is only applicable for control mode operation. */ - if (pdcp_xform->domain == RTE_SECURITY_PDCP_MODE_CONTROL) { - if (pdcp_xform->sn_size != RTE_SECURITY_PDCP_SN_SIZE_5 && - pdcp_xform->sn_size != RTE_SECURITY_PDCP_SN_SIZE_12) { - DPAA2_SEC_ERR( - "PDCP Seq Num size should be 5/12 bits for cmode"); - goto out; - } - if (auth_xform) { - session->auth_key.data = rte_zmalloc(NULL, - auth_xform->key.length, - RTE_CACHE_LINE_SIZE); - if (session->auth_key.data == NULL && - auth_xform->key.length > 0) { - DPAA2_SEC_ERR("No Memory for auth key"); - rte_free(session->cipher_key.data); - rte_free(priv); - return -ENOMEM; - } - session->auth_key.length = auth_xform->key.length; - memcpy(session->auth_key.data, auth_xform->key.data, - auth_xform->key.length); - session->auth_alg = auth_xform->algo; - } else { - session->auth_key.data = NULL; - session->auth_key.length = 0; - session->auth_alg = RTE_CRYPTO_AUTH_NULL; + if (auth_xform) { + session->auth_key.data = rte_zmalloc(NULL, + auth_xform->key.length, + RTE_CACHE_LINE_SIZE); + if (!session->auth_key.data && + auth_xform->key.length > 0) { + DPAA2_SEC_ERR("No Memory for auth key"); + rte_free(session->cipher_key.data); + rte_free(priv); + return -ENOMEM; } - authdata.key = (size_t)session->auth_key.data; - authdata.keylen = session->auth_key.length; - authdata.key_enc_flags = 0; - authdata.key_type = RTA_DATA_IMM; + session->auth_key.length = auth_xform->key.length; + memcpy(session->auth_key.data, auth_xform->key.data, + auth_xform->key.length); + session->auth_alg = auth_xform->algo; + } else { + session->auth_key.data = NULL; + session->auth_key.length = 0; + session->auth_alg = 0; + } + authdata.key = (size_t)session->auth_key.data; + authdata.keylen = session->auth_key.length; + authdata.key_enc_flags = 0; + authdata.key_type = RTA_DATA_IMM; + if (session->auth_alg) { switch (session->auth_alg) { case RTE_CRYPTO_AUTH_SNOW3G_UIA2: authdata.algtype = PDCP_AUTH_TYPE_SNOW; @@ -2745,6 +2739,13 @@ dpaa2_sec_set_pdcp_session(struct rte_cryptodev *dev, goto out; } + p_authdata = &authdata; + } else if (pdcp_xform->domain == RTE_SECURITY_PDCP_MODE_CONTROL) { + DPAA2_SEC_ERR("Crypto: Integrity must for c-plane"); + goto out; + } + + if (pdcp_xform->domain == RTE_SECURITY_PDCP_MODE_CONTROL) { if (session->dir == DIR_ENC) bufsize = cnstr_shdsc_pdcp_c_plane_encap( priv->flc_desc[0].desc, 1, swap, @@ -2774,7 +2775,7 @@ dpaa2_sec_set_pdcp_session(struct rte_cryptodev *dev, pdcp_xform->bearer, pdcp_xform->pkt_dir, pdcp_xform->hfn_threshold, - &cipherdata, 0); + &cipherdata, p_authdata, 0); else if (session->dir == DIR_DEC) bufsize = cnstr_shdsc_pdcp_u_plane_decap( priv->flc_desc[0].desc, 1, swap, @@ -2783,7 +2784,7 @@ dpaa2_sec_set_pdcp_session(struct rte_cryptodev *dev, pdcp_xform->bearer, pdcp_xform->pkt_dir, pdcp_xform->hfn_threshold, - &cipherdata, 0); + &cipherdata, p_authdata, 0); } if (bufsize < 0) { diff --git a/drivers/crypto/dpaa2_sec/hw/desc/pdcp.h b/drivers/crypto/dpaa2_sec/hw/desc/pdcp.h index 607c587e20..a636640c4a 100644 --- a/drivers/crypto/dpaa2_sec/hw/desc/pdcp.h +++ b/drivers/crypto/dpaa2_sec/hw/desc/pdcp.h @@ -1801,9 +1801,16 @@ static inline int pdcp_insert_uplane_15bit_op(struct program *p, bool swap __maybe_unused, struct alginfo *cipherdata, + struct alginfo *authdata, unsigned int dir) { int op; + + /* Insert auth key if requested */ + if (authdata && authdata->algtype) + KEY(p, KEY2, authdata->key_enc_flags, authdata->key, + authdata->keylen, INLINE_KEY(authdata)); + /* Insert Cipher Key */ KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key, cipherdata->keylen, INLINE_KEY(cipherdata)); @@ -2478,6 +2485,7 @@ cnstr_shdsc_pdcp_u_plane_encap(uint32_t *descbuf, unsigned short direction, uint32_t hfn_threshold, struct alginfo *cipherdata, + struct alginfo *authdata, unsigned char era_2_sw_hfn_ovrd) { struct program prg; @@ -2490,6 +2498,11 @@ cnstr_shdsc_pdcp_u_plane_encap(uint32_t *descbuf, return -EINVAL; } + if (authdata && !authdata->algtype && rta_sec_era < RTA_SEC_ERA_8) { + pr_err("Cannot use u-plane auth with era < 8"); + return -EINVAL; + } + PROGRAM_CNTXT_INIT(p, descbuf, 0); if (swap) PROGRAM_SET_BSWAP(p); @@ -2509,6 +2522,13 @@ cnstr_shdsc_pdcp_u_plane_encap(uint32_t *descbuf, if (err) return err; + /* Insert auth key if requested */ + if (authdata && authdata->algtype) { + KEY(p, KEY2, authdata->key_enc_flags, + (uint64_t)authdata->key, authdata->keylen, + INLINE_KEY(authdata)); + } + switch (sn_size) { case PDCP_SN_SIZE_7: case PDCP_SN_SIZE_12: @@ -2518,20 +2538,24 @@ cnstr_shdsc_pdcp_u_plane_encap(uint32_t *descbuf, pr_err("Invalid era for selected algorithm\n"); return -ENOTSUP; } + /* fallthrough */ case PDCP_CIPHER_TYPE_AES: case PDCP_CIPHER_TYPE_SNOW: + case PDCP_CIPHER_TYPE_NULL: /* Insert Cipher Key */ KEY(p, KEY1, cipherdata->key_enc_flags, (uint64_t)cipherdata->key, cipherdata->keylen, INLINE_KEY(cipherdata)); - PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL, - OP_PCLID_LTE_PDCP_USER, - (uint16_t)cipherdata->algtype); - break; - case PDCP_CIPHER_TYPE_NULL: - insert_copy_frame_op(p, - cipherdata, - OP_TYPE_ENCAP_PROTOCOL); + + if (authdata) + PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL, + OP_PCLID_LTE_PDCP_USER_RN, + ((uint16_t)cipherdata->algtype << 8) | + (uint16_t)authdata->algtype); + else + PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL, + OP_PCLID_LTE_PDCP_USER, + (uint16_t)cipherdata->algtype); break; default: pr_err("%s: Invalid encrypt algorithm selected: %d\n", @@ -2551,7 +2575,7 @@ cnstr_shdsc_pdcp_u_plane_encap(uint32_t *descbuf, default: err = pdcp_insert_uplane_15bit_op(p, swap, cipherdata, - OP_TYPE_ENCAP_PROTOCOL); + authdata, OP_TYPE_ENCAP_PROTOCOL); if (err) return err; break; @@ -2605,6 +2629,7 @@ cnstr_shdsc_pdcp_u_plane_decap(uint32_t *descbuf, unsigned short direction, uint32_t hfn_threshold, struct alginfo *cipherdata, + struct alginfo *authdata, unsigned char era_2_sw_hfn_ovrd) { struct program prg; @@ -2617,6 +2642,11 @@ cnstr_shdsc_pdcp_u_plane_decap(uint32_t *descbuf, return -EINVAL; } + if (authdata && !authdata->algtype && rta_sec_era < RTA_SEC_ERA_8) { + pr_err("Cannot use u-plane auth with era < 8"); + return -EINVAL; + } + PROGRAM_CNTXT_INIT(p, descbuf, 0); if (swap) PROGRAM_SET_BSWAP(p); @@ -2636,6 +2666,12 @@ cnstr_shdsc_pdcp_u_plane_decap(uint32_t *descbuf, if (err) return err; + /* Insert auth key if requested */ + if (authdata && authdata->algtype) + KEY(p, KEY2, authdata->key_enc_flags, + (uint64_t)authdata->key, authdata->keylen, + INLINE_KEY(authdata)); + switch (sn_size) { case PDCP_SN_SIZE_7: case PDCP_SN_SIZE_12: @@ -2645,20 +2681,23 @@ cnstr_shdsc_pdcp_u_plane_decap(uint32_t *descbuf, pr_err("Invalid era for selected algorithm\n"); return -ENOTSUP; } + /* fallthrough */ case PDCP_CIPHER_TYPE_AES: case PDCP_CIPHER_TYPE_SNOW: + case PDCP_CIPHER_TYPE_NULL: /* Insert Cipher Key */ KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key, cipherdata->keylen, INLINE_KEY(cipherdata)); - PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL, - OP_PCLID_LTE_PDCP_USER, - (uint16_t)cipherdata->algtype); - break; - case PDCP_CIPHER_TYPE_NULL: - insert_copy_frame_op(p, - cipherdata, - OP_TYPE_DECAP_PROTOCOL); + if (authdata) + PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL, + OP_PCLID_LTE_PDCP_USER_RN, + ((uint16_t)cipherdata->algtype << 8) | + (uint16_t)authdata->algtype); + else + PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL, + OP_PCLID_LTE_PDCP_USER, + (uint16_t)cipherdata->algtype); break; default: pr_err("%s: Invalid encrypt algorithm selected: %d\n", @@ -2678,7 +2717,7 @@ cnstr_shdsc_pdcp_u_plane_decap(uint32_t *descbuf, default: err = pdcp_insert_uplane_15bit_op(p, swap, cipherdata, - OP_TYPE_DECAP_PROTOCOL); + authdata, OP_TYPE_DECAP_PROTOCOL); if (err) return err; break; diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c index d29e563051..059d440999 100644 --- a/drivers/crypto/dpaa_sec/dpaa_sec.c +++ b/drivers/crypto/dpaa_sec/dpaa_sec.c @@ -386,6 +386,7 @@ dpaa_sec_prep_pdcp_cdb(dpaa_sec_session *ses) { struct alginfo authdata = {0}, cipherdata = {0}; struct sec_cdb *cdb = &ses->cdb; + struct alginfo *p_authdata = NULL; int32_t shared_desc_len = 0; int err; #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN @@ -418,7 +419,11 @@ dpaa_sec_prep_pdcp_cdb(dpaa_sec_session *ses) cipherdata.key_enc_flags = 0; cipherdata.key_type = RTA_DATA_IMM; - if (ses->pdcp.domain == RTE_SECURITY_PDCP_MODE_CONTROL) { + cdb->sh_desc[0] = cipherdata.keylen; + cdb->sh_desc[1] = 0; + cdb->sh_desc[2] = 0; + + if (ses->auth_alg) { switch (ses->auth_alg) { case RTE_CRYPTO_AUTH_SNOW3G_UIA2: authdata.algtype = PDCP_AUTH_TYPE_SNOW; @@ -443,32 +448,36 @@ dpaa_sec_prep_pdcp_cdb(dpaa_sec_session *ses) authdata.key_enc_flags = 0; authdata.key_type = RTA_DATA_IMM; - cdb->sh_desc[0] = cipherdata.keylen; + p_authdata = &authdata; + cdb->sh_desc[1] = authdata.keylen; - err = rta_inline_query(IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN, - MIN_JOB_DESC_SIZE, - (unsigned int *)cdb->sh_desc, - &cdb->sh_desc[2], 2); + } - if (err < 0) { - DPAA_SEC_ERR("Crypto: Incorrect key lengths"); - return err; - } - if (!(cdb->sh_desc[2] & 1) && cipherdata.keylen) { - cipherdata.key = (size_t)dpaa_mem_vtop( - (void *)(size_t)cipherdata.key); - cipherdata.key_type = RTA_DATA_PTR; - } - if (!(cdb->sh_desc[2] & (1<<1)) && authdata.keylen) { - authdata.key = (size_t)dpaa_mem_vtop( - (void *)(size_t)authdata.key); - authdata.key_type = RTA_DATA_PTR; - } + err = rta_inline_query(IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN, + MIN_JOB_DESC_SIZE, + (unsigned int *)cdb->sh_desc, + &cdb->sh_desc[2], 2); + if (err < 0) { + DPAA_SEC_ERR("Crypto: Incorrect key lengths"); + return err; + } - cdb->sh_desc[0] = 0; - cdb->sh_desc[1] = 0; - cdb->sh_desc[2] = 0; + if (!(cdb->sh_desc[2] & 1) && cipherdata.keylen) { + cipherdata.key = + (size_t)dpaa_mem_vtop((void *)(size_t)cipherdata.key); + cipherdata.key_type = RTA_DATA_PTR; + } + if (!(cdb->sh_desc[2] & (1 << 1)) && authdata.keylen) { + authdata.key = + (size_t)dpaa_mem_vtop((void *)(size_t)authdata.key); + authdata.key_type = RTA_DATA_PTR; + } + cdb->sh_desc[0] = 0; + cdb->sh_desc[1] = 0; + cdb->sh_desc[2] = 0; + + if (ses->pdcp.domain == RTE_SECURITY_PDCP_MODE_CONTROL) { if (ses->dir == DIR_ENC) shared_desc_len = cnstr_shdsc_pdcp_c_plane_encap( cdb->sh_desc, 1, swap, @@ -490,25 +499,6 @@ dpaa_sec_prep_pdcp_cdb(dpaa_sec_session *ses) &cipherdata, &authdata, 0); } else { - cdb->sh_desc[0] = cipherdata.keylen; - err = rta_inline_query(IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN, - MIN_JOB_DESC_SIZE, - (unsigned int *)cdb->sh_desc, - &cdb->sh_desc[2], 1); - - if (err < 0) { - DPAA_SEC_ERR("Crypto: Incorrect key lengths"); - return err; - } - if (!(cdb->sh_desc[2] & 1) && cipherdata.keylen) { - cipherdata.key = (size_t)dpaa_mem_vtop( - (void *)(size_t)cipherdata.key); - cipherdata.key_type = RTA_DATA_PTR; - } - cdb->sh_desc[0] = 0; - cdb->sh_desc[1] = 0; - cdb->sh_desc[2] = 0; - if (ses->dir == DIR_ENC) shared_desc_len = cnstr_shdsc_pdcp_u_plane_encap( cdb->sh_desc, 1, swap, @@ -517,7 +507,7 @@ dpaa_sec_prep_pdcp_cdb(dpaa_sec_session *ses) ses->pdcp.bearer, ses->pdcp.pkt_dir, ses->pdcp.hfn_threshold, - &cipherdata, 0); + &cipherdata, p_authdata, 0); else if (ses->dir == DIR_DEC) shared_desc_len = cnstr_shdsc_pdcp_u_plane_decap( cdb->sh_desc, 1, swap, @@ -526,7 +516,7 @@ dpaa_sec_prep_pdcp_cdb(dpaa_sec_session *ses) ses->pdcp.bearer, ses->pdcp.pkt_dir, ses->pdcp.hfn_threshold, - &cipherdata, 0); + &cipherdata, p_authdata, 0); } return shared_desc_len; @@ -2389,7 +2379,6 @@ dpaa_sec_set_pdcp_session(struct rte_cryptodev *dev, session->dir = DIR_ENC; } - /* Auth is only applicable for control mode operation. */ if (pdcp_xform->domain == RTE_SECURITY_PDCP_MODE_CONTROL) { if (pdcp_xform->sn_size != RTE_SECURITY_PDCP_SN_SIZE_5 && pdcp_xform->sn_size != RTE_SECURITY_PDCP_SN_SIZE_12) { @@ -2397,25 +2386,26 @@ dpaa_sec_set_pdcp_session(struct rte_cryptodev *dev, "PDCP Seq Num size should be 5/12 bits for cmode"); goto out; } - if (auth_xform) { - session->auth_key.data = rte_zmalloc(NULL, - auth_xform->key.length, - RTE_CACHE_LINE_SIZE); - if (session->auth_key.data == NULL && - auth_xform->key.length > 0) { - DPAA_SEC_ERR("No Memory for auth key"); - rte_free(session->cipher_key.data); - return -ENOMEM; - } - session->auth_key.length = auth_xform->key.length; - memcpy(session->auth_key.data, auth_xform->key.data, - auth_xform->key.length); - session->auth_alg = auth_xform->algo; - } else { - session->auth_key.data = NULL; - session->auth_key.length = 0; - session->auth_alg = RTE_CRYPTO_AUTH_NULL; + } + + if (auth_xform) { + session->auth_key.data = rte_zmalloc(NULL, + auth_xform->key.length, + RTE_CACHE_LINE_SIZE); + if (!session->auth_key.data && + auth_xform->key.length > 0) { + DPAA_SEC_ERR("No Memory for auth key"); + rte_free(session->cipher_key.data); + return -ENOMEM; } + session->auth_key.length = auth_xform->key.length; + memcpy(session->auth_key.data, auth_xform->key.data, + auth_xform->key.length); + session->auth_alg = auth_xform->algo; + } else { + session->auth_key.data = NULL; + session->auth_key.length = 0; + session->auth_alg = 0; } session->pdcp.domain = pdcp_xform->domain; session->pdcp.bearer = pdcp_xform->bearer;