178d03027SSrujana Challa /* SPDX-License-Identifier: BSD-3-Clause 278d03027SSrujana Challa * Copyright(C) 2021 Marvell. 378d03027SSrujana Challa */ 478d03027SSrujana Challa 55c770471SSrujana Challa #include <rte_udp.h> 65c770471SSrujana Challa 778d03027SSrujana Challa #include "cnxk_security.h" 878d03027SSrujana Challa 980d56d2dSArchana Muniganti #include "roc_api.h" 1080d56d2dSArchana Muniganti 1178d03027SSrujana Challa static int 12df22fe29SVidya Sagar Velumuri ot_ipsec_sa_common_param_fill(union roc_ot_ipsec_sa_word2 *w2, uint8_t *cipher_key, 13df22fe29SVidya Sagar Velumuri uint8_t *salt_key, uint8_t *hmac_opad_ipad, 1478d03027SSrujana Challa struct rte_security_ipsec_xform *ipsec_xfrm, 1578d03027SSrujana Challa struct rte_crypto_sym_xform *crypto_xfrm) 1678d03027SSrujana Challa { 179b4a4cc0STejasree Kondoj struct rte_crypto_sym_xform *auth_xfrm, *cipher_xfrm; 18b4409f2bSArchana Muniganti const uint8_t *key = NULL; 19246dea7eSArchana Muniganti uint8_t ccm_flag = 0; 2078d03027SSrujana Challa uint32_t *tmp_salt; 2178d03027SSrujana Challa uint64_t *tmp_key; 22b4409f2bSArchana Muniganti int i, length = 0; 2378d03027SSrujana Challa 2478d03027SSrujana Challa /* Set direction */ 25b4409f2bSArchana Muniganti if (ipsec_xfrm->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) 26b4409f2bSArchana Muniganti w2->s.dir = ROC_IE_SA_DIR_OUTBOUND; 27b4409f2bSArchana Muniganti else 2880d56d2dSArchana Muniganti w2->s.dir = ROC_IE_SA_DIR_INBOUND; 29b4409f2bSArchana Muniganti 30b4409f2bSArchana Muniganti if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AUTH) { 319b4a4cc0STejasree Kondoj auth_xfrm = crypto_xfrm; 329b4a4cc0STejasree Kondoj cipher_xfrm = crypto_xfrm->next; 33b4409f2bSArchana Muniganti } else { 349b4a4cc0STejasree Kondoj cipher_xfrm = crypto_xfrm; 359b4a4cc0STejasree Kondoj auth_xfrm = crypto_xfrm->next; 3678d03027SSrujana Challa } 3778d03027SSrujana Challa 3878d03027SSrujana Challa /* Set protocol - ESP vs AH */ 3978d03027SSrujana Challa switch (ipsec_xfrm->proto) { 4078d03027SSrujana Challa case RTE_SECURITY_IPSEC_SA_PROTO_ESP: 4180d56d2dSArchana Muniganti w2->s.protocol = ROC_IE_SA_PROTOCOL_ESP; 4278d03027SSrujana Challa break; 4378d03027SSrujana Challa case RTE_SECURITY_IPSEC_SA_PROTO_AH: 4480d56d2dSArchana Muniganti w2->s.protocol = ROC_IE_SA_PROTOCOL_AH; 4578d03027SSrujana Challa break; 4678d03027SSrujana Challa default: 4778d03027SSrujana Challa return -EINVAL; 4878d03027SSrujana Challa } 4978d03027SSrujana Challa 5078d03027SSrujana Challa /* Set mode - transport vs tunnel */ 5178d03027SSrujana Challa switch (ipsec_xfrm->mode) { 5278d03027SSrujana Challa case RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT: 5380d56d2dSArchana Muniganti w2->s.mode = ROC_IE_SA_MODE_TRANSPORT; 5478d03027SSrujana Challa break; 5578d03027SSrujana Challa case RTE_SECURITY_IPSEC_SA_MODE_TUNNEL: 5680d56d2dSArchana Muniganti w2->s.mode = ROC_IE_SA_MODE_TUNNEL; 5778d03027SSrujana Challa break; 5878d03027SSrujana Challa default: 5978d03027SSrujana Challa return -EINVAL; 6078d03027SSrujana Challa } 6178d03027SSrujana Challa 6278d03027SSrujana Challa /* Set encryption algorithm */ 6378d03027SSrujana Challa if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) { 6478d03027SSrujana Challa key = crypto_xfrm->aead.key.data; 6578d03027SSrujana Challa length = crypto_xfrm->aead.key.length; 6678d03027SSrujana Challa 6778d03027SSrujana Challa switch (crypto_xfrm->aead.algo) { 6878d03027SSrujana Challa case RTE_CRYPTO_AEAD_AES_GCM: 69c31a9465SAnoob Joseph w2->s.enc_type = ROC_IE_SA_ENC_AES_GCM; 70c31a9465SAnoob Joseph w2->s.auth_type = ROC_IE_SA_AUTH_NULL; 7178d03027SSrujana Challa memcpy(salt_key, &ipsec_xfrm->salt, 4); 7278d03027SSrujana Challa tmp_salt = (uint32_t *)salt_key; 7378d03027SSrujana Challa *tmp_salt = rte_be_to_cpu_32(*tmp_salt); 7478d03027SSrujana Challa break; 75246dea7eSArchana Muniganti case RTE_CRYPTO_AEAD_AES_CCM: 76c31a9465SAnoob Joseph w2->s.enc_type = ROC_IE_SA_ENC_AES_CCM; 77c31a9465SAnoob Joseph w2->s.auth_type = ROC_IE_SA_AUTH_NULL; 78246dea7eSArchana Muniganti ccm_flag = 0x07 & ~ROC_CPT_AES_CCM_CTR_LEN; 79246dea7eSArchana Muniganti *salt_key = ccm_flag; 80246dea7eSArchana Muniganti memcpy(PLT_PTR_ADD(salt_key, 1), &ipsec_xfrm->salt, 3); 81246dea7eSArchana Muniganti tmp_salt = (uint32_t *)salt_key; 82246dea7eSArchana Muniganti *tmp_salt = rte_be_to_cpu_32(*tmp_salt); 83246dea7eSArchana Muniganti break; 8478d03027SSrujana Challa default: 8578d03027SSrujana Challa return -ENOTSUP; 8678d03027SSrujana Challa } 8778d03027SSrujana Challa } else { 88b4409f2bSArchana Muniganti if (cipher_xfrm != NULL) { 899b4a4cc0STejasree Kondoj switch (cipher_xfrm->cipher.algo) { 907f4977e8SAnoob Joseph case RTE_CRYPTO_CIPHER_NULL: 91c31a9465SAnoob Joseph w2->s.enc_type = ROC_IE_SA_ENC_NULL; 927f4977e8SAnoob Joseph break; 939b4a4cc0STejasree Kondoj case RTE_CRYPTO_CIPHER_AES_CBC: 94c31a9465SAnoob Joseph w2->s.enc_type = ROC_IE_SA_ENC_AES_CBC; 959b4a4cc0STejasree Kondoj break; 96538bf100STejasree Kondoj case RTE_CRYPTO_CIPHER_AES_CTR: 97c31a9465SAnoob Joseph w2->s.enc_type = ROC_IE_SA_ENC_AES_CTR; 98538bf100STejasree Kondoj break; 99b934e65bSVamsi Attunuru case RTE_CRYPTO_CIPHER_3DES_CBC: 100c31a9465SAnoob Joseph w2->s.enc_type = ROC_IE_SA_ENC_3DES_CBC; 101b934e65bSVamsi Attunuru break; 1029b4a4cc0STejasree Kondoj default: 10378d03027SSrujana Challa return -ENOTSUP; 10478d03027SSrujana Challa } 10578d03027SSrujana Challa 106b4409f2bSArchana Muniganti key = cipher_xfrm->cipher.key.data; 107b4409f2bSArchana Muniganti length = cipher_xfrm->cipher.key.length; 108b4409f2bSArchana Muniganti } 109b4409f2bSArchana Muniganti 1109b4a4cc0STejasree Kondoj switch (auth_xfrm->auth.algo) { 11190a2ec4aSAnoob Joseph case RTE_CRYPTO_AUTH_NULL: 11228cd6c62SSrujana Challa if (w2->s.dir == ROC_IE_SA_DIR_INBOUND && ipsec_xfrm->replay_win_sz) { 11328cd6c62SSrujana Challa plt_err("anti-replay can't be supported with integrity service disabled"); 11428cd6c62SSrujana Challa return -EINVAL; 11528cd6c62SSrujana Challa } 116c31a9465SAnoob Joseph w2->s.auth_type = ROC_IE_SA_AUTH_NULL; 11790a2ec4aSAnoob Joseph break; 1189b4a4cc0STejasree Kondoj case RTE_CRYPTO_AUTH_SHA1_HMAC: 119c31a9465SAnoob Joseph w2->s.auth_type = ROC_IE_SA_AUTH_SHA1; 1209b4a4cc0STejasree Kondoj break; 1216dc3f45fSTejasree Kondoj case RTE_CRYPTO_AUTH_SHA256_HMAC: 122c31a9465SAnoob Joseph w2->s.auth_type = ROC_IE_SA_AUTH_SHA2_256; 12309e5c772STejasree Kondoj break; 12409e5c772STejasree Kondoj case RTE_CRYPTO_AUTH_SHA384_HMAC: 125c31a9465SAnoob Joseph w2->s.auth_type = ROC_IE_SA_AUTH_SHA2_384; 12609e5c772STejasree Kondoj break; 12709e5c772STejasree Kondoj case RTE_CRYPTO_AUTH_SHA512_HMAC: 128c31a9465SAnoob Joseph w2->s.auth_type = ROC_IE_SA_AUTH_SHA2_512; 1296dc3f45fSTejasree Kondoj break; 1307f4977e8SAnoob Joseph case RTE_CRYPTO_AUTH_AES_XCBC_MAC: 131c31a9465SAnoob Joseph w2->s.auth_type = ROC_IE_SA_AUTH_AES_XCBC_128; 1327f4977e8SAnoob Joseph break; 133e85982abSArchana Muniganti case RTE_CRYPTO_AUTH_AES_GMAC: 134c31a9465SAnoob Joseph w2->s.auth_type = ROC_IE_SA_AUTH_AES_GMAC; 135e85982abSArchana Muniganti key = auth_xfrm->auth.key.data; 136e85982abSArchana Muniganti length = auth_xfrm->auth.key.length; 137e85982abSArchana Muniganti memcpy(salt_key, &ipsec_xfrm->salt, 4); 138e85982abSArchana Muniganti tmp_salt = (uint32_t *)salt_key; 139e85982abSArchana Muniganti *tmp_salt = rte_be_to_cpu_32(*tmp_salt); 140e85982abSArchana Muniganti break; 1419b4a4cc0STejasree Kondoj default: 1429b4a4cc0STejasree Kondoj return -ENOTSUP; 1439b4a4cc0STejasree Kondoj } 1449b4a4cc0STejasree Kondoj 1457f4977e8SAnoob Joseph if (auth_xfrm->auth.algo == RTE_CRYPTO_AUTH_AES_XCBC_MAC) { 1467f4977e8SAnoob Joseph const uint8_t *auth_key = auth_xfrm->auth.key.data; 1477f4977e8SAnoob Joseph roc_aes_xcbc_key_derive(auth_key, hmac_opad_ipad); 1487f4977e8SAnoob Joseph } else { 149df22fe29SVidya Sagar Velumuri roc_se_hmac_opad_ipad_gen(w2->s.auth_type, auth_xfrm->auth.key.data, 150df22fe29SVidya Sagar Velumuri auth_xfrm->auth.key.length, &hmac_opad_ipad[0], 151df22fe29SVidya Sagar Velumuri ROC_SE_IPSEC); 1527f4977e8SAnoob Joseph } 15309e5c772STejasree Kondoj 15409e5c772STejasree Kondoj tmp_key = (uint64_t *)hmac_opad_ipad; 15509e5c772STejasree Kondoj for (i = 0; 15609e5c772STejasree Kondoj i < (int)(ROC_CTX_MAX_OPAD_IPAD_LEN / sizeof(uint64_t)); 15709e5c772STejasree Kondoj i++) 15809e5c772STejasree Kondoj tmp_key[i] = rte_be_to_cpu_64(tmp_key[i]); 15909e5c772STejasree Kondoj 1609b4a4cc0STejasree Kondoj } 1619b4a4cc0STejasree Kondoj 1625c770471SSrujana Challa /* Set encapsulation type */ 1635c770471SSrujana Challa if (ipsec_xfrm->options.udp_encap) 1645c770471SSrujana Challa w2->s.encap_type = ROC_IE_OT_SA_ENCAP_UDP; 1655c770471SSrujana Challa 16678d03027SSrujana Challa w2->s.spi = ipsec_xfrm->spi; 16778d03027SSrujana Challa 168b4409f2bSArchana Muniganti if (key != NULL && length != 0) { 16978d03027SSrujana Challa /* Copy encryption key */ 17078d03027SSrujana Challa memcpy(cipher_key, key, length); 17178d03027SSrujana Challa tmp_key = (uint64_t *)cipher_key; 17278d03027SSrujana Challa for (i = 0; i < (int)(ROC_CTX_MAX_CKEY_LEN / sizeof(uint64_t)); i++) 17378d03027SSrujana Challa tmp_key[i] = rte_be_to_cpu_64(tmp_key[i]); 174b4409f2bSArchana Muniganti } 17578d03027SSrujana Challa 1767f4977e8SAnoob Joseph /* Set AES key length */ 177c31a9465SAnoob Joseph if (w2->s.enc_type == ROC_IE_SA_ENC_AES_CBC || w2->s.enc_type == ROC_IE_SA_ENC_AES_CCM || 178c31a9465SAnoob Joseph w2->s.enc_type == ROC_IE_SA_ENC_AES_CTR || w2->s.enc_type == ROC_IE_SA_ENC_AES_GCM || 179c31a9465SAnoob Joseph w2->s.enc_type == ROC_IE_SA_ENC_AES_CCM || w2->s.auth_type == ROC_IE_SA_AUTH_AES_GMAC) { 18078d03027SSrujana Challa switch (length) { 18178d03027SSrujana Challa case ROC_CPT_AES128_KEY_LEN: 18280d56d2dSArchana Muniganti w2->s.aes_key_len = ROC_IE_SA_AES_KEY_LEN_128; 18378d03027SSrujana Challa break; 18478d03027SSrujana Challa case ROC_CPT_AES192_KEY_LEN: 18580d56d2dSArchana Muniganti w2->s.aes_key_len = ROC_IE_SA_AES_KEY_LEN_192; 18678d03027SSrujana Challa break; 18778d03027SSrujana Challa case ROC_CPT_AES256_KEY_LEN: 18880d56d2dSArchana Muniganti w2->s.aes_key_len = ROC_IE_SA_AES_KEY_LEN_256; 18978d03027SSrujana Challa break; 19078d03027SSrujana Challa default: 1917f4977e8SAnoob Joseph plt_err("Invalid AES key length"); 19278d03027SSrujana Challa return -EINVAL; 19378d03027SSrujana Challa } 1947f4977e8SAnoob Joseph } 19578d03027SSrujana Challa 196c4fcfaa7SAnoob Joseph if (ipsec_xfrm->life.packets_soft_limit != 0 || 197c4fcfaa7SAnoob Joseph ipsec_xfrm->life.packets_hard_limit != 0) { 198c4fcfaa7SAnoob Joseph if (ipsec_xfrm->life.bytes_soft_limit != 0 || 199c4fcfaa7SAnoob Joseph ipsec_xfrm->life.bytes_hard_limit != 0) { 200c4fcfaa7SAnoob Joseph plt_err("Expiry tracking with both packets & bytes is not supported"); 201c4fcfaa7SAnoob Joseph return -EINVAL; 202c4fcfaa7SAnoob Joseph } 203c4fcfaa7SAnoob Joseph w2->s.life_unit = ROC_IE_OT_SA_LIFE_UNIT_PKTS; 204c4fcfaa7SAnoob Joseph } 205c4fcfaa7SAnoob Joseph 206c4fcfaa7SAnoob Joseph if (ipsec_xfrm->life.bytes_soft_limit != 0 || 207c4fcfaa7SAnoob Joseph ipsec_xfrm->life.bytes_hard_limit != 0) { 208c4fcfaa7SAnoob Joseph if (ipsec_xfrm->life.packets_soft_limit != 0 || 209c4fcfaa7SAnoob Joseph ipsec_xfrm->life.packets_hard_limit != 0) { 210c4fcfaa7SAnoob Joseph plt_err("Expiry tracking with both packets & bytes is not supported"); 211c4fcfaa7SAnoob Joseph return -EINVAL; 212c4fcfaa7SAnoob Joseph } 213c4fcfaa7SAnoob Joseph w2->s.life_unit = ROC_IE_OT_SA_LIFE_UNIT_OCTETS; 214c4fcfaa7SAnoob Joseph } 215c4fcfaa7SAnoob Joseph 21678d03027SSrujana Challa return 0; 21778d03027SSrujana Challa } 21878d03027SSrujana Challa 21978d03027SSrujana Challa static size_t 22078d03027SSrujana Challa ot_ipsec_inb_ctx_size(struct roc_ot_ipsec_inb_sa *sa) 22178d03027SSrujana Challa { 22278d03027SSrujana Challa size_t size; 22378d03027SSrujana Challa 22478d03027SSrujana Challa /* Variable based on Anti-replay Window */ 22578d03027SSrujana Challa size = offsetof(struct roc_ot_ipsec_inb_sa, ctx) + 22678d03027SSrujana Challa offsetof(struct roc_ot_ipsec_inb_ctx_update_reg, ar_winbits); 22778d03027SSrujana Challa 22878d03027SSrujana Challa if (sa->w0.s.ar_win) 22978d03027SSrujana Challa size += (1 << (sa->w0.s.ar_win - 1)) * sizeof(uint64_t); 23078d03027SSrujana Challa 23178d03027SSrujana Challa return size; 23278d03027SSrujana Challa } 23378d03027SSrujana Challa 234733e9db8SRahul Bhansali static void 235733e9db8SRahul Bhansali ot_ipsec_update_ipv6_addr_endianness(uint64_t *addr) 236733e9db8SRahul Bhansali { 237733e9db8SRahul Bhansali *addr = rte_be_to_cpu_64(*addr); 238733e9db8SRahul Bhansali addr++; 239733e9db8SRahul Bhansali *addr = rte_be_to_cpu_64(*addr); 240733e9db8SRahul Bhansali } 241733e9db8SRahul Bhansali 24207d4bde1STejasree Kondoj static int 24307d4bde1STejasree Kondoj ot_ipsec_inb_tunnel_hdr_fill(struct roc_ot_ipsec_inb_sa *sa, 24407d4bde1STejasree Kondoj struct rte_security_ipsec_xform *ipsec_xfrm) 24507d4bde1STejasree Kondoj { 24607d4bde1STejasree Kondoj struct rte_security_ipsec_tunnel_param *tunnel; 24707d4bde1STejasree Kondoj 24807d4bde1STejasree Kondoj if (ipsec_xfrm->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) 24907d4bde1STejasree Kondoj return 0; 25007d4bde1STejasree Kondoj 25107d4bde1STejasree Kondoj if (ipsec_xfrm->options.tunnel_hdr_verify == 0) 25207d4bde1STejasree Kondoj return 0; 25307d4bde1STejasree Kondoj 25407d4bde1STejasree Kondoj tunnel = &ipsec_xfrm->tunnel; 25507d4bde1STejasree Kondoj 25607d4bde1STejasree Kondoj switch (tunnel->type) { 25707d4bde1STejasree Kondoj case RTE_SECURITY_IPSEC_TUNNEL_IPV4: 25807d4bde1STejasree Kondoj sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_4; 25907d4bde1STejasree Kondoj memcpy(&sa->outer_hdr.ipv4.src_addr, &tunnel->ipv4.src_ip, 26007d4bde1STejasree Kondoj sizeof(struct in_addr)); 26107d4bde1STejasree Kondoj memcpy(&sa->outer_hdr.ipv4.dst_addr, &tunnel->ipv4.dst_ip, 26207d4bde1STejasree Kondoj sizeof(struct in_addr)); 26307d4bde1STejasree Kondoj 26407d4bde1STejasree Kondoj /* IP Source and Dest are in LE/CPU endian */ 26507d4bde1STejasree Kondoj sa->outer_hdr.ipv4.src_addr = 26607d4bde1STejasree Kondoj rte_be_to_cpu_32(sa->outer_hdr.ipv4.src_addr); 26707d4bde1STejasree Kondoj sa->outer_hdr.ipv4.dst_addr = 26807d4bde1STejasree Kondoj rte_be_to_cpu_32(sa->outer_hdr.ipv4.dst_addr); 26907d4bde1STejasree Kondoj 27007d4bde1STejasree Kondoj break; 27107d4bde1STejasree Kondoj case RTE_SECURITY_IPSEC_TUNNEL_IPV6: 27207d4bde1STejasree Kondoj sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_6; 27307d4bde1STejasree Kondoj memcpy(&sa->outer_hdr.ipv6.src_addr, &tunnel->ipv6.src_addr, 274*2ede1422SRobin Jarry sizeof(sa->outer_hdr.ipv6.src_addr)); 27507d4bde1STejasree Kondoj memcpy(&sa->outer_hdr.ipv6.dst_addr, &tunnel->ipv6.dst_addr, 276*2ede1422SRobin Jarry sizeof(sa->outer_hdr.ipv6.dst_addr)); 27707d4bde1STejasree Kondoj 278733e9db8SRahul Bhansali /* IP Source and Dest are in LE/CPU endian */ 279733e9db8SRahul Bhansali ot_ipsec_update_ipv6_addr_endianness((uint64_t *)&sa->outer_hdr.ipv6.src_addr); 280733e9db8SRahul Bhansali ot_ipsec_update_ipv6_addr_endianness((uint64_t *)&sa->outer_hdr.ipv6.dst_addr); 281733e9db8SRahul Bhansali 28207d4bde1STejasree Kondoj break; 28307d4bde1STejasree Kondoj default: 28407d4bde1STejasree Kondoj return -EINVAL; 28507d4bde1STejasree Kondoj } 28607d4bde1STejasree Kondoj 28707d4bde1STejasree Kondoj switch (ipsec_xfrm->options.tunnel_hdr_verify) { 28807d4bde1STejasree Kondoj case RTE_SECURITY_IPSEC_TUNNEL_VERIFY_DST_ADDR: 28907d4bde1STejasree Kondoj sa->w2.s.ip_hdr_verify = ROC_IE_OT_SA_IP_HDR_VERIFY_DST_ADDR; 29007d4bde1STejasree Kondoj break; 29107d4bde1STejasree Kondoj case RTE_SECURITY_IPSEC_TUNNEL_VERIFY_SRC_DST_ADDR: 29207d4bde1STejasree Kondoj sa->w2.s.ip_hdr_verify = 29307d4bde1STejasree Kondoj ROC_IE_OT_SA_IP_HDR_VERIFY_SRC_DST_ADDR; 29407d4bde1STejasree Kondoj break; 29507d4bde1STejasree Kondoj default: 29607d4bde1STejasree Kondoj return -ENOTSUP; 29707d4bde1STejasree Kondoj } 29807d4bde1STejasree Kondoj 29907d4bde1STejasree Kondoj return 0; 30007d4bde1STejasree Kondoj } 30107d4bde1STejasree Kondoj 30278d03027SSrujana Challa int 30378d03027SSrujana Challa cnxk_ot_ipsec_inb_sa_fill(struct roc_ot_ipsec_inb_sa *sa, 30478d03027SSrujana Challa struct rte_security_ipsec_xform *ipsec_xfrm, 3055ece02e7SVidya Sagar Velumuri struct rte_crypto_sym_xform *crypto_xfrm, 3065ece02e7SVidya Sagar Velumuri bool is_inline) 30778d03027SSrujana Challa { 308f949cc3bSNithin Dabilpuram uint16_t sport = 4500, dport = 4500; 30978d03027SSrujana Challa union roc_ot_ipsec_sa_word2 w2; 31078d03027SSrujana Challa uint32_t replay_win_sz; 31178d03027SSrujana Challa size_t offset; 31278d03027SSrujana Challa int rc; 31378d03027SSrujana Challa 3145ece02e7SVidya Sagar Velumuri /* Initialize the SA */ 3155ece02e7SVidya Sagar Velumuri roc_ot_ipsec_inb_sa_init(sa, is_inline); 3165ece02e7SVidya Sagar Velumuri 31778d03027SSrujana Challa w2.u64 = 0; 31878d03027SSrujana Challa rc = ot_ipsec_sa_common_param_fill(&w2, sa->cipher_key, sa->w8.s.salt, 3199b4a4cc0STejasree Kondoj sa->hmac_opad_ipad, ipsec_xfrm, 3209b4a4cc0STejasree Kondoj crypto_xfrm); 32178d03027SSrujana Challa if (rc) 32278d03027SSrujana Challa return rc; 32378d03027SSrujana Challa 32478d03027SSrujana Challa /* Updata common word2 data */ 32578d03027SSrujana Challa sa->w2.u64 = w2.u64; 32678d03027SSrujana Challa 32778d03027SSrujana Challa /* Only support power-of-two window sizes supported */ 32878d03027SSrujana Challa replay_win_sz = ipsec_xfrm->replay_win_sz; 32978d03027SSrujana Challa if (replay_win_sz) { 33078d03027SSrujana Challa if (!rte_is_power_of_2(replay_win_sz) || 33178d03027SSrujana Challa replay_win_sz > ROC_AR_WIN_SIZE_MAX) 33278d03027SSrujana Challa return -ENOTSUP; 33378d03027SSrujana Challa 33478d03027SSrujana Challa sa->w0.s.ar_win = rte_log2_u32(replay_win_sz) - 5; 33578d03027SSrujana Challa } 33678d03027SSrujana Challa 33707d4bde1STejasree Kondoj rc = ot_ipsec_inb_tunnel_hdr_fill(sa, ipsec_xfrm); 33807d4bde1STejasree Kondoj if (rc) 33907d4bde1STejasree Kondoj return rc; 34007d4bde1STejasree Kondoj 341582085edSVidya Sagar Velumuri /* Default options for pkt_out and pkt_fmt are with 342582085edSVidya Sagar Velumuri * second pass meta and no defrag. 343582085edSVidya Sagar Velumuri */ 344582085edSVidya Sagar Velumuri sa->w0.s.pkt_format = ROC_IE_OT_SA_PKT_FMT_META; 345582085edSVidya Sagar Velumuri sa->w0.s.pkt_output = ROC_IE_OT_SA_PKT_OUTPUT_NO_FRAG; 346582085edSVidya Sagar Velumuri sa->w0.s.pkind = ROC_IE_OT_CPT_PKIND; 347582085edSVidya Sagar Velumuri 348582085edSVidya Sagar Velumuri if (ipsec_xfrm->options.ip_reassembly_en) 349582085edSVidya Sagar Velumuri sa->w0.s.pkt_output = ROC_IE_OT_SA_PKT_OUTPUT_HW_BASED_DEFRAG; 350582085edSVidya Sagar Velumuri 35178d03027SSrujana Challa /* ESN */ 35278d03027SSrujana Challa sa->w2.s.esn_en = !!ipsec_xfrm->options.esn; 3535c770471SSrujana Challa if (ipsec_xfrm->options.udp_encap) { 354f949cc3bSNithin Dabilpuram if (ipsec_xfrm->udp.sport) 355f949cc3bSNithin Dabilpuram sport = ipsec_xfrm->udp.sport; 356f949cc3bSNithin Dabilpuram 357f949cc3bSNithin Dabilpuram if (ipsec_xfrm->udp.dport) 358f949cc3bSNithin Dabilpuram dport = ipsec_xfrm->udp.dport; 359f949cc3bSNithin Dabilpuram 360f949cc3bSNithin Dabilpuram sa->w10.s.udp_src_port = sport; 361f949cc3bSNithin Dabilpuram sa->w10.s.udp_dst_port = dport; 3625c770471SSrujana Challa } 36378d03027SSrujana Challa 3642d5ca272STejasree Kondoj if (ipsec_xfrm->options.udp_ports_verify) 3652d5ca272STejasree Kondoj sa->w2.s.udp_ports_verify = 1; 3662d5ca272STejasree Kondoj 36778d03027SSrujana Challa offset = offsetof(struct roc_ot_ipsec_inb_sa, ctx); 36878d03027SSrujana Challa /* Word offset for HW managed SA field */ 36978d03027SSrujana Challa sa->w0.s.hw_ctx_off = offset / 8; 37078d03027SSrujana Challa /* Context push size for inbound spans up to hw_ctx including 37178d03027SSrujana Challa * ar_base field, in 8b units 37278d03027SSrujana Challa */ 37378d03027SSrujana Challa sa->w0.s.ctx_push_size = sa->w0.s.hw_ctx_off + 1; 37478d03027SSrujana Challa /* Entire context size in 128B units */ 37578d03027SSrujana Challa sa->w0.s.ctx_size = 37678d03027SSrujana Challa (PLT_ALIGN_CEIL(ot_ipsec_inb_ctx_size(sa), ROC_CTX_UNIT_128B) / 37778d03027SSrujana Challa ROC_CTX_UNIT_128B) - 37878d03027SSrujana Challa 1; 37978d03027SSrujana Challa 380c4fcfaa7SAnoob Joseph /** 381c4fcfaa7SAnoob Joseph * CPT MC triggers expiry when counter value changes from 2 to 1. To 382c4fcfaa7SAnoob Joseph * mitigate this behaviour add 1 to the life counter values provided. 383c4fcfaa7SAnoob Joseph */ 384c4fcfaa7SAnoob Joseph 385c4fcfaa7SAnoob Joseph if (ipsec_xfrm->life.bytes_soft_limit) { 386c4fcfaa7SAnoob Joseph sa->ctx.soft_life = ipsec_xfrm->life.bytes_soft_limit + 1; 387c4fcfaa7SAnoob Joseph sa->w0.s.soft_life_dec = 1; 388c4fcfaa7SAnoob Joseph } 389c4fcfaa7SAnoob Joseph 390c4fcfaa7SAnoob Joseph if (ipsec_xfrm->life.packets_soft_limit) { 391c4fcfaa7SAnoob Joseph sa->ctx.soft_life = ipsec_xfrm->life.packets_soft_limit + 1; 392c4fcfaa7SAnoob Joseph sa->w0.s.soft_life_dec = 1; 393c4fcfaa7SAnoob Joseph } 394c4fcfaa7SAnoob Joseph 395c4fcfaa7SAnoob Joseph if (ipsec_xfrm->life.bytes_hard_limit) { 396c4fcfaa7SAnoob Joseph sa->ctx.hard_life = ipsec_xfrm->life.bytes_hard_limit + 1; 397c4fcfaa7SAnoob Joseph sa->w0.s.hard_life_dec = 1; 398c4fcfaa7SAnoob Joseph } 399c4fcfaa7SAnoob Joseph 400c4fcfaa7SAnoob Joseph if (ipsec_xfrm->life.packets_hard_limit) { 401c4fcfaa7SAnoob Joseph sa->ctx.hard_life = ipsec_xfrm->life.packets_hard_limit + 1; 402c4fcfaa7SAnoob Joseph sa->w0.s.hard_life_dec = 1; 403c4fcfaa7SAnoob Joseph } 404c4fcfaa7SAnoob Joseph 40578d03027SSrujana Challa rte_wmb(); 40678d03027SSrujana Challa 40778d03027SSrujana Challa /* Enable SA */ 40878d03027SSrujana Challa sa->w2.s.valid = 1; 40978d03027SSrujana Challa return 0; 41078d03027SSrujana Challa } 41178d03027SSrujana Challa 41278d03027SSrujana Challa int 41378d03027SSrujana Challa cnxk_ot_ipsec_outb_sa_fill(struct roc_ot_ipsec_outb_sa *sa, 41478d03027SSrujana Challa struct rte_security_ipsec_xform *ipsec_xfrm, 41578d03027SSrujana Challa struct rte_crypto_sym_xform *crypto_xfrm) 41678d03027SSrujana Challa { 41778d03027SSrujana Challa struct rte_security_ipsec_tunnel_param *tunnel = &ipsec_xfrm->tunnel; 418f949cc3bSNithin Dabilpuram uint16_t sport = 4500, dport = 4500; 41978d03027SSrujana Challa union roc_ot_ipsec_sa_word2 w2; 42078d03027SSrujana Challa size_t offset; 42178d03027SSrujana Challa int rc; 42278d03027SSrujana Challa 4235ece02e7SVidya Sagar Velumuri /* Initialize the SA */ 4245ece02e7SVidya Sagar Velumuri roc_ot_ipsec_outb_sa_init(sa); 4255ece02e7SVidya Sagar Velumuri 42678d03027SSrujana Challa w2.u64 = 0; 42778d03027SSrujana Challa rc = ot_ipsec_sa_common_param_fill(&w2, sa->cipher_key, sa->iv.s.salt, 4289b4a4cc0STejasree Kondoj sa->hmac_opad_ipad, ipsec_xfrm, 4299b4a4cc0STejasree Kondoj crypto_xfrm); 43078d03027SSrujana Challa if (rc) 43178d03027SSrujana Challa return rc; 43278d03027SSrujana Challa 43378d03027SSrujana Challa /* Update common word2 data */ 43478d03027SSrujana Challa sa->w2.u64 = w2.u64; 43578d03027SSrujana Challa 43678d03027SSrujana Challa if (ipsec_xfrm->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) 43778d03027SSrujana Challa goto skip_tunnel_info; 43878d03027SSrujana Challa 43978d03027SSrujana Challa /* Tunnel header info */ 44078d03027SSrujana Challa switch (tunnel->type) { 44178d03027SSrujana Challa case RTE_SECURITY_IPSEC_TUNNEL_IPV4: 44280d56d2dSArchana Muniganti sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_4; 44378d03027SSrujana Challa memcpy(&sa->outer_hdr.ipv4.src_addr, &tunnel->ipv4.src_ip, 44478d03027SSrujana Challa sizeof(struct in_addr)); 44578d03027SSrujana Challa memcpy(&sa->outer_hdr.ipv4.dst_addr, &tunnel->ipv4.dst_ip, 44678d03027SSrujana Challa sizeof(struct in_addr)); 44778d03027SSrujana Challa 44878d03027SSrujana Challa /* IP Source and Dest seems to be in LE/CPU endian */ 44978d03027SSrujana Challa sa->outer_hdr.ipv4.src_addr = 45078d03027SSrujana Challa rte_be_to_cpu_32(sa->outer_hdr.ipv4.src_addr); 45178d03027SSrujana Challa sa->outer_hdr.ipv4.dst_addr = 45278d03027SSrujana Challa rte_be_to_cpu_32(sa->outer_hdr.ipv4.dst_addr); 45378d03027SSrujana Challa 45478d03027SSrujana Challa /* Outer header DF bit source */ 45578d03027SSrujana Challa if (!ipsec_xfrm->options.copy_df) { 45678d03027SSrujana Challa sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src = 45778d03027SSrujana Challa ROC_IE_OT_SA_COPY_FROM_SA; 45878d03027SSrujana Challa sa->w10.s.ipv4_df_or_ipv6_flw_lbl = tunnel->ipv4.df; 45978d03027SSrujana Challa } else { 46078d03027SSrujana Challa sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src = 46178d03027SSrujana Challa ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR; 46278d03027SSrujana Challa } 46378d03027SSrujana Challa 46478d03027SSrujana Challa /* Outer header DSCP source */ 46578d03027SSrujana Challa if (!ipsec_xfrm->options.copy_dscp) { 46678d03027SSrujana Challa sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_SA; 46778d03027SSrujana Challa sa->w10.s.dscp = tunnel->ipv4.dscp; 46878d03027SSrujana Challa } else { 46978d03027SSrujana Challa sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR; 47078d03027SSrujana Challa } 47178d03027SSrujana Challa break; 47278d03027SSrujana Challa case RTE_SECURITY_IPSEC_TUNNEL_IPV6: 47380d56d2dSArchana Muniganti sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_6; 47478d03027SSrujana Challa memcpy(&sa->outer_hdr.ipv6.src_addr, &tunnel->ipv6.src_addr, 475*2ede1422SRobin Jarry sizeof(sa->outer_hdr.ipv6.src_addr)); 47678d03027SSrujana Challa memcpy(&sa->outer_hdr.ipv6.dst_addr, &tunnel->ipv6.dst_addr, 477*2ede1422SRobin Jarry sizeof(sa->outer_hdr.ipv6.dst_addr)); 47878d03027SSrujana Challa 479733e9db8SRahul Bhansali /* IP Source and Dest are in LE/CPU endian */ 480733e9db8SRahul Bhansali ot_ipsec_update_ipv6_addr_endianness((uint64_t *)&sa->outer_hdr.ipv6.src_addr); 481733e9db8SRahul Bhansali ot_ipsec_update_ipv6_addr_endianness((uint64_t *)&sa->outer_hdr.ipv6.dst_addr); 482733e9db8SRahul Bhansali 48378d03027SSrujana Challa /* Outer header flow label source */ 48478d03027SSrujana Challa if (!ipsec_xfrm->options.copy_flabel) { 48578d03027SSrujana Challa sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src = 48678d03027SSrujana Challa ROC_IE_OT_SA_COPY_FROM_SA; 48778d03027SSrujana Challa 48878d03027SSrujana Challa sa->w10.s.ipv4_df_or_ipv6_flw_lbl = tunnel->ipv6.flabel; 48978d03027SSrujana Challa } else { 49078d03027SSrujana Challa sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src = 49178d03027SSrujana Challa ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR; 49278d03027SSrujana Challa } 49378d03027SSrujana Challa 49478d03027SSrujana Challa /* Outer header DSCP source */ 49578d03027SSrujana Challa if (!ipsec_xfrm->options.copy_dscp) { 49678d03027SSrujana Challa sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_SA; 49778d03027SSrujana Challa sa->w10.s.dscp = tunnel->ipv6.dscp; 49878d03027SSrujana Challa } else { 49978d03027SSrujana Challa sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR; 50078d03027SSrujana Challa } 50178d03027SSrujana Challa break; 50278d03027SSrujana Challa default: 50378d03027SSrujana Challa return -EINVAL; 50478d03027SSrujana Challa } 50578d03027SSrujana Challa 50678d03027SSrujana Challa skip_tunnel_info: 50778d03027SSrujana Challa /* ESN */ 50878d03027SSrujana Challa sa->w0.s.esn_en = !!ipsec_xfrm->options.esn; 50978d03027SSrujana Challa 510670af27bSTejasree Kondoj if (ipsec_xfrm->esn.value) 511670af27bSTejasree Kondoj sa->ctx.esn_val = ipsec_xfrm->esn.value - 1; 512670af27bSTejasree Kondoj 5135c770471SSrujana Challa if (ipsec_xfrm->options.udp_encap) { 514f949cc3bSNithin Dabilpuram if (ipsec_xfrm->udp.sport) 515f949cc3bSNithin Dabilpuram sport = ipsec_xfrm->udp.sport; 516f949cc3bSNithin Dabilpuram 517f949cc3bSNithin Dabilpuram if (ipsec_xfrm->udp.dport) 518f949cc3bSNithin Dabilpuram dport = ipsec_xfrm->udp.dport; 519f949cc3bSNithin Dabilpuram 520f949cc3bSNithin Dabilpuram sa->w10.s.udp_src_port = sport; 521f949cc3bSNithin Dabilpuram sa->w10.s.udp_dst_port = dport; 5225c770471SSrujana Challa } 5235c770471SSrujana Challa 52478d03027SSrujana Challa offset = offsetof(struct roc_ot_ipsec_outb_sa, ctx); 52578d03027SSrujana Challa /* Word offset for HW managed SA field */ 52678d03027SSrujana Challa sa->w0.s.hw_ctx_off = offset / 8; 527a4716f53SAnoob Joseph 528a4716f53SAnoob Joseph /* Context push size is up to err ctl in HW ctx */ 529a4716f53SAnoob Joseph sa->w0.s.ctx_push_size = sa->w0.s.hw_ctx_off + 1; 530a4716f53SAnoob Joseph 53178d03027SSrujana Challa /* Entire context size in 128B units */ 53278d03027SSrujana Challa offset = sizeof(struct roc_ot_ipsec_outb_sa); 53378d03027SSrujana Challa sa->w0.s.ctx_size = (PLT_ALIGN_CEIL(offset, ROC_CTX_UNIT_128B) / 53478d03027SSrujana Challa ROC_CTX_UNIT_128B) - 53578d03027SSrujana Challa 1; 53678d03027SSrujana Challa 53778d03027SSrujana Challa /* IPID gen */ 53878d03027SSrujana Challa sa->w2.s.ipid_gen = 1; 53978d03027SSrujana Challa 540c4fcfaa7SAnoob Joseph /** 541c4fcfaa7SAnoob Joseph * CPT MC triggers expiry when counter value changes from 2 to 1. To 542c4fcfaa7SAnoob Joseph * mitigate this behaviour add 1 to the life counter values provided. 543c4fcfaa7SAnoob Joseph */ 544c4fcfaa7SAnoob Joseph 545c4fcfaa7SAnoob Joseph if (ipsec_xfrm->life.bytes_soft_limit) { 546c4fcfaa7SAnoob Joseph sa->ctx.soft_life = ipsec_xfrm->life.bytes_soft_limit + 1; 547c4fcfaa7SAnoob Joseph sa->w0.s.soft_life_dec = 1; 548c4fcfaa7SAnoob Joseph } 549c4fcfaa7SAnoob Joseph 550c4fcfaa7SAnoob Joseph if (ipsec_xfrm->life.packets_soft_limit) { 551c4fcfaa7SAnoob Joseph sa->ctx.soft_life = ipsec_xfrm->life.packets_soft_limit + 1; 552c4fcfaa7SAnoob Joseph sa->w0.s.soft_life_dec = 1; 553c4fcfaa7SAnoob Joseph } 554c4fcfaa7SAnoob Joseph 555c4fcfaa7SAnoob Joseph if (ipsec_xfrm->life.bytes_hard_limit) { 556c4fcfaa7SAnoob Joseph sa->ctx.hard_life = ipsec_xfrm->life.bytes_hard_limit + 1; 557c4fcfaa7SAnoob Joseph sa->w0.s.hard_life_dec = 1; 558c4fcfaa7SAnoob Joseph } 559c4fcfaa7SAnoob Joseph 560c4fcfaa7SAnoob Joseph if (ipsec_xfrm->life.packets_hard_limit) { 561c4fcfaa7SAnoob Joseph sa->ctx.hard_life = ipsec_xfrm->life.packets_hard_limit + 1; 562c4fcfaa7SAnoob Joseph sa->w0.s.hard_life_dec = 1; 563c4fcfaa7SAnoob Joseph } 564c4fcfaa7SAnoob Joseph 56578d03027SSrujana Challa /* There are two words of CPT_CTX_HW_S for ucode to skip */ 56678d03027SSrujana Challa sa->w0.s.ctx_hdr_size = 1; 56778d03027SSrujana Challa sa->w0.s.aop_valid = 1; 56878d03027SSrujana Challa 56978d03027SSrujana Challa rte_wmb(); 57078d03027SSrujana Challa 57178d03027SSrujana Challa /* Enable SA */ 57278d03027SSrujana Challa sa->w2.s.valid = 1; 57378d03027SSrujana Challa return 0; 57478d03027SSrujana Challa } 57578d03027SSrujana Challa 57678d03027SSrujana Challa bool 57778d03027SSrujana Challa cnxk_ot_ipsec_inb_sa_valid(struct roc_ot_ipsec_inb_sa *sa) 57878d03027SSrujana Challa { 57978d03027SSrujana Challa return !!sa->w2.s.valid; 58078d03027SSrujana Challa } 58178d03027SSrujana Challa 58278d03027SSrujana Challa bool 58378d03027SSrujana Challa cnxk_ot_ipsec_outb_sa_valid(struct roc_ot_ipsec_outb_sa *sa) 58478d03027SSrujana Challa { 58578d03027SSrujana Challa return !!sa->w2.s.valid; 58678d03027SSrujana Challa } 58778d03027SSrujana Challa 58878d03027SSrujana Challa uint8_t 58978d03027SSrujana Challa cnxk_ipsec_ivlen_get(enum rte_crypto_cipher_algorithm c_algo, 59078d03027SSrujana Challa enum rte_crypto_auth_algorithm a_algo, 59178d03027SSrujana Challa enum rte_crypto_aead_algorithm aead_algo) 59278d03027SSrujana Challa { 59378d03027SSrujana Challa uint8_t ivlen = 0; 59478d03027SSrujana Challa 595246dea7eSArchana Muniganti if ((aead_algo == RTE_CRYPTO_AEAD_AES_GCM) || (aead_algo == RTE_CRYPTO_AEAD_AES_CCM)) 59678d03027SSrujana Challa ivlen = 8; 59778d03027SSrujana Challa 59878d03027SSrujana Challa switch (c_algo) { 59978d03027SSrujana Challa case RTE_CRYPTO_CIPHER_AES_CTR: 60078d03027SSrujana Challa ivlen = 8; 60178d03027SSrujana Challa break; 602e1a9ff69SVidya Sagar Velumuri case RTE_CRYPTO_CIPHER_DES_CBC: 60378d03027SSrujana Challa case RTE_CRYPTO_CIPHER_3DES_CBC: 60478d03027SSrujana Challa ivlen = ROC_CPT_DES_BLOCK_LENGTH; 60578d03027SSrujana Challa break; 60678d03027SSrujana Challa case RTE_CRYPTO_CIPHER_AES_CBC: 60778d03027SSrujana Challa ivlen = ROC_CPT_AES_BLOCK_LENGTH; 60878d03027SSrujana Challa break; 60978d03027SSrujana Challa default: 61078d03027SSrujana Challa break; 61178d03027SSrujana Challa } 61278d03027SSrujana Challa 61378d03027SSrujana Challa switch (a_algo) { 61478d03027SSrujana Challa case RTE_CRYPTO_AUTH_AES_GMAC: 61578d03027SSrujana Challa ivlen = 8; 61678d03027SSrujana Challa break; 61778d03027SSrujana Challa default: 61878d03027SSrujana Challa break; 61978d03027SSrujana Challa } 62078d03027SSrujana Challa 62178d03027SSrujana Challa return ivlen; 62278d03027SSrujana Challa } 62378d03027SSrujana Challa 62478d03027SSrujana Challa uint8_t 62578d03027SSrujana Challa cnxk_ipsec_icvlen_get(enum rte_crypto_cipher_algorithm c_algo, 62678d03027SSrujana Challa enum rte_crypto_auth_algorithm a_algo, 62778d03027SSrujana Challa enum rte_crypto_aead_algorithm aead_algo) 62878d03027SSrujana Challa { 62978d03027SSrujana Challa uint8_t icv = 0; 63078d03027SSrujana Challa 63178d03027SSrujana Challa (void)c_algo; 63278d03027SSrujana Challa 63378d03027SSrujana Challa switch (a_algo) { 63478d03027SSrujana Challa case RTE_CRYPTO_AUTH_NULL: 63578d03027SSrujana Challa icv = 0; 63678d03027SSrujana Challa break; 637fe87c455SVidya Sagar Velumuri case RTE_CRYPTO_AUTH_MD5_HMAC: 63878d03027SSrujana Challa case RTE_CRYPTO_AUTH_SHA1_HMAC: 63978d03027SSrujana Challa icv = 12; 64078d03027SSrujana Challa break; 64178d03027SSrujana Challa case RTE_CRYPTO_AUTH_SHA256_HMAC: 64278d03027SSrujana Challa case RTE_CRYPTO_AUTH_AES_GMAC: 64378d03027SSrujana Challa icv = 16; 64478d03027SSrujana Challa break; 64578d03027SSrujana Challa case RTE_CRYPTO_AUTH_SHA384_HMAC: 64678d03027SSrujana Challa icv = 24; 64778d03027SSrujana Challa break; 64878d03027SSrujana Challa case RTE_CRYPTO_AUTH_SHA512_HMAC: 64978d03027SSrujana Challa icv = 32; 65078d03027SSrujana Challa break; 6517f4977e8SAnoob Joseph case RTE_CRYPTO_AUTH_AES_XCBC_MAC: 6527f4977e8SAnoob Joseph icv = 12; 6537f4977e8SAnoob Joseph break; 65478d03027SSrujana Challa default: 65578d03027SSrujana Challa break; 65678d03027SSrujana Challa } 65778d03027SSrujana Challa 65878d03027SSrujana Challa switch (aead_algo) { 65978d03027SSrujana Challa case RTE_CRYPTO_AEAD_AES_GCM: 660246dea7eSArchana Muniganti case RTE_CRYPTO_AEAD_AES_CCM: 66178d03027SSrujana Challa icv = 16; 66278d03027SSrujana Challa break; 66378d03027SSrujana Challa default: 66478d03027SSrujana Challa break; 66578d03027SSrujana Challa } 66678d03027SSrujana Challa 66778d03027SSrujana Challa return icv; 66878d03027SSrujana Challa } 66978d03027SSrujana Challa 67078d03027SSrujana Challa uint8_t 67178d03027SSrujana Challa cnxk_ipsec_outb_roundup_byte(enum rte_crypto_cipher_algorithm c_algo, 67278d03027SSrujana Challa enum rte_crypto_aead_algorithm aead_algo) 67378d03027SSrujana Challa { 67478d03027SSrujana Challa uint8_t roundup_byte = 4; 67578d03027SSrujana Challa 676246dea7eSArchana Muniganti if ((aead_algo == RTE_CRYPTO_AEAD_AES_GCM) || (aead_algo == RTE_CRYPTO_AEAD_AES_CCM)) 67778d03027SSrujana Challa return roundup_byte; 67878d03027SSrujana Challa 67978d03027SSrujana Challa switch (c_algo) { 68078d03027SSrujana Challa case RTE_CRYPTO_CIPHER_AES_CTR: 68178d03027SSrujana Challa roundup_byte = 4; 68278d03027SSrujana Challa break; 68378d03027SSrujana Challa case RTE_CRYPTO_CIPHER_AES_CBC: 68478d03027SSrujana Challa roundup_byte = 16; 68578d03027SSrujana Challa break; 686e1a9ff69SVidya Sagar Velumuri case RTE_CRYPTO_CIPHER_DES_CBC: 68778d03027SSrujana Challa case RTE_CRYPTO_CIPHER_3DES_CBC: 68878d03027SSrujana Challa roundup_byte = 8; 68978d03027SSrujana Challa break; 69078d03027SSrujana Challa case RTE_CRYPTO_CIPHER_NULL: 69178d03027SSrujana Challa roundup_byte = 4; 69278d03027SSrujana Challa break; 69378d03027SSrujana Challa default: 69478d03027SSrujana Challa break; 69578d03027SSrujana Challa } 69678d03027SSrujana Challa 69778d03027SSrujana Challa return roundup_byte; 69878d03027SSrujana Challa } 69978d03027SSrujana Challa 70078d03027SSrujana Challa int 70178d03027SSrujana Challa cnxk_ipsec_outb_rlens_get(struct cnxk_ipsec_outb_rlens *rlens, 70278d03027SSrujana Challa struct rte_security_ipsec_xform *ipsec_xfrm, 70378d03027SSrujana Challa struct rte_crypto_sym_xform *crypto_xfrm) 70478d03027SSrujana Challa { 70578d03027SSrujana Challa struct rte_security_ipsec_tunnel_param *tunnel = &ipsec_xfrm->tunnel; 70678d03027SSrujana Challa enum rte_crypto_cipher_algorithm c_algo = RTE_CRYPTO_CIPHER_NULL; 70778d03027SSrujana Challa enum rte_crypto_auth_algorithm a_algo = RTE_CRYPTO_AUTH_NULL; 70878d03027SSrujana Challa enum rte_crypto_aead_algorithm aead_algo = 0; 70978d03027SSrujana Challa uint16_t partial_len = 0; 71078d03027SSrujana Challa uint8_t roundup_byte = 0; 71178d03027SSrujana Challa int8_t roundup_len = 0; 71278d03027SSrujana Challa 71378d03027SSrujana Challa memset(rlens, 0, sizeof(struct cnxk_ipsec_outb_rlens)); 71478d03027SSrujana Challa 71578d03027SSrujana Challa /* Get Cipher and Auth algo */ 71678d03027SSrujana Challa if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) { 71778d03027SSrujana Challa aead_algo = crypto_xfrm->aead.algo; 71878d03027SSrujana Challa } else { 71978d03027SSrujana Challa if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_CIPHER) 72078d03027SSrujana Challa c_algo = crypto_xfrm->cipher.algo; 72178d03027SSrujana Challa else 72278d03027SSrujana Challa a_algo = crypto_xfrm->auth.algo; 72378d03027SSrujana Challa 72478d03027SSrujana Challa if (crypto_xfrm->next) { 72578d03027SSrujana Challa if (crypto_xfrm->next->type == 72678d03027SSrujana Challa RTE_CRYPTO_SYM_XFORM_CIPHER) 72778d03027SSrujana Challa c_algo = crypto_xfrm->next->cipher.algo; 72878d03027SSrujana Challa else 72978d03027SSrujana Challa a_algo = crypto_xfrm->next->auth.algo; 73078d03027SSrujana Challa } 73178d03027SSrujana Challa } 73278d03027SSrujana Challa 73378d03027SSrujana Challa if (ipsec_xfrm->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP) { 73478d03027SSrujana Challa partial_len = ROC_CPT_ESP_HDR_LEN; 73578d03027SSrujana Challa roundup_len = ROC_CPT_ESP_TRL_LEN; 73678d03027SSrujana Challa } else { 73778d03027SSrujana Challa partial_len = ROC_CPT_AH_HDR_LEN; 73878d03027SSrujana Challa } 73978d03027SSrujana Challa 74078d03027SSrujana Challa if (ipsec_xfrm->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) { 74178d03027SSrujana Challa if (tunnel->type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) 74278d03027SSrujana Challa partial_len += ROC_CPT_TUNNEL_IPV4_HDR_LEN; 74378d03027SSrujana Challa else 74478d03027SSrujana Challa partial_len += ROC_CPT_TUNNEL_IPV6_HDR_LEN; 74578d03027SSrujana Challa } 74678d03027SSrujana Challa 74778d03027SSrujana Challa partial_len += cnxk_ipsec_ivlen_get(c_algo, a_algo, aead_algo); 74878d03027SSrujana Challa partial_len += cnxk_ipsec_icvlen_get(c_algo, a_algo, aead_algo); 74978d03027SSrujana Challa roundup_byte = cnxk_ipsec_outb_roundup_byte(c_algo, aead_algo); 75078d03027SSrujana Challa 7515c770471SSrujana Challa if (ipsec_xfrm->options.udp_encap) 7525c770471SSrujana Challa partial_len += sizeof(struct rte_udp_hdr); 7535c770471SSrujana Challa 75478d03027SSrujana Challa rlens->partial_len = partial_len; 75578d03027SSrujana Challa rlens->roundup_len = roundup_len; 75678d03027SSrujana Challa rlens->roundup_byte = roundup_byte; 75778d03027SSrujana Challa rlens->max_extended_len = partial_len + roundup_len + roundup_byte; 75878d03027SSrujana Challa return 0; 75978d03027SSrujana Challa } 760532963b8SVidya Sagar Velumuri 761532963b8SVidya Sagar Velumuri static inline int 762532963b8SVidya Sagar Velumuri on_ipsec_sa_ctl_set(struct rte_security_ipsec_xform *ipsec, 763532963b8SVidya Sagar Velumuri struct rte_crypto_sym_xform *crypto_xform, 764532963b8SVidya Sagar Velumuri struct roc_ie_on_sa_ctl *ctl) 765532963b8SVidya Sagar Velumuri { 766532963b8SVidya Sagar Velumuri struct rte_crypto_sym_xform *cipher_xform, *auth_xform; 767532963b8SVidya Sagar Velumuri int aes_key_len = 0; 768532963b8SVidya Sagar Velumuri 769532963b8SVidya Sagar Velumuri if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) { 770532963b8SVidya Sagar Velumuri auth_xform = crypto_xform; 771532963b8SVidya Sagar Velumuri cipher_xform = crypto_xform->next; 772532963b8SVidya Sagar Velumuri } else { 773532963b8SVidya Sagar Velumuri cipher_xform = crypto_xform; 774532963b8SVidya Sagar Velumuri auth_xform = crypto_xform->next; 775532963b8SVidya Sagar Velumuri } 776532963b8SVidya Sagar Velumuri 777532963b8SVidya Sagar Velumuri if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) 778532963b8SVidya Sagar Velumuri ctl->direction = ROC_IE_SA_DIR_OUTBOUND; 779532963b8SVidya Sagar Velumuri else 780532963b8SVidya Sagar Velumuri ctl->direction = ROC_IE_SA_DIR_INBOUND; 781532963b8SVidya Sagar Velumuri 782532963b8SVidya Sagar Velumuri if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) { 783532963b8SVidya Sagar Velumuri if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) 784532963b8SVidya Sagar Velumuri ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_4; 785532963b8SVidya Sagar Velumuri else if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV6) 786532963b8SVidya Sagar Velumuri ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_6; 787532963b8SVidya Sagar Velumuri else 788532963b8SVidya Sagar Velumuri return -EINVAL; 789532963b8SVidya Sagar Velumuri } 790532963b8SVidya Sagar Velumuri 791532963b8SVidya Sagar Velumuri if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) { 792532963b8SVidya Sagar Velumuri ctl->ipsec_mode = ROC_IE_SA_MODE_TRANSPORT; 793532963b8SVidya Sagar Velumuri ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_4; 794532963b8SVidya Sagar Velumuri } else if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) 795532963b8SVidya Sagar Velumuri ctl->ipsec_mode = ROC_IE_SA_MODE_TUNNEL; 796532963b8SVidya Sagar Velumuri else 797532963b8SVidya Sagar Velumuri return -EINVAL; 798532963b8SVidya Sagar Velumuri 799532963b8SVidya Sagar Velumuri if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH) 800532963b8SVidya Sagar Velumuri ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_AH; 801532963b8SVidya Sagar Velumuri else if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP) 802532963b8SVidya Sagar Velumuri ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_ESP; 803532963b8SVidya Sagar Velumuri else 804532963b8SVidya Sagar Velumuri return -EINVAL; 805532963b8SVidya Sagar Velumuri 806532963b8SVidya Sagar Velumuri if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) { 807532963b8SVidya Sagar Velumuri switch (crypto_xform->aead.algo) { 808532963b8SVidya Sagar Velumuri case RTE_CRYPTO_AEAD_AES_GCM: 809c31a9465SAnoob Joseph ctl->enc_type = ROC_IE_SA_ENC_AES_GCM; 810532963b8SVidya Sagar Velumuri aes_key_len = crypto_xform->aead.key.length; 811532963b8SVidya Sagar Velumuri break; 812246dea7eSArchana Muniganti case RTE_CRYPTO_AEAD_AES_CCM: 813c31a9465SAnoob Joseph ctl->enc_type = ROC_IE_SA_ENC_AES_CCM; 814246dea7eSArchana Muniganti aes_key_len = crypto_xform->aead.key.length; 815246dea7eSArchana Muniganti break; 816532963b8SVidya Sagar Velumuri default: 817532963b8SVidya Sagar Velumuri plt_err("Unsupported AEAD algorithm"); 818532963b8SVidya Sagar Velumuri return -ENOTSUP; 819532963b8SVidya Sagar Velumuri } 820532963b8SVidya Sagar Velumuri } else { 821532963b8SVidya Sagar Velumuri if (cipher_xform != NULL) { 822532963b8SVidya Sagar Velumuri switch (cipher_xform->cipher.algo) { 823532963b8SVidya Sagar Velumuri case RTE_CRYPTO_CIPHER_NULL: 824c31a9465SAnoob Joseph ctl->enc_type = ROC_IE_SA_ENC_NULL; 825532963b8SVidya Sagar Velumuri break; 826e1a9ff69SVidya Sagar Velumuri case RTE_CRYPTO_CIPHER_DES_CBC: 827c31a9465SAnoob Joseph ctl->enc_type = ROC_IE_SA_ENC_DES_CBC; 828e1a9ff69SVidya Sagar Velumuri break; 829e30c01fbSVidya Sagar Velumuri case RTE_CRYPTO_CIPHER_3DES_CBC: 830c31a9465SAnoob Joseph ctl->enc_type = ROC_IE_SA_ENC_3DES_CBC; 831e30c01fbSVidya Sagar Velumuri break; 832532963b8SVidya Sagar Velumuri case RTE_CRYPTO_CIPHER_AES_CBC: 833c31a9465SAnoob Joseph ctl->enc_type = ROC_IE_SA_ENC_AES_CBC; 834532963b8SVidya Sagar Velumuri aes_key_len = cipher_xform->cipher.key.length; 835532963b8SVidya Sagar Velumuri break; 836532963b8SVidya Sagar Velumuri case RTE_CRYPTO_CIPHER_AES_CTR: 837c31a9465SAnoob Joseph ctl->enc_type = ROC_IE_SA_ENC_AES_CTR; 838532963b8SVidya Sagar Velumuri aes_key_len = cipher_xform->cipher.key.length; 839532963b8SVidya Sagar Velumuri break; 840532963b8SVidya Sagar Velumuri default: 841532963b8SVidya Sagar Velumuri plt_err("Unsupported cipher algorithm"); 842532963b8SVidya Sagar Velumuri return -ENOTSUP; 843532963b8SVidya Sagar Velumuri } 844532963b8SVidya Sagar Velumuri } 845532963b8SVidya Sagar Velumuri 846532963b8SVidya Sagar Velumuri switch (auth_xform->auth.algo) { 847532963b8SVidya Sagar Velumuri case RTE_CRYPTO_AUTH_NULL: 848c31a9465SAnoob Joseph ctl->auth_type = ROC_IE_SA_AUTH_NULL; 849532963b8SVidya Sagar Velumuri break; 850532963b8SVidya Sagar Velumuri case RTE_CRYPTO_AUTH_MD5_HMAC: 851c31a9465SAnoob Joseph ctl->auth_type = ROC_IE_SA_AUTH_MD5; 852532963b8SVidya Sagar Velumuri break; 853532963b8SVidya Sagar Velumuri case RTE_CRYPTO_AUTH_SHA1_HMAC: 854c31a9465SAnoob Joseph ctl->auth_type = ROC_IE_SA_AUTH_SHA1; 855532963b8SVidya Sagar Velumuri break; 856532963b8SVidya Sagar Velumuri case RTE_CRYPTO_AUTH_SHA224_HMAC: 857c31a9465SAnoob Joseph ctl->auth_type = ROC_IE_SA_AUTH_SHA2_224; 858532963b8SVidya Sagar Velumuri break; 859532963b8SVidya Sagar Velumuri case RTE_CRYPTO_AUTH_SHA256_HMAC: 860c31a9465SAnoob Joseph ctl->auth_type = ROC_IE_SA_AUTH_SHA2_256; 861532963b8SVidya Sagar Velumuri break; 862532963b8SVidya Sagar Velumuri case RTE_CRYPTO_AUTH_SHA384_HMAC: 863c31a9465SAnoob Joseph ctl->auth_type = ROC_IE_SA_AUTH_SHA2_384; 864532963b8SVidya Sagar Velumuri break; 865532963b8SVidya Sagar Velumuri case RTE_CRYPTO_AUTH_SHA512_HMAC: 866c31a9465SAnoob Joseph ctl->auth_type = ROC_IE_SA_AUTH_SHA2_512; 867532963b8SVidya Sagar Velumuri break; 868532963b8SVidya Sagar Velumuri case RTE_CRYPTO_AUTH_AES_GMAC: 869c31a9465SAnoob Joseph ctl->auth_type = ROC_IE_SA_AUTH_AES_GMAC; 870532963b8SVidya Sagar Velumuri aes_key_len = auth_xform->auth.key.length; 871532963b8SVidya Sagar Velumuri break; 872532963b8SVidya Sagar Velumuri case RTE_CRYPTO_AUTH_AES_XCBC_MAC: 873c31a9465SAnoob Joseph ctl->auth_type = ROC_IE_SA_AUTH_AES_XCBC_128; 874532963b8SVidya Sagar Velumuri break; 875532963b8SVidya Sagar Velumuri default: 876532963b8SVidya Sagar Velumuri plt_err("Unsupported auth algorithm"); 877532963b8SVidya Sagar Velumuri return -ENOTSUP; 878532963b8SVidya Sagar Velumuri } 879532963b8SVidya Sagar Velumuri } 880532963b8SVidya Sagar Velumuri 881532963b8SVidya Sagar Velumuri /* Set AES key length */ 882c31a9465SAnoob Joseph if (ctl->enc_type == ROC_IE_SA_ENC_AES_CBC || ctl->enc_type == ROC_IE_SA_ENC_AES_CCM || 883c31a9465SAnoob Joseph ctl->enc_type == ROC_IE_SA_ENC_AES_CTR || ctl->enc_type == ROC_IE_SA_ENC_AES_GCM || 884c31a9465SAnoob Joseph ctl->enc_type == ROC_IE_SA_ENC_AES_CCM || ctl->auth_type == ROC_IE_SA_AUTH_AES_GMAC) { 885532963b8SVidya Sagar Velumuri switch (aes_key_len) { 886532963b8SVidya Sagar Velumuri case 16: 887532963b8SVidya Sagar Velumuri ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_128; 888532963b8SVidya Sagar Velumuri break; 889532963b8SVidya Sagar Velumuri case 24: 890532963b8SVidya Sagar Velumuri ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_192; 891532963b8SVidya Sagar Velumuri break; 892532963b8SVidya Sagar Velumuri case 32: 893532963b8SVidya Sagar Velumuri ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_256; 894532963b8SVidya Sagar Velumuri break; 895532963b8SVidya Sagar Velumuri default: 896532963b8SVidya Sagar Velumuri plt_err("Invalid AES key length"); 897532963b8SVidya Sagar Velumuri return -EINVAL; 898532963b8SVidya Sagar Velumuri } 899532963b8SVidya Sagar Velumuri } 900532963b8SVidya Sagar Velumuri 901532963b8SVidya Sagar Velumuri if (ipsec->options.esn) 902532963b8SVidya Sagar Velumuri ctl->esn_en = 1; 903532963b8SVidya Sagar Velumuri 904532963b8SVidya Sagar Velumuri if (ipsec->options.udp_encap == 1) 905532963b8SVidya Sagar Velumuri ctl->encap_type = ROC_IE_ON_SA_ENCAP_UDP; 906532963b8SVidya Sagar Velumuri 907532963b8SVidya Sagar Velumuri ctl->copy_df = ipsec->options.copy_df; 908532963b8SVidya Sagar Velumuri 909532963b8SVidya Sagar Velumuri ctl->spi = rte_cpu_to_be_32(ipsec->spi); 910532963b8SVidya Sagar Velumuri 911532963b8SVidya Sagar Velumuri rte_io_wmb(); 912532963b8SVidya Sagar Velumuri 913532963b8SVidya Sagar Velumuri ctl->valid = 1; 914532963b8SVidya Sagar Velumuri 915532963b8SVidya Sagar Velumuri return 0; 916532963b8SVidya Sagar Velumuri } 917532963b8SVidya Sagar Velumuri 918532963b8SVidya Sagar Velumuri static inline int 919532963b8SVidya Sagar Velumuri on_fill_ipsec_common_sa(struct rte_security_ipsec_xform *ipsec, 920532963b8SVidya Sagar Velumuri struct rte_crypto_sym_xform *crypto_xform, 921532963b8SVidya Sagar Velumuri struct roc_ie_on_common_sa *common_sa) 922532963b8SVidya Sagar Velumuri { 923532963b8SVidya Sagar Velumuri struct rte_crypto_sym_xform *cipher_xform, *auth_xform; 924532963b8SVidya Sagar Velumuri const uint8_t *cipher_key; 925532963b8SVidya Sagar Velumuri int cipher_key_len = 0; 926246dea7eSArchana Muniganti uint8_t ccm_flag = 0; 927532963b8SVidya Sagar Velumuri int ret; 928532963b8SVidya Sagar Velumuri 929532963b8SVidya Sagar Velumuri ret = on_ipsec_sa_ctl_set(ipsec, crypto_xform, &common_sa->ctl); 930532963b8SVidya Sagar Velumuri if (ret) 931532963b8SVidya Sagar Velumuri return ret; 932532963b8SVidya Sagar Velumuri 933532963b8SVidya Sagar Velumuri if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) { 934532963b8SVidya Sagar Velumuri auth_xform = crypto_xform; 935532963b8SVidya Sagar Velumuri cipher_xform = crypto_xform->next; 936532963b8SVidya Sagar Velumuri } else { 937532963b8SVidya Sagar Velumuri cipher_xform = crypto_xform; 938532963b8SVidya Sagar Velumuri auth_xform = crypto_xform->next; 939532963b8SVidya Sagar Velumuri } 940532963b8SVidya Sagar Velumuri 941532963b8SVidya Sagar Velumuri if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) { 942532963b8SVidya Sagar Velumuri if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) 943532963b8SVidya Sagar Velumuri memcpy(common_sa->iv.gcm.nonce, &ipsec->salt, 4); 944246dea7eSArchana Muniganti else if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_CCM) { 945246dea7eSArchana Muniganti ccm_flag = 0x07 & ~ROC_CPT_AES_CCM_CTR_LEN; 946246dea7eSArchana Muniganti *common_sa->iv.gcm.nonce = ccm_flag; 947246dea7eSArchana Muniganti memcpy(PLT_PTR_ADD(common_sa->iv.gcm.nonce, 1), &ipsec->salt, 3); 948246dea7eSArchana Muniganti } 949532963b8SVidya Sagar Velumuri cipher_key = crypto_xform->aead.key.data; 950532963b8SVidya Sagar Velumuri cipher_key_len = crypto_xform->aead.key.length; 951532963b8SVidya Sagar Velumuri } else { 952532963b8SVidya Sagar Velumuri if (cipher_xform) { 953532963b8SVidya Sagar Velumuri cipher_key = cipher_xform->cipher.key.data; 954532963b8SVidya Sagar Velumuri cipher_key_len = cipher_xform->cipher.key.length; 955532963b8SVidya Sagar Velumuri } 956532963b8SVidya Sagar Velumuri 957532963b8SVidya Sagar Velumuri if (auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) { 958532963b8SVidya Sagar Velumuri memcpy(common_sa->iv.gcm.nonce, &ipsec->salt, 4); 959532963b8SVidya Sagar Velumuri cipher_key = auth_xform->auth.key.data; 960532963b8SVidya Sagar Velumuri cipher_key_len = auth_xform->auth.key.length; 961532963b8SVidya Sagar Velumuri } 962532963b8SVidya Sagar Velumuri } 963532963b8SVidya Sagar Velumuri 964532963b8SVidya Sagar Velumuri if (cipher_key_len != 0) 965532963b8SVidya Sagar Velumuri memcpy(common_sa->cipher_key, cipher_key, cipher_key_len); 966532963b8SVidya Sagar Velumuri 967532963b8SVidya Sagar Velumuri return 0; 968532963b8SVidya Sagar Velumuri } 969532963b8SVidya Sagar Velumuri 970532963b8SVidya Sagar Velumuri int 971532963b8SVidya Sagar Velumuri cnxk_on_ipsec_outb_sa_create(struct rte_security_ipsec_xform *ipsec, 972532963b8SVidya Sagar Velumuri struct rte_crypto_sym_xform *crypto_xform, 973532963b8SVidya Sagar Velumuri struct roc_ie_on_outb_sa *out_sa) 974532963b8SVidya Sagar Velumuri { 975532963b8SVidya Sagar Velumuri struct roc_ie_on_ip_template *template = NULL; 976532963b8SVidya Sagar Velumuri struct rte_crypto_sym_xform *auth_xform; 977532963b8SVidya Sagar Velumuri struct roc_ie_on_sa_ctl *ctl; 978532963b8SVidya Sagar Velumuri struct rte_ipv6_hdr *ip6; 979532963b8SVidya Sagar Velumuri struct rte_ipv4_hdr *ip4; 98039ae58f2SVidya Sagar Velumuri uint16_t sport, dport; 981532963b8SVidya Sagar Velumuri size_t ctx_len; 982532963b8SVidya Sagar Velumuri int ret; 983532963b8SVidya Sagar Velumuri 984532963b8SVidya Sagar Velumuri ctl = &out_sa->common_sa.ctl; 985532963b8SVidya Sagar Velumuri 986532963b8SVidya Sagar Velumuri if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) 987532963b8SVidya Sagar Velumuri auth_xform = crypto_xform; 988532963b8SVidya Sagar Velumuri else 989532963b8SVidya Sagar Velumuri auth_xform = crypto_xform->next; 990532963b8SVidya Sagar Velumuri 991532963b8SVidya Sagar Velumuri ret = on_fill_ipsec_common_sa(ipsec, crypto_xform, &out_sa->common_sa); 992532963b8SVidya Sagar Velumuri if (ret) 993532963b8SVidya Sagar Velumuri return ret; 994532963b8SVidya Sagar Velumuri 995c31a9465SAnoob Joseph if (ctl->enc_type == ROC_IE_SA_ENC_AES_GCM || ctl->enc_type == ROC_IE_SA_ENC_AES_CCM || 996c31a9465SAnoob Joseph ctl->auth_type == ROC_IE_SA_AUTH_NULL || ctl->auth_type == ROC_IE_SA_AUTH_AES_GMAC) { 997532963b8SVidya Sagar Velumuri template = &out_sa->aes_gcm.template; 998532963b8SVidya Sagar Velumuri ctx_len = offsetof(struct roc_ie_on_outb_sa, aes_gcm.template); 999532963b8SVidya Sagar Velumuri } else { 1000532963b8SVidya Sagar Velumuri switch (ctl->auth_type) { 1001c31a9465SAnoob Joseph case ROC_IE_SA_AUTH_MD5: 1002c31a9465SAnoob Joseph case ROC_IE_SA_AUTH_SHA1: 1003532963b8SVidya Sagar Velumuri template = &out_sa->sha1.template; 1004c31a9465SAnoob Joseph ctx_len = offsetof(struct roc_ie_on_outb_sa, sha1.template); 1005532963b8SVidya Sagar Velumuri break; 1006c31a9465SAnoob Joseph case ROC_IE_SA_AUTH_SHA2_256: 1007c31a9465SAnoob Joseph case ROC_IE_SA_AUTH_SHA2_384: 1008c31a9465SAnoob Joseph case ROC_IE_SA_AUTH_SHA2_512: 1009532963b8SVidya Sagar Velumuri template = &out_sa->sha2.template; 1010c31a9465SAnoob Joseph ctx_len = offsetof(struct roc_ie_on_outb_sa, sha2.template); 1011532963b8SVidya Sagar Velumuri break; 1012c31a9465SAnoob Joseph case ROC_IE_SA_AUTH_AES_XCBC_128: 1013532963b8SVidya Sagar Velumuri template = &out_sa->aes_xcbc.template; 1014c31a9465SAnoob Joseph ctx_len = offsetof(struct roc_ie_on_outb_sa, aes_xcbc.template); 1015532963b8SVidya Sagar Velumuri break; 1016532963b8SVidya Sagar Velumuri default: 1017532963b8SVidya Sagar Velumuri plt_err("Unsupported auth algorithm"); 1018532963b8SVidya Sagar Velumuri return -EINVAL; 1019532963b8SVidya Sagar Velumuri } 1020532963b8SVidya Sagar Velumuri } 1021532963b8SVidya Sagar Velumuri 1022532963b8SVidya Sagar Velumuri ip4 = (struct rte_ipv4_hdr *)&template->ip4.ipv4_hdr; 102339ae58f2SVidya Sagar Velumuri 102439ae58f2SVidya Sagar Velumuri sport = 4500; 102539ae58f2SVidya Sagar Velumuri dport = 4500; 102639ae58f2SVidya Sagar Velumuri 102739ae58f2SVidya Sagar Velumuri /* If custom port values are provided, Overwrite default port values. */ 1028532963b8SVidya Sagar Velumuri if (ipsec->options.udp_encap) { 102939ae58f2SVidya Sagar Velumuri 103039ae58f2SVidya Sagar Velumuri if (ipsec->udp.sport) 103139ae58f2SVidya Sagar Velumuri sport = ipsec->udp.sport; 103239ae58f2SVidya Sagar Velumuri 103339ae58f2SVidya Sagar Velumuri if (ipsec->udp.dport) 103439ae58f2SVidya Sagar Velumuri dport = ipsec->udp.dport; 103539ae58f2SVidya Sagar Velumuri 1036532963b8SVidya Sagar Velumuri ip4->next_proto_id = IPPROTO_UDP; 103739ae58f2SVidya Sagar Velumuri template->ip4.udp_src = rte_be_to_cpu_16(sport); 103839ae58f2SVidya Sagar Velumuri template->ip4.udp_dst = rte_be_to_cpu_16(dport); 1039532963b8SVidya Sagar Velumuri } else { 1040532963b8SVidya Sagar Velumuri if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH) 1041532963b8SVidya Sagar Velumuri ip4->next_proto_id = IPPROTO_AH; 1042532963b8SVidya Sagar Velumuri else 1043532963b8SVidya Sagar Velumuri ip4->next_proto_id = IPPROTO_ESP; 1044532963b8SVidya Sagar Velumuri } 1045532963b8SVidya Sagar Velumuri 1046532963b8SVidya Sagar Velumuri if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) { 1047532963b8SVidya Sagar Velumuri if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) { 1048532963b8SVidya Sagar Velumuri uint16_t frag_off = 0; 1049532963b8SVidya Sagar Velumuri 1050532963b8SVidya Sagar Velumuri ctx_len += sizeof(template->ip4); 1051532963b8SVidya Sagar Velumuri 1052532963b8SVidya Sagar Velumuri ip4->version_ihl = RTE_IPV4_VHL_DEF; 10534440eb88SVidya Sagar Velumuri ip4->time_to_live = ipsec->tunnel.ipv4.ttl ? 10544440eb88SVidya Sagar Velumuri ipsec->tunnel.ipv4.ttl : 10554440eb88SVidya Sagar Velumuri 0x40; 1056532963b8SVidya Sagar Velumuri ip4->type_of_service |= (ipsec->tunnel.ipv4.dscp << 2); 1057532963b8SVidya Sagar Velumuri if (ipsec->tunnel.ipv4.df) 1058532963b8SVidya Sagar Velumuri frag_off |= RTE_IPV4_HDR_DF_FLAG; 1059532963b8SVidya Sagar Velumuri ip4->fragment_offset = rte_cpu_to_be_16(frag_off); 1060532963b8SVidya Sagar Velumuri 1061532963b8SVidya Sagar Velumuri memcpy(&ip4->src_addr, &ipsec->tunnel.ipv4.src_ip, 1062532963b8SVidya Sagar Velumuri sizeof(struct in_addr)); 1063532963b8SVidya Sagar Velumuri memcpy(&ip4->dst_addr, &ipsec->tunnel.ipv4.dst_ip, 1064532963b8SVidya Sagar Velumuri sizeof(struct in_addr)); 1065532963b8SVidya Sagar Velumuri } else if (ipsec->tunnel.type == 1066532963b8SVidya Sagar Velumuri RTE_SECURITY_IPSEC_TUNNEL_IPV6) { 1067532963b8SVidya Sagar Velumuri ctx_len += sizeof(template->ip6); 1068532963b8SVidya Sagar Velumuri 1069532963b8SVidya Sagar Velumuri ip6 = (struct rte_ipv6_hdr *)&template->ip6.ipv6_hdr; 1070532963b8SVidya Sagar Velumuri if (ipsec->options.udp_encap) { 1071532963b8SVidya Sagar Velumuri ip6->proto = IPPROTO_UDP; 107239ae58f2SVidya Sagar Velumuri template->ip6.udp_src = rte_be_to_cpu_16(sport); 107339ae58f2SVidya Sagar Velumuri template->ip6.udp_dst = rte_be_to_cpu_16(dport); 1074532963b8SVidya Sagar Velumuri } else { 107539ae58f2SVidya Sagar Velumuri ip6->proto = (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP) ? 1076532963b8SVidya Sagar Velumuri IPPROTO_ESP : 1077532963b8SVidya Sagar Velumuri IPPROTO_AH; 1078532963b8SVidya Sagar Velumuri } 1079532963b8SVidya Sagar Velumuri ip6->vtc_flow = 1080532963b8SVidya Sagar Velumuri rte_cpu_to_be_32(0x60000000 | 1081532963b8SVidya Sagar Velumuri ((ipsec->tunnel.ipv6.dscp 1082532963b8SVidya Sagar Velumuri << RTE_IPV6_HDR_TC_SHIFT) & 1083532963b8SVidya Sagar Velumuri RTE_IPV6_HDR_TC_MASK) | 1084532963b8SVidya Sagar Velumuri ((ipsec->tunnel.ipv6.flabel 1085532963b8SVidya Sagar Velumuri << RTE_IPV6_HDR_FL_SHIFT) & 1086532963b8SVidya Sagar Velumuri RTE_IPV6_HDR_FL_MASK)); 10874440eb88SVidya Sagar Velumuri ip6->hop_limits = ipsec->tunnel.ipv6.hlimit ? 10884440eb88SVidya Sagar Velumuri ipsec->tunnel.ipv6.hlimit : 10894440eb88SVidya Sagar Velumuri 0x40; 1090*2ede1422SRobin Jarry ip6->src_addr = ipsec->tunnel.ipv6.src_addr; 1091*2ede1422SRobin Jarry ip6->dst_addr = ipsec->tunnel.ipv6.dst_addr; 1092532963b8SVidya Sagar Velumuri } 1093532963b8SVidya Sagar Velumuri } else 1094532963b8SVidya Sagar Velumuri ctx_len += sizeof(template->ip4); 1095532963b8SVidya Sagar Velumuri 1096a7c3c42cSVidya Sagar Velumuri ctx_len = RTE_ALIGN_CEIL(ctx_len, 8); 1097532963b8SVidya Sagar Velumuri 1098532963b8SVidya Sagar Velumuri if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AEAD) { 1099729085b5SVidya Sagar Velumuri uint8_t *hmac_opad_ipad = (uint8_t *)&out_sa->sha2; 1100532963b8SVidya Sagar Velumuri 1101729085b5SVidya Sagar Velumuri if (auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_XCBC_MAC) { 1102729085b5SVidya Sagar Velumuri const uint8_t *auth_key = auth_xform->auth.key.data; 1103729085b5SVidya Sagar Velumuri 1104729085b5SVidya Sagar Velumuri roc_aes_xcbc_key_derive(auth_key, hmac_opad_ipad); 1105729085b5SVidya Sagar Velumuri } else if (auth_xform->auth.algo != RTE_CRYPTO_AUTH_NULL) { 1106df22fe29SVidya Sagar Velumuri roc_se_hmac_opad_ipad_gen( 1107df22fe29SVidya Sagar Velumuri out_sa->common_sa.ctl.auth_type, auth_xform->auth.key.data, 1108df22fe29SVidya Sagar Velumuri auth_xform->auth.key.length, &hmac_opad_ipad[0], ROC_SE_IPSEC); 1109532963b8SVidya Sagar Velumuri } 1110532963b8SVidya Sagar Velumuri } 1111532963b8SVidya Sagar Velumuri 1112532963b8SVidya Sagar Velumuri return ctx_len; 1113532963b8SVidya Sagar Velumuri } 1114532963b8SVidya Sagar Velumuri 1115532963b8SVidya Sagar Velumuri int 1116532963b8SVidya Sagar Velumuri cnxk_on_ipsec_inb_sa_create(struct rte_security_ipsec_xform *ipsec, 1117532963b8SVidya Sagar Velumuri struct rte_crypto_sym_xform *crypto_xform, 1118532963b8SVidya Sagar Velumuri struct roc_ie_on_inb_sa *in_sa) 1119532963b8SVidya Sagar Velumuri { 1120532963b8SVidya Sagar Velumuri struct rte_crypto_sym_xform *auth_xform = crypto_xform; 1121532963b8SVidya Sagar Velumuri const uint8_t *auth_key; 1122532963b8SVidya Sagar Velumuri int auth_key_len = 0; 1123532963b8SVidya Sagar Velumuri size_t ctx_len = 0; 1124532963b8SVidya Sagar Velumuri int ret; 1125532963b8SVidya Sagar Velumuri 1126532963b8SVidya Sagar Velumuri ret = on_fill_ipsec_common_sa(ipsec, crypto_xform, &in_sa->common_sa); 1127532963b8SVidya Sagar Velumuri if (ret) 1128532963b8SVidya Sagar Velumuri return ret; 1129532963b8SVidya Sagar Velumuri 113028cd6c62SSrujana Challa if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AEAD && 113128cd6c62SSrujana Challa crypto_xform->auth.algo == RTE_CRYPTO_AUTH_NULL && ipsec->replay_win_sz) { 113228cd6c62SSrujana Challa plt_err("anti-replay can't be supported with integrity service disabled"); 113328cd6c62SSrujana Challa return -EINVAL; 113428cd6c62SSrujana Challa } 1135532963b8SVidya Sagar Velumuri if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD || 1136532963b8SVidya Sagar Velumuri auth_xform->auth.algo == RTE_CRYPTO_AUTH_NULL || 1137532963b8SVidya Sagar Velumuri auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) { 1138729085b5SVidya Sagar Velumuri ctx_len = offsetof(struct roc_ie_on_inb_sa, sha1_or_gcm.hmac_key[0]); 1139532963b8SVidya Sagar Velumuri } else { 1140729085b5SVidya Sagar Velumuri uint8_t *hmac_opad_ipad = (uint8_t *)&in_sa->sha2; 1141532963b8SVidya Sagar Velumuri auth_key = auth_xform->auth.key.data; 1142532963b8SVidya Sagar Velumuri auth_key_len = auth_xform->auth.key.length; 1143532963b8SVidya Sagar Velumuri 1144532963b8SVidya Sagar Velumuri switch (auth_xform->auth.algo) { 1145532963b8SVidya Sagar Velumuri case RTE_CRYPTO_AUTH_NULL: 1146532963b8SVidya Sagar Velumuri break; 1147fe87c455SVidya Sagar Velumuri case RTE_CRYPTO_AUTH_MD5_HMAC: 1148532963b8SVidya Sagar Velumuri case RTE_CRYPTO_AUTH_SHA1_HMAC: 1149532963b8SVidya Sagar Velumuri memcpy(in_sa->sha1_or_gcm.hmac_key, auth_key, 1150532963b8SVidya Sagar Velumuri auth_key_len); 1151532963b8SVidya Sagar Velumuri ctx_len = offsetof(struct roc_ie_on_inb_sa, 1152532963b8SVidya Sagar Velumuri sha1_or_gcm.selector); 1153532963b8SVidya Sagar Velumuri break; 1154532963b8SVidya Sagar Velumuri case RTE_CRYPTO_AUTH_SHA256_HMAC: 1155532963b8SVidya Sagar Velumuri case RTE_CRYPTO_AUTH_SHA384_HMAC: 1156532963b8SVidya Sagar Velumuri case RTE_CRYPTO_AUTH_SHA512_HMAC: 1157532963b8SVidya Sagar Velumuri memcpy(in_sa->sha2.hmac_key, auth_key, auth_key_len); 1158532963b8SVidya Sagar Velumuri ctx_len = offsetof(struct roc_ie_on_inb_sa, 1159532963b8SVidya Sagar Velumuri sha2.selector); 1160532963b8SVidya Sagar Velumuri break; 1161532963b8SVidya Sagar Velumuri case RTE_CRYPTO_AUTH_AES_XCBC_MAC: 1162532963b8SVidya Sagar Velumuri memcpy(in_sa->aes_xcbc.key, auth_key, auth_key_len); 1163532963b8SVidya Sagar Velumuri ctx_len = offsetof(struct roc_ie_on_inb_sa, 1164532963b8SVidya Sagar Velumuri aes_xcbc.selector); 1165532963b8SVidya Sagar Velumuri break; 1166532963b8SVidya Sagar Velumuri default: 1167729085b5SVidya Sagar Velumuri plt_err("Unsupported auth algorithm %u", auth_xform->auth.algo); 1168532963b8SVidya Sagar Velumuri return -ENOTSUP; 1169532963b8SVidya Sagar Velumuri } 1170729085b5SVidya Sagar Velumuri if (auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_XCBC_MAC) { 1171729085b5SVidya Sagar Velumuri const uint8_t *auth_key = auth_xform->auth.key.data; 1172729085b5SVidya Sagar Velumuri 1173729085b5SVidya Sagar Velumuri roc_aes_xcbc_key_derive(auth_key, hmac_opad_ipad); 1174729085b5SVidya Sagar Velumuri } else if (auth_xform->auth.algo != RTE_CRYPTO_AUTH_NULL) { 1175df22fe29SVidya Sagar Velumuri roc_se_hmac_opad_ipad_gen( 1176df22fe29SVidya Sagar Velumuri in_sa->common_sa.ctl.auth_type, auth_xform->auth.key.data, 1177df22fe29SVidya Sagar Velumuri auth_xform->auth.key.length, &hmac_opad_ipad[0], ROC_SE_IPSEC); 1178729085b5SVidya Sagar Velumuri } 1179532963b8SVidya Sagar Velumuri } 1180532963b8SVidya Sagar Velumuri 1181532963b8SVidya Sagar Velumuri return ctx_len; 1182532963b8SVidya Sagar Velumuri } 1183