From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM02-SN1-obe.outbound.protection.outlook.com (mail-sn1nam02on0073.outbound.protection.outlook.com [104.47.36.73]) by dpdk.org (Postfix) with ESMTP id 610991CB4B for ; Thu, 5 Apr 2018 13:26:19 +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=7ptAk+15HWsXiWblVho8DeO5A/VbWThgAMzEPHMV0bU=; b=HGxvtrFnjKaDCota/VGeIPJRHlnienD1MRfmkxt0tTN9NEyyu0Y4l1l2HurIONDu+wUsJR7EWs9wr3qw7t0NHQTIp50v5Kf6zRCUGS94JeGdO3DommPtc8ctcdU4J3h/wJ/hsuiAmwWbOvOnA2hP5lbSKVm37C2D7/8Vn74dBOo= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Shally.Verma@cavium.com; Received: from hyd1sverma-dt.caveonetworks.com (115.113.156.2) by CY4PR0701MB3634.namprd07.prod.outlook.com (2603:10b6:910:92::36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.653.12; Thu, 5 Apr 2018 11:26:14 +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: Thu, 5 Apr 2018 16:54:48 +0530 Message-Id: <1522927489-23668-6-git-send-email-shally.verma@caviumnetworks.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1522927489-23668-1-git-send-email-shally.verma@caviumnetworks.com> References: <1522927489-23668-1-git-send-email-shally.verma@caviumnetworks.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [115.113.156.2] X-ClientProxiedBy: BM1PR0101CA0013.INDPRD01.PROD.OUTLOOK.COM (2603:1096:b00:18::23) To CY4PR0701MB3634.namprd07.prod.outlook.com (2603:10b6:910:92::36) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 401a56fe-7161-4f27-2ac5-08d59ae80c6e X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4604075)(4534165)(7168020)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020); SRVR:CY4PR0701MB3634; X-Microsoft-Exchange-Diagnostics: 1; CY4PR0701MB3634; 3:qdSrU+o5ukiNtaaypWa+tnFDIA7ESHBLI6vCOr1cCiD0NYSI3Xv1RiMbBzBJtRZjrpnsNtZU+YjfFiRyKsyoKY+pb7jo4G3BJuBgug58YPXz9yhmBVBZ2JaaFqxS6WZf6LB0ugjOEszggQXRTz0S1NK7TD44qvQJHSOPLWFxGRNwFBmDZczx1CnDCa4MceKdJU2QFaBVbISuzaMVnx/IBg49BNSlrSm2ybXaDoUVPmsjgh7fVg/fVNaXvs2B183J; 25:Gm5cy3t6DnHhjiisQk6CDPkKTHBE500q+KfWjTbzyJ3CK/+gwTeCpDjXkF+jFB+cSk1Ujun3072NrJ3uXOcPUVPh9Us/kRhvA3wrE2xdlEK+2kq8MltBoxr8ywHksxqqYBvD207leQUi7LHuaVVcYXzi2zlstPv7iv1no6gEYFAJXYmg8DGM5BuAx7QoIjh4YGU7Lzct6bsrb6haHkxMxN7cqZpH4zXjyzjIBbMSzGAuyJAzwqoXE5wu5Hs7Wjh4+wjkcQjYBugCr1tS87TvAgjbaxrh4wm+ggxMAdQ+Zv0wZz9OKnaYrf4DZrOzZIceOaFMngEJXlwaQnhI+cu77Q==; 31:laepGt+oN5Jx7EkECo/anLLhx+iow8JRiJYkt6TTBDUhOw3L/vA63rus0XTVPoy4j7NfbDRlhMfNkIZcpQG6Gz+67tw52UIodJBG93FdNXpwDyN5YRWnC2Rkun5poERGawOpUt5bFON2V7av8V6zvQXI4BgPeB+ly95k0nsg/1sGq2h+9k1fIvMDAkdP5+9azr5xZW8ILew36jSyAsXMbRNOAsofx9aVpC1WJwa25jo= X-MS-TrafficTypeDiagnostic: CY4PR0701MB3634: X-Microsoft-Exchange-Diagnostics: 1; CY4PR0701MB3634; 20:ZQihl4fg7lQ3n+kr8o/giCnPMcB5meXx9ftBEukv+Qt5WUIgLWpobbz8jilEF448Tq7jzwz5oWi61RweVOslCURevFgPgqGgRJC0wKi07/5fiJu9skjqMA4jM5bDPc2Heb8J1sUW3ZbDAFWnzqpxNvhRLO9YH+7q0MO0m+ZYJyN5s6sfMKr/HmM7NCkmO5t+sOfQQzUFI8Pq1L56sWc/58LibvHI8o8DtRPUrUrsvWpODDtgQhFpciax0bd1Zak8uOhXGqyMA/t1vaZJ+Tfr2UxTf8IrBTGnC/vJZVCegdnFUWVQzXNVoNvcy/JuWh44n9b3I/rAPQ7Dsnlz+HHlSaJaYTdR+CtuFh8iO0OwF607hZMjNb/Z/U9pvi+JSRZtEx1pWsuHJnl9IzGms4mcoqmg6ply/b04KLibf8bqX0/qvYEwxTvqDR5pZEn9hybhiOEyLsoh8h7XCXERUOederz2l4OQ8J6p4KChaqUhxp92Vtf5fVdzSXSuGGvHTL6JkUF85TZBdQJORSlZvDzLPwsTN2uWAhXMrZi87rMUeEOxFjxvT0pHway4XWntHl35n0HYTAzfZM0gJFqryiYtwtv2+c355KdknhnEW3/X6Pg=; 4:I+0dx1SqKyiM0KvyjIXOUYrbt0tB5FnuF2ofnKGSuEcjihyEO0zyUJnspY2a6ECIJCOc0MZ/eRUmeY9V2X8S1YZKP8FOacaAgxZS5hz/mZ/9G7ytZaExB17EoBFWDmxPxbFlZytbipmEPP28vXobeQfz5/ZeCqt7pp4eElz/MeRE+6Iue4t6CqGWaSO/b2fhjm7/csuDN3qEpHWHhRqwfxV/l4yr/1EnBpXzTwVQW9Uf7pyD+/NnYxcBHCGXbk2GTsf5MTfgOjX7S5ohx8rTuw== 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)(3002001)(3231221)(944501327)(52105095)(93006095)(10201501046)(6041310)(20161123564045)(20161123558120)(20161123562045)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(6072148)(201708071742011); SRVR:CY4PR0701MB3634; BCL:0; PCL:0; RULEID:; SRVR:CY4PR0701MB3634; X-Forefront-PRVS: 06339BAE63 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(346002)(39380400002)(366004)(376002)(396003)(39860400002)(199004)(189003)(72206003)(478600001)(59450400001)(106356001)(6116002)(47776003)(575784001)(7736002)(6486002)(55236004)(386003)(3846002)(4326008)(42882007)(66066001)(105586002)(486006)(2361001)(76176011)(6506007)(305945005)(25786009)(51416003)(16526019)(69596002)(5660300001)(186003)(2351001)(26005)(6916009)(36756003)(53416004)(6666003)(54906003)(48376002)(8936002)(52116002)(81156014)(476003)(8676002)(2616005)(956004)(11346002)(97736004)(446003)(68736007)(53936002)(6512007)(2906002)(316002)(107886003)(16586007)(50226002)(81166006)(50466002); DIR:OUT; SFP:1101; SCL:1; SRVR:CY4PR0701MB3634; 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; CY4PR0701MB3634; 23:YilI5FfpgS4YwW5FZOaqALfJORsFqNYLspyyO9E?= =?us-ascii?Q?UAKLq53S+WuXt5VQQ8uScGXi0X6mDsaabzCa2wpsgEtft7JVKJR8fMlf2Pdu?= =?us-ascii?Q?WsB82/Ev8YQV+87NGibmGdtcWb2GzcxLJBMJEyAGfC8KdXG7uItAy28quk7H?= =?us-ascii?Q?VDt29gTHgda0lwHIh5W4wPrqilvXB/TZ265aoqrwzVdasaRd8LsnDYby8VZ3?= =?us-ascii?Q?2mEETcUGt23uuk2Jt0FSGTaM/1BSJOQAGlCgEOpJIwYHezNrsDPL1hKVbeTo?= =?us-ascii?Q?EdGSkYNXju1t/08+3ABGTUCRNH0+rfOZ7jkaeg7nOIrBOTxwPlmiGI3M4wmO?= =?us-ascii?Q?x1LA1BGBTeGnMUl+t+U+HoG+iQddk6NbYcf2n0cMg4EUN+zyynfGYmOFLV8Z?= =?us-ascii?Q?KTKN+kEsy0vdNMUTSaZUIVqsHMCxyHdqRHh0Xdtk9aS1m7CbfZpsq4mtUw0W?= =?us-ascii?Q?PQYYHDd9sMN8IyiZo3vvVAiGnRoKiXotaBEj2VRDvjJh8+n+jajAP7JZX7TV?= =?us-ascii?Q?Wc0R6IOhYWrfyhMP+K9LAcQknbOTBsgesQhU8LVntGs7CIAO1dee/fbfKQ59?= =?us-ascii?Q?gCvF6f8YBTotvGJoQgD3EXBlbnYw3RBr67AKM6PVKRxXR0FIvltHsFMB7NEi?= =?us-ascii?Q?qhpfuQcZQjLI/Ixdiu+2l+0dM+68m2etdZU8eukqzQ0IOBUDn9l+YQ7OsZ9a?= =?us-ascii?Q?3MDN/u645KzudABCXcgFKlLJEKzosLWf9+WaNfRLNNDzsGXsmoTEItKYJI5W?= =?us-ascii?Q?lOwNh8guKoNLXIPlOyKGTMvi5h2C1tpYUm0qrL2OuBQBmxbEU/lfy4nH7obL?= =?us-ascii?Q?m8gYhPpKvqFydXOlxFTcdkRQzv6jR+82TA3ic822JuP9F62HizosOrln5qG2?= =?us-ascii?Q?vNWlr5PGqWiHsXhnOdOkaRhzdSbH/58NHOH/ecZ+zbO88PGC1ow4w368axqb?= =?us-ascii?Q?f7YdNj0VtgzN/PqoVhyUL0emJkhJkNoILtjPmexV1CLQ6wb5xxW9LVuKp+Bo?= =?us-ascii?Q?SFvrfx63qOt2ZPzLg67QUiTDpWs/DCiPriykH8rrCNfRWdyYudiLrOltxxah?= =?us-ascii?Q?SuQilUk42STRfZQLbaX99g0deHGAEs+lflZ0hqMqMIY/oblbO6RvxsH70/et?= =?us-ascii?Q?J5XZORD+fmWdk1//JjNRvwCToTTETNMYVDc4r6kRfK5JRnJMV80fsxpTkBBc?= =?us-ascii?Q?ZCg15DUpuT/+D9TPw1ju00/LP0wd7BErWPE+JoCNXnyWEHMUiBbfrpZAMQ5C?= =?us-ascii?Q?blPIyuAgtyxJLttZPW9Jp+M0d1tmqRrpZHhioxaN8Sg4xzTPUnmBuxvNgrDl?= =?us-ascii?Q?cMAw4XExUb2aZjJ1uTYRv75EY48gMkp6QcxbekyXyu8/9BffO3Uw9sjY3uMn?= =?us-ascii?Q?hQGNeKGElgrMd3oK4QxSHfEEciZXjgN9QLcFBVsPz1bqTz5uf?= X-Microsoft-Antispam-Message-Info: NToiHs4LkgBS8Z2RF4gZ5xaubgbJuxmqYs5Eo9goAu3bbhjpL0pviWdjP8u6pCXd1EyZHVqhZW2pJHZxEuh8ZGp0livlw9VKxbRQrZLuVccERQnivULdOyLAQc5RqJE86rCEMcb8k3hrrI8WJ1abGcfGmyWI6OC4VL0dhZ556I4Ryy1BSQfDS7iXPiSdJTv/ X-Microsoft-Exchange-Diagnostics: 1; CY4PR0701MB3634; 6:wc/Ei71awBYzd5S0KtS1j91Az9h+gLzgWMGXoXN+ysoP1dhj4Fj0NofXasOmH85nzkfIket17LMaBYWiiCN6/1g4rpW4RU7abgqLDlITXmQGdsWyQjc6/ezJJr8Y6lp0F63IFQW+F4VBEDNH7Iu93uyk1NItgsqtKaini7xmlLY5LfdS21ZOLqbAdYqBai6lyDzSibZB5AsUAqGxIpIPAhZ/+aN59/w9VA593n2pWuYO2Xw0ybaWu16Mg0BID48Jz7yTc1taF3ada6ZUEEVQl2c9AG4jGhOsNh+jv6O+wepYQJ4wkUbDCLvR0EbU/YQkNMzxcEGDTiggc5dJaEeJvf1RpOor25YE1VvJqMQjfvePyhsIISSAbLh/w2GrnaxDFbNx/N03fUufnZxmm2TYpKu7t5KBoeEMkPDfjiZZHcaz/pkoZCXbxlByozjRg9v2ajEQ2tGGmEs1TpP9Mx7W9w==; 5:JD87H7C+N5uF10bDTodLJ19Shk56zKRVuxbQGWh2/8WKcasbsI6SRRkPNxTCvHDCdjNoUAp0kk11qBmUIJ+Db6bSMWvDocifzCnRqGA6KYiBAX2a/z5xC5olAGDXRKIO4+dncXD4ipWPg/LWUxIixlKu9CvvRdmHuZCY9UmcWM4=; 24:6b0CsxHfjuf08+EZxFwXkImcZ9ZA0RbMuzK1YjO/jQux0VFPRBR74ryni/LMGextQeOladlBhy5fNTNIQ7CF+ve3MLCzRH1Ew16ACWThzT0= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; CY4PR0701MB3634; 7:kwhPqDucko2NPjUwiTa9ZjCa/+vELHV9Y13lFTOltA297EhmKJnqBMuVQxC0FhgNkQ0R35J5mo2PPPJucPwY7pt6jyMuBoD1Vxv4DxZj5njjRpkkZhefCg5VbGrkiCwILgIqJ+1XOruP1orsAIN54Yol89kaRJOt1pqaCFyTPp8TEYOP6WfBajywytBoWsE+KGUfxRJwR0FVooVXEYbw30Auuo5s1A2ZUZ4xEBNMIo2RZCjmuyW0JWXW7TecDDsA X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Apr 2018 11:26:14.5339 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 401a56fe-7161-4f27-2ac5-08d59ae80c6e X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 711e4ccf-2e9b-4bcf-a551-4094005b6194 X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR0701MB3634 Subject: [dpdk-dev] [PATCH v2 5/6] 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: , X-List-Received-Date: Thu, 05 Apr 2018 11:26:20 -0000 Add asymmetric crypto operation support in openssl PMD. Current list of supported asym xforms: * RSA * DSA * Deffie-hellman * Modular Operations changes from v1: - resolve new line error in dod/guides/cryptodevs/openssl.rst Signed-off-by: Shally Verma Signed-off-by: Sunila Sahu Signed-off-by: Ashish Gupta -- Please apply asymmetric crypto API patches before compilation --- doc/guides/cryptodevs/features/openssl.ini | 11 + doc/guides/cryptodevs/openssl.rst | 1 + 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, 806 insertions(+), 12 deletions(-) diff --git a/doc/guides/cryptodevs/features/openssl.ini b/doc/guides/cryptodevs/features/openssl.ini index 6915658..bef5c7f 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 427fc80..4f90be8 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: diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c index f584d0d..527e427 100644 --- a/drivers/crypto/openssl/rte_openssl_pmd.c +++ b/drivers/crypto/openssl/rte_openssl_pmd.c @@ -727,19 +727,35 @@ static void HMAC_CTX_free(HMAC_CTX *ctx) } /** 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 @@ static void HMAC_CTX_free(HMAC_CTX *ctx) 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 void HMAC_CTX_free(HMAC_CTX *ctx) 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 @@ static void HMAC_CTX_free(HMAC_CTX *ctx) 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 @@ static void HMAC_CTX_free(HMAC_CTX *ctx) 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 1cb87d5..ae8c44d 100644 --- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c +++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c @@ -469,6 +469,110 @@ }, } }, } }, + { /* 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 @@ 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 @@ } } +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 bc8dc7c..ebc9dee 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, -- 1.9.1