xref: /dpdk/app/test/test_cryptodev_security_ipsec.c (revision 9fb87fbfe9af962199a955678610ad92fcf43c9c)
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 
22*9fb87fbfSTejasree Kondoj static bool
23*9fb87fbfSTejasree Kondoj is_valid_ipv4_pkt(const struct rte_ipv4_hdr *pkt)
24*9fb87fbfSTejasree Kondoj {
25*9fb87fbfSTejasree Kondoj 	/* The IP version number must be 4 */
26*9fb87fbfSTejasree Kondoj 	if (((pkt->version_ihl) >> 4) != 4)
27*9fb87fbfSTejasree Kondoj 		return false;
28*9fb87fbfSTejasree Kondoj 	/*
29*9fb87fbfSTejasree Kondoj 	 * The IP header length field must be large enough to hold the
30*9fb87fbfSTejasree Kondoj 	 * minimum length legal IP datagram (20 bytes = 5 words).
31*9fb87fbfSTejasree Kondoj 	 */
32*9fb87fbfSTejasree Kondoj 	if ((pkt->version_ihl & 0xf) < 5)
33*9fb87fbfSTejasree Kondoj 		return false;
34*9fb87fbfSTejasree Kondoj 
35*9fb87fbfSTejasree Kondoj 	/*
36*9fb87fbfSTejasree Kondoj 	 * The IP total length field must be large enough to hold the IP
37*9fb87fbfSTejasree Kondoj 	 * datagram header, whose length is specified in the IP header length
38*9fb87fbfSTejasree Kondoj 	 * field.
39*9fb87fbfSTejasree Kondoj 	 */
40*9fb87fbfSTejasree Kondoj 	if (rte_cpu_to_be_16(pkt->total_length) < sizeof(struct rte_ipv4_hdr))
41*9fb87fbfSTejasree Kondoj 		return false;
42*9fb87fbfSTejasree Kondoj 
43*9fb87fbfSTejasree Kondoj 	return true;
44*9fb87fbfSTejasree Kondoj }
45*9fb87fbfSTejasree Kondoj 
46*9fb87fbfSTejasree Kondoj static bool
47*9fb87fbfSTejasree Kondoj is_valid_ipv6_pkt(const struct rte_ipv6_hdr *pkt)
48*9fb87fbfSTejasree Kondoj {
49*9fb87fbfSTejasree Kondoj 	/* The IP version number must be 6 */
50*9fb87fbfSTejasree Kondoj 	if ((rte_be_to_cpu_32((pkt->vtc_flow)) >> 28) != 6)
51*9fb87fbfSTejasree Kondoj 		return false;
52*9fb87fbfSTejasree Kondoj 
53*9fb87fbfSTejasree Kondoj 	return true;
54*9fb87fbfSTejasree Kondoj }
55*9fb87fbfSTejasree 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 */
357*9fb87fbfSTejasree Kondoj 			if (flags->ipv6)
358*9fb87fbfSTejasree Kondoj 				memcpy(td, &pkt_aes_256_gcm_v6, sizeof(*td));
359*9fb87fbfSTejasree 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 */
367*9fb87fbfSTejasree Kondoj 			if (flags->ipv6)
368*9fb87fbfSTejasree Kondoj 				memcpy(td, &pkt_aes_128_cbc_hmac_sha256_v6,
369*9fb87fbfSTejasree Kondoj 					sizeof(*td));
370*9fb87fbfSTejasree Kondoj 			else
371*9fb87fbfSTejasree Kondoj 				memcpy(td, &pkt_aes_128_cbc_hmac_sha256,
372*9fb87fbfSTejasree 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 
403*9fb87fbfSTejasree Kondoj 		if (flags->tunnel_ipv6)
404*9fb87fbfSTejasree Kondoj 			td->ipsec_xform.tunnel.type =
405*9fb87fbfSTejasree Kondoj 					RTE_SECURITY_IPSEC_TUNNEL_IPV6;
406*9fb87fbfSTejasree Kondoj 		else
407*9fb87fbfSTejasree Kondoj 			td->ipsec_xform.tunnel.type =
408*9fb87fbfSTejasree Kondoj 					RTE_SECURITY_IPSEC_TUNNEL_IPV4;
409*9fb87fbfSTejasree 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 
662474f1202SAnoob Joseph 	skip = test_ipsec_tunnel_hdr_len_get(td);
663474f1202SAnoob Joseph 
664474f1202SAnoob Joseph 	len -= skip;
665474f1202SAnoob Joseph 	output_text += skip;
666474f1202SAnoob Joseph 
66783243502SArchana Muniganti 	if ((td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
66883243502SArchana Muniganti 				flags->ip_csum) {
669daa02b5cSOlivier Matz 		if (m->ol_flags & RTE_MBUF_F_RX_IP_CKSUM_GOOD)
67083243502SArchana Muniganti 			ret = test_ipsec_l3_csum_verify(m);
67183243502SArchana Muniganti 		else
67283243502SArchana Muniganti 			ret = TEST_FAILED;
67383243502SArchana Muniganti 
67483243502SArchana Muniganti 		if (ret == TEST_FAILED)
67583243502SArchana Muniganti 			printf("Inner IP checksum test failed\n");
67683243502SArchana Muniganti 
67783243502SArchana Muniganti 		return ret;
67883243502SArchana Muniganti 	}
67983243502SArchana Muniganti 
68083243502SArchana Muniganti 	if ((td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
68183243502SArchana Muniganti 				flags->l4_csum) {
682daa02b5cSOlivier Matz 		if (m->ol_flags & RTE_MBUF_F_RX_L4_CKSUM_GOOD)
68383243502SArchana Muniganti 			ret = test_ipsec_l4_csum_verify(m);
68483243502SArchana Muniganti 		else
68583243502SArchana Muniganti 			ret = TEST_FAILED;
68683243502SArchana Muniganti 
68783243502SArchana Muniganti 		if (ret == TEST_FAILED)
68883243502SArchana Muniganti 			printf("Inner L4 checksum test failed\n");
68983243502SArchana Muniganti 
69083243502SArchana Muniganti 		return ret;
69183243502SArchana Muniganti 	}
69283243502SArchana Muniganti 
69383243502SArchana Muniganti 
694474f1202SAnoob Joseph 	if (memcmp(output_text, td->output_text.data + skip, len)) {
695474f1202SAnoob Joseph 		if (silent)
696474f1202SAnoob Joseph 			return TEST_FAILED;
697474f1202SAnoob Joseph 
698474f1202SAnoob Joseph 		printf("TestCase %s line %d: %s\n", __func__, __LINE__,
699474f1202SAnoob Joseph 			"output text not as expected\n");
700474f1202SAnoob Joseph 
701474f1202SAnoob Joseph 		rte_hexdump(stdout, "expected", td->output_text.data + skip,
702474f1202SAnoob Joseph 			    len);
703474f1202SAnoob Joseph 		rte_hexdump(stdout, "actual", output_text, len);
704474f1202SAnoob Joseph 		return TEST_FAILED;
705474f1202SAnoob Joseph 	}
706474f1202SAnoob Joseph 
7076622d9c9SAnoob Joseph 	return TEST_SUCCESS;
7086622d9c9SAnoob Joseph }
7096622d9c9SAnoob Joseph 
7106622d9c9SAnoob Joseph static int
7116622d9c9SAnoob Joseph test_ipsec_res_d_prepare(struct rte_mbuf *m, const struct ipsec_test_data *td,
7126622d9c9SAnoob Joseph 		   struct ipsec_test_data *res_d)
7136622d9c9SAnoob Joseph {
7146622d9c9SAnoob Joseph 	uint8_t *output_text = rte_pktmbuf_mtod(m, uint8_t *);
7156622d9c9SAnoob Joseph 	uint32_t len = rte_pktmbuf_pkt_len(m);
7166622d9c9SAnoob Joseph 
7176622d9c9SAnoob Joseph 	memcpy(res_d, td, sizeof(*res_d));
7186622d9c9SAnoob Joseph 	memcpy(res_d->input_text.data, output_text, len);
7196622d9c9SAnoob Joseph 	res_d->input_text.len = len;
7206622d9c9SAnoob Joseph 
7216622d9c9SAnoob Joseph 	res_d->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
7226622d9c9SAnoob Joseph 	if (res_d->aead) {
7236622d9c9SAnoob Joseph 		res_d->xform.aead.aead.op = RTE_CRYPTO_AEAD_OP_DECRYPT;
7246622d9c9SAnoob Joseph 	} else {
7258d290523SAnoob Joseph 		res_d->xform.chain.cipher.cipher.op =
7268d290523SAnoob Joseph 				RTE_CRYPTO_CIPHER_OP_DECRYPT;
7278d290523SAnoob Joseph 		res_d->xform.chain.auth.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
7286622d9c9SAnoob Joseph 	}
7296622d9c9SAnoob Joseph 
730474f1202SAnoob Joseph 	return TEST_SUCCESS;
731474f1202SAnoob Joseph }
732474f1202SAnoob Joseph 
733474f1202SAnoob Joseph int
734474f1202SAnoob Joseph test_ipsec_post_process(struct rte_mbuf *m, const struct ipsec_test_data *td,
7356622d9c9SAnoob Joseph 			struct ipsec_test_data *res_d, bool silent,
7366622d9c9SAnoob Joseph 			const struct ipsec_test_flags *flags)
737474f1202SAnoob Joseph {
738*9fb87fbfSTejasree Kondoj 	uint8_t *output_text = rte_pktmbuf_mtod(m, uint8_t *);
739cd928003STejasree Kondoj 	int ret;
740cd928003STejasree Kondoj 
741cd928003STejasree Kondoj 	if (flags->iv_gen &&
742cd928003STejasree Kondoj 	    td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
743cd928003STejasree Kondoj 		ret = test_ipsec_iv_verify_push(m, td);
744cd928003STejasree Kondoj 		if (ret != TEST_SUCCESS)
745cd928003STejasree Kondoj 			return ret;
746cd928003STejasree Kondoj 	}
747cd928003STejasree Kondoj 
748*9fb87fbfSTejasree Kondoj 	if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
749*9fb87fbfSTejasree Kondoj 		const struct rte_ipv4_hdr *iph4;
750*9fb87fbfSTejasree Kondoj 		const struct rte_ipv6_hdr *iph6;
751*9fb87fbfSTejasree Kondoj 
752*9fb87fbfSTejasree Kondoj 		if (td->ipsec_xform.tunnel.type ==
753*9fb87fbfSTejasree Kondoj 				RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
754*9fb87fbfSTejasree Kondoj 			iph4 = (const struct rte_ipv4_hdr *)output_text;
755*9fb87fbfSTejasree Kondoj 			if (is_valid_ipv4_pkt(iph4) == false) {
756*9fb87fbfSTejasree Kondoj 				printf("Outer header is not IPv4\n");
757*9fb87fbfSTejasree Kondoj 				return TEST_FAILED;
758*9fb87fbfSTejasree Kondoj 			}
759*9fb87fbfSTejasree Kondoj 		} else {
760*9fb87fbfSTejasree Kondoj 			iph6 = (const struct rte_ipv6_hdr *)output_text;
761*9fb87fbfSTejasree Kondoj 			if (is_valid_ipv6_pkt(iph6) == false) {
762*9fb87fbfSTejasree Kondoj 				printf("Outer header is not IPv6\n");
763*9fb87fbfSTejasree Kondoj 				return TEST_FAILED;
764*9fb87fbfSTejasree Kondoj 			}
765*9fb87fbfSTejasree Kondoj 		}
766*9fb87fbfSTejasree Kondoj 	}
767*9fb87fbfSTejasree Kondoj 
768474f1202SAnoob Joseph 	/*
769474f1202SAnoob Joseph 	 * In case of known vector tests & all inbound tests, res_d provided
770474f1202SAnoob Joseph 	 * would be NULL and output data need to be validated against expected.
771474f1202SAnoob Joseph 	 * For inbound, output_text would be plain packet and for outbound
772474f1202SAnoob Joseph 	 * output_text would IPsec packet. Validate by comparing against
773474f1202SAnoob Joseph 	 * known vectors.
7746622d9c9SAnoob Joseph 	 *
7756622d9c9SAnoob Joseph 	 * In case of combined mode tests, the output_text from outbound
7766622d9c9SAnoob Joseph 	 * operation (ie, IPsec packet) would need to be inbound processed to
7776622d9c9SAnoob Joseph 	 * obtain the plain text. Copy output_text to result data, 'res_d', so
7786622d9c9SAnoob Joseph 	 * that inbound processing can be done.
779474f1202SAnoob Joseph 	 */
7806622d9c9SAnoob Joseph 
7816622d9c9SAnoob Joseph 	if (res_d == NULL)
7826622d9c9SAnoob Joseph 		return test_ipsec_td_verify(m, td, silent, flags);
7836622d9c9SAnoob Joseph 	else
7846622d9c9SAnoob Joseph 		return test_ipsec_res_d_prepare(m, td, res_d);
785474f1202SAnoob Joseph }
786474f1202SAnoob Joseph 
787474f1202SAnoob Joseph int
788474f1202SAnoob Joseph test_ipsec_status_check(struct rte_crypto_op *op,
7896622d9c9SAnoob Joseph 			const struct ipsec_test_flags *flags,
7904aa52f21SAnoob Joseph 			enum rte_security_ipsec_sa_direction dir,
7914aa52f21SAnoob Joseph 			int pkt_num)
792474f1202SAnoob Joseph {
793474f1202SAnoob Joseph 	int ret = TEST_SUCCESS;
794474f1202SAnoob Joseph 
7956978f51eSAnoob Joseph 	if (dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
7966978f51eSAnoob Joseph 	    flags->sa_expiry_pkts_hard &&
7976978f51eSAnoob Joseph 	    pkt_num == IPSEC_TEST_PACKETS_MAX) {
7986978f51eSAnoob Joseph 		if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) {
7996978f51eSAnoob Joseph 			printf("SA hard expiry (pkts) test failed\n");
8006978f51eSAnoob Joseph 			return TEST_FAILED;
8016978f51eSAnoob Joseph 		} else {
8026978f51eSAnoob Joseph 			return TEST_SUCCESS;
8036978f51eSAnoob Joseph 		}
8046978f51eSAnoob Joseph 	}
8056978f51eSAnoob Joseph 
806270470eeSTejasree Kondoj 	if ((dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
807270470eeSTejasree Kondoj 	    flags->tunnel_hdr_verify) {
808270470eeSTejasree Kondoj 		if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) {
809270470eeSTejasree Kondoj 			printf("Tunnel header verify test case failed\n");
810270470eeSTejasree Kondoj 			return TEST_FAILED;
811270470eeSTejasree Kondoj 		} else {
812270470eeSTejasree Kondoj 			return TEST_SUCCESS;
813270470eeSTejasree Kondoj 		}
814270470eeSTejasree Kondoj 	}
815270470eeSTejasree Kondoj 
8160f453190STejasree Kondoj 	if (dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS && flags->icv_corrupt) {
8170f453190STejasree Kondoj 		if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) {
8180f453190STejasree Kondoj 			printf("ICV corruption test case failed\n");
8190f453190STejasree Kondoj 			ret = TEST_FAILED;
8200f453190STejasree Kondoj 		}
8210f453190STejasree Kondoj 	} else {
822474f1202SAnoob Joseph 		if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
8234aa52f21SAnoob Joseph 			printf("Security op processing failed [pkt_num: %d]\n",
8244aa52f21SAnoob Joseph 			       pkt_num);
8254aa52f21SAnoob Joseph 			ret = TEST_FAILED;
8264aa52f21SAnoob Joseph 		}
8274aa52f21SAnoob Joseph 	}
8284aa52f21SAnoob Joseph 
8294aa52f21SAnoob Joseph 	if (flags->sa_expiry_pkts_soft && pkt_num == IPSEC_TEST_PACKETS_MAX) {
8304aa52f21SAnoob Joseph 		if (!(op->aux_flags &
8314aa52f21SAnoob Joseph 		      RTE_CRYPTO_OP_AUX_FLAGS_IPSEC_SOFT_EXPIRY)) {
8324aa52f21SAnoob Joseph 			printf("SA soft expiry (pkts) test failed\n");
833474f1202SAnoob Joseph 			ret = TEST_FAILED;
834474f1202SAnoob Joseph 		}
8350f453190STejasree Kondoj 	}
836474f1202SAnoob Joseph 
837474f1202SAnoob Joseph 	return ret;
838474f1202SAnoob Joseph }
839