get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 123580,
    "url": "http://patches.dpdk.org/api/patches/123580/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20230209123402.1993179-1-vfialko@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": "<20230209123402.1993179-1-vfialko@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230209123402.1993179-1-vfialko@marvell.com",
    "date": "2023-02-09T12:34:02",
    "name": "[v2] test: add cryptodev crosscheck suite",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "69e37453b9def73b63a0c9c643460c5764c8347e",
    "submitter": {
        "id": 2390,
        "url": "http://patches.dpdk.org/api/people/2390/?format=api",
        "name": "Volodymyr Fialko",
        "email": "vfialko@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/20230209123402.1993179-1-vfialko@marvell.com/mbox/",
    "series": [
        {
            "id": 26921,
            "url": "http://patches.dpdk.org/api/series/26921/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=26921",
            "date": "2023-02-09T12:34:02",
            "name": "[v2] test: add cryptodev crosscheck suite",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/26921/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/123580/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/123580/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 7CB4141C4F;\n\tThu,  9 Feb 2023 13:34:38 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 676A34067B;\n\tThu,  9 Feb 2023 13:34:38 +0100 (CET)",
            "from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com\n [67.231.156.173])\n by mails.dpdk.org (Postfix) with ESMTP id 99C3B400D5\n for <dev@dpdk.org>; Thu,  9 Feb 2023 13:34:36 +0100 (CET)",
            "from pps.filterd (m0045851.ppops.net [127.0.0.1])\n by mx0b-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id\n 3199J69M026350; Thu, 9 Feb 2023 04:34:36 -0800",
            "from dc5-exch01.marvell.com ([199.233.59.181])\n by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3nm65m2qrs-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT);\n Thu, 09 Feb 2023 04:34:35 -0800",
            "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.42;\n Thu, 9 Feb 2023 04:34:33 -0800",
            "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.42 via Frontend\n Transport; Thu, 9 Feb 2023 04:34:33 -0800",
            "from cavium-DT10.. (unknown [10.28.34.39])\n by maili.marvell.com (Postfix) with ESMTP id 4807D5B692A;\n Thu,  9 Feb 2023 04:34:30 -0800 (PST)"
        ],
        "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=W9sgC0Q85Nkq1m8gNSWI7KLnjsmSIY+lyPPld2tZZIg=;\n b=D/BaXHgDBPlsyN5Bc587ea9xgOpzozwBOVJ+8VJshbSRJlGOHzcMcrE5XlchvMdU2Po8\n HAjoG87ZOrcJ11/1DGh7mR/K10BK09ro4hILaAKKBJKFScpbWgBbMAZDwknhdiLNOtZp\n J1kPW08glwlUPRqhJENDle4E9T5ikn6GE3tL5BJlOS+hFQ8GrmZ8if0e7Q2U07bMawJB\n aaWXzSuccfHcJAYNkae0oEm0OnFe+p3MdL2NWBH92rIyFQh2CfwhSzV8UkPsusgjFDAg\n MYUxhfmAoHirNvFkFcKezcCCjzoYunPUPp1/YE/6I40ROtf/9JYH74xabWW5yryxARSj +w==",
        "From": "Volodymyr Fialko <vfialko@marvell.com>",
        "To": "<dev@dpdk.org>, Akhil Goyal <gakhil@marvell.com>, Fan Zhang\n <fanzhang.oss@gmail.com>",
        "CC": "<jerinj@marvell.com>, <anoobj@marvell.com>, <hemant.agrawal@nxp.com>,\n <kai.ji@intel.com>, <ciara.power@intel.com>, Volodymyr Fialko\n <vfialko@marvell.com>",
        "Subject": "[PATCH v2] test: add cryptodev crosscheck suite",
        "Date": "Thu, 9 Feb 2023 13:34:02 +0100",
        "Message-ID": "<20230209123402.1993179-1-vfialko@marvell.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20221221110855.3970889-1-vfialko@marvell.com>",
        "References": "<20221221110855.3970889-1-vfialko@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Proofpoint-GUID": "2_2ZDCWLm3fKWipKEGImo7xvaDixkxCm",
        "X-Proofpoint-ORIG-GUID": "2_2ZDCWLm3fKWipKEGImo7xvaDixkxCm",
        "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.219,Aquarius:18.0.930,Hydra:6.0.562,FMLib:17.11.122.1\n definitions=2023-02-09_10,2023-02-08_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 a validation test suite that helps in verifying that the output\ngenerated by two different cryptodevs match for a wide range of input\nparameter combinations.\n\nCrypto autotest performs a comprehensive testing of the cryptodev but since\nit performs verification by comparing against known vectors, the extend to\nwhich various parameters (like packet size) can be tested is limited. This\ntest suite attempts to simulate various cases by running same test case on\ndifferent cryptodevs and compares the output generated. The test suite\nrelies on capabilities to determine the combinations of tests to be\nattempted.\n\nA typical use case would be to compare outputs generated from a standard\ndriver such as openSSL PMD and a new cryptodev PMD. This test suite is to\ncompliment the testing coverage that crypto autotest provides.\n\nCurrently supported symmetric xforms(cipher, auth, aead) without chaining.\n\nExample command:\nDPDK_TEST=cryptodev_crosscheck ./dpdk-test \\\n\t-a <cryptodev> --vdev \"crypto_openssl\"\n\nSigned-off-by: Volodymyr Fialko <vfialko@marvell.com>\n---\nV2:\n- Updated commit message.\n\n app/test/meson.build                 |    1 +\n app/test/test_cryptodev_crosscheck.c | 1008 ++++++++++++++++++++++++++\n 2 files changed, 1009 insertions(+)\n create mode 100644 app/test/test_cryptodev_crosscheck.c",
    "diff": "diff --git a/app/test/meson.build b/app/test/meson.build\nindex 1b9ce355f8..f0bcf99fb1 100644\n--- a/app/test/meson.build\n+++ b/app/test/meson.build\n@@ -33,6 +33,7 @@ test_sources = files(\n         'test_cryptodev.c',\n         'test_cryptodev_asym.c',\n         'test_cryptodev_blockcipher.c',\n+        'test_cryptodev_crosscheck.c',\n         'test_cryptodev_security_ipsec.c',\n         'test_cryptodev_security_pdcp.c',\n         'test_cycles.c',\ndiff --git a/app/test/test_cryptodev_crosscheck.c b/app/test/test_cryptodev_crosscheck.c\nnew file mode 100644\nindex 0000000000..e5f841409c\n--- /dev/null\n+++ b/app/test/test_cryptodev_crosscheck.c\n@@ -0,0 +1,1008 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(C) 2022 Marvell.\n+ */\n+#include <rte_cryptodev.h>\n+#include <rte_malloc.h>\n+\n+#include \"test.h\"\n+#include \"test_cryptodev.h\"\n+\n+#define MAX_NB_SESSIONS 1\n+#define MAX_TEST_STRING_LEN 256\n+\n+/* Define list end for known algorithms */\n+#define CRYPTO_AUTH_MAX_IDX (RTE_CRYPTO_AUTH_SHA3_512_HMAC)\n+#define CRYPTO_CIPHER_MAX_IDX (RTE_CRYPTO_CIPHER_DES_DOCSISBPI)\n+#define CRYPTO_AEAD_MAX_IDX (RTE_CRYPTO_AEAD_CHACHA20_POLY1305)\n+#define CRYPTO_ALGOS_LEN (CRYPTO_AUTH_MAX_IDX + CRYPTO_CIPHER_MAX_IDX + CRYPTO_AEAD_MAX_IDX)\n+\n+static struct rte_cryptodev_symmetric_capability common_symm_capas[CRYPTO_ALGOS_LEN];\n+\n+static struct rte_cryptodev_symmetric_capability*\n+common_capability_get(int algo, enum rte_crypto_sym_xform_type xform_type)\n+{\n+\tconst int type_to_offset[] = {\n+\t\t[RTE_CRYPTO_SYM_XFORM_AUTH] = 0,\n+\t\t[RTE_CRYPTO_SYM_XFORM_CIPHER] = CRYPTO_AUTH_MAX_IDX,\n+\t\t[RTE_CRYPTO_SYM_XFORM_AEAD] = CRYPTO_AUTH_MAX_IDX + CRYPTO_CIPHER_MAX_IDX,\n+\t};\n+\n+\treturn &common_symm_capas[type_to_offset[xform_type] + algo - 1];\n+}\n+\n+enum capability_select_type {\n+\tCAPABILITY_TYPE_MIN,\n+\tCAPABILITY_TYPE_MAX,\n+\tCAPABILITY_TYPE_LAST,\n+};\n+\n+static const char * const capability_select_strings[] = {\n+\t[CAPABILITY_TYPE_MIN] = \"MIN\",\n+\t[CAPABILITY_TYPE_MAX] = \"MAX\",\n+};\n+\n+static size_t input_length[] = { 64, 256, 512 };\n+\n+static const char*\n+algo_name_get(const struct rte_cryptodev_symmetric_capability *capa)\n+{\n+\tswitch (capa->xform_type) {\n+\tcase RTE_CRYPTO_SYM_XFORM_AUTH:\n+\t\treturn rte_crypto_auth_algorithm_strings[capa->auth.algo];\n+\tcase RTE_CRYPTO_SYM_XFORM_CIPHER:\n+\t\treturn rte_crypto_cipher_algorithm_strings[capa->cipher.algo];\n+\tcase RTE_CRYPTO_SYM_XFORM_AEAD:\n+\t\treturn rte_crypto_aead_algorithm_strings[capa->aead.algo];\n+\tdefault:\n+\t\treturn NULL;\n+\t}\n+}\n+\n+/* Calculate number of test cases(combinations) per algorithm */\n+#define NB_TEST_CASES_PER_ALGO (CAPABILITY_TYPE_LAST * RTE_DIM(input_length))\n+\n+enum crypto_op_type {\n+\tOP_ENCRYPT,\n+\tOP_DECRYPT,\n+};\n+\n+struct crosscheck_test_profile {\n+\tchar name[MAX_TEST_STRING_LEN];\n+\tsize_t input_buf_len;\n+\tuint16_t block_size;\n+\tuint16_t key_size;\n+\tuint8_t *key;\n+\tuint16_t iv_size;\n+\tuint8_t *iv;\n+\n+\tenum rte_crypto_sym_xform_type xform_type;\n+\tunion {\n+\t\tstruct {\n+\t\t\tenum rte_crypto_auth_algorithm algo;\n+\t\t\tuint16_t digest_size;\n+\t\t} auth;\n+\t\tstruct {\n+\t\t\tenum rte_crypto_cipher_algorithm algo;\n+\t\t\tuint32_t dataunit_set;\n+\t\t} cipher;\n+\t\tstruct {\n+\t\t\tenum rte_crypto_aead_algorithm algo;\n+\t\t\tuint16_t digest_size;\n+\t\t\tuint16_t aad_size;\n+\t\t} aead;\n+\t};\n+};\n+\n+struct meta_test_suite {\n+\tchar suite_name[MAX_TEST_STRING_LEN];\n+\tstruct crosscheck_test_profile profile[NB_TEST_CASES_PER_ALGO];\n+};\n+\n+static struct crypto_testsuite_params testsuite_params;\n+\n+static void\n+incrementing_generate(uint8_t *dst, uint8_t start, uint16_t size)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < size; i++)\n+\t\tdst[i] = start + i;\n+}\n+\n+static void\n+pattern_fill(uint8_t *input, const char *pattern, uint16_t size)\n+{\n+\tsize_t pattern_len = strlen(pattern);\n+\tsize_t filled_len = 0, to_fill;\n+\n+\twhile (filled_len < size) {\n+\t\tto_fill = RTE_MIN(pattern_len, size - filled_len);\n+\t\trte_memcpy(input, pattern, to_fill);\n+\t\tfilled_len += to_fill;\n+\t\tinput += to_fill;\n+\t}\n+}\n+\n+static struct crosscheck_test_profile\n+profile_create(struct rte_cryptodev_symmetric_capability *capa,\n+\t\tenum capability_select_type capability_type, size_t input_len)\n+{\n+\tstruct crosscheck_test_profile profile;\n+\n+\tmemset(&profile, 0, sizeof(profile));\n+\tprofile.xform_type = capa->xform_type;\n+\n+\tswitch (capa->xform_type) {\n+\tcase RTE_CRYPTO_SYM_XFORM_AUTH:\n+\t\tprofile.block_size = capa->auth.block_size;\n+\t\tprofile.auth.algo = capa->auth.algo;\n+\n+\t\tswitch (capability_type) {\n+\t\tcase CAPABILITY_TYPE_MIN:\n+\t\t\tprofile.key_size = capa->auth.key_size.min;\n+\t\t\tprofile.iv_size = capa->auth.iv_size.min;\n+\t\t\tprofile.auth.digest_size = capa->auth.digest_size.min;\n+\t\t\tbreak;\n+\t\tcase CAPABILITY_TYPE_MAX:\n+\t\t\tprofile.key_size = capa->auth.key_size.max;\n+\t\t\tprofile.iv_size = capa->auth.iv_size.max;\n+\t\t\tprofile.auth.digest_size = capa->auth.digest_size.max;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\trte_panic(\"Wrong capability profile type: %i\\n\", capability_type);\n+\t\t\tbreak;\n+\t\t}\n+\t\tbreak;\n+\tcase RTE_CRYPTO_SYM_XFORM_CIPHER:\n+\t\tprofile.block_size = capa->cipher.block_size;\n+\t\tprofile.cipher.algo = capa->cipher.algo;\n+\t\tprofile.cipher.dataunit_set = capa->cipher.dataunit_set;\n+\n+\t\tswitch (capability_type) {\n+\t\tcase CAPABILITY_TYPE_MIN:\n+\t\t\tprofile.key_size = capa->cipher.key_size.min;\n+\t\t\tprofile.iv_size = capa->cipher.iv_size.min;\n+\t\t\tbreak;\n+\t\tcase CAPABILITY_TYPE_MAX:\n+\t\t\tprofile.key_size = capa->cipher.key_size.max;\n+\t\t\tprofile.iv_size = capa->cipher.iv_size.max;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\trte_panic(\"Wrong capability profile type: %i\\n\", capability_type);\n+\t\t\tbreak;\n+\t\t}\n+\t\tbreak;\n+\tcase RTE_CRYPTO_SYM_XFORM_AEAD:\n+\t\tprofile.block_size = capa->aead.block_size;\n+\t\tprofile.aead.algo = capa->aead.algo;\n+\n+\t\tswitch (capability_type) {\n+\t\tcase CAPABILITY_TYPE_MIN:\n+\t\t\tprofile.key_size = capa->aead.key_size.min;\n+\t\t\tprofile.iv_size = capa->aead.iv_size.min;\n+\t\t\tprofile.aead.digest_size = capa->aead.digest_size.min;\n+\t\t\tprofile.aead.aad_size = capa->aead.aad_size.min;\n+\t\t\tbreak;\n+\t\tcase CAPABILITY_TYPE_MAX:\n+\t\t\tprofile.key_size = capa->aead.key_size.max;\n+\t\t\tprofile.iv_size = capa->aead.iv_size.max;\n+\t\t\tprofile.aead.digest_size = capa->aead.digest_size.max;\n+\t\t\tprofile.aead.aad_size = capa->aead.aad_size.max;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\trte_panic(\"Wrong capability profile type: %i\\n\", capability_type);\n+\t\t\tbreak;\n+\t\t}\n+\t\tbreak;\n+\tdefault:\n+\t\trte_panic(\"Wrong xform profile type: %i\\n\", capa->xform_type);\n+\t\tbreak;\n+\t}\n+\n+\tprofile.input_buf_len = RTE_ALIGN_CEIL(input_len, profile.block_size);\n+\n+\tif (profile.key_size) {\n+\t\tprofile.key = rte_zmalloc(NULL, profile.key_size, 0);\n+\t\tRTE_VERIFY(profile.key != NULL);\n+\t\tpattern_fill(profile.key, \"*Secret key*\", profile.key_size);\n+\t}\n+\n+\tif (profile.iv_size) {\n+\t\tprofile.iv = rte_zmalloc(NULL, profile.iv_size, 0);\n+\t\tRTE_VERIFY(profile.iv != NULL);\n+\t\tpattern_fill(profile.iv, \"IV \", profile.iv_size);\n+\t}\n+\n+\tsnprintf(profile.name, MAX_TEST_STRING_LEN,\n+\t\t\t\"'%s' - capabilities: '%s', input len: '%zu'\",\n+\t\t\talgo_name_get(capa), capability_select_strings[capability_type],\n+\t\t\tinput_len);\n+\n+\treturn profile;\n+}\n+\n+static inline int\n+common_range_set(struct rte_crypto_param_range *dst, const struct rte_crypto_param_range *src)\n+{\n+\t/* Check if ranges overlaps */\n+\tif ((dst->min > src->max) && (dst->max < src->min))\n+\t\treturn -1;\n+\tdst->min = RTE_MAX(dst->min, src->min);\n+\tdst->max = RTE_MIN(dst->max, src->max);\n+\n+\treturn 0;\n+}\n+\n+static void\n+capabilities_inspect(void)\n+{\n+\tstruct rte_cryptodev_sym_capability_idx cap_indexes[CRYPTO_ALGOS_LEN], *cap_idx;\n+\tstruct crypto_testsuite_params *ts_params = &testsuite_params;\n+\tconst struct rte_cryptodev_symmetric_capability *sym_capa;\n+\tstruct rte_cryptodev_symmetric_capability *common_capa;\n+\tuint32_t algo, i, dev_id, caps_idx;\n+\n+\tcaps_idx = 0;\n+\t/* Create capability idx for known algorithms*/\n+\tfor (algo = 1; algo <= CRYPTO_AUTH_MAX_IDX; algo++) {\n+\t\tcap_idx = &cap_indexes[caps_idx++];\n+\t\tcap_idx->type = RTE_CRYPTO_SYM_XFORM_AUTH;\n+\t\tcap_idx->algo.auth = algo;\n+\t}\n+\tfor (algo = 1; algo <= CRYPTO_CIPHER_MAX_IDX; algo++) {\n+\t\tcap_idx = &cap_indexes[caps_idx++];\n+\t\tcap_idx->type = RTE_CRYPTO_SYM_XFORM_CIPHER;\n+\t\tcap_idx->algo.cipher = algo;\n+\t}\n+\tfor (algo = 1; algo <= CRYPTO_AEAD_MAX_IDX; algo++) {\n+\t\tcap_idx = &cap_indexes[caps_idx++];\n+\t\tcap_idx->type = RTE_CRYPTO_SYM_XFORM_AEAD;\n+\t\tcap_idx->algo.aead = algo;\n+\t}\n+\n+\tfor (caps_idx = 0; caps_idx < CRYPTO_ALGOS_LEN; caps_idx++) {\n+\t\t/* Gather common capabilities */\n+\t\tcommon_capa = &common_symm_capas[caps_idx];\n+\t\tcommon_capa->xform_type = RTE_CRYPTO_SYM_XFORM_NOT_SPECIFIED;\n+\t\tfor (i = 0; i < ts_params->valid_dev_count; i++) {\n+\t\t\tdev_id = ts_params->valid_devs[i];\n+\t\t\tsym_capa = rte_cryptodev_sym_capability_get(dev_id,\n+\t\t\t\t\t&cap_indexes[caps_idx]);\n+\t\t\tif (sym_capa == NULL) {\n+\t\t\t\t/* Capability not supported by one of devs, mark and skip */\n+\t\t\t\tgoto next_algo;\n+\t\t\t}\n+\n+\t\t\tif (common_capa->xform_type == RTE_CRYPTO_SYM_XFORM_NOT_SPECIFIED) {\n+\t\t\t\t/* First time initialization, copy data, go to next device  */\n+\t\t\t\t*common_capa = *sym_capa;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\tswitch (sym_capa->xform_type) {\n+\t\t\tcase RTE_CRYPTO_SYM_XFORM_AUTH:\n+\t\t\t\tif (common_capa->auth.algo != sym_capa->auth.algo)\n+\t\t\t\t\tgoto next_algo;\n+\n+\t\t\t\tif (common_capa->auth.block_size != sym_capa->auth.block_size)\n+\t\t\t\t\tgoto next_algo;\n+\n+\t\t\t\tif (common_range_set(&common_capa->auth.key_size,\n+\t\t\t\t\t\t\t&sym_capa->auth.key_size))\n+\t\t\t\t\tgoto next_algo;\n+\t\t\t\tif (common_range_set(&common_capa->auth.digest_size,\n+\t\t\t\t\t\t\t&sym_capa->auth.digest_size))\n+\t\t\t\t\tgoto next_algo;\n+\t\t\t\tif (common_range_set(&common_capa->auth.aad_size,\n+\t\t\t\t\t\t\t&sym_capa->auth.aad_size))\n+\t\t\t\t\tgoto next_algo;\n+\t\t\t\tif (common_range_set(&common_capa->auth.iv_size,\n+\t\t\t\t\t\t\t&sym_capa->auth.iv_size))\n+\t\t\t\t\tgoto next_algo;\n+\t\t\t\tbreak;\n+\t\t\tcase RTE_CRYPTO_SYM_XFORM_CIPHER:\n+\t\t\t\tif (common_capa->cipher.algo != sym_capa->cipher.algo)\n+\t\t\t\t\tgoto next_algo;\n+\n+\t\t\t\tif (common_capa->cipher.block_size != sym_capa->cipher.block_size)\n+\t\t\t\t\tgoto next_algo;\n+\n+\t\t\t\tif (common_range_set(&common_capa->cipher.key_size,\n+\t\t\t\t\t\t\t&sym_capa->cipher.key_size))\n+\t\t\t\t\tgoto next_algo;\n+\n+\t\t\t\tif (common_range_set(&common_capa->cipher.iv_size,\n+\t\t\t\t\t\t\t&sym_capa->cipher.iv_size))\n+\t\t\t\t\tgoto next_algo;\n+\t\t\t\tif (common_capa->cipher.dataunit_set !=\n+\t\t\t\t\t\tsym_capa->cipher.dataunit_set)\n+\t\t\t\t\tgoto next_algo;\n+\t\t\t\tbreak;\n+\t\t\tcase RTE_CRYPTO_SYM_XFORM_AEAD:\n+\t\t\t\tif (common_capa->aead.algo != sym_capa->aead.algo)\n+\t\t\t\t\tgoto next_algo;\n+\n+\t\t\t\tif (common_capa->aead.block_size != sym_capa->aead.block_size)\n+\t\t\t\t\tgoto next_algo;\n+\n+\t\t\t\tif (common_range_set(&common_capa->aead.key_size,\n+\t\t\t\t\t\t\t&sym_capa->aead.key_size))\n+\t\t\t\t\tgoto next_algo;\n+\t\t\t\tif (common_range_set(&common_capa->aead.digest_size,\n+\t\t\t\t\t\t\t&sym_capa->aead.digest_size))\n+\t\t\t\t\tgoto next_algo;\n+\t\t\t\tif (common_range_set(&common_capa->aead.aad_size,\n+\t\t\t\t\t\t\t&sym_capa->aead.aad_size))\n+\t\t\t\t\tgoto next_algo;\n+\t\t\t\tif (common_range_set(&common_capa->aead.iv_size,\n+\t\t\t\t\t\t\t&sym_capa->aead.iv_size))\n+\t\t\t\t\tgoto next_algo;\n+\t\t\t\tbreak;\n+\t\t\tdefault:\n+\t\t\t\tRTE_LOG(ERR, USER1, \"Unsupported xform_type!\\n\");\n+\t\t\t\tgoto next_algo;\n+\t\t\t}\n+\t\t}\n+\n+\t\tcontinue;\n+next_algo:\n+\t\tcommon_capa->xform_type = RTE_CRYPTO_SYM_XFORM_NOT_SPECIFIED;\n+\t}\n+}\n+\n+static int\n+crosscheck_init(void)\n+{\n+\tstruct crypto_testsuite_params *ts_params = &testsuite_params;\n+\tconst uint32_t nb_queue_pairs = 1;\n+\tstruct rte_cryptodev_info info;\n+\tuint32_t session_priv_size = 0;\n+\tuint32_t nb_devs, dev_id;\n+\n+\tmemset(ts_params, 0, sizeof(*ts_params));\n+\n+\t/* Create list of valid crypto devs */\n+\tnb_devs = rte_cryptodev_count();\n+\tfor (dev_id = 0; dev_id < nb_devs; dev_id++) {\n+\t\trte_cryptodev_info_get(dev_id, &info);\n+\n+\t\tif (info.sym.max_nb_sessions != 0 && info.sym.max_nb_sessions < MAX_NB_SESSIONS)\n+\t\t\tcontinue;\n+\t\tif (info.max_nb_queue_pairs < nb_queue_pairs)\n+\t\t\tcontinue;\n+\t\tts_params->valid_devs[ts_params->valid_dev_count++] = dev_id;\n+\t\t/* Obtaining configuration parameters, that will satisfy all cryptodevs */\n+\t\tsession_priv_size = RTE_MAX(session_priv_size,\n+\t\t\t\trte_cryptodev_sym_get_private_session_size(dev_id));\n+\t}\n+\n+\tif (ts_params->valid_dev_count < 2) {\n+\t\tRTE_LOG(WARNING, USER1, \"Min number of cryptodevs for test is 2, found (%d)\\n\",\n+\t\t\t\tts_params->valid_dev_count);\n+\t\treturn TEST_SKIPPED;\n+\t}\n+\n+\t/* Create pools for mbufs, crypto operations and sessions */\n+\tts_params->mbuf_pool = rte_pktmbuf_pool_create(\"CRYPTO_MBUFPOOL\", NUM_MBUFS,\n+\t\t\tMBUF_CACHE_SIZE, 0, MBUF_SIZE, rte_socket_id());\n+\tif (ts_params->mbuf_pool == NULL) {\n+\t\tRTE_LOG(ERR, USER1, \"Can't create CRYPTO_MBUFPOOL\\n\");\n+\t\treturn TEST_FAILED;\n+\t}\n+\n+\tts_params->op_mpool = rte_crypto_op_pool_create(\"MBUF_CRYPTO_SYM_OP_POOL\",\n+\t\t\tRTE_CRYPTO_OP_TYPE_SYMMETRIC, NUM_MBUFS, MBUF_CACHE_SIZE,\n+\t\t\tDEFAULT_NUM_XFORMS * sizeof(struct rte_crypto_sym_xform) +\n+\t\t\tMAXIMUM_IV_LENGTH, rte_socket_id());\n+\n+\tif (ts_params->op_mpool == NULL) {\n+\t\tRTE_LOG(ERR, USER1, \"Can't create CRYPTO_OP_POOL\\n\");\n+\t\treturn TEST_FAILED;\n+\t}\n+\n+\tts_params->session_mpool = rte_cryptodev_sym_session_pool_create(\"test_sess_mp\",\n+\t\t\tMAX_NB_SESSIONS, session_priv_size, 0, 0, SOCKET_ID_ANY);\n+\tTEST_ASSERT_NOT_NULL(ts_params->session_mpool, \"session mempool allocation failed\");\n+\n+\t/* Setup queue pair conf params */\n+\tts_params->conf.nb_queue_pairs = nb_queue_pairs;\n+\tts_params->conf.socket_id = SOCKET_ID_ANY;\n+\tts_params->conf.ff_disable = RTE_CRYPTODEV_FF_SECURITY;\n+\tts_params->qp_conf.nb_descriptors = MAX_NUM_OPS_INFLIGHT;\n+\tts_params->qp_conf.mp_session = ts_params->session_mpool;\n+\n+\tcapabilities_inspect();\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+dev_configure_and_start(uint64_t ff_disable)\n+{\n+\tstruct crypto_testsuite_params *ts_params = &testsuite_params;\n+\tuint8_t i, dev_id;\n+\tuint16_t qp_id;\n+\n+\t/* Reconfigure device to default parameters */\n+\tts_params->conf.ff_disable = ff_disable;\n+\n+\t/* Configure cryptodevs */\n+\tfor (i = 0; i < ts_params->valid_dev_count; i++) {\n+\t\tdev_id = ts_params->valid_devs[i];\n+\t\tTEST_ASSERT_SUCCESS(rte_cryptodev_configure(dev_id, &ts_params->conf),\n+\t\t\t\t\"Failed to configure cryptodev %u with %u qps\",\n+\t\t\t\tdev_id, ts_params->conf.nb_queue_pairs);\n+\n+\n+\t\tfor (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs; qp_id++) {\n+\t\t\tTEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(\n+\t\t\t\tdev_id, qp_id, &ts_params->qp_conf,\n+\t\t\t\trte_cryptodev_socket_id(dev_id)),\n+\t\t\t\t\"Failed to setup queue pair %u on cryptodev %u\",\n+\t\t\t\tqp_id, dev_id);\n+\t\t}\n+\t\trte_cryptodev_stats_reset(dev_id);\n+\n+\t\t/* Start the device */\n+\t\tTEST_ASSERT_SUCCESS(rte_cryptodev_start(dev_id), \"Failed to start cryptodev %u\",\n+\t\t\t\tdev_id);\n+\t}\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+crosscheck_suite_setup(void)\n+{\n+\tdev_configure_and_start(RTE_CRYPTODEV_FF_SECURITY);\n+\n+\treturn 0;\n+}\n+\n+static void\n+crosscheck_suite_teardown(void)\n+{\n+\tstruct crypto_testsuite_params *ts_params = &testsuite_params;\n+\tuint8_t i, dev_id;\n+\n+\tfor (i = 0; i < ts_params->valid_dev_count; i++) {\n+\t\tdev_id = ts_params->valid_devs[i];\n+\t\trte_cryptodev_stop(dev_id);\n+\t}\n+}\n+\n+static struct rte_crypto_op *\n+crypto_request_process(uint8_t dev_id, struct rte_crypto_op *op)\n+{\n+\tstruct rte_crypto_op *res = NULL;\n+\n+\tif (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {\n+\t\tRTE_LOG(ERR, USER1, \"Error sending packet for encryption\\n\");\n+\t\treturn NULL;\n+\t}\n+\n+\twhile (rte_cryptodev_dequeue_burst(dev_id, 0, &res, 1) == 0)\n+\t\trte_pause();\n+\n+\tif (res->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {\n+\t\tRTE_LOG(ERR, USER1, \"Operation status %d\\n\", res->status);\n+\t\treturn NULL;\n+\t}\n+\n+\tif (res != op) {\n+\t\tRTE_LOG(ERR, USER1, \"Unexpected operation received!\\n\");\n+\t\trte_crypto_op_free(res);\n+\t\treturn NULL;\n+\t}\n+\n+\treturn res;\n+}\n+\n+/* Create free room at the start of segment, by moving existing data further */\n+static uint8_t*\n+mbuf_room_create(struct rte_mbuf *m, size_t size)\n+{\n+\tuint8_t *data;\n+\n+\tdata = rte_pktmbuf_mtod(m, uint8_t*);\n+\tmemmove(data + size, data, m->data_len);\n+\tm->data_len += size;\n+\tm->pkt_len += size;\n+\n+\treturn data;\n+}\n+\n+static struct rte_cryptodev_sym_session*\n+session_create(const struct crosscheck_test_profile *profile, uint8_t dev_id,\n+\t\tenum crypto_op_type op_type)\n+{\n+\tstruct rte_cryptodev_sym_session *session;\n+\tstruct rte_crypto_sym_xform xform;\n+\n+\tmemset(&xform, 0, sizeof(xform));\n+\n+\tswitch (profile->xform_type) {\n+\tcase RTE_CRYPTO_SYM_XFORM_AUTH:\n+\t\txform.type = RTE_CRYPTO_SYM_XFORM_AUTH;\n+\t\txform.next = NULL;\n+\t\txform.auth.algo = profile->auth.algo;\n+\t\txform.auth.op = op_type == OP_ENCRYPT ? RTE_CRYPTO_AUTH_OP_GENERATE :\n+\t\t\tRTE_CRYPTO_AUTH_OP_VERIFY;\n+\t\txform.auth.digest_length = profile->auth.digest_size;\n+\t\txform.auth.key.length = profile->key_size;\n+\t\txform.auth.key.data = profile->key;\n+\t\txform.auth.iv.length = profile->iv_size;\n+\t\txform.auth.iv.offset = IV_OFFSET;\n+\t\tbreak;\n+\tcase RTE_CRYPTO_SYM_XFORM_CIPHER:\n+\t\txform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;\n+\t\txform.next = NULL;\n+\t\txform.cipher.algo = profile->cipher.algo;\n+\t\txform.cipher.op = op_type == OP_ENCRYPT ? RTE_CRYPTO_CIPHER_OP_ENCRYPT :\n+\t\t\tRTE_CRYPTO_CIPHER_OP_DECRYPT;\n+\t\txform.cipher.key.length = profile->key_size;\n+\t\txform.cipher.key.data = profile->key;\n+\t\txform.cipher.iv.length = profile->iv_size;\n+\t\txform.cipher.iv.offset = IV_OFFSET;\n+\t\tbreak;\n+\tcase RTE_CRYPTO_SYM_XFORM_AEAD:\n+\t\txform.type = RTE_CRYPTO_SYM_XFORM_AEAD;\n+\t\txform.next = NULL;\n+\t\txform.aead.algo = profile->aead.algo;\n+\t\txform.aead.op = op_type == OP_ENCRYPT ? RTE_CRYPTO_AEAD_OP_ENCRYPT :\n+\t\t\tRTE_CRYPTO_AEAD_OP_DECRYPT;\n+\t\txform.aead.digest_length = profile->aead.digest_size;\n+\t\txform.aead.key.length = profile->key_size;\n+\t\txform.aead.key.data = profile->key;\n+\t\txform.aead.iv.length = profile->iv_size;\n+\t\txform.aead.iv.offset = IV_OFFSET;\n+\t\txform.aead.aad_length = profile->aead.aad_size;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn NULL;\n+\t}\n+\n+\tsession = rte_cryptodev_sym_session_create(dev_id, &xform, testsuite_params.session_mpool);\n+\n+\treturn session;\n+}\n+\n+static struct rte_mbuf*\n+mbuf_create(const uint8_t *input_buf, uint16_t input_len)\n+{\n+\tstruct rte_mbuf *pkt;\n+\tuint8_t *pkt_data;\n+\n+\tpkt = rte_pktmbuf_alloc(testsuite_params.mbuf_pool);\n+\tif (pkt == NULL) {\n+\t\tRTE_LOG(ERR, USER1,  \"Failed to allocate input buffer in mempool\");\n+\t\treturn NULL;\n+\t}\n+\n+\t/* zeroing tailroom */\n+\tmemset(rte_pktmbuf_mtod(pkt, uint8_t *), 0, rte_pktmbuf_tailroom(pkt));\n+\n+\tpkt_data = (uint8_t *)rte_pktmbuf_append(pkt, input_len);\n+\tif (pkt_data == NULL) {\n+\t\tRTE_LOG(ERR, USER1, \"no room to append data, len: %d\", input_len);\n+\t\tgoto error;\n+\t}\n+\trte_memcpy(pkt_data, input_buf, input_len);\n+\n+\treturn pkt;\n+error:\n+\trte_pktmbuf_free(pkt);\n+\treturn NULL;\n+}\n+\n+static uint16_t\n+profile_digest_get(const struct crosscheck_test_profile *profile)\n+{\n+\tswitch (profile->xform_type) {\n+\tcase RTE_CRYPTO_SYM_XFORM_AUTH:\n+\t\treturn profile->auth.digest_size;\n+\tcase RTE_CRYPTO_SYM_XFORM_AEAD:\n+\t\treturn profile->aead.digest_size;\n+\tdefault:\n+\t\treturn 0;\n+\t}\n+}\n+\n+static struct rte_crypto_op*\n+operation_create(const struct crosscheck_test_profile *profile,\n+\t\tstruct rte_mbuf *ibuf, enum crypto_op_type op_type)\n+{\n+\tuint8_t *digest_data = NULL, *aad_data = NULL, *iv_ptr = NULL;\n+\tuint16_t aad_size = 0, digest_size = 0, digest_offset = 0;\n+\tuint16_t plaintext_len = profile->input_buf_len;\n+\trte_iova_t digest_addr = 0, aad_addr = 0;\n+\tstruct rte_crypto_sym_op *sym_op;\n+\tstruct rte_crypto_op *op;\n+\n+\top = rte_crypto_op_alloc(testsuite_params.op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);\n+\tif (op == NULL) {\n+\t\tRTE_LOG(ERR, USER1, \"Failed to allocate symmetric crypto operation struct\");\n+\t\treturn NULL;\n+\t}\n+\n+\t/* Obtain aad and digest sizes */\n+\tdigest_size = profile_digest_get(profile);\n+\tif (profile->xform_type == RTE_CRYPTO_SYM_XFORM_AEAD)\n+\t\taad_size = profile->aead.aad_size;\n+\n+\tif (aad_size) {\n+\t\tif (op_type == OP_ENCRYPT) {\n+\t\t\tif (rte_pktmbuf_tailroom(ibuf) > plaintext_len + aad_size) {\n+\t\t\t\t/* Put aad to data segment */\n+\t\t\t\taad_data = mbuf_room_create(ibuf, aad_size);\n+\t\t\t} else {\n+\t\t\t\tRTE_LOG(ERR, USER1, \"No space for aad in single mbuf\\n\");\n+\t\t\t\tgoto error;\n+\t\t\t}\n+\t\t\tpattern_fill(aad_data, \"This is an aad.\", aad_size);\n+\t\t} else {\n+\t\t\taad_data = rte_pktmbuf_mtod(ibuf, uint8_t *);\n+\t\t}\n+\t\taad_addr = rte_pktmbuf_iova(ibuf);\n+\t}\n+\n+\tif (digest_size) {\n+\t\tdigest_offset = aad_size + plaintext_len;\n+\t\tif (op_type == OP_ENCRYPT) {\n+\t\t\tdigest_data = (uint8_t *)rte_pktmbuf_append(ibuf, digest_size);\n+\t\t\tif (digest_data == NULL) {\n+\t\t\t\tRTE_LOG(ERR, USER1, \"No room to append digest\\n\");\n+\t\t\t\tgoto error;\n+\t\t\t}\n+\t\t} else {\n+\t\t\tdigest_data = rte_pktmbuf_mtod_offset(ibuf, uint8_t *, digest_offset);\n+\t\t}\n+\t\tdigest_addr = rte_pktmbuf_iova_offset(ibuf, digest_offset);\n+\t}\n+\n+\tsym_op = op->sym;\n+\tmemset(sym_op, 0, sizeof(*sym_op));\n+\n+\tiv_ptr = rte_crypto_op_ctod_offset(op, uint8_t *, IV_OFFSET);\n+\trte_memcpy(iv_ptr, profile->iv, profile->iv_size);\n+\n+\tswitch (profile->xform_type) {\n+\tcase RTE_CRYPTO_SYM_XFORM_AUTH:\n+\t\tsym_op->auth.digest.phys_addr = digest_addr;\n+\t\tsym_op->auth.digest.data = digest_data;\n+\t\tsym_op->auth.data.length = plaintext_len;\n+\t\tbreak;\n+\tcase RTE_CRYPTO_SYM_XFORM_CIPHER:\n+\t\tsym_op->cipher.data.length = plaintext_len;\n+\t\tbreak;\n+\tcase RTE_CRYPTO_SYM_XFORM_AEAD:\n+\t\tsym_op->aead.aad.phys_addr = aad_addr;\n+\t\tsym_op->aead.aad.data = aad_data;\n+\t\tsym_op->aead.digest.phys_addr = digest_addr;\n+\t\tsym_op->aead.digest.data = digest_data;\n+\t\tsym_op->aead.data.offset = aad_size;\n+\t\tsym_op->aead.data.length = plaintext_len;\n+\t\tbreak;\n+\tdefault:\n+\t\tgoto error;\n+\t}\n+\n+\tsym_op->m_src = ibuf;\n+\n+\treturn op;\n+\n+error:\n+\trte_crypto_op_free(op);\n+\treturn NULL;\n+}\n+\n+static void\n+mbuf_to_buf_copy(const struct rte_mbuf *m, uint8_t *res_buf, uint16_t *len)\n+{\n+\tconst uint8_t *out;\n+\n+\t*len = m->pkt_len;\n+\tout = rte_pktmbuf_read(m, 0, *len, res_buf);\n+\t/* Single segment buffer */\n+\tif (out != res_buf)\n+\t\tmemcpy(res_buf, out, *len);\n+}\n+\n+static int\n+single_dev_process(const struct crosscheck_test_profile *profile, uint16_t dev_id, enum\n+\t\tcrypto_op_type op_type, const uint8_t *input_buf, uint16_t input_len,\n+\t\tuint8_t *output_buf, uint16_t *output_len)\n+{\n+\tstruct rte_cryptodev_sym_session *session = NULL;\n+\tstruct rte_mbuf *ibuf = NULL, *obuf = NULL;\n+\tstruct rte_crypto_op *op = NULL;\n+\tint ret = -1;\n+\n+\tsession = session_create(profile, dev_id, op_type);\n+\tif (session == NULL)\n+\t\tgoto error;\n+\n+\tibuf = mbuf_create(input_buf, input_len);\n+\tif (ibuf == NULL)\n+\t\tgoto error;\n+\n+\top = operation_create(profile, ibuf, op_type);\n+\tif (op == NULL)\n+\t\tgoto error;\n+\n+\tdebug_hexdump(stdout, \"Input:\", rte_pktmbuf_mtod(ibuf, uint8_t*), ibuf->pkt_len);\n+\n+\trte_crypto_op_attach_sym_session(op, session);\n+\n+\tstruct rte_crypto_op *res = crypto_request_process(dev_id, op);\n+\tif (res == NULL)\n+\t\tgoto error;\n+\n+\tobuf = op->sym->m_src;\n+\tif (obuf == NULL) {\n+\t\tRTE_LOG(ERR, USER1, \"Invalid packet received\\n\");\n+\t\tgoto error;\n+\t}\n+\tmbuf_to_buf_copy(obuf, output_buf, output_len);\n+\n+\tret = 0;\n+\n+error:\n+\tif (session != NULL) {\n+\t\tint sret;\n+\t\tsret = rte_cryptodev_sym_session_free(dev_id, session);\n+\t\tassert(sret == 0);\n+\t}\n+\trte_pktmbuf_free(ibuf);\n+\trte_crypto_op_free(op);\n+\treturn ret;\n+}\n+\n+static int\n+crosscheck_all_devices(const struct crosscheck_test_profile *profile, enum crypto_op_type op_type,\n+\t\tconst uint8_t *input_text, uint16_t input_len, uint8_t *output_text,\n+\t\tuint16_t *output_len)\n+{\n+\tstruct crypto_testsuite_params *ts_params = &testsuite_params;\n+\tuint16_t len = 0, expected_len = 0;\n+\tuint8_t expected_text[MBUF_SIZE];\n+\tuint8_t i, dev_id;\n+\tint status;\n+\n+\tfor (i = 0; i < ts_params->valid_dev_count; i++) {\n+\t\tdev_id = ts_params->valid_devs[i];\n+\t\tstatus = single_dev_process(profile, dev_id, op_type, input_text, input_len,\n+\t\t\t\toutput_text, &len);\n+\t\tTEST_ASSERT_SUCCESS(status, \"Error occurred during processing\");\n+\n+\t\tif (i == 0) {\n+\t\t\t/* First device, copy data for future comparisons */\n+\t\t\tmemcpy(expected_text, output_text, len);\n+\t\t\texpected_len = len;\n+\t\t} else {\n+\t\t\t/* Compare output against expected(first) output */\n+\t\t\tTEST_ASSERT_EQUAL(len, expected_len, \"Length mismatch %d != %d !\\n\",\n+\t\t\t\t\tlen, expected_len);\n+\n+\t\t\tif (memcmp(output_text, expected_text, len)) {\n+\t\t\t\tRTE_LOG(ERR, USER1, \"Output mismatch between dev 0 and %i\\n\",\n+\t\t\t\t\t\tdev_id);\n+\t\t\t\trte_hexdump(rte_log_get_stream(), \"expected\", expected_text, len);\n+\t\t\t\trte_hexdump(rte_log_get_stream(), \"received\", output_text, len);\n+\t\t\t\treturn TEST_FAILED;\n+\t\t\t}\n+\t\t}\n+\n+\t\tRTE_LOG(DEBUG, USER1, \"DEV ID: %u finished processing\\n\", dev_id);\n+\t\tdebug_hexdump(stdout, \"Output: \", output_text, len);\n+\t}\n+\n+\t*output_len = len;\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+check_negative_all_devices(const struct crosscheck_test_profile *profile,\n+\t\tenum crypto_op_type op_type, const uint8_t *input_text, uint16_t input_len)\n+{\n+\tstruct crypto_testsuite_params *ts_params = &testsuite_params;\n+\tuint8_t output_text[MBUF_SIZE];\n+\tuint8_t i, dev_id;\n+\tuint16_t len;\n+\tint status;\n+\n+\tfor (i = 0; i < ts_params->valid_dev_count; i++) {\n+\t\tdev_id = ts_params->valid_devs[i];\n+\t\tstatus = single_dev_process(profile, dev_id, op_type, input_text, input_len,\n+\t\t\t\toutput_text, &len);\n+\t\tTEST_ASSERT_FAIL(status, \"Error occurred during processing negative case\");\n+\n+\t}\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+crosscheck_with_profile_run(const struct crosscheck_test_profile *profile)\n+{\n+\tuint8_t input_text[profile->input_buf_len];\n+\tuint16_t output_len, encrypted_len;\n+\tuint8_t encrypted_text[MBUF_SIZE];\n+\tuint8_t output_text[MBUF_SIZE];\n+\tint status;\n+\n+\t/* Encrypt Stage */\n+\tRTE_LOG(DEBUG, USER1, \"Executing encrypt stage\\n\");\n+\t/* Fill input with incrementing pattern */\n+\tincrementing_generate(input_text, 'a', profile->input_buf_len);\n+\tstatus = crosscheck_all_devices(profile, OP_ENCRYPT, input_text, profile->input_buf_len,\n+\t\t\toutput_text, &output_len);\n+\tTEST_ASSERT_SUCCESS(status, \"Error occurred during encryption\");\n+\n+\t/* Decrypt Stage */\n+\tRTE_LOG(DEBUG, USER1, \"Executing decrypt stage\\n\");\n+\t/* Set up encrypted data as input */\n+\tencrypted_len = output_len;\n+\tmemcpy(encrypted_text, output_text, output_len);\n+\tstatus = crosscheck_all_devices(profile, OP_DECRYPT, encrypted_text, encrypted_len,\n+\t\t\toutput_text, &output_len);\n+\tTEST_ASSERT_SUCCESS(status, \"Error occurred during decryption\");\n+\n+\t/* Negative Stage */\n+\tRTE_LOG(DEBUG, USER1, \"Executing negative stage\\n\");\n+\tif (profile_digest_get(profile)) {\n+\t\t/* Corrupting one byte of digest */\n+\t\tencrypted_text[encrypted_len - 1] += 1;\n+\t\tstatus = check_negative_all_devices(profile, OP_DECRYPT, encrypted_text,\n+\t\t\t\tencrypted_len);\n+\t\tTEST_ASSERT_SUCCESS(status, \"Error occurred during decryption\");\n+\t}\n+\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+test_crosscheck_unit(const void *ptr)\n+{\n+\tconst struct crosscheck_test_profile *profile = ptr;\n+\n+\tif (profile->xform_type == RTE_CRYPTO_SYM_XFORM_NOT_SPECIFIED)\n+\t\treturn TEST_SKIPPED;\n+\n+\treturn crosscheck_with_profile_run(profile);\n+}\n+\n+static struct unit_test_suite*\n+sym_unit_test_suite_create(int algo, enum rte_crypto_sym_xform_type xform_type)\n+{\n+\tstruct rte_cryptodev_symmetric_capability *capabilities;\n+\tsize_t uts_size, total_size, input_sz;\n+\tstruct meta_test_suite *meta_ts;\n+\tstruct unit_test_suite *uts;\n+\tconst char *suite_prefix = NULL;\n+\tconst char *algo_name = NULL;\n+\tuint64_t test_case_idx = 0;\n+\tstruct unit_test_case *utc;\n+\tint cap_type;\n+\tchar *mem;\n+\n+\tswitch (xform_type) {\n+\tcase RTE_CRYPTO_SYM_XFORM_AUTH:\n+\t\tsuite_prefix = \"Algo AUTH \";\n+\t\talgo_name = rte_crypto_auth_algorithm_strings[algo];\n+\t\tbreak;\n+\tcase RTE_CRYPTO_SYM_XFORM_CIPHER:\n+\t\tsuite_prefix = \"Algo CIPHER\";\n+\t\talgo_name = rte_crypto_cipher_algorithm_strings[algo];\n+\t\tbreak;\n+\tcase RTE_CRYPTO_SYM_XFORM_AEAD:\n+\t\tsuite_prefix = \"Algo AEAD\";\n+\t\talgo_name = rte_crypto_aead_algorithm_strings[algo];\n+\t\tbreak;\n+\tdefault:\n+\t\treturn NULL;\n+\t}\n+\n+\t/* Calculate size for test suite with all test cases +1 NULL case */\n+\tuts_size = sizeof(struct unit_test_suite) +\n+\t\t(NB_TEST_CASES_PER_ALGO + 1) * sizeof(struct unit_test_case);\n+\n+\t/* Also allocate memory for suite meta data */\n+\ttotal_size = uts_size + sizeof(struct meta_test_suite);\n+\tmem = rte_zmalloc(NULL, total_size, 0);\n+\tif (mem == NULL)\n+\t\treturn NULL;\n+\tuts = (struct unit_test_suite *) mem;\n+\tmeta_ts = (struct meta_test_suite *) (mem + uts_size);\n+\n+\t/* Initialize test suite */\n+\tsnprintf(meta_ts->suite_name, MAX_TEST_STRING_LEN, \"%s '%s'\", suite_prefix, algo_name);\n+\tuts->suite_name = meta_ts->suite_name;\n+\n+\tcapabilities = common_capability_get(algo, xform_type);\n+\tif (capabilities->xform_type == 0) /* Skip case if current algo is not supported */\n+\t\treturn uts;\n+\n+\t/* Initialize test cases */\n+\n+\tfor (cap_type = 0; cap_type < CAPABILITY_TYPE_LAST; cap_type++) {\n+\t\tfor (input_sz = 0; input_sz < RTE_DIM(input_length); input_sz++) {\n+\t\t\tmeta_ts->profile[test_case_idx] = profile_create(\n+\t\t\t\t\tcapabilities, cap_type, input_length[input_sz]);\n+\t\t\tutc = &uts->unit_test_cases[test_case_idx];\n+\t\t\tutc->name = meta_ts->profile[test_case_idx].name;\n+\t\t\tutc->data = (const void *) &meta_ts->profile[test_case_idx];\n+\t\t\tutc->testcase_with_data = test_crosscheck_unit;\n+\t\t\tutc->enabled = true;\n+\n+\t\t\ttest_case_idx += 1;\n+\t\t\tRTE_VERIFY(test_case_idx <= NB_TEST_CASES_PER_ALGO);\n+\t\t}\n+\t}\n+\n+\treturn uts;\n+}\n+\n+static void\n+sym_unit_test_suite_free(struct unit_test_suite *suite)\n+{\n+\tstruct crosscheck_test_profile profile;\n+\tstruct unit_test_case *utc;\n+\tint i;\n+\n+\tfor (i = 0; suite->unit_test_cases[i].testcase_with_data; i++) {\n+\t\tutc = &suite->unit_test_cases[i];\n+\t\tprofile = *(const struct crosscheck_test_profile *)utc->data;\n+\t\trte_free(profile.key);\n+\t\trte_free(profile.iv);\n+\t}\n+\n+\trte_free(suite);\n+}\n+\n+static int\n+test_crosscheck(void)\n+{\n+\tint ret, i, ts_idx = 0;\n+\tstatic struct unit_test_suite ts = {\n+\t\t.suite_name = \"Crosscheck Unit Test Suite\",\n+\t\t.setup = crosscheck_suite_setup,\n+\t\t.teardown = crosscheck_suite_teardown,\n+\t\t.unit_test_cases = {TEST_CASES_END()}\n+\t};\n+\tstruct unit_test_suite *test_suites[CRYPTO_ALGOS_LEN+1] = {0};/* 1 for NULL-end suite */\n+\n+\t/* Allocate all required memory pools and crosscheck cryptodev capabilities */\n+\tret = crosscheck_init();\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/* Create test suite for each known algorithm */\n+\tts.unit_test_suites = test_suites;\n+\tfor (i = 1; i <= CRYPTO_AUTH_MAX_IDX; i++) {\n+\t\tts.unit_test_suites[ts_idx++] = sym_unit_test_suite_create(i,\n+\t\t\t\tRTE_CRYPTO_SYM_XFORM_AUTH);\n+\t}\n+\tfor (i = 1; i <= CRYPTO_CIPHER_MAX_IDX; i++) {\n+\t\tts.unit_test_suites[ts_idx++] = sym_unit_test_suite_create(i,\n+\t\t\t\tRTE_CRYPTO_SYM_XFORM_CIPHER);\n+\t}\n+\tfor (i = 1; i <= CRYPTO_AEAD_MAX_IDX; i++) {\n+\t\t/* AES_CCM requires special handling due to api requirements, skip now */\n+\t\tif (i == RTE_CRYPTO_AEAD_AES_CCM)\n+\t\t\tcontinue;\n+\t\tts.unit_test_suites[ts_idx++] = sym_unit_test_suite_create(i,\n+\t\t\t\tRTE_CRYPTO_SYM_XFORM_AEAD);\n+\t}\n+\n+\tret = unit_test_suite_runner(&ts);\n+\n+\tfor (i = 0; i < ts_idx; i++)\n+\t\tsym_unit_test_suite_free(ts.unit_test_suites[i]);\n+\n+\treturn ret;\n+}\n+\n+REGISTER_TEST_COMMAND(cryptodev_crosscheck, test_crosscheck);\n",
    "prefixes": [
        "v2"
    ]
}