From f6ab96f13d7a23b39fb5135b64ed8e99c425c7a9 Mon Sep 17 00:00:00 2001 From: Akhil Goyal Date: Mon, 1 Jun 2020 22:47:45 +0530 Subject: [PATCH] crypto/dpaax_sec: fix 18-bit PDCP cases with HFN override In case of RTA_SEC_ERA = 8, where the length of shared desc is large for some of PDCP cases, the descriptor buffer cannot hold 2 extra words when HFN override is enabled. As a result, the descriptor fails. This patch converts one of the keys from immediate key to reference key hence reducing the length of the descriptor. Fixes: 2e4cbdb4b2c2 ("crypto/dpaax_sec: support PDCP U-Plane with integrity") Cc: stable@dpdk.org Signed-off-by: Akhil Goyal Acked-by: Hemant Agrawal --- drivers/common/dpaax/caamflib/desc/pdcp.h | 44 +++++++++++++++++++++ drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c | 8 ++++ drivers/crypto/dpaa_sec/dpaa_sec.c | 33 +++------------- 3 files changed, 58 insertions(+), 27 deletions(-) diff --git a/drivers/common/dpaax/caamflib/desc/pdcp.h b/drivers/common/dpaax/caamflib/desc/pdcp.h index b5e2d24e47..99eb0f71a8 100644 --- a/drivers/common/dpaax/caamflib/desc/pdcp.h +++ b/drivers/common/dpaax/caamflib/desc/pdcp.h @@ -262,6 +262,50 @@ enum pdb_type_e { PDCP_PDB_TYPE_INVALID }; +/** + * rta_inline_pdcp_query() - Provide indications if a key can be passed as + * immediate data or shall be referenced in a + * shared descriptor. + * Return: 0 if data can be inlined or 1 if referenced. + */ +static inline int +rta_inline_pdcp_query(enum auth_type_pdcp auth_alg, + enum cipher_type_pdcp cipher_alg, + enum pdcp_sn_size sn_size, + int8_t hfn_ovd) +{ + /** + * Shared Descriptors for some of the cases does not fit in the + * MAX_DESC_SIZE of the descriptor especially when non-protocol + * descriptors are formed as in 18bit cases and when HFN override + * is enabled as 2 extra words are added in the job descriptor. + * The cases which exceed are for RTA_SEC_ERA=8 and HFN override + * enabled and 18bit uplane and either of following Algo combinations. + * - SNOW-AES + * - AES-SNOW + * - SNOW-SNOW + * - ZUC-SNOW + * + * We cannot make inline for all cases, as this will impact performance + * due to extra memory accesses for the keys. + */ + if ((rta_sec_era == RTA_SEC_ERA_8) && hfn_ovd && + (sn_size == PDCP_SN_SIZE_18) && + ((cipher_alg == PDCP_CIPHER_TYPE_SNOW && + auth_alg == PDCP_AUTH_TYPE_AES) || + (cipher_alg == PDCP_CIPHER_TYPE_AES && + auth_alg == PDCP_AUTH_TYPE_SNOW) || + (cipher_alg == PDCP_CIPHER_TYPE_SNOW && + auth_alg == PDCP_AUTH_TYPE_SNOW) || + (cipher_alg == PDCP_CIPHER_TYPE_ZUC && + auth_alg == PDCP_AUTH_TYPE_SNOW))) { + + return 1; + } + + return 0; +} + /* * Function for appending the portion of a PDCP Control Plane shared descriptor * which performs NULL encryption and integrity (i.e. copies the input frame diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c index 12f833136e..60fdced789 100644 --- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c +++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c @@ -3154,6 +3154,14 @@ dpaa2_sec_set_pdcp_session(struct rte_cryptodev *dev, goto out; } + if (rta_inline_pdcp_query(authdata.algtype, + cipherdata.algtype, + session->pdcp.sn_size, + session->pdcp.hfn_ovd)) { + cipherdata.key = DPAA2_VADDR_TO_IOVA(cipherdata.key); + cipherdata.key_type = RTA_DATA_PTR; + } + if (pdcp_xform->domain == RTE_SECURITY_PDCP_MODE_CONTROL) { if (session->dir == DIR_ENC) bufsize = cnstr_shdsc_pdcp_c_plane_encap( diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c index d9fa8bb369..01e79c8eaa 100644 --- a/drivers/crypto/dpaa_sec/dpaa_sec.c +++ b/drivers/crypto/dpaa_sec/dpaa_sec.c @@ -240,7 +240,6 @@ dpaa_sec_prep_pdcp_cdb(dpaa_sec_session *ses) 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 int swap = false; #else @@ -254,10 +253,6 @@ dpaa_sec_prep_pdcp_cdb(dpaa_sec_session *ses) cipherdata.algtype = ses->cipher_key.alg; cipherdata.algmode = ses->cipher_key.algmode; - cdb->sh_desc[0] = cipherdata.keylen; - cdb->sh_desc[1] = 0; - cdb->sh_desc[2] = 0; - if (ses->auth_alg) { authdata.key = (size_t)ses->auth_key.data; authdata.keylen = ses->auth_key.length; @@ -267,33 +262,17 @@ dpaa_sec_prep_pdcp_cdb(dpaa_sec_session *ses) authdata.algmode = ses->auth_key.algmode; 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) { + if (rta_inline_pdcp_query(authdata.algtype, + cipherdata.algtype, + ses->pdcp.sn_size, + ses->pdcp.hfn_ovd)) { cipherdata.key = - (size_t)rte_dpaa_mem_vtop((void *)(size_t)cipherdata.key); + (size_t)rte_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)rte_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) -- 2.20.1