get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/116942/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 116942,
    "url": "http://patches.dpdk.org/api/patches/116942/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/da6c7aec7de7da40883d3dc2ce4792ef7969c958.1664263264.git.gmuthukrishn@marvell.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<da6c7aec7de7da40883d3dc2ce4792ef7969c958.1664263264.git.gmuthukrishn@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/da6c7aec7de7da40883d3dc2ce4792ef7969c958.1664263264.git.gmuthukrishn@marvell.com",
    "date": "2022-09-27T07:26:10",
    "name": "[v2,5/7] examples/fips_validation: add asymmetric validation",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "0174db3ab361585b4144f0fdfda0698250d062ee",
    "submitter": {
        "id": 2301,
        "url": "http://patches.dpdk.org/api/people/2301/?format=api",
        "name": "Gowrishankar Muthukrishnan",
        "email": "gmuthukrishn@marvell.com"
    },
    "delegate": {
        "id": 6690,
        "url": "http://patches.dpdk.org/api/users/6690/?format=api",
        "username": "akhil",
        "first_name": "akhil",
        "last_name": "goyal",
        "email": "gakhil@marvell.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/da6c7aec7de7da40883d3dc2ce4792ef7969c958.1664263264.git.gmuthukrishn@marvell.com/mbox/",
    "series": [
        {
            "id": 24851,
            "url": "http://patches.dpdk.org/api/series/24851/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=24851",
            "date": "2022-09-27T07:26:05",
            "name": "FIPS asymmetric validation",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/24851/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/116942/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/116942/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 6110EA00C2;\n\tTue, 27 Sep 2022 09:26:55 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id C5A6942B6C;\n\tTue, 27 Sep 2022 09:26:35 +0200 (CEST)",
            "from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com\n [67.231.156.173])\n by mails.dpdk.org (Postfix) with ESMTP id EDA1842B6C\n for <dev@dpdk.org>; Tue, 27 Sep 2022 09:26:33 +0200 (CEST)",
            "from pps.filterd (m0045851.ppops.net [127.0.0.1])\n by mx0b-0016f401.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id\n 28R4B79G016222;\n Tue, 27 Sep 2022 00:26:33 -0700",
            "from dc5-exch01.marvell.com ([199.233.59.181])\n by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3jt1dp8wpw-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT);\n Tue, 27 Sep 2022 00:26:32 -0700",
            "from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH01.marvell.com\n (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.2;\n Tue, 27 Sep 2022 00:26:30 -0700",
            "from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com\n (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.2 via Frontend\n Transport; Tue, 27 Sep 2022 00:26:30 -0700",
            "from localhost.localdomain (unknown [10.28.34.38])\n by maili.marvell.com (Postfix) with ESMTP id 88A173F7080;\n Tue, 27 Sep 2022 00:26:28 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com;\n h=from : to : cc :\n subject : date : message-id : in-reply-to : references : mime-version :\n content-transfer-encoding : content-type; s=pfpt0220;\n bh=rf3865G7nFPh10PZG0Ttg1170OQxrO/lV7rN12Q6XjY=;\n b=D8+rs1/vzc+JAEALK3Zqra4Rzs4a74dRVeP3NJVxoFQ5mdoxfZkK5sP8TeLUmMCpLqgX\n hkAuDbWUcWiEyU6RmWlgJet05L5oOVfdqavx9HDSAfprMHf82Ve8Rqb4KAYxqh4Uo2Pr\n TwpfvhHhK1bWA2KqAF5XwaqqnMJNhv4SyhhYXkKERZjHSrO6NzBkUHp9xw2o4Yp9026X\n 7iB3hbe2SbU80lkBEdDjOZNZM8SNZlyvQ8Q0vhWx8UHIRWbOg973WGR3Zd44miPo0e32\n RmNrqKfUb5MFer4jftLNkgAjxxAAu++EixkBZz0q5PwrW5FGoI5iDY6Mj8bKEUcoWjEi GA==",
        "From": "Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>",
        "To": "<dev@dpdk.org>",
        "CC": "Anoob Joseph <anoobj@marvell.com>, Fan Zhang <roy.fan.zhang@intel.com>,\n Brian Dooley <brian.dooley@intel.com>,\n Akhil Goyal <gakhil@marvell.com>, <jerinj@marvell.com>,\n Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>",
        "Subject": "[v2 5/7] examples/fips_validation: add asymmetric validation",
        "Date": "Tue, 27 Sep 2022 12:56:10 +0530",
        "Message-ID": "\n <da6c7aec7de7da40883d3dc2ce4792ef7969c958.1664263264.git.gmuthukrishn@marvell.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<cover.1664263264.git.gmuthukrishn@marvell.com>",
        "References": "<cover.1664263264.git.gmuthukrishn@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Proofpoint-ORIG-GUID": "3j9u8U0NWt5kwwL9Amqbd_62LrJ54F0h",
        "X-Proofpoint-GUID": "3j9u8U0NWt5kwwL9Amqbd_62LrJ54F0h",
        "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.528,FMLib:17.11.122.1\n definitions=2022-09-27_02,2022-09-22_02,2022-06-22_01",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "Add support for asymmetric crypto validation starting with RSA.\nFor the generation of crypto values which is multiprecision in\nmath, openssl library is used only for this purpose.\n\nSigned-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>\nAcked-by: Brian Dooley <brian.dooley@intel.com>\n\n--\nv2:\n - improved handling priv key type.\n---\n config/meson.build                            |   6 +\n doc/guides/sample_app_ug/fips_validation.rst  |   1 +\n examples/fips_validation/fips_validation.c    |   2 +\n examples/fips_validation/fips_validation.h    |  47 +-\n .../fips_validation/fips_validation_gcm.c     |   8 +-\n .../fips_validation/fips_validation_rsa.c     | 520 ++++++++++++++++++\n examples/fips_validation/main.c               | 464 +++++++++++++---\n examples/fips_validation/meson.build          |   6 +\n 8 files changed, 962 insertions(+), 92 deletions(-)\n create mode 100644 examples/fips_validation/fips_validation_rsa.c",
    "diff": "diff --git a/config/meson.build b/config/meson.build\nindex 7f7b6c92fd..ed21a8e470 100644\n--- a/config/meson.build\n+++ b/config/meson.build\n@@ -226,6 +226,12 @@ if jansson_dep.found()\n     dpdk_conf.set('RTE_HAS_JANSSON', 1)\n endif\n \n+# check for openssl\n+openssl_dep = dependency('openssl', required: false, method: 'pkg-config')\n+if openssl_dep.found()\n+    dpdk_conf.set('RTE_HAS_OPENSSL', 1)\n+endif\n+\n # check for pcap\n pcap_dep = dependency('libpcap', required: false, method: 'pkg-config')\n pcap_lib = is_windows ? 'wpcap' : 'pcap'\ndiff --git a/doc/guides/sample_app_ug/fips_validation.rst b/doc/guides/sample_app_ug/fips_validation.rst\nindex 33a8c97575..5e9ad2d006 100644\n--- a/doc/guides/sample_app_ug/fips_validation.rst\n+++ b/doc/guides/sample_app_ug/fips_validation.rst\n@@ -66,6 +66,7 @@ ACVP\n     * SHA (1, 256, 384, 512) - AFT, MCT\n     * TDES-CBC - AFT, MCT\n     * TDES-ECB - AFT, MCT\n+    * RSA\n \n \n Application Information\ndiff --git a/examples/fips_validation/fips_validation.c b/examples/fips_validation/fips_validation.c\nindex be0634c3ac..5d485a2bd5 100644\n--- a/examples/fips_validation/fips_validation.c\n+++ b/examples/fips_validation/fips_validation.c\n@@ -471,6 +471,8 @@ fips_test_parse_one_json_vector_set(void)\n \telse if (strstr(algo_str, \"TDES-CBC\") ||\n \t\tstrstr(algo_str, \"TDES-ECB\"))\n \t\tinfo.algo = FIPS_TEST_ALGO_TDES;\n+\telse if (strstr(algo_str, \"RSA\"))\n+\t\tinfo.algo = FIPS_TEST_ALGO_RSA;\n \telse\n \t\treturn -EINVAL;\n \ndiff --git a/examples/fips_validation/fips_validation.h b/examples/fips_validation/fips_validation.h\nindex 43e5ffe4b0..ed59322635 100644\n--- a/examples/fips_validation/fips_validation.h\n+++ b/examples/fips_validation/fips_validation.h\n@@ -42,6 +42,7 @@ enum fips_test_algorithms {\n \t\tFIPS_TEST_ALGO_HMAC,\n \t\tFIPS_TEST_ALGO_TDES,\n \t\tFIPS_TEST_ALGO_SHA,\n+\t\tFIPS_TEST_ALGO_RSA,\n \t\tFIPS_TEST_ALGO_MAX\n };\n \n@@ -55,6 +56,9 @@ enum file_types {\n enum fips_test_op {\n \tFIPS_TEST_ENC_AUTH_GEN = 1,\n \tFIPS_TEST_DEC_AUTH_VERIF,\n+\tFIPS_TEST_ASYM_KEYGEN,\n+\tFIPS_TEST_ASYM_SIGGEN,\n+\tFIPS_TEST_ASYM_SIGVER\n };\n \n #define MAX_LINE_PER_VECTOR            16\n@@ -78,11 +82,22 @@ struct fips_test_vector {\n \t\t\tstruct fips_val aad;\n \t\t} aead;\n \t};\n+\tstruct {\n+\t\tstruct fips_val seed;\n+\t\tstruct fips_val signature;\n+\t\tstruct fips_val e;\n+\t\tstruct fips_val n;\n+\t\tstruct fips_val d;\n+\t\tstruct fips_val p;\n+\t\tstruct fips_val q;\n+\t\tstruct fips_val dp;\n+\t\tstruct fips_val dq;\n+\t\tstruct fips_val qinv;\n+\t} rsa;\n \n \tstruct fips_val pt;\n \tstruct fips_val ct;\n \tstruct fips_val iv;\n-\n \tenum rte_crypto_op_status status;\n };\n \n@@ -138,6 +153,12 @@ enum fips_sha_test_types {\n \tSHA_MCT\n };\n \n+enum fips_rsa_test_types {\n+\tRSA_AFT = 0,\n+\tRSA_GDT,\n+\tRSA_KAT\n+};\n+\n struct aesavs_interim_data {\n \tenum fips_aesavs_test_types test_type;\n \tuint32_t cipher_algo;\n@@ -164,8 +185,9 @@ struct ccm_interim_data {\n };\n \n struct sha_interim_data {\n-\tenum fips_sha_test_types test_type;\n+\t/* keep algo always on top as it is also used in asym digest */\n \tenum rte_crypto_auth_algorithm algo;\n+\tenum fips_sha_test_types test_type;\n };\n \n struct gcm_interim_data {\n@@ -182,6 +204,14 @@ struct xts_interim_data {\n \tenum xts_tweak_modes tweak_mode;\n };\n \n+struct rsa_interim_data {\n+\tenum rte_crypto_auth_algorithm auth;\n+\tuint16_t modulo;\n+\tuint16_t saltlen;\n+\tenum rte_crypto_rsa_padding_type padding;\n+\tenum rte_crypto_rsa_priv_key_type privkey;\n+};\n+\n #ifdef USE_JANSSON\n /*\n  * Maximum length of buffer to hold any json string.\n@@ -227,6 +257,7 @@ struct fips_test_interim_info {\n \t\tstruct sha_interim_data sha_data;\n \t\tstruct gcm_interim_data gcm_data;\n \t\tstruct xts_interim_data xts_data;\n+\t\tstruct rsa_interim_data rsa_data;\n \t} interim_info;\n \n \tenum fips_test_op op;\n@@ -302,6 +333,9 @@ parse_test_sha_json_test_type(void);\n \n int\n parse_test_tdes_json_init(void);\n+\n+int\n+parse_test_rsa_json_init(void);\n #endif /* USE_JANSSON */\n \n int\n@@ -363,11 +397,14 @@ update_info_vec(uint32_t count);\n \n typedef int (*fips_test_one_case_t)(void);\n typedef int (*fips_prepare_op_t)(void);\n-typedef int (*fips_prepare_xform_t)(struct rte_crypto_sym_xform *);\n+typedef int (*fips_prepare_sym_xform_t)(struct rte_crypto_sym_xform *);\n+typedef int (*fips_prepare_asym_xform_t)(struct rte_crypto_asym_xform *);\n \n struct fips_test_ops {\n-\tfips_prepare_xform_t prepare_xform;\n-\tfips_prepare_op_t prepare_op;\n+\tfips_prepare_sym_xform_t prepare_sym_xform;\n+\tfips_prepare_asym_xform_t prepare_asym_xform;\n+\tfips_prepare_op_t prepare_sym_op;\n+\tfips_prepare_op_t prepare_asym_op;\n \tfips_test_one_case_t test;\n };\n \ndiff --git a/examples/fips_validation/fips_validation_gcm.c b/examples/fips_validation/fips_validation_gcm.c\nindex 6b3d158629..e76c38ffc8 100644\n--- a/examples/fips_validation/fips_validation_gcm.c\n+++ b/examples/fips_validation/fips_validation_gcm.c\n@@ -80,12 +80,12 @@ parser_read_gcm_pt_len(const char *key, char *src,\n \n \tif (vec.pt.len == 0) {\n \t\tinfo.interim_info.gcm_data.is_gmac = 1;\n-\t\ttest_ops.prepare_op = prepare_auth_op;\n-\t\ttest_ops.prepare_xform = prepare_gmac_xform;\n+\t\ttest_ops.prepare_sym_op = prepare_auth_op;\n+\t\ttest_ops.prepare_sym_xform = prepare_gmac_xform;\n \t} else {\n \t\tinfo.interim_info.gcm_data.is_gmac = 0;\n-\t\ttest_ops.prepare_op = prepare_aead_op;\n-\t\ttest_ops.prepare_xform = prepare_gcm_xform;\n+\t\ttest_ops.prepare_sym_op = prepare_aead_op;\n+\t\ttest_ops.prepare_sym_xform = prepare_gcm_xform;\n \t}\n \n \treturn ret;\ndiff --git a/examples/fips_validation/fips_validation_rsa.c b/examples/fips_validation/fips_validation_rsa.c\nnew file mode 100644\nindex 0000000000..d3699f54d0\n--- /dev/null\n+++ b/examples/fips_validation/fips_validation_rsa.c\n@@ -0,0 +1,520 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(C) 2022 Marvell.\n+ */\n+\n+#include <string.h>\n+#include <time.h>\n+#include <stdio.h>\n+#include <sys/random.h>\n+#include <sys/types.h>\n+#include <unistd.h>\n+\n+#ifdef USE_OPENSSL\n+#include <openssl/bn.h>\n+#include <openssl/rand.h>\n+#endif /* USE_OPENSSL */\n+\n+#include <rte_cryptodev.h>\n+#include <rte_malloc.h>\n+\n+#include \"fips_validation.h\"\n+\n+#define TESTTYPE_JSON_STR\t\"testType\"\n+#define SIGTYPE_JSON_STR \"sigType\"\n+#define MOD_JSON_STR\t\"modulo\"\n+#define HASH_JSON_STR\t\"hashAlg\"\n+#define SALT_JSON_STR\t\"saltLen\"\n+#define E_JSON_STR\t\"e\"\n+#define N_JSON_STR\t\"n\"\n+\n+#define SEED_JSON_STR\t\"seed\"\n+#define MSG_JSON_STR\t\"message\"\n+#define SIG_JSON_STR\t\"signature\"\n+\n+#ifdef USE_JANSSON\n+struct {\n+\tuint8_t type;\n+\tconst char *desc;\n+} rsa_test_types[] = {\n+\t\t{RSA_AFT, \"AFT\"},\n+\t\t{RSA_GDT, \"GDT\"},\n+\t\t{RSA_KAT, \"KAT\"},\n+};\n+\n+struct {\n+\tenum rte_crypto_auth_algorithm auth;\n+\tconst char *desc;\n+} rsa_auth_algs[] = {\n+\t\t{RTE_CRYPTO_AUTH_SHA1, \"SHA-1\"},\n+\t\t{RTE_CRYPTO_AUTH_SHA224, \"SHA2-224\"},\n+\t\t{RTE_CRYPTO_AUTH_SHA256, \"SHA2-256\"},\n+\t\t{RTE_CRYPTO_AUTH_SHA384, \"SHA2-384\"},\n+\t\t{RTE_CRYPTO_AUTH_SHA512, \"SHA2-512\"},\n+};\n+\n+struct {\n+\tenum rte_crypto_rsa_padding_type padding;\n+\tconst char *desc;\n+} rsa_padding_types[] = {\n+\t\t{RTE_CRYPTO_RSA_PADDING_NONE, \"none\"},\n+\t\t{RTE_CRYPTO_RSA_PADDING_PKCS1_5, \"pkcs1v1.5\"},\n+\t\t{RTE_CRYPTO_RSA_PADDING_OAEP, \"oaep\"},\n+\t\t{RTE_CRYPTO_RSA_PADDING_PSS, \"pss\"},\n+};\n+\n+#ifdef USE_OPENSSL\n+static int\n+prepare_vec_rsa(void)\n+{\n+\tBIGNUM *p = NULL, *q = NULL, *n = NULL, *d = NULL, *e = NULL;\n+\tBIGNUM *dp = NULL, *dq = NULL, *qinv = NULL;\n+\tBIGNUM *r0, *r1, *r2, *r3, *r4;\n+\tBIGNUM *m = NULL, *r = NULL;\n+\tint bits, ret = -1, i;\n+\tchar modbuf[8], *buf;\n+\tBN_CTX *ctx = NULL;\n+\tunsigned long pid;\n+\n+\t/* Seed PRNG */\n+\tif (vec.rsa.seed.val) {\n+\t\twriteback_hex_str(\"\", info.one_line_text, &vec.rsa.seed);\n+\t\tRAND_seed((char *)info.one_line_text, strlen(info.one_line_text));\n+\t} else {\n+\t\tpid = getpid();\n+\t\tRAND_seed(&pid, sizeof(pid));\n+\t}\n+\n+\tif (!RAND_status())\n+\t\treturn -1;\n+\n+\t/* Check if e is known already */\n+\tif (vec.rsa.e.val) {\n+\t\twriteback_hex_str(\"\", info.one_line_text, &vec.rsa.e);\n+\t\tret = BN_hex2bn(&e, info.one_line_text);\n+\t\tif ((uint32_t)ret != strlen(info.one_line_text))\n+\t\t\tgoto err;\n+\t}\n+\n+\t/* BN context initialization */\n+\tctx = BN_CTX_new();\n+\tif (!ctx)\n+\t\tgoto err;\n+\n+\tBN_CTX_start(ctx);\n+\tr0 = BN_CTX_get(ctx);\n+\tr1 = BN_CTX_get(ctx);\n+\tr2 = BN_CTX_get(ctx);\n+\tr3 = BN_CTX_get(ctx);\n+\tr4 = BN_CTX_get(ctx);\n+\tif (!r4)\n+\t\tgoto err;\n+\n+\t/* Calculate bit length for prime numbers */\n+\tm = BN_new();\n+\tif (!m)\n+\t\tgoto err;\n+\n+\tsnprintf(modbuf, sizeof(modbuf), \"%d\", info.interim_info.rsa_data.modulo);\n+\tif (!BN_dec2bn(&m, modbuf))\n+\t\tgoto err;\n+\n+\tr = BN_new();\n+\tif (!r)\n+\t\tgoto err;\n+\n+\tif (!BN_rshift1(r, m))\n+\t\tgoto err;\n+\n+\tbuf = BN_bn2dec(r);\n+\tbits = atoi(buf);\n+\n+\tp = BN_new();\n+\tif (!p)\n+\t\tgoto err;\n+\n+\tq = BN_new();\n+\tif (!q)\n+\t\tgoto err;\n+\n+\tn = BN_new();\n+\tif (!n)\n+\t\tgoto err;\n+\n+\td = BN_new();\n+\tif (!d)\n+\t\tgoto err;\n+\n+\t/* Generate p and q suitably for RSA */\n+\tfor (i = 0; i < 10; i++) {\n+\t\tuint8_t j = 0;\n+\n+\t\tif (!BN_generate_prime_ex(p, bits, 0, NULL, NULL, NULL))\n+\t\t\tgoto err;\n+\n+\t\tdo {\n+\t\t\tRAND_add(&j, sizeof(j), 1);\n+\t\t\tif (!BN_generate_prime_ex(q, bits, 0, NULL, NULL, NULL))\n+\t\t\t\tgoto err;\n+\n+\t\t} while ((BN_cmp(p, q) == 0) && (j++ < 100));\n+\n+\t\tif (j >= 100) {\n+\t\t\tRTE_LOG(ERR, USER1, \"Error: insufficient %d retries to generate q\", j);\n+\t\t\tgoto err;\n+\t\t}\n+\n+\t\t/* pq */\n+\t\tif (!BN_mul(n, p, q, ctx))\n+\t\t\tgoto err;\n+\n+\t\t/* p-1 */\n+\t\tif (!BN_sub(r1, p, BN_value_one()))\n+\t\t\tgoto err;\n+\n+\t\t/* q-1 */\n+\t\tif (!BN_sub(r2, q, BN_value_one()))\n+\t\t\tgoto err;\n+\n+\t\t/* (p-1 * q-1) */\n+\t\tif (!BN_mul(r0, r1, r2, ctx))\n+\t\t\tgoto err;\n+\n+\t\t/* gcd(p-1, q-1)*/\n+\t\tif (!BN_gcd(r3, r1, r2, ctx))\n+\t\t\tgoto err;\n+\n+\t\t/* lcm(p-1, q-1) */\n+\t\tif (!BN_div(r4, r, r0, r3, ctx))\n+\t\t\tgoto err;\n+\n+\t\t/* check if div and rem are non-zero */\n+\t\tif (!r4 || !r)\n+\t\t\tgoto err;\n+\n+\t\t/* 0 < e < lcm */\n+\t\tif (!e) {\n+\t\t\tint k = 0;\n+\n+\t\t\te = BN_new();\n+\t\t\tdo {\n+\t\t\t\tRAND_add(&k, sizeof(k), 1);\n+\t\t\t\tif (!BN_rand(e, 32, 1, 1))\n+\t\t\t\t\tgoto err;\n+\n+\t\t\t\tif (!BN_gcd(r3, e, r4, ctx))\n+\t\t\t\t\tgoto err;\n+\n+\t\t\t\tif (BN_is_one(r3))\n+\t\t\t\t\tbreak;\n+\t\t\t} while (k++ < 10);\n+\n+\t\t\tif (k >= 10) {\n+\t\t\t\tRTE_LOG(ERR, USER1, \"Error: insufficient %d retries to generate e\",\n+\t\t\t\t\tk);\n+\t\t\t\tgoto err;\n+\t\t\t}\n+\t\t}\n+\n+\t\t/* (de) mod lcm == 1 */\n+\t\tif (!BN_mod_inverse(d, e, r4, ctx))\n+\t\t\tgoto err;\n+\n+\t\tif (!BN_gcd(r3, r1, e, ctx))\n+\t\t\tgoto err;\n+\n+\t\tif (!BN_gcd(r4, r2, e, ctx))\n+\t\t\tgoto err;\n+\n+\t\t/* check if gcd(p-1, e) and gcd(q-1, e) are 1 */\n+\t\tif (BN_is_one(r3) && BN_is_one(r4))\n+\t\t\tbreak;\n+\t}\n+\n+\tif (i >= 10) {\n+\t\tRTE_LOG(ERR, USER1, \"Error: insufficient %d retries to generate p and q\", i);\n+\t\tgoto err;\n+\t}\n+\n+\t/* d mod (p-1) */\n+\tdp = BN_new();\n+\tif (!dp)\n+\t\tgoto err;\n+\n+\tif (!BN_mod(dp, d, r1, ctx))\n+\t\tgoto err;\n+\n+\t/* d mod (q-1) */\n+\tdq = BN_new();\n+\tif (!dq)\n+\t\tgoto err;\n+\n+\tif (!BN_mod(dq, d, r2, ctx))\n+\t\tgoto err;\n+\n+\t/* modinv of q and p */\n+\tqinv = BN_new();\n+\tif (!qinv)\n+\t\tgoto err;\n+\n+\tif (!BN_mod_inverse(qinv, q, p, ctx))\n+\t\tgoto err;\n+\n+\tparse_uint8_hex_str(\"\", BN_bn2hex(e), &vec.rsa.e);\n+\tparse_uint8_hex_str(\"\", BN_bn2hex(p), &vec.rsa.p);\n+\tparse_uint8_hex_str(\"\", BN_bn2hex(q), &vec.rsa.q);\n+\tparse_uint8_hex_str(\"\", BN_bn2hex(n), &vec.rsa.n);\n+\tparse_uint8_hex_str(\"\", BN_bn2hex(d), &vec.rsa.d);\n+\tparse_uint8_hex_str(\"\", BN_bn2hex(dp), &vec.rsa.dp);\n+\tparse_uint8_hex_str(\"\", BN_bn2hex(dq), &vec.rsa.dq);\n+\tparse_uint8_hex_str(\"\", BN_bn2hex(qinv), &vec.rsa.qinv);\n+\n+\tret = 0;\n+err:\n+\tBN_CTX_end(ctx);\n+\tBN_CTX_free(ctx);\n+\tBN_free(m);\n+\tBN_free(r);\n+\tBN_free(p);\n+\tBN_free(q);\n+\tBN_free(n);\n+\tBN_free(d);\n+\tBN_free(e);\n+\treturn ret;\n+}\n+#else\n+static int\n+prepare_vec_rsa(void)\n+{\n+\t/*\n+\t * Generate RSA values.\n+\t */\n+\treturn -ENOTSUP;\n+}\n+#endif /* USE_OPENSSL */\n+\n+static int\n+parse_test_rsa_json_interim_writeback(struct fips_val *val)\n+{\n+\tRTE_SET_USED(val);\n+\n+\tif (info.op == FIPS_TEST_ASYM_SIGGEN) {\n+\t\tjson_t *obj;\n+\n+\t\t/* For siggen tests, RSA values can be created soon after\n+\t\t * the test group data are parsed.\n+\t\t */\n+\t\tif (vec.rsa.e.val) {\n+\t\t\trte_free(vec.rsa.e.val);\n+\t\t\tvec.rsa.e.val = NULL;\n+\t\t}\n+\n+\t\tif (prepare_vec_rsa() < 0)\n+\t\t\treturn -1;\n+\n+\t\twriteback_hex_str(\"\", info.one_line_text, &vec.rsa.n);\n+\t\tobj = json_string(info.one_line_text);\n+\t\tjson_object_set_new(json_info.json_write_group, \"n\", obj);\n+\n+\t\twriteback_hex_str(\"\", info.one_line_text, &vec.rsa.e);\n+\t\tobj = json_string(info.one_line_text);\n+\t\tjson_object_set_new(json_info.json_write_group, \"e\", obj);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+parse_test_rsa_json_writeback(struct fips_val *val)\n+{\n+\tjson_t *tcId;\n+\n+\tRTE_SET_USED(val);\n+\n+\ttcId = json_object_get(json_info.json_test_case, \"tcId\");\n+\n+\tjson_info.json_write_case = json_object();\n+\tjson_object_set(json_info.json_write_case, \"tcId\", tcId);\n+\n+\tif (info.op == FIPS_TEST_ASYM_KEYGEN) {\n+\t\tjson_t *obj;\n+\n+\t\twriteback_hex_str(\"\", info.one_line_text, &vec.rsa.seed);\n+\t\tobj = json_string(info.one_line_text);\n+\t\tjson_object_set_new(json_info.json_write_case, \"seed\", obj);\n+\n+\t\twriteback_hex_str(\"\", info.one_line_text, &vec.rsa.n);\n+\t\tobj = json_string(info.one_line_text);\n+\t\tjson_object_set_new(json_info.json_write_case, \"n\", obj);\n+\n+\t\twriteback_hex_str(\"\", info.one_line_text, &vec.rsa.e);\n+\t\tobj = json_string(info.one_line_text);\n+\t\tjson_object_set_new(json_info.json_write_case, \"e\", obj);\n+\n+\t\twriteback_hex_str(\"\", info.one_line_text, &vec.rsa.p);\n+\t\tobj = json_string(info.one_line_text);\n+\t\tjson_object_set_new(json_info.json_write_case, \"p\", obj);\n+\n+\t\twriteback_hex_str(\"\", info.one_line_text, &vec.rsa.q);\n+\t\tobj = json_string(info.one_line_text);\n+\t\tjson_object_set_new(json_info.json_write_case, \"q\", obj);\n+\n+\t\twriteback_hex_str(\"\", info.one_line_text, &vec.rsa.d);\n+\t\tobj = json_string(info.one_line_text);\n+\t\tjson_object_set_new(json_info.json_write_case, \"d\", obj);\n+\t} else if (info.op == FIPS_TEST_ASYM_SIGGEN) {\n+\t\tjson_t *obj;\n+\n+\t\twriteback_hex_str(\"\", info.one_line_text, &vec.rsa.signature);\n+\t\tobj = json_string(info.one_line_text);\n+\t\tjson_object_set_new(json_info.json_write_case, \"signature\", obj);\n+\t} else if (info.op == FIPS_TEST_ASYM_SIGVER) {\n+\t\tif (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS)\n+\t\t\tjson_object_set_new(json_info.json_write_case, \"testPassed\", json_true());\n+\t\telse\n+\t\t\tjson_object_set_new(json_info.json_write_case, \"testPassed\", json_false());\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+parse_interim_str(const char *key, char *src, struct fips_val *val)\n+{\n+\tuint32_t i;\n+\n+\tRTE_SET_USED(val);\n+\n+\tif (strcmp(key, SIGTYPE_JSON_STR) == 0) {\n+\t\tfor (i = 0; i < RTE_DIM(rsa_padding_types); i++)\n+\t\t\tif (strstr(src, rsa_padding_types[i].desc)) {\n+\t\t\t\tinfo.interim_info.rsa_data.padding = rsa_padding_types[i].padding;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\tif (i >= RTE_DIM(rsa_padding_types))\n+\t\t\treturn -EINVAL;\n+\n+\t}  else if (strcmp(key, MOD_JSON_STR) == 0) {\n+\t\tinfo.interim_info.rsa_data.modulo = atoi(src);\n+\t} else if (strcmp(key, HASH_JSON_STR) == 0) {\n+\t\tfor (i = 0; i < RTE_DIM(rsa_auth_algs); i++)\n+\t\t\tif (strstr(src, rsa_auth_algs[i].desc)) {\n+\t\t\t\tinfo.interim_info.rsa_data.auth = rsa_auth_algs[i].auth;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\tif (i >= RTE_DIM(rsa_auth_algs))\n+\t\t\treturn -EINVAL;\n+\n+\t}  else if (strcmp(key, SALT_JSON_STR) == 0) {\n+\t\tinfo.interim_info.rsa_data.saltlen = atoi(src);\n+\t} else if (strcmp(key, TESTTYPE_JSON_STR) == 0) {\n+\t\tfor (i = 0; i < RTE_DIM(rsa_test_types); i++)\n+\t\t\tif (strstr(src, rsa_test_types[i].desc)) {\n+\t\t\t\tinfo.parse_writeback = parse_test_rsa_json_writeback;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\tif (!info.parse_writeback || i >= RTE_DIM(rsa_test_types))\n+\t\t\treturn -EINVAL;\n+\n+\t} else {\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+parse_keygen_e_str(const char *key, char *src, struct fips_val *val)\n+{\n+\tparse_uint8_hex_str(key, src, val);\n+\n+\t/* For keygen tests, key \"e\" can be the end of input data\n+\t * to generate RSA values.\n+\t */\n+\treturn prepare_vec_rsa();\n+}\n+\n+struct fips_test_callback rsa_keygen_interim_json_vectors[] = {\n+\t\t{MOD_JSON_STR, parse_interim_str, NULL},\n+\t\t{HASH_JSON_STR, parse_interim_str, NULL},\n+\t\t{TESTTYPE_JSON_STR, parse_interim_str, NULL},\n+\t\t{NULL, NULL, NULL} /**< end pointer */\n+};\n+\n+struct fips_test_callback rsa_siggen_interim_json_vectors[] = {\n+\t\t{SIGTYPE_JSON_STR, parse_interim_str, NULL},\n+\t\t{MOD_JSON_STR, parse_interim_str, NULL},\n+\t\t{HASH_JSON_STR, parse_interim_str, NULL},\n+\t\t{SALT_JSON_STR, parse_interim_str, NULL},\n+\t\t{TESTTYPE_JSON_STR, parse_interim_str, NULL},\n+\t\t{NULL, NULL, NULL} /**< end pointer */\n+};\n+\n+struct fips_test_callback rsa_sigver_interim_json_vectors[] = {\n+\t\t{SIGTYPE_JSON_STR, parse_interim_str, NULL},\n+\t\t{MOD_JSON_STR, parse_interim_str, NULL},\n+\t\t{HASH_JSON_STR, parse_interim_str, NULL},\n+\t\t{SALT_JSON_STR, parse_interim_str, NULL},\n+\t\t{N_JSON_STR, parse_uint8_hex_str, &vec.rsa.n},\n+\t\t{E_JSON_STR, parse_uint8_hex_str, &vec.rsa.e},\n+\t\t{TESTTYPE_JSON_STR, parse_interim_str, NULL},\n+\t\t{NULL, NULL, NULL} /**< end pointer */\n+};\n+\n+struct fips_test_callback rsa_keygen_json_vectors[] = {\n+\t\t{SEED_JSON_STR, parse_uint8_hex_str, &vec.rsa.seed},\n+\t\t{E_JSON_STR, parse_keygen_e_str, &vec.rsa.e},\n+\t\t{NULL, NULL, NULL} /**< end pointer */\n+};\n+\n+struct fips_test_callback rsa_siggen_json_vectors[] = {\n+\t\t{MSG_JSON_STR, parse_uint8_hex_str, &vec.pt},\n+\t\t{NULL, NULL, NULL} /**< end pointer */\n+};\n+\n+struct fips_test_callback rsa_sigver_json_vectors[] = {\n+\t\t{MSG_JSON_STR, parse_uint8_hex_str, &vec.pt},\n+\t\t{SIG_JSON_STR, parse_uint8_hex_str, &vec.rsa.signature},\n+\t\t{NULL, NULL, NULL} /**< end pointer */\n+};\n+\n+int\n+parse_test_rsa_json_init(void)\n+{\n+\tjson_t *keyfmt_obj = json_object_get(json_info.json_vector_set, \"keyFormat\");\n+\tjson_t *mode_obj = json_object_get(json_info.json_vector_set, \"mode\");\n+\tconst char *keyfmt_str = json_string_value(keyfmt_obj);\n+\tconst char *mode_str = json_string_value(mode_obj);\n+\n+\tinfo.callbacks = NULL;\n+\tinfo.parse_writeback = NULL;\n+\tinfo.interim_callbacks = NULL;\n+\tinfo.parse_interim_writeback = NULL;\n+\n+\tif (strcmp(mode_str, \"keyGen\") == 0) {\n+\t\tinfo.op = FIPS_TEST_ASYM_KEYGEN;\n+\t\tinfo.callbacks = rsa_keygen_json_vectors;\n+\t\tinfo.interim_callbacks = rsa_keygen_interim_json_vectors;\n+\t} else if (strcmp(mode_str, \"sigGen\") == 0) {\n+\t\tinfo.op = FIPS_TEST_ASYM_SIGGEN;\n+\t\tinfo.callbacks = rsa_siggen_json_vectors;\n+\t\tinfo.interim_callbacks = rsa_siggen_interim_json_vectors;\n+\t\tinfo.parse_interim_writeback = parse_test_rsa_json_interim_writeback;\n+\t} else if (strcmp(mode_str, \"sigVer\") == 0) {\n+\t\tinfo.op = FIPS_TEST_ASYM_SIGVER;\n+\t\tinfo.callbacks = rsa_sigver_json_vectors;\n+\t\tinfo.interim_callbacks = rsa_sigver_interim_json_vectors;\n+\t} else {\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tinfo.interim_info.rsa_data.privkey = RTE_RSA_KEY_TYPE_QT;\n+\tif (keyfmt_str != NULL && strcmp(keyfmt_str, \"standard\") == 0)\n+\t\tinfo.interim_info.rsa_data.privkey = RTE_RSA_KEY_TYPE_EXP;\n+\n+\treturn 0;\n+}\n+#endif /* USE_JANSSON */\n+\ndiff --git a/examples/fips_validation/main.c b/examples/fips_validation/main.c\nindex 8babbb3298..ed86c10350 100644\n--- a/examples/fips_validation/main.c\n+++ b/examples/fips_validation/main.c\n@@ -36,6 +36,8 @@ enum {\n \tOPT_CRYPTODEV_BK_DIR_KEY_NUM,\n #define OPT_USE_JSON                \"use-json\"\n \tOPT_USE_JSON_NUM,\n+#define OPT_CRYPTODEV_ASYM          \"asymmetric\"\n+\tOPT_CRYPTODEV_ASYM_NUM,\n };\n \n struct fips_test_vector vec;\n@@ -50,27 +52,133 @@ struct cryptodev_fips_validate_env {\n \tconst char *rsp_path;\n \tuint32_t is_path_folder;\n \tuint8_t dev_id;\n-\tuint8_t dev_support_sgl;\n-\tuint16_t mbuf_data_room;\n \tstruct rte_mempool *mpool;\n-\tstruct rte_mempool *sess_mpool;\n \tstruct rte_mempool *sess_priv_mpool;\n-\tstruct rte_mempool *op_pool;\n+\tstruct fips_sym_env {\n+\t\tstruct rte_mempool *sess_mpool;\n+\t\tstruct rte_mempool *op_pool;\n+\t\tstruct rte_cryptodev_sym_session *sess;\n+\t\tstruct rte_crypto_op *op;\n+\t} sym;\n+\tstruct fips_asym_env {\n+\t\tstruct rte_mempool *sess_mpool;\n+\t\tstruct rte_mempool *op_pool;\n+\t\tstruct rte_cryptodev_asym_session *sess;\n+\t\tstruct rte_crypto_op *op;\n+\t} asym;\n+\tstruct rte_crypto_op *op;\n+\tuint8_t dev_support_sgl;\n+\tuint16_t mbuf_data_room;\n \tstruct rte_mbuf *mbuf;\n \tuint8_t *digest;\n \tuint16_t digest_len;\n-\tstruct rte_crypto_op *op;\n-\tstruct rte_cryptodev_sym_session *sess;\n+\tbool is_asym_test;\n \tuint16_t self_test;\n \tstruct fips_dev_broken_test_config *broken_test_config;\n } env;\n \n static int\n-cryptodev_fips_validate_app_int(void)\n+cryptodev_fips_validate_app_sym_init(void)\n+{\n+\tstruct rte_cryptodev_info dev_info;\n+\tstruct fips_sym_env *sym = &env.sym;\n+\tint ret;\n+\n+\trte_cryptodev_info_get(env.dev_id, &dev_info);\n+\tif (dev_info.feature_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)\n+\t\tenv.dev_support_sgl = 1;\n+\telse\n+\t\tenv.dev_support_sgl = 0;\n+\n+\tret = -ENOMEM;\n+\tsym->sess_mpool = rte_cryptodev_sym_session_pool_create(\n+\t\t\t\"FIPS_SYM_SESS_MEMPOOL\", 16, 0, 0, 0, rte_socket_id());\n+\tif (!sym->sess_mpool)\n+\t\tgoto error_exit;\n+\n+\tsym->op_pool = rte_crypto_op_pool_create(\n+\t\t\t\"FIPS_OP_SYM_POOL\",\n+\t\t\tRTE_CRYPTO_OP_TYPE_SYMMETRIC,\n+\t\t\t1, 0,\n+\t\t\t16,\n+\t\t\trte_socket_id());\n+\tif (!sym->op_pool)\n+\t\tgoto error_exit;\n+\n+\tsym->op = rte_crypto_op_alloc(sym->op_pool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);\n+\tif (!sym->op)\n+\t\tgoto error_exit;\n+\n+\treturn 0;\n+\n+error_exit:\n+\trte_mempool_free(sym->sess_mpool);\n+\trte_mempool_free(sym->op_pool);\n+\treturn ret;\n+}\n+\n+static void\n+cryptodev_fips_validate_app_sym_uninit(void)\n+{\n+\tstruct fips_sym_env *sym = &env.sym;\n+\n+\trte_pktmbuf_free(env.mbuf);\n+\trte_crypto_op_free(sym->op);\n+\trte_cryptodev_sym_session_clear(env.dev_id, sym->sess);\n+\trte_cryptodev_sym_session_free(sym->sess);\n+\trte_mempool_free(sym->sess_mpool);\n+\trte_mempool_free(sym->op_pool);\n+}\n+\n+static int\n+cryptodev_fips_validate_app_asym_init(void)\n+{\n+\tstruct fips_asym_env *asym = &env.asym;\n+\tint ret;\n+\n+\tret = -ENOMEM;\n+\tasym->sess_mpool = rte_cryptodev_asym_session_pool_create(\n+\t\t\t\"FIPS_ASYM_SESS_MEMPOOL\", 16, 0, 0, rte_socket_id());\n+\tif (!asym->sess_mpool)\n+\t\tgoto error_exit;\n+\n+\tasym->op_pool = rte_crypto_op_pool_create(\n+\t\t\t\"FIPS_OP_ASYM_POOL\",\n+\t\t\tRTE_CRYPTO_OP_TYPE_ASYMMETRIC,\n+\t\t\t1, 0,\n+\t\t\t16,\n+\t\t\trte_socket_id());\n+\tif (!asym->op_pool)\n+\t\tgoto error_exit;\n+\n+\tasym->op = rte_crypto_op_alloc(asym->op_pool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);\n+\tif (!asym->op)\n+\t\tgoto error_exit;\n+\n+\treturn 0;\n+\n+error_exit:\n+\trte_mempool_free(asym->sess_mpool);\n+\trte_mempool_free(asym->op_pool);\n+\treturn ret;\n+}\n+\n+static void\n+cryptodev_fips_validate_app_asym_uninit(void)\n+{\n+\tstruct fips_asym_env *asym = &env.asym;\n+\n+\trte_crypto_op_free(asym->op);\n+\trte_cryptodev_asym_session_free(env.dev_id, asym->sess);\n+\trte_mempool_free(asym->sess_mpool);\n+\trte_mempool_free(asym->op_pool);\n+}\n+\n+static int\n+cryptodev_fips_validate_app_init(void)\n {\n \tstruct rte_cryptodev_config conf = {rte_socket_id(), 1, 0};\n \tstruct rte_cryptodev_qp_conf qp_conf = {128, NULL, NULL};\n-\tstruct rte_cryptodev_info dev_info;\n \tuint32_t sess_sz = rte_cryptodev_sym_get_private_session_size(\n \t\t\tenv.dev_id);\n \tuint32_t nb_mbufs = UINT16_MAX / env.mbuf_data_room + 1;\n@@ -89,50 +197,30 @@ cryptodev_fips_validate_app_int(void)\n \tif (ret < 0)\n \t\treturn ret;\n \n-\trte_cryptodev_info_get(env.dev_id, &dev_info);\n-\tif (dev_info.feature_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)\n-\t\tenv.dev_support_sgl = 1;\n-\telse\n-\t\tenv.dev_support_sgl = 0;\n-\n+\tret = -ENOMEM;\n \tenv.mpool = rte_pktmbuf_pool_create(\"FIPS_MEMPOOL\", nb_mbufs,\n \t\t\t0, 0, sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM +\n \t\t\tenv.mbuf_data_room, rte_socket_id());\n \tif (!env.mpool)\n \t\treturn ret;\n \n-\tret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf,\n-\t\t\trte_socket_id());\n-\tif (ret < 0)\n-\t\treturn ret;\n-\n-\tret = -ENOMEM;\n-\n-\tenv.sess_mpool = rte_cryptodev_sym_session_pool_create(\n-\t\t\t\"FIPS_SESS_MEMPOOL\", 16, 0, 0, 0, rte_socket_id());\n-\tif (!env.sess_mpool)\n-\t\tgoto error_exit;\n-\n \tenv.sess_priv_mpool = rte_mempool_create(\"FIPS_SESS_PRIV_MEMPOOL\",\n \t\t\t16, sess_sz, 0, 0, NULL, NULL, NULL,\n \t\t\tNULL, rte_socket_id(), 0);\n \tif (!env.sess_priv_mpool)\n \t\tgoto error_exit;\n \n-\tenv.op_pool = rte_crypto_op_pool_create(\n-\t\t\t\"FIPS_OP_POOL\",\n-\t\t\tRTE_CRYPTO_OP_TYPE_SYMMETRIC,\n-\t\t\t1, 0,\n-\t\t\t16,\n-\t\t\trte_socket_id());\n-\tif (!env.op_pool)\n+\tret = cryptodev_fips_validate_app_sym_init();\n+\tif (ret < 0)\n \t\tgoto error_exit;\n \n-\tenv.op = rte_crypto_op_alloc(env.op_pool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);\n-\tif (!env.op)\n-\t\tgoto error_exit;\n+\tif (env.is_asym_test) {\n+\t\tret = cryptodev_fips_validate_app_asym_init();\n+\t\tif (ret < 0)\n+\t\t\tgoto error_exit;\n+\t}\n \n-\tqp_conf.mp_session = env.sess_mpool;\n+\tqp_conf.mp_session = env.sym.sess_mpool;\n \tqp_conf.mp_session_private = env.sess_priv_mpool;\n \n \tret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf,\n@@ -147,26 +235,21 @@ cryptodev_fips_validate_app_int(void)\n \treturn 0;\n \n error_exit:\n-\n \trte_mempool_free(env.mpool);\n-\trte_mempool_free(env.sess_mpool);\n \trte_mempool_free(env.sess_priv_mpool);\n-\trte_mempool_free(env.op_pool);\n-\n \treturn ret;\n }\n \n static void\n cryptodev_fips_validate_app_uninit(void)\n {\n-\trte_pktmbuf_free(env.mbuf);\n-\trte_crypto_op_free(env.op);\n-\trte_cryptodev_sym_session_clear(env.dev_id, env.sess);\n-\trte_cryptodev_sym_session_free(env.sess);\n+\tcryptodev_fips_validate_app_sym_uninit();\n+\n+\tif (env.is_asym_test)\n+\t\tcryptodev_fips_validate_app_asym_uninit();\n+\n \trte_mempool_free(env.mpool);\n-\trte_mempool_free(env.sess_mpool);\n \trte_mempool_free(env.sess_priv_mpool);\n-\trte_mempool_free(env.op_pool);\n }\n \n static int\n@@ -262,6 +345,8 @@ cryptodev_fips_validate_parse_args(int argc, char **argv)\n \t\t\t\tNULL, OPT_CRYPTODEV_BK_ID_NUM},\n \t\t{OPT_CRYPTODEV_BK_DIR_KEY, required_argument,\n \t\t\t\tNULL, OPT_CRYPTODEV_BK_DIR_KEY_NUM},\n+\t\t{OPT_CRYPTODEV_ASYM, no_argument,\n+\t\t\t\tNULL, OPT_CRYPTODEV_ASYM_NUM},\n \t\t{NULL, 0, 0, 0}\n \t};\n \n@@ -374,6 +459,10 @@ cryptodev_fips_validate_parse_args(int argc, char **argv)\n \t\t\t}\n \t\t\tbreak;\n \n+\t\tcase OPT_CRYPTODEV_ASYM_NUM:\n+\t\t\tenv.is_asym_test = true;\n+\t\t\tbreak;\n+\n \t\tdefault:\n \t\t\tcryptodev_fips_validate_usage(prgname);\n \t\t\treturn -EINVAL;\n@@ -414,7 +503,7 @@ main(int argc, char *argv[])\n \tif (ret < 0)\n \t\trte_exit(EXIT_FAILURE, \"Failed to parse arguments!\\n\");\n \n-\tret = cryptodev_fips_validate_app_int();\n+\tret = cryptodev_fips_validate_app_init();\n \tif (ret < 0) {\n \t\tRTE_LOG(ERR, USER1, \"Error %i: Failed init\\n\", ret);\n \t\treturn -1;\n@@ -653,7 +742,7 @@ prepare_cipher_op(void)\n \t\tsym->cipher.data.length = vec.ct.len;\n \t}\n \n-\trte_crypto_op_attach_sym_session(env.op, env.sess);\n+\trte_crypto_op_attach_sym_session(env.op, env.sym.sess);\n \n \tsym->m_src = env.mbuf;\n \tsym->cipher.data.offset = 0;\n@@ -701,7 +790,7 @@ prepare_auth_op(void)\n \t\tmemcpy(env.digest, vec.cipher_auth.digest.val,\n \t\t\t\tvec.cipher_auth.digest.len);\n \n-\trte_crypto_op_attach_sym_session(env.op, env.sess);\n+\trte_crypto_op_attach_sym_session(env.op, env.sym.sess);\n \n \treturn 0;\n }\n@@ -757,7 +846,55 @@ prepare_aead_op(void)\n \tsym->aead.aad.data = vec.aead.aad.val;\n \tsym->aead.aad.phys_addr = rte_malloc_virt2iova(sym->aead.aad.data);\n \n-\trte_crypto_op_attach_sym_session(env.op, env.sess);\n+\trte_crypto_op_attach_sym_session(env.op, env.sym.sess);\n+\n+\treturn 0;\n+}\n+\n+static int\n+prepare_rsa_op(void)\n+{\n+\tstruct rte_crypto_asym_op *asym;\n+\tstruct fips_val msg;\n+\n+\t__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);\n+\n+\tasym = env.op->asym;\n+\tasym->rsa.padding.type = info.interim_info.rsa_data.padding;\n+\tasym->rsa.padding.hash = info.interim_info.rsa_data.auth;\n+\n+\tif (env.digest) {\n+\t\tmsg.val = env.digest;\n+\t\tmsg.len = env.digest_len;\n+\t} else {\n+\t\tmsg.val = vec.pt.val;\n+\t\tmsg.len = vec.pt.len;\n+\t}\n+\n+\tif (info.op == FIPS_TEST_ASYM_SIGGEN) {\n+\t\tasym->rsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;\n+\t\tasym->rsa.message.data = msg.val;\n+\t\tasym->rsa.message.length = msg.len;\n+\n+\t\tif (vec.rsa.signature.val)\n+\t\t\trte_free(vec.rsa.signature.val);\n+\n+\t\tvec.rsa.signature.val = rte_zmalloc(NULL, vec.rsa.n.len, 0);\n+\t\tvec.rsa.signature.len = vec.rsa.n.len;\n+\t\tasym->rsa.sign.data = vec.rsa.signature.val;\n+\t\tasym->rsa.sign.length = 0;\n+\t} else if (info.op == FIPS_TEST_ASYM_SIGVER) {\n+\t\tasym->rsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;\n+\t\tasym->rsa.message.data = msg.val;\n+\t\tasym->rsa.message.length = msg.len;\n+\t\tasym->rsa.sign.data = vec.rsa.signature.val;\n+\t\tasym->rsa.sign.length = vec.rsa.signature.len;\n+\t} else {\n+\t\tRTE_LOG(ERR, USER1, \"Invalid op %d\\n\", info.op);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\trte_crypto_op_attach_asym_session(env.op, env.asym.sess);\n \n \treturn 0;\n }\n@@ -1145,6 +1282,87 @@ prepare_xts_xform(struct rte_crypto_sym_xform *xform)\n \treturn 0;\n }\n \n+static int\n+prepare_rsa_xform(struct rte_crypto_asym_xform *xform)\n+{\n+\tconst struct rte_cryptodev_asymmetric_xform_capability *cap;\n+\tstruct rte_cryptodev_asym_capability_idx cap_idx;\n+\tstruct rte_cryptodev_info dev_info;\n+\n+\txform->xform_type = RTE_CRYPTO_ASYM_XFORM_RSA;\n+\txform->next = NULL;\n+\n+\tcap_idx.type = xform->xform_type;\n+\tcap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);\n+\tif (!cap) {\n+\t\tRTE_LOG(ERR, USER1, \"Failed to get capability for cdev %u\\n\",\n+\t\t\t\tenv.dev_id);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tswitch (info.op) {\n+\tcase FIPS_TEST_ASYM_SIGGEN:\n+\t\tif (!rte_cryptodev_asym_xform_capability_check_optype(cap,\n+\t\t\tRTE_CRYPTO_ASYM_OP_SIGN)) {\n+\t\t\tRTE_LOG(ERR, USER1, \"PMD %s xform_op %u\\n\",\n+\t\t\t\tinfo.device_name, RTE_CRYPTO_ASYM_OP_SIGN);\n+\t\t\treturn -EPERM;\n+\t\t}\n+\t\tbreak;\n+\tcase FIPS_TEST_ASYM_SIGVER:\n+\t\tif (!rte_cryptodev_asym_xform_capability_check_optype(cap,\n+\t\t\tRTE_CRYPTO_ASYM_OP_VERIFY)) {\n+\t\t\tRTE_LOG(ERR, USER1, \"PMD %s xform_op %u\\n\",\n+\t\t\t\tinfo.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);\n+\t\t\treturn -EPERM;\n+\t\t}\n+\t\tbreak;\n+\tcase FIPS_TEST_ASYM_KEYGEN:\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\trte_cryptodev_info_get(env.dev_id, &dev_info);\n+\txform->rsa.key_type = info.interim_info.rsa_data.privkey;\n+\tswitch (xform->rsa.key_type) {\n+\tcase RTE_RSA_KEY_TYPE_QT:\n+\t\tif (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_QT)) {\n+\t\t\tRTE_LOG(ERR, USER1, \"PMD %s does not support QT key type\\n\",\n+\t\t\t\tinfo.device_name);\n+\t\t\treturn -EPERM;\n+\t\t}\n+\t\txform->rsa.qt.p.data = vec.rsa.p.val;\n+\t\txform->rsa.qt.p.length = vec.rsa.p.len;\n+\t\txform->rsa.qt.q.data = vec.rsa.q.val;\n+\t\txform->rsa.qt.q.length = vec.rsa.q.len;\n+\t\txform->rsa.qt.dP.data = vec.rsa.dp.val;\n+\t\txform->rsa.qt.dP.length = vec.rsa.dp.len;\n+\t\txform->rsa.qt.dQ.data = vec.rsa.dq.val;\n+\t\txform->rsa.qt.dQ.length = vec.rsa.dq.len;\n+\t\txform->rsa.qt.qInv.data = vec.rsa.qinv.val;\n+\t\txform->rsa.qt.qInv.length = vec.rsa.qinv.len;\n+\t\tbreak;\n+\tcase RTE_RSA_KEY_TYPE_EXP:\n+\t\tif (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_EXP)) {\n+\t\t\tRTE_LOG(ERR, USER1, \"PMD %s does not support EXP key type\\n\",\n+\t\t\t\tinfo.device_name);\n+\t\t\treturn -EPERM;\n+\t\t}\n+\t\txform->rsa.d.data = vec.rsa.d.val;\n+\t\txform->rsa.d.length = vec.rsa.d.len;\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\txform->rsa.e.data = vec.rsa.e.val;\n+\txform->rsa.e.length = vec.rsa.e.len;\n+\txform->rsa.n.data = vec.rsa.n.val;\n+\txform->rsa.n.length = vec.rsa.n.len;\n+\treturn 0;\n+}\n+\n static int\n get_writeback_data(struct fips_val *val)\n {\n@@ -1191,29 +1409,29 @@ get_writeback_data(struct fips_val *val)\n }\n \n static int\n-fips_run_test(void)\n+fips_run_sym_test(void)\n {\n \tstruct rte_crypto_sym_xform xform = {0};\n \tuint16_t n_deqd;\n \tint ret;\n \n-\tret = test_ops.prepare_xform(&xform);\n+\tret = test_ops.prepare_sym_xform(&xform);\n \tif (ret < 0)\n \t\treturn ret;\n \n-\tenv.sess = rte_cryptodev_sym_session_create(env.sess_mpool);\n-\tif (!env.sess)\n+\tenv.sym.sess = rte_cryptodev_sym_session_create(env.sym.sess_mpool);\n+\tif (!env.sym.sess)\n \t\treturn -ENOMEM;\n \n \tret = rte_cryptodev_sym_session_init(env.dev_id,\n-\t\t\tenv.sess, &xform, env.sess_priv_mpool);\n+\t\t\tenv.sym.sess, &xform, env.sess_priv_mpool);\n \tif (ret < 0) {\n \t\tRTE_LOG(ERR, USER1, \"Error %i: Init session\\n\",\n \t\t\t\tret);\n \t\tgoto exit;\n \t}\n \n-\tret = test_ops.prepare_op();\n+\tret = test_ops.prepare_sym_op();\n \tif (ret < 0) {\n \t\tRTE_LOG(ERR, USER1, \"Error %i: Prepare op\\n\",\n \t\t\t\tret);\n@@ -1229,20 +1447,90 @@ fips_run_test(void)\n \tdo {\n \t\tstruct rte_crypto_op *deqd_op;\n \n-\t\tn_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op,\n-\t\t\t\t1);\n+\t\tn_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1);\n \t} while (n_deqd == 0);\n \n \tvec.status = env.op->status;\n \n exit:\n-\trte_cryptodev_sym_session_clear(env.dev_id, env.sess);\n-\trte_cryptodev_sym_session_free(env.sess);\n-\tenv.sess = NULL;\n+\trte_cryptodev_sym_session_clear(env.dev_id, env.sym.sess);\n+\trte_cryptodev_sym_session_free(env.sym.sess);\n+\tenv.sym.sess = NULL;\n \n \treturn ret;\n }\n \n+static int\n+fips_run_asym_test(void)\n+{\n+\tstruct rte_crypto_asym_xform xform = {0};\n+\tstruct rte_crypto_asym_op *asym;\n+\tstruct rte_crypto_op *deqd_op;\n+\tint ret;\n+\n+\tif (info.op == FIPS_TEST_ASYM_KEYGEN) {\n+\t\tRTE_SET_USED(asym);\n+\t\tret = 0;\n+\t\tgoto exit;\n+\t}\n+\n+\tasym = env.op->asym;\n+\tret = test_ops.prepare_asym_xform(&xform);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = rte_cryptodev_asym_session_create(env.dev_id, &xform,  env.asym.sess_mpool,\n+\t\t\t(void *)&env.asym.sess);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = test_ops.prepare_asym_op();\n+\tif (ret < 0) {\n+\t\tRTE_LOG(ERR, USER1, \"Error %i: Prepare op\\n\", ret);\n+\t\tgoto exit;\n+\t}\n+\n+\tif (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) {\n+\t\tRTE_LOG(ERR, USER1, \"Error: Failed enqueue\\n\");\n+\t\tret = -1;\n+\t\tgoto exit;\n+\t}\n+\n+\twhile (rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1) == 0)\n+\t\trte_pause();\n+\n+\tvec.status = env.op->status;\n+\n+ exit:\n+\tif (env.asym.sess)\n+\t\trte_cryptodev_asym_session_free(env.dev_id, env.asym.sess);\n+\n+\tenv.asym.sess = NULL;\n+\treturn ret;\n+}\n+\n+static int\n+fips_run_test(void)\n+{\n+\tint ret;\n+\n+\tenv.op = env.sym.op;\n+\tif (env.is_asym_test) {\n+\t\tvec.cipher_auth.digest.len = parse_test_sha_hash_size(\n+\t\t\t\t\t\tinfo.interim_info.rsa_data.auth);\n+\t\ttest_ops.prepare_sym_xform = prepare_sha_xform;\n+\t\ttest_ops.prepare_sym_op = prepare_auth_op;\n+\t\tret = fips_run_sym_test();\n+\t\tif (ret < 0)\n+\t\t\treturn ret;\n+\t} else {\n+\t\treturn fips_run_sym_test();\n+\t}\n+\n+\tenv.op = env.asym.op;\n+\treturn fips_run_asym_test();\n+}\n+\n static int\n fips_generic_test(void)\n {\n@@ -1265,9 +1553,11 @@ fips_generic_test(void)\n \t\treturn ret;\n \t}\n \n-\tret = get_writeback_data(&val);\n-\tif (ret < 0)\n-\t\treturn ret;\n+\tif (!env.is_asym_test) {\n+\t\tret = get_writeback_data(&val);\n+\t\tif (ret < 0)\n+\t\t\treturn ret;\n+\t}\n \n \tswitch (info.file_type) {\n \tcase FIPS_TYPE_REQ:\n@@ -1814,60 +2104,65 @@ init_test_ops(void)\n \tswitch (info.algo) {\n \tcase FIPS_TEST_ALGO_AES_CBC:\n \tcase FIPS_TEST_ALGO_AES:\n-\t\ttest_ops.prepare_op = prepare_cipher_op;\n-\t\ttest_ops.prepare_xform  = prepare_aes_xform;\n+\t\ttest_ops.prepare_sym_op = prepare_cipher_op;\n+\t\ttest_ops.prepare_sym_xform  = prepare_aes_xform;\n \t\tif (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT)\n \t\t\ttest_ops.test = fips_mct_aes_test;\n \t\telse\n \t\t\ttest_ops.test = fips_generic_test;\n \t\tbreak;\n \tcase FIPS_TEST_ALGO_HMAC:\n-\t\ttest_ops.prepare_op = prepare_auth_op;\n-\t\ttest_ops.prepare_xform = prepare_hmac_xform;\n+\t\ttest_ops.prepare_sym_op = prepare_auth_op;\n+\t\ttest_ops.prepare_sym_xform = prepare_hmac_xform;\n \t\ttest_ops.test = fips_generic_test;\n \t\tbreak;\n \tcase FIPS_TEST_ALGO_TDES:\n-\t\ttest_ops.prepare_op = prepare_cipher_op;\n-\t\ttest_ops.prepare_xform  = prepare_tdes_xform;\n+\t\ttest_ops.prepare_sym_op = prepare_cipher_op;\n+\t\ttest_ops.prepare_sym_xform = prepare_tdes_xform;\n \t\tif (info.interim_info.tdes_data.test_type == TDES_MCT)\n \t\t\ttest_ops.test = fips_mct_tdes_test;\n \t\telse\n \t\t\ttest_ops.test = fips_generic_test;\n \t\tbreak;\n \tcase FIPS_TEST_ALGO_AES_GCM:\n-\t\ttest_ops.prepare_op = prepare_aead_op;\n-\t\ttest_ops.prepare_xform = prepare_gcm_xform;\n+\t\ttest_ops.prepare_sym_op = prepare_aead_op;\n+\t\ttest_ops.prepare_sym_xform = prepare_gcm_xform;\n \t\ttest_ops.test = fips_generic_test;\n \t\tbreak;\n \tcase FIPS_TEST_ALGO_AES_CMAC:\n-\t\ttest_ops.prepare_op = prepare_auth_op;\n-\t\ttest_ops.prepare_xform = prepare_cmac_xform;\n+\t\ttest_ops.prepare_sym_op = prepare_auth_op;\n+\t\ttest_ops.prepare_sym_xform = prepare_cmac_xform;\n \t\ttest_ops.test = fips_generic_test;\n \t\tbreak;\n \tcase FIPS_TEST_ALGO_AES_CCM:\n-\t\ttest_ops.prepare_op = prepare_aead_op;\n-\t\ttest_ops.prepare_xform = prepare_ccm_xform;\n+\t\ttest_ops.prepare_sym_op = prepare_aead_op;\n+\t\ttest_ops.prepare_sym_xform = prepare_ccm_xform;\n \t\ttest_ops.test = fips_generic_test;\n \t\tbreak;\n \tcase FIPS_TEST_ALGO_SHA:\n-\t\ttest_ops.prepare_op = prepare_auth_op;\n-\t\ttest_ops.prepare_xform = prepare_sha_xform;\n+\t\ttest_ops.prepare_sym_op = prepare_auth_op;\n+\t\ttest_ops.prepare_sym_xform = prepare_sha_xform;\n \t\tif (info.interim_info.sha_data.test_type == SHA_MCT)\n \t\t\ttest_ops.test = fips_mct_sha_test;\n \t\telse\n \t\t\ttest_ops.test = fips_generic_test;\n \t\tbreak;\n \tcase FIPS_TEST_ALGO_AES_XTS:\n-\t\ttest_ops.prepare_op = prepare_cipher_op;\n-\t\ttest_ops.prepare_xform = prepare_xts_xform;\n+\t\ttest_ops.prepare_sym_op = prepare_cipher_op;\n+\t\ttest_ops.prepare_sym_xform = prepare_xts_xform;\n+\t\ttest_ops.test = fips_generic_test;\n+\t\tbreak;\n+\tcase FIPS_TEST_ALGO_RSA:\n+\t\ttest_ops.prepare_asym_op = prepare_rsa_op;\n+\t\ttest_ops.prepare_asym_xform = prepare_rsa_xform;\n \t\ttest_ops.test = fips_generic_test;\n \t\tbreak;\n \tdefault:\n \t\tif (strstr(info.file_name, \"TECB\") ||\n \t\t\t\tstrstr(info.file_name, \"TCBC\")) {\n \t\t\tinfo.algo = FIPS_TEST_ALGO_TDES;\n-\t\t\ttest_ops.prepare_op = prepare_cipher_op;\n-\t\t\ttest_ops.prepare_xform\t= prepare_tdes_xform;\n+\t\t\ttest_ops.prepare_sym_op = prepare_cipher_op;\n+\t\t\ttest_ops.prepare_sym_xform = prepare_tdes_xform;\n \t\t\tif (info.interim_info.tdes_data.test_type == TDES_MCT)\n \t\t\t\ttest_ops.test = fips_mct_tdes_test;\n \t\t\telse\n@@ -2033,6 +2328,9 @@ fips_test_one_test_group(void)\n \tcase FIPS_TEST_ALGO_TDES:\n \t\tret = parse_test_tdes_json_init();\n \t\tbreak;\n+\tcase FIPS_TEST_ALGO_RSA:\n+\t\tret = parse_test_rsa_json_init();\n+\t\tbreak;\n \tdefault:\n \t\treturn -EINVAL;\n \t}\ndiff --git a/examples/fips_validation/meson.build b/examples/fips_validation/meson.build\nindex 8bca26a095..d310093189 100644\n--- a/examples/fips_validation/meson.build\n+++ b/examples/fips_validation/meson.build\n@@ -18,6 +18,7 @@ sources = files(\n         'fips_validation_ccm.c',\n         'fips_validation_sha.c',\n         'fips_validation_xts.c',\n+        'fips_validation_rsa.c',\n         'fips_dev_self_test.c',\n         'main.c',\n )\n@@ -26,3 +27,8 @@ if dpdk_conf.has('RTE_HAS_JANSSON')\n     ext_deps += jansson_dep\n     cflags += '-DUSE_JANSSON'\n endif\n+\n+if dpdk_conf.has('RTE_HAS_OPENSSL')\n+    ext_deps += openssl_dep\n+    cflags += '-DUSE_OPENSSL'\n+endif\n",
    "prefixes": [
        "v2",
        "5/7"
    ]
}