xref: /dpdk/app/test/test_cryptodev_security_ipsec.c (revision 65d68c7cd787101a5f11f9e3c16c0315633d6b02)
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 
403*65d68c7cSAnoob Joseph 		if (flags->transport) {
404*65d68c7cSAnoob Joseph 			td->ipsec_xform.mode =
405*65d68c7cSAnoob Joseph 					RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT;
406*65d68c7cSAnoob Joseph 		} else {
407*65d68c7cSAnoob Joseph 			td->ipsec_xform.mode =
408*65d68c7cSAnoob Joseph 					RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
409*65d68c7cSAnoob Joseph 
4109fb87fbfSTejasree Kondoj 			if (flags->tunnel_ipv6)
4119fb87fbfSTejasree Kondoj 				td->ipsec_xform.tunnel.type =
4129fb87fbfSTejasree Kondoj 						RTE_SECURITY_IPSEC_TUNNEL_IPV6;
4139fb87fbfSTejasree Kondoj 			else
4149fb87fbfSTejasree Kondoj 				td->ipsec_xform.tunnel.type =
4159fb87fbfSTejasree Kondoj 						RTE_SECURITY_IPSEC_TUNNEL_IPV4;
416*65d68c7cSAnoob Joseph 		}
417*65d68c7cSAnoob Joseph 
4189fb87fbfSTejasree Kondoj 
4196622d9c9SAnoob Joseph 	}
4206622d9c9SAnoob Joseph }
4216622d9c9SAnoob Joseph 
4226622d9c9SAnoob Joseph void
4236622d9c9SAnoob Joseph test_ipsec_td_update(struct ipsec_test_data td_inb[],
4246622d9c9SAnoob Joseph 		     const struct ipsec_test_data td_outb[],
4256622d9c9SAnoob Joseph 		     int nb_td,
4266622d9c9SAnoob Joseph 		     const struct ipsec_test_flags *flags)
4276622d9c9SAnoob Joseph {
4286622d9c9SAnoob Joseph 	int i;
4296622d9c9SAnoob Joseph 
4306622d9c9SAnoob Joseph 	for (i = 0; i < nb_td; i++) {
4316622d9c9SAnoob Joseph 		memcpy(td_inb[i].output_text.data, td_outb[i].input_text.data,
4326622d9c9SAnoob Joseph 		       td_outb[i].input_text.len);
4336622d9c9SAnoob Joseph 		td_inb[i].output_text.len = td_outb->input_text.len;
4346622d9c9SAnoob Joseph 
4350f453190STejasree Kondoj 		if (flags->icv_corrupt) {
4360f453190STejasree Kondoj 			int icv_pos = td_inb[i].input_text.len - 4;
4370f453190STejasree Kondoj 			td_inb[i].input_text.data[icv_pos] += 1;
4380f453190STejasree Kondoj 		}
439c8234341STejasree Kondoj 
4406978f51eSAnoob Joseph 		if (flags->sa_expiry_pkts_hard)
4416978f51eSAnoob Joseph 			td_inb[i].ipsec_xform.life.packets_hard_limit =
4426978f51eSAnoob Joseph 					IPSEC_TEST_PACKETS_MAX - 1;
4436978f51eSAnoob Joseph 
444c8234341STejasree Kondoj 		if (flags->udp_encap)
445c8234341STejasree Kondoj 			td_inb[i].ipsec_xform.options.udp_encap = 1;
4460532f50cSAnoob Joseph 
4479ec50a52STejasree Kondoj 		if (flags->udp_ports_verify)
4489ec50a52STejasree Kondoj 			td_inb[i].ipsec_xform.options.udp_ports_verify = 1;
4499ec50a52STejasree Kondoj 
450270470eeSTejasree Kondoj 		td_inb[i].ipsec_xform.options.tunnel_hdr_verify =
451270470eeSTejasree Kondoj 			flags->tunnel_hdr_verify;
452270470eeSTejasree Kondoj 
45383243502SArchana Muniganti 		if (flags->ip_csum)
45483243502SArchana Muniganti 			td_inb[i].ipsec_xform.options.ip_csum_enable = 1;
45583243502SArchana Muniganti 
45683243502SArchana Muniganti 		if (flags->l4_csum)
45783243502SArchana Muniganti 			td_inb[i].ipsec_xform.options.l4_csum_enable = 1;
45883243502SArchana Muniganti 
4590532f50cSAnoob Joseph 		/* Clear outbound specific flags */
4600532f50cSAnoob Joseph 		td_inb[i].ipsec_xform.options.iv_gen_disable = 0;
4610f453190STejasree Kondoj 	}
4626622d9c9SAnoob Joseph }
4636622d9c9SAnoob Joseph 
4646622d9c9SAnoob Joseph void
4656622d9c9SAnoob Joseph test_ipsec_display_alg(const struct crypto_param *param1,
4666622d9c9SAnoob Joseph 		       const struct crypto_param *param2)
4676622d9c9SAnoob Joseph {
4688d290523SAnoob Joseph 	if (param1->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
4698d290523SAnoob Joseph 		printf("\t%s [%d]",
4706622d9c9SAnoob Joseph 		       rte_crypto_aead_algorithm_strings[param1->alg.aead],
4718d290523SAnoob Joseph 		       param1->key_length * 8);
4728d290523SAnoob Joseph 	} else {
4738d290523SAnoob Joseph 		printf("\t%s",
4748d290523SAnoob Joseph 		       rte_crypto_cipher_algorithm_strings[param1->alg.cipher]);
4758d290523SAnoob Joseph 		if (param1->alg.cipher != RTE_CRYPTO_CIPHER_NULL)
4768d290523SAnoob Joseph 			printf(" [%d]", param1->key_length * 8);
4778d290523SAnoob Joseph 		printf(" %s",
4788d290523SAnoob Joseph 		       rte_crypto_auth_algorithm_strings[param2->alg.auth]);
4798d290523SAnoob Joseph 		if (param2->alg.auth != RTE_CRYPTO_AUTH_NULL)
4808d290523SAnoob Joseph 			printf(" [%dB ICV]", param2->digest_length);
4818d290523SAnoob Joseph 	}
4828d290523SAnoob Joseph 	printf("\n");
4836622d9c9SAnoob Joseph }
4846622d9c9SAnoob Joseph 
485474f1202SAnoob Joseph static int
486474f1202SAnoob Joseph test_ipsec_tunnel_hdr_len_get(const struct ipsec_test_data *td)
487474f1202SAnoob Joseph {
488474f1202SAnoob Joseph 	int len = 0;
489474f1202SAnoob Joseph 
490474f1202SAnoob Joseph 	if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
491474f1202SAnoob Joseph 		if (td->ipsec_xform.mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
492474f1202SAnoob Joseph 			if (td->ipsec_xform.tunnel.type ==
493474f1202SAnoob Joseph 					RTE_SECURITY_IPSEC_TUNNEL_IPV4)
494474f1202SAnoob Joseph 				len += sizeof(struct rte_ipv4_hdr);
495474f1202SAnoob Joseph 			else
496474f1202SAnoob Joseph 				len += sizeof(struct rte_ipv6_hdr);
497474f1202SAnoob Joseph 		}
498474f1202SAnoob Joseph 	}
499474f1202SAnoob Joseph 
500474f1202SAnoob Joseph 	return len;
501474f1202SAnoob Joseph }
502474f1202SAnoob Joseph 
503474f1202SAnoob Joseph static int
504cd928003STejasree Kondoj test_ipsec_iv_verify_push(struct rte_mbuf *m, const struct ipsec_test_data *td)
505cd928003STejasree Kondoj {
506cd928003STejasree Kondoj 	static uint8_t iv_queue[IV_LEN_MAX * IPSEC_TEST_PACKETS_MAX];
507cd928003STejasree Kondoj 	uint8_t *iv_tmp, *output_text = rte_pktmbuf_mtod(m, uint8_t *);
508cd928003STejasree Kondoj 	int i, iv_pos, iv_len;
509cd928003STejasree Kondoj 	static int index;
510cd928003STejasree Kondoj 
511cd928003STejasree Kondoj 	if (td->aead)
512cd928003STejasree Kondoj 		iv_len = td->xform.aead.aead.iv.length - td->salt.len;
513cd928003STejasree Kondoj 	else
514cd928003STejasree Kondoj 		iv_len = td->xform.chain.cipher.cipher.iv.length;
515cd928003STejasree Kondoj 
516cd928003STejasree Kondoj 	iv_pos = test_ipsec_tunnel_hdr_len_get(td) + sizeof(struct rte_esp_hdr);
517cd928003STejasree Kondoj 	output_text += iv_pos;
518cd928003STejasree Kondoj 
519cd928003STejasree Kondoj 	TEST_ASSERT(iv_len <= IV_LEN_MAX, "IV length greater than supported");
520cd928003STejasree Kondoj 
521cd928003STejasree Kondoj 	/* Compare against previous values */
522cd928003STejasree Kondoj 	for (i = 0; i < index; i++) {
523cd928003STejasree Kondoj 		iv_tmp = &iv_queue[i * IV_LEN_MAX];
524cd928003STejasree Kondoj 
525cd928003STejasree Kondoj 		if (memcmp(output_text, iv_tmp, iv_len) == 0) {
526cd928003STejasree Kondoj 			printf("IV repeated");
527cd928003STejasree Kondoj 			return TEST_FAILED;
528cd928003STejasree Kondoj 		}
529cd928003STejasree Kondoj 	}
530cd928003STejasree Kondoj 
531cd928003STejasree Kondoj 	/* Save IV for future comparisons */
532cd928003STejasree Kondoj 
533cd928003STejasree Kondoj 	iv_tmp = &iv_queue[index * IV_LEN_MAX];
534cd928003STejasree Kondoj 	memcpy(iv_tmp, output_text, iv_len);
535cd928003STejasree Kondoj 	index++;
536cd928003STejasree Kondoj 
537cd928003STejasree Kondoj 	if (index == IPSEC_TEST_PACKETS_MAX)
538cd928003STejasree Kondoj 		index = 0;
539cd928003STejasree Kondoj 
540cd928003STejasree Kondoj 	return TEST_SUCCESS;
541cd928003STejasree Kondoj }
542cd928003STejasree Kondoj 
543cd928003STejasree Kondoj static int
54483243502SArchana Muniganti test_ipsec_l3_csum_verify(struct rte_mbuf *m)
54583243502SArchana Muniganti {
54683243502SArchana Muniganti 	uint16_t actual_cksum, expected_cksum;
54783243502SArchana Muniganti 	struct rte_ipv4_hdr *ip;
54883243502SArchana Muniganti 
54983243502SArchana Muniganti 	ip = rte_pktmbuf_mtod(m, struct rte_ipv4_hdr *);
55083243502SArchana Muniganti 
55183243502SArchana Muniganti 	if (!is_ipv4((void *)ip))
55283243502SArchana Muniganti 		return TEST_SKIPPED;
55383243502SArchana Muniganti 
55483243502SArchana Muniganti 	actual_cksum = ip->hdr_checksum;
55583243502SArchana Muniganti 
55683243502SArchana Muniganti 	ip->hdr_checksum = 0;
55783243502SArchana Muniganti 
55883243502SArchana Muniganti 	expected_cksum = rte_ipv4_cksum(ip);
55983243502SArchana Muniganti 
56083243502SArchana Muniganti 	if (actual_cksum != expected_cksum)
56183243502SArchana Muniganti 		return TEST_FAILED;
56283243502SArchana Muniganti 
56383243502SArchana Muniganti 	return TEST_SUCCESS;
56483243502SArchana Muniganti }
56583243502SArchana Muniganti 
56683243502SArchana Muniganti static int
56783243502SArchana Muniganti test_ipsec_l4_csum_verify(struct rte_mbuf *m)
56883243502SArchana Muniganti {
56983243502SArchana Muniganti 	uint16_t actual_cksum = 0, expected_cksum = 0;
57083243502SArchana Muniganti 	struct rte_ipv4_hdr *ipv4;
57183243502SArchana Muniganti 	struct rte_ipv6_hdr *ipv6;
57283243502SArchana Muniganti 	struct rte_tcp_hdr *tcp;
57383243502SArchana Muniganti 	struct rte_udp_hdr *udp;
57483243502SArchana Muniganti 	void *ip, *l4;
57583243502SArchana Muniganti 
57683243502SArchana Muniganti 	ip = rte_pktmbuf_mtod(m, void *);
57783243502SArchana Muniganti 
57883243502SArchana Muniganti 	if (is_ipv4(ip)) {
57983243502SArchana Muniganti 		ipv4 = ip;
58083243502SArchana Muniganti 		l4 = RTE_PTR_ADD(ipv4, sizeof(struct rte_ipv4_hdr));
58183243502SArchana Muniganti 
58283243502SArchana Muniganti 		switch (ipv4->next_proto_id) {
58383243502SArchana Muniganti 		case IPPROTO_TCP:
58483243502SArchana Muniganti 			tcp = (struct rte_tcp_hdr *)l4;
58583243502SArchana Muniganti 			actual_cksum = tcp->cksum;
58683243502SArchana Muniganti 			tcp->cksum = 0;
58783243502SArchana Muniganti 			expected_cksum = rte_ipv4_udptcp_cksum(ipv4, l4);
58883243502SArchana Muniganti 			break;
58983243502SArchana Muniganti 		case IPPROTO_UDP:
59083243502SArchana Muniganti 			udp = (struct rte_udp_hdr *)l4;
59183243502SArchana Muniganti 			actual_cksum = udp->dgram_cksum;
59283243502SArchana Muniganti 			udp->dgram_cksum = 0;
59383243502SArchana Muniganti 			expected_cksum = rte_ipv4_udptcp_cksum(ipv4, l4);
59483243502SArchana Muniganti 			break;
59583243502SArchana Muniganti 		default:
59683243502SArchana Muniganti 			break;
59783243502SArchana Muniganti 		}
59883243502SArchana Muniganti 	} else {
59983243502SArchana Muniganti 		ipv6 = ip;
60083243502SArchana Muniganti 		l4 = RTE_PTR_ADD(ipv6, sizeof(struct rte_ipv6_hdr));
60183243502SArchana Muniganti 
60283243502SArchana Muniganti 		switch (ipv6->proto) {
60383243502SArchana Muniganti 		case IPPROTO_TCP:
60483243502SArchana Muniganti 			tcp = (struct rte_tcp_hdr *)l4;
60583243502SArchana Muniganti 			actual_cksum = tcp->cksum;
60683243502SArchana Muniganti 			tcp->cksum = 0;
60783243502SArchana Muniganti 			expected_cksum = rte_ipv6_udptcp_cksum(ipv6, l4);
60883243502SArchana Muniganti 			break;
60983243502SArchana Muniganti 		case IPPROTO_UDP:
61083243502SArchana Muniganti 			udp = (struct rte_udp_hdr *)l4;
61183243502SArchana Muniganti 			actual_cksum = udp->dgram_cksum;
61283243502SArchana Muniganti 			udp->dgram_cksum = 0;
61383243502SArchana Muniganti 			expected_cksum = rte_ipv6_udptcp_cksum(ipv6, l4);
61483243502SArchana Muniganti 			break;
61583243502SArchana Muniganti 		default:
61683243502SArchana Muniganti 			break;
61783243502SArchana Muniganti 		}
61883243502SArchana Muniganti 	}
61983243502SArchana Muniganti 
62083243502SArchana Muniganti 	if (actual_cksum != expected_cksum)
62183243502SArchana Muniganti 		return TEST_FAILED;
62283243502SArchana Muniganti 
62383243502SArchana Muniganti 	return TEST_SUCCESS;
62483243502SArchana Muniganti }
62583243502SArchana Muniganti 
62683243502SArchana Muniganti static int
627474f1202SAnoob Joseph test_ipsec_td_verify(struct rte_mbuf *m, const struct ipsec_test_data *td,
6286622d9c9SAnoob Joseph 		     bool silent, const struct ipsec_test_flags *flags)
629474f1202SAnoob Joseph {
630474f1202SAnoob Joseph 	uint8_t *output_text = rte_pktmbuf_mtod(m, uint8_t *);
631474f1202SAnoob Joseph 	uint32_t skip, len = rte_pktmbuf_pkt_len(m);
63283243502SArchana Muniganti 	int ret;
633474f1202SAnoob Joseph 
6346978f51eSAnoob Joseph 	/* For tests with status as error for test success, skip verification */
6356978f51eSAnoob Joseph 	if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
6366978f51eSAnoob Joseph 	    (flags->icv_corrupt ||
637270470eeSTejasree Kondoj 	     flags->sa_expiry_pkts_hard ||
638270470eeSTejasree Kondoj 	     flags->tunnel_hdr_verify))
6390f453190STejasree Kondoj 		return TEST_SUCCESS;
6400f453190STejasree Kondoj 
641c8234341STejasree Kondoj 	if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS &&
642c8234341STejasree Kondoj 	   flags->udp_encap) {
643c8234341STejasree Kondoj 		const struct rte_ipv4_hdr *iph4;
644c8234341STejasree Kondoj 		const struct rte_ipv6_hdr *iph6;
645c8234341STejasree Kondoj 
646c8234341STejasree Kondoj 		if (td->ipsec_xform.tunnel.type ==
647c8234341STejasree Kondoj 				RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
648c8234341STejasree Kondoj 			iph4 = (const struct rte_ipv4_hdr *)output_text;
649c8234341STejasree Kondoj 			if (iph4->next_proto_id != IPPROTO_UDP) {
650c8234341STejasree Kondoj 				printf("UDP header is not found\n");
651c8234341STejasree Kondoj 				return TEST_FAILED;
652c8234341STejasree Kondoj 			}
653c8234341STejasree Kondoj 		} else {
654c8234341STejasree Kondoj 			iph6 = (const struct rte_ipv6_hdr *)output_text;
655c8234341STejasree Kondoj 			if (iph6->proto != IPPROTO_UDP) {
656c8234341STejasree Kondoj 				printf("UDP header is not found\n");
657c8234341STejasree Kondoj 				return TEST_FAILED;
658c8234341STejasree Kondoj 			}
659c8234341STejasree Kondoj 		}
660c8234341STejasree Kondoj 
661c8234341STejasree Kondoj 		len -= sizeof(struct rte_udp_hdr);
662c8234341STejasree Kondoj 		output_text += sizeof(struct rte_udp_hdr);
663c8234341STejasree Kondoj 	}
664c8234341STejasree Kondoj 
665474f1202SAnoob Joseph 	if (len != td->output_text.len) {
666474f1202SAnoob Joseph 		printf("Output length (%d) not matching with expected (%d)\n",
667474f1202SAnoob Joseph 			len, td->output_text.len);
668474f1202SAnoob Joseph 		return TEST_FAILED;
669474f1202SAnoob Joseph 	}
670474f1202SAnoob Joseph 
671b7986bdeSTejasree Kondoj 	if ((td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) &&
672b7986bdeSTejasree Kondoj 				flags->fragment) {
673b7986bdeSTejasree Kondoj 		const struct rte_ipv4_hdr *iph4;
674b7986bdeSTejasree Kondoj 		iph4 = (const struct rte_ipv4_hdr *)output_text;
675b7986bdeSTejasree Kondoj 		if (iph4->fragment_offset) {
676b7986bdeSTejasree Kondoj 			printf("Output packet is fragmented");
677b7986bdeSTejasree Kondoj 			return TEST_FAILED;
678b7986bdeSTejasree Kondoj 		}
679b7986bdeSTejasree Kondoj 	}
680b7986bdeSTejasree Kondoj 
681474f1202SAnoob Joseph 	skip = test_ipsec_tunnel_hdr_len_get(td);
682474f1202SAnoob Joseph 
683474f1202SAnoob Joseph 	len -= skip;
684474f1202SAnoob Joseph 	output_text += skip;
685474f1202SAnoob Joseph 
68683243502SArchana Muniganti 	if ((td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
68783243502SArchana Muniganti 				flags->ip_csum) {
688daa02b5cSOlivier Matz 		if (m->ol_flags & RTE_MBUF_F_RX_IP_CKSUM_GOOD)
68983243502SArchana Muniganti 			ret = test_ipsec_l3_csum_verify(m);
69083243502SArchana Muniganti 		else
69183243502SArchana Muniganti 			ret = TEST_FAILED;
69283243502SArchana Muniganti 
69383243502SArchana Muniganti 		if (ret == TEST_FAILED)
69483243502SArchana Muniganti 			printf("Inner IP checksum test failed\n");
69583243502SArchana Muniganti 
69683243502SArchana Muniganti 		return ret;
69783243502SArchana Muniganti 	}
69883243502SArchana Muniganti 
69983243502SArchana Muniganti 	if ((td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
70083243502SArchana Muniganti 				flags->l4_csum) {
701daa02b5cSOlivier Matz 		if (m->ol_flags & RTE_MBUF_F_RX_L4_CKSUM_GOOD)
70283243502SArchana Muniganti 			ret = test_ipsec_l4_csum_verify(m);
70383243502SArchana Muniganti 		else
70483243502SArchana Muniganti 			ret = TEST_FAILED;
70583243502SArchana Muniganti 
70683243502SArchana Muniganti 		if (ret == TEST_FAILED)
70783243502SArchana Muniganti 			printf("Inner L4 checksum test failed\n");
70883243502SArchana Muniganti 
70983243502SArchana Muniganti 		return ret;
71083243502SArchana Muniganti 	}
71183243502SArchana Muniganti 
71283243502SArchana Muniganti 
713474f1202SAnoob Joseph 	if (memcmp(output_text, td->output_text.data + skip, len)) {
714474f1202SAnoob Joseph 		if (silent)
715474f1202SAnoob Joseph 			return TEST_FAILED;
716474f1202SAnoob Joseph 
717474f1202SAnoob Joseph 		printf("TestCase %s line %d: %s\n", __func__, __LINE__,
718474f1202SAnoob Joseph 			"output text not as expected\n");
719474f1202SAnoob Joseph 
720474f1202SAnoob Joseph 		rte_hexdump(stdout, "expected", td->output_text.data + skip,
721474f1202SAnoob Joseph 			    len);
722474f1202SAnoob Joseph 		rte_hexdump(stdout, "actual", output_text, len);
723474f1202SAnoob Joseph 		return TEST_FAILED;
724474f1202SAnoob Joseph 	}
725474f1202SAnoob Joseph 
7266622d9c9SAnoob Joseph 	return TEST_SUCCESS;
7276622d9c9SAnoob Joseph }
7286622d9c9SAnoob Joseph 
7296622d9c9SAnoob Joseph static int
7306622d9c9SAnoob Joseph test_ipsec_res_d_prepare(struct rte_mbuf *m, const struct ipsec_test_data *td,
7316622d9c9SAnoob Joseph 		   struct ipsec_test_data *res_d)
7326622d9c9SAnoob Joseph {
7336622d9c9SAnoob Joseph 	uint8_t *output_text = rte_pktmbuf_mtod(m, uint8_t *);
7346622d9c9SAnoob Joseph 	uint32_t len = rte_pktmbuf_pkt_len(m);
7356622d9c9SAnoob Joseph 
7366622d9c9SAnoob Joseph 	memcpy(res_d, td, sizeof(*res_d));
7376622d9c9SAnoob Joseph 	memcpy(res_d->input_text.data, output_text, len);
7386622d9c9SAnoob Joseph 	res_d->input_text.len = len;
7396622d9c9SAnoob Joseph 
7406622d9c9SAnoob Joseph 	res_d->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
7416622d9c9SAnoob Joseph 	if (res_d->aead) {
7426622d9c9SAnoob Joseph 		res_d->xform.aead.aead.op = RTE_CRYPTO_AEAD_OP_DECRYPT;
7436622d9c9SAnoob Joseph 	} else {
7448d290523SAnoob Joseph 		res_d->xform.chain.cipher.cipher.op =
7458d290523SAnoob Joseph 				RTE_CRYPTO_CIPHER_OP_DECRYPT;
7468d290523SAnoob Joseph 		res_d->xform.chain.auth.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
7476622d9c9SAnoob Joseph 	}
7486622d9c9SAnoob Joseph 
749474f1202SAnoob Joseph 	return TEST_SUCCESS;
750474f1202SAnoob Joseph }
751474f1202SAnoob Joseph 
752474f1202SAnoob Joseph int
753474f1202SAnoob Joseph test_ipsec_post_process(struct rte_mbuf *m, const struct ipsec_test_data *td,
7546622d9c9SAnoob Joseph 			struct ipsec_test_data *res_d, bool silent,
7556622d9c9SAnoob Joseph 			const struct ipsec_test_flags *flags)
756474f1202SAnoob Joseph {
7579fb87fbfSTejasree Kondoj 	uint8_t *output_text = rte_pktmbuf_mtod(m, uint8_t *);
758cd928003STejasree Kondoj 	int ret;
759cd928003STejasree Kondoj 
760*65d68c7cSAnoob Joseph 	if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
761*65d68c7cSAnoob Joseph 		const struct rte_ipv4_hdr *iph4;
762*65d68c7cSAnoob Joseph 		const struct rte_ipv6_hdr *iph6;
763*65d68c7cSAnoob Joseph 
764*65d68c7cSAnoob Joseph 		if (flags->iv_gen) {
765cd928003STejasree Kondoj 			ret = test_ipsec_iv_verify_push(m, td);
766cd928003STejasree Kondoj 			if (ret != TEST_SUCCESS)
767cd928003STejasree Kondoj 				return ret;
768cd928003STejasree Kondoj 		}
769cd928003STejasree Kondoj 
770*65d68c7cSAnoob Joseph 		iph4 = (const struct rte_ipv4_hdr *)output_text;
7719fb87fbfSTejasree Kondoj 
772*65d68c7cSAnoob Joseph 		if (td->ipsec_xform.mode ==
773*65d68c7cSAnoob Joseph 				RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) {
774*65d68c7cSAnoob Joseph 			if (flags->ipv6) {
775*65d68c7cSAnoob Joseph 				iph6 = (const struct rte_ipv6_hdr *)output_text;
776*65d68c7cSAnoob Joseph 				if (is_valid_ipv6_pkt(iph6) == false) {
777*65d68c7cSAnoob Joseph 					printf("Transport packet is not IPv6\n");
778*65d68c7cSAnoob Joseph 					return TEST_FAILED;
779*65d68c7cSAnoob Joseph 				}
780*65d68c7cSAnoob Joseph 			} else {
781*65d68c7cSAnoob Joseph 				if (is_valid_ipv4_pkt(iph4) == false) {
782*65d68c7cSAnoob Joseph 					printf("Transport packet is not IPv4\n");
783*65d68c7cSAnoob Joseph 					return TEST_FAILED;
784*65d68c7cSAnoob Joseph 				}
785*65d68c7cSAnoob Joseph 			}
786*65d68c7cSAnoob Joseph 		} else {
7879fb87fbfSTejasree Kondoj 			if (td->ipsec_xform.tunnel.type ==
7889fb87fbfSTejasree Kondoj 					RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
7899fb87fbfSTejasree Kondoj 				if (is_valid_ipv4_pkt(iph4) == false) {
790*65d68c7cSAnoob Joseph 					printf("Tunnel outer header is not IPv4\n");
7919fb87fbfSTejasree Kondoj 					return TEST_FAILED;
7929fb87fbfSTejasree Kondoj 				}
7939fb87fbfSTejasree Kondoj 			} else {
7949fb87fbfSTejasree Kondoj 				iph6 = (const struct rte_ipv6_hdr *)output_text;
7959fb87fbfSTejasree Kondoj 				if (is_valid_ipv6_pkt(iph6) == false) {
796*65d68c7cSAnoob Joseph 					printf("Tunnel outer header is not IPv6\n");
7979fb87fbfSTejasree Kondoj 					return TEST_FAILED;
7989fb87fbfSTejasree Kondoj 				}
7999fb87fbfSTejasree Kondoj 			}
8009fb87fbfSTejasree Kondoj 		}
801*65d68c7cSAnoob Joseph 	}
8029fb87fbfSTejasree Kondoj 
803474f1202SAnoob Joseph 	/*
804474f1202SAnoob Joseph 	 * In case of known vector tests & all inbound tests, res_d provided
805474f1202SAnoob Joseph 	 * would be NULL and output data need to be validated against expected.
806474f1202SAnoob Joseph 	 * For inbound, output_text would be plain packet and for outbound
807474f1202SAnoob Joseph 	 * output_text would IPsec packet. Validate by comparing against
808474f1202SAnoob Joseph 	 * known vectors.
8096622d9c9SAnoob Joseph 	 *
8106622d9c9SAnoob Joseph 	 * In case of combined mode tests, the output_text from outbound
8116622d9c9SAnoob Joseph 	 * operation (ie, IPsec packet) would need to be inbound processed to
8126622d9c9SAnoob Joseph 	 * obtain the plain text. Copy output_text to result data, 'res_d', so
8136622d9c9SAnoob Joseph 	 * that inbound processing can be done.
814474f1202SAnoob Joseph 	 */
8156622d9c9SAnoob Joseph 
8166622d9c9SAnoob Joseph 	if (res_d == NULL)
8176622d9c9SAnoob Joseph 		return test_ipsec_td_verify(m, td, silent, flags);
8186622d9c9SAnoob Joseph 	else
8196622d9c9SAnoob Joseph 		return test_ipsec_res_d_prepare(m, td, res_d);
820474f1202SAnoob Joseph }
821474f1202SAnoob Joseph 
822474f1202SAnoob Joseph int
823474f1202SAnoob Joseph test_ipsec_status_check(struct rte_crypto_op *op,
8246622d9c9SAnoob Joseph 			const struct ipsec_test_flags *flags,
8254aa52f21SAnoob Joseph 			enum rte_security_ipsec_sa_direction dir,
8264aa52f21SAnoob Joseph 			int pkt_num)
827474f1202SAnoob Joseph {
828474f1202SAnoob Joseph 	int ret = TEST_SUCCESS;
829474f1202SAnoob Joseph 
8306978f51eSAnoob Joseph 	if (dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
8316978f51eSAnoob Joseph 	    flags->sa_expiry_pkts_hard &&
8326978f51eSAnoob Joseph 	    pkt_num == IPSEC_TEST_PACKETS_MAX) {
8336978f51eSAnoob Joseph 		if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) {
8346978f51eSAnoob Joseph 			printf("SA hard expiry (pkts) test failed\n");
8356978f51eSAnoob Joseph 			return TEST_FAILED;
8366978f51eSAnoob Joseph 		} else {
8376978f51eSAnoob Joseph 			return TEST_SUCCESS;
8386978f51eSAnoob Joseph 		}
8396978f51eSAnoob Joseph 	}
8406978f51eSAnoob Joseph 
841270470eeSTejasree Kondoj 	if ((dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
842270470eeSTejasree Kondoj 	    flags->tunnel_hdr_verify) {
843270470eeSTejasree Kondoj 		if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) {
844270470eeSTejasree Kondoj 			printf("Tunnel header verify test case failed\n");
845270470eeSTejasree Kondoj 			return TEST_FAILED;
846270470eeSTejasree Kondoj 		} else {
847270470eeSTejasree Kondoj 			return TEST_SUCCESS;
848270470eeSTejasree Kondoj 		}
849270470eeSTejasree Kondoj 	}
850270470eeSTejasree Kondoj 
8510f453190STejasree Kondoj 	if (dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS && flags->icv_corrupt) {
8520f453190STejasree Kondoj 		if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) {
8530f453190STejasree Kondoj 			printf("ICV corruption test case failed\n");
8540f453190STejasree Kondoj 			ret = TEST_FAILED;
8550f453190STejasree Kondoj 		}
8560f453190STejasree Kondoj 	} else {
857474f1202SAnoob Joseph 		if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
8584aa52f21SAnoob Joseph 			printf("Security op processing failed [pkt_num: %d]\n",
8594aa52f21SAnoob Joseph 			       pkt_num);
8604aa52f21SAnoob Joseph 			ret = TEST_FAILED;
8614aa52f21SAnoob Joseph 		}
8624aa52f21SAnoob Joseph 	}
8634aa52f21SAnoob Joseph 
8644aa52f21SAnoob Joseph 	if (flags->sa_expiry_pkts_soft && pkt_num == IPSEC_TEST_PACKETS_MAX) {
8654aa52f21SAnoob Joseph 		if (!(op->aux_flags &
8664aa52f21SAnoob Joseph 		      RTE_CRYPTO_OP_AUX_FLAGS_IPSEC_SOFT_EXPIRY)) {
8674aa52f21SAnoob Joseph 			printf("SA soft expiry (pkts) test failed\n");
868474f1202SAnoob Joseph 			ret = TEST_FAILED;
869474f1202SAnoob Joseph 		}
8700f453190STejasree Kondoj 	}
871474f1202SAnoob Joseph 
872474f1202SAnoob Joseph 	return ret;
873474f1202SAnoob Joseph }
874