[11/21] test/security: add DTLS 1.2 anti-replay tests

Message ID 20240305072213.283205-12-asasidharan@marvell.com (mailing list archive)
State Superseded, archived
Delegated to: akhil goyal
Headers
Series Improvements and new test cases |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Aakash Sasidharan March 5, 2024, 7:22 a.m. UTC
  Add anti-replay test for DTLS 1.2.

Signed-off-by: Aakash Sasidharan <asasidharan@marvell.com>
---
 app/test/test_cryptodev.c                     | 115 ++++++++++++++-
 app/test/test_cryptodev_security_tls_record.c | 132 ++++++++++--------
 app/test/test_cryptodev_security_tls_record.h |  11 +-
 3 files changed, 188 insertions(+), 70 deletions(-)
  

Patch

diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c
index 44dc99b088..44d749a501 100644
--- a/app/test/test_cryptodev.c
+++ b/app/test/test_cryptodev.c
@@ -11827,6 +11827,10 @@  test_tls_record_proto_process(const struct tls_record_test_data td[],
 		.protocol = RTE_SECURITY_PROTOCOL_TLS_RECORD,
 	};
 
+	if ((tls_record_xform.ver == RTE_SECURITY_VERSION_DTLS_1_2) &&
+	    (sess_type == RTE_SECURITY_TLS_SESS_TYPE_READ))
+		sess_conf.tls_record.dtls_1_2.ar_win_sz = flags->ar_win_size;
+
 	if (td[0].aead)
 		test_tls_record_imp_nonce_update(&td[0], &tls_record_xform);
 
