[v2,14/14] cryptodev: add asym algorithms capabilities

Message ID 20220525155324.9288-15-arkadiuszx.kusztal@intel.com (mailing list archive)
State Superseded, archived
Delegated to: akhil goyal
Headers
Series cryptodev: rsa, dh, ecdh changes |

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/Intel-compilation warning apply issues

Commit Message

Arkadiusz Kusztal May 25, 2022, 3:53 p.m. UTC
  - Added asymmetric crypto algorithm specific capability struct.
Included fields like random number capability, padding flags etc.

Signed-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
---
 app/test-crypto-perf/main.c                  |  12 +-
 app/test-eventdev/test_perf_common.c         |   2 +-
 app/test/test_cryptodev_asym.c               | 210 +++++++++++++++++++++------
 app/test/test_event_crypto_adapter.c         |  16 +-
 drivers/crypto/openssl/rte_openssl_pmd_ops.c | 128 +++++++---------
 drivers/crypto/qat/dev/qat_asym_pmd_gen1.c   |  68 +++++++--
 lib/cryptodev/rte_crypto_asym.h              |  48 ++++++
 lib/cryptodev/rte_cryptodev.c                |  80 +++++++++-
 lib/cryptodev/rte_cryptodev.h                |  75 +++++++++-
 lib/cryptodev/version.map                    |   4 +
 10 files changed, 495 insertions(+), 148 deletions(-)
  

Comments

Akhil Goyal May 26, 2022, 12:54 p.m. UTC | #1
> - Added asymmetric crypto algorithm specific capability struct.
> Included fields like random number capability, padding flags etc.
> 
> Signed-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
> ---
>  app/test-crypto-perf/main.c                  |  12 +-
>  app/test-eventdev/test_perf_common.c         |   2 +-
>  app/test/test_cryptodev_asym.c               | 210 +++++++++++++++++++++------
>  app/test/test_event_crypto_adapter.c         |  16 +-
>  drivers/crypto/openssl/rte_openssl_pmd_ops.c | 128 +++++++---------
>  drivers/crypto/qat/dev/qat_asym_pmd_gen1.c   |  68 +++++++--
>  lib/cryptodev/rte_crypto_asym.h              |  48 ++++++
>  lib/cryptodev/rte_cryptodev.c                |  80 +++++++++-
>  lib/cryptodev/rte_cryptodev.h                |  75 +++++++++-
>  lib/cryptodev/version.map                    |   4 +
>  10 files changed, 495 insertions(+), 148 deletions(-)

This would also need a change in documentation.

