From patchwork Mon Jun 20 07:18:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tejasree Kondoj X-Patchwork-Id: 113083 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 0999CA0545; Mon, 20 Jun 2022 09:18:25 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E3EE9427EB; Mon, 20 Jun 2022 09:18:24 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 5AE2340150 for ; Mon, 20 Jun 2022 09:18:22 +0200 (CEST) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25JNE48W011897 for ; Mon, 20 Jun 2022 00:18:21 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=9XcsW0wBSLsqzdSjU7xBzj/6QZap0qGpGMoVF2sgVvs=; b=C5GpKF/38Q1yvW8I3HjWN2Al2jyOqwtKTDkegzj0gVdrWiXfLPTaZMHVMSEeKBSutZ7q msbnXNVp2trDqEaXnPKdnC86ztbLzdt1T0HLXFBoE4z5pBQEXm8j7cVDS+tNvG2ZwqYn Ub/C8slVrULDQrKmVNkwv5QrjaIvLaRPEV0Ta0FT1XBS5aA/wXfSO+sJLWGeUw8smkiV nzRYP6bJZcJo3PvWDN7XTKxe6Ko7kpia9ie36EPFwRYPMnAaZOJIAcsl3LVqa6DJ9vP1 Zihbg021rB/Lar5zCiC+0AeHxp2bjCPOoffkKp/WNlGpV9kDDnvr70DbcT612BwzuQYR dg== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3gsc2p5u2n-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Mon, 20 Jun 2022 00:18:18 -0700 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 20 Jun 2022 00:18:15 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend Transport; Mon, 20 Jun 2022 00:18:15 -0700 Received: from hyd1554.marvell.com (unknown [10.29.57.11]) by maili.marvell.com (Postfix) with ESMTP id 0026B5B6957; Mon, 20 Jun 2022 00:18:11 -0700 (PDT) From: Tejasree Kondoj To: Akhil Goyal CC: Vidya Sagar Velumuri , Jerin Jacob , Anoob Joseph , Nithin Dabilpuram , Archana Muniganti , "Ankur Dwivedi" , Kiran Kumar K , Sunil Kumar Kori , Satha Rao , Subject: [PATCH 1/3] crypto/cnxk: move IPsec SA creation to common Date: Mon, 20 Jun 2022 12:48:05 +0530 Message-ID: <20220620071807.951128-2-ktejasree@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220620071807.951128-1-ktejasree@marvell.com> References: <20220620071807.951128-1-ktejasree@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: CTkhrIgzYPGvUDiz4suEoTlE2M_V4Lss X-Proofpoint-GUID: CTkhrIgzYPGvUDiz4suEoTlE2M_V4Lss X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.64.514 definitions=2022-06-20_05,2022-06-17_01,2022-02-23_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Vidya Sagar Velumuri Move the IPsec SA creation to common. The code can be used by fastpath also to create the SAs Add changes to support new full context microcode Signed-off-by: Vidya Sagar Velumuri Signed-off-by: Archana Muniganti --- drivers/common/cnxk/cnxk_security.c | 398 +++++++++++++++ drivers/common/cnxk/cnxk_security.h | 11 + drivers/common/cnxk/roc_cpt.c | 93 ++++ drivers/common/cnxk/roc_cpt.h | 3 + drivers/common/cnxk/roc_ie_on.h | 21 +- drivers/common/cnxk/version.map | 3 + drivers/crypto/cnxk/cn9k_cryptodev_ops.c | 24 + drivers/crypto/cnxk/cn9k_ipsec.c | 594 +++-------------------- drivers/crypto/cnxk/cn9k_ipsec_la_ops.h | 16 +- drivers/crypto/cnxk/cnxk_cryptodev_ops.h | 1 + 10 files changed, 631 insertions(+), 533 deletions(-) diff --git a/drivers/common/cnxk/cnxk_security.c b/drivers/common/cnxk/cnxk_security.c index 72ee5ee91f..dca8742be3 100644 --- a/drivers/common/cnxk/cnxk_security.c +++ b/drivers/common/cnxk/cnxk_security.c @@ -971,3 +971,401 @@ cnxk_ipsec_outb_rlens_get(struct cnxk_ipsec_outb_rlens *rlens, rlens->max_extended_len = partial_len + roundup_len + roundup_byte; return 0; } + +static inline int +on_ipsec_sa_ctl_set(struct rte_security_ipsec_xform *ipsec, + struct rte_crypto_sym_xform *crypto_xform, + struct roc_ie_on_sa_ctl *ctl) +{ + struct rte_crypto_sym_xform *cipher_xform, *auth_xform; + int aes_key_len = 0; + + if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) { + auth_xform = crypto_xform; + cipher_xform = crypto_xform->next; + } else { + cipher_xform = crypto_xform; + auth_xform = crypto_xform->next; + } + + if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) + ctl->direction = ROC_IE_SA_DIR_OUTBOUND; + else + ctl->direction = ROC_IE_SA_DIR_INBOUND; + + if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) { + if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) + ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_4; + else if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV6) + ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_6; + else + return -EINVAL; + } + + if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) { + ctl->ipsec_mode = ROC_IE_SA_MODE_TRANSPORT; + ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_4; + } else if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) + ctl->ipsec_mode = ROC_IE_SA_MODE_TUNNEL; + else + return -EINVAL; + + if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH) + ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_AH; + else if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP) + ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_ESP; + else + return -EINVAL; + + if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) { + switch (crypto_xform->aead.algo) { + case RTE_CRYPTO_AEAD_AES_GCM: + ctl->enc_type = ROC_IE_ON_SA_ENC_AES_GCM; + aes_key_len = crypto_xform->aead.key.length; + break; + default: + plt_err("Unsupported AEAD algorithm"); + return -ENOTSUP; + } + } else { + if (cipher_xform != NULL) { + switch (cipher_xform->cipher.algo) { + case RTE_CRYPTO_CIPHER_NULL: + ctl->enc_type = ROC_IE_ON_SA_ENC_NULL; + break; + case RTE_CRYPTO_CIPHER_AES_CBC: + ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CBC; + aes_key_len = cipher_xform->cipher.key.length; + break; + case RTE_CRYPTO_CIPHER_AES_CTR: + ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CTR; + aes_key_len = cipher_xform->cipher.key.length; + break; + default: + plt_err("Unsupported cipher algorithm"); + return -ENOTSUP; + } + } + + switch (auth_xform->auth.algo) { + case RTE_CRYPTO_AUTH_NULL: + ctl->auth_type = ROC_IE_ON_SA_AUTH_NULL; + break; + case RTE_CRYPTO_AUTH_MD5_HMAC: + ctl->auth_type = ROC_IE_ON_SA_AUTH_MD5; + break; + case RTE_CRYPTO_AUTH_SHA1_HMAC: + ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA1; + break; + case RTE_CRYPTO_AUTH_SHA224_HMAC: + ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_224; + break; + case RTE_CRYPTO_AUTH_SHA256_HMAC: + ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_256; + break; + case RTE_CRYPTO_AUTH_SHA384_HMAC: + ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_384; + break; + case RTE_CRYPTO_AUTH_SHA512_HMAC: + ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_512; + break; + case RTE_CRYPTO_AUTH_AES_GMAC: + ctl->auth_type = ROC_IE_ON_SA_AUTH_AES_GMAC; + aes_key_len = auth_xform->auth.key.length; + break; + case RTE_CRYPTO_AUTH_AES_XCBC_MAC: + ctl->auth_type = ROC_IE_ON_SA_AUTH_AES_XCBC_128; + break; + default: + plt_err("Unsupported auth algorithm"); + return -ENOTSUP; + } + } + + /* Set AES key length */ + if (ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CBC || + ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CCM || + ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CTR || + ctl->enc_type == ROC_IE_ON_SA_ENC_AES_GCM || + ctl->auth_type == ROC_IE_ON_SA_AUTH_AES_GMAC) { + switch (aes_key_len) { + case 16: + ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_128; + break; + case 24: + ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_192; + break; + case 32: + ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_256; + break; + default: + plt_err("Invalid AES key length"); + return -EINVAL; + } + } + + if (ipsec->options.esn) + ctl->esn_en = 1; + + if (ipsec->options.udp_encap == 1) + ctl->encap_type = ROC_IE_ON_SA_ENCAP_UDP; + + ctl->copy_df = ipsec->options.copy_df; + + ctl->spi = rte_cpu_to_be_32(ipsec->spi); + + rte_io_wmb(); + + ctl->valid = 1; + + return 0; +} + +static inline int +on_fill_ipsec_common_sa(struct rte_security_ipsec_xform *ipsec, + struct rte_crypto_sym_xform *crypto_xform, + struct roc_ie_on_common_sa *common_sa) +{ + struct rte_crypto_sym_xform *cipher_xform, *auth_xform; + const uint8_t *cipher_key; + int cipher_key_len = 0; + int ret; + + ret = on_ipsec_sa_ctl_set(ipsec, crypto_xform, &common_sa->ctl); + if (ret) + return ret; + + if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) { + auth_xform = crypto_xform; + cipher_xform = crypto_xform->next; + } else { + cipher_xform = crypto_xform; + auth_xform = crypto_xform->next; + } + + if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) { + if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) + memcpy(common_sa->iv.gcm.nonce, &ipsec->salt, 4); + cipher_key = crypto_xform->aead.key.data; + cipher_key_len = crypto_xform->aead.key.length; + } else { + if (cipher_xform) { + cipher_key = cipher_xform->cipher.key.data; + cipher_key_len = cipher_xform->cipher.key.length; + } + + if (auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) { + memcpy(common_sa->iv.gcm.nonce, &ipsec->salt, 4); + cipher_key = auth_xform->auth.key.data; + cipher_key_len = auth_xform->auth.key.length; + } + } + + if (cipher_key_len != 0) + memcpy(common_sa->cipher_key, cipher_key, cipher_key_len); + + return 0; +} + +int +cnxk_on_ipsec_outb_sa_create(struct rte_security_ipsec_xform *ipsec, + struct rte_crypto_sym_xform *crypto_xform, + struct roc_ie_on_outb_sa *out_sa) +{ + struct roc_ie_on_ip_template *template = NULL; + struct rte_crypto_sym_xform *auth_xform; + struct roc_ie_on_sa_ctl *ctl; + struct rte_ipv6_hdr *ip6; + struct rte_ipv4_hdr *ip4; + const uint8_t *auth_key; + int auth_key_len = 0; + size_t ctx_len; + int ret; + + ctl = &out_sa->common_sa.ctl; + + if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) + auth_xform = crypto_xform; + else + auth_xform = crypto_xform->next; + + ret = on_fill_ipsec_common_sa(ipsec, crypto_xform, &out_sa->common_sa); + if (ret) + return ret; + + if (ctl->enc_type == ROC_IE_ON_SA_ENC_AES_GCM || + ctl->auth_type == ROC_IE_ON_SA_AUTH_NULL || + ctl->auth_type == ROC_IE_ON_SA_AUTH_AES_GMAC) { + template = &out_sa->aes_gcm.template; + ctx_len = offsetof(struct roc_ie_on_outb_sa, aes_gcm.template); + } else { + switch (ctl->auth_type) { + case ROC_IE_ON_SA_AUTH_SHA1: + template = &out_sa->sha1.template; + ctx_len = offsetof(struct roc_ie_on_outb_sa, + sha1.template); + break; + case ROC_IE_ON_SA_AUTH_SHA2_256: + case ROC_IE_ON_SA_AUTH_SHA2_384: + case ROC_IE_ON_SA_AUTH_SHA2_512: + template = &out_sa->sha2.template; + ctx_len = offsetof(struct roc_ie_on_outb_sa, + sha2.template); + break; + case ROC_IE_ON_SA_AUTH_AES_XCBC_128: + template = &out_sa->aes_xcbc.template; + ctx_len = offsetof(struct roc_ie_on_outb_sa, + aes_xcbc.template); + break; + default: + plt_err("Unsupported auth algorithm"); + return -EINVAL; + } + } + + ip4 = (struct rte_ipv4_hdr *)&template->ip4.ipv4_hdr; + if (ipsec->options.udp_encap) { + ip4->next_proto_id = IPPROTO_UDP; + template->ip4.udp_src = rte_be_to_cpu_16(4500); + template->ip4.udp_dst = rte_be_to_cpu_16(4500); + } else { + if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH) + ip4->next_proto_id = IPPROTO_AH; + else + ip4->next_proto_id = IPPROTO_ESP; + } + + if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) { + if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) { + uint16_t frag_off = 0; + + ctx_len += sizeof(template->ip4); + + ip4->version_ihl = RTE_IPV4_VHL_DEF; + ip4->time_to_live = ipsec->tunnel.ipv4.ttl; + ip4->type_of_service |= (ipsec->tunnel.ipv4.dscp << 2); + if (ipsec->tunnel.ipv4.df) + frag_off |= RTE_IPV4_HDR_DF_FLAG; + ip4->fragment_offset = rte_cpu_to_be_16(frag_off); + + memcpy(&ip4->src_addr, &ipsec->tunnel.ipv4.src_ip, + sizeof(struct in_addr)); + memcpy(&ip4->dst_addr, &ipsec->tunnel.ipv4.dst_ip, + sizeof(struct in_addr)); + } else if (ipsec->tunnel.type == + RTE_SECURITY_IPSEC_TUNNEL_IPV6) { + ctx_len += sizeof(template->ip6); + + ip6 = (struct rte_ipv6_hdr *)&template->ip6.ipv6_hdr; + if (ipsec->options.udp_encap) { + ip6->proto = IPPROTO_UDP; + template->ip6.udp_src = rte_be_to_cpu_16(4500); + template->ip6.udp_dst = rte_be_to_cpu_16(4500); + } else { + ip6->proto = (ipsec->proto == + RTE_SECURITY_IPSEC_SA_PROTO_ESP) ? + IPPROTO_ESP : + IPPROTO_AH; + } + ip6->vtc_flow = + rte_cpu_to_be_32(0x60000000 | + ((ipsec->tunnel.ipv6.dscp + << RTE_IPV6_HDR_TC_SHIFT) & + RTE_IPV6_HDR_TC_MASK) | + ((ipsec->tunnel.ipv6.flabel + << RTE_IPV6_HDR_FL_SHIFT) & + RTE_IPV6_HDR_FL_MASK)); + ip6->hop_limits = ipsec->tunnel.ipv6.hlimit; + memcpy(&ip6->src_addr, &ipsec->tunnel.ipv6.src_addr, + sizeof(struct in6_addr)); + memcpy(&ip6->dst_addr, &ipsec->tunnel.ipv6.dst_addr, + sizeof(struct in6_addr)); + } + } else + ctx_len += sizeof(template->ip4); + + ctx_len += RTE_ALIGN_CEIL(ctx_len, 8); + + if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AEAD) { + auth_key = auth_xform->auth.key.data; + auth_key_len = auth_xform->auth.key.length; + + switch (auth_xform->auth.algo) { + case RTE_CRYPTO_AUTH_AES_GMAC: + case RTE_CRYPTO_AUTH_NULL: + break; + case RTE_CRYPTO_AUTH_SHA1_HMAC: + memcpy(out_sa->sha1.hmac_key, auth_key, auth_key_len); + break; + case RTE_CRYPTO_AUTH_SHA256_HMAC: + case RTE_CRYPTO_AUTH_SHA384_HMAC: + case RTE_CRYPTO_AUTH_SHA512_HMAC: + memcpy(out_sa->sha2.hmac_key, auth_key, auth_key_len); + break; + case RTE_CRYPTO_AUTH_AES_XCBC_MAC: + memcpy(out_sa->aes_xcbc.key, auth_key, auth_key_len); + break; + default: + plt_err("Unsupported auth algorithm %u", + auth_xform->auth.algo); + return -ENOTSUP; + } + } + + return ctx_len; +} + +int +cnxk_on_ipsec_inb_sa_create(struct rte_security_ipsec_xform *ipsec, + struct rte_crypto_sym_xform *crypto_xform, + struct roc_ie_on_inb_sa *in_sa) +{ + struct rte_crypto_sym_xform *auth_xform = crypto_xform; + const uint8_t *auth_key; + int auth_key_len = 0; + size_t ctx_len = 0; + int ret; + + ret = on_fill_ipsec_common_sa(ipsec, crypto_xform, &in_sa->common_sa); + if (ret) + return ret; + + if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD || + auth_xform->auth.algo == RTE_CRYPTO_AUTH_NULL || + auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) { + ctx_len = offsetof(struct roc_ie_on_inb_sa, + sha1_or_gcm.hmac_key[0]); + } else { + auth_key = auth_xform->auth.key.data; + auth_key_len = auth_xform->auth.key.length; + + switch (auth_xform->auth.algo) { + case RTE_CRYPTO_AUTH_NULL: + break; + case RTE_CRYPTO_AUTH_SHA1_HMAC: + memcpy(in_sa->sha1_or_gcm.hmac_key, auth_key, + auth_key_len); + ctx_len = offsetof(struct roc_ie_on_inb_sa, + sha1_or_gcm.selector); + break; + case RTE_CRYPTO_AUTH_SHA256_HMAC: + case RTE_CRYPTO_AUTH_SHA384_HMAC: + case RTE_CRYPTO_AUTH_SHA512_HMAC: + memcpy(in_sa->sha2.hmac_key, auth_key, auth_key_len); + ctx_len = offsetof(struct roc_ie_on_inb_sa, + sha2.selector); + break; + case RTE_CRYPTO_AUTH_AES_XCBC_MAC: + memcpy(in_sa->aes_xcbc.key, auth_key, auth_key_len); + ctx_len = offsetof(struct roc_ie_on_inb_sa, + aes_xcbc.selector); + break; + default: + plt_err("Unsupported auth algorithm %u", + auth_xform->auth.algo); + return -ENOTSUP; + } + } + + return ctx_len; +} diff --git a/drivers/common/cnxk/cnxk_security.h b/drivers/common/cnxk/cnxk_security.h index 02cdad269c..4e477ec53f 100644 --- a/drivers/common/cnxk/cnxk_security.h +++ b/drivers/common/cnxk/cnxk_security.h @@ -59,4 +59,15 @@ cnxk_onf_ipsec_outb_sa_fill(struct roc_onf_ipsec_outb_sa *sa, bool __roc_api cnxk_onf_ipsec_inb_sa_valid(struct roc_onf_ipsec_inb_sa *sa); bool __roc_api cnxk_onf_ipsec_outb_sa_valid(struct roc_onf_ipsec_outb_sa *sa); +/* [CN9K] */ +int __roc_api +cnxk_on_ipsec_inb_sa_create(struct rte_security_ipsec_xform *ipsec, + struct rte_crypto_sym_xform *crypto_xform, + struct roc_ie_on_inb_sa *in_sa); + +int __roc_api +cnxk_on_ipsec_outb_sa_create(struct rte_security_ipsec_xform *ipsec, + struct rte_crypto_sym_xform *crypto_xform, + struct roc_ie_on_outb_sa *out_sa); + #endif /* _CNXK_SECURITY_H__ */ diff --git a/drivers/common/cnxk/roc_cpt.c b/drivers/common/cnxk/roc_cpt.c index 742723ad1d..e5b179e8e1 100644 --- a/drivers/common/cnxk/roc_cpt.c +++ b/drivers/common/cnxk/roc_cpt.c @@ -981,3 +981,96 @@ roc_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa_dptr, void *sa_cptr, return 0; } + +int +roc_on_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa, uint8_t opcode, + uint16_t ctx_len, uint8_t egrp) +{ + union cpt_res_s res, *hw_res; + struct cpt_inst_s inst; + uint64_t lmt_status; + int ret = 0; + + hw_res = plt_zmalloc(sizeof(*hw_res), ROC_CPT_RES_ALIGN); + if (unlikely(hw_res == NULL)) { + plt_err("Couldn't allocate memory for result address"); + return -ENOMEM; + } + + hw_res->cn9k.compcode = CPT_COMP_NOT_DONE; + + inst.w4.s.opcode_major = opcode; + inst.w4.s.opcode_minor = ctx_len >> 3; + inst.w4.s.param1 = 0; + inst.w4.s.param2 = 0; + inst.w4.s.dlen = ctx_len; + inst.dptr = rte_mempool_virt2iova(sa); + inst.rptr = 0; + inst.w7.s.cptr = rte_mempool_virt2iova(sa); + inst.w7.s.egrp = egrp; + + inst.w0.u64 = 0; + inst.w2.u64 = 0; + inst.w3.u64 = 0; + inst.res_addr = (uintptr_t)hw_res; + + rte_io_wmb(); + + do { + /* Copy CPT command to LMTLINE */ + roc_lmt_mov64((void *)lf->lmt_base, &inst); + lmt_status = roc_lmt_submit_ldeor(lf->io_addr); + } while (lmt_status == 0); + + const uint64_t timeout = plt_tsc_cycles() + 60 * plt_tsc_hz(); + + /* Wait until CPT instruction completes */ + do { + res.u64[0] = __atomic_load_n(&hw_res->u64[0], __ATOMIC_RELAXED); + if (unlikely(plt_tsc_cycles() > timeout)) { + plt_err("Request timed out"); + ret = -ETIMEDOUT; + goto free; + } + } while (res.cn9k.compcode == CPT_COMP_NOT_DONE); + + if (unlikely(res.cn9k.compcode != CPT_COMP_GOOD)) { + ret = res.cn9k.compcode; + switch (ret) { + case CPT_COMP_INSTERR: + plt_err("Request failed with instruction error"); + break; + case CPT_COMP_FAULT: + plt_err("Request failed with DMA fault"); + break; + case CPT_COMP_HWERR: + plt_err("Request failed with hardware error"); + break; + default: + plt_err("Request failed with unknown hardware completion code : 0x%x", + ret); + } + ret = -EINVAL; + goto free; + } + + if (unlikely(res.cn9k.uc_compcode != ROC_IE_ON_UCC_SUCCESS)) { + ret = res.cn9k.uc_compcode; + switch (ret) { + case ROC_IE_ON_AUTH_UNSUPPORTED: + plt_err("Invalid auth type"); + break; + case ROC_IE_ON_ENCRYPT_UNSUPPORTED: + plt_err("Invalid encrypt type"); + break; + default: + plt_err("Request failed with unknown microcode completion code : 0x%x", + ret); + } + ret = -ENOTSUP; + } + +free: + plt_free(hw_res); + return ret; +} diff --git a/drivers/common/cnxk/roc_cpt.h b/drivers/common/cnxk/roc_cpt.h index 99cb8b2862..1b2032b547 100644 --- a/drivers/common/cnxk/roc_cpt.h +++ b/drivers/common/cnxk/roc_cpt.h @@ -181,4 +181,7 @@ void __roc_api roc_cpt_parse_hdr_dump(const struct cpt_parse_hdr_s *cpth); int __roc_api roc_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa_dptr, void *sa_cptr, uint16_t sa_len); +int __roc_api roc_on_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa, + uint8_t opcode, uint16_t ctx_len, + uint8_t egrp); #endif /* _ROC_CPT_H_ */ diff --git a/drivers/common/cnxk/roc_ie_on.h b/drivers/common/cnxk/roc_ie_on.h index 7dd7b6595f..37f711c643 100644 --- a/drivers/common/cnxk/roc_ie_on.h +++ b/drivers/common/cnxk/roc_ie_on.h @@ -23,7 +23,7 @@ enum roc_ie_on_ucc_ipsec { }; /* Helper macros */ -#define ROC_IE_ON_INB_RPTR_HDR 0x8 +#define ROC_IE_ON_INB_RPTR_HDR 16 #define ROC_IE_ON_MAX_IV_LEN 16 #define ROC_IE_ON_PER_PKT_IV BIT(43) @@ -67,9 +67,17 @@ enum { struct roc_ie_on_outb_hdr { uint32_t ip_id; uint32_t seq; + uint32_t esn; + uint32_t df_tos; uint8_t iv[16]; }; +struct roc_ie_on_inb_hdr { + uint32_t sa_index; + uint64_t seq; + uint32_t pad; +}; + union roc_ie_on_bit_perfect_iv { uint8_t aes_iv[16]; uint8_t des_iv[8]; @@ -113,7 +121,7 @@ struct roc_ie_on_ip_template { union roc_on_ipsec_outb_param1 { uint16_t u16; struct { - uint16_t frag_num : 4; + uint16_t l2hdr_len : 4; uint16_t rsvd_4_6 : 3; uint16_t gre_select : 1; uint16_t dsiv : 1; @@ -171,8 +179,13 @@ struct roc_ie_on_common_sa { union roc_ie_on_bit_perfect_iv iv; /* w7 */ - uint32_t esn_hi; - uint32_t esn_low; + union { + uint64_t u64; + struct { + uint32_t th; + uint32_t tl; + }; + } seq_t; }; struct roc_ie_on_outb_sa { diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map index a77f3f6e3c..db61fe575d 100644 --- a/drivers/common/cnxk/version.map +++ b/drivers/common/cnxk/version.map @@ -23,6 +23,8 @@ INTERNAL { cnxk_ot_ipsec_outb_sa_fill; cnxk_ot_ipsec_inb_sa_valid; cnxk_ot_ipsec_outb_sa_valid; + cnxk_on_ipsec_inb_sa_create; + cnxk_on_ipsec_outb_sa_create; roc_ae_ec_grp_get; roc_ae_ec_grp_put; roc_ae_fpm_get; @@ -72,6 +74,7 @@ INTERNAL { roc_cpt_parse_hdr_dump; roc_cpt_rxc_time_cfg; roc_cpt_ctx_write; + roc_on_cpt_ctx_write; roc_dpi_configure; roc_dpi_dev_fini; roc_dpi_dev_init; diff --git a/drivers/crypto/cnxk/cn9k_cryptodev_ops.c b/drivers/crypto/cnxk/cn9k_cryptodev_ops.c index eccaf398df..7720730120 100644 --- a/drivers/crypto/cnxk/cn9k_cryptodev_ops.c +++ b/drivers/crypto/cnxk/cn9k_cryptodev_ops.c @@ -43,7 +43,9 @@ cn9k_cpt_sec_inst_fill(struct rte_crypto_op *op, struct cpt_inst_s *inst) { struct rte_crypto_sym_op *sym_op = op->sym; + struct roc_ie_on_common_sa *common_sa; struct cn9k_sec_session *priv; + struct roc_ie_on_sa_ctl *ctl; struct cn9k_ipsec_sa *sa; if (unlikely(sym_op->m_dst && sym_op->m_dst != sym_op->m_src)) { @@ -64,6 +66,12 @@ cn9k_cpt_sec_inst_fill(struct rte_crypto_op *op, infl_req->op_flags |= CPT_OP_FLAGS_IPSEC_DIR_INBOUND; + common_sa = &sa->in_sa.common_sa; + ctl = &common_sa->ctl; + + if (ctl->esn_en) + infl_req->op_flags |= CPT_OP_FLAGS_IPSEC_INB_ESN; + return process_inb_sa(op, sa, inst); } @@ -491,14 +499,28 @@ cn9k_cpt_sec_post_process(struct rte_crypto_op *cop, { struct rte_crypto_sym_op *sym_op = cop->sym; struct rte_mbuf *m = sym_op->m_src; + struct cn9k_sec_session *priv; + struct cn9k_ipsec_sa *sa; struct rte_ipv6_hdr *ip6; struct rte_ipv4_hdr *ip; uint16_t m_len = 0; char *data; + priv = get_sec_session_private_data(cop->sym->sec_session); + sa = &priv->sa; + if (infl_req->op_flags & CPT_OP_FLAGS_IPSEC_DIR_INBOUND) { + struct roc_ie_on_common_sa *common_sa = &sa->in_sa.common_sa; + data = rte_pktmbuf_mtod(m, char *); + if (infl_req->op_flags == CPT_OP_FLAGS_IPSEC_INB_ESN) { + struct roc_ie_on_inb_hdr *inb_hdr = + (struct roc_ie_on_inb_hdr *)data; + uint64_t seq = rte_be_to_cpu_64(inb_hdr->seq); + if (seq > common_sa->seq_t.u64) + common_sa->seq_t.u64 = seq; + } ip = (struct rte_ipv4_hdr *)(data + ROC_IE_ON_INB_RPTR_HDR); if (((ip->version_ihl & 0xf0) >> RTE_IPV4_IHL_MULTIPLIER) == @@ -515,6 +537,8 @@ cn9k_cpt_sec_post_process(struct rte_crypto_op *cop, m->data_len = m_len; m->pkt_len = m_len; m->data_off += ROC_IE_ON_INB_RPTR_HDR; + } else { + rte_pktmbuf_adj(m, sa->custom_hdr_len); } } diff --git a/drivers/crypto/cnxk/cn9k_ipsec.c b/drivers/crypto/cnxk/cn9k_ipsec.c index 82b8dae786..85f3f26c32 100644 --- a/drivers/crypto/cnxk/cn9k_ipsec.c +++ b/drivers/crypto/cnxk/cn9k_ipsec.c @@ -15,331 +15,26 @@ #include "roc_api.h" -static inline int -cn9k_cpt_enq_sa_write(struct cn9k_ipsec_sa *sa, struct cnxk_cpt_qp *qp, - uint8_t opcode, size_t ctx_len) -{ - struct roc_cpt *roc_cpt = qp->lf.roc_cpt; - uint64_t lmtline = qp->lmtline.lmt_base; - uint64_t io_addr = qp->lmtline.io_addr; - uint64_t lmt_status, time_out; - struct cpt_cn9k_res_s *res; - struct cpt_inst_s inst; - uint64_t *mdata; - int ret = 0; - - if (unlikely(rte_mempool_get(qp->meta_info.pool, (void **)&mdata) < 0)) - return -ENOMEM; - - res = (struct cpt_cn9k_res_s *)RTE_PTR_ALIGN(mdata, 16); - res->compcode = CPT_COMP_NOT_DONE; - - inst.w4.s.opcode_major = opcode; - inst.w4.s.opcode_minor = ctx_len >> 3; - inst.w4.s.param1 = 0; - inst.w4.s.param2 = 0; - inst.w4.s.dlen = ctx_len; - inst.dptr = rte_mempool_virt2iova(sa); - inst.rptr = 0; - inst.w7.s.cptr = rte_mempool_virt2iova(sa); - inst.w7.s.egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_IE]; - - inst.w0.u64 = 0; - inst.w2.u64 = 0; - inst.w3.u64 = 0; - inst.res_addr = rte_mempool_virt2iova(res); - - rte_io_wmb(); - - do { - /* Copy CPT command to LMTLINE */ - roc_lmt_mov64((void *)lmtline, &inst); - lmt_status = roc_lmt_submit_ldeor(io_addr); - } while (lmt_status == 0); - - time_out = rte_get_timer_cycles() + - DEFAULT_COMMAND_TIMEOUT * rte_get_timer_hz(); - - while (res->compcode == CPT_COMP_NOT_DONE) { - if (rte_get_timer_cycles() > time_out) { - rte_mempool_put(qp->meta_info.pool, mdata); - plt_err("Request timed out"); - return -ETIMEDOUT; - } - rte_io_rmb(); - } - - if (unlikely(res->compcode != CPT_COMP_GOOD)) { - ret = res->compcode; - switch (ret) { - case CPT_COMP_INSTERR: - plt_err("Request failed with instruction error"); - break; - case CPT_COMP_FAULT: - plt_err("Request failed with DMA fault"); - break; - case CPT_COMP_HWERR: - plt_err("Request failed with hardware error"); - break; - default: - plt_err("Request failed with unknown hardware " - "completion code : 0x%x", - ret); - } - ret = -EINVAL; - goto mempool_put; - } - - if (unlikely(res->uc_compcode != ROC_IE_ON_UCC_SUCCESS)) { - ret = res->uc_compcode; - switch (ret) { - case ROC_IE_ON_AUTH_UNSUPPORTED: - plt_err("Invalid auth type"); - break; - case ROC_IE_ON_ENCRYPT_UNSUPPORTED: - plt_err("Invalid encrypt type"); - break; - default: - plt_err("Request failed with unknown microcode " - "completion code : 0x%x", - ret); - } - ret = -ENOTSUP; - } - -mempool_put: - rte_mempool_put(qp->meta_info.pool, mdata); - return ret; -} - -static inline int -ipsec_sa_ctl_set(struct rte_security_ipsec_xform *ipsec, - struct rte_crypto_sym_xform *crypto_xform, - struct roc_ie_on_sa_ctl *ctl) -{ - struct rte_crypto_sym_xform *cipher_xform, *auth_xform; - int aes_key_len = 0; - - if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) { - auth_xform = crypto_xform; - cipher_xform = crypto_xform->next; - } else { - cipher_xform = crypto_xform; - auth_xform = crypto_xform->next; - } - - if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) - ctl->direction = ROC_IE_SA_DIR_OUTBOUND; - else - ctl->direction = ROC_IE_SA_DIR_INBOUND; - - if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) { - if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) - ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_4; - else if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV6) - ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_6; - else - return -EINVAL; - } - - if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) { - ctl->ipsec_mode = ROC_IE_SA_MODE_TRANSPORT; - ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_4; - } else if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) - ctl->ipsec_mode = ROC_IE_SA_MODE_TUNNEL; - else - return -EINVAL; - - if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH) - ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_AH; - else if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP) - ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_ESP; - else - return -EINVAL; - - if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) { - switch (crypto_xform->aead.algo) { - case RTE_CRYPTO_AEAD_AES_GCM: - ctl->enc_type = ROC_IE_ON_SA_ENC_AES_GCM; - aes_key_len = crypto_xform->aead.key.length; - break; - default: - plt_err("Unsupported AEAD algorithm"); - return -ENOTSUP; - } - } else { - if (cipher_xform != NULL) { - switch (cipher_xform->cipher.algo) { - case RTE_CRYPTO_CIPHER_NULL: - ctl->enc_type = ROC_IE_ON_SA_ENC_NULL; - break; - case RTE_CRYPTO_CIPHER_AES_CBC: - ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CBC; - aes_key_len = cipher_xform->cipher.key.length; - break; - case RTE_CRYPTO_CIPHER_AES_CTR: - ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CTR; - aes_key_len = cipher_xform->cipher.key.length; - break; - default: - plt_err("Unsupported cipher algorithm"); - return -ENOTSUP; - } - } - - switch (auth_xform->auth.algo) { - case RTE_CRYPTO_AUTH_NULL: - ctl->auth_type = ROC_IE_ON_SA_AUTH_NULL; - break; - case RTE_CRYPTO_AUTH_MD5_HMAC: - ctl->auth_type = ROC_IE_ON_SA_AUTH_MD5; - break; - case RTE_CRYPTO_AUTH_SHA1_HMAC: - ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA1; - break; - case RTE_CRYPTO_AUTH_SHA224_HMAC: - ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_224; - break; - case RTE_CRYPTO_AUTH_SHA256_HMAC: - ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_256; - break; - case RTE_CRYPTO_AUTH_SHA384_HMAC: - ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_384; - break; - case RTE_CRYPTO_AUTH_SHA512_HMAC: - ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_512; - break; - case RTE_CRYPTO_AUTH_AES_GMAC: - ctl->auth_type = ROC_IE_ON_SA_AUTH_AES_GMAC; - aes_key_len = auth_xform->auth.key.length; - break; - case RTE_CRYPTO_AUTH_AES_XCBC_MAC: - ctl->auth_type = ROC_IE_ON_SA_AUTH_AES_XCBC_128; - break; - default: - plt_err("Unsupported auth algorithm"); - return -ENOTSUP; - } - } - - /* Set AES key length */ - if (ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CBC || - ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CCM || - ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CTR || - ctl->enc_type == ROC_IE_ON_SA_ENC_AES_GCM || - ctl->auth_type == ROC_IE_ON_SA_AUTH_AES_GMAC) { - switch (aes_key_len) { - case 16: - ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_128; - break; - case 24: - ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_192; - break; - case 32: - ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_256; - break; - default: - plt_err("Invalid AES key length"); - return -EINVAL; - } - } - - if (ipsec->options.esn) - ctl->esn_en = 1; - - if (ipsec->options.udp_encap == 1) - ctl->encap_type = ROC_IE_ON_SA_ENCAP_UDP; - - ctl->copy_df = ipsec->options.copy_df; - - ctl->spi = rte_cpu_to_be_32(ipsec->spi); - - rte_io_wmb(); - - ctl->valid = 1; - - return 0; -} - -static inline int -fill_ipsec_common_sa(struct rte_security_ipsec_xform *ipsec, - struct rte_crypto_sym_xform *crypto_xform, - struct roc_ie_on_common_sa *common_sa) -{ - struct rte_crypto_sym_xform *cipher_xform, *auth_xform; - const uint8_t *cipher_key; - int cipher_key_len = 0; - int ret; - - ret = ipsec_sa_ctl_set(ipsec, crypto_xform, &common_sa->ctl); - if (ret) - return ret; - - if (ipsec->esn.value) { - common_sa->esn_low = ipsec->esn.low; - common_sa->esn_hi = ipsec->esn.hi; - } - - if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) { - auth_xform = crypto_xform; - cipher_xform = crypto_xform->next; - } else { - cipher_xform = crypto_xform; - auth_xform = crypto_xform->next; - } - - if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) { - if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) - memcpy(common_sa->iv.gcm.nonce, &ipsec->salt, 4); - cipher_key = crypto_xform->aead.key.data; - cipher_key_len = crypto_xform->aead.key.length; - } else { - if (cipher_xform) { - cipher_key = cipher_xform->cipher.key.data; - cipher_key_len = cipher_xform->cipher.key.length; - } - - if (auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) { - memcpy(common_sa->iv.gcm.nonce, &ipsec->salt, 4); - cipher_key = auth_xform->auth.key.data; - cipher_key_len = auth_xform->auth.key.length; - } - } - - if (cipher_key_len != 0) - memcpy(common_sa->cipher_key, cipher_key, cipher_key_len); - - return 0; -} - static int cn9k_ipsec_outb_sa_create(struct cnxk_cpt_qp *qp, struct rte_security_ipsec_xform *ipsec, struct rte_crypto_sym_xform *crypto_xform, struct rte_security_session *sec_sess) { - struct roc_ie_on_ip_template *template = NULL; struct roc_cpt *roc_cpt = qp->lf.roc_cpt; - struct rte_crypto_sym_xform *auth_xform; union roc_on_ipsec_outb_param1 param1; struct cnxk_cpt_inst_tmpl *inst_tmpl; - struct roc_ie_on_outb_sa *out_sa; struct cn9k_sec_session *sess; - struct roc_ie_on_sa_ctl *ctl; struct cn9k_ipsec_sa *sa; - struct rte_ipv6_hdr *ip6; - struct rte_ipv4_hdr *ip4; - const uint8_t *auth_key; union cpt_inst_w4 w4; union cpt_inst_w7 w7; - int auth_key_len = 0; size_t ctx_len; + uint8_t opcode; + uint8_t egrp; int ret; sess = get_sec_session_private_data(sec_sess); sa = &sess->sa; - out_sa = &sa->out_sa; - ctl = &out_sa->common_sa.ctl; memset(sa, 0, sizeof(struct cn9k_ipsec_sa)); @@ -353,153 +48,16 @@ cn9k_ipsec_outb_sa_create(struct cnxk_cpt_qp *qp, if (ipsec->esn.value) sa->esn = ipsec->esn.value; - if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) - auth_xform = crypto_xform; - else - auth_xform = crypto_xform->next; - - ret = fill_ipsec_common_sa(ipsec, crypto_xform, &out_sa->common_sa); - if (ret) - return ret; - ret = cnxk_ipsec_outb_rlens_get(&sa->rlens, ipsec, crypto_xform); if (ret) return ret; - if (ctl->enc_type == ROC_IE_ON_SA_ENC_AES_GCM || - ctl->auth_type == ROC_IE_ON_SA_AUTH_NULL || - ctl->auth_type == ROC_IE_ON_SA_AUTH_AES_GMAC) { - template = &out_sa->aes_gcm.template; - ctx_len = offsetof(struct roc_ie_on_outb_sa, aes_gcm.template); - } else { - switch (ctl->auth_type) { - case ROC_IE_ON_SA_AUTH_SHA1: - template = &out_sa->sha1.template; - ctx_len = offsetof(struct roc_ie_on_outb_sa, - sha1.template); - break; - case ROC_IE_ON_SA_AUTH_SHA2_256: - case ROC_IE_ON_SA_AUTH_SHA2_384: - case ROC_IE_ON_SA_AUTH_SHA2_512: - template = &out_sa->sha2.template; - ctx_len = offsetof(struct roc_ie_on_outb_sa, - sha2.template); - break; - case ROC_IE_ON_SA_AUTH_AES_XCBC_128: - template = &out_sa->aes_xcbc.template; - ctx_len = offsetof(struct roc_ie_on_outb_sa, - aes_xcbc.template); - break; - default: - plt_err("Unsupported auth algorithm"); - return -EINVAL; - } - } - - ip4 = (struct rte_ipv4_hdr *)&template->ip4.ipv4_hdr; - if (ipsec->options.udp_encap) { - ip4->next_proto_id = IPPROTO_UDP; - template->ip4.udp_src = rte_be_to_cpu_16(4500); - template->ip4.udp_dst = rte_be_to_cpu_16(4500); - } else { - if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH) - ip4->next_proto_id = IPPROTO_AH; - else - ip4->next_proto_id = IPPROTO_ESP; - } - - if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) { - if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) { - uint16_t frag_off = 0; - ctx_len += sizeof(template->ip4); - - ip4->version_ihl = RTE_IPV4_VHL_DEF; - ip4->time_to_live = ipsec->tunnel.ipv4.ttl; - ip4->type_of_service |= (ipsec->tunnel.ipv4.dscp << 2); - if (ipsec->tunnel.ipv4.df) - frag_off |= RTE_IPV4_HDR_DF_FLAG; - ip4->fragment_offset = rte_cpu_to_be_16(frag_off); - - memcpy(&ip4->src_addr, &ipsec->tunnel.ipv4.src_ip, - sizeof(struct in_addr)); - memcpy(&ip4->dst_addr, &ipsec->tunnel.ipv4.dst_ip, - sizeof(struct in_addr)); - } else if (ipsec->tunnel.type == - RTE_SECURITY_IPSEC_TUNNEL_IPV6) { - ctx_len += sizeof(template->ip6); - - ip6 = (struct rte_ipv6_hdr *)&template->ip6.ipv6_hdr; - if (ipsec->options.udp_encap) { - ip6->proto = IPPROTO_UDP; - template->ip6.udp_src = rte_be_to_cpu_16(4500); - template->ip6.udp_dst = rte_be_to_cpu_16(4500); - } else { - ip6->proto = (ipsec->proto == - RTE_SECURITY_IPSEC_SA_PROTO_ESP) ? - IPPROTO_ESP : - IPPROTO_AH; - } - ip6->vtc_flow = - rte_cpu_to_be_32(0x60000000 | - ((ipsec->tunnel.ipv6.dscp - << RTE_IPV6_HDR_TC_SHIFT) & - RTE_IPV6_HDR_TC_MASK) | - ((ipsec->tunnel.ipv6.flabel - << RTE_IPV6_HDR_FL_SHIFT) & - RTE_IPV6_HDR_FL_MASK)); - ip6->hop_limits = ipsec->tunnel.ipv6.hlimit; - memcpy(&ip6->src_addr, &ipsec->tunnel.ipv6.src_addr, - sizeof(struct in6_addr)); - memcpy(&ip6->dst_addr, &ipsec->tunnel.ipv6.dst_addr, - sizeof(struct in6_addr)); - } - } else - ctx_len += sizeof(template->ip4); - - ctx_len += RTE_ALIGN_CEIL(ctx_len, 8); - - if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AEAD) { - auth_key = auth_xform->auth.key.data; - auth_key_len = auth_xform->auth.key.length; - - switch (auth_xform->auth.algo) { - case RTE_CRYPTO_AUTH_AES_GMAC: - case RTE_CRYPTO_AUTH_NULL: - break; - case RTE_CRYPTO_AUTH_SHA1_HMAC: - memcpy(out_sa->sha1.hmac_key, auth_key, auth_key_len); - break; - case RTE_CRYPTO_AUTH_SHA256_HMAC: - case RTE_CRYPTO_AUTH_SHA384_HMAC: - case RTE_CRYPTO_AUTH_SHA512_HMAC: - memcpy(out_sa->sha2.hmac_key, auth_key, auth_key_len); - break; - case RTE_CRYPTO_AUTH_AES_XCBC_MAC: - memcpy(out_sa->aes_xcbc.key, auth_key, auth_key_len); - break; - default: - plt_err("Unsupported auth algorithm %u", - auth_xform->auth.algo); - return -ENOTSUP; - } - } - - inst_tmpl = &sa->inst; - - w4.u64 = 0; - w4.s.opcode_major = ROC_IE_ON_MAJOR_OP_PROCESS_OUTBOUND_IPSEC; - w4.s.opcode_minor = ctx_len >> 3; - - param1.u16 = 0; - param1.s.ikev2 = 1; - - sa->custom_hdr_len = sizeof(struct roc_ie_on_outb_hdr) - - ROC_IE_ON_MAX_IV_LEN; + sa->custom_hdr_len = + sizeof(struct roc_ie_on_outb_hdr) - ROC_IE_ON_MAX_IV_LEN; #ifdef LA_IPSEC_DEBUG /* Use IV from application in debug mode */ if (ipsec->options.iv_gen_disable == 1) { - param1.s.per_pkt_iv = ROC_IE_ON_IV_SRC_FROM_DPTR; sa->custom_hdr_len = sizeof(struct roc_ie_on_outb_hdr); if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) { @@ -520,17 +78,49 @@ cn9k_ipsec_outb_sa_create(struct cnxk_cpt_qp *qp, } #endif - w4.s.param1 = param1.u16; + ret = cnxk_on_ipsec_outb_sa_create(ipsec, crypto_xform, &sa->out_sa); - inst_tmpl->w4 = w4.u64; + if (ret < 0) + return ret; + + ctx_len = ret; + opcode = ROC_IE_ON_MAJOR_OP_WRITE_IPSEC_OUTBOUND; + egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_IE]; + ret = roc_on_cpt_ctx_write(&qp->lf, (void *)&sa->out_sa, opcode, + ctx_len, egrp); + + if (ret) + return ret; + + w4.u64 = 0; + w4.s.opcode_major = ROC_IE_ON_MAJOR_OP_PROCESS_OUTBOUND_IPSEC; + w4.s.opcode_minor = ctx_len >> 3; + + param1.u16 = 0; + param1.s.ikev2 = 1; + +#ifdef LA_IPSEC_DEBUG + /* Use IV from application in debug mode */ + if (ipsec->options.iv_gen_disable == 1) + param1.s.per_pkt_iv = ROC_IE_ON_IV_SRC_FROM_DPTR; +#else + if (ipsec->options.iv_gen_disable != 0) { + plt_err("Application provided IV is not supported"); + return -ENOTSUP; + } +#endif + + w4.s.param1 = param1.u16; w7.u64 = 0; - w7.s.egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_IE]; - w7.s.cptr = rte_mempool_virt2iova(out_sa); + w7.s.egrp = egrp; + w7.s.cptr = rte_mempool_virt2iova(&sa->out_sa); + + inst_tmpl = &sa->inst; + inst_tmpl->w4 = w4.u64; inst_tmpl->w7 = w7.u64; - return cn9k_cpt_enq_sa_write( - sa, qp, ROC_IE_ON_MAJOR_OP_WRITE_IPSEC_OUTBOUND, ctx_len); + return 0; } static int @@ -539,71 +129,54 @@ cn9k_ipsec_inb_sa_create(struct cnxk_cpt_qp *qp, struct rte_crypto_sym_xform *crypto_xform, struct rte_security_session *sec_sess) { - struct rte_crypto_sym_xform *auth_xform = crypto_xform; struct roc_cpt *roc_cpt = qp->lf.roc_cpt; - union roc_on_ipsec_inb_param2 param2; struct cnxk_cpt_inst_tmpl *inst_tmpl; - struct roc_ie_on_inb_sa *in_sa; + union roc_on_ipsec_inb_param2 param2; struct cn9k_sec_session *sess; struct cn9k_ipsec_sa *sa; - const uint8_t *auth_key; union cpt_inst_w4 w4; union cpt_inst_w7 w7; - int auth_key_len = 0; size_t ctx_len = 0; - int ret; + uint8_t opcode; + uint8_t egrp; + int ret = 0; sess = get_sec_session_private_data(sec_sess); sa = &sess->sa; - in_sa = &sa->in_sa; memset(sa, 0, sizeof(struct cn9k_ipsec_sa)); sa->dir = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; sa->replay_win_sz = ipsec->replay_win_sz; - ret = fill_ipsec_common_sa(ipsec, crypto_xform, &in_sa->common_sa); - if (ret) - return ret; - - if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD || - auth_xform->auth.algo == RTE_CRYPTO_AUTH_NULL || - auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) { - ctx_len = offsetof(struct roc_ie_on_inb_sa, - sha1_or_gcm.hmac_key[0]); - } else { - auth_key = auth_xform->auth.key.data; - auth_key_len = auth_xform->auth.key.length; - - switch (auth_xform->auth.algo) { - case RTE_CRYPTO_AUTH_NULL: - break; - case RTE_CRYPTO_AUTH_SHA1_HMAC: - memcpy(in_sa->sha1_or_gcm.hmac_key, auth_key, - auth_key_len); - ctx_len = offsetof(struct roc_ie_on_inb_sa, - sha1_or_gcm.selector); - break; - case RTE_CRYPTO_AUTH_SHA256_HMAC: - case RTE_CRYPTO_AUTH_SHA384_HMAC: - case RTE_CRYPTO_AUTH_SHA512_HMAC: - memcpy(in_sa->sha2.hmac_key, auth_key, auth_key_len); - ctx_len = offsetof(struct roc_ie_on_inb_sa, - sha2.selector); - break; - case RTE_CRYPTO_AUTH_AES_XCBC_MAC: - memcpy(in_sa->aes_xcbc.key, auth_key, auth_key_len); - ctx_len = offsetof(struct roc_ie_on_inb_sa, - aes_xcbc.selector); - break; - default: - plt_err("Unsupported auth algorithm %u", - auth_xform->auth.algo); + if (sa->replay_win_sz) { + if (sa->replay_win_sz > CNXK_ON_AR_WIN_SIZE_MAX) { + plt_err("Replay window size:%u is not supported", + sa->replay_win_sz); return -ENOTSUP; } + + /* Set window bottom to 1, base and top to size of window */ + sa->ar.winb = 1; + sa->ar.wint = sa->replay_win_sz; + sa->ar.base = sa->replay_win_sz; + + sa->in_sa.common_sa.seq_t.tl = sa->seq_lo; + sa->in_sa.common_sa.seq_t.th = sa->seq_hi; } - inst_tmpl = &sa->inst; + ret = cnxk_on_ipsec_inb_sa_create(ipsec, crypto_xform, &sa->in_sa); + + if (ret < 0) + return ret; + + ctx_len = ret; + opcode = ROC_IE_ON_MAJOR_OP_WRITE_IPSEC_INBOUND; + egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_IE]; + ret = roc_on_cpt_ctx_write(&qp->lf, (void *)&sa->in_sa, opcode, ctx_len, + egrp); + if (ret) + return ret; w4.u64 = 0; w4.s.opcode_major = ROC_IE_ON_MAJOR_OP_PROCESS_INBOUND_IPSEC; @@ -613,31 +186,14 @@ cn9k_ipsec_inb_sa_create(struct cnxk_cpt_qp *qp, param2.s.ikev2 = 1; w4.s.param2 = param2.u16; - inst_tmpl->w4 = w4.u64; + w7.s.egrp = egrp; + w7.s.cptr = rte_mempool_virt2iova(&sa->in_sa); - w7.u64 = 0; - w7.s.egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_IE]; - w7.s.cptr = rte_mempool_virt2iova(in_sa); + inst_tmpl = &sa->inst; + inst_tmpl->w4 = w4.u64; inst_tmpl->w7 = w7.u64; - if (sa->replay_win_sz) { - if (sa->replay_win_sz > CNXK_ON_AR_WIN_SIZE_MAX) { - plt_err("Replay window size:%u is not supported", - sa->replay_win_sz); - return -ENOTSUP; - } - - /* Set window bottom to 1, base and top to size of window */ - sa->ar.winb = 1; - sa->ar.wint = sa->replay_win_sz; - sa->ar.base = sa->replay_win_sz; - - in_sa->common_sa.esn_low = sa->seq_lo; - in_sa->common_sa.esn_hi = sa->seq_hi; - } - - return cn9k_cpt_enq_sa_write( - sa, qp, ROC_IE_ON_MAJOR_OP_WRITE_IPSEC_INBOUND, ctx_len); + return 0; } static inline int diff --git a/drivers/crypto/cnxk/cn9k_ipsec_la_ops.h b/drivers/crypto/cnxk/cn9k_ipsec_la_ops.h index df89aaca4e..bbb4404a89 100644 --- a/drivers/crypto/cnxk/cn9k_ipsec_la_ops.h +++ b/drivers/crypto/cnxk/cn9k_ipsec_la_ops.h @@ -20,7 +20,7 @@ ipsec_po_out_rlen_get(struct cn9k_ipsec_sa *sa, uint32_t plen) enc_payload_len = RTE_ALIGN_CEIL(plen + sa->rlens.roundup_len, sa->rlens.roundup_byte); - return sa->rlens.partial_len + enc_payload_len; + return sa->custom_hdr_len + sa->rlens.partial_len + enc_payload_len; } static __rte_always_inline int @@ -41,8 +41,8 @@ ipsec_antireplay_check(struct cn9k_ipsec_sa *sa, uint32_t win_sz, ctl = &common_sa->ctl; esn = ctl->esn_en; - esn_low = rte_be_to_cpu_32(common_sa->esn_low); - esn_hi = rte_be_to_cpu_32(common_sa->esn_hi); + esn_low = rte_be_to_cpu_32(common_sa->seq_t.tl); + esn_hi = rte_be_to_cpu_32(common_sa->seq_t.th); esp = rte_pktmbuf_mtod_offset(m, void *, sizeof(struct rte_ipv4_hdr)); seql = rte_be_to_cpu_32(esp->seq); @@ -62,8 +62,8 @@ ipsec_antireplay_check(struct cn9k_ipsec_sa *sa, uint32_t win_sz, if (esn && !ret) { seq_in_sa = ((uint64_t)esn_hi << 32) | esn_low; if (seq > seq_in_sa) { - common_sa->esn_low = rte_cpu_to_be_32(seql); - common_sa->esn_hi = rte_cpu_to_be_32(seqh); + common_sa->seq_t.tl = rte_cpu_to_be_32(seql); + common_sa->seq_t.th = rte_cpu_to_be_32(seqh); } } @@ -77,13 +77,10 @@ process_outb_sa(struct rte_crypto_op *cop, struct cn9k_ipsec_sa *sa, const unsigned int hdr_len = sa->custom_hdr_len; struct rte_crypto_sym_op *sym_op = cop->sym; struct rte_mbuf *m_src = sym_op->m_src; - struct roc_ie_on_outb_sa *out_sa; struct roc_ie_on_outb_hdr *hdr; uint32_t dlen, rlen; int32_t extend_tail; - out_sa = &sa->out_sa; - dlen = rte_pktmbuf_pkt_len(m_src) + hdr_len; rlen = ipsec_po_out_rlen_get(sa, dlen - hdr_len); @@ -114,8 +111,7 @@ process_outb_sa(struct rte_crypto_op *cop, struct cn9k_ipsec_sa *sa, hdr->seq = rte_cpu_to_be_32(sa->seq_lo); hdr->ip_id = rte_cpu_to_be_32(sa->ip_id); - - out_sa->common_sa.esn_hi = sa->seq_hi; + hdr->esn = rte_cpu_to_be_32(sa->seq_hi); sa->ip_id++; sa->esn++; diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.h b/drivers/crypto/cnxk/cnxk_cryptodev_ops.h index 7ece0214dc..ec99e6d660 100644 --- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.h +++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.h @@ -33,6 +33,7 @@ struct cpt_qp_meta_info { #define CPT_OP_FLAGS_METABUF (1 << 1) #define CPT_OP_FLAGS_AUTH_VERIFY (1 << 0) #define CPT_OP_FLAGS_IPSEC_DIR_INBOUND (1 << 2) +#define CPT_OP_FLAGS_IPSEC_INB_ESN (1 << 3) struct cpt_inflight_req { union cpt_res_s res;