@@ -11851,6 +11855,17 @@  test_tls_record_proto_process(const struct tls_record_test_data td[],
 		return TEST_SKIPPED;
 
 	for (i = 0; i < nb_td; i++) {
+		if (flags->ar_win_size &&
+			(sess_type == RTE_SECURITY_TLS_SESS_TYPE_WRITE)) {
+			sess_conf.tls_record.dtls_1_2.seq_no =
+				td[i].tls_record_xform.dtls_1_2.seq_no;
+			ret = rte_security_session_update(ctx, ut_params->sec_session, &sess_conf);
+			if (ret) {
+				printf("Could not update sequence number in session\n");
+				return TEST_SKIPPED;
+			}
+		}
+
 		/* Setup source mbuf payload */
 		ut_params->ibuf = create_segmented_mbuf(ts_params->mbuf_pool, td[i].input_text.len,
 				nb_segs, 0);
@@ -11890,17 +11905,19 @@  test_tls_record_proto_process(const struct tls_record_test_data td[],
 		/* Process crypto operation */
 		process_crypto_request(dev_id, ut_params->op);
 
-		ret = test_tls_record_status_check(ut_params->op);
+		ret = test_tls_record_status_check(ut_params->op, &td[i]);
 		if (ret != TEST_SUCCESS)
 			goto crypto_op_free;
 
 		if (res_d != NULL)
 			res_d_tmp = &res_d[i];
 
-		ret = test_tls_record_post_process(ut_params->ibuf, &td[i], res_d_tmp, silent);
-		if (ret != TEST_SUCCESS)
-			goto crypto_op_free;
-
+		if (ut_params->op->status == RTE_CRYPTO_OP_STATUS_SUCCESS) {
+			ret = test_tls_record_post_process(ut_params->ibuf, &td[i], res_d_tmp,
+							   silent);
+			if (ret != TEST_SUCCESS)
+				goto crypto_op_free;
+		}
 
 		rte_crypto_op_free(ut_params->op);
 		ut_params->op = NULL;
@@ -12190,6 +12207,90 @@  test_dtls_1_2_record_proto_display_list(void)
 	return test_tls_record_proto_all(&flags);
 }
 
+static int
+test_dtls_pkt_replay(const uint64_t seq_no[],
+		      bool replayed_pkt[], uint32_t nb_pkts,
+		      struct tls_record_test_flags *flags)
+{
+	struct tls_record_test_data td_outb[TEST_SEC_PKTS_MAX];
+	struct tls_record_test_data td_inb[TEST_SEC_PKTS_MAX];
+	unsigned int i, idx, pass_cnt = 0;
+	int ret;
+
+	for (i = 0; i < RTE_DIM(sec_alg_list); i++) {
+		test_tls_record_td_prepare(sec_alg_list[i].param1, sec_alg_list[i].param2, flags,
+					   td_outb, nb_pkts, 0);
+
+		for (idx = 0; idx < nb_pkts; idx++)
+			td_outb[idx].tls_record_xform.dtls_1_2.seq_no = seq_no[idx];
+
+		ret = test_tls_record_proto_process(td_outb, td_inb, nb_pkts, true, flags);
+		if (ret == TEST_SKIPPED)
+			continue;
+
+		if (ret == TEST_FAILED)
+			return TEST_FAILED;
+
+		test_tls_record_td_update(td_inb, td_outb, nb_pkts, flags);
+
+		for (idx = 0; idx < nb_pkts; idx++) {
+			td_inb[idx].tls_record_xform.dtls_1_2.ar_win_sz = flags->ar_win_size;
+			/* Set antireplay flag for packets to be dropped */
+			td_inb[idx].ar_packet = replayed_pkt[idx];
+		}
+
+		ret = test_tls_record_proto_process(td_inb, NULL, nb_pkts, true, flags);
+		if (ret == TEST_SKIPPED)
+			continue;
+
+		if (ret == TEST_FAILED)
+			return TEST_FAILED;
+
+		if (flags->display_alg)
+			test_sec_alg_display(sec_alg_list[i].param1, sec_alg_list[i].param2);
+
+		pass_cnt++;
+	}
+
+	if (pass_cnt > 0)
+		return TEST_SUCCESS;
+	else
+		return TEST_SKIPPED;
+}
+
+static int
+test_dtls_1_2_record_proto_antireplay(void)
+{
+	struct tls_record_test_flags flags;
+	uint64_t winsz = 64, seq_no[5];
+	uint32_t nb_pkts = 5;
+	bool replayed_pkt[5];
+
+	memset(&flags, 0, sizeof(flags));
+
+	flags.tls_version = RTE_SECURITY_VERSION_DTLS_1_2;
+	flags.ar_win_size = winsz;
+
+	/* 1. Advance the TOP of the window to WS * 2 */
+	seq_no[0] = winsz * 2;
+	/* 2. Test sequence number within the new window(WS + 1) */
+	seq_no[1] = winsz + 1;
+	/* 3. Test sequence number less than the window BOTTOM */
+	seq_no[2] = winsz;
+	/* 4. Test sequence number in the middle of the window */
+	seq_no[3] = winsz + (winsz / 2);
+	/* 5. Test replay of the packet in the middle of the window */
+	seq_no[4] = winsz + (winsz / 2);
+
+	replayed_pkt[0] = false;
+	replayed_pkt[1] = false;
+	replayed_pkt[2] = true;
+	replayed_pkt[3] = false;
+	replayed_pkt[4] = true;
+
+	return test_dtls_pkt_replay(seq_no, replayed_pkt, nb_pkts, &flags);
+}
+
 static int
 test_dtls_1_2_record_proto_sgl(void)
 {
@@ -17505,6 +17606,10 @@  static struct unit_test_suite dtls12_record_proto_testsuite  = {
 			"Zero len DTLS record with content type as ctrl",
 			ut_setup_security, ut_teardown,
 			test_dtls_1_2_record_proto_zero_len_non_app),
+		TEST_CASE_NAMED_ST(
+			"Antireplay with window size 64",
+			ut_setup_security, ut_teardown,
+			test_dtls_1_2_record_proto_antireplay),
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
diff --git a/app/test/test_cryptodev_security_tls_record.c b/app/test/test_cryptodev_security_tls_record.c
index c5410a4c92..907e043ddd 100644
--- a/app/test/test_cryptodev_security_tls_record.c
+++ b/app/test/test_cryptodev_security_tls_record.c
@@ -12,10 +12,21 @@ 
 #include "test_security_proto.h"
 
 int
-test_tls_record_status_check(struct rte_crypto_op *op)
+test_tls_record_status_check(struct rte_crypto_op *op,
+			     const struct tls_record_test_data *td)
 {
 	int ret = TEST_SUCCESS;
 
+	if ((td->tls_record_xform.type == RTE_SECURITY_TLS_SESS_TYPE_READ) &&
+	     td->ar_packet) {
+		if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) {
+			printf("Anti replay test case failed\n");
+			return TEST_FAILED;
+		} else {
+			return TEST_SUCCESS;
+		}
+	}
+
 	if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS)
 		ret = TEST_FAILED;
 
@@ -101,81 +112,80 @@  test_tls_record_td_prepare(const struct crypto_param *param1, const struct crypt
 			td->xform.chain.auth.auth.key.length = param2->key_length;
 			td->xform.chain.auth.auth.digest_length = param2->digest_length;
 		}
-	}
-
-	if (flags->data_walkthrough || flags->zero_len) {
-		test_sec_proto_pattern_set(td->input_text.data, data_len);
-		td->input_text.len = data_len;
-	}
-
-	if (flags->content_type == TLS_RECORD_TEST_CONTENT_TYPE_CUSTOM)
-		td->app_type = RTE_TLS_TYPE_MAX;
-	else if (flags->content_type == TLS_RECORD_TEST_CONTENT_TYPE_HANDSHAKE)
-		td->app_type = RTE_TLS_TYPE_HANDSHAKE;
 
-	tls_pkt_size = td->input_text.len;
+		if (flags->data_walkthrough || flags->zero_len) {
+			test_sec_proto_pattern_set(td->input_text.data, data_len);
+			td->input_text.len = data_len;
+		}
 
-	if (!td->aead) {
-		mac_len = td->xform.chain.auth.auth.digest_length;
-		switch (td->xform.chain.cipher.cipher.algo) {
-		case RTE_CRYPTO_CIPHER_3DES_CBC:
-			roundup_len = 8;
+		if (flags->content_type == TLS_RECORD_TEST_CONTENT_TYPE_CUSTOM)
+			td->app_type = RTE_TLS_TYPE_MAX;
+		else if (flags->content_type == TLS_RECORD_TEST_CONTENT_TYPE_HANDSHAKE)
+			td->app_type = RTE_TLS_TYPE_HANDSHAKE;
+
+		tls_pkt_size = td->input_text.len;
+
+		if (!td->aead) {
+			mac_len = td->xform.chain.auth.auth.digest_length;
+			switch (td->xform.chain.cipher.cipher.algo) {
+			case RTE_CRYPTO_CIPHER_3DES_CBC:
+				roundup_len = 8;
+				exp_nonce_len = 8;
+				break;
+			case RTE_CRYPTO_CIPHER_AES_CBC:
+				roundup_len = 16;
+				exp_nonce_len = 16;
+				break;
+			default:
+				roundup_len = 0;
+				exp_nonce_len = 0;
+				break;
+			}
+		} else {
+			mac_len = td->xform.aead.aead.digest_length;
+			roundup_len = 0;
 			exp_nonce_len = 8;
+		}
+
+		switch (td->tls_record_xform.ver) {
+		case RTE_SECURITY_VERSION_TLS_1_2:
+		case RTE_SECURITY_VERSION_TLS_1_3:
+			hdr_len = sizeof(struct rte_tls_hdr);
+			if (td->aead)
+				min_padding = 0;
+			else
+				min_padding = 1;
 			break;
-		case RTE_CRYPTO_CIPHER_AES_CBC:
-			roundup_len = 16;
-			exp_nonce_len = 16;
+		case RTE_SECURITY_VERSION_DTLS_1_2:
+			hdr_len = sizeof(struct rte_dtls_hdr);
+			if (td->aead)
+				min_padding = 0;
+			else
+				min_padding = 1;
 			break;
 		default:
-			roundup_len = 0;
-			exp_nonce_len = 0;
+			hdr_len = 0;
+			min_padding = 0;
 			break;
 		}
-	} else {
-		mac_len = td->xform.aead.aead.digest_length;
-		roundup_len = 0;
-		exp_nonce_len = 8;
-	}
-
-	switch (td->tls_record_xform.ver) {
-	case RTE_SECURITY_VERSION_TLS_1_2:
-	case RTE_SECURITY_VERSION_TLS_1_3:
-		hdr_len = sizeof(struct rte_tls_hdr);
-		if (td->aead)
-			min_padding = 0;
-		else
-			min_padding = 1;
-		break;
-	case RTE_SECURITY_VERSION_DTLS_1_2:
-		hdr_len = sizeof(struct rte_dtls_hdr);
-		if (td->aead)
-			min_padding = 0;
-		else
-			min_padding = 1;
-		break;
-	default:
-		hdr_len = 0;
-		min_padding = 0;
-		break;
-	}
 
-	tls_pkt_size += mac_len;
+		tls_pkt_size += mac_len;
 
-	/* Padding */
-	tls_pkt_size += min_padding;
+		/* Padding */
+		tls_pkt_size += min_padding;
 
-	if (roundup_len)
-		tls_pkt_size = RTE_ALIGN_MUL_CEIL(tls_pkt_size, roundup_len);
+		if (roundup_len)
+			tls_pkt_size = RTE_ALIGN_MUL_CEIL(tls_pkt_size, roundup_len);
 
-	/* Explicit nonce */
-	tls_pkt_size += exp_nonce_len;
+		/* Explicit nonce */
+		tls_pkt_size += exp_nonce_len;
 
-	/* Add TLS header */
-	tls_pkt_size += hdr_len;
+		/* Add TLS header */
+		tls_pkt_size += hdr_len;
 
-	td->output_text.len = tls_pkt_size;
+		td->output_text.len = tls_pkt_size;
 
-	RTE_SET_USED(flags);
+	}
 }
 
 void
