From patchwork Tue Apr 3 10:31:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shally Verma X-Patchwork-Id: 36929 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 A215B1B6EE; Tue, 3 Apr 2018 12:31:44 +0200 (CEST) Received: from NAM03-BY2-obe.outbound.protection.outlook.com (mail-by2nam03on0085.outbound.protection.outlook.com [104.47.42.85]) by dpdk.org (Postfix) with ESMTP id A74761B6E0 for ; Tue, 3 Apr 2018 12:31:42 +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=N/n7tslPKoy8DHb4WTPuUzMV34qZ5jToIidGFB4d5xo=; b=K9l/VDa5VJGV6aUig3H+oTMulDgWzLXmoLSbJU9oPmoELtrmEl+39R/QRDq7WMEJW9VQ0LkRwUAZZChnPX7JMpUhya9XhWwtsYdnzFPvb9G6vh9Gbr3DzdsGC5/d3FH0hRmnqILrZPanz9xcvjqIZLR+/9X9Zo2KAwc9b7FnWKE= 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:37 +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:08 +0530 Message-Id: <1522751469-21307-3-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: 5653ac42-4d4b-4e4b-81a4-08d5994e16b8 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:a/xqvIzfo+fSxw73INxdgw8LfgE3jJVuK2I+l02uXQhdnMzFxm1TxR7cmUbYvgpKNpEfnf32O62CbVvdwUcu72KLfb9ahXPSypN/DkmO4x3hW2qdcFyjp9JgzgwIqdYLe7P4OnWDEc9IvERpMgLDO5WnmcmOPfvc8XtTtl94jBhiByXTReUogBp3U6La1bvZHpAW98LLuYe8Il8o9XYGjQ9IdfiS0IwJzHeOUUx890L0v8RVyXm4ydBZf8PW2+CB; 25:lmWbWF9Gh9zhOEAf8LhyyI1qFx5u2nCcZJrPw0rChWMlEvRH+2jiNeRVN9pgxbaBOu7HYELMWuF5Zsug1CbRzRTKZ5GJQlXyfAsuCqtAr8VtEk19oHAO2TWx+Pljj1iIojtvLnEOEQnoLdyuX1yqRNdwxEjfasegrDBtvhqgV3BkU+HET154R74sQIJ0uxu2+/3RX9DM66yphgnc3POF4X8usFJS95BvCuPjs/VcVopCNfflw3xIchYaskNjpQRhLZO3Vr8U7h/B3F/XEv1p3QJEcl1+205MSw6ZPequ1eCxjUDhIWVx7YE9OupeQjw+6717DRrb2xagFcZ/S9baLQ==; 31:De6ztwIQTt/Lspqh0cv2SIW2CKepmGy7z1pncQqSEse8o11sgjfC77UKJObEKXZgbuCqvPIuwV+6nqNeUrRYGdGe+evcpQKOtFyb79SEauiihdODtu9nGFanWjsxtThfCOdercEa5z+GjafCmFavSWfYtE/zyEEdTAAdrppHPURY9uCPj1BiMtwxpzc/w92ysY5L17V6N85BoAf31xbq+rvnB5cgGy9Q0dp9NOinj0M= X-MS-TrafficTypeDiagnostic: CY4PR0701MB3633: X-Microsoft-Exchange-Diagnostics: 1; CY4PR0701MB3633; 20:uF/9+kFm3TgT7WE+RC4U/Z4UNbYV/2BZu43JeFjH9KgAur6wCygmXaKxSNna4XCkNpP9dxTUNEW7cra3/1u8NfERAjWGu6L5y+yaDzNgGNuI4eMvksQvjba/GvMleZqCJ6xq9n6+zo87TWfXHBCUI+J5GSOxbdVIG9g+AMKO1dUhz2HmS5hagDHmsi/MKlDx+z+qG0R1rJSG0ZS00Kq/XSB+iq3sWvkMZ3kC+FW96PDGMWmFY+PkdrvFuCAdaLuu3TEq8NtvT/XfS0uJCitfzNVYYhTZajEmme8H084UZpRvLdHS2UkFYwU7rKQIipHUtxg4xVVllNu+UptKfhyCeK0WURuSQQubjpd8AS3F2tkJKZIY95AyEsMVLLsD36LEAHvCM4cZkOpyUw7SXjp8LKcGlYqpg25H2qi0hD2aFWy0uXAyIi0eeseHue+PH0yXwbDJXXPCCxOeK8u417xT9mQQIJyGHMM/+ZiJUBI87RU7kKihAKPzCVpQ2OYqlRF1s4dCVcSZOHCAs9uX6fWhMnJVZul0xalGGhocCIAmSpCYzr5lPp19k5uXRCT94ybEkLKBMjPI8enQd9jYhMCQGyRFTc/N4m03VQGQFrnmdG8=; 4:Jt0SWptDsc21aqcCmruzoxT0BUAKfibtyg0eMW9fCP2yGl5QmuTQycnpyANvQuQYlfDZ3+gytVjuONgTW9s5kh/xK/r8pLFpsvlIsSoRgdxoeDThCZr6R094w0CHocCDD8igPrV9nz09WySn9cGmYzPo59fdr47/mNHYvjCETvi08VHFTcB2N89fFE0hpJier+T5km6SYgGlULBxJ/i6VkGrKZvAmmL/vK1vV3Mb2qfEgKWwN5Kb+lHHDI+cVr75Z4KuqK/S3ZYbHIsqYdd5bg== 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)(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)(42882007)(478600001)(47776003)(7736002)(316002)(2361001); 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:rMrxX3TobVhTNlv1kOEtTcmgwMeFKgQZHUbNtOR?= hA9ITsZNyCzyMmxIykrrhuw10J0ZyVmCQiSmValAfBhvs2Ey7tv+T4fGYPYfaDkbWwdVVnakQ5J207Nu9E907leiq9oB4hnfKK2dTqIr9txvIeVcoN7i0zeM8sCLFNhs/9+Maa8m8smqPhP64JCK6L5E/HOJh5Z68Dq9naC9NhOSW+8JOZ4TPfCDs8IDIu187sCuP7+FbC8xee3tsGjGXI56TGm2OhbMB+G1lmtiGPoGYqZimP6KPlAxWTMyI1AsNqrUxbjGkagu6ow/h8TsaBp6usG7BTYKqTzJojvk7wWVZxzpK3kg5bDcpWLUeyFmPLJ0l8OzJspwsi9iUvXCJZheXvSpj4mKhr+u+srEDDLMHZgGS55ht92pv6d8rlasmhJ0akl1N+wi49nDQS0nTRBPHH6wkE3Up6nA2UJrt/DVJNPhlpbxH6APzvnaqC1/EChcq/4dPohJZpD0oJ1MnEeuulmlHwnIHZ+8ie197yhBjndumEwh8yS6hROVk2KCGxT9EmItmMa/AAsUvqxL1Xpxbbgym9aHZ5uKnTeR3g2xFM1SGorm7s8+TTcXkNiNYlKDq9+7zh51OA/JJZ39ZsfpfYtR5SoWbS/NPy4hzpY8wFTRo1VH/T41PkaXwmaTD7Ob/1s7Hd1T7LBIF672imeewyafssANP3/6IBoGH/wz1wejVxV+1WKo+9apZblSISFuSZLl051TrWf47L/5RZtPaps52UGSvcoHbBTWmD38ObF4qo/NozwRRQ6EFZwnITAjXszgFLnJVypDpeKaTEhe19+i/aH9VjtFXblE78pP7+1JtAeLCMedCc7ohyF5cleQqJiFpyWyIYu38AiQGsItQpbjrgPBToU9/izLqKMYbGWNnxdK9aM3hcb5XrKGvfkGhS1HirjEYMtqpx1xXVf3hQ7/VC9zWZ91A23Znt0Ae6e3g0zFXvv9z/6f3OJGqBh39nPq2ba2XHP6CmLXzt5Dj3ExeJHMsRBsimUXHas/8DPPuorBc/OwyLqBJ4HMZykm2sbbt8cEOThX+xjZM1JU+Tx+/RjdIAcZ4/QPMFzdozAeQ+EVtCPuEsDd6Wmd3sENede0GvGV/ZjYbqfYnozzZJo6cVzjUSh2ES35Oig4cPUx3uw1sLIp/RVSIK9bRw1XeEDShobQVtHckYIeudwA3ms875AkW8ZxtfJfLrh+lZ//CPmCeHhgx7xTj1ks1Zpt8H9YeV1maN0QxEKk2RrihHppQY5xK24gfAMOVReCLH0fudQGuKQCU52U0B96rK5zuJgRActX+huRURtASkI1hq+LYY563218AkHdzOexFcSFvU/D6grkwd7+a1cI1pGXxVebJmBHn5oIM6gOeligzsA/Xv2zQFIipfWtQBX/SkA== X-Microsoft-Antispam-Message-Info: EUc7QvP6lG3zhz9pbFzCOIwGIN7p3GoUDpfqqrzaFEFbbtPTci5sRej4tLZV09OmZe8YO3miTnj9SKDQSIknxzUJS+fIEMYqNQT12VB0VH64O3HuCyDV8JnrGsB+WU5ACAzD/VjeCclOdbXmpWk7+pumLfrn6si9gprbk6WzhpDgSLamKYVHi52mTXRGhCv1 X-Microsoft-Exchange-Diagnostics: 1; CY4PR0701MB3633; 6:GBim08uI1KyTL4PX1m+1y1tbO2iAOSLvQsa1QK9L+5tcpXSfPuGZYtA7vL+03ZyXcepLun5HYhtFhW4zefrPTYSuoJL+1J8889mW7XQV4Wkjr4/AjHvKBvlq2fQYsPPadWNBdhB6Z6vEf7M+JLSe+8ylEhADa2SAUnQIXfo5EhYVX8sZGZWEX2N/OyqybrfIBTK3Lg/B8Fj5bi7S0UDCQ1kjNJ4roX0QbuMufXVbtwbl9y79gkCIHuaxjRTJ8QZnM6syj1jbxYwJZii3jidttwr8qt3prc0jT170hA7N7jSBOMSEUSuRpfduLmi9arvwch2voFisO3es//BuYMmvqscrkzZ+j20UGLzyNrZfIMp+DlODTLdr6+VqPp2GtQPCNNz2XDe0kjnnVsm8zdD/ilpSJ42kcN33bz2FAnZFEKJGdcVT4a8JqzPLVhWZOt6r36JIFxFdtPL4NQYknhCEeQ==; 5:8tBKR4EcLN9TzJHk7IscnEgva4xU65fVc6QV5pnGN9cKWplb4B04bqqJKOBdP7wWA8pzAcsjEarMemZx2m9oFdJpRFoPpwR3FR7/E22hQJwzQeFgFZgLZfKgq6q8zOw8cp2cDBTnn9QUsww7gxrNcjomwAYSoFpL4MfGrlqqxLI=; 24:POAI0lOGU7Uu8B/7b/gFrFuNktbDQsUrAzCUGyWUrPtAdofd2+0xa15Id8emf7yXS//x3u3Gl8ybcqTqIn/A/Ulj9gKxjz5GCQiKk7LfsiU= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; CY4PR0701MB3633; 7:3G3Ii8d+ighW0ulqjQWh/aU/tfZq99DUHngPvLQlqzI2ZgI9wPsK7mILaOnYEiG1Z9HNMyrvGkKYb/OvIUisLkGlw85NYYVn9FWDPGTxYb9SJPwxBA4fe48J/DISOe2vksC/dSNdaMxkLOSVYvPIUQLK223/2XWOjvcWYXrRgBboSHgOu1/LYnhxV38aLD30SjKVe/loM5dz6Xsde2NOjHqvbaTKfTfXs7WUulB2twk/osMExKzZWmK/JkYDgy8t X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Apr 2018 10:31:37.2513 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 5653ac42-4d4b-4e4b-81a4-08d5994e16b8 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 2/3] crypto/openssl: add asym crypto support 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 asymmetric crypto operation support in openssl PMD. Current list of supported asym xforms: * RSA * DSA * Deffie-hellman * Modular Operations Signed-off-by: Shally Verma Signed-off-by: Sunila Sahu Signed-off-by: Ashish Gupta --- doc/guides/cryptodevs/features/openssl.ini | 11 + doc/guides/cryptodevs/openssl.rst | 2 + drivers/crypto/openssl/rte_openssl_pmd.c | 377 ++++++++++++++++++++- drivers/crypto/openssl/rte_openssl_pmd_ops.c | 400 ++++++++++++++++++++++- drivers/crypto/openssl/rte_openssl_pmd_private.h | 29 ++ 5 files changed, 807 insertions(+), 12 deletions(-) diff --git a/doc/guides/cryptodevs/features/openssl.ini b/doc/guides/cryptodevs/features/openssl.ini index 691565865..bef5c7f79 100644 --- a/doc/guides/cryptodevs/features/openssl.ini +++ b/doc/guides/cryptodevs/features/openssl.ini @@ -7,6 +7,7 @@ Symmetric crypto = Y Sym operation chaining = Y Mbuf scatter gather = Y +Asymmetric crypto = Y ; ; Supported crypto algorithms of the 'openssl' crypto driver. @@ -49,3 +50,13 @@ AES GCM (256) = Y AES CCM (128) = Y AES CCM (192) = Y AES CCM (256) = Y + +; +; Supported Asymmetric algorithms of the 'openssl' crypto driver. +; +[Asymmetric] +RSA = Y +DSA = Y +Modular Exponentiation = Y +Modular Inversion = Y +Deffie-hellman = Y diff --git a/doc/guides/cryptodevs/openssl.rst b/doc/guides/cryptodevs/openssl.rst index 427fc807c..ccb037a80 100644 --- a/doc/guides/cryptodevs/openssl.rst +++ b/doc/guides/cryptodevs/openssl.rst @@ -80,6 +80,7 @@ crypto processing. Test name is cryptodev_openssl_autotest. For performance test cryptodev_openssl_perftest can be used. +For asymmetric crypto operations testing, run cryptodev_openssl_asym_autotest To verify real traffic l2fwd-crypto example can be used with this command: @@ -103,3 +104,4 @@ Limitations contiguous). * Hash only is not supported for GCM and GMAC. * Cipher only is not supported for GCM and GMAC. + diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c index f584d0d6f..527e42773 100644 --- a/drivers/crypto/openssl/rte_openssl_pmd.c +++ b/drivers/crypto/openssl/rte_openssl_pmd.c @@ -727,19 +727,35 @@ openssl_reset_session(struct openssl_session *sess) } /** Provide session for operation */ -static struct openssl_session * +static void * get_session(struct openssl_qp *qp, struct rte_crypto_op *op) { struct openssl_session *sess = NULL; + struct openssl_asym_session *asym_sess = NULL; if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) { - /* get existing session */ - if (likely(op->sym->session != NULL)) - sess = (struct openssl_session *) - get_session_private_data( - op->sym->session, - cryptodev_driver_id); + if (op->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) { + /* get existing session */ + if (likely(op->sym->session != NULL)) + sess = (struct openssl_session *) + get_session_private_data( + op->sym->session, + cryptodev_driver_id); + } else { + if (likely(op->asym->session != NULL)) + asym_sess = (struct openssl_asym_session *) + get_asym_session_private_data( + op->asym->session, + cryptodev_driver_id); + if (asym_sess == NULL) + op->status = + RTE_CRYPTO_OP_STATUS_INVALID_SESSION; + return asym_sess; + } } else { + if (op->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) + return NULL; /* sessionless asymmetric not supported */ + /* provide internal session */ void *_sess = NULL; void *_sess_private_data = NULL; @@ -1525,6 +1541,341 @@ process_openssl_auth_op(struct openssl_qp *qp, struct rte_crypto_op *op, op->status = RTE_CRYPTO_OP_STATUS_ERROR; } +static int process_openssl_modinv_op(struct rte_crypto_op *cop, + struct openssl_asym_session *sess) +{ + struct rte_crypto_asym_op *op = cop->asym; + BIGNUM *base = BN_CTX_get(sess->u.m.ctx); + BIGNUM *res = BN_CTX_get(sess->u.m.ctx); + + if (unlikely(base == NULL || res == NULL)) { + if (base) + BN_free(base); + if (res) + BN_free(res); + cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED; + return -1; + } + + base = BN_bin2bn((const unsigned char *)op->modinv.base.data, + op->modinv.base.length, base); + + if (BN_mod_inverse(res, base, sess->u.m.modulus, sess->u.m.ctx)) { + cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS; + op->modinv.base.length = BN_bn2bin(res, op->modinv.base.data); + } else { + cop->status = RTE_CRYPTO_OP_STATUS_ERROR; + } + + return 0; +} + +static int process_openssl_modexp_op(struct rte_crypto_op *cop, + struct openssl_asym_session *sess) +{ + struct rte_crypto_asym_op *op = cop->asym; + BIGNUM *base = BN_CTX_get(sess->u.e.ctx); + BIGNUM *res = BN_CTX_get(sess->u.e.ctx); + + if (unlikely(base == NULL || res == NULL)) { + if (base) + BN_free(base); + if (res) + BN_free(res); + cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED; + return -1; + } + + base = BN_bin2bn((const unsigned char *)op->modinv.base.data, + op->modinv.base.length, base); + + if (BN_mod_exp(res, base, sess->u.e.exp, + sess->u.e.mod, sess->u.e.ctx)) { + op->modinv.base.length = BN_bn2bin(res, op->modinv.base.data); + cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS; + } else { + cop->status = RTE_CRYPTO_OP_STATUS_ERROR; + } + + return 0; +} + +/* process rsa operations */ +static int process_openssl_rsa_op(struct rte_crypto_op *cop, + struct openssl_asym_session *sess) +{ + int ret = 0; + struct rte_crypto_asym_op *op = cop->asym; + RSA *rsa = sess->u.r.rsa; + uint32_t pad = (op->rsa.pad); + + switch (pad) { + case RTE_CRYPTO_RSA_PKCS1_V1_5_BT1: + case RTE_CRYPTO_RSA_PKCS1_V1_5_BT2: + pad = RSA_PKCS1_PADDING; + break; + case RTE_CRYPTO_RSA_PADDING_PSS: + pad = RSA_PKCS1_PSS_PADDING; + /* fall through */ + case RTE_CRYPTO_RSA_PADDING_OAEP: + pad = RSA_PKCS1_OAEP_PADDING; + /* fall through */ + default: + pad = RSA_NO_PADDING; + break; + } + + switch (op->rsa.op_type) { + case RTE_CRYPTO_ASYM_OP_ENCRYPT: + ret = RSA_public_encrypt(op->rsa.message.length, + op->rsa.message.data, + op->rsa.message.data, + rsa, + pad); + + op->rsa.message.length = ret; + OPENSSL_LOG_DBG("length of encrypted text %d\n", ret); + break; + + case RTE_CRYPTO_ASYM_OP_DECRYPT: + ret = RSA_private_decrypt(op->rsa.message.length, + op->rsa.message.data, + op->rsa.message.data, + rsa, + pad); + op->rsa.message.length = ret; + break; + + case RTE_CRYPTO_ASYM_OP_SIGN: + ret = RSA_private_encrypt(op->rsa.message.length, + op->rsa.message.data, + op->rsa.sign.data, + rsa, + pad); + op->rsa.sign.length = ret; + break; + + case RTE_CRYPTO_ASYM_OP_VERIFY: + ret = RSA_public_decrypt(op->rsa.sign.length, + op->rsa.sign.data, + op->rsa.sign.data, + rsa, + pad); + + OPENSSL_LOG_DBG( + "Length of public_decrypt %d length of message %d\n", + ret, op->rsa.message.length); + + if (memcmp(op->rsa.sign.data, op->rsa.message.data, + op->rsa.message.length)) { + OPENSSL_LOG_ERR("RSA sign Verification failed"); + ret = -1; + } + break; + default: + /* allow ops with invalid args to be pushed to + * completion queue + */ + cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS; + break; + } + + if (ret < 0) { + cop->status = RTE_CRYPTO_OP_STATUS_ERROR; + ret = 0; + } + + ret = 0; + return ret; +} + +static int +process_openssl_dh_op(struct rte_crypto_op *cop, + struct openssl_asym_session *sess) +{ + struct rte_crypto_dh_op_param *op = &cop->asym->dh; + DH *dh_key = sess->u.dh.dh_key; + + if (sess->u.dh.key_op & + (1 << RTE_CRYPTO_ASYM_OP_SHARED_SECRET_COMPUTE)) { + BIGNUM *peer_key = NULL; + + /* copy private key and peer key and compute shared secret */ + peer_key = BN_bin2bn(op->pub_key.data, + op->pub_key.length, + peer_key); + if (peer_key == NULL) { + cop->status = RTE_CRYPTO_OP_STATUS_ERROR; + return 0; + } + dh_key->priv_key = BN_bin2bn(op->priv_key.data, + op->priv_key.length, + dh_key->priv_key); + op->shared_secret.length = DH_compute_key( + op->shared_secret.data, + peer_key, dh_key); + if (!(op->shared_secret.length)) { + cop->status = RTE_CRYPTO_OP_STATUS_ERROR; + BN_free(peer_key); + return 0; + } + cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS; + BN_free(peer_key); + return 0; + } + + if ((sess->u.dh.key_op & + (1 << RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE)) && + !(sess->u.dh.key_op & + (1 << RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE))) { + /* generate public key using user-pass private key */ + dh_key->priv_key = BN_bin2bn(op->priv_key.data, + op->priv_key.length, + dh_key->priv_key); + if (dh_key->priv_key == NULL) { + cop->status = RTE_CRYPTO_OP_STATUS_ERROR; + return 0; + } + } + + /* generate public and private key pair */ + if (!DH_generate_key(dh_key)) { + cop->status = RTE_CRYPTO_OP_STATUS_ERROR; + return 0; + } + + if (sess->u.dh.key_op & + (1 << RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE)) { + OPENSSL_LOG_DBG("%s:%d updated priv key\n", + __func__, __LINE__); + + op->priv_key.length = BN_bn2bin(dh_key->priv_key, + op->priv_key.data); + } + + if (sess->u.dh.key_op & (1 << RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE)) { + OPENSSL_LOG_DBG("%s:%d update public key\n", + __func__, __LINE__); + + op->pub_key.length = BN_bn2bin(dh_key->pub_key, + op->pub_key.data); + } + cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS; + + return 0; +} + +static int +process_openssl_dsa_sign_op(struct rte_crypto_op *cop, + struct openssl_asym_session *sess) +{ + struct rte_crypto_dsa_op_param *op = &cop->asym->dsa; + DSA *dsa = sess->u.s.dsa; + DSA_SIG *sign; + + sign = DSA_do_sign(op->message.data, + op->message.length, + dsa); + + if (sign == NULL) { + OPENSSL_LOG_ERR("%s:%d\n", __func__, __LINE__); + cop->status = RTE_CRYPTO_OP_STATUS_ERROR; + } else { + op->r.length = BN_bn2bin(sign->r, op->r.data); + op->s.length = BN_bn2bin(sign->s, op->s.data); + cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS; + } + + DSA_SIG_free(sign); + return 0; +} + +static int +process_openssl_dsa_verify_op(struct rte_crypto_op *cop, + struct openssl_asym_session *sess) +{ + struct rte_crypto_dsa_op_param *op = &cop->asym->dsa; + DSA *dsa = sess->u.s.dsa; + int ret; + DSA_SIG *sign = DSA_SIG_new(); + + if (sign == NULL) { + OPENSSL_LOG_ERR(" %s:%d\n", __func__, __LINE__); + return -1; + } + + sign->r = BN_bin2bn(op->r.data, + op->r.length, + sign->r); + sign->s = BN_bin2bn(op->s.data, + op->s.length, + sign->s); + + dsa->pub_key = BN_bin2bn(op->y.data, + op->y.length, + dsa->pub_key); + + ret = DSA_do_verify(op->message.data, + op->message.length, + sign, + dsa); + + if (ret != 1) + cop->status = RTE_CRYPTO_OP_STATUS_ERROR; + else + cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS; + + DSA_SIG_free(sign); + + return 0; +} + + +static int +process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op, + struct openssl_asym_session *sess) +{ + int retval = 0; + + op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED; + + switch (sess->xfrm_type) { + case RTE_CRYPTO_ASYM_XFORM_RSA: + retval = process_openssl_rsa_op(op, sess); + break; + case RTE_CRYPTO_ASYM_XFORM_MODEX: + retval = process_openssl_modexp_op(op, sess); + break; + case RTE_CRYPTO_ASYM_XFORM_MODINV: + retval = process_openssl_modinv_op(op, sess); + break; + case RTE_CRYPTO_ASYM_XFORM_DH: + retval = process_openssl_dh_op(op, sess); + break; + case RTE_CRYPTO_ASYM_XFORM_DSA: + if (op->asym->dsa.op_type == RTE_CRYPTO_ASYM_OP_SIGN) + retval = process_openssl_dsa_sign_op(op, sess); + else if (op->asym->dsa.op_type == RTE_CRYPTO_ASYM_OP_VERIFY) + retval = process_openssl_dsa_verify_op(op, sess); + else + op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS; + break; + default: + op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS; + break; + } + if (!retval) { + /* op processed so push to completion queue as processed */ + retval = rte_ring_enqueue(qp->processed_ops, (void *)op); + if (retval) + /* return error if failed to put in completion queue */ + retval = -1; + } + + return retval; +} + + /** Process crypto operation for mbuf */ static int process_op(struct openssl_qp *qp, struct rte_crypto_op *op, @@ -1597,7 +1948,7 @@ static uint16_t openssl_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops, uint16_t nb_ops) { - struct openssl_session *sess; + void *sess; struct openssl_qp *qp = queue_pair; int i, retval; @@ -1606,7 +1957,12 @@ openssl_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops, if (unlikely(sess == NULL)) goto enqueue_err; - retval = process_op(qp, ops[i], sess); + if (ops[i]->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) + retval = process_op(qp, ops[i], + (struct openssl_session *) sess); + else + retval = process_asym_op(qp, ops[i], + (struct openssl_asym_session *) sess); if (unlikely(retval < 0)) goto enqueue_err; } @@ -1660,7 +2016,8 @@ cryptodev_openssl_create(const char *name, dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO | RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING | RTE_CRYPTODEV_FF_CPU_AESNI | - RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER; + RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER | + RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO; /* Set vector instructions mode supported */ internals = dev->data->dev_private; diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c index 1cb87d59a..ae8c44d3d 100644 --- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c +++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c @@ -469,6 +469,110 @@ static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = { }, } }, } }, + { /* RSA */ + .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC, + {.asym = { + .xform_type = RTE_CRYPTO_ASYM_XFORM_RSA, + .xfrm_capa = { + .xform_type = RTE_CRYPTO_ASYM_XFORM_RSA, + .op_types = ((1 << RTE_CRYPTO_ASYM_OP_SIGN) | + (1 << RTE_CRYPTO_ASYM_OP_VERIFY) | + (1 << RTE_CRYPTO_ASYM_OP_ENCRYPT) | + (1 << RTE_CRYPTO_ASYM_OP_DECRYPT)), + { + .modlen = { + /* min length is based on openssl rsa keygen */ + .min = 30, + /* value 0 symbolizes no limit on max length */ + .max = 0, + .increment = 1 + }, } + } + }, + } + }, + { /* modexp */ + .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC, + {.asym = { + .xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX, + .xfrm_capa = { + .xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX, + .op_types = 0, + { + .modlen = { + /* min length is based on openssl rsa keygen */ + .min = 0, + /* value 0 symbolizes no limit on max length */ + .max = 0, + .increment = 1 + }, } + } + }, + } + }, + { /* modinv */ + .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC, + {.asym = { + .xform_type = RTE_CRYPTO_ASYM_XFORM_MODINV, + .xfrm_capa = { + .xform_type = RTE_CRYPTO_ASYM_XFORM_MODINV, + .op_types = 0, + { + .modlen = { + /* min length is based on openssl rsa keygen */ + .min = 0, + /* value 0 symbolizes no limit on max length */ + .max = 0, + .increment = 1 + }, } + } + }, + } + }, + { /* dh */ + .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC, + {.asym = { + .xform_type = RTE_CRYPTO_ASYM_XFORM_DH, + .xfrm_capa = { + .xform_type = RTE_CRYPTO_ASYM_XFORM_DH, + .op_types = + ((1<data->nb_queue_pairs; } -/** Returns the size of the session structure */ +/** Returns the size of symmetric session structure */ static unsigned openssl_pmd_session_get_size(struct rte_cryptodev *dev __rte_unused) { return sizeof(struct openssl_session); } +/** Returns the size of the session structure */ +static unsigned +openssl_pmd_asym_session_get_size(struct rte_cryptodev *dev __rte_unused) +{ + return sizeof(struct openssl_asym_session); +} + /** Configure the session from a crypto xform chain */ static int openssl_pmd_session_configure(struct rte_cryptodev *dev __rte_unused, @@ -713,6 +824,236 @@ openssl_pmd_session_configure(struct rte_cryptodev *dev __rte_unused, return 0; } +static int openssl_set_asym_session_parameters( + struct openssl_asym_session *asym_session, + struct rte_crypto_asym_xform *xform) +{ + + if ((xform->xform_type != RTE_CRYPTO_ASYM_XFORM_DH) && + (xform->next != NULL)) { + OPENSSL_LOG_ERR("chained xfrms are not supported on %s", + rte_crypto_asym_xform_strings[xform->xform_type]); + return -1; + } + + switch (xform->xform_type) { + case RTE_CRYPTO_ASYM_XFORM_RSA: + { + struct rte_crypto_rsa_xform *xfrm = &(xform->rsa); + asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_RSA; + + RSA *rsa = RSA_new(); + if (rsa == NULL) + return -1; + /* copy xfrm data into rsa struct */ + rsa->n = BN_bin2bn((const unsigned char *)xfrm->n.data, + xfrm->n.length, rsa->n); + rsa->e = BN_bin2bn((const unsigned char *)xfrm->e.data, + xfrm->e.length, rsa->e); + if (xfrm->key_type == RTE_RSA_KEY_TYPE_EXP) { + rsa->d = BN_bin2bn((const unsigned char *)xfrm->d.data, + xfrm->d.length, + rsa->d); + } else { + rsa->p = BN_bin2bn( + (const unsigned char *)xfrm->qt.p.data, + xfrm->qt.p.length, + rsa->p); + rsa->q = BN_bin2bn( + (const unsigned char *)xfrm->qt.q.data, + xfrm->qt.q.length, + rsa->q); + rsa->dmp1 = BN_bin2bn( + (const unsigned char *)xfrm->qt.dP.data, + xfrm->qt.dP.length, + rsa->dmp1); + rsa->dmq1 = BN_bin2bn( + (const unsigned char *)xfrm->qt.dQ.data, + xfrm->qt.dQ.length, + rsa->dmq1); + rsa->iqmp = BN_bin2bn( + (const unsigned char *) + xfrm->qt.qInv.data, + xfrm->qt.qInv.length, + rsa->iqmp); + } + asym_session->u.r.rsa = rsa; + break; + } + case RTE_CRYPTO_ASYM_XFORM_MODEX: + { + struct rte_crypto_modex_xform *xfrm = &(xform->modex); + + asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_MODEX; + + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + OPENSSL_LOG_ERR(" failed to allocate resources\n"); + return -1; + } + BN_CTX_start(ctx); + BIGNUM *mod = BN_CTX_get(ctx); + BIGNUM *exp = BN_CTX_get(ctx); + if (mod == NULL || exp == NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return -1; + } + mod = BN_bin2bn((const unsigned char *)xfrm->modulus.data, + xfrm->modulus.length, mod); + exp = BN_bin2bn((const unsigned char *)xfrm->exponent.data, + xfrm->exponent.length, exp); + asym_session->u.e.ctx = ctx; + asym_session->u.e.mod = mod; + asym_session->u.e.exp = exp; + break; + } + case RTE_CRYPTO_ASYM_XFORM_MODINV: + { + struct rte_crypto_modinv_xform *xfrm = &(xform->modinv); + + asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_MODINV; + + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + OPENSSL_LOG_ERR(" failed to allocate resources\n"); + return -1; + } + BN_CTX_start(ctx); + BIGNUM *mod = BN_CTX_get(ctx); + if (mod == NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return -1; + } + + mod = BN_bin2bn((const unsigned char *) + xfrm->modulus.data, + xfrm->modulus.length, + mod); + asym_session->u.m.ctx = ctx; + asym_session->u.m.modulus = mod; + break; + } + case RTE_CRYPTO_ASYM_XFORM_DH: + { + asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_DH; + + asym_session->u.dh.dh_key = DH_new(); + DH *dh = asym_session->u.dh.dh_key; + if (dh == NULL) { + OPENSSL_LOG_ERR(" failed to allocate resources\n"); + return -1; + } + + dh->p = BN_bin2bn((const unsigned char *) + xform->dh.p.data, + xform->dh.p.length, + dh->p); + + dh->g = BN_bin2bn((const unsigned char *) + xform->dh.g.data, + xform->dh.g.length, + dh->g); + + /* setup xfrom for + * public key generate, or + * DH Priv key generate, or both + * public and private key generate + */ + asym_session->u.dh.key_op = (1 << xform->dh.type); + + if (xform->dh.type == RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE) { + /* check if next is pubkey */ + if ((xform->next != NULL) && + (xform->next->xform_type == + RTE_CRYPTO_ASYM_XFORM_DH) && + (xform->next->dh.type == + RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE)) { + /* setup op as pub/priv key pair generation */ + asym_session->u.dh.key_op |= + (1 << RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE); + } + } + break; + } + case RTE_CRYPTO_ASYM_XFORM_DSA: + { + asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_DSA; + + asym_session->u.s.dsa = DSA_new(); + DSA *dsa = asym_session->u.s.dsa; + if (dsa == NULL) { + OPENSSL_LOG_ERR( + " failed to allocate resources\n"); + return -1; + } + + dsa->p = BN_bin2bn((const unsigned char *) + xform->dsa.p.data, + xform->dsa.p.length, + dsa->p); + + dsa->g = BN_bin2bn((const unsigned char *) + xform->dsa.g.data, + xform->dsa.g.length, + dsa->g); + + dsa->q = BN_bin2bn((const unsigned char *) + xform->dsa.q.data, + xform->dsa.q.length, + dsa->q); + + dsa->priv_key = BN_bin2bn((const unsigned char *) + xform->dsa.x.data, + xform->dsa.x.length, + dsa->priv_key); + + break; + } + default: + return -1; + } + + return 0; +} + +/** Configure the session from a crypto xform chain */ +static int +openssl_pmd_asym_session_configure(struct rte_cryptodev *dev __rte_unused, + struct rte_crypto_asym_xform *xform, + struct rte_cryptodev_asym_session *sess, + struct rte_mempool *mempool) +{ + void *asym_sess_private_data; + int ret; + + if (unlikely(sess == NULL)) { + OPENSSL_LOG_ERR("invalid asymmetric session struct"); + return -EINVAL; + } + + if (rte_mempool_get(mempool, &asym_sess_private_data)) { + CDEV_LOG_ERR( + "Couldn't get object from session mempool"); + return -ENOMEM; + } + + ret = openssl_set_asym_session_parameters(asym_sess_private_data, + xform); + if (ret != 0) { + OPENSSL_LOG_ERR("failed configure session parameters"); + + /* Return session to mempool */ + rte_mempool_put(mempool, asym_sess_private_data); + return ret; + } + + set_asym_session_private_data(sess, dev->driver_id, + asym_sess_private_data); + + return 0; +} /** Clear the memory of session so it doesn't leave key material behind */ static void @@ -732,6 +1073,58 @@ openssl_pmd_session_clear(struct rte_cryptodev *dev, } } +static void openssl_reset_asym_session(struct openssl_asym_session *sess) +{ + switch (sess->xfrm_type) { + case RTE_CRYPTO_ASYM_XFORM_RSA: + if (sess->u.r.rsa) + RSA_free(sess->u.r.rsa); + break; + case RTE_CRYPTO_ASYM_XFORM_MODEX: + if (sess->u.e.ctx) { + BN_CTX_end(sess->u.e.ctx); + BN_CTX_free(sess->u.e.ctx); + } + break; + case RTE_CRYPTO_ASYM_XFORM_MODINV: + if (sess->u.m.ctx) { + BN_CTX_end(sess->u.m.ctx); + BN_CTX_free(sess->u.m.ctx); + } + break; + case RTE_CRYPTO_ASYM_XFORM_DH: + if (sess->u.dh.dh_key) + DH_free(sess->u.dh.dh_key); + break; + case RTE_CRYPTO_ASYM_XFORM_DSA: + if (sess->u.s.dsa) + DSA_free(sess->u.s.dsa); + break; + default: + break; + } +} + +/** Clear the memory of asymmetric session + * so it doesn't leave key material behind + */ +static void +openssl_pmd_asym_session_clear(struct rte_cryptodev *dev, + struct rte_cryptodev_asym_session *sess) +{ + uint8_t index = dev->driver_id; + void *sess_priv = get_asym_session_private_data(sess, index); + + /* Zero out the whole structure */ + if (sess_priv) { + openssl_reset_asym_session(sess_priv); + memset(sess_priv, 0, sizeof(struct openssl_asym_session)); + struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv); + set_asym_session_private_data(sess, index, NULL); + rte_mempool_put(sess_mp, sess_priv); + } +} + struct rte_cryptodev_ops openssl_pmd_ops = { .dev_configure = openssl_pmd_config, .dev_start = openssl_pmd_start, @@ -750,8 +1143,11 @@ struct rte_cryptodev_ops openssl_pmd_ops = { .queue_pair_count = openssl_pmd_qp_count, .session_get_size = openssl_pmd_session_get_size, + .asym_session_get_size = openssl_pmd_asym_session_get_size, .session_configure = openssl_pmd_session_configure, - .session_clear = openssl_pmd_session_clear + .asym_session_configure = openssl_pmd_asym_session_configure, + .session_clear = openssl_pmd_session_clear, + .asym_session_clear = openssl_pmd_asym_session_clear }; struct rte_cryptodev_ops *rte_openssl_pmd_ops = &openssl_pmd_ops; diff --git a/drivers/crypto/openssl/rte_openssl_pmd_private.h b/drivers/crypto/openssl/rte_openssl_pmd_private.h index bc8dc7cdc..ebc9dee53 100644 --- a/drivers/crypto/openssl/rte_openssl_pmd_private.h +++ b/drivers/crypto/openssl/rte_openssl_pmd_private.h @@ -8,6 +8,10 @@ #include #include #include +#include +#include +#include + #define CRYPTODEV_NAME_OPENSSL_PMD crypto_openssl /**< Open SSL Crypto PMD device name */ @@ -157,6 +161,31 @@ struct openssl_session { } __rte_cache_aligned; +/** OPENSSL crypto private asymmetric session structure */ +struct openssl_asym_session { + enum rte_crypto_asym_xform_type xfrm_type; + union { + struct rsa { + RSA *rsa; + } r; + struct exp { + BIGNUM *exp; + BIGNUM *mod; + BN_CTX *ctx; + } e; + struct mod { + BIGNUM *modulus; + BN_CTX *ctx; + } m; + struct dh { + DH *dh_key; + uint32_t key_op; + } dh; + struct { + DSA *dsa; + } s; + } u; +} __rte_cache_aligned; /** Set and validate OPENSSL crypto session parameters */ extern int openssl_set_session_parameters(struct openssl_session *sess,