diff --git a/app/test-crypto-perf/cperf_ops.c b/app/test-crypto-perf/cperf_ops.c
index e06b59f55..f851509ec 100644
--- a/app/test-crypto-perf/cperf_ops.c
+++ b/app/test-crypto-perf/cperf_ops.c
@@ -26,6 +26,10 @@ cperf_set_ops_security(struct rte_crypto_op **ops,
 			(struct rte_security_session *)sess;
 		uint32_t buf_sz;
 
+		uint32_t *per_pkt_hfn = rte_crypto_op_ctod_offset(ops[i],
+					uint32_t *, iv_offset);
+		*per_pkt_hfn = options->pdcp_ses_hfn_en ? 0 : PDCP_DEFAULT_HFN;
+
 		ops[i]->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
 		rte_security_attach_session(ops[i], sec_sess);
 		sym_op->m_src = (struct rte_mbuf *)((uint8_t *)ops[i] +
@@ -554,16 +558,15 @@ cperf_create_session(struct rte_mempool *sess_mp,
 		cipher_xform.cipher.algo = options->cipher_algo;
 		cipher_xform.cipher.op = options->cipher_op;
 		cipher_xform.cipher.iv.offset = iv_offset;
+		cipher_xform.cipher.iv.length = 4;
 
 		/* cipher different than null */
 		if (options->cipher_algo != RTE_CRYPTO_CIPHER_NULL) {
 			cipher_xform.cipher.key.data = test_vector->cipher_key.data;
 			cipher_xform.cipher.key.length = test_vector->cipher_key.length;
-			cipher_xform.cipher.iv.length = test_vector->cipher_iv.length;
 		} else {
 			cipher_xform.cipher.key.data = NULL;
 			cipher_xform.cipher.key.length = 0;
-			cipher_xform.cipher.iv.length = 0;
 		}
 
 		/* Setup Auth Parameters */
@@ -601,8 +604,10 @@ cperf_create_session(struct rte_mempool *sess_mp,
 				.domain = options->pdcp_domain,
 				.pkt_dir = 0,
 				.sn_size = options->pdcp_sn_sz,
-				.hfn = 0x1,
+				.hfn = options->pdcp_ses_hfn_en ?
+					PDCP_DEFAULT_HFN : 0,
 				.hfn_threshold = 0x70C0A,
+				.hfn_ovrd = !(options->pdcp_ses_hfn_en),
 			} },
 			.crypto_xform = &cipher_xform
 		};
diff --git a/app/test-crypto-perf/cperf_options.h b/app/test-crypto-perf/cperf_options.h
index e5f1edffc..256fabb07 100644
--- a/app/test-crypto-perf/cperf_options.h
+++ b/app/test-crypto-perf/cperf_options.h
@@ -50,6 +50,8 @@
 #ifdef RTE_LIBRTE_SECURITY
 #define CPERF_PDCP_SN_SZ	("pdcp-sn-sz")
 #define CPERF_PDCP_DOMAIN	("pdcp-domain")
+#define CPERF_PDCP_SES_HFN_EN	("pdcp-ses-hfn-en")
+#define PDCP_DEFAULT_HFN	0x1
 #define CPERF_DOCSIS_HDR_SZ	("docsis-hdr-sz")
 #endif
 
@@ -123,6 +125,7 @@ struct cperf_options {
 
 #ifdef RTE_LIBRTE_SECURITY
 	uint16_t pdcp_sn_sz;
+	uint16_t pdcp_ses_hfn_en;
 	enum rte_security_pdcp_domain pdcp_domain;
 	uint16_t docsis_hdr_sz;
 #endif
diff --git a/app/test-crypto-perf/cperf_options_parsing.c b/app/test-crypto-perf/cperf_options_parsing.c
index 20577a144..44aa7f925 100644
--- a/app/test-crypto-perf/cperf_options_parsing.c
+++ b/app/test-crypto-perf/cperf_options_parsing.c
@@ -58,6 +58,9 @@ usage(char *progname)
 		"           and dequeue in pmd-cyclecount benchmarking mode\n"
 		" --csv-friendly: enable test result output CSV friendly\n"
 #ifdef RTE_LIBRTE_SECURITY
+		" --pdcp-sn-sz N: set PDCP SN size N <5/7/12/15/18>\n"
+		" --pdcp-domain DOMAIN: set PDCP domain <control/user>\n"
+		" --pdcp-ses-hfn-en: enable session based fixed HFN\n"
 		" --docsis-hdr-sz: set DOCSIS header size\n"
 #endif
 		" -h: prints this help\n",
@@ -834,6 +837,7 @@ static struct option lgopts[] = {
 #ifdef RTE_LIBRTE_SECURITY
 	{ CPERF_PDCP_SN_SZ, required_argument, 0, 0 },
 	{ CPERF_PDCP_DOMAIN, required_argument, 0, 0 },
+	{ CPERF_PDCP_SES_HFN_EN, no_argument, 0, 0 },
 	{ CPERF_DOCSIS_HDR_SZ, required_argument, 0, 0 },
 #endif
 	{ CPERF_CSV, no_argument, 0, 0},
@@ -905,6 +909,7 @@ cperf_options_default(struct cperf_options *opts)
 #ifdef RTE_LIBRTE_SECURITY
 	opts->pdcp_sn_sz = 12;
 	opts->pdcp_domain = RTE_SECURITY_PDCP_MODE_CONTROL;
+	opts->pdcp_ses_hfn_en = 0;
 	opts->docsis_hdr_sz = 17;
 #endif
 }
@@ -945,6 +950,7 @@ cperf_opts_parse_long(int opt_idx, struct cperf_options *opts)
 #ifdef RTE_LIBRTE_SECURITY
 		{ CPERF_PDCP_SN_SZ,	parse_pdcp_sn_sz },
 		{ CPERF_PDCP_DOMAIN,	parse_pdcp_domain },
+		{ CPERF_PDCP_SES_HFN_EN,	parse_pdcp_ses_hfn_en },
 		{ CPERF_DOCSIS_HDR_SZ,	parse_docsis_hdr_sz },
 #endif
 		{ CPERF_CSV,		parse_csv_friendly},
@@ -1079,6 +1085,13 @@ check_docsis_buffer_length(struct cperf_options *options)
 
 	return 0;
 }
+
+static int
+parse_pdcp_ses_hfn_en(struct cperf_options *opts, const char *arg __rte_unused)
+{
+	opts->pdcp_ses_hfn_en = 1;
+	return 0;
+}
 #endif
 
 int
diff --git a/doc/guides/tools/cryptoperf.rst b/doc/guides/tools/cryptoperf.rst
index a8df8bc99..28b729dbd 100644
--- a/doc/guides/tools/cryptoperf.rst
+++ b/doc/guides/tools/cryptoperf.rst
@@ -347,6 +347,10 @@ The following are the application command-line options:
 
         Set DOCSIS header size(n) in bytes.
 
+* ``--pdcp-ses-hfn-en``
+
+        Enable fixed session based HFN instead of per packet HFN.
+
 Test Vector File
 ~~~~~~~~~~~~~~~~
 
