xref: /dpdk/app/test/test_cryptodev_security_ipsec.c (revision b7986bde8e2159b75b45ff92579d9ba19bda4c1b)
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 
188d290523SAnoob Joseph struct crypto_param_comb alg_list[RTE_DIM(aead_list) +
198d290523SAnoob Joseph 				  (RTE_DIM(cipher_list) *
208d290523SAnoob Joseph 				   RTE_DIM(auth_list))];
218d290523SAnoob Joseph 
229fb87fbfSTejasree Kondoj static bool
239fb87fbfSTejasree Kondoj is_valid_ipv4_pkt(const struct rte_ipv4_hdr *pkt)
249fb87fbfSTejasree Kondoj {
259fb87fbfSTejasree Kondoj 	/* The IP version number must be 4 */
269fb87fbfSTejasree Kondoj 	if (((pkt->version_ihl) >> 4) != 4)
279fb87fbfSTejasree Kondoj 		return false;
289fb87fbfSTejasree Kondoj 	/*
299fb87fbfSTejasree Kondoj 	 * The IP header length field must be large enough to hold the
309fb87fbfSTejasree Kondoj 	 * minimum length legal IP datagram (20 bytes = 5 words).
319fb87fbfSTejasree Kondoj 	 */
329fb87fbfSTejasree Kondoj 	if ((pkt->version_ihl & 0xf) < 5)
339fb87fbfSTejasree Kondoj 		return false;
349fb87fbfSTejasree Kondoj 
359fb87fbfSTejasree Kondoj 	/*
369fb87fbfSTejasree Kondoj 	 * The IP total length field must be large enough to hold the IP
379fb87fbfSTejasree Kondoj 	 * datagram header, whose length is specified in the IP header length
389fb87fbfSTejasree Kondoj 	 * field.
399fb87fbfSTejasree Kondoj 	 */
409fb87fbfSTejasree Kondoj 	if (rte_cpu_to_be_16(pkt->total_length) < sizeof(struct rte_ipv4_hdr))
419fb87fbfSTejasree Kondoj 		return false;
429fb87fbfSTejasree Kondoj 
439fb87fbfSTejasree Kondoj 	return true;
449fb87fbfSTejasree Kondoj }
459fb87fbfSTejasree Kondoj 
469fb87fbfSTejasree Kondoj static bool
479fb87fbfSTejasree Kondoj is_valid_ipv6_pkt(const struct rte_ipv6_hdr *pkt)
489fb87fbfSTejasree Kondoj {
499fb87fbfSTejasree Kondoj 	/* The IP version number must be 6 */
509fb87fbfSTejasree Kondoj 	if ((rte_be_to_cpu_32((pkt->vtc_flow)) >> 28) != 6)
519fb87fbfSTejasree Kondoj 		return false;
529fb87fbfSTejasree Kondoj 
539fb87fbfSTejasree Kondoj 	return true;
549fb87fbfSTejasree Kondoj }
559fb87fbfSTejasree Kondoj 
568d290523SAnoob Joseph void
578d290523SAnoob Joseph test_ipsec_alg_list_populate(void)
588d290523SAnoob Joseph {
598d290523SAnoob Joseph 	unsigned long i, j, index = 0;
608d290523SAnoob Joseph 
618d290523SAnoob Joseph 	for (i = 0; i < RTE_DIM(aead_list); i++) {
628d290523SAnoob Joseph 		alg_list[index].param1 = &aead_list[i];
638d290523SAnoob Joseph 		alg_list[index].param2 = NULL;
648d290523SAnoob Joseph 		index++;
658d290523SAnoob Joseph 	}
668d290523SAnoob Joseph 
678d290523SAnoob Joseph 	for (i = 0; i < RTE_DIM(cipher_list); i++) {
688d290523SAnoob Joseph 		for (j = 0; j < RTE_DIM(auth_list); j++) {
698d290523SAnoob Joseph 			alg_list[index].param1 = &cipher_list[i];
708d290523SAnoob Joseph 			alg_list[index].param2 = &auth_list[j];
718d290523SAnoob Joseph 			index++;
728d290523SAnoob Joseph 		}
738d290523SAnoob Joseph 	}
748d290523SAnoob Joseph }
756622d9c9SAnoob Joseph 
76474f1202SAnoob Joseph int
77474f1202SAnoob Joseph test_ipsec_sec_caps_verify(struct rte_security_ipsec_xform *ipsec_xform,
78474f1202SAnoob Joseph 			   const struct rte_security_capability *sec_cap,
79474f1202SAnoob Joseph 			   bool silent)
80474f1202SAnoob Joseph {
81474f1202SAnoob Joseph 	/* Verify security capabilities */
82474f1202SAnoob Joseph 
83474f1202SAnoob Joseph 	if (ipsec_xform->options.esn == 1 && sec_cap->ipsec.options.esn == 0) {
84474f1202SAnoob Joseph 		if (!silent)
85474f1202SAnoob Joseph 			RTE_LOG(INFO, USER1, "ESN is not supported\n");
86474f1202SAnoob Joseph 		return -ENOTSUP;
87474f1202SAnoob Joseph 	}
88474f1202SAnoob Joseph 
89474f1202SAnoob Joseph 	if (ipsec_xform->options.udp_encap == 1 &&
90474f1202SAnoob Joseph 	    sec_cap->ipsec.options.udp_encap == 0) {
91474f1202SAnoob Joseph 		if (!silent)
92474f1202SAnoob Joseph 			RTE_LOG(INFO, USER1, "UDP encapsulation is not supported\n");
93474f1202SAnoob Joseph 		return -ENOTSUP;
94474f1202SAnoob Joseph 	}
95474f1202SAnoob Joseph 
969ec50a52STejasree Kondoj 	if (ipsec_xform->options.udp_ports_verify == 1 &&
979ec50a52STejasree Kondoj 	    sec_cap->ipsec.options.udp_ports_verify == 0) {
989ec50a52STejasree Kondoj 		if (!silent)
999ec50a52STejasree Kondoj 			RTE_LOG(INFO, USER1, "UDP encapsulation ports "
1009ec50a52STejasree Kondoj 				"verification is not supported\n");
1019ec50a52STejasree Kondoj 		return -ENOTSUP;
1029ec50a52STejasree Kondoj 	}
1039ec50a52STejasree Kondoj 
104474f1202SAnoob Joseph 	if (ipsec_xform->options.copy_dscp == 1 &&
105474f1202SAnoob Joseph 	    sec_cap->ipsec.options.copy_dscp == 0) {
106474f1202SAnoob Joseph 		if (!silent)
107474f1202SAnoob Joseph 			RTE_LOG(INFO, USER1, "Copy DSCP is not supported\n");
108474f1202SAnoob Joseph 		return -ENOTSUP;
109474f1202SAnoob Joseph 	}
110474f1202SAnoob Joseph 
111474f1202SAnoob Joseph 	if (ipsec_xform->options.copy_flabel == 1 &&
112474f1202SAnoob Joseph 	    sec_cap->ipsec.options.copy_flabel == 0) {
113474f1202SAnoob Joseph 		if (!silent)
114474f1202SAnoob Joseph 			RTE_LOG(INFO, USER1, "Copy Flow Label is not supported\n");
115474f1202SAnoob Joseph 		return -ENOTSUP;
116474f1202SAnoob Joseph 	}
117474f1202SAnoob Joseph 
118474f1202SAnoob Joseph 	if (ipsec_xform->options.copy_df == 1 &&
119474f1202SAnoob Joseph 	    sec_cap->ipsec.options.copy_df == 0) {
120474f1202SAnoob Joseph 		if (!silent)
121474f1202SAnoob Joseph 			RTE_LOG(INFO, USER1, "Copy DP bit is not supported\n");
122474f1202SAnoob Joseph 		return -ENOTSUP;
123474f1202SAnoob Joseph 	}
124474f1202SAnoob Joseph 
125474f1202SAnoob Joseph 	if (ipsec_xform->options.dec_ttl == 1 &&
126474f1202SAnoob Joseph 	    sec_cap->ipsec.options.dec_ttl == 0) {
127474f1202SAnoob Joseph 		if (!silent)
128474f1202SAnoob Joseph 			RTE_LOG(INFO, USER1, "Decrement TTL is not supported\n");
129474f1202SAnoob Joseph 		return -ENOTSUP;
130474f1202SAnoob Joseph 	}
131474f1202SAnoob Joseph 
132474f1202SAnoob Joseph 	if (ipsec_xform->options.ecn == 1 && sec_cap->ipsec.options.ecn == 0) {
133474f1202SAnoob Joseph 		if (!silent)
134474f1202SAnoob Joseph 			RTE_LOG(INFO, USER1, "ECN is not supported\n");
135474f1202SAnoob Joseph 		return -ENOTSUP;
136474f1202SAnoob Joseph 	}
137474f1202SAnoob Joseph 
138474f1202SAnoob Joseph 	if (ipsec_xform->options.stats == 1 &&
139474f1202SAnoob Joseph 	    sec_cap->ipsec.options.stats == 0) {
140474f1202SAnoob Joseph 		if (!silent)
141474f1202SAnoob Joseph 			RTE_LOG(INFO, USER1, "Stats is not supported\n");
142474f1202SAnoob Joseph 		return -ENOTSUP;
143474f1202SAnoob Joseph 	}
144474f1202SAnoob Joseph 
1450532f50cSAnoob Joseph 	if ((ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) &&
1460532f50cSAnoob Joseph 	    (ipsec_xform->options.iv_gen_disable == 1) &&
1470532f50cSAnoob Joseph 	    (sec_cap->ipsec.options.iv_gen_disable != 1)) {
1480532f50cSAnoob Joseph 		if (!silent)
1490532f50cSAnoob Joseph 			RTE_LOG(INFO, USER1,
1500532f50cSAnoob Joseph 				"Application provided IV is not supported\n");
1510532f50cSAnoob Joseph 		return -ENOTSUP;
1520532f50cSAnoob Joseph 	}
1530532f50cSAnoob Joseph 
154270470eeSTejasree Kondoj 	if ((ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
155270470eeSTejasree Kondoj 	    (ipsec_xform->options.tunnel_hdr_verify >
156270470eeSTejasree Kondoj 	    sec_cap->ipsec.options.tunnel_hdr_verify)) {
157270470eeSTejasree Kondoj 		if (!silent)
158270470eeSTejasree Kondoj 			RTE_LOG(INFO, USER1,
159270470eeSTejasree Kondoj 				"Tunnel header verify is not supported\n");
160270470eeSTejasree Kondoj 		return -ENOTSUP;
161270470eeSTejasree Kondoj 	}
162270470eeSTejasree Kondoj 
16383243502SArchana Muniganti 	if (ipsec_xform->options.ip_csum_enable == 1 &&
16483243502SArchana Muniganti 	    sec_cap->ipsec.options.ip_csum_enable == 0) {
16583243502SArchana Muniganti 		if (!silent)
16683243502SArchana Muniganti 			RTE_LOG(INFO, USER1,
16783243502SArchana Muniganti 				"Inner IP checksum is not supported\n");
16883243502SArchana Muniganti 		return -ENOTSUP;
16983243502SArchana Muniganti 	}
17083243502SArchana Muniganti 
17183243502SArchana Muniganti 	if (ipsec_xform->options.l4_csum_enable == 1 &&
17283243502SArchana Muniganti 	    sec_cap->ipsec.options.l4_csum_enable == 0) {
17383243502SArchana Muniganti 		if (!silent)
17483243502SArchana Muniganti 			RTE_LOG(INFO, USER1,
17583243502SArchana Muniganti 				"Inner L4 checksum is not supported\n");
17683243502SArchana Muniganti 		return -ENOTSUP;
17783243502SArchana Muniganti 	}
17883243502SArchana Muniganti 
179474f1202SAnoob Joseph 	return 0;
180474f1202SAnoob Joseph }
181474f1202SAnoob Joseph 
182474f1202SAnoob Joseph int
183474f1202SAnoob Joseph test_ipsec_crypto_caps_aead_verify(
184474f1202SAnoob Joseph 		const struct rte_security_capability *sec_cap,
185474f1202SAnoob Joseph 		struct rte_crypto_sym_xform *aead)
186474f1202SAnoob Joseph {
187474f1202SAnoob Joseph 	const struct rte_cryptodev_symmetric_capability *sym_cap;
188474f1202SAnoob Joseph 	const struct rte_cryptodev_capabilities *crypto_cap;
189474f1202SAnoob Joseph 	int j = 0;
190474f1202SAnoob Joseph 
191474f1202SAnoob Joseph 	while ((crypto_cap = &sec_cap->crypto_capabilities[j++])->op !=
192474f1202SAnoob Joseph 			RTE_CRYPTO_OP_TYPE_UNDEFINED) {
193474f1202SAnoob Joseph 		if (crypto_cap->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC &&
194474f1202SAnoob Joseph 				crypto_cap->sym.xform_type == aead->type &&
195474f1202SAnoob Joseph 				crypto_cap->sym.aead.algo == aead->aead.algo) {
196474f1202SAnoob Joseph 			sym_cap = &crypto_cap->sym;
197474f1202SAnoob Joseph 			if (rte_cryptodev_sym_capability_check_aead(sym_cap,
198474f1202SAnoob Joseph 					aead->aead.key.length,
199474f1202SAnoob Joseph 					aead->aead.digest_length,
200474f1202SAnoob Joseph 					aead->aead.aad_length,
201474f1202SAnoob Joseph 					aead->aead.iv.length) == 0)
202474f1202SAnoob Joseph 				return 0;
203474f1202SAnoob Joseph 		}
204474f1202SAnoob Joseph 	}
205474f1202SAnoob Joseph 
206474f1202SAnoob Joseph 	return -ENOTSUP;
207474f1202SAnoob Joseph }
208474f1202SAnoob Joseph 
20967d2a188SAnoob Joseph int
21067d2a188SAnoob Joseph test_ipsec_crypto_caps_cipher_verify(
21167d2a188SAnoob Joseph 		const struct rte_security_capability *sec_cap,
21267d2a188SAnoob Joseph 		struct rte_crypto_sym_xform *cipher)
21367d2a188SAnoob Joseph {
21467d2a188SAnoob Joseph 	const struct rte_cryptodev_symmetric_capability *sym_cap;
21567d2a188SAnoob Joseph 	const struct rte_cryptodev_capabilities *cap;
21667d2a188SAnoob Joseph 	int j = 0;
21767d2a188SAnoob Joseph 
21867d2a188SAnoob Joseph 	while ((cap = &sec_cap->crypto_capabilities[j++])->op !=
21967d2a188SAnoob Joseph 			RTE_CRYPTO_OP_TYPE_UNDEFINED) {
22067d2a188SAnoob Joseph 		if (cap->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC &&
22167d2a188SAnoob Joseph 				cap->sym.xform_type == cipher->type &&
22267d2a188SAnoob Joseph 				cap->sym.cipher.algo == cipher->cipher.algo) {
22367d2a188SAnoob Joseph 			sym_cap = &cap->sym;
22467d2a188SAnoob Joseph 			if (rte_cryptodev_sym_capability_check_cipher(sym_cap,
22567d2a188SAnoob Joseph 					cipher->cipher.key.length,
22667d2a188SAnoob Joseph 					cipher->cipher.iv.length) == 0)
22767d2a188SAnoob Joseph 				return 0;
22867d2a188SAnoob Joseph 		}
22967d2a188SAnoob Joseph 	}
23067d2a188SAnoob Joseph 
23167d2a188SAnoob Joseph 	return -ENOTSUP;
23267d2a188SAnoob Joseph }
23367d2a188SAnoob Joseph 
23467d2a188SAnoob Joseph int
23567d2a188SAnoob Joseph test_ipsec_crypto_caps_auth_verify(
23667d2a188SAnoob Joseph 		const struct rte_security_capability *sec_cap,
23767d2a188SAnoob Joseph 		struct rte_crypto_sym_xform *auth)
23867d2a188SAnoob Joseph {
23967d2a188SAnoob Joseph 	const struct rte_cryptodev_symmetric_capability *sym_cap;
24067d2a188SAnoob Joseph 	const struct rte_cryptodev_capabilities *cap;
24167d2a188SAnoob Joseph 	int j = 0;
24267d2a188SAnoob Joseph 
24367d2a188SAnoob Joseph 	while ((cap = &sec_cap->crypto_capabilities[j++])->op !=
24467d2a188SAnoob Joseph 			RTE_CRYPTO_OP_TYPE_UNDEFINED) {
24567d2a188SAnoob Joseph 		if (cap->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC &&
24667d2a188SAnoob Joseph 				cap->sym.xform_type == auth->type &&
24767d2a188SAnoob Joseph 				cap->sym.auth.algo == auth->auth.algo) {
24867d2a188SAnoob Joseph 			sym_cap = &cap->sym;
24967d2a188SAnoob Joseph 			if (rte_cryptodev_sym_capability_check_auth(sym_cap,
25067d2a188SAnoob Joseph 					auth->auth.key.length,
25167d2a188SAnoob Joseph 					auth->auth.digest_length,
25267d2a188SAnoob Joseph 					auth->auth.iv.length) == 0)
25367d2a188SAnoob Joseph 				return 0;
25467d2a188SAnoob Joseph 		}
25567d2a188SAnoob Joseph 	}
25667d2a188SAnoob Joseph 
25767d2a188SAnoob Joseph 	return -ENOTSUP;
25867d2a188SAnoob Joseph }
25967d2a188SAnoob Joseph 
260474f1202SAnoob Joseph void
261474f1202SAnoob Joseph test_ipsec_td_in_from_out(const struct ipsec_test_data *td_out,
262474f1202SAnoob Joseph 			  struct ipsec_test_data *td_in)
263474f1202SAnoob Joseph {
264474f1202SAnoob Joseph 	memcpy(td_in, td_out, sizeof(*td_in));
265474f1202SAnoob Joseph 
266474f1202SAnoob Joseph 	/* Populate output text of td_in with input text of td_out */
267474f1202SAnoob Joseph 	memcpy(td_in->output_text.data, td_out->input_text.data,
268474f1202SAnoob Joseph 	       td_out->input_text.len);
269474f1202SAnoob Joseph 	td_in->output_text.len = td_out->input_text.len;
270474f1202SAnoob Joseph 
271474f1202SAnoob Joseph 	/* Populate input text of td_in with output text of td_out */
272474f1202SAnoob Joseph 	memcpy(td_in->input_text.data, td_out->output_text.data,
273474f1202SAnoob Joseph 	       td_out->output_text.len);
274474f1202SAnoob Joseph 	td_in->input_text.len = td_out->output_text.len;
275474f1202SAnoob Joseph 
276474f1202SAnoob Joseph 	td_in->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
277474f1202SAnoob Joseph 
278474f1202SAnoob Joseph 	if (td_in->aead) {
279474f1202SAnoob Joseph 		td_in->xform.aead.aead.op = RTE_CRYPTO_AEAD_OP_DECRYPT;
280474f1202SAnoob Joseph 	} else {
281474f1202SAnoob Joseph 		td_in->xform.chain.auth.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
282474f1202SAnoob Joseph 		td_in->xform.chain.cipher.cipher.op =
283474f1202SAnoob Joseph 				RTE_CRYPTO_CIPHER_OP_DECRYPT;
284474f1202SAnoob Joseph 	}
285474f1202SAnoob Joseph }
286474f1202SAnoob Joseph 
28783243502SArchana Muniganti static bool
28883243502SArchana Muniganti is_ipv4(void *ip)
28983243502SArchana Muniganti {
29083243502SArchana Muniganti 	struct rte_ipv4_hdr *ipv4 = ip;
29183243502SArchana Muniganti 	uint8_t ip_ver;
29283243502SArchana Muniganti 
29383243502SArchana Muniganti 	ip_ver = (ipv4->version_ihl & 0xf0) >> RTE_IPV4_IHL_MULTIPLIER;
29483243502SArchana Muniganti 	if (ip_ver == IPVERSION)
29583243502SArchana Muniganti 		return true;
29683243502SArchana Muniganti 	else
29783243502SArchana Muniganti 		return false;
29883243502SArchana Muniganti }
29983243502SArchana Muniganti 
30083243502SArchana Muniganti static void
30183243502SArchana Muniganti test_ipsec_csum_init(void *ip, bool l3, bool l4)
30283243502SArchana Muniganti {
30383243502SArchana Muniganti 	struct rte_ipv4_hdr *ipv4;
30483243502SArchana Muniganti 	struct rte_tcp_hdr *tcp;
30583243502SArchana Muniganti 	struct rte_udp_hdr *udp;
30683243502SArchana Muniganti 	uint8_t next_proto;
30783243502SArchana Muniganti 	uint8_t size;
30883243502SArchana Muniganti 
30983243502SArchana Muniganti 	if (is_ipv4(ip)) {
31083243502SArchana Muniganti 		ipv4 = ip;
31183243502SArchana Muniganti 		size = sizeof(struct rte_ipv4_hdr);
31283243502SArchana Muniganti 		next_proto = ipv4->next_proto_id;
31383243502SArchana Muniganti 
31483243502SArchana Muniganti 		if (l3)
31583243502SArchana Muniganti 			ipv4->hdr_checksum = 0;
31683243502SArchana Muniganti 	} else {
31783243502SArchana Muniganti 		size = sizeof(struct rte_ipv6_hdr);
31883243502SArchana Muniganti 		next_proto = ((struct rte_ipv6_hdr *)ip)->proto;
31983243502SArchana Muniganti 	}
32083243502SArchana Muniganti 
32183243502SArchana Muniganti 	if (l4) {
32283243502SArchana Muniganti 		switch (next_proto) {
32383243502SArchana Muniganti 		case IPPROTO_TCP:
32483243502SArchana Muniganti 			tcp = (struct rte_tcp_hdr *)RTE_PTR_ADD(ip, size);
32583243502SArchana Muniganti 			tcp->cksum = 0;
32683243502SArchana Muniganti 			break;
32783243502SArchana Muniganti 		case IPPROTO_UDP:
32883243502SArchana Muniganti 			udp = (struct rte_udp_hdr *)RTE_PTR_ADD(ip, size);
32983243502SArchana Muniganti 			udp->dgram_cksum = 0;
33083243502SArchana Muniganti 			break;
33183243502SArchana Muniganti 		default:
33283243502SArchana Muniganti 			return;
33383243502SArchana Muniganti 		}
33483243502SArchana Muniganti 	}
33583243502SArchana Muniganti }
33683243502SArchana Muniganti 
3376622d9c9SAnoob Joseph void
3386622d9c9SAnoob Joseph test_ipsec_td_prepare(const struct crypto_param *param1,
3396622d9c9SAnoob Joseph 		      const struct crypto_param *param2,
3406622d9c9SAnoob Joseph 		      const struct ipsec_test_flags *flags,
3416622d9c9SAnoob Joseph 		      struct ipsec_test_data *td_array,
3426622d9c9SAnoob Joseph 		      int nb_td)
3436622d9c9SAnoob Joseph 
3446622d9c9SAnoob Joseph {
3456622d9c9SAnoob Joseph 	struct ipsec_test_data *td;
3466622d9c9SAnoob Joseph 	int i;
3476622d9c9SAnoob Joseph 
3486622d9c9SAnoob Joseph 	memset(td_array, 0, nb_td * sizeof(*td));
3496622d9c9SAnoob Joseph 
3506622d9c9SAnoob Joseph 	for (i = 0; i < nb_td; i++) {
3516622d9c9SAnoob Joseph 		td = &td_array[i];
3528d290523SAnoob Joseph 
3538d290523SAnoob Joseph 		/* Prepare fields based on param */
3548d290523SAnoob Joseph 
3558d290523SAnoob Joseph 		if (param1->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
3566622d9c9SAnoob Joseph 			/* Copy template for packet & key fields */
3579fb87fbfSTejasree Kondoj 			if (flags->ipv6)
3589fb87fbfSTejasree Kondoj 				memcpy(td, &pkt_aes_256_gcm_v6, sizeof(*td));
3599fb87fbfSTejasree Kondoj 			else
3606622d9c9SAnoob Joseph 				memcpy(td, &pkt_aes_256_gcm, sizeof(*td));
3616622d9c9SAnoob Joseph 
3626622d9c9SAnoob Joseph 			td->aead = true;
3636622d9c9SAnoob Joseph 			td->xform.aead.aead.algo = param1->alg.aead;
3646622d9c9SAnoob Joseph 			td->xform.aead.aead.key.length = param1->key_length;
3658d290523SAnoob Joseph 		} else {
3668d290523SAnoob Joseph 			/* Copy template for packet & key fields */
3679fb87fbfSTejasree Kondoj 			if (flags->ipv6)
3689fb87fbfSTejasree Kondoj 				memcpy(td, &pkt_aes_128_cbc_hmac_sha256_v6,
3699fb87fbfSTejasree Kondoj 					sizeof(*td));
3709fb87fbfSTejasree Kondoj 			else
3719fb87fbfSTejasree Kondoj 				memcpy(td, &pkt_aes_128_cbc_hmac_sha256,
3729fb87fbfSTejasree Kondoj 					sizeof(*td));
3738d290523SAnoob Joseph 
3748d290523SAnoob Joseph 			td->aead = false;
3758d290523SAnoob Joseph 			td->xform.chain.cipher.cipher.algo = param1->alg.cipher;
3768d290523SAnoob Joseph 			td->xform.chain.cipher.cipher.key.length =
3778d290523SAnoob Joseph 					param1->key_length;
3788d290523SAnoob Joseph 			td->xform.chain.auth.auth.algo = param2->alg.auth;
3798d290523SAnoob Joseph 			td->xform.chain.auth.auth.key.length =
3808d290523SAnoob Joseph 					param2->key_length;
3818d290523SAnoob Joseph 			td->xform.chain.auth.auth.digest_length =
3828d290523SAnoob Joseph 					param2->digest_length;
3838d290523SAnoob Joseph 
3848d290523SAnoob Joseph 		}
3850532f50cSAnoob Joseph 
3860532f50cSAnoob Joseph 		if (flags->iv_gen)
3870532f50cSAnoob Joseph 			td->ipsec_xform.options.iv_gen_disable = 0;
3884aa52f21SAnoob Joseph 
3894aa52f21SAnoob Joseph 		if (flags->sa_expiry_pkts_soft)
3904aa52f21SAnoob Joseph 			td->ipsec_xform.life.packets_soft_limit =
3914aa52f21SAnoob Joseph 					IPSEC_TEST_PACKETS_MAX - 1;
39283243502SArchana Muniganti 
39383243502SArchana Muniganti 		if (flags->ip_csum) {
39483243502SArchana Muniganti 			td->ipsec_xform.options.ip_csum_enable = 1;
39583243502SArchana Muniganti 			test_ipsec_csum_init(&td->input_text.data, true, false);
39683243502SArchana Muniganti 		}
39783243502SArchana Muniganti 
39883243502SArchana Muniganti 		if (flags->l4_csum) {
39983243502SArchana Muniganti 			td->ipsec_xform.options.l4_csum_enable = 1;
40083243502SArchana Muniganti 			test_ipsec_csum_init(&td->input_text.data, false, true);
40183243502SArchana Muniganti 		}
40283243502SArchana Muniganti 
4039fb87fbfSTejasree Kondoj 		if (flags->tunnel_ipv6)
4049fb87fbfSTejasree Kondoj 			td->ipsec_xform.tunnel.type =
4059fb87fbfSTejasree Kondoj 					RTE_SECURITY_IPSEC_TUNNEL_IPV6;
4069fb87fbfSTejasree Kondoj 		else
4079fb87fbfSTejasree Kondoj 			td->ipsec_xform.tunnel.type =
4089fb87fbfSTejasree Kondoj 					RTE_SECURITY_IPSEC_TUNNEL_IPV4;
4099fb87fbfSTejasree Kondoj 
4106622d9c9SAnoob Joseph 	}
4116622d9c9SAnoob Joseph }
4126622d9c9SAnoob Joseph 
4136622d9c9SAnoob Joseph void
4146622d9c9SAnoob Joseph test_ipsec_td_update(struct ipsec_test_data td_inb[],
4156622d9c9SAnoob Joseph 		     const struct ipsec_test_data td_outb[],
4166622d9c9SAnoob Joseph 		     int nb_td,
4176622d9c9SAnoob Joseph 		     const struct ipsec_test_flags *flags)
4186622d9c9SAnoob Joseph {
4196622d9c9SAnoob Joseph 	int i;
4206622d9c9SAnoob Joseph 
4216622d9c9SAnoob Joseph 	for (i = 0; i < nb_td; i++) {
4226622d9c9SAnoob Joseph 		memcpy(td_inb[i].output_text.data, td_outb[i].input_text.data,
4236622d9c9SAnoob Joseph 		       td_outb[i].input_text.len);
4246622d9c9SAnoob Joseph 		td_inb[i].output_text.len = td_outb->input_text.len;
4256622d9c9SAnoob Joseph 
4260f453190STejasree Kondoj 		if (flags->icv_corrupt) {
4270f453190STejasree Kondoj 			int icv_pos = td_inb[i].input_text.len - 4;
4280f453190STejasree Kondoj 			td_inb[i].input_text.data[icv_pos] += 1;
4290f453190STejasree Kondoj 		}
430c8234341STejasree Kondoj 
4316978f51eSAnoob Joseph 		if (flags->sa_expiry_pkts_hard)
4326978f51eSAnoob Joseph 			td_inb[i].ipsec_xform.life.packets_hard_limit =
4336978f51eSAnoob Joseph 					IPSEC_TEST_PACKETS_MAX - 1;
4346978f51eSAnoob Joseph 
435c8234341STejasree Kondoj 		if (flags->udp_encap)
436c8234341STejasree Kondoj 			td_inb[i].ipsec_xform.options.udp_encap = 1;
4370532f50cSAnoob Joseph 
4389ec50a52STejasree Kondoj 		if (flags->udp_ports_verify)
4399ec50a52STejasree Kondoj 			td_inb[i].ipsec_xform.options.udp_ports_verify = 1;
4409ec50a52STejasree Kondoj 
441270470eeSTejasree Kondoj 		td_inb[i].ipsec_xform.options.tunnel_hdr_verify =
442270470eeSTejasree Kondoj 			flags->tunnel_hdr_verify;
443270470eeSTejasree Kondoj 
44483243502SArchana Muniganti 		if (flags->ip_csum)
44583243502SArchana Muniganti 			td_inb[i].ipsec_xform.options.ip_csum_enable = 1;
44683243502SArchana Muniganti 
44783243502SArchana Muniganti 		if (flags->l4_csum)
44883243502SArchana Muniganti 			td_inb[i].ipsec_xform.options.l4_csum_enable = 1;
44983243502SArchana Muniganti 
4500532f50cSAnoob Joseph 		/* Clear outbound specific flags */
4510532f50cSAnoob Joseph 		td_inb[i].ipsec_xform.options.iv_gen_disable = 0;
4520f453190STejasree Kondoj 	}
4536622d9c9SAnoob Joseph }
4546622d9c9SAnoob Joseph 
4556622d9c9SAnoob Joseph void
4566622d9c9SAnoob Joseph test_ipsec_display_alg(const struct crypto_param *param1,
4576622d9c9SAnoob Joseph 		       const struct crypto_param *param2)
4586622d9c9SAnoob Joseph {
4598d290523SAnoob Joseph 	if (param1->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
4608d290523SAnoob Joseph 		printf("\t%s [%d]",
4616622d9c9SAnoob Joseph 		       rte_crypto_aead_algorithm_strings[param1->alg.aead],
4628d290523SAnoob Joseph 		       param1->key_length * 8);
4638d290523SAnoob Joseph 	} else {
4648d290523SAnoob Joseph 		printf("\t%s",
4658d290523SAnoob Joseph 		       rte_crypto_cipher_algorithm_strings[param1->alg.cipher]);
4668d290523SAnoob Joseph 		if (param1->alg.cipher != RTE_CRYPTO_CIPHER_NULL)
4678d290523SAnoob Joseph 			printf(" [%d]", param1->key_length * 8);
4688d290523SAnoob Joseph 		printf(" %s",
4698d290523SAnoob Joseph 		       rte_crypto_auth_algorithm_strings[param2->alg.auth]);
4708d290523SAnoob Joseph 		if (param2->alg.auth != RTE_CRYPTO_AUTH_NULL)
4718d290523SAnoob Joseph 			printf(" [%dB ICV]", param2->digest_length);
4728d290523SAnoob Joseph 	}
4738d290523SAnoob Joseph 	printf("\n");
4746622d9c9SAnoob Joseph }
4756622d9c9SAnoob Joseph 
476474f1202SAnoob Joseph static int
477474f1202SAnoob Joseph test_ipsec_tunnel_hdr_len_get(const struct ipsec_test_data *td)
478474f1202SAnoob Joseph {
479474f1202SAnoob Joseph 	int len = 0;
480474f1202SAnoob Joseph 
481474f1202SAnoob Joseph 	if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
482474f1202SAnoob Joseph 		if (td->ipsec_xform.mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
483474f1202SAnoob Joseph 			if (td->ipsec_xform.tunnel.type ==
484474f1202SAnoob Joseph 					RTE_SECURITY_IPSEC_TUNNEL_IPV4)
485474f1202SAnoob Joseph 				len += sizeof(struct rte_ipv4_hdr);
486474f1202SAnoob Joseph 			else
487474f1202SAnoob Joseph 				len += sizeof(struct rte_ipv6_hdr);
488474f1202SAnoob Joseph 		}
489474f1202SAnoob Joseph 	}
490474f1202SAnoob Joseph 
491474f1202SAnoob Joseph 	return len;
492474f1202SAnoob Joseph }
493474f1202SAnoob Joseph 
494474f1202SAnoob Joseph static int
495cd928003STejasree Kondoj test_ipsec_iv_verify_push(struct rte_mbuf *m, const struct ipsec_test_data *td)
496cd928003STejasree Kondoj {
497cd928003STejasree Kondoj 	static uint8_t iv_queue[IV_LEN_MAX * IPSEC_TEST_PACKETS_MAX];
498cd928003STejasree Kondoj 	uint8_t *iv_tmp, *output_text = rte_pktmbuf_mtod(m, uint8_t *);
499cd928003STejasree Kondoj 	int i, iv_pos, iv_len;
500cd928003STejasree Kondoj 	static int index;
501cd928003STejasree Kondoj 
502cd928003STejasree Kondoj 	if (td->aead)
503cd928003STejasree Kondoj 		iv_len = td->xform.aead.aead.iv.length - td->salt.len;
504cd928003STejasree Kondoj 	else
505cd928003STejasree Kondoj 		iv_len = td->xform.chain.cipher.cipher.iv.length;
506cd928003STejasree Kondoj 
507cd928003STejasree Kondoj 	iv_pos = test_ipsec_tunnel_hdr_len_get(td) + sizeof(struct rte_esp_hdr);
508cd928003STejasree Kondoj 	output_text += iv_pos;
509cd928003STejasree Kondoj 
510cd928003STejasree Kondoj 	TEST_ASSERT(iv_len <= IV_LEN_MAX, "IV length greater than supported");
511cd928003STejasree Kondoj 
512cd928003STejasree Kondoj 	/* Compare against previous values */
513cd928003STejasree Kondoj 	for (i = 0; i < index; i++) {
514cd928003STejasree Kondoj 		iv_tmp = &iv_queue[i * IV_LEN_MAX];
515cd928003STejasree Kondoj 
516cd928003STejasree Kondoj 		if (memcmp(output_text, iv_tmp, iv_len) == 0) {
517cd928003STejasree Kondoj 			printf("IV repeated");
518cd928003STejasree Kondoj 			return TEST_FAILED;
519cd928003STejasree Kondoj 		}
520cd928003STejasree Kondoj 	}
521cd928003STejasree Kondoj 
522cd928003STejasree Kondoj 	/* Save IV for future comparisons */
523cd928003STejasree Kondoj 
524cd928003STejasree Kondoj 	iv_tmp = &iv_queue[index * IV_LEN_MAX];
525cd928003STejasree Kondoj 	memcpy(iv_tmp, output_text, iv_len);
526cd928003STejasree Kondoj 	index++;
527cd928003STejasree Kondoj 
528cd928003STejasree Kondoj 	if (index == IPSEC_TEST_PACKETS_MAX)
529cd928003STejasree Kondoj 		index = 0;
530cd928003STejasree Kondoj 
531cd928003STejasree Kondoj 	return TEST_SUCCESS;
532cd928003STejasree Kondoj }
533cd928003STejasree Kondoj 
534cd928003STejasree Kondoj static int
53583243502SArchana Muniganti test_ipsec_l3_csum_verify(struct rte_mbuf *m)
53683243502SArchana Muniganti {
53783243502SArchana Muniganti 	uint16_t actual_cksum, expected_cksum;
53883243502SArchana Muniganti 	struct rte_ipv4_hdr *ip;
53983243502SArchana Muniganti 
54083243502SArchana Muniganti 	ip = rte_pktmbuf_mtod(m, struct rte_ipv4_hdr *);
54183243502SArchana Muniganti 
54283243502SArchana Muniganti 	if (!is_ipv4((void *)ip))
54383243502SArchana Muniganti 		return TEST_SKIPPED;
54483243502SArchana Muniganti 
54583243502SArchana Muniganti 	actual_cksum = ip->hdr_checksum;
54683243502SArchana Muniganti 
54783243502SArchana Muniganti 	ip->hdr_checksum = 0;
54883243502SArchana Muniganti 
54983243502SArchana Muniganti 	expected_cksum = rte_ipv4_cksum(ip);
55083243502SArchana Muniganti 
55183243502SArchana Muniganti 	if (actual_cksum != expected_cksum)
55283243502SArchana Muniganti 		return TEST_FAILED;
55383243502SArchana Muniganti 
55483243502SArchana Muniganti 	return TEST_SUCCESS;
55583243502SArchana Muniganti }
55683243502SArchana Muniganti 
55783243502SArchana Muniganti static int
55883243502SArchana Muniganti test_ipsec_l4_csum_verify(struct rte_mbuf *m)
55983243502SArchana Muniganti {
56083243502SArchana Muniganti 	uint16_t actual_cksum = 0, expected_cksum = 0;
56183243502SArchana Muniganti 	struct rte_ipv4_hdr *ipv4;
56283243502SArchana Muniganti 	struct rte_ipv6_hdr *ipv6;
56383243502SArchana Muniganti 	struct rte_tcp_hdr *tcp;
56483243502SArchana Muniganti 	struct rte_udp_hdr *udp;
56583243502SArchana Muniganti 	void *ip, *l4;
56683243502SArchana Muniganti 
56783243502SArchana Muniganti 	ip = rte_pktmbuf_mtod(m, void *);
56883243502SArchana Muniganti 
56983243502SArchana Muniganti 	if (is_ipv4(ip)) {
57083243502SArchana Muniganti 		ipv4 = ip;
57183243502SArchana Muniganti 		l4 = RTE_PTR_ADD(ipv4, sizeof(struct rte_ipv4_hdr));
57283243502SArchana Muniganti 
57383243502SArchana Muniganti 		switch (ipv4->next_proto_id) {
57483243502SArchana Muniganti 		case IPPROTO_TCP:
57583243502SArchana Muniganti 			tcp = (struct rte_tcp_hdr *)l4;
57683243502SArchana Muniganti 			actual_cksum = tcp->cksum;
57783243502SArchana Muniganti 			tcp->cksum = 0;
57883243502SArchana Muniganti 			expected_cksum = rte_ipv4_udptcp_cksum(ipv4, l4);
57983243502SArchana Muniganti 			break;
58083243502SArchana Muniganti 		case IPPROTO_UDP:
58183243502SArchana Muniganti 			udp = (struct rte_udp_hdr *)l4;
58283243502SArchana Muniganti 			actual_cksum = udp->dgram_cksum;
58383243502SArchana Muniganti 			udp->dgram_cksum = 0;
58483243502SArchana Muniganti 			expected_cksum = rte_ipv4_udptcp_cksum(ipv4, l4);
58583243502SArchana Muniganti 			break;
58683243502SArchana Muniganti 		default:
58783243502SArchana Muniganti 			break;
58883243502SArchana Muniganti 		}
58983243502SArchana Muniganti 	} else {
59083243502SArchana Muniganti 		ipv6 = ip;
59183243502SArchana Muniganti 		l4 = RTE_PTR_ADD(ipv6, sizeof(struct rte_ipv6_hdr));
59283243502SArchana Muniganti 
59383243502SArchana Muniganti 		switch (ipv6->proto) {
59483243502SArchana Muniganti 		case IPPROTO_TCP:
59583243502SArchana Muniganti 			tcp = (struct rte_tcp_hdr *)l4;
59683243502SArchana Muniganti 			actual_cksum = tcp->cksum;
59783243502SArchana Muniganti 			tcp->cksum = 0;
59883243502SArchana Muniganti 			expected_cksum = rte_ipv6_udptcp_cksum(ipv6, l4);
59983243502SArchana Muniganti 			break;
60083243502SArchana Muniganti 		case IPPROTO_UDP:
60183243502SArchana Muniganti 			udp = (struct rte_udp_hdr *)l4;
60283243502SArchana Muniganti 			actual_cksum = udp->dgram_cksum;
60383243502SArchana Muniganti 			udp->dgram_cksum = 0;
60483243502SArchana Muniganti 			expected_cksum = rte_ipv6_udptcp_cksum(ipv6, l4);
60583243502SArchana Muniganti 			break;
60683243502SArchana Muniganti 		default:
60783243502SArchana Muniganti 			break;
60883243502SArchana Muniganti 		}
60983243502SArchana Muniganti 	}
61083243502SArchana Muniganti 
61183243502SArchana Muniganti 	if (actual_cksum != expected_cksum)
61283243502SArchana Muniganti 		return TEST_FAILED;
61383243502SArchana Muniganti 
61483243502SArchana Muniganti 	return TEST_SUCCESS;
61583243502SArchana Muniganti }
61683243502SArchana Muniganti 
61783243502SArchana Muniganti static int
618474f1202SAnoob Joseph test_ipsec_td_verify(struct rte_mbuf *m, const struct ipsec_test_data *td,
6196622d9c9SAnoob Joseph 		     bool silent, const struct ipsec_test_flags *flags)
620474f1202SAnoob Joseph {
621474f1202SAnoob Joseph 	uint8_t *output_text = rte_pktmbuf_mtod(m, uint8_t *);
622474f1202SAnoob Joseph 	uint32_t skip, len = rte_pktmbuf_pkt_len(m);
62383243502SArchana Muniganti 	int ret;
624474f1202SAnoob Joseph 
6256978f51eSAnoob Joseph 	/* For tests with status as error for test success, skip verification */
6266978f51eSAnoob Joseph 	if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
6276978f51eSAnoob Joseph 	    (flags->icv_corrupt ||
628270470eeSTejasree Kondoj 	     flags->sa_expiry_pkts_hard ||
629270470eeSTejasree Kondoj 	     flags->tunnel_hdr_verify))
6300f453190STejasree Kondoj 		return TEST_SUCCESS;
6310f453190STejasree Kondoj 
632c8234341STejasree Kondoj 	if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS &&
633c8234341STejasree Kondoj 	   flags->udp_encap) {
634c8234341STejasree Kondoj 		const struct rte_ipv4_hdr *iph4;
635c8234341STejasree Kondoj 		const struct rte_ipv6_hdr *iph6;
636c8234341STejasree Kondoj 
637c8234341STejasree Kondoj 		if (td->ipsec_xform.tunnel.type ==
638c8234341STejasree Kondoj 				RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
639c8234341STejasree Kondoj 			iph4 = (const struct rte_ipv4_hdr *)output_text;
640c8234341STejasree Kondoj 			if (iph4->next_proto_id != IPPROTO_UDP) {
641c8234341STejasree Kondoj 				printf("UDP header is not found\n");
642c8234341STejasree Kondoj 				return TEST_FAILED;
643c8234341STejasree Kondoj 			}
644c8234341STejasree Kondoj 		} else {
645c8234341STejasree Kondoj 			iph6 = (const struct rte_ipv6_hdr *)output_text;
646c8234341STejasree Kondoj 			if (iph6->proto != IPPROTO_UDP) {
647c8234341STejasree Kondoj 				printf("UDP header is not found\n");
648c8234341STejasree Kondoj 				return TEST_FAILED;
649c8234341STejasree Kondoj 			}
650c8234341STejasree Kondoj 		}
651c8234341STejasree Kondoj 
652c8234341STejasree Kondoj 		len -= sizeof(struct rte_udp_hdr);
653c8234341STejasree Kondoj 		output_text += sizeof(struct rte_udp_hdr);
654c8234341STejasree Kondoj 	}
655c8234341STejasree Kondoj 
656474f1202SAnoob Joseph 	if (len != td->output_text.len) {
657474f1202SAnoob Joseph 		printf("Output length (%d) not matching with expected (%d)\n",
658474f1202SAnoob Joseph 			len, td->output_text.len);
659474f1202SAnoob Joseph 		return TEST_FAILED;
660474f1202SAnoob Joseph 	}
661474f1202SAnoob Joseph 
662*b7986bdeSTejasree Kondoj 	if ((td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) &&
663*b7986bdeSTejasree Kondoj 				flags->fragment) {
664*b7986bdeSTejasree Kondoj 		const struct rte_ipv4_hdr *iph4;
665*b7986bdeSTejasree Kondoj 		iph4 = (const struct rte_ipv4_hdr *)output_text;
666*b7986bdeSTejasree Kondoj 		if (iph4->fragment_offset) {
667*b7986bdeSTejasree Kondoj 			printf("Output packet is fragmented");
668*b7986bdeSTejasree Kondoj 			return TEST_FAILED;
669*b7986bdeSTejasree Kondoj 		}
670*b7986bdeSTejasree Kondoj 	}
671*b7986bdeSTejasree Kondoj 
672474f1202SAnoob Joseph 	skip = test_ipsec_tunnel_hdr_len_get(td);
673474f1202SAnoob Joseph 
674474f1202SAnoob Joseph 	len -= skip;
675474f1202SAnoob Joseph 	output_text += skip;
676474f1202SAnoob Joseph 
67783243502SArchana Muniganti 	if ((td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
67883243502SArchana Muniganti 				flags->ip_csum) {
679daa02b5cSOlivier Matz 		if (m->ol_flags & RTE_MBUF_F_RX_IP_CKSUM_GOOD)
68083243502SArchana Muniganti 			ret = test_ipsec_l3_csum_verify(m);
68183243502SArchana Muniganti 		else
68283243502SArchana Muniganti 			ret = TEST_FAILED;
68383243502SArchana Muniganti 
68483243502SArchana Muniganti 		if (ret == TEST_FAILED)
68583243502SArchana Muniganti 			printf("Inner IP checksum test failed\n");
68683243502SArchana Muniganti 
68783243502SArchana Muniganti 		return ret;
68883243502SArchana Muniganti 	}
68983243502SArchana Muniganti 
69083243502SArchana Muniganti 	if ((td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
69183243502SArchana Muniganti 				flags->l4_csum) {
692daa02b5cSOlivier Matz 		if (m->ol_flags & RTE_MBUF_F_RX_L4_CKSUM_GOOD)
69383243502SArchana Muniganti 			ret = test_ipsec_l4_csum_verify(m);
69483243502SArchana Muniganti 		else
69583243502SArchana Muniganti 			ret = TEST_FAILED;
69683243502SArchana Muniganti 
69783243502SArchana Muniganti 		if (ret == TEST_FAILED)
69883243502SArchana Muniganti 			printf("Inner L4 checksum test failed\n");
69983243502SArchana Muniganti 
70083243502SArchana Muniganti 		return ret;
70183243502SArchana Muniganti 	}
70283243502SArchana Muniganti 
70383243502SArchana Muniganti 
704474f1202SAnoob Joseph 	if (memcmp(output_text, td->output_text.data + skip, len)) {
705474f1202SAnoob Joseph 		if (silent)
706474f1202SAnoob Joseph 			return TEST_FAILED;
707474f1202SAnoob Joseph 
708474f1202SAnoob Joseph 		printf("TestCase %s line %d: %s\n", __func__, __LINE__,
709474f1202SAnoob Joseph 			"output text not as expected\n");
710474f1202SAnoob Joseph 
711474f1202SAnoob Joseph 		rte_hexdump(stdout, "expected", td->output_text.data + skip,
712474f1202SAnoob Joseph 			    len);
713474f1202SAnoob Joseph 		rte_hexdump(stdout, "actual", output_text, len);
714474f1202SAnoob Joseph 		return TEST_FAILED;
715474f1202SAnoob Joseph 	}
716474f1202SAnoob Joseph 
7176622d9c9SAnoob Joseph 	return TEST_SUCCESS;
7186622d9c9SAnoob Joseph }
7196622d9c9SAnoob Joseph 
7206622d9c9SAnoob Joseph static int
7216622d9c9SAnoob Joseph test_ipsec_res_d_prepare(struct rte_mbuf *m, const struct ipsec_test_data *td,
7226622d9c9SAnoob Joseph 		   struct ipsec_test_data *res_d)
7236622d9c9SAnoob Joseph {
7246622d9c9SAnoob Joseph 	uint8_t *output_text = rte_pktmbuf_mtod(m, uint8_t *);
7256622d9c9SAnoob Joseph 	uint32_t len = rte_pktmbuf_pkt_len(m);
7266622d9c9SAnoob Joseph 
7276622d9c9SAnoob Joseph 	memcpy(res_d, td, sizeof(*res_d));
7286622d9c9SAnoob Joseph 	memcpy(res_d->input_text.data, output_text, len);
7296622d9c9SAnoob Joseph 	res_d->input_text.len = len;
7306622d9c9SAnoob Joseph 
7316622d9c9SAnoob Joseph 	res_d->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
7326622d9c9SAnoob Joseph 	if (res_d->aead) {
7336622d9c9SAnoob Joseph 		res_d->xform.aead.aead.op = RTE_CRYPTO_AEAD_OP_DECRYPT;
7346622d9c9SAnoob Joseph 	} else {
7358d290523SAnoob Joseph 		res_d->xform.chain.cipher.cipher.op =
7368d290523SAnoob Joseph 				RTE_CRYPTO_CIPHER_OP_DECRYPT;
7378d290523SAnoob Joseph 		res_d->xform.chain.auth.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
7386622d9c9SAnoob Joseph 	}
7396622d9c9SAnoob Joseph 
740474f1202SAnoob Joseph 	return TEST_SUCCESS;
741474f1202SAnoob Joseph }
742474f1202SAnoob Joseph 
743474f1202SAnoob Joseph int
744474f1202SAnoob Joseph test_ipsec_post_process(struct rte_mbuf *m, const struct ipsec_test_data *td,
7456622d9c9SAnoob Joseph 			struct ipsec_test_data *res_d, bool silent,
7466622d9c9SAnoob Joseph 			const struct ipsec_test_flags *flags)
747474f1202SAnoob Joseph {
7489fb87fbfSTejasree Kondoj 	uint8_t *output_text = rte_pktmbuf_mtod(m, uint8_t *);
749cd928003STejasree Kondoj 	int ret;
750cd928003STejasree Kondoj 
751cd928003STejasree Kondoj 	if (flags->iv_gen &&
752cd928003STejasree Kondoj 	    td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
753cd928003STejasree Kondoj 		ret = test_ipsec_iv_verify_push(m, td);
754cd928003STejasree Kondoj 		if (ret != TEST_SUCCESS)
755cd928003STejasree Kondoj 			return ret;
756cd928003STejasree Kondoj 	}
757cd928003STejasree Kondoj 
7589fb87fbfSTejasree Kondoj 	if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
7599fb87fbfSTejasree Kondoj 		const struct rte_ipv4_hdr *iph4;
7609fb87fbfSTejasree Kondoj 		const struct rte_ipv6_hdr *iph6;
7619fb87fbfSTejasree Kondoj 
7629fb87fbfSTejasree Kondoj 		if (td->ipsec_xform.tunnel.type ==
7639fb87fbfSTejasree Kondoj 				RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
7649fb87fbfSTejasree Kondoj 			iph4 = (const struct rte_ipv4_hdr *)output_text;
7659fb87fbfSTejasree Kondoj 			if (is_valid_ipv4_pkt(iph4) == false) {
7669fb87fbfSTejasree Kondoj 				printf("Outer header is not IPv4\n");
7679fb87fbfSTejasree Kondoj 				return TEST_FAILED;
7689fb87fbfSTejasree Kondoj 			}
7699fb87fbfSTejasree Kondoj 		} else {
7709fb87fbfSTejasree Kondoj 			iph6 = (const struct rte_ipv6_hdr *)output_text;
7719fb87fbfSTejasree Kondoj 			if (is_valid_ipv6_pkt(iph6) == false) {
7729fb87fbfSTejasree Kondoj 				printf("Outer header is not IPv6\n");
7739fb87fbfSTejasree Kondoj 				return TEST_FAILED;
7749fb87fbfSTejasree Kondoj 			}
7759fb87fbfSTejasree Kondoj 		}
7769fb87fbfSTejasree Kondoj 	}
7779fb87fbfSTejasree Kondoj 
778474f1202SAnoob Joseph 	/*
779474f1202SAnoob Joseph 	 * In case of known vector tests & all inbound tests, res_d provided
780474f1202SAnoob Joseph 	 * would be NULL and output data need to be validated against expected.
781474f1202SAnoob Joseph 	 * For inbound, output_text would be plain packet and for outbound
782474f1202SAnoob Joseph 	 * output_text would IPsec packet. Validate by comparing against
783474f1202SAnoob Joseph 	 * known vectors.
7846622d9c9SAnoob Joseph 	 *
7856622d9c9SAnoob Joseph 	 * In case of combined mode tests, the output_text from outbound
7866622d9c9SAnoob Joseph 	 * operation (ie, IPsec packet) would need to be inbound processed to
7876622d9c9SAnoob Joseph 	 * obtain the plain text. Copy output_text to result data, 'res_d', so
7886622d9c9SAnoob Joseph 	 * that inbound processing can be done.
789474f1202SAnoob Joseph 	 */
7906622d9c9SAnoob Joseph 
7916622d9c9SAnoob Joseph 	if (res_d == NULL)
7926622d9c9SAnoob Joseph 		return test_ipsec_td_verify(m, td, silent, flags);
7936622d9c9SAnoob Joseph 	else
7946622d9c9SAnoob Joseph 		return test_ipsec_res_d_prepare(m, td, res_d);
795474f1202SAnoob Joseph }
796474f1202SAnoob Joseph 
797474f1202SAnoob Joseph int
798474f1202SAnoob Joseph test_ipsec_status_check(struct rte_crypto_op *op,
7996622d9c9SAnoob Joseph 			const struct ipsec_test_flags *flags,
8004aa52f21SAnoob Joseph 			enum rte_security_ipsec_sa_direction dir,
8014aa52f21SAnoob Joseph 			int pkt_num)
802474f1202SAnoob Joseph {
803474f1202SAnoob Joseph 	int ret = TEST_SUCCESS;
804474f1202SAnoob Joseph 
8056978f51eSAnoob Joseph 	if (dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
8066978f51eSAnoob Joseph 	    flags->sa_expiry_pkts_hard &&
8076978f51eSAnoob Joseph 	    pkt_num == IPSEC_TEST_PACKETS_MAX) {
8086978f51eSAnoob Joseph 		if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) {
8096978f51eSAnoob Joseph 			printf("SA hard expiry (pkts) test failed\n");
8106978f51eSAnoob Joseph 			return TEST_FAILED;
8116978f51eSAnoob Joseph 		} else {
8126978f51eSAnoob Joseph 			return TEST_SUCCESS;
8136978f51eSAnoob Joseph 		}
8146978f51eSAnoob Joseph 	}
8156978f51eSAnoob Joseph 
816270470eeSTejasree Kondoj 	if ((dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
817270470eeSTejasree Kondoj 	    flags->tunnel_hdr_verify) {
818270470eeSTejasree Kondoj 		if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) {
819270470eeSTejasree Kondoj 			printf("Tunnel header verify test case failed\n");
820270470eeSTejasree Kondoj 			return TEST_FAILED;
821270470eeSTejasree Kondoj 		} else {
822270470eeSTejasree Kondoj 			return TEST_SUCCESS;
823270470eeSTejasree Kondoj 		}
824270470eeSTejasree Kondoj 	}
825270470eeSTejasree Kondoj 
8260f453190STejasree Kondoj 	if (dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS && flags->icv_corrupt) {
8270f453190STejasree Kondoj 		if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) {
8280f453190STejasree Kondoj 			printf("ICV corruption test case failed\n");
8290f453190STejasree Kondoj 			ret = TEST_FAILED;
8300f453190STejasree Kondoj 		}
8310f453190STejasree Kondoj 	} else {
832474f1202SAnoob Joseph 		if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
8334aa52f21SAnoob Joseph 			printf("Security op processing failed [pkt_num: %d]\n",
8344aa52f21SAnoob Joseph 			       pkt_num);
8354aa52f21SAnoob Joseph 			ret = TEST_FAILED;
8364aa52f21SAnoob Joseph 		}
8374aa52f21SAnoob Joseph 	}
8384aa52f21SAnoob Joseph 
8394aa52f21SAnoob Joseph 	if (flags->sa_expiry_pkts_soft && pkt_num == IPSEC_TEST_PACKETS_MAX) {
8404aa52f21SAnoob Joseph 		if (!(op->aux_flags &
8414aa52f21SAnoob Joseph 		      RTE_CRYPTO_OP_AUX_FLAGS_IPSEC_SOFT_EXPIRY)) {
8424aa52f21SAnoob Joseph 			printf("SA soft expiry (pkts) test failed\n");
843474f1202SAnoob Joseph 			ret = TEST_FAILED;
844474f1202SAnoob Joseph 		}
8450f453190STejasree Kondoj 	}
846474f1202SAnoob Joseph 
847474f1202SAnoob Joseph 	return ret;
848474f1202SAnoob Joseph }
849