From patchwork Wed May 16 06:05:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shally Verma X-Patchwork-Id: 40078 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 AEBB31B6A7; Wed, 16 May 2018 08:06:10 +0200 (CEST) Received: from NAM01-BN3-obe.outbound.protection.outlook.com (mail-bn3nam01on0062.outbound.protection.outlook.com [104.47.33.62]) by dpdk.org (Postfix) with ESMTP id 76E5E1B6B9 for ; Wed, 16 May 2018 08:06:08 +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:X-MS-Exchange-SenderADCheck; bh=YuH4+NW116GqTyLGHrac7I6Vs4f+rN3aiYuYTv5RAZ0=; b=B3QHNVcQG2Q2t0OxnO974PIii3/WgMxK+nE7FqqzoLLPAPiUxOdFXKij97bQ4+Bswb1nOzKG2SRluStCWWFKZ44r0ieD2+ijqpR+QCwCEyaG4n0UmUv/3YBE5HEINh13++oOgxsVfJqPHiZSc+d2Fer1KjKqkSMQ0yyeFI8Xa+M= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Shally.Verma@cavium.com; Received: from hyd1sverma-dt.caveonetworks.com (115.113.156.2) by DM5PR0701MB3637.namprd07.prod.outlook.com (2603:10b6:4:7d::38) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.755.16; Wed, 16 May 2018 06:06:04 +0000 From: Shally Verma To: pablo.de.lara.guarch@intel.com Cc: fiona.trahe@intel.com, akhil.goyal@nxp.com, dev@dpdk.org, pathreya@caviumnetworks.com, Sunila Sahu , Ashish Gupta Date: Wed, 16 May 2018 11:35:11 +0530 Message-Id: <1526450713-17299-5-git-send-email-shally.verma@caviumnetworks.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1526450713-17299-1-git-send-email-shally.verma@caviumnetworks.com> References: <1526450713-17299-1-git-send-email-shally.verma@caviumnetworks.com> MIME-Version: 1.0 X-Originating-IP: [115.113.156.2] X-ClientProxiedBy: PN1PR0101CA0047.INDPRD01.PROD.OUTLOOK.COM (2603:1096:c00:c::33) To DM5PR0701MB3637.namprd07.prod.outlook.com (2603:10b6:4:7d::38) X-MS-PublicTrafficType: Email X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4534165)(7168020)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020); SRVR:DM5PR0701MB3637; X-Microsoft-Exchange-Diagnostics: 1; DM5PR0701MB3637; 3:biJsx3O822/KgWubqcsYLCKI04oETNuhoTEUxFNk1j62fKFq8hfoj9BKs+kbEY69EuuKceQpvlzQpNzz3+jKhSf7wxceRsVeVOtOkpiTHY0XLUWTqU+eNpqhFhPhDH24OfzV5szHom99DXxn7kXgwLGQwdV+X13oZKsMihgBsT0HGyuAecSfVoVwzw9xAXhaAX4j0lRqrqk9cvNO9qvWejDUKpkrf7spqR+i4GWr2J5fyxFtJs7obtMBwPT7lFZo; 25:19w2lP+UTJQbQHVTU0t66Uq2war0vN2zgxUZwbCG0yhnUb9tKLK0jLToRlS4vm2DiW4s9LAJAchi6u8RJFIO+aQmE/fvBAnbLvOtuBCP5QiOFTeGVUSNsGO5/dwihOsAQzTWKylYOd7WH4ScxkFMkHYJRZEFAtfo8aJhIsE/pDz1IxksrsMTKxqF3Z/baL8P0C2oPRrflKYP/TjS6/cgEdqlnNwIBpxdS1B1Rm2oNQb2G/G5fRrrkNDSw/9hAXvYQIVpbJtk8DwUPCi5ooLoXkA0eMIRDDJkn6urapJvKYRWCNzYnlXxs7LIHVLyLF7OEnPRAKZaLMpD6bVJXLoNNQ==; 31:wOOndVT5at1ND3Vv7cz04tmCVFuE/muxmpcFU5Idtpbn36nvfApXVXGuNk3Exw4tJsXJeSAf7VWdNKFs5ZvKZ8cMl2tBcbRWZpA7e5HqwjNPc1gvHligUBJ3WhPUSaXhtI8uI6a1Upaueza1BKiIdbAE1d/oyeLA341mmP98VBI97IgOQl+gDLkrmkH9HpFR5x/Un3qTCYKukl/6UfvuXZLPiSMs9saLhfpxW2stbDQ= X-MS-TrafficTypeDiagnostic: DM5PR0701MB3637: X-Microsoft-Exchange-Diagnostics: 1; DM5PR0701MB3637; 20:owhLdazkJAO+ca4AzUykTQRvvFOWw+E8MUj3sBLeeEGg7mrJ1OsEOowof2fMVOyZW2MEES5Er/E9thlKygMml4GLMXZ2QIAV2a/ckzXFcf3MzKQnfhMk8dWG/9tMaHY89V6t5PgNYo+WFE0Jcg0z0OOnN8ObMGxBqHsT/qp4RIyX5sS6yX3yLXLxJhmgveBKnF39Rxt9dFCpQfaKUV74kjCR+4rp2GK7ROld2hZiLej8/lcxIkWz95b8mh7IDrnNi+lW+9009SnmxPfmBxowQWcybHmm3TTVLeoyw8KZDWYG0Ox6RpkFxqj0MzyXoGmOCGr26LxZb6xz2+kyF1vMI3ynWEHK/2lfI2wJj0nqHCgKhkJXEhyc3uV3zWt7m+xQMFSmPCfbT4kAgnOlqNH6qMv5mdiGwdM8W5wbcyCIVcE5phQhe+Jw9p+3fZGMkxn01MJimogMxwrH5rYOuUFZ5sXNB8kKJjoY1L+wl2us9MKrrTmXK0CYtBHQSyNco+hL9D4bvUM44AcGcQ6S+xdHvBziyD/iDLt+Rba/1c6676iPv3OPnEV4mrNttDa7lmnBu30sSrYU8yFWIizglSH5gBGhR40pz5kSGqbSHheRR+M=; 4:wqW0uAG1IPONwHdQVN7fLje6z02EANYPNOV19irUR34l/ZqXrsNfMst8FcyX+9pnvVeJQNlFTmxdA6QJOUg6pmV15Rx2V9F8Np6AIFtyKfmGTVy16iS6qHPjlEltd7BC/9aRbPb6wQzUWrmXaBpzqXuS4D1gVMH45nOLpIHNTnBXV6mr2PjPuVeyTM5Pik6/ZhrfRbB2+OI8IZHs0dTPIJXkc/4Ah9WoRmKTi2HKj3ISbwvOVHaavP8qTOcLPO9GxtHIPlXX3NaogT51DPJHfQ== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(3231254)(944501410)(52105095)(93006095)(3002001)(10201501046)(149027)(150027)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123564045)(20161123562045)(20161123558120)(20161123560045)(6072148)(201708071742011); SRVR:DM5PR0701MB3637; BCL:0; PCL:0; RULEID:; SRVR:DM5PR0701MB3637; X-Forefront-PRVS: 0674DC6DD3 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(346002)(376002)(396003)(39380400002)(366004)(39860400002)(189003)(199004)(76176011)(6486002)(7736002)(305945005)(42882007)(106356001)(105586002)(3846002)(6116002)(8656006)(53416004)(6666003)(53946003)(47776003)(2351001)(2361001)(59450400001)(66066001)(6506007)(386003)(6512007)(55236004)(16526019)(8676002)(54906003)(51416003)(52116002)(50226002)(186003)(69596002)(81166006)(16586007)(316002)(26005)(6916009)(81156014)(107886003)(5660300001)(8936002)(53936002)(36756003)(48376002)(50466002)(25786009)(478600001)(575784001)(956004)(72206003)(5890100001)(97736004)(476003)(11346002)(446003)(486006)(4326008)(2906002)(44832011)(68736007)(2616005)(579004)(559001); DIR:OUT; SFP:1101; SCL:1; SRVR:DM5PR0701MB3637; H:hyd1sverma-dt.caveonetworks.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; Received-SPF: None (protection.outlook.com: cavium.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DM5PR0701MB3637; 23:u+vKl6+PVrn2Pxlp9o2k13YlmhlLn+bGpvSWp21?= cvE/8IPim9WgaD+ajiaHY9LYMSQED1rM9BeRSGHY0oh3ohZdOeLsoHRNtU4B2e8qLUiolTy7aCpxyF6QQQ/H/ruk3w4NjbZVtRzJNw78NY80ZD0B4HDBHwQdim4TMF+w4DY/r2C0iqvUCILCwWWd+6n3iUDpujoyAZN84f/bSk1B39CztXP2G2yE5bAGBr1XME7V989JKjkULF+WmymOtmRoD3/8iI+iKNe8pDBJfi/YfEkaCJOlSUfXFt7lYONcdoS4qe/ygfnkzJd4ZRgxYt/3dmAR1XaVCOXZpBQ+bqhU7Kl3STNwvdHuLt6SK7SaT4Dn0iW1WubzuaSQVqBDyHmhwML/wwOHYTogbNln25LSebNbcItbK2AT9IZlzD6WEGeFjaMZnrYnQsauzwEMnNbpXIbN7RvITHfWor5If+p0qv20OtLwSyZ4dKShH+sGBoSjLpJIpd+k8mGLA3SHQWZfb4o5lNTKAxHyixw028B+qU5Ps/+OFOSB7dCSwTvXZRmqioBp0xPpZLpIdZ6jsNF8bj7K+FhYGY5hFpp2O0zQXf6C403J6pLMBol3fTyGW5uWZAQUBd+xvgjYSQeu3gE60XDNJz6ZwVx0mhfLZeold2B6m1zgXozT+R2JTCHYUtYph1xJH8UKOMBvliXwFV64LwxLusnjCEr48LzbhrslQPCULTAO8t9rJjqHKoYbXivJTA5oJBeHxu2348fg9EXwPAzlDNPUdzDus7/H7fv5w+MZBagT+g/2lw2C9hy0S4eN3wmIfRdV0jmWtZ2Wuq9WmbGcRSR9E0PkfAsqC9MOfEvUAiSzicpGoIwhPz2W/A81hjcRpnchyt+de284YcVypEwMTXCcDfTaZQiZMnmbi5OKyYSS/srWLoQHT8gLmqdbah7XYIbl8zi/CKVv7huAAwSKYeLmJEV2+U27lVO3UdFEpBMS9EQlgHlbTOOHcUMRfp9DkpPr+2ALQSxMdgT1sbI2HXIIypDOumiALeDhtV4ZQywkUhLMMvW11ANo/K55t/Ao7jwCbWp+Ce4DiwlGeoMbn1ByfBPYRYIWd5sR3z+X+Izw8xCxB37slFBQ3j9AsFBVnf+HoY5EWz3rzIxWHyix2Jl2O8Q+NvTLKFljUNa8X8cEf+HhVB7x8f8w0lhPODjByGniOvcBnEmEIRzLFxTdfGQin5QJYWzosPwL7H5Gj5r13MZDkQe4aTXHjWPx92m0CdIIUpbPd4YOQgGHMPT+wPOJEcTb9C4E7TnmIm0Ll6O23T1JLQTmMcXaRgkkr9rf1Fn/F0Wj0VXyjtZ9mOgRtpUNa4LzMsHDrM2k7BMDF9Hljxk2BDbkUu2NaeLSciET1xFJCRcKdpzmwP23IF14LLsAZmDXYYebLyvsovclJpMQgwb5MvcBgGt9nbKT/WdB8zRVfNKjjgdql1HpJuYAiNHc+9GE+QNpvql+vnZdFqb8W9+FPHJ4OCAjvcDU= X-Microsoft-Antispam-Message-Info: BpL5chIHKn9pdu8ZSAkxSEkuynemq01jRMbvFtFTbOro4KAWTwgq5oJoHYMNlN8hsMhe05fAqvjpaz3N2ipATATUfRg2azM2Jys4U09yyrmKjl7aEiKzcTiGxIwtOcsfS37wLsYEa4a6Dj6cKWuQTekKZepJjwFWtBrBCkt4A7lJE5s1N2nA3ClQwz4SkIeh X-Microsoft-Exchange-Diagnostics: 1; DM5PR0701MB3637; 6:4kfomWFkR+zHkmk0+qI9TTAzMdRvKrcjZ14oeOEK7dJsNZ6Rigv93ZDa+LKu18H49vsTWtw+056m1hEm/qsyiz+6jKfBZnhM5MKFR+Y2bCNwUGLAGqYb02ehc6qCEXGbbJDbrAnM4MQ8xipTUkRRJgBFUrT1b21qQk1S+xBE3foFh6pm2pm1Hd/y/70+nxOVfn90aLNoao9CE8PlVRk7jN/+jSFkJ47Ysj3d/4OD/iFQ9OtJPt5QiiISMWXm8IBT4N+pzByNDjtK6KifbuE/1iItUxcg9tBPyV9YRFCV9dkgRFV3l7yW0JD5jmyTS3IJEnML+8q7Se6XSZ8Riws6o1Ei2Ovh4qIPQ3YyX/k5RYOtpBKngv/+KFU0naupIvD875a9Ht5NNO7KUbxrnsasQC89jFJfDbVr2ptk3A1wXBffDRwWDQWOaUR6cQP09cUETs3RHNaSAgx+jm+n6IdZzw==; 5:JKxeWkG+kS83DF/wykVQhdqKe9O7AfQrGDYxcxaacqtBWXdotVCRQ7BjuyRMN5W5QopCP5smhbHii7gTkWp+5rdwmDxHjiCePaKZm01ZotlV40ozOPCPzydAY3JnarwvgW3RGtVvq0ps2gQ3xDkVvFfz2nJfOkIons2VrnOZnbQ=; 24:c8RCwoDphKfdYiG/ifkKxiavP5/atrwmQ8Qdm7xUE6IxOtees+g97wWNlqXi05DbdUJgIWmoRVvY64f+7jmTE2gOdMVmkCKI7GFnxXBCyEA= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; DM5PR0701MB3637; 7:86UNpcRQ0nRm6Q/oSaWB7z0Xi/NwOcX2AtV9ixv3z2AWCjD0DMWcwQ+TEmgOTf/HvoSNHSCrllrY8QI1xROGXm694mk8RkxHoVBW7mzlnX+iVv6v9QMOR4eTbg1Cph6dGdYNerN3Hu1Xql3hrDx0YGzeO3eiIg01UHnlSbs9A00Oppw2+KSRaueD93yn7W0TkpstAy9LjF0R5R8Jy045jeS4qTYTHDBSNdeLcCIfdBhbVNGuBGjCYFofp1BqQ8uL X-MS-Office365-Filtering-Correlation-Id: 828d0b9c-1bc8-4957-cd6b-08d5baf31ce0 X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 May 2018 06:06:04.3044 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 828d0b9c-1bc8-4957-cd6b-08d5baf31ce0 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 711e4ccf-2e9b-4bcf-a551-4094005b6194 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR0701MB3637 Subject: [dpdk-dev] [PATCH v3 4/6] test/crypto: 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" Add 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. Changes from v2: - Change test application to use the renamed APIs and to use xform type from capability structure Signed-off-by: Shally Verma Signed-off-by: Sunila Sahu Signed-off-by: Ashish Gupta --- This patch dependent on asym crypto API patches. Please apply them before compilation --- --- test/test/Makefile | 3 +- test/test/meson.build | 1 + test/test/test_cryptodev_asym.c | 1787 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 1790 insertions(+), 1 deletion(-) diff --git a/test/test/Makefile b/test/test/Makefile index d1a75fe92..9526b939d 100644 --- a/test/test/Makefile +++ b/test/test/Makefile @@ -179,6 +179,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_COMPRESSDEV_TEST),y) SRCS-$(CONFIG_RTE_LIBRTE_COMPRESSDEV) += test_compressdev.c @@ -205,7 +206,7 @@ CFLAGS += $(WERROR_FLAGS) CFLAGS += -D_GNU_SOURCE -LDLIBS += -lm +LDLIBS += -lm -lcrypto ifeq ($(CONFIG_RTE_COMPRESSDEV_TEST),y) ifeq ($(CONFIG_RTE_LIBRTE_COMPRESSDEV),y) LDLIBS += -lz diff --git a/test/test/meson.build b/test/test/meson.build index 3c8edf521..85bb90a42 100644 --- a/test/test/meson.build +++ b/test/test/meson.build @@ -21,6 +21,7 @@ test_sources = files('commands.c', 'test_cpuflags.c', 'test_crc.c', 'test_cryptodev.c', + 'test_cryptodev_asym.c', 'test_cryptodev_blockcipher.c', 'test_cycles.c', 'test_debug.c', diff --git a/test/test/test_cryptodev_asym.c b/test/test/test_cryptodev_asym.c new file mode 100644 index 000000000..a904c2785 --- /dev/null +++ b/test/test/test_cryptodev_asym.c @@ -0,0 +1,1787 @@ +/* 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_asym_get_private_session_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; + const struct rte_cryptodev_capabilities *dev_capa; + 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)) { + RTE_LOG(INFO, USER1, + "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++) { + dev_capa = &(dev_info.capabilities[i]); + if (dev_info.capabilities[i].op == + RTE_CRYPTO_OP_TYPE_ASYMMETRIC) { + idx.type = dev_capa->asym.xfrm_capa.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_asym_get_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_asym_get_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);