diff --git a/app/test/test_cryptodev_security_tls_record.h b/app/test/test_cryptodev_security_tls_record.h
index 22572537ef..e706e38e46 100644
--- a/app/test/test_cryptodev_security_tls_record.h
+++ b/app/test/test_cryptodev_security_tls_record.h
@@ -89,16 +89,18 @@  struct tls_record_test_data {
 	struct rte_security_tls_record_xform tls_record_xform;
 	uint8_t app_type;
 	bool aead;
+	bool ar_packet;
 };
 
 struct tls_record_test_flags {
 	bool display_alg;
-	uint8_t nb_segs_in_mbuf;
 	bool data_walkthrough;
-	enum rte_security_tls_version tls_version;
 	bool pkt_corruption;
-	enum tls_record_test_content_type content_type;
 	bool zero_len;
+	uint8_t nb_segs_in_mbuf;
+	enum rte_security_tls_version tls_version;
+	enum tls_record_test_content_type content_type;
+	int ar_win_size;
 };
 
 extern struct tls_record_test_data tls_test_data_aes_128_gcm_v1;
@@ -123,7 +125,8 @@  extern struct tls_record_test_data dtls_test_data_aes_256_cbc_sha384_hmac;
 extern struct tls_record_test_data dtls_test_data_3des_cbc_sha1_hmac;
 extern struct tls_record_test_data dtls_test_data_null_cipher_sha1_hmac;
 
-int test_tls_record_status_check(struct rte_crypto_op *op);
+int test_tls_record_status_check(struct rte_crypto_op *op,
+				 const struct tls_record_test_data *td);
 
 int test_tls_record_sec_caps_verify(struct rte_security_tls_record_xform *tls_record_xform,
 				    const struct rte_security_capability *sec_cap, bool silent);