From patchwork Wed Mar 23 15:04:16 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tudor Ambarus X-Patchwork-Id: 8650731 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: X-Original-To: patchwork-linux-crypto@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 4F8E99F44D for ; Wed, 23 Mar 2016 15:04:37 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B46D420211 for ; Wed, 23 Mar 2016 15:04:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 119B82025A for ; Wed, 23 Mar 2016 15:04:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753574AbcCWPEd (ORCPT ); Wed, 23 Mar 2016 11:04:33 -0400 Received: from mail-bl2on0068.outbound.protection.outlook.com ([65.55.169.68]:49792 "EHLO na01-bl2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754055AbcCWPEc (ORCPT ); Wed, 23 Mar 2016 11:04:32 -0400 Received: from BLUPR03CA010.namprd03.prod.outlook.com (10.255.124.27) by DM2PR03MB383.namprd03.prod.outlook.com (10.141.55.17) with Microsoft SMTP Server (TLS) id 15.1.434.16; Wed, 23 Mar 2016 15:04:29 +0000 Received: from BL2FFO11FD053.protection.gbl (10.255.124.4) by BLUPR03CA010.outlook.office365.com (10.255.124.27) with Microsoft SMTP Server (TLS) id 15.1.447.15 via Frontend Transport; Wed, 23 Mar 2016 15:04:28 +0000 Authentication-Results: spf=fail (sender IP is 192.88.168.50) smtp.mailfrom=nxp.com; nxp.com; dkim=none (message not signed) header.d=none;nxp.com; dmarc=none action=none header.from=nxp.com; Received-SPF: Fail (protection.outlook.com: domain of nxp.com does not designate 192.88.168.50 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.168.50; helo=tx30smr01.am.freescale.net; Received: from tx30smr01.am.freescale.net (192.88.168.50) by BL2FFO11FD053.mail.protection.outlook.com (10.173.161.181) with Microsoft SMTP Server (TLS) id 15.1.443.6 via Frontend Transport; Wed, 23 Mar 2016 15:04:28 +0000 Received: from enigma.ea.freescale.net (enigma.ea.freescale.net [10.171.77.120]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id u2NF4M5q030045; Wed, 23 Mar 2016 08:04:26 -0700 From: Tudor Ambarus To: , CC: , , , Tudor Ambarus Subject: [PATCH v2 1/4] crypto: rsa - generalize ASN.1 sequences Date: Wed, 23 Mar 2016 17:04:16 +0200 Message-ID: <1458745459-1096-2-git-send-email-tudor-dan.ambarus@nxp.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1458745459-1096-1-git-send-email-tudor-dan.ambarus@nxp.com> References: <1458745459-1096-1-git-send-email-tudor-dan.ambarus@nxp.com> X-EOPAttributedMessage: 0 X-Matching-Connectors: 131032190686898451; (91ab9b29-cfa4-454e-5278-08d120cd25b8); () X-Forefront-Antispam-Report: CIP:192.88.168.50; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(2980300002)(1109001)(1110001)(339900001)(199003)(189002)(1220700001)(189998001)(77096005)(47776003)(5003940100001)(11100500001)(2950100001)(50226001)(92566002)(4326007)(86362001)(2906002)(87936001)(19580395003)(5001770100001)(48376002)(50986999)(104016004)(36756003)(19580405001)(50466002)(586003)(76176999)(106466001)(105606002)(5008740100001)(85426001)(6806005)(229853001)(81166005)(33646002)(1096002)(7059030)(4720700001); DIR:OUT; SFP:1101; SCL:1; SRVR:DM2PR03MB383; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; MLV:sfv; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BL2FFO11FD053; 1:7pcT02SE4XTc9k3BmF5xRIOaXNZUO2Ellpi189jhXMknjwew0NY7xz5QY7WlEjKBm8CAUXHfBLHMXXeATTPRT9nzhxtmlryddzmyxFURH4SnbaIn1hu9Vx/KPTkIpjjZzL0MZs2OQzmVCc8zJ2PaziOfrFW6AT9W9DqAhxYZ816JjQ23vV9seJkDPIUZxEe8Ac9Y5RfsagE3+bkz9whC1uD1rZi9QFTzr+H3Q+1eSMz5Ol7GQBuwVID7opoMFnERSCxvmxqHbv6YPHliOqQe1pTf5lVdPn2177ecjt9wRfDifoXPHcdoZm+w4XPvSxMIzwKcVEKkrw+20P1IPPh/wbAza7bo7kB++H8TFaHxlqBVGZZjqqV7uh3n45boaqQJ9e4NEqiRqpniHthQXRELuHdkARC0bCtdXQiVlCxwZTorB2Jsf4UJAiJVifx7Qknfl0bDmVcqEoD0wS5NJgmZXRqQDrnIJ1mDL+bwFV3o73Zpfu/a0k/2sJuvSwj7dyNYi1uTAb11xVWYgIDaYdfdtbb/8D4nzq+N2XjaiPminpt6tvJkRT8hPB6qlla9VTXHWkXoHDqVDTy1C7ncf9kOerU+AcAJvyhT3xRi71q4QeD/7cpFEuoaXjC9tjQUjN2VtDMFPB+EOPZyaURDytzidkjFSUEzrHwCU+UPXT0/6z8= MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: 05590b32-c73b-47b9-a913-08d3532c6e7f X-Microsoft-Exchange-Diagnostics: 1; DM2PR03MB383; 2:JEd6aehRNNP/6/Re89EwL+KcF52IpC1/0gq3nWj2qZTmCDefN76Gx9ggWuYRlHjMquh8hjLeabizYTYHhQozxv4+wRWtAVXXMb1HER3ZSWBu3/3sjkqT+nhWiXjIWgvg/3fBOPXd2vgac59CPkr9ogxJxq/09kw60LRnYYWr9NnLpXeqc2ESmYn3HFHEnSiB; 3:zJDDuGdNSf2JvhqVj4X3GfBL8ZF6nQGcWPLdrf9O8Bj7H9jnXGc0axuvJhOlyi/KlhbBwy3FKl+X1SXMzGlQ1WtmVMICL8OXhq/qMSwVvJDqJaCWLSKYVGBHP3fsSf4/652d4Ye5o0JLXSHTUsl8onfPBZU3ngSRkSUfcN+SGJ5GEw4rgIvtP+jYwvAZv1rldP6j9Es6NVWueDvFrtWt8XQx53vHprEr/eYX9Mukano=; 25:v2hhWv58+svfLwcVVE3RYFIR6LFYzfWsC8gz/+5LtByHOHbf63QcIiPipvIlW7vKFenreUlgk5KiukFr8TcPEp9nKrNkncbVqNa7OFZJiNk4PSHtvQIVP/DRtyBkVDdux7pD9HeIRQO4HZaDnNPGqtdop14sTUvuLVnZPbwS8E+o7A+/QarBTF44KVLwEsXYjcp/0yhial5wjPrXH+RHJHXt17/WxJPFF8YsWl1/dJlyCdgk5SSWXk2ogxwrSgRHIkidl66EKSWLuHiaW7a752BRnXgoUx3YEyKJBV+UJRd14uM3iL64OXDloDeXCn7UtUq54ZseJMQ5i4mx7u/3fTlO5/exTUqYvduTZtxGjs/IBtDb3/kdg+tk9ONPIi+SVtuXEgSYLyrjrVa39gKPgHr4YJZpK/rzHJTemirWkJFG4+ioyPejVYO1MFE97B2Ue5iuDzck5KwpFcBqvR5QB8TDcJxFYawVfK3ts2hsBEB1lR7Ix6doyyH+ 6oEBTFTW8+B3OYEV0dhxdgYg07RCFQ== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:DM2PR03MB383; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(13023025)(13024025)(13017025)(13015025)(5005006)(8121501046)(13018025)(10201501046)(3002001); SRVR:DM2PR03MB383; BCL:0; PCL:0; RULEID:(400006); SRVR:DM2PR03MB383; X-Microsoft-Exchange-Diagnostics: 1; DM2PR03MB383; 4:yoVRYLjGoCSmmhwm9U+oIWsfiX0unygERrve/Zow6BjdgtcXe5FHF6WkBYmQR9CoGRhwUriHW5kJpV0L5Spp6AaWFU78GABtG6u5Q9TUdAhaY/kUmjp3jXQejS4K8zmIkWQ9vBFOwmRcEBC4j/cNhuqvxGhtWHQRrc0bc1aflY+PY+HUsN2dNwVFIHbeh+FBM877zzqKsrr4gCjexLZPEVWejgH9y34y8LmXaztyIjVrPsgL99b8hIvnlabcN1XEIhXrNElHArN7baqM6NA3AOdKpOprgAmJOWB5yJ/70ZPsVLALWCt1dQ3cm9YW9hIgp2B6+xUWlMKgBosHgf3dlEOhGrWo63VyF3D6+LUX/LfYK5k2u3z3ukQjcC3ohfw96vP2xKIMKtCEdADgK2EVELETQ3AnwDw6qebJbGwha1QzmXFwqHleCvqMGulb/iEaGuffZvBXaYkpoQFUMupr4A== X-Forefront-PRVS: 08902E536D X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DM2PR03MB383; 23:DieXLHE0GpiOZeFCg2h86AdOO7nTRtIcGXE9WaOr+p?= =?us-ascii?Q?Bg2Cv/I9RBdVJxs383fDjTO+I0v0hY5f/s1HwAH3IgPh7u3GM3nUnH4CRre0?= =?us-ascii?Q?s4anoH0D3R8uaPllYh+wh058NwtlKTzlt090xIlyz81VHBDbPFEgkCLWr1jC?= =?us-ascii?Q?tEgNbMZOgVZQ7B6XoIfE7HCPElXu07mBKzggpGNTlqIuH0dVSOyLRrWLhsj/?= =?us-ascii?Q?4X2vqm2gN7gpZivL5g3UEKsVq3lC1TB+4KM92CiqrdgihozmWXmsHb92fhUI?= =?us-ascii?Q?I6l4Raz49Rbg401bl01SzastZfHPKz89Sr6IseGKJR6/JfkywlNEmlNaN+FU?= =?us-ascii?Q?4oFQC8hUX7BSHUXhsJdYC3U07OcnpUPuHWfoGBJII7taluh4DCH9T/tys/sq?= =?us-ascii?Q?GQUSFLRYszJYSMlXu7DY8o5IqS2T7o2eU9KFmH1yXnx/D14tAe4U60wd5vBT?= =?us-ascii?Q?cHsPU9o6wl02JxSotkmHPw91sd2jVIXoqR7Ez8tlKy/MJpZkxqVw89ETwgaG?= =?us-ascii?Q?/kHwp5ArGO8XNOeiyWv9JEu1pY74owvPcr2Qj1v63LVImymS0uj7W5C2MLo4?= =?us-ascii?Q?L64izFQ9SmWir1OMJo2+UZm66Sq4oclF8NxVnznhqEGUVgKn4m4ifV6PXmn2?= =?us-ascii?Q?mN50t8uDFFHY2FaLUIH2nQ4jbRkv3npUtuk6ASAQQ9CR0fyZ892Mc/j53Lfc?= =?us-ascii?Q?qxWoupQqmA20oG+i0yTewZ0UjI64ywnkHmaqdFnACDNYXd3ix7wYlDypzJoA?= =?us-ascii?Q?UFD7tW87bMNX7X/BPAT3PcJrO3WQgAuuXLUpXKVp2vDM8Imr99MMYyw1vNL7?= =?us-ascii?Q?KG2MJN/3psqbIkm+ZZuiAkdtlkNDUoI1fNG+jslRuH51qtxlZh08yEfSqkXq?= =?us-ascii?Q?f4QP36Tr9uXhtkxAmP4PNUO2rck2XuxSyGHBdVrmz9E75GX3DGPFh/XvQ+ZO?= =?us-ascii?Q?305p6n0BauQJhDKZmJswOaISBDfRDKDj91UoCYHpzUvgUdFAY7Hd6/cpXfdN?= =?us-ascii?Q?hklP8k0+MCg3QRkg1EH99W50CmTZVbntzhJJ/B7l73kOKVPDgxBuWCLhnRpA?= =?us-ascii?Q?yXjNZh/oxdr1Mz6aixsMNI57sj?= X-Microsoft-Exchange-Diagnostics: 1; DM2PR03MB383; 5:FlGpjRuCoQfNtFIjwZTkjcM8DgByj46nSUqhwcQPYSVhsLYv/8KRvzbsi4tGDEKINTiUGG7qa2Z91AJ5zPlwA9apMQrpzlcmfg39DlEi0b5j7Ggvco8i4ACZpxLJbrQOo8oZL+oSQXDR3uKLyA5m/FJYcW1+mm+NQCWRfd+MvDg=; 24:eV1ZVVrpVMKl4J0Npo0tXNUfOxNi6QO78M4G/Z2kwCHdYmrb4dr2b6oextrb9Qqn6ucoEClpBdE0EXfsM4m97U2EOuPlx4c0riWdQ5hS6Ps= SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Mar 2016 15:04:28.4870 (UTC) X-MS-Exchange-CrossTenant-Id: 5afe0b00-7697-4969-b663-5eab37d5f47e X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=5afe0b00-7697-4969-b663-5eab37d5f47e; Ip=[192.88.168.50]; Helo=[tx30smr01.am.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM2PR03MB383 Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Use common ASN.1 sequences for all RSA implementations. Give hardware RSA implementations the chance to use the RSA's software implementation parser even if they are likely to want to use raw integers. The parser expects a context that contains at the first address a pointer to a struct rsa_asn1_action instance that has function pointers to specific parser actions (return MPI or raw integer keys), followed by a key representation structure (for MPI or raw integers). This approach has the advantage that users can select specific parser actions by using a general parser with function pointers to specific actions. Signed-off-by: Tudor Ambarus Acked-by: Cristian Stoica --- crypto/rsa.c | 60 ++++++++++----- crypto/rsa_helper.c | 166 ++++++++++++++++++++++++++++++++---------- include/crypto/internal/rsa.h | 31 ++++++-- 3 files changed, 194 insertions(+), 63 deletions(-) diff --git a/crypto/rsa.c b/crypto/rsa.c index 77d737f..7cb0153 100644 --- a/crypto/rsa.c +++ b/crypto/rsa.c @@ -19,7 +19,7 @@ * RSAEP function [RFC3447 sec 5.1.1] * c = m^e mod n; */ -static int _rsa_enc(const struct rsa_key *key, MPI c, MPI m) +static int _rsa_enc(const struct rsa_mpi_key *key, MPI c, MPI m) { /* (1) Validate 0 <= m < n */ if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0) @@ -33,7 +33,7 @@ static int _rsa_enc(const struct rsa_key *key, MPI c, MPI m) * RSADP function [RFC3447 sec 5.1.2] * m = c^d mod n; */ -static int _rsa_dec(const struct rsa_key *key, MPI m, MPI c) +static int _rsa_dec(const struct rsa_mpi_key *key, MPI m, MPI c) { /* (1) Validate 0 <= c < n */ if (mpi_cmp_ui(c, 0) < 0 || mpi_cmp(c, key->n) >= 0) @@ -47,7 +47,7 @@ static int _rsa_dec(const struct rsa_key *key, MPI m, MPI c) * RSASP1 function [RFC3447 sec 5.2.1] * s = m^d mod n */ -static int _rsa_sign(const struct rsa_key *key, MPI s, MPI m) +static int _rsa_sign(const struct rsa_mpi_key *key, MPI s, MPI m) { /* (1) Validate 0 <= m < n */ if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0) @@ -61,7 +61,7 @@ static int _rsa_sign(const struct rsa_key *key, MPI s, MPI m) * RSAVP1 function [RFC3447 sec 5.2.2] * m = s^e mod n; */ -static int _rsa_verify(const struct rsa_key *key, MPI m, MPI s) +static int _rsa_verify(const struct rsa_mpi_key *key, MPI m, MPI s) { /* (1) Validate 0 <= s < n */ if (mpi_cmp_ui(s, 0) < 0 || mpi_cmp(s, key->n) >= 0) @@ -71,15 +71,17 @@ static int _rsa_verify(const struct rsa_key *key, MPI m, MPI s) return mpi_powm(m, s, key->e, key->n); } -static inline struct rsa_key *rsa_get_key(struct crypto_akcipher *tfm) +static inline struct rsa_mpi_key *rsa_get_key(struct crypto_akcipher *tfm) { - return akcipher_tfm_ctx(tfm); + struct rsa_ctx *ctx = akcipher_tfm_ctx(tfm); + + return &ctx->key; } static int rsa_enc(struct akcipher_request *req) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); - const struct rsa_key *pkey = rsa_get_key(tfm); + const struct rsa_mpi_key *pkey = rsa_get_key(tfm); MPI m, c = mpi_alloc(0); int ret = 0; int sign; @@ -118,7 +120,7 @@ err_free_c: static int rsa_dec(struct akcipher_request *req) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); - const struct rsa_key *pkey = rsa_get_key(tfm); + const struct rsa_mpi_key *pkey = rsa_get_key(tfm); MPI c, m = mpi_alloc(0); int ret = 0; int sign; @@ -156,7 +158,7 @@ err_free_m: static int rsa_sign(struct akcipher_request *req) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); - const struct rsa_key *pkey = rsa_get_key(tfm); + const struct rsa_mpi_key *pkey = rsa_get_key(tfm); MPI m, s = mpi_alloc(0); int ret = 0; int sign; @@ -195,7 +197,7 @@ err_free_s: static int rsa_verify(struct akcipher_request *req) { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); - const struct rsa_key *pkey = rsa_get_key(tfm); + const struct rsa_mpi_key *pkey = rsa_get_key(tfm); MPI s, m = mpi_alloc(0); int ret = 0; int sign; @@ -251,15 +253,16 @@ static int rsa_check_key_length(unsigned int len) static int rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen) { - struct rsa_key *pkey = akcipher_tfm_ctx(tfm); + struct rsa_ctx *ctx = akcipher_tfm_ctx(tfm); + struct rsa_mpi_key *pkey = &ctx->key; int ret; - ret = rsa_parse_pub_key(pkey, key, keylen); + ret = rsa_parse_mpi_pub_key(ctx, key, keylen); if (ret) return ret; if (rsa_check_key_length(mpi_get_size(pkey->n) << 3)) { - rsa_free_key(pkey); + rsa_free_mpi_key(pkey); ret = -EINVAL; } return ret; @@ -268,15 +271,16 @@ static int rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, static int rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen) { - struct rsa_key *pkey = akcipher_tfm_ctx(tfm); + struct rsa_ctx *ctx = akcipher_tfm_ctx(tfm); + struct rsa_mpi_key *pkey = &ctx->key; int ret; - ret = rsa_parse_priv_key(pkey, key, keylen); + ret = rsa_parse_mpi_priv_key(ctx, key, keylen); if (ret) return ret; if (rsa_check_key_length(mpi_get_size(pkey->n) << 3)) { - rsa_free_key(pkey); + rsa_free_mpi_key(pkey); ret = -EINVAL; } return ret; @@ -284,16 +288,31 @@ static int rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key, static int rsa_max_size(struct crypto_akcipher *tfm) { - struct rsa_key *pkey = akcipher_tfm_ctx(tfm); + struct rsa_mpi_key *pkey = rsa_get_key(tfm); return pkey->n ? mpi_get_size(pkey->n) : -EINVAL; } +static const struct rsa_asn1_action rsa_action = { + .get_n = rsa_get_mpi_n, + .get_e = rsa_get_mpi_e, + .get_d = rsa_get_mpi_d, +}; + +static int rsa_init_tfm(struct crypto_akcipher *tfm) +{ + struct rsa_ctx *ctx = akcipher_tfm_ctx(tfm); + + ctx->action = &rsa_action; + + return 0; +} + static void rsa_exit_tfm(struct crypto_akcipher *tfm) { - struct rsa_key *pkey = akcipher_tfm_ctx(tfm); + struct rsa_mpi_key *pkey = rsa_get_key(tfm); - rsa_free_key(pkey); + rsa_free_mpi_key(pkey); } static struct akcipher_alg rsa = { @@ -304,13 +323,14 @@ static struct akcipher_alg rsa = { .set_priv_key = rsa_set_priv_key, .set_pub_key = rsa_set_pub_key, .max_size = rsa_max_size, + .init = rsa_init_tfm, .exit = rsa_exit_tfm, .base = { .cra_name = "rsa", .cra_driver_name = "rsa-generic", .cra_priority = 100, .cra_module = THIS_MODULE, - .cra_ctxsize = sizeof(struct rsa_key), + .cra_ctxsize = sizeof(struct rsa_ctx), }, }; diff --git a/crypto/rsa_helper.c b/crypto/rsa_helper.c index d226f48..0149ed3 100644 --- a/crypto/rsa_helper.c +++ b/crypto/rsa_helper.c @@ -21,7 +21,95 @@ int rsa_get_n(void *context, size_t hdrlen, unsigned char tag, const void *value, size_t vlen) { - struct rsa_key *key = context; + const struct rsa_asn1_action **action = context; + + if ((*action)->get_n) + return (*action)->get_n(context, value, vlen); + + return 0; +} + +int rsa_get_e(void *context, size_t hdrlen, unsigned char tag, + const void *value, size_t vlen) +{ + const struct rsa_asn1_action **action = context; + + if ((*action)->get_e) + return (*action)->get_e(context, value, vlen); + + return 0; +} + +int rsa_get_d(void *context, size_t hdrlen, unsigned char tag, + const void *value, size_t vlen) +{ + const struct rsa_asn1_action **action = context; + + if ((*action)->get_d) + return (*action)->get_d(context, value, vlen); + + return 0; +} + +int rsa_get_p(void *context, size_t hdrlen, unsigned char tag, + const void *value, size_t vlen) +{ + const struct rsa_asn1_action **action = context; + + if ((*action)->get_p) + return (*action)->get_p(context, value, vlen); + + return 0; +} + +int rsa_get_q(void *context, size_t hdrlen, unsigned char tag, + const void *value, size_t vlen) +{ + const struct rsa_asn1_action **action = context; + + if ((*action)->get_q) + return (*action)->get_q(context, value, vlen); + + return 0; +} + +int rsa_get_dp(void *context, size_t hdrlen, unsigned char tag, + const void *value, size_t vlen) +{ + const struct rsa_asn1_action **action = context; + + if ((*action)->get_dp) + return (*action)->get_dp(context, value, vlen); + + return 0; +} + +int rsa_get_dq(void *context, size_t hdrlen, unsigned char tag, + const void *value, size_t vlen) +{ + const struct rsa_asn1_action **action = context; + + if ((*action)->get_dq) + return (*action)->get_dq(context, value, vlen); + + return 0; +} + +int rsa_get_qinv(void *context, size_t hdrlen, unsigned char tag, + const void *value, size_t vlen) +{ + const struct rsa_asn1_action **action = context; + + if ((*action)->get_qinv) + return (*action)->get_qinv(context, value, vlen); + + return 0; +} + +int rsa_get_mpi_n(void *context, const void *value, size_t vlen) +{ + struct rsa_ctx *ctx = context; + struct rsa_mpi_key *key = &ctx->key; key->n = mpi_read_raw_data(value, vlen); @@ -38,11 +126,12 @@ int rsa_get_n(void *context, size_t hdrlen, unsigned char tag, } return 0; } +EXPORT_SYMBOL_GPL(rsa_get_mpi_n); -int rsa_get_e(void *context, size_t hdrlen, unsigned char tag, - const void *value, size_t vlen) +int rsa_get_mpi_e(void *context, const void *value, size_t vlen) { - struct rsa_key *key = context; + struct rsa_ctx *ctx = context; + struct rsa_mpi_key *key = &ctx->key; key->e = mpi_read_raw_data(value, vlen); @@ -51,11 +140,12 @@ int rsa_get_e(void *context, size_t hdrlen, unsigned char tag, return 0; } +EXPORT_SYMBOL_GPL(rsa_get_mpi_e); -int rsa_get_d(void *context, size_t hdrlen, unsigned char tag, - const void *value, size_t vlen) +int rsa_get_mpi_d(void *context, const void *value, size_t vlen) { - struct rsa_key *key = context; + struct rsa_ctx *ctx = context; + struct rsa_mpi_key *key = &ctx->key; key->d = mpi_read_raw_data(value, vlen); @@ -72,8 +162,14 @@ int rsa_get_d(void *context, size_t hdrlen, unsigned char tag, } return 0; } +EXPORT_SYMBOL_GPL(rsa_get_mpi_d); -static void free_mpis(struct rsa_key *key) +/** + * rsa_free_mpi_key() - frees rsa key allocated by rsa_parse_key() + * + * @rsa_mpi_key: struct rsa_mpi_key key representation + */ +void rsa_free_mpi_key(struct rsa_mpi_key *key) { mpi_free(key->n); mpi_free(key->e); @@ -82,68 +178,64 @@ static void free_mpis(struct rsa_key *key) key->e = NULL; key->d = NULL; } +EXPORT_SYMBOL_GPL(rsa_free_mpi_key); /** - * rsa_free_key() - frees rsa key allocated by rsa_parse_key() + * rsa_parse_mpi_pub_key() - extracts an RSA public key from BER encoded buffer + * and stores it in the provided context. * - * @rsa_key: struct rsa_key key representation - */ -void rsa_free_key(struct rsa_key *key) -{ - free_mpis(key); -} -EXPORT_SYMBOL_GPL(rsa_free_key); - -/** - * rsa_parse_pub_key() - extracts an rsa public key from BER encoded buffer - * and stores it in the provided struct rsa_key - * - * @rsa_key: struct rsa_key key representation + * @rsa_ctx: RSA internal context * @key: key in BER format * @key_len: length of key * * Return: 0 on success or error code in case of error */ -int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key, - unsigned int key_len) +int rsa_parse_mpi_pub_key(struct rsa_ctx *ctx, const void *key, + unsigned int key_len) { + struct rsa_mpi_key *rsa_key = &ctx->key; int ret; - free_mpis(rsa_key); - ret = asn1_ber_decoder(&rsapubkey_decoder, rsa_key, key, key_len); + /* Free the old key if any */ + rsa_free_mpi_key(rsa_key); + + ret = asn1_ber_decoder(&rsapubkey_decoder, ctx, key, key_len); if (ret < 0) goto error; return 0; error: - free_mpis(rsa_key); + rsa_free_mpi_key(rsa_key); return ret; } -EXPORT_SYMBOL_GPL(rsa_parse_pub_key); +EXPORT_SYMBOL_GPL(rsa_parse_mpi_pub_key); /** - * rsa_parse_pub_key() - extracts an rsa private key from BER encoded buffer - * and stores it in the provided struct rsa_key + * rsa_parse_mpi_priv_key() - extracts an RSA private key from BER encoded + * buffer and stores it in the provided context. * - * @rsa_key: struct rsa_key key representation + * @rsa_ctx: RSA internal context * @key: key in BER format * @key_len: length of key * * Return: 0 on success or error code in case of error */ -int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key, - unsigned int key_len) +int rsa_parse_mpi_priv_key(struct rsa_ctx *ctx, const void *key, + unsigned int key_len) { + struct rsa_mpi_key *rsa_key = &ctx->key; int ret; - free_mpis(rsa_key); - ret = asn1_ber_decoder(&rsaprivkey_decoder, rsa_key, key, key_len); + /* Free the old key if any */ + rsa_free_mpi_key(rsa_key); + + ret = asn1_ber_decoder(&rsaprivkey_decoder, ctx, key, key_len); if (ret < 0) goto error; return 0; error: - free_mpis(rsa_key); + rsa_free_mpi_key(rsa_key); return ret; } -EXPORT_SYMBOL_GPL(rsa_parse_priv_key); +EXPORT_SYMBOL_GPL(rsa_parse_mpi_priv_key); diff --git a/include/crypto/internal/rsa.h b/include/crypto/internal/rsa.h index c7585bd..f8ef7b1 100644 --- a/include/crypto/internal/rsa.h +++ b/include/crypto/internal/rsa.h @@ -14,19 +14,38 @@ #define _RSA_HELPER_ #include -struct rsa_key { +struct rsa_asn1_action { + int (*get_n)(void *context, const void *value, size_t vlen); + int (*get_e)(void *context, const void *value, size_t vlen); + int (*get_d)(void *context, const void *value, size_t vlen); + int (*get_p)(void *context, const void *value, size_t vlen); + int (*get_q)(void *context, const void *value, size_t vlen); + int (*get_dp)(void *context, const void *value, size_t vlen); + int (*get_dq)(void *context, const void *value, size_t vlen); + int (*get_qinv)(void *context, const void *value, size_t vlen); +}; + +struct rsa_mpi_key { MPI n; MPI e; MPI d; }; -int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key, - unsigned int key_len); +struct rsa_ctx { + const struct rsa_asn1_action *action; + struct rsa_mpi_key key; +}; + +int rsa_get_mpi_n(void *context, const void *value, size_t vlen); +int rsa_get_mpi_e(void *context, const void *value, size_t vlen); +int rsa_get_mpi_d(void *context, const void *value, size_t vlen); -int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key, - unsigned int key_len); +void rsa_free_mpi_key(struct rsa_mpi_key *key); -void rsa_free_key(struct rsa_key *rsa_key); +int rsa_parse_mpi_pub_key(struct rsa_ctx *ctx, const void *key, + unsigned int key_len); +int rsa_parse_mpi_priv_key(struct rsa_ctx *ctx, const void *key, + unsigned int key_len); extern struct crypto_template rsa_pkcs1pad_tmpl; #endif