From patchwork Tue Apr 3 10:31:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shally Verma X-Patchwork-Id: 36928 X-Patchwork-Delegate: pablo.de.lara.guarch@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id F011D1B6D5; Tue, 3 Apr 2018 12:31:41 +0200 (CEST) Received: from NAM03-BY2-obe.outbound.protection.outlook.com (mail-by2nam03on0043.outbound.protection.outlook.com [104.47.42.43]) by dpdk.org (Postfix) with ESMTP id 0B00A2C01 for ; Tue, 3 Apr 2018 12:31:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=CAVIUMNETWORKS.onmicrosoft.com; s=selector1-cavium-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=b+21Lpz4HfTeZIBkFNNwgRoXAeahOomYBFTbCF/x7zQ=; b=kuSdS+NQRkqDzNXPQcEJt/kiAF2NehW9JVUGg40jXU9/q0icq5H+mG2SuxxVSdQTOwXIAjI1gPnF69fSLmtkvAR4wT0qk6ohtjYBl+WCW/JTznz7AhHNA11CCSfplpa4aE7NAvf6Hp6jsy+3wfGhVZOJ/cD3wzb+Z10Gh7U2uWo= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Shally.Verma@cavium.com; Received: from hyd1sverma-dt.caveonetworks.com (115.113.156.2) by CY4PR0701MB3633.namprd07.prod.outlook.com (2603:10b6:910:92::35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.653.12; Tue, 3 Apr 2018 10:31:32 +0000 From: Shally Verma To: pablo.de.lara.guarch@intel.com Cc: declan.doherty@intel.com, fiona.trahe@intel.com, pathreya@caviumnetworks.com, ssahu@caviumnetworks.com, agupta@caviumnetworks.com, dev@dpdk.org, Sunila Sahu , Ashish Gupta Date: Tue, 3 Apr 2018 16:01:07 +0530 Message-Id: <1522751469-21307-2-git-send-email-shally.verma@caviumnetworks.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1522751469-21307-1-git-send-email-shally.verma@caviumnetworks.com> References: <1522751469-21307-1-git-send-email-shally.verma@caviumnetworks.com> MIME-Version: 1.0 X-Originating-IP: [115.113.156.2] X-ClientProxiedBy: MA1PR0101CA0004.INDPRD01.PROD.OUTLOOK.COM (2603:1096:a00:21::14) To CY4PR0701MB3633.namprd07.prod.outlook.com (2603:10b6:910:92::35) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 68515b58-bd5d-46fc-7afc-08d5994e13e8 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4604075)(4534165)(7168020)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020); SRVR:CY4PR0701MB3633; X-Microsoft-Exchange-Diagnostics: 1; CY4PR0701MB3633; 3:BU6FK9fpMCKPXfKQCsYqrVf1p7KlOtQqcze0qxL1U2AGo5VPpOxtooWK/fN5jkcWEG+1LakAE3CeBf4bPjl+DKzVmF3J9/no0tdcEXJOEFkjZPCyzTTu5L5nGlm0b7q8X+SLUgMZg7CRzBh2FV/CDc5/rLeAVUVh5957z5X5MjrWW7FATqVXYDaHMRxjGE5gz2Me9e/Qq0q94qX9nxbaDV54z/nc19/iDG0JZhkte58Fp1WztXKkMPhjgnk1Snx8; 25:UM5LzyENB4XmMXPfrOR8W6RRnwjKZjm7ObTgiohI0z3o0yfT5RxKwVsG3GuIg1WXHZ/Ob+cLMCnpj1T8/X6FzEm6rR5qhOUHO1MFLzjDlbB24eSkWKnfAlr+twtemymi3hiRsvykiySdE7oEYFHfN1LB0kz3Kj6dSiZkcdWWZQQEmlU0cH9UYErF09bY30BcTyylH/X2SoNywEIWBgb3PmLnl9ARaiEVK0g+U+TKEuAaBH0yXdhorocbRSqeKJbDVN7tJUl0PpJxe01b9EWv81CLHnxJk7MO/O9M35fEdRJkAsDY/WVGnARBpyX/o4Dlc0+CQWCxd3NNy6papVk+QA==; 31:RigHuNAUiDC+4v8wc/Mqv+qGbpsd+sXuIxL7eDHpoKEflkWTJ0EN8stJfqQrbq2z8OG9u+J7YnBBhloOQE8EydTblzjFHTlXEKdnhT4Mpm0jxbKuoeVhjqm8tt+WgPP3LDGoTvIVctEnhqBbc7npA/zqefbfWHW6UE5aJNh6NqWX7eXo4WQ3aCVLL63rDFA341bLtpDSamzo5wkr/LtVox1qR2LO4hs3k3948PPxf2U= X-MS-TrafficTypeDiagnostic: CY4PR0701MB3633: X-Microsoft-Exchange-Diagnostics: 1; CY4PR0701MB3633; 20:rdjnWOtvj6zH6piFEzy6RTOPBi7d7CIdNKdjhbhsYGb0K4rYWCv30gArKkz4PVj5d59Ua/jcxRbU1RZ0453E+bNDZ0i8Z+3UrngXi4bE2muu32DhZQRBRaNIHS7HYHstRWwQYDQGVPg4KJKfCuteEjcNhJmJzZApBd4YOifyAcmmHnU47Ba5hlyKnIpgK6W34ubuiEAs57MJKZW1Vvp6P4YVvrBeUg6ka8aWWNAZWHD7AfN9xDn+Frsr+RDxzkh9a2XXOV0gftv7g8uaDL++mkSjPhaTr92RI9cSvcVPUYwDYiMv/D/+aoc+Zut1mZGjJTFLxpjyYjwb2N+rT0Xod7aoNdzJVJjwKoTBt46XG9gEV85SxiJTZkJRm/j5SNQ1xWmqVr9saLH/qdNA9FkcFRJIMmm4FYMnXMzHaB5IDsERUkConSzTFPTqH2tJgSa9QZk40VP2zrEKqoxCzOKEG5oVS60nCn7wZPvK9fee5j9kAWk1gmHR5wh48rTgvpXXIplq8lvwaUbMm7tvBRCJpnqjIl9JGDVp6AVl0KZ/D+ufI3BcIeu/sbP5RvFLN26Hi/xnCTNJP2Bl30moVCWjzsZQ71hkvBMv9LrdiuSDmUc=; 4:ROsHgruIAHGI2QFnuGtjR8zMyRmx5r2qa56ci9sz4GM/tHTcUsLmUG82QCT/Pj0QS9hC+vd1yDS+Y522bLrFusFp65myX/uYke8CXE81qC8Smhjuykzh2iiKADRb/Cai2IJM5bTMkJHl6J3xcNG5NSb9YVAFOZiaQrnFRXYT9MlcCCqrRw2GB30v8+Nx1KGGuDLiYGmceOtoM6TioPZGkeDJTFq5H97TSIkDPLkCvPsJWgr2/oX8shRAE0SD9gQExuvzQODHQip45QtQyODIMg== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(3231221)(944501327)(52105095)(10201501046)(93006095)(3002001)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(20161123558120)(20161123562045)(20161123564045)(6072148)(201708071742011); SRVR:CY4PR0701MB3633; BCL:0; PCL:0; RULEID:; SRVR:CY4PR0701MB3633; X-Forefront-PRVS: 0631F0BC3D X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(366004)(346002)(376002)(39380400002)(39860400002)(396003)(199004)(189003)(81156014)(305945005)(81166006)(186003)(69596002)(2616005)(5660300001)(11346002)(16526019)(956004)(8936002)(16586007)(6512007)(53946003)(107886003)(486005)(53936002)(54906003)(8676002)(476003)(486005)(446003)(4326008)(106356001)(72206003)(51416003)(76176011)(97736004)(53416004)(66066001)(68736007)(48376002)(25786009)(6916009)(6666003)(52116002)(105586002)(59450400001)(386003)(6506007)(6116002)(3846002)(55236004)(50466002)(50226002)(2906002)(6486002)(2351001)(36756003)(575784001)(26005)(5890100001)(42882007)(478600001)(47776003)(7736002)(316002)(2361001)(579004)(559001); DIR:OUT; SFP:1101; SCL:1; SRVR:CY4PR0701MB3633; H:hyd1sverma-dt.caveonetworks.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; Received-SPF: None (protection.outlook.com: cavium.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; CY4PR0701MB3633; 23:x6iHarfp6cZIm3U/xRF1EQZx1/g6O7JCSNUXDPI?= cVuDDPzLxkhFwb3TWaXXHqnIiA5s/IQSt0XY7ZBRJJjpf/soSIy/fVapEnCT2b31S6FQosFWwZkWBWI6uMRRJ3Fku4uANzvMg/DVmRe+fBcclyTJHw4jntQyeVzgKB4YVDKwuT1x5UArj9IJD+7sxSa9GCngEmEo5jOwJFKvDRjp4dhA8LizKeVHzdEb2s15FnFrr9EyWDkM/+B1KQg0pG0ILUXsKAcvtGK5ncVn400ABGrFFKsf0pCoE6ZzvyJQEHgRXuYvGefDaB4G/8wpKay+W+oeme1o+RQSiq1tobO204Pvodz1yf8SmYoHRg/PONVPt+/ec95fhxhWwk1b0JpS4+eMt4mmsREGpFv2wmoMSlbQD0ZLo93iO7FsxV6+dgKCKlhWk5kpv3doFkFXwN82suowhPhe8WZfEWWzzvsk5bktOte3I8dHHJ/8MLp5pzd6GvvSkYlodtvix8MesTKBkQdZCV1mjw0k8Vb9Qthv+IgipXpfLMnH0KBA0xxBSwyXfL7ZXL/wParmL84GfdhGKRTOjbNzHPBylLGrT2NLubVYjpZsZSfgCyRfxvB7GabfxHsmaKem1x23JAEQfaAK33jsDthoQMGQIYmyn3kIpvTDuk418wQAz0KNG1pZr53E/MZwwAX+UwNsiPAS48eIXGKweBFLrrj6pWrljKDeruez2JV9cZuODKfQSkke5BBrCl9XwJILujTXxFuvt7MDHXdR1p4h8Jnw3Pbk9oTlC3oMc/Zv9CC48HyGBuwrzaGp7szVyFYWPCcTS7zmKp/Vd0tr8Acz5/58fFDWdHFeuLDEuSG4IzWjHmB4I+g3SXdVMGyieVF6agfsJdNEMMc2YPgwFL7bsLW/uuWK+EbgzEm0SAfdoq4kfcQtTfM53whgzE4J57Mm1YZyuQQg5Gtstuuv8w3Sj2QY7BESAoU6Qgvsfh7Ell1WD+7zPbwWZVOrHiD4yW8pWfXPbp0fFlDy1EZzfmeiOhyG8ylvwHWMlXzpVXvgeDE4kO4UqRUTOU9O7RkCt0YOXMhvhm6ZktHkFezUaGR31qcD9FcQkAMlLJfjlaf5NGBRA0Xcae4cUJebT/tdpXvSH8p1UT12mFbWUuawnpM7zpqOuJvjV4Alpo8sPAC6ruC47HCIQU663ijZXqC6fNne9FSTvHWdtWIbLrsssMOxALESmG9BmYapFpyQogFc7mOWfKD5H3BOOUWdfV6eKCwoHNJ45c3Bg9sXOes2fU28FMj1EOHNjphRVvv5bpQE0d10JXeI/Md7GT9wCaDZv/XkILw4uWfDVI4u3kJw61AYtfdJXtmWMpxHd/GTcI2/YJvuF6Jc/lUD84b7WgEBQ5VSH5lK7O/VqkWES0O4ePi+Xa9rT9rAAcVj9cX0pwlFKlyF5ZZwdOUImcgOMg46ThybsJ1WpFnyei3lSOsOvT7HCMq0IeWKRABVCUQ== X-Microsoft-Antispam-Message-Info: xSW0Vl6XapWmk/GA86JwQSAUfre1aIUYvM7eVk8ZM2tHUjduyTa8KHbZVamGWKFZVas0Z1rMomxIvaPQk166Rap/wELD8IK6SDjrysfkJEHa8rLiX6AvkP7Hc+bEizjeTqij8MdqOyDe9hhAPHJ0WdQe6OoZHxLd7eV+nS2Y73hiPLvCzJUgIf+hgk8CWAqU X-Microsoft-Exchange-Diagnostics: 1; CY4PR0701MB3633; 6:xLjw4PBcvnJ1IXES81RWRaZQK4rpQ+pNhP1CWgSITWk7dFn7je+WJRz8slr6p8uOtdSCymCAeKtFjygiVjQVBfK+xTLLWNqvsjNzW+eZJmqxDZmXdk7S709antQBGznHL7TFsIwjrS2HVQDV2GlzNXRCUPVPAAnHlky3OyLXq5eO+UZ0jmIM8o8FYT7sd4tsrEjkMxKMfJfTO8F5vpF9KiVcp1+6yyEiqpeULjSvFF0x8/EilxAMI3/yZFsywMRoOz0WPVRxPBXTwpTzaKbE05WN5jxQkcV/tNuDSRCk5M5SIXy4JvTPkWNc2NZKzU/RMy6ZCgrTBBjPLb85QZsj4LDxtXz9Aw8k4lfzjQvpGQj2OkhulEOVD4j2ztnEahIiIVWXm/7ylDPperz1r507VS85igRZn87Gg4q4ZB+y96Br/ChBOQWeWc6lYqqcG7Lr3HmyPnBci6r/foDPSkRZiw==; 5:1V+ICUa8NjE+vWfGyCHU34e/vQKZxMsO5sv+FRbNJj58EbCJ6TlX7gjraD5UEkW87k4mUMEjSvK5iyB8RzoEJnJGrwWqO+/SCFKoIJEzYVNMCrXYoOayAjx7z3IJ6+JnCjTFvo6mDkBW7aCybNfn/bFefMNbKhKiIisNHYhRNNY=; 24:7ASTXq/f0g4Bam3ilsgS8VibRTwlRoJ+kUFsMJkDLk9j/oeLA+WliU6g4VM6T+ktISixLoqhZwPUJ4qjTZp8sTypo87xBILFh0cFXMUkSP0= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; CY4PR0701MB3633; 7:cGckHrDq4UR0GSGxlFBdrrVDKdRGYsYu/NZSoElxL6a15DQatpA+L3VkWlFv409L8/3vDYb8yTf77CLhGX0C7/UK9Li8p80fivyuBNtgM0XVXol2UnrlDYs0eN2LFiJnagkiGLIwEjE7yE2lAg/fIp6rVckE7ReAKliVLKAj/gOZop6ADdWuMsyloI4Wp+qXzlGqY5hTPFjLA1t1BV0FCDnW+T6hL7nvp2msksIaArkEaKYqSyRKLHBC8lN9IdOT X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Apr 2018 10:31:32.1107 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 68515b58-bd5d-46fc-7afc-08d5994e13e8 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 711e4ccf-2e9b-4bcf-a551-4094005b6194 X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR0701MB3633 Subject: [dpdk-dev] [PATCH v1 1/3] lib/cryptodev: add unit testcase for asym crypto X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Initial unit test case to test openssl PMD asym crypto operations. Test case invoke asymmetric operation on DPDK Openssl PMD and cross-verify results via Openssl SW library. Tests have been verified with openssl 1.0.2m release. Tested for: * RSA Encrypt, Decrypt, Sign and Verify using pre-defined test vectors * Modular Inversion and Exponentiation using pre-defined test vectors * Deiffie-Hellman Public key generation using pre-defined private key and dynamically generated test vectors * Deffie-hellman private key generation using dynamically generated test vectors * Deffie-hellman private and public key pair generation using xform chain and using dynamically generated test vectors * Deffie-hellman shared secret compute using dynamically generated test vectors * DSA Sign and Verification Deffie-hellman testcases use run-time generated test params, thus may take some time for execution. Signed-off-by: Shally Verma Signed-off-by: Sunila Sahu Signed-off-by: Ashish Gupta --- test/test/Makefile | 3 +- test/test/test_cryptodev_asym.c | 1785 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 1787 insertions(+), 1 deletion(-) diff --git a/test/test/Makefile b/test/test/Makefile index a88cc38bf..04ab52265 100644 --- a/test/test/Makefile +++ b/test/test/Makefile @@ -180,6 +180,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring_perf.c SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_blockcipher.c SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev.c +SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_asym.c ifeq ($(CONFIG_RTE_LIBRTE_EVENTDEV),y) SRCS-y += test_eventdev.c @@ -200,7 +201,7 @@ CFLAGS += $(WERROR_FLAGS) CFLAGS += -D_GNU_SOURCE -LDLIBS += -lm +LDLIBS += -lm -lcrypto # Disable VTA for memcpy test ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y) diff --git a/test/test/test_cryptodev_asym.c b/test/test/test_cryptodev_asym.c new file mode 100644 index 000000000..5f15d10c5 --- /dev/null +++ b/test/test/test_cryptodev_asym.c @@ -0,0 +1,1785 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2017-2018 Cavium Networks + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "test.h" +#include "test_cryptodev.h" + +#define TEST_DATA_SIZE 4096 +#define TEST_NUM_BUFS 10 +#define TEST_NUM_SESSIONS 4 +#define ASYM_TEST_MSG_LEN 256 +#define TEST_DH_MOD_LEN 1024 + +static int gbl_driver_id; +struct crypto_testsuite_params { + struct rte_mempool *op_mpool; + struct rte_mempool *session_mpool; + struct rte_cryptodev_config conf; + struct rte_cryptodev_qp_conf qp_conf; + uint8_t valid_devs[RTE_CRYPTO_MAX_DEVS]; + uint8_t valid_dev_count; +}; + +struct crypto_unittest_params { + struct rte_cryptodev_asym_session *sess; + struct rte_crypto_op *op; +}; + +static struct crypto_testsuite_params testsuite_params = { NULL }; + +struct rsa_test_data { + enum rte_crypto_asym_op_type op_type; + + struct { + uint8_t data[TEST_DATA_SIZE]; + unsigned int len; + } plainText; + struct { + uint8_t data[TEST_DATA_SIZE]; + unsigned int len; + } encryptedText; + struct { + uint8_t data[TEST_DATA_SIZE]; + unsigned int len; + } signText; +}; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" + +static unsigned char base[] = { 0xF8, 0xBA, 0x1A, 0x55, 0xD0, 0x2F, 0x85, + 0xAE, 0x96, 0x7B, 0xB6, 0x2F, 0xB6, 0xCD, + 0xA8, 0xEB, 0x7E, 0x78, 0xA0, 0x50 }; + +static struct rsa_test_data rsa_test_case = { + .op_type = RTE_CRYPTO_ASYM_OP_ENCRYPT, + .plainText = { + .data = { + 0xF8, 0xBA, 0x1A, 0x55, 0xD0, 0x2F, 0x85, 0xAE, + 0x96, 0x7B, 0xB6, 0x2F, 0xB6, 0xCD, 0xA8, 0xEB, + 0x7E, 0x78, 0xA0, 0x50 + }, + .len = 20 + }, + .encryptedText = { + .data = { + 0x4B, 0x22, 0x88, 0xF1, 0x91, 0x5A, 0x6A, 0xCC, + 0x75, 0xD6, 0x40, 0xE3, 0x58, 0xCA, 0xC8, 0x70, + 0x9B, 0x2B, 0xC7, 0x36, 0x1F, 0xAE, 0x38, 0xF3, + 0x97, 0xA6, 0xEE, 0xA7, 0xDB, 0xFF, 0x9F, 0x09, + 0x73, 0x1A, 0x2F, 0x01, 0xFA, 0xAF, 0x77, 0x09, + 0xE1, 0x8D, 0x3E, 0x2D, 0x1D, 0x45, 0x15, 0x66, + 0xE1, 0x79, 0xD7, 0xC6, 0x94, 0x1D, 0x54, 0xBF, + 0xDD, 0xAB, 0x46, 0x34, 0xC7, 0x55, 0x62, 0x5B, + 0x9D, 0xBD, 0x28, 0xDB, 0x46, 0x0D, 0x2D, 0x3D, + 0x41, 0x46, 0xDA, 0x45, 0x31, 0x78, 0xD5, 0xE7, + 0x2C, 0xA4, 0x1F, 0x73, 0xBE, 0x62, 0x41, 0x2C, + 0x5C, 0x8D, 0x0D, 0xFA, 0xCC, 0x4C, 0xC1, 0x69, + 0x90, 0xC9, 0x50, 0x21, 0x20, 0x90, 0x72, 0x70, + 0x55, 0xA0, 0x25, 0x11, 0x5B, 0x96, 0x96, 0x07, + 0x98, 0x90, 0x10, 0x81, 0x9E, 0x32, 0x16, 0x02, + 0x6F, 0x52, 0xCF, 0xDB, 0x57, 0x9C, 0x57, 0xD2 + }, + .len = 128 + }, + .signText = { + .data = { + 0x2F, 0x42, 0xB3, 0xB1, 0x7F, 0xA8, 0x66, 0x00, + 0xC6, 0xB4, 0x7D, 0x12, 0x67, 0x5F, 0x94, 0xF7, + 0x25, 0xD6, 0x7E, 0x14, 0xE4, 0xC2, 0x63, 0xB2, + 0xDC, 0x1B, 0x13, 0xC0, 0xDA, 0xDA, 0x0D, 0x32, + 0x9B, 0xF4, 0x8A, 0x62, 0x90, 0xE7, 0xB3, 0xF3, + 0xBB, 0x5A, 0xAB, 0x5F, 0xF8, 0xAF, 0xF4, 0x19, + 0x0D, 0xA5, 0x66, 0x25, 0x95, 0x69, 0x57, 0x43, + 0x87, 0x44, 0xB0, 0x92, 0x1A, 0x39, 0xA6, 0x97, + 0x06, 0xFD, 0xF3, 0x20, 0x72, 0xFB, 0xEA, 0xEF, + 0xCF, 0xD1, 0x88, 0xCA, 0x23, 0x26, 0xA9, 0xA9, + 0x22, 0xCD, 0xA0, 0x10, 0xF9, 0x14, 0x28, 0xC7, + 0x0E, 0x82, 0xE1, 0xCD, 0xC3, 0x31, 0x0F, 0x75, + 0x6D, 0x69, 0xCD, 0x55, 0x30, 0xA3, 0x26, 0xCB, + 0xF8, 0xBC, 0xF3, 0xC5, 0xFA, 0xD7, 0x7E, 0x51, + 0x81, 0xC9, 0x5C, 0x9F, 0x2A, 0x40, 0x40, 0x83, + 0xB3, 0xBA, 0xDB, 0x94, 0x2D, 0x31, 0x1C, 0xF8 + + }, + .len = 128 + } +}; + +/** rsa xform using exponent key */ +struct rte_crypto_asym_xform rsa_xform = { + .next = NULL, + .xform_type = RTE_CRYPTO_ASYM_XFORM_RSA, + .rsa = { + .n = { + .data = + (uint8_t *) + ("\x00\xb3\xa1\xaf\xb7\x13\x08\x00\x0a\x35\xdc\x2b\x20\x8d" + "\xa1\xb5\xce\x47\x8a\xc3\x80\xf4\x7d\x4a\xa2\x62\xfd\x61\x7f" + "\xb5\xa8\xde\x0a\x17\x97\xa0\xbf\xdf\x56\x5a\x3d\x51\x56\x4f" + "\x70\x70\x3f\x63\x6a\x44\x5b\xad\x84\x0d\x3f\x27\x6e\x3b\x34" + "\x91\x60\x14\xb9\xaa\x72\xfd\xa3\x64\xd2\x03\xa7\x53\x87\x9e" + "\x88\x0b\xc1\x14\x93\x1a\x62\xff\xb1\x5d\x74\xcd\x59\x63\x18" + "\x11\x3d\x4f\xba\x75\xd4\x33\x4e\x23\x6b\x7b\x57\x44\xe1\xd3" + "\x03\x13\xa6\xf0\x8b\x60\xb0\x9e\xee\x75\x08\x9d\x71\x63\x13" + "\xcb\xa6\x81\x92\x14\x03\x22\x2d\xde\x55"), + .length = 129 + }, + .e = { + .data = (uint8_t *)("\x01\x00\x01"), + .length = 3 + }, + .key_type = RTE_RSA_KEY_TYPE_EXP, + { + .d = { + .data = + (uint8_t *) + ("\x24\xd7\xea\xf4\x7f\xe0\xca\x31\x4d\xee\xc4\xa1\xbe\xab\x06" + "\x61\x32\xe7\x51\x46\x27\xdf\x72\xe9\x6f\xa8\x4c\xd1\x26\xef" + "\x65\xeb\x67\xff\x5f\xa7\x3b\x25\xb9\x08\x8e\xa0\x47\x56\xe6" + "\x8e\xf9\xd3\x18\x06\x3d\xc6\xb1\xf8\xdc\x1b\x8d\xe5\x30\x54" + "\x26\xac\x16\x3b\x7b\xad\x46\x9e\x21\x6a\x57\xe6\x81\x56\x1d" + "\x2a\xc4\x39\x63\x67\x81\x2c\xca\xcc\xf8\x42\x04\xbe\xcf\x8f" + "\x6c\x5b\x81\x46\xb9\xc7\x62\x90\x87\x35\x03\x9b\x89\xcb\x37" + "\xbd\xf1\x1b\x99\xa1\x9a\x78\xd5\x4c\xdd\x3f\x41\x0c\xb7\x1a" + "\xd9\x7b\x87\x5f\xbe\xb1\x83\x41"), + .length = 128 + }, + } + } +}; + +struct rte_crypto_asym_xform modex_xform = { + .next = NULL, + .xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX, + .modex = { + .modulus = { + .data = + (uint8_t *) + ("\x00\xb3\xa1\xaf\xb7\x13\x08\x00\x0a\x35\xdc\x2b\x20\x8d" + "\xa1\xb5\xce\x47\x8a\xc3\x80\xf4\x7d\x4a\xa2\x62\xfd\x61\x7f" + "\xb5\xa8\xde\x0a\x17\x97\xa0\xbf\xdf\x56\x5a\x3d\x51\x56\x4f" + "\x70\x70\x3f\x63\x6a\x44\x5b\xad\x84\x0d\x3f\x27\x6e\x3b\x34" + "\x91\x60\x14\xb9\xaa\x72\xfd\xa3\x64\xd2\x03\xa7\x53\x87\x9e" + "\x88\x0b\xc1\x14\x93\x1a\x62\xff\xb1\x5d\x74\xcd\x59\x63\x18" + "\x11\x3d\x4f\xba\x75\xd4\x33\x4e\x23\x6b\x7b\x57\x44\xe1\xd3" + "\x03\x13\xa6\xf0\x8b\x60\xb0\x9e\xee\x75\x08\x9d\x71\x63\x13" + "\xcb\xa6\x81\x92\x14\x03\x22\x2d\xde\x55"), + .length = 129 + }, + .exponent = { + .data = (uint8_t *)("\x01\x00\x01"), + .length = 3 + } + } +}; + +struct rte_crypto_asym_xform modinv_xform = { + .next = NULL, + .xform_type = RTE_CRYPTO_ASYM_XFORM_MODINV, + .modinv = { + .modulus = { + .data = + (uint8_t *) + ("\x00\xb3\xa1\xaf\xb7\x13\x08\x00\x0a\x35\xdc\x2b\x20\x8d" + "\xa1\xb5\xce\x47\x8a\xc3\x80\xf4\x7d\x4a\xa2\x62\xfd\x61\x7f" + "\xb5\xa8\xde\x0a\x17\x97\xa0\xbf\xdf\x56\x5a\x3d\x51\x56\x4f" + "\x70\x70\x3f\x63\x6a\x44\x5b\xad\x84\x0d\x3f\x27\x6e\x3b\x34" + "\x91\x60\x14\xb9\xaa\x72\xfd\xa3\x64\xd2\x03\xa7\x53\x87\x9e" + "\x88\x0b\xc1\x14\x93\x1a\x62\xff\xb1\x5d\x74\xcd\x59\x63\x18" + "\x11\x3d\x4f\xba\x75\xd4\x33\x4e\x23\x6b\x7b\x57\x44\xe1\xd3" + "\x03\x13\xa6\xf0\x8b\x60\xb0\x9e\xee\x75\x08\x9d\x71\x63\x13" + "\xcb\xa6\x81\x92\x14\x03\x22\x2d\xde\x55"), + .length = 129 + } + } +}; + +#pragma GCC diagnostic pop + +static int +test_rsa(struct rsa_test_data *t) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_mempool *op_mpool = ts_params->op_mpool; + struct rte_mempool *sess_mpool = ts_params->session_mpool; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_crypto_asym_op *asym_op = NULL; + struct rte_crypto_op *op = NULL, *result_op = NULL; + struct rte_cryptodev_asym_session *sess = NULL; + RSA *rsa = NULL; + int status = TEST_SUCCESS; + uint8_t tmp_buf[TEST_DATA_SIZE]; + int tmp_len = 0; + uint8_t output_buf[TEST_DATA_SIZE] = {0}; + uint8_t input_buf[TEST_DATA_SIZE] = {0}; + char test_msg[ASYM_TEST_MSG_LEN + 1]; + + sess = rte_cryptodev_asym_session_create(sess_mpool); + + if (!sess) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + + if (rte_cryptodev_asym_session_init(dev_id, sess, &rsa_xform, + sess_mpool) < 0) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "unabled to config sym session"); + status = TEST_FAILED; + goto error_exit; + } + + + /* set up crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); + if (!op) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to allocate asymmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + + asym_op = op->asym; + asym_op->rsa.op_type = t->op_type; + asym_op->rsa.pad = RTE_CRYPTO_RSA_PKCS1_V1_5_BT1; + + if (t->op_type == RTE_CRYPTO_ASYM_OP_ENCRYPT) { + memcpy(input_buf, t->plainText.data, t->plainText.len); + asym_op->rsa.message.data = input_buf; + asym_op->rsa.message.length = t->plainText.len; + } else if (t->op_type == RTE_CRYPTO_ASYM_OP_SIGN) { + asym_op->rsa.message.data = t->plainText.data; + asym_op->rsa.message.length = t->plainText.len; + asym_op->rsa.sign.data = output_buf; + } else if (t->op_type == RTE_CRYPTO_ASYM_OP_DECRYPT) { + memcpy(input_buf, t->encryptedText.data, t->encryptedText.len); + asym_op->rsa.message.data = input_buf; + asym_op->rsa.message.length = t->encryptedText.len; + } else if (t->op_type == RTE_CRYPTO_ASYM_OP_VERIFY) { + memcpy(input_buf, t->signText.data, t->signText.len); + asym_op->rsa.message.data = t->plainText.data; + asym_op->rsa.message.length = t->plainText.len; + asym_op->rsa.sign.data = input_buf; + asym_op->rsa.sign.length = t->signText.len; + } + + /* attach asymmetric crypto session to crypto operations */ + rte_crypto_op_attach_asym_session(op, sess); + + snprintf(test_msg, ASYM_TEST_MSG_LEN, "Process ASYM operation"); + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + /* verify result using sw lib */ + rsa = RSA_new(); + if (rsa == NULL) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to allocate sw RSA"); + status = TEST_FAILED; + goto error_exit; + } + + rsa->n = + BN_bin2bn( + (const unsigned char *)rsa_xform.rsa.n.data, + rsa_xform.rsa.n.length, + rsa->n); + rsa->e = BN_bin2bn((const unsigned char *)rsa_xform.rsa.e.data, + rsa_xform.rsa.e.length, + rsa->e); + rsa->d = BN_bin2bn((const unsigned char *)rsa_xform.rsa.d.data, + rsa_xform.rsa.d.length, + rsa->d); + + if (t->op_type == RTE_CRYPTO_ASYM_OP_ENCRYPT) { + debug_hexdump(stdout, "Encrypted output:", + asym_op->rsa.message.data, + asym_op->rsa.message.length); + + /* decrypt using openssl lib */ + tmp_len = RSA_private_decrypt(asym_op->rsa.message.length, + asym_op->rsa.message.data, + tmp_buf, + rsa, + RSA_PKCS1_PADDING); + + if (memcmp(t->plainText.data, tmp_buf, tmp_len)) { + snprintf(test_msg, + ASYM_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Crypto data not as expected"); + status = TEST_FAILED; + goto error_exit; + } + } else if (t->op_type == RTE_CRYPTO_ASYM_OP_SIGN) { + debug_hexdump(stdout, "RSA Sign output:", + asym_op->rsa.sign.data, + asym_op->rsa.sign.length); + + /* verify generated sign using openssl lib */ + tmp_len = RSA_public_decrypt(asym_op->rsa.sign.length, + asym_op->rsa.sign.data, + tmp_buf, rsa, + RSA_PKCS1_PADDING); + + if (memcmp(asym_op->rsa.message.data, tmp_buf, tmp_len)) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Crypto data not as expected"); + status = TEST_FAILED; + goto error_exit; + } + } else if (t->op_type == RTE_CRYPTO_ASYM_OP_DECRYPT) { + if (memcmp(asym_op->rsa.message.data, + t->plainText.data, + t->plainText.len)) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Crypto data not as expected"); + status = TEST_FAILED; + goto error_exit; + } + } else if (t->op_type == RTE_CRYPTO_ASYM_OP_VERIFY) { + /* compare verification output in sign to original message */ + if (memcmp(asym_op->rsa.sign.data, + asym_op->rsa.message.data, + asym_op->rsa.message.length)) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u " + "FAILED: %s", __LINE__, + "Crypto data not as expected"); + status = TEST_FAILED; + goto error_exit; + } + } + + snprintf(test_msg, ASYM_TEST_MSG_LEN, "PASS"); + +error_exit: + if (rsa) + RSA_free(rsa); + if (sess) { + rte_cryptodev_asym_session_clear(dev_id, sess); + rte_cryptodev_asym_session_free(sess); + } + + if (op) + rte_crypto_op_free(op); + + return status; +} + +static int +testsuite_setup(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_cryptodev_info info; + uint32_t i = 0, nb_devs, dev_id; + int ret; + uint16_t qp_id; + + memset(ts_params, 0, sizeof(*ts_params)); + + ts_params->op_mpool = rte_crypto_op_pool_create( + "CRYPTO_ASYM_OP_POOL", + RTE_CRYPTO_OP_TYPE_ASYMMETRIC, + TEST_NUM_BUFS, 0, + 0, + rte_socket_id()); + if (ts_params->op_mpool == NULL) { + RTE_LOG(ERR, USER1, "Can't create ASYM_CRYPTO_OP_POOL\n"); + return TEST_FAILED; + } + + /* Create an OPENSSL device if required */ + if (gbl_driver_id == rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD))) { + nb_devs = rte_cryptodev_device_count_by_driver( + rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD))); + if (nb_devs < 1) { + ret = rte_vdev_init( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD), + NULL); + + TEST_ASSERT(ret == 0, "Failed to create " + "instance of pmd : %s", + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)); + } + } + + nb_devs = rte_cryptodev_count(); + if (nb_devs < 1) { + RTE_LOG(ERR, USER1, "No crypto devices found?\n"); + return TEST_FAILED; + } + + /* Create list of valid crypto devs */ + for (i = 0; i < nb_devs; i++) { + rte_cryptodev_info_get(i, &info); + if (info.driver_id == gbl_driver_id) + ts_params->valid_devs[ts_params->valid_dev_count++] = i; + } + + if (ts_params->valid_dev_count < 1) + return TEST_FAILED; + + /* Set up all the qps on the first of the valid devices found */ + + dev_id = ts_params->valid_devs[0]; + + rte_cryptodev_info_get(dev_id, &info); + + /* check if device support asymmetric , skip if not */ + if (!(info.feature_flags & + RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)) { + RTE_LOG(ERR, USER1, "Device doesn't support asymmetric. " + "Test Skipped.\n"); + return TEST_FAILED; + } + + /* configure device with num qp */ + ts_params->conf.nb_queue_pairs = info.max_nb_queue_pairs; + ts_params->conf.socket_id = SOCKET_ID_ANY; + TEST_ASSERT_SUCCESS(rte_cryptodev_configure(dev_id, + &ts_params->conf), + "Failed to configure cryptodev %u with %u qps", + dev_id, ts_params->conf.nb_queue_pairs); + + /* configure qp */ + ts_params->qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT; + for (qp_id = 0; qp_id < info.max_nb_queue_pairs; qp_id++) { + TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( + dev_id, qp_id, &ts_params->qp_conf, + rte_cryptodev_socket_id(dev_id), + ts_params->session_mpool), + "Failed to setup queue pair %u on cryptodev %u ASYM", + qp_id, dev_id); + } + + /* setup asym session pool */ + unsigned int session_size = + rte_cryptodev_get_asym_session_private_size(dev_id); + /* + * Create mempool with TEST_NUM_SESSIONS * 2, + * to include the session headers + */ + ts_params->session_mpool = rte_mempool_create( + "test_asym_sess_mp", + TEST_NUM_SESSIONS * 2, + session_size, + 0, 0, NULL, NULL, NULL, + NULL, SOCKET_ID_ANY, + 0); + + TEST_ASSERT_NOT_NULL(ts_params->session_mpool, + "session mempool allocation failed"); + + return TEST_SUCCESS; +} + +static void +testsuite_teardown(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + + if (ts_params->op_mpool != NULL) { + RTE_LOG(DEBUG, USER1, "CRYPTO_OP_POOL count %u\n", + rte_mempool_avail_count(ts_params->op_mpool)); + } + + /* Free session mempools */ + if (ts_params->session_mpool != NULL) { + rte_mempool_free(ts_params->session_mpool); + ts_params->session_mpool = NULL; + } +} + +static int +ut_setup(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + + uint16_t qp_id; + + /* Reconfigure device to default parameters */ + ts_params->conf.socket_id = SOCKET_ID_ANY; + + TEST_ASSERT_SUCCESS(rte_cryptodev_configure(ts_params->valid_devs[0], + &ts_params->conf), + "Failed to configure cryptodev %u", + ts_params->valid_devs[0]); + + for (qp_id = 0; qp_id < ts_params->conf.nb_queue_pairs ; qp_id++) { + TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup( + ts_params->valid_devs[0], qp_id, + &ts_params->qp_conf, + rte_cryptodev_socket_id(ts_params->valid_devs[0]), + ts_params->session_mpool), + "Failed to setup queue pair %u on cryptodev %u", + qp_id, ts_params->valid_devs[0]); + } + + rte_cryptodev_stats_reset(ts_params->valid_devs[0]); + + /* Start the device */ + TEST_ASSERT_SUCCESS(rte_cryptodev_start(ts_params->valid_devs[0]), + "Failed to start cryptodev %u", + ts_params->valid_devs[0]); + + return TEST_SUCCESS; +} + +static void +ut_teardown(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_cryptodev_stats stats; + + rte_cryptodev_stats_get(ts_params->valid_devs[0], &stats); + + /* Stop the device */ + rte_cryptodev_stop(ts_params->valid_devs[0]); +} + +static inline void print_asym_capa( + const struct rte_cryptodev_asymmetric_xfrm_capability *capa) +{ + int i = 0; + + printf("\nxform type: %s\n===================\n", + rte_crypto_asym_xform_strings[capa->xform_type]); + printf("operation supported -"); + + for (i = 0; i < RTE_CRYPTO_ASYM_OP_LIST_END; i++) { + /* check supported operations */ + if (rte_cryptodev_asym_xfrm_capability_check_optype(capa, i)) + printf(" %s", + rte_crypto_asym_op_strings[i]); + } + switch (capa->xform_type) { + case RTE_CRYPTO_ASYM_XFORM_RSA: + case RTE_CRYPTO_ASYM_XFORM_MODINV: + case RTE_CRYPTO_ASYM_XFORM_MODEX: + case RTE_CRYPTO_ASYM_XFORM_DH: + case RTE_CRYPTO_ASYM_XFORM_DSA: + printf(" modlen: min %d max %d increment %d\n", + capa->modlen.min, + capa->modlen.max, + capa->modlen.increment); + break; + default: + break; + } +} + +/* ***** Plaintext data for tests ***** */ +static int +test_capability(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_cryptodev_info dev_info; + int i = 0; + struct rte_cryptodev_asym_capability_idx idx; + const struct rte_cryptodev_asymmetric_xfrm_capability *capa; + + rte_cryptodev_info_get(dev_id, &dev_info); + if (!(dev_info.feature_flags & + RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)) { + printf("Device doesn't support asymmetric. " + "Test Skipped.\n"); + return TEST_SUCCESS; + } + + /* print xfrm capability */ + for (i = 0; + dev_info.capabilities[i].op != RTE_CRYPTO_OP_TYPE_UNDEFINED; + i++) { + if (dev_info.capabilities[i].op == + RTE_CRYPTO_OP_TYPE_ASYMMETRIC) { + idx.type = dev_info.capabilities[i].asym.xform_type; + + capa = rte_cryptodev_asym_capability_get(dev_id, + (const struct + rte_cryptodev_asym_capability_idx *) &idx); + print_asym_capa(capa); + } + } + return TEST_SUCCESS; +} + +static int +test_dh_gen_shared_sec(DH *testkey, struct rte_crypto_asym_xform *xfrm) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_mempool *op_mpool = ts_params->op_mpool; + struct rte_mempool *sess_mpool = ts_params->session_mpool; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_crypto_asym_op *asym_op = NULL; + struct rte_crypto_op *op = NULL, *result_op = NULL; + struct rte_cryptodev_asym_session *sess = NULL; + int status = TEST_SUCCESS; + char test_msg[ASYM_TEST_MSG_LEN + 1]; + uint8_t output[TEST_DH_MOD_LEN]; + struct rte_crypto_asym_xform xform = *xfrm; + uint8_t peer[] = "01234567890123456789012345678901234567890123456789"; + + sess = rte_cryptodev_asym_session_create(sess_mpool); + if (sess == NULL) { + snprintf(test_msg, + ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + /* set up crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); + if (!op) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to allocate asymmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + asym_op = op->asym; + + /* Setup a xform and op to generate private key only */ + xform.dh.type = RTE_CRYPTO_ASYM_OP_SHARED_SECRET_COMPUTE; + xform.next = NULL; + asym_op->dh.priv_key.data = rte_malloc(NULL, + BN_num_bytes(testkey->priv_key), + 0); + asym_op->dh.priv_key.length = BN_bn2bin(testkey->priv_key, + asym_op->dh.priv_key.data); + asym_op->dh.pub_key.data = (uint8_t *)peer; + asym_op->dh.pub_key.length = sizeof(peer); + asym_op->dh.shared_secret.data = output; + asym_op->dh.shared_secret.length = sizeof(output); + + if (rte_cryptodev_asym_session_init(dev_id, sess, &xform, + sess_mpool) < 0) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "unabled to config sym session"); + status = TEST_FAILED; + goto error_exit; + } + + /* attach asymmetric crypto session to crypto operations */ + rte_crypto_op_attach_asym_session(op, sess); + + snprintf(test_msg, ASYM_TEST_MSG_LEN, "Process ASYM operation"); + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + debug_hexdump(stdout, "shared secret:", + asym_op->dh.shared_secret.data, + asym_op->dh.shared_secret.length); + + /* compute shared secret using sw and compare */ + BIGNUM *p = NULL; + p = BN_bin2bn(peer, sizeof(peer), p); + if (p != NULL) { + size_t test_len; + uint8_t *test_shared = rte_malloc(NULL, DH_size(testkey), 0); + test_len = DH_compute_key(test_shared, p, testkey); + + debug_hexdump(stdout, "sw shared secret:", + test_shared, + test_len); + + if ((test_len != asym_op->dh.shared_secret.length) || + (memcmp(test_shared, + asym_op->dh.shared_secret.data, test_len))) { + RTE_LOG(ERR, USER1, + "shared secret compute verification failed\n"); + status = TEST_FAILED; + } + rte_free(test_shared); + BN_free(p); + } +error_exit: + if (sess != NULL) { + rte_cryptodev_asym_session_clear(dev_id, sess); + rte_cryptodev_asym_session_free(sess); + } + if (op != NULL) { + if (asym_op->dh.priv_key.data != NULL) + rte_free(asym_op->dh.priv_key.data); + rte_crypto_op_free(op); + } + return status; +} + +static int +test_dh_gen_priv_key(DH *testkey __rte_unused, + struct rte_crypto_asym_xform *xfrm) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_mempool *op_mpool = ts_params->op_mpool; + struct rte_mempool *sess_mpool = ts_params->session_mpool; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_crypto_asym_op *asym_op = NULL; + struct rte_crypto_op *op = NULL, *result_op = NULL; + struct rte_cryptodev_asym_session *sess = NULL; + int status = TEST_SUCCESS; + char test_msg[ASYM_TEST_MSG_LEN + 1]; + uint8_t output[TEST_DH_MOD_LEN]; + struct rte_crypto_asym_xform xform = *xfrm; + + sess = rte_cryptodev_asym_session_create(sess_mpool); + if (sess == NULL) { + snprintf(test_msg, + ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + /* set up crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); + if (!op) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to allocate asymmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + asym_op = op->asym; + + /* Setup a xform and op to generate private key only */ + xform.dh.type = RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE; + xform.next = NULL; + asym_op->dh.priv_key.data = output; + asym_op->dh.priv_key.length = sizeof(output); + + if (rte_cryptodev_asym_session_init(dev_id, sess, &xform, + sess_mpool) < 0) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "unabled to config sym session"); + status = TEST_FAILED; + goto error_exit; + } + + /* attach asymmetric crypto session to crypto operations */ + rte_crypto_op_attach_asym_session(op, sess); + + snprintf(test_msg, ASYM_TEST_MSG_LEN, "Process ASYM operation"); + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + debug_hexdump(stdout, "private key:", + asym_op->dh.priv_key.data, + asym_op->dh.priv_key.length); + + +error_exit: + if (sess != NULL) { + rte_cryptodev_asym_session_clear(dev_id, sess); + rte_cryptodev_asym_session_free(sess); + } + if (op != NULL) + rte_crypto_op_free(op); + + return status; +} + + +static int +test_dh_gen_pub_key(DH *testkey, + struct rte_crypto_asym_xform *xfrm) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_mempool *op_mpool = ts_params->op_mpool; + struct rte_mempool *sess_mpool = ts_params->session_mpool; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_crypto_asym_op *asym_op = NULL; + struct rte_crypto_op *op = NULL, *result_op = NULL; + struct rte_cryptodev_asym_session *sess = NULL; + int status = TEST_SUCCESS; + char test_msg[ASYM_TEST_MSG_LEN + 1]; + uint8_t output[TEST_DH_MOD_LEN]; + struct rte_crypto_asym_xform xform = *xfrm; + + sess = rte_cryptodev_asym_session_create(sess_mpool); + if (sess == NULL) { + snprintf(test_msg, + ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + /* set up crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); + if (!op) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to allocate asymmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + asym_op = op->asym; + /* Setup a xform chain to generate public key + * using test private key + * + */ + xform.dh.type = RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE; + xform.next = NULL; + + asym_op->dh.pub_key.data = output; + asym_op->dh.pub_key.length = sizeof(output); + /* load pre-defined private key */ + asym_op->dh.priv_key.data = rte_malloc(NULL, + BN_num_bytes(testkey->priv_key), + 0); + asym_op->dh.priv_key.length = BN_bn2bin(testkey->priv_key, + asym_op->dh.priv_key.data); + + if (rte_cryptodev_asym_session_init(dev_id, sess, &xform, + sess_mpool) < 0) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "unabled to config sym session"); + status = TEST_FAILED; + goto error_exit; + } + + /* attach asymmetric crypto session to crypto operations */ + rte_crypto_op_attach_asym_session(op, sess); + + snprintf(test_msg, ASYM_TEST_MSG_LEN, "Process ASYM operation"); + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + debug_hexdump(stdout, "pub key:", + asym_op->dh.pub_key.data, asym_op->dh.pub_key.length); + + BIGNUM *r = BN_new(); + if (r != NULL) { + /* if priv key is same, then pub too should be same */ + r = BN_bin2bn(asym_op->dh.pub_key.data, + asym_op->dh.pub_key.length, r); + if (BN_cmp(testkey->pub_key, r)) + status = TEST_FAILED; + BN_free(r); + } + +error_exit: + if (sess != NULL) { + rte_cryptodev_asym_session_clear(dev_id, sess); + rte_cryptodev_asym_session_free(sess); + } + if (op != NULL) { + if (asym_op->dh.priv_key.data != NULL) + rte_free(asym_op->dh.priv_key.data); + rte_crypto_op_free(op); + + } + return status; +} + + +static int +test_dh_gen_kp(DH *testkey, struct rte_crypto_asym_xform *xfrm) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_mempool *op_mpool = ts_params->op_mpool; + struct rte_mempool *sess_mpool = ts_params->session_mpool; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_crypto_asym_op *asym_op = NULL; + struct rte_crypto_op *op = NULL, *result_op = NULL; + struct rte_cryptodev_asym_session *sess = NULL; + int status = TEST_SUCCESS; + char test_msg[ASYM_TEST_MSG_LEN + 1]; + uint8_t out_pub_key[TEST_DH_MOD_LEN]; + uint8_t out_prv_key[TEST_DH_MOD_LEN]; + struct rte_crypto_asym_xform pub_key_xform; + struct rte_crypto_asym_xform xform = *xfrm; + + sess = rte_cryptodev_asym_session_create(sess_mpool); + if (sess == NULL) { + snprintf(test_msg, + ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + /* set up crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); + if (!op) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to allocate asymmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + asym_op = op->asym; + /* Setup a xform chain to generate + * private key first followed by + * public key + */ + xform.dh.type = RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE; + pub_key_xform.xform_type = RTE_CRYPTO_ASYM_XFORM_DH; + pub_key_xform.dh.type = RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE; + xform.next = &pub_key_xform; + + asym_op->dh.pub_key.data = out_pub_key; + asym_op->dh.pub_key.length = sizeof(out_pub_key); + asym_op->dh.priv_key.data = out_prv_key; + asym_op->dh.priv_key.length = sizeof(out_prv_key); + if (rte_cryptodev_asym_session_init(dev_id, sess, &xform, + sess_mpool) < 0) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "unabled to config sym session"); + status = TEST_FAILED; + goto error_exit; + } + + /* attach asymmetric crypto session to crypto operations */ + rte_crypto_op_attach_asym_session(op, sess); + + snprintf(test_msg, ASYM_TEST_MSG_LEN, "Process ASYM operation"); + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + debug_hexdump(stdout, "priv key:", + out_prv_key, asym_op->dh.priv_key.length); + debug_hexdump(stdout, "pub key:", + out_pub_key, asym_op->dh.pub_key.length); + + BIGNUM *r = BN_new(); + if (r != NULL) { + r = BN_bin2bn(asym_op->dh.priv_key.data, + asym_op->dh.priv_key.length, r); + + /* if priv key is same, then pub too should be same */ + if (!BN_cmp(testkey->priv_key, r)) { + r = BN_bin2bn(asym_op->dh.pub_key.data, + asym_op->dh.pub_key.length, r); + if (BN_cmp(testkey->pub_key, r)) + status = TEST_FAILED; + } + BN_free(r); + } + +error_exit: + if (sess != NULL) { + rte_cryptodev_asym_session_clear(dev_id, sess); + rte_cryptodev_asym_session_free(sess); + } + if (op != NULL) + rte_crypto_op_free(op); + + return status; +} + +static int +test_RSA_encryption(void) +{ + rsa_test_case.op_type = RTE_CRYPTO_ASYM_OP_ENCRYPT; + return test_rsa(&rsa_test_case); +} + +static int +test_RSA_decryption(void) +{ + rsa_test_case.op_type = RTE_CRYPTO_ASYM_OP_DECRYPT; + return test_rsa(&rsa_test_case); +} + +static int +test_RSA_sign(void) +{ + rsa_test_case.op_type = RTE_CRYPTO_ASYM_OP_SIGN; + return test_rsa(&rsa_test_case); +} + +static int +test_RSA_verify(void) +{ + int status; + rsa_test_case.op_type = RTE_CRYPTO_ASYM_OP_VERIFY; + status = test_rsa(&rsa_test_case); + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + return TEST_SUCCESS; +} + +static int +test_mod_inv(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_mempool *op_mpool = ts_params->op_mpool; + struct rte_mempool *sess_mpool = ts_params->session_mpool; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_crypto_asym_op *asym_op = NULL; + struct rte_crypto_op *op = NULL, *result_op = NULL; + struct rte_cryptodev_asym_session *sess = NULL; + int status = TEST_SUCCESS; + char test_msg[ASYM_TEST_MSG_LEN + 1]; + struct rte_cryptodev_asym_capability_idx cap_idx; + const struct rte_cryptodev_asymmetric_xfrm_capability *capability; + BN_CTX *ctx = NULL; + uint8_t input[TEST_DATA_SIZE] = {0}, sw_res[TEST_DATA_SIZE] = {0}; + uint8_t sw_res_len = 0; + + if (rte_cryptodev_get_asym_xform_enum( + &modinv_xform.xform_type, "modinv") < 0) { + snprintf(test_msg, + ASYM_TEST_MSG_LEN, + "Invalid ASYNC algorithm specified\n"); + return -1; + } + + cap_idx.type = modinv_xform.xform_type; + capability = rte_cryptodev_asym_capability_get(dev_id, + &cap_idx); + + if (rte_cryptodev_asym_xfrm_capability_check_modlen( + capability, + modinv_xform.modinv.modulus.length)) { + snprintf(test_msg, + ASYM_TEST_MSG_LEN, + "Invalid MODULOUS length specified\n"); + return -1; + } + + sess = rte_cryptodev_asym_session_create(sess_mpool); + if (!sess) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, "line %u " + "FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + + if (rte_cryptodev_asym_session_init(dev_id, sess, &modinv_xform, + sess_mpool) < 0) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "unabled to config sym session"); + status = TEST_FAILED; + goto error_exit; + } + + /* generate crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); + if (!op) { + snprintf(test_msg, + ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to allocate asymmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + asym_op = op->asym; + memcpy(input, base, sizeof(base)); + asym_op->modinv.base.data = input; + asym_op->modinv.base.length = sizeof(base); + + /* attach asymmetric crypto session to crypto operations */ + rte_crypto_op_attach_asym_session(op, sess); + + snprintf(test_msg, ASYM_TEST_MSG_LEN, "Process ASYM operation"); + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + if (result_op == NULL) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + snprintf(test_msg, + ASYM_TEST_MSG_LEN, + "Modinv :%s length:%lu\n", + asym_op->modinv.base.data, + asym_op->modinv.base.length); + + /* cross verify output using sw lib */ + ctx = BN_CTX_new(); + if (ctx == NULL) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to allocate CTX"); + status = TEST_FAILED; + goto error_exit; + } + BN_CTX_start(ctx); + BIGNUM *x = BN_CTX_get(ctx); + BIGNUM *m = BN_CTX_get(ctx); + BIGNUM *r = BN_CTX_get(ctx); + + if (!x || !m || !r) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to allocate Bignum"); + status = TEST_FAILED; + goto error_exit; + } + + m = BN_bin2bn( + (const unsigned char *)modinv_xform.modinv.modulus.data, + modinv_xform.modinv.modulus.length, m); + x = BN_bin2bn((const unsigned char *)base, sizeof(base), x); + if (!BN_mod_inverse(r, x, m, ctx)) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "SW Mod Inv failed"); + status = TEST_FAILED; + goto error_exit; + } else { + sw_res_len = BN_bn2bin(r, sw_res); + if (memcmp(sw_res, result_op->asym->modinv.base.data, + result_op->asym->modinv.base.length)) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "resulted len[%lu]:expected len[%d]" + "FAILED: %s", + result_op->asym->modinv.base.length, + sw_res_len, + "SW validation fails"); + status = TEST_FAILED; + goto error_exit; + } + } + snprintf(test_msg, ASYM_TEST_MSG_LEN, "PASS"); + +error_exit: + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + if (sess) { + rte_cryptodev_asym_session_clear(dev_id, sess); + rte_cryptodev_asym_session_free(sess); + } + + if (op) + rte_crypto_op_free(op); + return status; +} + +static int +test_mod_exp(void) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_mempool *op_mpool = ts_params->op_mpool; + struct rte_mempool *sess_mpool = ts_params->session_mpool; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_crypto_asym_op *asym_op = NULL; + struct rte_crypto_op *op = NULL, *result_op = NULL; + struct rte_cryptodev_asym_session *sess = NULL; + int status = TEST_SUCCESS; + char test_msg[ASYM_TEST_MSG_LEN + 1]; + struct rte_cryptodev_asym_capability_idx cap_idx; + const struct rte_cryptodev_asymmetric_xfrm_capability *capability; + BN_CTX *ctx = NULL; + uint8_t input[TEST_DATA_SIZE] = {0}, sw_res[TEST_DATA_SIZE] = {0}; + uint8_t sw_res_len = 0; + + if (rte_cryptodev_get_asym_xform_enum(&modex_xform.xform_type, + "modexp") + < 0) { + snprintf(test_msg, + ASYM_TEST_MSG_LEN, + "Invalid ASYNC algorithm specified\n"); + return -1; + } + + /* check for modlen capability */ + cap_idx.type = modex_xform.xform_type; + capability = rte_cryptodev_asym_capability_get(dev_id, &cap_idx); + + if (rte_cryptodev_asym_xfrm_capability_check_modlen( + capability, modex_xform.modex.modulus.length)) { + snprintf(test_msg, + ASYM_TEST_MSG_LEN, + "Invalid MODULOUS length specified\n"); + return -1; + } + + /* generate crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); + if (!op) { + snprintf(test_msg, + ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to allocate asymmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + + sess = rte_cryptodev_asym_session_create(sess_mpool); + if (!sess) { + snprintf(test_msg, + ASYM_TEST_MSG_LEN, + "line %u " + "FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + + if (rte_cryptodev_asym_session_init(dev_id, sess, &modex_xform, + sess_mpool) < 0) { + snprintf(test_msg, + ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "unabled to config sym session"); + status = TEST_FAILED; + goto error_exit; + } + + asym_op = op->asym; + memcpy(input, base, sizeof(base)); + asym_op->modex.base.data = input; + asym_op->modex.base.length = sizeof(base); + /* attach asymmetric crypto session to crypto operations */ + rte_crypto_op_attach_asym_session(op, sess); + + snprintf(test_msg, ASYM_TEST_MSG_LEN, "Process ASYM operation"); + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + snprintf(test_msg, + ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + snprintf(test_msg, + ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + /* cross verify output using sw lib */ + ctx = BN_CTX_new(); + if (ctx == NULL) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to allocate CTX"); + status = TEST_FAILED; + goto error_exit; + } + BN_CTX_start(ctx); + BIGNUM *x = BN_CTX_get(ctx); + BIGNUM *m = BN_CTX_get(ctx); + BIGNUM *e = BN_CTX_get(ctx); + BIGNUM *r = BN_CTX_get(ctx); + + if (!x || !m || !e || !r) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to allocate Bignum"); + status = TEST_FAILED; + goto error_exit; + } + + m = BN_bin2bn( + (const unsigned char *)modex_xform.modex.modulus.data, + modex_xform.modex.modulus.length, m); + e = BN_bin2bn( + (const unsigned char *)modex_xform.modex.exponent.data, + modex_xform.modex.exponent.length, e); + x = BN_bin2bn((const unsigned char *)base, sizeof(base), x); + if (!BN_mod_exp(r, x, e, m, ctx)) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "SW Mod Exp failed"); + status = TEST_FAILED; + goto error_exit; + } else { + sw_res_len = BN_bn2bin(r, sw_res); + /* compare PMD result with sw result */ + if (memcmp(sw_res, + result_op->asym->modex.base.data, + result_op->asym->modex.base.length)) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "resulted len[%lu]:expected len[%d]" + " FAILED: %s", + result_op->asym->modinv.base.length, + sw_res_len, + "SW validation fails"); + status = TEST_FAILED; + goto error_exit; + } + } + snprintf(test_msg, ASYM_TEST_MSG_LEN, "PASS"); + +error_exit: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + if (sess != NULL) { + rte_cryptodev_asym_session_clear(dev_id, sess); + rte_cryptodev_asym_session_free(sess); + } + + if (op != NULL) + rte_crypto_op_free(op); + + return status; +} + +static int +test_dh_keygenration(void) +{ + int status; + struct rte_crypto_asym_xform xform; + uint8_t p[TEST_DH_MOD_LEN]; + uint8_t g[TEST_DH_MOD_LEN]; + + /* generate dh test params using openssl apis */ + DH *key = NULL; + key = DH_new(); + if (key == NULL || + (DH_generate_parameters_ex(key, + TEST_DH_MOD_LEN, + DH_GENERATOR_2, NULL) != 1)) { + RTE_LOG(ERR, USER1, + "Unable to generate test params\n"); + status = TEST_FAILED; + return -1; + } + + xform.dh.p.length = BN_bn2bin((const BIGNUM *)key->p, p); + xform.dh.g.length = BN_bn2bin((const BIGNUM *)key->g, g); + + debug_hexdump(stdout, "p:", p, xform.dh.p.length); + debug_hexdump(stdout, "g:", g, xform.dh.g.length); + + if (!DH_generate_key(key)) { + RTE_LOG(ERR, USER1, + "Unable to generate test params\n"); + status = TEST_FAILED; + return -1; + } + + /* load test params into dh xform */ + xform.dh.p.data = p; + xform.dh.g.data = g; + xform.xform_type = RTE_CRYPTO_ASYM_XFORM_DH; + + RTE_LOG(INFO, USER1, + "Test Public and Private key pair generation\n"); + + status = test_dh_gen_kp(key, &xform); + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + RTE_LOG(INFO, USER1, + "Test Public Key Generation using pre-defined priv key\n"); + + status = test_dh_gen_pub_key(key, &xform); + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + RTE_LOG(INFO, USER1, + "Test Private Key Generation only\n"); + + status = test_dh_gen_priv_key(key, &xform); + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + RTE_LOG(INFO, USER1, + "Test shared secret compute\n"); + + status = test_dh_gen_shared_sec(key, &xform); + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + DH_free(key); + return status; +} + +static int +test_dsa_sign(DSA *testdsa, uint8_t *message, size_t msg_len) +{ + struct crypto_testsuite_params *ts_params = &testsuite_params; + struct rte_mempool *op_mpool = ts_params->op_mpool; + struct rte_mempool *sess_mpool = ts_params->session_mpool; + uint8_t dev_id = ts_params->valid_devs[0]; + struct rte_crypto_asym_op *asym_op = NULL; + struct rte_crypto_op *op = NULL, *result_op = NULL; + struct rte_cryptodev_asym_session *sess = NULL; + int status = TEST_SUCCESS; + char test_msg[ASYM_TEST_MSG_LEN + 1]; + uint8_t r[TEST_DH_MOD_LEN]; + uint8_t s[TEST_DH_MOD_LEN]; + struct rte_crypto_asym_xform xform; + + sess = rte_cryptodev_asym_session_create(sess_mpool); + if (sess == NULL) { + snprintf(test_msg, + ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", __LINE__, + "Session creation failed"); + status = TEST_FAILED; + goto error_exit; + } + /* set up crypto op data structure */ + op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC); + if (!op) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to allocate asymmetric crypto " + "operation struct"); + status = TEST_FAILED; + goto error_exit; + } + asym_op = op->asym; + + /* Setup a xform for DSA */ + xform.xform_type = RTE_CRYPTO_ASYM_XFORM_DSA; + xform.next = NULL; + xform.dsa.x.data = rte_malloc(NULL, + BN_num_bytes(testdsa->priv_key), + 0); + xform.dsa.p.data = rte_malloc(NULL, + BN_num_bytes(testdsa->p), + 0); + xform.dsa.q.data = rte_malloc(NULL, + BN_num_bytes(testdsa->q), + 0); + xform.dsa.g.data = rte_malloc(NULL, + BN_num_bytes(testdsa->g), + 0); + + /* copy test params to xform params */ + xform.dsa.x.length = BN_bn2bin(testdsa->priv_key, + xform.dsa.x.data); + xform.dsa.p.length = BN_bn2bin(testdsa->p, + xform.dsa.p.data); + xform.dsa.q.length = BN_bn2bin(testdsa->q, + xform.dsa.q.data); + xform.dsa.g.length = BN_bn2bin(testdsa->g, + xform.dsa.g.data); + + if (rte_cryptodev_asym_session_init(dev_id, sess, &xform, + sess_mpool) < 0) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "unabled to config sym session"); + status = TEST_FAILED; + goto error_exit; + } + + /* attach asymmetric crypto session to crypto operations */ + rte_crypto_op_attach_asym_session(op, sess); + asym_op->dsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN; + asym_op->dsa.message.data = message; + asym_op->dsa.message.length = msg_len; + asym_op->dsa.r.length = sizeof(r); + asym_op->dsa.r.data = r; + asym_op->dsa.s.length = sizeof(s); + asym_op->dsa.s.data = s; + + snprintf(test_msg, ASYM_TEST_MSG_LEN, "Process ASYM operation"); + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + asym_op = result_op->asym; + + debug_hexdump(stdout, "r:", + asym_op->dsa.r.data, asym_op->dsa.r.length); + debug_hexdump(stdout, "s:", + asym_op->dsa.s.data, asym_op->dsa.s.length); + + /* verify using sw */ + DSA_SIG *sig = DSA_SIG_new(); + if (!sig) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to allocate sw DSA sign"); + status = TEST_FAILED; + goto error_exit; + } + sig->r = BN_bin2bn(asym_op->dsa.r.data, asym_op->dsa.r.length, + sig->r); + sig->s = BN_bin2bn(asym_op->dsa.s.data, asym_op->dsa.s.length, + sig->s); + if (!DSA_do_verify(message, msg_len, sig, testdsa)) { + status = TEST_FAILED; + snprintf(test_msg, ASYM_TEST_MSG_LEN, + " sign compute cross verification failed\n"); + DSA_SIG_free(sig); + goto error_exit; + } + DSA_SIG_free(sig); + + /* Test PMD DSA sign verification using signer public key */ + asym_op->dsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY; + + /* copy signer public key */ + asym_op->dsa.y.data = rte_malloc(NULL, + BN_num_bytes(testdsa->pub_key), + 0); + asym_op->dsa.y.length = BN_bn2bin(testdsa->pub_key, + asym_op->dsa.y.data); + + /* Process crypto operation */ + if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Error sending packet for operation"); + status = TEST_FAILED; + goto error_exit; + } + + while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0) + rte_pause(); + + if (result_op == NULL) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + goto error_exit; + } + + if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) { + snprintf(test_msg, ASYM_TEST_MSG_LEN, + "line %u FAILED: %s", + __LINE__, "Failed to process asym crypto op"); + status = TEST_FAILED; + } + +error_exit: + if (sess != NULL) { + rte_cryptodev_asym_session_clear(dev_id, sess); + rte_cryptodev_asym_session_free(sess); + } + if (op != NULL) { + if (xform.dsa.x.data) + rte_free(xform.dsa.x.data); + if (xform.dsa.p.data) + rte_free(xform.dsa.p.data); + if (xform.dsa.q.data) + rte_free(xform.dsa.q.data); + if (xform.dsa.g.data) + rte_free(xform.dsa.g.data); + rte_crypto_op_free(op); + } + return status; +} + +static int +test_dsa(void) +{ + int status; + DSA *dsa = DSA_new(); + uint8_t dgst[] = "01234567890123456789"; + /* generate test params */ + if (dsa == NULL || !DSA_generate_parameters_ex(dsa, TEST_DH_MOD_LEN, + NULL, 0, NULL, NULL, NULL)) { + RTE_LOG(ERR, USER1, + " failed to generate test params\n"); + return TEST_FAILED; + } + if (!DSA_generate_key(dsa)) { + RTE_LOG(ERR, USER1, + " failed to generate test params\n"); + return TEST_FAILED; + } + + /* test DSA sign using generated private key */ + status = test_dsa_sign(dsa, dgst, sizeof(dgst)); + TEST_ASSERT_EQUAL(status, 0, "Test failed"); + + DSA_free(dsa); + return status; +} + + +static struct unit_test_suite cryptodev_openssl_asym_testsuite = { + .suite_name = "Crypto Device OPENSSL ASYM Unit Test Suite", + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { + TEST_CASE_ST(ut_setup, ut_teardown, test_capability), + TEST_CASE_ST(ut_setup, ut_teardown, test_dsa), + TEST_CASE_ST(ut_setup, ut_teardown, test_dh_keygenration), + TEST_CASE_ST(ut_setup, ut_teardown, test_RSA_encryption), + TEST_CASE_ST(ut_setup, ut_teardown, test_RSA_decryption), + TEST_CASE_ST(ut_setup, ut_teardown, test_RSA_sign), + TEST_CASE_ST(ut_setup, ut_teardown, test_RSA_verify), + TEST_CASE_ST(ut_setup, ut_teardown, test_mod_inv), + TEST_CASE_ST(ut_setup, ut_teardown, test_mod_exp), + TEST_CASES_END() /**< NULL terminate unit test array */ + } +}; + +static int +test_cryptodev_openssl_asym(void) +{ + gbl_driver_id = rte_cryptodev_driver_id_get( + RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD)); + + if (gbl_driver_id == -1) { + RTE_LOG(ERR, USER1, "OPENSSL PMD must be loaded. Check if " + "CONFIG_RTE_LIBRTE_PMD_OPENSSL is enabled " + "in config file to run this testsuite.\n"); + return TEST_FAILED; + } + + return unit_test_suite_runner(&cryptodev_openssl_asym_testsuite); +} + +REGISTER_TEST_COMMAND(cryptodev_openssl_asym_autotest, + test_cryptodev_openssl_asym);