> 
> diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
> index 17e30a8e74..f8a4c9cdcf 100644
> --- a/app/test-crypto-perf/main.c
> +++ b/app/test-crypto-perf/main.c
> @@ -364,8 +364,8 @@ cperf_verify_devices_capabilities(struct cperf_options
> *opts,
>  	struct rte_cryptodev_sym_capability_idx cap_idx;
>  	const struct rte_cryptodev_symmetric_capability *capability;
>  	struct rte_cryptodev_asym_capability_idx asym_cap_idx;
> -	const struct rte_cryptodev_asymmetric_xform_capability
> *asym_capability;
> -
> +	const struct rte_cryptodev_asymmetric_capability *asym_capability;
> +	struct rte_crypto_mod_capability mod_capa = {0};
> 
>  	uint8_t i, cdev_id;
>  	int ret;
> @@ -381,11 +381,11 @@ cperf_verify_devices_capabilities(struct
> cperf_options *opts,
>  			if (asym_capability == NULL)
>  				return -1;
> 
> -			ret =
> rte_cryptodev_asym_xform_capability_check_modlen(
> -				asym_capability, opts->modex_data-
> >modulus.len);
> -			if (ret != 0)
> +			mod_capa.max_mod_size = opts->modex_data-
> >modulus.len;
> +			ret = rte_cryptodev_capa_check_mod(asym_capability,
> +						mod_capa);
> +			if (ret == 0)
>  				return ret;
> -
>  		}
> 
>  		if (opts->op_type == CPERF_AUTH_ONLY ||
> diff --git a/app/test-eventdev/test_perf_common.c b/app/test-
> eventdev/test_perf_common.c
> index b41785492e..ac8e6410ab 100644
> --- a/app/test-eventdev/test_perf_common.c
> +++ b/app/test-eventdev/test_perf_common.c
> @@ -846,7 +846,7 @@ cryptodev_sym_sess_create(struct prod_data *p, struct
> test_perf *t)
>  static void *
>  cryptodev_asym_sess_create(struct prod_data *p, struct test_perf *t)
>  {
> -	const struct rte_cryptodev_asymmetric_xform_capability *capability;
> +	const struct rte_cryptodev_asymmetric_capability *capability;
>  	struct rte_cryptodev_asym_capability_idx cap_idx;
>  	struct rte_crypto_asym_xform xform;
>  	void *sess;
> diff --git a/app/test/test_cryptodev_asym.c b/app/test/test_cryptodev_asym.c
> index 072dbb30f4..c531265642 100644
> --- a/app/test/test_cryptodev_asym.c
> +++ b/app/test/test_cryptodev_asym.c
> @@ -311,10 +311,11 @@ test_cryptodev_asym_op(struct
> crypto_testsuite_params_asym *ts_params,
>  	struct rte_crypto_asym_xform xform_tc;
>  	void *sess = NULL;
>  	struct rte_cryptodev_asym_capability_idx cap_idx;
> -	const struct rte_cryptodev_asymmetric_xform_capability *capability;
> +	const struct rte_cryptodev_asymmetric_capability *capability;
>  	uint8_t dev_id = ts_params->valid_devs[0];
>  	uint8_t input[TEST_DATA_SIZE] = {0};
>  	uint8_t *result = NULL;
> +	struct rte_crypto_mod_capability mod_capa = {0};
> 
>  	int ret, status = TEST_SUCCESS;
> 
> @@ -358,8 +359,10 @@ test_cryptodev_asym_op(struct
> crypto_testsuite_params_asym *ts_params,
>  		asym_op->modex.base.length = data_tc->modex.base.len;
>  		asym_op->modex.result.data = result;
>  		asym_op->modex.result.length = data_tc->modex.result_len;
> -		if
> (rte_cryptodev_asym_xform_capability_check_modlen(capability,
> -				xform_tc.modex.modulus.length)) {
> +
> +		mod_capa.max_mod_size = xform_tc.modex.modulus.length;
> +		if  (!rte_cryptodev_capa_check_mod(capability,
> +			mod_capa)) {
>  			snprintf(test_msg, ASYM_TEST_MSG_LEN,
>  				"line %u "
>  				"FAILED: %s", __LINE__,
> @@ -378,8 +381,10 @@ test_cryptodev_asym_op(struct
> crypto_testsuite_params_asym *ts_params,
>  		asym_op->modinv.base.length = data_tc->modinv.base.len;
>  		asym_op->modinv.result.data = result;
>  		asym_op->modinv.result.length = data_tc->modinv.result_len;
> -		if
> (rte_cryptodev_asym_xform_capability_check_modlen(capability,
> -				xform_tc.modinv.modulus.length)) {
> +
> +		mod_capa.max_mod_size = xform_tc.modinv.modulus.length;
> +		if  (!rte_cryptodev_capa_check_mod(capability,
> +			mod_capa)) {
>  			snprintf(test_msg, ASYM_TEST_MSG_LEN,
>  				"line %u "
>  				"FAILED: %s", __LINE__,
> @@ -963,38 +968,100 @@ ut_teardown_asym(void)
>  	rte_cryptodev_stop(ts_params->valid_devs[0]);
>  }
> 
> -static inline void print_asym_capa(
> -		const struct rte_cryptodev_asymmetric_xform_capability
> *capa)
> +static void
> +print_rsa_capability(
> +	const struct rte_cryptodev_asymmetric_capability *capa)
>  {
>  	int i = 0;
> 
> +	printf("\nSupported paddings:");
> +	for (; i < 32; i++) {
> +		if (capa->rsa.padding & RTE_BIT32(i))
> +			printf("\n - %s", rte_crypto_asym_rsa_padding[i]);
> +	}
> +	printf("\nSupported hash functions:");
> +	for (i = 0; i < 32; i++) {
> +		if (capa->rsa.hash & RTE_BIT32(i))
> +			printf("\n - %s", rte_crypto_auth_algorithm_strings[i]);
> +	}
> +	printf("\nMaximum key size: ");
> +	if (capa->rsa.max_key_size == 0)
> +		printf("Unlimited");
> +	else
> +		printf("%hu", capa->rsa.max_key_size);
> +}
> +
> +static void
> +print_supported_curves(uint64_t curves)
> +{
> +	int i = 0;
> +
> +	printf("\nSupported elliptic curves:");
> +	for (; i < 64; i++) {
> +		if (curves & RTE_BIT64(i))
> +			printf("\n - %s", rte_crypto_curves_strings[i]);
> +	}
> +}
> +
> +static inline void print_asym_capa(
> +		const struct rte_cryptodev_asymmetric_capability *capa)
> +{
>  	printf("\nxform type: %s\n===================\n",
>  			rte_crypto_asym_xform_strings[capa->xform_type]);
> -	printf("operation supported -");
> 
> -	for (i = 0; i < RTE_CRYPTO_ASYM_OP_LIST_END; i++) {
> -		/* check supported operations */
> -		if (rte_cryptodev_asym_xform_capability_check_optype(capa,
> i))
> -			printf(" %s",
> -					rte_crypto_asym_op_strings[i]);
> -		}
> -		switch (capa->xform_type) {
> -		case RTE_CRYPTO_ASYM_XFORM_RSA:
> -		case RTE_CRYPTO_ASYM_XFORM_MODINV:
> -		case RTE_CRYPTO_ASYM_XFORM_MODEX:
> -		case RTE_CRYPTO_ASYM_XFORM_DH:
> -		case RTE_CRYPTO_ASYM_XFORM_DSA:
> -			printf(" modlen: min %d max %d increment %d",
> -					capa->modlen.min,
> -					capa->modlen.max,
> -					capa->modlen.increment);
> +	switch (capa->xform_type) {
> +	case RTE_CRYPTO_ASYM_XFORM_MODEX:
> +	case RTE_CRYPTO_ASYM_XFORM_MODINV:
> +		printf("Maximum size of modulus: ");
> +		if (capa->mod.max_mod_size == 0)
> +			printf("Unlimited");
> +		else
> +			printf("%hu", capa->mod.max_mod_size);
>  		break;
> -		case RTE_CRYPTO_ASYM_XFORM_ECDSA:
> -		case RTE_CRYPTO_ASYM_XFORM_ECPM:
> -		default:
> -			break;
> -		}
> -		printf("\n");
> +	case RTE_CRYPTO_ASYM_XFORM_RSA:
> +		print_rsa_capability(capa);
> +		break;
> +	case RTE_CRYPTO_ASYM_XFORM_DH:

ECDH?? I hope it will be added once it is tested in this app.

> +		printf("Maximum group size: ");
> +		if (capa->dh.max_group_size == 0)
> +			printf("Unlimited");
> +		else
> +			printf("%hu", capa->dh.max_group_size);
> +		printf("\nSupport for private key generation: ");
> +		if (capa->dh.priv_key_gen)
> +			printf("Yes");
> +		else
> +			printf("No");
> +		break;
> +	case RTE_CRYPTO_ASYM_XFORM_DSA:
> +		printf("Maximum key size: ");
> +		if (capa->dsa.max_key_size == 0)
> +			printf("Unlimited");
> +		else
> +			printf("%hu", capa->dsa.max_key_size);
> +		printf("\nSupport for random 'k' generation: ");
> +		if (capa->dsa.random_k)
> +			printf("Yes");
> +		else
> +			printf("No");
> +		break;
> +
> +		break;
> +	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
> +		print_supported_curves(capa->ecdsa.curves);
> +		printf("\nSupport for random 'k' generation: ");
> +		if (capa->ecdsa.random_k)
> +			printf("Yes");
> +		else
> +			printf("No");
> +		break;
> +	case RTE_CRYPTO_ASYM_XFORM_ECPM:
> +		print_supported_curves(capa->ecpm.curves);
> +		break;
> +	default:
> +		break;
> +	}
> +	printf("\n");
>  }
> 
>  static int
> @@ -1006,7 +1073,7 @@ test_capability(void)
>  	const struct rte_cryptodev_capabilities *dev_capa;
>  	int i = 0;
>  	struct rte_cryptodev_asym_capability_idx idx;
> -	const struct rte_cryptodev_asymmetric_xform_capability *capa;
> +	const struct rte_cryptodev_asymmetric_capability *capa;
> 
>  	rte_cryptodev_info_get(dev_id, &dev_info);
>  	if (!(dev_info.feature_flags &
> @@ -1023,7 +1090,7 @@ test_capability(void)
>  		dev_capa = &(dev_info.capabilities[i]);
>  		if (dev_info.capabilities[i].op ==
>  				RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
> -			idx.type = dev_capa->asym.xform_capa.xform_type;
> +			idx.type = dev_capa->asym.xform_type;
> 
>  			capa = rte_cryptodev_asym_capability_get(dev_id,
>  				(const struct
> @@ -1386,10 +1453,11 @@ test_mod_inv(void)
>  	void *sess = NULL;
>  	int status = TEST_SUCCESS;
>  	struct rte_cryptodev_asym_capability_idx cap_idx;
> -	const struct rte_cryptodev_asymmetric_xform_capability *capability;
> +	const struct rte_cryptodev_asymmetric_capability *capability;
>  	uint8_t input[TEST_DATA_SIZE] = {0};
>  	int ret = 0;
>  	uint8_t result[sizeof(mod_p)] = { 0 };
> +	struct rte_crypto_mod_capability mod_capa = {0};
> 
>  	if (rte_cryptodev_asym_get_xform_enum(
>  		&modinv_xform.xform_type, "modinv") < 0) {
> @@ -1408,13 +1476,11 @@ test_mod_inv(void)
>  		return TEST_SKIPPED;
>  	}
> 
> -	if (rte_cryptodev_asym_xform_capability_check_modlen(
> -		capability,
> -		modinv_xform.modinv.modulus.length)) {
> -		RTE_LOG(ERR, USER1,
> -				 "Invalid MODULUS length specified\n");
> -				return TEST_SKIPPED;
> -		}
> +	mod_capa.max_mod_size = modinv_xform.modinv.modulus.length;
> +	if  (!rte_cryptodev_capa_check_mod(capability, mod_capa)) {
> +		RTE_LOG(ERR, USER1, "Invalid MODULUS length specified\n");
> +		return TEST_SKIPPED;
> +	}
> 
>  	ret = rte_cryptodev_asym_session_create(dev_id, &modinv_xform,
> sess_mpool, &sess);
>  	if (ret < 0) {
> @@ -1499,7 +1565,8 @@ test_mod_exp(void)
>  	void *sess = NULL;
>  	int status = TEST_SUCCESS;
>  	struct rte_cryptodev_asym_capability_idx cap_idx;
> -	const struct rte_cryptodev_asymmetric_xform_capability *capability;
> +	const struct rte_cryptodev_asymmetric_capability *capability;
> +	struct rte_crypto_mod_capability mod_capa = {0};
>  	uint8_t input[TEST_DATA_SIZE] = {0};
>  	int ret = 0;
>  	uint8_t result[sizeof(mod_p)] = { 0 };
> @@ -1522,12 +1589,11 @@ test_mod_exp(void)
>  		return TEST_SKIPPED;
>  	}
> 
> -	if (rte_cryptodev_asym_xform_capability_check_modlen(
> -			capability, modex_xform.modex.modulus.length)) {
> -		RTE_LOG(ERR, USER1,
> -				"Invalid MODULUS length specified\n");
> -				return TEST_SKIPPED;
> -		}
> +	mod_capa.max_mod_size = modex_xform.modex.modulus.length;
> +	if  (!rte_cryptodev_capa_check_mod(capability, mod_capa)) {
> +		RTE_LOG(ERR, USER1, "Invalid MODULUS length specified\n");
> +		return TEST_SKIPPED;
> +	}
> 
>  	/* Create op, create session, and process packets. 8< */
>  	op = rte_crypto_op_alloc(op_mpool,
> RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
> @@ -1785,6 +1851,8 @@ test_ecdsa_sign_verify(enum curve curve_id)
>  	struct rte_crypto_asym_xform xform;
>  	struct rte_crypto_asym_op *asym_op;
>  	struct rte_cryptodev_info dev_info;
> +	struct rte_cryptodev_asym_capability_idx idx;
> +	const struct rte_cryptodev_asymmetric_capability *capabilities;
>  	struct rte_crypto_op *op = NULL;
>  	int ret, status = TEST_SUCCESS;
> 
> @@ -1814,6 +1882,25 @@ test_ecdsa_sign_verify(enum curve curve_id)
> 
>  	rte_cryptodev_info_get(dev_id, &dev_info);
> 
> +	struct rte_crypto_ecdsa_capability capa = {
> +		.curves = RTE_BIT32(input_params.curve),
> +		.random_k = 0
> +	};
> +
> +	idx.type = RTE_CRYPTO_ASYM_XFORM_ECDSA;
> +	capabilities = rte_cryptodev_asym_capability_get(dev_id,
> +		(const struct
> +		rte_cryptodev_asym_capability_idx *) &idx);
> +
> +	if (capabilities == NULL) {
> +		status = TEST_SKIPPED;
> +		goto exit;
> +	}
> +	if (!rte_cryptodev_capa_check_ecdsa(capabilities, capa)) {
> +		status = TEST_SKIPPED;
> +		goto exit;
> +	}
> +
>  	/* Setup crypto op data structure */
>  	op = rte_crypto_op_alloc(op_mpool,
> RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
>  	if (op == NULL) {
> @@ -1962,6 +2049,8 @@ test_ecdsa_sign_verify_all_curve(void)
>  		status = test_ecdsa_sign_verify(curve_id);
>  		if (status == TEST_SUCCESS) {
>  			msg = "succeeded";
> +		} else if (status == TEST_SKIPPED) {
> +			continue;
>  		} else {
>  			msg = "failed";
>  			overall_status = status;
> @@ -1987,6 +2076,8 @@ test_ecpm(enum curve curve_id)
>  	struct rte_crypto_asym_xform xform;
>  	struct rte_crypto_asym_op *asym_op;
>  	struct rte_cryptodev_info dev_info;
> +	struct rte_cryptodev_asym_capability_idx idx;
> +	const struct rte_cryptodev_asymmetric_capability *capabilities;
>  	struct rte_crypto_op *op = NULL;
>  	int ret, status = TEST_SUCCESS;
> 
> @@ -2016,6 +2107,24 @@ test_ecpm(enum curve curve_id)
> 
>  	rte_cryptodev_info_get(dev_id, &dev_info);
> 
> +	struct rte_crypto_ecdsa_capability capa = {
> +		.curves = RTE_BIT32(input_params.curve)
> +	};
> +
> +	idx.type = RTE_CRYPTO_ASYM_XFORM_ECPM;
> +	capabilities = rte_cryptodev_asym_capability_get(dev_id,
> +		(const struct
> +		rte_cryptodev_asym_capability_idx *) &idx);
> +
> +	if (capabilities == NULL) {
> +		status = TEST_SKIPPED;
> +		goto exit;
> +	}
> +	if (!rte_cryptodev_capa_check_ecdsa(capabilities, capa)) {
> +		status = TEST_SKIPPED;
> +		goto exit;
> +	}
> +
>  	/* Setup crypto op data structure */
>  	op = rte_crypto_op_alloc(op_mpool,
> RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
>  	if (op == NULL) {
> @@ -2124,6 +2233,8 @@ test_ecpm_all_curve(void)
>  		status = test_ecpm(curve_id);
>  		if (status == TEST_SUCCESS) {
>  			msg = "succeeded";
> +		} else if (status == TEST_SKIPPED) {
> +			continue;
>  		} else {
>  			msg = "failed";
>  			overall_status = status;
> @@ -2162,7 +2273,12 @@ static struct unit_test_suite
> cryptodev_qat_asym_testsuite  = {
>  	.setup = testsuite_setup,
>  	.teardown = testsuite_teardown,
>  	.unit_test_cases = {
> +		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
> test_capability),
>  		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
> test_one_by_one),
> +		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
> +			     test_ecdsa_sign_verify_all_curve),
> +		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
> +				test_ecpm_all_curve),
>  		TEST_CASES_END() /**< NULL terminate unit test array */
>  	}
>  };

I think patch need to be split for adding test app changes.


> diff --git a/app/test/test_event_crypto_adapter.c
> b/app/test/test_event_crypto_adapter.c
> index 2ecc7e2cea..9a62241371 100644
> --- a/app/test/test_event_crypto_adapter.c
> +++ b/app/test/test_event_crypto_adapter.c
> @@ -450,7 +450,7 @@ test_session_with_op_forward_mode(void)
>  static int
>  test_asym_op_forward_mode(uint8_t session_less)
>  {
> -	const struct rte_cryptodev_asymmetric_xform_capability *capability;
> +	const struct rte_cryptodev_asymmetric_capability *capability;
>  	struct rte_cryptodev_asym_capability_idx cap_idx;
>  	struct rte_crypto_asym_xform xform_tc;
>  	union rte_event_crypto_metadata m_data;
> @@ -458,6 +458,7 @@ test_asym_op_forward_mode(uint8_t session_less)
>  	struct rte_crypto_asym_op *asym_op;
>  	struct rte_crypto_op *op;
>  	uint8_t input[4096] = {0};
> +	struct rte_crypto_mod_capability mod_capa = {0};
>  	uint8_t *result = NULL;
>  	struct rte_event ev;
>  	void *sess = NULL;
> @@ -503,8 +504,9 @@ test_asym_op_forward_mode(uint8_t session_less)
>  	asym_op->modex.base.length = modex_test_case.base.len;
>  	asym_op->modex.result.data = result;
>  	asym_op->modex.result.length = modex_test_case.result_len;
> -	if (rte_cryptodev_asym_xform_capability_check_modlen(capability,
> -			xform_tc.modex.modulus.length)) {
> +
> +	mod_capa.max_mod_size = xform_tc.modex.modulus.length;
> +	if  (!rte_cryptodev_capa_check_mod(capability, mod_capa)) {
>  		RTE_LOG(INFO, USER1,
>  			"line %u FAILED: %s", __LINE__,
>  			"Invalid MODULUS length specified");
> @@ -784,7 +786,7 @@ test_session_with_op_new_mode(void)
>  static int
>  test_asym_op_new_mode(uint8_t session_less)
>  {
> -	const struct rte_cryptodev_asymmetric_xform_capability *capability;
> +	const struct rte_cryptodev_asymmetric_capability *capability;
>  	struct rte_cryptodev_asym_capability_idx cap_idx;
>  	struct rte_crypto_asym_xform xform_tc;
>  	union rte_event_crypto_metadata m_data;
> @@ -792,6 +794,7 @@ test_asym_op_new_mode(uint8_t session_less)
>  	struct rte_crypto_asym_op *asym_op;
>  	struct rte_crypto_op *op;
>  	uint8_t input[4096] = {0};
> +	struct rte_crypto_mod_capability mod_capa = {0};

Can you move this above to maintain reverse Xmas tree?

>  	uint8_t *result = NULL;
>  	void *sess = NULL;
>  	uint32_t cap;
> @@ -835,8 +838,9 @@ test_asym_op_new_mode(uint8_t session_less)
>  	asym_op->modex.base.length = modex_test_case.base.len;
>  	asym_op->modex.result.data = result;
>  	asym_op->modex.result.length = modex_test_case.result_len;
> -	if (rte_cryptodev_asym_xform_capability_check_modlen(capability,
> -			xform_tc.modex.modulus.length)) {
> +
> +	mod_capa.max_mod_size = xform_tc.modex.modulus.length;
> +	if  (!rte_cryptodev_capa_check_mod(capability, mod_capa)) {
>  		RTE_LOG(INFO, USER1,
>  			"line %u FAILED: %s", __LINE__,
>  			"Invalid MODULUS length specified");
> diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> index 16ec5e15eb..e734fc2a69 100644
> --- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> +++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> @@ -7,6 +7,7 @@
>  #include <rte_common.h>
>  #include <rte_malloc.h>
>  #include <cryptodev_pmd.h>
> +#include <rte_bitops.h>
> 
>  #include "openssl_pmd_private.h"
>  #include "compat.h"
> @@ -470,103 +471,82 @@ static const struct rte_cryptodev_capabilities
> openssl_pmd_capabilities[] = {
>  			}, }
>  		}, }
>  	},
> -	{	/* RSA */
> +	{	/* Modular exponentiation */
>  		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
>  		{.asym = {
> -			.xform_capa = {
> -				.xform_type =
> RTE_CRYPTO_ASYM_XFORM_RSA,
> -				.op_types = ((1 <<
> RTE_CRYPTO_ASYM_OP_SIGN) |
> -					(1 << RTE_CRYPTO_ASYM_OP_VERIFY)
> |
> -					(1 <<
> RTE_CRYPTO_ASYM_OP_ENCRYPT) |
> -					(1 <<
> RTE_CRYPTO_ASYM_OP_DECRYPT)),
> -				{
> -				.modlen = {
> -				/* min length is based on openssl rsa keygen */
> -				.min = 30,
> -				/* value 0 symbolizes no limit on max length */
> -				.max = 0,
> -				.increment = 1
> -				}, }
> +			.xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX,
> +			.mod = {
> +				.max_mod_size = 0
> +				}
>  			}
> -		},
>  		}
>  	},
> -	{	/* modexp */
> +	{	/* Modular multiplicative inverse */
>  		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
>  		{.asym = {
> -			.xform_capa = {
> -				.xform_type =
> RTE_CRYPTO_ASYM_XFORM_MODEX,
> -				.op_types = 0,
> -				{
> -				.modlen = {
> -				/* value 0 symbolizes no limit on min length */
> -				.min = 0,
> -				/* value 0 symbolizes no limit on max length */
> -				.max = 0,
> -				.increment = 1
> -				}, }
> +			.xform_type = RTE_CRYPTO_ASYM_XFORM_MODINV,
> +			.mod = {
> +				.max_mod_size = 0
> +				}
>  			}
> -		},
>  		}
>  	},
> -	{	/* modinv */
> +	{	/* RSA */
>  		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
>  		{.asym = {
> -			.xform_capa = {
> -				.xform_type =
> RTE_CRYPTO_ASYM_XFORM_MODINV,
> -				.op_types = 0,
> -				{
> -				.modlen = {
> -				/* value 0 symbolizes no limit on min length */
> -				.min = 0,
> -				/* value 0 symbolizes no limit on max length */
> -				.max = 0,
> -				.increment = 1
> -				}, }
> +			.xform_type = RTE_CRYPTO_ASYM_XFORM_RSA,
> +			.rsa = {
> +				.padding =
> +
> 	RTE_BIT32(RTE_CRYPTO_RSA_PADDING_NONE) |
> +
> 	RTE_BIT32(RTE_CRYPTO_RSA_PADDING_PKCS1_5),
> +				.hash =
> +					RTE_BIT32(RTE_CRYPTO_AUTH_MD5)
> |
> +					RTE_BIT32(RTE_CRYPTO_AUTH_SHA1)
> 	|
> +
> 	RTE_BIT32(RTE_CRYPTO_AUTH_SHA224) |
> +
> 	RTE_BIT32(RTE_CRYPTO_AUTH_SHA256) |
> +
> 	RTE_BIT32(RTE_CRYPTO_AUTH_SHA384) |
> +
> 	RTE_BIT32(RTE_CRYPTO_AUTH_SHA512),
> +				.max_key_size = 0
> +				}
>  			}
> -		},
>  		}
>  	},
> -	{	/* dh */
> +	{	/* Diffie-Hellman */
>  		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
>  		{.asym = {
> -			.xform_capa = {
> -				.xform_type =
> RTE_CRYPTO_ASYM_XFORM_DH,
> -				.op_types =
> -
> 	((1<<RTE_CRYPTO_ASYM_KE_PRIVATE_KEY_GENERATE) |
> -				(1 <<
> RTE_CRYPTO_ASYM_KE_PUBLIC_KEY_GENERATE |
> -				(1 <<
> -
> 	RTE_CRYPTO_ASYM_KE_SHARED_SECRET_COMPUTE))),
> -				{
> -				.modlen = {
> -				/* value 0 symbolizes no limit on min length */
> -				.min = 0,
> -				/* value 0 symbolizes no limit on max length */
> -				.max = 0,
> -				.increment = 1
> -				}, }
> +			.xform_type = RTE_CRYPTO_ASYM_XFORM_DH,
> +			.dh = {
> +				.max_group_size = 0,
> +				.priv_key_gen = 1
> +				}
>  			}
> -		},
>  		}
>  	},
> -	{	/* dsa */
> +	{	/* DSA */
>  		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
>  		{.asym = {
> -			.xform_capa = {
> -				.xform_type =
> RTE_CRYPTO_ASYM_XFORM_DSA,
> -				.op_types =
> -				((1<<RTE_CRYPTO_ASYM_OP_SIGN) |
> -				(1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
> -				{
> -				.modlen = {
> -				/* value 0 symbolizes no limit on min length */
> -				.min = 0,
> -				/* value 0 symbolizes no limit on max length */
> -				.max = 0,
> -				.increment = 1
> -				}, }
> +			.xform_type = RTE_CRYPTO_ASYM_XFORM_DSA,
> +			.dsa = {
> +				.max_key_size = 0,
> +				.random_k = 1
> +				}
> +			}
> +		}
> +	},
> +	{	/* ECDSA */
> +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> +		{.asym = {
> +			.xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA,
> +			.ecdsa = {
> +				.curves =
> +
> 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP192R1) |
> +
> 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP224R1) |
> +
> 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP256R1) |
> +
> 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP384R1) |
> +
> 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP521R1),
> +				.random_k = 1
> +				}
>  			}
> -		},
>  		}
>  	},
> 

Do not combine PMD changes for capabilities in cryptodev patch for new APIs.


> diff --git a/drivers/crypto/qat/dev/qat_asym_pmd_gen1.c
> b/drivers/crypto/qat/dev/qat_asym_pmd_gen1.c
> index 4499fdaf2d..d5144bca84 100644
> --- a/drivers/crypto/qat/dev/qat_asym_pmd_gen1.c
> +++ b/drivers/crypto/qat/dev/qat_asym_pmd_gen1.c
> @@ -28,16 +28,64 @@ struct rte_cryptodev_ops qat_asym_crypto_ops_gen1 =
> {
>  };
> 
>  static struct rte_cryptodev_capabilities qat_asym_crypto_caps_gen1[] = {
> -	QAT_ASYM_CAP(MODEX,
> -		0, 1, 512, 1),
> -	QAT_ASYM_CAP(MODINV,
> -		0, 1, 512, 1),
> -	QAT_ASYM_CAP(RSA,
> -			((1 << RTE_CRYPTO_ASYM_OP_SIGN) |
> -			(1 << RTE_CRYPTO_ASYM_OP_VERIFY) |
> -			(1 << RTE_CRYPTO_ASYM_OP_ENCRYPT) |
> -			(1 << RTE_CRYPTO_ASYM_OP_DECRYPT)),
> -			64, 512, 64),
> +	{	/* Modular exponentiation */
> +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> +		{.asym = {
> +			.xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX,
> +			.mod = {
> +				.max_mod_size = 4096
> +				}
> +			}
> +		}
> +	},
> +	{	/* Modular multiplicative inverse */
> +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> +		{.asym = {
> +			.xform_type = RTE_CRYPTO_ASYM_XFORM_MODINV,
> +			.mod = {
> +				.max_mod_size = 4096
> +				}
> +			}
> +		}
> +	},
> +	{	/* RSA */
> +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> +		{.asym = {
> +			.xform_type = RTE_CRYPTO_ASYM_XFORM_RSA,
> +			.rsa = {
> +				.padding =
> +
> 	RTE_BIT32(RTE_CRYPTO_RSA_PADDING_NONE),
> +				.hash = 0,
> +				.max_key_size = 4096
> +				}
> +			}
> +		}
> +	},
> +	{	/* ECDSA */
> +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> +		{.asym = {
> +			.xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA,
> +			.ecdsa = {
> +				.curves =
> +
> 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP256R1) |
> +
> 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP521R1),
> +				.random_k = 0
> +				}
> +			}
> +		}
> +	},
> +	{	/* ECPM */
> +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> +		{.asym = {
> +			.xform_type = RTE_CRYPTO_ASYM_XFORM_ECPM,
> +			.ecdsa = {
> +				.curves =
> +
> 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP256R1) |
> +
> 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP521R1)
> +				}
> +			}
> +		}
> +	},
>  	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
>  };
> 
> diff --git a/lib/cryptodev/rte_crypto_asym.h b/lib/cryptodev/rte_crypto_asym.h
> index d90a7a1957..41b22450d3 100644
> --- a/lib/cryptodev/rte_crypto_asym.h
> +++ b/lib/cryptodev/rte_crypto_asym.h
> @@ -41,6 +41,14 @@ rte_crypto_asym_ke_strings[];
>  extern const char *
>  rte_crypto_asym_op_strings[];
> 
> +/** RSA padding type name strings */
> +extern const char *
> +rte_crypto_asym_rsa_padding[];

rte_crypto_asym_rsa_padding_strings

> +
> +/** Elliptic curves name strings */
> +extern const char *
> +rte_crypto_curves_strings[];
> +
>  /**
>   * Buffer to hold crypto params required for asym operations.
>   *
> @@ -265,6 +273,46 @@ struct rte_crypto_rsa_padding {
>  	 */
>  };
> 
> +struct rte_crypto_mod_capability {
> +	uint16_t max_mod_size;
> +	/**< Maximum supported modulus size in bytes, 0 means no limit */
> +};
> +
> +struct rte_crypto_rsa_capability {
> +	uint32_t padding;
> +	/**< List of supported paddings */
How is this list supposed to work?
I believe this should be enum to specify a single value.
Driver can maintain a static array to list all supported ones.
And application can query if a particular capability which it intend to use
Is supported by the PMD.

> +	uint32_t hash;
> +	/**< List of supported hash functions */
Same comment here as well

> +	uint32_t max_key_size;
> +	/**< Maximum supported key size in bytes, 0 means no limit */
> +};
> +
> +struct rte_crypto_dh_capability {
> +	uint16_t max_group_size;
> +	/**< Maximum group  in bytes, 0 means no limit */
Maximum group size in bytes ...

> +	uint8_t priv_key_gen;
> +	/**< Does PMD supports private key generation generation */
Is it a flag? Please comment it properly.

> +};
> +
> +struct rte_crypto_dsa_capability {
> +	uint16_t max_key_size;
> +	/**< Maximum supported key size in bytes, 0 means no limit */
> +	uint8_t random_k;
> +	/**< Does PMD supports random 'k' generation */

Comments should not ask questions.

> +};
> +
> +struct rte_crypto_ecdsa_capability {
> +	uint64_t curves;
> +	/**< Supported elliptic curve ids */
Shouldn't this also be enum?

> +	uint8_t random_k;
> +	/**< Does PMD supports random 'k' generation */

Same comment as above.
> +};
> +
> +struct rte_crypto_ecpm_capability {
> +	uint64_t curves;
> +	/**< Supported elliptic curve ids */

Enum??

> +};
> +
>  /**
>   * Asymmetric RSA transform data
>   *
> diff --git a/lib/cryptodev/rte_cryptodev.c b/lib/cryptodev/rte_cryptodev.c
> index 57ee6b3f07..b1ad1112fe 100644
> --- a/lib/cryptodev/rte_cryptodev.c
> +++ b/lib/cryptodev/rte_cryptodev.c
> @@ -190,6 +190,27 @@ const char *rte_crypto_asym_ke_strings[] = {
>  };
> 
>  /**
> + * RSA padding string identifiers
> + */
> +const char *rte_crypto_asym_rsa_padding[] = {
> +	[RTE_CRYPTO_RSA_PADDING_NONE] =
> "RTE_CRYPTO_RSA_PADDING_NONE",
> +	[RTE_CRYPTO_RSA_PADDING_PKCS1_5] =
> "RTE_CRYPTO_RSA_PADDING_PKCS1_5",
> +	[RTE_CRYPTO_RSA_PADDING_OAEP] =
> "RTE_CRYPTO_RSA_PADDING_OAEP",
> +	[RTE_CRYPTO_RSA_PADDING_PSS] =
> "RTE_CRYPTO_RSA_PADDING_PSS"
> +};
> +
> +/**
> + * Elliptic curves string identifiers
> + */
> +const char *rte_crypto_curves_strings[] = {
> +	[RTE_CRYPTO_EC_GROUP_SECP192R1] =
> "RTE_CRYPTO_EC_GROUP_SECP192R1",
> +	[RTE_CRYPTO_EC_GROUP_SECP224R1] =
> "RTE_CRYPTO_EC_GROUP_SECP224R1",
> +	[RTE_CRYPTO_EC_GROUP_SECP256R1] =
> "RTE_CRYPTO_EC_GROUP_SECP256R1",
> +	[RTE_CRYPTO_EC_GROUP_SECP384R1] =
> "RTE_CRYPTO_EC_GROUP_SECP384R1",
> +	[RTE_CRYPTO_EC_GROUP_SECP521R1] =
> "RTE_CRYPTO_EC_GROUP_SECP521R1",
> +};
> +
> +/**
>   * The private data structure stored in the sym session mempool private data.
>   */
>  struct rte_cryptodev_sym_session_pool_private_data {
> @@ -347,7 +368,7 @@ param_range_check(uint16_t size, const struct
> rte_crypto_param_range *range)
>  	return -1;
>  }
> 
> -const struct rte_cryptodev_asymmetric_xform_capability *
> +const struct rte_cryptodev_asymmetric_capability *
>  rte_cryptodev_asym_capability_get(uint8_t dev_id,
>  		const struct rte_cryptodev_asym_capability_idx *idx)
>  {
> @@ -363,8 +384,8 @@ rte_cryptodev_asym_capability_get(uint8_t dev_id,
>  		if (capability->op != RTE_CRYPTO_OP_TYPE_ASYMMETRIC)
>  			continue;
> 
> -		if (capability->asym.xform_capa.xform_type == idx->type)
> -			return &capability->asym.xform_capa;
> +		if (capability->asym.xform_type == idx->type)
> +			return &capability->asym;
>  	}
>  	return NULL;
>  };
> @@ -456,6 +477,59 @@ rte_cryptodev_asym_xform_capability_check_modlen(
>  	return 0;
>  }
> 
> +int
> +rte_cryptodev_capa_check_mod(

API name should be rte_cryptodev_mod_capa_check
Verb should come in the end.
Fix other APIs also.

> +	const struct rte_cryptodev_asymmetric_capability *capa,
> +	struct rte_crypto_mod_capability mod)
> +{
> +	if (capa->mod.max_mod_size == 0)
> +		return 1;
> +
> +	if (mod.max_mod_size <= capa->mod.max_mod_size)
> +		return 1;
> +	else
> +		return 0;
> +}
> +
> +int
> +rte_cryptodev_capa_check_rsa(
> +	const struct rte_cryptodev_asymmetric_capability *capa,
> +	struct rte_crypto_rsa_capability rsa)
> +{
> +	if (rsa.padding != (capa->rsa.padding & rsa.padding))
> +		return 0;
> +	if (rsa.hash != (capa->rsa.hash & rsa.hash))
> +		return 0;
> +	if (capa->rsa.max_key_size == 0)
> +		return 1;
> +	if (rsa.max_key_size <= capa->rsa.max_key_size)
> +		return 1;
> +	else
> +		return 0;
> +}

Can we have something similar to symmetric crypto/rte_security capabilities?

> +
> +int
> +rte_cryptodev_capa_check_ecdsa(
> +	const struct rte_cryptodev_asymmetric_capability *capa,
> +	struct rte_crypto_ecdsa_capability ecdsa)
> +{
> +	if (ecdsa.curves != (capa->ecdsa.curves & ecdsa.curves))
> +		return 0;
> +	if (ecdsa.random_k == 1 && capa->ecdsa.random_k == 0)
> +		return 0;
> +	return 1;
> +}
> +
> +int
> +rte_cryptodev_capa_check_ecpm(
> +	const struct rte_cryptodev_asymmetric_capability *capa,
> +	struct rte_crypto_ecpm_capability ecpm)
> +{
> +	if (ecpm.curves != (capa->ecpm.curves & ecpm.curves))
> +		return 0;
> +	return 1;
> +}
> +
>  /* spinlock for crypto device enq callbacks */
>  static rte_spinlock_t rte_cryptodev_callback_lock =
> RTE_SPINLOCK_INITIALIZER;
> 
> diff --git a/lib/cryptodev/rte_cryptodev.h b/lib/cryptodev/rte_cryptodev.h
> index 2c2c2edeb7..6c5bd819b2 100644
> --- a/lib/cryptodev/rte_cryptodev.h
> +++ b/lib/cryptodev/rte_cryptodev.h
> @@ -184,6 +184,19 @@ struct rte_cryptodev_asymmetric_xform_capability {
>   *
>   */
>  struct rte_cryptodev_asymmetric_capability {
> +	enum rte_crypto_asym_xform_type xform_type;
> +	/**< Asymmetric transform type */
> +	uint32_t op_types;
> +	/**< bitmask for supported rte_crypto_asym_op_type */
> +	union {
> +		struct rte_crypto_mod_capability mod;
> +		struct rte_crypto_rsa_capability rsa;
> +		struct rte_crypto_dh_capability dh;
> +		struct rte_crypto_dsa_capability dsa;
> +		struct rte_crypto_ecdsa_capability ecdsa;
> +		struct rte_crypto_ecpm_capability ecpm;
> +	};
> +
>  	struct rte_cryptodev_asymmetric_xform_capability xform_capa;
>  };
> 
> @@ -247,7 +260,7 @@ rte_cryptodev_sym_capability_get(uint8_t dev_id,
>   *   - Return NULL if the capability not exist.
>   */
>  __rte_experimental
> -const struct rte_cryptodev_asymmetric_xform_capability *
> +const struct rte_cryptodev_asymmetric_capability *
>  rte_cryptodev_asym_capability_get(uint8_t dev_id,
>  		const struct rte_cryptodev_asym_capability_idx *idx);
> 
> @@ -339,6 +352,66 @@ rte_cryptodev_asym_xform_capability_check_modlen(
>  		uint16_t modlen);
> 
>  /**
> + * Check if requested Modexp features are supported
> + *
> + * @param	capability	Description of the asymmetric crypto
> capability.
> + * @param	mod		Modexp requested capability.
> + *
> + * @return
> + *   - Return 1 if the parameters are in range of the capability.
> + *   - Return 0 if the parameters are out of range of the capability.
> + */
> +__rte_experimental
> +int
> +rte_cryptodev_capa_check_mod(
> +	const struct rte_cryptodev_asymmetric_capability *capa,
> +	struct rte_crypto_mod_capability mod);
> +/**
> + * Check if requested RSA features are supported
> + *
> + * @param	capability	Description of the asymmetric crypto
> capability.
> + * @param	rsa		RSA requested capability.
> + *
> + * @return
> + *   - Return 1 if the parameters are in range of the capability.
> + *   - Return 0 if the parameters are out of range of the capability.
> + */
> +__rte_experimental
> +int
> +rte_cryptodev_capa_check_rsa(
> +	const struct rte_cryptodev_asymmetric_capability *capa,
> +	struct rte_crypto_rsa_capability rsa);
> +/**
> + * Check if requested ECDSA features are supported
> + *
> + * @param	capability	Description of the asymmetric crypto
> capability.
> + * @param	ecdsa		ECDSA requested capability.
> + *
> + * @return
> + *   - Return 1 if the parameters are in range of the capability.
> + *   - Return 0 if the parameters are out of range of the capability.
> + */
> +__rte_experimental
> +int
> +rte_cryptodev_capa_check_ecdsa(
> +	const struct rte_cryptodev_asymmetric_capability *capa,
> +	struct rte_crypto_ecdsa_capability ecdsa);
> +/**
> + * Check if requested ECPM features are supported
> + *
> + * @param	capability	Description of the asymmetric crypto
> capability.
> + * @param	ecpm		ECPM requested capability.
> + *
> + * @return
> + *   - Return 1 if the parameters are in range of the capability.
> + *   - Return 0 if the parameters are out of range of the capability.
> + */
> +__rte_experimental
> +int
> +rte_cryptodev_capa_check_ecpm(
> +	const struct rte_cryptodev_asymmetric_capability *capa,
> +	struct rte_crypto_ecpm_capability ecpm);
> +/**
>   * Provide the cipher algorithm enum, given an algorithm string
>   *
>   * @param	algo_enum	A pointer to the cipher algorithm
> diff --git a/lib/cryptodev/version.map b/lib/cryptodev/version.map
> index f0abfaa47d..4d93b9a947 100644
> --- a/lib/cryptodev/version.map
> +++ b/lib/cryptodev/version.map
> @@ -108,6 +108,10 @@ EXPERIMENTAL {
> 
>  	#added in 22.07
>  	rte_cryptodev_session_event_mdata_set;
> +	rte_cryptodev_capa_check_mod;
> +	rte_cryptodev_capa_check_rsa;
> +	rte_cryptodev_capa_check_ecdsa;
> +	rte_cryptodev_capa_check_ecpm;
>  };
> 
>  INTERNAL {
> --
> 2.13.6
  
Arkadiusz Kusztal May 26, 2022, 2:19 p.m. UTC | #2
> -----Original Message-----
> From: Akhil Goyal <gakhil@marvell.com>
> Sent: Thursday, May 26, 2022 2:54 PM
> To: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>; dev@dpdk.org
> Cc: Zhang, Roy Fan <roy.fan.zhang@intel.com>
> Subject: RE: [EXT] [PATCH v2 14/14] cryptodev: add asym algorithms capabilities
> 
> > - Added asymmetric crypto algorithm specific capability struct.
> > Included fields like random number capability, padding flags etc.
> >
> > Signed-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
> > ---
> >  app/test-crypto-perf/main.c                  |  12 +-
> >  app/test-eventdev/test_perf_common.c         |   2 +-
> >  app/test/test_cryptodev_asym.c               | 210 +++++++++++++++++++++------
> >  app/test/test_event_crypto_adapter.c         |  16 +-
> >  drivers/crypto/openssl/rte_openssl_pmd_ops.c | 128 +++++++---------
> >  drivers/crypto/qat/dev/qat_asym_pmd_gen1.c   |  68 +++++++--
> >  lib/cryptodev/rte_crypto_asym.h              |  48 ++++++
> >  lib/cryptodev/rte_cryptodev.c                |  80 +++++++++-
> >  lib/cryptodev/rte_cryptodev.h                |  75 +++++++++-
> >  lib/cryptodev/version.map                    |   4 +
> >  10 files changed, 495 insertions(+), 148 deletions(-)
> 
> This would also need a change in documentation.
> 
> >
> > diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
> > index 17e30a8e74..f8a4c9cdcf 100644
> > --- a/app/test-crypto-perf/main.c
> > +++ b/app/test-crypto-perf/main.c
> > @@ -364,8 +364,8 @@ cperf_verify_devices_capabilities(struct
> > cperf_options *opts,
> >  	struct rte_cryptodev_sym_capability_idx cap_idx;
> >  	const struct rte_cryptodev_symmetric_capability *capability;
> >  	struct rte_cryptodev_asym_capability_idx asym_cap_idx;
> > -	const struct rte_cryptodev_asymmetric_xform_capability
> > *asym_capability;
> > -
> > +	const struct rte_cryptodev_asymmetric_capability *asym_capability;
> > +	struct rte_crypto_mod_capability mod_capa = {0};
> >
> >  	uint8_t i, cdev_id;
> >  	int ret;
> > @@ -381,11 +381,11 @@ cperf_verify_devices_capabilities(struct
> > cperf_options *opts,
> >  			if (asym_capability == NULL)
> >  				return -1;
> >
> > -			ret =
> > rte_cryptodev_asym_xform_capability_check_modlen(
> > -				asym_capability, opts->modex_data-
> > >modulus.len);
> > -			if (ret != 0)
> > +			mod_capa.max_mod_size = opts->modex_data-
> > >modulus.len;
> > +			ret = rte_cryptodev_capa_check_mod(asym_capability,
> > +						mod_capa);
> > +			if (ret == 0)
> >  				return ret;
> > -
> >  		}
> >
> >  		if (opts->op_type == CPERF_AUTH_ONLY || diff --git
> > a/app/test-eventdev/test_perf_common.c b/app/test-
> > eventdev/test_perf_common.c index b41785492e..ac8e6410ab 100644
> > --- a/app/test-eventdev/test_perf_common.c
> > +++ b/app/test-eventdev/test_perf_common.c
> > @@ -846,7 +846,7 @@ cryptodev_sym_sess_create(struct prod_data *p,
> > struct test_perf *t)  static void *  cryptodev_asym_sess_create(struct
> > prod_data *p, struct test_perf *t)  {
> > -	const struct rte_cryptodev_asymmetric_xform_capability *capability;
> > +	const struct rte_cryptodev_asymmetric_capability *capability;
> >  	struct rte_cryptodev_asym_capability_idx cap_idx;
> >  	struct rte_crypto_asym_xform xform;
> >  	void *sess;
> > diff --git a/app/test/test_cryptodev_asym.c
> > b/app/test/test_cryptodev_asym.c index 072dbb30f4..c531265642 100644
> > --- a/app/test/test_cryptodev_asym.c
> > +++ b/app/test/test_cryptodev_asym.c
> > @@ -311,10 +311,11 @@ test_cryptodev_asym_op(struct
> > crypto_testsuite_params_asym *ts_params,
> >  	struct rte_crypto_asym_xform xform_tc;
> >  	void *sess = NULL;
> >  	struct rte_cryptodev_asym_capability_idx cap_idx;
> > -	const struct rte_cryptodev_asymmetric_xform_capability *capability;
> > +	const struct rte_cryptodev_asymmetric_capability *capability;
> >  	uint8_t dev_id = ts_params->valid_devs[0];
> >  	uint8_t input[TEST_DATA_SIZE] = {0};
> >  	uint8_t *result = NULL;
> > +	struct rte_crypto_mod_capability mod_capa = {0};
> >
> >  	int ret, status = TEST_SUCCESS;
> >
> > @@ -358,8 +359,10 @@ test_cryptodev_asym_op(struct
> > crypto_testsuite_params_asym *ts_params,
> >  		asym_op->modex.base.length = data_tc->modex.base.len;
> >  		asym_op->modex.result.data = result;
> >  		asym_op->modex.result.length = data_tc->modex.result_len;
> > -		if
> > (rte_cryptodev_asym_xform_capability_check_modlen(capability,
> > -				xform_tc.modex.modulus.length)) {
> > +
> > +		mod_capa.max_mod_size = xform_tc.modex.modulus.length;
> > +		if  (!rte_cryptodev_capa_check_mod(capability,
> > +			mod_capa)) {
> >  			snprintf(test_msg, ASYM_TEST_MSG_LEN,
> >  				"line %u "
> >  				"FAILED: %s", __LINE__,
> > @@ -378,8 +381,10 @@ test_cryptodev_asym_op(struct
> > crypto_testsuite_params_asym *ts_params,
> >  		asym_op->modinv.base.length = data_tc->modinv.base.len;
> >  		asym_op->modinv.result.data = result;
> >  		asym_op->modinv.result.length = data_tc->modinv.result_len;
> > -		if
> > (rte_cryptodev_asym_xform_capability_check_modlen(capability,
> > -				xform_tc.modinv.modulus.length)) {
> > +
> > +		mod_capa.max_mod_size = xform_tc.modinv.modulus.length;
> > +		if  (!rte_cryptodev_capa_check_mod(capability,
> > +			mod_capa)) {
> >  			snprintf(test_msg, ASYM_TEST_MSG_LEN,
> >  				"line %u "
> >  				"FAILED: %s", __LINE__,
> > @@ -963,38 +968,100 @@ ut_teardown_asym(void)
> >  	rte_cryptodev_stop(ts_params->valid_devs[0]);
> >  }
> >
> > -static inline void print_asym_capa(
> > -		const struct rte_cryptodev_asymmetric_xform_capability
> > *capa)
> > +static void
> > +print_rsa_capability(
> > +	const struct rte_cryptodev_asymmetric_capability *capa)
> >  {
> >  	int i = 0;
> >
> > +	printf("\nSupported paddings:");
> > +	for (; i < 32; i++) {
> > +		if (capa->rsa.padding & RTE_BIT32(i))
> > +			printf("\n - %s", rte_crypto_asym_rsa_padding[i]);
> > +	}
> > +	printf("\nSupported hash functions:");
> > +	for (i = 0; i < 32; i++) {
> > +		if (capa->rsa.hash & RTE_BIT32(i))
> > +			printf("\n - %s", rte_crypto_auth_algorithm_strings[i]);
> > +	}
> > +	printf("\nMaximum key size: ");
> > +	if (capa->rsa.max_key_size == 0)
> > +		printf("Unlimited");
> > +	else
> > +		printf("%hu", capa->rsa.max_key_size); }
> > +
> > +static void
> > +print_supported_curves(uint64_t curves) {
> > +	int i = 0;
> > +
> > +	printf("\nSupported elliptic curves:");
> > +	for (; i < 64; i++) {
> > +		if (curves & RTE_BIT64(i))
> > +			printf("\n - %s", rte_crypto_curves_strings[i]);
> > +	}
> > +}
> > +
> > +static inline void print_asym_capa(
> > +		const struct rte_cryptodev_asymmetric_capability *capa) {
> >  	printf("\nxform type: %s\n===================\n",
> >  			rte_crypto_asym_xform_strings[capa->xform_type]);
> > -	printf("operation supported -");
> >
> > -	for (i = 0; i < RTE_CRYPTO_ASYM_OP_LIST_END; i++) {
> > -		/* check supported operations */
> > -		if (rte_cryptodev_asym_xform_capability_check_optype(capa,
> > i))
> > -			printf(" %s",
> > -					rte_crypto_asym_op_strings[i]);
> > -		}
> > -		switch (capa->xform_type) {
> > -		case RTE_CRYPTO_ASYM_XFORM_RSA:
> > -		case RTE_CRYPTO_ASYM_XFORM_MODINV:
> > -		case RTE_CRYPTO_ASYM_XFORM_MODEX:
> > -		case RTE_CRYPTO_ASYM_XFORM_DH:
> > -		case RTE_CRYPTO_ASYM_XFORM_DSA:
> > -			printf(" modlen: min %d max %d increment %d",
> > -					capa->modlen.min,
> > -					capa->modlen.max,
> > -					capa->modlen.increment);
> > +	switch (capa->xform_type) {
> > +	case RTE_CRYPTO_ASYM_XFORM_MODEX:
> > +	case RTE_CRYPTO_ASYM_XFORM_MODINV:
> > +		printf("Maximum size of modulus: ");
> > +		if (capa->mod.max_mod_size == 0)
> > +			printf("Unlimited");
> > +		else
> > +			printf("%hu", capa->mod.max_mod_size);
> >  		break;
> > -		case RTE_CRYPTO_ASYM_XFORM_ECDSA:
> > -		case RTE_CRYPTO_ASYM_XFORM_ECPM:
> > -		default:
> > -			break;
> > -		}
> > -		printf("\n");
> > +	case RTE_CRYPTO_ASYM_XFORM_RSA:
> > +		print_rsa_capability(capa);
> > +		break;
> > +	case RTE_CRYPTO_ASYM_XFORM_DH:
> 
> ECDH?? I hope it will be added once it is tested in this app.
> 
> > +		printf("Maximum group size: ");
> > +		if (capa->dh.max_group_size == 0)
> > +			printf("Unlimited");
> > +		else
> > +			printf("%hu", capa->dh.max_group_size);
> > +		printf("\nSupport for private key generation: ");
> > +		if (capa->dh.priv_key_gen)
> > +			printf("Yes");
> > +		else
> > +			printf("No");
> > +		break;
> > +	case RTE_CRYPTO_ASYM_XFORM_DSA:
> > +		printf("Maximum key size: ");
> > +		if (capa->dsa.max_key_size == 0)
> > +			printf("Unlimited");
> > +		else
> > +			printf("%hu", capa->dsa.max_key_size);
> > +		printf("\nSupport for random 'k' generation: ");
> > +		if (capa->dsa.random_k)
> > +			printf("Yes");
> > +		else
> > +			printf("No");
> > +		break;
> > +
> > +		break;
> > +	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
> > +		print_supported_curves(capa->ecdsa.curves);
> > +		printf("\nSupport for random 'k' generation: ");
> > +		if (capa->ecdsa.random_k)
> > +			printf("Yes");
> > +		else
> > +			printf("No");
> > +		break;
> > +	case RTE_CRYPTO_ASYM_XFORM_ECPM:
> > +		print_supported_curves(capa->ecpm.curves);
> > +		break;
> > +	default:
> > +		break;
> > +	}
> > +	printf("\n");
> >  }
> >
> >  static int
> > @@ -1006,7 +1073,7 @@ test_capability(void)
> >  	const struct rte_cryptodev_capabilities *dev_capa;
> >  	int i = 0;
> >  	struct rte_cryptodev_asym_capability_idx idx;
> > -	const struct rte_cryptodev_asymmetric_xform_capability *capa;
> > +	const struct rte_cryptodev_asymmetric_capability *capa;
> >
> >  	rte_cryptodev_info_get(dev_id, &dev_info);
> >  	if (!(dev_info.feature_flags &
> > @@ -1023,7 +1090,7 @@ test_capability(void)
> >  		dev_capa = &(dev_info.capabilities[i]);
> >  		if (dev_info.capabilities[i].op ==
> >  				RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
> > -			idx.type = dev_capa->asym.xform_capa.xform_type;
> > +			idx.type = dev_capa->asym.xform_type;
> >
> >  			capa = rte_cryptodev_asym_capability_get(dev_id,
> >  				(const struct
> > @@ -1386,10 +1453,11 @@ test_mod_inv(void)
> >  	void *sess = NULL;
> >  	int status = TEST_SUCCESS;
> >  	struct rte_cryptodev_asym_capability_idx cap_idx;
> > -	const struct rte_cryptodev_asymmetric_xform_capability *capability;
> > +	const struct rte_cryptodev_asymmetric_capability *capability;
> >  	uint8_t input[TEST_DATA_SIZE] = {0};
> >  	int ret = 0;
> >  	uint8_t result[sizeof(mod_p)] = { 0 };
> > +	struct rte_crypto_mod_capability mod_capa = {0};
> >
> >  	if (rte_cryptodev_asym_get_xform_enum(
> >  		&modinv_xform.xform_type, "modinv") < 0) { @@ -1408,13
> +1476,11 @@
> > test_mod_inv(void)
> >  		return TEST_SKIPPED;
> >  	}
> >
> > -	if (rte_cryptodev_asym_xform_capability_check_modlen(
> > -		capability,
> > -		modinv_xform.modinv.modulus.length)) {
> > -		RTE_LOG(ERR, USER1,
> > -				 "Invalid MODULUS length specified\n");
> > -				return TEST_SKIPPED;
> > -		}
> > +	mod_capa.max_mod_size = modinv_xform.modinv.modulus.length;
> > +	if  (!rte_cryptodev_capa_check_mod(capability, mod_capa)) {
> > +		RTE_LOG(ERR, USER1, "Invalid MODULUS length specified\n");
> > +		return TEST_SKIPPED;
> > +	}
> >
> >  	ret = rte_cryptodev_asym_session_create(dev_id, &modinv_xform,
> > sess_mpool, &sess);
> >  	if (ret < 0) {
> > @@ -1499,7 +1565,8 @@ test_mod_exp(void)
> >  	void *sess = NULL;
> >  	int status = TEST_SUCCESS;
> >  	struct rte_cryptodev_asym_capability_idx cap_idx;
> > -	const struct rte_cryptodev_asymmetric_xform_capability *capability;
> > +	const struct rte_cryptodev_asymmetric_capability *capability;
> > +	struct rte_crypto_mod_capability mod_capa = {0};
> >  	uint8_t input[TEST_DATA_SIZE] = {0};
> >  	int ret = 0;
> >  	uint8_t result[sizeof(mod_p)] = { 0 }; @@ -1522,12 +1589,11 @@
> > test_mod_exp(void)
> >  		return TEST_SKIPPED;
> >  	}
> >
> > -	if (rte_cryptodev_asym_xform_capability_check_modlen(
> > -			capability, modex_xform.modex.modulus.length)) {
> > -		RTE_LOG(ERR, USER1,
> > -				"Invalid MODULUS length specified\n");
> > -				return TEST_SKIPPED;
> > -		}
> > +	mod_capa.max_mod_size = modex_xform.modex.modulus.length;
> > +	if  (!rte_cryptodev_capa_check_mod(capability, mod_capa)) {
> > +		RTE_LOG(ERR, USER1, "Invalid MODULUS length specified\n");
> > +		return TEST_SKIPPED;
> > +	}
> >
> >  	/* Create op, create session, and process packets. 8< */
> >  	op = rte_crypto_op_alloc(op_mpool,
> > RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
> > @@ -1785,6 +1851,8 @@ test_ecdsa_sign_verify(enum curve curve_id)
> >  	struct rte_crypto_asym_xform xform;
> >  	struct rte_crypto_asym_op *asym_op;
> >  	struct rte_cryptodev_info dev_info;
> > +	struct rte_cryptodev_asym_capability_idx idx;
> > +	const struct rte_cryptodev_asymmetric_capability *capabilities;
> >  	struct rte_crypto_op *op = NULL;
> >  	int ret, status = TEST_SUCCESS;
> >
> > @@ -1814,6 +1882,25 @@ test_ecdsa_sign_verify(enum curve curve_id)
> >
> >  	rte_cryptodev_info_get(dev_id, &dev_info);
> >
> > +	struct rte_crypto_ecdsa_capability capa = {
> > +		.curves = RTE_BIT32(input_params.curve),
> > +		.random_k = 0
> > +	};
> > +
> > +	idx.type = RTE_CRYPTO_ASYM_XFORM_ECDSA;
> > +	capabilities = rte_cryptodev_asym_capability_get(dev_id,
> > +		(const struct
> > +		rte_cryptodev_asym_capability_idx *) &idx);
> > +
> > +	if (capabilities == NULL) {
> > +		status = TEST_SKIPPED;
> > +		goto exit;
> > +	}
> > +	if (!rte_cryptodev_capa_check_ecdsa(capabilities, capa)) {
> > +		status = TEST_SKIPPED;
> > +		goto exit;
> > +	}
> > +
> >  	/* Setup crypto op data structure */
> >  	op = rte_crypto_op_alloc(op_mpool,
> > RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
> >  	if (op == NULL) {
> > @@ -1962,6 +2049,8 @@ test_ecdsa_sign_verify_all_curve(void)
> >  		status = test_ecdsa_sign_verify(curve_id);
> >  		if (status == TEST_SUCCESS) {
> >  			msg = "succeeded";
> > +		} else if (status == TEST_SKIPPED) {
> > +			continue;
> >  		} else {
> >  			msg = "failed";
> >  			overall_status = status;
> > @@ -1987,6 +2076,8 @@ test_ecpm(enum curve curve_id)
> >  	struct rte_crypto_asym_xform xform;
> >  	struct rte_crypto_asym_op *asym_op;
> >  	struct rte_cryptodev_info dev_info;
> > +	struct rte_cryptodev_asym_capability_idx idx;
> > +	const struct rte_cryptodev_asymmetric_capability *capabilities;
> >  	struct rte_crypto_op *op = NULL;
> >  	int ret, status = TEST_SUCCESS;
> >
> > @@ -2016,6 +2107,24 @@ test_ecpm(enum curve curve_id)
> >
> >  	rte_cryptodev_info_get(dev_id, &dev_info);
> >
> > +	struct rte_crypto_ecdsa_capability capa = {
> > +		.curves = RTE_BIT32(input_params.curve)
> > +	};
> > +
> > +	idx.type = RTE_CRYPTO_ASYM_XFORM_ECPM;
> > +	capabilities = rte_cryptodev_asym_capability_get(dev_id,
> > +		(const struct
> > +		rte_cryptodev_asym_capability_idx *) &idx);
> > +
> > +	if (capabilities == NULL) {
> > +		status = TEST_SKIPPED;
> > +		goto exit;
> > +	}
> > +	if (!rte_cryptodev_capa_check_ecdsa(capabilities, capa)) {
> > +		status = TEST_SKIPPED;
> > +		goto exit;
> > +	}
> > +
> >  	/* Setup crypto op data structure */
> >  	op = rte_crypto_op_alloc(op_mpool,
> > RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
> >  	if (op == NULL) {
> > @@ -2124,6 +2233,8 @@ test_ecpm_all_curve(void)
> >  		status = test_ecpm(curve_id);
> >  		if (status == TEST_SUCCESS) {
> >  			msg = "succeeded";
> > +		} else if (status == TEST_SKIPPED) {
> > +			continue;
> >  		} else {
> >  			msg = "failed";
> >  			overall_status = status;
> > @@ -2162,7 +2273,12 @@ static struct unit_test_suite
> > cryptodev_qat_asym_testsuite  = {
> >  	.setup = testsuite_setup,
> >  	.teardown = testsuite_teardown,
> >  	.unit_test_cases = {
> > +		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
> > test_capability),
> >  		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
> test_one_by_one),
> > +		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
> > +			     test_ecdsa_sign_verify_all_curve),
> > +		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
> > +				test_ecpm_all_curve),
> >  		TEST_CASES_END() /**< NULL terminate unit test array */
> >  	}
> >  };
> 
> I think patch need to be split for adding test app changes.
> 
> 
> > diff --git a/app/test/test_event_crypto_adapter.c
> > b/app/test/test_event_crypto_adapter.c
> > index 2ecc7e2cea..9a62241371 100644
> > --- a/app/test/test_event_crypto_adapter.c
> > +++ b/app/test/test_event_crypto_adapter.c
> > @@ -450,7 +450,7 @@ test_session_with_op_forward_mode(void)
> >  static int
> >  test_asym_op_forward_mode(uint8_t session_less)  {
> > -	const struct rte_cryptodev_asymmetric_xform_capability *capability;
> > +	const struct rte_cryptodev_asymmetric_capability *capability;
> >  	struct rte_cryptodev_asym_capability_idx cap_idx;
> >  	struct rte_crypto_asym_xform xform_tc;
> >  	union rte_event_crypto_metadata m_data; @@ -458,6 +458,7 @@
> > test_asym_op_forward_mode(uint8_t session_less)
> >  	struct rte_crypto_asym_op *asym_op;
> >  	struct rte_crypto_op *op;
> >  	uint8_t input[4096] = {0};
> > +	struct rte_crypto_mod_capability mod_capa = {0};
> >  	uint8_t *result = NULL;
> >  	struct rte_event ev;
> >  	void *sess = NULL;
> > @@ -503,8 +504,9 @@ test_asym_op_forward_mode(uint8_t session_less)
> >  	asym_op->modex.base.length = modex_test_case.base.len;
> >  	asym_op->modex.result.data = result;
> >  	asym_op->modex.result.length = modex_test_case.result_len;
> > -	if (rte_cryptodev_asym_xform_capability_check_modlen(capability,
> > -			xform_tc.modex.modulus.length)) {
> > +
> > +	mod_capa.max_mod_size = xform_tc.modex.modulus.length;
> > +	if  (!rte_cryptodev_capa_check_mod(capability, mod_capa)) {
> >  		RTE_LOG(INFO, USER1,
> >  			"line %u FAILED: %s", __LINE__,
> >  			"Invalid MODULUS length specified"); @@ -784,7
> +786,7 @@
> > test_session_with_op_new_mode(void)
> >  static int
> >  test_asym_op_new_mode(uint8_t session_less)  {
> > -	const struct rte_cryptodev_asymmetric_xform_capability *capability;
> > +	const struct rte_cryptodev_asymmetric_capability *capability;
> >  	struct rte_cryptodev_asym_capability_idx cap_idx;
> >  	struct rte_crypto_asym_xform xform_tc;
> >  	union rte_event_crypto_metadata m_data; @@ -792,6 +794,7 @@
> > test_asym_op_new_mode(uint8_t session_less)
> >  	struct rte_crypto_asym_op *asym_op;
> >  	struct rte_crypto_op *op;
> >  	uint8_t input[4096] = {0};
> > +	struct rte_crypto_mod_capability mod_capa = {0};
> 
> Can you move this above to maintain reverse Xmas tree?
> 
> >  	uint8_t *result = NULL;
> >  	void *sess = NULL;
> >  	uint32_t cap;
> > @@ -835,8 +838,9 @@ test_asym_op_new_mode(uint8_t session_less)
> >  	asym_op->modex.base.length = modex_test_case.base.len;
> >  	asym_op->modex.result.data = result;
> >  	asym_op->modex.result.length = modex_test_case.result_len;
> > -	if (rte_cryptodev_asym_xform_capability_check_modlen(capability,
> > -			xform_tc.modex.modulus.length)) {
> > +
> > +	mod_capa.max_mod_size = xform_tc.modex.modulus.length;
> > +	if  (!rte_cryptodev_capa_check_mod(capability, mod_capa)) {
> >  		RTE_LOG(INFO, USER1,
> >  			"line %u FAILED: %s", __LINE__,
> >  			"Invalid MODULUS length specified"); diff --git
> > a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> > b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> > index 16ec5e15eb..e734fc2a69 100644
> > --- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> > +++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> > @@ -7,6 +7,7 @@
> >  #include <rte_common.h>
> >  #include <rte_malloc.h>
> >  #include <cryptodev_pmd.h>
> > +#include <rte_bitops.h>
> >
> >  #include "openssl_pmd_private.h"
> >  #include "compat.h"
> > @@ -470,103 +471,82 @@ static const struct rte_cryptodev_capabilities
> > openssl_pmd_capabilities[] = {
> >  			}, }
> >  		}, }
> >  	},
> > -	{	/* RSA */
> > +	{	/* Modular exponentiation */
> >  		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> >  		{.asym = {
> > -			.xform_capa = {
> > -				.xform_type =
> > RTE_CRYPTO_ASYM_XFORM_RSA,
> > -				.op_types = ((1 <<
> > RTE_CRYPTO_ASYM_OP_SIGN) |
> > -					(1 << RTE_CRYPTO_ASYM_OP_VERIFY)
> > |
> > -					(1 <<
> > RTE_CRYPTO_ASYM_OP_ENCRYPT) |
> > -					(1 <<
> > RTE_CRYPTO_ASYM_OP_DECRYPT)),
> > -				{
> > -				.modlen = {
> > -				/* min length is based on openssl rsa keygen */
> > -				.min = 30,
> > -				/* value 0 symbolizes no limit on max length */
> > -				.max = 0,
> > -				.increment = 1
> > -				}, }
> > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX,
> > +			.mod = {
> > +				.max_mod_size = 0
> > +				}
> >  			}
> > -		},
> >  		}
> >  	},
> > -	{	/* modexp */
> > +	{	/* Modular multiplicative inverse */
> >  		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> >  		{.asym = {
> > -			.xform_capa = {
> > -				.xform_type =
> > RTE_CRYPTO_ASYM_XFORM_MODEX,
> > -				.op_types = 0,
> > -				{
> > -				.modlen = {
> > -				/* value 0 symbolizes no limit on min length */
> > -				.min = 0,
> > -				/* value 0 symbolizes no limit on max length */
> > -				.max = 0,
> > -				.increment = 1
> > -				}, }
> > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_MODINV,
> > +			.mod = {
> > +				.max_mod_size = 0
> > +				}
> >  			}
> > -		},
> >  		}
> >  	},
> > -	{	/* modinv */
> > +	{	/* RSA */
> >  		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> >  		{.asym = {
> > -			.xform_capa = {
> > -				.xform_type =
> > RTE_CRYPTO_ASYM_XFORM_MODINV,
> > -				.op_types = 0,
> > -				{
> > -				.modlen = {
> > -				/* value 0 symbolizes no limit on min length */
> > -				.min = 0,
> > -				/* value 0 symbolizes no limit on max length */
> > -				.max = 0,
> > -				.increment = 1
> > -				}, }
> > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_RSA,
> > +			.rsa = {
> > +				.padding =
> > +
> > 	RTE_BIT32(RTE_CRYPTO_RSA_PADDING_NONE) |
> > +
> > 	RTE_BIT32(RTE_CRYPTO_RSA_PADDING_PKCS1_5),
> > +				.hash =
> > +					RTE_BIT32(RTE_CRYPTO_AUTH_MD5)
> > |
> > +					RTE_BIT32(RTE_CRYPTO_AUTH_SHA1)
> > 	|
> > +
> > 	RTE_BIT32(RTE_CRYPTO_AUTH_SHA224) |
> > +
> > 	RTE_BIT32(RTE_CRYPTO_AUTH_SHA256) |
> > +
> > 	RTE_BIT32(RTE_CRYPTO_AUTH_SHA384) |
> > +
> > 	RTE_BIT32(RTE_CRYPTO_AUTH_SHA512),
> > +				.max_key_size = 0
> > +				}
> >  			}
> > -		},
> >  		}
> >  	},
> > -	{	/* dh */
> > +	{	/* Diffie-Hellman */
> >  		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> >  		{.asym = {
> > -			.xform_capa = {
> > -				.xform_type =
> > RTE_CRYPTO_ASYM_XFORM_DH,
> > -				.op_types =
> > -
> > 	((1<<RTE_CRYPTO_ASYM_KE_PRIVATE_KEY_GENERATE) |
> > -				(1 <<
> > RTE_CRYPTO_ASYM_KE_PUBLIC_KEY_GENERATE |
> > -				(1 <<
> > -
> > 	RTE_CRYPTO_ASYM_KE_SHARED_SECRET_COMPUTE))),
> > -				{
> > -				.modlen = {
> > -				/* value 0 symbolizes no limit on min length */
> > -				.min = 0,
> > -				/* value 0 symbolizes no limit on max length */
> > -				.max = 0,
> > -				.increment = 1
> > -				}, }
> > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_DH,
> > +			.dh = {
> > +				.max_group_size = 0,
> > +				.priv_key_gen = 1
> > +				}
> >  			}
> > -		},
> >  		}
> >  	},
> > -	{	/* dsa */
> > +	{	/* DSA */
> >  		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> >  		{.asym = {
> > -			.xform_capa = {
> > -				.xform_type =
> > RTE_CRYPTO_ASYM_XFORM_DSA,
> > -				.op_types =
> > -				((1<<RTE_CRYPTO_ASYM_OP_SIGN) |
> > -				(1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
> > -				{
> > -				.modlen = {
> > -				/* value 0 symbolizes no limit on min length */
> > -				.min = 0,
> > -				/* value 0 symbolizes no limit on max length */
> > -				.max = 0,
> > -				.increment = 1
> > -				}, }
> > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_DSA,
> > +			.dsa = {
> > +				.max_key_size = 0,
> > +				.random_k = 1
> > +				}
> > +			}
> > +		}
> > +	},
> > +	{	/* ECDSA */
> > +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> > +		{.asym = {
> > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA,
> > +			.ecdsa = {
> > +				.curves =
> > +
> > 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP192R1) |
> > +
> > 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP224R1) |
> > +
> > 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP256R1) |
> > +
> > 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP384R1) |
> > +
> > 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP521R1),
> > +				.random_k = 1
> > +				}
> >  			}
> > -		},
> >  		}
> >  	},
> >
> 
> Do not combine PMD changes for capabilities in cryptodev patch for new APIs.
> 
> 
> > diff --git a/drivers/crypto/qat/dev/qat_asym_pmd_gen1.c
> > b/drivers/crypto/qat/dev/qat_asym_pmd_gen1.c
> > index 4499fdaf2d..d5144bca84 100644
> > --- a/drivers/crypto/qat/dev/qat_asym_pmd_gen1.c
> > +++ b/drivers/crypto/qat/dev/qat_asym_pmd_gen1.c
> > @@ -28,16 +28,64 @@ struct rte_cryptodev_ops qat_asym_crypto_ops_gen1
> > = {  };
> >
> >  static struct rte_cryptodev_capabilities qat_asym_crypto_caps_gen1[] = {
> > -	QAT_ASYM_CAP(MODEX,
> > -		0, 1, 512, 1),
> > -	QAT_ASYM_CAP(MODINV,
> > -		0, 1, 512, 1),
> > -	QAT_ASYM_CAP(RSA,
> > -			((1 << RTE_CRYPTO_ASYM_OP_SIGN) |
> > -			(1 << RTE_CRYPTO_ASYM_OP_VERIFY) |
> > -			(1 << RTE_CRYPTO_ASYM_OP_ENCRYPT) |
> > -			(1 << RTE_CRYPTO_ASYM_OP_DECRYPT)),
> > -			64, 512, 64),
> > +	{	/* Modular exponentiation */
> > +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> > +		{.asym = {
> > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX,
> > +			.mod = {
> > +				.max_mod_size = 4096
> > +				}
> > +			}
> > +		}
> > +	},
> > +	{	/* Modular multiplicative inverse */
> > +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> > +		{.asym = {
> > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_MODINV,
> > +			.mod = {
> > +				.max_mod_size = 4096
> > +				}
> > +			}
> > +		}
> > +	},
> > +	{	/* RSA */
> > +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> > +		{.asym = {
> > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_RSA,
> > +			.rsa = {
> > +				.padding =
> > +
> > 	RTE_BIT32(RTE_CRYPTO_RSA_PADDING_NONE),
> > +				.hash = 0,
> > +				.max_key_size = 4096
> > +				}
> > +			}
> > +		}
> > +	},
> > +	{	/* ECDSA */
> > +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> > +		{.asym = {
> > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA,
> > +			.ecdsa = {
> > +				.curves =
> > +
> > 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP256R1) |
> > +
> > 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP521R1),
> > +				.random_k = 0
> > +				}
> > +			}
> > +		}
> > +	},
> > +	{	/* ECPM */
> > +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> > +		{.asym = {
> > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_ECPM,
> > +			.ecdsa = {
> > +				.curves =
> > +
> > 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP256R1) |
> > +
> > 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP521R1)
> > +				}
> > +			}
> > +		}
> > +	},
> >  	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
> >  };
> >
> > diff --git a/lib/cryptodev/rte_crypto_asym.h
> > b/lib/cryptodev/rte_crypto_asym.h index d90a7a1957..41b22450d3 100644
> > --- a/lib/cryptodev/rte_crypto_asym.h
> > +++ b/lib/cryptodev/rte_crypto_asym.h
> > @@ -41,6 +41,14 @@ rte_crypto_asym_ke_strings[];  extern const char *
> > rte_crypto_asym_op_strings[];
> >
> > +/** RSA padding type name strings */
> > +extern const char *
> > +rte_crypto_asym_rsa_padding[];
> 
> rte_crypto_asym_rsa_padding_strings
> 
> > +
> > +/** Elliptic curves name strings */
> > +extern const char *
> > +rte_crypto_curves_strings[];
> > +
> >  /**
> >   * Buffer to hold crypto params required for asym operations.
> >   *
> > @@ -265,6 +273,46 @@ struct rte_crypto_rsa_padding {
> >  	 */
> >  };
> >
> > +struct rte_crypto_mod_capability {
> > +	uint16_t max_mod_size;
> > +	/**< Maximum supported modulus size in bytes, 0 means no limit */ };
> > +
> > +struct rte_crypto_rsa_capability {
> > +	uint32_t padding;
> > +	/**< List of supported paddings */
> How is this list supposed to work?
> I believe this should be enum to specify a single value.
> Driver can maintain a static array to list all supported ones.
> And application can query if a particular capability which it intend to use Is
> supported by the PMD.
> 
> > +	uint32_t hash;
> > +	/**< List of supported hash functions */
> Same comment here as well
> 
> > +	uint32_t max_key_size;
> > +	/**< Maximum supported key size in bytes, 0 means no limit */ };
> > +
> > +struct rte_crypto_dh_capability {
> > +	uint16_t max_group_size;
> > +	/**< Maximum group  in bytes, 0 means no limit */
> Maximum group size in bytes ...
> 
> > +	uint8_t priv_key_gen;
> > +	/**< Does PMD supports private key generation generation */
> Is it a flag? Please comment it properly.
> 
> > +};
> > +
> > +struct rte_crypto_dsa_capability {
> > +	uint16_t max_key_size;
> > +	/**< Maximum supported key size in bytes, 0 means no limit */
> > +	uint8_t random_k;
> > +	/**< Does PMD supports random 'k' generation */
> 
> Comments should not ask questions.
> 
> > +};
> > +
> > +struct rte_crypto_ecdsa_capability {
> > +	uint64_t curves;
> > +	/**< Supported elliptic curve ids */
> Shouldn't this also be enum?
> 
> > +	uint8_t random_k;
> > +	/**< Does PMD supports random 'k' generation */
> 
> Same comment as above.
> > +};
> > +
> > +struct rte_crypto_ecpm_capability {
> > +	uint64_t curves;
> > +	/**< Supported elliptic curve ids */
> 
> Enum??
> 
> > +};
> > +
> >  /**
> >   * Asymmetric RSA transform data
> >   *
> > diff --git a/lib/cryptodev/rte_cryptodev.c
> > b/lib/cryptodev/rte_cryptodev.c index 57ee6b3f07..b1ad1112fe 100644
> > --- a/lib/cryptodev/rte_cryptodev.c
> > +++ b/lib/cryptodev/rte_cryptodev.c
> > @@ -190,6 +190,27 @@ const char *rte_crypto_asym_ke_strings[] = {  };
> >
> >  /**
> > + * RSA padding string identifiers
> > + */
> > +const char *rte_crypto_asym_rsa_padding[] = {
> > +	[RTE_CRYPTO_RSA_PADDING_NONE] =
> > "RTE_CRYPTO_RSA_PADDING_NONE",
> > +	[RTE_CRYPTO_RSA_PADDING_PKCS1_5] =
> > "RTE_CRYPTO_RSA_PADDING_PKCS1_5",
> > +	[RTE_CRYPTO_RSA_PADDING_OAEP] =
> > "RTE_CRYPTO_RSA_PADDING_OAEP",
> > +	[RTE_CRYPTO_RSA_PADDING_PSS] =
> > "RTE_CRYPTO_RSA_PADDING_PSS"
> > +};
> > +
> > +/**
> > + * Elliptic curves string identifiers  */ const char
> > +*rte_crypto_curves_strings[] = {
> > +	[RTE_CRYPTO_EC_GROUP_SECP192R1] =
> > "RTE_CRYPTO_EC_GROUP_SECP192R1",
> > +	[RTE_CRYPTO_EC_GROUP_SECP224R1] =
> > "RTE_CRYPTO_EC_GROUP_SECP224R1",
> > +	[RTE_CRYPTO_EC_GROUP_SECP256R1] =
> > "RTE_CRYPTO_EC_GROUP_SECP256R1",
> > +	[RTE_CRYPTO_EC_GROUP_SECP384R1] =
> > "RTE_CRYPTO_EC_GROUP_SECP384R1",
> > +	[RTE_CRYPTO_EC_GROUP_SECP521R1] =
> > "RTE_CRYPTO_EC_GROUP_SECP521R1",
> > +};
> > +
> > +/**
> >   * The private data structure stored in the sym session mempool private data.
> >   */
> >  struct rte_cryptodev_sym_session_pool_private_data { @@ -347,7 +368,7
> > @@ param_range_check(uint16_t size, const struct
> > rte_crypto_param_range *range)
> >  	return -1;
> >  }
> >
> > -const struct rte_cryptodev_asymmetric_xform_capability *
> > +const struct rte_cryptodev_asymmetric_capability *
> >  rte_cryptodev_asym_capability_get(uint8_t dev_id,
> >  		const struct rte_cryptodev_asym_capability_idx *idx)  { @@ -
> 363,8
> > +384,8 @@ rte_cryptodev_asym_capability_get(uint8_t dev_id,
> >  		if (capability->op != RTE_CRYPTO_OP_TYPE_ASYMMETRIC)
> >  			continue;
> >
> > -		if (capability->asym.xform_capa.xform_type == idx->type)
> > -			return &capability->asym.xform_capa;
> > +		if (capability->asym.xform_type == idx->type)
> > +			return &capability->asym;
> >  	}
> >  	return NULL;
> >  };
> > @@ -456,6 +477,59 @@
> rte_cryptodev_asym_xform_capability_check_modlen(
> >  	return 0;
> >  }
> >
> > +int
> > +rte_cryptodev_capa_check_mod(
> 
> API name should be rte_cryptodev_mod_capa_check Verb should come in the
> end.
> Fix other APIs also.
> 
> > +	const struct rte_cryptodev_asymmetric_capability *capa,
> > +	struct rte_crypto_mod_capability mod) {
> > +	if (capa->mod.max_mod_size == 0)
> > +		return 1;
> > +
> > +	if (mod.max_mod_size <= capa->mod.max_mod_size)
> > +		return 1;
> > +	else
> > +		return 0;
> > +}
> > +
> > +int
> > +rte_cryptodev_capa_check_rsa(
> > +	const struct rte_cryptodev_asymmetric_capability *capa,
> > +	struct rte_crypto_rsa_capability rsa) {
> > +	if (rsa.padding != (capa->rsa.padding & rsa.padding))
> > +		return 0;
> > +	if (rsa.hash != (capa->rsa.hash & rsa.hash))
> > +		return 0;
> > +	if (capa->rsa.max_key_size == 0)
> > +		return 1;
> > +	if (rsa.max_key_size <= capa->rsa.max_key_size)
> > +		return 1;
> > +	else
> > +		return 0;
> > +}
> 
> Can we have something similar to symmetric crypto/rte_security capabilities?
In what way similar? There are mostly range checks in symmetric.
> 
> > +
> > +int
> > +rte_cryptodev_capa_check_ecdsa(
> > +	const struct rte_cryptodev_asymmetric_capability *capa,
> > +	struct rte_crypto_ecdsa_capability ecdsa) {
> > +	if (ecdsa.curves != (capa->ecdsa.curves & ecdsa.curves))
> > +		return 0;
> > +	if (ecdsa.random_k == 1 && capa->ecdsa.random_k == 0)
> > +		return 0;
> > +	return 1;
> > +}
> > +
> > +int
> > +rte_cryptodev_capa_check_ecpm(
> > +	const struct rte_cryptodev_asymmetric_capability *capa,
> > +	struct rte_crypto_ecpm_capability ecpm) {
> > +	if (ecpm.curves != (capa->ecpm.curves & ecpm.curves))
> > +		return 0;
> > +	return 1;
> > +}
> > +
> >  /* spinlock for crypto device enq callbacks */  static rte_spinlock_t
> > rte_cryptodev_callback_lock = RTE_SPINLOCK_INITIALIZER;
> >
> > diff --git a/lib/cryptodev/rte_cryptodev.h
> > b/lib/cryptodev/rte_cryptodev.h index 2c2c2edeb7..6c5bd819b2 100644
> > --- a/lib/cryptodev/rte_cryptodev.h
> > +++ b/lib/cryptodev/rte_cryptodev.h
> > @@ -184,6 +184,19 @@ struct rte_cryptodev_asymmetric_xform_capability {
> >   *
> >   */
> >  struct rte_cryptodev_asymmetric_capability {
> > +	enum rte_crypto_asym_xform_type xform_type;
> > +	/**< Asymmetric transform type */
> > +	uint32_t op_types;
> > +	/**< bitmask for supported rte_crypto_asym_op_type */
> > +	union {
> > +		struct rte_crypto_mod_capability mod;
> > +		struct rte_crypto_rsa_capability rsa;
> > +		struct rte_crypto_dh_capability dh;
> > +		struct rte_crypto_dsa_capability dsa;
> > +		struct rte_crypto_ecdsa_capability ecdsa;
> > +		struct rte_crypto_ecpm_capability ecpm;
> > +	};
> > +
> >  	struct rte_cryptodev_asymmetric_xform_capability xform_capa;  };
> >
> > @@ -247,7 +260,7 @@ rte_cryptodev_sym_capability_get(uint8_t dev_id,
> >   *   - Return NULL if the capability not exist.
> >   */
> >  __rte_experimental
> > -const struct rte_cryptodev_asymmetric_xform_capability *
> > +const struct rte_cryptodev_asymmetric_capability *
> >  rte_cryptodev_asym_capability_get(uint8_t dev_id,
> >  		const struct rte_cryptodev_asym_capability_idx *idx);
> >
> > @@ -339,6 +352,66 @@
> rte_cryptodev_asym_xform_capability_check_modlen(
> >  		uint16_t modlen);
> >
> >  /**
> > + * Check if requested Modexp features are supported
> > + *
> > + * @param	capability	Description of the asymmetric crypto
> > capability.
> > + * @param	mod		Modexp requested capability.
> > + *
> > + * @return
> > + *   - Return 1 if the parameters are in range of the capability.
> > + *   - Return 0 if the parameters are out of range of the capability.
> > + */
> > +__rte_experimental
> > +int
> > +rte_cryptodev_capa_check_mod(
> > +	const struct rte_cryptodev_asymmetric_capability *capa,
> > +	struct rte_crypto_mod_capability mod);
> > +/**
> > + * Check if requested RSA features are supported
> > + *
> > + * @param	capability	Description of the asymmetric crypto
> > capability.
> > + * @param	rsa		RSA requested capability.
> > + *
> > + * @return
> > + *   - Return 1 if the parameters are in range of the capability.
> > + *   - Return 0 if the parameters are out of range of the capability.
> > + */
> > +__rte_experimental
> > +int
> > +rte_cryptodev_capa_check_rsa(
> > +	const struct rte_cryptodev_asymmetric_capability *capa,
> > +	struct rte_crypto_rsa_capability rsa);
> > +/**
> > + * Check if requested ECDSA features are supported
> > + *
> > + * @param	capability	Description of the asymmetric crypto
> > capability.
> > + * @param	ecdsa		ECDSA requested capability.
> > + *
> > + * @return
> > + *   - Return 1 if the parameters are in range of the capability.
> > + *   - Return 0 if the parameters are out of range of the capability.
> > + */
> > +__rte_experimental
> > +int
> > +rte_cryptodev_capa_check_ecdsa(
> > +	const struct rte_cryptodev_asymmetric_capability *capa,
> > +	struct rte_crypto_ecdsa_capability ecdsa);
> > +/**
> > + * Check if requested ECPM features are supported
> > + *
> > + * @param	capability	Description of the asymmetric crypto
> > capability.
> > + * @param	ecpm		ECPM requested capability.
> > + *
> > + * @return
> > + *   - Return 1 if the parameters are in range of the capability.
> > + *   - Return 0 if the parameters are out of range of the capability.
> > + */
> > +__rte_experimental
> > +int
> > +rte_cryptodev_capa_check_ecpm(
> > +	const struct rte_cryptodev_asymmetric_capability *capa,
> > +	struct rte_crypto_ecpm_capability ecpm);
> > +/**
> >   * Provide the cipher algorithm enum, given an algorithm string
> >   *
> >   * @param	algo_enum	A pointer to the cipher algorithm
> > diff --git a/lib/cryptodev/version.map b/lib/cryptodev/version.map
> > index f0abfaa47d..4d93b9a947 100644
> > --- a/lib/cryptodev/version.map
> > +++ b/lib/cryptodev/version.map
> > @@ -108,6 +108,10 @@ EXPERIMENTAL {
> >
> >  	#added in 22.07
> >  	rte_cryptodev_session_event_mdata_set;
> > +	rte_cryptodev_capa_check_mod;
> > +	rte_cryptodev_capa_check_rsa;
> > +	rte_cryptodev_capa_check_ecdsa;
> > +	rte_cryptodev_capa_check_ecpm;
> >  };
> >
> >  INTERNAL {
> > --
> > 2.13.6
  
Akhil Goyal May 26, 2022, 3 p.m. UTC | #3
> -----Original Message-----
> From: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>
> Sent: Thursday, May 26, 2022 7:49 PM
> To: Akhil Goyal <gakhil@marvell.com>; dev@dpdk.org
> Cc: Zhang, Roy Fan <roy.fan.zhang@intel.com>
> Subject: RE: [EXT] [PATCH v2 14/14] cryptodev: add asym algorithms capabilities
> 
> 
> 
> > -----Original Message-----
> > From: Akhil Goyal <gakhil@marvell.com>
> > Sent: Thursday, May 26, 2022 2:54 PM
> > To: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>; dev@dpdk.org
> > Cc: Zhang, Roy Fan <roy.fan.zhang@intel.com>
> > Subject: RE: [EXT] [PATCH v2 14/14] cryptodev: add asym algorithms
> capabilities
> >
> > > - Added asymmetric crypto algorithm specific capability struct.
> > > Included fields like random number capability, padding flags etc.
> > >
> > > Signed-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
> > > ---
> > >  app/test-crypto-perf/main.c                  |  12 +-
> > >  app/test-eventdev/test_perf_common.c         |   2 +-
> > >  app/test/test_cryptodev_asym.c               | 210 +++++++++++++++++++++----
> --
> > >  app/test/test_event_crypto_adapter.c         |  16 +-
> > >  drivers/crypto/openssl/rte_openssl_pmd_ops.c | 128 +++++++---------
> > >  drivers/crypto/qat/dev/qat_asym_pmd_gen1.c   |  68 +++++++--
> > >  lib/cryptodev/rte_crypto_asym.h              |  48 ++++++
> > >  lib/cryptodev/rte_cryptodev.c                |  80 +++++++++-
> > >  lib/cryptodev/rte_cryptodev.h                |  75 +++++++++-
> > >  lib/cryptodev/version.map                    |   4 +
> > >  10 files changed, 495 insertions(+), 148 deletions(-)
> >
> > This would also need a change in documentation.
> >
> > >
> > > diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
> > > index 17e30a8e74..f8a4c9cdcf 100644
> > > --- a/app/test-crypto-perf/main.c
> > > +++ b/app/test-crypto-perf/main.c
> > > @@ -364,8 +364,8 @@ cperf_verify_devices_capabilities(struct
> > > cperf_options *opts,
> > >  	struct rte_cryptodev_sym_capability_idx cap_idx;
> > >  	const struct rte_cryptodev_symmetric_capability *capability;
> > >  	struct rte_cryptodev_asym_capability_idx asym_cap_idx;
> > > -	const struct rte_cryptodev_asymmetric_xform_capability
> > > *asym_capability;
> > > -
> > > +	const struct rte_cryptodev_asymmetric_capability *asym_capability;
> > > +	struct rte_crypto_mod_capability mod_capa = {0};
> > >
> > >  	uint8_t i, cdev_id;
> > >  	int ret;
> > > @@ -381,11 +381,11 @@ cperf_verify_devices_capabilities(struct
> > > cperf_options *opts,
> > >  			if (asym_capability == NULL)
> > >  				return -1;
> > >
> > > -			ret =
> > > rte_cryptodev_asym_xform_capability_check_modlen(
> > > -				asym_capability, opts->modex_data-
> > > >modulus.len);
> > > -			if (ret != 0)
> > > +			mod_capa.max_mod_size = opts->modex_data-
> > > >modulus.len;
> > > +			ret = rte_cryptodev_capa_check_mod(asym_capability,
> > > +						mod_capa);
> > > +			if (ret == 0)
> > >  				return ret;
> > > -
> > >  		}
> > >
> > >  		if (opts->op_type == CPERF_AUTH_ONLY || diff --git
> > > a/app/test-eventdev/test_perf_common.c b/app/test-
> > > eventdev/test_perf_common.c index b41785492e..ac8e6410ab 100644
> > > --- a/app/test-eventdev/test_perf_common.c
> > > +++ b/app/test-eventdev/test_perf_common.c
> > > @@ -846,7 +846,7 @@ cryptodev_sym_sess_create(struct prod_data *p,
> > > struct test_perf *t)  static void *  cryptodev_asym_sess_create(struct
> > > prod_data *p, struct test_perf *t)  {
> > > -	const struct rte_cryptodev_asymmetric_xform_capability *capability;
> > > +	const struct rte_cryptodev_asymmetric_capability *capability;
> > >  	struct rte_cryptodev_asym_capability_idx cap_idx;
> > >  	struct rte_crypto_asym_xform xform;
> > >  	void *sess;
> > > diff --git a/app/test/test_cryptodev_asym.c
> > > b/app/test/test_cryptodev_asym.c index 072dbb30f4..c531265642 100644
> > > --- a/app/test/test_cryptodev_asym.c
> > > +++ b/app/test/test_cryptodev_asym.c
> > > @@ -311,10 +311,11 @@ test_cryptodev_asym_op(struct
> > > crypto_testsuite_params_asym *ts_params,
> > >  	struct rte_crypto_asym_xform xform_tc;
> > >  	void *sess = NULL;
> > >  	struct rte_cryptodev_asym_capability_idx cap_idx;
> > > -	const struct rte_cryptodev_asymmetric_xform_capability *capability;
> > > +	const struct rte_cryptodev_asymmetric_capability *capability;
> > >  	uint8_t dev_id = ts_params->valid_devs[0];
> > >  	uint8_t input[TEST_DATA_SIZE] = {0};
> > >  	uint8_t *result = NULL;
> > > +	struct rte_crypto_mod_capability mod_capa = {0};
> > >
> > >  	int ret, status = TEST_SUCCESS;
> > >
> > > @@ -358,8 +359,10 @@ test_cryptodev_asym_op(struct
> > > crypto_testsuite_params_asym *ts_params,
> > >  		asym_op->modex.base.length = data_tc->modex.base.len;
> > >  		asym_op->modex.result.data = result;
> > >  		asym_op->modex.result.length = data_tc->modex.result_len;
> > > -		if
> > > (rte_cryptodev_asym_xform_capability_check_modlen(capability,
> > > -				xform_tc.modex.modulus.length)) {
> > > +
> > > +		mod_capa.max_mod_size = xform_tc.modex.modulus.length;
> > > +		if  (!rte_cryptodev_capa_check_mod(capability,
> > > +			mod_capa)) {
> > >  			snprintf(test_msg, ASYM_TEST_MSG_LEN,
> > >  				"line %u "
> > >  				"FAILED: %s", __LINE__,
> > > @@ -378,8 +381,10 @@ test_cryptodev_asym_op(struct
> > > crypto_testsuite_params_asym *ts_params,
> > >  		asym_op->modinv.base.length = data_tc->modinv.base.len;
> > >  		asym_op->modinv.result.data = result;
> > >  		asym_op->modinv.result.length = data_tc->modinv.result_len;
> > > -		if
> > > (rte_cryptodev_asym_xform_capability_check_modlen(capability,
> > > -				xform_tc.modinv.modulus.length)) {
> > > +
> > > +		mod_capa.max_mod_size = xform_tc.modinv.modulus.length;
> > > +		if  (!rte_cryptodev_capa_check_mod(capability,
> > > +			mod_capa)) {
> > >  			snprintf(test_msg, ASYM_TEST_MSG_LEN,
> > >  				"line %u "
> > >  				"FAILED: %s", __LINE__,
> > > @@ -963,38 +968,100 @@ ut_teardown_asym(void)
> > >  	rte_cryptodev_stop(ts_params->valid_devs[0]);
> > >  }
> > >
> > > -static inline void print_asym_capa(
> > > -		const struct rte_cryptodev_asymmetric_xform_capability
> > > *capa)
> > > +static void
> > > +print_rsa_capability(
> > > +	const struct rte_cryptodev_asymmetric_capability *capa)
> > >  {
> > >  	int i = 0;
> > >
> > > +	printf("\nSupported paddings:");
> > > +	for (; i < 32; i++) {
> > > +		if (capa->rsa.padding & RTE_BIT32(i))
> > > +			printf("\n - %s", rte_crypto_asym_rsa_padding[i]);
> > > +	}
> > > +	printf("\nSupported hash functions:");
> > > +	for (i = 0; i < 32; i++) {
> > > +		if (capa->rsa.hash & RTE_BIT32(i))
> > > +			printf("\n - %s", rte_crypto_auth_algorithm_strings[i]);
> > > +	}
> > > +	printf("\nMaximum key size: ");
> > > +	if (capa->rsa.max_key_size == 0)
> > > +		printf("Unlimited");
> > > +	else
> > > +		printf("%hu", capa->rsa.max_key_size); }
> > > +
> > > +static void
> > > +print_supported_curves(uint64_t curves) {
> > > +	int i = 0;
> > > +
> > > +	printf("\nSupported elliptic curves:");
> > > +	for (; i < 64; i++) {
> > > +		if (curves & RTE_BIT64(i))
> > > +			printf("\n - %s", rte_crypto_curves_strings[i]);
> > > +	}
> > > +}
> > > +
> > > +static inline void print_asym_capa(
> > > +		const struct rte_cryptodev_asymmetric_capability *capa) {
> > >  	printf("\nxform type: %s\n===================\n",
> > >  			rte_crypto_asym_xform_strings[capa->xform_type]);
> > > -	printf("operation supported -");
> > >
> > > -	for (i = 0; i < RTE_CRYPTO_ASYM_OP_LIST_END; i++) {
> > > -		/* check supported operations */
> > > -		if (rte_cryptodev_asym_xform_capability_check_optype(capa,
> > > i))
> > > -			printf(" %s",
> > > -					rte_crypto_asym_op_strings[i]);
> > > -		}
> > > -		switch (capa->xform_type) {
> > > -		case RTE_CRYPTO_ASYM_XFORM_RSA:
> > > -		case RTE_CRYPTO_ASYM_XFORM_MODINV:
> > > -		case RTE_CRYPTO_ASYM_XFORM_MODEX:
> > > -		case RTE_CRYPTO_ASYM_XFORM_DH:
> > > -		case RTE_CRYPTO_ASYM_XFORM_DSA:
> > > -			printf(" modlen: min %d max %d increment %d",
> > > -					capa->modlen.min,
> > > -					capa->modlen.max,
> > > -					capa->modlen.increment);
> > > +	switch (capa->xform_type) {
> > > +	case RTE_CRYPTO_ASYM_XFORM_MODEX:
> > > +	case RTE_CRYPTO_ASYM_XFORM_MODINV:
> > > +		printf("Maximum size of modulus: ");
> > > +		if (capa->mod.max_mod_size == 0)
> > > +			printf("Unlimited");
> > > +		else
> > > +			printf("%hu", capa->mod.max_mod_size);
> > >  		break;
> > > -		case RTE_CRYPTO_ASYM_XFORM_ECDSA:
> > > -		case RTE_CRYPTO_ASYM_XFORM_ECPM:
> > > -		default:
> > > -			break;
> > > -		}
> > > -		printf("\n");
> > > +	case RTE_CRYPTO_ASYM_XFORM_RSA:
> > > +		print_rsa_capability(capa);
> > > +		break;
> > > +	case RTE_CRYPTO_ASYM_XFORM_DH:
> >
> > ECDH?? I hope it will be added once it is tested in this app.
> >
> > > +		printf("Maximum group size: ");
> > > +		if (capa->dh.max_group_size == 0)
> > > +			printf("Unlimited");
> > > +		else
> > > +			printf("%hu", capa->dh.max_group_size);
> > > +		printf("\nSupport for private key generation: ");
> > > +		if (capa->dh.priv_key_gen)
> > > +			printf("Yes");
> > > +		else
> > > +			printf("No");
> > > +		break;
> > > +	case RTE_CRYPTO_ASYM_XFORM_DSA:
> > > +		printf("Maximum key size: ");
> > > +		if (capa->dsa.max_key_size == 0)
> > > +			printf("Unlimited");
> > > +		else
> > > +			printf("%hu", capa->dsa.max_key_size);
> > > +		printf("\nSupport for random 'k' generation: ");
> > > +		if (capa->dsa.random_k)
> > > +			printf("Yes");
> > > +		else
> > > +			printf("No");
> > > +		break;
> > > +
> > > +		break;
> > > +	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
> > > +		print_supported_curves(capa->ecdsa.curves);
> > > +		printf("\nSupport for random 'k' generation: ");
> > > +		if (capa->ecdsa.random_k)
> > > +			printf("Yes");
> > > +		else
> > > +			printf("No");
> > > +		break;
> > > +	case RTE_CRYPTO_ASYM_XFORM_ECPM:
> > > +		print_supported_curves(capa->ecpm.curves);
> > > +		break;
> > > +	default:
> > > +		break;
> > > +	}
> > > +	printf("\n");
> > >  }
> > >
> > >  static int
> > > @@ -1006,7 +1073,7 @@ test_capability(void)
> > >  	const struct rte_cryptodev_capabilities *dev_capa;
> > >  	int i = 0;
> > >  	struct rte_cryptodev_asym_capability_idx idx;
> > > -	const struct rte_cryptodev_asymmetric_xform_capability *capa;
> > > +	const struct rte_cryptodev_asymmetric_capability *capa;
> > >
> > >  	rte_cryptodev_info_get(dev_id, &dev_info);
> > >  	if (!(dev_info.feature_flags &
> > > @@ -1023,7 +1090,7 @@ test_capability(void)
> > >  		dev_capa = &(dev_info.capabilities[i]);
> > >  		if (dev_info.capabilities[i].op ==
> > >  				RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
> > > -			idx.type = dev_capa->asym.xform_capa.xform_type;
> > > +			idx.type = dev_capa->asym.xform_type;
> > >
> > >  			capa = rte_cryptodev_asym_capability_get(dev_id,
> > >  				(const struct
> > > @@ -1386,10 +1453,11 @@ test_mod_inv(void)
> > >  	void *sess = NULL;
> > >  	int status = TEST_SUCCESS;
> > >  	struct rte_cryptodev_asym_capability_idx cap_idx;
> > > -	const struct rte_cryptodev_asymmetric_xform_capability *capability;
> > > +	const struct rte_cryptodev_asymmetric_capability *capability;
> > >  	uint8_t input[TEST_DATA_SIZE] = {0};
> > >  	int ret = 0;
> > >  	uint8_t result[sizeof(mod_p)] = { 0 };
> > > +	struct rte_crypto_mod_capability mod_capa = {0};
> > >
> > >  	if (rte_cryptodev_asym_get_xform_enum(
> > >  		&modinv_xform.xform_type, "modinv") < 0) { @@ -1408,13
> > +1476,11 @@
> > > test_mod_inv(void)
> > >  		return TEST_SKIPPED;
> > >  	}
> > >
> > > -	if (rte_cryptodev_asym_xform_capability_check_modlen(
> > > -		capability,
> > > -		modinv_xform.modinv.modulus.length)) {
> > > -		RTE_LOG(ERR, USER1,
> > > -				 "Invalid MODULUS length specified\n");
> > > -				return TEST_SKIPPED;
> > > -		}
> > > +	mod_capa.max_mod_size = modinv_xform.modinv.modulus.length;
> > > +	if  (!rte_cryptodev_capa_check_mod(capability, mod_capa)) {
> > > +		RTE_LOG(ERR, USER1, "Invalid MODULUS length specified\n");
> > > +		return TEST_SKIPPED;
> > > +	}
> > >
> > >  	ret = rte_cryptodev_asym_session_create(dev_id, &modinv_xform,
> > > sess_mpool, &sess);
> > >  	if (ret < 0) {
> > > @@ -1499,7 +1565,8 @@ test_mod_exp(void)
> > >  	void *sess = NULL;
> > >  	int status = TEST_SUCCESS;
> > >  	struct rte_cryptodev_asym_capability_idx cap_idx;
> > > -	const struct rte_cryptodev_asymmetric_xform_capability *capability;
> > > +	const struct rte_cryptodev_asymmetric_capability *capability;
> > > +	struct rte_crypto_mod_capability mod_capa = {0};
> > >  	uint8_t input[TEST_DATA_SIZE] = {0};
> > >  	int ret = 0;
> > >  	uint8_t result[sizeof(mod_p)] = { 0 }; @@ -1522,12 +1589,11 @@
> > > test_mod_exp(void)
> > >  		return TEST_SKIPPED;
> > >  	}
> > >
> > > -	if (rte_cryptodev_asym_xform_capability_check_modlen(
> > > -			capability, modex_xform.modex.modulus.length)) {
> > > -		RTE_LOG(ERR, USER1,
> > > -				"Invalid MODULUS length specified\n");
> > > -				return TEST_SKIPPED;
> > > -		}
> > > +	mod_capa.max_mod_size = modex_xform.modex.modulus.length;
> > > +	if  (!rte_cryptodev_capa_check_mod(capability, mod_capa)) {
> > > +		RTE_LOG(ERR, USER1, "Invalid MODULUS length specified\n");
> > > +		return TEST_SKIPPED;
> > > +	}
> > >
> > >  	/* Create op, create session, and process packets. 8< */
> > >  	op = rte_crypto_op_alloc(op_mpool,
> > > RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
> > > @@ -1785,6 +1851,8 @@ test_ecdsa_sign_verify(enum curve curve_id)
> > >  	struct rte_crypto_asym_xform xform;
> > >  	struct rte_crypto_asym_op *asym_op;
> > >  	struct rte_cryptodev_info dev_info;
> > > +	struct rte_cryptodev_asym_capability_idx idx;
> > > +	const struct rte_cryptodev_asymmetric_capability *capabilities;
> > >  	struct rte_crypto_op *op = NULL;
> > >  	int ret, status = TEST_SUCCESS;
> > >
> > > @@ -1814,6 +1882,25 @@ test_ecdsa_sign_verify(enum curve curve_id)
> > >
> > >  	rte_cryptodev_info_get(dev_id, &dev_info);
> > >
> > > +	struct rte_crypto_ecdsa_capability capa = {
> > > +		.curves = RTE_BIT32(input_params.curve),
> > > +		.random_k = 0
> > > +	};
> > > +
> > > +	idx.type = RTE_CRYPTO_ASYM_XFORM_ECDSA;
> > > +	capabilities = rte_cryptodev_asym_capability_get(dev_id,
> > > +		(const struct
> > > +		rte_cryptodev_asym_capability_idx *) &idx);
> > > +
> > > +	if (capabilities == NULL) {
> > > +		status = TEST_SKIPPED;
> > > +		goto exit;
> > > +	}
> > > +	if (!rte_cryptodev_capa_check_ecdsa(capabilities, capa)) {
> > > +		status = TEST_SKIPPED;
> > > +		goto exit;
> > > +	}
> > > +
> > >  	/* Setup crypto op data structure */
> > >  	op = rte_crypto_op_alloc(op_mpool,
> > > RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
> > >  	if (op == NULL) {
> > > @@ -1962,6 +2049,8 @@ test_ecdsa_sign_verify_all_curve(void)
> > >  		status = test_ecdsa_sign_verify(curve_id);
> > >  		if (status == TEST_SUCCESS) {
> > >  			msg = "succeeded";
> > > +		} else if (status == TEST_SKIPPED) {
> > > +			continue;
> > >  		} else {
> > >  			msg = "failed";
> > >  			overall_status = status;
> > > @@ -1987,6 +2076,8 @@ test_ecpm(enum curve curve_id)
> > >  	struct rte_crypto_asym_xform xform;
> > >  	struct rte_crypto_asym_op *asym_op;
> > >  	struct rte_cryptodev_info dev_info;
> > > +	struct rte_cryptodev_asym_capability_idx idx;
> > > +	const struct rte_cryptodev_asymmetric_capability *capabilities;
> > >  	struct rte_crypto_op *op = NULL;
> > >  	int ret, status = TEST_SUCCESS;
> > >
> > > @@ -2016,6 +2107,24 @@ test_ecpm(enum curve curve_id)
> > >
> > >  	rte_cryptodev_info_get(dev_id, &dev_info);
> > >
> > > +	struct rte_crypto_ecdsa_capability capa = {
> > > +		.curves = RTE_BIT32(input_params.curve)
> > > +	};
> > > +
> > > +	idx.type = RTE_CRYPTO_ASYM_XFORM_ECPM;
> > > +	capabilities = rte_cryptodev_asym_capability_get(dev_id,
> > > +		(const struct
> > > +		rte_cryptodev_asym_capability_idx *) &idx);
> > > +
> > > +	if (capabilities == NULL) {
> > > +		status = TEST_SKIPPED;
> > > +		goto exit;
> > > +	}
> > > +	if (!rte_cryptodev_capa_check_ecdsa(capabilities, capa)) {
> > > +		status = TEST_SKIPPED;
> > > +		goto exit;
> > > +	}
> > > +
> > >  	/* Setup crypto op data structure */
> > >  	op = rte_crypto_op_alloc(op_mpool,
> > > RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
> > >  	if (op == NULL) {
> > > @@ -2124,6 +2233,8 @@ test_ecpm_all_curve(void)
> > >  		status = test_ecpm(curve_id);
> > >  		if (status == TEST_SUCCESS) {
> > >  			msg = "succeeded";
> > > +		} else if (status == TEST_SKIPPED) {
> > > +			continue;
> > >  		} else {
> > >  			msg = "failed";
> > >  			overall_status = status;
> > > @@ -2162,7 +2273,12 @@ static struct unit_test_suite
> > > cryptodev_qat_asym_testsuite  = {
> > >  	.setup = testsuite_setup,
> > >  	.teardown = testsuite_teardown,
> > >  	.unit_test_cases = {
> > > +		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
> > > test_capability),
> > >  		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
> > test_one_by_one),
> > > +		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
> > > +			     test_ecdsa_sign_verify_all_curve),
> > > +		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
> > > +				test_ecpm_all_curve),
> > >  		TEST_CASES_END() /**< NULL terminate unit test array */
> > >  	}
> > >  };
> >
> > I think patch need to be split for adding test app changes.
> >
> >
> > > diff --git a/app/test/test_event_crypto_adapter.c
> > > b/app/test/test_event_crypto_adapter.c
> > > index 2ecc7e2cea..9a62241371 100644
> > > --- a/app/test/test_event_crypto_adapter.c
> > > +++ b/app/test/test_event_crypto_adapter.c
> > > @@ -450,7 +450,7 @@ test_session_with_op_forward_mode(void)
> > >  static int
> > >  test_asym_op_forward_mode(uint8_t session_less)  {
> > > -	const struct rte_cryptodev_asymmetric_xform_capability *capability;
> > > +	const struct rte_cryptodev_asymmetric_capability *capability;
> > >  	struct rte_cryptodev_asym_capability_idx cap_idx;
> > >  	struct rte_crypto_asym_xform xform_tc;
> > >  	union rte_event_crypto_metadata m_data; @@ -458,6 +458,7 @@
> > > test_asym_op_forward_mode(uint8_t session_less)
> > >  	struct rte_crypto_asym_op *asym_op;
> > >  	struct rte_crypto_op *op;
> > >  	uint8_t input[4096] = {0};
> > > +	struct rte_crypto_mod_capability mod_capa = {0};
> > >  	uint8_t *result = NULL;
> > >  	struct rte_event ev;
> > >  	void *sess = NULL;
> > > @@ -503,8 +504,9 @@ test_asym_op_forward_mode(uint8_t session_less)
> > >  	asym_op->modex.base.length = modex_test_case.base.len;
> > >  	asym_op->modex.result.data = result;
> > >  	asym_op->modex.result.length = modex_test_case.result_len;
> > > -	if (rte_cryptodev_asym_xform_capability_check_modlen(capability,
> > > -			xform_tc.modex.modulus.length)) {
> > > +
> > > +	mod_capa.max_mod_size = xform_tc.modex.modulus.length;
> > > +	if  (!rte_cryptodev_capa_check_mod(capability, mod_capa)) {
> > >  		RTE_LOG(INFO, USER1,
> > >  			"line %u FAILED: %s", __LINE__,
> > >  			"Invalid MODULUS length specified"); @@ -784,7
> > +786,7 @@
> > > test_session_with_op_new_mode(void)
> > >  static int
> > >  test_asym_op_new_mode(uint8_t session_less)  {
> > > -	const struct rte_cryptodev_asymmetric_xform_capability *capability;
> > > +	const struct rte_cryptodev_asymmetric_capability *capability;
> > >  	struct rte_cryptodev_asym_capability_idx cap_idx;
> > >  	struct rte_crypto_asym_xform xform_tc;
> > >  	union rte_event_crypto_metadata m_data; @@ -792,6 +794,7 @@
> > > test_asym_op_new_mode(uint8_t session_less)
> > >  	struct rte_crypto_asym_op *asym_op;
> > >  	struct rte_crypto_op *op;
> > >  	uint8_t input[4096] = {0};
> > > +	struct rte_crypto_mod_capability mod_capa = {0};
> >
> > Can you move this above to maintain reverse Xmas tree?
> >
> > >  	uint8_t *result = NULL;
> > >  	void *sess = NULL;
> > >  	uint32_t cap;
> > > @@ -835,8 +838,9 @@ test_asym_op_new_mode(uint8_t session_less)
> > >  	asym_op->modex.base.length = modex_test_case.base.len;
> > >  	asym_op->modex.result.data = result;
> > >  	asym_op->modex.result.length = modex_test_case.result_len;
> > > -	if (rte_cryptodev_asym_xform_capability_check_modlen(capability,
> > > -			xform_tc.modex.modulus.length)) {
> > > +
> > > +	mod_capa.max_mod_size = xform_tc.modex.modulus.length;
> > > +	if  (!rte_cryptodev_capa_check_mod(capability, mod_capa)) {
> > >  		RTE_LOG(INFO, USER1,
> > >  			"line %u FAILED: %s", __LINE__,
> > >  			"Invalid MODULUS length specified"); diff --git
> > > a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> > > b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> > > index 16ec5e15eb..e734fc2a69 100644
> > > --- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> > > +++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> > > @@ -7,6 +7,7 @@
> > >  #include <rte_common.h>
> > >  #include <rte_malloc.h>
> > >  #include <cryptodev_pmd.h>
> > > +#include <rte_bitops.h>
> > >
> > >  #include "openssl_pmd_private.h"
> > >  #include "compat.h"
> > > @@ -470,103 +471,82 @@ static const struct rte_cryptodev_capabilities
> > > openssl_pmd_capabilities[] = {
> > >  			}, }
> > >  		}, }
> > >  	},
> > > -	{	/* RSA */
> > > +	{	/* Modular exponentiation */
> > >  		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> > >  		{.asym = {
> > > -			.xform_capa = {
> > > -				.xform_type =
> > > RTE_CRYPTO_ASYM_XFORM_RSA,
> > > -				.op_types = ((1 <<
> > > RTE_CRYPTO_ASYM_OP_SIGN) |
> > > -					(1 << RTE_CRYPTO_ASYM_OP_VERIFY)
> > > |
> > > -					(1 <<
> > > RTE_CRYPTO_ASYM_OP_ENCRYPT) |
> > > -					(1 <<
> > > RTE_CRYPTO_ASYM_OP_DECRYPT)),
> > > -				{
> > > -				.modlen = {
> > > -				/* min length is based on openssl rsa keygen */
> > > -				.min = 30,
> > > -				/* value 0 symbolizes no limit on max length */
> > > -				.max = 0,
> > > -				.increment = 1
> > > -				}, }
> > > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX,
> > > +			.mod = {
> > > +				.max_mod_size = 0
> > > +				}
> > >  			}
> > > -		},
> > >  		}
> > >  	},
> > > -	{	/* modexp */
> > > +	{	/* Modular multiplicative inverse */
> > >  		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> > >  		{.asym = {
> > > -			.xform_capa = {
> > > -				.xform_type =
> > > RTE_CRYPTO_ASYM_XFORM_MODEX,
> > > -				.op_types = 0,
> > > -				{
> > > -				.modlen = {
> > > -				/* value 0 symbolizes no limit on min length */
> > > -				.min = 0,
> > > -				/* value 0 symbolizes no limit on max length */
> > > -				.max = 0,
> > > -				.increment = 1
> > > -				}, }
> > > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_MODINV,
> > > +			.mod = {
> > > +				.max_mod_size = 0
> > > +				}
> > >  			}
> > > -		},
> > >  		}
> > >  	},
> > > -	{	/* modinv */
> > > +	{	/* RSA */
> > >  		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> > >  		{.asym = {
> > > -			.xform_capa = {
> > > -				.xform_type =
> > > RTE_CRYPTO_ASYM_XFORM_MODINV,
> > > -				.op_types = 0,
> > > -				{
> > > -				.modlen = {
> > > -				/* value 0 symbolizes no limit on min length */
> > > -				.min = 0,
> > > -				/* value 0 symbolizes no limit on max length */
> > > -				.max = 0,
> > > -				.increment = 1
> > > -				}, }
> > > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_RSA,
> > > +			.rsa = {
> > > +				.padding =
> > > +
> > > 	RTE_BIT32(RTE_CRYPTO_RSA_PADDING_NONE) |
> > > +
> > > 	RTE_BIT32(RTE_CRYPTO_RSA_PADDING_PKCS1_5),
> > > +				.hash =
> > > +					RTE_BIT32(RTE_CRYPTO_AUTH_MD5)
> > > |
> > > +					RTE_BIT32(RTE_CRYPTO_AUTH_SHA1)
> > > 	|
> > > +
> > > 	RTE_BIT32(RTE_CRYPTO_AUTH_SHA224) |
> > > +
> > > 	RTE_BIT32(RTE_CRYPTO_AUTH_SHA256) |
> > > +
> > > 	RTE_BIT32(RTE_CRYPTO_AUTH_SHA384) |
> > > +
> > > 	RTE_BIT32(RTE_CRYPTO_AUTH_SHA512),
> > > +				.max_key_size = 0
> > > +				}
> > >  			}
> > > -		},
> > >  		}
> > >  	},
> > > -	{	/* dh */
> > > +	{	/* Diffie-Hellman */
> > >  		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> > >  		{.asym = {
> > > -			.xform_capa = {
> > > -				.xform_type =
> > > RTE_CRYPTO_ASYM_XFORM_DH,
> > > -				.op_types =
> > > -
> > > 	((1<<RTE_CRYPTO_ASYM_KE_PRIVATE_KEY_GENERATE) |
> > > -				(1 <<
> > > RTE_CRYPTO_ASYM_KE_PUBLIC_KEY_GENERATE |
> > > -				(1 <<
> > > -
> > > 	RTE_CRYPTO_ASYM_KE_SHARED_SECRET_COMPUTE))),
> > > -				{
> > > -				.modlen = {
> > > -				/* value 0 symbolizes no limit on min length */
> > > -				.min = 0,
> > > -				/* value 0 symbolizes no limit on max length */
> > > -				.max = 0,
> > > -				.increment = 1
> > > -				}, }
> > > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_DH,
> > > +			.dh = {
> > > +				.max_group_size = 0,
> > > +				.priv_key_gen = 1
> > > +				}
> > >  			}
> > > -		},
> > >  		}
> > >  	},
> > > -	{	/* dsa */
> > > +	{	/* DSA */
> > >  		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> > >  		{.asym = {
> > > -			.xform_capa = {
> > > -				.xform_type =
> > > RTE_CRYPTO_ASYM_XFORM_DSA,
> > > -				.op_types =
> > > -				((1<<RTE_CRYPTO_ASYM_OP_SIGN) |
> > > -				(1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
> > > -				{
> > > -				.modlen = {
> > > -				/* value 0 symbolizes no limit on min length */
> > > -				.min = 0,
> > > -				/* value 0 symbolizes no limit on max length */
> > > -				.max = 0,
> > > -				.increment = 1
> > > -				}, }
> > > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_DSA,
> > > +			.dsa = {
> > > +				.max_key_size = 0,
> > > +				.random_k = 1
> > > +				}
> > > +			}
> > > +		}
> > > +	},
> > > +	{	/* ECDSA */
> > > +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> > > +		{.asym = {
> > > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA,
> > > +			.ecdsa = {
> > > +				.curves =
> > > +
> > > 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP192R1) |
> > > +
> > > 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP224R1) |
> > > +
> > > 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP256R1) |
> > > +
> > > 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP384R1) |
> > > +
> > > 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP521R1),
> > > +				.random_k = 1
> > > +				}
> > >  			}
> > > -		},
> > >  		}
> > >  	},
> > >
> >
> > Do not combine PMD changes for capabilities in cryptodev patch for new APIs.
> >
> >
> > > diff --git a/drivers/crypto/qat/dev/qat_asym_pmd_gen1.c
> > > b/drivers/crypto/qat/dev/qat_asym_pmd_gen1.c
> > > index 4499fdaf2d..d5144bca84 100644
> > > --- a/drivers/crypto/qat/dev/qat_asym_pmd_gen1.c
> > > +++ b/drivers/crypto/qat/dev/qat_asym_pmd_gen1.c
> > > @@ -28,16 +28,64 @@ struct rte_cryptodev_ops
> qat_asym_crypto_ops_gen1
> > > = {  };
> > >
> > >  static struct rte_cryptodev_capabilities qat_asym_crypto_caps_gen1[] = {
> > > -	QAT_ASYM_CAP(MODEX,
> > > -		0, 1, 512, 1),
> > > -	QAT_ASYM_CAP(MODINV,
> > > -		0, 1, 512, 1),
> > > -	QAT_ASYM_CAP(RSA,
> > > -			((1 << RTE_CRYPTO_ASYM_OP_SIGN) |
> > > -			(1 << RTE_CRYPTO_ASYM_OP_VERIFY) |
> > > -			(1 << RTE_CRYPTO_ASYM_OP_ENCRYPT) |
> > > -			(1 << RTE_CRYPTO_ASYM_OP_DECRYPT)),
> > > -			64, 512, 64),
> > > +	{	/* Modular exponentiation */
> > > +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> > > +		{.asym = {
> > > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX,
> > > +			.mod = {
> > > +				.max_mod_size = 4096
> > > +				}
> > > +			}
> > > +		}
> > > +	},
> > > +	{	/* Modular multiplicative inverse */
> > > +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> > > +		{.asym = {
> > > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_MODINV,
> > > +			.mod = {
> > > +				.max_mod_size = 4096
> > > +				}
> > > +			}
> > > +		}
> > > +	},
> > > +	{	/* RSA */
> > > +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> > > +		{.asym = {
> > > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_RSA,
> > > +			.rsa = {
> > > +				.padding =
> > > +
> > > 	RTE_BIT32(RTE_CRYPTO_RSA_PADDING_NONE),
> > > +				.hash = 0,
> > > +				.max_key_size = 4096
> > > +				}
> > > +			}
> > > +		}
> > > +	},
> > > +	{	/* ECDSA */
> > > +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> > > +		{.asym = {
> > > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA,
> > > +			.ecdsa = {
> > > +				.curves =
> > > +
> > > 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP256R1) |
> > > +
> > > 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP521R1),
> > > +				.random_k = 0
> > > +				}
> > > +			}
> > > +		}
> > > +	},
> > > +	{	/* ECPM */
> > > +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> > > +		{.asym = {
> > > +			.xform_type = RTE_CRYPTO_ASYM_XFORM_ECPM,
> > > +			.ecdsa = {
> > > +				.curves =
> > > +
> > > 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP256R1) |
> > > +
> > > 	RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP521R1)
> > > +				}
> > > +			}
> > > +		}
> > > +	},
> > >  	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
> > >  };
> > >
> > > diff --git a/lib/cryptodev/rte_crypto_asym.h
> > > b/lib/cryptodev/rte_crypto_asym.h index d90a7a1957..41b22450d3 100644
> > > --- a/lib/cryptodev/rte_crypto_asym.h
> > > +++ b/lib/cryptodev/rte_crypto_asym.h
> > > @@ -41,6 +41,14 @@ rte_crypto_asym_ke_strings[];  extern const char *
> > > rte_crypto_asym_op_strings[];
> > >
> > > +/** RSA padding type name strings */
> > > +extern const char *
> > > +rte_crypto_asym_rsa_padding[];
> >
> > rte_crypto_asym_rsa_padding_strings
> >
> > > +
> > > +/** Elliptic curves name strings */
> > > +extern const char *
> > > +rte_crypto_curves_strings[];
> > > +
> > >  /**
> > >   * Buffer to hold crypto params required for asym operations.
> > >   *
> > > @@ -265,6 +273,46 @@ struct rte_crypto_rsa_padding {
> > >  	 */
> > >  };
> > >
> > > +struct rte_crypto_mod_capability {
> > > +	uint16_t max_mod_size;
> > > +	/**< Maximum supported modulus size in bytes, 0 means no limit */ };
> > > +
> > > +struct rte_crypto_rsa_capability {
> > > +	uint32_t padding;
> > > +	/**< List of supported paddings */
> > How is this list supposed to work?
> > I believe this should be enum to specify a single value.
> > Driver can maintain a static array to list all supported ones.
> > And application can query if a particular capability which it intend to use Is
> > supported by the PMD.
> >
> > > +	uint32_t hash;
> > > +	/**< List of supported hash functions */
> > Same comment here as well
> >
> > > +	uint32_t max_key_size;
> > > +	/**< Maximum supported key size in bytes, 0 means no limit */ };
> > > +
> > > +struct rte_crypto_dh_capability {
> > > +	uint16_t max_group_size;
> > > +	/**< Maximum group  in bytes, 0 means no limit */
> > Maximum group size in bytes ...
> >
> > > +	uint8_t priv_key_gen;
> > > +	/**< Does PMD supports private key generation generation */
> > Is it a flag? Please comment it properly.
> >
> > > +};
> > > +
> > > +struct rte_crypto_dsa_capability {
> > > +	uint16_t max_key_size;
> > > +	/**< Maximum supported key size in bytes, 0 means no limit */
> > > +	uint8_t random_k;
> > > +	/**< Does PMD supports random 'k' generation */
> >
> > Comments should not ask questions.
> >
> > > +};
> > > +
> > > +struct rte_crypto_ecdsa_capability {
> > > +	uint64_t curves;
> > > +	/**< Supported elliptic curve ids */
> > Shouldn't this also be enum?
> >
> > > +	uint8_t random_k;
> > > +	/**< Does PMD supports random 'k' generation */
> >
> > Same comment as above.
> > > +};
> > > +
> > > +struct rte_crypto_ecpm_capability {
> > > +	uint64_t curves;
> > > +	/**< Supported elliptic curve ids */
> >
> > Enum??
> >
> > > +};
> > > +
> > >  /**
> > >   * Asymmetric RSA transform data
> > >   *
> > > diff --git a/lib/cryptodev/rte_cryptodev.c
> > > b/lib/cryptodev/rte_cryptodev.c index 57ee6b3f07..b1ad1112fe 100644
> > > --- a/lib/cryptodev/rte_cryptodev.c
> > > +++ b/lib/cryptodev/rte_cryptodev.c
> > > @@ -190,6 +190,27 @@ const char *rte_crypto_asym_ke_strings[] = {  };
> > >
> > >  /**
> > > + * RSA padding string identifiers
> > > + */
> > > +const char *rte_crypto_asym_rsa_padding[] = {
> > > +	[RTE_CRYPTO_RSA_PADDING_NONE] =
> > > "RTE_CRYPTO_RSA_PADDING_NONE",
> > > +	[RTE_CRYPTO_RSA_PADDING_PKCS1_5] =
> > > "RTE_CRYPTO_RSA_PADDING_PKCS1_5",
> > > +	[RTE_CRYPTO_RSA_PADDING_OAEP] =
> > > "RTE_CRYPTO_RSA_PADDING_OAEP",
> > > +	[RTE_CRYPTO_RSA_PADDING_PSS] =
> > > "RTE_CRYPTO_RSA_PADDING_PSS"
> > > +};
> > > +
> > > +/**
> > > + * Elliptic curves string identifiers  */ const char
> > > +*rte_crypto_curves_strings[] = {
> > > +	[RTE_CRYPTO_EC_GROUP_SECP192R1] =
> > > "RTE_CRYPTO_EC_GROUP_SECP192R1",
> > > +	[RTE_CRYPTO_EC_GROUP_SECP224R1] =
> > > "RTE_CRYPTO_EC_GROUP_SECP224R1",
> > > +	[RTE_CRYPTO_EC_GROUP_SECP256R1] =
> > > "RTE_CRYPTO_EC_GROUP_SECP256R1",
> > > +	[RTE_CRYPTO_EC_GROUP_SECP384R1] =
> > > "RTE_CRYPTO_EC_GROUP_SECP384R1",
> > > +	[RTE_CRYPTO_EC_GROUP_SECP521R1] =
> > > "RTE_CRYPTO_EC_GROUP_SECP521R1",
> > > +};
> > > +
> > > +/**
> > >   * The private data structure stored in the sym session mempool private
> data.
> > >   */
> > >  struct rte_cryptodev_sym_session_pool_private_data { @@ -347,7 +368,7
> > > @@ param_range_check(uint16_t size, const struct
> > > rte_crypto_param_range *range)
> > >  	return -1;
> > >  }
> > >
> > > -const struct rte_cryptodev_asymmetric_xform_capability *
> > > +const struct rte_cryptodev_asymmetric_capability *
> > >  rte_cryptodev_asym_capability_get(uint8_t dev_id,
> > >  		const struct rte_cryptodev_asym_capability_idx *idx)  { @@ -
> > 363,8
> > > +384,8 @@ rte_cryptodev_asym_capability_get(uint8_t dev_id,
> > >  		if (capability->op != RTE_CRYPTO_OP_TYPE_ASYMMETRIC)
> > >  			continue;
> > >
> > > -		if (capability->asym.xform_capa.xform_type == idx->type)
> > > -			return &capability->asym.xform_capa;
> > > +		if (capability->asym.xform_type == idx->type)
> > > +			return &capability->asym;
> > >  	}
> > >  	return NULL;
> > >  };
> > > @@ -456,6 +477,59 @@
> > rte_cryptodev_asym_xform_capability_check_modlen(
> > >  	return 0;
> > >  }
> > >
> > > +int
> > > +rte_cryptodev_capa_check_mod(
> >
> > API name should be rte_cryptodev_mod_capa_check Verb should come in the
> > end.
> > Fix other APIs also.
> >
> > > +	const struct rte_cryptodev_asymmetric_capability *capa,
> > > +	struct rte_crypto_mod_capability mod) {
> > > +	if (capa->mod.max_mod_size == 0)
> > > +		return 1;
> > > +
> > > +	if (mod.max_mod_size <= capa->mod.max_mod_size)
> > > +		return 1;
> > > +	else
> > > +		return 0;
> > > +}
> > > +
> > > +int
> > > +rte_cryptodev_capa_check_rsa(
> > > +	const struct rte_cryptodev_asymmetric_capability *capa,
> > > +	struct rte_crypto_rsa_capability rsa) {
> > > +	if (rsa.padding != (capa->rsa.padding & rsa.padding))
> > > +		return 0;
> > > +	if (rsa.hash != (capa->rsa.hash & rsa.hash))
> > > +		return 0;
> > > +	if (capa->rsa.max_key_size == 0)
> > > +		return 1;
> > > +	if (rsa.max_key_size <= capa->rsa.max_key_size)
> > > +		return 1;
> > > +	else
> > > +		return 0;
> > > +}
> >
> > Can we have something similar to symmetric crypto/rte_security capabilities?
> In what way similar? There are mostly range checks in symmetric.

Please ignore this comment, I misinterpreted xforms with algos.
For each of the xforms we can have separate API to check.
All algos in that particular xform can be clubbed in same API.

> >
> > > +
> > > +int
> > > +rte_cryptodev_capa_check_ecdsa(
> > > +	const struct rte_cryptodev_asymmetric_capability *capa,
> > > +	struct rte_crypto_ecdsa_capability ecdsa) {
> > > +	if (ecdsa.curves != (capa->ecdsa.curves & ecdsa.curves))
> > > +		return 0;
> > > +	if (ecdsa.random_k == 1 && capa->ecdsa.random_k == 0)
> > > +		return 0;
> > > +	return 1;
> > > +}
> > > +
> > > +int
> > > +rte_cryptodev_capa_check_ecpm(
> > > +	const struct rte_cryptodev_asymmetric_capability *capa,
> > > +	struct rte_crypto_ecpm_capability ecpm) {
> > > +	if (ecpm.curves != (capa->ecpm.curves & ecpm.curves))
> > > +		return 0;
> > > +	return 1;
> > > +}
> > > +
> > >  /* spinlock for crypto device enq callbacks */  static rte_spinlock_t
> > > rte_cryptodev_callback_lock = RTE_SPINLOCK_INITIALIZER;
> > >
> > > diff --git a/lib/cryptodev/rte_cryptodev.h
> > > b/lib/cryptodev/rte_cryptodev.h index 2c2c2edeb7..6c5bd819b2 100644
> > > --- a/lib/cryptodev/rte_cryptodev.h
> > > +++ b/lib/cryptodev/rte_cryptodev.h
> > > @@ -184,6 +184,19 @@ struct rte_cryptodev_asymmetric_xform_capability
> {
> > >   *
> > >   */
> > >  struct rte_cryptodev_asymmetric_capability {
> > > +	enum rte_crypto_asym_xform_type xform_type;
> > > +	/**< Asymmetric transform type */
> > > +	uint32_t op_types;
> > > +	/**< bitmask for supported rte_crypto_asym_op_type */
> > > +	union {
> > > +		struct rte_crypto_mod_capability mod;
> > > +		struct rte_crypto_rsa_capability rsa;
> > > +		struct rte_crypto_dh_capability dh;
> > > +		struct rte_crypto_dsa_capability dsa;
> > > +		struct rte_crypto_ecdsa_capability ecdsa;
> > > +		struct rte_crypto_ecpm_capability ecpm;
> > > +	};
> > > +
> > >  	struct rte_cryptodev_asymmetric_xform_capability xform_capa;  };
> > >
> > > @@ -247,7 +260,7 @@ rte_cryptodev_sym_capability_get(uint8_t dev_id,
> > >   *   - Return NULL if the capability not exist.
> > >   */
> > >  __rte_experimental
> > > -const struct rte_cryptodev_asymmetric_xform_capability *
> > > +const struct rte_cryptodev_asymmetric_capability *
> > >  rte_cryptodev_asym_capability_get(uint8_t dev_id,
> > >  		const struct rte_cryptodev_asym_capability_idx *idx);
> > >
> > > @@ -339,6 +352,66 @@
> > rte_cryptodev_asym_xform_capability_check_modlen(
> > >  		uint16_t modlen);
> > >
> > >  /**
> > > + * Check if requested Modexp features are supported
> > > + *
> > > + * @param	capability	Description of the asymmetric crypto
> > > capability.
> > > + * @param	mod		Modexp requested capability.
> > > + *
> > > + * @return
> > > + *   - Return 1 if the parameters are in range of the capability.
> > > + *   - Return 0 if the parameters are out of range of the capability.
> > > + */
> > > +__rte_experimental
> > > +int
> > > +rte_cryptodev_capa_check_mod(
> > > +	const struct rte_cryptodev_asymmetric_capability *capa,
> > > +	struct rte_crypto_mod_capability mod);
> > > +/**
> > > + * Check if requested RSA features are supported
> > > + *
> > > + * @param	capability	Description of the asymmetric crypto
> > > capability.
> > > + * @param	rsa		RSA requested capability.
> > > + *
> > > + * @return
> > > + *   - Return 1 if the parameters are in range of the capability.
> > > + *   - Return 0 if the parameters are out of range of the capability.
> > > + */
> > > +__rte_experimental
> > > +int
> > > +rte_cryptodev_capa_check_rsa(
> > > +	const struct rte_cryptodev_asymmetric_capability *capa,
> > > +	struct rte_crypto_rsa_capability rsa);
> > > +/**
> > > + * Check if requested ECDSA features are supported
> > > + *
> > > + * @param	capability	Description of the asymmetric crypto
> > > capability.
> > > + * @param	ecdsa		ECDSA requested capability.
> > > + *
> > > + * @return
> > > + *   - Return 1 if the parameters are in range of the capability.
> > > + *   - Return 0 if the parameters are out of range of the capability.
> > > + */
> > > +__rte_experimental
> > > +int
> > > +rte_cryptodev_capa_check_ecdsa(
> > > +	const struct rte_cryptodev_asymmetric_capability *capa,
> > > +	struct rte_crypto_ecdsa_capability ecdsa);
> > > +/**
> > > + * Check if requested ECPM features are supported
> > > + *
> > > + * @param	capability	Description of the asymmetric crypto
> > > capability.
> > > + * @param	ecpm		ECPM requested capability.
> > > + *
> > > + * @return
> > > + *   - Return 1 if the parameters are in range of the capability.
> > > + *   - Return 0 if the parameters are out of range of the capability.
> > > + */
> > > +__rte_experimental
> > > +int
> > > +rte_cryptodev_capa_check_ecpm(
> > > +	const struct rte_cryptodev_asymmetric_capability *capa,
> > > +	struct rte_crypto_ecpm_capability ecpm);
> > > +/**
> > >   * Provide the cipher algorithm enum, given an algorithm string
> > >   *
> > >   * @param	algo_enum	A pointer to the cipher algorithm
> > > diff --git a/lib/cryptodev/version.map b/lib/cryptodev/version.map
> > > index f0abfaa47d..4d93b9a947 100644
> > > --- a/lib/cryptodev/version.map
> > > +++ b/lib/cryptodev/version.map
> > > @@ -108,6 +108,10 @@ EXPERIMENTAL {
> > >
> > >  	#added in 22.07
> > >  	rte_cryptodev_session_event_mdata_set;
> > > +	rte_cryptodev_capa_check_mod;
> > > +	rte_cryptodev_capa_check_rsa;
> > > +	rte_cryptodev_capa_check_ecdsa;
> > > +	rte_cryptodev_capa_check_ecpm;
> > >  };
> > >
> > >  INTERNAL {
> > > --
> > > 2.13.6
  

Patch

diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
index 17e30a8e74..f8a4c9cdcf 100644
--- a/app/test-crypto-perf/main.c
+++ b/app/test-crypto-perf/main.c
@@ -364,8 +364,8 @@  cperf_verify_devices_capabilities(struct cperf_options *opts,
 	struct rte_cryptodev_sym_capability_idx cap_idx;
 	const struct rte_cryptodev_symmetric_capability *capability;
 	struct rte_cryptodev_asym_capability_idx asym_cap_idx;
-	const struct rte_cryptodev_asymmetric_xform_capability *asym_capability;
-
+	const struct rte_cryptodev_asymmetric_capability *asym_capability;
+	struct rte_crypto_mod_capability mod_capa = {0};
 
 	uint8_t i, cdev_id;
 	int ret;
@@ -381,11 +381,11 @@  cperf_verify_devices_capabilities(struct cperf_options *opts,
 			if (asym_capability == NULL)
 				return -1;
 
-			ret = rte_cryptodev_asym_xform_capability_check_modlen(
-				asym_capability, opts->modex_data->modulus.len);
-			if (ret != 0)
+			mod_capa.max_mod_size = opts->modex_data->modulus.len;
+			ret = rte_cryptodev_capa_check_mod(asym_capability,
+						mod_capa);
+			if (ret == 0)
 				return ret;
-
 		}
 
 		if (opts->op_type == CPERF_AUTH_ONLY ||
diff --git a/app/test-eventdev/test_perf_common.c b/app/test-eventdev/test_perf_common.c
index b41785492e..ac8e6410ab 100644
--- a/app/test-eventdev/test_perf_common.c
+++ b/app/test-eventdev/test_perf_common.c
@@ -846,7 +846,7 @@  cryptodev_sym_sess_create(struct prod_data *p, struct test_perf *t)
 static void *
 cryptodev_asym_sess_create(struct prod_data *p, struct test_perf *t)
 {
-	const struct rte_cryptodev_asymmetric_xform_capability *capability;
+	const struct rte_cryptodev_asymmetric_capability *capability;
 	struct rte_cryptodev_asym_capability_idx cap_idx;
 	struct rte_crypto_asym_xform xform;
 	void *sess;
diff --git a/app/test/test_cryptodev_asym.c b/app/test/test_cryptodev_asym.c
index 072dbb30f4..c531265642 100644
--- a/app/test/test_cryptodev_asym.c
+++ b/app/test/test_cryptodev_asym.c
@@ -311,10 +311,11 @@  test_cryptodev_asym_op(struct crypto_testsuite_params_asym *ts_params,
 	struct rte_crypto_asym_xform xform_tc;
 	void *sess = NULL;
 	struct rte_cryptodev_asym_capability_idx cap_idx;
-	const struct rte_cryptodev_asymmetric_xform_capability *capability;
+	const struct rte_cryptodev_asymmetric_capability *capability;
 	uint8_t dev_id = ts_params->valid_devs[0];
 	uint8_t input[TEST_DATA_SIZE] = {0};
 	uint8_t *result = NULL;
+	struct rte_crypto_mod_capability mod_capa = {0};
 
 	int ret, status = TEST_SUCCESS;
 
@@ -358,8 +359,10 @@  test_cryptodev_asym_op(struct crypto_testsuite_params_asym *ts_params,
 		asym_op->modex.base.length = data_tc->modex.base.len;
 		asym_op->modex.result.data = result;
 		asym_op->modex.result.length = data_tc->modex.result_len;
-		if (rte_cryptodev_asym_xform_capability_check_modlen(capability,
-				xform_tc.modex.modulus.length)) {
+
+		mod_capa.max_mod_size = xform_tc.modex.modulus.length;
+		if  (!rte_cryptodev_capa_check_mod(capability,
+			mod_capa)) {
 			snprintf(test_msg, ASYM_TEST_MSG_LEN,
 				"line %u "
 				"FAILED: %s", __LINE__,
@@ -378,8 +381,10 @@  test_cryptodev_asym_op(struct crypto_testsuite_params_asym *ts_params,
 		asym_op->modinv.base.length = data_tc->modinv.base.len;
 		asym_op->modinv.result.data = result;
 		asym_op->modinv.result.length = data_tc->modinv.result_len;
-		if (rte_cryptodev_asym_xform_capability_check_modlen(capability,
-				xform_tc.modinv.modulus.length)) {
+
+		mod_capa.max_mod_size = xform_tc.modinv.modulus.length;
+		if  (!rte_cryptodev_capa_check_mod(capability,
+			mod_capa)) {
 			snprintf(test_msg, ASYM_TEST_MSG_LEN,
 				"line %u "
 				"FAILED: %s", __LINE__,
@@ -963,38 +968,100 @@  ut_teardown_asym(void)
 	rte_cryptodev_stop(ts_params->valid_devs[0]);
 }
 
-static inline void print_asym_capa(
-		const struct rte_cryptodev_asymmetric_xform_capability *capa)
+static void
+print_rsa_capability(
+	const struct rte_cryptodev_asymmetric_capability *capa)
 {
 	int i = 0;
 
+	printf("\nSupported paddings:");
+	for (; i < 32; i++) {
+		if (capa->rsa.padding & RTE_BIT32(i))
+			printf("\n - %s", rte_crypto_asym_rsa_padding[i]);
+	}
+	printf("\nSupported hash functions:");
+	for (i = 0; i < 32; i++) {
+		if (capa->rsa.hash & RTE_BIT32(i))
+			printf("\n - %s", rte_crypto_auth_algorithm_strings[i]);
+	}
+	printf("\nMaximum key size: ");
+	if (capa->rsa.max_key_size == 0)
+		printf("Unlimited");
+	else
+		printf("%hu", capa->rsa.max_key_size);
+}
+
+static void
+print_supported_curves(uint64_t curves)
+{
+	int i = 0;
+
+	printf("\nSupported elliptic curves:");
+	for (; i < 64; i++) {
+		if (curves & RTE_BIT64(i))
+			printf("\n - %s", rte_crypto_curves_strings[i]);
+	}
+}
+
+static inline void print_asym_capa(
+		const struct rte_cryptodev_asymmetric_capability *capa)
+{
 	printf("\nxform type: %s\n===================\n",
 			rte_crypto_asym_xform_strings[capa->xform_type]);
-	printf("operation supported -");
 
-	for (i = 0; i < RTE_CRYPTO_ASYM_OP_LIST_END; i++) {
-		/* check supported operations */
-		if (rte_cryptodev_asym_xform_capability_check_optype(capa, i))
-			printf(" %s",
-					rte_crypto_asym_op_strings[i]);
-		}
-		switch (capa->xform_type) {
-		case RTE_CRYPTO_ASYM_XFORM_RSA:
-		case RTE_CRYPTO_ASYM_XFORM_MODINV:
-		case RTE_CRYPTO_ASYM_XFORM_MODEX:
-		case RTE_CRYPTO_ASYM_XFORM_DH:
-		case RTE_CRYPTO_ASYM_XFORM_DSA:
-			printf(" modlen: min %d max %d increment %d",
-					capa->modlen.min,
-					capa->modlen.max,
-					capa->modlen.increment);
+	switch (capa->xform_type) {
+	case RTE_CRYPTO_ASYM_XFORM_MODEX:
+	case RTE_CRYPTO_ASYM_XFORM_MODINV:
+		printf("Maximum size of modulus: ");
+		if (capa->mod.max_mod_size == 0)
+			printf("Unlimited");
+		else
+			printf("%hu", capa->mod.max_mod_size);
 		break;
-		case RTE_CRYPTO_ASYM_XFORM_ECDSA:
-		case RTE_CRYPTO_ASYM_XFORM_ECPM:
-		default:
-			break;
-		}
-		printf("\n");
+	case RTE_CRYPTO_ASYM_XFORM_RSA:
+		print_rsa_capability(capa);
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_DH:
+		printf("Maximum group size: ");
+		if (capa->dh.max_group_size == 0)
+			printf("Unlimited");
+		else
+			printf("%hu", capa->dh.max_group_size);
+		printf("\nSupport for private key generation: ");
+		if (capa->dh.priv_key_gen)
+			printf("Yes");
+		else
+			printf("No");
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_DSA:
+		printf("Maximum key size: ");
+		if (capa->dsa.max_key_size == 0)
+			printf("Unlimited");
+		else
+			printf("%hu", capa->dsa.max_key_size);
+		printf("\nSupport for random 'k' generation: ");
+		if (capa->dsa.random_k)
+			printf("Yes");
+		else
+			printf("No");
+		break;
+
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
+		print_supported_curves(capa->ecdsa.curves);
+		printf("\nSupport for random 'k' generation: ");
+		if (capa->ecdsa.random_k)
+			printf("Yes");
+		else
+			printf("No");
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECPM:
+		print_supported_curves(capa->ecpm.curves);
+		break;
+	default:
+		break;
+	}
+	printf("\n");
 }
 
 static int
@@ -1006,7 +1073,7 @@  test_capability(void)
 	const struct rte_cryptodev_capabilities *dev_capa;
 	int i = 0;
 	struct rte_cryptodev_asym_capability_idx idx;
-	const struct rte_cryptodev_asymmetric_xform_capability *capa;
+	const struct rte_cryptodev_asymmetric_capability *capa;
 
 	rte_cryptodev_info_get(dev_id, &dev_info);
 	if (!(dev_info.feature_flags &
@@ -1023,7 +1090,7 @@  test_capability(void)
 		dev_capa = &(dev_info.capabilities[i]);
 		if (dev_info.capabilities[i].op ==
 				RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
-			idx.type = dev_capa->asym.xform_capa.xform_type;
+			idx.type = dev_capa->asym.xform_type;
 
 			capa = rte_cryptodev_asym_capability_get(dev_id,
 				(const struct
@@ -1386,10 +1453,11 @@  test_mod_inv(void)
 	void *sess = NULL;
 	int status = TEST_SUCCESS;
 	struct rte_cryptodev_asym_capability_idx cap_idx;
-	const struct rte_cryptodev_asymmetric_xform_capability *capability;
+	const struct rte_cryptodev_asymmetric_capability *capability;
 	uint8_t input[TEST_DATA_SIZE] = {0};
 	int ret = 0;
 	uint8_t result[sizeof(mod_p)] = { 0 };
+	struct rte_crypto_mod_capability mod_capa = {0};
 
 	if (rte_cryptodev_asym_get_xform_enum(
 		&modinv_xform.xform_type, "modinv") < 0) {
@@ -1408,13 +1476,11 @@  test_mod_inv(void)
 		return TEST_SKIPPED;
 	}
 
-	if (rte_cryptodev_asym_xform_capability_check_modlen(
-		capability,
-		modinv_xform.modinv.modulus.length)) {
-		RTE_LOG(ERR, USER1,
-				 "Invalid MODULUS length specified\n");
-				return TEST_SKIPPED;
-		}
+	mod_capa.max_mod_size = modinv_xform.modinv.modulus.length;
+	if  (!rte_cryptodev_capa_check_mod(capability, mod_capa)) {
+		RTE_LOG(ERR, USER1, "Invalid MODULUS length specified\n");
+		return TEST_SKIPPED;
+	}
 
 	ret = rte_cryptodev_asym_session_create(dev_id, &modinv_xform, sess_mpool, &sess);
 	if (ret < 0) {
@@ -1499,7 +1565,8 @@  test_mod_exp(void)
 	void *sess = NULL;
 	int status = TEST_SUCCESS;
 	struct rte_cryptodev_asym_capability_idx cap_idx;
-	const struct rte_cryptodev_asymmetric_xform_capability *capability;
+	const struct rte_cryptodev_asymmetric_capability *capability;
+	struct rte_crypto_mod_capability mod_capa = {0};
 	uint8_t input[TEST_DATA_SIZE] = {0};
 	int ret = 0;
 	uint8_t result[sizeof(mod_p)] = { 0 };
@@ -1522,12 +1589,11 @@  test_mod_exp(void)
 		return TEST_SKIPPED;
 	}
 
-	if (rte_cryptodev_asym_xform_capability_check_modlen(
-			capability, modex_xform.modex.modulus.length)) {
-		RTE_LOG(ERR, USER1,
-				"Invalid MODULUS length specified\n");
-				return TEST_SKIPPED;
-		}
+	mod_capa.max_mod_size = modex_xform.modex.modulus.length;
+	if  (!rte_cryptodev_capa_check_mod(capability, mod_capa)) {
+		RTE_LOG(ERR, USER1, "Invalid MODULUS length specified\n");
+		return TEST_SKIPPED;
+	}
 
 	/* Create op, create session, and process packets. 8< */
 	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
@@ -1785,6 +1851,8 @@  test_ecdsa_sign_verify(enum curve curve_id)
 	struct rte_crypto_asym_xform xform;
 	struct rte_crypto_asym_op *asym_op;
 	struct rte_cryptodev_info dev_info;
+	struct rte_cryptodev_asym_capability_idx idx;
+	const struct rte_cryptodev_asymmetric_capability *capabilities;
 	struct rte_crypto_op *op = NULL;
 	int ret, status = TEST_SUCCESS;
 
@@ -1814,6 +1882,25 @@  test_ecdsa_sign_verify(enum curve curve_id)
 
 	rte_cryptodev_info_get(dev_id, &dev_info);
 
+	struct rte_crypto_ecdsa_capability capa = {
+		.curves = RTE_BIT32(input_params.curve),
+		.random_k = 0
+	};
+
+	idx.type = RTE_CRYPTO_ASYM_XFORM_ECDSA;
+	capabilities = rte_cryptodev_asym_capability_get(dev_id,
+		(const struct
+		rte_cryptodev_asym_capability_idx *) &idx);
+
+	if (capabilities == NULL) {
+		status = TEST_SKIPPED;
+		goto exit;
+	}
+	if (!rte_cryptodev_capa_check_ecdsa(capabilities, capa)) {
+		status = TEST_SKIPPED;
+		goto exit;
+	}
+
 	/* Setup crypto op data structure */
 	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
 	if (op == NULL) {
@@ -1962,6 +2049,8 @@  test_ecdsa_sign_verify_all_curve(void)
 		status = test_ecdsa_sign_verify(curve_id);
 		if (status == TEST_SUCCESS) {
 			msg = "succeeded";
+		} else if (status == TEST_SKIPPED) {
+			continue;
 		} else {
 			msg = "failed";
 			overall_status = status;
@@ -1987,6 +2076,8 @@  test_ecpm(enum curve curve_id)
 	struct rte_crypto_asym_xform xform;
 	struct rte_crypto_asym_op *asym_op;
 	struct rte_cryptodev_info dev_info;
+	struct rte_cryptodev_asym_capability_idx idx;
+	const struct rte_cryptodev_asymmetric_capability *capabilities;
 	struct rte_crypto_op *op = NULL;
 	int ret, status = TEST_SUCCESS;
 
@@ -2016,6 +2107,24 @@  test_ecpm(enum curve curve_id)
 
 	rte_cryptodev_info_get(dev_id, &dev_info);
 
+	struct rte_crypto_ecdsa_capability capa = {
+		.curves = RTE_BIT32(input_params.curve)
+	};
+
+	idx.type = RTE_CRYPTO_ASYM_XFORM_ECPM;
+	capabilities = rte_cryptodev_asym_capability_get(dev_id,
+		(const struct
+		rte_cryptodev_asym_capability_idx *) &idx);
+
+	if (capabilities == NULL) {
+		status = TEST_SKIPPED;
+		goto exit;
+	}
+	if (!rte_cryptodev_capa_check_ecdsa(capabilities, capa)) {
+		status = TEST_SKIPPED;
+		goto exit;
+	}
+
 	/* Setup crypto op data structure */
 	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
 	if (op == NULL) {
@@ -2124,6 +2233,8 @@  test_ecpm_all_curve(void)
 		status = test_ecpm(curve_id);
 		if (status == TEST_SUCCESS) {
 			msg = "succeeded";
+		} else if (status == TEST_SKIPPED) {
+			continue;
 		} else {
 			msg = "failed";
 			overall_status = status;
@@ -2162,7 +2273,12 @@  static struct unit_test_suite cryptodev_qat_asym_testsuite  = {
 	.setup = testsuite_setup,
 	.teardown = testsuite_teardown,
 	.unit_test_cases = {
+		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_capability),
 		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_one_by_one),
+		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
+			     test_ecdsa_sign_verify_all_curve),
+		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
+				test_ecpm_all_curve),
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
diff --git a/app/test/test_event_crypto_adapter.c b/app/test/test_event_crypto_adapter.c
index 2ecc7e2cea..9a62241371 100644
--- a/app/test/test_event_crypto_adapter.c
+++ b/app/test/test_event_crypto_adapter.c
@@ -450,7 +450,7 @@  test_session_with_op_forward_mode(void)
 static int
 test_asym_op_forward_mode(uint8_t session_less)
 {
-	const struct rte_cryptodev_asymmetric_xform_capability *capability;
+	const struct rte_cryptodev_asymmetric_capability *capability;
 	struct rte_cryptodev_asym_capability_idx cap_idx;
 	struct rte_crypto_asym_xform xform_tc;
 	union rte_event_crypto_metadata m_data;
@@ -458,6 +458,7 @@  test_asym_op_forward_mode(uint8_t session_less)
 	struct rte_crypto_asym_op *asym_op;
 	struct rte_crypto_op *op;
 	uint8_t input[4096] = {0};
+	struct rte_crypto_mod_capability mod_capa = {0};
 	uint8_t *result = NULL;
 	struct rte_event ev;
 	void *sess = NULL;
@@ -503,8 +504,9 @@  test_asym_op_forward_mode(uint8_t session_less)
 	asym_op->modex.base.length = modex_test_case.base.len;
 	asym_op->modex.result.data = result;
 	asym_op->modex.result.length = modex_test_case.result_len;
-	if (rte_cryptodev_asym_xform_capability_check_modlen(capability,
-			xform_tc.modex.modulus.length)) {
+
+	mod_capa.max_mod_size = xform_tc.modex.modulus.length;
+	if  (!rte_cryptodev_capa_check_mod(capability, mod_capa)) {
 		RTE_LOG(INFO, USER1,
 			"line %u FAILED: %s", __LINE__,
 			"Invalid MODULUS length specified");
@@ -784,7 +786,7 @@  test_session_with_op_new_mode(void)
 static int
 test_asym_op_new_mode(uint8_t session_less)
 {
-	const struct rte_cryptodev_asymmetric_xform_capability *capability;
+	const struct rte_cryptodev_asymmetric_capability *capability;
 	struct rte_cryptodev_asym_capability_idx cap_idx;
 	struct rte_crypto_asym_xform xform_tc;
 	union rte_event_crypto_metadata m_data;
@@ -792,6 +794,7 @@  test_asym_op_new_mode(uint8_t session_less)
 	struct rte_crypto_asym_op *asym_op;
 	struct rte_crypto_op *op;
 	uint8_t input[4096] = {0};
+	struct rte_crypto_mod_capability mod_capa = {0};
 	uint8_t *result = NULL;
 	void *sess = NULL;
 	uint32_t cap;
@@ -835,8 +838,9 @@  test_asym_op_new_mode(uint8_t session_less)
 	asym_op->modex.base.length = modex_test_case.base.len;
 	asym_op->modex.result.data = result;
 	asym_op->modex.result.length = modex_test_case.result_len;
-	if (rte_cryptodev_asym_xform_capability_check_modlen(capability,
-			xform_tc.modex.modulus.length)) {
+
+	mod_capa.max_mod_size = xform_tc.modex.modulus.length;
+	if  (!rte_cryptodev_capa_check_mod(capability, mod_capa)) {
 		RTE_LOG(INFO, USER1,
 			"line %u FAILED: %s", __LINE__,
 			"Invalid MODULUS length specified");
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index 16ec5e15eb..e734fc2a69 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -7,6 +7,7 @@ 
 #include <rte_common.h>
 #include <rte_malloc.h>
 #include <cryptodev_pmd.h>
+#include <rte_bitops.h>
 
 #include "openssl_pmd_private.h"
 #include "compat.h"
@@ -470,103 +471,82 @@  static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
 			}, }
 		}, }
 	},
-	{	/* RSA */
+	{	/* Modular exponentiation */
 		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
 		{.asym = {
-			.xform_capa = {
-				.xform_type = RTE_CRYPTO_ASYM_XFORM_RSA,
-				.op_types = ((1 << RTE_CRYPTO_ASYM_OP_SIGN) |
-					(1 << RTE_CRYPTO_ASYM_OP_VERIFY) |
-					(1 << RTE_CRYPTO_ASYM_OP_ENCRYPT) |
-					(1 << RTE_CRYPTO_ASYM_OP_DECRYPT)),
-				{
-				.modlen = {
-				/* min length is based on openssl rsa keygen */
-				.min = 30,
-				/* value 0 symbolizes no limit on max length */
-				.max = 0,
-				.increment = 1
-				}, }
+			.xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX,
+			.mod = {
+				.max_mod_size = 0
+				}
 			}
-		},
 		}
 	},
-	{	/* modexp */
+	{	/* Modular multiplicative inverse */
 		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
 		{.asym = {
-			.xform_capa = {
-				.xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX,
-				.op_types = 0,
-				{
-				.modlen = {
-				/* value 0 symbolizes no limit on min length */
-				.min = 0,
-				/* value 0 symbolizes no limit on max length */
-				.max = 0,
-				.increment = 1
-				}, }
+			.xform_type = RTE_CRYPTO_ASYM_XFORM_MODINV,
+			.mod = {
+				.max_mod_size = 0
+				}
 			}
-		},
 		}
 	},
-	{	/* modinv */
+	{	/* RSA */
 		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
 		{.asym = {
-			.xform_capa = {
-				.xform_type = RTE_CRYPTO_ASYM_XFORM_MODINV,
-				.op_types = 0,
-				{
-				.modlen = {
-				/* value 0 symbolizes no limit on min length */
-				.min = 0,
-				/* value 0 symbolizes no limit on max length */
-				.max = 0,
-				.increment = 1
-				}, }
+			.xform_type = RTE_CRYPTO_ASYM_XFORM_RSA,
+			.rsa = {
+				.padding =
+					RTE_BIT32(RTE_CRYPTO_RSA_PADDING_NONE) |
+					RTE_BIT32(RTE_CRYPTO_RSA_PADDING_PKCS1_5),
+				.hash =
+					RTE_BIT32(RTE_CRYPTO_AUTH_MD5) |
+					RTE_BIT32(RTE_CRYPTO_AUTH_SHA1)	|
+					RTE_BIT32(RTE_CRYPTO_AUTH_SHA224) |
+					RTE_BIT32(RTE_CRYPTO_AUTH_SHA256) |
+					RTE_BIT32(RTE_CRYPTO_AUTH_SHA384) |
+					RTE_BIT32(RTE_CRYPTO_AUTH_SHA512),
+				.max_key_size = 0
+				}
 			}
-		},
 		}
 	},
-	{	/* dh */
+	{	/* Diffie-Hellman */
 		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
 		{.asym = {
-			.xform_capa = {
-				.xform_type = RTE_CRYPTO_ASYM_XFORM_DH,
-				.op_types =
-				((1<<RTE_CRYPTO_ASYM_KE_PRIVATE_KEY_GENERATE) |
-				(1 << RTE_CRYPTO_ASYM_KE_PUBLIC_KEY_GENERATE |
-				(1 <<
-				RTE_CRYPTO_ASYM_KE_SHARED_SECRET_COMPUTE))),
-				{
-				.modlen = {
-				/* value 0 symbolizes no limit on min length */
-				.min = 0,
-				/* value 0 symbolizes no limit on max length */
-				.max = 0,
-				.increment = 1
-				}, }
+			.xform_type = RTE_CRYPTO_ASYM_XFORM_DH,
+			.dh = {
+				.max_group_size = 0,
+				.priv_key_gen = 1
+				}
 			}
-		},
 		}
 	},
-	{	/* dsa */
+	{	/* DSA */
 		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
 		{.asym = {
-			.xform_capa = {
-				.xform_type = RTE_CRYPTO_ASYM_XFORM_DSA,
-				.op_types =
-				((1<<RTE_CRYPTO_ASYM_OP_SIGN) |
-				(1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
-				{
-				.modlen = {
-				/* value 0 symbolizes no limit on min length */
-				.min = 0,
-				/* value 0 symbolizes no limit on max length */
-				.max = 0,
-				.increment = 1
-				}, }
+			.xform_type = RTE_CRYPTO_ASYM_XFORM_DSA,
+			.dsa = {
+				.max_key_size = 0,
+				.random_k = 1
+				}
+			}
+		}
+	},
+	{	/* ECDSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA,
+			.ecdsa = {
+				.curves =
+					RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP192R1) |
+					RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP224R1) |
+					RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP256R1) |
+					RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP384R1) |
+					RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP521R1),
+				.random_k = 1
+				}
 			}
-		},
 		}
 	},
 
diff --git a/drivers/crypto/qat/dev/qat_asym_pmd_gen1.c b/drivers/crypto/qat/dev/qat_asym_pmd_gen1.c
index 4499fdaf2d..d5144bca84 100644
--- a/drivers/crypto/qat/dev/qat_asym_pmd_gen1.c
+++ b/drivers/crypto/qat/dev/qat_asym_pmd_gen1.c
@@ -28,16 +28,64 @@  struct rte_cryptodev_ops qat_asym_crypto_ops_gen1 = {
 };
 
 static struct rte_cryptodev_capabilities qat_asym_crypto_caps_gen1[] = {
-	QAT_ASYM_CAP(MODEX,
-		0, 1, 512, 1),
-	QAT_ASYM_CAP(MODINV,
-		0, 1, 512, 1),
-	QAT_ASYM_CAP(RSA,
-			((1 << RTE_CRYPTO_ASYM_OP_SIGN) |
-			(1 << RTE_CRYPTO_ASYM_OP_VERIFY) |
-			(1 << RTE_CRYPTO_ASYM_OP_ENCRYPT) |
-			(1 << RTE_CRYPTO_ASYM_OP_DECRYPT)),
-			64, 512, 64),
+	{	/* Modular exponentiation */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX,
+			.mod = {
+				.max_mod_size = 4096
+				}
+			}
+		}
+	},
+	{	/* Modular multiplicative inverse */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_type = RTE_CRYPTO_ASYM_XFORM_MODINV,
+			.mod = {
+				.max_mod_size = 4096
+				}
+			}
+		}
+	},
+	{	/* RSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_type = RTE_CRYPTO_ASYM_XFORM_RSA,
+			.rsa = {
+				.padding =
+					RTE_BIT32(RTE_CRYPTO_RSA_PADDING_NONE),
+				.hash = 0,
+				.max_key_size = 4096
+				}
+			}
+		}
+	},
+	{	/* ECDSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA,
+			.ecdsa = {
+				.curves =
+					RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP256R1) |
+					RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP521R1),
+				.random_k = 0
+				}
+			}
+		}
+	},
+	{	/* ECPM */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_type = RTE_CRYPTO_ASYM_XFORM_ECPM,
+			.ecdsa = {
+				.curves =
+					RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP256R1) |
+					RTE_BIT64(RTE_CRYPTO_EC_GROUP_SECP521R1)
+				}
+			}
+		}
+	},
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
 
diff --git a/lib/cryptodev/rte_crypto_asym.h b/lib/cryptodev/rte_crypto_asym.h
index d90a7a1957..41b22450d3 100644
--- a/lib/cryptodev/rte_crypto_asym.h
+++ b/lib/cryptodev/rte_crypto_asym.h
@@ -41,6 +41,14 @@  rte_crypto_asym_ke_strings[];
 extern const char *
 rte_crypto_asym_op_strings[];
 
+/** RSA padding type name strings */
+extern const char *
+rte_crypto_asym_rsa_padding[];
+
+/** Elliptic curves name strings */
+extern const char *
+rte_crypto_curves_strings[];
+
 /**
  * Buffer to hold crypto params required for asym operations.
  *
@@ -265,6 +273,46 @@  struct rte_crypto_rsa_padding {
 	 */
 };
 
+struct rte_crypto_mod_capability {
+	uint16_t max_mod_size;
+	/**< Maximum supported modulus size in bytes, 0 means no limit */
+};
+
+struct rte_crypto_rsa_capability {
+	uint32_t padding;
+	/**< List of supported paddings */
+	uint32_t hash;
+	/**< List of supported hash functions */
+	uint32_t max_key_size;
+	/**< Maximum supported key size in bytes, 0 means no limit */
+};
+
+struct rte_crypto_dh_capability {
+	uint16_t max_group_size;
+	/**< Maximum group  in bytes, 0 means no limit */
+	uint8_t priv_key_gen;
+	/**< Does PMD supports private key generation generation */
+};
+
+struct rte_crypto_dsa_capability {
+	uint16_t max_key_size;
+	/**< Maximum supported key size in bytes, 0 means no limit */
+	uint8_t random_k;
+	/**< Does PMD supports random 'k' generation */
+};
+
+struct rte_crypto_ecdsa_capability {
+	uint64_t curves;
+	/**< Supported elliptic curve ids */
+	uint8_t random_k;
+	/**< Does PMD supports random 'k' generation */
+};
+
+struct rte_crypto_ecpm_capability {
+	uint64_t curves;
+	/**< Supported elliptic curve ids */
+};
+
 /**
  * Asymmetric RSA transform data
  *
diff --git a/lib/cryptodev/rte_cryptodev.c b/lib/cryptodev/rte_cryptodev.c
index 57ee6b3f07..b1ad1112fe 100644
--- a/lib/cryptodev/rte_cryptodev.c
+++ b/lib/cryptodev/rte_cryptodev.c
@@ -190,6 +190,27 @@  const char *rte_crypto_asym_ke_strings[] = {
 };
 
 /**
+ * RSA padding string identifiers
+ */
+const char *rte_crypto_asym_rsa_padding[] = {
+	[RTE_CRYPTO_RSA_PADDING_NONE] = "RTE_CRYPTO_RSA_PADDING_NONE",
+	[RTE_CRYPTO_RSA_PADDING_PKCS1_5] = "RTE_CRYPTO_RSA_PADDING_PKCS1_5",
+	[RTE_CRYPTO_RSA_PADDING_OAEP] = "RTE_CRYPTO_RSA_PADDING_OAEP",
+	[RTE_CRYPTO_RSA_PADDING_PSS] = "RTE_CRYPTO_RSA_PADDING_PSS"
+};
+
+/**
+ * Elliptic curves string identifiers
+ */
+const char *rte_crypto_curves_strings[] = {
+	[RTE_CRYPTO_EC_GROUP_SECP192R1] = "RTE_CRYPTO_EC_GROUP_SECP192R1",
+	[RTE_CRYPTO_EC_GROUP_SECP224R1] = "RTE_CRYPTO_EC_GROUP_SECP224R1",
+	[RTE_CRYPTO_EC_GROUP_SECP256R1] = "RTE_CRYPTO_EC_GROUP_SECP256R1",
+	[RTE_CRYPTO_EC_GROUP_SECP384R1] = "RTE_CRYPTO_EC_GROUP_SECP384R1",
+	[RTE_CRYPTO_EC_GROUP_SECP521R1] = "RTE_CRYPTO_EC_GROUP_SECP521R1",
+};
+
+/**
  * The private data structure stored in the sym session mempool private data.
  */
 struct rte_cryptodev_sym_session_pool_private_data {
@@ -347,7 +368,7 @@  param_range_check(uint16_t size, const struct rte_crypto_param_range *range)
 	return -1;
 }
 
-const struct rte_cryptodev_asymmetric_xform_capability *
+const struct rte_cryptodev_asymmetric_capability *
 rte_cryptodev_asym_capability_get(uint8_t dev_id,
 		const struct rte_cryptodev_asym_capability_idx *idx)
 {
@@ -363,8 +384,8 @@  rte_cryptodev_asym_capability_get(uint8_t dev_id,
 		if (capability->op != RTE_CRYPTO_OP_TYPE_ASYMMETRIC)
 			continue;
 
-		if (capability->asym.xform_capa.xform_type == idx->type)
-			return &capability->asym.xform_capa;
+		if (capability->asym.xform_type == idx->type)
+			return &capability->asym;
 	}
 	return NULL;
 };
@@ -456,6 +477,59 @@  rte_cryptodev_asym_xform_capability_check_modlen(
 	return 0;
 }
 
+int
+rte_cryptodev_capa_check_mod(
+	const struct rte_cryptodev_asymmetric_capability *capa,
+	struct rte_crypto_mod_capability mod)
+{
+	if (capa->mod.max_mod_size == 0)
+		return 1;
+
+	if (mod.max_mod_size <= capa->mod.max_mod_size)
+		return 1;
+	else
+		return 0;
+}
+
+int
+rte_cryptodev_capa_check_rsa(
+	const struct rte_cryptodev_asymmetric_capability *capa,
+	struct rte_crypto_rsa_capability rsa)
+{
+	if (rsa.padding != (capa->rsa.padding & rsa.padding))
+		return 0;
+	if (rsa.hash != (capa->rsa.hash & rsa.hash))
+		return 0;
+	if (capa->rsa.max_key_size == 0)
+		return 1;
+	if (rsa.max_key_size <= capa->rsa.max_key_size)
+		return 1;
+	else
+		return 0;
+}
+
+int
+rte_cryptodev_capa_check_ecdsa(
+	const struct rte_cryptodev_asymmetric_capability *capa,
+	struct rte_crypto_ecdsa_capability ecdsa)
+{
+	if (ecdsa.curves != (capa->ecdsa.curves & ecdsa.curves))
+		return 0;
+	if (ecdsa.random_k == 1 && capa->ecdsa.random_k == 0)
+		return 0;
+	return 1;
+}
+
+int
+rte_cryptodev_capa_check_ecpm(
+	const struct rte_cryptodev_asymmetric_capability *capa,
+	struct rte_crypto_ecpm_capability ecpm)
+{
+	if (ecpm.curves != (capa->ecpm.curves & ecpm.curves))
+		return 0;
+	return 1;
+}
+
 /* spinlock for crypto device enq callbacks */
 static rte_spinlock_t rte_cryptodev_callback_lock = RTE_SPINLOCK_INITIALIZER;
 
diff --git a/lib/cryptodev/rte_cryptodev.h b/lib/cryptodev/rte_cryptodev.h
index 2c2c2edeb7..6c5bd819b2 100644
--- a/lib/cryptodev/rte_cryptodev.h
+++ b/lib/cryptodev/rte_cryptodev.h
@@ -184,6 +184,19 @@  struct rte_cryptodev_asymmetric_xform_capability {
  *
  */
 struct rte_cryptodev_asymmetric_capability {
+	enum rte_crypto_asym_xform_type xform_type;
+	/**< Asymmetric transform type */
+	uint32_t op_types;
+	/**< bitmask for supported rte_crypto_asym_op_type */
+	union {
+		struct rte_crypto_mod_capability mod;
+		struct rte_crypto_rsa_capability rsa;
+		struct rte_crypto_dh_capability dh;
+		struct rte_crypto_dsa_capability dsa;
+		struct rte_crypto_ecdsa_capability ecdsa;
+		struct rte_crypto_ecpm_capability ecpm;
+	};
+
 	struct rte_cryptodev_asymmetric_xform_capability xform_capa;
 };
 
@@ -247,7 +260,7 @@  rte_cryptodev_sym_capability_get(uint8_t dev_id,
  *   - Return NULL if the capability not exist.
  */
 __rte_experimental
-const struct rte_cryptodev_asymmetric_xform_capability *
+const struct rte_cryptodev_asymmetric_capability *
 rte_cryptodev_asym_capability_get(uint8_t dev_id,
 		const struct rte_cryptodev_asym_capability_idx *idx);
 
@@ -339,6 +352,66 @@  rte_cryptodev_asym_xform_capability_check_modlen(
 		uint16_t modlen);
 
 /**
+ * Check if requested Modexp features are supported
+ *
+ * @param	capability	Description of the asymmetric crypto capability.
+ * @param	mod		Modexp requested capability.
+ *
+ * @return
+ *   - Return 1 if the parameters are in range of the capability.
+ *   - Return 0 if the parameters are out of range of the capability.
+ */
+__rte_experimental
+int
+rte_cryptodev_capa_check_mod(
+	const struct rte_cryptodev_asymmetric_capability *capa,
+	struct rte_crypto_mod_capability mod);
+/**
+ * Check if requested RSA features are supported
+ *
+ * @param	capability	Description of the asymmetric crypto capability.
+ * @param	rsa		RSA requested capability.
+ *
+ * @return
+ *   - Return 1 if the parameters are in range of the capability.
+ *   - Return 0 if the parameters are out of range of the capability.
+ */
+__rte_experimental
+int
+rte_cryptodev_capa_check_rsa(
+	const struct rte_cryptodev_asymmetric_capability *capa,
+	struct rte_crypto_rsa_capability rsa);
+/**
+ * Check if requested ECDSA features are supported
+ *
+ * @param	capability	Description of the asymmetric crypto capability.
+ * @param	ecdsa		ECDSA requested capability.
+ *
+ * @return
+ *   - Return 1 if the parameters are in range of the capability.
+ *   - Return 0 if the parameters are out of range of the capability.
+ */
+__rte_experimental
+int
+rte_cryptodev_capa_check_ecdsa(
+	const struct rte_cryptodev_asymmetric_capability *capa,
+	struct rte_crypto_ecdsa_capability ecdsa);
+/**
+ * Check if requested ECPM features are supported
+ *
+ * @param	capability	Description of the asymmetric crypto capability.
+ * @param	ecpm		ECPM requested capability.
+ *
+ * @return
+ *   - Return 1 if the parameters are in range of the capability.
+ *   - Return 0 if the parameters are out of range of the capability.
+ */
+__rte_experimental
+int
+rte_cryptodev_capa_check_ecpm(
+	const struct rte_cryptodev_asymmetric_capability *capa,
+	struct rte_crypto_ecpm_capability ecpm);
+/**
  * Provide the cipher algorithm enum, given an algorithm string
  *
  * @param	algo_enum	A pointer to the cipher algorithm
diff --git a/lib/cryptodev/version.map b/lib/cryptodev/version.map
index f0abfaa47d..4d93b9a947 100644
--- a/lib/cryptodev/version.map
+++ b/lib/cryptodev/version.map
@@ -108,6 +108,10 @@  EXPERIMENTAL {
 
 	#added in 22.07
 	rte_cryptodev_session_event_mdata_set;
+	rte_cryptodev_capa_check_mod;
+	rte_cryptodev_capa_check_rsa;
+	rte_cryptodev_capa_check_ecdsa;
+	rte_cryptodev_capa_check_ecpm;
 };
 
 INTERNAL {