diff --git a/app/test/test_cryptodev_asym.c b/app/test/test_cryptodev_asym.c
index 0fea47c42e..a097023011 100644
--- a/app/test/test_cryptodev_asym.c
+++ b/app/test/test_cryptodev_asym.c
@@ -23,6 +23,7 @@
 #include "test_cryptodev_rsa_test_vectors.h"
 #include "test_cryptodev_asym_util.h"
 #include "test.h"
+#include "test_cryptodev_ecdh_vectors.h"
 
 #define TEST_NUM_BUFS 10
 #define TEST_NUM_SESSIONS 4
@@ -2362,6 +2363,358 @@ test_ecdsa_verify(const void *input_vector)
 	return TEST_SUCCESS;
 }
 
+/*
+ * This function is split into 3 steps: STEP1, STEP1.5, STEP2
+ * Steps 1 and 2 are just DH steps (Public key and shared secret generation).
+ * Step 1.5 is Public Key verification (if point belongs to elliptic curve)
+ */
+static int
+test_ecdh(const void *input_vector)
+{
+	const struct ECDH_test_vector *test_vector = input_vector;
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	struct rte_crypto_asym_xform xform = {
+		.next = NULL,
+		.xform_type = RTE_CRYPTO_ASYM_XFORM_ECDH,
+		.ec.curve_id = test_vector->curve_id
+	};
+	const uint8_t dev_id = ts_params->valid_devs[0];
+
+	uint8_t alice_x[test_vector->curve_bytesize],
+		alice_y[test_vector->curve_bytesize];
+	uint8_t bob_x[test_vector->curve_bytesize],
+		bob_y[test_vector->curve_bytesize];
+	uint8_t alice_xZ[test_vector->curve_bytesize],
+		alice_yZ[test_vector->curve_bytesize];
+	uint8_t bob_xZ[test_vector->curve_bytesize],
+		bob_yZ[test_vector->curve_bytesize];
+	struct rte_crypto_op *alice_op = NULL, *bob_op = NULL;
+
+	alice_op = rte_crypto_op_alloc(op_mpool,
+		RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	bob_op = rte_crypto_op_alloc(op_mpool,
+		RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+
+	/*
+	 * STEP 1a:
+	 * Generate Alice public key
+	 */
+
+	alice_op->sess_type = RTE_CRYPTO_OP_SESSIONLESS;
+	alice_op->asym->xform = &xform;
+	alice_op->asym->ecdh.ke_type = RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE;
+	alice_op->asym->ecdh.priv_key = test_vector->alice_d;
+	alice_op->asym->ecdh.pub_key.x.data = alice_x;
+	alice_op->asym->ecdh.pub_key.y.data = alice_y;
+
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &alice_op, 1) != 1) {
+		RTE_LOG(ERR, USER1, "Error sending packet for sign\n");
+		return -1;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &alice_op, 1) == 0)
+		rte_pause();
+
+	if (alice_op->asym->ecdh.pub_key.x.length !=
+			test_vector->alice_q.x.length) {
+		RTE_LOG(ERR, USER1,
+				"Incorrect Alice public key length (X coeff) Received length = %lu Expeceted length = %lu\n",
+				test_vector->alice_q.x.length,
+				alice_op->asym->ecdh.pub_key.x.length
+			);
+		goto error;
+	}
+	if (alice_op->asym->ecdh.pub_key.y.length !=
+			test_vector->alice_q.y.length) {
+		RTE_LOG(ERR, USER1,
+				"Incorrect Alice public key length (Y coeff) Received length = %lu Expeceted length = %lu\n",
+					test_vector->alice_q.y.length,
+					alice_op->asym->ecdh.pub_key.y.length
+				);
+		goto error;
+	}
+	if (memcmp(alice_op->asym->ecdh.pub_key.x.data,
+			test_vector->alice_q.x.data,
+			test_vector->alice_q.x.length)
+	) {
+		RTE_LOG(ERR, USER1, "Incorrect Alice public key X\n");
+		debug_hexdump(stdout, "Generated PublicKey x (Alice):",
+			alice_op->asym->ecdh.pub_key.x.data,
+			alice_op->asym->ecdh.pub_key.x.length);
+		goto error;
+	}
+	if (memcmp(alice_op->asym->ecdh.pub_key.y.data,
+			test_vector->alice_q.y.data,
+			test_vector->alice_q.y.length)
+	) {
+		RTE_LOG(ERR, USER1, "Incorrect Alice public key Y\n");
+		debug_hexdump(stdout, "Generated PublicKey y (Alice):",
+				alice_op->asym->ecdh.pub_key.y.data,
+				alice_op->asym->ecdh.pub_key.y.length);
+		goto error;
+	}
+
+
+	/*
+	 * STEP 1b:
+	 * Generate Bob public key
+	 */
+
+	bob_op->sess_type = RTE_CRYPTO_OP_SESSIONLESS;
+	bob_op->asym->xform = &xform;
+	bob_op->asym->ecdh.ke_type = RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE;
+	bob_op->asym->ecdh.priv_key = test_vector->bob_d;
+	bob_op->asym->ecdh.pub_key.x.data = bob_x;
+	bob_op->asym->ecdh.pub_key.y.data = bob_y;
+
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &bob_op, 1) != 1) {
+		RTE_LOG(ERR, USER1, "Error sending packet for sign\n");
+		goto error;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &bob_op, 1) == 0)
+		rte_pause();
+
+	if (bob_op->asym->ecdh.pub_key.x.length !=
+			test_vector->bob_q.x.length) {
+		RTE_LOG(ERR, USER1,
+			"Incorrect Bob's public key length (X coeff) Received length = %lu Expeceted length = %lu\n",
+			test_vector->bob_q.x.length,
+			bob_op->asym->ecdh.pub_key.x.length
+		);
+		goto error;
+	}
+	if (bob_op->asym->ecdh.pub_key.y.length !=
+			test_vector->bob_q.y.length) {
+		RTE_LOG(ERR, USER1,
+			"Incorrect Bob's public key length (Y coeff) Received length = %lu Expeceted length = %lu\n",
+			test_vector->bob_q.y.length,
+			bob_op->asym->ecdh.pub_key.y.length
+		);
+		goto error;
+	}
+	if (memcmp(bob_op->asym->ecdh.pub_key.x.data,
+			test_vector->bob_q.x.data,
+			test_vector->bob_q.x.length)
+	) {
+		RTE_LOG(ERR, USER1, "Incorrect Bob's public key X\n");
+		debug_hexdump(stdout,
+			"Generated PublicKey x (bob):",
+			bob_op->asym->ecdh.pub_key.x.data,
+			bob_op->asym->ecdh.pub_key.x.length
+		);
+		goto error;
+	}
+	if (memcmp(bob_op->asym->ecdh.pub_key.y.data,
+			test_vector->bob_q.y.data,
+			test_vector->bob_q.y.length)
+	) {
+		RTE_LOG(ERR, USER1, "Incorrect Bob's public key Y\n");
+		debug_hexdump(stdout,
+			"Generated PublicKey y (bob):",
+			bob_op->asym->ecdh.pub_key.y.data,
+			bob_op->asym->ecdh.pub_key.y.length
+		);
+		goto error;
+	}
+
+	/*
+	 * STEP 1.5a:
+	 * Alice verifies Bob's public key, reusing op, other parameters
+	 * then already set, only what Alice needs to do is to set public
+	 * key of Bob and change key exchange type to VERIFY.
+	 */
+
+	alice_op->asym->ecdh.ke_type = RTE_CRYPTO_ASYM_KE_PUB_KEY_VERIFY;
+	alice_op->asym->ecdh.pub_key.x.data = bob_x;
+	alice_op->asym->ecdh.pub_key.x.length =
+		bob_op->asym->ecdh.pub_key.x.length;
+	alice_op->asym->ecdh.pub_key.y.data = bob_y;
+	alice_op->asym->ecdh.pub_key.y.length =
+		bob_op->asym->ecdh.pub_key.y.length;
+
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &alice_op, 1) != 1) {
+		RTE_LOG(ERR, USER1, "Error sending packet for sign\n");
+		goto error;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &alice_op, 1) == 0)
+		rte_pause();
+
+	if (alice_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to verify Bob's public key, it does not belongs to curve points\n"
+			);
+		return TEST_FAILED;
+	}
+
+	/*
+	 * STEP 1.5b:
+	 * Bob verifies Alice's public key, reusing op, other parameters
+	 * then already set, only what Bob needs to do is to set public
+	 * key of Alice and change key exchange type to VERIFY.
+	 */
+
+	bob_op->asym->ecdh.ke_type = RTE_CRYPTO_ASYM_KE_PUB_KEY_VERIFY;
+	bob_op->asym->ecdh.pub_key.x.data = alice_x;
+	bob_op->asym->ecdh.pub_key.x.length =
+		alice_op->asym->ecdh.pub_key.x.length;
+	bob_op->asym->ecdh.pub_key.y.data = alice_y;
+	bob_op->asym->ecdh.pub_key.y.length =
+		alice_op->asym->ecdh.pub_key.y.length;
+
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &bob_op, 1) != 1) {
+		RTE_LOG(ERR, USER1, "Error sending packet for sign\n");
+		goto error;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &bob_op, 1) == 0)
+		rte_pause();
+
+	if (bob_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to verify Alice's public key, it does not belongs to curve points\n"
+			);
+		goto error;
+	}
+
+	/*
+	 * STEP 2a:
+	 * Alice generates shared secret Z, since Bob's public key was already
+	 * set when doing verification only key exchange type need to be
+	 * changed, and setting place where Z will be copied by the PMD.
+	 */
+
+	alice_op->asym->ecdh.ke_type = RTE_CRYPTO_ASYM_KE_SHARED_SECRET_COMPUTE;
+	alice_op->asym->ecdh.shared_secret.x.data = alice_xZ;
+	alice_op->asym->ecdh.shared_secret.y.data = alice_yZ;
+
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &alice_op, 1) != 1) {
+		RTE_LOG(ERR, USER1, "Error sending packet for sign\n");
+		goto error;
+	}
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &alice_op, 1) == 0)
+		rte_pause();
+
+	if (alice_op->asym->ecdh.shared_secret.x.length !=
+			test_vector->Z.x.length) {
+		RTE_LOG(ERR, USER1,
+				"Incorrect Alice's shared secret length X Received = %lu Expected = %lu\n",
+				alice_op->asym->ecdh.shared_secret.x.length,
+				test_vector->Z.x.length
+		);
+		goto error;
+	}
+	if (alice_op->asym->ecdh.shared_secret.y.length !=
+			test_vector->Z.y.length) {
+		RTE_LOG(ERR, USER1,
+				"Incorrect Alice's shared secret length Y Received = %lu Expected = %lu\n",
+				alice_op->asym->ecdh.shared_secret.y.length,
+				test_vector->Z.y.length
+		);
+		goto error;
+	}
+
+	if (memcmp(alice_op->asym->ecdh.shared_secret.x.data,
+			test_vector->Z.x.data,
+			test_vector->Z.x.length)
+	) {
+		RTE_LOG(ERR, USER1, "Incorrect Alice's shared secret X\n");
+		debug_hexdump(stdout,
+			"Generated SharedSecret x (Alice):",
+			alice_op->asym->ecdh.shared_secret.x.data,
+			alice_op->asym->ecdh.shared_secret.x.length
+		);
+		goto error;
+	}
+	if (memcmp(alice_op->asym->ecdh.shared_secret.y.data,
+			test_vector->Z.y.data,
+			test_vector->Z.y.length)
+	) {
+		RTE_LOG(ERR, USER1, "Incorrect Alice's shared secret Y\n");
+		debug_hexdump(stdout,
+			"Generated SharedSecret y (Alice):",
+			alice_op->asym->ecdh.shared_secret.y.data,
+			alice_op->asym->ecdh.shared_secret.y.length
+		);
+		goto error;
+	}
+
+	/*
+	 * STEP 2b:
+	 * Bob generates shared secret Z, since Alice's public key was already
+	 * set when doing verification only key exchange type need to be
+	 * changed, and setting place where Z will be copied by the PMD.
+	 */
+
+	bob_op->asym->ecdh.ke_type = RTE_CRYPTO_ASYM_KE_SHARED_SECRET_COMPUTE;
+	bob_op->asym->ecdh.shared_secret.x.data = bob_xZ;
+	bob_op->asym->ecdh.shared_secret.y.data = bob_yZ;
+
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &bob_op, 1) != 1) {
+		RTE_LOG(ERR, USER1, "Error sending packet for sign\n");
+		goto error;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &bob_op, 1) == 0)
+		rte_pause();
+
+	if (bob_op->asym->ecdh.shared_secret.x.length !=
+			test_vector->Z.x.length) {
+		RTE_LOG(ERR, USER1,
+				"Incorrect Bob's shared secret length X Received = %lu Expected = %lu\n",
+				bob_op->asym->ecdh.shared_secret.x.length,
+				test_vector->Z.x.length
+		);
+		goto error;
+	}
+	if (bob_op->asym->ecdh.shared_secret.y.length !=
+			test_vector->Z.y.length) {
+		RTE_LOG(ERR, USER1,
+				"Incorrect Bob's shared secret length Y Received = %lu Expected = %lu\n",
+				bob_op->asym->ecdh.shared_secret.y.length,
+				test_vector->Z.y.length
+		);
+		goto error;
+	}
+
+	if (memcmp(bob_op->asym->ecdh.shared_secret.x.data,
+			test_vector->Z.x.data,
+			test_vector->Z.x.length)
+	) {
+		RTE_LOG(ERR, USER1, "Incorrect Bob's shared secret X\n");
+		debug_hexdump(stdout,
+			"Generated SharedSecret x (Bob):",
+			bob_op->asym->ecdh.shared_secret.x.data,
+			bob_op->asym->ecdh.shared_secret.x.length
+		);
+		goto error;
+	}
+	if (memcmp(bob_op->asym->ecdh.shared_secret.y.data,
+			test_vector->Z.y.data,
+			test_vector->Z.y.length)
+	) {
+		RTE_LOG(ERR, USER1, "Incorrect Bob's shared secret Y\n");
+		debug_hexdump(stdout,
+			"Generated SharedSecret y (Bob):",
+			bob_op->asym->ecdh.shared_secret.y.data,
+			bob_op->asym->ecdh.shared_secret.y.length
+		);
+		goto error;
+	}
+
+	/* Both shared secret where correctly verified -> Test passed */
+
+	return TEST_SUCCESS;
+error:
+	rte_crypto_op_free(alice_op);
+	rte_crypto_op_free(bob_op);
+	return TEST_FAILED;
+}
+
 static struct unit_test_suite cryptodev_openssl_asym_testsuite  = {
 	.suite_name = "Crypto Device OPENSSL ASYM Unit Test Suite",
 	.setup = testsuite_setup,
@@ -2391,6 +2744,10 @@ static struct unit_test_suite cryptodev_qat_asym_testsuite  = {
 	.teardown = testsuite_teardown,
 	.unit_test_cases = {
 		TEST_CASE_NAMED_WITH_DATA(
+			"Test - ECDH secp256r1, RFC 5114 256 Random",
+			ut_setup_asym, ut_teardown_asym,
+			test_ecdh, &rfc5114_secp256r1),
+		TEST_CASE_NAMED_WITH_DATA(
 			"Test - ECDSA secp256r1 signature generation",
 			ut_setup_asym, ut_teardown_asym,
 			test_ecdsa_sign, &ecdsa_param_secp256r1),
diff --git a/app/test/test_cryptodev_ecdh_vectors.h b/app/test/test_cryptodev_ecdh_vectors.h
new file mode 100644
index 0000000000..553e33de38
--- /dev/null
+++ b/app/test/test_cryptodev_ecdh_vectors.h
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2022 Intel Corporation
+ */
+
+#ifndef __TEST_CRYPTODEV_ECDH_VECTORS_H__
+#define __TEST_CRYPTODEV_ECDH_VECTORS_H__
+
+#include "rte_crypto_asym.h"
+
+/*
+ * Elliptic Curve Diffie-Hellman test vector struct
+ * Peers are named Alice and Bob
+ * q - is a public key
+ * d - is a private key
+ * Z - is a shared secret
+ */
+
+struct ECDH_test_vector {
+	enum rte_crypto_curve_id curve_id;
+	int curve_bytesize;
+	rte_crypto_uint alice_d;
+	rte_crypto_uint bob_d;
+	struct rte_crypto_ec_point alice_q;
+	struct rte_crypto_ec_point bob_q;
+	struct rte_crypto_ec_point Z;
+};
+
+/*
+ * Elliptic Curve Diffie-Hellman test
+ * It consist of three phases:
+ * - Generation of public key based on private key
+ * - Verification of peer's public key
+ * - Generation of shared secret
+ * Peers in tests are named Alice and Bob
+ */
+
+/* RFC 5114 256-bit Random ECP Group Data */
+
+/*
+ * Alice's parameters
+ */
+static uint8_t rfc5114_256b_dA[] = {
+	0x81, 0x42, 0x64, 0x14, 0x5F, 0x2F, 0x56, 0xF2,
+	0xE9, 0x6A, 0x8E, 0x33, 0x7A, 0x12, 0x84, 0x99,
+	0x3F, 0xAF, 0x43, 0x2A, 0x5A, 0xBC, 0xE5, 0x9E,
+	0x86, 0x7B, 0x72, 0x91, 0xD5, 0x07, 0xA3, 0xAF,
+};
+
+static uint8_t rfc5114_256b_x_qA[] = {
+	0x2A, 0xF5, 0x02, 0xF3, 0xBE, 0x89, 0x52, 0xF2,
+	0xC9, 0xB5, 0xA8, 0xD4, 0x16, 0x0D, 0x09, 0xE9,
+	0x71, 0x65, 0xBE, 0x50, 0xBC, 0x42, 0xAE, 0x4A,
+	0x5E, 0x8D, 0x3B, 0x4B, 0xA8, 0x3A, 0xEB, 0x15,
+};
+
+static uint8_t rfc5114_256b_y_qA[] = {
+	0xEB, 0x0F, 0xAF, 0x4C, 0xA9, 0x86, 0xC4, 0xD3,
+	0x86, 0x81, 0xA0, 0xF9, 0x87, 0x2D, 0x79, 0xD5,
+	0x67, 0x95, 0xBD, 0x4B, 0xFF, 0x6E, 0x6D, 0xE3,
+	0xC0, 0xF5, 0x01, 0x5E, 0xCE, 0x5E, 0xFD, 0x85,
+};
+
+/*
+ * Bob's parameters
+ */
+static uint8_t rfc5114_256b_dB[] = {
+	0x2C, 0xE1, 0x78, 0x8E, 0xC1, 0x97, 0xE0, 0x96,
+	0xDB, 0x95, 0xA2, 0x00, 0xCC, 0x0A, 0xB2, 0x6A,
+	0x19, 0xCE, 0x6B, 0xCC, 0xAD, 0x56, 0x2B, 0x8E,
+	0xEE, 0x1B, 0x59, 0x37, 0x61, 0xCF, 0x7F, 0x41,
+};
+
+static uint8_t rfc5114_256b_x_qB[] = {
+	0xB1, 0x20, 0xDE, 0x4A, 0xA3, 0x64, 0x92, 0x79,
+	0x53, 0x46, 0xE8, 0xDE, 0x6C, 0x2C, 0x86, 0x46,
+	0xAE, 0x06, 0xAA, 0xEA, 0x27, 0x9F, 0xA7, 0x75,
+	0xB3, 0xAB, 0x07, 0x15, 0xF6, 0xCE, 0x51, 0xB0,
+};
+
+static uint8_t rfc5114_256b_y_qB[] = {
+	0x9F, 0x1B, 0x7E, 0xEC, 0xE2, 0x0D, 0x7B, 0x5E,
+	0xD8, 0xEC, 0x68, 0x5F, 0xA3, 0xF0, 0x71, 0xD8,
+	0x37, 0x27, 0x02, 0x70, 0x92, 0xA8, 0x41, 0x13,
+	0x85, 0xC3, 0x4D, 0xDE, 0x57, 0x08, 0xB2, 0xB6,
+};
+
+static uint8_t rfc5114_256b_x_Z[] = {
+	0xDD, 0x0F, 0x53, 0x96, 0x21, 0x9D, 0x1E, 0xA3,
+	0x93, 0x31, 0x04, 0x12, 0xD1, 0x9A, 0x08, 0xF1,
+	0xF5, 0x81, 0x1E, 0x9D, 0xC8, 0xEC, 0x8E, 0xEA,
+	0x7F, 0x80, 0xD2, 0x1C, 0x82, 0x0C, 0x27, 0x88,
+};
+
+static uint8_t rfc5114_256b_y_Z[] = {
+	0x03, 0x57, 0xDC, 0xCD, 0x4C, 0x80, 0x4D, 0x0D,
+	0x8D, 0x33, 0xAA, 0x42, 0xB8, 0x48, 0x83, 0x4A,
+	0xA5, 0x60, 0x5F, 0x9A, 0xB0, 0xD3, 0x72, 0x39,
+	0xA1, 0x15, 0xBB, 0xB6, 0x47, 0x93, 0x6F, 0x50,
+};
+
+static struct ECDH_test_vector rfc5114_secp256r1 = {
+	.curve_id = RTE_CRYPTO_EC_GROUP_SECP256R1,
+	.curve_bytesize = 32,
+	.alice_d = {
+		.data = rfc5114_256b_dA,
+		.length = sizeof(rfc5114_256b_dA),
+	},
+	.alice_q = {
+		.x = {
+			.data = rfc5114_256b_x_qA,
+			.length = sizeof(rfc5114_256b_x_qA),
+		},
+		.y = {
+			.data = rfc5114_256b_y_qA,
+			.length = sizeof(rfc5114_256b_y_qA),
+		},
+	},
+	.bob_d = {
+		.data = rfc5114_256b_dB,
+		.length = sizeof(rfc5114_256b_dB)
+	},
+	.bob_q = {
+		.x = {
+			.data = rfc5114_256b_x_qB,
+			.length = sizeof(rfc5114_256b_x_qB),
+		},
+		.y = {
+			.data = rfc5114_256b_y_qB,
+			.length = sizeof(rfc5114_256b_y_qB),
+		},
+	},
+	.Z = {
+		.x = {
+			.data = rfc5114_256b_x_Z,
+			.length = sizeof(rfc5114_256b_x_Z),
+		},
+		.y = {
+			.data = rfc5114_256b_y_Z,
+			.length = sizeof(rfc5114_256b_y_Z),
+		}
+	}
+};
+
+#endif
\ No newline at end of file
