get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 134918,
    "url": "http://patchwork.dpdk.org/api/patches/134918/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20231207130216.140-7-anoobj@marvell.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<20231207130216.140-7-anoobj@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20231207130216.140-7-anoobj@marvell.com",
    "date": "2023-12-07T13:02:08",
    "name": "[06/14] test/crypto: add TLS record tests",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "4866d8efcc51e548c522445e3dd582d278bb1f14",
    "submitter": {
        "id": 1205,
        "url": "http://patchwork.dpdk.org/api/people/1205/?format=api",
        "name": "Anoob Joseph",
        "email": "anoobj@marvell.com"
    },
    "delegate": {
        "id": 6690,
        "url": "http://patchwork.dpdk.org/api/users/6690/?format=api",
        "username": "akhil",
        "first_name": "akhil",
        "last_name": "goyal",
        "email": "gakhil@marvell.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20231207130216.140-7-anoobj@marvell.com/mbox/",
    "series": [
        {
            "id": 30476,
            "url": "http://patchwork.dpdk.org/api/series/30476/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=30476",
            "date": "2023-12-07T13:02:02",
            "name": "Add TLS record test suite",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/30476/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/134918/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/134918/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 6D51E43699;\n\tThu,  7 Dec 2023 14:03:25 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id EFBFD42F15;\n\tThu,  7 Dec 2023 14:02:42 +0100 (CET)",
            "from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com\n [67.231.148.174])\n by mails.dpdk.org (Postfix) with ESMTP id ED18C42F0B\n for <dev@dpdk.org>; Thu,  7 Dec 2023 14:02:40 +0100 (CET)",
            "from pps.filterd (m0045849.ppops.net [127.0.0.1])\n by mx0a-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id\n 3B76M57I017039; Thu, 7 Dec 2023 05:02:40 -0800",
            "from dc5-exch02.marvell.com ([199.233.59.182])\n by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3uu8qe98ka-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT);\n Thu, 07 Dec 2023 05:02:39 -0800",
            "from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.48;\n Thu, 7 Dec 2023 05:02:38 -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.48 via Frontend\n Transport; Thu, 7 Dec 2023 05:02:38 -0800",
            "from BG-LT92004.corp.innovium.com (unknown [10.28.163.189])\n by maili.marvell.com (Postfix) with ESMTP id CA9C83F70B2;\n Thu,  7 Dec 2023 05:02:35 -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=DqgfsLpYLLmVVZlAeX/wxwotoKAReTX8rcy5HzQypqI=;\n b=FPF+EvHiCbJ1+wn215rJaDdazsLESOYAOcrHUAsFfB91+92jQECi5e6sqFqVae0QT2fh\n qwk1vrGb26IG2HP8g6EmAD4KDfIPNNYuq0J3iSEZWuQGkeLouEDp7ZHLq7t67JBbDoQ6\n /IQmyXvETrUBwXV1sGBOkD/2zTNKnSAJJGV/Es8qV989WpF38KAJub7UvFtmq7uO4MM/\n 3VU8TRpCh/i7/ezi5vzmaVJKDvHiEnz2I1oSpKwgYl7B6WKCzW9aZQEEFldfAwG1J/T1\n DhmmRSKPaFIBFpHqEUkAi5Uvp3fQuMPfVOyrNhOj1stAFsv4rmQOUpuw/WHfB4S6IZ6A Sg==",
        "From": "Anoob Joseph <anoobj@marvell.com>",
        "To": "Akhil Goyal <gakhil@marvell.com>, Jerin Jacob <jerinj@marvell.com>",
        "CC": "Harry van Haaren <harry.van.haaren@intel.com>, Hemant Agrawal\n <hemant.agrawal@nxp.com>, Konstantin Ananyev\n <konstantin.v.ananyev@yandex.ru>, <dev@dpdk.org>, Vidya Sagar Velumuri\n <vvelumuri@marvell.com>",
        "Subject": "[PATCH 06/14] test/crypto: add TLS record tests",
        "Date": "Thu, 7 Dec 2023 18:32:08 +0530",
        "Message-ID": "<20231207130216.140-7-anoobj@marvell.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20231207130216.140-1-anoobj@marvell.com>",
        "References": "<20231207130216.140-1-anoobj@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Proofpoint-GUID": "NEj-PnZk8DQjHaSCcM7lXtV2f59XGht6",
        "X-Proofpoint-ORIG-GUID": "NEj-PnZk8DQjHaSCcM7lXtV2f59XGht6",
        "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.272,Aquarius:18.0.997,Hydra:6.0.619,FMLib:17.11.176.26\n definitions=2023-12-07_10,2023-12-07_01,2023-05-22_02",
        "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 framework for testing TLS record cases. The framework supports\ntesting with known vector tests in both session types (read & write).\n\nSigned-off-by: Anoob Joseph <anoobj@marvell.com>\nSigned-off-by: Vidya Sagar Velumuri <vvelumuri@marvell.com>\n---\n app/test/meson.build                          |   1 +\n app/test/test_cryptodev.c                     | 282 +++++++++++++++++-\n app/test/test_cryptodev.h                     |   2 +\n app/test/test_cryptodev_security_tls_record.c | 151 ++++++++++\n app/test/test_cryptodev_security_tls_record.h |  71 +++++\n ...yptodev_security_tls_record_test_vectors.h |  16 +\n 6 files changed, 515 insertions(+), 8 deletions(-)\n create mode 100644 app/test/test_cryptodev_security_tls_record.c\n create mode 100644 app/test/test_cryptodev_security_tls_record.h\n create mode 100644 app/test/test_cryptodev_security_tls_record_test_vectors.h",
    "diff": "diff --git a/app/test/meson.build b/app/test/meson.build\nindex 58e120a6ab..f9e81eda2e 100644\n--- a/app/test/meson.build\n+++ b/app/test/meson.build\n@@ -56,6 +56,7 @@ source_file_deps = {\n     'test_cryptodev_crosscheck.c': test_cryptodev_deps,\n     'test_cryptodev_security_ipsec.c': test_cryptodev_deps,\n     'test_cryptodev_security_pdcp.c': test_cryptodev_deps,\n+    'test_cryptodev_security_tls_record.c': ['cryptodev', 'security'],\n     'test_cycles.c': [],\n     'test_debug.c': [],\n     'test_devargs.c': ['kvargs'],\ndiff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c\nindex fbb97d5456..cd83370790 100644\n--- a/app/test/test_cryptodev.c\n+++ b/app/test/test_cryptodev.c\n@@ -53,6 +53,7 @@\n #include \"test_cryptodev_security_pdcp_sdap_test_vectors.h\"\n #include \"test_cryptodev_security_pdcp_test_func.h\"\n #include \"test_cryptodev_security_docsis_test_vectors.h\"\n+#include \"test_cryptodev_security_tls_record.h\"\n #include \"test_security_proto.h\"\n \n #define SDAP_DISABLED\t0\n@@ -807,7 +808,7 @@ crypto_gen_testsuite_setup(void)\n \n #ifdef RTE_LIB_SECURITY\n static int\n-ipsec_proto_testsuite_setup(void)\n+sec_proto_testsuite_setup(enum rte_security_session_protocol protocol)\n {\n \tstruct crypto_testsuite_params *ts_params = &testsuite_params;\n \tstruct crypto_unittest_params *ut_params = &unittest_params;\n@@ -817,8 +818,8 @@ ipsec_proto_testsuite_setup(void)\n \trte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);\n \n \tif (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_SECURITY)) {\n-\t\tRTE_LOG(INFO, USER1, \"Feature flag requirements for IPsec Proto \"\n-\t\t\t\t\"testsuite not met\\n\");\n+\t\tRTE_LOG(INFO, USER1,\n+\t\t\t\"Feature flag requirements for security protocol testsuite not met\\n\");\n \t\treturn TEST_SKIPPED;\n \t}\n \n@@ -830,11 +831,9 @@ ipsec_proto_testsuite_setup(void)\n \t/* Set action type */\n \tut_params->type = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL;\n \n-\tif (security_proto_supported(\n-\t\t\tRTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,\n-\t\t\tRTE_SECURITY_PROTOCOL_IPSEC) < 0) {\n-\t\tRTE_LOG(INFO, USER1, \"Capability requirements for IPsec Proto \"\n-\t\t\t\t\"test not met\\n\");\n+\tif (security_proto_supported(RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL, protocol) < 0) {\n+\t\tRTE_LOG(INFO, USER1,\n+\t\t\t\"Capability requirements for security protocol test not met\\n\");\n \t\tret = TEST_SKIPPED;\n \t}\n \n@@ -850,6 +849,18 @@ ipsec_proto_testsuite_setup(void)\n \treturn ret;\n }\n \n+static int\n+ipsec_proto_testsuite_setup(void)\n+{\n+\treturn sec_proto_testsuite_setup(RTE_SECURITY_PROTOCOL_IPSEC);\n+}\n+\n+static int\n+tls_record_proto_testsuite_setup(void)\n+{\n+\treturn sec_proto_testsuite_setup(RTE_SECURITY_PROTOCOL_TLS_RECORD);\n+}\n+\n static int\n pdcp_proto_testsuite_setup(void)\n {\n@@ -11654,6 +11665,244 @@ test_docsis_proto_downlink(const void *data)\n \n \treturn ret;\n }\n+\n+static void\n+test_tls_record_imp_nonce_update(const struct tls_record_test_data *td,\n+\t\t\t\t struct rte_security_tls_record_xform *tls_record_xform)\n+{\n+\tunsigned int imp_nonce_len;\n+\tuint8_t *imp_nonce;\n+\n+\tswitch (tls_record_xform->ver) {\n+\tcase RTE_SECURITY_VERSION_TLS_1_2:\n+\t\timp_nonce_len = RTE_SECURITY_TLS_1_2_IMP_NONCE_LEN;\n+\t\timp_nonce = tls_record_xform->tls_1_2.imp_nonce;\n+\t\tbreak;\n+\tcase RTE_SECURITY_VERSION_DTLS_1_2:\n+\t\timp_nonce_len = RTE_SECURITY_DTLS_1_2_IMP_NONCE_LEN;\n+\t\timp_nonce = tls_record_xform->dtls_1_2.imp_nonce;\n+\t\tbreak;\n+\tcase RTE_SECURITY_VERSION_TLS_1_3:\n+\t\timp_nonce_len = RTE_SECURITY_TLS_1_3_IMP_NONCE_LEN;\n+\t\timp_nonce = tls_record_xform->tls_1_3.imp_nonce;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn;\n+\t}\n+\n+\timp_nonce_len = RTE_MIN(imp_nonce_len, td[0].imp_nonce.len);\n+\tmemcpy(imp_nonce, td[0].imp_nonce.data, imp_nonce_len);\n+}\n+\n+static int\n+test_tls_record_proto_process(const struct tls_record_test_data td[],\n+\t\t\t      struct tls_record_test_data res_d[], int nb_td, bool silent,\n+\t\t\t      const struct tls_record_test_flags *flags)\n+{\n+\tstruct crypto_testsuite_params *ts_params = &testsuite_params;\n+\tstruct crypto_unittest_params *ut_params = &unittest_params;\n+\tstruct rte_security_tls_record_xform tls_record_xform;\n+\tstruct rte_security_capability_idx sec_cap_idx;\n+\tconst struct rte_security_capability *sec_cap;\n+\tenum rte_security_tls_sess_type sess_type;\n+\tuint8_t dev_id = ts_params->valid_devs[0];\n+\tstruct rte_security_ctx *ctx;\n+\tint i, ret = TEST_SUCCESS;\n+\n+\tut_params->type = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL;\n+\tgbl_action_type = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL;\n+\n+\t/* Use first test data to create session */\n+\n+\t/* Copy TLS record xform */\n+\tmemcpy(&tls_record_xform, &td[0].tls_record_xform, sizeof(tls_record_xform));\n+\n+\tsess_type = tls_record_xform.type;\n+\n+\tctx = rte_cryptodev_get_sec_ctx(dev_id);\n+\n+\tsec_cap_idx.action = ut_params->type;\n+\tsec_cap_idx.protocol = RTE_SECURITY_PROTOCOL_TLS_RECORD;\n+\tsec_cap_idx.tls_record.type = tls_record_xform.type;\n+\tsec_cap_idx.tls_record.ver = tls_record_xform.ver;\n+\n+\tsec_cap = rte_security_capability_get(ctx, &sec_cap_idx);\n+\tif (sec_cap == NULL)\n+\t\treturn TEST_SKIPPED;\n+\n+\t/* Copy cipher session parameters */\n+\tif (td[0].aead) {\n+\t\tmemcpy(&ut_params->aead_xform, &td[0].xform.aead, sizeof(ut_params->aead_xform));\n+\t\tut_params->aead_xform.aead.key.data = td[0].key.data;\n+\t\tut_params->aead_xform.aead.iv.offset = IV_OFFSET;\n+\n+\t\t/* Verify crypto capabilities */\n+\t\tif (test_sec_crypto_caps_aead_verify(sec_cap, &ut_params->aead_xform) != 0) {\n+\t\t\tif (!silent)\n+\t\t\t\tRTE_LOG(INFO, USER1, \"Crypto capabilities not supported\\n\");\n+\t\t\treturn TEST_SKIPPED;\n+\t\t}\n+\t} else {\n+\t\tmemcpy(&ut_params->cipher_xform, &td[0].xform.chain.cipher,\n+\t\t       sizeof(ut_params->cipher_xform));\n+\t\tmemcpy(&ut_params->auth_xform, &td[0].xform.chain.auth,\n+\t\t       sizeof(ut_params->auth_xform));\n+\t\tut_params->cipher_xform.cipher.key.data = td[0].key.data;\n+\t\tut_params->cipher_xform.cipher.iv.offset = IV_OFFSET;\n+\t\tut_params->auth_xform.auth.key.data = td[0].auth_key.data;\n+\n+\t\t/* Verify crypto capabilities */\n+\n+\t\tif (test_sec_crypto_caps_cipher_verify(sec_cap, &ut_params->cipher_xform) != 0) {\n+\t\t\tif (!silent)\n+\t\t\t\tRTE_LOG(INFO, USER1, \"Cipher crypto capabilities not supported\\n\");\n+\t\t\treturn TEST_SKIPPED;\n+\t\t}\n+\n+\t\tif (test_sec_crypto_caps_auth_verify(sec_cap, &ut_params->auth_xform) != 0) {\n+\t\t\tif (!silent)\n+\t\t\t\tRTE_LOG(INFO, USER1, \"Auth crypto capabilities not supported\\n\");\n+\t\t\treturn TEST_SKIPPED;\n+\t\t}\n+\t}\n+\n+\tif (test_tls_record_sec_caps_verify(&tls_record_xform, sec_cap, silent) != 0)\n+\t\treturn TEST_SKIPPED;\n+\n+\tstruct rte_security_session_conf sess_conf = {\n+\t\t.action_type = ut_params->type,\n+\t\t.protocol = RTE_SECURITY_PROTOCOL_TLS_RECORD,\n+\t};\n+\n+\tif (td[0].aead)\n+\t\ttest_tls_record_imp_nonce_update(&td[0], &tls_record_xform);\n+\n+\tsess_conf.tls_record = tls_record_xform;\n+\n+\tif (td[0].aead) {\n+\t\tsess_conf.crypto_xform = &ut_params->aead_xform;\n+\t} else {\n+\t\tif (sess_type == RTE_SECURITY_TLS_SESS_TYPE_READ) {\n+\t\t\tsess_conf.crypto_xform = &ut_params->cipher_xform;\n+\t\t\tut_params->cipher_xform.next = &ut_params->auth_xform;\n+\t\t} else {\n+\t\t\tsess_conf.crypto_xform = &ut_params->auth_xform;\n+\t\t\tut_params->auth_xform.next = &ut_params->cipher_xform;\n+\t\t}\n+\t}\n+\n+\t/* Create security session */\n+\tut_params->sec_session = rte_security_session_create(ctx, &sess_conf,\n+\t\t\t\t\tts_params->session_mpool);\n+\tif (ut_params->sec_session == NULL)\n+\t\treturn TEST_SKIPPED;\n+\n+\tfor (i = 0; i < nb_td; i++) {\n+\t\t/* Setup source mbuf payload */\n+\t\tut_params->ibuf = create_segmented_mbuf(ts_params->mbuf_pool, td[i].input_text.len,\n+\t\t\t\t1, 0);\n+\t\tpktmbuf_write(ut_params->ibuf, 0, td[i].input_text.len, td[i].input_text.data);\n+\n+\t\t/* Generate crypto op data structure */\n+\t\tut_params->op = rte_crypto_op_alloc(ts_params->op_mpool,\n+\t\t\t\t\t\t    RTE_CRYPTO_OP_TYPE_SYMMETRIC);\n+\t\tif (ut_params->op == NULL) {\n+\t\t\tprintf(\"Could not allocate crypto op\");\n+\t\t\tret = TEST_FAILED;\n+\t\t\tgoto crypto_op_free;\n+\t\t}\n+\n+\t\t/* Attach session to operation */\n+\t\trte_security_attach_session(ut_params->op, ut_params->sec_session);\n+\n+\t\t/* Set crypto operation mbufs */\n+\t\tut_params->op->sym->m_src = ut_params->ibuf;\n+\t\tut_params->op->sym->m_dst = NULL;\n+\t\tut_params->op->param1.tls_record.content_type = td[i].app_type;\n+\n+\t\t/* Copy IV in crypto operation when IV generation is disabled */\n+\t\tif (sess_type == RTE_SECURITY_TLS_SESS_TYPE_WRITE &&\n+\t\t    tls_record_xform.options.iv_gen_disable == 1) {\n+\t\t\tuint8_t *iv;\n+\t\t\tint len;\n+\n+\t\t\tiv = rte_crypto_op_ctod_offset(ut_params->op, uint8_t *, IV_OFFSET);\n+\t\t\tif (td[i].aead)\n+\t\t\t\tlen = td[i].xform.aead.aead.iv.length - 4;\n+\t\t\telse\n+\t\t\t\tlen = td[i].xform.chain.cipher.cipher.iv.length;\n+\t\t\tmemcpy(iv, td[i].iv.data, len);\n+\t\t}\n+\n+\t\t/* Process crypto operation */\n+\t\tprocess_crypto_request(dev_id, ut_params->op);\n+\n+\t\tret = test_tls_record_status_check(ut_params->op);\n+\t\tif (ret != TEST_SUCCESS)\n+\t\t\tgoto crypto_op_free;\n+\n+\t\tret = test_tls_record_post_process(ut_params->ibuf, &td[i], NULL, silent);\n+\t\tif (ret != TEST_SUCCESS)\n+\t\t\tgoto crypto_op_free;\n+\n+\n+\t\trte_crypto_op_free(ut_params->op);\n+\t\tut_params->op = NULL;\n+\n+\t\trte_pktmbuf_free(ut_params->ibuf);\n+\t\tut_params->ibuf = NULL;\n+\t}\n+\n+crypto_op_free:\n+\trte_crypto_op_free(ut_params->op);\n+\tut_params->op = NULL;\n+\n+\trte_pktmbuf_free(ut_params->ibuf);\n+\tut_params->ibuf = NULL;\n+\n+\tif (ut_params->sec_session)\n+\t\trte_security_session_destroy(ctx, ut_params->sec_session);\n+\tut_params->sec_session = NULL;\n+\n+\tRTE_SET_USED(res_d);\n+\tRTE_SET_USED(flags);\n+\n+\treturn ret;\n+}\n+\n+static int\n+test_tls_record_proto_known_vec(const void *test_data)\n+{\n+\tstruct tls_record_test_data td_write;\n+\tstruct tls_record_test_flags flags;\n+\n+\tmemset(&flags, 0, sizeof(flags));\n+\n+\tmemcpy(&td_write, test_data, sizeof(td_write));\n+\n+\t/* Disable IV gen to be able to test with known vectors */\n+\ttd_write.tls_record_xform.options.iv_gen_disable = 1;\n+\n+\treturn test_tls_record_proto_process(&td_write, NULL, 1, false, &flags);\n+}\n+\n+static int\n+test_tls_record_proto_known_vec_read(const void *test_data)\n+{\n+\tconst struct tls_record_test_data *td = test_data;\n+\tstruct tls_record_test_flags flags;\n+\tstruct tls_record_test_data td_inb;\n+\n+\tmemset(&flags, 0, sizeof(flags));\n+\n+\tif (td->tls_record_xform.type == RTE_SECURITY_TLS_SESS_TYPE_WRITE)\n+\t\ttest_tls_record_td_read_from_write(td, &td_inb);\n+\telse\n+\t\tmemcpy(&td_inb, td, sizeof(td_inb));\n+\n+\treturn test_tls_record_proto_process(&td_inb, NULL, 1, false, &flags);\n+}\n+\n #endif\n \n static int\n@@ -16560,6 +16809,22 @@ static struct unit_test_suite pdcp_proto_testsuite  = {\n \t}\n };\n \n+static struct unit_test_suite tls12_record_proto_testsuite  = {\n+\t.suite_name = \"TLS 1.2 Record Protocol Unit Test Suite\",\n+\t.setup = tls_record_proto_testsuite_setup,\n+\t.unit_test_cases = {\n+\t\tTEST_CASE_NAMED_WITH_DATA(\n+\t\t\t\"Known vector TBD\",\n+\t\t\tut_setup_security, ut_teardown,\n+\t\t\ttest_tls_record_proto_known_vec, &tls_test_data1),\n+\t\tTEST_CASE_NAMED_WITH_DATA(\n+\t\t\t\"Known vector TBD\",\n+\t\t\tut_setup_security, ut_teardown,\n+\t\t\ttest_tls_record_proto_known_vec_read, &tls_test_data1),\n+\t\tTEST_CASES_END() /**< NULL terminate unit test array */\n+\t}\n+};\n+\n #define ADD_UPLINK_TESTCASE(data)\t\t\t\t\t\t\\\n \tTEST_CASE_NAMED_WITH_DATA(data.test_descr_uplink, ut_setup_security,\t\\\n \tut_teardown, test_docsis_proto_uplink, (const void *) &data),\t\t\\\n@@ -17567,6 +17832,7 @@ run_cryptodev_testsuite(const char *pmd_name)\n \t\t&ipsec_proto_testsuite,\n \t\t&pdcp_proto_testsuite,\n \t\t&docsis_proto_testsuite,\n+\t\t&tls12_record_proto_testsuite,\n #endif\n \t\t&end_testsuite\n \t};\ndiff --git a/app/test/test_cryptodev.h b/app/test/test_cryptodev.h\nindex f2c417a267..f27d9697fd 100644\n--- a/app/test/test_cryptodev.h\n+++ b/app/test/test_cryptodev.h\n@@ -4,6 +4,8 @@\n #ifndef TEST_CRYPTODEV_H_\n #define TEST_CRYPTODEV_H_\n \n+#include <rte_cryptodev.h>\n+\n #define HEX_DUMP 0\n \n #define FALSE                           0\ndiff --git a/app/test/test_cryptodev_security_tls_record.c b/app/test/test_cryptodev_security_tls_record.c\nnew file mode 100644\nindex 0000000000..be8f5270cc\n--- /dev/null\n+++ b/app/test/test_cryptodev_security_tls_record.c\n@@ -0,0 +1,151 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(C) 2023 Marvell.\n+ */\n+\n+#include <rte_crypto.h>\n+\n+#include \"test.h\"\n+#include \"test_cryptodev_security_tls_record.h\"\n+#include \"test_cryptodev_security_tls_record_test_vectors.h\"\n+\n+int\n+test_tls_record_status_check(struct rte_crypto_op *op)\n+{\n+\tint ret = TEST_SUCCESS;\n+\n+\tif (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS)\n+\t\tret = TEST_FAILED;\n+\n+\treturn ret;\n+}\n+\n+int\n+test_tls_record_sec_caps_verify(struct rte_security_tls_record_xform *tls_record_xform,\n+\t\t\t\tconst struct rte_security_capability *sec_cap, bool silent)\n+{\n+\t/* Verify security capabilities */\n+\n+\tRTE_SET_USED(tls_record_xform);\n+\tRTE_SET_USED(sec_cap);\n+\tRTE_SET_USED(silent);\n+\n+\treturn 0;\n+}\n+\n+void\n+test_tls_record_td_read_from_write(const struct tls_record_test_data *td_out,\n+\t\t\t\t   struct tls_record_test_data *td_in)\n+{\n+\tmemcpy(td_in, td_out, sizeof(*td_in));\n+\n+\t/* Populate output text of td_in with input text of td_out */\n+\tmemcpy(td_in->output_text.data, td_out->input_text.data, td_out->input_text.len);\n+\ttd_in->output_text.len = td_out->input_text.len;\n+\n+\t/* Populate input text of td_in with output text of td_out */\n+\tmemcpy(td_in->input_text.data, td_out->output_text.data, td_out->output_text.len);\n+\ttd_in->input_text.len = td_out->output_text.len;\n+\n+\ttd_in->tls_record_xform.type = RTE_SECURITY_TLS_SESS_TYPE_READ;\n+\n+\tif (td_in->aead) {\n+\t\ttd_in->xform.aead.aead.op = RTE_CRYPTO_AEAD_OP_DECRYPT;\n+\t} else {\n+\t\ttd_in->xform.chain.auth.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;\n+\t\ttd_in->xform.chain.cipher.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT;\n+\t}\n+}\n+\n+static int\n+test_tls_record_td_verify(uint8_t *output_text, uint32_t len, const struct tls_record_test_data *td,\n+\t\t\t bool silent)\n+{\n+\tif (len != td->output_text.len) {\n+\t\tprintf(\"Output length (%d) not matching with expected (%d)\\n\",\n+\t\t\tlen, td->output_text.len);\n+\t\treturn TEST_FAILED;\n+\t}\n+\n+\tif (memcmp(output_text, td->output_text.data, len)) {\n+\t\tif (silent)\n+\t\t\treturn TEST_FAILED;\n+\n+\t\tprintf(\"[%s : %d] %s\\n\", __func__, __LINE__, \"Output text not as expected\\n\");\n+\n+\t\trte_hexdump(stdout, \"expected\", td->output_text.data, len);\n+\t\trte_hexdump(stdout, \"actual\", output_text, len);\n+\t\treturn TEST_FAILED;\n+\t}\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+static int\n+test_tls_record_res_d_prepare(const uint8_t *output_text, uint32_t len,\n+\t\t\t      const struct tls_record_test_data *td,\n+\t\t\t      struct tls_record_test_data *res_d)\n+{\n+\tmemcpy(res_d, td, sizeof(*res_d));\n+\n+\tmemcpy(&res_d->input_text.data, output_text, len);\n+\tres_d->input_text.len = len;\n+\n+\tres_d->tls_record_xform.type = RTE_SECURITY_TLS_SESS_TYPE_READ;\n+\tif (res_d->aead) {\n+\t\tres_d->xform.aead.aead.op = RTE_CRYPTO_AEAD_OP_DECRYPT;\n+\t} else {\n+\t\tres_d->xform.chain.cipher.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT;\n+\t\tres_d->xform.chain.auth.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;\n+\t}\n+\n+\treturn TEST_SUCCESS;\n+}\n+\n+int\n+test_tls_record_post_process(const struct rte_mbuf *m, const struct tls_record_test_data *td,\n+\t\t\t     struct tls_record_test_data *res_d, bool silent)\n+{\n+\tuint32_t len = rte_pktmbuf_pkt_len(m), data_len;\n+\tuint8_t output_text[TLS_RECORD_MAX_LEN];\n+\tconst struct rte_mbuf *seg;\n+\tconst uint8_t *output;\n+\n+\tmemset(output_text, 0, TLS_RECORD_MAX_LEN);\n+\n+\t/*\n+\t * Actual data in packet might be less in error cases, hence take minimum of pkt_len and sum\n+\t * of data_len. This is done to run through negative test cases.\n+\t */\n+\tdata_len = 0;\n+\tseg = m;\n+\twhile (seg) {\n+\t\tdata_len += seg->data_len;\n+\t\tseg = seg->next;\n+\t}\n+\n+\tlen = RTE_MIN(len, data_len);\n+\tTEST_ASSERT(len <= TLS_RECORD_MAX_LEN, \"Invalid packet length: %u\", len);\n+\n+\t/* Copy mbuf payload to continuous buffer */\n+\toutput = rte_pktmbuf_read(m, 0, len, output_text);\n+\tif (output != output_text) {\n+\t\t/* Single segment mbuf, copy manually */\n+\t\tmemcpy(output_text, output, len);\n+\t}\n+\n+\t/*\n+\t * In case of known vector tests & all record read (decrypt) tests, res_d provided would be\n+\t * NULL and output data need to be validated against expected. For record read (decrypt),\n+\t * output_text would be plain payload and for record write (encrypt), output_text would TLS\n+\t * record. Validate by comparing against known vectors.\n+\t *\n+\t * In case of combined mode tests, the output_text from TLS write (encrypt) operation (ie,\n+\t * TLS record) would need to be decrypted using a TLS read operation to obtain the plain\n+\t * text. Copy output_text to result data, 'res_d', so that inbound processing can be done.\n+\t */\n+\n+\tif (res_d == NULL)\n+\t\treturn test_tls_record_td_verify(output_text, len, td, silent);\n+\telse\n+\t\treturn test_tls_record_res_d_prepare(output_text, len, td, res_d);\n+}\ndiff --git a/app/test/test_cryptodev_security_tls_record.h b/app/test/test_cryptodev_security_tls_record.h\nnew file mode 100644\nindex 0000000000..9a0cf70218\n--- /dev/null\n+++ b/app/test/test_cryptodev_security_tls_record.h\n@@ -0,0 +1,71 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(C) 2023 Marvell.\n+ */\n+\n+#ifndef _TEST_CRYPTODEV_SECURITY_TLS_RECORD_H_\n+#define _TEST_CRYPTODEV_SECURITY_TLS_RECORD_H_\n+\n+#include <rte_cryptodev.h>\n+#include <rte_security.h>\n+\n+#define TLS_RECORD_MAX_LEN 16384u\n+\n+struct tls_record_test_data {\n+\tstruct {\n+\t\tuint8_t data[32];\n+\t} key;\n+\n+\tstruct {\n+\t\tuint8_t data[64];\n+\t} auth_key;\n+\n+\tstruct {\n+\t\tuint8_t data[TLS_RECORD_MAX_LEN];\n+\t\tunsigned int len;\n+\t} input_text;\n+\n+\tstruct {\n+\t\tuint8_t data[TLS_RECORD_MAX_LEN];\n+\t\tunsigned int len;\n+\t} output_text;\n+\n+\tstruct {\n+\t\tuint8_t data[12];\n+\t\tunsigned int len;\n+\t} imp_nonce;\n+\n+\tstruct {\n+\t\tuint8_t data[16];\n+\t} iv;\n+\n+\tunion {\n+\t\tstruct {\n+\t\t\tstruct rte_crypto_sym_xform cipher;\n+\t\t\tstruct rte_crypto_sym_xform auth;\n+\t\t} chain;\n+\t\tstruct rte_crypto_sym_xform aead;\n+\t} xform;\n+\n+\tstruct rte_security_tls_record_xform tls_record_xform;\n+\tuint8_t app_type;\n+\tbool aead;\n+};\n+\n+struct tls_record_test_flags {\n+\tbool display_alg;\n+};\n+\n+extern struct tls_record_test_data tls_test_data1;\n+\n+int test_tls_record_status_check(struct rte_crypto_op *op);\n+\n+int test_tls_record_sec_caps_verify(struct rte_security_tls_record_xform *tls_record_xform,\n+\t\t\t\t    const struct rte_security_capability *sec_cap, bool silent);\n+\n+void test_tls_record_td_read_from_write(const struct tls_record_test_data *td_out,\n+\t\t\t\t\tstruct tls_record_test_data *td_in);\n+\n+int test_tls_record_post_process(const struct rte_mbuf *m, const struct tls_record_test_data *td,\n+\t\t\t\t struct tls_record_test_data *res_d, bool silent);\n+\n+#endif\ndiff --git a/app/test/test_cryptodev_security_tls_record_test_vectors.h b/app/test/test_cryptodev_security_tls_record_test_vectors.h\nnew file mode 100644\nindex 0000000000..5aa0d27fda\n--- /dev/null\n+++ b/app/test/test_cryptodev_security_tls_record_test_vectors.h\n@@ -0,0 +1,16 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Marvell\n+ */\n+\n+#ifndef _TEST_CRYPTODEV_SECURITY_TLS_RECORD_TEST_VECTORS_H_\n+#define _TEST_CRYPTODEV_SECURITY_TLS_RECORD_TEST_VECTORS_H_\n+\n+#include <rte_crypto.h>\n+#include <rte_security.h>\n+\n+#include \"test_cryptodev.h\"\n+#include \"test_cryptodev_security_tls_record.h\"\n+\n+struct tls_record_test_data tls_test_data1;\n+\n+#endif\n",
    "prefixes": [
        "06/14"
    ]
}