During IPsec operations, driver code pre-check whether KEYS can be inlined to limited size descriptor or not and based on that it decides to copy the complete KEY in descriptor or just give the memory pointer of KEY in descriptor. This pre-check code does not take care of padding required for security engine to make the KEYs inline which results in incorrect length descriptor for some algorithms.
This patch fixes this issue by updating the pre-check code with proper padding size included for each supported algorithm. Fixes: 453b9593a3cf ("crypto/dpaax_sec: fix inline query for descriptors") Cc: sta...@dpdk.org Signed-off-by: Gagandeep Singh <g.si...@nxp.com> --- drivers/common/dpaax/caamflib/desc/ipsec.h | 73 ++++++++++++++++++++++ drivers/crypto/dpaa_sec/dpaa_sec.c | 4 +- 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/drivers/common/dpaax/caamflib/desc/ipsec.h b/drivers/common/dpaax/caamflib/desc/ipsec.h index eff26f6f8b..b902873970 100644 --- a/drivers/common/dpaax/caamflib/desc/ipsec.h +++ b/drivers/common/dpaax/caamflib/desc/ipsec.h @@ -728,6 +728,79 @@ static inline void __gen_auth_key(struct program *program, authdata->key, authdata->key_type); } +/** + * rta_inline_ipsec_query() - Provide indications on which data items can be inlined + * and which shall be referenced in IPsec shared descriptor. + * @sd_base_len: Shared descriptor base length - bytes consumed by the commands, + * excluding the data items to be inlined (or corresponding + * pointer if an item is not inlined). Each cnstr_* function that + * generates descriptors should have a define mentioning + * corresponding length. + * @jd_len: Maximum length of the job descriptor(s) that will be used + * together with the shared descriptor. + * @data_len: Array of lengths of the data items trying to be inlined + * @inl_mask: 32bit mask with bit x = 1 if data item x can be inlined, 0 + * otherwise. + * @count: Number of data items (size of @data_len array); must be <= 32 + * @auth_algtype: Authentication algorithm type. + * @auth_index: Index value of data_len for authentication key length. + * -1 if authentication key length is not present in data_len. + * + * Return: 0 if data can be inlined / referenced, negative value if not. If 0, + * check @inl_mask for details. + */ +static inline int +rta_inline_ipsec_query(unsigned int sd_base_len, + unsigned int jd_len, + unsigned int *data_len, + uint32_t *inl_mask, + unsigned int count, + uint32_t auth_algtype, + int32_t auth_index) +{ + uint32_t dkp_protid; + + switch (auth_algtype & OP_PCL_IPSEC_AUTH_MASK) { + case OP_PCL_IPSEC_HMAC_MD5_96: + case OP_PCL_IPSEC_HMAC_MD5_128: + dkp_protid = OP_PCLID_DKP_MD5; + break; + case OP_PCL_IPSEC_HMAC_SHA1_96: + case OP_PCL_IPSEC_HMAC_SHA1_160: + dkp_protid = OP_PCLID_DKP_SHA1; + break; + case OP_PCL_IPSEC_HMAC_SHA2_256_128: + dkp_protid = OP_PCLID_DKP_SHA256; + break; + case OP_PCL_IPSEC_HMAC_SHA2_384_192: + dkp_protid = OP_PCLID_DKP_SHA384; + break; + case OP_PCL_IPSEC_HMAC_SHA2_512_256: + dkp_protid = OP_PCLID_DKP_SHA512; + break; + case OP_PCL_IPSEC_HMAC_SHA2_224_96: + case OP_PCL_IPSEC_HMAC_SHA2_224_112: + case OP_PCL_IPSEC_HMAC_SHA2_224_224: + dkp_protid = OP_PCLID_DKP_SHA224; + break; + default: + return rta_inline_query(sd_base_len, + jd_len, + data_len, + inl_mask, count); + } + + /* Updating the maximum supported inline key length */ + if (auth_index != -1) { + if (split_key_len(dkp_protid) > data_len[auth_index]) + data_len[auth_index] = split_key_len(dkp_protid); + } + return rta_inline_query(sd_base_len, + jd_len, + data_len, + inl_mask, count); +} + /** * cnstr_shdsc_ipsec_encap - IPSec ESP encapsulation protocol-level shared * descriptor. diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c index 44528eaf7f..679f78c4b9 100644 --- a/drivers/crypto/dpaa_sec/dpaa_sec.c +++ b/drivers/crypto/dpaa_sec/dpaa_sec.c @@ -395,10 +395,10 @@ dpaa_sec_prep_ipsec_cdb(dpaa_sec_session *ses) cdb->sh_desc[0] = cipherdata.keylen; cdb->sh_desc[1] = authdata.keylen; - err = rta_inline_query(IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN, + err = rta_inline_ipsec_query(IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN, DESC_JOB_IO_LEN, (unsigned int *)cdb->sh_desc, - &cdb->sh_desc[2], 2); + &cdb->sh_desc[2], 2, authdata.algtype, 1); if (err < 0) { DPAA_SEC_ERR("Crypto: Incorrect key lengths"); -- 2.25.1