1474f1202SAnoob Joseph /* SPDX-License-Identifier: BSD-3-Clause 2474f1202SAnoob Joseph * Copyright(C) 2021 Marvell. 3474f1202SAnoob Joseph */ 4474f1202SAnoob Joseph 5474f1202SAnoob Joseph #include <rte_common.h> 6474f1202SAnoob Joseph #include <rte_cryptodev.h> 7cd928003STejasree Kondoj #include <rte_esp.h> 8474f1202SAnoob Joseph #include <rte_ip.h> 9474f1202SAnoob Joseph #include <rte_security.h> 1083243502SArchana Muniganti #include <rte_tcp.h> 11c8234341STejasree Kondoj #include <rte_udp.h> 12474f1202SAnoob Joseph 13474f1202SAnoob Joseph #include "test.h" 14474f1202SAnoob Joseph #include "test_cryptodev_security_ipsec.h" 15474f1202SAnoob Joseph 16cd928003STejasree Kondoj #define IV_LEN_MAX 16 17cd928003STejasree Kondoj 18456ed793STyler Retzlaff #ifndef IPVERSION 19456ed793STyler Retzlaff #define IPVERSION 4 20456ed793STyler Retzlaff #endif 21456ed793STyler Retzlaff 228d290523SAnoob Joseph struct crypto_param_comb alg_list[RTE_DIM(aead_list) + 238d290523SAnoob Joseph (RTE_DIM(cipher_list) * 248d290523SAnoob Joseph RTE_DIM(auth_list))]; 258d290523SAnoob Joseph 26663d78beSArchana Muniganti struct crypto_param_comb ah_alg_list[2 * (RTE_DIM(auth_list) - 1)]; 27663d78beSArchana Muniganti 289fb87fbfSTejasree Kondoj static bool 299fb87fbfSTejasree Kondoj is_valid_ipv4_pkt(const struct rte_ipv4_hdr *pkt) 309fb87fbfSTejasree Kondoj { 319fb87fbfSTejasree Kondoj /* The IP version number must be 4 */ 329fb87fbfSTejasree Kondoj if (((pkt->version_ihl) >> 4) != 4) 339fb87fbfSTejasree Kondoj return false; 349fb87fbfSTejasree Kondoj /* 359fb87fbfSTejasree Kondoj * The IP header length field must be large enough to hold the 369fb87fbfSTejasree Kondoj * minimum length legal IP datagram (20 bytes = 5 words). 379fb87fbfSTejasree Kondoj */ 389fb87fbfSTejasree Kondoj if ((pkt->version_ihl & 0xf) < 5) 399fb87fbfSTejasree Kondoj return false; 409fb87fbfSTejasree Kondoj 419fb87fbfSTejasree Kondoj /* 429fb87fbfSTejasree Kondoj * The IP total length field must be large enough to hold the IP 439fb87fbfSTejasree Kondoj * datagram header, whose length is specified in the IP header length 449fb87fbfSTejasree Kondoj * field. 459fb87fbfSTejasree Kondoj */ 469fb87fbfSTejasree Kondoj if (rte_cpu_to_be_16(pkt->total_length) < sizeof(struct rte_ipv4_hdr)) 479fb87fbfSTejasree Kondoj return false; 489fb87fbfSTejasree Kondoj 499fb87fbfSTejasree Kondoj return true; 509fb87fbfSTejasree Kondoj } 519fb87fbfSTejasree Kondoj 529fb87fbfSTejasree Kondoj static bool 539fb87fbfSTejasree Kondoj is_valid_ipv6_pkt(const struct rte_ipv6_hdr *pkt) 549fb87fbfSTejasree Kondoj { 559fb87fbfSTejasree Kondoj /* The IP version number must be 6 */ 569fb87fbfSTejasree Kondoj if ((rte_be_to_cpu_32((pkt->vtc_flow)) >> 28) != 6) 579fb87fbfSTejasree Kondoj return false; 589fb87fbfSTejasree Kondoj 599fb87fbfSTejasree Kondoj return true; 609fb87fbfSTejasree Kondoj } 619fb87fbfSTejasree Kondoj 628d290523SAnoob Joseph void 638d290523SAnoob Joseph test_ipsec_alg_list_populate(void) 648d290523SAnoob Joseph { 658d290523SAnoob Joseph unsigned long i, j, index = 0; 668d290523SAnoob Joseph 678d290523SAnoob Joseph for (i = 0; i < RTE_DIM(aead_list); i++) { 688d290523SAnoob Joseph alg_list[index].param1 = &aead_list[i]; 698d290523SAnoob Joseph alg_list[index].param2 = NULL; 708d290523SAnoob Joseph index++; 718d290523SAnoob Joseph } 728d290523SAnoob Joseph 738d290523SAnoob Joseph for (i = 0; i < RTE_DIM(cipher_list); i++) { 748d290523SAnoob Joseph for (j = 0; j < RTE_DIM(auth_list); j++) { 758d290523SAnoob Joseph alg_list[index].param1 = &cipher_list[i]; 768d290523SAnoob Joseph alg_list[index].param2 = &auth_list[j]; 778d290523SAnoob Joseph index++; 788d290523SAnoob Joseph } 798d290523SAnoob Joseph } 808d290523SAnoob Joseph } 816622d9c9SAnoob Joseph 82663d78beSArchana Muniganti void 83663d78beSArchana Muniganti test_ipsec_ah_alg_list_populate(void) 84663d78beSArchana Muniganti { 85663d78beSArchana Muniganti unsigned long i, index = 0; 86663d78beSArchana Muniganti 87663d78beSArchana Muniganti for (i = 1; i < RTE_DIM(auth_list); i++) { 88663d78beSArchana Muniganti ah_alg_list[index].param1 = &auth_list[i]; 89663d78beSArchana Muniganti ah_alg_list[index].param2 = NULL; 90663d78beSArchana Muniganti index++; 91663d78beSArchana Muniganti } 92663d78beSArchana Muniganti 93663d78beSArchana Muniganti for (i = 1; i < RTE_DIM(auth_list); i++) { 94663d78beSArchana Muniganti /* NULL cipher */ 95663d78beSArchana Muniganti ah_alg_list[index].param1 = &cipher_list[0]; 96663d78beSArchana Muniganti 97663d78beSArchana Muniganti ah_alg_list[index].param2 = &auth_list[i]; 98663d78beSArchana Muniganti index++; 99663d78beSArchana Muniganti } 100663d78beSArchana Muniganti } 101663d78beSArchana Muniganti 102474f1202SAnoob Joseph int 103474f1202SAnoob Joseph test_ipsec_sec_caps_verify(struct rte_security_ipsec_xform *ipsec_xform, 104474f1202SAnoob Joseph const struct rte_security_capability *sec_cap, 105474f1202SAnoob Joseph bool silent) 106474f1202SAnoob Joseph { 107474f1202SAnoob Joseph /* Verify security capabilities */ 108474f1202SAnoob Joseph 109474f1202SAnoob Joseph if (ipsec_xform->options.esn == 1 && sec_cap->ipsec.options.esn == 0) { 110474f1202SAnoob Joseph if (!silent) 111474f1202SAnoob Joseph RTE_LOG(INFO, USER1, "ESN is not supported\n"); 112474f1202SAnoob Joseph return -ENOTSUP; 113474f1202SAnoob Joseph } 114474f1202SAnoob Joseph 115474f1202SAnoob Joseph if (ipsec_xform->options.udp_encap == 1 && 116474f1202SAnoob Joseph sec_cap->ipsec.options.udp_encap == 0) { 117474f1202SAnoob Joseph if (!silent) 118474f1202SAnoob Joseph RTE_LOG(INFO, USER1, "UDP encapsulation is not supported\n"); 119474f1202SAnoob Joseph return -ENOTSUP; 120474f1202SAnoob Joseph } 121474f1202SAnoob Joseph 1229ec50a52STejasree Kondoj if (ipsec_xform->options.udp_ports_verify == 1 && 1239ec50a52STejasree Kondoj sec_cap->ipsec.options.udp_ports_verify == 0) { 1249ec50a52STejasree Kondoj if (!silent) 1259ec50a52STejasree Kondoj RTE_LOG(INFO, USER1, "UDP encapsulation ports " 1269ec50a52STejasree Kondoj "verification is not supported\n"); 1279ec50a52STejasree Kondoj return -ENOTSUP; 1289ec50a52STejasree Kondoj } 1299ec50a52STejasree Kondoj 130474f1202SAnoob Joseph if (ipsec_xform->options.copy_dscp == 1 && 131474f1202SAnoob Joseph sec_cap->ipsec.options.copy_dscp == 0) { 132474f1202SAnoob Joseph if (!silent) 133474f1202SAnoob Joseph RTE_LOG(INFO, USER1, "Copy DSCP is not supported\n"); 134474f1202SAnoob Joseph return -ENOTSUP; 135474f1202SAnoob Joseph } 136474f1202SAnoob Joseph 137474f1202SAnoob Joseph if (ipsec_xform->options.copy_flabel == 1 && 138474f1202SAnoob Joseph sec_cap->ipsec.options.copy_flabel == 0) { 139474f1202SAnoob Joseph if (!silent) 140474f1202SAnoob Joseph RTE_LOG(INFO, USER1, "Copy Flow Label is not supported\n"); 141474f1202SAnoob Joseph return -ENOTSUP; 142474f1202SAnoob Joseph } 143474f1202SAnoob Joseph 144474f1202SAnoob Joseph if (ipsec_xform->options.copy_df == 1 && 145474f1202SAnoob Joseph sec_cap->ipsec.options.copy_df == 0) { 146474f1202SAnoob Joseph if (!silent) 147474f1202SAnoob Joseph RTE_LOG(INFO, USER1, "Copy DP bit is not supported\n"); 148474f1202SAnoob Joseph return -ENOTSUP; 149474f1202SAnoob Joseph } 150474f1202SAnoob Joseph 151474f1202SAnoob Joseph if (ipsec_xform->options.dec_ttl == 1 && 152474f1202SAnoob Joseph sec_cap->ipsec.options.dec_ttl == 0) { 153474f1202SAnoob Joseph if (!silent) 154474f1202SAnoob Joseph RTE_LOG(INFO, USER1, "Decrement TTL is not supported\n"); 155474f1202SAnoob Joseph return -ENOTSUP; 156474f1202SAnoob Joseph } 157474f1202SAnoob Joseph 158474f1202SAnoob Joseph if (ipsec_xform->options.ecn == 1 && sec_cap->ipsec.options.ecn == 0) { 159474f1202SAnoob Joseph if (!silent) 160474f1202SAnoob Joseph RTE_LOG(INFO, USER1, "ECN is not supported\n"); 161474f1202SAnoob Joseph return -ENOTSUP; 162474f1202SAnoob Joseph } 163474f1202SAnoob Joseph 164474f1202SAnoob Joseph if (ipsec_xform->options.stats == 1 && 165474f1202SAnoob Joseph sec_cap->ipsec.options.stats == 0) { 166474f1202SAnoob Joseph if (!silent) 167474f1202SAnoob Joseph RTE_LOG(INFO, USER1, "Stats is not supported\n"); 168474f1202SAnoob Joseph return -ENOTSUP; 169474f1202SAnoob Joseph } 170474f1202SAnoob Joseph 1710532f50cSAnoob Joseph if ((ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) && 1720532f50cSAnoob Joseph (ipsec_xform->options.iv_gen_disable == 1) && 1730532f50cSAnoob Joseph (sec_cap->ipsec.options.iv_gen_disable != 1)) { 1740532f50cSAnoob Joseph if (!silent) 1750532f50cSAnoob Joseph RTE_LOG(INFO, USER1, 1760532f50cSAnoob Joseph "Application provided IV is not supported\n"); 1770532f50cSAnoob Joseph return -ENOTSUP; 1780532f50cSAnoob Joseph } 1790532f50cSAnoob Joseph 180270470eeSTejasree Kondoj if ((ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) && 181270470eeSTejasree Kondoj (ipsec_xform->options.tunnel_hdr_verify > 182270470eeSTejasree Kondoj sec_cap->ipsec.options.tunnel_hdr_verify)) { 183270470eeSTejasree Kondoj if (!silent) 184270470eeSTejasree Kondoj RTE_LOG(INFO, USER1, 185270470eeSTejasree Kondoj "Tunnel header verify is not supported\n"); 186270470eeSTejasree Kondoj return -ENOTSUP; 187270470eeSTejasree Kondoj } 188270470eeSTejasree Kondoj 18983243502SArchana Muniganti if (ipsec_xform->options.ip_csum_enable == 1 && 19083243502SArchana Muniganti sec_cap->ipsec.options.ip_csum_enable == 0) { 19183243502SArchana Muniganti if (!silent) 19283243502SArchana Muniganti RTE_LOG(INFO, USER1, 19383243502SArchana Muniganti "Inner IP checksum is not supported\n"); 19483243502SArchana Muniganti return -ENOTSUP; 19583243502SArchana Muniganti } 19683243502SArchana Muniganti 19783243502SArchana Muniganti if (ipsec_xform->options.l4_csum_enable == 1 && 19883243502SArchana Muniganti sec_cap->ipsec.options.l4_csum_enable == 0) { 19983243502SArchana Muniganti if (!silent) 20083243502SArchana Muniganti RTE_LOG(INFO, USER1, 20183243502SArchana Muniganti "Inner L4 checksum is not supported\n"); 20283243502SArchana Muniganti return -ENOTSUP; 20383243502SArchana Muniganti } 20483243502SArchana Muniganti 205d02c6bfcSTejasree Kondoj if (ipsec_xform->replay_win_sz > sec_cap->ipsec.replay_win_sz_max) { 206d02c6bfcSTejasree Kondoj if (!silent) 207d02c6bfcSTejasree Kondoj RTE_LOG(INFO, USER1, 208d02c6bfcSTejasree Kondoj "Replay window size is not supported\n"); 209d02c6bfcSTejasree Kondoj return -ENOTSUP; 210d02c6bfcSTejasree Kondoj } 211d02c6bfcSTejasree Kondoj 212474f1202SAnoob Joseph return 0; 213474f1202SAnoob Joseph } 214474f1202SAnoob Joseph 215474f1202SAnoob Joseph int 216474f1202SAnoob Joseph test_ipsec_crypto_caps_aead_verify( 217474f1202SAnoob Joseph const struct rte_security_capability *sec_cap, 218474f1202SAnoob Joseph struct rte_crypto_sym_xform *aead) 219474f1202SAnoob Joseph { 220474f1202SAnoob Joseph const struct rte_cryptodev_symmetric_capability *sym_cap; 221474f1202SAnoob Joseph const struct rte_cryptodev_capabilities *crypto_cap; 222474f1202SAnoob Joseph int j = 0; 223474f1202SAnoob Joseph 224474f1202SAnoob Joseph while ((crypto_cap = &sec_cap->crypto_capabilities[j++])->op != 225474f1202SAnoob Joseph RTE_CRYPTO_OP_TYPE_UNDEFINED) { 226474f1202SAnoob Joseph if (crypto_cap->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC && 227474f1202SAnoob Joseph crypto_cap->sym.xform_type == aead->type && 228474f1202SAnoob Joseph crypto_cap->sym.aead.algo == aead->aead.algo) { 229474f1202SAnoob Joseph sym_cap = &crypto_cap->sym; 230474f1202SAnoob Joseph if (rte_cryptodev_sym_capability_check_aead(sym_cap, 231474f1202SAnoob Joseph aead->aead.key.length, 232474f1202SAnoob Joseph aead->aead.digest_length, 233474f1202SAnoob Joseph aead->aead.aad_length, 234474f1202SAnoob Joseph aead->aead.iv.length) == 0) 235474f1202SAnoob Joseph return 0; 236474f1202SAnoob Joseph } 237474f1202SAnoob Joseph } 238474f1202SAnoob Joseph 239474f1202SAnoob Joseph return -ENOTSUP; 240474f1202SAnoob Joseph } 241474f1202SAnoob Joseph 24267d2a188SAnoob Joseph int 24367d2a188SAnoob Joseph test_ipsec_crypto_caps_cipher_verify( 24467d2a188SAnoob Joseph const struct rte_security_capability *sec_cap, 24567d2a188SAnoob Joseph struct rte_crypto_sym_xform *cipher) 24667d2a188SAnoob Joseph { 24767d2a188SAnoob Joseph const struct rte_cryptodev_symmetric_capability *sym_cap; 24867d2a188SAnoob Joseph const struct rte_cryptodev_capabilities *cap; 24967d2a188SAnoob Joseph int j = 0; 25067d2a188SAnoob Joseph 25167d2a188SAnoob Joseph while ((cap = &sec_cap->crypto_capabilities[j++])->op != 25267d2a188SAnoob Joseph RTE_CRYPTO_OP_TYPE_UNDEFINED) { 25367d2a188SAnoob Joseph if (cap->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC && 25467d2a188SAnoob Joseph cap->sym.xform_type == cipher->type && 25567d2a188SAnoob Joseph cap->sym.cipher.algo == cipher->cipher.algo) { 25667d2a188SAnoob Joseph sym_cap = &cap->sym; 25767d2a188SAnoob Joseph if (rte_cryptodev_sym_capability_check_cipher(sym_cap, 25867d2a188SAnoob Joseph cipher->cipher.key.length, 25967d2a188SAnoob Joseph cipher->cipher.iv.length) == 0) 26067d2a188SAnoob Joseph return 0; 26167d2a188SAnoob Joseph } 26267d2a188SAnoob Joseph } 26367d2a188SAnoob Joseph 26467d2a188SAnoob Joseph return -ENOTSUP; 26567d2a188SAnoob Joseph } 26667d2a188SAnoob Joseph 26767d2a188SAnoob Joseph int 26867d2a188SAnoob Joseph test_ipsec_crypto_caps_auth_verify( 26967d2a188SAnoob Joseph const struct rte_security_capability *sec_cap, 27067d2a188SAnoob Joseph struct rte_crypto_sym_xform *auth) 27167d2a188SAnoob Joseph { 27267d2a188SAnoob Joseph const struct rte_cryptodev_symmetric_capability *sym_cap; 27367d2a188SAnoob Joseph const struct rte_cryptodev_capabilities *cap; 27467d2a188SAnoob Joseph int j = 0; 27567d2a188SAnoob Joseph 27667d2a188SAnoob Joseph while ((cap = &sec_cap->crypto_capabilities[j++])->op != 27767d2a188SAnoob Joseph RTE_CRYPTO_OP_TYPE_UNDEFINED) { 27867d2a188SAnoob Joseph if (cap->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC && 27967d2a188SAnoob Joseph cap->sym.xform_type == auth->type && 28067d2a188SAnoob Joseph cap->sym.auth.algo == auth->auth.algo) { 28167d2a188SAnoob Joseph sym_cap = &cap->sym; 28267d2a188SAnoob Joseph if (rte_cryptodev_sym_capability_check_auth(sym_cap, 28367d2a188SAnoob Joseph auth->auth.key.length, 28467d2a188SAnoob Joseph auth->auth.digest_length, 28567d2a188SAnoob Joseph auth->auth.iv.length) == 0) 28667d2a188SAnoob Joseph return 0; 28767d2a188SAnoob Joseph } 28867d2a188SAnoob Joseph } 28967d2a188SAnoob Joseph 29067d2a188SAnoob Joseph return -ENOTSUP; 29167d2a188SAnoob Joseph } 29267d2a188SAnoob Joseph 293474f1202SAnoob Joseph void 294474f1202SAnoob Joseph test_ipsec_td_in_from_out(const struct ipsec_test_data *td_out, 295474f1202SAnoob Joseph struct ipsec_test_data *td_in) 296474f1202SAnoob Joseph { 297474f1202SAnoob Joseph memcpy(td_in, td_out, sizeof(*td_in)); 298474f1202SAnoob Joseph 299474f1202SAnoob Joseph /* Populate output text of td_in with input text of td_out */ 300474f1202SAnoob Joseph memcpy(td_in->output_text.data, td_out->input_text.data, 301474f1202SAnoob Joseph td_out->input_text.len); 302474f1202SAnoob Joseph td_in->output_text.len = td_out->input_text.len; 303474f1202SAnoob Joseph 304474f1202SAnoob Joseph /* Populate input text of td_in with output text of td_out */ 305474f1202SAnoob Joseph memcpy(td_in->input_text.data, td_out->output_text.data, 306474f1202SAnoob Joseph td_out->output_text.len); 307474f1202SAnoob Joseph td_in->input_text.len = td_out->output_text.len; 308474f1202SAnoob Joseph 309474f1202SAnoob Joseph td_in->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; 310474f1202SAnoob Joseph 311474f1202SAnoob Joseph if (td_in->aead) { 312474f1202SAnoob Joseph td_in->xform.aead.aead.op = RTE_CRYPTO_AEAD_OP_DECRYPT; 313474f1202SAnoob Joseph } else { 314474f1202SAnoob Joseph td_in->xform.chain.auth.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; 315474f1202SAnoob Joseph td_in->xform.chain.cipher.cipher.op = 316474f1202SAnoob Joseph RTE_CRYPTO_CIPHER_OP_DECRYPT; 317474f1202SAnoob Joseph } 318474f1202SAnoob Joseph } 319474f1202SAnoob Joseph 32083243502SArchana Muniganti static bool 32183243502SArchana Muniganti is_ipv4(void *ip) 32283243502SArchana Muniganti { 32383243502SArchana Muniganti struct rte_ipv4_hdr *ipv4 = ip; 32483243502SArchana Muniganti uint8_t ip_ver; 32583243502SArchana Muniganti 32683243502SArchana Muniganti ip_ver = (ipv4->version_ihl & 0xf0) >> RTE_IPV4_IHL_MULTIPLIER; 32783243502SArchana Muniganti if (ip_ver == IPVERSION) 32883243502SArchana Muniganti return true; 32983243502SArchana Muniganti else 33083243502SArchana Muniganti return false; 33183243502SArchana Muniganti } 33283243502SArchana Muniganti 33383243502SArchana Muniganti static void 33483243502SArchana Muniganti test_ipsec_csum_init(void *ip, bool l3, bool l4) 33583243502SArchana Muniganti { 33683243502SArchana Muniganti struct rte_ipv4_hdr *ipv4; 33783243502SArchana Muniganti struct rte_tcp_hdr *tcp; 33883243502SArchana Muniganti struct rte_udp_hdr *udp; 33983243502SArchana Muniganti uint8_t next_proto; 34083243502SArchana Muniganti uint8_t size; 34183243502SArchana Muniganti 34283243502SArchana Muniganti if (is_ipv4(ip)) { 34383243502SArchana Muniganti ipv4 = ip; 34483243502SArchana Muniganti size = sizeof(struct rte_ipv4_hdr); 34583243502SArchana Muniganti next_proto = ipv4->next_proto_id; 34683243502SArchana Muniganti 34783243502SArchana Muniganti if (l3) 34883243502SArchana Muniganti ipv4->hdr_checksum = 0; 34983243502SArchana Muniganti } else { 35083243502SArchana Muniganti size = sizeof(struct rte_ipv6_hdr); 35183243502SArchana Muniganti next_proto = ((struct rte_ipv6_hdr *)ip)->proto; 35283243502SArchana Muniganti } 35383243502SArchana Muniganti 35483243502SArchana Muniganti if (l4) { 35583243502SArchana Muniganti switch (next_proto) { 35683243502SArchana Muniganti case IPPROTO_TCP: 35783243502SArchana Muniganti tcp = (struct rte_tcp_hdr *)RTE_PTR_ADD(ip, size); 35883243502SArchana Muniganti tcp->cksum = 0; 35983243502SArchana Muniganti break; 36083243502SArchana Muniganti case IPPROTO_UDP: 36183243502SArchana Muniganti udp = (struct rte_udp_hdr *)RTE_PTR_ADD(ip, size); 36283243502SArchana Muniganti udp->dgram_cksum = 0; 36383243502SArchana Muniganti break; 36483243502SArchana Muniganti default: 36583243502SArchana Muniganti return; 36683243502SArchana Muniganti } 36783243502SArchana Muniganti } 36883243502SArchana Muniganti } 36983243502SArchana Muniganti 3706622d9c9SAnoob Joseph void 3716622d9c9SAnoob Joseph test_ipsec_td_prepare(const struct crypto_param *param1, 3726622d9c9SAnoob Joseph const struct crypto_param *param2, 3736622d9c9SAnoob Joseph const struct ipsec_test_flags *flags, 3746622d9c9SAnoob Joseph struct ipsec_test_data *td_array, 3756622d9c9SAnoob Joseph int nb_td) 3766622d9c9SAnoob Joseph 3776622d9c9SAnoob Joseph { 3786622d9c9SAnoob Joseph struct ipsec_test_data *td; 3796622d9c9SAnoob Joseph int i; 3806622d9c9SAnoob Joseph 3816622d9c9SAnoob Joseph memset(td_array, 0, nb_td * sizeof(*td)); 3826622d9c9SAnoob Joseph 3836622d9c9SAnoob Joseph for (i = 0; i < nb_td; i++) { 3846622d9c9SAnoob Joseph td = &td_array[i]; 3858d290523SAnoob Joseph 3868d290523SAnoob Joseph /* Prepare fields based on param */ 3878d290523SAnoob Joseph 3888d290523SAnoob Joseph if (param1->type == RTE_CRYPTO_SYM_XFORM_AEAD) { 3896622d9c9SAnoob Joseph /* Copy template for packet & key fields */ 3909fb87fbfSTejasree Kondoj if (flags->ipv6) 3919fb87fbfSTejasree Kondoj memcpy(td, &pkt_aes_256_gcm_v6, sizeof(*td)); 3929fb87fbfSTejasree Kondoj else 3936622d9c9SAnoob Joseph memcpy(td, &pkt_aes_256_gcm, sizeof(*td)); 3946622d9c9SAnoob Joseph 395d3142999SArchana Muniganti if (param1->alg.aead == RTE_CRYPTO_AEAD_AES_CCM) 396d3142999SArchana Muniganti td->salt.len = 3; 397d3142999SArchana Muniganti 3986622d9c9SAnoob Joseph td->aead = true; 3996622d9c9SAnoob Joseph td->xform.aead.aead.algo = param1->alg.aead; 4006622d9c9SAnoob Joseph td->xform.aead.aead.key.length = param1->key_length; 4018d290523SAnoob Joseph } else { 4028d290523SAnoob Joseph /* Copy template for packet & key fields */ 4039fb87fbfSTejasree Kondoj if (flags->ipv6) 4049fb87fbfSTejasree Kondoj memcpy(td, &pkt_aes_128_cbc_hmac_sha256_v6, 4059fb87fbfSTejasree Kondoj sizeof(*td)); 4069fb87fbfSTejasree Kondoj else 4079fb87fbfSTejasree Kondoj memcpy(td, &pkt_aes_128_cbc_hmac_sha256, 4089fb87fbfSTejasree Kondoj sizeof(*td)); 4098d290523SAnoob Joseph 4108d290523SAnoob Joseph td->aead = false; 411663d78beSArchana Muniganti 412663d78beSArchana Muniganti if (param1->type == RTE_CRYPTO_SYM_XFORM_AUTH) { 413663d78beSArchana Muniganti td->xform.chain.auth.auth.algo = 414663d78beSArchana Muniganti param1->alg.auth; 415663d78beSArchana Muniganti td->xform.chain.auth.auth.key.length = 416663d78beSArchana Muniganti param1->key_length; 417663d78beSArchana Muniganti td->xform.chain.auth.auth.digest_length = 418663d78beSArchana Muniganti param1->digest_length; 419663d78beSArchana Muniganti td->auth_only = true; 4200e4cc244SArchana Muniganti 4210e4cc244SArchana Muniganti if (td->xform.chain.auth.auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) { 4220e4cc244SArchana Muniganti td->xform.chain.auth.auth.iv.length = 4230e4cc244SArchana Muniganti param1->iv_length; 4240e4cc244SArchana Muniganti td->aes_gmac = true; 4250e4cc244SArchana Muniganti } 426663d78beSArchana Muniganti } else { 427663d78beSArchana Muniganti td->xform.chain.cipher.cipher.algo = 428663d78beSArchana Muniganti param1->alg.cipher; 4298d290523SAnoob Joseph td->xform.chain.cipher.cipher.key.length = 4308d290523SAnoob Joseph param1->key_length; 43167b5428dSAnoob Joseph td->xform.chain.cipher.cipher.iv.length = 43267b5428dSAnoob Joseph param1->iv_length; 433663d78beSArchana Muniganti td->xform.chain.auth.auth.algo = 434663d78beSArchana Muniganti param2->alg.auth; 4358d290523SAnoob Joseph td->xform.chain.auth.auth.key.length = 4368d290523SAnoob Joseph param2->key_length; 4378d290523SAnoob Joseph td->xform.chain.auth.auth.digest_length = 4388d290523SAnoob Joseph param2->digest_length; 4390e4cc244SArchana Muniganti 4400e4cc244SArchana Muniganti if (td->xform.chain.auth.auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) { 4410e4cc244SArchana Muniganti td->xform.chain.auth.auth.iv.length = 4420e4cc244SArchana Muniganti param2->iv_length; 4430e4cc244SArchana Muniganti td->aes_gmac = true; 4440e4cc244SArchana Muniganti } 445663d78beSArchana Muniganti } 446663d78beSArchana Muniganti } 4478d290523SAnoob Joseph 448663d78beSArchana Muniganti if (flags->ah) { 449663d78beSArchana Muniganti td->ipsec_xform.proto = 450663d78beSArchana Muniganti RTE_SECURITY_IPSEC_SA_PROTO_AH; 4518d290523SAnoob Joseph } 4520532f50cSAnoob Joseph 4530532f50cSAnoob Joseph if (flags->iv_gen) 4540532f50cSAnoob Joseph td->ipsec_xform.options.iv_gen_disable = 0; 4554aa52f21SAnoob Joseph 4564aa52f21SAnoob Joseph if (flags->sa_expiry_pkts_soft) 4574aa52f21SAnoob Joseph td->ipsec_xform.life.packets_soft_limit = 4584aa52f21SAnoob Joseph IPSEC_TEST_PACKETS_MAX - 1; 45983243502SArchana Muniganti 46083243502SArchana Muniganti if (flags->ip_csum) { 46183243502SArchana Muniganti td->ipsec_xform.options.ip_csum_enable = 1; 46283243502SArchana Muniganti test_ipsec_csum_init(&td->input_text.data, true, false); 46383243502SArchana Muniganti } 46483243502SArchana Muniganti 46583243502SArchana Muniganti if (flags->l4_csum) { 46683243502SArchana Muniganti td->ipsec_xform.options.l4_csum_enable = 1; 46783243502SArchana Muniganti test_ipsec_csum_init(&td->input_text.data, false, true); 46883243502SArchana Muniganti } 46983243502SArchana Muniganti 47065d68c7cSAnoob Joseph if (flags->transport) { 47165d68c7cSAnoob Joseph td->ipsec_xform.mode = 47265d68c7cSAnoob Joseph RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT; 47365d68c7cSAnoob Joseph } else { 47465d68c7cSAnoob Joseph td->ipsec_xform.mode = 47565d68c7cSAnoob Joseph RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; 47665d68c7cSAnoob Joseph 4779fb87fbfSTejasree Kondoj if (flags->tunnel_ipv6) 4789fb87fbfSTejasree Kondoj td->ipsec_xform.tunnel.type = 4799fb87fbfSTejasree Kondoj RTE_SECURITY_IPSEC_TUNNEL_IPV6; 4809fb87fbfSTejasree Kondoj else 4819fb87fbfSTejasree Kondoj td->ipsec_xform.tunnel.type = 4829fb87fbfSTejasree Kondoj RTE_SECURITY_IPSEC_TUNNEL_IPV4; 48365d68c7cSAnoob Joseph } 48465d68c7cSAnoob Joseph 4852c85598cSAnkur Dwivedi if (flags->stats_success) 4862c85598cSAnkur Dwivedi td->ipsec_xform.options.stats = 1; 4879fb87fbfSTejasree Kondoj 488825ab5c3STejasree Kondoj if (flags->fragment) { 489825ab5c3STejasree Kondoj struct rte_ipv4_hdr *ip; 490825ab5c3STejasree Kondoj ip = (struct rte_ipv4_hdr *)&td->input_text.data; 491825ab5c3STejasree Kondoj ip->fragment_offset = 4; 492825ab5c3STejasree Kondoj ip->hdr_checksum = rte_ipv4_cksum(ip); 493825ab5c3STejasree Kondoj } 494825ab5c3STejasree Kondoj 495e2cbb384SAnoob Joseph if (flags->df == TEST_IPSEC_COPY_DF_INNER_0 || 496e2cbb384SAnoob Joseph flags->df == TEST_IPSEC_COPY_DF_INNER_1) 497e2cbb384SAnoob Joseph td->ipsec_xform.options.copy_df = 1; 49870c60cfdSAnoob Joseph 49970c60cfdSAnoob Joseph if (flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_0 || 50070c60cfdSAnoob Joseph flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_1) 50170c60cfdSAnoob Joseph td->ipsec_xform.options.copy_dscp = 1; 50242902e81SVolodymyr Fialko 50391d1d052SVamsi Attunuru if (flags->flabel == TEST_IPSEC_COPY_FLABEL_INNER_0 || 50491d1d052SVamsi Attunuru flags->flabel == TEST_IPSEC_COPY_FLABEL_INNER_1) 50591d1d052SVamsi Attunuru td->ipsec_xform.options.copy_flabel = 1; 50691d1d052SVamsi Attunuru 50742902e81SVolodymyr Fialko if (flags->dec_ttl_or_hop_limit) 50842902e81SVolodymyr Fialko td->ipsec_xform.options.dec_ttl = 1; 5096622d9c9SAnoob Joseph } 5106622d9c9SAnoob Joseph } 5116622d9c9SAnoob Joseph 5126622d9c9SAnoob Joseph void 5136622d9c9SAnoob Joseph test_ipsec_td_update(struct ipsec_test_data td_inb[], 5146622d9c9SAnoob Joseph const struct ipsec_test_data td_outb[], 5156622d9c9SAnoob Joseph int nb_td, 5166622d9c9SAnoob Joseph const struct ipsec_test_flags *flags) 5176622d9c9SAnoob Joseph { 5186622d9c9SAnoob Joseph int i; 5196622d9c9SAnoob Joseph 5206622d9c9SAnoob Joseph for (i = 0; i < nb_td; i++) { 5216622d9c9SAnoob Joseph memcpy(td_inb[i].output_text.data, td_outb[i].input_text.data, 5226622d9c9SAnoob Joseph td_outb[i].input_text.len); 5236622d9c9SAnoob Joseph td_inb[i].output_text.len = td_outb->input_text.len; 5246622d9c9SAnoob Joseph 5250f453190STejasree Kondoj if (flags->icv_corrupt) { 5260f453190STejasree Kondoj int icv_pos = td_inb[i].input_text.len - 4; 5270f453190STejasree Kondoj td_inb[i].input_text.data[icv_pos] += 1; 5280f453190STejasree Kondoj } 529c8234341STejasree Kondoj 5306978f51eSAnoob Joseph if (flags->sa_expiry_pkts_hard) 5316978f51eSAnoob Joseph td_inb[i].ipsec_xform.life.packets_hard_limit = 5326978f51eSAnoob Joseph IPSEC_TEST_PACKETS_MAX - 1; 5336978f51eSAnoob Joseph 534c8234341STejasree Kondoj if (flags->udp_encap) 535c8234341STejasree Kondoj td_inb[i].ipsec_xform.options.udp_encap = 1; 5360532f50cSAnoob Joseph 5379ec50a52STejasree Kondoj if (flags->udp_ports_verify) 5389ec50a52STejasree Kondoj td_inb[i].ipsec_xform.options.udp_ports_verify = 1; 5399ec50a52STejasree Kondoj 540270470eeSTejasree Kondoj td_inb[i].ipsec_xform.options.tunnel_hdr_verify = 541270470eeSTejasree Kondoj flags->tunnel_hdr_verify; 542270470eeSTejasree Kondoj 54383243502SArchana Muniganti if (flags->ip_csum) 54483243502SArchana Muniganti td_inb[i].ipsec_xform.options.ip_csum_enable = 1; 54583243502SArchana Muniganti 54683243502SArchana Muniganti if (flags->l4_csum) 54783243502SArchana Muniganti td_inb[i].ipsec_xform.options.l4_csum_enable = 1; 54883243502SArchana Muniganti 5490532f50cSAnoob Joseph /* Clear outbound specific flags */ 5500532f50cSAnoob Joseph td_inb[i].ipsec_xform.options.iv_gen_disable = 0; 5510f453190STejasree Kondoj } 5526622d9c9SAnoob Joseph } 5536622d9c9SAnoob Joseph 5546622d9c9SAnoob Joseph void 5556622d9c9SAnoob Joseph test_ipsec_display_alg(const struct crypto_param *param1, 5566622d9c9SAnoob Joseph const struct crypto_param *param2) 5576622d9c9SAnoob Joseph { 5588d290523SAnoob Joseph if (param1->type == RTE_CRYPTO_SYM_XFORM_AEAD) { 5598d290523SAnoob Joseph printf("\t%s [%d]", 5606622d9c9SAnoob Joseph rte_crypto_aead_algorithm_strings[param1->alg.aead], 5618d290523SAnoob Joseph param1->key_length * 8); 562663d78beSArchana Muniganti } else if (param1->type == RTE_CRYPTO_SYM_XFORM_AUTH) { 563663d78beSArchana Muniganti printf("\t%s", 564663d78beSArchana Muniganti rte_crypto_auth_algorithm_strings[param1->alg.auth]); 565663d78beSArchana Muniganti if (param1->alg.auth != RTE_CRYPTO_AUTH_NULL) 566663d78beSArchana Muniganti printf(" [%dB ICV]", param1->digest_length); 5678d290523SAnoob Joseph } else { 5688d290523SAnoob Joseph printf("\t%s", 5698d290523SAnoob Joseph rte_crypto_cipher_algorithm_strings[param1->alg.cipher]); 5708d290523SAnoob Joseph if (param1->alg.cipher != RTE_CRYPTO_CIPHER_NULL) 5718d290523SAnoob Joseph printf(" [%d]", param1->key_length * 8); 5728d290523SAnoob Joseph printf(" %s", 5738d290523SAnoob Joseph rte_crypto_auth_algorithm_strings[param2->alg.auth]); 5748d290523SAnoob Joseph if (param2->alg.auth != RTE_CRYPTO_AUTH_NULL) 5758d290523SAnoob Joseph printf(" [%dB ICV]", param2->digest_length); 5768d290523SAnoob Joseph } 5778d290523SAnoob Joseph printf("\n"); 5786622d9c9SAnoob Joseph } 5796622d9c9SAnoob Joseph 580474f1202SAnoob Joseph static int 581474f1202SAnoob Joseph test_ipsec_tunnel_hdr_len_get(const struct ipsec_test_data *td) 582474f1202SAnoob Joseph { 583474f1202SAnoob Joseph int len = 0; 584474f1202SAnoob Joseph 585474f1202SAnoob Joseph if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { 586474f1202SAnoob Joseph if (td->ipsec_xform.mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) { 587474f1202SAnoob Joseph if (td->ipsec_xform.tunnel.type == 588474f1202SAnoob Joseph RTE_SECURITY_IPSEC_TUNNEL_IPV4) 589474f1202SAnoob Joseph len += sizeof(struct rte_ipv4_hdr); 590474f1202SAnoob Joseph else 591474f1202SAnoob Joseph len += sizeof(struct rte_ipv6_hdr); 592474f1202SAnoob Joseph } 593474f1202SAnoob Joseph } 594474f1202SAnoob Joseph 595474f1202SAnoob Joseph return len; 596474f1202SAnoob Joseph } 597474f1202SAnoob Joseph 598474f1202SAnoob Joseph static int 599cd928003STejasree Kondoj test_ipsec_iv_verify_push(struct rte_mbuf *m, const struct ipsec_test_data *td) 600cd928003STejasree Kondoj { 601cd928003STejasree Kondoj static uint8_t iv_queue[IV_LEN_MAX * IPSEC_TEST_PACKETS_MAX]; 602cd928003STejasree Kondoj uint8_t *iv_tmp, *output_text = rte_pktmbuf_mtod(m, uint8_t *); 603cd928003STejasree Kondoj int i, iv_pos, iv_len; 604cd928003STejasree Kondoj static int index; 605cd928003STejasree Kondoj 606cd928003STejasree Kondoj if (td->aead) 607cd928003STejasree Kondoj iv_len = td->xform.aead.aead.iv.length - td->salt.len; 608cd928003STejasree Kondoj else 609cd928003STejasree Kondoj iv_len = td->xform.chain.cipher.cipher.iv.length; 610cd928003STejasree Kondoj 611cd928003STejasree Kondoj iv_pos = test_ipsec_tunnel_hdr_len_get(td) + sizeof(struct rte_esp_hdr); 612cd928003STejasree Kondoj output_text += iv_pos; 613cd928003STejasree Kondoj 614cd928003STejasree Kondoj TEST_ASSERT(iv_len <= IV_LEN_MAX, "IV length greater than supported"); 615cd928003STejasree Kondoj 616cd928003STejasree Kondoj /* Compare against previous values */ 617cd928003STejasree Kondoj for (i = 0; i < index; i++) { 618cd928003STejasree Kondoj iv_tmp = &iv_queue[i * IV_LEN_MAX]; 619cd928003STejasree Kondoj 620cd928003STejasree Kondoj if (memcmp(output_text, iv_tmp, iv_len) == 0) { 621cd928003STejasree Kondoj printf("IV repeated"); 622cd928003STejasree Kondoj return TEST_FAILED; 623cd928003STejasree Kondoj } 624cd928003STejasree Kondoj } 625cd928003STejasree Kondoj 626cd928003STejasree Kondoj /* Save IV for future comparisons */ 627cd928003STejasree Kondoj 628cd928003STejasree Kondoj iv_tmp = &iv_queue[index * IV_LEN_MAX]; 629cd928003STejasree Kondoj memcpy(iv_tmp, output_text, iv_len); 630cd928003STejasree Kondoj index++; 631cd928003STejasree Kondoj 632cd928003STejasree Kondoj if (index == IPSEC_TEST_PACKETS_MAX) 633cd928003STejasree Kondoj index = 0; 634cd928003STejasree Kondoj 635cd928003STejasree Kondoj return TEST_SUCCESS; 636cd928003STejasree Kondoj } 637cd928003STejasree Kondoj 638cd928003STejasree Kondoj static int 63983243502SArchana Muniganti test_ipsec_l3_csum_verify(struct rte_mbuf *m) 64083243502SArchana Muniganti { 64183243502SArchana Muniganti uint16_t actual_cksum, expected_cksum; 64283243502SArchana Muniganti struct rte_ipv4_hdr *ip; 64383243502SArchana Muniganti 64483243502SArchana Muniganti ip = rte_pktmbuf_mtod(m, struct rte_ipv4_hdr *); 64583243502SArchana Muniganti 64683243502SArchana Muniganti if (!is_ipv4((void *)ip)) 64783243502SArchana Muniganti return TEST_SKIPPED; 64883243502SArchana Muniganti 64983243502SArchana Muniganti actual_cksum = ip->hdr_checksum; 65083243502SArchana Muniganti 65183243502SArchana Muniganti ip->hdr_checksum = 0; 65283243502SArchana Muniganti 65383243502SArchana Muniganti expected_cksum = rte_ipv4_cksum(ip); 65483243502SArchana Muniganti 65583243502SArchana Muniganti if (actual_cksum != expected_cksum) 65683243502SArchana Muniganti return TEST_FAILED; 65783243502SArchana Muniganti 65883243502SArchana Muniganti return TEST_SUCCESS; 65983243502SArchana Muniganti } 66083243502SArchana Muniganti 66183243502SArchana Muniganti static int 66283243502SArchana Muniganti test_ipsec_l4_csum_verify(struct rte_mbuf *m) 66383243502SArchana Muniganti { 66483243502SArchana Muniganti uint16_t actual_cksum = 0, expected_cksum = 0; 66583243502SArchana Muniganti struct rte_ipv4_hdr *ipv4; 66683243502SArchana Muniganti struct rte_ipv6_hdr *ipv6; 66783243502SArchana Muniganti struct rte_tcp_hdr *tcp; 66883243502SArchana Muniganti struct rte_udp_hdr *udp; 66983243502SArchana Muniganti void *ip, *l4; 67083243502SArchana Muniganti 67183243502SArchana Muniganti ip = rte_pktmbuf_mtod(m, void *); 67283243502SArchana Muniganti 67383243502SArchana Muniganti if (is_ipv4(ip)) { 67483243502SArchana Muniganti ipv4 = ip; 67583243502SArchana Muniganti l4 = RTE_PTR_ADD(ipv4, sizeof(struct rte_ipv4_hdr)); 67683243502SArchana Muniganti 67783243502SArchana Muniganti switch (ipv4->next_proto_id) { 67883243502SArchana Muniganti case IPPROTO_TCP: 67983243502SArchana Muniganti tcp = (struct rte_tcp_hdr *)l4; 68083243502SArchana Muniganti actual_cksum = tcp->cksum; 68183243502SArchana Muniganti tcp->cksum = 0; 68283243502SArchana Muniganti expected_cksum = rte_ipv4_udptcp_cksum(ipv4, l4); 68383243502SArchana Muniganti break; 68483243502SArchana Muniganti case IPPROTO_UDP: 68583243502SArchana Muniganti udp = (struct rte_udp_hdr *)l4; 68683243502SArchana Muniganti actual_cksum = udp->dgram_cksum; 68783243502SArchana Muniganti udp->dgram_cksum = 0; 68883243502SArchana Muniganti expected_cksum = rte_ipv4_udptcp_cksum(ipv4, l4); 68983243502SArchana Muniganti break; 69083243502SArchana Muniganti default: 69183243502SArchana Muniganti break; 69283243502SArchana Muniganti } 69383243502SArchana Muniganti } else { 69483243502SArchana Muniganti ipv6 = ip; 69583243502SArchana Muniganti l4 = RTE_PTR_ADD(ipv6, sizeof(struct rte_ipv6_hdr)); 69683243502SArchana Muniganti 69783243502SArchana Muniganti switch (ipv6->proto) { 69883243502SArchana Muniganti case IPPROTO_TCP: 69983243502SArchana Muniganti tcp = (struct rte_tcp_hdr *)l4; 70083243502SArchana Muniganti actual_cksum = tcp->cksum; 70183243502SArchana Muniganti tcp->cksum = 0; 70283243502SArchana Muniganti expected_cksum = rte_ipv6_udptcp_cksum(ipv6, l4); 70383243502SArchana Muniganti break; 70483243502SArchana Muniganti case IPPROTO_UDP: 70583243502SArchana Muniganti udp = (struct rte_udp_hdr *)l4; 70683243502SArchana Muniganti actual_cksum = udp->dgram_cksum; 70783243502SArchana Muniganti udp->dgram_cksum = 0; 70883243502SArchana Muniganti expected_cksum = rte_ipv6_udptcp_cksum(ipv6, l4); 70983243502SArchana Muniganti break; 71083243502SArchana Muniganti default: 71183243502SArchana Muniganti break; 71283243502SArchana Muniganti } 71383243502SArchana Muniganti } 71483243502SArchana Muniganti 71583243502SArchana Muniganti if (actual_cksum != expected_cksum) 71683243502SArchana Muniganti return TEST_FAILED; 71783243502SArchana Muniganti 71883243502SArchana Muniganti return TEST_SUCCESS; 71983243502SArchana Muniganti } 72083243502SArchana Muniganti 72183243502SArchana Muniganti static int 72242902e81SVolodymyr Fialko test_ipsec_ttl_or_hop_decrement_verify(void *received, void *expected) 72342902e81SVolodymyr Fialko { 72442902e81SVolodymyr Fialko struct rte_ipv4_hdr *iph4_ex, *iph4_re; 72542902e81SVolodymyr Fialko struct rte_ipv6_hdr *iph6_ex, *iph6_re; 72642902e81SVolodymyr Fialko 72742902e81SVolodymyr Fialko if (is_ipv4(received) && is_ipv4(expected)) { 72842902e81SVolodymyr Fialko iph4_ex = expected; 72942902e81SVolodymyr Fialko iph4_re = received; 73042902e81SVolodymyr Fialko iph4_ex->time_to_live -= 1; 73142902e81SVolodymyr Fialko if (iph4_re->time_to_live != iph4_ex->time_to_live) 73242902e81SVolodymyr Fialko return TEST_FAILED; 73342902e81SVolodymyr Fialko } else if (!is_ipv4(received) && !is_ipv4(expected)) { 73442902e81SVolodymyr Fialko iph6_ex = expected; 73542902e81SVolodymyr Fialko iph6_re = received; 73642902e81SVolodymyr Fialko iph6_ex->hop_limits -= 1; 73742902e81SVolodymyr Fialko if (iph6_re->hop_limits != iph6_ex->hop_limits) 73842902e81SVolodymyr Fialko return TEST_FAILED; 73942902e81SVolodymyr Fialko } else { 74042902e81SVolodymyr Fialko printf("IP header version miss match\n"); 74142902e81SVolodymyr Fialko return TEST_FAILED; 74242902e81SVolodymyr Fialko } 74342902e81SVolodymyr Fialko 74442902e81SVolodymyr Fialko return TEST_SUCCESS; 74542902e81SVolodymyr Fialko } 74642902e81SVolodymyr Fialko 74742902e81SVolodymyr Fialko static int 748474f1202SAnoob Joseph test_ipsec_td_verify(struct rte_mbuf *m, const struct ipsec_test_data *td, 7496622d9c9SAnoob Joseph bool silent, const struct ipsec_test_flags *flags) 750474f1202SAnoob Joseph { 751474f1202SAnoob Joseph uint8_t *output_text = rte_pktmbuf_mtod(m, uint8_t *); 752474f1202SAnoob Joseph uint32_t skip, len = rte_pktmbuf_pkt_len(m); 753e2cbb384SAnoob Joseph uint8_t td_output_text[4096]; 75483243502SArchana Muniganti int ret; 755474f1202SAnoob Joseph 7566978f51eSAnoob Joseph /* For tests with status as error for test success, skip verification */ 7576978f51eSAnoob Joseph if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS && 7586978f51eSAnoob Joseph (flags->icv_corrupt || 759270470eeSTejasree Kondoj flags->sa_expiry_pkts_hard || 760d02c6bfcSTejasree Kondoj flags->tunnel_hdr_verify || 761d02c6bfcSTejasree Kondoj td->ar_packet)) 7620f453190STejasree Kondoj return TEST_SUCCESS; 7630f453190STejasree Kondoj 764c8234341STejasree Kondoj if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS && 765c8234341STejasree Kondoj flags->udp_encap) { 766c8234341STejasree Kondoj const struct rte_ipv4_hdr *iph4; 767c8234341STejasree Kondoj const struct rte_ipv6_hdr *iph6; 768c8234341STejasree Kondoj 769c8234341STejasree Kondoj if (td->ipsec_xform.tunnel.type == 770c8234341STejasree Kondoj RTE_SECURITY_IPSEC_TUNNEL_IPV4) { 771c8234341STejasree Kondoj iph4 = (const struct rte_ipv4_hdr *)output_text; 772c8234341STejasree Kondoj if (iph4->next_proto_id != IPPROTO_UDP) { 773c8234341STejasree Kondoj printf("UDP header is not found\n"); 774c8234341STejasree Kondoj return TEST_FAILED; 775c8234341STejasree Kondoj } 776c8234341STejasree Kondoj } else { 777c8234341STejasree Kondoj iph6 = (const struct rte_ipv6_hdr *)output_text; 778c8234341STejasree Kondoj if (iph6->proto != IPPROTO_UDP) { 779c8234341STejasree Kondoj printf("UDP header is not found\n"); 780c8234341STejasree Kondoj return TEST_FAILED; 781c8234341STejasree Kondoj } 782c8234341STejasree Kondoj } 783c8234341STejasree Kondoj 784c8234341STejasree Kondoj len -= sizeof(struct rte_udp_hdr); 785c8234341STejasree Kondoj output_text += sizeof(struct rte_udp_hdr); 786c8234341STejasree Kondoj } 787c8234341STejasree Kondoj 788474f1202SAnoob Joseph if (len != td->output_text.len) { 789474f1202SAnoob Joseph printf("Output length (%d) not matching with expected (%d)\n", 790474f1202SAnoob Joseph len, td->output_text.len); 791474f1202SAnoob Joseph return TEST_FAILED; 792474f1202SAnoob Joseph } 793474f1202SAnoob Joseph 794b7986bdeSTejasree Kondoj if ((td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) && 795b7986bdeSTejasree Kondoj flags->fragment) { 796b7986bdeSTejasree Kondoj const struct rte_ipv4_hdr *iph4; 797b7986bdeSTejasree Kondoj iph4 = (const struct rte_ipv4_hdr *)output_text; 798b7986bdeSTejasree Kondoj if (iph4->fragment_offset) { 799b7986bdeSTejasree Kondoj printf("Output packet is fragmented"); 800b7986bdeSTejasree Kondoj return TEST_FAILED; 801b7986bdeSTejasree Kondoj } 802b7986bdeSTejasree Kondoj } 803b7986bdeSTejasree Kondoj 804474f1202SAnoob Joseph skip = test_ipsec_tunnel_hdr_len_get(td); 805474f1202SAnoob Joseph 806474f1202SAnoob Joseph len -= skip; 807474f1202SAnoob Joseph output_text += skip; 808474f1202SAnoob Joseph 80983243502SArchana Muniganti if ((td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) && 81083243502SArchana Muniganti flags->ip_csum) { 811daa02b5cSOlivier Matz if (m->ol_flags & RTE_MBUF_F_RX_IP_CKSUM_GOOD) 81283243502SArchana Muniganti ret = test_ipsec_l3_csum_verify(m); 81383243502SArchana Muniganti else 81483243502SArchana Muniganti ret = TEST_FAILED; 81583243502SArchana Muniganti 81683243502SArchana Muniganti if (ret == TEST_FAILED) 81783243502SArchana Muniganti printf("Inner IP checksum test failed\n"); 81883243502SArchana Muniganti 81983243502SArchana Muniganti return ret; 82083243502SArchana Muniganti } 82183243502SArchana Muniganti 82283243502SArchana Muniganti if ((td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) && 82383243502SArchana Muniganti flags->l4_csum) { 824daa02b5cSOlivier Matz if (m->ol_flags & RTE_MBUF_F_RX_L4_CKSUM_GOOD) 82583243502SArchana Muniganti ret = test_ipsec_l4_csum_verify(m); 82683243502SArchana Muniganti else 82783243502SArchana Muniganti ret = TEST_FAILED; 82883243502SArchana Muniganti 82983243502SArchana Muniganti if (ret == TEST_FAILED) 83083243502SArchana Muniganti printf("Inner L4 checksum test failed\n"); 83183243502SArchana Muniganti 83283243502SArchana Muniganti return ret; 83383243502SArchana Muniganti } 83483243502SArchana Muniganti 835e2cbb384SAnoob Joseph memcpy(td_output_text, td->output_text.data + skip, len); 83683243502SArchana Muniganti 83742902e81SVolodymyr Fialko if ((td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) && 83842902e81SVolodymyr Fialko flags->dec_ttl_or_hop_limit) { 83942902e81SVolodymyr Fialko if (test_ipsec_ttl_or_hop_decrement_verify(output_text, td_output_text)) { 84042902e81SVolodymyr Fialko printf("Inner TTL/hop limit decrement test failed\n"); 84142902e81SVolodymyr Fialko return TEST_FAILED; 84242902e81SVolodymyr Fialko } 84342902e81SVolodymyr Fialko } 84442902e81SVolodymyr Fialko 845e2cbb384SAnoob Joseph if (test_ipsec_pkt_update(td_output_text, flags)) { 846e2cbb384SAnoob Joseph printf("Could not update expected vector"); 847e2cbb384SAnoob Joseph return TEST_FAILED; 848e2cbb384SAnoob Joseph } 849e2cbb384SAnoob Joseph 850e2cbb384SAnoob Joseph if (memcmp(output_text, td_output_text, len)) { 851474f1202SAnoob Joseph if (silent) 852474f1202SAnoob Joseph return TEST_FAILED; 853474f1202SAnoob Joseph 854474f1202SAnoob Joseph printf("TestCase %s line %d: %s\n", __func__, __LINE__, 855474f1202SAnoob Joseph "output text not as expected\n"); 856474f1202SAnoob Joseph 857e2cbb384SAnoob Joseph rte_hexdump(stdout, "expected", td_output_text, len); 858474f1202SAnoob Joseph rte_hexdump(stdout, "actual", output_text, len); 859474f1202SAnoob Joseph return TEST_FAILED; 860474f1202SAnoob Joseph } 861474f1202SAnoob Joseph 8626622d9c9SAnoob Joseph return TEST_SUCCESS; 8636622d9c9SAnoob Joseph } 8646622d9c9SAnoob Joseph 8656622d9c9SAnoob Joseph static int 8666622d9c9SAnoob Joseph test_ipsec_res_d_prepare(struct rte_mbuf *m, const struct ipsec_test_data *td, 8676622d9c9SAnoob Joseph struct ipsec_test_data *res_d) 8686622d9c9SAnoob Joseph { 8696622d9c9SAnoob Joseph uint8_t *output_text = rte_pktmbuf_mtod(m, uint8_t *); 8706622d9c9SAnoob Joseph uint32_t len = rte_pktmbuf_pkt_len(m); 8716622d9c9SAnoob Joseph 8726622d9c9SAnoob Joseph memcpy(res_d, td, sizeof(*res_d)); 8736622d9c9SAnoob Joseph memcpy(res_d->input_text.data, output_text, len); 8746622d9c9SAnoob Joseph res_d->input_text.len = len; 8756622d9c9SAnoob Joseph 8766622d9c9SAnoob Joseph res_d->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; 8776622d9c9SAnoob Joseph if (res_d->aead) { 8786622d9c9SAnoob Joseph res_d->xform.aead.aead.op = RTE_CRYPTO_AEAD_OP_DECRYPT; 8796622d9c9SAnoob Joseph } else { 8808d290523SAnoob Joseph res_d->xform.chain.cipher.cipher.op = 8818d290523SAnoob Joseph RTE_CRYPTO_CIPHER_OP_DECRYPT; 8828d290523SAnoob Joseph res_d->xform.chain.auth.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; 8836622d9c9SAnoob Joseph } 8846622d9c9SAnoob Joseph 885474f1202SAnoob Joseph return TEST_SUCCESS; 886474f1202SAnoob Joseph } 887474f1202SAnoob Joseph 88870c60cfdSAnoob Joseph static int 88970c60cfdSAnoob Joseph test_ipsec_iph4_hdr_validate(const struct rte_ipv4_hdr *iph4, 89070c60cfdSAnoob Joseph const struct ipsec_test_flags *flags) 89170c60cfdSAnoob Joseph { 89270c60cfdSAnoob Joseph uint8_t tos, dscp; 89370c60cfdSAnoob Joseph uint16_t f_off; 89470c60cfdSAnoob Joseph 89570c60cfdSAnoob Joseph if (!is_valid_ipv4_pkt(iph4)) { 89670c60cfdSAnoob Joseph printf("Tunnel outer header is not IPv4\n"); 89770c60cfdSAnoob Joseph return -1; 89870c60cfdSAnoob Joseph } 89970c60cfdSAnoob Joseph 900663d78beSArchana Muniganti if (flags->ah && iph4->next_proto_id != IPPROTO_AH) { 901663d78beSArchana Muniganti printf("Tunnel outer header proto is not AH\n"); 902663d78beSArchana Muniganti return -1; 903663d78beSArchana Muniganti } 904663d78beSArchana Muniganti 90570c60cfdSAnoob Joseph f_off = rte_be_to_cpu_16(iph4->fragment_offset); 90670c60cfdSAnoob Joseph if (flags->df == TEST_IPSEC_COPY_DF_INNER_1 || 90770c60cfdSAnoob Joseph flags->df == TEST_IPSEC_SET_DF_1_INNER_0) { 90870c60cfdSAnoob Joseph if (!(f_off & RTE_IPV4_HDR_DF_FLAG)) { 90970c60cfdSAnoob Joseph printf("DF bit is not set\n"); 91070c60cfdSAnoob Joseph return -1; 91170c60cfdSAnoob Joseph } 91270c60cfdSAnoob Joseph } else { 91370c60cfdSAnoob Joseph if (f_off & RTE_IPV4_HDR_DF_FLAG) { 91470c60cfdSAnoob Joseph printf("DF bit is set\n"); 91570c60cfdSAnoob Joseph return -1; 91670c60cfdSAnoob Joseph } 91770c60cfdSAnoob Joseph } 91870c60cfdSAnoob Joseph 91970c60cfdSAnoob Joseph tos = iph4->type_of_service; 92070c60cfdSAnoob Joseph dscp = (tos & RTE_IPV4_HDR_DSCP_MASK) >> 2; 92170c60cfdSAnoob Joseph 92270c60cfdSAnoob Joseph if (flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_1 || 92370c60cfdSAnoob Joseph flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0) { 92470c60cfdSAnoob Joseph if (dscp != TEST_IPSEC_DSCP_VAL) { 92570c60cfdSAnoob Joseph printf("DSCP value is not matching [exp: %x, actual: %x]\n", 92670c60cfdSAnoob Joseph TEST_IPSEC_DSCP_VAL, dscp); 92770c60cfdSAnoob Joseph return -1; 92870c60cfdSAnoob Joseph } 92970c60cfdSAnoob Joseph } else { 93070c60cfdSAnoob Joseph if (dscp != 0) { 93170c60cfdSAnoob Joseph printf("DSCP value is set [exp: 0, actual: %x]\n", 93270c60cfdSAnoob Joseph dscp); 93370c60cfdSAnoob Joseph return -1; 93470c60cfdSAnoob Joseph } 93570c60cfdSAnoob Joseph } 93670c60cfdSAnoob Joseph 93770c60cfdSAnoob Joseph return 0; 93870c60cfdSAnoob Joseph } 93970c60cfdSAnoob Joseph 94070c60cfdSAnoob Joseph static int 94170c60cfdSAnoob Joseph test_ipsec_iph6_hdr_validate(const struct rte_ipv6_hdr *iph6, 94270c60cfdSAnoob Joseph const struct ipsec_test_flags *flags) 94370c60cfdSAnoob Joseph { 94470c60cfdSAnoob Joseph uint32_t vtc_flow; 94591d1d052SVamsi Attunuru uint32_t flabel; 94670c60cfdSAnoob Joseph uint8_t dscp; 94770c60cfdSAnoob Joseph 94870c60cfdSAnoob Joseph if (!is_valid_ipv6_pkt(iph6)) { 94970c60cfdSAnoob Joseph printf("Tunnel outer header is not IPv6\n"); 95070c60cfdSAnoob Joseph return -1; 95170c60cfdSAnoob Joseph } 95270c60cfdSAnoob Joseph 95370c60cfdSAnoob Joseph vtc_flow = rte_be_to_cpu_32(iph6->vtc_flow); 95470c60cfdSAnoob Joseph dscp = (vtc_flow & RTE_IPV6_HDR_DSCP_MASK) >> 95570c60cfdSAnoob Joseph (RTE_IPV6_HDR_TC_SHIFT + 2); 95670c60cfdSAnoob Joseph 95770c60cfdSAnoob Joseph if (flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_1 || 95870c60cfdSAnoob Joseph flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0) { 95970c60cfdSAnoob Joseph if (dscp != TEST_IPSEC_DSCP_VAL) { 96070c60cfdSAnoob Joseph printf("DSCP value is not matching [exp: %x, actual: %x]\n", 96170c60cfdSAnoob Joseph TEST_IPSEC_DSCP_VAL, dscp); 96270c60cfdSAnoob Joseph return -1; 96370c60cfdSAnoob Joseph } 96470c60cfdSAnoob Joseph } else { 96570c60cfdSAnoob Joseph if (dscp != 0) { 96670c60cfdSAnoob Joseph printf("DSCP value is set [exp: 0, actual: %x]\n", 96770c60cfdSAnoob Joseph dscp); 96870c60cfdSAnoob Joseph return -1; 96970c60cfdSAnoob Joseph } 97070c60cfdSAnoob Joseph } 97170c60cfdSAnoob Joseph 97291d1d052SVamsi Attunuru flabel = vtc_flow & RTE_IPV6_HDR_FL_MASK; 97391d1d052SVamsi Attunuru 97491d1d052SVamsi Attunuru if (flags->flabel == TEST_IPSEC_COPY_FLABEL_INNER_1 || 97591d1d052SVamsi Attunuru flags->flabel == TEST_IPSEC_SET_FLABEL_1_INNER_0) { 97691d1d052SVamsi Attunuru if (flabel != TEST_IPSEC_FLABEL_VAL) { 97791d1d052SVamsi Attunuru printf("FLABEL value is not matching [exp: %x, actual: %x]\n", 97891d1d052SVamsi Attunuru TEST_IPSEC_FLABEL_VAL, flabel); 97991d1d052SVamsi Attunuru return -1; 98091d1d052SVamsi Attunuru } 98191d1d052SVamsi Attunuru } else { 98291d1d052SVamsi Attunuru if (flabel != 0) { 98391d1d052SVamsi Attunuru printf("FLABEL value is set [exp: 0, actual: %x]\n", 98491d1d052SVamsi Attunuru flabel); 98591d1d052SVamsi Attunuru return -1; 98691d1d052SVamsi Attunuru } 98791d1d052SVamsi Attunuru } 98891d1d052SVamsi Attunuru 98970c60cfdSAnoob Joseph return 0; 99070c60cfdSAnoob Joseph } 99170c60cfdSAnoob Joseph 992474f1202SAnoob Joseph int 993474f1202SAnoob Joseph test_ipsec_post_process(struct rte_mbuf *m, const struct ipsec_test_data *td, 9946622d9c9SAnoob Joseph struct ipsec_test_data *res_d, bool silent, 9956622d9c9SAnoob Joseph const struct ipsec_test_flags *flags) 996474f1202SAnoob Joseph { 9979fb87fbfSTejasree Kondoj uint8_t *output_text = rte_pktmbuf_mtod(m, uint8_t *); 998cd928003STejasree Kondoj int ret; 999cd928003STejasree Kondoj 100065d68c7cSAnoob Joseph if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { 100165d68c7cSAnoob Joseph const struct rte_ipv4_hdr *iph4; 100265d68c7cSAnoob Joseph const struct rte_ipv6_hdr *iph6; 100365d68c7cSAnoob Joseph 100465d68c7cSAnoob Joseph if (flags->iv_gen) { 1005cd928003STejasree Kondoj ret = test_ipsec_iv_verify_push(m, td); 1006cd928003STejasree Kondoj if (ret != TEST_SUCCESS) 1007cd928003STejasree Kondoj return ret; 1008cd928003STejasree Kondoj } 1009cd928003STejasree Kondoj 101065d68c7cSAnoob Joseph iph4 = (const struct rte_ipv4_hdr *)output_text; 10119fb87fbfSTejasree Kondoj 101265d68c7cSAnoob Joseph if (td->ipsec_xform.mode == 101365d68c7cSAnoob Joseph RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) { 101465d68c7cSAnoob Joseph if (flags->ipv6) { 101565d68c7cSAnoob Joseph iph6 = (const struct rte_ipv6_hdr *)output_text; 101665d68c7cSAnoob Joseph if (is_valid_ipv6_pkt(iph6) == false) { 101765d68c7cSAnoob Joseph printf("Transport packet is not IPv6\n"); 101865d68c7cSAnoob Joseph return TEST_FAILED; 101965d68c7cSAnoob Joseph } 102065d68c7cSAnoob Joseph } else { 102165d68c7cSAnoob Joseph if (is_valid_ipv4_pkt(iph4) == false) { 102265d68c7cSAnoob Joseph printf("Transport packet is not IPv4\n"); 102365d68c7cSAnoob Joseph return TEST_FAILED; 102465d68c7cSAnoob Joseph } 1025663d78beSArchana Muniganti 1026663d78beSArchana Muniganti if (flags->ah && iph4->next_proto_id != IPPROTO_AH) { 1027663d78beSArchana Muniganti printf("Transport IPv4 header proto is not AH\n"); 1028663d78beSArchana Muniganti return -1; 1029663d78beSArchana Muniganti } 103065d68c7cSAnoob Joseph } 103165d68c7cSAnoob Joseph } else { 10329fb87fbfSTejasree Kondoj if (td->ipsec_xform.tunnel.type == 10339fb87fbfSTejasree Kondoj RTE_SECURITY_IPSEC_TUNNEL_IPV4) { 103470c60cfdSAnoob Joseph if (test_ipsec_iph4_hdr_validate(iph4, flags)) 10359fb87fbfSTejasree Kondoj return TEST_FAILED; 10369fb87fbfSTejasree Kondoj } else { 10379fb87fbfSTejasree Kondoj iph6 = (const struct rte_ipv6_hdr *)output_text; 103870c60cfdSAnoob Joseph if (test_ipsec_iph6_hdr_validate(iph6, flags)) 10399fb87fbfSTejasree Kondoj return TEST_FAILED; 10409fb87fbfSTejasree Kondoj } 10419fb87fbfSTejasree Kondoj } 10429fb87fbfSTejasree Kondoj } 10439fb87fbfSTejasree Kondoj 1044474f1202SAnoob Joseph /* 1045474f1202SAnoob Joseph * In case of known vector tests & all inbound tests, res_d provided 1046474f1202SAnoob Joseph * would be NULL and output data need to be validated against expected. 1047474f1202SAnoob Joseph * For inbound, output_text would be plain packet and for outbound 1048474f1202SAnoob Joseph * output_text would IPsec packet. Validate by comparing against 1049474f1202SAnoob Joseph * known vectors. 10506622d9c9SAnoob Joseph * 10516622d9c9SAnoob Joseph * In case of combined mode tests, the output_text from outbound 10526622d9c9SAnoob Joseph * operation (ie, IPsec packet) would need to be inbound processed to 10536622d9c9SAnoob Joseph * obtain the plain text. Copy output_text to result data, 'res_d', so 10546622d9c9SAnoob Joseph * that inbound processing can be done. 1055474f1202SAnoob Joseph */ 10566622d9c9SAnoob Joseph 10576622d9c9SAnoob Joseph if (res_d == NULL) 10586622d9c9SAnoob Joseph return test_ipsec_td_verify(m, td, silent, flags); 10596622d9c9SAnoob Joseph else 10606622d9c9SAnoob Joseph return test_ipsec_res_d_prepare(m, td, res_d); 1061474f1202SAnoob Joseph } 1062474f1202SAnoob Joseph 1063474f1202SAnoob Joseph int 1064d02c6bfcSTejasree Kondoj test_ipsec_status_check(const struct ipsec_test_data *td, 1065d02c6bfcSTejasree Kondoj struct rte_crypto_op *op, 10666622d9c9SAnoob Joseph const struct ipsec_test_flags *flags, 10674aa52f21SAnoob Joseph enum rte_security_ipsec_sa_direction dir, 10684aa52f21SAnoob Joseph int pkt_num) 1069474f1202SAnoob Joseph { 1070474f1202SAnoob Joseph int ret = TEST_SUCCESS; 1071474f1202SAnoob Joseph 1072d02c6bfcSTejasree Kondoj if ((dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) && 1073d02c6bfcSTejasree Kondoj td->ar_packet) { 1074d02c6bfcSTejasree Kondoj if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) { 1075d02c6bfcSTejasree Kondoj printf("Anti replay test case failed\n"); 1076d02c6bfcSTejasree Kondoj return TEST_FAILED; 1077d02c6bfcSTejasree Kondoj } else { 1078d02c6bfcSTejasree Kondoj return TEST_SUCCESS; 1079d02c6bfcSTejasree Kondoj } 1080d02c6bfcSTejasree Kondoj } 1081d02c6bfcSTejasree Kondoj 10826978f51eSAnoob Joseph if (dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS && 10836978f51eSAnoob Joseph flags->sa_expiry_pkts_hard && 10846978f51eSAnoob Joseph pkt_num == IPSEC_TEST_PACKETS_MAX) { 10856978f51eSAnoob Joseph if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) { 10866978f51eSAnoob Joseph printf("SA hard expiry (pkts) test failed\n"); 10876978f51eSAnoob Joseph return TEST_FAILED; 10886978f51eSAnoob Joseph } else { 10896978f51eSAnoob Joseph return TEST_SUCCESS; 10906978f51eSAnoob Joseph } 10916978f51eSAnoob Joseph } 10926978f51eSAnoob Joseph 1093270470eeSTejasree Kondoj if ((dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) && 1094270470eeSTejasree Kondoj flags->tunnel_hdr_verify) { 1095270470eeSTejasree Kondoj if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) { 1096270470eeSTejasree Kondoj printf("Tunnel header verify test case failed\n"); 1097270470eeSTejasree Kondoj return TEST_FAILED; 1098270470eeSTejasree Kondoj } else { 1099270470eeSTejasree Kondoj return TEST_SUCCESS; 1100270470eeSTejasree Kondoj } 1101270470eeSTejasree Kondoj } 1102270470eeSTejasree Kondoj 11030f453190STejasree Kondoj if (dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS && flags->icv_corrupt) { 11040f453190STejasree Kondoj if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) { 11050f453190STejasree Kondoj printf("ICV corruption test case failed\n"); 11060f453190STejasree Kondoj ret = TEST_FAILED; 11070f453190STejasree Kondoj } 11080f453190STejasree Kondoj } else { 1109474f1202SAnoob Joseph if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { 11104aa52f21SAnoob Joseph printf("Security op processing failed [pkt_num: %d]\n", 11114aa52f21SAnoob Joseph pkt_num); 11124aa52f21SAnoob Joseph ret = TEST_FAILED; 11134aa52f21SAnoob Joseph } 11144aa52f21SAnoob Joseph } 11154aa52f21SAnoob Joseph 11164aa52f21SAnoob Joseph if (flags->sa_expiry_pkts_soft && pkt_num == IPSEC_TEST_PACKETS_MAX) { 11174aa52f21SAnoob Joseph if (!(op->aux_flags & 11184aa52f21SAnoob Joseph RTE_CRYPTO_OP_AUX_FLAGS_IPSEC_SOFT_EXPIRY)) { 11194aa52f21SAnoob Joseph printf("SA soft expiry (pkts) test failed\n"); 1120474f1202SAnoob Joseph ret = TEST_FAILED; 1121474f1202SAnoob Joseph } 11220f453190STejasree Kondoj } 1123474f1202SAnoob Joseph 1124474f1202SAnoob Joseph return ret; 1125474f1202SAnoob Joseph } 11262c85598cSAnkur Dwivedi 11272c85598cSAnkur Dwivedi int 11282c85598cSAnkur Dwivedi test_ipsec_stats_verify(struct rte_security_ctx *ctx, 1129*2973dbf9SAkhil Goyal void *sess, 11302c85598cSAnkur Dwivedi const struct ipsec_test_flags *flags, 11312c85598cSAnkur Dwivedi enum rte_security_ipsec_sa_direction dir) 11322c85598cSAnkur Dwivedi { 11332c85598cSAnkur Dwivedi struct rte_security_stats stats = {0}; 11342c85598cSAnkur Dwivedi int ret = TEST_SUCCESS; 11352c85598cSAnkur Dwivedi 11362c85598cSAnkur Dwivedi if (flags->stats_success) { 11372c85598cSAnkur Dwivedi if (rte_security_session_stats_get(ctx, sess, &stats) < 0) 11382c85598cSAnkur Dwivedi return TEST_FAILED; 11392c85598cSAnkur Dwivedi 11402c85598cSAnkur Dwivedi if (dir == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { 11412c85598cSAnkur Dwivedi if (stats.ipsec.opackets != 1 || 11422c85598cSAnkur Dwivedi stats.ipsec.oerrors != 0) 11432c85598cSAnkur Dwivedi ret = TEST_FAILED; 11442c85598cSAnkur Dwivedi } else { 11452c85598cSAnkur Dwivedi if (stats.ipsec.ipackets != 1 || 11462c85598cSAnkur Dwivedi stats.ipsec.ierrors != 0) 11472c85598cSAnkur Dwivedi ret = TEST_FAILED; 11482c85598cSAnkur Dwivedi } 11492c85598cSAnkur Dwivedi } 11502c85598cSAnkur Dwivedi 11512c85598cSAnkur Dwivedi return ret; 11522c85598cSAnkur Dwivedi } 1153e2cbb384SAnoob Joseph 1154e2cbb384SAnoob Joseph int 1155e2cbb384SAnoob Joseph test_ipsec_pkt_update(uint8_t *pkt, const struct ipsec_test_flags *flags) 1156e2cbb384SAnoob Joseph { 1157e2cbb384SAnoob Joseph struct rte_ipv4_hdr *iph4; 115870c60cfdSAnoob Joseph struct rte_ipv6_hdr *iph6; 1159e2cbb384SAnoob Joseph bool cksum_dirty = false; 1160e2cbb384SAnoob Joseph 1161e2cbb384SAnoob Joseph iph4 = (struct rte_ipv4_hdr *)pkt; 1162e2cbb384SAnoob Joseph 1163e2cbb384SAnoob Joseph if (flags->df == TEST_IPSEC_COPY_DF_INNER_1 || 1164e2cbb384SAnoob Joseph flags->df == TEST_IPSEC_SET_DF_0_INNER_1 || 1165e2cbb384SAnoob Joseph flags->df == TEST_IPSEC_COPY_DF_INNER_0 || 1166e2cbb384SAnoob Joseph flags->df == TEST_IPSEC_SET_DF_1_INNER_0) { 116770c60cfdSAnoob Joseph uint16_t frag_off; 1168e2cbb384SAnoob Joseph 1169e2cbb384SAnoob Joseph if (!is_ipv4(iph4)) { 117070c60cfdSAnoob Joseph printf("Invalid packet type\n"); 1171e2cbb384SAnoob Joseph return -1; 1172e2cbb384SAnoob Joseph } 1173e2cbb384SAnoob Joseph 1174e2cbb384SAnoob Joseph frag_off = rte_be_to_cpu_16(iph4->fragment_offset); 1175e2cbb384SAnoob Joseph 1176e2cbb384SAnoob Joseph if (flags->df == TEST_IPSEC_COPY_DF_INNER_1 || 1177e2cbb384SAnoob Joseph flags->df == TEST_IPSEC_SET_DF_0_INNER_1) 1178e2cbb384SAnoob Joseph frag_off |= RTE_IPV4_HDR_DF_FLAG; 1179e2cbb384SAnoob Joseph else 1180e2cbb384SAnoob Joseph frag_off &= ~RTE_IPV4_HDR_DF_FLAG; 1181e2cbb384SAnoob Joseph 1182e2cbb384SAnoob Joseph iph4->fragment_offset = rte_cpu_to_be_16(frag_off); 1183e2cbb384SAnoob Joseph cksum_dirty = true; 1184e2cbb384SAnoob Joseph } 1185e2cbb384SAnoob Joseph 118670c60cfdSAnoob Joseph if (flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_1 || 118770c60cfdSAnoob Joseph flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1 || 118870c60cfdSAnoob Joseph flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_0 || 118991d1d052SVamsi Attunuru flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0 || 119091d1d052SVamsi Attunuru flags->flabel == TEST_IPSEC_COPY_FLABEL_INNER_1 || 119191d1d052SVamsi Attunuru flags->flabel == TEST_IPSEC_SET_FLABEL_0_INNER_1 || 119291d1d052SVamsi Attunuru flags->flabel == TEST_IPSEC_COPY_FLABEL_INNER_0 || 119391d1d052SVamsi Attunuru flags->flabel == TEST_IPSEC_SET_FLABEL_1_INNER_0) { 119470c60cfdSAnoob Joseph 119570c60cfdSAnoob Joseph if (is_ipv4(iph4)) { 119670c60cfdSAnoob Joseph uint8_t tos; 119770c60cfdSAnoob Joseph 119870c60cfdSAnoob Joseph tos = iph4->type_of_service; 119970c60cfdSAnoob Joseph if (flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_1 || 120070c60cfdSAnoob Joseph flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1) 120170c60cfdSAnoob Joseph tos |= (RTE_IPV4_HDR_DSCP_MASK & 120270c60cfdSAnoob Joseph (TEST_IPSEC_DSCP_VAL << 2)); 120370c60cfdSAnoob Joseph else 120470c60cfdSAnoob Joseph tos &= ~RTE_IPV4_HDR_DSCP_MASK; 120570c60cfdSAnoob Joseph 120670c60cfdSAnoob Joseph iph4->type_of_service = tos; 120770c60cfdSAnoob Joseph cksum_dirty = true; 120870c60cfdSAnoob Joseph } else { 120970c60cfdSAnoob Joseph uint32_t vtc_flow; 121070c60cfdSAnoob Joseph 121170c60cfdSAnoob Joseph iph6 = (struct rte_ipv6_hdr *)pkt; 121270c60cfdSAnoob Joseph 121370c60cfdSAnoob Joseph vtc_flow = rte_be_to_cpu_32(iph6->vtc_flow); 121470c60cfdSAnoob Joseph if (flags->dscp == TEST_IPSEC_COPY_DSCP_INNER_1 || 121570c60cfdSAnoob Joseph flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1) 121670c60cfdSAnoob Joseph vtc_flow |= (RTE_IPV6_HDR_DSCP_MASK & 121770c60cfdSAnoob Joseph (TEST_IPSEC_DSCP_VAL << (RTE_IPV6_HDR_TC_SHIFT + 2))); 121870c60cfdSAnoob Joseph else 121970c60cfdSAnoob Joseph vtc_flow &= ~RTE_IPV6_HDR_DSCP_MASK; 122070c60cfdSAnoob Joseph 122191d1d052SVamsi Attunuru if (flags->flabel == TEST_IPSEC_COPY_FLABEL_INNER_1 || 122291d1d052SVamsi Attunuru flags->flabel == TEST_IPSEC_SET_FLABEL_0_INNER_1) 122391d1d052SVamsi Attunuru vtc_flow |= (RTE_IPV6_HDR_FL_MASK & 122491d1d052SVamsi Attunuru (TEST_IPSEC_FLABEL_VAL << RTE_IPV6_HDR_FL_SHIFT)); 122591d1d052SVamsi Attunuru else 122691d1d052SVamsi Attunuru vtc_flow &= ~RTE_IPV6_HDR_FL_MASK; 122791d1d052SVamsi Attunuru 122870c60cfdSAnoob Joseph iph6->vtc_flow = rte_cpu_to_be_32(vtc_flow); 122970c60cfdSAnoob Joseph } 123070c60cfdSAnoob Joseph } 123170c60cfdSAnoob Joseph 1232e2cbb384SAnoob Joseph if (cksum_dirty && is_ipv4(iph4)) { 1233e2cbb384SAnoob Joseph iph4->hdr_checksum = 0; 1234e2cbb384SAnoob Joseph iph4->hdr_checksum = rte_ipv4_cksum(iph4); 1235e2cbb384SAnoob Joseph } 1236e2cbb384SAnoob Joseph 1237e2cbb384SAnoob Joseph return 0; 1238e2cbb384SAnoob Joseph } 1239